-
Notifications
You must be signed in to change notification settings - Fork 7.6k
CPU and APB Frequency support #2220
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
Changes from 2 commits
3d54e6d
797aa09
256d006
2c8df88
1e8b9fb
cccf011
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,31 +42,42 @@ void yield() | |
vPortYield(); | ||
} | ||
|
||
static uint32_t _cpu_freq_mhz = 240; | ||
static uint32_t _cpu_freq_mhz = CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ; | ||
static uint32_t _sys_time_multiplier = 1; | ||
|
||
bool cpuFrequencySet(uint32_t cpu_freq_mhz){ | ||
if(_cpu_freq_mhz == cpu_freq_mhz){ | ||
bool setCpuFrequency(uint32_t cpu_freq_mhz){ | ||
rtc_cpu_freq_config_t conf, cconf; | ||
rtc_clk_cpu_freq_get_config(&cconf); | ||
if(cconf.freq_mhz == cpu_freq_mhz && _cpu_freq_mhz == cpu_freq_mhz){ | ||
return true; | ||
} | ||
rtc_cpu_freq_config_t conf; | ||
if(!rtc_clk_cpu_freq_mhz_to_config(cpu_freq_mhz, &conf)){ | ||
log_e("CPU clock could not be set to %u MHz", cpu_freq_mhz); | ||
return false; | ||
} | ||
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO | ||
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); | ||
delay(10); | ||
#endif | ||
rtc_clk_cpu_freq_set_config(&conf); | ||
_cpu_freq_mhz = conf.freq_mhz; | ||
_sys_time_multiplier = 80 / getApbFrequency(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will always set There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. how did I miss this :D |
||
return true; | ||
} | ||
|
||
uint32_t cpuFrequencyGet(){ | ||
uint32_t getCpuFrequency(){ | ||
rtc_cpu_freq_config_t conf; | ||
rtc_clk_cpu_freq_get_config(&conf); | ||
return conf.freq_mhz; | ||
} | ||
|
||
uint32_t getApbFrequency(){ | ||
return rtc_clk_apb_freq_get() / 1000000; | ||
} | ||
|
||
unsigned long IRAM_ATTR micros() | ||
{ | ||
return (unsigned long) ((esp_timer_get_time() * 240) / _cpu_freq_mhz); | ||
return (unsigned long) (esp_timer_get_time()) * _sys_time_multiplier; | ||
} | ||
|
||
unsigned long IRAM_ATTR millis() | ||
|
@@ -109,6 +120,9 @@ bool btInUse(){ return false; } | |
|
||
void initArduino() | ||
{ | ||
#ifdef F_CPU | ||
setCpuFrequency(F_CPU/1000000L); | ||
#endif | ||
#if CONFIG_SPIRAM_SUPPORT | ||
psramInit(); | ||
#endif | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,6 +27,7 @@ | |
#include "soc/io_mux_reg.h" | ||
#include "soc/gpio_sig_map.h" | ||
#include "soc/dport_reg.h" | ||
#include "soc/rtc.h" | ||
#include "esp_intr_alloc.h" | ||
|
||
#define UART_REG_BASE(u) ((u==0)?DR_REG_UART_BASE:( (u==1)?DR_REG_UART1_BASE:( (u==2)?DR_REG_UART2_BASE:0))) | ||
|
@@ -352,7 +353,7 @@ void uartSetBaudRate(uart_t* uart, uint32_t baud_rate) | |
return; | ||
} | ||
UART_MUTEX_LOCK(); | ||
uint32_t clk_div = ((UART_CLK_FREQ<<4)/baud_rate); | ||
uint32_t clk_div = ((rtc_clk_apb_freq_get()<<4)/baud_rate); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There needs to be some limits between
This is with Serial Monitor Baud set to 19200. With Baud set to 115200 the ESP32 hangs when Frequency is changed to 1MHz.
Testing code: uint8_t speeds[] ={240,160,80,40,26,24,20,13,12,10,8,6,5,4,3,2,1};
void loop() {
static int c=0;
c++;
if(c>=sizeof(speeds)) c = 0;
Serial.flush();
if(!setCpuFrequency(speeds[c])){
Serial.printf("\nError setting freq[%d]=%dMHZ\n\n",c,speeds[c]);
} else{
delay(100);
Serial.begin(BAUD);
Wire.begin(SDA,SCL,100000);
Serial.printf(" After change of clock to speed[%d]=%d\n",c,speeds[c]);
Serial.printf(" rtc_clk_cpu_freq_get=%d, cpuFreq=%d\n",rtc_clk_cpu_freq_get(),getCpuFrequency());
Serial.printf(" current apb freq =%d, apbFreq=%d\n",rtc_clk_apb_freq_get(),getApbFrequency());
runBlocks();
delay(5000);
}
} Chuck. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tested with 40MHz crystal :) and uart works fine. Thanks for testing 26MHz! |
||
uart->dev->clk_div.div_int = clk_div>>4 ; | ||
uart->dev->clk_div.div_frag = clk_div & 0xf; | ||
UART_MUTEX_UNLOCK(); | ||
|
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.
I tried this mod a couple of weeks ago, the returned value didn't change, it stayed at 80,000,000. But the actual hardware clock changed speed, I could see the i2c bus speed change on my oscilloscope.
Have you changed the code inside
rtc_clk_apb_freq_get()
since Rc1 1.0.1 ?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.
to me it changes now when you set the cpu frequency below 80MHz. I have not tested I2C, but tested other peripherals. Give it a go :)
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.
see private glitter
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.
An upper bounds needs to be applied to I2C bus freq versus CPU freq:
This limits it to 1/100th APB frequency so a 5MHz APB has a max i2c of 50KHz down to 10KHz at 1MHz. I tried up to 1/80 APB, I2C did not function. In my newer code I have other places I need
MIN_I2C_CLKS
.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.
This is a good solution I think. Will also venture into dynamic cpu scaling and will see how we can manage that.