Showing results for 
Search instead for 
Did you mean: 

STM32U5 ADC1 bulb sampling multiple channels


I am using ADC1 on STM32U5 to sample two channels periodically using the DMA and a TIM6 trigger. I am doing this in bulb mode since I would like for the ADC capacitor to charge for the entire duration.

I had thought that the ADC would sample the first channel on the first TIM6 trigger and then the second channel on the second trigger. However, it seems like the ADC is racing through both channels when triggered, probably sampling them according to the SMPR register sample time for those channels.

Is that how bulb mode is expected to work when sampling multiple channels? It isn't clear. I would like the time delta between each sample to be locked to the TIM6 period rather than sampling both channels as quickly as possible then "bulbing" only the first channel.

If that's just the way bulb mode works with multiple channels, would SMPTRIG work for me instead? SMPTRIG explicitly states that sampling starts on the rising edge and conversion triggers on the falling edge, so maybe I could use CCR registers in the timer unit to shape the waveform I would like and each timer period would do just one channel rather than racing through them all? Or will SMPTRIG also race through the remaining channels after the first one is triggered?

I can provide the full ADC register configuration if it would be helpful.




> I had thought that the ADC would sample the first channel on the first TIM6 trigger and then the second channel on the second trigger.

Timing of conversions purely from programmer's point of view should be unaffected, i.e. you should get a conversion result after trigger+SMPx+conversion_time, exactly the same as when BULB is not set.

Do you observe otherwise? How exactly do you observe that?

> I can provide the full ADC register configuration

Readout. Compare between timing-wise working case.


I'm not sure if I explained it properly. I have a sequence of two channels. The first edge should trigger a SMPx sampling time and conversion of the first channel in the sequence. What I would then want is it to go back in to bulb mode to start sampling the second channel and then the second edge would trigger an additional SMPx sampling time and conversion of the second channel in the sequence. It would then go back in to bulb mode and start the sequence all over again on the next trigger edge.

What I am observing is that the second channel goes in to SMPx immediately after the first channel and is then converted rather than waiting for an edge trigger - i.e. there is no bulb time between the two channels in a sequence.

There were two hints that this is happening: the first was that the TIM period to get the proper number of conversions was not what I was expecting it to be. The second, and most obvious, was that I configured the ADC to sample the same channel twice in the sequence instead of two separate channels. When I do this on a moving signal I expect the sampled voltages to be evenly distributed along the signal. Instead, I get pairs of voltages that are nearly identical to each other so they must have been sampled back-to-back.

I'll post the ADC registers when I get back to the office tomorrow.


As promised, here are the ADC1 and TIM6 registers, dumped at runtime:

ADC1 Registers
        ISR_1: 0000100B
        IER_1: 00000000
         CR_1: 10010005
      CFGR1_1: 000005A3
      CFGR2_1: 00002000
      SMPR1_1: 00000000
      SMPR2_1: 00010000
      PCSEL_1: 00008000
       SQR1_1: 0000F3C1
       SQR2_1: 00000000
       SQR3_1: 00000000
       SQR4_1: 00000000
         DR_1: FFFFF493
       JSQR_1: 00000000
       OFR1_1: 78002000
       OFR2_1: 00000000
       OFR3_1: 00000000
       OFR4_1: 00000000
      GCOMP_1: 00000000
       JDR1_1: 00000000
       JDR2_1: 00000000
       JDR3_1: 00000000
       JDR4_1: 00000000
     AWD2CR_1: 00000000
     AWD3CR_1: 00000000
       LTR1_1: 00000000
       HTR1_1: 01FFFFFF
       LTR2_1: 00000000
       HTR2_1: 01FFFFFF
       LTR3_1: 00000000
       HTR3_1: 01FFFFFF
     DIFSEL_1: 00000000
    CALFACT_1: 00010000
   CALFACT2_1: 03CA096A
          CCR: 00080000
TIM6 Registers
          CR1: 00000001
          CR2: 00000020
         DIER: 00000000
           SR: 00000001
          EGR: 00000000
          CNT: 00000423
          PSC: 00000000
          ARR: 000004FF

I've also included a screenshot of what I am seeing from my ADC samples. This is measuring a 1 kHz sine wave at 250 ksps, reading channel 15 twice in each sequence (as configured in the registers above), for a duration of 1 ms. So, there are 250 samples total, with 125 of them for the first channel in the sequence and the other 125 for the second channel in the sequence (again, both of which are channel 15).

In the graph, the X coordinates are increasing with sample number (sample 0 is the first conversion from sequence 0, sample 1 is the second conversion from sequence 0, sample 2 is the first conversion from sequence 1, etc...). My expectation was that all points would lie on the sine wave which would be the case if the second sample in the sequence was waiting for my TIM trigger. Instead, it is clear that the second sample is being taken very soon after the first sample in each sequence. Note that there is some noise in my hardware which is a Nucleo board and a bunch of jumpers that are not well shielded, but the samples from 150-250 are pretty clean here and show the problem clearly.


I am going to try using SMPTRIG to do this measurement instead of bulb mode and see if that helps.



I should add that I am using the offset register to subtract out 0x2000 and make the values signed; in my plotting tool I am adding the offset back in which is why all the ADC values are positive and not straddling the X-axis.

So, I tried with SMPTRIG mode instead of BULB mode and it does not seem to work at all if your sequence has more than one channel. I will open a tech support ticket to ask about that.

My conclusion is that it might not be possible to sample more than one channel on a regular tick that doesn't correspond to one of the ADC's built-in sample times, otherwise I could just use continuous mode.

I wrote too soon! Using discontinuous mode and bulb mode together seems to work, using DISCEN=1 and DISCNUM=0 (1 channel). Each trigger advances just to the next channel so the samples are all equidistant in time. Hopefully the bulb sampling is active between triggers.