Merge branch 'bugfix/bootloader_v10_backwards_compat' into 'master'
esp32: Fix backwards compatibility for pre-v2.1 bootloaders See merge request !1673
This commit is contained in:
commit
f8bda324ec
6 changed files with 130 additions and 45 deletions
|
@ -48,6 +48,7 @@
|
||||||
#include "bootloader_flash.h"
|
#include "bootloader_flash.h"
|
||||||
#include "bootloader_random.h"
|
#include "bootloader_random.h"
|
||||||
#include "bootloader_config.h"
|
#include "bootloader_config.h"
|
||||||
|
#include "bootloader_clock.h"
|
||||||
|
|
||||||
#include "flash_qio_mode.h"
|
#include "flash_qio_mode.h"
|
||||||
|
|
||||||
|
@ -75,7 +76,6 @@ static void set_cache_and_start_app(uint32_t drom_addr,
|
||||||
static void update_flash_config(const esp_image_header_t* pfhdr);
|
static void update_flash_config(const esp_image_header_t* pfhdr);
|
||||||
static void vddsdio_configure();
|
static void vddsdio_configure();
|
||||||
static void flash_gpio_configure();
|
static void flash_gpio_configure();
|
||||||
static void clock_configure(void);
|
|
||||||
static void uart_console_configure(void);
|
static void uart_console_configure(void);
|
||||||
static void wdt_reset_check(void);
|
static void wdt_reset_check(void);
|
||||||
|
|
||||||
|
@ -447,7 +447,7 @@ void bootloader_main()
|
||||||
{
|
{
|
||||||
vddsdio_configure();
|
vddsdio_configure();
|
||||||
flash_gpio_configure();
|
flash_gpio_configure();
|
||||||
clock_configure();
|
bootloader_clock_configure();
|
||||||
uart_console_configure();
|
uart_console_configure();
|
||||||
wdt_reset_check();
|
wdt_reset_check();
|
||||||
ESP_LOGI(TAG, "ESP-IDF %s 2nd stage bootloader", IDF_VER);
|
ESP_LOGI(TAG, "ESP-IDF %s 2nd stage bootloader", IDF_VER);
|
||||||
|
@ -835,46 +835,6 @@ static void IRAM_ATTR flash_gpio_configure()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clock_configure(void)
|
|
||||||
{
|
|
||||||
// ROM bootloader may have put a lot of text into UART0 FIFO.
|
|
||||||
// Wait for it to be printed.
|
|
||||||
// This is not needed on power on reset, when ROM bootloader is running at
|
|
||||||
// 40 MHz. But in case of TG WDT reset, CPU may still be running at >80 MHZ,
|
|
||||||
// and will be done with the bootloader much earlier than UART FIFO is empty.
|
|
||||||
uart_tx_wait_idle(0);
|
|
||||||
|
|
||||||
/* Set CPU to 80MHz. Keep other clocks unmodified. */
|
|
||||||
rtc_cpu_freq_t cpu_freq = RTC_CPU_FREQ_80M;
|
|
||||||
|
|
||||||
/* On ESP32 rev 0, switching to 80MHz if clock was previously set to
|
|
||||||
* 240 MHz may cause the chip to lock up (see section 3.5 of the errata
|
|
||||||
* document). For rev. 0, switch to 240 instead if it was chosen in
|
|
||||||
* menuconfig.
|
|
||||||
*/
|
|
||||||
uint32_t chip_ver_reg = REG_READ(EFUSE_BLK0_RDATA3_REG);
|
|
||||||
if ((chip_ver_reg & EFUSE_RD_CHIP_VER_REV1_M) == 0 &&
|
|
||||||
CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ == 240) {
|
|
||||||
cpu_freq = RTC_CPU_FREQ_240M;
|
|
||||||
}
|
|
||||||
|
|
||||||
rtc_clk_config_t clk_cfg = RTC_CLK_CONFIG_DEFAULT();
|
|
||||||
clk_cfg.xtal_freq = CONFIG_ESP32_XTAL_FREQ;
|
|
||||||
clk_cfg.cpu_freq = cpu_freq;
|
|
||||||
clk_cfg.slow_freq = rtc_clk_slow_freq_get();
|
|
||||||
clk_cfg.fast_freq = rtc_clk_fast_freq_get();
|
|
||||||
rtc_clk_init(clk_cfg);
|
|
||||||
/* As a slight optimization, if 32k XTAL was enabled in sdkconfig, we enable
|
|
||||||
* it here. Usually it needs some time to start up, so we amortize at least
|
|
||||||
* part of the start up time by enabling 32k XTAL early.
|
|
||||||
* App startup code will wait until the oscillator has started up.
|
|
||||||
*/
|
|
||||||
#ifdef CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL
|
|
||||||
if (!rtc_clk_32k_enabled()) {
|
|
||||||
rtc_clk_32k_bootstrap();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static void uart_console_configure(void)
|
static void uart_console_configure(void)
|
||||||
{
|
{
|
||||||
|
|
21
components/bootloader_support/include/bootloader_clock.h
Normal file
21
components/bootloader_support/include/bootloader_clock.h
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
// Copyright 2017 Espressif Systems (Shanghai) PTE LTD
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/** @brief Configure clocks for early boot
|
||||||
|
*
|
||||||
|
* Called by bootloader, or by the app if the bootloader version is old (pre v2.1).
|
||||||
|
*/
|
||||||
|
void bootloader_clock_configure(void);
|
61
components/bootloader_support/src/bootloader_clock.c
Normal file
61
components/bootloader_support/src/bootloader_clock.c
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
// Copyright 2017 Espressif Systems (Shanghai) PTE LTD
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
#include "rom/uart.h"
|
||||||
|
#include "rom/rtc.h"
|
||||||
|
#include "soc/soc.h"
|
||||||
|
#include "soc/rtc.h"
|
||||||
|
#include "soc/dport_reg.h"
|
||||||
|
#include "soc/efuse_reg.h"
|
||||||
|
#include "soc/rtc_cntl_reg.h"
|
||||||
|
|
||||||
|
void bootloader_clock_configure()
|
||||||
|
{
|
||||||
|
// ROM bootloader may have put a lot of text into UART0 FIFO.
|
||||||
|
// Wait for it to be printed.
|
||||||
|
// This is not needed on power on reset, when ROM bootloader is running at
|
||||||
|
// 40 MHz. But in case of TG WDT reset, CPU may still be running at >80 MHZ,
|
||||||
|
// and will be done with the bootloader much earlier than UART FIFO is empty.
|
||||||
|
uart_tx_wait_idle(0);
|
||||||
|
|
||||||
|
/* Set CPU to 80MHz. Keep other clocks unmodified. */
|
||||||
|
rtc_cpu_freq_t cpu_freq = RTC_CPU_FREQ_80M;
|
||||||
|
|
||||||
|
/* On ESP32 rev 0, switching to 80MHz if clock was previously set to
|
||||||
|
* 240 MHz may cause the chip to lock up (see section 3.5 of the errata
|
||||||
|
* document). For rev. 0, switch to 240 instead if it was chosen in
|
||||||
|
* menuconfig.
|
||||||
|
*/
|
||||||
|
uint32_t chip_ver_reg = REG_READ(EFUSE_BLK0_RDATA3_REG);
|
||||||
|
if ((chip_ver_reg & EFUSE_RD_CHIP_VER_REV1_M) == 0 &&
|
||||||
|
CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ == 240) {
|
||||||
|
cpu_freq = RTC_CPU_FREQ_240M;
|
||||||
|
}
|
||||||
|
|
||||||
|
rtc_clk_config_t clk_cfg = RTC_CLK_CONFIG_DEFAULT();
|
||||||
|
clk_cfg.xtal_freq = CONFIG_ESP32_XTAL_FREQ;
|
||||||
|
clk_cfg.cpu_freq = cpu_freq;
|
||||||
|
clk_cfg.slow_freq = rtc_clk_slow_freq_get();
|
||||||
|
clk_cfg.fast_freq = rtc_clk_fast_freq_get();
|
||||||
|
rtc_clk_init(clk_cfg);
|
||||||
|
/* As a slight optimization, if 32k XTAL was enabled in sdkconfig, we enable
|
||||||
|
* it here. Usually it needs some time to start up, so we amortize at least
|
||||||
|
* part of the start up time by enabling 32k XTAL early.
|
||||||
|
* App startup code will wait until the oscillator has started up.
|
||||||
|
*/
|
||||||
|
#ifdef CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL
|
||||||
|
if (!rtc_clk_32k_enabled()) {
|
||||||
|
rtc_clk_32k_bootstrap();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -776,6 +776,22 @@ config ESP_TIMER_PROFILING
|
||||||
used for timer storage, and should only be used for debugging/testing
|
used for timer storage, and should only be used for debugging/testing
|
||||||
purposes.
|
purposes.
|
||||||
|
|
||||||
|
config COMPATIBLE_PRE_V2_1_BOOTLOADERS
|
||||||
|
bool "App compatible with bootloaders before IDF v2.1"
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
Bootloaders before IDF v2.1 did less initialisation of the
|
||||||
|
system clock. This setting needs to be enabled to build an app
|
||||||
|
which can be booted by these older bootloaders.
|
||||||
|
|
||||||
|
If this setting is enabled, the app can be booted by any bootloader
|
||||||
|
from IDF v1.0 up to the current version.
|
||||||
|
|
||||||
|
If this setting is disabled, the app can only be booted by bootloaders
|
||||||
|
from IDF v2.1 or newer.
|
||||||
|
|
||||||
|
Enabling this setting adds approximately 1KB to the app's IRAM usage.
|
||||||
|
|
||||||
endmenu # ESP32-Specific
|
endmenu # ESP32-Specific
|
||||||
|
|
||||||
menu Wi-Fi
|
menu Wi-Fi
|
||||||
|
|
|
@ -27,10 +27,10 @@
|
||||||
#include "soc/soc.h"
|
#include "soc/soc.h"
|
||||||
#include "soc/rtc.h"
|
#include "soc/rtc.h"
|
||||||
#include "soc/rtc_cntl_reg.h"
|
#include "soc/rtc_cntl_reg.h"
|
||||||
#include "soc/dport_reg.h"
|
|
||||||
#include "soc/i2s_reg.h"
|
#include "soc/i2s_reg.h"
|
||||||
#include "driver/periph_ctrl.h"
|
#include "driver/periph_ctrl.h"
|
||||||
#include "xtensa/core-macros.h"
|
#include "xtensa/core-macros.h"
|
||||||
|
#include "bootloader_clock.h"
|
||||||
|
|
||||||
/* Number of cycles to wait from the 32k XTAL oscillator to consider it running.
|
/* Number of cycles to wait from the 32k XTAL oscillator to consider it running.
|
||||||
* Larger values increase startup delay. Smaller values may cause false positive
|
* Larger values increase startup delay. Smaller values may cause false positive
|
||||||
|
@ -54,6 +54,22 @@ void esp_clk_init(void)
|
||||||
{
|
{
|
||||||
rtc_config_t cfg = RTC_CONFIG_DEFAULT();
|
rtc_config_t cfg = RTC_CONFIG_DEFAULT();
|
||||||
rtc_init(cfg);
|
rtc_init(cfg);
|
||||||
|
|
||||||
|
#ifdef CONFIG_COMPATIBLE_PRE_V2_1_BOOTLOADERS
|
||||||
|
/* Check the bootloader set the XTAL frequency.
|
||||||
|
|
||||||
|
Bootloaders pre-v2.1 don't do this.
|
||||||
|
*/
|
||||||
|
rtc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get();
|
||||||
|
if (xtal_freq == RTC_XTAL_FREQ_AUTO) {
|
||||||
|
ESP_EARLY_LOGW(TAG, "RTC domain not initialised by bootloader");
|
||||||
|
bootloader_clock_configure();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/* If this assertion fails, either upgrade the bootloader or enable CONFIG_COMPATIBLE_PRE_V2_1_BOOTLOADERS */
|
||||||
|
assert(rtc_clk_xtal_freq_get() != RTC_XTAL_FREQ_AUTO);
|
||||||
|
#endif
|
||||||
|
|
||||||
rtc_clk_fast_freq_set(RTC_FAST_FREQ_8M);
|
rtc_clk_fast_freq_set(RTC_FAST_FREQ_8M);
|
||||||
|
|
||||||
#ifdef CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL
|
#ifdef CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL
|
||||||
|
|
|
@ -149,13 +149,24 @@ void rtc_clk_init(rtc_clk_config_t cfg);
|
||||||
/**
|
/**
|
||||||
* @brief Get main XTAL frequency
|
* @brief Get main XTAL frequency
|
||||||
*
|
*
|
||||||
* This is the value passed to rtc_clk_init function, or if the value was
|
* This is the value stored in RTC register RTC_XTAL_FREQ_REG by the bootloader. As passed to
|
||||||
* RTC_XTAL_FREQ_AUTO, the detected XTAL frequency.
|
* rtc_clk_init function, or if the value was RTC_XTAL_FREQ_AUTO, the detected
|
||||||
|
* XTAL frequency.
|
||||||
*
|
*
|
||||||
* @return XTAL frequency, one of rtc_xtal_freq_t
|
* @return XTAL frequency, one of rtc_xtal_freq_t
|
||||||
*/
|
*/
|
||||||
rtc_xtal_freq_t rtc_clk_xtal_freq_get();
|
rtc_xtal_freq_t rtc_clk_xtal_freq_get();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Update XTAL frequency
|
||||||
|
*
|
||||||
|
* Updates the XTAL value stored in RTC_XTAL_FREQ_REG. Usually this value is ignored
|
||||||
|
* after startup.
|
||||||
|
*
|
||||||
|
* @param xtal_freq New frequency value
|
||||||
|
*/
|
||||||
|
void rtc_clk_xtal_freq_update(rtc_xtal_freq_t xtal_freq);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enable or disable 32 kHz XTAL oscillator
|
* @brief Enable or disable 32 kHz XTAL oscillator
|
||||||
* @param en true to enable, false to disable
|
* @param en true to enable, false to disable
|
||||||
|
|
Loading…
Reference in a new issue