-
Notifications
You must be signed in to change notification settings - Fork 5
Feat: Add cpu clock increase #42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
👋 Hello Dzarda7, we appreciate your contribution to this project! Click to see more instructions ...
Review and merge process you can expect ...
|
|
@erhankur After this, the rominit from set baudrate function can be basically removed I believe, only issue is the ESP32-C2 where we need to determine crystal frequency from previously initialized baudrate. If you can suggest different way to detect it how you do that, then I can fix this also. Only other way I can think of is calculate RTC clock and compare, which is a bit overkill for the stub. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR adds CPU clock frequency increase functionality across all ESP targets and fixes the UART baudrate setting mechanism. The implementation increases CPU speeds to maximize stub performance while ensuring proper UART communication after clock changes.
Key changes:
- Introduces clock initialization infrastructure with target-specific implementations
- Updates UART baudrate calculation to use correct clock sources (APB frequency instead of crystal/CPU frequency)
- Adds delays before/after baudrate changes for stability
- Includes volatile casts in register manipulation macros to prevent compiler optimization issues
Reviewed changes
Copilot reviewed 59 out of 64 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/target/*/src/clock.c | Target-specific clock initialization implementations setting CPU frequencies (ESP32: 160MHz, ESP32-S2: 240MHz, ESP32-P4: 320MHz, etc.) |
| src/target/*/src/uart.c | Updated baudrate calculation to use APB frequency and added stability delays |
| src/target/base/include/target/clock.h | New internal API header defining clock initialization and frequency getter functions |
| src/target//ld/.rom.api.ld | Updated ROM API mappings for clock-related functions (esp_rom_get_xtal_freq, removed esp_rom_get_apb_freq where replaced) |
| include/esp-stub-lib/soc_utils.h | Added volatile casts to register manipulation macros to prevent unwanted compiler optimizations |
| src/target/*/CMakeLists.txt | Added clock.c source files to build configuration for each target |
| src/clock.c | Top-level clock wrapper calling target-specific initialization |
| src/target/common/src/uart.c | Updated weak default UART implementation to use crystal frequency |
| PROVIDE ( esp_rom_get_xtal_freq = ets_clk_get_xtal_freq ); | ||
| PROVIDE ( esp_rom_get_cpu_freq = ets_clk_get_cpu_freq ); |
Copilot
AI
Dec 16, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Duplicate PROVIDE declaration for esp_rom_get_cpu_freq. Line 29 declares it, and line 31 declares it again. Remove one of the duplicate declarations.
| stub_target_rom_uart_init(uart_num, clock); | ||
|
|
||
| // Set UART clock source to APB, after this, baudrate needs to be set again to recalculate the clock divider | ||
| SET_PERI_REG_BITS(UART_CLK_CONF_REG(0), UART_SCLK_SEL_V, 1, UART_SCLK_SEL_S); |
Copilot
AI
Dec 16, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment states "Set UART clock source to APB, after this, baudrate needs to be set again to recalculate the clock divider". However, the code is changing the clock source to APB (value 1) but the baudrate is being set immediately after without any verification that the clock source change has taken effect. Consider adding a brief explanation of why this is safe, or if any additional synchronization is needed after changing the clock source.
| SET_PERI_REG_BITS(UART_CLK_CONF_REG(0), UART_SCLK_SEL_V, 1, UART_SCLK_SEL_S); | |
| SET_PERI_REG_BITS(UART_CLK_CONF_REG(0), UART_SCLK_SEL_V, 1, UART_SCLK_SEL_S); | |
| // Ensure the clock source change has taken effect before setting baudrate. | |
| // On ESP32-C3, register writes are synchronous, but a short delay is added for safety and future compatibility. | |
| stub_lib_delay_us(10); // 10us is sufficient for peripheral clock domain sync |
|
BTW to be completely correct, we should set dbias voltage for CPU accordingly to the frequency increase which we are not doing. It is done for ESP32, ESP32-C2 and ESP32-S2 as it is simple there. For newer chips we need to read the calibration value from eFuse, which is quite complicated so it was left out for now as we also did not do that in the old stub and issue was found only foe ESP32-S3 (even thought we might have missed some and considered them as HW issue). |
|
|
||
| #pragma once | ||
|
|
||
| #include <stdint.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to include
| #pragma once | ||
|
|
||
| #include <stdint.h> | ||
| #include <stdbool.h> |
There was a problem hiding this comment.
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
| { | ||
| uint32_t clock = esp_rom_get_cpu_freq() << 4; | ||
| uint32_t divisor = clock / baudrate; | ||
| extern void stub_lib_delay_us(uint32_t us); |
There was a problem hiding this comment.
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.
|
|
||
| #define RTC_STORE5 (DR_REG_RTCCNTL_BASE + 0xb4) | ||
|
|
||
| #define MHZ 1000000 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the definitions, we can create a new header under base/
| */ | ||
|
|
||
| #include <stdint.h> | ||
| #include <stdbool.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to include. Please check also other files.
| esp_rom_set_cpu_ticks_per_us(s_cpu_freq / MHZ); | ||
| } | ||
|
|
||
| uint32_t stub_target_get_cpu_freq(void) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I see, stub_target_get_cpu_freq same for all targets. You could return s_cpu_freq from targets and process it inside common?
| esp_rom_set_cpu_ticks_per_us(esp_rom_get_xtal_freq() / 1000000); | ||
| stub_target_rom_uart_init(uart_num, UART_CLK_FREQ_ROM); | ||
| uint32_t clock = stub_target_get_apb_freq(); | ||
| stub_target_rom_uart_init(uart_num, clock); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| stub_target_rom_uart_init(uart_num, clock); | |
| stub_target_rom_uart_init(uart_num, stub_target_get_apb_freq()); |
| REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, 1); | ||
| REG_SET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_PLL_FREQ_SEL, 1); | ||
| REG_SET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPUPERIOD_SEL, 1); | ||
| s_cpu_freq = 160 * MHZ; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also for other targets
#define CPU_FREQ_MHZ 160 // on top
s_cpu_freq = CPU_FREQ_MHZ * MHZ;
esp_rom_set_cpu_ticks_per_us(CPU_FREQ_MHZ);|
|
||
| uint32_t stub_target_get_cpu_freq(void) | ||
| { | ||
| if (s_cpu_freq == 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you want to check if stub_target_clock_init is called? If not called, will it be different from the value that set in clock init?
Description
This PR adds CPU frequency increase and fixes the set baudrate function.
Related
Testing
Tested on all targets and measured CPU frequency using Logic analyzer.
Checklist
Before submitting a Pull Request, please ensure the following: