AnsweredAssumed Answered

Switching "32 MHz HSI" to "4 MHz MSI" and go back in runtime

Question asked by ferraro.francesc.001 on Oct 12, 2015
Latest reply on Oct 16, 2015 by ferraro.francesc.001
I use the STM32L151RBT6.
I can work well with a clock initialized with the "Code 1"HSI 32MKz or with a clock initialized with the "Code 2" MSI 4MHz.

But I do not know how to change the clock in runtime.

I would like:
loop
{
configure to 32MHz HSI
switch to 4MHz MSI
configure to STOP mode with RTC clocked by LSI
wakeup and work to 4 MHz MSI
switch to 32MHz HSI
}


the "Code 1" and the "Code 2" works well only after the reset, but how do switch correctly "32 MHz HSI" to "4 MHz MSI" and go back?
some advice?

(I will estimate, maybe I'm just less than 4 MHz.)

“Code 1”
/*  PLL configuration */
  RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLMUL | RCC_CFGR_PLLDIV));
  RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSI | RCC_CFGR_PLLMUL6 | RCC_CFGR_PLLDIV3);
  /* Enable PLL */
  RCC->CR |= RCC_CR_PLLON;
  /* Wait till PLL is ready */
  while((RCC->CR & RCC_CR_PLLRDY) == 0);
  /* Select PLL as system clock source */
  RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
  RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
  /* Wait till PLL is used as system clock source */
  while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_PLL);

  
“Code 2” 
  __IO uint32_t StartUpCounter = 0, MSIStatus = 0;  
  /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/    
  /* Enable MSI */    
  RCC->CR |= ((uint32_t)RCC_CR_MSION);
   /* Wait till MSI is ready and if Time out is reached exit */
  do
  {
    MSIStatus = RCC->CR & RCC_CR_MSIRDY;
    StartUpCounter++;  
  } while((MSIStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
  if ((RCC->CR & RCC_CR_MSIRDY) != RESET)
  {
    MSIStatus = (uint32_t)0x01;
  }
  else
  {
    MSIStatus = (uint32_t)0x00;
  }  
  
  if (MSIStatus == (uint32_t)0x01)
  { 
    /* Enable 64-bit access */
    FLASH->ACR |= FLASH_ACR_ACC64;  
    /* Enable Prefetch Buffer */
    FLASH->ACR |= FLASH_ACR_PRFTEN;    
    /* Flash 1 wait state */
    FLASH->ACR |= FLASH_ACR_LATENCY; 
    /* Enable the PWR APB1 Clock */
    RCC->APB1ENR |= RCC_APB1ENR_PWREN;
    /* Select the Voltage Range 3 (1.2V) */
    PWR->CR = PWR_CR_VOS;
    /* Wait Until the Voltage Regulator is ready */
    while((PWR->CSR & PWR_CSR_VOSF) != RESET);    
    /* HCLK = SYSCLK */
    RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
    /* PCLK2 = HCLK */
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
    /* PCLK1 = HCLK */
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1;
    /* Set MSI clock range */
    RCC->ICSCR &= (uint32_t)((uint32_t)~(RCC_ICSCR_MSIRANGE));    
    RCC->ICSCR |= (uint32_t)RCC_ICSCR_MSIRANGE_6;
    /* Select MSI as system clock source */
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
    RCC->CFGR |= (uint32_t)RCC_CFGR_SW_MSI;    
    /* Wait till MSI is used as system clock source */
    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x00);
  }
  else
  { 
    /* If MSI fails to start-up, the application will have wrong clock 
       configuration. User can add here some code to deal with this error */    
  } 


Outcomes