From aaf0828250def88cc5dd4b3a48a76755c4152b8b Mon Sep 17 00:00:00 2001 From: Howard Su Date: Sat, 21 Jan 2023 05:45:18 +0800 Subject: [PATCH] change clock_gpio_init to take float and add clock_gpio_init_int_frac (#1178) --- src/rp2_common/hardware_clocks/clocks.c | 4 ++-- .../hardware_clocks/include/hardware/clocks.h | 19 +++++++++++++++++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/rp2_common/hardware_clocks/clocks.c b/src/rp2_common/hardware_clocks/clocks.c index 9ba51f0..86c5e8d 100644 --- a/src/rp2_common/hardware_clocks/clocks.c +++ b/src/rp2_common/hardware_clocks/clocks.c @@ -314,7 +314,7 @@ void clocks_enable_resus(resus_callback_t resus_callback) { clocks_hw->resus.ctrl = CLOCKS_CLK_SYS_RESUS_CTRL_ENABLE_BITS | timeout; } -void clock_gpio_init(uint gpio, uint src, uint div) { +void clock_gpio_init_int_frac(uint gpio, uint src, uint32_t div_int, uint8_t div_frac) { // 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 @@ -330,7 +330,7 @@ void clock_gpio_init(uint gpio, uint src, uint div) { // Set up the gpclk generator clocks_hw->clk[gpclk].ctrl = (src << CLOCKS_CLK_GPOUT0_CTRL_AUXSRC_LSB) | CLOCKS_CLK_GPOUT0_CTRL_ENABLE_BITS; - clocks_hw->clk[gpclk].div = div << CLOCKS_CLK_GPOUT0_DIV_INT_LSB; + clocks_hw->clk[gpclk].div = (div_int << CLOCKS_CLK_GPOUT0_DIV_INT_LSB) | div_frac; // Set gpio pin to gpclock function gpio_set_function(gpio, GPIO_FUNC_GPCK); diff --git a/src/rp2_common/hardware_clocks/include/hardware/clocks.h b/src/rp2_common/hardware_clocks/include/hardware/clocks.h index 80aabb2..bc4d9ac 100644 --- a/src/rp2_common/hardware_clocks/include/hardware/clocks.h +++ b/src/rp2_common/hardware_clocks/include/hardware/clocks.h @@ -172,9 +172,24 @@ void clocks_enable_resus(resus_callback_t resus_callback); * * \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. * \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 amount to divide the source clock by. This is useful to not overwhelm the GPIO pin with a fast clock. + * \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. + * \param div_frac The fractional part of the value to divide the source clock by. This is in range of 0..255 (/256). */ -void clock_gpio_init(uint gpio, uint src, uint div); +void clock_gpio_init_int_frac(uint gpio, uint src, uint32_t div_int, uint8_t div_frac); + +/*! \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. + * \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. + */ +static inline void clock_gpio_init(uint gpio, uint src, float div) +{ + uint div_int = (uint)div; + uint8_t frac = (uint8_t)((div - (float)div_int) * (1u << CLOCKS_CLK_GPOUT0_DIV_INT_LSB)); + clock_gpio_init_int_frac(gpio, src, div_int, frac); +} /*! \brief Configure a clock to come from a gpio input * \ingroup hardware_clocks