Skip to content

Commit 82a67d4

Browse files
LucasTambormarekmatej
authored andcommitted
zephyr: Add LP UART support for C6
Add LP UART support for LP Core on C6 Signed-off-by: Lucas Tamborrino <[email protected]>
1 parent c33e522 commit 82a67d4

File tree

4 files changed

+28
-19
lines changed

4 files changed

+28
-19
lines changed

components/esp_hw_support/port/esp32c6/rtc_clk.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,9 @@ rtc_xtal_freq_t rtc_clk_xtal_freq_get(void)
364364
{
365365
uint32_t xtal_freq_mhz = clk_ll_xtal_load_freq_mhz();
366366
if (xtal_freq_mhz == 0) {
367+
#if !defined(CONFIG_SOC_ESP32C6_LPCORE)
367368
ESP_HW_LOGW(TAG, "invalid RTC_XTAL_FREQ_REG value, assume 40MHz");
369+
#endif
368370
clk_ll_xtal_store_freq_mhz(RTC_XTAL_FREQ_40M);
369371
return RTC_XTAL_FREQ_40M;
370372
}

components/hal/esp32c6/clk_tree_hal.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
#include "hal/assert.h"
1111
#include "hal/log.h"
1212

13+
#if !defined(CONFIG_SOC_ESP32C6_LPCORE)
1314
static const char *CLK_HAL_TAG = "clk_hal";
15+
#endif
1416

1517
uint32_t clk_hal_soc_root_get_freq_mhz(soc_cpu_clk_src_t cpu_clk_src)
1618
{
@@ -69,7 +71,9 @@ uint32_t clk_hal_xtal_get_freq_mhz(void)
6971
{
7072
uint32_t freq = clk_ll_xtal_load_freq_mhz();
7173
if (freq == 0) {
74+
#if !defined(CONFIG_SOC_ESP32C6_LPCORE)
7275
HAL_LOGW(CLK_HAL_TAG, "invalid RTC_XTAL_FREQ_REG value, assume 40MHz");
76+
#endif
7377
return (uint32_t)RTC_XTAL_FREQ_40M;
7478
}
7579
return freq;

components/hal/esp32c6/include/hal/uart_ll.h

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ FORCE_INLINE_ATTR void lp_uart_ll_get_sclk(uart_dev_t *hw, uart_sclk_t *source_c
125125
* @param hw Address offset of the LP UART peripheral registers
126126
* @param src_clk Source clock for the LP UART peripheral
127127
*/
128-
static inline void lp_uart_ll_set_source_clk(uart_dev_t *hw, soc_periph_lp_uart_clk_src_t src_clk)
128+
FORCE_INLINE_ATTR void lp_uart_ll_set_source_clk(uart_dev_t *hw, soc_periph_lp_uart_clk_src_t src_clk)
129129
{
130130
(void)hw;
131131
switch (src_clk) {
@@ -141,9 +141,6 @@ static inline void lp_uart_ll_set_source_clk(uart_dev_t *hw, soc_periph_lp_uart_
141141
}
142142
}
143143

144-
/// LP_CLKRST.lpperi is a shared register, so this function must be used in an atomic way
145-
#define lp_uart_ll_set_source_clk(...) (void)__DECLARE_RCC_ATOMIC_ENV; lp_uart_ll_set_source_clk(__VA_ARGS__)
146-
147144
/**
148145
* @brief Configure the lp uart baud-rate.
149146
*
@@ -155,18 +152,28 @@ static inline void lp_uart_ll_set_source_clk(uart_dev_t *hw, soc_periph_lp_uart_
155152
*/
156153
FORCE_INLINE_ATTR void lp_uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud, uint32_t sclk_freq)
157154
{
158-
#define DIV_UP(a, b) (((a) + (b) - 1) / (b))
159-
const uint32_t max_div = BIT(12) - 1; // UART divider integer part only has 12 bits
160-
uint32_t sclk_div = DIV_UP(sclk_freq, (uint64_t)max_div * baud);
155+
// Constants
156+
const uint32_t MAX_DIV_BITS = 12; // UART divider integer part bits
157+
const uint32_t MAX_DIV = (1U << MAX_DIV_BITS) - 1; // Maximum divider value
161158

162-
if (sclk_div == 0) abort();
159+
// Ensure baud rate and sclk_freq are valid
160+
if (baud == 0 || sclk_freq == 0) abort();
163161

164-
uint32_t clk_div = ((sclk_freq) << 4) / (baud * sclk_div);
165-
// The baud rate configuration register is divided into
166-
// an integer part and a fractional part.
167-
hw->clkdiv_sync.clkdiv_int = clk_div >> 4;
168-
hw->clkdiv_sync.clkdiv_frag = clk_div & 0xf;
162+
// Calculate sclk divider
163+
uint32_t sclk_div = (sclk_freq + MAX_DIV * baud - 1) / (MAX_DIV * baud);
164+
if (sclk_div == 0) abort(); // Handle invalid sclk_div
165+
166+
// Calculate clk_div with integer and fractional parts
167+
uint32_t clk_div = (sclk_freq * 16) / (baud * sclk_div);
168+
uint32_t clk_div_int = clk_div >> 4; // Integer part
169+
uint32_t clk_div_frac = clk_div & 0xF; // Fractional part
170+
171+
// Configure hardware registers
172+
hw->clkdiv_sync.clkdiv_int = clk_div_int;
173+
hw->clkdiv_sync.clkdiv_frag = clk_div_frac;
169174
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clk_conf, sclk_div_num, sclk_div - 1);
175+
176+
// Update UART hardware
170177
uart_ll_update(hw);
171178
}
172179

@@ -176,15 +183,12 @@ FORCE_INLINE_ATTR void lp_uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud, ui
176183
* @param hw_id LP UART instance ID
177184
* @param enable True to enable, False to disable
178185
*/
179-
static inline void _lp_uart_ll_enable_bus_clock(int hw_id, bool enable)
186+
FORCE_INLINE_ATTR void lp_uart_ll_enable_bus_clock(int hw_id, bool enable)
180187
{
181188
(void)hw_id;
182189
LPPERI.clk_en.lp_uart_ck_en = enable;
183190
}
184191

185-
/// LPPERI.clk_en is a shared register, so this function must be used in an atomic way
186-
#define lp_uart_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; _lp_uart_ll_enable_bus_clock(__VA_ARGS__)
187-
188192
/**
189193
* @brief Enable the UART clock.
190194
*

zephyr/esp32c6/CMakeLists.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ if(CONFIG_SOC_SERIES_ESP32C6)
353353
../../components/efuse/${CONFIG_SOC_SERIES}/esp_efuse_utility.c
354354
)
355355
endif()
356-
356+
357357
if(CONFIG_SOC_ESP32C6_LPCORE)
358358
zephyr_compile_definitions(IS_ULP_COCPU)
359359
zephyr_ld_options("-nostartfiles")
@@ -367,7 +367,6 @@ if(CONFIG_SOC_SERIES_ESP32C6)
367367
../../components/ulp/lp_core/lp_core.c
368368
../../components/ulp/lp_core/shared/ulp_lp_core_lp_timer_shared.c
369369
../../components/ulp/lp_core/shared/ulp_lp_core_memory_shared.c
370-
../../components/driver/gpio/rtc_io.c
371370
../../components/hal/rtc_io_hal.c
372371
)
373372

0 commit comments

Comments
 (0)