Skip to content

Commit bf3c790

Browse files
committed
feat(esp_hw_support): support clock output feature on esp32c5/esp32c61
1 parent 4235058 commit bf3c790

File tree

18 files changed

+212
-80
lines changed

18 files changed

+212
-80
lines changed

components/esp_hw_support/test_apps/esp_hw_support_unity_tests/main/test_esp_clock_output.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Unlicense OR CC0-1.0
55
*/
@@ -154,9 +154,9 @@ TEST_CASE("GPIO output internal clock one-to-many", "[gpio_output_clock][ignore]
154154
TEST_ESP_OK(esp_clock_output_start(test_clk_out_sig[3], test_clk_out_io[0], &clkout_mapping_hdl_7)); // [0]:1 [1]:0 [2]:2
155155

156156
// Stop all
157-
esp_clock_output_stop(clkout_mapping_hdl_2);
158-
esp_clock_output_stop(clkout_mapping_hdl_5);
159-
esp_clock_output_stop(clkout_mapping_hdl_6);
160-
esp_clock_output_stop(clkout_mapping_hdl_7);
157+
TEST_ESP_OK(esp_clock_output_stop(clkout_mapping_hdl_2));
158+
TEST_ESP_OK(esp_clock_output_stop(clkout_mapping_hdl_5));
159+
// clkout_mapping_hdl_6 never been alloc succeed, not need to do stop.
160+
TEST_ESP_OK(esp_clock_output_stop(clkout_mapping_hdl_7));
161161
}
162162
#endif

components/hal/esp32c5/clk_tree_hal.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -72,10 +72,10 @@ uint32_t clk_hal_xtal_get_freq_mhz(void)
7272

7373
void clk_hal_clock_output_setup(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id)
7474
{
75-
abort(); // TODO: IDF-10968
75+
gpio_ll_set_pin_ctrl(clk_sig, CLKOUT_CHANNEL_MASK(channel_id), CLKOUT_CHANNEL_SHIFT(channel_id));
7676
}
7777

7878
void clk_hal_clock_output_teardown(clock_out_channel_t channel_id)
7979
{
80-
abort(); // TODO: IDF-10968
80+
gpio_ll_set_pin_ctrl(0, CLKOUT_CHANNEL_MASK(channel_id), CLKOUT_CHANNEL_SHIFT(channel_id));
8181
}

components/hal/esp32c5/include/hal/clk_tree_ll.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,39 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_rtc_slow_load_cal(v
603603
return REG_READ(RTC_SLOW_CLK_CAL_REG);
604604
}
605605

606+
/*
607+
* Enable/Disable the clock gate for clock output signal source
608+
*/
609+
static inline void clk_ll_enable_clkout_source(soc_clkout_sig_id_t clk_src, bool en)
610+
{
611+
switch (clk_src)
612+
{
613+
case CLKOUT_SIG_PLL_F22M:
614+
PCR.ctrl_clk_out_en.clk22_oen = en;
615+
break;
616+
case CLKOUT_SIG_PLL_F44M:
617+
PCR.ctrl_clk_out_en.clk44_oen = en;
618+
break;
619+
case CLKOUT_SIG_PLL_F40M:
620+
PCR.ctrl_clk_out_en.clk_bb_oen = en;
621+
break;
622+
case CLKOUT_SIG_PLL_F80M:
623+
PCR.ctrl_clk_out_en.clk80_oen = en;
624+
break;
625+
case CLKOUT_SIG_PLL_F160M:
626+
PCR.ctrl_clk_out_en.clk160_oen = en;
627+
break;
628+
case CLKOUT_SIG_PLL_F480M:
629+
PCR.ctrl_clk_out_en.clk_480m_oen = en;
630+
break;
631+
case CLKOUT_SIG_XTAL:
632+
PCR.ctrl_clk_out_en.clk_xtal_oen = en;
633+
break;
634+
default:
635+
break;
636+
}
637+
}
638+
606639
#ifdef __cplusplus
607640
}
608641
#endif

