Saturday, September 28, 2013

Programming Example : RCC


#include "stm32f2xx.h"

/* 
PLL clock flow:
    HSE_VALUE = 25MHz

    PLL_VCO_Input = (HSE_VALUE or HSI_VALUE) / PLL_M 
                  = 25MHz / 25
                  = 1MHz

    PLL_VCO = PLL_VCO_Input * PLL_N
            = 1MHz * 240
            = 240MHz

    SYSCLK = PLL_VCO / PLL_P
           = 240MHz / 2
           = 120MHz

    PLL48CK = PLL_VCO / PLL_Q
            = 240MHz / 5
            = 48MHz

Range:
    PLL_VCO_Input: 1 ~ 2MHz, 2MHz is recommended.
    PLL_VCO: 64 ~ 432MHz
    PLL48CK: requires 48MHz(USB OTG FS)
             requires lower than or equal to 48MHz(SDIO, RNG)

    PLL_M: 2 ~ 63
    PLL_N: 64 ~ 432
    PLL_P: 2, 4, 6, 8
    PLL_Q: 2 ~ 15
*/

#define PLL_M   25
#define PLL_N   240
#define PLL_P   2
#define PLL_Q   5

void FLASH_Config(void);
void RCC_PeriphClockConfig(void);

int main(void)
{
  __IO uint32_t HSEStartUpStatus = 0;

  /* Enable HSE, and wait till HSE is ready */
  RCC_HSEConfig(RCC_HSE_ON);
  HSEStartUpStatus = RCC_WaitForHSEStartUp();

  if (HSEStartUpStatus == SUCCESS)
  {
    /* Flash Configuration */
    FLASH_Config();
 
    /* Peripheral Clock Configuration */
    RCC_PeriphClockConfig();
     
    /* Config the main PLL Clock to 120MHz */
    RCC_PLLConfig(RCC_PLLSource_HSE, PLL_M, PLL_N, PLL_P, PLL_Q);
 
    /* Enable the main PLL, and wait till the main PLL is ready */
    RCC_PLLCmd(ENABLE);
    while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
 
    /* Select the main PLL as system clock source, 
      and wait till the main PLL is used as system clock source */
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
    while (RCC_GetSYSCLKSource() != RCC_CFGR_SWS_PLL);
  }
  else
  {
    /* If HSE fails to start up, user can add here some code 
      to deal with this error */
  }
}

void FLASH_Config(void)
{
  /* Flash 3 wait state, prefetch buffer and cache ON */
  FLASH_SetLatency(FLASH_Latency_3);
  FLASH_PrefetchBufferCmd(ENABLE);
  FLASH_InstructionCacheCmd(ENABLE);
  FLASH_DataCacheCmd(ENABLE);
}

void RCC_PeriphClockConfig(void)
{
  /* HCLK, PCLK1, PCLK2 Configuration */
  RCC_HCLKConfig(RCC_SYSCLK_Div1);
  RCC_PCLK2Config(RCC_HCLK_Div2);
  RCC_PCLK1Config(RCC_HCLK_Div4);
}


/*
<HSE Enable & Ready>
1. HSE Enable
@reg   RCC->CR
@desc  Bit 18, HSEBYP: HSE clock bypass
       Bit 16, HSEON: HSE clock enable
@fn    void RCC_HSEConfig(uint8_t RCC_HSE)
@param RCC_HSE_ON
@ref   stm32f2xx_rcc.h

2. HSE Ready
@reg   RCC->CR
@desc  Bit 17, HSERDY: HSE clock ready flag
@fn    ErrorStatus RCC_WaitForHSEStartUp(void)
       FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG)
@param HSE_STARTUP_TIMEOUT, RCC_FLAG_HSERDY
@ref   stm32f2xx.h, stm32f2xx_rcc.h


<Flash Configuration>
1. Latency cycle, Instruction prefetch, Instruction cache, Data cache
@reg   FLASH->ACR
@desc  Bit 10, DCEN: Data cache enable
       Bit 9, ICEN: Instruction cache enable
       Bit 8, PRFTEN: Prefetch enable
       Bits 2:0, LATENCY: Wait state for latency
@fn    void FLASH_SetLatency(uint32_t FLASH_Latency)
       void FLASH_PrefetchBufferCmd(FunctionalState NewState)
       void FLASH_InstructionCacheCmd(FunctionalState NewState)
       void FLASH_DataCacheCmd(FunctionalState NewState)
@param FLASH_Latency_3
@ref   stm32f2xx_flash.h


<Peripheral Clock Configuration>
1. Peripheral clock prescaler
@reg   RCC->CFGR
@desc  Bits 15:13, PPRE2: APB high-speed prescaler (APB2), must not exceed 60MHz
       Bits 12:10, PPRE1: APB low-speed prescaler (APB1), must not exceed 30MHz
       Bits 7:4, HPRE: AHB prescaler
@fn    void RCC_HCLKConfig(uint32_t RCC_SYSCLK)
       void RCC_PCLK1Config(uint32_t RCC_HCLK)
       void RCC_PCLK2Config(uint32_t RCC_HCLK)
@param RCC_SYSCLK_Div1, RCC_HCLK_Div2, RCC_HCLK_Div4
@ref   stm32f2xx_rcc.h


<PLL Configuration>
@reg   RCC->PLLCFGR
@desc  Bits 27:24, PLLQ: Main PLL division factor for USB OTG FS, SDIO, RNG clock
       Bit 22, PLLSRC: Main PLL(PLL) and audio PLL(PLLI2S) entry clock source
       Bits 17:16, PLLP: Main PLL division factor for main system clock
       Bits 14:6, PLLN: Main PLL multiplication factor for VCO
       Bits 5:0, PLLM: Division factor for main PLL(PLL) and audio PLL(PLLI2S) input clock
@fn    void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t PLLM, uint32_t PLLN, uint32_t PLLP, uint32_t PLLQ)
@param RCC_PLLSource_HSE
@ref   stm32f2xx_rcc.h

<Main PLL Enable & Ready>
1. Main PLL Enable
@reg   RCC->CR
@desc  Bit 24, PLLON: Main PLL enable
@fn    void RCC_PLLCmd(FunctionalState NewState)
@param CR_PLLON_BB (using Bit Banding)
@ref   stm32f2xx_rcc.h

2. Main PLL Ready
@reg   RCC->CR
@desc  Bit 25, PLLRDY: Main PLL clock ready flag
@fn    FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG)
@param RCC_FLAG_PLLRDY
@ref   stm32f2xx_rcc.h


<System Clock Configuration as the main PLL>
1. System clock configuration

@reg   RCC->CFGR

@desc  Bits 1:0, SW: System clock switch

@fn    void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource)
@param RCC_SYSCLKSource_PLLCLK
@ref   stm32f2xx_rcc.h

2. Check the system clock status

1. System clock configuration



@reg   RCC->CFGR

@desc  Bits 3:2, SWS: System clock switch status

@fn    uint8_t RCC_GetSYSCLKSource(void)
@param RCC_CFGR_SWS_PLL
@ref   stm32f2xx.h
*/

1 comment:

  1. There is a good example.
    SetSysClock() function in system_stm32f2xx.c

    ReplyDelete