Part Number: TMS320F28375D
Device: TMS320F28375D
Peripherals Involved: SPI, DMA, External Interrupt
In our application, SPI DMA is used, interrupt-driven packet transactions. After running successfully for a large number of cycles (randomly between 19K to 85K transactions), the DMA channel completely halts because the PERINTFLG (Peripheral Interrupt Flag) gets stuck. Once this flag becomes stuck, no further DMA triggers are recognized, freezing all communication until a device reset.
Implementation Details
DMA configuration:
//====================================================================================
DMAInitialize();
// Configure DMA CH5 (TX)
DMACH5AddrConfig(&SpibRegs.SPITXBUF, send_frame.data);
DMACH5BurstConfig(BURST, 1, 0);
DMACH5TransferConfig(TRANSFER, 1, 0);
DMACH5ModeConfig(DMA_SPIBTX, PERINT_ENABLE, ONESHOT_DISABLE, CONT_DISABLE,
SYNC_DISABLE, SYNC_SRC, OVRFLOW_DISABLE, SIXTEEN_BIT,
CHINT_END, CHINT_ENABLE);
// Configure DMA CH6 (RX)
DMACH6AddrConfig(dma_rx_buffer, &SpibRegs.SPIRXBUF);
DMACH6BurstConfig(BURST, 0, 1);
DMACH6TransferConfig(TRANSFER, 0, 1);
DMACH6ModeConfig(DMA_SPIBRX, PERINT_ENABLE, ONESHOT_DISABLE, CONT_DISABLE,
SYNC_DISABLE, SYNC_SRC, OVRFLOW_DISABLE, SIXTEEN_BIT,
CHINT_END, CHINT_ENABLE);
//====================================================================================
DMA transfers are triggered by a peripheral/external hardware event (interrupt-driven). Both the transaction requests and the DMA TX/RX completely handled inside ISRs. A low-priority background routine runs in the main loop to check link status. However, this routine is strictly guarded by safety conditions:
-> It only executes when no DMA transaction is active.
-> It only executes when no request/response handling is in progress.
Observed Behavior
-> The system operates normally for thousands of consecutive, back-to-back interrupt-driven DMA bursts.
-> Unpredictably (after 19K, 30K, 55K, or up to 85K successful transfers), the communication drops.
-> Upon debugging during the fault condition, we found that the PERINTFLG bit for the specific DMA channel remains set/stuck, preventing the channel from recognizing subsequent trigger events.
1. What conditions or edge cases can cause a DMA channel's PERINTFLG to lock up or fail to clear when driven by peripheral interrupts?
2. Can main-loop status checks create a race condition with the DMA state machine or interrupt logic?
3. What is the recommended recovery procedure or best practice to safely reset/recover a DMA channel if its PERINTFLG gets stuck during runtime?
Sincerely,
Abhimanyu