Skip to content

Commit c827bb4

Browse files
authored
CPU and APB Frequency support (espressif#2220)
* Add support to HAL for APB frequencies different than 80MHz * Add support for CPU frequencies in the IDE board menu * Switch to fast set_config * Add method to uart so debug can be reassigned after apb frequency switch * Return real APB frequency
1 parent 1628f53 commit c827bb4

9 files changed

+101
-34
lines changed

Diff for: boards.txt

+30
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
menu.UploadSpeed=Upload Speed
2+
menu.CPUFreq=CPU Frequency
23
menu.FlashFreq=Flash Frequency
34
menu.FlashMode=Flash Mode
45
menu.FlashSize=Flash Size
@@ -49,6 +50,35 @@ esp32.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080
4950
esp32.menu.PartitionScheme.fatflash=16M Fat
5051
esp32.menu.PartitionScheme.fatflash.build.partitions=ffat
5152

53+
esp32.menu.CPUFreq.240=240MHz
54+
esp32.menu.CPUFreq.240.build.f_cpu=240000000L
55+
esp32.menu.CPUFreq.160=160MHz
56+
esp32.menu.CPUFreq.160.build.f_cpu=160000000L
57+
esp32.menu.CPUFreq.80=80MHz
58+
esp32.menu.CPUFreq.80.build.f_cpu=80000000L
59+
esp32.menu.CPUFreq.40=40MHz (40MHz XTAL)
60+
esp32.menu.CPUFreq.40.build.f_cpu=40000000L
61+
esp32.menu.CPUFreq.26=26MHz (26MHz XTAL)
62+
esp32.menu.CPUFreq.26.build.f_cpu=26000000L
63+
esp32.menu.CPUFreq.20=20MHz (40MHz XTAL)
64+
esp32.menu.CPUFreq.20.build.f_cpu=20000000L
65+
esp32.menu.CPUFreq.13=13MHz
66+
esp32.menu.CPUFreq.13.build.f_cpu=13000000L
67+
esp32.menu.CPUFreq.10=10MHz (40MHz XTAL)
68+
esp32.menu.CPUFreq.10.build.f_cpu=10000000L
69+
esp32.menu.CPUFreq.8=8MHz (40MHz XTAL)
70+
esp32.menu.CPUFreq.8.build.f_cpu=8000000L
71+
esp32.menu.CPUFreq.5=5MHz
72+
esp32.menu.CPUFreq.5.build.f_cpu=5000000L
73+
esp32.menu.CPUFreq.4=4MHz
74+
esp32.menu.CPUFreq.4.build.f_cpu=4000000L
75+
esp32.menu.CPUFreq.3=3MHz
76+
esp32.menu.CPUFreq.3.build.f_cpu=3000000L
77+
esp32.menu.CPUFreq.2=2MHz
78+
esp32.menu.CPUFreq.2.build.f_cpu=2000000L
79+
esp32.menu.CPUFreq.1=1MHz
80+
esp32.menu.CPUFreq.1.build.f_cpu=1000000L
81+
5282
esp32.menu.FlashMode.qio=QIO
5383
esp32.menu.FlashMode.qio.build.flash_mode=dio
5484
esp32.menu.FlashMode.qio.build.boot=qio

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -1611,7 +1611,7 @@ i2c_err_t i2cSetFrequency(i2c_t * i2c, uint32_t clk_speed)
16111611
}
16121612
I2C_FIFO_CONF_t f;
16131613

1614-
uint32_t period = (APB_CLK_FREQ/clk_speed) / 2;
1614+
uint32_t period = (getApbFrequency()/clk_speed) / 2;
16151615
uint32_t halfPeriod = period/2;
16161616
uint32_t quarterPeriod = period/4;
16171617

