From 5e55ffc95a5547202c239389249ef848c38460c6 Mon Sep 17 00:00:00 2001 From: wanglei Date: Tue, 5 Nov 2019 13:10:03 +0800 Subject: [PATCH] fix dummy issue in spi mem and make some spiflash api called from idf --- .../ld/esp32s2beta.rom.spiflash.ld | 2 - components/spi_flash/CMakeLists.txt | 9 +- components/spi_flash/component.mk | 2 +- .../{ => esp32}/spi_flash_rom_patch.c | 288 ++------ .../esp32s2beta/spi_flash_rom_patch.c | 621 ++++++++++++++++++ 5 files changed, 679 insertions(+), 243 deletions(-) rename components/spi_flash/{ => esp32}/spi_flash_rom_patch.c (72%) create mode 100644 components/spi_flash/esp32s2beta/spi_flash_rom_patch.c diff --git a/components/esp_rom/esp32s2beta/ld/esp32s2beta.rom.spiflash.ld b/components/esp_rom/esp32s2beta/ld/esp32s2beta.rom.spiflash.ld index 71195da2b..bf486f979 100644 --- a/components/esp_rom/esp32s2beta/ld/esp32s2beta.rom.spiflash.ld +++ b/components/esp_rom/esp32s2beta/ld/esp32s2beta.rom.spiflash.ld @@ -12,8 +12,6 @@ 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 a3525021f..69c140a51 100644 --- a/components/spi_flash/CMakeLists.txt +++ b/components/spi_flash/CMakeLists.txt @@ -3,7 +3,9 @@ if(BOOTLOADER_BUILD) if (CONFIG_IDF_TARGET_ESP32) # ESP32 Bootloader needs SPIUnlock from this file, but doesn't # need other parts of this component - set(srcs "spi_flash_rom_patch.c") + set(srcs "esp32/spi_flash_rom_patch.c") + elseif (CONFIG_IDF_TARGET_ESP32S2BETA) + set(srcs "esp32s2beta/spi_flash_rom_patch.c") else() # but on other platforms no source files are needed for bootloader set(srcs) @@ -20,7 +22,10 @@ else() if (CONFIG_IDF_TARGET_ESP32) list(APPEND srcs - "spi_flash_rom_patch.c") + "esp32/spi_flash_rom_patch.c") + elseif (CONFIG_IDF_TARGET_ESP32S2BETA) + list(APPEND srcs + "esp32s2beta/spi_flash_rom_patch.c") endif() # New implementation after IDF v4.0 diff --git a/components/spi_flash/component.mk b/components/spi_flash/component.mk index 74bcce42c..e0b7b5590 100644 --- a/components/spi_flash/component.mk +++ b/components/spi_flash/component.mk @@ -7,5 +7,5 @@ COMPONENT_ADD_LDFRAGMENTS += linker.lf ifdef IS_BOOTLOADER_BUILD # Bootloader needs updated SPIUnlock from this file -COMPONENT_OBJS := spi_flash_rom_patch.o +COMPONENT_OBJS := esp32/spi_flash_rom_patch.o endif diff --git a/components/spi_flash/spi_flash_rom_patch.c b/components/spi_flash/esp32/spi_flash_rom_patch.c similarity index 72% rename from components/spi_flash/spi_flash_rom_patch.c rename to components/spi_flash/esp32/spi_flash_rom_patch.c index efbe883ea..125c2dfa5 100644 --- a/components/spi_flash/spi_flash_rom_patch.c +++ b/components/spi_flash/esp32/spi_flash_rom_patch.c @@ -12,15 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. #include "sdkconfig.h" -#if CONFIG_IDF_TARGET_ESP32 #include "esp32/rom/ets_sys.h" #include "esp32/rom/gpio.h" #include "esp32/rom/spi_flash.h" -#elif CONFIG_IDF_TARGET_ESP32S2BETA -#include "esp32s2beta/rom/ets_sys.h" -#include "esp32s2beta/rom/gpio.h" -#include "esp32s2beta/rom/spi_flash.h" -#endif #include "soc/spi_periph.h" @@ -80,21 +74,11 @@ esp_rom_spiflash_result_t esp_rom_spiflash_unlock(void) status &= ESP_ROM_SPIFLASH_QE; esp_rom_spiflash_wait_idle(&g_rom_spiflash_chip); -#if CONFIG_IDF_TARGET_ESP32 REG_WRITE(SPI_CMD_REG(SPI_IDX), SPI_FLASH_WREN); while (REG_READ(SPI_CMD_REG(SPI_IDX)) != 0) { } -#elif CONFIG_IDF_TARGET_ESP32S2BETA - REG_WRITE(SPI_MEM_CMD_REG(SPI_IDX), SPI_MEM_FLASH_WREN); - while (REG_READ(SPI_MEM_CMD_REG(SPI_IDX)) != 0) { - } -#endif esp_rom_spiflash_wait_idle(&g_rom_spiflash_chip); -#if CONFIG_IDF_TARGET_ESP32 SET_PERI_REG_MASK(SPI_CTRL_REG(SPI_IDX), SPI_WRSR_2B); -#elif CONFIG_IDF_TARGET_ESP32S2BETA - SET_PERI_REG_MASK(SPI_MEM_CTRL_REG(SPI_IDX), SPI_MEM_WRSR_2B); -#endif if (esp_rom_spiflash_write_status(&g_rom_spiflash_chip, status) != ESP_ROM_SPIFLASH_RESULT_OK) { return ESP_ROM_SPIFLASH_RESULT_ERR; } @@ -102,7 +86,6 @@ esp_rom_spiflash_result_t esp_rom_spiflash_unlock(void) return ESP_ROM_SPIFLASH_RESULT_OK; } - #if CONFIG_SPI_FLASH_ROM_DRIVER_PATCH extern uint8_t g_rom_spiflash_dummy_len_plus[]; @@ -116,11 +99,7 @@ static esp_rom_spiflash_result_t esp_rom_spiflash_erase_chip_internal(esp_rom_sp esp_rom_spiflash_wait_idle(spi); // Chip erase. -#if CONFIG_IDF_TARGET_ESP32 WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_FLASH_CE); -#elif CONFIG_IDF_TARGET_ESP32S2BETA - WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_CE); -#endif while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0); // check erase is finished. @@ -141,11 +120,7 @@ static esp_rom_spiflash_result_t esp_rom_spiflash_erase_sector_internal(esp_rom_ // sector erase 4Kbytes erase is sector erase. WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, addr & 0xffffff); -#if CONFIG_IDF_TARGET_ESP32 WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_FLASH_SE); -#elif CONFIG_IDF_TARGET_ESP32S2BETA - WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_SE); -#endif while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0); esp_rom_spiflash_wait_idle(spi); @@ -160,11 +135,7 @@ static esp_rom_spiflash_result_t esp_rom_spiflash_erase_block_internal(esp_rom_s // sector erase 4Kbytes erase is sector erase. WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, addr & 0xffffff); -#if CONFIG_IDF_TARGET_ESP32 WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_FLASH_BE); -#elif CONFIG_IDF_TARGET_ESP32S2BETA - WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_BE); -#endif while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0); esp_rom_spiflash_wait_idle(spi); @@ -218,11 +189,7 @@ static esp_rom_spiflash_result_t esp_rom_spiflash_program_page_internal(esp_rom_ } temp_bl = 0; } -#if CONFIG_IDF_TARGET_ESP32 WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_FLASH_PP); -#elif CONFIG_IDF_TARGET_ESP32S2BETA - WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_PP); -#endif while ( READ_PERI_REG(PERIPHS_SPI_FLASH_CMD ) != 0 ); esp_rom_spiflash_wait_idle(spi); @@ -231,67 +198,6 @@ static esp_rom_spiflash_result_t esp_rom_spiflash_program_page_internal(esp_rom_ 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; - - esp_rom_spiflash_wait_idle(spi); - - 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)); -#if CONFIG_IDF_TARGET_ESP32 - REG_WRITE(SPI_MISO_DLEN_REG(1), ((ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM << 3) - 1) << SPI_USR_MISO_DBITLEN_S); - WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, temp_addr << 8); - REG_WRITE(PERIPHS_SPI_FLASH_CMD, SPI_USR); -#elif CONFIG_IDF_TARGET_ESP32S2BETA - 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 << 8); - REG_WRITE(PERIPHS_SPI_FLASH_CMD, SPI_MEM_USR); -#endif - 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 << 8); -#if CONFIG_IDF_TARGET_ESP32 - REG_WRITE(SPI_MISO_DLEN_REG(1), ((ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM << 3) - 1) << SPI_USR_MISO_DBITLEN_S); - REG_WRITE(PERIPHS_SPI_FLASH_CMD, SPI_USR); -#elif CONFIG_IDF_TARGET_ESP32S2BETA - 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); -#endif - 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; -} - 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; @@ -299,11 +205,7 @@ esp_rom_spiflash_result_t esp_rom_spiflash_read_status(esp_rom_spiflash_chip_t * if (g_rom_spiflash_dummy_len_plus[1] == 0) { while (ESP_ROM_SPIFLASH_BUSY_FLAG == (status_value & ESP_ROM_SPIFLASH_BUSY_FLAG)) { WRITE_PERI_REG(PERIPHS_SPI_FLASH_STATUS, 0); // clear regisrter -#if CONFIG_IDF_TARGET_ESP32 WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_FLASH_RDSR); -#elif CONFIG_IDF_TARGET_ESP32S2BETA - WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_RDSR); -#endif while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0); status_value = READ_PERI_REG(PERIPHS_SPI_FLASH_STATUS) & (spi->status_mask); @@ -333,17 +235,63 @@ esp_rom_spiflash_result_t esp_rom_spiflash_write_status(esp_rom_spiflash_chip_t // update status value by status_value WRITE_PERI_REG(PERIPHS_SPI_FLASH_STATUS, status_value); // write status regisrter -#if CONFIG_IDF_TARGET_ESP32 WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_FLASH_WRSR); -#elif CONFIG_IDF_TARGET_ESP32S2BETA - WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_WRSR); -#endif 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; + + esp_rom_spiflash_wait_idle(spi); + + 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_MISO_DLEN_REG(1), ((ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM << 3) - 1) << SPI_USR_MISO_DBITLEN_S); + WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, temp_addr << 8); + REG_WRITE(PERIPHS_SPI_FLASH_CMD, SPI_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 << 8); + REG_WRITE(SPI_MISO_DLEN_REG(1), ((ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM << 3) - 1) << SPI_USR_MISO_DBITLEN_S); + REG_WRITE(PERIPHS_SPI_FLASH_CMD, SPI_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; @@ -351,11 +299,7 @@ static esp_rom_spiflash_result_t esp_rom_spiflash_enable_write(esp_rom_spiflash_ esp_rom_spiflash_wait_idle(spi); //enable write -#if CONFIG_IDF_TARGET_ESP32 WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_FLASH_WREN); // enable write operation -#elif CONFIG_IDF_TARGET_ESP32S2BETA - WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_WREN); // enable write operation -#endif while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0); // make sure the flash is ready for writing @@ -368,7 +312,6 @@ static esp_rom_spiflash_result_t esp_rom_spiflash_enable_write(esp_rom_spiflash_ static void spi_cache_mode_switch(uint32_t modebit) { -#if CONFIG_IDF_TARGET_ESP32 if ((modebit & SPI_FREAD_QIO) && (modebit & SPI_FASTRD_MODE)) { REG_CLR_BIT(SPI_USER_REG(0), SPI_USR_MOSI); REG_SET_BIT(SPI_USER_REG(0), SPI_USR_MISO | SPI_USR_DUMMY | SPI_USR_ADDR); @@ -405,43 +348,6 @@ static void spi_cache_mode_switch(uint32_t modebit) REG_SET_FIELD(SPI_USER1_REG(0), SPI_USR_ADDR_BITLEN, SPI0_R_SIO_ADDR_BITSLEN); REG_SET_FIELD(SPI_USER2_REG(0), SPI_USR_COMMAND_VALUE, 0x03); } -#elif CONFIG_IDF_TARGET_ESP32S2BETA - 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); - } -#endif } esp_rom_spiflash_result_t esp_rom_spiflash_lock(void) @@ -470,50 +376,26 @@ esp_rom_spiflash_result_t esp_rom_spiflash_lock(void) esp_rom_spiflash_result_t esp_rom_spiflash_config_readmode(esp_rom_spiflash_read_mode_t mode) { uint32_t modebit; -#if CONFIG_IDF_TARGET_ESP32 while ((REG_READ(SPI_EXT2_REG(1)) & SPI_ST)) { } while ((REG_READ(SPI_EXT2_REG(0)) & SPI_ST)) { } -#elif CONFIG_IDF_TARGET_ESP32S2BETA - while ((REG_READ(SPI_MEM_FSM_REG(1)) & SPI_MEM_ST)) { - } - while ((REG_READ(SPI_MEM_FSM_REG(0)) & SPI_MEM_ST)) { - } -#endif //clear old mode bit -#if CONFIG_IDF_TARGET_ESP32 CLEAR_PERI_REG_MASK(PERIPHS_SPI_FLASH_CTRL, SPI_FREAD_QIO | SPI_FREAD_QUAD | SPI_FREAD_DIO | SPI_FREAD_DUAL | SPI_FASTRD_MODE); CLEAR_PERI_REG_MASK(SPI_CTRL_REG(0), SPI_FREAD_QIO | SPI_FREAD_QUAD | SPI_FREAD_DIO | SPI_FREAD_DUAL | SPI_FASTRD_MODE); -#elif CONFIG_IDF_TARGET_ESP32S2BETA - 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); -#endif //configure read mode switch (mode) { -#if CONFIG_IDF_TARGET_ESP32 case ESP_ROM_SPIFLASH_QIO_MODE : modebit = SPI_FREAD_QIO | SPI_FASTRD_MODE; break; case ESP_ROM_SPIFLASH_QOUT_MODE : modebit = SPI_FREAD_QUAD | SPI_FASTRD_MODE; break; case ESP_ROM_SPIFLASH_DIO_MODE : modebit = SPI_FREAD_DIO | SPI_FASTRD_MODE; break; case ESP_ROM_SPIFLASH_DOUT_MODE : modebit = SPI_FREAD_DUAL | SPI_FASTRD_MODE; break; case ESP_ROM_SPIFLASH_FASTRD_MODE: modebit = SPI_FASTRD_MODE; break; -#elif CONFIG_IDF_TARGET_ESP32S2BETA - 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; -#endif case ESP_ROM_SPIFLASH_SLOWRD_MODE: modebit = 0; break; default : modebit = 0; } SET_PERI_REG_MASK(PERIPHS_SPI_FLASH_CTRL, modebit); -#if CONFIG_IDF_TARGET_ESP32 SET_PERI_REG_MASK(SPI_CTRL_REG(0), modebit); -#elif CONFIG_IDF_TARGET_ESP32S2BETA - SET_PERI_REG_MASK(SPI_MEM_CTRL_REG(0), modebit); -#endif spi_cache_mode_switch(modebit); return ESP_ROM_SPIFLASH_RESULT_OK; @@ -535,13 +417,8 @@ esp_rom_spiflash_result_t esp_rom_spiflash_erase_chip(void) esp_rom_spiflash_result_t esp_rom_spiflash_erase_block(uint32_t block_num) { // flash write is always 1 line currently -#if CONFIG_IDF_TARGET_ESP32 REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_DUMMY); REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_USR_ADDR_BITLEN, ESP_ROM_SPIFLASH_W_SIO_ADDR_BITSLEN); -#elif CONFIG_IDF_TARGET_ESP32S2BETA - 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); -#endif //check program size if (block_num >= ((g_rom_spiflash_chip.chip_size) / (g_rom_spiflash_chip.block_size))) { return ESP_ROM_SPIFLASH_RESULT_ERR; @@ -560,13 +437,8 @@ esp_rom_spiflash_result_t esp_rom_spiflash_erase_block(uint32_t block_num) esp_rom_spiflash_result_t esp_rom_spiflash_erase_sector(uint32_t sector_num) { // flash write is always 1 line currently -#if CONFIG_IDF_TARGET_ESP32 REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_DUMMY); REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_USR_ADDR_BITLEN, ESP_ROM_SPIFLASH_W_SIO_ADDR_BITSLEN); -#elif CONFIG_IDF_TARGET_ESP32S2BETA - 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); -#endif //check program size if (sector_num >= ((g_rom_spiflash_chip.chip_size) / (g_rom_spiflash_chip.sector_size))) { return ESP_ROM_SPIFLASH_RESULT_ERR; @@ -590,13 +462,8 @@ esp_rom_spiflash_result_t esp_rom_spiflash_write(uint32_t target, const uint32_t uint8_t i; // flash write is always 1 line currently -#if CONFIG_IDF_TARGET_ESP32 REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_DUMMY); REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_USR_ADDR_BITLEN, ESP_ROM_SPIFLASH_W_SIO_ADDR_BITSLEN); -#elif CONFIG_IDF_TARGET_ESP32S2BETA - 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); -#endif //check program size if ( (target + len) > (g_rom_spiflash_chip.chip_size)) { return ESP_ROM_SPIFLASH_RESULT_ERR; @@ -634,7 +501,6 @@ esp_rom_spiflash_result_t esp_rom_spiflash_write(uint32_t target, const uint32_t return ESP_ROM_SPIFLASH_RESULT_OK; } -#if CONFIG_IDF_TARGET_ESP32 esp_rom_spiflash_result_t esp_rom_spiflash_write_encrypted(uint32_t flash_addr, uint32_t *data, uint32_t len) { esp_rom_spiflash_result_t ret = ESP_ROM_SPIFLASH_RESULT_OK; @@ -660,14 +526,12 @@ esp_rom_spiflash_result_t esp_rom_spiflash_write_encrypted(uint32_t flash_addr, return ret; } -#endif 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; modebit = READ_PERI_REG(PERIPHS_SPI_FLASH_CTRL); -#if CONFIG_IDF_TARGET_ESP32 if ((modebit & SPI_FREAD_QIO) && (modebit & SPI_FASTRD_MODE)) { REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_MOSI); REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_MISO | SPI_USR_DUMMY | SPI_USR_ADDR); @@ -679,44 +543,17 @@ esp_rom_spiflash_result_t esp_rom_spiflash_read(uint32_t target, uint32_t *dest_ REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_MOSI); REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_MISO | SPI_USR_ADDR); if (modebit & SPI_FREAD_DIO) { -#elif CONFIG_IDF_TARGET_ESP32S2BETA - 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) { -#endif if (g_rom_spiflash_dummy_len_plus[1] == 0) { -#if CONFIG_IDF_TARGET_ESP32 REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_DUMMY); REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_USR_ADDR_BITLEN, SPI1_R_DIO_ADDR_BITSLEN); REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_USR_COMMAND_BITLEN_S) | 0xBB); -#elif CONFIG_IDF_TARGET_ESP32S2BETA - 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); -#endif } else { -#if CONFIG_IDF_TARGET_ESP32 REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_DUMMY); REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_USR_ADDR_BITLEN, SPI1_R_DIO_ADDR_BITSLEN); REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_USR_DUMMY_CYCLELEN, g_rom_spiflash_dummy_len_plus[1] - 1); REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG2, SPI_USR_COMMAND_VALUE, 0xBB); -#elif CONFIG_IDF_TARGET_ESP32S2BETA - 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); -#endif } } else { -#if CONFIG_IDF_TARGET_ESP32 if ((modebit & SPI_FREAD_QUAD)) { //REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG2, SPI_USR_COMMAND_VALUE, 0x6B); REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_USR_COMMAND_BITLEN_S) | 0x6B); @@ -730,21 +567,8 @@ esp_rom_spiflash_result_t esp_rom_spiflash_read(uint32_t target, uint32_t *dest_ REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_DUMMY); REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_USR_ADDR_BITLEN, SPI1_R_FAST_ADDR_BITSLEN); REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_USR_DUMMY_CYCLELEN, SPI1_R_FAST_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[1]); -#elif CONFIG_IDF_TARGET_ESP32S2BETA - 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]); -#endif } } else { -#if CONFIG_IDF_TARGET_ESP32 REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_MOSI); if (g_rom_spiflash_dummy_len_plus[1] == 0) { REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_DUMMY); @@ -756,18 +580,6 @@ esp_rom_spiflash_result_t esp_rom_spiflash_read(uint32_t target, uint32_t *dest_ REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_USR_ADDR_BITLEN, SPI1_R_SIO_ADDR_BITSLEN); //REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG2, SPI_USR_COMMAND_VALUE, 0x03); REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_USR_COMMAND_BITLEN_S) | 0x03); -#elif CONFIG_IDF_TARGET_ESP32S2BETA - 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); -#endif } if ( ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_read_data(&g_rom_spiflash_chip, target, dest_addr, len)) { diff --git a/components/spi_flash/esp32s2beta/spi_flash_rom_patch.c b/components/spi_flash/esp32s2beta/spi_flash_rom_patch.c new file mode 100644 index 000000000..e6656e2fb --- /dev/null +++ b/components/spi_flash/esp32s2beta/spi_flash_rom_patch.c @@ -0,0 +1,621 @@ +// 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 "esp32s2beta/rom/ets_sys.h" +#include "esp32s2beta/rom/gpio.h" +#include "esp32s2beta/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) { + 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); + REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY); + 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 << 8); + 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 << 8); + 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