Part Number: DK-TM4C129X
I want to setup a scatter gather operation that includes both peripheral and memory scatter-gather on an ADC DMA channel
- transfer data from ADC FIFO to buffer 1 (peripheral)
- transfer 0x1 from memory to another memory location to act as a buffer 1 done flag (memory)
- transfer data from ADC FIFO to buffer 2 (peripheral)
- transfer 0x1 from memory to another memory location to act as a buffer 2 done flag (memory)
- transfer scatter-gather task 1 into primary channel structure to continue looping without any interrupts (memory)
If I remove items 2 and 4, the scatter-gather looping works. When items 2 and 4 are included, buffer 1 is filled with ADC data and buffer 1 done flag is set from 0 to 1 but, nothing else happens.
Task list:
// DMA Task used to reload DMA task list tDMAControlTable dmaADCReload; // DMA Task list to transfer tDMAControlTable dmaADCTasks[4] = { uDMATaskStructEntry(512, UDMA_SIZE_32, UDMA_SRC_INC_NONE, (void *)(ADC1_BASE + ADC_O_SSFIFO0), UDMA_DST_INC_32, &u32_adc_results_buf_a[0], UDMA_ARB_4, UDMA_MODE_PER_SCATTER_GATHER), uDMATaskStructEntry(1, UDMA_SIZE_32, UDMA_SRC_INC_NONE, &u32_true_flag, UDMA_DST_INC_NONE, &u32_chk_adc_buf_a, UDMA_ARB_4, UDMA_MODE_MEM_SCATTER_GATHER), uDMATaskStructEntry(512, UDMA_SIZE_32, UDMA_SRC_INC_NONE, (void *)(ADC1_BASE + ADC_O_SSFIFO0), UDMA_DST_INC_32, &u32_adc_results_buf_b[0], UDMA_ARB_4, UDMA_MODE_PER_SCATTER_GATHER),
uDMATaskStructEntry(1, UDMA_SIZE_32, UDMA_SRC_INC_NONE, &u32_true_flag, UDMA_DST_INC_NONE, &u32_chk_adc_buf_b, UDMA_ARB_1, UDMA_MODE_MEM_SCATTER_GATHER),
uDMATaskStructEntry(4, UDMA_SIZE_32,
UDMA_SRC_INC_32, &dmaADCReload,
UDMA_DST_INC_32, 0,
UDMA_ARB_4, UDMA_MODE_MEM_SCATTER_GATHER)
};
Initialization:
// ADC 1 Sequence 0 uDMA Configuration MAP_uDMAChannelAssign(UDMA_CH24_ADC1_0); // Assign channel 24 to ADC1 SS0 MAP_uDMAChannelAttributeEnable(UDMA_SEC_CHANNEL_ADC10, UDMA_ATTR_USEBURST); /* * Configures primary control structure in memory scatter-gather mode */ MAP_uDMAChannelScatterGatherSet(UDMA_SEC_CHANNEL_ADC10, 4, &dmaADCTasks, true); // Copy primary control structure to reload task structure dmaADCReload.pvSrcEndAddr = ((tDMAControlTable *)_pu8_dma_control_table)[UDMA_SEC_CHANNEL_ADC10].pvSrcEndAddr; dmaADCReload.pvDstEndAddr = ((tDMAControlTable *)_pu8_dma_control_table)[UDMA_SEC_CHANNEL_ADC10].pvDstEndAddr; dmaADCReload.ui32Control = ((tDMAControlTable *)_pu8_dma_control_table)[UDMA_SEC_CHANNEL_ADC10].ui32Control; dmaADCReload.ui32Spare = ((tDMAControlTable *)_pu8_dma_control_table)[UDMA_SEC_CHANNEL_ADC10].ui32Spare; // Set destination address of looping task dmaADCTasks[2].pvDstEndAddr = _pu8_dma_control_table + (sizeof(tDMAControlTable) * (UDMA_SEC_CHANNEL_ADC10 + 1)) - 1; // Enable sequence 0 MAP_uDMAChannelEnable(UDMA_SEC_CHANNEL_ADC10);