我正在使用散聚模式将 SPI 传感器与 DMA 连接。 我在这里一定会错过一些东西。
为了从传感器 FIFO 中提取192个字节、我填充了一个任务表、每个任务表都是 DMA_ControlTable 类型的元素。 此类表如下所示;其中385个条目、需要大约6 KB、但我有足够的内存:
/* SPI 读取 DMA 序列*/ DMA_ControlTable SpiAccReadoutSEQ[N_of _ACC_DMA_tasks];
该序列倾向于重复相同的任务、只需更改几个参数;因此我编写了以下代码以快速初始化任务列表:
// SPI 读取任务 DMA_ControlTable SendAccReadoutAddr = DMA_TaskStructEntry (1、UDMA_SIZE_8、 UDMA_SRC_INC_NONE、&AccOutputAddr、 UDMA_DST_INC_NONE、&SPI_Module_Address->TXBUF、 UDMA_ARB_1、(UDMA_MODE_MEM_SP散 射_收集+ UDMA_MODE_ALT_SELECT); DMA_ControlTable SendFirstDummyByte = DMA_TaskStructEntry (1、UDMA_SIZE_8、 UDMA_SRC_INC_NONE、&dummyTx、 UDMA_DST_INC_NONE、&SPI_Module_Address->TXBUF、 UDMA_ARB_1、(UDMA_MODE_PER_SP散 射_收集+ UDMA_MODE_ALT_SELECT); DMA_ControlTable SendDummyByte = DMA_TaskStructEntry (1、UDMA_SIZE_8、 UDMA_SRC_INC_NONE、&dummyTx、 UDMA_DST_INC_NONE、&SPI_Module_Address->TXBUF、 UDMA_ARB_1、(UDMA_MODE_MEM_SP散 射_收集+ UDMA_MODE_ALT_SELECT); DMA_ControlTable 检索字节 FromAcc = DMA_TaskStructEntry (1、UDMA_SIZE_8、 UDMA_SRC_INC_NONE、&SPI_Module_Address->RXBUF、 UDMA_DST_INC_NONE、&AccDataBuffer[0]、 UDMA_ARB_1、(UDMA_MODE_PER_SP散 射_收集+ UDMA_MODE_ALT_SELECT); DMA_ControlTable 检索 LastByteFromAcc = DMA_TaskStructEntry (1、UDMA_SIZE_8、 UDMA_SRC_INC_NONE、&SPI_Module_Address->RXBUF、 UDMA_DST_INC_NONE、&AccDataBuffer[ACC_DATA_Buffer_LEN - 1]、 UDMA_ARB_1、UDMA_MODE_BASIC); SpiAccReadoutSEQ[0]= SendAccReadoutAddr; SpiAccReadoutSEQ[1]= SendFirstDummyByte; SpiAccReadoutSEQ[2]=检索字节从 Acc; 对于(I = 3;I < N_of _ACC_DMA_tasks;I += 2) { SpiAccReadoutSEQ[i]= SendDummyByte; if (i = N_of _acc_dma_tasks - 2) 中断; SpiAccReadoutSEQ[i+1]=检索字节从 Acc; SpiAccReadoutSEQ[i+1].dstEndAddr =&AccDataBuffer[(I-1)/2]; } SpiAccReadoutseq[N_of _ACC_DMA_tasks - 1]=获取 LastByteFromAcc;
DMA 的配置如下:
- 控制表:我使用6个通道以及替代通道、因此根据 uDMA 寻址方案、我分配了16个插槽:
/* DMA 控制表*/ #if defined (__TI_Compiler_version__) #pragma DATA_ALIGN (DmaControlTable,1024) #Elif defined (__IAR_SYSTEMS_ICC__) #pragma DATA_ALIGNing=1024 #Elif defined (__GNUC__) __(aligned ((aligned (__IAR_systems_cus))))__dmaControlTable_241024_ad_ad_(dirt_arm_en_en_ador_en_en_en_(#elift_(_status_(1024 )
- 外设初始化(我保留了正在使用的其他通道的跟踪、不管怎样、它们工作正常):
//启用 DMA DMA_enableModule(); //分配控制表 DMA_setControlBase (DmaControlTable); //配置 DMA 传输 DMA_setChannelControl (DMA_Wired_UART_TX_CH|UDMA_PRI_SELECT、UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_ARB_NONE | UDMA_INC_1); DMA_setChannelControl (DMA_Wired_UART_RX_CH|UDMA_PRI_SELECT、UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_ARB_8 | UDMA_INC_1); DMA_setChannelControl (DMA_OPTIC_UART_TX_CH|UDMA_PRI_SELECT、UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_ARB_NONE | UDMA_INC_1); DMA_setChannelControl (DMA_OPTIC_UART_RX_CH|UDMA_PRI_SELECT、UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_ARC_8 | UDMA_INC_1); DMA_setChannelControl (DMA_append_packet_ch|UDMA_PRI_SELECT、UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_ARB_8 | UDMA_INC_1024); //分配通道 dma_assignChannel (dma_optical_uart_TX_CH); DMA_assignChannel (DMA_wired_UART_TX_CH); dma_assignChannel (dma_optical_uart_RX_CH); DMA_assignChannel (DMA_wired_UART_RX_CH); DMA_assignChannel (DMA_SPI_TX_CH); DMA_assignChannel (DMA_SPI_RX_CH); dma_assignChannel (dma_append_packet_CH); //清除 IFG 寄存器 DMA_Channel->INT0_CLRFLG = 0xFFFFFFFF; //将中断分配给特定的 DMA ISR DMA_assignInterrupt (INT_DMA_SPI、DMA_SPI_RX_CH_NUM); //在启用前清除特定的 DMA 中断标志 DMA_clearInterruptFlag (DMA_SPI_RX_CH 和0x0F); //启用 SPI DMA 中断 DMA_enableInterrupt (INT_DMA_SPI);
- 调用传感器读取过程:
void FetchInertialData (SpiDeviceHandle *句柄) { //超时计数器 volatile uint16_t Timeout; //在开始数据传输之前,等待一些时间 超时= handle->CsInterval_T; while (--Timeout); //预载建立时间 超时= handle->setup_T; //清除 SPI Rx 中断标志 Handle->SpiModuleAddress->IFG &=~SPI_Receive_interrupt_FLAG; //降低 CS GPIO_setOutputLowOnPin (handle->CsPort、handle->CsPin); //等待建立时间 while (--Timeout); //在散聚模式下执行数据提取 if (handle =&AccSpiHandle) DMA_setChannelScatterGather (DMA_SPI_RX_CH、N_of _ACC_DMA_tasks、SpiAccReadoutSeq、0); DMA_enableChannel (DMA_SPI_RX_CH_NUM); DMA_requestSoftwareTransfer (DMA_SPI_RX_CH_NUM); }
SPI 外设工作正常、可在启动时读取和写入传感器设置。 当我尝试通过 DMA 获取外部 FIFO 内容时、会出现问题:MOSI 和 MISO 不移动、并且在示波器上对 SCK 脉冲进行计数、我只看到10字节的传输尝试。 DMA_INT1正确触发、显然太早。 我怀疑触发器有问题、有些任务只是重叠、但我现在看不出原因。
是否有线索?
