STM32G4 Voltage reference problem - Page 1
Forum section: electronics / general

author: syntax333
author_rank: Regular Contributor
timestamp: March 30, 2020, 09:22:45 am
content: Hi I am currently working on a project where I need to use internal Voltage reference as reference for ADCs inside STM32G4 Nucleo board (STM32G431KB). I can write to bits of VREFBUF registes (Confirmed by Debug Session). After enabling the VREF I wait for VRR bit of CSR register to set. However, it never does thus my code stucks in while loop.You can see the code below.Code:#include "main.h"#include "SysClock_Config.h"void DummyDelay(int x){int temp = x;while(temp){temp--;}}void Initialization(void){RCC->AHB2ENR |= RCC_AHB2ENR_GPIOAEN | RCC_AHB2ENR_ADC12EN; //Enable GPIOA and ADC ClockGPIOA->MODER |= GPIO_MODER_MODER0; //Set PA0 as AnalogVREFBUF->CSR |= (0b01<<VREFBUF_CSR_VRS_Pos); //Set Internal Reference as 2.5VVREFBUF->CSR &= ~(VREFBUF_CSR_HIZ); //Disable High-ImpedanceVREFBUF->CSR |= VREFBUF_CSR_ENVR; //Enable Voltage referencewhile(!(VREFBUF->CSR & VREFBUF_CSR_VRR)); //Wait until Reference Voltage Level is reached.ADC1->CR &= ~(ADC_CR_ADEN); //Disable ADCADC12_COMMON->CCR |= (0b00<<ADC_CCR_CKMODE_Pos); //Select ADC clock Source in PeripheralADC1->CR &= ~(ADC_CR_DEEPPWD); //Disable ADC Deep-Power-Down modeADC1->CR |= ADC_CR_ADVREGEN; //Enable ADC Voltage RegulatorDummyDelay(10000);ADC1->CFGR |= ADC_CFGR_CONT; //ADC continuous modeADC1->CFGR &= ~(ADC_CFGR_RES); //12-bit ADCADC1->SQR1 |= (0b0000 << ADC_SQR1_L_Pos) | (1 << ADC_SQR1_SQ1_Pos); // Only 1 conversion for ADC channel 1ADC1->DIFSEL &= ~(ADC_DIFSEL_DIFSEL_0); //Single Ended InputADC1->CFGR |= ADC_CFGR_OVRMOD; //Enable Overrun mode *MIGHT NOT BE NECESSARY*ADC1->CR &= ~(ADC_CR_ADCALDIF); //Single Ended Mode CalibrationADC1->CR |= ADC_CR_ADCAL; //Start Calibrationwhile(ADC1->CR & ADC_CR_ADCAL); //Wait Until Calibration CompleteADC1->ISR |= ADC_ISR_ADRDY; //Clear ADRDY FlagADC1->CR |= ADC_CR_ADEN; //Enable ADCwhile(!(ADC1->ISR & ADC_ISR_ADRDY)); //Wait Until ADC Enables}int main(void){uint16_t ADC_Value;HAL_Init();SystemClock_Config();Initialization();ADC1->CR |= ADC_CR_ADSTART; //Start ADC Sampling/Conversion Sequencewhile (1){while(!(ADC1->ISR & ADC_ISR_EOC)); //Wait for End of ConversionADC_Value = ADC1->DR; //Save data to variable}}void Error_Handler(void){}void SystemClock_Config(void){RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};/** Configure the main internal regulator output voltage*/HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);/** Initializes the CPU, AHB and APB busses clocks*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV4;RCC_OscInitStruct.PLL.PLLN = 50;RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV5;RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB busses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7) != HAL_OK){Error_Handler();}/** Initializes the peripherals clocks*/PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC12;PeriphClkInit.Adc12ClockSelection = RCC_ADC12CLKSOURCE_PLL;if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK){Error_Handler();}SysTick->CTRL &= ~(SysTick_CTRL_ENABLE_Msk);}Do anyone knows the reason for this? I checked clocks and Voltage levels of VDD and AVDD pins, everything seems fine...

author: AlexD
author_rank: Newbie
timestamp: April 02, 2020, 03:50:38 pm
content: Hi,I believe this is, because the VREFBUF cannot be used on that specific chip. The Datasheet (not the Reference manual) says: "The VREF+pin is double-bonded with VDDAon some packages. In these packages theinternal voltage reference buffer is not available.". That would mean, there is no analog switch for the reference voltage that selects between the VREFBUF and an VDDAas the reference.I'm not 100% sure about that, because the peripheral table in the Datasheet says the K devices (32pin LQFP packages) do have a voltage reference buffer. But since that chip has no VREF+Pin, it has to be bonded to VDDAinternally.