diff options
-rw-r--r-- | libmaple/include/libmaple/rcc.h | 53 | ||||
-rw-r--r-- | libmaple/stm32f1/include/series/rcc.h | 88 | ||||
-rw-r--r-- | libmaple/stm32f1/rcc.c | 40 | ||||
-rw-r--r-- | libmaple/stm32f2/include/series/rcc.h | 36 | ||||
-rw-r--r-- | libmaple/stm32f2/rcc.c | 26 |
5 files changed, 105 insertions, 138 deletions
diff --git a/libmaple/include/libmaple/rcc.h b/libmaple/include/libmaple/rcc.h index 9ed12bc..3055bb4 100644 --- a/libmaple/include/libmaple/rcc.h +++ b/libmaple/include/libmaple/rcc.h @@ -77,11 +77,26 @@ typedef enum rcc_sysclk_src { * * - enum rcc_prescaler: And a suitable set of dividers for * rcc_set_prescaler(). + * + * - enum rcc_pllsrc: For each PLL source. Same source, same token. + * + * - A target-dependent type to be pointed to by the data field in a + * struct rcc_pll_cfg. */ +#ifdef __DOXYGEN__ +/* RCC register map base pointer */ +#define RCC_BASE +#endif + /* Clock prescaler management. */ -void rcc_set_prescaler(rcc_prescaler prescaler, uint32 divider); +/** + * @brief Set the divider on a peripheral prescaler + * @param prescaler prescaler to set + * @param divider prescaler divider + */ +extern void rcc_set_prescaler(rcc_prescaler prescaler, uint32 divider); /* SYSCLK. */ @@ -94,13 +109,20 @@ void rcc_switch_sysclk(rcc_sysclk_src sysclk_src); */ typedef struct rcc_pll_cfg { rcc_pllsrc pllsrc; /**< PLL source */ - void *data; /**< Series-specific configuration - * data. See the <series/rcc.h> for your - * MCU for more information on what to put - * here. */ + + /** Series-specific configuration data. */ + void *data; } rcc_pll_cfg; -void rcc_configure_pll(rcc_pll_cfg *pll_cfg); +/** + * @brief Configure the main PLL. + * + * You may only call this function while the PLL is disabled. + * + * @param pll_cfg Desired PLL configuration. The contents of this + * struct depend entirely on the target. + */ +extern void rcc_configure_pll(rcc_pll_cfg *pll_cfg); /* System and secondary clock sources. */ @@ -111,8 +133,23 @@ int rcc_is_clk_ready(rcc_clk clock); /* Peripheral clock lines and clock domains. */ -void rcc_clk_enable(rcc_clk_id id); -void rcc_reset_dev(rcc_clk_id id); +/** + * @brief Turn on the clock line on a peripheral + * @param id Clock ID of the peripheral to turn on. + */ +extern void rcc_clk_enable(rcc_clk_id id); + +/** + * @brief Reset a peripheral. + * + * Caution: not all rcc_clk_id values refer to a peripheral which can + * be reset. (Only rcc_clk_ids for peripherals with bits in an RCC + * reset register can be used here.) + * + * @param id Clock ID of the peripheral to reset. + */ +extern void rcc_reset_dev(rcc_clk_id id); + rcc_clk_domain rcc_dev_clk(rcc_clk_id id); /* Clock security system */ diff --git a/libmaple/stm32f1/include/series/rcc.h b/libmaple/stm32f1/include/series/rcc.h index 3e7f7c6..c20d5d6 100644 --- a/libmaple/stm32f1/include/series/rcc.h +++ b/libmaple/stm32f1/include/series/rcc.h @@ -43,7 +43,7 @@ extern "C"{ * Register map */ -/** RCC register map type */ +/** STM32F1 RCC register map type */ typedef struct rcc_reg_map { __io uint32 CR; /**< Clock control register */ __io uint32 CFGR; /**< Clock configuration register */ @@ -57,7 +57,6 @@ typedef struct rcc_reg_map { __io uint32 CSR; /**< Control/status register */ } rcc_reg_map; -/** RCC register map base pointer */ #define RCC_BASE ((struct rcc_reg_map*)0x40021000) /* @@ -389,10 +388,7 @@ typedef struct rcc_reg_map { */ /** - * @brief Identifies bus and clock line for a peripheral. - * - * Also generally useful as a unique identifier for that peripheral - * (or its corresponding device struct). + * @brief STM32F1 rcc_clk_id. */ typedef enum rcc_clk_id { RCC_GPIOA, @@ -444,28 +440,7 @@ typedef enum rcc_clk_id { } rcc_clk_id; /** - * @brief Deprecated PLL multipliers, for rcc_clk_init(). - */ -typedef enum rcc_pll_multiplier { - RCC_PLLMUL_2 = (0x0 << 18), - RCC_PLLMUL_3 = (0x1 << 18), - RCC_PLLMUL_4 = (0x2 << 18), - RCC_PLLMUL_5 = (0x3 << 18), - RCC_PLLMUL_6 = (0x4 << 18), - RCC_PLLMUL_7 = (0x5 << 18), - RCC_PLLMUL_8 = (0x6 << 18), - RCC_PLLMUL_9 = (0x7 << 18), - RCC_PLLMUL_10 = (0x8 << 18), - RCC_PLLMUL_11 = (0x9 << 18), - RCC_PLLMUL_12 = (0xA << 18), - RCC_PLLMUL_13 = (0xB << 18), - RCC_PLLMUL_14 = (0xC << 18), - RCC_PLLMUL_15 = (0xD << 18), - RCC_PLLMUL_16 = (0xE << 18), -} rcc_pll_multiplier; - -/** - * @brief PLL clock sources. + * @brief STM32F1 PLL clock sources. * @see rcc_configure_pll() */ typedef enum rcc_pllsrc { @@ -473,6 +448,10 @@ typedef enum rcc_pllsrc { RCC_PLLSRC_HSI_DIV_2 = (0x0 << 16) } rcc_pllsrc; +/** + * @brief STM32F1 clock domains. + * @see rcc_dev_clk() + */ typedef enum rcc_clk_domain { RCC_APB1, RCC_APB2, @@ -480,7 +459,7 @@ typedef enum rcc_clk_domain { } rcc_clk_domain; /** - * Prescaler identifiers + * @brief STM32F1 Prescaler identifiers * @see rcc_set_prescaler() */ typedef enum rcc_prescaler { @@ -492,7 +471,7 @@ typedef enum rcc_prescaler { } rcc_prescaler; /** - * ADC prescaler dividers + * @brief STM32F1 ADC prescaler dividers * @see rcc_set_prescaler() */ typedef enum rcc_adc_divider { @@ -503,7 +482,7 @@ typedef enum rcc_adc_divider { } rcc_adc_divider; /** - * APB1 prescaler dividers + * @brief STM32F1 APB1 prescaler dividers * @see rcc_set_prescaler() */ typedef enum rcc_apb1_divider { @@ -515,7 +494,7 @@ typedef enum rcc_apb1_divider { } rcc_apb1_divider; /** - * APB2 prescaler dividers + * @brief STM32F1 APB2 prescaler dividers * @see rcc_set_prescaler() */ typedef enum rcc_apb2_divider { @@ -527,7 +506,7 @@ typedef enum rcc_apb2_divider { } rcc_apb2_divider; /** - * AHB prescaler dividers + * @brief STM32F1 AHB prescaler dividers * @see rcc_set_prescaler() */ typedef enum rcc_ahb_divider { @@ -544,7 +523,7 @@ typedef enum rcc_ahb_divider { } rcc_ahb_divider; /** - * @brief Available clock sources. + * @brief STM32F1 clock sources. */ typedef enum rcc_clk { RCC_CLK_PLL = (uint16)((offsetof(struct rcc_reg_map, CR) << 8) | @@ -562,26 +541,45 @@ typedef enum rcc_clk { * (approximately 32 KHz). */ } rcc_clk; -/* - * Series-specific functionality. +/** + * @brief STM32F1 PLL multipliers. */ - -__deprecated -void rcc_clk_init(rcc_sysclk_src sysclk_src, - rcc_pllsrc pll_src, - rcc_pll_multiplier pll_mul); +typedef enum rcc_pll_multiplier { + RCC_PLLMUL_2 = (0x0 << 18), + RCC_PLLMUL_3 = (0x1 << 18), + RCC_PLLMUL_4 = (0x2 << 18), + RCC_PLLMUL_5 = (0x3 << 18), + RCC_PLLMUL_6 = (0x4 << 18), + RCC_PLLMUL_7 = (0x5 << 18), + RCC_PLLMUL_8 = (0x6 << 18), + RCC_PLLMUL_9 = (0x7 << 18), + RCC_PLLMUL_10 = (0x8 << 18), + RCC_PLLMUL_11 = (0x9 << 18), + RCC_PLLMUL_12 = (0xA << 18), + RCC_PLLMUL_13 = (0xB << 18), + RCC_PLLMUL_14 = (0xC << 18), + RCC_PLLMUL_15 = (0xD << 18), + RCC_PLLMUL_16 = (0xE << 18), +} rcc_pll_multiplier; /** - * @brief STM32F1-specific PLL configuration values. - * - * Use this as the "data" field in a struct rcc_pll_cfg. - * + * @brief STM32F1 PLL configuration values. + * Point to one of these with the "data" field in a struct rcc_pll_cfg. * @see struct rcc_pll_cfg. */ typedef struct stm32f1_rcc_pll_data { rcc_pll_multiplier pll_mul; /**< PLL multiplication factor. */ } stm32f1_rcc_pll_data; +/* + * Deprecated bits. + */ + +__deprecated +void rcc_clk_init(rcc_sysclk_src sysclk_src, + rcc_pllsrc pll_src, + rcc_pll_multiplier pll_mul); + #ifdef __cplusplus } #endif diff --git a/libmaple/stm32f1/rcc.c b/libmaple/stm32f1/rcc.c index ca81755..a83bea3 100644 --- a/libmaple/stm32f1/rcc.c +++ b/libmaple/stm32f1/rcc.c @@ -96,23 +96,11 @@ const struct rcc_dev_info rcc_dev_table[] = { }; /** - * @brief Deprecated. + * @brief Deprecated; STM32F1 only. * * Initialize the clock control system. Initializes the system * clock source to use the PLL driven by an external oscillator. * - * This function is limited and nonportable. Instead of using it, - * follow this (portable) procedure: - * - * 1. Switch to HSI by calling rcc_switch_sysclk(RCC_CLKSRC_HSI). - * 2. Turn off HSE by calling rcc_turn_off_clk(RCC_CLK_HSE). - * 3. Turn off the PLL by calling rcc_turn_off_clk(RCC_CLK_HSE). - * 4. Reconfigure the PLL using rcc_configure_pll(). - * 5. Turn on RCC_CLK_HSE using rcc_turn_on_clk() and wait for it to - * become ready by busy-waiting on rcc_is_clk_ready(). - * 6. Turn on RCC_CLK_PLL using the same methods. - * 7. Switch to the PLL with rcc_switch_sysclk(RCC_CLKSRC_PLL). - * * @param sysclk_src system clock source, must be PLL * @param pll_src pll clock source, must be HSE * @param pll_mul pll multiplier @@ -141,14 +129,7 @@ void rcc_clk_init(rcc_sysclk_src sysclk_src, rcc_switch_sysclk(RCC_CLKSRC_PLL); } -/** - * @brief Configure the main PLL. - * - * You may only call this function while the PLL is disabled. - * - * @param pll_cfg Desired PLL configuration. The data field must point - * to a valid struct stm32f1_rcc_pll_data. - */ +/* pll_cfg->data must point to a valid struct stm32f1_rcc_pll_data. */ void rcc_configure_pll(rcc_pll_cfg *pll_cfg) { stm32f1_rcc_pll_data *data = pll_cfg->data; rcc_pll_multiplier pll_mul = data->pll_mul; @@ -163,10 +144,6 @@ void rcc_configure_pll(rcc_pll_cfg *pll_cfg) { RCC_BASE->CFGR = cfgr; } -/** - * @brief Turn on the clock line on a peripheral - * @param id Clock ID of the peripheral to turn on. - */ void rcc_clk_enable(rcc_clk_id id) { static __io uint32* enable_regs[] = { [APB1] = &RCC_BASE->APB1ENR, @@ -176,14 +153,6 @@ void rcc_clk_enable(rcc_clk_id id) { rcc_do_clk_enable(enable_regs, id); } -/** - * @brief Reset a peripheral. - * - * Caution: not all rcc_clk_id values refer to a peripheral which can - * be reset. - * - * @param id Clock ID of the peripheral to reset. - */ void rcc_reset_dev(rcc_clk_id id) { static __io uint32* reset_regs[] = { [APB1] = &RCC_BASE->APB1RSTR, @@ -192,11 +161,6 @@ void rcc_reset_dev(rcc_clk_id id) { rcc_do_reset_dev(reset_regs, id); } -/** - * @brief Set the divider on a peripheral prescaler - * @param prescaler prescaler to set - * @param divider prescaler divider - */ void rcc_set_prescaler(rcc_prescaler prescaler, uint32 divider) { static const uint32 masks[] = { [RCC_PRESCALER_AHB] = RCC_CFGR_HPRE, diff --git a/libmaple/stm32f2/include/series/rcc.h b/libmaple/stm32f2/include/series/rcc.h index 9c3fdd5..52f6b4a 100644 --- a/libmaple/stm32f2/include/series/rcc.h +++ b/libmaple/stm32f2/include/series/rcc.h @@ -49,7 +49,7 @@ extern "C"{ * Register map */ -/** RCC register map type */ +/** STM32F1 RCC register map type */ typedef struct rcc_reg_map { __io uint32 CR; /**< Clock control register */ __io uint32 PLLCFGR; /**< PLL configuration register */ @@ -93,7 +93,6 @@ typedef struct rcc_reg_map { __io uint32 PLLI2SCFGR; /**< PLLI2S configuration register */ } rcc_reg_map; -/* RCC register map base pointer */ #define RCC_BASE ((struct rcc_reg_map*)0x40023800) /* @@ -742,7 +741,7 @@ typedef struct rcc_reg_map { */ /** - * @brief Available clock sources. + * @brief STM32F2 clock sources. */ typedef enum rcc_clk { RCC_CLK_PLLI2S = (uint16)((offsetof(struct rcc_reg_map, CR) << 8) | @@ -764,8 +763,7 @@ typedef enum rcc_clk { } rcc_clk; /** - * @brief Identifies bus and clock line for a peripheral or peripheral - * clock. + * @brief STM32F2 rcc_clk_id. */ typedef enum rcc_clk_id { RCC_OTGHSULPI, @@ -832,7 +830,7 @@ typedef enum rcc_clk_id { } rcc_clk_id; /** - * @brief PLL entry clock source + * @brief STM32F2 PLL entry clock source * @see rcc_configure_pll() */ typedef enum rcc_pllsrc { @@ -841,7 +839,7 @@ typedef enum rcc_pllsrc { } rcc_pllsrc; /** - * @brief Peripheral clock domains. + * @brief STM32F2 Peripheral clock domains. */ typedef enum rcc_clk_domain { RCC_APB1, @@ -856,7 +854,7 @@ typedef enum rcc_clk_domain { */ /** - * @brief Prescaler identifiers. + * @brief STM32F2 Prescaler identifiers. */ typedef enum rcc_prescaler { RCC_PRESCALER_MCO2, @@ -868,7 +866,7 @@ typedef enum rcc_prescaler { } rcc_prescaler; /** - * @brief MCO2 prescaler dividers. + * @brief STM32F2 MCO2 prescaler dividers. */ typedef enum rcc_mco2_divider { RCC_MCO2_DIV_1 = RCC_CFGR_MCO2PRE_DIV_1, @@ -879,7 +877,7 @@ typedef enum rcc_mco2_divider { } rcc_mco2_divider; /** - * @brief MCO1 prescaler dividers. + * @brief STM32F2 MCO1 prescaler dividers. */ typedef enum rcc_mco1_divider { RCC_MCO1_DIV_1 = RCC_CFGR_MCO1PRE_DIV_1, @@ -890,14 +888,14 @@ typedef enum rcc_mco1_divider { } rcc_mco1_divider; /** - * @brief RTC prescaler dividers. + * @brief STM32F2 RTC prescaler dividers. */ typedef enum rcc_rtc_divider { /* TODO */ RCC_RTC_DIV_TODO = 0xFFFFFFFF, } rcc_rtc_divider; /** - * @brief AP2 prescaler dividers. + * @brief STM32F2 AP2 prescaler dividers. */ typedef enum rcc_apb2_divider { RCC_APB2_HCLK_DIV_1 = 0, @@ -908,7 +906,7 @@ typedef enum rcc_apb2_divider { } rcc_apb2_divider; /** - * @brief AP1 prescaler dividers. + * @brief STM32F2 APB1 prescaler dividers. */ typedef enum rcc_apb1_divider { RCC_APB1_HCLK_DIV_1 = 0, @@ -919,7 +917,7 @@ typedef enum rcc_apb1_divider { } rcc_apb1_divider; /** - * @brief AHB prescaler dividers. + * @brief STM32F2 AHB prescaler dividers. */ typedef enum rcc_ahb_divider { RCC_AHB_SYSCLK_DIV_1 = 0, @@ -933,15 +931,9 @@ typedef enum rcc_ahb_divider { RCC_AHB_SYSCLK_DIV_512 = RCC_CFGR_HPRE_SYSCLK_DIV_512, } rcc_ahb_divider; -/* - * Series-specific PLL configuration. - */ - /** - * @brief STM32F2-specific PLL configuration values. - * - * Use this as the "data" field in a struct rcc_pll_cfg. - * + * @brief STM32F2 PLL configuration values. + * Point to one of these with the "data" field in a struct rcc_pll_cfg. * @see struct rcc_pll_cfg. */ typedef struct stm32f2_rcc_pll_data { diff --git a/libmaple/stm32f2/rcc.c b/libmaple/stm32f2/rcc.c index a13e56d..7fc7eb0 100644 --- a/libmaple/stm32f2/rcc.c +++ b/libmaple/stm32f2/rcc.c @@ -110,10 +110,6 @@ const struct rcc_dev_info rcc_dev_table[] = { [RCC_TIMER1] = DEV_ENTRY(APB2, TIM1), }; -/** - * @brief Turn on the clock line on a peripheral - * @param id Clock ID of the peripheral to turn on. - */ void rcc_clk_enable(rcc_clk_id id) { static __io uint32* enable_regs[] = { [RCC_AHB1] = &RCC_BASE->AHB1ENR, @@ -125,14 +121,6 @@ void rcc_clk_enable(rcc_clk_id id) { rcc_do_clk_enable(enable_regs, id); } -/** - * @brief Reset a peripheral. - * - * Caution: not all rcc_clk_id values refer to a peripheral which can - * be reset. - * - * @param id Clock ID of the peripheral to reset. - */ void rcc_reset_dev(rcc_clk_id id) { static __io uint32* reset_regs[] = { [RCC_AHB1] = &RCC_BASE->AHB1RSTR, @@ -144,11 +132,6 @@ void rcc_reset_dev(rcc_clk_id id) { rcc_do_reset_dev(reset_regs, id); } -/** - * @brief Set the divider on a peripheral prescaler - * @param prescaler prescaler to set - * @param divider prescaler divider - */ void rcc_set_prescaler(rcc_prescaler prescaler, uint32 divider) { static const uint32 masks[] = { [RCC_PRESCALER_MCO2] = RCC_CFGR_MCO2PRE, @@ -161,14 +144,7 @@ void rcc_set_prescaler(rcc_prescaler prescaler, uint32 divider) { rcc_do_set_prescaler(masks, prescaler, divider); } -/** - * @brief Configure the main PLL. - * - * You may only call this function while the PLL is disabled. - * - * @param pll_cfg Desired PLL configuration. The data field must point - * to a valid struct stm32f2_rcc_pll_data. - */ +/* pll_cfg->data must point to a struct stm32f2_rcc_pll_data. */ void rcc_configure_pll(rcc_pll_cfg *pll_cfg) { stm32f2_rcc_pll_data *data = pll_cfg->data; uint32 pllcfgr; |