'STM32F407 Register Level Clock Configuration Issue

I am working on an STM32F407 Discovery Board. But I didn't solve my clock configuration problem. I want to 168 MHz working frequency and I get help from CubeMX Clock Configuration Manager. And this is my PLLCFGR Register value from CubeMX: 0x4405408. (I have problem with this register). Then I was copy paste all RCC registers to my CMSIS code. This is my clock configuration code:

RCC->CFGR       = 0x4008940A;  //MCO2 Source is PLLI2S (4), HSE Divided by 8 for RTC (8), APB2 Divided by 2 for 84Mhz, APB1 Divided by 4 for 42 Mhz
RCC->CR         = 0x0F0B6783;  //PLL, PLLI2S, HSE, CSS ON
RCC->PLLCFGR    = 0x04405408;  //PLLQ 4 (4), PLLSRC = HSE (4), PLLP 2 (0), PLLN 336 (54), PLLM 8 (8)
RCC->PLLI2SCFGR = 0x50003C00;  //PLLI2SR 5 (5), PLLI2SN 240 (3C)

But I can't read the same values from SFRs menu in Atollic. All registers are correct but the PLLCFGR register value is 0x04405419. This issue effects my clock speed, peripheral speed etc. I want to set PLLM bits to 8 but I read 19. So I get less speed then I want, because PLLM bits decide PLL input clock division. How can I solve this register problem?



Solution 1:[1]

When doing the clock configuration, you can't just load the registers with their final values. You need to follow some logical order and satisfy the limits mentioned in the reference manual. You must also consider the flash memory wait states.

Here is an example code to run STM32F407 at 48 MHz, using 8 MHz HSE. I feel lazy to modify & test it for 168 MHz, but this should give you the idea and a starting point.

FLASH->ACR |= FLASH_ACR_LATENCY_1WS; // 1 wait state for 48 MHz
RCC->CR |= RCC_CR_HSEON; // Activate external clock (HSE: 8 MHz)
while ((RCC->CR & RCC_CR_HSERDY) == 0); // Wait until HSE is ready
RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLQ;
RCC->PLLCFGR |= 4 << RCC_PLLCFGR_PLLQ_Pos; // PLL-Q: /4
RCC->PLLCFGR |= RCC_PLLCFGR_PLLSRC_HSE; // PLL source is HSE
RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLP; // PLL-P: /2
RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLN;
RCC->PLLCFGR |= 96 << RCC_PLLCFGR_PLLN_Pos; // PLL-N: x96
RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLM;
RCC->PLLCFGR |= 4 << RCC_PLLCFGR_PLLM_Pos; // PLL-M: /4
RCC->CR |= RCC_CR_PLLON; // Activate the PLL (Output: 96 MHz)
while ((RCC->CR & RCC_CR_PLLRDY) == 0); // Wait until PLL is ready
RCC->CFGR |= RCC_CFGR_HPRE_DIV2 // AHB divider: /2 (48 MHz)
        | RCC_CFGR_PPRE1_DIV2 // APB1 divider: /2 (24 MHz)
        | RCC_CFGR_PPRE2_DIV2; // APB2 divider: /2 (24 MHz)
RCC->CFGR |= RCC_CFGR_SW_PLL; // Switching to PLL clock source

Solution 2:[2]

I found my Issue where did came from. system_stm32f4xx.c and stm32f4xx.h files need changes for Stm32f4 Discovery board. This codes writing for 25Mhz HSE crystal but Discovery Board has 8Mhz HSE crystal. Then PLL bits. These bits defined in system_stm32f4xx.c file. You must be change PLL bits as you want. Thanks all of us;)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Tagli
Solution 2 RasimGök