From 5a163815406814d1b0b8596b47ec5e6ed6ee8a4b Mon Sep 17 00:00:00 2001 From: Darryl Ring Date: Thu, 20 Aug 2026 16:27:30 -0700 Subject: [PATCH] arch/arm/stm32h5: Fix MCO clock pins and config Add the correct pin map definitions for MCO1 and MCO2, and add the clock division option to stm32_mco{1,2}config with a macro. This matches the STM32H7 implementation. Signed-off-by: Darryl Ring --- .../src/stm32h5/hardware/stm32h56xxx_pinmap.h | 3 ++- .../arm/src/stm32h5/hardware/stm32h5xxx_rcc.h | 20 ++++++------------- arch/arm/src/stm32h5/stm32_rcc.h | 16 +++++++++------ 3 files changed, 18 insertions(+), 21 deletions(-) diff --git a/arch/arm/src/stm32h5/hardware/stm32h56xxx_pinmap.h b/arch/arm/src/stm32h5/hardware/stm32h56xxx_pinmap.h index c9e8d59d7b6..672870ef0d4 100644 --- a/arch/arm/src/stm32h5/hardware/stm32h56xxx_pinmap.h +++ b/arch/arm/src/stm32h5/hardware/stm32h56xxx_pinmap.h @@ -127,7 +127,8 @@ /* Clocks outputs */ -#define GPIO_MCO_0 (GPIO_ALT|GPIO_AF0|GPIO_PORTA|GPIO_PIN8) +#define GPIO_MCO1_0 (GPIO_ALT|GPIO_AF0|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN8) +#define GPIO_MCO2_0 (GPIO_ALT|GPIO_AF0|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN9) /* I2C */ diff --git a/arch/arm/src/stm32h5/hardware/stm32h5xxx_rcc.h b/arch/arm/src/stm32h5/hardware/stm32h5xxx_rcc.h index 3383507d502..2303e8dfdda 100644 --- a/arch/arm/src/stm32h5/hardware/stm32h5xxx_rcc.h +++ b/arch/arm/src/stm32h5/hardware/stm32h5xxx_rcc.h @@ -218,15 +218,11 @@ #define RCC_CFGR1_TIMPRE (1 << 15) /* timers clocks prescaler selection */ #define RCC_CFGR1_MCO1PRE_SHIFT (18) /* Bits 21-18: MCO1 Prescaler */ -#define RCC_CFGR1_MCO1PRE_MASK (0xf << RCC_CFGR1_MCO1PRE_SHIFT) -# define RCC_CFGR1_MCO1PRE_MCO1 (0 << RCC_CFGR1_MCO1PRE_SHIFT) /* 0xx: MCO1 not divided */ -# define RCC_CFGR1_MCO1PRE_MCO1d2 (2 << RCC_CFGR1_MCO1PRE_SHIFT) /* 10: MCO1 divided by 2 */ -# define RCC_CFGR1_MCO1PRE_MCO1d4 (4 << RCC_CFGR1_MCO1PRE_SHIFT) /* 100: MCO1 divided by 4 */ -# define RCC_CFGR1_MCO1PRE_MCO1d8 (8 << RCC_CFGR1_MCO1PRE_SHIFT) /* 1000: MCO1 divided by 8 */ -# define RCC_CFGR1_MCO1PRE_MCO1d15 (15 << RCC_CFGR1_MCO1PRE_SHIFT) /* 1111: MCO1 divided by 15 */ +#define RCC_CFGR1_MCO1PRE_MASK (0xfU << RCC_CFGR1_MCO1PRE_SHIFT) +#define RCC_CFGR1_MCO1PRE(x) (((x) << RCC_CFGR1_MCO1PRE_SHIFT) & RCC_CFGR1_MCO1PRE_MASK) #define RCC_CFGR1_MCO1SEL_SHIFT (22) /* Bits 24-22: Microcontroller Clock Output1 */ -#define RCC_CFGR1_MCO1SEL_MASK (0x7 << RCC_CFGR1_MCO1SEL_SHIFT) +#define RCC_CFGR1_MCO1SEL_MASK (0x7U << RCC_CFGR1_MCO1SEL_SHIFT) # define RCC_CFGR1_MCO1SEL_HSI (0 << RCC_CFGR1_MCO1SEL_SHIFT) /* 0000: HSI clock selected */ # define RCC_CFGR1_MCO1SEL_LSE (1 << RCC_CFGR1_MCO1SEL_SHIFT) /* 0001: LSE clock selected */ # define RCC_CFGR1_MCO1SEL_HSE (2 << RCC_CFGR1_MCO1SEL_SHIFT) /* 0010: HSE clock selected */ @@ -234,15 +230,11 @@ # define RCC_CFGR1_MCO1SEL_HSI48 (4 << RCC_CFGR1_MCO1SEL_SHIFT) /* 0100: HSI48 clock selected */ #define RCC_CFGR1_MCO2PRE_SHIFT (25) /* Bits 28-25: MCO2 Prescaler */ -#define RCC_CFGR1_MCO2PRE_MASK (0xf << RCC_CFGR1_MCO2PRE_SHIFT) -# define RCC_CFGR1_MCO2PRE_MCO2 (0 << RCC_CFGR1_MCO2PRE_SHIFT) /* 0xx: MCO2 not divided */ -# define RCC_CFGR1_MCO2PRE_MCO2d2 (2 << RCC_CFGR1_MCO2PRE_SHIFT) /* 10: MCO2 divided by 2 */ -# define RCC_CFGR1_MCO2PRE_MCO2d4 (4 << RCC_CFGR1_MCO2PRE_SHIFT) /* 100: MCO2 divided by 4 */ -# define RCC_CFGR1_MCO2PRE_MCO2d8 (8 << RCC_CFGR1_MCO2PRE_SHIFT) /* 1000: MCO2 divided by 8 */ -# define RCC_CFGR1_MCO2PRE_MCO2d15 (15 << RCC_CFGR1_MCO2PRE_SHIFT) /* 1111: MCO2 divided by 15 */ +#define RCC_CFGR1_MCO2PRE_MASK (0xfU << RCC_CFGR1_MCO2PRE_SHIFT) +#define RCC_CFGR1_MCO2PRE(x) (((x) << RCC_CFGR1_MCO2PRE_SHIFT) & RCC_CFGR1_MCO2PRE_MASK) #define RCC_CFGR1_MCO2SEL_SHIFT (29) /* Bits 31-29: Microcontroller Clock Output1 */ -#define RCC_CFGR1_MCO2SEL_MASK (0x7 << RCC_CFGR1_MCO2SEL_SHIFT) +#define RCC_CFGR1_MCO2SEL_MASK (0x7U << RCC_CFGR1_MCO2SEL_SHIFT) # define RCC_CFGR1_MCO2SEL_SYSCLLK (0 << RCC_CFGR1_MCO2SEL_SHIFT) /* 0000: Main SYSCLLK selected */ # define RCC_CFGR1_MCO2SEL_PLL2 (1 << RCC_CFGR1_MCO2SEL_SHIFT) /* 0001: Main PLL2 selected */ # define RCC_CFGR1_MCO2SEL_HSE (2 << RCC_CFGR1_MCO2SEL_SHIFT) /* 0010: HSE clock selected */ diff --git a/arch/arm/src/stm32h5/stm32_rcc.h b/arch/arm/src/stm32h5/stm32_rcc.h index 8e0f56fb786..ac95eadf5b9 100644 --- a/arch/arm/src/stm32h5/stm32_rcc.h +++ b/arch/arm/src/stm32h5/stm32_rcc.h @@ -67,21 +67,23 @@ extern "C" * chip/stm32h5_rcc.h {RCC_CFGR_SYSCLK, RCC_CFGR_INTCLK, * RCC_CFGR_EXTCLK, RCC_CFGR_PLLCLKd2, RCC_CFGR_PLL2CLK, * RCC_CFGR_PLL3CLKd2, RCC_CFGR_XT1, RCC_CFGR_PLL3CLK} + * div - Clock divider passed through the RCC_CFGR_MCO1PRE macro from + * chip/stm32h5_rcc.h {RCC_CFGR_MCO1PRE(x) where x is 0..15})} * * Returned Value: * None * ****************************************************************************/ -static inline void stm32_mco1config(uint32_t source) +static inline void stm32_mco1config(uint32_t source, uint32_t div) { uint32_t regval; /* Set MCO source */ regval = getreg32(STM32_RCC_CFGR1); - regval &= ~(RCC_CFGR1_MCO1SEL_MASK); - regval |= (source & RCC_CFGR1_MCO1SEL_MASK); + regval &= ~(RCC_CFGR1_MCO1SEL_MASK | RCC_CFGR1_MCO1PRE_MASK); + regval |= (source | div); putreg32(regval, STM32_RCC_CFGR1); } @@ -95,21 +97,23 @@ static inline void stm32_mco1config(uint32_t source) * chip/stm32h5_rcc.h {RCC_CFGR_SYSCLK, RCC_CFGR_INTCLK, * RCC_CFGR_EXTCLK, RCC_CFGR_PLLCLKd2, RCC_CFGR_PLL2CLK, * RCC_CFGR_PLL3CLKd2, RCC_CFGR_XT1, RCC_CFGR_PLL3CLK} + * div - Clock divider passed through the RCC_CFGR_MCO2PRE macro from + * chip/stm32h5_rcc.h {RCC_CFGR_MCO2PRE(x) where x is 0..15})} * * Returned Value: * None * ****************************************************************************/ -static inline void stm32_mco2config(uint32_t source) +static inline void stm32_mco2config(uint32_t source, uint32_t div) { uint32_t regval; /* Set MCO source */ regval = getreg32(STM32_RCC_CFGR1); - regval &= ~(RCC_CFGR1_MCO2SEL_MASK); - regval |= (source & RCC_CFGR1_MCO2SEL_MASK); + regval &= ~(RCC_CFGR1_MCO2SEL_MASK | RCC_CFGR1_MCO2PRE_MASK); + regval |= (source | div); putreg32(regval, STM32_RCC_CFGR1); }