STM32F303 ADC1 calibration stuck
Hi
I'm porting my STM32F103 code to the STM32F303, and noticed the significant difference in the ref manual regarding the ADC module. Being a beginner in STM32 MCUs, I'm struggling to get my calibration run correctly.
I feel like I am doing as I'm supposed to, but my calibration gets stuck in line 38. Debugging the register bits, ADCAL remains 1, even though it should be cleared by hardware once calibration is over.
Can anyone see what I'm doing wrong?
PS: If I don't run the calibration, my ADC works, but gives the wrong values, which is why I would like to run my calibration
Thank you.
/**
* STM32F303CC ADC
* Uses ADC1
* Reads the temperature from the internal temp sensor.
* Also, SWV is implemented. PB3 on MCU is used for TRACESWO
* NOT DONE YET
*/
#include <stdint.h>
#include <stdio.h>
#include "stm32f3xx.h"
#define AVG_SLOPE 4.3 // mV per C
#define V25 1.43 // V
volatile uint32_t msTicks = 0;
int main(void)
{
__NVIC_EnableIRQ(ADC1_2_IRQn);
SystemCoreClockUpdate();
SysTick_Config(SystemCoreClock / 1000); // 1ms interrupt
// Setup of ADC1
uint16_t i = 0;
RCC->AHBENR |= RCC_AHBENR_ADC12EN;
for(;i<255;i++);
i=0;
ADC1->IER |= ADC_IER_EOCIE;
ADC1->CR &= ~ADC_CR_ADVREGEN;
ADC1->CR |= ADC_CR_ADVREGEN_0;
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; // Enables SysTick
while(msTicks<1);
msTicks = 0;
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; // Disables SysTick until next delay call
ADC1->CR |= ADC_CR_ADCAL; //ADCALDIF = 0
while(ADC1->CR && ADC_CR_ADCAL); // Wait for calibration to be over
ADC1->CFGR |= ADC_CFGR_EXTEN_0 | ADC_CFGR_EXTSEL_0 | ADC_CFGR_EXTSEL_1;
ADC1->SMPR1 |= ADC_SMPR1_SMP1_2;
ADC12_COMMON->CCR |= ADC12_CCR_TSEN | ADC12_CCR_CKMODE_0;
ADC1->SQR1 |= (16<<ADC_SQR1_SQ1_Pos); // ADC channel 16 for Temp sensor
ADC1->CR |= ADC_CR_ADEN;
while(!(ADC1->ISR && ADC_ISR_ADRDY));
ADC1->CR |= ADC_CR_ADSTART;
// Enables Port A on APB2 bus to set PA1 to AF
RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
for(;i<255;i++);
i=0;
GPIOA->MODER |= GPIO_MODER_MODER1_1;
GPIOA->AFR[0] |= (1<<GPIO_AFRL_AFRL1_Pos);
// Enables TIM2 bus
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
for(;i<255;i++);
i=0;
TIM2->DIER |= TIM_DIER_UIE;
TIM2->PSC = 7999;
TIM2->ARR = 1000;
TIM2->CCR2 = 500;
TIM2->EGR |= TIM_EGR_CC2G;
TIM2->CCER |= TIM_CCER_CC2E;
TIM2->CCMR1 |= TIM_CCMR1_OC2PE | TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2;
TIM2->CR1 |= TIM_CR1_ARPE | TIM_CR1_URS | TIM_CR1_CEN;
/* Loop forever */
for(;;);
}
void ADC1_2_IRQHandler(void)
{
// Handles the IRQ of ADC1. EOC flag is cleared by reading data register
static uint32_t temp = 0;
static uint32_t temp_sensor = 0;
temp = ADC1->DR;
temp_sensor = (V25-temp*3.3/4095)/(AVG_SLOPE)*1000+25;
printf("Temperature is: %lu\n", temp_sensor);
}
void SysTick_Handler(void)
{
msTicks++;
}