This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

F28335使用DMA接收MCBSP数据,最大接收频率只到5MHZ?



我使用DMA搬运mcbspa数据,mcbspa做SPI从设备,主设备是STM32,每5毫秒发送5个word,DMA这边设置成每接收25个word产生一次中断,并复位,现在发现主设备SPI传输时钟频率为5mhz以下就没问题,数据不丢失也不出错,主设备SPI时钟频率达到8mhz就接收到的就大量错误了,代码如下,请指导!

STM32端传输设置:16位,SPI_CPOL_High, SPI_CPHA_2Edge,FirstBit_MSB

f28335,MCBSP设置:

McbspaRegs.SPCR2.all = 0x0000; // Reset FS generator, sample rate generator & transmitter


McbspaRegs.SPCR1.all = 0x0000; // Reset Receiver, Right justify word

McbspaRegs.MFFINT.all = 0x0; // Disable all interrupts

McbspaRegs.SPCR1.bit.RJUST = 0;


McbspaRegs.SPCR1.bit.CLKSTP = 2; // 


McbspaRegs.PCR.bit.CLKXP = 0; // 


McbspaRegs.PCR.bit.CLKRP = 1; // 


McbspaRegs.PCR.bit.CLKXM = 0;


McbspaRegs.PCR.bit.CLKRM = 0;


McbspaRegs.PCR.bit.FSRP = 0;


McbspaRegs.PCR.bit.FSRM = 0;


McbspaRegs.PCR.bit.SCLKME = 0;


McbspaRegs.PCR.bit.FSXM = 0;


McbspaRegs.PCR.bit.FSXP = 1;


McbspaRegs.RCR2.bit.RPHASE = 0;


McbspaRegs.RCR2.bit.RDATDLY = 0; // FSX setup time 1 in master mode. 0 for slave mode (Receive)


McbspaRegs.XCR2.bit.XDATDLY = 0; // FSX setup time 1 in master mode. 0 for slave mode (Transmit)


McbspaRegs.SRGR2.bit.CLKSM = 1;


McbspaRegs.SRGR1.bit.CLKGDV = 0x01;


McbspaRegs.SRGR2.bit.FPER = 1;


McbspaRegs.RCR1.bit.RFRLEN1 = 4;


McbspaRegs.RCR1.bit.RWDLEN1 = 2; // 16-bit word


McbspaRegs.XCR1.bit.XFRLEN1 = 4;


McbspaRegs.XCR1.bit.XWDLEN1 = 2; // 16-bit word

McbspaRegs.RCR2.bit.RFRLEN2 = 4;


McbspaRegs.RCR2.bit.RWDLEN2 = 2;


McbspaRegs.XCR2.bit.XFRLEN2 = 4;


McbspaRegs.XCR2.bit.XWDLEN2 = 2;

McbspaRegs.RCR2.bit.RCOMPAND = 0; //No companding, any size data, MSB received first


McbspaRegs.XCR2.bit.XCOMPAND = 0;


delay_loop(); // Wait at least 2 SRG clock cycles

McbspaRegs.SPCR2.bit.GRST=1; // Enable the sample rate generator


clkg_delay_loop(); // Wait at least 2 CLKG cycles
McbspaRegs.SPCR2.bit.XRST=1; // Release TX from Reset
McbspaRegs.SPCR1.bit.RRST=1; // Release RX from Reset
McbspaRegs.SPCR2.bit.FRST=1; // Frame Sync Generator reset

F28335 DMA设置:

interrupt void local_D_INTCH1_ISR(void) // DMA Ch2
{
k++;
for(int i = 0;i<25;i++)
{
if(rdata[i] != (i%5))
{
j++;
catch2 = rdata[i];
}
}

EALLOW; // NEED TO EXECUTE EALLOW INSIDE ISR !!!
DmaRegs.CH1.CONTROL.bit.HALT = 1 ;
DmaRegs.CH1.CONTROL.bit.RUN = 1; // Re-enable DMA CH2. Should be done every transfer
PieCtrlRegs.PIEACK.all |= PIEACK_GROUP7; // To receive more interrupts from this PIE group, acknowledge this interrupt

EDIS;

return;

}

void Config_DMA_CH1(Uint32 dst_addr)
{
EALLOW;

// Perform a hard reset on DMA
DmaRegs.DMACTRL.bit.HARDRESET = 1;
__asm(" nop"); // one NOP required after HARDRESET

// Allow DMA to run free on emulation suspend
DmaRegs.DEBUGCTRL.bit.FREE = 1;

DmaRegs.CH1.MODE.bit.CHINTE = 0;


DmaRegs.CH1.BURST_SIZE.all = 0; // 1 word/burst


DmaRegs.CH1.SRC_BURST_STEP = 0; // no effect when using 1 word/burst


DmaRegs.CH1.DST_BURST_STEP = 0; // no effect when using 1 word/burst


DmaRegs.CH1.TRANSFER_SIZE = 24; // Interrupt every 25 bursts/transfer


DmaRegs.CH1.SRC_TRANSFER_STEP = 0; // Don't move source address


DmaRegs.CH1.DST_TRANSFER_STEP = 1; // Move to next word in buffer after each word in a burst


DmaRegs.CH1.SRC_ADDR_SHADOW = &McbspaRegs.DRR1.all;; // Start address = McBSPA DRR


DmaRegs.CH1.SRC_BEG_ADDR_SHADOW = &McbspaRegs.DRR1.all; // Not needed unless using wrap function


DmaRegs.CH1.DST_ADDR_SHADOW = dst_addr; // Start address = Receive buffer (for McBSP-A)


DmaRegs.CH1.DST_BEG_ADDR_SHADOW = dst_addr; // Not needed unless using wrap function


DmaRegs.CH1.CONTROL.bit.PERINTCLR = 1; // Clear peripheral interrupt event flag


DmaRegs.CH1.CONTROL.bit.SYNCCLR = 1; // Clear sync flag


DmaRegs.CH1.CONTROL.bit.ERRCLR = 1; // Clear sync error flag


DmaRegs.CH1.DST_WRAP_SIZE = 0xFFFF; // Put to maximum - don't want destination wrap


DmaRegs.CH1.SRC_WRAP_SIZE = 0xFFFF; // Put to maximum - don't want source wrap


DmaRegs.CH1.MODE.bit.CHINTE = 1; // Enable channel interrupt


DmaRegs.CH1.MODE.bit.CHINTMODE = 1; // Interrupt at end of transfer


DmaRegs.CH1.MODE.bit.PERINTE = 1; // Enable peripheral interrupt event


DmaRegs.CH1.MODE.bit.PERINTSEL = 15; // Peripheral interrupt select = McBSP MRSYNCA


DmaRegs.CH1.CONTROL.bit.PERINTCLR = 1; // Clear any spurious interrupt flags

PieVectTable.DINTCH1= &local_D_INTCH1_ISR;

PieCtrlRegs.PIEACK.bit.ACK7 = 1;


PieCtrlRegs.PIEIER7.bit.INTx1 = 1;


IER |= PIEACK_GROUP7;

EDIS;
}

dst_addr参数是Uint16的数组。

求解!