diff --git a/boards/xtensa/esp32/esp32.dts b/boards/xtensa/esp32/esp32.dts index 7981f7a88e8..f598f07c5d8 100644 --- a/boards/xtensa/esp32/esp32.dts +++ b/boards/xtensa/esp32/esp32.dts @@ -20,6 +20,7 @@ zephyr,sram = &sram0; zephyr,console = &uart0; zephyr,shell-uart = &uart0; + zephyr,flash = &flash0; }; }; @@ -110,3 +111,7 @@ &trng0 { status = "okay"; }; + +&flash0 { + status = "okay"; +}; diff --git a/drivers/flash/CMakeLists.txt b/drivers/flash/CMakeLists.txt index 4a2e2e109ee..88b7a7f1b3b 100644 --- a/drivers/flash/CMakeLists.txt +++ b/drivers/flash/CMakeLists.txt @@ -20,6 +20,7 @@ zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_RV32M1 soc_flash_rv32m1.c) zephyr_library_sources_ifdef(CONFIG_FLASH_STM32_QSPI flash_stm32_qspi.c) zephyr_library_sources_ifdef(CONFIG_FLASH_MCUX_FLEXSPI flash_mcux_flexspi.c) zephyr_library_sources_ifdef(CONFIG_FLASH_MCUX_FLEXSPI_NOR flash_mcux_flexspi_nor.c) +zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_ESP32 flash_esp32.c) if(CONFIG_SOC_FLASH_STM32) if(CONFIG_SOC_SERIES_STM32H7X) diff --git a/drivers/flash/Kconfig b/drivers/flash/Kconfig index 3eaa7682dff..fed4509de16 100644 --- a/drivers/flash/Kconfig +++ b/drivers/flash/Kconfig @@ -60,6 +60,8 @@ config FLASH_PAGE_LAYOUT source "drivers/flash/Kconfig.at45" +source "drivers/flash/Kconfig.esp32" + source "drivers/flash/Kconfig.nrf" source "drivers/flash/Kconfig.lpc" diff --git a/drivers/flash/Kconfig.esp32 b/drivers/flash/Kconfig.esp32 new file mode 100644 index 00000000000..be1d621c277 --- /dev/null +++ b/drivers/flash/Kconfig.esp32 @@ -0,0 +1,16 @@ +# Copyright (c) 2020 Espressif Systems (Shanghai) Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FLASH_ESP32 + bool "Espressif ESP32 flash driver" + default y + select FLASH_HAS_DRIVER_ENABLED + select FLASH_HAS_PAGE_LAYOUT + depends on SOC_ESP32 + help + Enable ESP32 internal flash driver. + +config MPU_ALLOW_FLASH_WRITE + bool "Add MPU access to write to flash" + help + Enable this to allow MPU RWX access to flash memory diff --git a/drivers/flash/flash_esp32.c b/drivers/flash/flash_esp32.c new file mode 100644 index 00000000000..813dced2e8f --- /dev/null +++ b/drivers/flash/flash_esp32.c @@ -0,0 +1,622 @@ +/* + * Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT espressif_esp32_flash_controller +#define SOC_NV_FLASH_NODE DT_INST(0, soc_nv_flash) + +#define FLASH_WRITE_BLK_SZ DT_PROP(SOC_NV_FLASH_NODE, write_block_size) +#define FLASH_ERASE_BLK_SZ DT_PROP(SOC_NV_FLASH_NODE, erase_block_size) + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "stubs.h" +#include +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(flash_esp32, CONFIG_FLASH_LOG_LEVEL); + +struct flash_esp32_dev_config { + spi_dev_t *controller; + esp_rom_spiflash_chip_t *chip; +}; + +struct flash_esp32_dev_data { + struct k_sem sem; +}; + +static const struct flash_parameters flash_esp32_parameters = { + .write_block_size = FLASH_WRITE_BLK_SZ, + .erase_value = 0xff, +}; + +#define DEV_DATA(dev) ((struct flash_esp32_dev_data *const)(dev)->data) +#define DEV_CFG(dev) ((const struct flash_esp32_dev_config *const)(dev)->config) +#define SPI1_EXTRA_DUMMIES (g_rom_spiflash_dummy_len_plus[1]) +#define MAX_BUFF_ALLOC_RETRIES 5 +#define MAX_READ_CHUNK 16384 +#define ADDRESS_MASK_24BIT 0xFFFFFF +#define SPI_TIMEOUT_MSEC 500 + +static inline void flash_esp32_sem_take(const struct device *dev) +{ + k_sem_take(&DEV_DATA(dev)->sem, K_FOREVER); +} + +static inline void flash_esp32_sem_give(const struct device *dev) +{ + k_sem_give(&DEV_DATA(dev)->sem); +} + +static inline int flash_esp32_wait_cmd_done(const spi_dev_t *hw) +{ + int64_t timeout = k_uptime_get() + SPI_TIMEOUT_MSEC; + + while (!spi_flash_ll_cmd_is_done(hw)) { + if (k_uptime_get() > timeout) { + LOG_ERR("controller has timed out"); + return -ETIMEDOUT; + } + } + + return 0; +} + +static inline bool points_to_dram(const void *ptr) +{ + return ((intptr_t)ptr >= SOC_DRAM_LOW && (intptr_t)ptr < SOC_DRAM_HIGH); +} + +int configure_read_mode(spi_dev_t *hw, + uint32_t cmd, + uint32_t addr_bitlen, + int dummy_len, + bool byte_cmd) +{ + if (dummy_len) { + spi_flash_ll_set_dummy(hw, dummy_len); + } + + spi_flash_ll_set_addr_bitlen(hw, addr_bitlen); + + if (!byte_cmd) { + REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG2, SPI_USR_COMMAND_VALUE, cmd); + } else { + spi_flash_ll_set_command8(hw, (uint8_t) cmd); + } + + return 0; +} + +static int set_read_options(const struct device *dev) +{ + spi_dev_t *hw = DEV_CFG(dev)->controller; + uint32_t dummy_len = 0; + uint32_t addr_len; + uint8_t read_cmd; + bool byte_cmd = true; + uint32_t read_mode = READ_PERI_REG(PERIPHS_SPI_FLASH_CTRL); + + if ((read_mode & SPI_FREAD_QIO) && (read_mode & SPI_FASTRD_MODE)) { + spi_ll_enable_mosi(hw, 0); + spi_ll_enable_miso(hw, 1); + dummy_len = 1 + SPI1_R_QIO_DUMMY_CYCLELEN + SPI1_EXTRA_DUMMIES; + addr_len = SPI1_R_QIO_ADDR_BITSLEN + 1; + read_cmd = CMD_FASTRD_QIO; + } else if (read_mode & SPI_FASTRD_MODE) { + spi_ll_enable_mosi(hw, 0); + spi_ll_enable_miso(hw, 1); + if (read_mode & SPI_FREAD_DIO) { + read_cmd = CMD_FASTRD_DIO; + if (SPI1_EXTRA_DUMMIES == 0) { + spi_flash_ll_set_dummy(hw, 0); + addr_len = SPI1_R_DIO_ADDR_BITSLEN + 1; + } else { + byte_cmd = false; + dummy_len = SPI1_EXTRA_DUMMIES; + addr_len = SPI1_R_DIO_ADDR_BITSLEN + 1; + } + } else { + if ((read_mode & SPI_FREAD_QUAD)) { + read_cmd = CMD_FASTRD_QUAD; + } else if ((read_mode & SPI_FREAD_DUAL)) { + read_cmd = CMD_FASTRD_DUAL; + } else { + read_cmd = CMD_FASTRD; + } + dummy_len = 1 + SPI1_R_FAST_DUMMY_CYCLELEN + SPI1_EXTRA_DUMMIES; + addr_len = SPI1_R_FAST_ADDR_BITSLEN + 1; + } + } else { + spi_ll_enable_mosi(hw, 0); + if (SPI1_EXTRA_DUMMIES == 0) { + spi_flash_ll_set_dummy(hw, 0); + } else { + dummy_len = SPI1_EXTRA_DUMMIES; + } + spi_ll_enable_miso(hw, 1); + addr_len = SPI1_R_SIO_ADDR_BITSLEN + 1; + read_cmd = CMD_READ; + } + + return configure_read_mode(hw, read_cmd, addr_len, dummy_len, byte_cmd); +} + +static int read_once(const struct device *dev, void *buffer, uint32_t address, uint32_t read_len) +{ + spi_dev_t *hw = DEV_CFG(dev)->controller; + int bitlen = spi_flash_ll_get_addr_bitlen(hw); + + spi_flash_ll_set_usr_address(hw, address << (bitlen - 24), bitlen); + spi_flash_ll_set_miso_bitlen(hw, read_len * 8); + spi_flash_ll_user_start(hw); + + int rc = flash_esp32_wait_cmd_done(hw); + + if (rc != 0) { + return rc; + } + + spi_flash_ll_get_buffer_data(hw, buffer, read_len); + return 0; +} + +static int read_data(const struct device *dev, uint8_t *buffer, uint32_t address, uint32_t length) +{ + int rc = 0; + + rc = set_read_options(dev); + + if (rc == -ENOTSUP) { + LOG_ERR("configure host io mode failed - unsupported"); + return rc; + } + + while (rc == 0 && length > 0) { + uint32_t read_len = MIN(length, SPI_FLASH_HAL_MAX_READ_BYTES); + + rc = read_once(dev, buffer, address, read_len); + + address += read_len; + length -= read_len; + buffer += read_len; + } + + return rc; +} + +static int flash_esp32_read(const struct device *dev, off_t address, void *buffer, size_t length) +{ + const struct flash_esp32_dev_config *const cfg = DEV_CFG(dev); + const spi_flash_guard_funcs_t *guard = spi_flash_guard_get(); + uint32_t chip_size = cfg->chip->chip_size; + + if (length == 0) { + return 0; + } + + if (buffer == NULL || address > chip_size || address + length > chip_size) { + return -EINVAL; + } + + bool direct_read = points_to_dram(buffer); + uint8_t *temp_buff = NULL; + size_t read_chunk = MIN(MAX_READ_CHUNK, length); + size_t temp_chunk = MAX_READ_CHUNK; + int rc = 0; + + flash_esp32_sem_take(dev); + + if (!direct_read) { + + unsigned int retries = MAX_BUFF_ALLOC_RETRIES; + + while (temp_buff == NULL && retries--) { + read_chunk = MIN(read_chunk, temp_chunk); + temp_chunk >>= 1; + read_chunk = (read_chunk + 3) & ~3; + temp_buff = k_malloc(read_chunk); + } + + LOG_INF("allocate temp buffer: %p (%d)", temp_buff, read_chunk); + + if (temp_buff == NULL) { + rc = -ENOMEM; + goto out; + } + } + + uint8_t *buff = (uint8_t *)buffer; + + do { + guard->start(); + + uint8_t *read_buff = (temp_buff) ? temp_buff : buffer; + size_t read_len = MIN(read_chunk, length); + + rc = read_data(dev, read_buff, address, read_len); + + if (rc) { + guard->end(); + break; + } + + guard->end(); + + if (temp_buff) { + memcpy(buffer, temp_buff, read_len); + } + + address += read_len; + length -= read_len; + buff += read_len; + buffer = (void *)buff; + } while (rc == 0 && length > 0); + + k_free(temp_buff); + +out: + flash_esp32_sem_give(dev); + + return rc; +} + +static inline void set_write_options(const struct device *dev) +{ + spi_dev_t *hw = DEV_CFG(dev)->controller; + + spi_flash_ll_set_dummy(hw, 0); + /* only single line flash write is currently supported */ + spi_flash_ll_set_addr_bitlen(hw, (1 + ESP_ROM_SPIFLASH_W_SIO_ADDR_BITSLEN)); +} + +static int read_status(const struct device *dev, uint32_t *status) +{ + const struct flash_esp32_dev_config *const cfg = DEV_CFG(dev); + uint32_t status_value = ESP_ROM_SPIFLASH_BUSY_FLAG; + + if (SPI1_EXTRA_DUMMIES == 0) { + while (ESP_ROM_SPIFLASH_BUSY_FLAG == + (status_value & ESP_ROM_SPIFLASH_BUSY_FLAG)) { + WRITE_PERI_REG(PERIPHS_SPI_FLASH_STATUS, 0); + WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_FLASH_RDSR); + + int rc = flash_esp32_wait_cmd_done(cfg->controller); + + if (rc != 0) { + return rc; + } + + status_value = READ_PERI_REG(PERIPHS_SPI_FLASH_STATUS); + status_value &= cfg->chip->status_mask; + } + } else { + while (ESP_ROM_SPIFLASH_BUSY_FLAG == (status_value & ESP_ROM_SPIFLASH_BUSY_FLAG)) { + esp_rom_spiflash_read_user_cmd(&status_value, CMD_RDSR); + } + } + *status = status_value; + + return 0; +} + +static inline bool host_idle(spi_dev_t *hw) +{ + bool idle = spi_flash_ll_host_idle(hw); + + idle &= spi_flash_ll_host_idle(&SPI0); + + return idle; +} + +static int wait_idle(const struct device *dev) +{ + const struct flash_esp32_dev_config *const cfg = DEV_CFG(dev); + uint32_t status; + int64_t timeout = k_uptime_get() + SPI_TIMEOUT_MSEC; + + /* wait for spi control ready */ + while (host_idle(cfg->controller)) { + if (k_uptime_get() > timeout) { + return -ETIMEDOUT; + } + } + + /* wait for flash status ready */ + if (read_status(dev, &status) != 0) { + return -EINVAL; + } + return 0; +} + +static int write_protect(const struct device *dev, bool write_protect) +{ + const struct flash_esp32_dev_config *const cfg = DEV_CFG(dev); + uint32_t flash_status = 0; + + wait_idle(dev); + + /* enable writing */ + spi_flash_ll_set_write_protect(cfg->controller, write_protect); + + int rc = flash_esp32_wait_cmd_done(cfg->controller); + + if (rc != 0) { + return rc; + } + + /* make sure the flash is ready for writing */ + while (ESP_ROM_SPIFLASH_WRENABLE_FLAG != (flash_status & ESP_ROM_SPIFLASH_WRENABLE_FLAG)) { + read_status(dev, &flash_status); + } + + return 0; +} + +static int program_page(const struct device *dev, uint32_t spi_addr, + uint32_t *addr_source, int32_t byte_length) +{ + const struct flash_esp32_dev_config *const cfg = DEV_CFG(dev); + spi_dev_t *hw = DEV_CFG(dev)->controller; + + /* check 4byte alignment */ + if ((byte_length & 0x3) != 0) { + return -EINVAL; + } + + /* check if write in one page */ + if ((cfg->chip->page_size) < ((spi_addr % (cfg->chip->page_size)) + byte_length)) { + return -EINVAL; + } + + wait_idle(dev); + + uint32_t addr; + uint32_t prog_len; + + while (byte_length > 0) { + if (write_protect(dev, false) != 0) { + return -EINVAL; + } + + addr = spi_addr & ADDRESS_MASK_24BIT; + + if (byte_length >= ESP_ROM_SPIFLASH_BUFF_BYTE_WRITE_NUM) { + addr |= ESP_ROM_SPIFLASH_BUFF_BYTE_WRITE_NUM << ESP_ROM_SPIFLASH_BYTES_LEN; + prog_len = (uint32_t)ESP_ROM_SPIFLASH_BUFF_BYTE_WRITE_NUM; + spi_flash_ll_set_address(hw, addr); + spi_flash_ll_program_page(hw, addr_source, prog_len); + byte_length -= ESP_ROM_SPIFLASH_BUFF_BYTE_WRITE_NUM; + spi_addr += ESP_ROM_SPIFLASH_BUFF_BYTE_WRITE_NUM; + } else { + addr |= byte_length << ESP_ROM_SPIFLASH_BYTES_LEN; + prog_len = (uint32_t)byte_length; + spi_flash_ll_set_address(hw, addr); + spi_flash_ll_program_page(hw, addr_source, prog_len); + byte_length = 0; + } + + int rc = flash_esp32_wait_cmd_done(hw); + + if (rc != 0) { + return rc; + } + + wait_idle(dev); + } + + return 0; +} + +static int flash_esp32_write(const struct device *dev, + off_t address, + const void *buffer, + size_t length) +{ + const struct flash_esp32_dev_config *const cfg = DEV_CFG(dev); + + uint32_t page_size; + uint32_t prog_len, prog_num; + int rc = 0; + + flash_esp32_sem_take(dev); + + set_write_options(dev); + + /* check program size */ + if ((address + length) > (cfg->chip->chip_size)) { + rc = -EINVAL; + goto out; + } + + page_size = cfg->chip->page_size; + prog_len = page_size - (address % page_size); + if (length < prog_len) { + rc = program_page(dev, address, (uint32_t *)buffer, length); + if (rc) { + goto out; + } + } else { + rc = program_page(dev, address, (uint32_t *)buffer, prog_len); + + if (rc) { + goto out; + } + + /* whole page program */ + prog_num = (length - prog_len) / page_size; + for (uint8_t i = 0; i < prog_num; ++i) { + rc = program_page(dev, + address + prog_len, + (uint32_t *)buffer + (prog_len >> 2), + page_size); + + if (rc) { + goto out; + } + + prog_len += page_size; + } + + /* remain parts to program */ + rc = program_page(dev, + address + prog_len, + (uint32_t *)buffer + (prog_len >> 2), + length - prog_len); + if (rc) { + LOG_ERR("invalid page programming setting"); + } + } + +out: + flash_esp32_sem_give(dev); + + return rc; +} + +static int erase_sector(const struct device *dev, uint32_t start_addr) +{ + spi_dev_t *hw = DEV_CFG(dev)->controller; + int rc = write_protect(dev, false); + + if (rc == 0) { + rc = wait_idle(dev); + } + + if (rc == 0) { + spi_flash_ll_set_addr_bitlen(hw, 24); + spi_flash_ll_set_address(hw, start_addr & ADDRESS_MASK_24BIT); + spi_flash_ll_erase_sector(hw); + + rc = flash_esp32_wait_cmd_done(hw); + if (rc) { + return rc; + } + + rc = wait_idle(dev); + if (rc) { + LOG_ERR("waiting for host device idle state has failed"); + } + } + + return rc; +} + +static int flash_esp32_erase(const struct device *dev, off_t start, size_t len) +{ + uint32_t block_erase_size = DEV_CFG(dev)->chip->block_size; + uint32_t sector_size = DEV_CFG(dev)->chip->sector_size; + uint32_t chip_size = DEV_CFG(dev)->chip->chip_size; + const spi_flash_guard_funcs_t *guard = spi_flash_guard_get(); + + if (sector_size == 0 || (block_erase_size % sector_size) != 0) { + return -EIO; + } + if (start > chip_size || start + len > chip_size) { + return -EINVAL; + } + if ((start % sector_size) != 0 || (len % sector_size) != 0) { + return -EINVAL; + } + + flash_esp32_sem_take(dev); + + set_write_options(dev); + + int rc = 0; + + while (rc == 0 && len >= sector_size) { + guard->start(); + + rc = erase_sector(dev, start); + if (rc) { + guard->end(); + goto out; + } + + start += sector_size; + len -= sector_size; + + guard->end(); + } + +out: + flash_esp32_sem_give(dev); + + return rc; +} + +static int flash_esp32_write_protection(const struct device *dev, bool enable) +{ + return 0; +} + +#if CONFIG_FLASH_PAGE_LAYOUT +static const struct flash_pages_layout flash_esp32_pages_layout = { + .pages_count = DT_REG_SIZE(SOC_NV_FLASH_NODE) / FLASH_ERASE_BLK_SZ, + .pages_size = DT_PROP(SOC_NV_FLASH_NODE, erase_block_size), +}; + +void flash_esp32_page_layout(const struct device *dev, + const struct flash_pages_layout **layout, + size_t *layout_size) +{ + *layout = &flash_esp32_pages_layout; + *layout_size = 1; +} +#endif /* CONFIG_FLASH_PAGE_LAYOUT */ + +static const struct flash_parameters * +flash_esp32_get_parameters(const struct device *dev) +{ + ARG_UNUSED(dev); + + return &flash_esp32_parameters; +} + +static int flash_esp32_init(const struct device *dev) +{ + struct flash_esp32_dev_data *const dev_data = DEV_DATA(dev); + + k_sem_init(&dev_data->sem, 1, 1); + + return 0; +} + +static const struct flash_driver_api flash_esp32_driver_api = { + .read = flash_esp32_read, + .write = flash_esp32_write, + .erase = flash_esp32_erase, + .write_protection = flash_esp32_write_protection, + .get_parameters = flash_esp32_get_parameters, +#ifdef CONFIG_FLASH_PAGE_LAYOUT + .page_layout = flash_esp32_page_layout, +#endif +}; + +static struct flash_esp32_dev_data flash_esp32_data; + +static const struct flash_esp32_dev_config flash_esp32_config = { + .controller = (spi_dev_t *) DT_INST_REG_ADDR(0), + .chip = &g_rom_flashchip +}; + +DEVICE_DT_INST_DEFINE(0, flash_esp32_init, + device_pm_control_nop, + &flash_esp32_data, &flash_esp32_config, + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, + &flash_esp32_driver_api); diff --git a/dts/bindings/flash_controller/espressif,esp32-flash-controller.yaml b/dts/bindings/flash_controller/espressif,esp32-flash-controller.yaml new file mode 100644 index 00000000000..c1bfa3bf696 --- /dev/null +++ b/dts/bindings/flash_controller/espressif,esp32-flash-controller.yaml @@ -0,0 +1,5 @@ +description: ESP32 Family flash controller + +compatible: "espressif,esp32-flash-controller" + +include: flash-controller.yaml diff --git a/dts/xtensa/espressif/esp32.dtsi b/dts/xtensa/espressif/esp32.dtsi index 8a9ac87adc0..20339266ccf 100644 --- a/dts/xtensa/espressif/esp32.dtsi +++ b/dts/xtensa/espressif/esp32.dtsi @@ -12,6 +12,7 @@ / { chosen { zephyr,entropy = &trng0; + zephyr,flash-controller = &flash; }; cpus { @@ -55,6 +56,24 @@ status = "ok"; }; + flash: flash-controller@3ff42000 { + compatible = "espressif,esp32-flash-controller"; + label = "FLASH_CTRL"; + reg = <0x3ff42000 0x1000>; + /* interrupts = <3 0>; */ + + #address-cells = <1>; + #size-cells = <1>; + + flash0: flash@0 { + compatible = "soc-nv-flash"; + label = "FLASH_ESP32"; + reg = <0 0x400000>; + erase-block-size = <4096>; + write-block-size = <1>; + }; + }; + uart0: uart@3ff40000 { compatible = "espressif,esp32-uart"; reg = <0x3ff40000 0x400>; diff --git a/soc/xtensa/esp32/linker.ld b/soc/xtensa/esp32/linker.ld index 2e4f52825a2..29f0ccf6de3 100644 --- a/soc/xtensa/esp32/linker.ld +++ b/soc/xtensa/esp32/linker.ld @@ -40,6 +40,10 @@ PROVIDE ( Cache_Read_Disable_rom = 0x40009ab8 ); PROVIDE ( Cache_Read_Enable_rom = 0x40009a84 ); PROVIDE ( Cache_Read_Init_rom = 0x40009950 ); PROVIDE ( phy_get_romfuncs = 0x40004100 ); +PROVIDE ( esp_rom_spiflash_read_user_cmd = 0x400621b0 ); +PROVIDE ( g_rom_spiflash_dummy_len_plus = 0x3ffae290 ); +PROVIDE ( g_rom_flashchip = 0x3ffae270 ); +PROVIDE ( SPI0 = 0x3ff43000 ); PROVIDE ( SPI1 = 0x3ff42fff ); PROVIDE ( SPI2 = 0x3ff64fff ); PROVIDE ( SPI3 = 0x3ff65fff ); @@ -269,6 +273,7 @@ _net_buf_pool_list = _esp_net_buf_pool_list; *libzephyr.a:log_core.*(.rodata .rodata.*) *libzephyr.a:log_backend_uart.*(.rodata .rodata.*) *libzephyr.a:log_output.*(.rodata .rodata.*) + *libdrivers__flash.a:flash_esp32.*(.rodata .rodata.*) *libdrivers__serial.a:uart_esp32.*(.rodata .rodata.*) . = ALIGN(4); @@ -380,7 +385,7 @@ __shell_root_cmds_end = __esp_shell_root_cmds_end; *libsoc.a:cpu_util.*(.literal .text .literal.* .text.*) *libhal.a:(.literal .text .literal.* .text.*) *libgcc.a:lib2funcs.*(.literal .text .literal.* .text.*) - *libzephyr.a:spi_flash_rom_patch.*(.literal .text .literal.* .text.*) + *libdrivers__flash.a:flash_esp32.*(.literal .text .literal.* .text.*) *libzephyr.a:log_noos.*(.literal .text .literal.* .text.*) *libzephyr.a:xtensa_sys_timer.*(.literal .text .literal.* .text.*) *libzephyr.a:log_core.*(.literal .text .literal.* .text.*) diff --git a/soc/xtensa/esp32/soc.c b/soc/xtensa/esp32/soc.c index 74b5dff7d29..664dd24586c 100644 --- a/soc/xtensa/esp32/soc.c +++ b/soc/xtensa/esp32/soc.c @@ -21,6 +21,7 @@ #include "hal/soc_ll.h" #include "soc/cpu.h" #include "soc/gpio_periph.h" +#include "esp_spi_flash.h" extern void z_cstart(void); @@ -95,6 +96,9 @@ void __attribute__((section(".iram1"))) __start(void) *wdt_rtc_protect = 0; #endif +#if CONFIG_SOC_FLASH_ESP32 + spi_flash_guard_set(&g_flash_guard_default_ops); +#endif /* Start Zephyr */ z_cstart(); diff --git a/soc/xtensa/esp32/soc.h b/soc/xtensa/esp32/soc.h index 25fd3c3db26..686dd5558cf 100644 --- a/soc/xtensa/esp32/soc.h +++ b/soc/xtensa/esp32/soc.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -45,4 +46,8 @@ extern void esp32_rom_ets_set_appcpu_boot_addr(void *addr); extern uint8_t esp32_rom_i2c_readReg(uint8_t block, uint8_t host_id, uint8_t reg_add); extern void esp32_rom_i2c_writeReg(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data); +/* ROM information related to SPI Flash chip timing and device */ +extern esp_rom_spiflash_chip_t g_rom_flashchip; +extern uint8_t g_rom_spiflash_dummy_len_plus[]; + #endif /* __SOC_H__ */