components/hal/esp32c5/include/hal/gpio_ll.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <stdlib.h>
1818
#include <stdbool.h>
1919
#include "soc/soc.h"
20+
#include "soc/gpio_ext_reg.h"
2021
#include "soc/gpio_periph.h"
2122
#include "soc/gpio_struct.h"
2223
#include "soc/lp_aon_struct.h"
@@ -716,6 +717,19 @@ static inline void gpio_ll_sleep_output_enable(gpio_dev_t *hw, uint32_t gpio_num
716717
IO_MUX.gpio[gpio_num].mcu_oe = 1;
717718
}
718719

720+
/**
721+
* @brief Control the pin in the IOMUX
722+
*
723+
* @param bmap write mask of control value
724+
* @param val Control value
725+
* @param shift write mask shift of control value
726+
*/
727+
__attribute__((always_inline))
728+
static inline void gpio_ll_set_pin_ctrl(uint32_t val, uint32_t bmap, uint32_t shift)
729+
{
730+
SET_PERI_REG_BITS(GPIO_EXT_PIN_CTRL_REG, bmap, val, shift);
731+
}
732+
719733
#ifdef __cplusplus
720734
}
721735
#endif

components/hal/esp32c61/clk_tree_hal.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
/*
2-
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

77
#include "hal/clk_tree_hal.h"
88
#include "hal/clk_tree_ll.h"
9+
#include "hal/gpio_ll.h"
910
#include "hal/assert.h"
1011

1112
uint32_t clk_hal_soc_root_get_freq_mhz(soc_cpu_clk_src_t cpu_clk_src)
@@ -65,3 +66,13 @@ uint32_t clk_hal_xtal_get_freq_mhz(void)
6566
HAL_ASSERT(freq == SOC_XTAL_FREQ_40M);
6667
return freq;
6768
}
69+
70+
void clk_hal_clock_output_setup(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id)
71+
{
72+
gpio_ll_set_pin_ctrl(clk_sig, CLKOUT_CHANNEL_MASK(channel_id), CLKOUT_CHANNEL_SHIFT(channel_id));
73+
}
74+
75+
void clk_hal_clock_output_teardown(clock_out_channel_t channel_id)
76+
{
77+
gpio_ll_set_pin_ctrl(0, CLKOUT_CHANNEL_MASK(channel_id), CLKOUT_CHANNEL_SHIFT(channel_id));
78+
}

components/hal/esp32c61/include/hal/clk_tree_ll.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,36 @@ static inline __attribute__((always_inline)) uint64_t clk_ll_rtc_slow_load_rtc_f
570570
return REG_READ(RTC_FIX_US_LOW_REG) | ((uint64_t)REG_READ(RTC_FIX_US_HIGH_REG) << 32);
571571
}
572572

573+
/*
574+
* Enable/Disable the clock gate for clock output signal source
575+
*/
576+
static inline void clk_ll_enable_clkout_source(soc_clkout_sig_id_t clk_src, bool en)
577+
{
578+
switch (clk_src)
579+
{
580+
case CLKOUT_SIG_PLL_F22M:
581+
PCR.ctrl_clk_out_en.clk22_oen = en;
582+
break;
583+
case CLKOUT_SIG_PLL_F44M:
584+
PCR.ctrl_clk_out_en.clk44_oen = en;
585+
break;
586+
case CLKOUT_SIG_PLL_F40M:
587+
PCR.ctrl_clk_out_en.clk_bb_oen = en;
588+
break;
589+
case CLKOUT_SIG_PLL_F80M:
590+
PCR.ctrl_clk_out_en.clk80_oen = en;
591+
break;
592+
case CLKOUT_SIG_PLL_F160M:
593+
PCR.ctrl_clk_out_en.clk160_oen = en;
594+
break;
595+
case CLKOUT_SIG_XTAL:
596+
PCR.ctrl_clk_out_en.clk_xtal_oen = en;
597+
break;
598+
default:
599+
break;
600+
}
601+
}
602+
573603
#ifdef __cplusplus
574604
}
575605
#endif

