cancel
Showing results for 
Search instead for 
Did you mean: 

ADC DMA with TIM21 TRGO conversion source on STM32L010

DWann
Associate III

I've got an application where I'm performing an ADC DMA transfer where the ADC conversions are triggered by the TIM2 TRGO. Everything was running smoothly until a PCB respin forced me to switch over to TIM21 to trigger the conversion. I didn't see a problem with that but now my DMA transfer doesn't work (nothing making it to the buffer).

From the documentation, I see that TIM2 supports DMA request generation while TIM21 does not. Could this be the issue? I wouldn't have thought so - the ADC should be the one requesting the DMA, not the timer. All the timer should be doing is firing the TRGO.

Any thoughts?

12 REPLIES 12
TDK
Guru

> I see that TIM2 supports DMA request generation while TIM21 does not. Could this be the issue?

No, the DMA request is made by the ADC.

The timer can trigger the ADC on CH2 and (possibly) TRGO. Probably just a bug in your code somewhere. Or maybe your device is category 1, which doesn't have the TRGO option.

0693W000003QZojQAG.png

If you feel a post has answered your question, please click "Accept as Solution".
DWann
Associate III

That's what I was hoping for. Thanks for the feedback. This is a category 2 device, so I guess I'm bug hunting.

And does the TIM21 fire the ADC? Without DMA, you should see some activity on the ADC status bits.

Alternatively, regardless of "class", you should still be able to use the TRG1.

JW

DWann
Associate III

I've taken a step back and created a very simple application with just ADC, TIM2, and TIM21. The timers are configured identically, and both are started prior to calling HAL_ADC_Start_DMA(). If I specify the ADC conversion trigger as ADC_EXTERNALTRIGCONV_T2_TRGO, it works. But If I specify the conversion trigger as ADC_EXTERNALTRIGCONV_T21_TRGO, it does not work.

If just step over the HAL_ADC_Start_DMA() function, I can see that immediately after being called, the ADRDY bit is set if the trigger source is T2_TRGO. ADRDY is not set if the trigger source is T21_TRGO. Both timers are incrementing. I'm puzzled.

UPDATE:

When TIM2 is initialized, the DMAR register is set to 1. If I clear that register before starting the ADC, the ADRDY bit is never set. So while I agree that that the documentation indicates otherwise, it sure seems like the timer needs DMA generation capability to be used as a trigger for an ADC DMA transfer.

Clicking in CubeMX won't get you too far from the few usual and tested cases.

TIMx_DMAR is not a real register, rather, it's a window through which you see other TIM registered, by default TIMx_CR1. The value of 1 there is TIMx_CR1.CEN=1. Read the TIM chapter in RM.

ADRDY indicates if ADC is enabled at all, do either there's an interrupt which clears it, or ADC was never enabled for whatever reason. Cube is open source, read the ADC chapter and proceed accordingly.

JW

DWann
Associate III

Correction to the prior post - it wasn't the ADRDY bit getting set, it was the EOS and EOSMP bits.  Regardless, it works with TIM2 TRGO and not with TIM21 TRGO.

I found a post about a similar problem with the STM32F74xxx. But in that case, it was documented in the errata sheet. There is no such mention in the errata sheet for the STM32L010.

https://community.st.com/s/question/0D50X0000BAFE9HSQX/adc-trigger-with-timer-not-working

I finally resorted to using TRG1 and just using output compare on TIM21 chan 2. That did the trick. (Should have done that a much earlier)

In conclusion, I can work around the issue, but I suspect there some undocumented errata regarding TIM21 TRGO triggereing of the ADC on the STM32L010C6.

What's the device ID (DBG_IDCODE)?

JW

You can also try to use TIM22_TRGO with EXTSEL = 100

0693W000003QqUgQAK.png

Yes, it appears to be a bunch of bugs and errors in the documentation.

JW

ID code is 0x20186425, so definitely category 2 device.