I am trying to bring up one of the ADC's on the STM32L476 Nucleo board. I think i have things configured ok, but i must be missing a step. I know this can be done use the HAL API and CubeMX, but i prefer register level access when bringing up a new board. Here is my code - i think it's commented to enough so it can be understood. I stripped out the rest of the code to keep it simple.
The problem i don't understand is that when the code starts the while loop - the ADC is not ready - that is the ADC1->ISR[0] is not set - and does not get set. I have confirmed the bits are set where i think they should be using keil.
Can anyone spot what is missing?
#include <stm32l4xx.h>
#include <stdio.h>
#ifdef __cplusplus
extern "C"
#endif
int main(void)
{
uint32_t adcResult = 0;
/* Configure the clocks - using MSI as SYSCLK @16MHz */
RCC->CR &= 0xFFFFFF07; //Clear ~MSIRANGE bits and MSIRGSEL bit
RCC->CR |= 0x00000089; //Set MSI to 16MHz and MSIRGSEL bit
char *dataPtr = NULL;
//init ADC1
ADC1->CR &= 0xDFFFFFFF; //Take ADC out of deep power down - i break at this point to allow enough time - doesn't help
ADC1->CR |= 0x10000000; //Enable ADC1 votage regulator
RCC->AHB2ENR |= 0x00002001; //Enable the ADC clock, and GPIOA clk
GPIOA->ASCR |= 0x00000001; //Connect analog switch to GPIOA[0]
GPIOA->MODER |= 0x00000003; //Set A0 for analog input mode
ADC1->ISR |= 0x00000001; //Clear the ADRDY bit in the ADCx_ISR register by writing ‘1’.
ADC1->SQR1 |= 0x00000040; //Set for a sequence of 1 conversion on CH0
while (1)
{
ADC1->CR |= 0x00000004; //Convst
while(!(ADC1->ISR & 0x4));
adcResult = ADC1->DR;
sprintf(dataPtr, "%d", adcResult);
}
}
I solved this - finally. If anyone gets into the same place. I had set the SYSCLK as the ADC clock source, but this needs to be setup in RCC->CCIPR[29:28].
It's the little things...
User contributions licensed under CC BY-SA 3.0