我在 TM4C1294上的 SPI0上有一个 SPI 闪存。 读取块时、从单字节命令到几 KB 命令的传输长度各不相同。
我将使用软件中的 GPIO 控制帧选择引脚、并使用 SSI_DMARX 中断完成传输并关闭帧引脚。
对于超过几个字节的传输、这在100%的时间内都很有效、但是对于短传输、中断不会每次触发。
我猜我有一个比赛状态、但我已经尝试了我想的所有东西、所以现在寻求帮助。
以下是初始化代码:
//为外部串行存储器设置 uDMA rom_uDMAEnable(); memset (uDMAControlTable、0、sizeof (uDMAControlTable)); rom_uDMAControlBaseSet (uDMAControlTable); ROM_IntEnable (INT_UDMAERR); // SSI0用于 EXT 闪存和 FRAM SSIConfigSetExpClk (SSI0_BASE、系统 CoreClock、SSI_FRF_MOTO_MODE_0、SSI_MODE_MASTER、16000000、 8); ROM_SSIEnable (SSI0_BASE); ROM_uDMAChannelAssign (UDMA_CH10_SSI0RX); ROM_uDMAChannelAssign (UDMA_CH11_SSI0TX); ROM_uDMAChannelAttributeDisable (UDMA_CH10_SSI0RX、 UDMA_ATTR_ALL);//UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIOR| UDMA_ATTR_REQMASK); ROM_UDMA_LDCC_UDMA_RESTAULT_UDMA_RESTON_UDMA_LD_UCC_UDMA_RESTAULT_UCC_UDR_UDR_TR_UDMA_RESTON_UCC_TR_UDMA_LD_UDMA_RESTAULT_UCC_TR_UTR_UDMA_LD_UDMA_RESTON_UTR_TR_UTR_UDMA_RESTON_TR_TR_UTR_TR_UDMA_LD_TR_UDMA_RESTDA_TR_UTR_TR_TR_TR_TR_TR_UTR_UTR_TRIGN ;UDMA_RESTR_UDMA_LD_UTR_UTR_UTR_UTR_UTR_UTR_UTR_UTR_UTR_UTR
这里是运行传输的函数:
void bsp_simem (uint16_t n、uint8_t * buf) { uint16_t c、r; uint32_t a; R = n; while (r){ // DMA 一次只能执行1024字节的操作,因此将其块化: 如果(r > 1024) C = 1024; 其他 C = r; ROM_SSIDMADisable (SSI0_BASE、SSI_DMA_RX | SSI_DMA_TX);//重新配置时禁用 EVENT_CLEAR (BSP_EVENTs, EV_SSI); //确保标志已关闭 HWREG (SSI0_BASE + SSI_O_CR1)&=~SSI_CR1_EOT;//请参阅勘误表 while (ROM_SSIDataGetNonBlocking (SSI0_BASE、&a)){} //刷新 FIFO //设置 DMA 以发送和接收 ROM_uDMAChannelTransferSet (UDMA_CH11_SSI0TX | UDMA_PRI_SELECT、UDMA_MODE_BASIC、buf、(void *)(SSI0_BASE + SSI_O_DR)、c); ROM_uDMAChannelTransferSet (UDMA_CH10_SSI0RX | UDMA_PRI_SELECT、UDMA_MODE_BASIC、(void *)(SSI0_BASE + SSI_O_DR)、buf、c); ROM_uDMAChannelEnable (UDMA_CH10_SSI0RX); ROM_uDMAChannelEnable (UDMA_CH11_SSI0TX); ROM_SSIDMAEnable (SSI0_BASE、SSI_DMA_RX | SSI_DMA_TX);//开始! if (EVENT_WAIT_TIMEOUT (BSP_EVENT_SSI、5)=0) //等待中断,但不超过50ms DMA 勘误计数++; r -= c; buf += c; } }
最后、这里是 ISR。
void SSI0_IRQHandler (void)//外部闪存/ram { uint32_t f; ROM_SSIDMADisable (SSI0_BASE、SSI_DMA_RX | SSI_DMA_TX); f = ROM_SSIIntStatus (SSI0_BASE、false); ROM_SSIIntClear (SSI0_BASE、f);//清除任何中断 EVENT_SET (BSP_EVENTs, EV_SSI); }
这在99.9%的时间内工作、但随机中断不会被触发、并且更频繁地进行较短的传输。 当我将 SPI 时钟减慢至1MHz 时、它的工作效果会更好、但单字节传输偶尔也会失败。
我非常希望有任何想法或建议。
谢谢、
// Anders