I am trying to use DMA3 to change the source address of DMA1, in order to get DMA1 to write a new configuration block of data to a timer on each trigger. I have the timer ZERO event triggering DMA1 (and toggling a GPIO) and this seems to be fine. I also have DMA3 set to trigger from DMA1's 3-word block completion and perform a single word write from an SRAM array to DMA1's DMASA register. The Transfer size is configured so that once the array is exhausted, DMA3 will raise an event to toggle a GPIO, and I can see this is happening.
What I would expect to see is that the DMASA register of DMA1 is being changed - however whenever I halt the debugger I can see that the original programmed value is still there. DMA3 does not seem to be updating it. If I configure DMA3 to instead write to a value in SRAM, I can see that value is changing as expected. Is there something particular I need to do to ensure that the DMASA register is updated by a second DMA channel?
DMA1 is configured as this:
DMA3 is this:
And I'm using this code in my application:
static const uint32_t pulse_periods_and_length[NUM_PULSES * 3] = {LOAD_val0, 0, CC_01_val0, LOAD_val1, 0, CC_01_val1 ... }; static const uint32_t pulse_period_pointer[NUM_PULSES] = { (uint32_t)(&pulse_periods_and_length[0]), (uint32_t)(&pulse_periods_and_length[3]), ... (uint32_t)(&pulse_periods_and_length[24]), }; uint32_t test_array[NUM_PULSES] = { 0, }; int main(void) { SYSCFG_DL_init(); // configure initial period for timer DL_Timer_setLoadValue(DR_INST, DR1_START_PULSE_PERIOD_TICKS / 2); DL_Timer_setCaptureCompareValue(DR_INST, DR1_START_PULSE_HIGH_TIMER_VALUE, GPIO_DR_C0_IDX); DL_DMA_setSrcAddr(DMA, DR_PULSE_UPDATE_DMA_CHAN_ID, (uint32_t)(&pulse_periods_and_length[0])); DL_DMA_setDestAddr(DMA, DR_PULSE_UPDATE_DMA_CHAN_ID, (uint32_t)(&DR_INST->COUNTERREGS.LOAD)); DL_DMA_enableChannel(DMA, DR_PULSE_UPDATE_DMA_CHAN_ID); DL_DMA_setSrcAddr(DMA, DR_DMA_RECONFIGURE_CHAN_ID, (uint32_t)(&pulse_period_pointer[1])); DL_DMA_setDestAddr(DMA, DR_DMA_RECONFIGURE_CHAN_ID, (uint32_t)(&DMA->DMACHAN[DR_PULSE_UPDATE_DMA_CHAN_ID].DMASA)); // DL_DMA_setDestAddr(DMA, DR_DMA_RECONFIGURE_CHAN_ID, (uint32_t)(&test_array[0])); // DL_DMA_setTransferSize(DMA, DR_DMA_RECONFIGURE_CHAN_ID, 4); // shortened for testing DL_DMA_enableChannel(DMA, DR_DMA_RECONFIGURE_CHAN_ID); DL_Timer_startCounter(DR_INST); while(1) { __WFI(); } }