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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user