STM32 gotchas
213. ADC with DMA stops working

ADC is the peripheral which perhaps varies the most across STM32 families, so details of its working have to be carefully studied for each family . Of course, in the overall picture, the basic principles are the same: in all families, ADCs can be run relatively fast, and support sequences of conversions performed automatically, immediately after each other, or upon a rapid trigger. This makes reading out the conversion results by processor (either by polling or in interrupt) hard or straight impossible, necessitating to use DMA to store the conversion results into a buffer in memory, from where they then can be subsequently processed.

The basic principle of using DMA with ADC is again relatively simple - set up an suitable channel/stream in DMA to transfer the appropriate amount of samples from ADC's data register (ADC_DR) into the buffer in memory; set given DMA channel/stream request to ADC where applicable (either in DMA or in DMAMUX, depending on family); enable DMA requests in ADC (by setting a bit like ADC_CR2.DMA/ADC_CFGR1.DMAEN or similar), and off you go: each subsequent conversion end triggers the DMA, which then transfers the result of conversion into memory.

Sometimes, this process starts, but then unexpectedly stops. Here, again, it's the details which matter.

In most families' ADC, in the unlikely but not impossible case DMA is not able to pick all the converted data (or when enabling DMA and ADC is incorrectly sequenced), ADC overruns (as indicated by ADC_SR.OVR), and DMA is internally blocked. Procedure to re-enable DMA require to clear the overrun flag and reset DMA channel/stream as appropriate.

To prevent ADC overrun when DMA completes all transfers it was configured to (i.e. is not configured for circular transfers), most families' ADC automatically disable further conversions when the respective DMA channel/stream indicates transfer complete. This behaviour can be avoided by setting an appropriate configuration bit (ADC_CR2.DDS/ADC_CFGR1.DMACFG or similar). If an unaware user tries to set DMA to be circular, and does not set this bit, conversion thus DMA transfers unexpectedly stop after DMA reaches the set number of transfers for the first time.