mirror of
https://github.com/espressif/ESP8266_RTOS_SDK.git
synced 2025-05-22 01:27:11 +08:00
161 lines
4.8 KiB
C
161 lines
4.8 KiB
C
// Copyright 2018-2019 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 "sdkconfig.h"
|
|
#include "esp_attr.h"
|
|
#include "spi_flash.h"
|
|
#include "esp_log.h"
|
|
#include "esp_system.h"
|
|
#include "esp8266/eagle_soc.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
|
|
|
|
typedef struct flash_hdr {
|
|
uint8_t magic;
|
|
uint8_t blocks;
|
|
uint8_t spi_mode;
|
|
uint8_t spi_speed : 4;
|
|
uint8_t spi_size_map : 4;
|
|
uint32_t entry_addr;
|
|
} flash_hdr_t;
|
|
|
|
typedef struct boot_hdr {
|
|
uint8_t user_bin : 2;
|
|
uint8_t boot_status : 1;
|
|
uint8_t to_qio : 1;
|
|
uint8_t reserve : 4;
|
|
|
|
uint8_t version : 5;
|
|
uint8_t test_pass_flag : 1;
|
|
uint8_t test_start_flag : 1;
|
|
uint8_t enhance_boot_flag : 1;
|
|
|
|
uint8_t test_bin_addr[3];
|
|
uint8_t user_bin_addr[3];
|
|
} boot_hdr_t;
|
|
|
|
extern int ets_printf(const char *fmt, ...);
|
|
|
|
static const char *TAG = "chip_boot";
|
|
|
|
/*
|
|
* @brief initialize the chip including flash I/O and chip cache according to
|
|
* boot parameters which are stored at the flash
|
|
*/
|
|
void chip_boot(void)
|
|
{
|
|
int ret;
|
|
int usebin;
|
|
uint32_t freqdiv, flash_size, sect_size;
|
|
uint32_t freqbits;
|
|
uint32_t cache_map;
|
|
flash_hdr_t fhdr;
|
|
boot_hdr_t bhdr;
|
|
|
|
uint32_t flash_map_table[FALSH_SIZE_MAP_MAX] = {
|
|
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 void phy_get_bb_evm(void);
|
|
extern void cache_init(uint32_t , uint32_t, uint32_t);
|
|
extern void user_spi_flash_dio_to_qio_pre_init(void);
|
|
extern int esp_get_boot_param(uint32_t, uint32_t, void *, uint32_t);
|
|
|
|
phy_get_bb_evm();
|
|
|
|
SET_PERI_REG_MASK(PERIPHS_SPI_FLASH_USRREG, BIT5);
|
|
|
|
ret = spi_flash_read(CONFIG_PARTITION_TABLE_CUSTOM_APP_BIN_OFFSET, &fhdr, sizeof(flash_hdr_t));
|
|
if (ret) {
|
|
ESP_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_map < flash_map_table_size) {
|
|
flash_size = flash_map_table[fhdr.spi_size_map];
|
|
} else {
|
|
flash_size = 0;
|
|
ESP_LOGE(TAG, "SPI size error is %d\n", fhdr.spi_size_map);
|
|
}
|
|
sect_size = 4 * 1024;
|
|
|
|
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);
|
|
|
|
ret = esp_get_boot_param(flash_size, sect_size, &bhdr, sizeof(boot_hdr_t));
|
|
if (ret) {
|
|
ESP_LOGE(TAG, "Get boot parameters %d\n", ret);
|
|
}
|
|
|
|
if (bhdr.user_bin == 1) {
|
|
if (bhdr.boot_status == 1)
|
|
usebin = 1;
|
|
else
|
|
usebin = 0;
|
|
} else {
|
|
if (bhdr.boot_status == 1)
|
|
usebin = 0;
|
|
else {
|
|
if (bhdr.version == 4) {
|
|
bhdr.boot_status = 1;
|
|
usebin = 0;
|
|
} else
|
|
usebin = 1;
|
|
}
|
|
}
|
|
|
|
cache_map = 0;
|
|
if (fhdr.spi_size_map == FLASH_SIZE_16M_MAP_1024_1024
|
|
|| fhdr.spi_size_map == FLASH_SIZE_32M_MAP_1024_1024
|
|
|| fhdr.spi_size_map == FLASH_SIZE_64M_MAP_1024_1024
|
|
|| fhdr.spi_size_map == FLASH_SIZE_128M_MAP_1024_1024) {
|
|
if (bhdr.version >= 4
|
|
&& bhdr.version <= 0x1f) {
|
|
if (usebin == 1)
|
|
cache_map = 1;
|
|
} else {
|
|
ESP_LOGE(TAG, "Need boot 1.4+\n");
|
|
}
|
|
}
|
|
|
|
cache_init(cache_map, 0, 0);
|
|
|
|
if (bhdr.to_qio == 0)
|
|
user_spi_flash_dio_to_qio_pre_init();
|
|
}
|