I got scan mode working with DMA. I decided to just use continuous mode and have the DMA cyclically transfer the scan sequence of channel readings into a struct with an appropriate number of fields.
It was actually pretty easy and clear what to do from looking at some of the SPL/HAL code and example code on WCH's GitHub. Although I am curious as to why on their ADC DMA example they choose to use a transfer size of 16 bits, when the ADC data register is 32 bit. I suppose it doesn't really matter, as the ADC has only 10 bit resolution, so values will never be larger than 16 bits. Maybe transfers with 16 bit size occupies the peripheral bus for less time? Anyway, it all works fine for me with 32-bit transfer size.
I'm still none the wiser exactly what mechanism is used to trigger the DMA transfer by the ADC. At the moment my best guess is "magic!".
I wish their documentation was a bit better.
By the way, because the docs state that 32-bit transfer sizes must have a 4-byte-aligned source and destination address, I did this for the memory destination:
static struct {
uint32_t ch_a2 __attribute__((warn_if_not_aligned(4)));
uint32_t ch_a3 __attribute__((warn_if_not_aligned(4)));
} adc_values __attribute__((aligned(4)));
Overkill?
I'm thinking how you have it setup either the EOC flag is never "seen", as its taken by DMA engine, or, the ADC conversion is just not starting if ADC_CTLR2->DMA is off and settings are for continuous?
Hmm, maybe you're right. Perhaps the EOC is 'stolen' by the DMA in scan mode, or scanning doesn't start without DMA mode set too.
If you have a good debugger that can view the registers live its nice, unsure if thats available for CH32v003 though.
Yes, you're able to debug with GDB, although I can't right now because for some reason OpenOCD is not cooperating lately, even though I had it working before and haven't changed anything. Oh well...