From c514f671c7700cf10bd890012de1e3cc7b06315d Mon Sep 17 00:00:00 2001 From: Adam Podogrocki Date: Thu, 24 Nov 2016 14:30:19 +0100 Subject: [PATCH] clock/stm32: add STM32F3X reset and clock control Change-Id: Ie5f3ffec0b3aaf15f9d9f8063d2bab6be5aebb6e Signed-off-by: Adam Podogrocki --- .../soc/st_stm32/stm32f3/flash_registers.h | 70 +++ arch/arm/soc/st_stm32/stm32f3/soc_registers.h | 1 + drivers/clock_control/Kconfig | 2 + drivers/clock_control/Kconfig.stm32f3x | 125 ++++++ drivers/clock_control/Makefile | 1 + drivers/clock_control/stm32f3x_clock.c | 408 ++++++++++++++++++ .../clock_control/stm32_clock_control.h | 3 + .../clock_control/stm32f3_clock_control.h | 124 ++++++ 8 files changed, 734 insertions(+) create mode 100644 arch/arm/soc/st_stm32/stm32f3/flash_registers.h create mode 100644 drivers/clock_control/Kconfig.stm32f3x create mode 100644 drivers/clock_control/stm32f3x_clock.c create mode 100644 include/drivers/clock_control/stm32f3_clock_control.h diff --git a/arch/arm/soc/st_stm32/stm32f3/flash_registers.h b/arch/arm/soc/st_stm32/stm32f3/flash_registers.h new file mode 100644 index 00000000000..e8d294381d3 --- /dev/null +++ b/arch/arm/soc/st_stm32/stm32f3/flash_registers.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2016 RnDity Sp. z o.o. + * + * 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. + */ + +#ifndef _STM32F3X_FLASH_REGISTERS_H_ +#define _STM32F3X_FLASH_REGISTERS_H_ + +#include + +/** + * @brief + * + * Based on reference manual: + * STM32F101xx, STM32F102xx, STM32F103xx, STM32F105xx and STM32F107xx + * advanced ARM ® -based 32-bit MCUs + * & + * STM32F334xx advanced ARM ® -based 32-bit MCUs + * + * Chapter 3.3.3: Embedded Flash Memory + */ + +enum { + STM32_FLASH_LATENCY_0 = 0x0, + STM32_FLASH_LATENCY_1 = 0x1, + STM32_FLASH_LATENCY_2 = 0x2, +}; + +/* 3.3.3 FLASH_ACR */ +union ef_acr { + uint32_t val; + struct { + uint32_t latency :3 __packed; + uint32_t hlfcya :1 __packed; + uint32_t prftbe :1 __packed; + uint32_t prftbs :1 __packed; + uint32_t rsvd__6_31 :26 __packed; + } bit; +}; + +/* 3.3.3 Embedded flash registers */ +struct stm32_flash { + union ef_acr acr; + uint32_t keyr; + uint32_t optkeyr; + uint32_t sr; + uint32_t cr; + uint32_t ar; + uint32_t rsvd; + uint32_t obr; + uint32_t wrpr; +}; + +/* list of device commands */ +enum stm32_embedded_flash_cmd { + STM32_FLASH_CMD_LATENCY_FOR_CLOCK_SET, +}; + +#endif /* _STM32F3X_FLASH_REGISTERS_H_ */ diff --git a/arch/arm/soc/st_stm32/stm32f3/soc_registers.h b/arch/arm/soc/st_stm32/stm32f3/soc_registers.h index f18acf949e1..3819ebf5c10 100644 --- a/arch/arm/soc/st_stm32/stm32f3/soc_registers.h +++ b/arch/arm/soc/st_stm32/stm32f3/soc_registers.h @@ -19,5 +19,6 @@ /* include register mapping headers */ #include "rcc_registers.h" +#include "flash_registers.h" #endif /* _STM32F3X_SOC_REGISTERS_H_ */ diff --git a/drivers/clock_control/Kconfig b/drivers/clock_control/Kconfig index 149ca05805f..bb06baa8f72 100644 --- a/drivers/clock_control/Kconfig +++ b/drivers/clock_control/Kconfig @@ -48,6 +48,8 @@ source "drivers/clock_control/Kconfig.stm32f10x" source "drivers/clock_control/Kconfig.stm32f107xx" +source "drivers/clock_control/Kconfig.stm32f3x" + source "drivers/clock_control/Kconfig.stm32f4x" source "drivers/clock_control/Kconfig.stm32l4x" diff --git a/drivers/clock_control/Kconfig.stm32f3x b/drivers/clock_control/Kconfig.stm32f3x new file mode 100644 index 00000000000..3ca11c66cfb --- /dev/null +++ b/drivers/clock_control/Kconfig.stm32f3x @@ -0,0 +1,125 @@ +# Kconfig - STM32F3 MCU clock control driver config +# +# Copyright (c) 2016 RnDity Sp. z o.o. +# +# 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. +# + +if SOC_SERIES_STM32F3X + +menuconfig CLOCK_CONTROL_STM32F3X + bool + prompt "STM32F3x Reset & Clock Control" + depends on CLOCK_CONTROL && SOC_SERIES_STM32F3X + default y if SOC_SERIES_STM32F3X + help + Enable driver for Reset & Clock Control subsystem found + in STM32F3 family of MCUs + +config CLOCK_CONTROL_STM32F3X_DEVICE_INIT_PRIORITY + int "Clock Control Device Priority" + default 1 + depends on CLOCK_CONTROL_STM32F3X + help + This option controls the priority of clock control + device initialization. Higher priority ensures that the device + is initialized earlier in the startup cycle. If unsure, leave + at default value 1 + +choice +prompt "STM32F3x System Clock Source" +depends on CLOCK_CONTROL_STM32F3X + +config CLOCK_STM32F3X_SYSCLK_SRC_HSI + bool "HSI" + help + Use HSI as source of SYSCLK + +config CLOCK_STM32F3X_SYSCLK_SRC_HSE + bool "HSE" + help + Use HSE as source of SYSCLK + +config CLOCK_STM32F3X_SYSCLK_SRC_PLL + bool "PLL" + help + Use PLL as source of SYSCLK + +endchoice + +choice +prompt "STM32F3x PLL Clock Source" +depends on CLOCK_CONTROL_STM32F3X && CLOCK_STM32F3X_SYSCLK_SRC_PLL + +config CLOCK_STM32F3X_PLL_SRC_HSI + bool "HSI" + help + Use HSI/2 as source of PLL + +config CLOCK_STM32F3X_PLL_SRC_HSE + bool "HSE" + help + Use HSE as source of PLL + +endchoice + +config CLOCK_STM32F3X_HSE_BYPASS + bool "HSE bypass" + depends on CLOCK_CONTROL_STM32F3X && (CLOCK_STM32F3X_PLL_SRC_HSE || CLOCK_STM32F3X_SYSCLK_SRC_HSE) + help + Enable this option to bypass external high-speed clock (HSE). + +config CLOCK_STM32F3X_PLL_PREDIV + int "PREDIV1 Prescler" + depends on CLOCK_CONTROL_STM32F3X && CLOCK_STM32F3X_PLL_SRC_HSE + default 0 + range 0 16 + help + PREDIV is PLLSCR clock signal prescaler, allowed values: 0 - 16. + +config CLOCK_STM32F3X_PLL_MULTIPLIER + int "PLL multiplier" + depends on CLOCK_CONTROL_STM32F3X && CLOCK_STM32F3X_SYSCLK_SRC_PLL + default 9 + range 2 16 + help + PLL multiplier, allowed values: 2-16. PLL output must not exceed 72MHz. + +config CLOCK_STM32F3X_AHB_PRESCALER + int "AHB prescaler" + depends on CLOCK_CONTROL_STM32F3X + default 0 + range 0 512 + help + AHB prescaler, allowed values: 0, 2, 4, 8, 16, 64, 128, + 256, 512. + +config CLOCK_STM32F3X_APB1_PRESCALER + int "APB1 prescaler" + depends on CLOCK_CONTROL_STM32F3X + default 0 + range 0 16 + help + APB1 Low speed clock (PCLK1) prescaler, allowed values: + 0, 2, 4, 8, 16. The APB1 clock must not exceed 36MHz. + +config CLOCK_STM32F3X_APB2_PRESCALER + int "APB2 prescaler" + depends on CLOCK_CONTROL_STM32F3X + default 0 + range 0 16 + help + APB2 High speed clock (PCLK2) prescaler, allowed values: + 0, 2, 4, 8, 16 + +endif diff --git a/drivers/clock_control/Makefile b/drivers/clock_control/Makefile index 5d7b93b4418..2abf05add8a 100644 --- a/drivers/clock_control/Makefile +++ b/drivers/clock_control/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_CLOCK_CONTROL_NRF5) += nrf5_power_clock.o obj-$(CONFIG_CLOCK_CONTROL_QUARK_SE) += quark_se_clock_control.o obj-$(CONFIG_CLOCK_CONTROL_STM32F10X) += stm32f10x_clock.o obj-$(CONFIG_CLOCK_CONTROL_STM32F10X_CONN_LINE) += stm32f107xx_clock.o +obj-$(CONFIG_CLOCK_CONTROL_STM32F3X) += stm32f3x_clock.o obj-$(CONFIG_CLOCK_CONTROL_STM32F4X) += stm32f4x_clock.o obj-$(CONFIG_CLOCK_CONTROL_STM32L4X) += stm32l4x_clock.o obj-$(CONFIG_CLOCK_CONTROL_BEETLE) += beetle_clock_control.o diff --git a/drivers/clock_control/stm32f3x_clock.c b/drivers/clock_control/stm32f3x_clock.c new file mode 100644 index 00000000000..8c21e850a3d --- /dev/null +++ b/drivers/clock_control/stm32f3x_clock.c @@ -0,0 +1,408 @@ +/* + * Copyright (c) 2016 RnDity Sp. z o.o. + * + * 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. + */ + +/** + * @brief Driver for Reset & Clock Control of STM32F3x family processor. + * + * Based on reference manual: + * STM32F303xB.C.D.E advanced ARM-based 32-bit MCU + * advanced ARM ® -based 32-bit MCUs + * + * Chapter 9: Reset and clock control (RCC) + * + * STM32F334xx advanced ARM ® -based 32-bit MCUs + * + * Chapter 8: Reset and clock control (RCC) + */ + +#include +#include +#include +#include +#include +#include + +struct stm32f3x_rcc_data { + uint8_t *base; +}; + +static int stm32f3x_clock_control_on(struct device *dev, + clock_control_subsys_t sub_system) +{ + struct stm32f3x_rcc_data *data = dev->driver_data; + + volatile struct stm32f3x_rcc *rcc = + (struct stm32f3x_rcc *)(data->base); + uint32_t subsys = POINTER_TO_UINT(sub_system); + + if (subsys > STM32F3X_CLOCK_AHB_BASE) { + subsys &= ~(STM32F3X_CLOCK_AHB_BASE); + rcc->ahbenr |= subsys; + } else if (subsys > STM32F3X_CLOCK_APB2_BASE) { + subsys &= ~(STM32F3X_CLOCK_APB2_BASE); + rcc->apb2enr |= subsys; + } else { + rcc->apb1enr |= subsys; + } + + return 0; +} + +static int stm32f3x_clock_control_off(struct device *dev, + clock_control_subsys_t sub_system) +{ + struct stm32f3x_rcc_data *data = dev->driver_data; + + volatile struct stm32f3x_rcc *rcc = + (struct stm32f3x_rcc *)(data->base); + uint32_t subsys = POINTER_TO_UINT(sub_system); + + if (subsys > STM32F3X_CLOCK_AHB_BASE) { + subsys &= ~(STM32F3X_CLOCK_AHB_BASE); + rcc->ahbenr &= ~subsys; + } else if (subsys > STM32F3X_CLOCK_APB2_BASE) { + subsys &= ~(STM32F3X_CLOCK_APB2_BASE); + rcc->apb2enr &= ~subsys; + } else { + rcc->apb1enr &= ~subsys; + } + + return 0; +} + +/** + * @brief helper for mapping a setting to register value + */ +struct regval_map { + int val; + int reg; +}; + +static int map_reg_val(const struct regval_map *map, + size_t cnt, int val, uint8_t normalize) +{ + for (int i = 0; i < cnt; i++) { + if (map[i].val == val) { + return (map[i].reg >> normalize); + } + } + + return 0; +} + +/** + * @brief map APB prescaler setting to register value + */ +static int apb_prescaler(int prescaler) +{ + if (prescaler == 0) { + return RCC_HCLK_DIV1; + } + + const struct regval_map map[] = { + {0, RCC_HCLK_DIV1}, + {2, RCC_HCLK_DIV2}, + {4, RCC_HCLK_DIV4}, + {8, RCC_HCLK_DIV8}, + {16, RCC_HCLK_DIV16}, + }; + + return map_reg_val(map, ARRAY_SIZE(map), + prescaler, RCC_CFGR_PPRE1_Pos); +} + +/** + * @brief map AHB prescaler setting to register value + */ +static int ahb_prescaler(int prescaler) +{ + if (prescaler == 0) { + return RCC_SYSCLK_DIV1; + } + + const struct regval_map map[] = { + {0, RCC_SYSCLK_DIV1}, + {2, RCC_SYSCLK_DIV2}, + {4, RCC_SYSCLK_DIV4}, + {8, RCC_SYSCLK_DIV8}, + {16, RCC_SYSCLK_DIV16}, + {64, RCC_SYSCLK_DIV64}, + {128, RCC_SYSCLK_DIV128}, + {256, RCC_SYSCLK_DIV256}, + {512, RCC_SYSCLK_DIV512}, + }; + + return map_reg_val(map, ARRAY_SIZE(map), + prescaler, RCC_CFGR_HPRE_Pos); +} + +/** + * @brief map PLL multiplier setting to register value + */ +static int pllmul(int mul) +{ + /* x2 -> 0x0 + * x3 -> 0x1 + * x4 -> 0x2 + * ... + * x15 -> 0xd + * x16 -> 0xe + * x16 -> 0xf + */ + return mul - 2; +} + +/** + * @brief select PREDIV division factor + */ +static int prediv_prescaler(int prescaler) +{ + if (prescaler == 0) { + return RCC_HSE_PREDIV_DIV1; + } + + const struct regval_map map[] = { + {0, RCC_HSE_PREDIV_DIV1}, + {2, RCC_HSE_PREDIV_DIV2}, + {3, RCC_HSE_PREDIV_DIV3}, + {4, RCC_HSE_PREDIV_DIV4}, + {5, RCC_HSE_PREDIV_DIV5}, + {6, RCC_HSE_PREDIV_DIV6}, + {7, RCC_HSE_PREDIV_DIV7}, + {8, RCC_HSE_PREDIV_DIV8}, + {9, RCC_HSE_PREDIV_DIV9}, + {10, RCC_HSE_PREDIV_DIV10}, + {11, RCC_HSE_PREDIV_DIV11}, + {12, RCC_HSE_PREDIV_DIV12}, + {13, RCC_HSE_PREDIV_DIV13}, + {14, RCC_HSE_PREDIV_DIV14}, + {15, RCC_HSE_PREDIV_DIV15}, + {16, RCC_HSE_PREDIV_DIV16}, + }; + + return map_reg_val(map, ARRAY_SIZE(map), prescaler, 0); +} + +/** + * @brief select System Clock Source + */ +static int system_clock(int source) +{ + __ASSERT_NO_MSG(IS_RCC_SYSCLKSOURCE(source)); + return (source >> RCC_CFGR_SW_Pos); +} + +/** + * @brief select PLL Clock Source + */ +static int pll_source(int source) +{ + __ASSERT_NO_MSG(IS_RCC_PLLSOURCE(source)); + return (source >> RCC_CFGR_PLLSRC_Pos); +} + +static uint32_t get_ahb_clock(uint32_t sysclk) +{ + /* AHB clock is generated based on SYSCLK */ + uint32_t sysclk_div = CONFIG_CLOCK_STM32F3X_AHB_PRESCALER; + + if (sysclk_div == 0) { + sysclk_div = 1; + } + + return sysclk / sysclk_div; +} + +static uint32_t get_apb_clock(uint32_t ahb_clock, uint32_t prescaler) +{ + if (prescaler == 0) { + prescaler = 1; + } + + return ahb_clock / prescaler; +} + +static +int stm32f3x_clock_control_get_subsys_rate(struct device *clock, + clock_control_subsys_t sub_system, + uint32_t *rate) +{ + ARG_UNUSED(clock); + + uint32_t subsys = POINTER_TO_UINT(sub_system); + uint32_t prescaler = CONFIG_CLOCK_STM32F3X_APB1_PRESCALER; + /* assumes SYSCLK is SYS_CLOCK_HW_CYCLES_PER_SEC */ + uint32_t ahb_clock = + get_ahb_clock(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC); + + if (subsys > STM32F3X_CLOCK_AHB_BASE) { + prescaler = CONFIG_CLOCK_STM32F3X_AHB_PRESCALER; + } else if (subsys > STM32F3X_CLOCK_APB2_BASE) { + prescaler = CONFIG_CLOCK_STM32F3X_APB2_PRESCALER; + } + + *rate = get_apb_clock(ahb_clock, prescaler); + + return 0; +} + +static const struct clock_control_driver_api stm32f3x_clock_control_api = { + .on = stm32f3x_clock_control_on, + .off = stm32f3x_clock_control_off, + .get_rate = stm32f3x_clock_control_get_subsys_rate, +}; + +/** + * @brief setup embedded flash controller + * + * Configure flash access time latency depending on SYSCLK. + */ +static void setup_flash(void) +{ + volatile struct stm32_flash *flash = + (struct stm32_flash *)(FLASH_R_BASE); + + if (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC <= 24000000) { + flash->acr.bit.latency = STM32_FLASH_LATENCY_0; + } else if (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC <= 48000000) { + flash->acr.bit.latency = STM32_FLASH_LATENCY_1; + } else if (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC <= 72000000) { + flash->acr.bit.latency = STM32_FLASH_LATENCY_2; + } +} + +static int stm32f3x_clock_control_init(struct device *dev) +{ + struct stm32f3x_rcc_data *data = dev->driver_data; + volatile struct stm32f3x_rcc *rcc = + (struct stm32f3x_rcc *)(data->base); + /* SYSCLK source defaults to HSI */ + int sysclk_src = system_clock(RCC_SYSCLKSOURCE_HSI); + uint32_t hpre = ahb_prescaler(CONFIG_CLOCK_STM32F3X_AHB_PRESCALER); + uint32_t ppre1 = apb_prescaler(CONFIG_CLOCK_STM32F3X_APB1_PRESCALER); + uint32_t ppre2 = apb_prescaler(CONFIG_CLOCK_STM32F3X_APB2_PRESCALER); +#ifdef CONFIG_CLOCK_STM32F3X_PLL_MULTIPLIER + uint32_t pll_mul = pllmul(CONFIG_CLOCK_STM32F3X_PLL_MULTIPLIER); +#endif /* CONFIG_CLOCK_STM32F3X_PLL_MULTIPLIER */ +#ifdef CONFIG_CLOCK_STM32F3X_PLL_PREDIV + uint32_t prediv = + prediv_prescaler(CONFIG_CLOCK_STM32F3X_PLL_PREDIV); +#endif /* CONFIG_CLOCK_STM32F3X_PLL_PREDIV */ + + /* disable PLL */ + rcc->cr.bit.pllon = 0; + /* disable HSE */ + rcc->cr.bit.hseon = 0; + +#ifdef CONFIG_CLOCK_STM32F3X_HSE_BYPASS + /* HSE is disabled, HSE bypass can be enabled*/ + rcc->cr.bit.hsebyp = 1; +#endif + +#ifdef CONFIG_CLOCK_STM32F3X_PLL_SRC_HSI + /* enable HSI clock */ + rcc->cr.bit.hsion = 1; + /* this should end after one test */ + while (rcc->cr.bit.hsirdy != 1) { + } + + /* HSI clock divided by 2 selected as PLL entry clock source. */ + rcc->cfgr.bit.pllsrc = pll_source(RCC_PLLSOURCE_HSI); +#endif /* CONFIG_CLOCK_STM32F3X_PLL_SRC_HSI */ + +#ifdef CONFIG_CLOCK_STM32F3X_PLL_SRC_HSE + + /* wait for to become ready */ + rcc->cr.bit.hseon = 1; + while (rcc->cr.bit.hserdy != 1) { + } + +#ifdef CONFIG_CLOCK_STM32F3X_PLL_PREDIV + rcc->cfgr2.bit.prediv = prediv; +#endif /* CONFIG_CLOCK_STM32F3X_PLL_PREDIV */ + /* HSE clock selected as PLL entry clock source. */ + rcc->cfgr.bit.pllsrc = pll_source(RCC_PLLSOURCE_HSE); +#endif /* CONFIG_CLOCK_STM32F3X_PLL_SRC_HSE */ + + /* setup AHB prescaler */ + rcc->cfgr.bit.hpre = hpre; + + /* setup APB1, must not exceed 36MHz */ + rcc->cfgr.bit.ppre1 = ppre1; + + /* setup APB2 */ + rcc->cfgr.bit.ppre2 = ppre2; + +#ifdef CONFIG_CLOCK_STM32F3X_SYSCLK_SRC_HSI + /* enable HSI clock */ + rcc->cr.bit.hsion = 1; + /* this should end after one test */ + while (rcc->cr.bit.hsirdy != 1) { + } + sysclk_src = system_clock(RCC_SYSCLKSOURCE_HSI); +#elif defined(CONFIG_CLOCK_STM32F3X_SYSCLK_SRC_PLL) + /* setup PLL multiplication (PLL must be disabled) */ + rcc->cfgr.bit.pllmul = pll_mul; + + /* enable PLL */ + rcc->cr.bit.pllon = 1; + + /* wait for PLL to become ready */ + while (rcc->cr.bit.pllrdy != 1) { + } + + sysclk_src = system_clock(RCC_SYSCLKSOURCE_PLLCLK); +#elif defined(CONFIG_CLOCK_STM32F3X_SYSCLK_SRC_HSE) + /* wait for to become ready */ + rcc->cr.bit.hseon = 1; + while (rcc->cr.bit.hserdy != 1) { + } + + sysclk_src = system_clock(RCC_SYSCLKSOURCE_HSE); +#endif + + /* configure flash access latency before SYSCLK source + * switch + */ + setup_flash(); + + /* set SYSCLK clock value */ + rcc->cfgr.bit.sw = sysclk_src; + + /* wait for SYSCLK to switch the source */ + while (rcc->cfgr.bit.sws != sysclk_src) { + } + + dev->driver_api = &stm32f3x_clock_control_api; + + return 0; +} + +static struct stm32f3x_rcc_data stm32f3x_rcc_data = { + .base = (uint8_t *)RCC_BASE, +}; + +/* FIXME: move prescaler/multiplier defines into device config */ + +/** + * @brief RCC device, note that priority is intentionally set to 1 so + * that the device init runs just after SOC init + */ +DEVICE_INIT(rcc_stm32f3x, STM32_CLOCK_CONTROL_NAME, + &stm32f3x_clock_control_init, + &stm32f3x_rcc_data, NULL, + PRE_KERNEL_1, + CONFIG_CLOCK_CONTROL_STM32F3X_DEVICE_INIT_PRIORITY); diff --git a/include/drivers/clock_control/stm32_clock_control.h b/include/drivers/clock_control/stm32_clock_control.h index 910f16128e8..45db18d0b84 100644 --- a/include/drivers/clock_control/stm32_clock_control.h +++ b/include/drivers/clock_control/stm32_clock_control.h @@ -1,6 +1,7 @@ /* * Copyright (c) 2016 Open-RnD Sp. z o.o. * Copyright (c) 2016 BayLibre, SAS + * Copyright (c) 2016 RnDity Sp. z o.o. * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,6 +15,8 @@ #ifdef CONFIG_SOC_SERIES_STM32F1X #include "stm32f1_clock_control.h" +#elif CONFIG_SOC_SERIES_STM32F3X +#include "stm32f3_clock_control.h" #elif CONFIG_SOC_SERIES_STM32F4X #include "stm32f4_clock_control.h" #elif CONFIG_SOC_SERIES_STM32L4X diff --git a/include/drivers/clock_control/stm32f3_clock_control.h b/include/drivers/clock_control/stm32f3_clock_control.h new file mode 100644 index 00000000000..31f7eaf9988 --- /dev/null +++ b/include/drivers/clock_control/stm32f3_clock_control.h @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2016 RnDity Sp. z o.o. + * + * 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. + */ +#ifndef _STM32F3_CLOCK_CONTROL_H_ +#define _STM32F3_CLOCK_CONTROL_H_ + +/** + * @file + * + * @brief Clock subsystem IDs for STM32F3 family + */ + +/* APB1 */ +#define STM32F3X_CLOCK_SUBSYS_TIM2 (1 << 0) +#define STM32F3X_CLOCK_SUBSYS_TIM3 (1 << 1) +#ifndef CONFIG_SOC_STM32F334X8 +#define STM32F3X_CLOCK_SUBSYS_TIM4 (1 << 2) +#endif +#ifdef CONFIG_SOC_STM32F373XC +#define STM32F3X_CLOCK_SUBSYS_TIM5 (1 << 3) +#endif +#define STM32F3X_CLOCK_SUBSYS_TIM6 (1 << 4) +#define STM32F3X_CLOCK_SUBSYS_TIM7 (1 << 5) +#ifdef CONFIG_SOC_STM32F373XC +#define STM32F3X_CLOCK_SUBSYS_TIM12 (1 << 6) +#define STM32F3X_CLOCK_SUBSYS_TIM13 (1 << 7) +#define STM32F3X_CLOCK_SUBSYS_TIM14 (1 << 8) +#define STM32F3X_CLOCK_SUBSYS_TIM18 (1 << 9) +#endif +#define STM32F3X_CLOCK_SUBSYS_WWDG (1 << 11) +#ifndef CONFIG_SOC_STM32F334X8 +#define STM32F3X_CLOCK_SUBSYS_SPI2 (1 << 14) +#define STM32F3X_CLOCK_SUBSYS_SPI3 (1 << 15) +#endif +#define STM32F3X_CLOCK_SUBSYS_USART2 (1 << 17) +#define STM32F3X_CLOCK_SUBSYS_USART3 (1 << 18) +#ifndef CONFIG_SOC_STM32F334X8 +#define STM32F3X_CLOCK_SUBSYS_UART4 (1 << 19) +#define STM32F3X_CLOCK_SUBSYS_UART5 (1 << 20) +#endif +#define STM32F3X_CLOCK_SUBSYS_I2C1 (1 << 21) +#ifndef CONFIG_SOC_STM32F334X8 +#define STM32F3X_CLOCK_SUBSYS_I2C2 (1 << 22) +#define STM32F3X_CLOCK_SUBSYS_USB (1 << 23) +#endif +#define STM32F3X_CLOCK_SUBSYS_CAN (1 << 25) +#define STM32F3X_CLOCK_SUBSYS_DAC2 (1 << 26) +#define STM32F3X_CLOCK_SUBSYS_PWR (1 << 28) +#define STM32F3X_CLOCK_SUBSYS_DAC1 (1 << 29) + +#define STM32F3X_CLOCK_APB2_BASE (1 << 30) + +/* APB2 */ +#define STM32F3X_CLOCK_SUBSYS_SYSCFG (STM32F3X_CLOCK_APB2_BASE | 1 << 0) +#ifndef CONFIG_SOC_STM32F373XC +#define STM32F3X_CLOCK_SUBSYS_TIM1 (STM32F3X_CLOCK_APB2_BASE | 1 << 11) +#endif +#define STM32F3X_CLOCK_SUBSYS_SPI1 (STM32F3X_CLOCK_APB2_BASE | 1 << 12) +#ifdef CONFIG_SOC_STM32F303XC +#define STM32F3X_CLOCK_SUBSYS_TIM8 (STM32F3X_CLOCK_APB2_BASE | 1 << 13) +#endif +#define STM32F3X_CLOCK_SUBSYS_USART1 (STM32F3X_CLOCK_APB2_BASE | 1 << 14) +#ifndef CONFIG_SOC_STM32F334X8 +#define STM32F3X_CLOCK_SUBSYS_SPI4 (STM32F3X_CLOCK_APB2_BASE | 1 << 15) +#endif +#define STM32F3X_CLOCK_SUBSYS_TIM15 (STM32F3X_CLOCK_APB2_BASE | 1 << 16) +#define STM32F3X_CLOCK_SUBSYS_TIM16 (STM32F3X_CLOCK_APB2_BASE | 1 << 17) +#define STM32F3X_CLOCK_SUBSYS_TIM17 (STM32F3X_CLOCK_APB2_BASE | 1 << 18) +#ifndef CONFIG_SOC_STM32F334X8 +#define STM32F3X_CLOCK_SUBSYS_TIM19 (STM32F3X_CLOCK_APB2_BASE | 1 << 19) +#endif +#ifdef CONFIG_SOC_STM32F303XC +#define STM32F3X_CLOCK_SUBSYS_TIM20 (STM32F3X_CLOCK_APB2_BASE | 1 << 20) +#endif +#ifdef CONFIG_SOC_STM32F334X8 +#define STM32F3X_CLOCK_SUBSYS_HRTIMER1 (STM32F3X_CLOCK_APB2_BASE | 1 << 29) +#endif +#define STM32F3X_CLOCK_AHB_BASE (1 << 31) + +/* AHB */ +#define STM32F3X_CLOCK_SUBSYS_DMA1 (STM32F3X_CLOCK_AHB_BASE | 1 << 0) + +#ifndef CONFIG_SOC_STM32F334X8 +#define STM32F3X_CLOCK_SUBSYS_DMA2 (STM32F3X_CLOCK_AHB_BASE | 1 << 1) +#endif +#define STM32F3X_CLOCK_SUBSYS_SRAM (STM32F3X_CLOCK_AHB_BASE | 1 << 2) +#define STM32F3X_CLOCK_SUBSYS_FLITF (STM32F3X_CLOCK_AHB_BASE | 1 << 4) +#ifndef CONFIG_SOC_STM32F334X8 +#define STM32F3X_CLOCK_SUBSYS_FMC (STM32F3X_CLOCK_AHB_BASE | 1 << 5) +#endif +#define STM32F3X_CLOCK_SUBSYS_CRC (STM32F3X_CLOCK_AHB_BASE | 1 << 6) +#ifndef CONFIG_SOC_STM32F334X8 +#define STM32F3X_CLOCK_SUBSYS_IOPH (STM32F3X_CLOCK_AHB_BASE | 1 << 16) +#endif +#define STM32F3X_CLOCK_SUBSYS_IOPA (STM32F3X_CLOCK_AHB_BASE | 1 << 17) +#define STM32F3X_CLOCK_SUBSYS_IOPB (STM32F3X_CLOCK_AHB_BASE | 1 << 18) +#define STM32F3X_CLOCK_SUBSYS_IOPC (STM32F3X_CLOCK_AHB_BASE | 1 << 19) +#define STM32F3X_CLOCK_SUBSYS_IOPD (STM32F3X_CLOCK_AHB_BASE | 1 << 20) +#ifndef CONFIG_SOC_STM32F334X8 +#define STM32F3X_CLOCK_SUBSYS_IOPE (STM32F3X_CLOCK_AHB_BASE | 1 << 21) +#endif +#define STM32F3X_CLOCK_SUBSYS_IOPF (STM32F3X_CLOCK_AHB_BASE | 1 << 22) +#ifndef CONFIG_SOC_STM32F334X8 +#define STM32F3X_CLOCK_SUBSYS_IOPG (STM32F3X_CLOCK_AHB_BASE | 1 << 23) +#endif +#define STM32F3X_CLOCK_SUBSYS_TSC (STM32F3X_CLOCK_AHB_BASE | 1 << 24) +#define STM32F3X_CLOCK_SUBSYS_ADC12 (STM32F3X_CLOCK_AHB_BASE | 1 << 28) +#ifndef CONFIG_SOC_STM32F334X8 +#define STM32F3X_CLOCK_SUBSYS_ADC34 (STM32F3X_CLOCK_AHB_BASE | 1 << 29) +#endif + +#endif /* _STM32F3_CLOCK_CONTROL_H_ */