@@ -1657,7 +1657,7 @@ uint32_t i2cGetFrequency(i2c_t * i2c)
16571657
uint32_t result = 0;
16581658
uint32_t old_count = (i2c->dev->scl_low_period.period+i2c->dev->scl_high_period.period);
16591659
if(old_count>0) {
1660-
result = APB_CLK_FREQ / old_count;
1660+
result = getApbFrequency() / old_count;
16611661
} else {
16621662
result = 0;
16631663
}

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ static void _ledcSetupTimer(uint8_t chan, uint32_t div_num, uint8_t bit_num, boo
8484
//max bit_num 0x1F (31)
8585
static double _ledcSetupTimerFreq(uint8_t chan, double freq, uint8_t bit_num)
8686
{
87-
uint64_t clk_freq = APB_CLK_FREQ;
87+
uint64_t clk_freq = getApbFrequency();
8888
clk_freq <<= 8;//div_num is 8 bit decimal
8989
uint32_t div_num = (clk_freq >> bit_num) / freq;
9090
bool apb_clk = true;
@@ -117,7 +117,7 @@ static double _ledcTimerRead(uint8_t chan)
117117
LEDC_MUTEX_UNLOCK();
118118
uint64_t clk_freq = 1000000;
119119
if(apb_clk) {
120-
clk_freq *= 80;
120+
clk_freq = getApbFrequency();
121121
}
122122
clk_freq <<= 8;//div_num is 8 bit decimal
123123
return (clk_freq >> bit_num) / (double)div_num;

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

+28-7
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
#endif //CONFIG_BT_ENABLED
2727
#include <sys/time.h>
2828
#include "soc/rtc.h"
29+
#include "soc/rtc_cntl_reg.h"
30+
#include "rom/rtc.h"
2931
#include "esp32-hal.h"
3032

3133
//Undocumented!!! Get chip temperature in Farenheit
@@ -42,31 +44,47 @@ void yield()
4244
vPortYield();
4345
}
4446

45-
static uint32_t _cpu_freq_mhz = 240;
47+
static uint32_t _cpu_freq_mhz = CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ;
48+
static uint32_t _sys_time_multiplier = 1;
4649

47-
bool cpuFrequencySet(uint32_t cpu_freq_mhz){
48-
if(_cpu_freq_mhz == cpu_freq_mhz){
50+
bool setCpuFrequency(uint32_t cpu_freq_mhz){
51+
rtc_cpu_freq_config_t conf, cconf;
52+
rtc_clk_cpu_freq_get_config(&cconf);
53+
if(cconf.freq_mhz == cpu_freq_mhz && _cpu_freq_mhz == cpu_freq_mhz){
4954
return true;
5055
}
51-
rtc_cpu_freq_config_t conf;
5256
if(!rtc_clk_cpu_freq_mhz_to_config(cpu_freq_mhz, &conf)){
5357
log_e("CPU clock could not be set to %u MHz", cpu_freq_mhz);
5458
return false;
5559
}
56-
rtc_clk_cpu_freq_set_config(&conf);
60+
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO
61+
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);
62+
delay(10);
63+
#endif
64+
rtc_clk_cpu_freq_set_config_fast(&conf);
5765
_cpu_freq_mhz = conf.freq_mhz;
66+
_sys_time_multiplier = 80 / getApbFrequency();
5867
return true;
5968
}
6069

61-
uint32_t cpuFrequencyGet(){
70+
uint32_t getCpuFrequency(){
6271
rtc_cpu_freq_config_t conf;
6372
rtc_clk_cpu_freq_get_config(&conf);
6473
return conf.freq_mhz;
6574
}
6675

76+
uint32_t getApbFrequency(){
77+
rtc_cpu_freq_config_t conf;
78+
rtc_clk_cpu_freq_get_config(&conf);
79+
if(conf.freq_mhz >= 80){
80+
return 80000000;
81+
}
82+
return (conf.source_freq_mhz * 1000000) / conf.div;
83+
}
84+
6785
unsigned long IRAM_ATTR micros()
6886
{
69-
return (unsigned long) ((esp_timer_get_time() * 240) / _cpu_freq_mhz);
87+
return (unsigned long) (esp_timer_get_time()) * _sys_time_multiplier;
7088
}
7189

7290
unsigned long IRAM_ATTR millis()
@@ -109,6 +127,9 @@ bool btInUse(){ return false; }
109127

110128
void initArduino()
111129
{
130+
#ifdef F_CPU
131+
setCpuFrequency(F_CPU/1000000L);
132+
#endif
112133
#if CONFIG_SPIRAM_SUPPORT
113134
psramInit();
114135
#endif

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

+3-2
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ uint32_t sigmaDeltaSetup(uint8_t channel, uint32_t freq) //chan 0-7 freq 1220-31
4343
_sd_sys_lock = xSemaphoreCreateMutex();
4444
}
4545
#endif
46-
uint32_t prescale = (10000000/(freq*32)) - 1;
46+
uint32_t apb_freq = getApbFrequency();
47+
uint32_t prescale = (apb_freq/(freq*256)) - 1;
4748
if(prescale > 0xFF) {
4849
prescale = 0xFF;
4950
}
@@ -52,7 +53,7 @@ uint32_t sigmaDeltaSetup(uint8_t channel, uint32_t freq) //chan 0-7 freq 1220-31
5253
SIGMADELTA.cg.clk_en = 0;
5354
SIGMADELTA.cg.clk_en = 1;
5455
SD_MUTEX_UNLOCK();
55-
return 10000000/((prescale + 1) * 32);
56+
return apb_freq/((prescale + 1) * 256);
5657
}
5758

5859
void sigmaDeltaWrite(uint8_t channel, uint8_t duty) //chan 0-7 duty 8 bit

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

+10-7
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "soc/io_mux_reg.h"
2727
#include "soc/gpio_sig_map.h"
2828
#include "soc/dport_reg.h"
29+
#include "soc/rtc.h"
2930

3031
#define SPI_CLK_IDX(p) ((p==0)?SPICLK_OUT_IDX:((p==1)?SPICLK_OUT_IDX:((p==2)?HSPICLK_OUT_IDX:((p==3)?VSPICLK_OUT_IDX:0))))
3132
#define SPI_MISO_IDX(p) ((p==0)?SPIQ_OUT_IDX:((p==1)?SPIQ_OUT_IDX:((p==2)?HSPIQ_OUT_IDX:((p==3)?VSPIQ_OUT_IDX:0))))
@@ -750,7 +751,7 @@ void spiEndTransaction(spi_t * spi)
750751
SPI_MUTEX_UNLOCK();
751752
}
752753

753-
void spiWriteByteNL(spi_t * spi, uint8_t data)
754+
void IRAM_ATTR spiWriteByteNL(spi_t * spi, uint8_t data)
754755
{
755756
if(!spi) {
756757
return;
@@ -776,7 +777,7 @@ uint8_t spiTransferByteNL(spi_t * spi, uint8_t data)
776777
return data;
777778
}
778779

779-
void spiWriteShortNL(spi_t * spi, uint16_t data)
780+
void IRAM_ATTR spiWriteShortNL(spi_t * spi, uint16_t data)
780781
{
781782
if(!spi) {
782783
return;
@@ -811,7 +812,7 @@ uint16_t spiTransferShortNL(spi_t * spi, uint16_t data)
811812
return data;
812813
}
813814

814-
void spiWriteLongNL(spi_t * spi, uint32_t data)
815+
void IRAM_ATTR spiWriteLongNL(spi_t * spi, uint32_t data)
815816
{
816817
if(!spi) {
817818
return;
@@ -959,7 +960,7 @@ void spiTransferBitsNL(spi_t * spi, uint32_t data, uint32_t * out, uint8_t bits)
959960
}
960961
}
961962

962-
void spiWritePixelsNL(spi_t * spi, const void * data_in, size_t len){
963+
void IRAM_ATTR spiWritePixelsNL(spi_t * spi, const void * data_in, size_t len){
963964
size_t longs = len >> 2;
964965
if(len & 3){
965966
longs++;
@@ -1017,18 +1018,20 @@ typedef union {
10171018
};
10181019
} spiClk_t;
10191020

1020-
#define ClkRegToFreq(reg) (CPU_CLK_FREQ / (((reg)->regPre + 1) * ((reg)->regN + 1)))
1021+
#define ClkRegToFreq(reg) (apb_freq / (((reg)->regPre + 1) * ((reg)->regN + 1)))
10211022

10221023
uint32_t spiClockDivToFrequency(uint32_t clockDiv)
10231024
{
1025+
uint32_t apb_freq = getApbFrequency();
10241026
spiClk_t reg = { clockDiv };
10251027
return ClkRegToFreq(&reg);
10261028
}
10271029

10281030
uint32_t spiFrequencyToClockDiv(uint32_t freq)
10291031
{
1032+
uint32_t apb_freq = getApbFrequency();
10301033

1031-
if(freq >= CPU_CLK_FREQ) {
1034+
if(freq >= apb_freq) {
10321035
return SPI_CLK_EQU_SYSCLK;
10331036
}
10341037

@@ -1051,7 +1054,7 @@ uint32_t spiFrequencyToClockDiv(uint32_t freq)
10511054
reg.regN = calN;
10521055

10531056
while(calPreVari++ <= 1) {
1054-
calPre = (((CPU_CLK_FREQ / (reg.regN + 1)) / freq) - 1) + calPreVari;
1057+
calPre = (((apb_freq / (reg.regN + 1)) / freq) - 1) + calPreVari;
10551058
if(calPre > 0x1FFF) {
10561059
reg.regPre = 0x1FFF;
10571060
} else if(calPre <= 0) {

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ void IRAM_ATTR __timerISR(void * arg){
8484
i = 4;
8585
//call callbacks
8686
while(i--){
87-
if(__timerInterruptHandlers[i] && status & (1 << i)){
87+
if(__timerInterruptHandlers[i] && (status & (1 << i))){
8888
__timerInterruptHandlers[i]();
8989
}
9090
}

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

+17-11
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "soc/io_mux_reg.h"
2828
#include "soc/gpio_sig_map.h"
2929
#include "soc/dport_reg.h"
30+
#include "soc/rtc.h"
3031
#include "esp_intr_alloc.h"
3132

3233
#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)
352353
return;
353354
}
354355
UART_MUTEX_LOCK();
355-
uint32_t clk_div = ((UART_CLK_FREQ<<4)/baud_rate);
356+
uint32_t clk_div = ((getApbFrequency()<<4)/baud_rate);
356357
uart->dev->clk_div.div_int = clk_div>>4 ;
357358
uart->dev->clk_div.div_frag = clk_div & 0xf;
358359
UART_MUTEX_UNLOCK();
@@ -385,17 +386,8 @@ static void IRAM_ATTR uart2_write_char(char c)
385386
ESP_REG(DR_REG_UART2_BASE) = c;
386387
}
387388

388-
void uartSetDebug(uart_t* uart)
389+
void uart_install_putc()
389390
{
390-
if(uart == NULL || uart->num > 2) {
391-
s_uart_debug_nr = -1;
392-
ets_install_putc1(NULL);
393-
return;
394-
}
395-
if(s_uart_debug_nr == uart->num) {
396-
return;
397-
}
398-
s_uart_debug_nr = uart->num;
399391
switch(s_uart_debug_nr) {
400392
case 0:
401393
ets_install_putc1((void (*)(char)) &uart0_write_char);
@@ -412,6 +404,20 @@ void uartSetDebug(uart_t* uart)
412404
}
413405
}
414406

407+
void uartSetDebug(uart_t* uart)
408+
{
409+
if(uart == NULL || uart->num > 2) {
410+
s_uart_debug_nr = -1;
411+
//ets_install_putc1(NULL);
412+
//return;
413+
} else
414+
if(s_uart_debug_nr == uart->num) {
415+
return;
416+
} else
417+
s_uart_debug_nr = uart->num;
418+
uart_install_putc();
419+
}
420+
415421
int uartGetDebug()
416422
{
417423
return s_uart_debug_nr;

Diff for: cores/esp32/esp32-hal.h

+8-2
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,14 @@ void yield(void);
7272
//returns chip temperature in Celsius
7373
float temperatureRead();
7474

75-
bool cpuFrequencySet(uint32_t cpu_freq_mhz);
76-
uint32_t cpuFrequencyGet();
75+
//function takes the following frequencies as valid values:
76+
// 240, 160, 80 <<< For all XTAL types
77+
// 40, 20, 13, 10, 8, 5, 4, 3, 2, 1 <<< For 40MHz XTAL
78+
// 26, 13, 5, 4, 3, 2, 1 <<< For 26MHz XTAL
79+
// 24, 12, 8, 6, 4, 3, 2, 1 <<< For 24MHz XTAL
80+
bool setCpuFrequency(uint32_t cpu_freq_mhz);
81+
uint32_t getCpuFrequency();
82+
uint32_t getApbFrequency();
7783

7884
unsigned long micros();
7985
unsigned long millis();

0 commit comments

Comments
 (0)