1
\$\begingroup\$

I am trying to switch the cyctem clock source on the stm32l433 MCU from the MSI (set by default) to PLL. My code for setting up the PLL & switching the sysclk source is this:

/* Set latency to 4ws to support up to 80MHz */
SET_LATENCY(FLASH_ACR_LATENCY_4WS);
while ((FLASH->ACR & FLASH_ACR_LATENCY) != FLASH_ACR_LATENCY_4WS)
    ;

/* Disable PLL, enable HSI16 & HSI48 */
RCC->CR = (RCC->CR & ~RCC_CR_PLLON) | RCC_CR_HSION;
if (!(RCC->CRRCR & RCC_CRRCR_HSI48ON))
    RCC->CRRCR |= RCC_CRRCR_HSI48ON;
/* Wait for PLL, HSI16 & 48 */
while (!(RCC->CRRCR & RCC_CRRCR_HSI48RDY) || !(RCC->CR & RCC_CR_HSIRDY) || (RCC->CR & RCC_CR_PLLRDY))
    ;

/* Setup PLL */
RCC->PLLCFGR &= ~(RCC_PLLCFGR_PLLREN | RCC_PLLCFGR_PLLR |
                  RCC_PLLCFGR_PLLQEN | RCC_PLLCFGR_PLLQ |
                  RCC_PLLCFGR_PLLPEN | RCC_PLLCFGR_PLLPDIV | RCC_PLLCFGR_PLLP |
                  RCC_PLLCFGR_PLLN | RCC_PLLCFGR_PLLM);
RCC->PLLCFGR |= (78 << RCC_PLLCFGR_PLLN_Pos) | (0b11 << RCC_PLLCFGR_PLLM_Pos); /* Set up PLL multiplier to 78/4 */
RCC->PLLCFGR |= 0b01 << RCC_PLLCFGR_PLLR_Pos;                                  /* Set PLL division to 4 */

/* Enable PLL & wait for it */
RCC->PLLCFGR |= RCC_PLLCFGR_PLLREN;
RCC->CR |= RCC_CR_PLLON;
while (RCC->CR & RCC_CR_PLLRDY)
    ;

/* Setup system prescalers */
RCC->CFGR &= ~RCC_CFGR_HPRE;                                     /* Set AHB prescaler to no division */
RCC->CFGR = (RCC->CFGR & ~RCC_CFGR_PPRE1) | RCC_CFGR_PPRE1_DIV4; /* Set APB1 prescaler to 4 */
RCC->CFGR &= ~RCC_CFGR_PPRE2;                                    /* Set APB2 prescaler to no division */

/* Set PLL as sysclk source & wait for it */
RCC->CFGR = (RCC->CFGR & ~RCC_CFGR_SW) | RCC_CFGR_SW_PLL;
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL)
    ;

Everything runs fine until I try to set PLL as the sysclk source. After I set SW bits to PLL, i need to read the SWS bits to make sure that the hardware has applied the change, and when the program reaches the while loop to wait for the SWS bits, it hangs and never exits the loop.

Am I doing something wrong or in the wrong order? Is there any other register I need to set before changing sysclk source?

I have tried switching to HSI16 instead of PLL and that clock source does work and the MCU exits the while loop almost immediately. I have checked that both my PLLN and PLLM values are in the acceptable range and thet the VCOin and VCOout are in the acceptable frequency range too.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ What clock source is selected for the PLL input? Is that source enabled? What is the frequency of this source? \$\endgroup\$
    – Justme
    Commented Mar 2, 2021 at 5:42
  • \$\begingroup\$ @Justme Thx for pointing it out, i actually forgot to set pll source, that was the issue. \$\endgroup\$
    – JustClaire
    Commented Mar 2, 2021 at 5:56

1 Answer 1

2
\$\begingroup\$

The code does not set a clock source for the PLL so it does not work.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.