CPU and APB Frequency support (#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
This commit is contained in:
parent
1628f533a1
commit
c827bb4177
30
boards.txt
30
boards.txt
@ -1,4 +1,5 @@
|
||||
menu.UploadSpeed=Upload Speed
|
||||
menu.CPUFreq=CPU Frequency
|
||||
menu.FlashFreq=Flash Frequency
|
||||
menu.FlashMode=Flash Mode
|
||||
menu.FlashSize=Flash Size
|
||||
@ -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
|
||||
|
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
@ -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;
|
||||
|
@ -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
|
||||
@ -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();
|
||||
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()
|
||||
@ -109,6 +127,9 @@ bool btInUse(){ return false; }
|
||||
|
||||
void initArduino()
|
||||
{
|
||||
#ifdef F_CPU
|
||||
setCpuFrequency(F_CPU/1000000L);
|
||||
#endif
|
||||
#if CONFIG_SPIRAM_SUPPORT
|
||||
psramInit();
|
||||
#endif
|
||||
|
@ -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;
|
||||
}
|
||||
@ -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
|
||||
|
@ -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))))
|
||||
@ -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;
|
||||
@ -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;
|
||||
@ -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;
|
||||
@ -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++;
|
||||
@ -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(®);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -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) {
|
||||
|
@ -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]();
|
||||
}
|
||||
}
|
||||
|
@ -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 = ((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();
|
||||
@ -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);
|
||||
@ -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;
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user