Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ set(srcs
src/security.c
src/uart.c
src/usb_serial_jtag.c
src/clock.c
)

if(STUB_LOG_ENABLED IN_LIST STUB_COMPILE_DEFS)
Expand Down
6 changes: 6 additions & 0 deletions example/stub_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <stddef.h>
#include <string.h>

#include <esp-stub-lib/clock.h>
#include <esp-stub-lib/log.h>
#include <esp-stub-lib/flash.h>
#include <esp-stub-lib/err.h>
Expand Down Expand Up @@ -63,6 +64,11 @@ static void example_security(void)
}
}

static void __attribute__((unused)) test_clock_init(void)
{
stub_lib_clock_init();
}

static int __attribute__((unused)) handle_test_uart(void)
{
void *uart_rx_interrupt_handler = NULL;
Expand Down
22 changes: 22 additions & 0 deletions include/esp-stub-lib/clock.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*/

#pragma once

#include <stdint.h>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to include


#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

/**
* @brief Initialize clock to higher CPU frequency if possible
*/
void stub_lib_clock_init(void);

#ifdef __cplusplus
}
#endif // __cplusplus
16 changes: 9 additions & 7 deletions include/esp-stub-lib/soc_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

#pragma once

#include <stdint.h>

#define ETS_UNCACHED_ADDR(addr) (addr)
#define ETS_CACHED_ADDR(addr) (addr)

Expand All @@ -28,11 +30,11 @@
} while(0)

#define REG_CLR_BIT(_r, _b) do { \
REG_WRITE(_r, REG_READ(_r) & (~(_b))); \
REG_WRITE(_r, REG_READ(_r) & (~(volatile uint32_t)(_b))); \
} while(0)

#define REG_SET_BITS(_r, _b, _m) do { \
REG_WRITE(_r, (REG_READ(_r) & ~(_m)) | ((_b) & (_m))); \
REG_WRITE(_r, (REG_READ(_r) & ~(volatile uint32_t)(_m)) | ((volatile uint32_t)(_b) & (volatile uint32_t)(_m))); \
} while(0)

// Field manipulation macros
Expand All @@ -41,17 +43,17 @@
})

