I am trying to configure the RCC clock of a STM32G474RE board with PLL using HSI16 as clock source and PLLM = 1, PLLN = 10, AHB = 1, APB1 = 1 and APB2 = 4 as the configuration. However when I run the code the PLLRDY flag is never set and I'm stuck in the infinite loop.
#include "main.h"
void SytemClockConfig(void){
/*Enable HSI16*/
RCC->CR |= RCC_CR_HSION;
while(!(RCC->CR & RCC_CR_HSIRDY)){}
/*Configure PWR and FLASH*/
RCC->APB1ENR1 |= RCC_APB1ENR1_PWREN;
PWR->CR1 |= (0x01 & PWR_CR1_VOS_Msk);
FLASH->ACR |= FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_LATENCY_2WS | FLASH_ACR_PRFTEN;
/*Configure AHB and APB*/
RCC->CFGR |= (0x00 & RCC_CFGR_HPRE_Msk);
RCC->CFGR |= (0x00 & RCC_CFGR_PPRE1_Msk);
RCC->CFGR |= (0x05 & RCC_CFGR_PPRE2_Msk);
/*Config PLL*/
RCC->PLLCFGR |= (0x02 & RCC_PLLCFGR_PLLSRC_Msk);
RCC->PLLCFGR |= (0x00 & RCC_PLLCFGR_PLLM_Msk);
RCC->PLLCFGR &= ~(RCC_PLLCFGR_PLLN_Msk);
RCC->PLLCFGR |= (0x0A & RCC_PLLCFGR_PLLN_Msk);
RCC->PLLCFGR |= (0x01 & RCC_PLLCFGR_PLLREN_Msk);
RCC->PLLCFGR |= (0x00 & RCC_PLLCFGR_PLLR_Msk);
/*Enable PLL*/
RCC->CR |= (0x01 & RCC_CR_PLLON);
while(!(RCC->CR & RCC_CR_PLLRDY)){}
RCC->CFGR |= (0x05 & RCC_CFGR_SW_Msk);
while((RCC->CFGR & RCC_CFGR_SWS) != (0x03 & RCC_CFGR_SWS_Msk)){}
}
int main(void){
SytemClockConfig();
}
You simply do not write the values you think you write. You need to learn how binary logical operations work. Basically, almost all operations are wrong. I will give you only some examples.
RCC->CR |= (0x01 & RCC_CR_PLLON);
this operation does nothin'. PLLON bit is at position 24. You binary AND 1
and 1 << 24
. The result is 0
. Then you binary OR it to the RCC -> CR register. This operation does nothing. You need to RCC->CR |= RCC_CR_PLLON;
RCC->CFGR |= (0x00 & RCC_CFGR_HPRE_Msk);
it is the same as RCC->CFGR |= 0
; (It does not zero HPRE bits!!!)
And many many more (almost all of them).
I would suggest to practice binary logic operations before attempting any bare metal programming.
If you want to:
n
- VAL |= (1U << n)
n
- VAL &= ~(1 << n)
n
- VAL ^= (1 << n)
If you want to put value 5
into PPRE2
bits in the register
uint32_t tmp = RCC->CFGR;
tmp &= ~RCC_CFGR_PPRE2_Msk;
tmp |= 5UL << RCC_CFGR_PPRE2_Pos
RCC->CFGR = tmp;
I would suggest using temporary variables and assign value to the register.