drivers: clock_control: stm32: Add HSE CSS support
Add support for enabling the clock security system, which can detect failures of the HSE clock. Includes tests for nucleo_h743zi and nucleo_g474re. Signed-off-by: Kevin ORourke <kevin.orourke@ferroamp.se>
This commit is contained in:
parent
c758f1cc14
commit
fbfd36e81e
|
@ -10,6 +10,8 @@ menuconfig CLOCK_CONTROL_STM32_CUBE
|
|||
select USE_STM32_LL_UTILS
|
||||
select USE_STM32_LL_RCC if (SOC_SERIES_STM32MP1X || SOC_SERIES_STM32H7X || \
|
||||
SOC_SERIES_STM32F4X || SOC_SERIES_STM32F7X)
|
||||
select RUNTIME_NMI if ($(dt_nodelabel_enabled,clk_hse) && \
|
||||
$(dt_nodelabel_has_prop,clk_hse,css-enabled))
|
||||
help
|
||||
Enable driver for Reset & Clock Control subsystem found
|
||||
in STM32 family of MCUs
|
||||
|
|
|
@ -567,6 +567,11 @@ static void set_up_fixed_clock_sources(void)
|
|||
while (LL_RCC_HSE_IsReady() != 1) {
|
||||
/* Wait for HSE ready */
|
||||
}
|
||||
/* Check if we need to enable HSE clock security system or not */
|
||||
#if STM32_HSE_CSS
|
||||
z_arm_nmi_set_handler(HAL_RCC_NMI_IRQHandler);
|
||||
LL_RCC_HSE_EnableCSS();
|
||||
#endif /* STM32_HSE_CSS */
|
||||
}
|
||||
|
||||
if (IS_ENABLED(STM32_HSI_ENABLED)) {
|
||||
|
@ -817,6 +822,16 @@ int stm32_clock_control_init(const struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if defined(STM32_HSE_CSS)
|
||||
void __weak stm32_hse_css_callback(void) {}
|
||||
|
||||
/* Called by the HAL in response to an HSE CSS interrupt */
|
||||
void HAL_RCC_CSSCallback(void)
|
||||
{
|
||||
stm32_hse_css_callback();
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief RCC device, note that priority is intentionally set to 1 so
|
||||
* that the device init runs just after SOC init
|
||||
|
|
|
@ -586,6 +586,11 @@ static void set_up_fixed_clock_sources(void)
|
|||
LL_RCC_HSE_Enable();
|
||||
while (LL_RCC_HSE_IsReady() != 1) {
|
||||
}
|
||||
/* Check if we need to enable HSE clock security system or not */
|
||||
#if STM32_HSE_CSS
|
||||
z_arm_nmi_set_handler(HAL_RCC_NMI_IRQHandler);
|
||||
LL_RCC_HSE_EnableCSS();
|
||||
#endif /* STM32_HSE_CSS */
|
||||
}
|
||||
|
||||
if (IS_ENABLED(STM32_HSI_ENABLED)) {
|
||||
|
@ -930,6 +935,16 @@ int stm32_clock_control_init(const struct device *dev)
|
|||
}
|
||||
#endif /* CONFIG_CPU_CORTEX_M7 */
|
||||
|
||||
#if defined(STM32_HSE_CSS)
|
||||
void __weak stm32_hse_css_callback(void) {}
|
||||
|
||||
/* Called by the HAL in response to an HSE CSS interrupt */
|
||||
void HAL_RCC_CSSCallback(void)
|
||||
{
|
||||
stm32_hse_css_callback();
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief RCC device, note that priority is intentionally set to 1 so
|
||||
* that the device init runs just after SOC init
|
||||
|
|
|
@ -13,3 +13,19 @@ properties:
|
|||
description: |
|
||||
HSE crystal oscillator bypass
|
||||
Set to the property to by-pass the oscillator with an external clock.
|
||||
|
||||
css-enabled:
|
||||
type: boolean
|
||||
description: |
|
||||
HSE clock security system enabled
|
||||
Set the property to enable the clock security system (CSS) for the HSE clock.
|
||||
|
||||
If a failure is detected on the HSE clock, the HSE oscillator is automatically disabled,
|
||||
a clock failure event is sent to timers, and a non-maskable interrupt is generated to
|
||||
inform the software about the failure, allowing the MCU to perform rescue operations.
|
||||
See the MCU reference manual for details.
|
||||
|
||||
The interaction of CSS and low-power modes is unclear from the documentation.
|
||||
For at least some devices Zephyr will reconfigure the clocks on resuming from low-power
|
||||
modes; this will include re-enabling CSS. However it is important that you verify
|
||||
this for your own hardware.
|
||||
|
|
|
@ -369,6 +369,7 @@
|
|||
#define STM32_HSE_ENABLED 1
|
||||
#define STM32_HSE_BYPASS DT_PROP(DT_NODELABEL(clk_hse), hse_bypass)
|
||||
#define STM32_HSE_FREQ DT_PROP(DT_NODELABEL(clk_hse), clock_frequency)
|
||||
#define STM32_HSE_CSS DT_PROP(DT_NODELABEL(clk_hse), css_enabled)
|
||||
#elif DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(clk_hse), st_stm32wl_hse_clock, okay)
|
||||
#define STM32_HSE_ENABLED 1
|
||||
#define STM32_HSE_TCXO DT_PROP(DT_NODELABEL(clk_hse), hse_tcxo)
|
||||
|
@ -460,4 +461,16 @@ struct stm32_pclken {
|
|||
#define STM32_CLOCK_VAL_GET(clock) \
|
||||
(((clock) >> STM32_CLOCK_VAL_SHIFT) & STM32_CLOCK_VAL_MASK)
|
||||
|
||||
#if defined(STM32_HSE_CSS)
|
||||
/**
|
||||
* @brief Called if the HSE clock security system detects a clock fault.
|
||||
*
|
||||
* The function is called in interrupt context.
|
||||
*
|
||||
* The default (weakly-linked) implementation does nothing and should be
|
||||
* overridden.
|
||||
*/
|
||||
void stm32_hse_css_callback(void);
|
||||
#endif
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_STM32_CLOCK_CONTROL_H_ */
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Ferroamp AB (publ)
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
* Warning: This overlay assumes the HSE clock has already been enabled,
|
||||
* for example by hse_24.overlay.
|
||||
*/
|
||||
|
||||
&clk_hse {
|
||||
css-enabled;
|
||||
};
|
|
@ -105,4 +105,17 @@ ZTEST(stm32_sysclck_config, test_pll_src)
|
|||
#endif
|
||||
|
||||
}
|
||||
|
||||
#if STM32_HSE_ENABLED
|
||||
ZTEST(stm32_sysclck_config, test_hse_css)
|
||||
{
|
||||
/* there is no function to read CSS status, so read directly from the register */
|
||||
#if STM32_HSE_CSS
|
||||
zassert_true(READ_BIT(RCC->CR, RCC_CR_CSSON), "HSE CSS is not enabled");
|
||||
#else
|
||||
zassert_false(READ_BIT(RCC->CR, RCC_CR_CSSON), "HSE CSS unexpectedly enabled");
|
||||
#endif /* STM32_HSE_CSS */
|
||||
|
||||
}
|
||||
#endif /* STM32_HSE_ENABLED */
|
||||
ZTEST_SUITE(stm32_sysclck_config, NULL, NULL, NULL, NULL, NULL);
|
||||
|
|
|
@ -114,6 +114,10 @@ tests:
|
|||
drivers.clock.stm32_clock_configuration.common_core.g4.sysclksrc_hse_24:
|
||||
extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/hse_24.overlay"
|
||||
platform_allow: nucleo_g474re
|
||||
drivers.clock.stm32_clock_configuration.common_core.g4.sysclksrc_hse_24.css:
|
||||
extra_args:
|
||||
DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/hse_24.overlay;boards/hse_css.overlay"
|
||||
platform_allow: nucleo_g474re
|
||||
drivers.clock.stm32_clock_configuration.common_core.l0_l1.sysclksrc_hse_8:
|
||||
extra_args:
|
||||
DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/clear_msi.overlay;boards/hse_8.overlay"
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Ferroamp AB (publ)
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
* Warning: This overlay assumes the HSE clock has already been enabled,
|
||||
* for example by hse_8.overlay.
|
||||
*/
|
||||
|
||||
&clk_hse {
|
||||
css-enabled;
|
||||
};
|
|
@ -76,4 +76,17 @@ ZTEST(stm32_syclck_config, test_pll_src)
|
|||
#endif
|
||||
|
||||
}
|
||||
|
||||
#if STM32_HSE_ENABLED
|
||||
ZTEST(stm32_syclck_config, test_hse_css)
|
||||
{
|
||||
/* there is no function to read CSS status, so read directly from the register */
|
||||
#if STM32_HSE_CSS
|
||||
zassert_true(READ_BIT(RCC->CR, RCC_CR_CSSHSEON), "HSE CSS is not enabled");
|
||||
#else
|
||||
zassert_false(READ_BIT(RCC->CR, RCC_CR_CSSHSEON), "HSE CSS unexpectedly enabled");
|
||||
#endif /* STM32_HSE_CSS */
|
||||
|
||||
}
|
||||
#endif /* STM32_HSE_ENABLED */
|
||||
ZTEST_SUITE(stm32_syclck_config, NULL, NULL, NULL, NULL, NULL);
|
||||
|
|
|
@ -28,6 +28,12 @@ tests:
|
|||
platform_allow: nucleo_h743zi
|
||||
integration_platforms:
|
||||
- nucleo_h743zi
|
||||
drivers.clock.stm32_clock_configuration.h7_core.sysclksrc_hse_8_css:
|
||||
extra_args:
|
||||
DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/hse_8.overlay;boards/hse_css.overlay"
|
||||
platform_allow: nucleo_h743zi
|
||||
integration_platforms:
|
||||
- nucleo_h743zi
|
||||
drivers.clock.stm32_clock_configuration.h7_core.sysclksrc_pll_csi_96:
|
||||
extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/pll_csi_96.overlay"
|
||||
platform_allow: nucleo_h743zi
|
||||
|
|
Loading…
Reference in a new issue