#define REG_SET_FIELD(_r, _f, _v) do { \
REG_WRITE(_r, (REG_READ(_r) & ~((_f##_V) << (_f##_S))) | (((_v) & (_f##_V)) << (_f##_S))); \
REG_WRITE(_r, (REG_READ(_r) & ~((volatile uint32_t)((_f##_V) << (_f##_S)))) | (((volatile uint32_t)(_v) & (_f##_V)) << (_f##_S))); \
} while(0)

// Value field manipulation macros
#define VALUE_GET_FIELD(_r, _f) (((_r) >> (_f##_S)) & (_f))

#define VALUE_GET_FIELD2(_r, _f) (((_r) & (_f)) >> (_f##_S))

#define VALUE_SET_FIELD(_r, _f, _v) ((_r) = ((_r) & ~((_f) << (_f##_S))) | ((_v) << (_f##_S)))
#define VALUE_SET_FIELD(_r, _f, _v) ((_r) = ((_r) & ~((volatile uint32_t)((_f) << (_f##_S)))) | ((volatile uint32_t)(_v) << (_f##_S)))

#define VALUE_SET_FIELD2(_r, _f, _v) ((_r) = ((_r) & ~(_f)) | ((_v) << (_f##_S)))
#define VALUE_SET_FIELD2(_r, _f, _v) ((_r) = ((_r) & ~(volatile uint32_t)(_f)) | ((volatile uint32_t)(_v) << (_f##_S)))

// Field to value conversion macros
#define FIELD_TO_VALUE(_f, _v) (((_v) & (_f)) << _f##_S)
Expand All @@ -64,7 +66,7 @@
#define WRITE_PERI_REG(addr, val) REG_WRITE(ETS_UNCACHED_ADDR(addr), (uint32_t)(val))

#define CLEAR_PERI_REG_MASK(reg, mask) do { \
WRITE_PERI_REG(reg, READ_PERI_REG(reg) & (~(mask))); \
WRITE_PERI_REG(reg, READ_PERI_REG(reg) & (~(volatile uint32_t)(mask))); \
} while(0)

#define SET_PERI_REG_MASK(reg, mask) do { \
Expand All @@ -80,7 +82,7 @@
})

#define SET_PERI_REG_BITS(reg, bit_map, value, shift) do { \
WRITE_PERI_REG(reg, (READ_PERI_REG(reg) & (~((bit_map) << (shift)))) | (((value) & (bit_map)) << (shift))); \
WRITE_PERI_REG(reg, (READ_PERI_REG(reg) & (~((volatile uint32_t)(bit_map) << (shift)))) | (((volatile uint32_t)(value) & (volatile uint32_t)(bit_map)) << (shift))); \
} while(0)

#define GET_PERI_REG_BITS2(reg, mask, shift) ({ \
Expand Down
12 changes: 12 additions & 0 deletions src/clock.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*/

#include <target/clock.h>

void stub_lib_clock_init(void)
{
stub_target_clock_init();
}
29 changes: 29 additions & 0 deletions src/target/base/include/target/clock.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*/

#pragma once

#include <stdint.h>
#include <stdbool.h>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to include stdbool.h


/**
* @brief Initialize clock
*/
void stub_target_clock_init(void);

/**
* @brief Get CPU frequency
*
* @return CPU frequency in Hz
*/
uint32_t stub_target_get_cpu_freq(void);

/**
* @brief Get APB frequency
*
* @return APB frequency in Hz
*/
uint32_t stub_target_get_apb_freq(void);
19 changes: 11 additions & 8 deletions src/target/common/src/uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#include <target/clock.h>
#include <target/uart.h>

extern void esp_rom_set_cpu_ticks_per_us(uint32_t ticks_per_us);
extern uint32_t esp_rom_get_cpu_freq(void);
extern void esp_rom_uart_set_as_console(uint8_t uart_no);
extern void esp_rom_uart_tx_wait_idle(uint8_t uart_num);
extern void esp_rom_uart_div_modify(uint8_t uart_no, uint32_t divisor);
extern void esp_rom_uart_flush_tx(uint8_t uart_no);
extern uint32_t esp_rom_get_xtal_freq(void);

void __attribute__((weak)) stub_target_uart_wait_idle(uint8_t uart_num)
{
Expand All @@ -23,20 +23,23 @@ void __attribute__((weak)) stub_target_uart_wait_idle(uint8_t uart_num)

void __attribute__((weak)) stub_target_uart_init(uint8_t uart_num)
{
esp_rom_set_cpu_ticks_per_us(esp_rom_get_cpu_freq() / 1000000);
stub_target_rom_uart_attach(NULL);
uint32_t clock = esp_rom_get_cpu_freq();
uint32_t clock = esp_rom_get_xtal_freq();
stub_target_rom_uart_init(uart_num, clock);
esp_rom_uart_set_as_console(uart_num);
}

void __attribute__((weak)) stub_target_uart_rominit_set_baudrate(uint8_t uart_num, uint32_t baudrate)
{
uint32_t clock = esp_rom_get_cpu_freq() << 4;
uint32_t divisor = clock / baudrate;
extern void stub_lib_delay_us(uint32_t us);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#include <esp-stub-lib/rom_wrappers.h> Or without wrapper ets_delay_us. It is ok to call rom functions directly from targets.


stub_lib_delay_us(5 * 1000);

uint32_t clk_div = (esp_rom_get_xtal_freq() << 4) / baudrate;
stub_target_uart_wait_idle(uart_num);
esp_rom_uart_div_modify(uart_num, divisor);
// TODO: Consider decimal part
esp_rom_uart_div_modify(uart_num, clk_div);

stub_lib_delay_us(5 * 1000);
}

void __attribute__((weak)) stub_target_uart_tx_flush(uint8_t uart_no)
Expand Down
1 change: 1 addition & 0 deletions src/target/esp32/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ set(srcs
src/trax.c
src/uart.c
src/security.c
src/clock.c
)

add_library(${ESP_TARGET_LIB} STATIC ${srcs})
Expand Down
Loading