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.
// DMA Initialization for data size <= 16-bit
void init_dma()
{
EALLOW;
DmaRegs.DMACTRL.bit.HARDRESET = 1;
__asm(" NOP"); // Only 1 NOP needed per Design
DmaRegs.CH1.MODE.bit.CHINTE = 0;
// Channel 1, McBSPA transmit
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 = 127; // Interrupt every frame (127 bursts/transfer)
DmaRegs.CH1.SRC_TRANSFER_STEP = 1; // Move to next word in buffer after each word in a burst
DmaRegs.CH1.DST_TRANSFER_STEP = 0; // Don't move destination address
DmaRegs.CH1.SRC_ADDR_SHADOW = (Uint32) &sdata[0]; // Start address = buffer
DmaRegs.CH1.SRC_BEG_ADDR_SHADOW = (Uint32) &sdata[0]; // Not needed unless using wrap function
DmaRegs.CH1.DST_ADDR_SHADOW = (Uint32) &McbspaRegs.DXR1.all; // Start address = McBSPA DXR
DmaRegs.CH1.DST_BEG_ADDR_SHADOW = (Uint32) &McbspaRegs.DXR1.all; // 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.SYNCE = 0; // No sync signal
DmaRegs.CH1.MODE.bit.SYNCSEL = 0; // No sync signal
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 = DMA_MXEVTA; // Peripheral interrupt select = McBSP MXSYNCA
DmaRegs.CH1.CONTROL.bit.PERINTCLR = 1; // Clear any spurious interrupt flags
// Channel 2, McBSPA Receive
DmaRegs.CH2.MODE.bit.CHINTE = 0;
DmaRegs.CH2.BURST_SIZE.all = 0; // 1 word/burst
DmaRegs.CH2.SRC_BURST_STEP = 0; // no effect when using 1 word/burst
DmaRegs.CH2.DST_BURST_STEP = 0; // no effect when using 1 word/burst
DmaRegs.CH2.TRANSFER_SIZE = 127; // Interrupt every 127 bursts/transfer
DmaRegs.CH2.SRC_TRANSFER_STEP = 0; // Don't move source address
DmaRegs.CH2.DST_TRANSFER_STEP = 1; // Move to next word in buffer after each word in a burst
DmaRegs.CH2.SRC_ADDR_SHADOW = (Uint32) &McbspaRegs.DRR1.all; // Start address = McBSPA DRR
DmaRegs.CH2.SRC_BEG_ADDR_SHADOW = (Uint32) &McbspaRegs.DRR1.all; // Not needed unless using wrap function
DmaRegs.CH2.DST_ADDR_SHADOW = (Uint32) &rdata[0]; // Start address = Receive buffer (for McBSP-A)
DmaRegs.CH2.DST_BEG_ADDR_SHADOW = (Uint32) &rdata[0]; // Not needed unless using wrap function
DmaRegs.CH2.CONTROL.bit.PERINTCLR = 1; // Clear peripheral interrupt event flag
DmaRegs.CH2.CONTROL.bit.SYNCCLR = 1; // Clear sync flag
DmaRegs.CH2.CONTROL.bit.ERRCLR = 1; // Clear sync error flag
DmaRegs.CH2.DST_WRAP_SIZE = 0xFFFF; // Put to maximum - don't want destination wrap
DmaRegs.CH2.SRC_WRAP_SIZE = 0xFFFF; // Put to maximum - don't want source wrap
DmaRegs.CH2.MODE.bit.CHINTE = 1; // Enable channel interrupt
DmaRegs.CH2.MODE.bit.CHINTMODE = 1; // Interrupt at end of transfer
DmaRegs.CH2.MODE.bit.PERINTE = 1; // Enable peripheral interrupt event
DmaRegs.CH2.MODE.bit.PERINTSEL = DMA_MREVTA; // Peripheral interrupt select = McBSP MRSYNCA
DmaRegs.CH2.CONTROL.bit.PERINTCLR = 1; // Clear any spurious interrupt flags
EDIS;
}
一、项目中使用到F28335的MCBSP作为SPI使用进行数据收发,在不适用DMA情况下正常。当使用DMA进行数据收发。多次收发后DMA中断无法产生,RUNSTS状态永久1.
二、以上是我参考《Example_2833xMcBSP_DLB_DMA.c》进行配置的
三、由于使用场景的特殊性,并未使用DMA中断判断收发是否完成,使用的是RUNSTS进行判断。数据收发间隔5MS,
收发代码如下:
EALLOW;
DmaRegs.CH1.CONTROL.bit.HALT =1;
DmaRegs.CH2.CONTROL.bit.HALT =1;
DmaRegs.CH1.TRANSFER_SIZE = (rx_len+2); // Interrupt every frame (127 bursts/transfer
DmaRegs.CH2.TRANSFER_SIZE = (rx_len+2); // Interrupt every 127 bursts/transfer
DmaRegs.CH1.CONTROL.bit.RUN = 1; // Start DMA Transmit from McBSP-A
DmaRegs.CH2.CONTROL.bit.RUN = 1; // Start DMA Receive from McBSP-A
EDIS;
while(DmaRegs.CH1.CONTROL.bit.RUNSTS||DmaRegs.CH2.CONTROL.bit.RUNSTS)//未发送完成
{
}
大家好,最近项目中使用到F28335的MCBSP作为SPI使用进行数据收发。(1)不开启DMA时,工作正常(2)如果开启DMA,若干次收发数据后。DMA中断不产生中断,RUNSTS位位1。具体是什么原因?
二、DMA配置是参考《Example_2833xMcBSP_DLB_DMA.c》进行配置的,具体如下:
// DMA Initialization for data size <= 16-bit
void init_dma()
{
EALLOW;
DmaRegs.DMACTRL.bit.HARDRESET = 1;
__asm(" NOP"); // Only 1 NOP needed per Design
DmaRegs.CH1.MODE.bit.CHINTE = 0;
// Channel 1, McBSPA transmit
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 = 127; // Interrupt every frame (127 bursts/transfer)
DmaRegs.CH1.SRC_TRANSFER_STEP = 1; // Move to next word in buffer after each word in a burst
DmaRegs.CH1.DST_TRANSFER_STEP = 0; // Don't move destination address
DmaRegs.CH1.SRC_ADDR_SHADOW = (Uint32) &sdata[0]; // Start address = buffer
DmaRegs.CH1.SRC_BEG_ADDR_SHADOW = (Uint32) &sdata[0]; // Not needed unless using wrap function
DmaRegs.CH1.DST_ADDR_SHADOW = (Uint32) &McbspaRegs.DXR1.all; // Start address = McBSPA DXR
DmaRegs.CH1.DST_BEG_ADDR_SHADOW = (Uint32) &McbspaRegs.DXR1.all; // 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.SYNCE = 0; // No sync signal
DmaRegs.CH1.MODE.bit.SYNCSEL = 0; // No sync signal
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 = DMA_MXEVTA; // Peripheral interrupt select = McBSP MXSYNCA
DmaRegs.CH1.CONTROL.bit.PERINTCLR = 1; // Clear any spurious interrupt flags
// Channel 2, McBSPA Receive
DmaRegs.CH2.MODE.bit.CHINTE = 0;
DmaRegs.CH2.BURST_SIZE.all = 0; // 1 word/burst
DmaRegs.CH2.SRC_BURST_STEP = 0; // no effect when using 1 word/burst
DmaRegs.CH2.DST_BURST_STEP = 0; // no effect when using 1 word/burst
DmaRegs.CH2.TRANSFER_SIZE = 127; // Interrupt every 127 bursts/transfer
DmaRegs.CH2.SRC_TRANSFER_STEP = 0; // Don't move source address
DmaRegs.CH2.DST_TRANSFER_STEP = 1; // Move to next word in buffer after each word in a burst
DmaRegs.CH2.SRC_ADDR_SHADOW = (Uint32) &McbspaRegs.DRR1.all; // Start address = McBSPA DRR
DmaRegs.CH2.SRC_BEG_ADDR_SHADOW = (Uint32) &McbspaRegs.DRR1.all; // Not needed unless using wrap function
DmaRegs.CH2.DST_ADDR_SHADOW = (Uint32) &rdata[0]; // Start address = Receive buffer (for McBSP-A)
DmaRegs.CH2.DST_BEG_ADDR_SHADOW = (Uint32) &rdata[0]; // Not needed unless using wrap function
DmaRegs.CH2.CONTROL.bit.PERINTCLR = 1; // Clear peripheral interrupt event flag
DmaRegs.CH2.CONTROL.bit.SYNCCLR = 1; // Clear sync flag
DmaRegs.CH2.CONTROL.bit.ERRCLR = 1; // Clear sync error flag
DmaRegs.CH2.DST_WRAP_SIZE = 0xFFFF; // Put to maximum - don't want destination wrap
DmaRegs.CH2.SRC_WRAP_SIZE = 0xFFFF; // Put to maximum - don't want source wrap
DmaRegs.CH2.MODE.bit.CHINTE = 1; // Enable channel interrupt
DmaRegs.CH2.MODE.bit.CHINTMODE = 1; // Interrupt at end of transfer
DmaRegs.CH2.MODE.bit.PERINTE = 1; // Enable peripheral interrupt event
DmaRegs.CH2.MODE.bit.PERINTSEL = DMA_MREVTA; // Peripheral interrupt select = McBSP MRSYNCA
DmaRegs.CH2.CONTROL.bit.PERINTCLR = 1; // Clear any spurious interrupt flags
EDIS;
}
三、由于使用场景的特殊性,并未使用DMA中断判断收发是否完成(中断什么都不做),使用的是RUNSTS进行判断。数据收发间隔5MS,
收发代码如下:
EALLOW;
DmaRegs.CH1.TRANSFER_SIZE = (rx_len+2); // Interrupt every frame (127 bursts/transfer
DmaRegs.CH2.TRANSFER_SIZE = (rx_len+2); // Interrupt every 127 bursts/transfer
DmaRegs.CH1.CONTROL.bit.RUN = 1; // Start DMA Transmit from McBSP-A
DmaRegs.CH2.CONTROL.bit.RUN = 1; // Start DMA Receive from McBSP-A
EDIS;
while(DmaRegs.CH1.CONTROL.bit.RUNSTS||DmaRegs.CH2.CONTROL.bit.RUNSTS)//未发送完成
{
}
为更加有效地解决您的问题,我们建议您将问题发布在E2E英文技术论坛上https://e2e.ti.com/support/microcontrollers/c2000/f/171,将由资深的工程师为您提供帮助。我们的E2E英文社区有TI专家进行回复,并得到全球各地工程师的支持,分享他们的知识和经验。