Skip to content

Commit e61c486

Browse files
committed
Use max CPU clock frequency
1 parent e4ac738 commit e61c486

File tree

7 files changed

+142
-23
lines changed

7 files changed

+142
-23
lines changed

Cargo.lock

Lines changed: 8 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ edition = "2018"
77
[dependencies]
88
panic-never = "0.1.0"
99
ufmt = { version = "0.1.0", optional = true }
10-
10+
cfg-if = "1.0"
1111

1212
[features]
1313
log = ["ufmt"]
@@ -22,6 +22,9 @@ esp32c5 = []
2222
esp32c6 = []
2323
esp32h2 = []
2424

25+
# use max CPU frequency
26+
max-cpu-frequency = []
27+
2528
[profile.release]
2629
codegen-units = 1
2730
debug = false

ld/esp32c3.x

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ MEMORY {
33
IRAM : ORIGIN = 0x40390000, LENGTH = 0x10000
44
}
55

6+
PROVIDE( ets_delay_us = 0x40000050 );
67
PROVIDE( esp_rom_spiflash_wait_idle = 0x4000010c );
78
PROVIDE( esp_rom_spiflash_write_encrypted = 0x40000110 );
89
PROVIDE( esp_rom_spiflash_write_encrypted_dest = 0x40000114 );

