stm32: added peripheral clock get helpers for all stm32 platforms.

Allows for abstraction for code that's dependent on knowing the source clock
for a peripheral. Implemented a few core peripherals that tend to have clock
tree differences between platforms (USART, timers, I2C, SPI).
This commit is contained in:
Brian Viele
2020-03-06 00:57:21 -05:00
committed by Karl Palsson
parent df55d45cc1
commit e41ac6ea71
24 changed files with 860 additions and 94 deletions

View File

@@ -67,6 +67,13 @@ bool rcc_is_osc_ready(enum rcc_osc osc);
*/
void rcc_wait_for_osc_ready(enum rcc_osc osc);
/**
* This will return the divisor 1/2/4/8/16/64/128/256/512 which is set as a
* 4-bit value, typically used for hpre and other prescalers.
* @param div_val Masked and shifted divider value from register (e.g. RCC_CFGR)
*/
uint16_t rcc_get_div_from_hpre(uint8_t div_val);
END_DECLS
/**@}*/

View File

@@ -149,6 +149,7 @@ Control</b>
#define RCC_CFGR_PPRE_SHIFT 8
#define RCC_CFGR_PPRE (7 << RCC_CFGR_PPRE_SHIFT)
#define RCC_CFGR_PPRE_MASK 0x7
/** @defgroup rcc_cfgr_apb1pre RCC_CFGR APB prescale Factors
@{*/
#define RCC_CFGR_PPRE_NODIV (0 << RCC_CFGR_PPRE_SHIFT)
@@ -160,6 +161,7 @@ Control</b>
#define RCC_CFGR_HPRE_SHIFT 4
#define RCC_CFGR_HPRE (0xf << RCC_CFGR_HPRE_SHIFT)
#define RCC_CFGR_HPRE_MASK 0xf
/** @defgroup rcc_cfgr_ahbpre RCC_CFGR AHB prescale Factors
@{*/
#define RCC_CFGR_HPRE_NODIV (0x0 << RCC_CFGR_HPRE_SHIFT)
@@ -383,6 +385,12 @@ Control</b>
/**@}*/
/* --- RCC_CFGR3 values ---------------------------------------------------- */
#define RCC_CFGR3_USART3SW_SHIFT 18
#define RCC_CFGR3_USART3SW (3 << RCC_CFGR3_USART2SW_SHIFT)
#define RCC_CFGR3_USART3SW_PCLK (0 << RCC_CFGR3_USART2SW_SHIFT)
#define RCC_CFGR3_USART3SW_SYSCLK (1 << RCC_CFGR3_USART2SW_SHIFT)
#define RCC_CFGR3_USART3SW_LSE (2 << RCC_CFGR3_USART2SW_SHIFT)
#define RCC_CFGR3_USART3SW_HSI (3 << RCC_CFGR3_USART2SW_SHIFT)
#define RCC_CFGR3_USART2SW_SHIFT 16
#define RCC_CFGR3_USART2SW (3 << RCC_CFGR3_USART2SW_SHIFT)
@@ -403,6 +411,8 @@ Control</b>
#define RCC_CFGR3_USART1SW_LSE (2 << RCC_CFGR3_USART1SW_SHIFT)
#define RCC_CFGR3_USART1SW_HSI (3 << RCC_CFGR3_USART1SW_SHIFT)
#define RCC_CFGR3_USARTxSW_MASK 3
/* --- RCC_CFGR3 values ---------------------------------------------------- */
#define RCC_CR2_HSI48CAL_SHIFT 24
@@ -579,6 +589,10 @@ enum rcc_osc rcc_usb_clock_source(void);
void rcc_clock_setup_in_hse_8mhz_out_48mhz(void);
void rcc_clock_setup_in_hsi_out_48mhz(void);
void rcc_clock_setup_in_hsi48_out_48mhz(void);
uint32_t rcc_get_usart_clk_freq(uint32_t usart);
uint32_t rcc_get_timer_clk_freq(uint32_t timer);
uint32_t rcc_get_i2c_clk_freq(uint32_t i2c);
uint32_t rcc_get_spi_clk_freq(uint32_t spi);
END_DECLS

View File

