Skip to content
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

CPU and APB Frequency support #2220

Merged
merged 6 commits into from
Dec 20, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions boards.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
menu.UploadSpeed=Upload Speed
menu.CPUFreq=CPU Frequency
menu.FlashFreq=Flash Frequency
menu.FlashMode=Flash Mode
menu.FlashSize=Flash Size
Expand Down Expand Up @@ -49,6 +50,35 @@ esp32.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080
esp32.menu.PartitionScheme.fatflash=16M Fat
esp32.menu.PartitionScheme.fatflash.build.partitions=ffat

esp32.menu.CPUFreq.240=240MHz
esp32.menu.CPUFreq.240.build.f_cpu=240000000L
esp32.menu.CPUFreq.160=160MHz
esp32.menu.CPUFreq.160.build.f_cpu=160000000L
esp32.menu.CPUFreq.80=80MHz
esp32.menu.CPUFreq.80.build.f_cpu=80000000L
esp32.menu.CPUFreq.40=40MHz (40MHz XTAL)
esp32.menu.CPUFreq.40.build.f_cpu=40000000L
esp32.menu.CPUFreq.26=26MHz (26MHz XTAL)
esp32.menu.CPUFreq.26.build.f_cpu=26000000L
esp32.menu.CPUFreq.20=20MHz (40MHz XTAL)
esp32.menu.CPUFreq.20.build.f_cpu=20000000L
esp32.menu.CPUFreq.13=13MHz
esp32.menu.CPUFreq.13.build.f_cpu=13000000L
esp32.menu.CPUFreq.10=10MHz (40MHz XTAL)
esp32.menu.CPUFreq.10.build.f_cpu=10000000L
esp32.menu.CPUFreq.8=8MHz (40MHz XTAL)
esp32.menu.CPUFreq.8.build.f_cpu=8000000L
esp32.menu.CPUFreq.5=5MHz
esp32.menu.CPUFreq.5.build.f_cpu=5000000L
esp32.menu.CPUFreq.4=4MHz
esp32.menu.CPUFreq.4.build.f_cpu=4000000L
esp32.menu.CPUFreq.3=3MHz
esp32.menu.CPUFreq.3.build.f_cpu=3000000L
esp32.menu.CPUFreq.2=2MHz
esp32.menu.CPUFreq.2.build.f_cpu=2000000L
esp32.menu.CPUFreq.1=1MHz
esp32.menu.CPUFreq.1.build.f_cpu=1000000L

esp32.menu.FlashMode.qio=QIO
esp32.menu.FlashMode.qio.build.flash_mode=dio
esp32.menu.FlashMode.qio.build.boot=qio
Expand Down
4 changes: 2 additions & 2 deletions cores/esp32/esp32-hal-i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -1611,7 +1611,7 @@ i2c_err_t i2cSetFrequency(i2c_t * i2c, uint32_t clk_speed)
}
I2C_FIFO_CONF_t f;

uint32_t period = (APB_CLK_FREQ/clk_speed) / 2;
uint32_t period = (getApbFrequency()/clk_speed) / 2;
uint32_t halfPeriod = period/2;
uint32_t quarterPeriod = period/4;

