mirror of
https://github.com/espressif/ESP8266_RTOS_SDK.git
synced 2025-05-22 01:27:11 +08:00
feat(bootloader): Initialize SPI flash clock and I/O mode at bootloader
This commit is contained in:
@ -1,4 +1,15 @@
|
|||||||
menu "Bootloader config"
|
menu "Bootloader config"
|
||||||
|
|
||||||
|
config BOOTLOADER_INIT_SPI_FLASH
|
||||||
|
bool "Bootloader init SPI flash"
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
Enable this option, software will initialize SPI flash clock and I/O mode at bootloader instead of at APP.
|
||||||
|
So it will speed up system starting and reduce the time cost at loading firmware.
|
||||||
|
|
||||||
|
If your system bootloader is based on v3.0, the option must not be enable, because the v3.0 bootloader don't support
|
||||||
|
this function.
|
||||||
|
|
||||||
choice LOG_BOOTLOADER_LEVEL
|
choice LOG_BOOTLOADER_LEVEL
|
||||||
bool "Bootloader log verbosity"
|
bool "Bootloader log verbosity"
|
||||||
default LOG_BOOTLOADER_LEVEL_INFO
|
default LOG_BOOTLOADER_LEVEL_INFO
|
||||||
|
@ -619,46 +619,26 @@ static esp_err_t bootloader_main()
|
|||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
update_flash_config(&fhdr);
|
||||||
|
|
||||||
ESP_LOGI(TAG, "ESP-IDF %s 2nd stage bootloader", IDF_VER);
|
ESP_LOGI(TAG, "ESP-IDF %s 2nd stage bootloader", IDF_VER);
|
||||||
|
|
||||||
ESP_LOGI(TAG, "compile time " __TIME__ );
|
ESP_LOGI(TAG, "compile time " __TIME__ );
|
||||||
|
|
||||||
print_flash_info(&fhdr);
|
print_flash_info(&fhdr);
|
||||||
|
|
||||||
update_flash_config(&fhdr);
|
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_flash_config(const esp_image_header_t* pfhdr)
|
static void update_flash_config(const esp_image_header_t* pfhdr)
|
||||||
{
|
{
|
||||||
// uint32_t size;
|
#ifdef CONFIG_BOOTLOADER_INIT_SPI_FLASH
|
||||||
// switch(pfhdr->spi_size) {
|
extern void esp_spi_flash_init(uint32_t spi_speed, uint32_t spi_mode);
|
||||||
// case ESP_IMAGE_FLASH_SIZE_1MB:
|
|
||||||
// size = 1;
|
|
||||||
// break;
|
|
||||||
// case ESP_IMAGE_FLASH_SIZE_2MB:
|
|
||||||
// case ESP_IMAGE_FLASH_SIZE_2MB_C1:
|
|
||||||
// size = 2;
|
|
||||||
// break;
|
|
||||||
// case ESP_IMAGE_FLASH_SIZE_4MB:
|
|
||||||
// case ESP_IMAGE_FLASH_SIZE_4MB_C1:
|
|
||||||
// size = 4;
|
|
||||||
// break;
|
|
||||||
// case ESP_IMAGE_FLASH_SIZE_8MB:
|
|
||||||
// size = 8;
|
|
||||||
// break;
|
|
||||||
// case ESP_IMAGE_FLASH_SIZE_16MB:
|
|
||||||
// size = 16;
|
|
||||||
// break;
|
|
||||||
// default:
|
|
||||||
// size = 2;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Set flash chip size
|
esp_spi_flash_init(pfhdr->spi_speed, pfhdr->spi_mode);
|
||||||
// esp_rom_spiflash_config_param(g_rom_flashchip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff);
|
|
||||||
// TODO: set mode
|
ESP_LOGD(TAG, "bootloader initialize SPI flash clock and I/O");
|
||||||
// TODO: set frequency
|
#endif /* CONFIG_BOOTLOADER_INIT_SPI_FLASH */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_flash_info(const esp_image_header_t* phdr)
|
static void print_flash_info(const esp_image_header_t* phdr)
|
||||||
|
@ -256,4 +256,8 @@
|
|||||||
#define PERIPHS_SPI_FLASH_CTRL SPI_CTRL(SPI)
|
#define PERIPHS_SPI_FLASH_CTRL SPI_CTRL(SPI)
|
||||||
#define PERIPHS_SPI_FLASH_CMD SPI_CMD(SPI)
|
#define PERIPHS_SPI_FLASH_CMD SPI_CMD(SPI)
|
||||||
|
|
||||||
|
#define SPI0_CLK_EQU_SYSCLK BIT8
|
||||||
|
|
||||||
|
#define PERIPHS_SPI_FLASH_USRREG (0x60000200 + 0x1c)
|
||||||
|
|
||||||
#endif // SPI_REGISTER_H_INCLUDED
|
#endif // SPI_REGISTER_H_INCLUDED
|
||||||
|
@ -13,86 +13,17 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
#include "esp_attr.h"
|
|
||||||
|
#ifndef CONFIG_BOOTLOADER_INIT_SPI_FLASH
|
||||||
#include "spi_flash.h"
|
#include "spi_flash.h"
|
||||||
#include "esp_log.h"
|
|
||||||
#include "esp_system.h"
|
|
||||||
#include "esp8266/eagle_soc.h"
|
|
||||||
#include "esp8266/rom_functions.h"
|
|
||||||
#include "esp_image_format.h"
|
|
||||||
|
|
||||||
#define PERIPHS_SPI_FLASH_USRREG (0x60000200 + 0x1c)
|
|
||||||
#define PERIPHS_SPI_FLASH_CTRL (0x60000200 + 0x08)
|
|
||||||
#define PERIPHS_IO_MUX_CONF_U (0x60000800)
|
|
||||||
|
|
||||||
#define SPI0_CLK_EQU_SYSCLK BIT8
|
|
||||||
#define SPI_FLASH_CLK_EQU_SYSCLK BIT12
|
|
||||||
|
|
||||||
static const char *TAG = "chip_boot";
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @brief initialize the chip including flash I/O and chip cache according to
|
* @brief initialize the chip
|
||||||
* boot parameters which are stored at the flash
|
|
||||||
*/
|
*/
|
||||||
void chip_boot(size_t start_addr)
|
void chip_boot(void)
|
||||||
{
|
{
|
||||||
int ret;
|
extern void esp_spi_flash_init(uint32_t spi_speed, uint32_t spi_mode);
|
||||||
uint32_t freqdiv, flash_size;
|
|
||||||
uint32_t freqbits;
|
|
||||||
esp_image_header_t fhdr;
|
|
||||||
|
|
||||||
uint32_t flash_map_table[FALSH_SIZE_MAP_MAX] = {
|
esp_spi_flash_init(CONFIG_SPI_FLASH_FREQ, CONFIG_SPI_FLASH_MODE);
|
||||||
1 * 1024 * 1024,
|
|
||||||
2 * 1024 * 1024,
|
|
||||||
4 * 1024 * 1024,
|
|
||||||
8 * 1024 * 1024,
|
|
||||||
16 * 1024 * 1024
|
|
||||||
};
|
|
||||||
uint32_t flash_map_table_size = sizeof(flash_map_table) / sizeof(flash_map_table[0]);
|
|
||||||
|
|
||||||
extern esp_spi_flash_chip_t flashchip;
|
|
||||||
extern void phy_get_bb_evm(void);
|
|
||||||
extern void cache_init(uint8_t);
|
|
||||||
extern void user_spi_flash_dio_to_qio_pre_init(void);
|
|
||||||
|
|
||||||
phy_get_bb_evm();
|
|
||||||
|
|
||||||
SET_PERI_REG_MASK(PERIPHS_SPI_FLASH_USRREG, BIT5);
|
|
||||||
|
|
||||||
ret = spi_flash_read(start_addr, &fhdr, sizeof(esp_image_header_t));
|
|
||||||
if (ret) {
|
|
||||||
ESP_EARLY_LOGE(TAG, "SPI flash read result %d\n", ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (3 > fhdr.spi_speed)
|
|
||||||
freqdiv = fhdr.spi_speed + 2;
|
|
||||||
else if (0x0F == fhdr.spi_speed)
|
|
||||||
freqdiv = 1;
|
|
||||||
else
|
|
||||||
freqdiv = 2;
|
|
||||||
|
|
||||||
if (fhdr.spi_size < flash_map_table_size) {
|
|
||||||
flash_size = flash_map_table[fhdr.spi_size];
|
|
||||||
ESP_EARLY_LOGD(TAG, "SPI flash size is %d\n", flash_size);
|
|
||||||
} else {
|
|
||||||
flash_size = 0;
|
|
||||||
ESP_EARLY_LOGE(TAG, "SPI size error is %d\n", fhdr.spi_size);
|
|
||||||
}
|
|
||||||
flashchip.chip_size = flash_size;
|
|
||||||
|
|
||||||
if (1 >= freqdiv) {
|
|
||||||
freqbits = SPI_FLASH_CLK_EQU_SYSCLK;
|
|
||||||
SET_PERI_REG_MASK(PERIPHS_SPI_FLASH_CTRL, SPI_FLASH_CLK_EQU_SYSCLK);
|
|
||||||
SET_PERI_REG_MASK(PERIPHS_IO_MUX_CONF_U, SPI0_CLK_EQU_SYSCLK);
|
|
||||||
} else {
|
|
||||||
freqbits = ((freqdiv - 1) << 8) + ((freqdiv / 2 - 1) << 4) + (freqdiv - 1);
|
|
||||||
CLEAR_PERI_REG_MASK(PERIPHS_SPI_FLASH_CTRL, SPI_FLASH_CLK_EQU_SYSCLK);
|
|
||||||
CLEAR_PERI_REG_MASK(PERIPHS_IO_MUX_CONF_U, SPI0_CLK_EQU_SYSCLK);
|
|
||||||
}
|
|
||||||
SET_PERI_REG_BITS(PERIPHS_SPI_FLASH_CTRL, 0xfff, freqbits, 0);
|
|
||||||
|
|
||||||
if (fhdr.spi_mode == ESP_IMAGE_SPI_MODE_QIO) {
|
|
||||||
ESP_EARLY_LOGD(TAG, "SPI flash enable QIO mode\n");
|
|
||||||
user_spi_flash_dio_to_qio_pre_init();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
#endif /* CONFIG_BOOTLOADER_INIT_SPI_FLASH */
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
#define FLASH_MAP_ADDR 0x40200000
|
#define FLASH_MAP_ADDR 0x40200000
|
||||||
#define FLASH_MAP_SIZE 0x00100000
|
#define FLASH_MAP_SIZE 0x00100000
|
||||||
|
|
||||||
extern void chip_boot(size_t start_addr);
|
extern void chip_boot(void);
|
||||||
extern int rtc_init(void);
|
extern int rtc_init(void);
|
||||||
extern int mac_init(void);
|
extern int mac_init(void);
|
||||||
extern int base_gpio_init(void);
|
extern int base_gpio_init(void);
|
||||||
@ -41,6 +41,7 @@ extern int watchdog_init(void);
|
|||||||
extern int wifi_timer_init(void);
|
extern int wifi_timer_init(void);
|
||||||
extern int wifi_nvs_init(void);
|
extern int wifi_nvs_init(void);
|
||||||
extern esp_err_t esp_pthread_init(void);
|
extern esp_err_t esp_pthread_init(void);
|
||||||
|
extern void phy_get_bb_evm(void);
|
||||||
|
|
||||||
static void user_init_entry(void *param)
|
static void user_init_entry(void *param)
|
||||||
{
|
{
|
||||||
@ -55,6 +56,8 @@ static void user_init_entry(void *param)
|
|||||||
for (func = &__init_array_start; func < &__init_array_end; func++)
|
for (func = &__init_array_start; func < &__init_array_end; func++)
|
||||||
func[0]();
|
func[0]();
|
||||||
|
|
||||||
|
phy_get_bb_evm();
|
||||||
|
|
||||||
assert(nvs_flash_init() == 0);
|
assert(nvs_flash_init() == 0);
|
||||||
assert(wifi_nvs_init() == 0);
|
assert(wifi_nvs_init() == 0);
|
||||||
assert(rtc_init() == 0);
|
assert(rtc_init() == 0);
|
||||||
@ -108,7 +111,9 @@ void call_user_start(size_t start_addr)
|
|||||||
"wsr a0, vecbase\n"
|
"wsr a0, vecbase\n"
|
||||||
: : :"memory");
|
: : :"memory");
|
||||||
|
|
||||||
chip_boot(start_addr);
|
#ifndef CONFIG_BOOTLOADER_INIT_SPI_FLASH
|
||||||
|
chip_boot();
|
||||||
|
#endif
|
||||||
|
|
||||||
/* clear bss data */
|
/* clear bss data */
|
||||||
for (p = &_bss_start; p < &_bss_end; p++)
|
for (p = &_bss_start; p < &_bss_end; p++)
|
||||||
|
@ -63,6 +63,14 @@ config FLASHMODE_DOUT
|
|||||||
bool "DOUT"
|
bool "DOUT"
|
||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
|
config FLASHMODE_SWITCH_TO_QIO
|
||||||
|
bool "Try to switch to QIO mode at startup"
|
||||||
|
default y
|
||||||
|
depends on FLASHMODE_DIO
|
||||||
|
help
|
||||||
|
If users use SPI flash DIO mode to download firmware, bootloader or application
|
||||||
|
can switch to QIO mode by enable this option.
|
||||||
|
|
||||||
# Note: we use esptool.py to flash bootloader in
|
# Note: we use esptool.py to flash bootloader in
|
||||||
# dio mode for QIO/QOUT, bootloader then upgrades
|
# dio mode for QIO/QOUT, bootloader then upgrades
|
||||||
# itself to quad mode during initialisation
|
# itself to quad mode during initialisation
|
||||||
@ -73,6 +81,13 @@ config ESPTOOLPY_FLASHMODE
|
|||||||
default "dio" if FLASHMODE_DIO
|
default "dio" if FLASHMODE_DIO
|
||||||
default "dout" if FLASHMODE_DOUT
|
default "dout" if FLASHMODE_DOUT
|
||||||
|
|
||||||
|
config SPI_FLASH_MODE
|
||||||
|
hex
|
||||||
|
default 0x0 if FLASHMODE_QIO
|
||||||
|
default 0x1 if FLASHMODE_QOUT
|
||||||
|
default 0x2 if FLASHMODE_DIO
|
||||||
|
default 0x3 if FLASHMODE_DOUT
|
||||||
|
|
||||||
choice ESPTOOLPY_FLASHFREQ
|
choice ESPTOOLPY_FLASHFREQ
|
||||||
prompt "Flash SPI speed"
|
prompt "Flash SPI speed"
|
||||||
default ESPTOOLPY_FLASHFREQ_40M
|
default ESPTOOLPY_FLASHFREQ_40M
|
||||||
@ -96,6 +111,12 @@ config ESPTOOLPY_FLASHFREQ
|
|||||||
default "26m" if ESPTOOLPY_FLASHFREQ_26M
|
default "26m" if ESPTOOLPY_FLASHFREQ_26M
|
||||||
default "20m" if ESPTOOLPY_FLASHFREQ_20M
|
default "20m" if ESPTOOLPY_FLASHFREQ_20M
|
||||||
|
|
||||||
|
config SPI_FLASH_FREQ
|
||||||
|
hex
|
||||||
|
default 0xf if ESPTOOLPY_FLASHFREQ_80M
|
||||||
|
default 0x0 if ESPTOOLPY_FLASHFREQ_40M
|
||||||
|
default 0x1 if ESPTOOLPY_FLASHFREQ_26M
|
||||||
|
default 0x2 if ESPTOOLPY_FLASHFREQ_20M
|
||||||
|
|
||||||
choice ESPTOOLPY_FLASHSIZE
|
choice ESPTOOLPY_FLASHSIZE
|
||||||
prompt "Flash size"
|
prompt "Flash size"
|
||||||
@ -122,6 +143,14 @@ config ESPTOOLPY_FLASHSIZE
|
|||||||
default "8MB" if ESPTOOLPY_FLASHSIZE_8MB
|
default "8MB" if ESPTOOLPY_FLASHSIZE_8MB
|
||||||
default "16MB" if ESPTOOLPY_FLASHSIZE_16MB
|
default "16MB" if ESPTOOLPY_FLASHSIZE_16MB
|
||||||
|
|
||||||
|
config SPI_FLASH_SIZE
|
||||||
|
hex
|
||||||
|
default 0x100000 if ESPTOOLPY_FLASHSIZE_1MB
|
||||||
|
default 0x200000 if ESPTOOLPY_FLASHSIZE_2MB
|
||||||
|
default 0x400000 if ESPTOOLPY_FLASHSIZE_4MB
|
||||||
|
default 0x800000 if ESPTOOLPY_FLASHSIZE_8MB
|
||||||
|
default 0x1000000 if ESPTOOLPY_FLASHSIZE_16MB
|
||||||
|
|
||||||
choice ESPTOOLPY_BEFORE
|
choice ESPTOOLPY_BEFORE
|
||||||
prompt "Before flashing"
|
prompt "Before flashing"
|
||||||
default ESPTOOLPY_BEFORE_RESET
|
default ESPTOOLPY_BEFORE_RESET
|
||||||
|
@ -2,8 +2,10 @@
|
|||||||
# Component Makefile
|
# Component Makefile
|
||||||
#
|
#
|
||||||
|
|
||||||
ifndef IS_BOOTLOADER_BUILD
|
|
||||||
COMPONENT_SRCDIRS := src
|
COMPONENT_SRCDIRS := src
|
||||||
|
|
||||||
|
ifdef IS_BOOTLOADER_BUILD
|
||||||
|
COMPONENT_OBJS := src/spi_flash.o src/spi_flash_raw.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
CFLAGS += -DPARTITION_QUEUE_HEADER=\"sys/queue.h\"
|
CFLAGS += -DPARTITION_QUEUE_HEADER=\"sys/queue.h\"
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "spi_flash.h"
|
#include "spi_flash.h"
|
||||||
|
#include "driver/spi_register.h"
|
||||||
|
#include "esp8266/pin_mux_register.h"
|
||||||
#include "priv/esp_spi_flash_raw.h"
|
#include "priv/esp_spi_flash_raw.h"
|
||||||
|
|
||||||
#include "esp_attr.h"
|
#include "esp_attr.h"
|
||||||
@ -43,9 +45,15 @@
|
|||||||
#define SPI_FLASH_RDSR2 0x35
|
#define SPI_FLASH_RDSR2 0x35
|
||||||
#define SPI_FLASH_PROTECT_STATUS (BIT(2)|BIT(3)|BIT(4)|BIT(5)|BIT(6)|BIT(14))
|
#define SPI_FLASH_PROTECT_STATUS (BIT(2)|BIT(3)|BIT(4)|BIT(5)|BIT(6)|BIT(14))
|
||||||
|
|
||||||
|
#ifndef BOOTLOADER_BUILD
|
||||||
#define FLASH_INTR_DECLARE(t)
|
#define FLASH_INTR_DECLARE(t)
|
||||||
#define FLASH_INTR_LOCK(t) vPortEnterCritical()
|
#define FLASH_INTR_LOCK(t) vPortEnterCritical()
|
||||||
#define FLASH_INTR_UNLOCK(t) vPortExitCritical()
|
#define FLASH_INTR_UNLOCK(t) vPortExitCritical()
|
||||||
|
#else
|
||||||
|
#define FLASH_INTR_DECLARE(t)
|
||||||
|
#define FLASH_INTR_LOCK(t)
|
||||||
|
#define FLASH_INTR_UNLOCK(t)
|
||||||
|
#endif
|
||||||
|
|
||||||
#define FLASH_ALIGN_BYTES 4
|
#define FLASH_ALIGN_BYTES 4
|
||||||
#define FLASH_ALIGN(addr) ((((size_t)addr) + (FLASH_ALIGN_BYTES - 1)) & (~(FLASH_ALIGN_BYTES - 1)))
|
#define FLASH_ALIGN(addr) ((((size_t)addr) + (FLASH_ALIGN_BYTES - 1)) & (~(FLASH_ALIGN_BYTES - 1)))
|
||||||
@ -61,7 +69,7 @@ extern void vPortExitCritical(void);
|
|||||||
|
|
||||||
esp_spi_flash_chip_t flashchip = {
|
esp_spi_flash_chip_t flashchip = {
|
||||||
0x1640ef,
|
0x1640ef,
|
||||||
(32 / 8) * 1024 * 1024,
|
CONFIG_SPI_FLASH_SIZE,
|
||||||
64 * 1024,
|
64 * 1024,
|
||||||
4 * 1024,
|
4 * 1024,
|
||||||
256,
|
256,
|
||||||
@ -720,3 +728,33 @@ esp_err_t spi_flash_erase_range(size_t start_address, size_t size)
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void esp_spi_flash_init(uint32_t spi_speed, uint32_t spi_mode)
|
||||||
|
{
|
||||||
|
uint32_t freqdiv, freqbits;
|
||||||
|
|
||||||
|
SET_PERI_REG_MASK(PERIPHS_SPI_FLASH_USRREG, BIT5);
|
||||||
|
|
||||||
|
if (spi_speed < 3)
|
||||||
|
freqdiv = spi_speed + 2;
|
||||||
|
else if (0x0F == spi_speed)
|
||||||
|
freqdiv = 1;
|
||||||
|
else
|
||||||
|
freqdiv = 2;
|
||||||
|
|
||||||
|
if (1 >= freqdiv) {
|
||||||
|
freqbits = SPI_FLASH_CLK_EQU_SYSCLK;
|
||||||
|
SET_PERI_REG_MASK(PERIPHS_SPI_FLASH_CTRL, SPI_FLASH_CLK_EQU_SYSCLK);
|
||||||
|
SET_PERI_REG_MASK(PERIPHS_IO_MUX_CONF_U, SPI0_CLK_EQU_SYSCLK);
|
||||||
|
} else {
|
||||||
|
freqbits = ((freqdiv - 1) << 8) + ((freqdiv / 2 - 1) << 4) + (freqdiv - 1);
|
||||||
|
CLEAR_PERI_REG_MASK(PERIPHS_SPI_FLASH_CTRL, SPI_FLASH_CLK_EQU_SYSCLK);
|
||||||
|
CLEAR_PERI_REG_MASK(PERIPHS_IO_MUX_CONF_U, SPI0_CLK_EQU_SYSCLK);
|
||||||
|
}
|
||||||
|
SET_PERI_REG_BITS(PERIPHS_SPI_FLASH_CTRL, 0xfff, freqbits, 0);
|
||||||
|
|
||||||
|
#ifndef CONFIG_FLASHMODE_SWITCH_TO_QIO
|
||||||
|
if (spi_mode == 0)
|
||||||
|
#endif
|
||||||
|
user_spi_flash_dio_to_qio_pre_init();
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user