cancel
Showing results for 
Search instead for 
Did you mean: 

Bare Metal ADC on NUCLEO-H745ZI-Q

zirogravity
Associate II

Hello,

I am troubleshooting a similar problem as described in this post TM32H7 ADC Baremetal - Cannot get ADC module ready

I am using PF10 on ADC3 as it is already routed to the CN10 header. Intentionally ignoring CMSIS header/defines in the spirit of learning. Using the default RCC /64MHz HSI / clock and have basic uart functionality on usart3. Using CM4 and ignoring CM7.

Initializing as follows:

//Enable clock access to GPIOF
RCC->AHB4ENR |=GPIOFEN;

//Set PF10 mode to analog
//The reset state for the pins is analog mode
//GPIOF->MODER |=(1U<<20);
//GPIOF->MODER |=(1U<<21);

//Enable clock access to ADC
RCC->AHB4ENR |=ADC3EN;

//Set ADC Kernel Clock Source to Peripheral Clock
RCC->D3CCIPR &=~(1U<<16);
RCC->D3CCIPR |= (1U<<17);

//Reset the ADC peripheral
RCC->AHB4RSTR |= (1U<<24);
RCC->AHB4RSTR &=~(1U<<24);

//DISABLE THE ADC BEFORE CONFIGURATION
ADC3->CR &=~ADEN;
while(ADC3->CR & ADEN){};

//ADC channel pre-selection register
ADC3->PCSEL  |=(1U<<6);

//Set ADC Continous Conversion Mode
ADC3->CFGR |=(1U<<13);

//ADC Channel Sequence
//Channel 6 of ADC3 so we need ADC_SQR1: SQ[4:0]=6 =0b110
//Only one channel ADC_SQR1:  L[3:0]=0 (length 1)
ADC3->SQR1 &= ~(1U<<0);
ADC3->SQR1 |=  (1U<<7);
ADC3->SQR1 |=  (1U<<8);

//Set ADC Clock Mode
//00: CK_ADCx (x=1 to 23) (Asynchronous clock mode), generated at product level (refer to
//Section Reset and Clock Control (RCC))
//01: adc_sclk/1 (Synchronous clock mode).
//10: adc_sclk/2 (Synchronous clock mode)
//11: adc_sclk/4 (Synchronous clock mode)
ADC3_COMMON->CCR |=((1U<<16)|(1U<<17));

//Clear the Deep Power Down Bit
ADC3->CR &=~DEEPPWD;

//Enable the ADC VREG
ADC3->CR |= ADVREGEN;

//Wait for ADC LDO Ready Flag
while(!(ADC3->ISR & LDORDY));

//1. Clear the ADRDY bit in the ADC_ISR register by writing ‘1’
ADC3->ISR |=ISR_ADRDY;

//2. Set ADEN=1.
ADC3->CR |= ADEN;

//3. Wait until ADRDY=1 (ADRDY is set after the ADC startup time). 
while(!(ADC3->ISR & ISR_ADRDY)){};

//4. Clear the ADRDY bit in the ADC_ISR register by writing ‘1’ (optional).
//ADC3->ISR |=ISR_ADRDY;

 It appears that I get a single ADC reading on "reset" but nothing after that. I can GND or apply 3.3V on PF10 and report an ADC count value via uart.

Screenshot from 2024-11-26 18-02-05.png

My adc read function and from what I can tell EOC never gets set/reset after each read.

uint32_t adc_read(void){

	//RM0399 Rev 4 page 1034
	//Wait for conversion completion
	 while(!(ADC3->ISR & ISR_EOC)){};

	 //Wait for sequence completion
	 //while(!(ADC3->ISR & ISR_EOS));

	//Read converted results
	return (ADC3->DR);
}

I have tried various insertions of delays in the form of:

for(int i=0; i<10000;i++);

 in various section of the code per the RM but that does not seem to be it. My overall main() is:

uint32_t adc3_ch6_count;

int main(void){

	usart3_tx_init();

	pf10_adc_init();

	start_conversion(); //Start ADC Conversion ADC3->CR |=  ADSTART;
}

	while(1){

		//for (int i=0;i<10000;i++);
		adc3_ch6_count =adc_read();
		printf("\nADC3_CH6 Count: %lu\r", adc3_ch6_count);
		for(int i=0; i<10000;i++);

	}
}

 

0 REPLIES 0