cancel
Showing results for 
Search instead for 
Did you mean: 

stm32h743 adc1 eos flag will not be set until I read the DR

Whono.1
Associate II

Hi all,

recently I am trying to use ADC to sample 4 channel current signals. Since there is no critical time requirement, I plan to use scan mode. In my opinion, the ADC will automatically complete four channel signal conversion stuff, then set the EOS flag, which can lead to an interrupt. afterwards, I can read all four channel conversion result in the interrupt service routine.

but when I have finish the design, and then try to debug, I found that, the EOS interrupt will never be enterred. Then I try a lot of methods, and finally found that, if I read the DR some time after I start the ADC conversion, then the interrupt can be enterred ! Besides, I found that, I can not even get the EOS flag, if I just poll for it forever!

I suspect that, this could be a STM32H743 chip logic issue, because, I have use the similar method for ADC sampling with STM32F4 series.

Can anyone give me some hints? thanks a lot!

1 ACCEPTED SOLUTION

Accepted Solutions

Hi, I guess I have found the root cause.

uhADCxConvertedValue[0] = HAL_ADC_GetValue(&hadc1);

uhADCxConvertedValue[1] = HAL_ADC_GetValue(&hadc1);

 uhADCxConvertedValue[2] = HAL_ADC_GetValue(&hadc1);

 while(0 == __HAL_ADC_GET_FLAG(&hadc1, ADC_FLAG_EOS));

uhADCxConvertedValue[3] = HAL_ADC_GetValue(&hadc1);

code like upside can work fine. Notice that, I try to poll for the EOS flag after I have read the ADC_DR three times. if I put the polling statement earlier, then a dead loop will happen.

And the test code seems to support my assumption: EOS has deep correlation with the edge of EOC. In fact I have also try to clear EOC flag three times, afterwards, I can also get the EOS flag, but in this situation, the data in FIFO seems also be cleared, thought I have not read the ADC_DR.

View solution in original post

7 REPLIES 7
Nikita91
Lead II

If you use EOS then you use regular channels.

EOS is end of sequence: The ADC sets the EOS flag as soon as the LAST data of the regular conversion sequence is available in the ADC_DR register.

Without DMA and regular channels you must read each channel data after each conversion, so use EOC.

To read 4 channels at the end of the sequence use injected channels.

thanks for your suggestion.

however, I want to dig more.​

As for the EOC solution​, sure it works. but it violates my initial intention. and for the inject channel solution, I will spend some time on investigation.

I think that, I have always been using ​regular channels, and you say that, EOS would be set at the end of the final conversion in the sequence, which is exactly the thought also in my brain. but this is the key issue which is confusing me. without reading ADC_DR, the EOS bit can not be set! so could you kindly give me more hints on this situation, or can you provide some docs or links?

Nikita91
Lead II

The ADC has only one data register to read the converted regular channels values.

If you wait for the last channel conversion to read the datas, the ADCx->DR register will be overwritten, and you will read only the last channel value.

So you must read the DR register after every conversion, in the EOC interrupt routine: you must read the value before the end of the next conversion

Read the stm32h743  reference manual.

​but in the official manual, it says that ADC has eight stage FIFO. if this is true, I think, basically my scheme can work. and even it is not true, at least I should get the EOS flag set, no matter the data is overwritten or not.

I suddenly has an idea, maybe the EOS can only be set after 4 rising edge​ of EOC has been generated, and in my case, I do not read DR or clear EOC manually, which will keep EOC always set, and so the EOS can never be set.

I will verify it later. ​

Hi, I guess I have found the root cause.

uhADCxConvertedValue[0] = HAL_ADC_GetValue(&hadc1);

uhADCxConvertedValue[1] = HAL_ADC_GetValue(&hadc1);

 uhADCxConvertedValue[2] = HAL_ADC_GetValue(&hadc1);

 while(0 == __HAL_ADC_GET_FLAG(&hadc1, ADC_FLAG_EOS));

uhADCxConvertedValue[3] = HAL_ADC_GetValue(&hadc1);

code like upside can work fine. Notice that, I try to poll for the EOS flag after I have read the ADC_DR three times. if I put the polling statement earlier, then a dead loop will happen.

And the test code seems to support my assumption: EOS has deep correlation with the edge of EOC. In fact I have also try to clear EOC flag three times, afterwards, I can also get the EOS flag, but in this situation, the data in FIFO seems also be cleared, thought I have not read the ADC_DR.

You are right, I forgot that there is a FIFO on the STM32H7...

ABasa.5
Associate

Hi,

Recently, while implementing an application on STM32H743 MCU, I stumbled upon a similar problem.

In my application, I would like to read three channels one after another in polling mode. I was under the assumption that polling for EOS flag is sufficient. This type of wait did not work (same issue has been observed and reported at the beginning of this thread). I did single stepping and came to a conclusion somewhat similar to the solution indicated in the previous message from @Whono.1​ but with a slight deviation. According to my observation, EOS flag will be set only after we have reset the first EOC flag. (No matter how many channels need to be converted). This solution is clumsy but works.

There is another elegant solution present. Set the AUTODLY bit in CFGR register. Then wait for EOC flag before reading the DR register. This solution works as expected. No need to wait for EOS flag. Just wait for EOC flag and read DR register for every channel. The drawback??? It might be bit slow but I have nothing substantial to prove that here.