components/hal/esp32c61/include/hal/gpio_ll.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <stdbool.h>
1919
#include "soc/soc.h"
2020
#include "soc/gpio_periph.h"
21+
#include "soc/gpio_ext_reg.h"
2122
#include "soc/gpio_struct.h"
2223
#include "soc/lp_aon_struct.h"
2324
#include "soc/pmu_struct.h"
@@ -716,6 +717,18 @@ static inline void gpio_ll_sleep_output_enable(gpio_dev_t *hw, uint32_t gpio_num
716717
IO_MUX.gpion[gpio_num].gpion_mcu_oe = 1;
717718
}
718719

720+
/**
721+
* @brief Control the pin in the IOMUX
722+
*
723+
* @param bmap write mask of control value
724+
* @param val Control value
725+
* @param shift write mask shift of control value
726+
*/
727+
__attribute__((always_inline))
728+
static inline void gpio_ll_set_pin_ctrl(uint32_t val, uint32_t bmap, uint32_t shift)
729+
{
730+
SET_PERI_REG_BITS(GPIO_EXT_PIN_CTRL_REG, bmap, val, shift);
731+
}
719732
#ifdef __cplusplus
720733
}
721734
#endif

components/soc/esp32c5/include/soc/Kconfig.soc_caps.in

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,14 @@ config SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
603603
bool
604604
default y
605605

606+
config SOC_GPIO_CLOCKOUT_BY_GPIO_MATRIX
607+
bool
608+
default y
609+
610+
config SOC_CLOCKOUT_HAS_SOURCE_GATE
611+
bool
612+
default y
613+
606614
config SOC_GPIO_CLOCKOUT_CHANNEL_NUM
607615
int
608616
default 3

components/soc/esp32c5/include/soc/clk_tree_defs.h

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -538,19 +538,24 @@ typedef enum {
538538
} soc_periph_flash_clk_src_t;
539539

