diff --git a/arch/arm/soc/st_stm32/stm32f1/rcc_registers.h b/arch/arm/soc/st_stm32/stm32f1/rcc_registers.h new file mode 100644 index 00000000000..cf5702c5e5a --- /dev/null +++ b/arch/arm/soc/st_stm32/stm32f1/rcc_registers.h @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2016 Open-RnD 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 _STM32F10X_CLOCK_H_ +#define _STM32F10X_CLOCK_H_ + +/** + * @brief Driver for Reset & Clock Control of STM32F10x family processor. + * + * Based on reference manual: + * STM32F101xx, STM32F102xx, STM32F103xx, STM32F105xx and STM32F107xx + * advanced ARM ® -based 32-bit MCUs + * + * Chapter 7: Low-, medium-, high- and XL-density reset and + * clock control + */ + +/* 8.3.1 Clock control register (RCC_CR) */ +enum { + STM32F10X_RCC_CFG_PLL_SRC_HSI = 0x0, + STM32F10X_RCC_CFG_PLL_SRC_PREDIV1 = 0x1, +}; + +enum { + STM32F10X_RCC_CFG_SYSCLK_SRC_HSI = 0x0, + STM32F10X_RCC_CFG_SYSCLK_SRC_HSE = 0x1, + STM32F10X_RCC_CFG_SYSCLK_SRC_PLL = 0x2, +}; + +enum { + STM32F10X_RCC_CFG_HCLK_DIV_0 = 0x0, + STM32F10X_RCC_CFG_HCLK_DIV_2 = 0x4, + STM32F10X_RCC_CFG_HCLK_DIV_4 = 0x5, + STM32F10X_RCC_CFG_HCLK_DIV_8 = 0x6, + STM32F10X_RCC_CFG_HCLK_DIV_16 = 0x7, +}; + +enum { + STM32F10X_RCC_CFG_SYSCLK_DIV_0 = 0x0, + STM32F10X_RCC_CFG_SYSCLK_DIV_2 = 0x8, + STM32F10X_RCC_CFG_SYSCLK_DIV_4 = 0x9, + STM32F10X_RCC_CFG_SYSCLK_DIV_8 = 0xa, + STM32F10X_RCC_CFG_SYSCLK_DIV_16 = 0xb, + STM32F10X_RCC_CFG_SYSCLK_DIV_64 = 0xc, + STM32F10X_RCC_CFG_SYSCLK_DIV_128 = 0xd, + STM32F10X_RCC_CFG_SYSCLK_DIV_256 = 0xe, + STM32F10X_RCC_CFG_SYSCLK_DIV_512 = 0xf, +}; + +/** + * @brief Reset and Clock Control + */ + +union __rcc_cr { + uint32_t val; + struct { + uint32_t hsion :1 __packed; + uint32_t hsirdy :1 __packed; + uint32_t rsvd__2 :1 __packed; + uint32_t hsitrim :5 __packed; + uint32_t hsical :8 __packed; + uint32_t hseon :1 __packed; + uint32_t hserdy :1 __packed; + uint32_t hsebyp :1 __packed; + uint32_t csson :1 __packed; + uint32_t rsvd__20_23 :4 __packed; + uint32_t pllon :1 __packed; + uint32_t pllrdy :1 __packed; + uint32_t rsvd__26_31 :6 __packed; + } bit; +}; + +union __rcc_cfgr { + uint32_t val; + struct { + uint32_t sw :2 __packed; + uint32_t sws :2 __packed; + uint32_t hpre :4 __packed; + uint32_t ppre1 :3 __packed; + uint32_t ppre2 :3 __packed; + uint32_t adcpre :2 __packed; + uint32_t pllsrc :1 __packed; + uint32_t pllxtpre :1 __packed; + uint32_t pllmul :4 __packed; + uint32_t usbpre :1 __packed; + uint32_t rsvd__23 :1 __packed; + uint32_t mco :3 __packed; + uint32_t rsvd__27_31 :5 __packed; + } bit; +}; + +struct stm32f10x_rcc { + union __rcc_cr cr; + union __rcc_cfgr cfgr; + uint32_t cir; + uint32_t apb2rstr; + uint32_t apb1rstr; + uint32_t ahbenr; + uint32_t apb2enr; + uint32_t apb1enr; + uint32_t bdcr; + uint32_t csr; +}; + +#endif /* _STM32F10X_CLOCK_H_ */ diff --git a/arch/arm/soc/st_stm32/stm32f1/soc_registers.h b/arch/arm/soc/st_stm32/stm32f1/soc_registers.h index 6327572c6a2..4f76a08d1f9 100644 --- a/arch/arm/soc/st_stm32/stm32f1/soc_registers.h +++ b/arch/arm/soc/st_stm32/stm32f1/soc_registers.h @@ -18,5 +18,6 @@ #define _STM32F10X_SOC_REGISTERS_H_ /* include register mapping headers */ +#include "rcc_registers.h" #endif /* _STM32F10X_SOC_REGISTERS_H_ */ diff --git a/drivers/clock_control/Kconfig b/drivers/clock_control/Kconfig index 4cd45965601..a0f62ad1ab5 100644 --- a/drivers/clock_control/Kconfig +++ b/drivers/clock_control/Kconfig @@ -39,4 +39,6 @@ config CLOCK_CONTROL_DEBUG source "drivers/clock_control/Kconfig.quark_se" +source "drivers/clock_control/Kconfig.stm32f10x" + endif # CLOCK_CONTROL diff --git a/drivers/clock_control/Kconfig.stm32f10x b/drivers/clock_control/Kconfig.stm32f10x new file mode 100644 index 00000000000..643ada8eab8 --- /dev/null +++ b/drivers/clock_control/Kconfig.stm32f10x @@ -0,0 +1,112 @@ +# Kconfig - STM32F1 MCU clock control driver config +# +# Copyright (c) 2016 Open-RnD 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_STM32F1X + +config CLOCK_CONTROL_STM32F10X + bool + prompt "STM32F10x Reset & Clock Control" + depends on CLOCK_CONTROL && SOC_STM32F1X + default y if SOC_STM32F1X + help + Enable driver for Reset & Clock Control subsystem found + in STM32F1 family of MCUs + +config CLOCK_CONTROL_STM32F10X_DEVICE_PRIORITY + int "Clock Control Device Priority" + default 1 + depends on CLOCK_CONTROL_STM32F10X + 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 "STM32F10x System Clock Source" +depends on CLOCK_CONTROL_STM32F10X + +config CLOCK_STM32F10X_SYSCLK_SRC_HSI + bool "HSI" + help + Use HSI as source of SYSCLK + +config CLOCK_STM32F10X_SYSCLK_SRC_HSE + bool "HSE" + help + Use HSE as source of SYSCLK + +config CLOCK_STM32F10X_SYSCLK_SRC_PLL + bool "PLL" + help + Use PLL as source of SYSCLK + +endchoice + +choice +prompt "STM32F10x PLL Clock Source" +depends on CLOCK_CONTROL_STM32F10X + +config CLOCK_STM32F10X_PLL_SRC_HSI + bool "HSI" + help + Use HSI as source of PLL + +config CLOCK_STM32F10X_PLL_SRC_PREDIV1 + bool "PREDIV1" + help + Use PREDIV1 as source of PLL + +endchoice + +config CLOCK_STM32F10X_PLL_MULTIPLIER + int "PLL multiplier" + depends on CLOCK_CONTROL_STM32F10X + default 9 + range 2 16 + help + PLL multiplier, allowed values: 2-16 + +config CLOCK_STM32F10X_AHB_PRESCALER + int "AHB prescaler" + depends on CLOCK_CONTROL_STM32F10X + default 0 + range 0 512 + help + AHB prescaler, allowed values: 0, 2, 4, 8, 16, 64, 128, + 256, 512. + +config CLOCK_STM32F10X_APB1_PRESCALER + int "APB1 prescaler" + depends on CLOCK_CONTROL_STM32F10X + default 0 + range 0 16 + help + APB1 Low speed clock (PCLK1) prescaler, allowed values: + 0, 2, 4, 8, 16 + +config CLOCK_STM32F10X_APB2_PRESCALER + int "APB2 prescaler" + depends on CLOCK_CONTROL_STM32F10X + 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 293cb817919..1cdf87cc0cf 100644 --- a/drivers/clock_control/Makefile +++ b/drivers/clock_control/Makefile @@ -1 +1,2 @@ obj-$(CONFIG_CLOCK_CONTROL_QUARK_SE) += quark_se_clock_control.o +obj-$(CONFIG_CLOCK_CONTROL_STM32F10X) += stm32f10x_clock.o diff --git a/drivers/clock_control/stm32f10x_clock.c b/drivers/clock_control/stm32f10x_clock.c new file mode 100644 index 00000000000..ecd64de09a8 --- /dev/null +++ b/drivers/clock_control/stm32f10x_clock.c @@ -0,0 +1,276 @@ +/* + * Copyright (c) 2016 Open-RnD 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 STM32F10x family processor. + * + * Based on reference manual: + * STM32F101xx, STM32F102xx, STM32F103xx, STM32F105xx and STM32F107xx + * advanced ARM ® -based 32-bit MCUs + * + * Chapter 7: Low-, medium-, high- and XL-density reset and + * clock control + */ + +#include +#include +#include +#include +#include + +struct stm32f10x_rcc_data { + uint8_t *base; +}; + +static inline int stm32f10x_clock_control_on(struct device *dev, + clock_control_subsys_t sub_system) +{ + struct stm32f10x_rcc_data *data = dev->driver_data; + + volatile struct stm32f10x_rcc *rcc = (struct stm32f10x_rcc *)(data->base); + + uint32_t subsys = POINTER_TO_UINT(sub_system); + + if (subsys > STM32F10X_CLOCK_APB2_BASE) { + subsys &= ~(STM32F10X_CLOCK_APB2_BASE); + rcc->apb2enr |= subsys; + } else { + rcc->apb1enr |= subsys; + } + return DEV_OK; +} + +static inline int stm32f10x_clock_control_off(struct device *dev, + clock_control_subsys_t sub_system) +{ + struct stm32f10x_rcc_data *data = dev->driver_data; + volatile struct stm32f10x_rcc *rcc = + (struct stm32f10x_rcc *)(data->base); + uint32_t subsys = POINTER_TO_UINT(sub_system); + + if (subsys > STM32F10X_CLOCK_APB2_BASE) { + subsys &= ~(STM32F10X_CLOCK_APB2_BASE); + rcc->apb2enr &= ~subsys; + } else { + rcc->apb1enr &= ~subsys; + } + return DEV_OK; +} + +/** + * @brief helper for mapping a setting to register value + */ +struct regval_map { + int val; + int reg; +}; + +int map_reg_val(const struct regval_map *map, size_t cnt, int val) +{ + for (int i = 0; i < cnt; i++) { + if (map[i].val == val) { + return map[i].reg; + } + } + return 0; +} + +/** + * @brief map APB prescaler setting to register value + */ +static int __apb_prescaler(int prescaler) +{ + if (prescaler == 0) { + return STM32F10X_RCC_CFG_HCLK_DIV_0; + } + + const struct regval_map map[] = { + {0, STM32F10X_RCC_CFG_HCLK_DIV_0}, + {2, STM32F10X_RCC_CFG_HCLK_DIV_2}, + {4, STM32F10X_RCC_CFG_HCLK_DIV_4}, + {8, STM32F10X_RCC_CFG_HCLK_DIV_8}, + {16, STM32F10X_RCC_CFG_HCLK_DIV_16}, + }; + + return map_reg_val(map, ARRAY_SIZE(map), prescaler); +} + +/** + * @brief map AHB prescaler setting to register value + */ +static int __ahb_prescaler(int prescaler) +{ + if (prescaler == 0) + return STM32F10X_RCC_CFG_SYSCLK_DIV_0; + + const struct regval_map map[] = { + {0, STM32F10X_RCC_CFG_SYSCLK_DIV_0}, + {2, STM32F10X_RCC_CFG_SYSCLK_DIV_2}, + {4, STM32F10X_RCC_CFG_SYSCLK_DIV_4}, + {8, STM32F10X_RCC_CFG_SYSCLK_DIV_8}, + {16, STM32F10X_RCC_CFG_SYSCLK_DIV_16}, + {64, STM32F10X_RCC_CFG_SYSCLK_DIV_64}, + {128, STM32F10X_RCC_CFG_SYSCLK_DIV_128}, + {256, STM32F10X_RCC_CFG_SYSCLK_DIV_256}, + {512, STM32F10X_RCC_CFG_SYSCLK_DIV_512}, + }; + return map_reg_val(map, ARRAY_SIZE(map), prescaler); +} + +/** + * @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; +} + + + +uint32_t __get_ahb_clock(uint32_t sysclk) +{ + /* AHB clock is generated based on SYSCLK */ + uint32_t sysclk_div = CONFIG_CLOCK_STM32F10X_AHB_PRESCALER; + + if (sysclk_div == 0) { + sysclk_div = 1; + } + return sysclk / sysclk_div; +} + +uint32_t __get_apb_clock(uint32_t ahb_clock, uint32_t prescaler) +{ + if (prescaler == 0) { + prescaler = 1; + } + return ahb_clock / prescaler; +} + +static int stm32f10x_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_STM32F10X_APB1_PRESCALER; + + if (subsys > STM32F10X_CLOCK_APB2_BASE) { + prescaler = CONFIG_CLOCK_STM32F10X_APB2_PRESCALER; + } + + /* assumes SYSCLK is SYS_CLOCK_HW_CYCLES_PER_SEC */ + uint32_t ahb_clock = + __get_ahb_clock(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC); + + *rate = __get_apb_clock(ahb_clock, prescaler); + + return DEV_OK; +} + +static struct clock_control_driver_api stm32f10x_clock_control_api = { + .on = stm32f10x_clock_control_on, + .off = stm32f10x_clock_control_off, + .get_rate = stm32f10x_clock_control_get_subsys_rate, +}; + +int stm32f10x_clock_control_init(struct device *dev) +{ + struct stm32f10x_rcc_data *data = dev->driver_data; + volatile struct stm32f10x_rcc *rcc = + (struct stm32f10x_rcc *)(data->base); + + /* enable HSI clock */ + rcc->cr.bit.hsion = 1; + /* this should end after one test */ + while (rcc->cr.bit.hsirdy != 1) { + } + + /* disable PLL */ + rcc->cr.bit.pllon = 0; + +#ifdef CONFIG_CLOCK_STM32F10X_PLL_SRC_HSI + /* PLL input from HSI/2 = 4MHz */ + rcc->cfgr.bit.pllsrc = STM32F10X_RCC_CFG_PLL_SRC_HSI; +#elif defined(CONFIG_CLOCK_STM32F10X_PLL_SRC_PREDIV1) + #error PREDIV1 as PLL source is not supported + rcc->cfgr.bit.pllsrc = STM32F10X_RCC_CFG_PLL_SRC_PREDIV1; +#endif + + uint32_t pllmul = __pllmul(CONFIG_CLOCK_STM32F10X_PLL_MULTIPLIER); + /* setup PLL multiplication (PLL must be disabled) */ + rcc->cfgr.bit.pllmul = pllmul; + + /* enable PLL */ + rcc->cr.bit.pllon = 1; + + /* wait for PLL to become ready */ + while (rcc->cr.bit.pllrdy != 1) { + } + + uint32_t hpre = __ahb_prescaler(CONFIG_CLOCK_STM32F10X_AHB_PRESCALER); + /* setup AHB prescaler */ + rcc->cfgr.bit.hpre = hpre; + + uint32_t ppre1 = __apb_prescaler(CONFIG_CLOCK_STM32F10X_APB1_PRESCALER); + /* setup APB1, must not exceed 36MHz, prescaler set to 0 */ + rcc->cfgr.bit.ppre1 = ppre1; + + uint32_t ppre2 = __apb_prescaler(CONFIG_CLOCK_STM32F10X_APB2_PRESCALER); + /* setup APB2 to use 36MHz, prescaler set to 0 */ + rcc->cfgr.bit.ppre2 = ppre2; + + /* setup SYSCLK source, default to HSI */ + int sysclk_src = STM32F10X_RCC_CFG_SYSCLK_SRC_HSI; +#ifdef CONFIG_CLOCK_STM32F10X_SYSCLK_SRC_PLL + sysclk_src = STM32F10X_RCC_CFG_SYSCLK_SRC_PLL; +#elif defined(CONFIG_CLOCK_STM32F10X_SYSCLK_SRC_HSE) + sysclk_src = STM32F10X_RCC_CFG_SYSCLK_SRC_HSE; +#endif + /* 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 = &stm32f10x_clock_control_api; + return DEV_OK; +} + +static struct stm32f10x_rcc_data stm32f10x_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_stm32f10x, STM32_CLOCK_CONTROL_NAME, + &stm32f10x_clock_control_init, + &stm32f10x_rcc_data, NULL, + PRIMARY, CONFIG_CLOCK_CONTROL_STM32F10X_DEVICE_PRIORITY); diff --git a/include/drivers/clock_control/stm32_clock_control.h b/include/drivers/clock_control/stm32_clock_control.h new file mode 100644 index 00000000000..35e14577571 --- /dev/null +++ b/include/drivers/clock_control/stm32_clock_control.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2016 Open-RnD 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 _STM32_CLOCK_CONTROL_H_ +#define _STM32_CLOCK_CONTROL_H_ + +#include + +/* common clock control device name for all STM32 chips */ +#define STM32_CLOCK_CONTROL_NAME "stm32-cc" + +#ifdef CONFIG_SOC_STM32F1X +#include "stm32f1_clock_control.h" +#endif + +#endif /* _STM32_CLOCK_CONTROL_H_ */ diff --git a/include/drivers/clock_control/stm32f1_clock_control.h b/include/drivers/clock_control/stm32f1_clock_control.h new file mode 100644 index 00000000000..55c2e9d6930 --- /dev/null +++ b/include/drivers/clock_control/stm32f1_clock_control.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2016 Open-RnD 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 _STM32F1_CLOCK_CONTROL_H_ +#define _STM32F1_CLOCK_CONTROL_H_ + +/** + * @file clock subsystem IDs for STM32F1 family + */ + +enum { + /* APB1 */ + STM32F10X_CLOCK_SUBSYS_TIM2 = 1 << 0, + STM32F10X_CLOCK_SUBSYS_TIM3 = 1 << 1, + STM32F10X_CLOCK_SUBSYS_TIM4 = 1 << 2, + STM32F10X_CLOCK_SUBSYS_TIM5 = 1 << 3, + STM32F10X_CLOCK_SUBSYS_TIM6 = 1 << 4, + STM32F10X_CLOCK_SUBSYS_TIM7 = 1 << 5, + STM32F10X_CLOCK_SUBSYS_WWDG = 1 << 11, + STM32F10X_CLOCK_SUBSYS_SPI2 = 1 << 14, + STM32F10X_CLOCK_SUBSYS_SPI3 = 1 << 15, + STM32F10X_CLOCK_SUBSYS_USART2 = 1 << 17, + STM32F10X_CLOCK_SUBSYS_USART3 = 1 << 18, + STM32F10X_CLOCK_SUBSYS_UART4 = 1 << 19, + STM32F10X_CLOCK_SUBSYS_UART5 = 1 << 20, + STM32F10X_CLOCK_SUBSYS_I2C1 = 1 << 21, + STM32F10X_CLOCK_SUBSYS_I2C2 = 1 << 22, + STM32F10X_CLOCK_SUBSYS_CAN1 = 1 << 25, + STM32F10X_CLOCK_SUBSYS_CAN2 = 1 << 26, + STM32F10X_CLOCK_SUBSYS_BKP = 1 << 27, + STM32F10X_CLOCK_SUBSYS_PWR = 1 << 28, + STM32F10X_CLOCK_SUBSYS_DAC = 1 << 29, + + STM32F10X_CLOCK_APB2_BASE = 1 << 31, + /* APB2 */ + STM32F10X_CLOCK_SUBSYS_AFIO = STM32F10X_CLOCK_APB2_BASE | 1 << 0, + STM32F10X_CLOCK_SUBSYS_IOPA = STM32F10X_CLOCK_APB2_BASE | 1 << 2, + STM32F10X_CLOCK_SUBSYS_IOPB = STM32F10X_CLOCK_APB2_BASE | 1 << 3, + STM32F10X_CLOCK_SUBSYS_IOPC = STM32F10X_CLOCK_APB2_BASE | 1 << 4, + STM32F10X_CLOCK_SUBSYS_IOPD = STM32F10X_CLOCK_APB2_BASE | 1 << 5, + STM32F10X_CLOCK_SUBSYS_IOPE = STM32F10X_CLOCK_APB2_BASE | 1 << 6, + STM32F10X_CLOCK_SUBSYS_ADC1 = STM32F10X_CLOCK_APB2_BASE | 1 << 9, + STM32F10X_CLOCK_SUBSYS_ADC2 = STM32F10X_CLOCK_APB2_BASE | 1 << 10, + STM32F10X_CLOCK_SUBSYS_TIM1 = STM32F10X_CLOCK_APB2_BASE | 1 << 11, + STM32F10X_CLOCK_SUBSYS_SPI1 = STM32F10X_CLOCK_APB2_BASE | 1 << 12, + STM32F10X_CLOCK_SUBSYS_USART1 = STM32F10X_CLOCK_APB2_BASE | 1 << 14, + +}; + +#endif /* _STM32F1_CLOCK_CONTROL_H_ */