From 72c5458a87e2ee65f234c9551ac9661a0f91fdb0 Mon Sep 17 00:00:00 2001 From: Peter Harper Date: Mon, 2 Jun 2025 13:17:10 +0100 Subject: [PATCH 1/3] Fix powman_timer_use_gpio Fixes #2471 --- src/rp2_common/hardware_powman/powman.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/rp2_common/hardware_powman/powman.c b/src/rp2_common/hardware_powman/powman.c index 2f9b9c367..6af650a1e 100644 --- a/src/rp2_common/hardware_powman/powman.c +++ b/src/rp2_common/hardware_powman/powman.c @@ -102,7 +102,15 @@ static void powman_timer_use_gpio(uint32_t gpio, uint32_t use, uint32_t using) { if (was_running) powman_timer_stop(); invalid_params_if(HARDWARE_POWMAN, !((gpio == 12) || (gpio == 14) || (gpio == 20) || (gpio == 22))); gpio_set_input_enabled(gpio, true); - powman_write(&powman_hw->ext_time_ref, gpio); + uint32_t source = 0; // 12 + if (gpio == 20) { + source = 1; + } else if (gpio == 14) { + source = 2; + } else if (gpio == 22) { + source = 3; + } + powman_write(&powman_hw->ext_time_ref, source); powman_set_bits(&powman_hw->timer, use); if (was_running) { powman_timer_start(); From 45be1df33350183dea3797f232273636f79d8c63 Mon Sep 17 00:00:00 2001 From: Peter Harper Date: Mon, 2 Jun 2025 13:18:01 +0100 Subject: [PATCH 2/3] Fix docs for clock_gpio_init etc for RP2350 You can also use gpios 13 and 15 on RP2350 --- .../hardware_clocks/include/hardware/clocks.h | 39 +++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/src/rp2_common/hardware_clocks/include/hardware/clocks.h b/src/rp2_common/hardware_clocks/include/hardware/clocks.h index 68f4b1a50..e238e841c 100644 --- a/src/rp2_common/hardware_clocks/include/hardware/clocks.h +++ b/src/rp2_common/hardware_clocks/include/hardware/clocks.h @@ -399,7 +399,18 @@ void clocks_enable_resus(resus_callback_t resus_callback); /*! \brief Output an optionally divided clock to the specified gpio pin. * \ingroup hardware_clocks * - * \param gpio The GPIO pin to output the clock to. Valid GPIOs are: 21, 23, 24, 25. These GPIOs are connected to the GPOUT0-3 clock generators. + * \if rp2040_specific + * On RP2040 valid GPIOs are 21, 23, 24, 25. + * These GPIOs are connected to the GPOUT0-3 clock generators. + * \endif + * \if rp2350_specific + * On RP2350 valid GPIOs are 13, 15, 21, 23, 24, 25. + * GPIOs 13 and 21 are connected to the GPOUT0 clock generator. + * GPIOs 15 and 23 are connected to the GPOUT1 clock generator. + * GPIOs 24 and 25 are connected to the GPOUT2-3 clock generators. + * \endif + * + * \param gpio The GPIO pin to output the clock to. * \param src The source clock. See the register field CLOCKS_CLK_GPOUT0_CTRL_AUXSRC for a full list. The list is the same for each GPOUT clock generator. * \param div_int The integer part of the value to divide the source clock by. This is useful to not overwhelm the GPIO pin with a fast clock. This is in range of 1..2^24-1 on RP2040 * and 1..2^16-1 on RP2350 @@ -410,7 +421,18 @@ void clock_gpio_init_int_frac16(uint gpio, uint src, uint32_t div_int, uint16_t /*! \brief Output an optionally divided clock to the specified gpio pin. * \ingroup hardware_clocks * - * \param gpio The GPIO pin to output the clock to. Valid GPIOs are: 21, 23, 24, 25. These GPIOs are connected to the GPOUT0-3 clock generators. + * * \if rp2040_specific + * On RP2040 valid GPIOs are 21, 23, 24, 25. + * These GPIOs are connected to the GPOUT0-3 clock generators. + * \endif + * \if rp2350_specific + * On RP2350 valid GPIOs are 13, 15, 21, 23, 24, 25. + * GPIOs 13 and 21 are connected to the GPOUT0 clock generator. + * GPIOs 15 and 23 are connected to the GPOUT1 clock generator. + * GPIOs 24 and 25 are connected to the GPOUT2-3 clock generators. + * \endif + * + * \param gpio The GPIO pin to output the clock to. * \param src The source clock. See the register field CLOCKS_CLK_GPOUT0_CTRL_AUXSRC for a full list. The list is the same for each GPOUT clock generator. * \param div_int The integer part of the value to divide the source clock by. This is useful to not overwhelm the GPIO pin with a fast clock. This is in range of 1..2^24-1 on RP2040 * and 1..2^16-1 on RP2350 @@ -428,7 +450,18 @@ static inline void clock_gpio_init_int_frac(uint gpio, uint src, uint32_t div_in /*! \brief Output an optionally divided clock to the specified gpio pin. * \ingroup hardware_clocks * - * \param gpio The GPIO pin to output the clock to. Valid GPIOs are: 21, 23, 24, 25. These GPIOs are connected to the GPOUT0-3 clock generators. + * \if rp2040_specific + * On RP2040 valid GPIOs are 21, 23, 24, 25. + * These GPIOs are connected to the GPOUT0-3 clock generators. + * \endif + * \if rp2350_specific + * On RP2350 valid GPIOs are 13, 15, 21, 23, 24, 25. + * GPIOs 13 and 21 are connected to the GPOUT0 clock generator. + * GPIOs 15 and 23 are connected to the GPOUT1 clock generator. + * GPIOs 24 and 25 are connected to the GPOUT2-3 clock generators. + * \endif + * + * \param gpio The GPIO pin to output the clock to. * \param src The source clock. See the register field CLOCKS_CLK_GPOUT0_CTRL_AUXSRC for a full list. The list is the same for each GPOUT clock generator. * \param div The float amount to divide the source clock by. This is useful to not overwhelm the GPIO pin with a fast clock. */ From a5faaa305f7793de34de88b81a968d673f21b9f3 Mon Sep 17 00:00:00 2001 From: graham sanderson Date: Tue, 15 Jul 2025 16:31:42 -0500 Subject: [PATCH 3/3] macro-ify the mapping from GPI to ext_time_ref_source - note i kept this private for now, as it's a bit murky --- src/rp2_common/hardware_powman/powman.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/rp2_common/hardware_powman/powman.c b/src/rp2_common/hardware_powman/powman.c index 6af650a1e..9867259fd 100644 --- a/src/rp2_common/hardware_powman/powman.c +++ b/src/rp2_common/hardware_powman/powman.c @@ -97,19 +97,24 @@ void powman_timer_set_1khz_tick_source_xosc_with_hz(uint32_t xosc_freq_hz) { } } +#ifndef GPIO_TO_POWMAN_EXT_TIME_REF_SOURCE +#define GPIO_TO_POWMAN_EXT_TIME_REF_SOURCE(gpio, default_ext_time_ref_source) \ + ((gpio) == 12 ? 0 : \ + ((gpio) == 20 ? 1 : \ + ((gpio) == 14 ? 2 : \ + ((gpio) == 22 ? 3 : \ + (default_ext_time_ref_source))))) +#endif + +static inline uint32_t gpio_to_powman_ext_time_ref_source(uint gpio, uint32_t default_ext_time_ref_source) { + return GPIO_TO_POWMAN_EXT_TIME_REF_SOURCE(gpio, ({invalid_params_if(HARDWARE_POWMAN, true); default_ext_time_ref_source;})); +} + static void powman_timer_use_gpio(uint32_t gpio, uint32_t use, uint32_t using) { bool was_running = powman_timer_is_running(); if (was_running) powman_timer_stop(); - invalid_params_if(HARDWARE_POWMAN, !((gpio == 12) || (gpio == 14) || (gpio == 20) || (gpio == 22))); + uint32_t source = gpio_to_powman_ext_time_ref_source(gpio, 0); gpio_set_input_enabled(gpio, true); - uint32_t source = 0; // 12 - if (gpio == 20) { - source = 1; - } else if (gpio == 14) { - source = 2; - } else if (gpio == 22) { - source = 3; - } powman_write(&powman_hw->ext_time_ref, source); powman_set_bits(&powman_hw->timer, use); if (was_running) {