Expand Down Expand Up @@ -1657,7 +1657,7 @@ uint32_t i2cGetFrequency(i2c_t * i2c)
uint32_t result = 0;
uint32_t old_count = (i2c->dev->scl_low_period.period+i2c->dev->scl_high_period.period);
if(old_count>0) {
result = APB_CLK_FREQ / old_count;
result = getApbFrequency() / old_count;
} else {
result = 0;
}
Expand Down
4 changes: 2 additions & 2 deletions cores/esp32/esp32-hal-ledc.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ static void _ledcSetupTimer(uint8_t chan, uint32_t div_num, uint8_t bit_num, boo
//max bit_num 0x1F (31)
static double _ledcSetupTimerFreq(uint8_t chan, double freq, uint8_t bit_num)
{
uint64_t clk_freq = APB_CLK_FREQ;
uint64_t clk_freq = getApbFrequency();
clk_freq <<= 8;//div_num is 8 bit decimal
uint32_t div_num = (clk_freq >> bit_num) / freq;
bool apb_clk = true;
Expand Down Expand Up @@ -117,7 +117,7 @@ static double _ledcTimerRead(uint8_t chan)
LEDC_MUTEX_UNLOCK();
uint64_t clk_freq = 1000000;
if(apb_clk) {
clk_freq *= 80;
clk_freq = getApbFrequency();
}
clk_freq <<= 8;//div_num is 8 bit decimal
return (clk_freq >> bit_num) / (double)div_num;
Expand Down
35 changes: 28 additions & 7 deletions cores/esp32/esp32-hal-misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
#endif //CONFIG_BT_ENABLED
#include <sys/time.h>
#include "soc/rtc.h"
#include "soc/rtc_cntl_reg.h"
#include "rom/rtc.h"
#include "esp32-hal.h"

//Undocumented!!! Get chip temperature in Farenheit
Expand All @@ -42,31 +44,47 @@ 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;
}
rtc_clk_cpu_freq_set_config(&conf);
#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_fast(&conf);
_cpu_freq_mhz = conf.freq_mhz;
_sys_time_multiplier = 80 / getApbFrequency();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will always set _sys_time_multiplier to 0 all the time?

Copy link
Member Author

Choose a reason for hiding this comment

The 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(){
rtc_cpu_freq_config_t conf;
rtc_clk_cpu_freq_get_config(&conf);
if(conf.freq_mhz >= 80){
return 80000000;
}
return (conf.source_freq_mhz * 1000000) / conf.div;
}

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()
Expand Down Expand Up @@ -109,6 +127,9 @@ bool btInUse(){ return false; }

void initArduino()
{
#ifdef F_CPU
setCpuFrequency(F_CPU/1000000L);
#endif
#if CONFIG_SPIRAM_SUPPORT
psramInit();
#endif
Expand Down
5 changes: 3 additions & 2 deletions cores/esp32/esp32-hal-sigmadelta.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ uint32_t sigmaDeltaSetup(uint8_t channel, uint32_t freq) //chan 0-7 freq 1220-31
_sd_sys_lock = xSemaphoreCreateMutex();
}
#endif
uint32_t prescale = (10000000/(freq*32)) - 1;
uint32_t apb_freq = getApbFrequency();
uint32_t prescale = (apb_freq/(freq*256)) - 1;
if(prescale > 0xFF) {
prescale = 0xFF;
}
Expand All @@ -52,7 +53,7 @@ uint32_t sigmaDeltaSetup(uint8_t channel, uint32_t freq) //chan 0-7 freq 1220-31
SIGMADELTA.cg.clk_en = 0;
SIGMADELTA.cg.clk_en = 1;
SD_MUTEX_UNLOCK();
return 10000000/((prescale + 1) * 32);
return apb_freq/((prescale + 1) * 256);
}

void sigmaDeltaWrite(uint8_t channel, uint8_t duty) //chan 0-7 duty 8 bit
Expand Down
17 changes: 10 additions & 7 deletions cores/esp32/esp32-hal-spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "soc/io_mux_reg.h"
#include "soc/gpio_sig_map.h"
#include "soc/dport_reg.h"
#include "soc/rtc.h"

#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))))
#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))))
Expand Down Expand Up @@ -750,7 +751,7 @@ void spiEndTransaction(spi_t * spi)
SPI_MUTEX_UNLOCK();
}

