This is an automated email from the ASF dual-hosted git repository. jerzy pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/mynewt-core.git
commit 1044336da6111341ce9607c8b0870aa84103d993 Author: Jerzy Kasenberg <[email protected]> AuthorDate: Thu Oct 23 22:26:28 2025 +0200 hw/mcu/stm32f4: Add PLL helper functions This adds several function for PLL frequency checking. Signed-off-by: Jerzy Kasenberg <[email protected]> --- hw/mcu/stm/stm32f4xx/include/mcu/clock_stm32f4xx.h | 83 ++++++++++++++++++++ hw/mcu/stm/stm32f4xx/src/clock_stm32f4xx.c | 88 +++++++++++++++++++++- 2 files changed, 169 insertions(+), 2 deletions(-) diff --git a/hw/mcu/stm/stm32f4xx/include/mcu/clock_stm32f4xx.h b/hw/mcu/stm/stm32f4xx/include/mcu/clock_stm32f4xx.h new file mode 100644 index 000000000..8ac14a5b0 --- /dev/null +++ b/hw/mcu/stm/stm32f4xx/include/mcu/clock_stm32f4xx.h @@ -0,0 +1,83 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef __MCU_CLOCK_STM32F4XX_H_ +#define __MCU_CLOCK_STM32F4XX_H_ + +#include <stdint.h> +#include <stm32_common/mcu.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Return PLL VCO frequency + * + * @return PLL VCO frequency + */ +uint32_t stm32f4xx_pll_vco_freq(void); + +/** + * Return PLLI2S VCO frequency + * + * @return PLLI2S VCO frequency + */ +uint32_t stm32f4xx_plli2s_vco_freq(void); + +/** + * Return PLL P frequency (can be SYSCLK) + * + * @return PLL P frequency + */ +uint32_t stm32f4xx_pll_p_freq(void); + +/** + * Return PLL Q frequency (usually 48MHz) + * + * @return PLL Q frequency + */ +uint32_t stm32f4xx_pll_q_freq(void); + +/** + * Return PLL R frequency + * + * @return PLL R frequency + */ +uint32_t stm32f4xx_pll_r_freq(void); + +/** + * Return PLLI2S Q frequency + * + * @return PLLI2S Q frequency + */ +uint32_t stm32f4xx_plli2s_q_freq(void); + +/** + * Return PLLI2S R frequency + * + * @return PLLI2S R frequency + */ +uint32_t stm32f4xx_plli2s_r_freq(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __MCU_CLOCK_STM32F4XX_H_ */ diff --git a/hw/mcu/stm/stm32f4xx/src/clock_stm32f4xx.c b/hw/mcu/stm/stm32f4xx/src/clock_stm32f4xx.c index 6c305677d..b70420c64 100644 --- a/hw/mcu/stm/stm32f4xx/src/clock_stm32f4xx.c +++ b/hw/mcu/stm/stm32f4xx/src/clock_stm32f4xx.c @@ -24,9 +24,93 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "stm32f4xx_hal_pwr_ex.h" -#include "stm32f4xx_hal.h" #include <assert.h> +#include <stm32f4xx_hal_pwr_ex.h> +#include <stm32f4xx_hal.h> +#include <mcu/clock_stm32f4xx.h> + +#define FIELD_VAL(per, reg, field) \ + ((per->reg & per##_##reg##_##field##_Msk) >> per##_##reg##_##field##_Pos) + +uint32_t +stm32f4xx_pll_vco_freq(void) +{ + uint32_t pll_vco; + uint32_t pll_source_freq; + uint32_t pll_m; + + pll_source_freq = FIELD_VAL(RCC, PLLCFGR, PLLSRC) ? HSE_VALUE : HSI_VALUE; + pll_m = RCC->PLLCFGR & RCC_PLLCFGR_PLLM; + + pll_vco = (pll_source_freq / pll_m) * FIELD_VAL(RCC, PLLCFGR, PLLN); + + return pll_vco; +} + +uint32_t +stm32f4xx_plli2s_vco_freq(void) +{ + uint32_t pll_vco; + uint32_t pll_source_freq; + uint32_t pll_m; + +#ifdef RCC_PLLI2SCFGR_PLLI2SSRC + pll_source_freq = FIELD_VAL(RCC, PLLI2SCFGR, PLLI2SSRC) ? HSE_VALUE : HSI_VALUE; + pll_m = FIELD_VAL(RCC, PLLI2SCFGR, PLLI2SM); +#else + pll_source_freq = FIELD_VAL(RCC, PLLCFGR, PLLSRC) ? HSE_VALUE : HSI_VALUE; + pll_m = RCC->PLLCFGR & RCC_PLLCFGR_PLLM; +#endif + + pll_vco = (pll_source_freq / pll_m); + pll_vco *= FIELD_VAL(RCC, PLLI2SCFGR, PLLI2SN); + + return pll_vco; +} + +uint32_t +stm32f4xx_pll_p_freq(void) +{ + uint32_t pll_p = (FIELD_VAL(RCC, PLLCFGR, PLLP) + 1) * 2; + + return stm32f4xx_pll_vco_freq() / pll_p; +} + +uint32_t +stm32f4xx_pll_q_freq(void) +{ + uint32_t pll_q = FIELD_VAL(RCC, PLLCFGR, PLLQ); + + return stm32f4xx_pll_vco_freq() / pll_q; +} + +#ifdef RCC_PLLCFGR_PLLR +uint32_t +stm32f4xx_pll_r_freq(void) +{ + uint32_t pll_r = FIELD_VAL(RCC, PLLCFGR, PLLR); + + return stm32f4xx_pll_vco_freq() / pll_r; +} +#endif + +#ifdef RCC_PLLI2SCFGR_PLLP +uint32_t +stm32f4xx_plli2s_p_freq(void) +{ + uint32_t pll_p = (FIELD_VAL(RCC, PLLI2SCFGR, PLLP) + 1) * 2; + + return stm32f4xx_plli2s_vco_freq() / pll_p; +} +#endif + +uint32_t +stm32f4xx_plli2s_r_freq(void) +{ + uint32_t pll_r = FIELD_VAL(RCC, PLLI2SCFGR, PLLI2SR); + + return stm32f4xx_pll_vco_freq() / pll_r; +} /* * This allows an user to have a custom clock configuration by zeroing
