2020-12-21 12:26 PM
Chip: STM32L030
Trying to calibrate the ADC at startup with the following code into the initialization procedure:
ADC1->CR |= 0X80000000; // calibration started
while (!(ADC1->ISR & 0X800)); // waiting for the calibration to finish
When compiled with Atollic, version 9.2.0, this code works perfectly. But when compiled with Stm32CubeIde, it gets trapped into the calibration command which never finish!
2020-12-22 06:23 AM
EOCAL is set at the end of the calibration. You're waiting until it's set. This is a race condition. So either the loop will immediately pass (if calibration isn't done yet), or it will never exit.
This is a software bug, not a CubeIDE issue.
2020-12-22 11:44 AM
This is exactly what my code does! If it is not a CubeIDE issue, how do you explain that Atollic 9.2.0 compiles successfully?
2020-12-22 12:33 PM
2020-12-23 04:24 AM
At your request, here is my complete initialization code. I don't think it is very enlighting.
int adsetup() {
int n = 10000; // timeout
RCC->IOPENR |= 1; // port A enabled
GPIOA->MODER &= 0XFFFFFFFC; // Analog input at PA0
GPIOA->PUPDR &= 0XFFFFFFFC; // No pull-up at PA0
RCC->APB2ENR |= 0X200; // ADC clock started
if (ADC1->CR & 1) ADC1->CR |= 2; // ADC setup
ADC1->CR |= 0X80000000; // ADC calibration started
while (!(ADC1->ISR & 0X800)) { // waiting for the calibration to finish
watchdog(); // macro to refresh the watchdog
if (!--n) return FALSE; // failure exit
}
ADC1->ISR |= 0X800; // clearing EOCAL
ADC1->CHSELR = 1; // Channel 0 selected
ADC1->SMPR |= 7; // 160 ADC cycles sampling time (320usec)
ADC1->CFGR1 = 0XC0A000; // continuous conversion, analog watchdog enabled
ADC1->IER = 0X80; // analog watchdog interrupt enabled
ADC1->TR = 0XA000600; // analog watchdog window setup
ADC1->CFGR2 |= 0X8000009D; // ADC clock setup, over-sample = 16, shift = 4
ADC1->CR |= 5; // ADC started
return TRUE; // successfull initialization
}
2020-12-24 07:09 AM
> Chip: STM32L030
There is no such chip...
Use code tags when posting code. And use the readable CMSIS defined bit field names.
if (ADC1->CR & 1) ADC1->CR |= 2; // ADC setup
ADC1->CR |= 0X80000000; // ADC calibration started
while (!(ADC1->ISR & 0X800)) { // waiting for the calibration to finish
watchdog(); // macro to refresh the watchdog
if (!--n) return FALSE; // failure exit
}
ADC1->ISR |= 0X800; // clearing EOCAL
Do not use read-modify-write on ISR register and be careful with CR as it also has "rs" bits like ISR. Probably the most important - you are not waiting for ADDIS command to complete. And ultimately I would want the watchdog to act if the code gets stuck in that loop...
2020-12-24 08:17 AM
Thanks Piranha for your attention, but it doesn't help:
1 - STM32L030F4P6 chip on my desk, and on my board!
2 - Read-modify-write instructions? there is no such a warning in the datasheet. I also have separated them in 2 parts with no avail.
3 - ADDIS: I added a waiting loop with no result
4 - You ignore the fact that Atollic 9.2.0 compiles successfully!
5 - The watchdog works and the loop exits FALSE.
Hard to admit that you have a problem? I don't, I completed my project without ADC calibration.
My question is definitely not answered.
2020-12-24 09:07 AM
> 1 - STM32L030F4P6 chip on my desk, and on my board!
Can you link the product page to prove that it does exist? Google shows no hits. Maybe you have a counterfeit part. Hard to prove a negative.
> 2 - Read-modify-write instructions? there is no such a warning in the datasheet. I also have separated them in 2 parts with no avail.
> ADC1->ISR |= 0X800; // clearing EOCAL
This clears ALL flags, not just EOCAL. This is covered in the reference manual (for STM32L0X0). To clear only EOCAL:
ADC1->ISR = ADC_ISR_EOCAL;
There are other requirements for starting calibration and you're not checking for them all. From the reference manual (for STM32L0X0):
The software is allowed to set ADCAL only when the ADC is disabled (ADCAL=0, ADSTART=0, ADSTP=0, ADDIS=0 and ADEN=0).
2020-12-25 02:33 AM
> 1 - Sorry, my mistake, the chip is STM32L010F4P6
> 2 - Clearing all flags? good, this is what I want
> 3 - ADCAL=0, ADSTART=0, ADSTP=0, ADDIS=0 and ADEN=0.: this is the RESET state
> 4 - Please stop seeking what is wrong in the code: it works fine with ATOLLIC. STM32CUBE has a problem!
> 5 - In the past, you gave me an excellent advice: to look at the generated assembler code. I would like to do that. I cannot find any assembler window.
2020-12-25 07:54 AM
> 4 - Please stop seeking what is wrong in the code: it works fine with ATOLLIC. STM32CUBE has a problem!
Okay, must be an STM32CubeIDE issue then if you say the code is right. Use ATOLLIC instead.
Good luck.