diff --git a/src/rp2_common/hardware_clocks/clocks.c b/src/rp2_common/hardware_clocks/clocks.c index 2d41c73d2..1362a3a28 100644 --- a/src/rp2_common/hardware_clocks/clocks.c +++ b/src/rp2_common/hardware_clocks/clocks.c @@ -243,21 +243,8 @@ void clocks_enable_resus(resus_callback_t resus_callback) { } void clock_gpio_init_int_frac16(uint gpio, uint src, uint32_t div_int, uint16_t div_frac16) { - // Bit messy but it's as much code to loop through a lookup - // table. The sources for each gpout generators are the same - // so just call with the sources from GP0 - uint gpclk = 0; - if (gpio == 21) gpclk = clk_gpout0; - else if (gpio == 23) gpclk = clk_gpout1; - else if (gpio == 24) gpclk = clk_gpout2; - else if (gpio == 25) gpclk = clk_gpout3; -#if !PICO_RP2040 - else if (gpio == 13) gpclk = clk_gpout0; - else if (gpio == 15) gpclk = clk_gpout1; -#endif - else { - invalid_params_if(HARDWARE_CLOCKS, true); - } + // note this includes an invalid_params_if before defaulting to clk_gpout0 + uint gpclk = gpio_to_gpout_clock_handle(gpio, clk_gpout0); invalid_params_if(HARDWARE_CLOCKS, div_int >> REG_FIELD_WIDTH(CLOCKS_CLK_GPOUT0_DIV_INT)); // Set up the gpclk generator diff --git a/src/rp2_common/hardware_clocks/include/hardware/clocks.h b/src/rp2_common/hardware_clocks/include/hardware/clocks.h index ee8e95535..a5ffaa83f 100644 --- a/src/rp2_common/hardware_clocks/include/hardware/clocks.h +++ b/src/rp2_common/hardware_clocks/include/hardware/clocks.h @@ -544,6 +544,42 @@ static inline bool set_sys_clock_khz(uint32_t freq_khz, bool required) { return false; } +#define GPIO_TO_GPOUT_CLOCK_HANDLE_RP2040(gpio, default_clk_handle) \ + ((gpio) == 21 ? clk_gpout0 : \ + ((gpio) == 23 ? clk_gpout1 : \ + ((gpio) == 24 ? clk_gpout2 : \ + ((gpio) == 25 ? clk_gpout3 : \ + (default_clk_handle))))) + +#define GPIO_TO_GPOUT_CLOCK_HANDLE_RP2350(gpio, default_clk_handle) \ + ((gpio) == 13 ? clk_gpout0 : \ + ((gpio) == 15 ? clk_gpout1 : \ + (GPIO_TO_GPOUT_CLOCK_HANDLE_RP2040(gpio, default_clk_handle)))) + +/** + * \def GPIO_TO_GPOUT_CLOCK_HANDLE(gpio, default_clk_handle) + * \ingroup hardware_clocks + * \hideinitializer + * \brief Returns the GPOUT clock number associated with a particular GPIO if there is one, or default_clk_handle otherwise + * + * Note this macro is intended to resolve at compile time, and does no parameter checking + */ +#ifndef GPIO_TO_GPOUT_CLOCK_HANDLE +#if PICO_RP2040 +#define GPIO_TO_GPOUT_CLOCK_HANDLE GPIO_TO_GPOUT_CLOCK_HANDLE_RP2040 +#else +#define GPIO_TO_GPOUT_CLOCK_HANDLE GPIO_TO_GPOUT_CLOCK_HANDLE_RP2350 +#endif +#endif + +/** + * \brief return the associated GPOUT clock for a given GPIO if any + * \ingroup hardware_clocks + * \return the GPOUT clock number associated with a particular GPIO or default_clk_handle otherwise + */ +static inline clock_handle_t gpio_to_gpout_clock_handle(uint gpio, clock_handle_t default_clk_handle) { + return GPIO_TO_GPOUT_CLOCK_HANDLE(gpio, ({invalid_params_if(HARDWARE_CLOCKS, true); default_clk_handle;})); +} #ifdef __cplusplus } #endif