ld/esp32s2.x

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ MEMORY {
1010
* These are all weak symbols that could be overwritten in ESP-IDF.
1111
*/
1212

13+
PROVIDE ( ets_delay_us = 0x4000d888 );
1314
PROVIDE ( ets_efuse_get_spiconfig = 0x4000e4a0 );
1415
PROVIDE ( s_cdcacm_old_rts = 0x3ffffd34 );
1516
PROVIDE ( SelectSpiFunction = 0x40015d08 );

ld/esp32s3.x

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,7 @@ MEMORY {
33
IRAM : ORIGIN = 0x40380400, LENGTH = 0x10000
44
}
55

6-
/* ROM function interface esp32s3.rom.ld for esp32s3
7-
*
8-
*
9-
* Generated from ./interface-esp32s3.yml md5sum 39c4ce259b11323b9404c192b01b712b
10-
*
11-
* Compatible with ROM where ECO version equal or greater to 0.
12-
*
13-
* THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT.
14-
*/
15-
6+
PROVIDE( ets_delay_us = 0x40000600 );
167
PROVIDE ( esp_rom_spiflash_attach = spi_flash_attach );
178

189
/***************************************

src/flash.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ extern "C" {
4646
#[cfg(feature = "esp32s3")]
4747
#[allow(non_camel_case_types)]
4848
mod s3 {
49-
5049
type spi_flash_func_t = unsafe extern "C" fn();
5150
type spi_flash_op_t = unsafe extern "C" fn() -> i32;
5251
type spi_flash_erase_t = unsafe extern "C" fn(u32) -> i32;
@@ -82,7 +81,6 @@ use s3::*;
8281

8382
#[cfg(feature = "esp32s3")]
8483
extern "C" {
85-
8684
static mut rom_spiflash_legacy_funcs: *const spiflash_legacy_funcs_t;
8785
static mut rom_spiflash_legacy_data: *mut ();
8886

src/main.rs

Lines changed: 127 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
#![no_main]
33
#![cfg_attr(target_arch = "xtensa", feature(asm_experimental_arch))]
44

5+
// TODO: implement clock frequency setting for ESP32-C5
6+
57
// Target memory configuration
68

79
// Decompressor is 43776 bytes, reserve more in case compiler changes layout
@@ -78,7 +80,6 @@ const ERROR_BASE_FLASH: i32 = -4000;
7880

7981
#[cfg(feature = "log")]
8082
mod log {
81-
8283
extern "C" {
8384
fn uart_tx_one_char(byte: u8);
8485
}
@@ -119,22 +120,138 @@ macro_rules! dprintln {
119120
($fmt:expr, $($arg:tt)*) => {};
120121
}
121122

123+
#[cfg(all(feature = "max-cpu-frequency", not(feature = "esp32c5")))]
124+
mod max_cpu_frequency {
125+
cfg_if::cfg_if! {
126+
if #[cfg(feature = "esp32")] {
127+
const SYSTEM_CPU_PER_CONF_REG: *mut u32 = 0x3FF0003C as *mut u32;
128+
const SYSTEM_CPUPERIOD_SEL_M: u32 = 3;
129+
const SYSTEM_CPUPERIOD_MAX: u32 = 2;
130+
131+
const SYSTEM_SYSCLK_CONF_REG: *mut u32 = 0x3FF48070 as *mut u32;
132+
const SYSTEM_SOC_CLK_SEL_M: u32 = 3 << 27;
133+
const SYSTEM_SOC_CLK_MAX: u32 = 1 << 27;
134+
} else if #[cfg(feature = "esp32s2")] {
135+
const SYSTEM_CPU_PER_CONF_REG: *mut u32 = 0x3F4C0018 as *mut u32;
136+
const SYSTEM_CPUPERIOD_SEL_M: u32 = 3;
137+
const SYSTEM_CPUPERIOD_MAX: u32 = 2;
138+
139+
const SYSTEM_SYSCLK_CONF_REG: *mut u32 = 0x3F4C008C as *mut u32;
140+
const SYSTEM_SOC_CLK_SEL_M: u32 = 3 << 10;
141+
const SYSTEM_SOC_CLK_MAX: u32 = 1 << 10;
142+
} else if #[cfg(feature = "esp32s3")] {
143+
const SYSTEM_CPU_PER_CONF_REG: *mut u32 = 0x600C0010 as *mut u32;
144+
const SYSTEM_CPUPERIOD_SEL_M: u32 = 3;
145+
const SYSTEM_CPUPERIOD_MAX: u32 = 2;
146+
147+
const SYSTEM_SYSCLK_CONF_REG: *mut u32 = 0x600C0060 as *mut u32;
148+
const SYSTEM_SOC_CLK_SEL_M: u32 = 3 << 10;
149+
const SYSTEM_SOC_CLK_MAX: u32 = 1 << 10;
150+
} else if #[cfg(any(feature = "esp32c2", feature = "esp32c3"))] {
151+
const SYSTEM_CPU_PER_CONF_REG: *mut u32 = 0x600C0008 as *mut u32;
152+
const SYSTEM_CPUPERIOD_SEL_M: u32 = 3;
153+
const SYSTEM_CPUPERIOD_MAX: u32 = 1;
154+
155+
const SYSTEM_SYSCLK_CONF_REG: *mut u32 = 0x600C0058 as *mut u32;
156+
const SYSTEM_SOC_CLK_SEL_M: u32 = 3 << 10;
157+
const SYSTEM_SOC_CLK_MAX: u32 = 1 << 10;
158+
} else if #[cfg(feature = "esp32h2")] {
159+
const PCR_SYSCLK_CONF_REG: *mut u32 = 0x6009610c as *mut u32;
160+
161+
const PCR_SOC_CLK_SEL_M: u32 = 3 << 16;
162+
const PCR_SOC_CLK_MAX: u32 = 1 << 16;
163+
} else if #[cfg(feature = "esp32c6")] {
164+
const PCR_SYSCLK_CONF_REG: *mut u32 = 0x60096110 as *mut u32;
165+
166+
const PCR_SOC_CLK_SEL_M: u32 = 3 << 16;
167+
const PCR_SOC_CLK_MAX: u32 = 1 << 16;
168+
}
169+
}
170+
171+
pub struct CpuSaveState {
172+
#[cfg(not(any(feature = "esp32c6", feature = "esp32h2")))]
173+
saved_cpu_per_conf_reg: u32,
174+
saved_sysclk_conf_reg: u32,
175+
}
176+
177+
pub fn set_max_cpu_freq(state: &mut CpuSaveState) {
178+
cfg_if::cfg_if! {
179+
if #[cfg(any(feature = "esp32c6", feature = "esp32h2"))] {
180+
state.saved_sysclk_conf_reg = unsafe { PCR_SYSCLK_CONF_REG.read_volatile() };
181+
} else {
182+
state.saved_cpu_per_conf_reg = unsafe { SYSTEM_CPU_PER_CONF_REG.read_volatile() };
183+
state.saved_sysclk_conf_reg = unsafe { SYSTEM_SYSCLK_CONF_REG.read_volatile() };
184+
}
185+
}
186+
187+
cfg_if::cfg_if! {
188+
if #[cfg(any(feature = "esp32c6", feature = "esp32h2"))] {
189+
unsafe { PCR_SYSCLK_CONF_REG.write_volatile((state.saved_sysclk_conf_reg & !PCR_SOC_CLK_SEL_M) | PCR_SOC_CLK_MAX) };
190+
} else if #[cfg(feature = "esp32s3")] {
191+
extern "C" {
192+
fn ets_delay_us(us: u32);
193+
}
194+
195+
unsafe { SYSTEM_SYSCLK_CONF_REG.write_volatile((state.saved_sysclk_conf_reg & !SYSTEM_SOC_CLK_SEL_M) | SYSTEM_SOC_CLK_MAX) };
196+
// Leave some time for the change to settle, needed for ESP32-S3
197+
unsafe { ets_delay_us(100) };
198+
unsafe { SYSTEM_CPU_PER_CONF_REG.write_volatile((state.saved_cpu_per_conf_reg & !SYSTEM_CPUPERIOD_SEL_M) | SYSTEM_CPUPERIOD_MAX) };
199+
} else {
200+
unsafe { SYSTEM_CPU_PER_CONF_REG.write_volatile((state.saved_cpu_per_conf_reg & !SYSTEM_CPUPERIOD_SEL_M) | SYSTEM_CPUPERIOD_MAX) };
201+
unsafe { SYSTEM_SYSCLK_CONF_REG.write_volatile((state.saved_sysclk_conf_reg & !SYSTEM_SOC_CLK_SEL_M) | SYSTEM_SOC_CLK_MAX) };
202+
}
203+
}
204+
}
205+
206+
pub fn restore_max_cpu_freq(state: &mut CpuSaveState) {
207+
cfg_if::cfg_if! {
208+
if #[cfg(any(feature = "esp32c6", feature = "esp32h2"))] {
209+
unsafe { PCR_SYSCLK_CONF_REG.write_volatile(state.saved_sysclk_conf_reg) };
210+
} else {
211+
unsafe { SYSTEM_SYSCLK_CONF_REG.write_volatile(state.saved_sysclk_conf_reg) };
212+
unsafe { SYSTEM_CPU_PER_CONF_REG.write_volatile(state.saved_cpu_per_conf_reg) };
213+
}
214+
}
215+
}
216+
}
217+
218+
#[cfg(any(not(feature = "max-cpu-frequency"), feature = "esp32c5"))]
219+
mod max_cpu_frequency {
220+
pub struct CpuSaveState {}
221+
222+
pub fn set_max_cpu_freq(_: &mut CpuSaveState) {}
223+
pub fn restore_max_cpu_freq(_: &mut CpuSaveState) {}
224+
}
225+
226+
use max_cpu_frequency::*;
227+
228+
struct FlasherState {
229+
inited: u32,
230+
saved_cpu_state: CpuSaveState,
231+
decompressor: Decompressor,
232+
}
233+
122234
const INITED_MAGIC: u32 = 0xAAC0FFEE;
123-
const INITED: *mut u32 = STATE_ADDR as *mut u32;
124-
const DECOMPRESSOR: *mut Decompressor = (STATE_ADDR + 4) as *mut Decompressor;
235+
const STATE_OBJ: *mut FlasherState = STATE_ADDR as *mut FlasherState;
236+
237+
fn state() -> &'static mut FlasherState {
238+
unsafe { &mut *STATE_OBJ }
239+
}
125240

126241
fn is_inited() -> bool {
127-
unsafe { *INITED == INITED_MAGIC }
242+
state().inited == INITED_MAGIC
128243
}
129244

130245
/// Setup the device for the flashing process.
131246
#[no_mangle]
132247
pub unsafe extern "C" fn Init_impl(_adr: u32, _clk: u32, _fnc: u32) -> i32 {
133248
dprintln!("INIT");
134249

250+
set_max_cpu_freq(&mut state().saved_cpu_state);
251+
135252
if flash::attach() == 0 {
136-
*DECOMPRESSOR = Decompressor::new();
137-
*INITED = INITED_MAGIC;
253+
state().decompressor = Decompressor::new();
254+
state().inited = INITED_MAGIC;
138255
0
139256
} else {
140257
1
@@ -175,7 +292,7 @@ pub unsafe extern "C" fn ProgramPage_impl(adr: u32, sz: u32, buf: *const u8) ->
175292

176293
let input = core::slice::from_raw_parts(buf, sz as usize);
177294

178-
(*DECOMPRESSOR).program(adr, input)
295+
state().decompressor.program(adr, input)
179296
}
180297

181298
#[no_mangle]
@@ -193,7 +310,7 @@ pub unsafe extern "C" fn Verify_impl(adr: u32, sz: u32, buf: *const u8) -> i32 {
193310

194311
let input = core::slice::from_raw_parts(buf, sz as usize);
195312

196-
(*DECOMPRESSOR).verify(adr, input)
313+
state().decompressor.verify(adr, input)
197314
}
198315

199316
#[no_mangle]
@@ -219,7 +336,8 @@ pub unsafe extern "C" fn UnInit_impl(fnc: u32) -> i32 {
219336
return ERROR_BASE_INTERNAL - 1;
220337
};
221338

222-
*INITED = 0;
339+
restore_max_cpu_freq(&mut state().saved_cpu_state);
340+
state().inited = 0;
223341

224342
if fnc == 2 {
225343
// The flash ROM functions don't wait for the end of the last operation.

0 commit comments

Comments
 (0)