Skip to main content
Associate II
March 27, 2024
Solved

Unable to configure Clock using baremetal PLL in stm32 G071RB

  • March 27, 2024
  • 4 replies
  • 2142 views

i tried to configure clock by writing code in its appropriate registers...
following is the clock configuration function

 

void SystemClockConfig(void){
    #define PLLN  16
 
//using external clock source
RCC->CR |= RCC_CR_HSEON;
while(!(RCC->CR & RCC_CR_HSERDY));
//enabling power interface
RCC->APBENR1 |= RCC_APBENR1_PWREN;
//configuring voltage regulator to default 01
PWR->CR1 |= (0x1UL << PWR_CR1_VOS_Pos);
PWR->CR1 &= ~(0x2UL << PWR_CR1_VOS_Pos);//                  
//configure flash prefetch and latency
FLASH->ACR |= (FLASH_ACR_ICEN | FLASH_ACR_PRFTEN | FLASH_ACR_LATENCY_1);
//configuring prescalers for main clock and peripheral clocks
RCC->CFGR |= (RCC_CFGR_HPRE_0 | RCC_CFGR_PPRE_0);
//configure main PLL; PLLM, PLLN, PLLR
RCC->PLLCFGR |= ((PLLN<<8) | (RCC_PLLCFGR_PLLSRC));//      
RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLM;
RCC->PLLCFGR |= RCC_PLLCFGR_PLLREN;
RCC->PLLCFGR |= RCC_PLLCFGR_PLLR_0;
//enable PLL
RCC->CR |= RCC_CR_PLLON;
while(!(RCC->CR & RCC_CR_PLLRDY));
//set the clock source
RCC->CFGR |= RCC_CFGR_SW_1;
// while(!(RCC->CFGR & RCC_CFGR_SWS_1));
    while(((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_1));
 
}

furthermore,

when the Xtal frequency is greyed out as <undefined> in the dialog Options for target - Target tab. so I am unable to set the clock frequency to 64mhz

 

in the main.c code when I try to include this clock configuration, it fails to make any changes to the code and the simple led blink program fails to execute after flashing

 

following is my main.c file

 

#include "stm32g071xx.h"
 
 
#include "RCC_CLock_Config.h"
 
 
void Timer6Config(void){
//enable Timer 6
RCC->APBENR1 |= (1<<4);
//setting prescaler
//64Mhz/64= 1Mhz -> 1us
TIM6->PSC |= 64-1;//The counter clock frequency CK_CNT is equal to fCK_PSC / (PSC[15:0] + 1).
TIM6->ARR |= 0xffff;
//enabling timer and waiting for flag to set
TIM6->CR1 |= (1<<0);//enable the counter
while(!(TIM6->SR& (1<<0)));
}
 
void Delay_us(uint16_t time_in_us){
TIM6->CNT = 0;
while(TIM6->CNT<time_in_us);
}
void Delay_ms(uint16_t time_in_ms){
TIM6->CNT=0;
for(uint16_t i=0; i<time_in_ms; i++){
Delay_us(1000);
}
}
//__attribute__((optimize("-O0")))
void Delay(uint32_t time){
while(time--);
}
 
void GPIO_Config(void){
RCC->IOPENR |= (1<<2);
GPIOC->MODER &= ~(1<<25);
}
int main(void){
//SystemClockConfig();
Timer6Config();
GPIO_Config();
 
 
while(1){
 
 
GPIOC->BSRR |= (1<<12);
Delay_ms(500);
GPIOC->BSRR |= (1<<12)<<16;
Delay_ms(500);
}
 
 
 
}
 
I am a beginner,
 
any help would be appreciated.....
    This topic has been closed for replies.
    Best answer by STM_Thirty2

    Per the User Manual for the Nucleo-G071RB

    X3_G0.png

     

    Further more you can configure the target to use MCO from STLink:
    MCO_G0.png

    I modified your register level code to start up the HSI at 64MHz, this code woks and is tested, the rest of you code I did not implement:

     

     

    void pwr_settings(void){
    	//enabling power interface
    	RCC->APBENR1 |= RCC_APBENR1_PWREN;
    	//configuring voltage regulator to default 01
    	PWR->CR1 |= (0x1UL << PWR_CR1_VOS_Pos);
    	PWR->CR1 &= ~(0x2UL << PWR_CR1_VOS_Pos);//
    	//configure flash prefetch and latency
    	FLASH->ACR |= (FLASH_ACR_ICEN | FLASH_ACR_PRFTEN | FLASH_ACR_LATENCY_1);
    }
    
    void SystemClockConfig(void){
     #define PLLN 16
    
     //using internal clock source
     RCC->CR |= RCC_CR_HSION;
     while(!(RCC->CR & RCC_CR_HSIRDY));
    
     pwr_settings();
     //configure main PLL; PLLM, PLLN, PLLR
     RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLN; // reset PLLN since it is NOT 0 on reset
     RCC->PLLCFGR |= ((8<<RCC_PLLCFGR_PLLN_Pos) | (2<<RCC_PLLCFGR_PLLSRC_Pos));// use HSI , N=8
     RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLM; // M=1
     RCC->PLLCFGR |= RCC_PLLCFGR_PLLR_0; // R=2
     RCC->CR |= RCC_CR_PLLON; //enable PLL
     RCC->PLLCFGR |= RCC_PLLCFGR_PLLREN; // enable PLLR output after PLL is enabled
     while(!(RCC->CR & RCC_CR_PLLRDY)); //wait for PLL to be ready
    
    
     //configuring prescalers for main clock and peripheral clocks
     RCC->CFGR &= ~(RCC_CFGR_HPRE); // AHB prescaler to 1
     // set system clock to PLL
     RCC->CFGR |= RCC_CFGR_SW_1; // set system clock to PLL
     // wait for pll to be used as sys clock, check for RCC_CFGR_SWS_1
     while(!(RCC->CFGR & RCC_CFGR_SWS_1));
    
     // set APB prescaler to 1
     RCC->CFGR &= ~(RCC_CFGR_PPRE); // APB prescaler to 1
    
     // update cmsis system core clock
     SystemCoreClockUpdate(); // CMSIS defdined function to update SystemCoreClock variable
    
    }

     

     

     

    4 replies

    waclawek.jan
    Super User
    March 27, 2024

    I assume you see blinking with SystemClockConfig() commented out, and that you are aware of that 8x faster blinking may be too fast to see by eye.

    I don't see anything fatal in your code.

    Can you single-step the SystemClockConfig() code and observe the registers' content? Or at least, try variants with lighting up the LED at various points of SystemClockConfig() and see how far does it get.

    JW

    HZ_itAuthor
    Associate II
    March 28, 2024

    Thanks for response,

    I commented the SystemClockConfig() in main to verify if my blink code works by using just the timer6 configurations....and it did work that way...

    when I tried to uncomment SystemClockConfig() and debug it, after stepping in line: RCC->CR |= RCC_CR_HSEON; it sets the HSEON bit in RCC_CR register to 1 but having the HSION and HSIRDY bit still 1 aswell

    when i step into next instruction:while(!(RCC->CR & RCC_CR_HSERDY)); the code execution never leaves the loop and the debug is stuck in there as the RCC_CR_HSERDY bit does not set.....I believe this suggests that the clock is not switched to HSE

    could advise on why this might be the issue?

     

    my guess is that the clock frequency is not set accordingly and as I am unable to set it from Options for target - Target tab as Xtal frequency is greyed out as <undefined> I dont know how I can set the frequency to 64MHz before debug

     

    any help would be appreciated

    STM_Thirty2
    STM_Thirty2Best answer
    ST Employee
    March 28, 2024

    Per the User Manual for the Nucleo-G071RB

    X3_G0.png

     

    Further more you can configure the target to use MCO from STLink:
    MCO_G0.png

    I modified your register level code to start up the HSI at 64MHz, this code woks and is tested, the rest of you code I did not implement:

     

     

    void pwr_settings(void){
    	//enabling power interface
    	RCC->APBENR1 |= RCC_APBENR1_PWREN;
    	//configuring voltage regulator to default 01
    	PWR->CR1 |= (0x1UL << PWR_CR1_VOS_Pos);
    	PWR->CR1 &= ~(0x2UL << PWR_CR1_VOS_Pos);//
    	//configure flash prefetch and latency
    	FLASH->ACR |= (FLASH_ACR_ICEN | FLASH_ACR_PRFTEN | FLASH_ACR_LATENCY_1);
    }
    
    void SystemClockConfig(void){
     #define PLLN 16
    
     //using internal clock source
     RCC->CR |= RCC_CR_HSION;
     while(!(RCC->CR & RCC_CR_HSIRDY));
    
     pwr_settings();
     //configure main PLL; PLLM, PLLN, PLLR
     RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLN; // reset PLLN since it is NOT 0 on reset
     RCC->PLLCFGR |= ((8<<RCC_PLLCFGR_PLLN_Pos) | (2<<RCC_PLLCFGR_PLLSRC_Pos));// use HSI , N=8
     RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLM; // M=1
     RCC->PLLCFGR |= RCC_PLLCFGR_PLLR_0; // R=2
     RCC->CR |= RCC_CR_PLLON; //enable PLL
     RCC->PLLCFGR |= RCC_PLLCFGR_PLLREN; // enable PLLR output after PLL is enabled
     while(!(RCC->CR & RCC_CR_PLLRDY)); //wait for PLL to be ready
    
    
     //configuring prescalers for main clock and peripheral clocks
     RCC->CFGR &= ~(RCC_CFGR_HPRE); // AHB prescaler to 1
     // set system clock to PLL
     RCC->CFGR |= RCC_CFGR_SW_1; // set system clock to PLL
     // wait for pll to be used as sys clock, check for RCC_CFGR_SWS_1
     while(!(RCC->CFGR & RCC_CFGR_SWS_1));
    
     // set APB prescaler to 1
     RCC->CFGR &= ~(RCC_CFGR_PPRE); // APB prescaler to 1
    
     // update cmsis system core clock
     SystemCoreClockUpdate(); // CMSIS defdined function to update SystemCoreClock variable
    
    }

     

     

     

    "If you feel a post has answered your question, please click ""Accept as Solution"""
    HZ_itAuthor
    Associate II
    March 28, 2024

    Thanks for your response...
    I configured my clock for HSI and it works with precise delay....

    appreciate for your help!