@@ -790,7 +790,10 @@ void rcc_clock_setup_in_hse_25mhz_out_72mhz(void) LIBOPENCM3_DEPRECATED("use rcc
*/
void rcc_clock_setup_pll(const struct rcc_clock_scale *clock);
void rcc_backupdomain_reset(void);
uint32_t rcc_get_usart_clk_freq(uint32_t usart);
uint32_t rcc_get_timer_clk_freq(uint32_t timer);
uint32_t rcc_get_i2c_clk_freq(uint32_t i2c);
uint32_t rcc_get_spi_clk_freq(uint32_t spi);
END_DECLS
#endif

View File

@@ -850,6 +850,10 @@ void rcc_set_main_pll_hse(uint32_t pllm, uint32_t plln, uint32_t pllp,
uint32_t rcc_system_clock_source(void);
void rcc_clock_setup_hse_3v3(const struct rcc_clock_scale *clock);
void rcc_backupdomain_reset(void);
uint32_t rcc_get_usart_clk_freq(uint32_t usart);
uint32_t rcc_get_timer_clk_freq(uint32_t timer);
uint32_t rcc_get_i2c_clk_freq(uint32_t i2c);
uint32_t rcc_get_spi_clk_freq(uint32_t spi);
END_DECLS

View File

@@ -436,6 +436,9 @@
#define RCC_CFGR3_UART1SW_LSE 0x2
#define RCC_CFGR3_UART1SW_HSI 0x3
/* Shared mask for UART clock source. */
#define RCC_CFGR3_UARTxSW_MASK 0x3
/* --- Variable definitions ------------------------------------------------ */
extern uint32_t rcc_ahb_frequency;
@@ -655,6 +658,10 @@ uint32_t rcc_get_i2c_clocks(void);
void rcc_usb_prescale_1_5(void);
void rcc_usb_prescale_1(void);
void rcc_adc_prescale(uint32_t prescale1, uint32_t prescale2);
uint32_t rcc_get_usart_clk_freq(uint32_t usart);
uint32_t rcc_get_timer_clk_freq(uint32_t timer);
uint32_t rcc_get_i2c_clk_freq(uint32_t i2c);
uint32_t rcc_get_spi_clk_freq(uint32_t spi);
END_DECLS

View File

@@ -1127,8 +1127,12 @@ void rcc_set_main_pll_hse(uint32_t pllm, uint32_t plln, uint32_t pllp,
uint32_t rcc_system_clock_source(void);
void rcc_clock_setup_pll(const struct rcc_clock_scale *clock);
void __attribute__((deprecated("Use rcc_clock_setup_pll as direct replacement"))) rcc_clock_setup_hse_3v3(const struct rcc_clock_scale *clock);
uint32_t rcc_get_usart_clk_freq(uint32_t usart);
uint32_t rcc_get_timer_clk_freq(uint32_t timer);
uint32_t rcc_get_i2c_clk_freq(uint32_t i2c);
uint32_t rcc_get_spi_clk_freq(uint32_t spi);
END_DECLS
#endif
/**@}*/
/**@}*/

View File

@@ -646,6 +646,10 @@
#define RCC_DCKCFGR2_UART2SEL_SHIFT 2
#define RCC_DCKCFGR2_UART1SEL_MASK 0x3
#define RCC_DCKCFGR2_UART1SEL_SHIFT 0
#define RCC_DCKCFGR2_UARTxSEL_PCLK 0
#define RCC_DCKCFGR2_UARTxSEL_SYSCLK 1
#define RCC_DCKCFGR2_UARTxSEL_HSI 2
extern uint32_t rcc_ahb_frequency;
extern uint32_t rcc_apb1_frequency;
@@ -986,6 +990,11 @@ void rcc_set_main_pll_hse(uint32_t pllm, uint32_t plln, uint32_t pllp,
uint32_t rcc_system_clock_source(void);
void rcc_clock_setup_hse(const struct rcc_clock_scale *clock, uint32_t hse_mhz);
void rcc_clock_setup_hsi(const struct rcc_clock_scale *clock);
uint32_t rcc_get_usart_clk_freq(uint32_t usart);
uint32_t rcc_get_timer_clk_freq(uint32_t timer);
uint32_t rcc_get_i2c_clk_freq(uint32_t i2c);
uint32_t rcc_get_spi_clk_freq(uint32_t spi);
END_DECLS
/**@}*/

View File

@@ -251,7 +251,7 @@
#define RCC_PLLCFGR_PLLM_SHIFT 0x4
#define RCC_PLLCFGR_PLLM_MASK 0x7
/** @defgroup rcc_pllcfgr_pllm PLLM
* @brief Division factor M [1..8] for PLL input clock. Input frequency must be between 4mhz and 16mhz.
* @brief Division factor M [1..8] for PLL input clock. Input frequency must be between 4mhz and 16mhz.
@{*/
#define RCC_PLLCFGR_PLLM_DIV(x) ((x)-1)
/**@}*/
@@ -629,7 +629,7 @@ extern uint32_t rcc_apb1_frequency;
#define rcc_apb2_frequency rcc_apb1_frequency
/* --- Function prototypes ------------------------------------------------- */
#define _REG_BIT(offset, bit) (((offset) << 5) + (bit))
enum rcc_osc {
@@ -778,7 +778,7 @@ enum rcc_periph_rst {
struct rcc_clock_scale {
enum rcc_osc sysclock_source;
/* PLL as sysclock source cfg */
uint8_t pll_source;
uint8_t pll_div;
@@ -841,6 +841,10 @@ void rcc_clock_setup(const struct rcc_clock_scale *clock);
void rcc_set_rng_clk_div(uint32_t rng_div);
void rcc_set_peripheral_clk_sel(uint32_t periph, uint32_t sel);
uint32_t rcc_get_usart_clk_freq(uint32_t usart);
uint32_t rcc_get_timer_clk_freq(uint32_t timer);
uint32_t rcc_get_i2c_clk_freq(uint32_t i2c);
uint32_t rcc_get_spi_clk_freq(uint32_t spi);
END_DECLS

View File

@@ -409,6 +409,7 @@ LGPL License Terms @ref lgpl_license
#define RCC_D2CCIP2R_RNGSEL_LSI 3
#define RCC_D2CCIP2R_USART16SEL_PCLK2 0
#define RCC_D2CCIP2R_USART234578SEL_PCLK1 0
#define RCC_D2CCIP2R_USARTSEL_PCLK 0
#define RCC_D2CCIP2R_USARTSEL_PLL2Q 1
#define RCC_D2CCIP2R_USARTSEL_PLL3Q 2
#define RCC_D2CCIP2R_USARTSEL_HSI 3
@@ -732,13 +733,34 @@ void rcc_clock_setup_pll(const struct rcc_pll_config *config);
uint32_t rcc_get_bus_clk_freq(enum rcc_clock_source source);
/**
* Get the clock rate (in Hz) of the specified peripheral. This will pull the
* proper sources out of the clock tree and calculate the clock for the
* peripheral for return to the user, based on current settings.
* @param[in] periph Peripheral base address to get the clock rate for.
* @return Clock rate in Hz for the specified peripheral. 0 if undefined or error.
* Get the peripheral clock speed for the USART at base specified.
* @param usart Base address of USART to get clock frequency for (e.g. USART1_BASE).
*/
uint32_t rcc_get_peripheral_clk_freq(uint32_t periph);
uint32_t rcc_get_usart_clk_freq(uint32_t usart);
/**
* Get the peripheral clock speed for the Timer at base specified.
* @param timer Base address of TIMER to get clock frequency for (e.g. TIM1_BASE).
*/
uint32_t rcc_get_timer_clk_freq(uint32_t timer);
/**
* Get the peripheral clock speed for the I2C device at base specified.
* @param i2c Base address of I2C to get clock frequency for (e.g. I2C1_BASE).
*/
uint32_t rcc_get_i2c_clk_freq(uint32_t i2c);
/**
* Get the peripheral clock speed for the SPI device at base specified.
* @param spi Base address of SPI device to get clock frequency for (e.g. SPI1_BASE).
*/
uint32_t rcc_get_spi_clk_freq(uint32_t spi);
/**
* Get the peripheral clock speed for the FDCAN device at base specified.
* @param fdcan Base address of FDCAN to get clock frequency for (e.g. FDCAN1_BASE).
*/
uint32_t rcc_get_fdcan_clk_freq(uint32_t fdcan);
/**
* Set the clksel value for the specified peripheral. This code will determine

View File

@@ -709,11 +709,14 @@ void rcc_clock_setup_pll(const struct rcc_clock_scale *clock);
void rcc_set_msi_range(uint32_t msi_range);
void rcc_set_peripheral_clk_sel(uint32_t periph, uint32_t sel);
void rcc_set_lptim1_sel(uint32_t lptim1_sel);
void rcc_set_lpuart1_sel(uint32_t lpupart1_sel);
void rcc_set_usart1_sel(uint32_t usart1_sel);
void rcc_set_usart2_sel(uint32_t usart2_sel);
uint32_t rcc_get_usart_clk_freq(uint32_t usart);
uint32_t rcc_get_timer_clk_freq(uint32_t timer);
uint32_t rcc_get_i2c_clk_freq(uint32_t i2c);
uint32_t rcc_get_spi_clk_freq(uint32_t spi);
END_DECLS

View File

@@ -660,6 +660,10 @@ void rcc_clock_setup_msi(const struct rcc_clock_scale *clock);
void rcc_clock_setup_hsi(const struct rcc_clock_scale *clock);
void rcc_clock_setup_pll(const struct rcc_clock_scale *clock);
void rcc_backupdomain_reset(void);
uint32_t rcc_get_usart_clk_freq(uint32_t usart);
uint32_t rcc_get_timer_clk_freq(uint32_t timer);
uint32_t rcc_get_i2c_clk_freq(uint32_t i2c);
uint32_t rcc_get_spi_clk_freq(uint32_t spi);
END_DECLS

View File

@@ -987,6 +987,10 @@ void rcc_set_clock48_source(uint32_t clksel);
void rcc_enable_rtc_clock(void);
void rcc_disable_rtc_clock(void);
void rcc_set_rtc_clock_source(enum rcc_osc clk);
uint32_t rcc_get_usart_clk_freq(uint32_t usart);
uint32_t rcc_get_timer_clk_freq(uint32_t timer);
uint32_t rcc_get_i2c_clk_freq(uint32_t i2c);
uint32_t rcc_get_spi_clk_freq(uint32_t spi);
END_DECLS