Internal Oscillator

Posted on
  • Is there an easy way to switch to the internal oscillator on the pico board?

  • The high speed internal, or low speed?

    You can do it with some poke commands - you'd have to look in the chip's reference manual though. There's some info on how to access hardware here: espruino.com/STM32+Peripheral­s

    But it doesn't specifically cover the oscillators.

    The problem you might find is that the internal oscillator isn't good enough for USB, so the second you move to it, USB will drop out.

    Out of interest, why do you want to do it? On newer builds (the ones from GitHub, or 1v86 when it comes out) can change the clock rate with E.setClock: github.com/espruino/Espruino/blo­b/master/src/jswrap_espruino.c#L780

    If you were doing it for reduced power consumption, you might find setClock is good enough for what you want.

  • I was looking to port the code to a board with no external oscillator, I figured out the code changes and post them here if anyone else is interested:

    --- a/targets/stm32/jshardware.c
    +++ b/targets/stm32/jshardware.c
    @@ -2487,13 +2487,14 @@ bool jshSleep(JsSysTime timeUntilWake) {
     [#endif](http://forum.espruino.com/searc­h/?q=%23endif)
     [#endif](http://forum.espruino.com/searc­h/?q=%23endif)
         // recover oscillator
    -    RCC_HSEConfig(RCC_HSE_ON);
    -    if( RCC_WaitForHSEStartUp() == SUCCESS) {
    +      RCC_HSICmd(ENABLE);
    +//    RCC_HSEConfig(RCC_HSE_ON);
    +//    if( RCC_WaitForHSEStartUp() == SUCCESS) {
           RCC_PLLCmd(ENABLE);
           while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)­ == RESET);
           RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK­);
           while(RCC_GetSYSCLKSource() != 0x08);
    -    }
    +//    }
         RTC_WaitForSynchro(); // make sure any RTC reads will be done
     [#ifdef](http://forum.espruino.com/searc­h/?q=%23ifdef) USB
         jshSetUSBPower(true);
    @@ -2916,14 +2917,14 @@ unsigned int jshSetSystemClock(JsVar *options) {
       if (pclk2<-1) return 0;
     
       // Run off external clock - 8Mhz - while we configure everything
    -  RCC_SYSCLKConfig(RCC_SYSCLKSource_HSE);
    +  RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI);
       // set latency
       if (latency!=255) FLASH_SetLatency(latency);
       if (pclk1>=0) RCC_PCLK1Config(pclk1);
       if (pclk2>=0) RCC_PCLK2Config(pclk2);
       // update PLL
       RCC_PLLCmd(DISABLE);
    -  RCC_PLLConfig(RCC_PLLSource_HSE, m, n, p, q);
    +  RCC_PLLConfig(RCC_PLLSource_HSI, m, n, p, q);
       RCC_PLLCmd(ENABLE);
       while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)­ == RESET) {}
       RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK­);
    

    and

    --- a/targetlibs/stm32f4/lib/system_stm32f4x­x.c
    +++ b/targetlibs/stm32f4/lib/system_stm32f4x­x.c
    @@ -256,7 +256,7 @@
     // SYSCLK = PLL_VCO / PLL_P 
     
     [#define](http://forum.espruino.com/sear­ch/?q=%23define) PLL_M      8
    -#define PLL_Q      7
    +#define PLL_Q      4
     
     [#if](http://forum.espruino.com/search/?­q=%23if) defined (STM32F40_41xxx)
     [#define](http://forum.espruino.com/sear­ch/?q=%23define) PLL_N      336
    @@ -269,8 +269,8 @@
     [#endif](http://forum.espruino.com/searc­h/?q=%23endif) /* STM32F427_437x || STM32F429_439xx */
     
     [#if](http://forum.espruino.com/search/?­q=%23if) defined (STM32F401xx) // 84Mhz
    -#define PLL_N      336
    -#define PLL_P      4
    +#define PLL_N      84
    +#define PLL_P      2
     [#endif](http://forum.espruino.com/searc­h/?q=%23endif) /* STM32F401xx */
     
     [#if](http://forum.espruino.com/search/?­q=%23if) defined (STM32F411xx) // 96Mhz 
    @@ -499,29 +499,29 @@ static void SetSysClock(void)
     /***************************************­***************************************/­
     /*            PLL (clocked by HSE) used as System clock source                */
     /***************************************­***************************************/­
    -  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
    +//  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
     
       /* Enable HSE */
    -  RCC->CR |= ((uint32_t)RCC_CR_HSEON);
    +//  RCC->CR |= ((uint32_t)RCC_CR_HSEON);
     
       /* Wait till HSE is ready and if Time out is reached exit */
    -  do
    -  {
    -    HSEStatus = RCC->CR & RCC_CR_HSERDY;
    -    StartUpCounter++;
    -  } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
    -
    -  if ((RCC->CR & RCC_CR_HSERDY) != RESET)
    -  {
    -    HSEStatus = (uint32_t)0x01;
    -  }
    -  else
    -  {
    -    HSEStatus = (uint32_t)0x00;
    -  }
    -
    -  if (HSEStatus == (uint32_t)0x01)
    -  {
    +//  do
    +//  {
    +//    HSEStatus = RCC->CR & RCC_CR_HSERDY;
    +//    StartUpCounter++;
    +//  } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
    +//
    +//  if ((RCC->CR & RCC_CR_HSERDY) != RESET)
    +//  {
    +//    HSEStatus = (uint32_t)0x01;
    +//  }
    +//  else
    +//  {
    +//    HSEStatus = (uint32_t)0x00;
    +//  }
    +
    +//  if (HSEStatus == (uint32_t)0x01)
    +//  {
         /* Select regulator voltage output Scale 1 mode */
         RCC->APB1ENR |= RCC_APB1ENR_PWREN;
         PWR->CR |= PWR_CR_VOS;
    @@ -547,7 +547,7 @@ static void SetSysClock(void)
     
         /* Configure the main PLL */
         RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |
    -                   (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);
    +                   (RCC_PLLCFGR_PLLSRC_HSI) | (PLL_Q << 24);
     
         /* Enable the main PLL */
         RCC->CR |= RCC_CR_PLLON;
    
  • As far as I know it should have worked as-is... Did it not? If the HSE doesn't start it drops back to HSI (in system_stm32f4xx.c). jshSetSystemClock might fail but that's only used when you call E.setClock.

    I guess the code for jshSleep might need some fiddling so it checks which oscillator it was using before it sleeps?

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Internal Oscillator

Posted by Avatar for Mark3072 @Mark3072

Actions