STM32F107VC/RCC/Clock Modes example

From Teknologisk videncenter
Jump to: navigation, search

Clock mode 1

Clock Mode 1:HSI Oscillator as SYSCLK (Default)

Configuring clock mode 1

If the controller is using the HSE clock, and you want to shift to HSI direct clocking.

/* sub rcc_clockmode1()
   abstract: Select default as System Clock (HSI 8 Mhz)

   input...:  -

   output..: -
   limits..: No errorcheck performed
   *********************************************
   See: http://mars.tekkom.dk/mediawiki/index.php/STM32F107VC/RSS/Clock_Paths
        http://mars.tekkom.dk/mediawiki/index.php/STM32F107VC/RSS
   *********************************************
   Step 1: Enabling the HSI clock - RCC_CR bit (If not enabled)
  		   HSION = 1 HSI : oscillator on
   Step 2: Waiting until HSI clock is ready an can be used as Clock Source 
           RCC_CR bit HSIRDY = 0 : Oscillator Not Ready
		   RCC_CR bit HSIRDY = 1 : Oscillator Ready
   Step 3: Select HSI in SW[1:0] as Clock Source
           RCC_CFGR bits SW[1:0] = 00 : HSI selected
   Step 4: Select AHB prescaler=1 
           RCC_CFGR bits HPRE[3:0] = 0000 
   Step 5: Setting FLASH wait states FLASH_ACR bits LATENCY[2:0] to 0 Wáit States(section 3.3) 
  		   LATECY[2:0] = 000 - Zero wait state. ( 0 Hz  < SYSCLK <= 24 Mhz)
  		   LATECY[2:0] = 001 - One wait state.  (24 MHz < SYSCLK <= 48 Mhz)
  		   LATECY[2:0] = 010 - Two wait state.  (48 MHz < SYSCLK <= 72 Mhz)
   Step 6: Disabling HSE Clock- RCC_CR bit
  		   HSEON = 0 : oscillator off
*/
void rcc_clockmode1( void ) {
  	// Step 1 - Enabling the HSI clock - If not enabled and ready
	if ( (RCC->CR & RCC_CR_HSIRDY) == 0) {
 	  RCC->CR |= RCC_CR_HSION;  // HSION=1
	
	  //Step 2 - Waiting until HSI clock is ready
	  while ((RCC->CR & RCC_CR_HSIRDY) == 0) {}; // Wait HSIRDY = 1
	}
	//Step 3: Select HSI in SW[1:0] as Clock Source
	//         Take care. SW[1:0] Select the clock source
	RCC->CFGR &= 0xfffffffc;

	//Step 4: Select AHB prescaler=1 
	RCC->CFGR &= 0xffffff0f; // HPRE[3:0] = 0000

    //Step 5: Setting FLASH wait states FLASH_ACR bits LATENCY[2:0] to 0 Wáit
	FLASH->ACR &= 0xfffffff8; //LATENCY[2:0] = 000
	
	//Step 6: Disabling HSE Clock- RCC_CR bit
	RCC->CR &= ~RCC_CR_HSEON;

}

Clock mode 5

Clock Mode 5:HSE through all Prescalers and Multipliers.

Configuring Clock mode 5