void spiWriteByteNL(spi_t * spi, uint8_t data)
void IRAM_ATTR spiWriteByteNL(spi_t * spi, uint8_t data)
{
if(!spi) {
return;
Expand All @@ -776,7 +777,7 @@ uint8_t spiTransferByteNL(spi_t * spi, uint8_t data)
return data;
}

void spiWriteShortNL(spi_t * spi, uint16_t data)
void IRAM_ATTR spiWriteShortNL(spi_t * spi, uint16_t data)
{
if(!spi) {
return;
Expand Down Expand Up @@ -811,7 +812,7 @@ uint16_t spiTransferShortNL(spi_t * spi, uint16_t data)
return data;
}

void spiWriteLongNL(spi_t * spi, uint32_t data)
void IRAM_ATTR spiWriteLongNL(spi_t * spi, uint32_t data)
{
if(!spi) {
return;
Expand Down Expand Up @@ -959,7 +960,7 @@ void spiTransferBitsNL(spi_t * spi, uint32_t data, uint32_t * out, uint8_t bits)
}
}

void spiWritePixelsNL(spi_t * spi, const void * data_in, size_t len){
void IRAM_ATTR spiWritePixelsNL(spi_t * spi, const void * data_in, size_t len){
size_t longs = len >> 2;
if(len & 3){
longs++;
Expand Down Expand Up @@ -1017,18 +1018,20 @@ typedef union {
};
} spiClk_t;

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

uint32_t spiClockDivToFrequency(uint32_t clockDiv)
{
uint32_t apb_freq = getApbFrequency();
spiClk_t reg = { clockDiv };
return ClkRegToFreq(&reg);
}

uint32_t spiFrequencyToClockDiv(uint32_t freq)
{
uint32_t apb_freq = getApbFrequency();

if(freq >= CPU_CLK_FREQ) {
if(freq >= apb_freq) {
return SPI_CLK_EQU_SYSCLK;
}

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

while(calPreVari++ <= 1) {
calPre = (((CPU_CLK_FREQ / (reg.regN + 1)) / freq) - 1) + calPreVari;
calPre = (((apb_freq / (reg.regN + 1)) / freq) - 1) + calPreVari;
if(calPre > 0x1FFF) {
reg.regPre = 0x1FFF;
} else if(calPre <= 0) {
Expand Down
2 changes: 1 addition & 1 deletion cores/esp32/esp32-hal-timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ void IRAM_ATTR __timerISR(void * arg){
i = 4;
//call callbacks
while(i--){
if(__timerInterruptHandlers[i] && status & (1 << i)){
if(__timerInterruptHandlers[i] && (status & (1 << i))){
__timerInterruptHandlers[i]();
}
}
Expand Down
28 changes: 17 additions & 11 deletions cores/esp32/esp32-hal-uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)))
Expand Down Expand Up @@ -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 = ((getApbFrequency()<<4)/baud_rate);
uart->dev->clk_div.div_int = clk_div>>4 ;
uart->dev->clk_div.div_frag = clk_div & 0xf;
UART_MUTEX_UNLOCK();
Expand Down Expand Up @@ -385,17 +386,8 @@ static void IRAM_ATTR uart2_write_char(char c)
ESP_REG(DR_REG_UART2_BASE) = c;
}

void uartSetDebug(uart_t* uart)
void uart_install_putc()
{
if(uart == NULL || uart->num > 2) {
s_uart_debug_nr = -1;
ets_install_putc1(NULL);
return;
}
if(s_uart_debug_nr == uart->num) {
return;
}
s_uart_debug_nr = uart->num;
switch(s_uart_debug_nr) {
case 0:
ets_install_putc1((void (*)(char)) &uart0_write_char);
Expand All @@ -412,6 +404,20 @@ void uartSetDebug(uart_t* uart)
}
}

void uartSetDebug(uart_t* uart)
{
if(uart == NULL || uart->num > 2) {
s_uart_debug_nr = -1;
//ets_install_putc1(NULL);
//return;
} else
if(s_uart_debug_nr == uart->num) {
return;
} else
s_uart_debug_nr = uart->num;
uart_install_putc();
}

int uartGetDebug()
{
return s_uart_debug_nr;
Expand Down
10 changes: 8 additions & 2 deletions cores/esp32/esp32-hal.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,14 @@ void yield(void);
//returns chip temperature in Celsius
float temperatureRead();

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

unsigned long micros();
unsigned long millis();
Expand Down