mbed library sources. Supersedes mbed-src.
Dependents: Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more
targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/TARGET_NUCLEO_F767ZI/system_clock.c
- Committer:
- AnnaBridge
- Date:
- 2019-02-20
- Revision:
- 189:f392fc9709a3
- Parent:
- 187:0387e8f68319
File content as of revision 189:f392fc9709a3:
/* mbed Microcontroller Library * Copyright (c) 2006-2017 ARM Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * This file configures the system clock as follows: *-------------------------------------------------------------------- * System clock source | 1- USE_PLL_HSE_EXTC (external 8 MHz clock) * | 2- USE_PLL_HSE_XTAL (external 8 MHz xtal) * | 3- USE_PLL_HSI (internal 16 MHz clock) *-------------------------------------------------------------------- * SYSCLK(MHz) | 216 * AHBCLK (MHz) | 216 * APB1CLK (MHz) | 54 * APB2CLK (MHz) | 108 * USB capable (48 MHz) | YES *-------------------------------------------------------------------- **/ #include "stm32f7xx.h" #include "nvic_addr.h" #include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ /* #define VECT_TAB_SRAM */ #define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field. This value must be a multiple of 0x200. */ // clock source is selected with CLOCK_SOURCE in json config #define USE_PLL_HSE_EXTC 0x8 // Use external clock (ST Link MCO) #define USE_PLL_HSE_XTAL 0x4 // Use external xtal (X3 on board - not provided by default) #define USE_PLL_HSI 0x2 // Use HSI internal clock #if ( ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) ) uint8_t SetSysClock_PLL_HSE(uint8_t bypass); #endif /* ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) */ #if ((CLOCK_SOURCE) & USE_PLL_HSI) uint8_t SetSysClock_PLL_HSI(void); #endif /* ((CLOCK_SOURCE) & USE_PLL_HSI) */ /** * @brief Setup the microcontroller system * Initialize the Embedded Flash Interface, the PLL and update the * SystemFrequency variable. * @param None * @retval None */ void SystemInit(void) { /* FPU settings ------------------------------------------------------------*/ #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) SCB->CPACR |= ((3UL << 10 * 2) | (3UL << 11 * 2)); /* set CP10 and CP11 Full Access */ #endif /* Reset the RCC clock configuration to the default reset state ------------*/ /* Set HSION bit */ RCC->CR |= (uint32_t)0x00000001; /* Reset CFGR register */ RCC->CFGR = 0x00000000; /* Reset HSEON, CSSON and PLLON bits */ RCC->CR &= (uint32_t)0xFEF6FFFF; /* Reset PLLCFGR register */ RCC->PLLCFGR = 0x24003010; /* Reset HSEBYP bit */ RCC->CR &= (uint32_t)0xFFFBFFFF; /* Disable all interrupts */ RCC->CIR = 0x00000000; #if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM) SystemInit_ExtMemCtl(); #endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */ /* Configure the Vector Table location add offset address ------------------*/ #ifdef VECT_TAB_SRAM SCB->VTOR = RAMDTCM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ #else SCB->VTOR = NVIC_FLASH_VECTOR_ADDRESS; /* Vector Table Relocation in Internal FLASH */ #endif } /** * @brief Configures the System clock source, PLL Multiplier and Divider factors, * AHB/APBx prescalers and Flash settings * @note This function should be called only once the RCC clock configuration * is reset to the default reset state (done in SystemInit() function). * @param None * @retval None */ void SetSysClock(void) { #if ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) /* 1- Try to start with HSE and external clock */ if (SetSysClock_PLL_HSE(1) == 0) #endif { #if ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) /* 2- If fail try to start with HSE and external xtal */ if (SetSysClock_PLL_HSE(0) == 0) #endif { #if ((CLOCK_SOURCE) & USE_PLL_HSI) /* 3- If fail start with HSI clock */ if (SetSysClock_PLL_HSI() == 0) #endif { { error("SetSysClock failed\n"); } } } } // Output clock on MCO2 pin(PC9) for debugging purpose // Can be visualized on CN8 connector pin 4 //HAL_RCC_MCOConfig(RCC_MCO2, RCC_MCO2SOURCE_SYSCLK, RCC_MCODIV_4); // 216 MHz / 4 = 54 MHz } #if ( ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) ) /******************************************************************************/ /* PLL (clocked by HSE) used as System clock source */ /******************************************************************************/ uint8_t SetSysClock_PLL_HSE(uint8_t bypass) { RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_OscInitTypeDef RCC_OscInitStruct; RCC_PeriphCLKInitTypeDef RCC_PeriphClkInitStruct; // Enable power clock __PWR_CLK_ENABLE(); __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); // Enable HSE oscillator and activate PLL with HSE as source RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; if (bypass == 0) { RCC_OscInitStruct.HSEState = RCC_HSE_ON; /* External xtal on OSC_IN/OSC_OUT */ } else { RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; /* External clock on OSC_IN */ } // Warning: this configuration is for a 8 MHz xtal clock only RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = 4; // VCO input clock = 2 MHz (8 MHz / 4) RCC_OscInitStruct.PLL.PLLN = 216; // VCO output clock = 432 MHz (2 MHz * 216) RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; // PLLCLK = 216 MHz (432 MHz / 2) RCC_OscInitStruct.PLL.PLLQ = 9; // USB clock = 48 MHz (432 MHz / 9) --> OK for USB RCC_OscInitStruct.PLL.PLLR = 2; // I2S clock if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { return 0; // FAIL } // Activate the OverDrive to reach the 216 MHz Frequency if (HAL_PWREx_EnableOverDrive() != HAL_OK) { return 0; // FAIL } // Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; // 216 MHz RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; // 216 MHz RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; // 54 MHz RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; // 108 MHz if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7) != HAL_OK) { return 0; // FAIL } RCC_PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_CLK48; RCC_PeriphClkInitStruct.Clk48ClockSelection = RCC_CLK48SOURCE_PLL; if (HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInitStruct) != HAL_OK) { return 0; // FAIL } return 1; // OK } #endif /* ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) */ #if ((CLOCK_SOURCE) & USE_PLL_HSI) /******************************************************************************/ /* PLL (clocked by HSI) used as System clock source */ /******************************************************************************/ uint8_t SetSysClock_PLL_HSI(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_OscInitTypeDef RCC_OscInitStruct; RCC_PeriphCLKInitTypeDef RCC_PeriphClkInitStruct; // Enable power clock __PWR_CLK_ENABLE(); // Enable HSI oscillator and activate PLL with HSI as source RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSEState = RCC_HSE_OFF; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; RCC_OscInitStruct.PLL.PLLM = 8; // VCO input clock = 2 MHz (16 MHz / 8) RCC_OscInitStruct.PLL.PLLN = 216; // VCO output clock = 432 MHz (2 MHz * 216) RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; // PLLCLK = 216 MHz (432 MHz / 2) RCC_OscInitStruct.PLL.PLLQ = 9; RCC_OscInitStruct.PLL.PLLR = 2; // I2S clock if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { return 0; // FAIL } // Activate the OverDrive to reach the 216 MHz Frequency if (HAL_PWREx_EnableOverDrive() != HAL_OK) { return 0; // FAIL } // Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; // 216 MHz RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; // 216 MHz RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; // 54 MHz RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; // 108 MHz if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7) != HAL_OK) { return 0; // FAIL } RCC_PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_CLK48; RCC_PeriphClkInitStruct.Clk48ClockSelection = RCC_CLK48SOURCE_PLL; if (HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInitStruct) != HAL_OK) { return 0; // FAIL } return 1; // OK } #endif /* ((CLOCK_SOURCE) & USE_PLL_HSI) */