cancel
Showing results for 
Search instead for 
Did you mean: 

I am trying to run my ADC according to RM0399. In the first steps when I enable the ADC voltage regulator (ADVREGEN in ADC_CR) and check its status through the LDORDY bit in ADC_ISR register the LDORDY bit is never set. Why is that? Did I miss a step?

HTess.1
Associate III

1 ACCEPTED SOLUTION

Accepted Solutions
Insert a wait between enabling clock and using the peripheral like HAL does. Verify clock is enabled in register settings.
If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

13 REPLIES 13
TDK
Guru

Show your code. Are you waiting the required time before checking? Are you clearing DEEPPWD? Is the ADC clock enabled?

If you feel a post has answered your question, please click "Accept as Solution".
Piranha
Chief II

Why you are not following the section 26.4.6 of the reference manual?

HTess.1
Associate III

I cleared DEEPPWD first line and I enabled all the clocks I could find (should the Domain register clock be enabled or enabling the clock assiociated to a peripheral enough). As for the waiting time the datasheet says to wait around 5µs I tried 10µs but shouldn't the LDORDY bit act as the delay check?

HTess.1
Associate III
void ADC_Init(void) {
  /***************REGISTER SHORTCUT*********************/
  uint32_t ISR = *ADC_ISR;
  uint32_t IER = *ADC_IER;
  uint32_t CR = *ADC_CR;
  uint32_t CFGR = *ADC_CFGR;
  uint32_t CFGR2 = *ADC_CFGR2;
  uint32_t SMPR1 = *ADC_SMPR1;
  uint32_t PCSEL = *ADC_PCSEL;
  uint32_t DR = *ADC_DR;
  uint32_t DIFSEL = *ADC_DIFSEL;
  uint32_t SQR1 = *ADC_SQR1;
  uint32_t SQR2 = *ADC_SQR2;
  uint32_t SQR3 = *ADC_SQR3;
  uint32_t SQR4 = *ADC_SQR4;
  uint32_t CSR = *ADC1_CSR;
  uint32_t CCR = *ADC1_CCR;
  
  /***************CLOCK and PIN config******************/
  
  *RCC_APB4ENR|=(1 << SYSCFGEN);// Enable SYSCFG Peripheral Clock
  *RCC_AHB4ENR |= (1 << GPIOAEN); //Enable clock GPIO port A
  *GPIOA_MODER |= (3 << MODER0); //Analog mode port 0
  *SYSCFG_PMCR|=(1 << PA0SO); //Connect the PA0 to PA0_C
  *RCC_AHB1ENR |= (1 << ADC1EN); //ADC peripheral clock enable
 
 
  /***************ADC not Enabled yet********************/
  //ADC VOLTAGE REGULATOR-----------------------------
  CR = 0x00000000; //End deep power down
  *ADC_CR = CR;
  CR = (1<<ADVREGEN); //ADC voltage regulator Enabled
  *ADC_CR = CR;
  while ((*ADC_ISR & (1 << LDORDY)) == 0) {
      dataFromRegister=*ADC_ISR;
      Serial.println(dataFromRegister,BIN);
  }
  //delayMicroseconds(10);//wait for voltage regulator to be enabled (datasheets quote 5µs delay)
  //ADC CALIBRATION-----------------------------------
  CR &= ~(1 << ADCALDIF);
  *ADC_CR = CR;//ADCALDIF single ended inputs mode
  CR = (1 << ADCALLIN); //ADCALLIN calibration linéaire ET offset
  *ADC_CR = CR;
  *ADC_CR |= (1 << ADCAL); //calibration ADCAL=1
  while(*ADC_CR & (1 << ADCAL) != 0){}  
  //ADC prescaler selection clock and sample time delay
  CCR |= (3<<CKMODE);
  CCR |= (3<<PRESC);
  CCR |= (8<<DELAY);
  *ADC1_CCR = CCR;//
  //Set input mode------------------------------------
  DIFSEL &= ~(1 << DIFSEL1); //DIFSEL[19:0]: single ended mode for channel 1
  *ADC_DIFSEL = DIFSEL;
 
  /*******************ADC Enable**********************/
  *ADC_ISR |= (1 << ADRDY); // Reset ADC ready flag
  *ADC_CR |= (1 << ADEN); //Enable ADC
  while (!(*ADC_ISR & (1 << ADRDY))); //Wait for ready flag
  *ADC_ISR |= (1 << ADRDY);
 
  /********************ADC Enabled********************/
  //ADC CFGR------------------------------------------
  CFGR |= (1 << OVRMOD); //OVRMOD = 1 DR overwritten if overrun
  CFGR |= (6 << RES); //RES[2:0]: Data resolution 110=12bits
  CFGR &= ~(3 << DMNGT); //DMNGT[1:0]: Data Management configuration 00 data stored in DR only
  CFGR |= (1 << CONT); //CONT: Single / continuous conversion mode for regular conversions
  CFGR &= ~(3 << EXTEN);//Hardware trigger detec disabled
  *ADC_CFGR = CFGR;
  //*ADC_CFGR2 |= (1 << 5);//right shift for oversampling
  //ADC SQR1------------------------------------------
  SQR1 |= (1 << SQ1); //1st conv chan 1 (00001) and one conv by sequence (0000)
  *ADC_SQR1 = SQR1;
  //ADC SMPR1-----------------------------------------
  SMPR1 |= (3 << SMP1); //SMP0[2:0]: Channel 1 sampling time selection 011: 16.5 ADC clock cycles
  *ADC_SMPR1 = SMPR1;
  // ADC PCSEL----------------------------------------
  PCSEL |= (1 << PCSEL1); //PCSEL[19:0] :Channel 1 (VINP[i]) pre selection
  *ADC_PCSEL = PCSEL;
}

But I am, I have read it through and through looking for a missing step ...

TDK
Guru

Where is your definition of ADC_ISR? Is it volatile?

Using standard CMSIS headers would make things a lot easier for others to read.

When you debug the code, do you see the expected value within ADC_CR while waiting for LDORDY?

If you feel a post has answered your question, please click "Accept as Solution".
HTess.1
Associate III

I define all of my registers this way :

volatile uint32_t* const REG = (uint32_t*) ADDRESS_HEXA;

As for the second question weirdly enough I get a 100000000000000000000000000000 meaning DEEPPWD is still enabled (I must have made a dumb mistake somewhere)

Insert a wait between enabling clock and using the peripheral like HAL does. Verify clock is enabled in register settings.
If you feel a post has answered your question, please click "Accept as Solution".

It works thanks a lot!