stm32:rcc: update _get_clock (uart/i2c) to handle all cases
Adds handling for missing cases. While i2c only has 3 cases, uarts have
all 4, so make sure they're handled properly.
Removes duplicated/redundant definitions.
Adds doxygen wrappers, even if only for internal use.
Fixes: e41ac6ea71 stm32: added peripheral clock get helpers for all stm32
Signed-of-by: Karl Palsson <karlp@tweak.au>
This commit is contained in:
@@ -630,12 +630,14 @@ static uint32_t rcc_get_usart_clksel_freq(uint8_t shift) {
|
||||
uint8_t clksel = (RCC_CFGR3 >> shift) & RCC_CFGR3_USARTxSW_MASK;
|
||||
uint8_t hpre = (RCC_CFGR >> RCC_CFGR_HPRE_SHIFT) & RCC_CFGR_HPRE_MASK;
|
||||
switch (clksel) {
|
||||
case RCC_CFGR3_USART1SW_PCLK:
|
||||
return rcc_apb1_frequency;
|
||||
case RCC_CFGR3_USART1SW_SYSCLK:
|
||||
return rcc_ahb_frequency * rcc_get_div_from_hpre(hpre);
|
||||
case RCC_CFGR3_USART1SW_HSI:
|
||||
return 8000000U;
|
||||
case RCC_CFGR3_USARTxSW_PCLK:
|
||||
return rcc_apb1_frequency;
|
||||
case RCC_CFGR3_USARTxSW_SYSCLK:
|
||||
return rcc_ahb_frequency * rcc_get_div_from_hpre(hpre);
|
||||
case RCC_CFGR3_USARTxSW_LSE:
|
||||
return 32768;
|
||||
case RCC_CFGR3_USARTxSW_HSI:
|
||||
return 8000000U;
|
||||
}
|
||||
cm3_assert_not_reached();
|
||||
}
|
||||
|
||||
@@ -498,12 +498,14 @@ static uint32_t rcc_get_usart_clksel_freq(uint32_t apb_clk, uint8_t shift) {
|
||||
uint8_t clksel = (RCC_CFGR3 >> shift) & RCC_CFGR3_UARTxSW_MASK;
|
||||
uint8_t hpre = (RCC_CFGR >> RCC_CFGR_HPRE_SHIFT) & RCC_CFGR_HPRE_MASK;
|
||||
switch (clksel) {
|
||||
case RCC_CFGR3_UART1SW_PCLK:
|
||||
return apb_clk;
|
||||
case RCC_CFGR3_UART1SW_SYSCLK:
|
||||
return rcc_ahb_frequency * rcc_get_div_from_hpre(hpre);
|
||||
case RCC_CFGR3_UART1SW_HSI:
|
||||
return 8000000U;
|
||||
case RCC_CFGR3_UARTxSW_PCLK:
|
||||
return apb_clk;
|
||||
case RCC_CFGR3_UARTxSW_SYSCLK:
|
||||
return rcc_ahb_frequency * rcc_get_div_from_hpre(hpre);
|
||||
case RCC_CFGR3_UARTxSW_LSE:
|
||||
return 32768;
|
||||
case RCC_CFGR3_UARTxSW_HSI:
|
||||
return 8000000U;
|
||||
}
|
||||
cm3_assert_not_reached();
|
||||
}
|
||||
|
||||
@@ -485,18 +485,20 @@ void rcc_clock_setup_hsi(const struct rcc_clock_scale *clock)
|
||||
}
|
||||
|
||||
static uint32_t rcc_usart_i2c_clksel_freq(uint32_t apb_clk, uint8_t shift) {
|
||||
uint8_t clksel = (RCC_DCKCFGR2 >> shift) & RCC_DCKCFGR2_UART1SEL_MASK;
|
||||
uint8_t clksel = (RCC_DCKCFGR2 >> shift) & RCC_DCKCFGR2_UARTxSEL_MASK;
|
||||
uint8_t hpre = (RCC_CFGR >> RCC_CFGR_HPRE_SHIFT) & RCC_CFGR_HPRE_MASK;
|
||||
switch (clksel) {
|
||||
case RCC_DCKCFGR2_UARTxSEL_PCLK:
|
||||
return apb_clk;
|
||||
case RCC_DCKCFGR2_UARTxSEL_SYSCLK:
|
||||
return rcc_ahb_frequency * rcc_get_div_from_hpre(hpre);
|
||||
case RCC_DCKCFGR2_UARTxSEL_HSI:
|
||||
return 16000000U;
|
||||
default:
|
||||
cm3_assert_not_reached();
|
||||
case RCC_DCKCFGR2_UARTxSEL_PCLK:
|
||||
return apb_clk;
|
||||
case RCC_DCKCFGR2_UARTxSEL_SYSCLK:
|
||||
return rcc_ahb_frequency * rcc_get_div_from_hpre(hpre);
|
||||
/* This case is only valid for uarts, not for i2c! */
|
||||
case RCC_DCKCFGR2_UARTxSEL_LSE:
|
||||
return 32768;
|
||||
case RCC_DCKCFGR2_UARTxSEL_HSI:
|
||||
return 16000000U;
|
||||
}
|
||||
cm3_assert_not_reached();
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
@@ -532,11 +532,11 @@ void rcc_set_peripheral_clk_sel(uint32_t periph, uint32_t sel)
|
||||
break;
|
||||
case USART2_BASE:
|
||||
shift = RCC_CCIPR_USART2SEL_SHIFT;
|
||||
mask = RCC_CCIPR_USART2SEL_MASK;
|
||||
mask = RCC_CCIPR_USARTxSEL_MASK;
|
||||
break;
|
||||
case USART1_BASE:
|
||||
shift = RCC_CCIPR_USART1SEL_SHIFT;
|
||||
mask = RCC_CCIPR_USART1SEL_MASK;
|
||||
mask = RCC_CCIPR_USARTxSEL_MASK;
|
||||
break;
|
||||
default:
|
||||
cm3_assert_not_reached();
|
||||
@@ -548,15 +548,17 @@ void rcc_set_peripheral_clk_sel(uint32_t periph, uint32_t sel)
|
||||
}
|
||||
|
||||
static uint32_t rcc_get_clksel_freq(uint8_t shift) {
|
||||
uint8_t clksel = (RCC_CCIPR >> shift) & RCC_CCIPR_USART1SEL_MASK;
|
||||
uint8_t clksel = (RCC_CCIPR >> shift) & RCC_CCIPR_USARTxSEL_MASK;
|
||||
uint8_t hpre = (RCC_CFGR >> RCC_CFGR_HPRE_SHIFT) & RCC_CFGR_HPRE_MASK;
|
||||
switch (clksel) {
|
||||
case RCC_CCIPR_USART1SEL_PCLK:
|
||||
return rcc_apb1_frequency;
|
||||
case RCC_CCIPR_USART1SEL_SYSCLK:
|
||||
return rcc_ahb_frequency * rcc_get_div_from_hpre(hpre);
|
||||
case RCC_CCIPR_USART1SEL_HSI16:
|
||||
return 16000000U;
|
||||
case RCC_CCIPR_USARTxSEL_PCLK:
|
||||
return rcc_apb1_frequency;
|
||||
case RCC_CCIPR_USARTxSEL_SYSCLK:
|
||||
return rcc_ahb_frequency * rcc_get_div_from_hpre(hpre);
|
||||
case RCC_CCIPR_USARTxSEL_LSE:
|
||||
return 32768;
|
||||
case RCC_CCIPR_USARTxSEL_HSI16:
|
||||
return 16000000U;
|
||||
}
|
||||
cm3_assert_not_reached();
|
||||
}
|
||||
@@ -571,11 +573,14 @@ uint32_t rcc_get_usart_clk_freq(uint32_t usart)
|
||||
return rcc_get_clksel_freq(RCC_CCIPR_USART1SEL_SHIFT);
|
||||
} else if (usart == USART2_BASE) {
|
||||
return rcc_get_clksel_freq(RCC_CCIPR_USART2SEL_SHIFT);
|
||||
} else if (usart == USART3_BASE) {
|
||||
return rcc_get_clksel_freq(RCC_CCIPR_USART3SEL_SHIFT);
|
||||
} else if (usart == LPUART1_BASE) {
|
||||
return rcc_get_clksel_freq(RCC_CCIPR_LPUART1SEL_SHIFT);
|
||||
} else {
|
||||
return rcc_apb1_frequency;
|
||||
} else if (usart == LPUART2_BASE) {
|
||||
return rcc_get_clksel_freq(RCC_CCIPR_LPUART2SEL_SHIFT);
|
||||
}
|
||||
cm3_assert_not_reached();
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
@@ -593,13 +598,14 @@ uint32_t rcc_get_timer_clk_freq(uint32_t timer __attribute__((unused)))
|
||||
/** @brief Get the peripheral clock speed for the I2C device at base specified.
|
||||
* @param i2c Base address of I2C to get clock frequency for.
|
||||
*/
|
||||
uint32_t rcc_get_i2c_clk_freq(uint32_t i2c __attribute__((unused)))
|
||||
uint32_t rcc_get_i2c_clk_freq(uint32_t i2c)
|
||||
{
|
||||
if (i2c == I2C1_BASE) {
|
||||
return rcc_get_clksel_freq(RCC_CCIPR_I2C1SEL_SHIFT);
|
||||
} else {
|
||||
return rcc_apb1_frequency;
|
||||
} else if (i2c == I2C2_BASE) {
|
||||
return rcc_get_clksel_freq(RCC_CCIPR_I2C2SEL_SHIFT);
|
||||
}
|
||||
cm3_assert_not_reached();
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
@@ -277,17 +277,21 @@ uint32_t rcc_get_usart_clk_freq(uint32_t usart)
|
||||
}
|
||||
|
||||
/* Based on extracted clksel value, return the clock. */
|
||||
if (clksel == RCC_D2CCIP2R_USARTSEL_PCLK) {
|
||||
switch(clksel) {
|
||||
case RCC_D2CCIP2R_USARTSEL_PCLK:
|
||||
return pclk;
|
||||
} else if (clksel == RCC_D2CCIP2R_USARTSEL_PLL2Q) {
|
||||
case RCC_D2CCIP2R_USARTSEL_PLL2Q:
|
||||
return rcc_clock_tree.pll2.q_mhz * HZ_PER_MHZ;
|
||||
} else if (clksel == RCC_D2CCIP2R_USARTSEL_PLL3Q) {
|
||||
case RCC_D2CCIP2R_USARTSEL_PLL3Q:
|
||||
return rcc_clock_tree.pll3.q_mhz * HZ_PER_MHZ;
|
||||
} else if (clksel == RCC_D2CCIP2R_USARTSEL_HSI) {
|
||||
case RCC_D2CCIP2R_USARTSEL_HSI:
|
||||
return RCC_HSI_BASE_FREQUENCY;
|
||||
} else {
|
||||
return 0U;
|
||||
case RCC_D2CCIP2R_USARTSEL_CSI:
|
||||
return 4000000;
|
||||
case RCC_D2CCIP2R_USARTSEL_LSE:
|
||||
return 32768;
|
||||
}
|
||||
cm3_assert_not_reached();
|
||||
}
|
||||
|
||||
uint32_t rcc_get_timer_clk_freq(uint32_t timer __attribute__((unused)))
|
||||
|
||||
@@ -420,7 +420,7 @@ void rcc_set_lptim1_sel(uint32_t lptim1_sel)
|
||||
*/
|
||||
void rcc_set_lpuart1_sel(uint32_t lpuart1_sel)
|
||||
{
|
||||
RCC_CCIPR &= ~(RCC_CCIPR_LPUART1SEL_MASK << RCC_CCIPR_LPTIM1SEL_SHIFT);
|
||||
RCC_CCIPR &= ~(RCC_CCIPR_LPUARTxSEL_MASK << RCC_CCIPR_LPTIM1SEL_SHIFT);
|
||||
RCC_CCIPR |= (lpuart1_sel << RCC_CCIPR_LPTIM1SEL_SHIFT);
|
||||
}
|
||||
|
||||
@@ -431,7 +431,7 @@ void rcc_set_lpuart1_sel(uint32_t lpuart1_sel)
|
||||
*/
|
||||
void rcc_set_usart1_sel(uint32_t usart1_sel)
|
||||
{
|
||||
RCC_CCIPR &= ~(RCC_CCIPR_USART1SEL_MASK << RCC_CCIPR_USART1SEL_SHIFT);
|
||||
RCC_CCIPR &= ~(RCC_CCIPR_USARTxSEL_MASK << RCC_CCIPR_USART1SEL_SHIFT);
|
||||
RCC_CCIPR |= (usart1_sel << RCC_CCIPR_USART1SEL_SHIFT);
|
||||
}
|
||||
|
||||
@@ -442,7 +442,7 @@ void rcc_set_usart1_sel(uint32_t usart1_sel)
|
||||
*/
|
||||
void rcc_set_usart2_sel(uint32_t usart2_sel)
|
||||
{
|
||||
RCC_CCIPR &= ~(RCC_CCIPR_USART2SEL_MASK << RCC_CCIPR_USART2SEL_SHIFT);
|
||||
RCC_CCIPR &= ~(RCC_CCIPR_USARTxSEL_MASK << RCC_CCIPR_USART2SEL_SHIFT);
|
||||
RCC_CCIPR |= (usart2_sel << RCC_CCIPR_USART2SEL_SHIFT);
|
||||
}
|
||||
|
||||
@@ -464,27 +464,27 @@ void rcc_set_peripheral_clk_sel(uint32_t periph, uint32_t sel)
|
||||
|
||||
case I2C3_BASE:
|
||||
shift = RCC_CCIPR_I2C3SEL_SHIFT;
|
||||
mask = RCC_CCIPR_I2C3SEL_MASK;
|
||||
mask = RCC_CCIPR_I2CxSEL_MASK;
|
||||
break;
|
||||
|
||||
case I2C1_BASE:
|
||||
shift = RCC_CCIPR_I2C1SEL_SHIFT;
|
||||
mask = RCC_CCIPR_I2C1SEL_MASK;
|
||||
mask = RCC_CCIPR_I2CxSEL_MASK;
|
||||
break;
|
||||
|
||||
case LPUART1_BASE:
|
||||
shift = RCC_CCIPR_LPUART1SEL_SHIFT;
|
||||
mask = RCC_CCIPR_LPUART1SEL_MASK;
|
||||
mask = RCC_CCIPR_LPUARTxSEL_MASK;
|
||||
break;
|
||||
|
||||
case USART2_BASE:
|
||||
shift = RCC_CCIPR_USART2SEL_SHIFT;
|
||||
mask = RCC_CCIPR_USART2SEL_MASK;
|
||||
mask = RCC_CCIPR_USARTxSEL_MASK;
|
||||
break;
|
||||
|
||||
case USART1_BASE:
|
||||
shift = RCC_CCIPR_USART1SEL_SHIFT;
|
||||
mask = RCC_CCIPR_USART1SEL_MASK;
|
||||
mask = RCC_CCIPR_USARTxSEL_MASK;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -498,14 +498,14 @@ void rcc_set_peripheral_clk_sel(uint32_t periph, uint32_t sel)
|
||||
|
||||
/* Helper to calculate the frequency of a clksel based clock. */
|
||||
static uint32_t rcc_uart_i2c_clksel_freq_hz(uint32_t apb_clk, uint8_t shift) {
|
||||
uint8_t clksel = (RCC_CCIPR >> shift) & RCC_CCIPR_I2C1SEL_MASK;
|
||||
uint8_t clksel = (RCC_CCIPR >> shift) & RCC_CCIPR_I2CxSEL_MASK;
|
||||
uint8_t hpre = (RCC_CFGR >> RCC_CFGR_HPRE_SHIFT) & RCC_CFGR_HPRE_MASK;
|
||||
switch (clksel) {
|
||||
case RCC_CCIPR_USART1SEL_APB:
|
||||
case RCC_CCIPR_USARTxSEL_PCLK:
|
||||
return apb_clk;
|
||||
case RCC_CCIPR_USART1SEL_SYS:
|
||||
case RCC_CCIPR_USARTxSEL_SYSCLK:
|
||||
return rcc_ahb_frequency * rcc_get_div_from_hpre(hpre);
|
||||
case RCC_CCIPR_USART1SEL_HSI16:
|
||||
case RCC_CCIPR_USARTxSEL_HSI:
|
||||
return 16000000U;
|
||||
}
|
||||
cm3_assert_not_reached();
|
||||
@@ -520,9 +520,9 @@ uint32_t rcc_get_usart_clk_freq(uint32_t usart)
|
||||
if (usart == LPUART1_BASE) {
|
||||
return rcc_uart_i2c_clksel_freq_hz(rcc_apb1_frequency, RCC_CCIPR_LPUART1SEL_SHIFT);
|
||||
} else if (usart == USART1_BASE) {
|
||||
return rcc_uart_i2c_clksel_freq_hz(rcc_apb2_frequency, RCC_CCIPR_USART1SEL_SHIFT);
|
||||
return rcc_uart_i2c_clksel_freq_hz(rcc_apb2_frequency, RCC_CCIPR_USART1SEL_SHIFT);
|
||||
} else {
|
||||
return rcc_uart_i2c_clksel_freq_hz(rcc_apb1_frequency, RCC_CCIPR_USART2SEL_SHIFT);
|
||||
return rcc_uart_i2c_clksel_freq_hz(rcc_apb1_frequency, RCC_CCIPR_USART2SEL_SHIFT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user