title: stm32f4 clock configuration won't enable bits in PWR register
body: <p>I've recently purchased a NUCLEO-F446RE board (an STM32F4 product) and I'm having major problems enabling bits in the PWR register.</p>
  
  <p>My goal is to blink an LED using the timer and I'm trying to configure the HSI clock to a max system frequency of 180 MHz.</p>
  
  <p>I have followed instructions in the reference manual to a 'T'. Below is a screenshot of the instructions: <a href="https://i.stack.imgur.com/FmJXL.png" rel="nofollow noreferrer">Screenshot to reference manual</a></p>
  
  <p>IDE: Keil v5</p>
  
  <p>The board is running the latest firmware. </p>
  
  <p>This is my code:</p>
  
  <pre><code>/* Includes ------------------------------------------------------------------*/
  #include "stm32f4xx.h"
  
  /* Private function prototypes -----------------------------------------------*/
  static void sysClockConfig(void);
  static void tim3Config(void);
  
  /**
    ******************************************************************************
    * @brief  Main program.
    * @note   None
    * @param  None
    * @retval None
    ******************************************************************************
    */
  int main(void) {
  
      sysClockConfig();
      tim3Config();
  
      RCC-&gt;AHB1ENR |= RCC_AHB1ENR_GPIOAEN;                //Enable GPIOA CLK
      GPIOA-&gt;MODER |= GPIO_MODER_MODE5_0;                 //GPIOA pin5 selected as output
      GPIOA-&gt;ODR   |= GPIO_ODR_OD5;                       //GPIOA pin5 set high
      volatile int i;
  
      while(1) {
  
          GPIOA-&gt;ODR |= GPIO_ODR_OD5;
          for(i=0; i&lt;1000000; i++);
          GPIOA-&gt;ODR &amp;= ~GPIO_ODR_OD5;
          for(i=0; i&lt;1000000; i++);
      }
  
  }
  
  /**
    ******************************************************************************
    * @brief  Configures sysmtem clock and main PLL.
    *         Initializes voltage regulator scaling and overdrive mode.
    *         Initializes flash memory.
    * @note   CLK  SRC  = HSI -&gt; PLL
    #         SYS  CLK  = 180 MHz
    *         AHB  CLK  = 180 MHz
    *         APB1 CLK  =  45 MHz
    *         APB2 CLK  =  90 MHz
    *         Change latency depending on freq and voltage (see table 5, pg.63)
    *         Look at pg.94 for CLK config sequence
    * @param  None
    * @retval None
    ******************************************************************************
    */
  static void sysClockConfig(void) {
  
      RCC-&gt;CR |=  RCC_CR_HSION;                           //Enables HSI clock
      while( !(RCC-&gt;CR &amp; RCC_CR_HSIRDY) );                //Waits until HSI is stable
      RCC-&gt;CFGR |= RCC_CFGR_SW_HSI;                       //Select HSI is SYS CLK
      while( RCC-&gt;CFGR &amp; RCC_CFGR_SWS_HSI );              //Wait until HSI is SYS CLK
      RCC-&gt;CR &amp;= ~RCC_CR_PLLON;                            //Disables PLL
  
      //-----&gt; ISSUE #1 &lt;-----
      PWR-&gt;CR |= PWR_CR_VOS;                              //Voltage reg = scale 3
      while( !(PWR-&gt;CSR &amp; PWR_CSR_VOSRDY) );              //Waits until scaling is ready
  
      /** PLL config: I2S/SAI/SPDIF = VCO / R  
        *                  USB/SDIO = VCO / Q
        *                   SYS CLK = VCO / P
        *                       VCO = HSI * (N/M)  
        */
      RCC-&gt;PLLCFGR |= (  8u                   |           //PLL_M   =   8
                      (180u &lt;&lt;  6)            |           //PLL_N   = 180
                      (  0u &lt;&lt; 16)            |           //PLL_P   =   2
                      (RCC_PLLCFGR_PLLSRC_HSI)|           //PLL SRC = HSI 
                      (  8u &lt;&lt; 24)            |           //PLL_Q   =   8
                      (  4u &lt;&lt; 28)             );         //PLL_R   =   4
  
      RCC-&gt;CR |= RCC_CR_PLLON;                            //Enable PLL
  
      //-----&gt; ISSUE #2 &lt;-----
      PWR-&gt;CR |= PWR_CR_ODEN;                             //Enables Overdrive mode
      while( !(PWR-&gt;CSR &amp; PWR_CSR_ODRDY) );               //Waits until OD is ready
      PWR-&gt;CR |= PWR_CR_ODSWEN;                           //Swites Overdrive mode   
      while( !(PWR-&gt;CSR &amp; PWR_CSR_ODSWRDY) );             //Waits until OD switch is ready
  
      FLASH-&gt;ACR |= (FLASH_ACR_PRFTEN     |               //Prefetch enable
                     FLASH_ACR_ICEN       |               //Intruction cache enable
                     FLASH_ACR_DCEN       |               //Data cache enable
                     FLASH_ACR_LATENCY_5WS );             //FLASH 5 wait states          
  
      while( !(RCC-&gt;CR &amp; RCC_CR_PLLRDY) );                //Waits until PLL is locked
  
      RCC-&gt;CFGR |= (RCC_CFGR_HPRE_DIV1    |               //AHB  = Sys CLK DIV_1
                    RCC_CFGR_PPRE1_DIV4   |               //APB1 = AHB CLK DIV_4
                    RCC_CFGR_PPRE2_DIV2   |               //APB2 = AHB CLK DIV_2
                    RCC_CFGR_SW_PLL        );             //Select PLL as SYS CLK
      while( !(RCC-&gt;CFGR &amp; RCC_CFGR_SWS_PLL) );           //Waits until PLL is SYS CLK
  }
  
  /**
    ******************************************************************************
    * @brief  Configures TIM3.
    * @note   None
    * @param  None
    * @retval None
    ******************************************************************************
    */
  static void tim3Config(void) {
  
  }
  </code></pre>
  
  <p>I haven't finished setting up the timer, so I'm just using a CPU wasting loop to blink the LED.</p>
  
  <p>There are 2 issues (1 minor &amp; 1 major):</p>
  
  <p>1.</p>
  
  <pre><code>PWR-&gt;CR |= PWR_CR_VOS;
  while( !(PWR-&gt;CSR &amp; PWR_CSR_VOSRDY) );
  </code></pre>
  
  <p>When I execute the code above, it gets stuck in a infinite loop. This isn't a huge deal considering the value is enabled by default. Although I'd like to know why this is occurring. I've been commenting this block out to execute the following block of code.</p>
  
  <p>2.</p>
  
  <pre><code>PWR-&gt;CR |= PWR_CR_ODEN;
  while( !(PWR-&gt;CSR &amp; PWR_CSR_ODRDY) );
  PWR-&gt;CR |= PWR_CR_ODSWEN;
  while( !(PWR-&gt;CSR &amp; PWR_CSR_ODSWRDY) );
  </code></pre>
  
  <p>The code above is the most troubling. When I debug my code, PWR_CR_ODEN does not enable and eventually gets stuck in a infinite loop on the 2nd line. I've also tried enabling the bit by using: </p>
  
  <pre><code>PWR-&gt;CR |= (1 &lt;&lt; 16);
  </code></pre>
  
  <p>But it still get stucks on the 2nd line of code.</p>
  
  <p>The reference manual has not indicated anything special in configuring this register. I'm completely lost here.</p>
  
  <p>Oddly enough, if I completely omit the 2 blocks of code the program will execute and blink the LED. However, I'd like to resolve the problems shown above and understand why this is happening.</p>
  
  <p>Any help is greatly appreciated. And sorry for the long post.</p>