diff --git a/components/esp_rom/esp32s2/ld/esp32s2.rom.spiflash.ld b/components/esp_rom/esp32s2/ld/esp32s2.rom.spiflash.ld index f0f7670ef..197f7dcdc 100644 --- a/components/esp_rom/esp32s2/ld/esp32s2.rom.spiflash.ld +++ b/components/esp_rom/esp32s2/ld/esp32s2.rom.spiflash.ld @@ -7,6 +7,8 @@ PROVIDE ( g_ticks_per_us_pro = g_ticks_per_us ); PROVIDE ( g_rom_flashchip = SPI_flashchip_data ); PROVIDE ( g_rom_spiflash_chip = SPI_flashchip_data ); PROVIDE ( esp_rom_spiflash_config_param = SPIParamCfg ); +PROVIDE ( esp_rom_spiflash_read = SPIRead ); +PROVIDE ( esp_rom_spiflash_read_status = SPI_read_status ); PROVIDE ( esp_rom_spiflash_read_statushigh = SPI_read_status_high ); PROVIDE ( esp_rom_spiflash_read_user_cmd = SPI_user_command_read ); PROVIDE ( esp_rom_spiflash_write = SPIWrite ); diff --git a/components/spi_flash/CMakeLists.txt b/components/spi_flash/CMakeLists.txt index 54634f928..19d96b8e8 100644 --- a/components/spi_flash/CMakeLists.txt +++ b/components/spi_flash/CMakeLists.txt @@ -5,8 +5,6 @@ if(BOOTLOADER_BUILD) # ESP32 Bootloader needs SPIUnlock from this file, but doesn't # need other parts of this component set(srcs "esp32/spi_flash_rom_patch.c") - elseif (CONFIG_IDF_TARGET_ESP32S2) - set(srcs "esp32s2/spi_flash_rom_patch.c") else() # but on other platforms no source files are needed for bootloader set(srcs) @@ -24,9 +22,6 @@ else() if (CONFIG_IDF_TARGET_ESP32) list(APPEND srcs "esp32/spi_flash_rom_patch.c") - elseif (CONFIG_IDF_TARGET_ESP32S2) - list(APPEND srcs - "esp32s2/spi_flash_rom_patch.c") endif() # New implementation after IDF v4.0 diff --git a/components/spi_flash/esp32s2/spi_flash_rom_patch.c b/components/spi_flash/esp32s2/spi_flash_rom_patch.c deleted file mode 100644 index 46f0ffefa..000000000 --- a/components/spi_flash/esp32s2/spi_flash_rom_patch.c +++ /dev/null @@ -1,621 +0,0 @@ -// Copyright 2015-2016 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 "esp32s2/rom/ets_sys.h" -#include "esp32s2/rom/gpio.h" -#include "esp32s2/rom/spi_flash.h" -#include "soc/spi_periph.h" - - -#define SPI_IDX 1 -#define OTH_IDX 0 - -extern esp_rom_spiflash_chip_t g_rom_spiflash_chip; - -esp_rom_spiflash_result_t esp_rom_spiflash_wait_idle(esp_rom_spiflash_chip_t *spi) -{ - uint32_t status; - while ((REG_READ(SPI_MEM_FSM_REG(1)) & SPI_MEM_ST)) { - } - while ((REG_READ(SPI_MEM_FSM_REG(0)) & SPI_MEM_ST)) { - } - //wait for flash status ready - if ( ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_read_status(spi, &status)) { - return ESP_ROM_SPIFLASH_RESULT_ERR; - } - return ESP_ROM_SPIFLASH_RESULT_OK; -} - - -/* Modified version of esp_rom_spiflash_unlock() that replaces version in ROM. - - This works around a bug where esp_rom_spiflash_unlock sometimes reads the wrong - high status byte (RDSR2 result) and then copies it back to the - flash status, which can cause the CMP bit or Status Register - Protect bit to become set. - - Like other ROM SPI functions, this function is not designed to be - called directly from an RTOS environment without taking precautions - about interrupts, CPU coordination, flash mapping. However some of - the functions in esp_spi_flash.c call it. - */ -esp_rom_spiflash_result_t esp_rom_spiflash_unlock(void) -{ - uint32_t status; - - esp_rom_spiflash_wait_idle(&g_rom_spiflash_chip); - - if (esp_rom_spiflash_read_statushigh(&g_rom_spiflash_chip, &status) != ESP_ROM_SPIFLASH_RESULT_OK) { - return ESP_ROM_SPIFLASH_RESULT_ERR; - } - - /* Clear all bits except QIE, if it is set. - (This is different from ROM esp_rom_spiflash_unlock, which keeps all bits as-is.) - */ - status &= ESP_ROM_SPIFLASH_QE; - - esp_rom_spiflash_wait_idle(&g_rom_spiflash_chip); - REG_WRITE(SPI_MEM_CMD_REG(SPI_IDX), SPI_MEM_FLASH_WREN); - while (REG_READ(SPI_MEM_CMD_REG(SPI_IDX)) != 0) { - } - esp_rom_spiflash_wait_idle(&g_rom_spiflash_chip); - SET_PERI_REG_MASK(SPI_MEM_CTRL_REG(SPI_IDX), SPI_MEM_WRSR_2B); - if (esp_rom_spiflash_write_status(&g_rom_spiflash_chip, status) != ESP_ROM_SPIFLASH_RESULT_OK) { - return ESP_ROM_SPIFLASH_RESULT_ERR; - } - - return ESP_ROM_SPIFLASH_RESULT_OK; -} - -#if CONFIG_SPI_FLASH_ROM_DRIVER_PATCH - -extern uint8_t g_rom_spiflash_dummy_len_plus[]; - -static esp_rom_spiflash_result_t esp_rom_spiflash_enable_write(esp_rom_spiflash_chip_t *spi); - -//only support spi1 -static esp_rom_spiflash_result_t esp_rom_spiflash_erase_chip_internal(esp_rom_spiflash_chip_t *spi) -{ - esp_rom_spiflash_wait_idle(spi); - - // Chip erase. - WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_CE); - while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0); - - // check erase is finished. - esp_rom_spiflash_wait_idle(spi); - - return ESP_ROM_SPIFLASH_RESULT_OK; -} - -//only support spi1 -static esp_rom_spiflash_result_t esp_rom_spiflash_erase_sector_internal(esp_rom_spiflash_chip_t *spi, uint32_t addr) -{ - //check if addr is 4k alignment - if (0 != (addr & 0xfff)) { - return ESP_ROM_SPIFLASH_RESULT_ERR; - } - - esp_rom_spiflash_wait_idle(spi); - - // sector erase 4Kbytes erase is sector erase. - WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, addr & 0xffffff); - WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_SE); - while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0); - - esp_rom_spiflash_wait_idle(spi); - - return ESP_ROM_SPIFLASH_RESULT_OK; -} - -//only support spi1 -static esp_rom_spiflash_result_t esp_rom_spiflash_erase_block_internal(esp_rom_spiflash_chip_t *spi, uint32_t addr) -{ - esp_rom_spiflash_wait_idle(spi); - - // sector erase 4Kbytes erase is sector erase. - WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, addr & 0xffffff); - WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_BE); - while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0); - - esp_rom_spiflash_wait_idle(spi); - - return ESP_ROM_SPIFLASH_RESULT_OK; -} - -//only support spi1 -static esp_rom_spiflash_result_t esp_rom_spiflash_program_page_internal(esp_rom_spiflash_chip_t *spi, uint32_t spi_addr, - uint32_t *addr_source, int32_t byte_length) -{ - uint32_t temp_addr; - int32_t temp_bl; - uint8_t i; - uint8_t remain_word_num; - - //check 4byte alignment - if (0 != (byte_length & 0x3)) { - return ESP_ROM_SPIFLASH_RESULT_ERR; - } - - //check if write in one page - if ((spi->page_size) < ((spi_addr % (spi->page_size)) + byte_length)) { - return ESP_ROM_SPIFLASH_RESULT_ERR; - } - - esp_rom_spiflash_wait_idle(spi); - - temp_addr = spi_addr; - temp_bl = byte_length; - - while (temp_bl > 0 ) { - if ( ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_enable_write(spi)) { - return ESP_ROM_SPIFLASH_RESULT_ERR; - } - if ( temp_bl >= ESP_ROM_SPIFLASH_BUFF_BYTE_WRITE_NUM ) { - WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, (temp_addr & 0xffffff) | ( ESP_ROM_SPIFLASH_BUFF_BYTE_WRITE_NUM << ESP_ROM_SPIFLASH_BYTES_LEN )); // 32 byte a block - - for (i = 0; i < (ESP_ROM_SPIFLASH_BUFF_BYTE_WRITE_NUM >> 2); i++) { - WRITE_PERI_REG(PERIPHS_SPI_FLASH_C0 + i * 4, *addr_source++); - } - temp_bl = temp_bl - 32; - temp_addr = temp_addr + 32; - } else { - WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, (temp_addr & 0xffffff) | (temp_bl << ESP_ROM_SPIFLASH_BYTES_LEN )); - - remain_word_num = (0 == (temp_bl & 0x3)) ? (temp_bl >> 2) : (temp_bl >> 2) + 1; - for (i = 0; i < remain_word_num; i++) { - WRITE_PERI_REG(PERIPHS_SPI_FLASH_C0 + i * 4, *addr_source++); - temp_bl = temp_bl - 4; - } - temp_bl = 0; - } - WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_PP); - while ( READ_PERI_REG(PERIPHS_SPI_FLASH_CMD ) != 0 ); - - esp_rom_spiflash_wait_idle(spi); - } - - return ESP_ROM_SPIFLASH_RESULT_OK; -} - -esp_rom_spiflash_result_t esp_rom_spiflash_read_status(esp_rom_spiflash_chip_t *spi, uint32_t *status) -{ - uint32_t status_value = ESP_ROM_SPIFLASH_BUSY_FLAG; - - if (g_rom_spiflash_dummy_len_plus[1] == 0) { - REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY); - while (ESP_ROM_SPIFLASH_BUSY_FLAG == (status_value & ESP_ROM_SPIFLASH_BUSY_FLAG)) { - WRITE_PERI_REG(PERIPHS_SPI_FLASH_STATUS, 0); // clear regisrter - WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_RDSR); - while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0); - - status_value = READ_PERI_REG(PERIPHS_SPI_FLASH_STATUS) & (spi->status_mask); - } - } else { - while (ESP_ROM_SPIFLASH_BUSY_FLAG == (status_value & ESP_ROM_SPIFLASH_BUSY_FLAG)) { - esp_rom_spiflash_read_user_cmd(&status_value, 0x05); - } - } - *status = status_value; - - return ESP_ROM_SPIFLASH_RESULT_OK; -} - -esp_rom_spiflash_result_t esp_rom_spiflash_read_statushigh(esp_rom_spiflash_chip_t *spi, uint32_t *status) -{ - esp_rom_spiflash_result_t ret; - esp_rom_spiflash_wait_idle(&g_rom_spiflash_chip); - ret = esp_rom_spiflash_read_user_cmd(status, 0x35); - *status = *status << 8; - return ret; -} - -esp_rom_spiflash_result_t esp_rom_spiflash_write_status(esp_rom_spiflash_chip_t *spi, uint32_t status_value) -{ - esp_rom_spiflash_wait_idle(spi); - - // update status value by status_value - WRITE_PERI_REG(PERIPHS_SPI_FLASH_STATUS, status_value); // write status regisrter - WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_WRSR); - while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0); - esp_rom_spiflash_wait_idle(spi); - - return ESP_ROM_SPIFLASH_RESULT_OK; -} - -//only support spi1 -static esp_rom_spiflash_result_t esp_rom_spiflash_read_data(esp_rom_spiflash_chip_t *spi, uint32_t flash_addr, - uint32_t *addr_dest, int32_t byte_length) -{ - uint32_t temp_addr; - int32_t temp_length; - uint8_t i; - uint8_t remain_word_num; - - //address range check - if ((flash_addr + byte_length) > (spi->chip_size)) { - return ESP_ROM_SPIFLASH_RESULT_ERR; - } - - temp_addr = flash_addr; - temp_length = byte_length; - - while (temp_length > 0) { - if (temp_length >= ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM) { - //WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, temp_addr |(ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM << ESP_ROM_SPIFLASH_BYTES_LEN)); - REG_WRITE(SPI_MEM_MISO_DLEN_REG(1), ((ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM << 3) - 1) << SPI_MEM_USR_MISO_DBITLEN_S); - WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, temp_addr); - REG_WRITE(PERIPHS_SPI_FLASH_CMD, SPI_MEM_USR); - while (REG_READ(PERIPHS_SPI_FLASH_CMD) != 0); - - for (i = 0; i < (ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM >> 2); i++) { - *addr_dest++ = READ_PERI_REG(PERIPHS_SPI_FLASH_C0 + i * 4); - } - temp_length = temp_length - ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM; - temp_addr = temp_addr + ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM; - } else { - //WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, temp_addr |(temp_length << ESP_ROM_SPIFLASH_BYTES_LEN )); - WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, temp_addr); - REG_WRITE(SPI_MEM_MISO_DLEN_REG(1), ((ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM << 3) - 1) << SPI_MEM_USR_MISO_DBITLEN_S); - REG_WRITE(PERIPHS_SPI_FLASH_CMD, SPI_MEM_USR); - while (REG_READ(PERIPHS_SPI_FLASH_CMD) != 0); - - remain_word_num = (0 == (temp_length & 0x3)) ? (temp_length >> 2) : (temp_length >> 2) + 1; - for (i = 0; i < remain_word_num; i++) { - *addr_dest++ = READ_PERI_REG(PERIPHS_SPI_FLASH_C0 + i * 4); - } - temp_length = 0; - } - } - - return ESP_ROM_SPIFLASH_RESULT_OK; -} - -static esp_rom_spiflash_result_t esp_rom_spiflash_enable_write(esp_rom_spiflash_chip_t *spi) -{ - uint32_t flash_status = 0; - - esp_rom_spiflash_wait_idle(spi); - - //enable write - WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_WREN); // enable write operation - while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0); - - // make sure the flash is ready for writing - while (ESP_ROM_SPIFLASH_WRENABLE_FLAG != (flash_status & ESP_ROM_SPIFLASH_WRENABLE_FLAG)) { - esp_rom_spiflash_read_status(spi, &flash_status); - } - - return ESP_ROM_SPIFLASH_RESULT_OK; -} - -static void spi_cache_mode_switch(uint32_t modebit) -{ - if ((modebit & SPI_MEM_FREAD_QIO) && (modebit & SPI_MEM_FASTRD_MODE)) { - REG_CLR_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_MOSI); - REG_SET_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_MISO | SPI_MEM_USR_DUMMY | SPI_MEM_USR_ADDR); - REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_ADDR_BITLEN, SPI0_R_QIO_ADDR_BITSLEN); - REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN, SPI0_R_QIO_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[0]); - REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_VALUE, 0xEB); - } else if (modebit & SPI_MEM_FASTRD_MODE) { - REG_CLR_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_MOSI); - REG_SET_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_MISO | SPI_MEM_USR_DUMMY | SPI_MEM_USR_ADDR); - REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_ADDR_BITLEN, SPI0_R_FAST_ADDR_BITSLEN); - if ((modebit & SPI_MEM_FREAD_QUAD)) { - REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_VALUE, 0x6B); - REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN, SPI0_R_FAST_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[0]); - } else if ((modebit & SPI_MEM_FREAD_DIO)) { - REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN, SPI0_R_DIO_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[0]); - REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_VALUE, 0xBB); - } else if ((modebit & SPI_MEM_FREAD_DUAL)) { - REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN, SPI0_R_FAST_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[0]); - REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_VALUE, 0x3B); - } else { - REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN, SPI0_R_FAST_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[0]); - REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_VALUE, 0x0B); - } - } else { - REG_CLR_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_MOSI); - if (g_rom_spiflash_dummy_len_plus[0] == 0) { - REG_CLR_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_DUMMY); - } else { - REG_SET_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_DUMMY); - REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN, g_rom_spiflash_dummy_len_plus[0] - 1); - } - REG_SET_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_MISO | SPI_MEM_USR_ADDR); - REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_ADDR_BITLEN, SPI0_R_SIO_ADDR_BITSLEN); - REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_VALUE, 0x03); - } -} - -esp_rom_spiflash_result_t esp_rom_spiflash_lock(void) -{ - uint32_t status; - - //read QE bit, not write if not QE - if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_read_statushigh(&g_rom_spiflash_chip, &status)) { - return ESP_ROM_SPIFLASH_RESULT_ERR; - } - //enable 2 byte status writing - SET_PERI_REG_MASK(PERIPHS_SPI_FLASH_CTRL, ESP_ROM_SPIFLASH_TWO_BYTE_STATUS_EN); - - if ( ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_enable_write(&g_rom_spiflash_chip)) { - return ESP_ROM_SPIFLASH_RESULT_ERR; - } - - if ( ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_write_status(&g_rom_spiflash_chip, status | ESP_ROM_SPIFLASH_WR_PROTECT)) { - return ESP_ROM_SPIFLASH_RESULT_ERR; - } - - return ESP_ROM_SPIFLASH_RESULT_OK; -} - - -esp_rom_spiflash_result_t esp_rom_spiflash_config_readmode(esp_rom_spiflash_read_mode_t mode) -{ - uint32_t modebit; - while ((REG_READ(SPI_MEM_FSM_REG(1)) & SPI_MEM_ST)) { - } - while ((REG_READ(SPI_MEM_FSM_REG(0)) & SPI_MEM_ST)) { - } - //clear old mode bit - CLEAR_PERI_REG_MASK(PERIPHS_SPI_FLASH_CTRL, SPI_MEM_FREAD_QIO | SPI_MEM_FREAD_QUAD | SPI_MEM_FREAD_DIO | SPI_MEM_FREAD_DUAL | SPI_MEM_FASTRD_MODE); - CLEAR_PERI_REG_MASK(SPI_MEM_CTRL_REG(0), SPI_MEM_FREAD_QIO | SPI_MEM_FREAD_QUAD | SPI_MEM_FREAD_DIO | SPI_MEM_FREAD_DUAL | SPI_MEM_FASTRD_MODE); - //configure read mode - switch (mode) { - case ESP_ROM_SPIFLASH_QIO_MODE : modebit = SPI_MEM_FREAD_QIO | SPI_MEM_FASTRD_MODE; break; - case ESP_ROM_SPIFLASH_QOUT_MODE : modebit = SPI_MEM_FREAD_QUAD | SPI_MEM_FASTRD_MODE; break; - case ESP_ROM_SPIFLASH_DIO_MODE : modebit = SPI_MEM_FREAD_DIO | SPI_MEM_FASTRD_MODE; break; - case ESP_ROM_SPIFLASH_DOUT_MODE : modebit = SPI_MEM_FREAD_DUAL | SPI_MEM_FASTRD_MODE; break; - case ESP_ROM_SPIFLASH_FASTRD_MODE: modebit = SPI_MEM_FASTRD_MODE; break; - case ESP_ROM_SPIFLASH_SLOWRD_MODE: modebit = 0; break; - default : modebit = 0; - } - - SET_PERI_REG_MASK(PERIPHS_SPI_FLASH_CTRL, modebit); - SET_PERI_REG_MASK(SPI_MEM_CTRL_REG(0), modebit); - spi_cache_mode_switch(modebit); - - return ESP_ROM_SPIFLASH_RESULT_OK; -} - -esp_rom_spiflash_result_t esp_rom_spiflash_erase_chip(void) -{ - if ( ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_enable_write(&g_rom_spiflash_chip)) { - return ESP_ROM_SPIFLASH_RESULT_ERR; - } - - if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_erase_chip_internal(&g_rom_spiflash_chip)) { - return ESP_ROM_SPIFLASH_RESULT_ERR; - } - - return ESP_ROM_SPIFLASH_RESULT_OK; -} - -esp_rom_spiflash_result_t esp_rom_spiflash_erase_block(uint32_t block_num) -{ - // flash write is always 1 line currently - REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY); - REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, ESP_ROM_SPIFLASH_W_SIO_ADDR_BITSLEN); - //check program size - if (block_num >= ((g_rom_spiflash_chip.chip_size) / (g_rom_spiflash_chip.block_size))) { - return ESP_ROM_SPIFLASH_RESULT_ERR; - } - - if ( ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_enable_write(&g_rom_spiflash_chip)) { - return ESP_ROM_SPIFLASH_RESULT_ERR; - } - - if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_erase_block_internal(&g_rom_spiflash_chip, block_num * (g_rom_spiflash_chip.block_size))) { - return ESP_ROM_SPIFLASH_RESULT_ERR; - } - return ESP_ROM_SPIFLASH_RESULT_OK; -} - -esp_rom_spiflash_result_t esp_rom_spiflash_erase_sector(uint32_t sector_num) -{ - // flash write is always 1 line currently - REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY); - REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, ESP_ROM_SPIFLASH_W_SIO_ADDR_BITSLEN); - //check program size - if (sector_num >= ((g_rom_spiflash_chip.chip_size) / (g_rom_spiflash_chip.sector_size))) { - return ESP_ROM_SPIFLASH_RESULT_ERR; - } - - if ( ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_enable_write(&g_rom_spiflash_chip)) { - return ESP_ROM_SPIFLASH_RESULT_ERR; - } - - if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_erase_sector_internal(&g_rom_spiflash_chip, sector_num * (g_rom_spiflash_chip.sector_size))) { - return ESP_ROM_SPIFLASH_RESULT_ERR; - } - - return ESP_ROM_SPIFLASH_RESULT_OK; -} - -esp_rom_spiflash_result_t esp_rom_spiflash_write(uint32_t target, const uint32_t *src_addr, int32_t len) -{ - uint32_t page_size; - uint32_t pgm_len, pgm_num; - uint8_t i; - - // flash write is always 1 line currently - REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY); - REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, ESP_ROM_SPIFLASH_W_SIO_ADDR_BITSLEN); - //check program size - if ( (target + len) > (g_rom_spiflash_chip.chip_size)) { - return ESP_ROM_SPIFLASH_RESULT_ERR; - } - - page_size = g_rom_spiflash_chip.page_size; - pgm_len = page_size - (target % page_size); - if (len < pgm_len) { - if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_program_page_internal(&g_rom_spiflash_chip, - target, (uint32_t *)src_addr, len)) { - return ESP_ROM_SPIFLASH_RESULT_ERR; - } - } else { - if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_program_page_internal(&g_rom_spiflash_chip, - target, (uint32_t *)src_addr, pgm_len)) { - return ESP_ROM_SPIFLASH_RESULT_ERR; - } - - //whole page program - pgm_num = (len - pgm_len) / page_size; - for (i = 0; i < pgm_num; i++) { - if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_program_page_internal(&g_rom_spiflash_chip, - target + pgm_len, (uint32_t *)src_addr + (pgm_len >> 2), page_size)) { - return ESP_ROM_SPIFLASH_RESULT_ERR; - } - pgm_len += page_size; - } - - //remain parts to program - if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_program_page_internal(&g_rom_spiflash_chip, - target + pgm_len, (uint32_t *)src_addr + (pgm_len >> 2), len - pgm_len)) { - return ESP_ROM_SPIFLASH_RESULT_ERR; - } - } - return ESP_ROM_SPIFLASH_RESULT_OK; -} - -esp_rom_spiflash_result_t esp_rom_spiflash_read(uint32_t target, uint32_t *dest_addr, int32_t len) -{ - // QIO or SIO, non-QIO regard as SIO - uint32_t modebit; - esp_rom_spiflash_wait_idle(&g_rom_spiflash_chip); - modebit = READ_PERI_REG(PERIPHS_SPI_FLASH_CTRL); - if ((modebit & SPI_MEM_FREAD_QIO) && (modebit & SPI_MEM_FASTRD_MODE)) { - REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_MOSI); - REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_MISO | SPI_MEM_USR_DUMMY | SPI_MEM_USR_ADDR); - REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, SPI1_R_QIO_ADDR_BITSLEN); - REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_DUMMY_CYCLELEN, SPI1_R_QIO_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[1]); - //REG_SET_FIELD(PERIPHS_SPI_SPI_MEM_H_USRREG2, SPI_USR_COMMAND_VALUE, 0xEB); - REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_MEM_USR_COMMAND_BITLEN_S) | 0xEB); - } else if (modebit & SPI_MEM_FASTRD_MODE) { - REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_MOSI); - REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_MISO | SPI_MEM_USR_ADDR); - if (modebit & SPI_MEM_FREAD_DIO) { - if (g_rom_spiflash_dummy_len_plus[1] == 0) { - REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY); - REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, SPI1_R_DIO_ADDR_BITSLEN); - REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_MEM_USR_COMMAND_BITLEN_S) | 0xBB); - } else { - REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY); - REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, SPI1_R_DIO_ADDR_BITSLEN); - REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_DUMMY_CYCLELEN, g_rom_spiflash_dummy_len_plus[1] - 1); - REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG2, SPI_MEM_USR_COMMAND_VALUE, 0xBB); - } - } else { - if ((modebit & SPI_MEM_FREAD_QUAD)) { - REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_MEM_USR_COMMAND_BITLEN_S) | 0x6B); - } else if ((modebit & SPI_MEM_FREAD_DUAL)) { - REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_MEM_USR_COMMAND_BITLEN_S) | 0x3B); - } else { - REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_MEM_USR_COMMAND_BITLEN_S) | 0x0B); - } - REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY); - REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, SPI1_R_FAST_ADDR_BITSLEN); - REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_DUMMY_CYCLELEN, SPI1_R_FAST_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[1]); - } - } else { - REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_MOSI); - if (g_rom_spiflash_dummy_len_plus[1] == 0) { - REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY); - } else { - REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY); - REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_DUMMY_CYCLELEN, g_rom_spiflash_dummy_len_plus[1] - 1); - } - REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_MISO | SPI_MEM_USR_ADDR); - REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, SPI1_R_SIO_ADDR_BITSLEN); - REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_MEM_USR_COMMAND_BITLEN_S) | 0x03); - } - - if ( ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_read_data(&g_rom_spiflash_chip, target, dest_addr, len)) { - return ESP_ROM_SPIFLASH_RESULT_ERR; - } - return ESP_ROM_SPIFLASH_RESULT_OK; -} - -esp_rom_spiflash_result_t esp_rom_spiflash_erase_area(uint32_t start_addr, uint32_t area_len) -{ - int32_t total_sector_num; - int32_t head_sector_num; - uint32_t sector_no; - uint32_t sector_num_per_block; - - //set read mode to Fastmode ,not QDIO mode for erase - // - // TODO: this is probably a bug as it doesn't re-enable QIO mode, not serious as this - // function is not used in IDF. - esp_rom_spiflash_config_readmode(ESP_ROM_SPIFLASH_SLOWRD_MODE); - - //check if area is oversize of flash - if ((start_addr + area_len) > g_rom_spiflash_chip.chip_size) { - return ESP_ROM_SPIFLASH_RESULT_ERR; - } - - //start_addr is aligned as sector boundary - if (0 != (start_addr % g_rom_spiflash_chip.sector_size)) { - return ESP_ROM_SPIFLASH_RESULT_ERR; - } - - //Unlock flash to enable erase - if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_unlock(/*&g_rom_spiflash_chip*/)) { - return ESP_ROM_SPIFLASH_RESULT_ERR; - } - - sector_no = start_addr / g_rom_spiflash_chip.sector_size; - sector_num_per_block = g_rom_spiflash_chip.block_size / g_rom_spiflash_chip.sector_size; - total_sector_num = (0 == (area_len % g_rom_spiflash_chip.sector_size)) ? area_len / g_rom_spiflash_chip.sector_size : - 1 + (area_len / g_rom_spiflash_chip.sector_size); - - //check if erase area reach over block boundary - head_sector_num = sector_num_per_block - (sector_no % sector_num_per_block); - - head_sector_num = (head_sector_num >= total_sector_num) ? total_sector_num : head_sector_num; - - //JJJ, BUG of 6.0 erase - //middle part of area is aligned by blocks - total_sector_num -= head_sector_num; - - //head part of area is erased - while (0 != head_sector_num) { - if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_erase_sector(sector_no)) { - return ESP_ROM_SPIFLASH_RESULT_ERR; - } - sector_no++; - head_sector_num--; - } - while (total_sector_num > sector_num_per_block) { - if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_erase_block(sector_no / sector_num_per_block)) { - return ESP_ROM_SPIFLASH_RESULT_ERR; - } - sector_no += sector_num_per_block; - total_sector_num -= sector_num_per_block; - } - - //tail part of area burn - while (0 < total_sector_num) { - if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_erase_sector(sector_no)) { - return ESP_ROM_SPIFLASH_RESULT_ERR; - } - sector_no++; - total_sector_num--; - } - - return ESP_ROM_SPIFLASH_RESULT_OK; -} - -#endif