540540
//////////////////////////////////////////////CLOCK OUTPUT///////////////////////////////////////////////////////////
541-
typedef enum { // TODO
542-
CLKOUT_SIG_PLL = 1, /*!< PLL_CLK is the output of crystal oscillator frequency multiplier */
543-
CLKOUT_SIG_XTAL = 5, /*!< Main crystal oscillator clock */
544-
CLKOUT_SIG_PLL_F80M = 13, /*!< From PLL, usually be 80MHz */
545-
CLKOUT_SIG_CPU = 16, /*!< CPU clock */
546-
CLKOUT_SIG_AHB = 17, /*!< AHB clock */
547-
CLKOUT_SIG_APB = 18, /*!< APB clock */
548-
CLKOUT_SIG_XTAL32K = 21, /*!< External 32kHz crystal clock */
549-
CLKOUT_SIG_EXT32K = 22, /*!< External slow clock input through XTAL_32K_P */
550-
CLKOUT_SIG_RC_FAST = 23, /*!< RC fast clock, about 17.5MHz */
551-
CLKOUT_SIG_RC_32K = 24, /*!< Internal slow RC oscillator */
552-
CLKOUT_SIG_RC_SLOW = 25, /*!< RC slow clock, depends on the RTC_CLK_SRC configuration */
553-
CLKOUT_SIG_INVALID = 0xFF,
541+
typedef enum {
542+
CLKOUT_SIG_INVALID = 0,
543+
CLKOUT_SIG_PLL_F160M = 1, /*!< Divided from PLL_F480M */
544+
CLKOUT_SIG_PLL_F22M = 2, /*!< Divided from PLL_F160M */
545+
CLKOUT_SIG_PLL_F40M = 3, /*!< Divided from PLL_F160M */
546+
CLKOUT_SIG_XTAL = 5, /*!< Main crystal oscillator clock */
547+
CLKOUT_SIG_PLL_F44M = 0xA, /*!< Divided from PLL_F160M */
548+
CLKOUT_SIG_PLL_F480M = 0xB, /*!< From PLL, usually be 480MHz */
549+
CLKOUT_SIG_PLL_F80M = 0xD, /*!< Divided from PLL_F160M */
550+
CLKOUT_SIG_I2S_APB = 0xF, /*!< APB clock for i2s */
551+
CLKOUT_SIG_CPU = 0x10, /*!< CPU clock */
552+
CLKOUT_SIG_AHB = 0x11, /*!< AHB clock */
553+
CLKOUT_SIG_APB = 0x12, /*!< APB clock */
554+
CLKOUT_SIG_XTAL32K = 0x15, /*!< External 32kHz crystal clock */
555+
CLKOUT_SIG_EXT32K = 0x16, /*!< External slow clock input through XTAL_32K_P */
556+
CLKOUT_SIG_RC_FAST = 0x17, /*!< RC fast clock, about 17.5MHz */
557+
CLKOUT_SIG_RC_32K = 0x18, /*!< Internal slow RC oscillator */
558+
CLKOUT_SIG_RC_SLOW = 0x19, /*!< RC slow clock, depends on the RTC_CLK_SRC configuration */
554559
} soc_clkout_sig_id_t;
555560

556561
#ifdef __cplusplus

components/soc/esp32c5/include/soc/clkout_channel.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2010-2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -8,6 +8,7 @@
88

99
#include "esp_assert.h"
1010
#include "soc/soc_caps.h"
11+
#include "soc/gpio_ext_reg.h"
1112
#include "soc/io_mux_reg.h"
1213
#include "soc/gpio_sig_map.h"
1314

@@ -26,13 +27,13 @@ typedef enum clock_out_channel {
2627
(channel == CLKOUT_CHANNEL_2) ? CLK_OUT_OUT2_IDX : \
2728
(channel == CLKOUT_CHANNEL_3) ? CLK_OUT_OUT3_IDX : SIG_GPIO_OUT_IDX)
2829

29-
#define CLKOUT_CHANNEL_MASK(channel) ((channel == CLKOUT_CHANNEL_1) ? CLK_OUT1 : \
30-
(channel == CLKOUT_CHANNEL_2) ? CLK_OUT2 : \
31-
(channel == CLKOUT_CHANNEL_3) ? CLK_OUT3 : 0)
30+
#define CLKOUT_CHANNEL_MASK(channel) ((channel == CLKOUT_CHANNEL_1) ? GPIO_EXT_CLK_OUT1 : \
31+
(channel == CLKOUT_CHANNEL_2) ? GPIO_EXT_CLK_OUT2 : \
32+
(channel == CLKOUT_CHANNEL_3) ? GPIO_EXT_CLK_OUT3 : 0)
3233

33-
#define CLKOUT_CHANNEL_SHIFT(channel) ((channel == CLKOUT_CHANNEL_1) ? CLK_OUT1_S : \
34-
(channel == CLKOUT_CHANNEL_2) ? CLK_OUT2_S : \
35-
(channel == CLKOUT_CHANNEL_3) ? CLK_OUT3_S : 0)
34+
#define CLKOUT_CHANNEL_SHIFT(channel) ((channel == CLKOUT_CHANNEL_1) ? GPIO_EXT_CLK_OUT1_S : \
35+
(channel == CLKOUT_CHANNEL_2) ? GPIO_EXT_CLK_OUT2_S : \
36+
(channel == CLKOUT_CHANNEL_3) ? GPIO_EXT_CLK_OUT3_S : 0)
3637

3738
ESP_STATIC_ASSERT(CLKOUT_CHANNEL_MAX == SOC_GPIO_CLOCKOUT_CHANNEL_NUM, "clock_out_channel enumeration mismatch");
3839

0 commit comments

Comments
 (0)