git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@14372 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
Giovanni Di Sirio 2021-05-15 10:12:23 +00:00
parent 112f264974
commit 634a9b55d2
6 changed files with 643 additions and 43 deletions

View File

@ -289,7 +289,7 @@ extern "C" {
*/
static inline bool halClockSwitchMode(const halclkcfg_t *ccp) {
return hal_clock_switch_mode(ccp);
return hal_lld_clock_switch_mode(ccp);
}
/**
@ -301,7 +301,7 @@ static inline bool halClockSwitchMode(const halclkcfg_t *ccp) {
*
* @xclass
*/
static inline halfreq_t halClockGetPointX(halclkpoint_t clkpt) {
static inline halfreq_t halClockGetPointX(unsigned clkpt) {
return hal_lld_get_clock_point(clkpt);
}

View File

@ -407,6 +407,7 @@
#error "STM32_ST_USE_TIMER specifies an unsupported timer"
#endif
#if 0 /* TODO remove */
#if ST_CLOCK_SRC % OSAL_ST_FREQUENCY != 0
#error "the selected ST frequency is not obtainable because integer rounding"
#endif
@ -414,6 +415,7 @@
#if (ST_CLOCK_SRC / OSAL_ST_FREQUENCY) - 1 > 0xFFFF
#error "the selected ST frequency is not obtainable because TIM timer prescaler limits"
#endif
#endif
#endif /* OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING */
@ -486,6 +488,10 @@ void st_lld_init(void) {
#if OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING
/* Free running counter mode.*/
osalDbgAssert((ST_CLOCK_SRC % OSAL_ST_FREQUENCY) == 0U,
"clock rounding error");
osalDbgAssert(((ST_CLOCK_SRC / OSAL_ST_FREQUENCY) - 1U) < 0x10000,
"clock prescaler overflow");
/* Enabling timer clock.*/
ST_ENABLE_CLOCK();

View File

@ -38,10 +38,130 @@
*/
uint32_t SystemCoreClock = STM32_HCLK;
#if defined(HAL_LLD_USE_CLOCK_MANAGEMENT) || defined(__DOXYGEN__)
/**
* @brief Post-reset clock configuration.
*/
const halclkcfg_t hal_clkcfg_reset = {
.pwr_cr1 = PWR_CR1_VOS_0,
.pwr_cr2 = 0U,
.pwr_cr3 = PWR_CR3_EIWF,
.pwr_cr4 = 0U,
.pwr_cr5 = PWR_CR5_R1MODE,
.rcc_cr = RCC_CR_HSIKERON | RCC_CR_HSION,
.rcc_cfgr = RCC_CFGR_SW_HSI,
.rcc_pllcfgr = 0U,
.flash_acr = FLASH_ACR_DBG_SWEN | FLASH_ACR_DCEN |
FLASH_ACR_ICEN | FLASH_ACR_LATENCY_1WS
};
/**
* @brief Default clock configuration.
*/
const halclkcfg_t hal_clkcfg_default = {
.pwr_cr1 = STM32_VOS_RANGE1,
.pwr_cr2 = STM32_PWR_CR2,
.pwr_cr3 = STM32_PWR_CR3,
.pwr_cr4 = STM32_PWR_CR4,
.pwr_cr5 = STM32_CR5BITS,
.rcc_cr = 0U
#if STM32_HSI16_ENABLED
| RCC_CR_HSIKERON | RCC_CR_HSION
#endif
#if STM32_HSE_ENABLED
| RCC_CR_HSEON
#endif
#if STM32_ACTIVATE_PLL
| RCC_CR_PLLON
#endif
,
.rcc_cfgr = STM32_MCOPRE | STM32_MCOSEL |
STM32_PPRE2 | STM32_PPRE1 |
STM32_HPRE | STM32_SW,
.rcc_pllcfgr = STM32_PLLPDIV | STM32_PLLR |
STM32_PLLREN | STM32_PLLQ |
STM32_PLLQEN | STM32_PLLP |
STM32_PLLPEN | STM32_PLLN |
STM32_PLLM | STM32_PLLSRC,
.flash_acr = FLASH_ACR_DBG_SWEN | FLASH_ACR_DCEN |
FLASH_ACR_ICEN | FLASH_ACR_PRFTEN |
STM32_FLASHBITS
};
#endif /* defined(HAL_LLD_USE_CLOCK_MANAGEMENT) */
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
#if defined(HAL_LLD_USE_CLOCK_MANAGEMENT) || defined(__DOXYGEN__)
/**
* @brief Dynamic clock points for this device.
*/
static halfreq_t clock_points[CLK_ARRAY_SIZE];
/**
* @brief Type of a structure representing system limits.
*/
typedef struct {
halfreq_t sysclk_max_boost;
halfreq_t sysclk_max_noboost;
halfreq_t pllin_max;
halfreq_t pllin_min;
halfreq_t pllvco_max;
halfreq_t pllvco_min;
halfreq_t pllp_max;
halfreq_t pllp_min;
halfreq_t pllq_max;
halfreq_t pllq_min;
halfreq_t pllr_max;
halfreq_t pllr_min;
halfreq_t flash_thresholds[9];
} system_limits_t;
/**
* @brief System limits for VOS RANGE1.
*/
static const system_limits_t vos_range1 = {
.sysclk_max_boost = 170000000U,
.sysclk_max_noboost = 150000000U,
.pllin_max = 16000000U,
.pllin_min = 2660000U,
.pllvco_max = 344000000U,
.pllvco_min = 96000000U,
.pllp_max = 170000000U,
.pllp_min = 2064500U,
.pllq_max = 170000000U,
.pllq_min = 8000000U,
.pllr_max = 170000000U,
.pllr_min = 8000000U,
.flash_thresholds = { 20000000U, 40000000U, 60000000U, 80000000U,
100000000U, 120000000U, 140000000U, 160000000U,
170000000U}
};
/**
* @brief System limits for VOS RANGE2.
*/
static const system_limits_t vos_range2 = {
.sysclk_max_boost = 0U,
.sysclk_max_noboost = 26000000U,
.pllin_max = 16000000U,
.pllin_min = 2660000U,
.pllvco_max = 128000000U,
.pllvco_min = 96000000U,
.pllp_max = 26000000U,
.pllp_min = 2064500U,
.pllq_max = 26000000U,
.pllq_min = 8000000U,
.pllr_max = 26000000U,
.pllr_min = 8000000U,
.flash_thresholds = { 8000000U, 16000000U, 26000000U, 0U,
0U, 0U, 0U, 0U,
0U}
};
#endif /* defined(HAL_LLD_USE_CLOCK_MANAGEMENT) */
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
@ -85,6 +205,301 @@ __STATIC_INLINE void bd_init(void) {
RCC->BDCR = bdcr;
}
#if defined(HAL_LLD_USE_CLOCK_MANAGEMENT) || defined(__DOXYGEN__)
/**
* @brief Recalculates the clock tree frequencies.
*
* @param[in] ccp pointer to clock a @p halclkcfg_t structure
* @return The frequency calculation result.
* @retval false if the clock settings look valid
* @retval true if the clock settings look invalid
*
* @notapi
*/
bool hal_clock_check_tree(const halclkcfg_t *ccp) {
static const uint32_t hprediv[16] = {1U, 1U, 1U, 1U, 1U, 1U, 1U, 1U,
2U, 4U, 8U, 16U, 64U, 128U, 256U, 512U};
static const uint32_t pprediv[16] = {1U, 1U, 1U, 1U, 2U, 4U, 8U, 16U};
const system_limits_t *slp;
halfreq_t hsi16clk = 0U, hseclk = 0U, pllselclk;
halfreq_t pllpclk = 0U, pllqclk = 0U, pllrclk = 0U;
halfreq_t sysclk, hclk, pclk1, pclk2, pclk1tim, pclk2tim, mcoclk;
uint32_t mcodiv;
/* System limits based on desired VOS settings.*/
if ((ccp->pwr_cr1 & PWR_CR1_VOS_Msk) == PWR_CR1_VOS_1) {
slp = &vos_range2;
}
else if ((ccp->pwr_cr1 & PWR_CR1_VOS_Msk) == PWR_CR1_VOS_0) {
slp = &vos_range1;
}
else {
return true;
}
/* HSI16 clock.*/
if ((ccp->rcc_cr & RCC_CR_HSION) != 0U) {
hsi16clk = STM32_HSI16CLK;
}
/* HSE clock.*/
if ((ccp->rcc_cr & RCC_CR_HSEON) != 0U) {
hseclk = STM32_HSECLK;
}
/* PLL MUX clock.*/
switch (ccp->rcc_pllcfgr & RCC_PLLCFGR_PLLSRC_Msk) {
case RCC_PLLCFGR_PLLSRC_HSI:
pllselclk = hsi16clk;
break;
case RCC_PLLCFGR_PLLSRC_HSE:
pllselclk = hseclk;
break;
default:
pllselclk = 0U;
}
/* PLL outputs.*/
if ((ccp->rcc_cr & RCC_CR_PLLON) != 0U) {
uint32_t pllmdiv, pllndiv, pllpdiv, pllqdiv, pllrdiv;
halfreq_t pllvcoclk;
/* PLL M divider.*/
pllmdiv = ((ccp->rcc_pllcfgr & RCC_PLLCFGR_PLLM_Msk) >> RCC_PLLCFGR_PLLM_Pos) + 1U;
/* PLL N divider.*/
pllndiv = (ccp->rcc_pllcfgr & RCC_PLLCFGR_PLLN_Msk) >> RCC_PLLCFGR_PLLN_Pos;
if (pllndiv < 8) {
return true;
}
/* PLL VCO frequency.*/
pllvcoclk = (pllselclk / (halfreq_t)pllmdiv) * (halfreq_t)pllndiv;
if((pllvcoclk < slp->pllvco_min) || (pllvcoclk > slp->pllvco_max)) {
return true;
}
/* PLL P output frequency.*/
pllpdiv = (ccp->rcc_pllcfgr & RCC_PLLCFGR_PLLPDIV_Msk) >> RCC_PLLCFGR_PLLPDIV_Pos;
if (pllpdiv == 1U) {
return true;
}
if (pllpdiv == 0U) {
if ((ccp->rcc_pllcfgr & RCC_PLLCFGR_PLLP) == 0U) {
pllpdiv = 7U;
}
else {
pllpdiv = 17U;
}
}
if ((ccp->rcc_pllcfgr & RCC_PLLCFGR_PLLPEN) != 0U) {
pllpclk = pllvcoclk / pllpdiv;
if((pllpclk < slp->pllp_min) || (pllpclk > slp->pllp_max)) {
return true;
}
}
/* PLL Q output frequency.*/
pllqdiv = 2U + (2U * (ccp->rcc_pllcfgr & RCC_PLLCFGR_PLLQ_Msk) >> RCC_PLLCFGR_PLLQ_Pos);
if ((ccp->rcc_pllcfgr & RCC_PLLCFGR_PLLQEN) != 0U) {
pllqclk = pllvcoclk / pllqdiv;
if((pllqclk < slp->pllq_min) || (pllqclk > slp->pllq_max)) {
return true;
}
}
/* PLL R output frequency.*/
pllrdiv = 2U + (2U * (ccp->rcc_pllcfgr & RCC_PLLCFGR_PLLR_Msk) >> RCC_PLLCFGR_PLLR_Pos);
if ((ccp->rcc_pllcfgr & RCC_PLLCFGR_PLLREN) != 0U) {
pllrclk = pllvcoclk / pllrdiv;
if((pllrclk < slp->pllr_min) || (pllrclk > slp->pllr_max)) {
return true;
}
}
}
/* SYSCLK frequency.*/
switch(ccp->rcc_cfgr & RCC_CFGR_SW_Msk) {
case RCC_CFGR_SW_HSI:
sysclk = hsi16clk;
break;
case RCC_CFGR_SW_HSE:
sysclk = hseclk;
break;
case RCC_CFGR_SW_PLL:
sysclk = pllrclk;
break;
default:
sysclk = 0U;
}
if ((ccp->pwr_cr5 & PWR_CR5_R1MODE) == 0U) {
if (sysclk < slp->sysclk_max_boost) {
return true;
}
}
else {
if (sysclk < slp->sysclk_max_noboost) {
return true;
}
}
/* HCLK frequency.*/
hclk = sysclk / hprediv[(ccp->rcc_cfgr & RCC_CFGR_HPRE_Msk) >> RCC_CFGR_HPRE_Pos];
/* PPRE1 frequency.*/
pclk1 = hclk / pprediv[(ccp->rcc_cfgr & RCC_CFGR_PPRE1_Msk) >> RCC_CFGR_PPRE1_Pos];
if ((ccp->rcc_cfgr & RCC_CFGR_PPRE1_Msk) < RCC_CFGR_PPRE1_DIV2) {
pclk1tim = pclk1;
}
else {
pclk1tim = pclk1 * 2U;
}
/* PPRE2 frequency.*/
pclk2 = hclk / pprediv[(ccp->rcc_cfgr & RCC_CFGR_PPRE2_Msk) >> RCC_CFGR_PPRE2_Pos];
if ((ccp->rcc_cfgr & RCC_CFGR_PPRE1_Msk) < RCC_CFGR_PPRE2_DIV2) {
pclk2tim = pclk2;
}
else {
pclk2tim = pclk2 * 2U;
}
/* MCO clock.*/
switch(ccp->rcc_cfgr & RCC_CFGR_MCOSEL_Msk) {
case STM32_MCOSEL_NOCLOCK:
mcoclk = 0U;
break;
case STM32_MCOSEL_SYSCLK:
mcoclk = sysclk;
break;
case STM32_MCOSEL_HSI16:
mcoclk = hsi16clk;
break;
case STM32_MCOSEL_HSE:
mcoclk = hseclk;
break;
case STM32_MCOSEL_PLLRCLK:
mcoclk = pllrclk;
break;
case STM32_MCOSEL_LSI:
mcoclk = STM32_LSICLK;
break;
case STM32_MCOSEL_LSE:
mcoclk = STM32_LSECLK;
break;
case STM32_MCOSEL_HSI48:
mcoclk = STM32_HSI48CLK;
break;
default:
mcoclk = 0U;
}
mcodiv = 1U << ((ccp->rcc_cfgr & RCC_CFGR_MCOPRE_Msk) >> RCC_CFGR_MCOPRE_Pos);
if (mcodiv > 16U) {
return true;
}
mcoclk /= mcodiv;
/* Writing out results.*/
clock_points[CLK_SYSCLK] = sysclk;
clock_points[CLK_PLLPCLK] = pllpclk;
clock_points[CLK_PLLQCLK] = pllqclk;
clock_points[CLK_PLLRCLK] = pllrclk;
clock_points[CLK_HCLK] = hclk;
clock_points[CLK_PCLK1] = pclk1;
clock_points[CLK_PCLK1TIM] = pclk1tim;
clock_points[CLK_PCLK2] = pclk2;
clock_points[CLK_PCLK2TIM] = pclk2tim;
clock_points[CLK_MCO] = mcoclk;
return false;
}
/**
* @brief Switches to a different clock configuration.
*
* @param[in] ccp pointer to clock a @p halclkcfg_t structure
* @return The clock switch result.
* @retval false if the clock switch succeeded
* @retval true if the clock switch failed
*
* @notapi
*/
bool hal_lld_clock_raw_switch(const halclkcfg_t *ccp) {
/* Restoring default PWR settings related clocks and sleep modes.*/
PWR->CR1 = PWR_CR1_VOS_0;
PWR->CR2 = 0U;
PWR->CR3 = PWR_CR3_EIWF;
PWR->CR4 = 0U;
/* Making sure HSI is activated.*/
RCC->CR |= RCC_CR_HSION;
while ((RCC->CR & RCC_CR_HSIRDY) == 0U) {
}
/* Disabling boost mode.*/
PWR->CR5 = PWR_CR5_R1MODE;
/* Switching to the HSI oscillator.*/
RCC->CFGR = (RCC->CFGR & ~RCC_CFGR_SW_Msk) | RCC_CFGR_SW_HSI;
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI) {
/* Waiting for clock switch.*/
}
/* Resetting flash ACR settings to the default value.*/
FLASH->ACR = 0x00040601U;
/* HSE setup.*/
if ((ccp->rcc_cr & RCC_CR_HSEON) == 0U) {
RCC->CR &= ~RCC_CR_HSEON;
}
else {
RCC->CR |= RCC_CR_HSEON;
while ((RCC->CR & RCC_CR_HSERDY) == 0U) {
/* Waiting for HSE activation.*/
}
}
/* PLL setup.*/
RCC->PLLCFGR = ccp->rcc_pllcfgr;
/* HSI, HSE, PLL enabled if specified.*/
RCC->CR = ccp->rcc_cr;
/* PLL activation polling if required.*/
if ((ccp->rcc_cr & RCC_CR_PLLON) != 0U) {
while ((RCC->CR & RCC_CR_PLLRDY) == 0U) {
/* Waiting for PLL lock.*/
}
}
/* MCO and bus dividers first.*/
RCC->CFGR = (RCC->CFGR & RCC_CFGR_SW_Msk) | (ccp->rcc_cfgr & ~RCC_CFGR_SW_Msk);
/* Final flash ACR settings.*/
FLASH->ACR = ccp->flash_acr;
/* Final PWR modes.*/
PWR->CR1 = ccp->pwr_cr1;
PWR->CR2 = ccp->pwr_cr2;
PWR->CR3 = ccp->pwr_cr3;
PWR->CR4 = ccp->pwr_cr4;
PWR->CR5 = ccp->pwr_cr5;
/* Switching to the final clock source.*/
RCC->CFGR = (RCC->CFGR & ~RCC_CFGR_SW_Msk) | (ccp->rcc_cfgr & RCC_CFGR_SW_Msk);
while ((RCC->CFGR & RCC_CFGR_SWS) != ((ccp->rcc_cfgr & RCC_CFGR_SW_Msk) << RCC_CFGR_SWS_Pos)) {
/* Waiting for clock switch.*/
}
return false;
}
#endif /* defined(HAL_LLD_USE_CLOCK_MANAGEMENT) */
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
@ -100,6 +515,12 @@ __STATIC_INLINE void bd_init(void) {
*/
void hal_lld_init(void) {
#if defined(HAL_LLD_USE_CLOCK_MANAGEMENT)
if (hal_clock_check_tree(&hal_clkcfg_default)) {
osalSysHalt("clkcfg");
}
#endif
/* DMA subsystems initialization.*/
#if defined(STM32_DMA_REQUIRED)
dmaInit();
@ -112,6 +533,7 @@ void hal_lld_init(void) {
irqInit();
}
#if defined(HAL_LLD_USE_CLOCK_MANAGEMENT) || defined(__DOXYGEN__)
/**
* @brief STM32L4xx clocks and PLL initialization.
* @note All the involved constants come from the file @p board.h.
@ -121,6 +543,51 @@ void hal_lld_init(void) {
*/
void stm32_clock_init(void) {
#if !STM32_NO_INIT
/* Reset of all peripherals.
Note, GPIOs are not reset because initialized before this point in
board files.*/
rccResetAHB1(~0);
rccResetAHB2(~STM32_GPIO_EN_MASK);
rccResetAHB3(~0);
rccResetAPB1R1(~0);
rccResetAPB1R2(~0);
rccResetAPB2(~0);
/* SYSCFG clock enabled here because it is a multi-functional unit shared
among multiple drivers.*/
rccEnableAPB2(RCC_APB2ENR_SYSCFGEN, false);
/* PWR clock enable.*/
#if (HAL_USE_RTC == TRUE) && defined(RCC_APBENR1_RTCAPBEN)
rccEnableAPB1R1(RCC_APB1ENR1_PWREN | RCC_APB1ENR1_RTCAPBEN, false)
#else
rccEnableAPB1R1(RCC_APB1ENR1_PWREN, false)
#endif
/* Backup domain made accessible.*/
PWR->CR1 |= PWR_CR1_DBP;
/* Backup domain reset.*/
bd_reset();
/* Static clocks setup.*/
lse_init();
lsi_init();
/* Selecting the default clock/power/flash configuration.*/
if (hal_lld_clock_raw_switch(&hal_clkcfg_default)) {
osalSysHalt("clkswc");
}
/* Backup domain initializations.*/
bd_init();
#endif /* STM32_NO_INIT */
}
#else /* !defined(HAL_LLD_USE_CLOCK_MANAGEMENT) */
void stm32_clock_init(void) {
#if !STM32_NO_INIT
/* Reset of all peripherals.
@ -201,5 +668,47 @@ void stm32_clock_init(void) {
#endif /* STM32_NO_INIT */
}
#endif /* !defined(HAL_LLD_USE_CLOCK_MANAGEMENT) */
#if defined(HAL_LLD_USE_CLOCK_MANAGEMENT) || defined(__DOXYGEN__)
/**
* @brief Switches to a different clock configuration
*
* @param[in] ccp pointer to clock a @p halclkcfg_t structure
* @return The clock switch result.
* @retval false if the clock switch succeeded
* @retval true if the clock switch failed
*
* @notapi
*/
bool hal_lld_clock_switch_mode(const halclkcfg_t *ccp) {
if (hal_clock_check_tree(ccp)) {
return true;
}
if (hal_lld_clock_raw_switch(ccp)) {
return true;
}
return false;
}
/**
* @brief Returns the frequency of a clock point in Hz.
*
* @param[in] clkpt clock point to be returned
* @return The clock point frequency in Hz or zero if the
* frequency is unknown.
*
* @notapi
*/
halfreq_t hal_lld_get_clock_point(unsigned clkpt) {
osalDbgAssert(clkpt < CLK_ARRAY_SIZE, "invalid clock point");
return clock_points[clkpt];
}
#endif /* defined(HAL_LLD_USE_CLOCK_MANAGEMENT) */
/** @} */

View File

@ -80,6 +80,23 @@
#endif
/** @} */
/**
* @name Clock points names
* @{
*/
#define CLK_SYSCLK 0U
#define CLK_PLLPCLK 1U
#define CLK_PLLQCLK 2U
#define CLK_PLLRCLK 3U
#define CLK_HCLK 4U
#define CLK_PCLK1 5U
#define CLK_PCLK1TIM 6U
#define CLK_PCLK2 7U
#define CLK_PCLK2TIM 8U
#define CLK_MCO 9U
#define CLK_ARRAY_SIZE 10U
/** @} */
/**
* @name VOS field definitions
* @{
@ -266,6 +283,13 @@
#define STM32_NO_INIT FALSE
#endif
/**
* @brief Enables the dynamic clock handling.
*/
#if !defined(STM32_CLOCK_DYNAMIC) || defined(__DOXYGEN__)
#define STM32_CLOCK_DYNAMIC FALSE
#endif
/**
* @brief Core voltage selection.
* @note This setting affects all the performance and clock related
@ -590,6 +614,11 @@
/* Derived constants and error checks. */
/*===========================================================================*/
/* Clock handling mode selection.*/
#if STM32_CLOCK_DYNAMIC == TRUE
#define HAL_LLD_USE_CLOCK_MANAGEMENT
#endif
/*
* Configuration-related checks.
*/
@ -762,7 +791,7 @@
#elif STM32_VOS == STM32_VOS_RANGE2
#define STM32_SYSCLK_MAX 26000000
#define STM32_SYSCLK_MAX_NOBOOST 150000000
#define STM32_SYSCLK_MAX_NOBOOST 26000000
#define STM32_HSECLK_MAX 26000000
#define STM32_HSECLK_BYP_MAX 26000000
#define STM32_HSECLK_MIN 8000000
@ -1069,7 +1098,7 @@
#define STM32_MCODIVCLK 0
#elif STM32_MCOSEL == STM32_MCOSEL_SYSCLK
#define STM32_MCODIVCLK STM32_SYSCLK
#define STM32_MCODIVCLK hal_lld_get_clock_point(CLK_SYSCLK)
#elif STM32_MCOSEL == STM32_MCOSEL_HSI16
#define STM32_MCODIVCLK STM32_HSI16CLK
@ -1078,7 +1107,7 @@
#define STM32_MCODIVCLK STM32_HSECLK
#elif STM32_MCOSEL == STM32_MCOSEL_PLLRCLK
#define STM32_MCODIVCLK STM32_PLL_R_CLKOUT
#define STM32_MCODIVCLK hal_lld_get_clock_point(CLK_PLLRCLK)
#elif STM32_MCOSEL == STM32_MCOSEL_LSI
#define STM32_MCODIVCLK STM32_LSICLK
@ -1138,10 +1167,10 @@
* @brief USART1 clock frequency.
*/
#if (STM32_USART1SEL == STM32_USART1SEL_PCLK2) || defined(__DOXYGEN__)
#define STM32_USART1CLK STM32_PCLK2
#define STM32_USART1CLK hal_lld_get_clock_point(CLK_PCLK2)
#elif STM32_USART1SEL == STM32_USART1SEL_SYSCLK
#define STM32_USART1CLK STM32_SYSCLK
#define STM32_USART1CLK hal_lld_get_clock_point(CLK_SYSCLK)
#elif STM32_USART1SEL == STM32_USART1SEL_HSI16
#define STM32_USART1CLK STM32_HSI16CLK
@ -1157,10 +1186,10 @@
* @brief USART2 clock frequency.
*/
#if (STM32_USART2SEL == STM32_USART2SEL_PCLK1) || defined(__DOXYGEN__)
#define STM32_USART2CLK STM32_PCLK1
#define STM32_USART2CLK hal_lld_get_clock_point(CLK_PCLK1)
#elif STM32_USART2SEL == STM32_USART2SEL_SYSCLK
#define STM32_USART2CLK STM32_SYSCLK
#define STM32_USART2CLK hal_lld_get_clock_point(CLK_SYSCLK)
#elif STM32_USART2SEL == STM32_USART2SEL_HSI16
#define STM32_USART2CLK STM32_HSI16CLK
@ -1176,10 +1205,10 @@
* @brief USART3 clock frequency.
*/
#if (STM32_USART3SEL == STM32_USART3SEL_PCLK1) || defined(__DOXYGEN__)
#define STM32_USART3CLK STM32_PCLK1
#define STM32_USART3CLK hal_lld_get_clock_point(CLK_PCLK1)
#elif STM32_USART3SEL == STM32_USART3SEL_SYSCLK
#define STM32_USART3CLK STM32_SYSCLK
#define STM32_USART3CLK hal_lld_get_clock_point(CLK_SYSCLK)
#elif STM32_USART3SEL == STM32_USART3SEL_HSI16
#define STM32_USART3CLK STM32_HSI16CLK
@ -1195,10 +1224,10 @@
* @brief UART4 clock frequency.
*/
#if (STM32_UART4SEL == STM32_UART4SEL_PCLK1) || defined(__DOXYGEN__)
#define STM32_UART4CLK STM32_PCLK1
#define STM32_UART4CLK hal_lld_get_clock_point(CLK_PCLK1)
#elif STM32_UART4SEL == STM32_UART4SEL_SYSCLK
#define STM32_UART4CLK STM32_SYSCLK
#define STM32_UART4CLK hal_lld_get_clock_point(CLK_SYSCLK)
#elif STM32_UART4SEL == STM32_UART4SEL_HSI16
#define STM32_UART4CLK STM32_HSI16CLK
@ -1214,10 +1243,10 @@
* @brief UART5 clock frequency.
*/
#if (STM32_UART5SEL == STM32_UART5SEL_PCLK1) || defined(__DOXYGEN__)
#define STM32_UART5CLK STM32_PCLK1
#define STM32_UART5CLK hal_lld_get_clock_point(CLK_PCLK1)
#elif STM32_UART5SEL == STM32_UART5SEL_SYSCLK
#define STM32_UART5CLK STM32_SYSCLK
#define STM32_UART5CLK hal_lld_get_clock_point(CLK_SYSCLK)
#elif STM32_UART5SEL == STM32_UART5SEL_HSI16
#define STM32_UART5CLK STM32_HSI16CLK
@ -1233,10 +1262,10 @@
* @brief LPUART1 clock frequency.
*/
#if (STM32_LPUART1SEL == STM32_LPUART1SEL_PCLK1) || defined(__DOXYGEN__)
#define STM32_LPUART1CLK STM32_PCLK1
#define STM32_LPUART1CLK hal_lld_get_clock_point(CLK_PCLK1)
#elif STM32_LPUART1SEL == STM32_LPUART1SEL_SYSCLK
#define STM32_LPUART1CLK STM32_SYSCLK
#define STM32_LPUART1CLK hal_lld_get_clock_point(CLK_SYSCLK)
#elif STM32_LPUART1SEL == STM32_LPUART1SEL_HSI16
#define STM32_LPUART1CLK STM32_HSI16CLK
@ -1252,10 +1281,10 @@
* @brief I2C1 clock frequency.
*/
#if (STM32_I2C1SEL == STM32_I2C1SEL_PCLK1) || defined(__DOXYGEN__)
#define STM32_I2C1CLK STM32_PCLK1
#define STM32_I2C1CLK hal_lld_get_clock_point(CLK_PCLK1)
#elif STM32_I2C1SEL == STM32_I2C1SEL_SYSCLK
#define STM32_I2C1CLK STM32_SYSCLK
#define STM32_I2C1CLK hal_lld_get_clock_point(CLK_SYSCLK)
#elif STM32_I2C1SEL == STM32_I2C1SEL_HSI16
#define STM32_I2C1CLK STM32_HSI16CLK
@ -1268,10 +1297,10 @@
* @brief I2C2 clock frequency.
*/
#if (STM32_I2C2SEL == STM32_I2C2SEL_PCLK1) || defined(__DOXYGEN__)
#define STM32_I2C2CLK STM32_PCLK1
#define STM32_I2C2CLK hal_lld_get_clock_point(CLK_PCLK1)
#elif STM32_I2C2SEL == STM32_I2C2SEL_SYSCLK
#define STM32_I2C2CLK STM32_SYSCLK
#define STM32_I2C2CLK hal_lld_get_clock_point(CLK_SYSCLK)
#elif STM32_I2C2SEL == STM32_I2C2SEL_HSI16
#define STM32_I2C2CLK STM32_HSI16CLK
@ -1284,10 +1313,10 @@
* @brief I2C3 clock frequency.
*/
#if (STM32_I2C3SEL == STM32_I2C3SEL_PCLK1) || defined(__DOXYGEN__)
#define STM32_I2C3CLK STM32_PCLK1
#define STM32_I2C3CLK hal_lld_get_clock_point(CLK_PCLK1)
#elif STM32_I2C3SEL == STM32_I2C3SEL_SYSCLK
#define STM32_I2C3CLK STM32_SYSCLK
#define STM32_I2C3CLK hal_lld_get_clock_point(CLK_SYSCLK)
#elif STM32_I2C3SEL == STM32_I2C3SEL_HSI16
#define STM32_I2C3CLK STM32_HSI16CLK
@ -1300,10 +1329,10 @@
* @brief I2C4 clock frequency.
*/
#if (STM32_I2C4SEL == STM32_I2C4SEL_PCLK1) || defined(__DOXYGEN__)
#define STM32_I2C4CLK STM32_PCLK1
#define STM32_I2C4CLK hal_lld_get_clock_point(CLK_PCLK1)
#elif STM32_I2C4SEL == STM32_I2C4SEL_SYSCLK
#define STM32_I2C4CLK STM32_SYSCLK
#define STM32_I2C4CLK hal_lld_get_clock_point(CLK_SYSCLK)
#elif STM32_I2C4SEL == STM32_I2C4SEL_HSI16
#define STM32_I2C4CLK STM32_HSI16CLK
@ -1316,7 +1345,7 @@
* @brief LPTIM1 clock frequency.
*/
#if (STM32_LPTIM1SEL == STM32_LPTIM1SEL_PCLK1) || defined(__DOXYGEN__)
#define STM32_LPTIM1CLK STM32_PCLK1
#define STM32_LPTIM1CLK hal_lld_get_clock_point(CLK_PCLK1
#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_LSI
#define STM32_LPTIM1CLK STM32_LSICLK
@ -1335,10 +1364,10 @@
* @brief SAI1 clock frequency.
*/
#if (STM32_SAI1SEL == STM32_SAI1SEL_SYSCLK) || defined(__DOXYGEN__)
#define STM32_SAI1CLK STM32_SYSCLK
#define STM32_SAI1CLK hal_lld_get_clock_point(CLK_SYSCLK)
#elif STM32_SAI1SEL == STM32_SAI1SEL_PLLQCLK
#define STM32_SAI1CLK STM32_PLL_Q_CLKOUT
#define STM32_SAI1CLK hal_lld_get_clock_point(CLK_PLLQCLK)
#elif STM32_SAI1SEL == STM32_SAI1SEL_HSI16
#define STM32_SAI1CLK STM32_HSI16CLK
@ -1354,10 +1383,10 @@
* @brief I2S23 clock frequency.
*/
#if (STM32_I2S23SEL == STM32_I2S23SEL_SYSCLK) || defined(__DOXYGEN__)
#define STM32_I2S23CLK STM32_SYSCLK
#define STM32_I2S23CLK hal_lld_get_clock_point(CLK_SYSCLK)
#elif STM32_I2S23SEL == STM32_I2S23SEL_PLLPCLK
#define STM32_I2S23CLK STM32_PLL_P_CLKOUT
#define STM32_I2S23CLK hal_lld_get_clock_point(CLK_PLLPCLK)
#elif STM32_I2S23SEL == STM32_I2S23SEL_HSI16
#define STM32_I2S23CLK STM32_HSI16CLK
@ -1376,10 +1405,10 @@
#define STM32_FDCANCLK STM32_HSECLK
#elif STM32_FDCANSEL == STM32_FDCANSEL_PLLQCLK
#define STM32_FDCANCLK STM32_PLL_Q_CLKOUT
#define STM32_FDCANCLK hal_lld_get_clock_point(CLK_PLLQCLK)
#elif STM32_FDCANSEL == STM32_FDCANSEL_PCLK1
#define STM32_FDCANCLK STM32_PCLK1
#define STM32_FDCANCLK hal_lld_get_clock_point(CLK_PCLK1)
#else
#error "invalid source selected for FDCAN clock"
@ -1392,7 +1421,7 @@
#define STM32_48CLK STM32_HSI48CLK
#elif STM32_CLK48SEL == STM32_CLK48SEL_PLLQCLK
#define STM32_48CLK STM32_PLL_Q_CLKOUT
#define STM32_48CLK hal_lld_get_clock_point(CLK_PLLQCLK)
#else
#error "invalid source selected for 48MHz clock"
@ -1405,10 +1434,10 @@
#define STM32_ADC12CLK 0
#elif STM32_ADC12SEL == STM32_ADC12SEL_PLLPCLK
#define STM32_ADC12CLK STM32_PLL_P_CLKOUT
#define STM32_ADC12CLK hal_lld_get_clock_point(CLK_PLLPCLK)
#elif STM32_ADC12SEL == STM32_ADC12SEL_SYSCLK
#define STM32_ADC12CLK STM32_SYSCLK
#define STM32_ADC12CLK hal_lld_get_clock_point(CLK_SYSCLK)
#else
#error "invalid source selected for ADC clock"
@ -1421,10 +1450,10 @@
#define STM32_ADC345CLK 0
#elif STM32_ADC345SEL == STM32_ADC345SEL_PLLPCLK
#define STM32_ADC345CLK STM32_PLL_P_CLKOUT
#define STM32_ADC345CLK hal_lld_get_clock_point(CLK_PLLPCLK)
#elif STM32_ADC345SEL == STM32_ADC345SEL_SYSCLK
#define STM32_ADC345CLK STM32_SYSCLK
#define STM32_ADC345CLK hal_lld_get_clock_point(CLK_SYSCLK)
#else
#error "invalid source selected for ADC clock"
@ -1451,12 +1480,12 @@
/**
* @brief Clock of timers connected to APB1.
*/
#define STM32_TIMCLK1 STM32_TIMP1CLK
#define STM32_TIMCLK1 hal_lld_get_clock_point(CLK_PCLK1TIM)
/**
* @brief Clock of timers connected to APB2.
*/
#define STM32_TIMCLK2 STM32_TIMP2CLK
#define STM32_TIMCLK2 hal_lld_get_clock_point(CLK_PCLK2TIM)
/**
* @brief RNG clock point.
@ -1513,10 +1542,57 @@
/* Driver data structures and types. */
/*===========================================================================*/
#if defined(HAL_LLD_USE_CLOCK_MANAGEMENT) || defined(__DOXYGEN__)
/**
* @brief Type of a clock point frequency in Hz.
*/
typedef uint32_t halfreq_t;
/**
* @brief Type of a clock configuration structure.
*/
typedef struct {
uint32_t pwr_cr1;
uint32_t pwr_cr2;
uint32_t pwr_cr3;
uint32_t pwr_cr4;
uint32_t pwr_cr5;
uint32_t rcc_cr;
uint32_t rcc_cfgr;
uint32_t rcc_pllcfgr;
uint32_t flash_acr;
} halclkcfg_t;
#endif /* defined(HAL_LLD_USE_CLOCK_MANAGEMENT) */
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
#if !defined(HAL_LLD_USE_CLOCK_MANAGEMENT)
/**
* @brief Returns the frequency of a clock point in Hz.
* @note Static implementation.
*
* @param[in] clkpt clock point to be returned
* @return The clock point frequency in Hz or zero if the
* frequency is unknown.
*
* @notapi
*/
#define hal_lld_get_clock_point(clkpt) \
((clkpt) == CLK_SYSCLK ? STM32_SYSCLK : \
(clkpt) == CLK_PLLPCLK ? STM32_PLL_P_CLKOUT : \
(clkpt) == CLK_PLLQCLK ? STM32_PLL_Q_CLKOUT : \
(clkpt) == CLK_PLLRCLK ? STM32_PLL_R_CLKOUT : \
(clkpt) == CLK_HCLK ? STM32_HCLK : \
(clkpt) == CLK_PCLK1 ? STM32_PCLK1 : \
(clkpt) == CLK_PCLK1TIM ? STM32_TIMP1CLK : \
(clkpt) == CLK_PCLK2 ? STM32_PCLK2 : \
(clkpt) == CLK_PCLK2TIM ? STM32_TIMP2CLK : \
(clkpt) == CLK_MCO ? STM32_MCOCLK : \
0U)
#endif /* !defined(HAL_LLD_USE_CLOCK_MANAGEMENT) */
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
@ -1531,11 +1607,20 @@
#include "stm32_rcc.h"
#include "stm32_tim.h"
#if defined(HAL_LLD_USE_CLOCK_MANAGEMENT) && !defined(__DOXYGEN__)
extern const halclkcfg_t hal_clkcfg_reset;
extern const halclkcfg_t hal_clkcfg_default;
#endif
#ifdef __cplusplus
extern "C" {
#endif
void hal_lld_init(void);
void stm32_clock_init(void);
#if defined(HAL_LLD_USE_CLOCK_MANAGEMENT) || defined(__DOXYGEN__)
bool hal_lld_clock_switch_mode(const halclkcfg_t *ccp);
halfreq_t hal_lld_get_clock_point(unsigned clkpt);
#endif /* defined(HAL_LLD_USE_CLOCK_MANAGEMENT) */
#ifdef __cplusplus
}
#endif

View File

@ -84,7 +84,7 @@ void hal_lld_init(void) {
*
* @notapi
*/
bool hal_clock_switch_mode(const halclkcfg_t *ccp) {
bool hal_lld_clock_switch_mode(const halclkcfg_t *ccp) {
(void)ccp;
@ -100,7 +100,7 @@ bool hal_clock_switch_mode(const halclkcfg_t *ccp) {
*
* @notapi
*/
halfreq_t hal_lld_get_clock_point(halclkpoint_t clkpt) {
halfreq_t hal_lld_get_clock_point(unsigned clkpt) {
(void)clkpt;

View File

@ -106,8 +106,8 @@ extern "C" {
#endif
void hal_lld_init(void);
#if defined(HAL_LLD_USE_CLOCK_MANAGEMENT) || defined(__DOXYGEN__)
bool hal_clock_switch_mode(const halclkcfg_t *ccp);
halfreq_t hal_lld_get_clock_point(halclkpoint_t clkpt);
bool hal_lld_clock_switch_mode(const halclkcfg_t *ccp);
halfreq_t hal_lld_get_clock_point(unsigned clkpt);
#endif /* defined(HAL_LLD_USE_CLOCK_MANAGEMENT) */
#ifdef __cplusplus
}