Due to some design requirement, I need to change DMA descriptor at runtime. To achieve this, I am following below steps:
- Abort DMA channel. DMA hardware will then save currently executing descriptor at write_back RAM location of same DMA channel.
- Wait until Abort Completed
- Modify DMA descriptor on write_back RAM location.
- Enable DMA channel again
This is code snippet I am using:
//Select DMA channel
DMAC->CHID.reg = DMAC_CHID_ID(cSPIDMAResource0.channel_id);
//Abort Selected DMA channel
DMAC->CHCTRLA.reg &= ~DMA_CHANNEL_ENABLE_BIT_POS;
//Wait until Abort completed
while((DMAC->CHCTRLA.reg & DMA_CHANNEL_ENABLE_BIT_POS) == DMA_CHANNEL_ENABLE_BIT_POS);
/*
Modify Descriptor here
*/
//Enable DMA channel
DMAC->CHCTRLA.reg |= DMA_CHANNEL_ENABLE_BIT_POS;
Above mentioned steps work fine without any problem, But I am facing Descriptor corruption issue during long run.
DMA hardware is storing currently executing descriptor at the write_back RAM location of another DMA channel (instead of own write_back RAM location) when DMA abort is performed.
If anyone has any idea of what went wrong, or has an idea of how I can avoid the Descriptor corruption issue completely, I would like to try it out.