cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F302: Unable to set Register CR: ADSTART

ebommer
Associate II
Posted on September 30, 2014 at 23:20

I am trying to get the ADC working on a STM32F302 processor and I am noticing while single stepping the code is when I call�? HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef* hadc)�? and exercise the code the “CR''Register never changes:

if (__HAL_ADC_NONMULTIMODE_OR_MULTIMODEMASTER(hadc) )
{
hadc->Instance->CR |= ADC_CR_ADSTART;
}

I have read the manual and it states if the ADEN = 1 and the ADDIS = 0 and there are no pending ADC disable the bit should set.

Currently ADEN = 1 and ADDIS = 0, but I don’t see the value updated.

#stm32-adc #stm32-adc
10 REPLIES 10
Posted on October 01, 2014 at 02:32

Well it's not a memory cell, is it possible that it auto-resets once the conversion completes, and that's a fraction of the time the debugger will take.

Also if you have the debugger peripheral view parked over the ADC, and it reads the data register, this will likely impact other registers/status
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
ebommer
Associate II
Posted on October 01, 2014 at 15:13

I don't think it Auto resetting because the ''ISR'' Register ''EOC'' is not being set.  I was hoping that once I solved the start bit issue the ''EOC'' will set.

frankmeyer9
Associate II
Posted on October 01, 2014 at 17:07

I have never seen any code relying on the state of ADSTART to detect if a sampling is finished, and neither is this recommended in the reference manual.

Albeit one could expect this flag to be set for the whole duration of a sample/conversion, the actual hardware might not live up to that expectation. It wouldn't be the first inaccuracy in the manual.

Better use the EOC flag instead.

ebommer
Associate II
Posted on October 01, 2014 at 17:27

Sorry for the confusion.

I am not using the ''ADSTART'' to determine if the sample is complete.

My comment was when I set ''ADSTART'' I am not seeing ''EOC set.

I am unable to read my ADC values so I am single stepping the code and noticed that when I write to the ''ADSTART'' its not being set, the question was raised that the ADC may be compete very fast and resetting the value.  I am assuming if that true I should see the ISR ''EOC'' then set, which its not.  Later in my code I read the ISR ''EOC'' to determine if the conversion is complete and the read times out since its not set.  I think the root of my problem is my lack of ability to set the CR ''ADSTART'' 

ADEN is set and ADDIS is

NOT

set

Posted on October 02, 2014 at 10:42

Hi ebommer,

Can you provide us the complete test case ?

I think you are seeing this bit set to 0 because the conversion is done quickly, this is already mentionned in the reference manual when no regular conversion is ongoing this bit is set to 0.

0690X00000602tDQAQ.jpg

In order to see this bit status try to slow down your system, and also the ADC by putting smallest sample time and try to poll on this pit.

Regards,

Heisenberg.

ebommer
Associate II
Posted on October 02, 2014 at 17:39

Hi

Heisenberg I was wrong. I wrote some test code and captured the ADSTART and EOC being set and cleared very quickly. So with that information I now am trying to understand the EOC. My code is based off an example from ''

STM32Cube_FW_F3_V1.0.0 -ADC_Sequencer''

From my understanding the software to trigger the ADC calls:

TestTemp1 = HAL_ADC_Start(&hadc1);
//* Wait for conversion completion before conditional check hereafter */
TestTemp2 = HAL_ADC_PollForConversion(&hadc1, 10);

The “HAL_ADC_Start(&hadc1)�? returns HAL_OK, but the “HAL_ADC_PollForConversion(&hadc1, 10)�? returns HAL_ERROR(HAL_ADC_STATE_TIMEOUT). The error is due to the checking of EOC and EOS flags, which by this time are cleared so I am timing out

Below is the code that is timing out code from the HAL ADC polling routine. I am assuming from the example code the EOC should still be set, but seems to be getting cleared by the DMA reading the DR register is my guess, so I am not sure what I should be doing.

tmp_Flag_EOC = (ADC_FLAG_EOC | ADC_FLAG_EOS);
/* Wait until End of Conversion flag is raised */
while(HAL_IS_BIT_CLR(hadc->Instance->ISR, tmp_Flag_EOC))
{
/* Check if timeout is disabled (set to infinite wait) */
if(Timeout != HAL_MAX_DELAY)
{
if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
{
/* Update ADC state machine to timeout */
hadc->State = HAL_ADC_STATE_TIMEOUT;
/* Process unlocked */
__HAL_UNLOCK(hadc);
return HAL_ERROR;
}

Posted on October 02, 2014 at 19:05

When you use the ADC + DMA, then you use the DMA HT/TC interrupts to indicate the End-Of-Conversion for the block of data read.

Yes the DMA reading ADC->DR will clear the EOC, as will sitting the debugger over the ADC peripheral presenting you the register content. The ADC's EOC triggers the DMA transfer, which is going to occur a lot quicker than you're ever going to be able to react to it. Figure an interrupt will eat about 12 processor cycles just preserving state before even entering the IRQHandler.
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
ebommer
Associate II
Posted on October 02, 2014 at 19:32

So I missing something in the example. It sets up the DMA, and calls the ADC start to start a conversion, then polls for results of the conversion. But the polling routine always returns an error because EOC in not longer active when it polls it and times out. Is it supposed to work that way?

Below is from the ST example main(), with the LED and DAC code removed. Am I missing something here about the proper operation of the example..

int main(void)
{
/*## Start ADC conversions #################################################*/
/* Start ADC conversion on regular group with transfer by DMA */
if (HAL_ADC_Start_DMA(&AdcHandle,(uint32_t *)aADCxConvertedValues,
ADCCONVERTEDVALUES_BUFFER_SIZE) != HAL_OK)
{ /* Start Error */
Error_Handler();
}
/* Infinite loop */
while (1)
{
/* Start ADC conversion */
/* Since sequencer is enabled in discontinuous mode, this will perform */
/* the conversion of the next rank in sequencer. */
/* Note: For this example, conversion is triggered by software start, */
/* therefore ''HAL_ADC_Start()'' must be called for each conversion. */
/* Since DMA transfer has been initiated previously by function */
/* ''HAL_ADC_Start_DMA()'', this function will keep DMA transfer */
/* active. */
HAL_ADC_Start(&AdcHandle);
/* Wait for conversion completion before conditional check hereafter */
HAL_ADC_PollForConversion(&AdcHandle, 1);
}
}

Posted on October 02, 2014 at 20:09

Yeah, I'm not going to touch HAL/CUBE examples with a barge pole, I've posted a lot of examples of how this can be done on assorted STM32 family parts, using the Standard Peripheral Library, hopefully with a lot more clarity.

Analyzing some of this stuff will undoubtedly give you headaches.
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..