您好!
我指的是有关 McBSP DMA 的链接主题的最后一个问题。
在我们的系统中、一个 SPI 从器件被连接至用作 SPI 主器件的 C2000 McBSP 模块(通过 McBSP)。 从器件定期(每1ms)请求 SPI 主器件使用 GPIO (外部中断)启动 SPI 传输。 传输的字节数为12字节。 SPI 传输由 DMA 处理并在 EXTI 中断(来自从器件)中启动。 由于 C2000也在控制电机、EXTI ISR 所花费的时间必须尽可能短(= McBSP + DMA 传输初始化且 START 必须是最佳)。
问题是:如果我在启动时只初始化一次 DMA 通道、那么第一次传输是正确的(发送了12个字节)、但下一次传输不完整:缺少前4个字节(仅发送了8个字节)。
您是否有什么想法不是为了重新启用 DMA 通道(运行= 1)来重新启动完整的传输?
下面是 DMA 配置:
DMA->DMACTRL |=(1 <<0); ASM (" NOP"); //通道1:McBSPA 发送 //------ dma->ch1.burse_size = 1u; //每个突发 DMA 2个16位字->CH1.SRC_BURST_STEP = 1;//递增1个16位地址。 在 dma->ch1.dst_burst_step = 1之间;//递增1个16位 addr。 在 dma->ch1.transfer_size = 2U 之间;//每隔(2 + 1)个突发(= 12字节)中断一次。 DMA->CH1.SRC_TRANSFER_STEP = 1;//在突发中的每个字之后移至缓冲器中的下一个字。 DMA->CH1.dst_transfer_step = 0xFFFF;//减量返回 McBSP DXR2寄存器。 dma->ch1.SRC_ADDR_SHADDADDR =(UINT32_t)&p_txBuf[0]; dma->ch1.SRC_beg_ADDR_SHADDR =(UINT32_t)&p_txBuf[0];// TODO (S):不需要-要检查。 dma->ch1.dst_ADDR_SHADDADDR =(uint32_t)&obj->mcbspAHandle->DXR2; dma->ch1.dst_beg_ADDR_shadow =(uint32_t)&obj->mcbspAHandle->DXR2;// TODO (S):不需要检查。 //清除同步错误标志 dma->ch1.control |=(1U <<7); //设置为最大值以避免任何源/目标绕回。 DMA->CH1.SRC_WOP_SIZE = 0xFFFFFFU; DMA->CH1.DST_WOP_SIZE = 0xFFFFFFU; // DMA->CH1.MODE |=(1U << 15);//启用通道中断。 DMA->CH1.MODE |=(1U <<9);//在传输结束时生成中断。 DMA->CH1.MODE |=(1U <<8);//启用外设中断事件。 DMA->CH1.MODE |=(14U <<0);// DMA 中断源:MXEVTA (McBSP 传输)。 dma->ch1.control |=(1U <<4);//清除所有杂散中断标志。 //通道2:McBSPA 接收 //--------------- dma->ch2.burse_size = 1u; //每个突发 DMA 2个16位字->CH2.SRC_BURST_STEP = 1;//递增1个16位地址。 在 dma->ch2.dst_burst_step = 1之间;//递增1个16位 addr。 在 dma->ch2.transfer_size = 2U 之间;//每隔(2 + 1)个突发(= 12字节)中断一次。 DMA->CH2.SRC_TRANSFER_STEP = 0xFFFF;//再回到 McBSP DRR2寄存器。 dma->ch2.dst_transfer_step = 1;//在突发中的每个字之后移动到缓冲器中的下一个字。 dma->ch2.SRC_ADDR_SHADDR_SHADDR =(UINT32_t)&obj->mcbspAHandle->DRR2; dma->ch2.SRC_beg_ADDR_SHADDR_SHADDR =(UINT32_t)&obj->mcbspAHandle->DRR2;// TODO (S):不需要检查。 dma->ch2.dst_ADDR_SHADDADDR =(UINT32_t)&p_rxBuf[0]; dma->ch2.dst_beg_ADDR_SHADDR =(UINT32_t)&p_rxBuf[0];// TODO (S):不需要-要检查。 //清除同步错误标志 dma->ch2.control |=(1U <<7); //设置为最大值以避免任何源/目标绕回。 DMA->CH2.SRC_WOP_SIZE = 0xFFFFFFU; DMA->CH2.DST_WOP_SIZE = 0xFFFFFFU; DMA->CH2.MODE |=(1U << 15);//启用通道中断。 DMA->CH2.MODE |=(1U <<9);//在传输结束时生成中断。 DMA->CH2.MODE |=(1U <<8);//启用外设中断事件。 DMA->CH2.MODE |=(15U << 0);// DMA 中断源:MREVTA (McBSP 接收)。 dma->ch2.control |=(1U <<4);//清除任何伪中断标志。
以下是在每个从器件请求时重新启动传输的代码:
enable_protected_register_write_mode; dma->ch1.control |=(1U <<0); dma->ch2.control |=(1U <<0); disable_protected_register_write_mode;
以下是第一个传输(完成):
下面是下一次传输(缺少字节):
此致