尊敬的TI工程师
您好,我在使用28377d的SPI的DMA模式时发现问题,请求您的帮助解答。
首先我在syscfg中将SPI与DMA配置如下图。
在board.c中生成的初始化部分对应代码如下:
void Board_init() { EALLOW; PinMux_init(); DMA_init(); SPI_init(); EDIS; } //***************************************************************************** // // PINMUX Configurations // //***************************************************************************** void PinMux_init() { // // PinMux for modules assigned to CPU1 // // // SPIA -> mySPI0 Pinmux // GPIO_setPinConfig(mySPI0_SPIPICO_PIN_CONFIG); GPIO_setPadConfig(mySPI0_SPIPICO_GPIO, GPIO_PIN_TYPE_STD); GPIO_setQualificationMode(mySPI0_SPIPICO_GPIO, GPIO_QUAL_ASYNC); GPIO_setPinConfig(mySPI0_SPIPOCI_PIN_CONFIG); GPIO_setPadConfig(mySPI0_SPIPOCI_GPIO, GPIO_PIN_TYPE_STD); GPIO_setQualificationMode(mySPI0_SPIPOCI_GPIO, GPIO_QUAL_ASYNC); GPIO_setPinConfig(mySPI0_SPICLK_PIN_CONFIG); GPIO_setPadConfig(mySPI0_SPICLK_GPIO, GPIO_PIN_TYPE_STD); GPIO_setQualificationMode(mySPI0_SPICLK_GPIO, GPIO_QUAL_ASYNC); GPIO_setPinConfig(mySPI0_SPIPTE_PIN_CONFIG); GPIO_setPadConfig(mySPI0_SPIPTE_GPIO, GPIO_PIN_TYPE_STD); GPIO_setQualificationMode(mySPI0_SPIPTE_GPIO, GPIO_QUAL_ASYNC); } //***************************************************************************** // // DMA Configurations // //***************************************************************************** void DMA_init(){ DMA_initController(); mySPI0_RX_DMA_init(); mySPI0_TX_DMA_init(); } void mySPI0_RX_DMA_init(){ DMA_setEmulationMode(DMA_EMULATION_STOP); DMA_configAddresses(mySPI0_RX_DMA_BASE, DualMCUCommSPI_destAddress, mySPI0_RX_DMA_ADDRESS); DMA_configBurst(mySPI0_RX_DMA_BASE, 1U, 0, 1); DMA_configTransfer(mySPI0_RX_DMA_BASE, 2U, 0, 1); DMA_configWrap(mySPI0_RX_DMA_BASE, 65535U, 0, 65535U, 0); DMA_configMode(mySPI0_RX_DMA_BASE, mySPI0_RX_DMA_TRIGGER, DMA_CFG_ONESHOT_DISABLE | DMA_CFG_CONTINUOUS_DISABLE | DMA_CFG_SIZE_16BIT); DMA_enableTrigger(mySPI0_RX_DMA_BASE); DMA_stopChannel(mySPI0_RX_DMA_BASE); } void mySPI0_TX_DMA_init(){ DMA_setEmulationMode(DMA_EMULATION_STOP); DMA_configAddresses(mySPI0_TX_DMA_BASE, mySPI0_TX_DMA_ADDRESS, DualMCUCommSPI_srcAddress); DMA_configBurst(mySPI0_TX_DMA_BASE, 1U, 1, 0); DMA_configTransfer(mySPI0_TX_DMA_BASE, 2U, 1, 0); DMA_configWrap(mySPI0_TX_DMA_BASE, 65535U, 0, 65535U, 0); DMA_configMode(mySPI0_TX_DMA_BASE, mySPI0_TX_DMA_TRIGGER, DMA_CFG_ONESHOT_DISABLE | DMA_CFG_CONTINUOUS_DISABLE | DMA_CFG_SIZE_16BIT); DMA_enableTrigger(mySPI0_TX_DMA_BASE); DMA_stopChannel(mySPI0_TX_DMA_BASE); } //***************************************************************************** // // SPI Configurations // //***************************************************************************** void SPI_init(){ mySPI0_init(); } void mySPI0_init(){ SPI_disableModule(mySPI0_BASE); SPI_setConfig(mySPI0_BASE, DEVICE_LSPCLK_FREQ, SPI_PROT_POL0PHA1, SPI_MODE_CONTROLLER, mySPI0_BITRATE, mySPI0_DATAWIDTH); SPI_setPTESignalPolarity(mySPI0_BASE, SPI_PTE_ACTIVE_LOW); SPI_enableFIFO(mySPI0_BASE); SPI_disableLoopback(mySPI0_BASE); SPI_setEmulationMode(mySPI0_BASE, SPI_EMULATION_STOP_AFTER_TRANSMIT); SPI_enableModule(mySPI0_BASE); }
我在使用该SPI模块时发现,当我使用NonFIFO的primitive模式或pollingFIFO模式时,都能正确传输,但是当我用DMA模式时,传输故障,具体表现为:传输主机端完成发送接收动作后跳出该轮任务并判定传输失败,但从机却一直处在准备态,等待主机发起传输。
我把主机端的SPI应用函数放在下面这里:
typedef union SPI_ExchangeData { uint16_t data16[2]; // 16-bit representation uint32_t data32; // 32-bit representation } SPI_ExchangeData; SPI_ExchangeData gdataSendSPI[DualMCUCommSPI_BUFFER_SIZE_32BIT]; SPI_ExchangeData gdataReceiveSPI[DualMCUCommSPI_BUFFER_SIZE_32BIT]; const void *DualMCUCommSPI_destAddress = (const void*) gdataReceiveSPI; const void *DualMCUCommSPI_srcAddress = (const void*) gdataSendSPI; typedef enum { PRIMITIVE, POLLING, DMA, } TRANSFER_METHOD; void DualMCUCommSPI_transfer(TRANSFER_METHOD transferMethod) { switch(transferMethod) { case PRIMITIVE: { DualMCUCommSPI_transferPrimitive(); break; } case POLLING: { DualMCUCommSPI_transferPolling(); break; } case DMA: { DualMCUCommSPI_transferDMA(); break; } } } void DualMCUCommSPI_transferDMA(void) { DMA_startChannel(DualMCUCommSPI_TX_DMA_BASE); DMA_startChannel(DualMCUCommSPI_RX_DMA_BASE); } void DualMCUCommSPI_transferPolling(void) { SPI_pollingFIFOTransaction(DualMCUCommSPI_BASE, 16, (uint16_t *)&gdataSendSPI, (uint16_t *)&gdataReceiveSPI, 2, 0); } void DualMCUCommSPI_transferPrimitive(void) { SPI_writeDataNonBlocking(DualMCUCommSPI_BASE, gdataSendSPI[0].data16[0]); gdataReceiveSPI[0].data16[0] = SPI_readDataBlockingNonFIFO(DualMCUCommSPI_BASE); SPI_writeDataNonBlocking(DualMCUCommSPI_BASE, gdataSendSPI[0].data16[1]); gdataReceiveSPI[0].data16[1] = SPI_readDataBlockingNonFIFO(DualMCUCommSPI_BASE); }
SPI_DMA的方式我在F28388D上面曾验证测试通过,现在同样的调用方法在F28377D上却行不通,您帮我看看故障原因是DMA配置有误还是调用方式有误,除了开启TX和RX的DMA通道 还需要别的动作吗。