TI中文支持网
TI专业的中文技术问题搜集分享网站

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的数组。

求解!

Susan Yang:28335 DMA参数如下

• Word Size: 16-bit or 32-bit (McBSPs limited to 16-bit)
• Throughput: 4 cycles/word (5 cycles/word for McBSP reads)

您可以计算一下,是不是DMA来不及处理

我使用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的数组。

求解!

chen zeng:

回复 Susan Yang:

请问怎么计算?主设备发送是一次发送5个16-bit

赞(0)
未经允许不得转载:TI中文支持网 » F28335使用DMA接收MCBSP数据,最大接收频率只到5MHZ?
分享到: 更多 (0)