Hello,
I'm trying to implement a continuous circular DMA on a K22 to read from the ADC.
I have the PDB and ADC side working fine, but I'm struggling with the DMA. The DMA only runs once and not continuously. The callback function only gets called twice (since I have half buffer interrupts turned on) but no more after that.
I have used EDMA_SetModulo and TCDx.DLAST_SGA as suggested by others. And also ensure that DMA_CSR_DREQ is disabled with EDMA_EnableAutoStopRequest
I looked through all the forum posts and went through all the examples (Thanks mjbcswitzerland!), but nothing seems to work for me.
What am I missing? Is there a way to automatically keep the DMA running forever without needing any software intervention (like retriggering the DMA in the callback) ?
I've attached my EDMA Initialization code below :
static void adc_dma_callback(edma_handle_t *handle, void *userData, bool transferDone, uint32_t tcds){
if (transferDone){
printf("Full");
}else{
printf("Half");
}
}
void edma_init(void){
edma_config_t userConfig;
EDMA_GetDefaultConfig(&userConfig);
EDMA_Init(DMA0, &userConfig);
EDMA_CreateHandle(&dma_handle, DMA0, DMA_CH);
EDMA_InstallTCDMemory(&dma_handle, NULL, 0);
EDMA_SetCallback(&dma_handle, adc_dma_callback, NULL);
EDMA_SetModulo(DMA0, DMA_CH, kEDMA_ModuloDisable, kEDMA_Modulo4Kbytes);
dma_handle.base->TCD[DMA_CH].DLAST_SGA = -2*(int32_t)sizeof(adcBuffer);
EDMA_PrepareTransfer(&transfer_config, (void *)ADC16_RESULT_REG_ADDR, sizeof(uint32_t),
(void *)adcBuffer, sizeof(uint32_t), sizeof(uint32_t),
sizeof(adcBuffer), kEDMA_PeripheralToMemory);
status_t ret = EDMA_SubmitTransfer(&dma_handle, &transfer_config);
EDMA_EnableAutoStopRequest(DMA0, DMA_CH, false);
EDMA_EnableAsyncRequest(DMA0, DMA_CH, true);
if(ret == kStatus_Success) {
EDMA_EnableChannelInterrupts(DMA0, DMA_CH, kEDMA_MajorInterruptEnable|kEDMA_HalfInterruptEnable);
EDMA_StartTransfer(&dma_handle);
}else{
printf("ERR: DMA SUBMIT");
}
}