Skip to content

Commit 67d5ebc

Browse files
committed
Improve updated devisors
1 parent f7c56e3 commit 67d5ebc

File tree

2 files changed

+38
-14
lines changed

2 files changed

+38
-14
lines changed

Diff for: cores/esp32/esp32-hal-cpu.c

+32-11
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "soc/rtc.h"
2323
#include "soc/rtc_cntl_reg.h"
2424
#include "rom/rtc.h"
25+
#include "soc/apb_ctrl_reg.h"
2526
#include "esp32-hal.h"
2627
#include "esp32-hal-cpu.h"
2728

@@ -31,16 +32,11 @@ typedef struct apb_change_cb_s {
3132
apb_change_cb_t cb;
3233
} apb_change_t;
3334

35+
const uint32_t MHZ = 1000000;
36+
3437
static apb_change_t * apb_change_callbacks = NULL;
3538
static xSemaphoreHandle apb_change_lock = NULL;
3639

37-
static uint32_t calculateApb(rtc_cpu_freq_config_t * conf){
38-
if(conf->freq_mhz >= 80){
39-
return 80000000;
40-
}
41-
return (conf->source_freq_mhz * 1000000) / conf->div;
42-
}
43-
4440
static void initApbChangeCallback(){
4541
static volatile bool initialized = false;
4642
if(!initialized){
@@ -119,31 +115,56 @@ bool removeApbChangeCallback(void * arg, apb_change_cb_t cb){
119115
return true;
120116
}
121117

118+
static uint32_t calculateApb(rtc_cpu_freq_config_t * conf){
119+
if(conf->freq_mhz >= 80){
120+
return 80 * MHZ;
121+
}
122+
return (conf->source_freq_mhz * MHZ) / conf->div;
123+
}
124+
122125
void esp_timer_impl_update_apb_freq(uint32_t apb_ticks_per_us); //private in IDF
123126

124127
bool setCpuFrequency(uint32_t cpu_freq_mhz){
125128
rtc_cpu_freq_config_t conf, cconf;
126129
uint32_t capb, apb;
130+
//Get current CPU clock configuration
127131
rtc_clk_cpu_freq_get_config(&cconf);
132+
//return if frequency has not changed
128133
if(cconf.freq_mhz == cpu_freq_mhz){
129134
return true;
130135
}
136+
//Get configuration for the new CPU frequency
131137
if(!rtc_clk_cpu_freq_mhz_to_config(cpu_freq_mhz, &conf)){
132138
log_e("CPU clock could not be set to %u MHz", cpu_freq_mhz);
133139
return false;
134140
}
141+
//Current APB
135142
capb = calculateApb(&cconf);
143+
//New APB
136144
apb = calculateApb(&conf);
137-
log_i("%s: %u / %u = %u Mhz", (conf.source == RTC_CPU_FREQ_SRC_PLL)?"PLL":((conf.source == RTC_CPU_FREQ_SRC_APLL)?"APLL":((conf.source == RTC_CPU_FREQ_SRC_XTAL)?"XTAL":"8M")), conf.source_freq_mhz, conf.div, conf.freq_mhz);
145+
log_i("%s: %u / %u = %u Mhz, APB: %u Hz", (conf.source == RTC_CPU_FREQ_SRC_PLL)?"PLL":((conf.source == RTC_CPU_FREQ_SRC_APLL)?"APLL":((conf.source == RTC_CPU_FREQ_SRC_XTAL)?"XTAL":"8M")), conf.source_freq_mhz, conf.div, conf.freq_mhz, apb);
146+
//Call peripheral functions before the APB change
138147
if(capb != apb && apb_change_callbacks){
139148
triggerApbChangeCallback(APB_BEFORE_CHANGE, capb, apb);
140149
}
150+
//Make the frequency change
141151
rtc_clk_cpu_freq_set_config_fast(&conf);
152+
if(capb != apb){
153+
//Update REF_TICK
154+
uint32_t xtal_mhz = rtc_clk_xtal_freq_get();
155+
uint32_t tick_freq_mhz = (conf.freq_mhz >= xtal_mhz)?xtal_mhz:conf.freq_mhz;
156+
uint32_t tick_conf = tick_freq_mhz / (REF_CLK_FREQ / MHZ) - 1;
157+
ESP_REG(APB_CTRL_XTAL_TICK_CONF_REG) = tick_conf;
158+
//Update APB Freq REG
159+
rtc_clk_apb_freq_update(apb);
160+
//Update esp_timer divisor
161+
esp_timer_impl_update_apb_freq(apb / MHZ);
162+
}
142163
//Update FreeRTOS Tick Divisor
143-
_xt_tick_divisor = cpu_freq_mhz * 1000000 / XT_TICK_PER_SEC;
164+
uint32_t fcpu = (conf.freq_mhz >= 80)?(conf.freq_mhz * MHZ):(apb);
165+
_xt_tick_divisor = fcpu / XT_TICK_PER_SEC;
166+
//Call peripheral functions after the APB change
144167
if(capb != apb && apb_change_callbacks){
145-
//Update esp_timer divisor
146-
esp_timer_impl_update_apb_freq(apb / 1000000);
147168
triggerApbChangeCallback(APB_AFTER_CHANGE, capb, apb);
148169
}
149170
return true;

Diff for: cores/esp32/esp32-hal-misc.c

+6-3
Original file line numberDiff line numberDiff line change
@@ -100,15 +100,18 @@ void disableCore1WDT(){
100100
}
101101
#endif
102102

103-
unsigned long IRAM_ATTR micros(){
103+
unsigned long IRAM_ATTR micros()
104+
{
104105
return (unsigned long) (esp_timer_get_time());
105106
}
106107

107-
unsigned long IRAM_ATTR millis(){
108+
unsigned long IRAM_ATTR millis()
109+
{
108110
return (unsigned long) (esp_timer_get_time() / 1000);
109111
}
110112

111-
void delay(uint32_t ms){
113+
void delay(uint32_t ms)
114+
{
112115
vTaskDelay(ms / portTICK_PERIOD_MS);
113116
}
114117

0 commit comments

Comments
 (0)