/* sub rcc_clockmode5()
   abstract: Select HSE as System Clock with,
     Crystal = 25 MHz
	 SYSCLK  = 72 MHz
	 FCLK    = 72 MHz
	 OTGFSCLK= 48 MHz (USB)

   input...:  -

   output..: -
   limits..: No errorcheck performed
   *********************************************
   See: http://mars.tekkom.dk/mediawiki/index.php/STM32F107VC/RSS/Clock_Paths
        http://mars.tekkom.dk/mediawiki/index.php/STM32F107VC/RSS
   *********************************************
   
   To select the frequencies 72 MHz as SYSCLK from 25 MHz Crystal the
   following calculation is necesary 25 MHz / 5 * 16 / 10 * 9 = 72 MHz
   
   PREDIV2 - Divide by 5
   PLL2MUL - Multiply by 16
   PREDIV1 - Divide by 10
   PLLMUL  - Multiply by 9  
   
   Step  0: HSEBYP default = 0 (Using Crystral = default)
   Step  1: Shift to Clockmode=1 (Freeing the Clock Path for programming)
   Step  2: Enabling the HSE clock - RCC_CR bit
  		   HSION = 1 HSE : oscillator on
   Step  3: Waiting until HSE clock is ready an can be used as Clock Source 
           RCC_CR bit HSERDY = 0 : Oscillator Not Ready
		   RCC_CR bit HSERDY = 1 : Oscillator Ready
   Step  4: Select RCC_CFGR2 PREDIV2[3:0] divide by 5 =  0100
   Step  5: Disable RCC_CR PLL2ON = Disable (Shut down PLL2MUL)
   Step  6: Select RCC_CFGR2 PLL2MUL[3:0] multiply by 16 = 1110
   Step  7: Enable RCC_CR PLL2ON = Enable (Start pll2MUL after programmed)
   Step  8: Wait for PLL2MUL to lock RCC_CR bit PLL2RDY = 1
   Step  9: Select PLL2MUL as PREDIV1SRC - RCC_CFGR2 bit PREDIV1SRC = 1
   Step 10: Select RCC_CFGR2 PREDIV1[3:0] divide by 10 = 1001
   Step 11: Select PREDIV1 as PLLSRC - RCC_CFGR bit PLLSRC = 1
   Step 12: Disable RCC_CR bit PLLON = 0
   Step 13: Select RCC_CFGR PLLMUL[3:0] multiply by 9 = 0111
   Step 14: Enable RCC_CR bit PLLON = 1
   Step 15: Wait for PLLMUL to lock RCC_CR bit PLLRDY = 1
   Step 16: USB Prescaler divide by 3 ( 72 Mhz * 2 / 3 )  = 48 MHz
            RCC_CFGR bit OTGFSPRE = 0
   Step 17: Select AHB prescaler=1 - RCC_CFGR bits HPRE[3:0] = 0000
   Step 18: Enable prefetch FLASH_ACR bit PRFTBE = 1
   Step 19: Setting FLASH wait states FLASH_ACR bits LATENCY[2:0] to 2 Wáit States(section 3.3) 
  		    LATECY[2:0] = 000 - Zero wait state. ( 0 Hz  < SYSCLK <= 24 Mhz)
  		    LATECY[2:0] = 001 - One wait state.  (24 MHz < SYSCLK <= 48 Mhz)
  		    LATECY[2:0] = 010 - Two wait state.  (48 MHz < SYSCLK <= 72 Mhz) 
   Step 20: RCC_CFGR bits PPRE1[2:0] = 100 -APB1 Prescaler divide by 2 = 36 MHz
   Step 21: RCC_CFGR bits ADCPRE[1:0] = 10 ADC-prescaler divide by 6 72 MHz / 6 = 12 MHz
   Step 22: Select PLLCLK in SW[1:0] as Clock Source
            RCC_CR SW[1:0] = 10
   Step 23: Disabling HSI Clock- RCC_CR bit
  		   HSION = 0 : oscillator off
           RCC_CFGR bits SW[1:0] = 00 : HSI selected
*/
void rcc_clockmode5( void ) {
int i;
	//Step  1: Shift to Clockmode=1
	rcc_clockmode1();

	// Step 2 - Enabling the HSE clock
 	RCC->CR |= RCC_CR_HSEON;  // HSEON=1
	
	//Step 3 - Waiting until HSE clock is ready
	while ((RCC->CR & RCC_CR_HSERDY) == 0) {}; // Wait HSERDY = 1

	//Step  4: Select RCC_CFGR2 PREDIV2[3:0] divide by 5 =  0100 (bits[7:4])
	RCC->CFGR2 |= 0x00000040; // Setting bit x1xx
	RCC->CFGR2 &= 0xffffff4f; // Resetting bit 0x00

    //Step  5: Disable RCC_CR PLL2ON = Disable (Shut down PLL2MUL)
	RCC->CR &= ~( 1 << 26 ); // Resetting bit 26 disabling PPL2MUL

	//Step  6: Select RCC_CFGR2 PLL2MUL[3:0] multiply by 16 = 1110 (bits[11:8])
	RCC->CFGR2 |= 0x00000e00; // Setting bits 111x
	RCC->CFGR2 &= 0xfffffeff; // Resetting bit xxx0

	//Step  7: Enable RCC_CR PLL2ON = Enable (Start pll2MUL after programmed)
	RCC->CR |=  1 << 26 ; // Setting bit 26 enabling PPL2MUL

	//Step  8: Wait for PLL2MUL to lock RCC_CR bit PLL2RDY = 1
	while ((RCC->CR & RCC_CR_PLL2RDY) == 0) {}; // Wait PLL2RDY = 1

	//Step  9: Select PLL2MUL as PREDIV1SRC - RCC_CFGR2 bit PREDIV1SRC = 1
	RCC->CFGR2 |= 1 << 16; // Setting bit 16 selecting PLL2MUL

	//Step 10: Select RCC_CFGR2 PREDIV1[3:0] divide by 10 = 1001 (bits[3:0])
	RCC->CFGR2 |= 0x00000009; // Setting bits 1xx1
	RCC->CFGR2 &= 0xfffffff9; // Resetting bit x00x

	//Step 11: Select PREDIV1 as PLLSRC - RCC_CFGR bit PLLSRC = 1
	RCC->CFGR |= RCC_CFGR_PLLSRC;

	//Step 12: Disable RCC_CR bit PLLON = 0
	RCC->CR &= ~( 1 << 24 ); // Resetting bit 24 disabling PPLMUL

	//Step 13: Select RCC_CFGR PLLMUL[3:0] multiply by 9 = 0111	(bits[21:18])
	RCC->CFGR &= ~( 1 << 21 ); // Bit 21 = 0
	RCC->CFGR |= 1 << 20; 		// bit 20 = 1
	RCC->CFGR |= 1 << 19; 		// bit 19 = 1
	RCC->CFGR |= 1 << 18; 		// bit 18 = 1

	//Step 14: Enable RCC_CR bit PLLON = 1
	RCC->CR |=  1 << 24 ; // Setting bit 24 enabling PPLMUL

	//Step 15: Wait for PLLMUL to lock RCC_CR bit PLLRDY = 1
	while ((RCC->CR & RCC_CR_PLL1RDY) == 0) {}; // Wait PLL1RDY = 1

	//Step 16: USB Prescaler divide by 3 ( 72 Mhz * 2 / 3 )  = 48 MHz
	RCC->CFGR &= ~(1 << 22); //Resetting OTGFSPRE selects divide by 3

	//Step 17: Select AHB prescaler=1 - RCC_CFGR bits HPRE[3:0] = 0000 (bits[7:4])
	RCC->CFGR2 &= 0xffffff0f; // Resetting bit 0000

	//Step 18: Enable prefetch FLASH_ACR bit PRFTBE = 1
	FLASH->ACR |= 1 << 4;

	//Step 19: Setting FLASH wait states FLASH_ACR bits LATENCY[2:0] to 2 Wáit States(section 3.3)
	FLASH->ACR |= 0x00000002;
	FLASH->ACR &= 0xfffffffa;
	
	for(i=0;i < 100000;i++);

	//Step 20: RCC_CFGR bits PPRE1[2:0] = 100 -APB1 Prescaler divide by 2 = 36 MHz
	rcc_cfgr( 0x00000300, 0 ); //Set PPRE1[1:0] = 0
	rcc_cfgr( 0x00000400, 1 ); //Set PPRE1[2] = 1

	//Step 21: RCC_CFGR bits PPRE1[2:0] = 100 -APB1 Prescaler divide by 2 = 36 MHz
	rcc_cfgr( 1 << 14, 0 ); //Set ADCPRE[0] = 0
	rcc_cfgr( 1 << 15, 1 ); //Set ADCPRE[1] = 1
	
	//Step 22: Select PLLCLK in SW[1:0] as Clock Source
	RCC->CFGR |= RCC_CFGR_PLLON;

   //Step 23 - Disable HSI
	RCC->CR &= ~RCC_CR_HSION;
}
}