]> granicus.if.org Git - esp-idf/commitdiff
spi_flash: Fixed bug in SPI flash ROM driver to work with embedded flash chip
authorAlexey Gerenkov <alexey@espressif.com>
Thu, 9 Mar 2017 07:29:00 +0000 (10:29 +0300)
committerIvan Grokhotkov <ivan@espressif.com>
Tue, 11 Apr 2017 02:51:19 +0000 (10:51 +0800)
1) fixed SPI_read_status: added check for flash busy flag in matrix mode
2) fixed SPI_page_program: enable write before writing data to SPI FIFO
3) SPI flash ROM funcs replacement is controlled via menuconfig option

15 files changed:
components/bootloader/src/main/bootloader_start.c
components/bootloader/src/main/component.mk
components/bootloader/src/main/flash_qio_mode.c
components/bootloader_support/src/bootloader_flash.c
components/esp32/component.mk
components/esp32/include/rom/spi_flash.h
components/esp32/ld/esp32.common.ld
components/esp32/ld/esp32.rom.ld
components/esp32/ld/esp32.rom.spiflash.ld [new file with mode: 0644]
components/spi_flash/Kconfig
components/spi_flash/flash_ops.c
components/spi_flash/spi_flash_rom_patch.c
components/spi_flash/test/test_partitions.c
components/spi_flash/test/test_read_write.c
docs/security/flash-encryption.rst

index 0df7d029440a41a632cd3aa7d195f5aefca42684..536077af4fa76f82b2338a1e44e337f34c9ebf37 100644 (file)
@@ -248,7 +248,7 @@ void bootloader_main()
 #endif
     esp_image_header_t fhdr;
     bootloader_state_t bs;
-    SpiFlashOpResult spiRet1,spiRet2;
+    esp_rom_spiflash_result_t spiRet1,spiRet2;
     esp_ota_select_entry_t sa,sb;
     const esp_ota_select_entry_t *ota_select_map;
 
@@ -258,7 +258,7 @@ void bootloader_main()
     /* disable watch dog here */
     REG_CLR_BIT( RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_FLASHBOOT_MOD_EN );
     REG_CLR_BIT( TIMG_WDTCONFIG0_REG(0), TIMG_WDT_FLASHBOOT_MOD_EN );
-    SPIUnlock();
+    esp_rom_spiflash_unlock();
 
     ESP_LOGI(TAG, "Enabling RNG early entropy source...");
     bootloader_random_enable();
@@ -298,7 +298,7 @@ void bootloader_main()
         memcpy(&sb, (uint8_t *)ota_select_map + SPI_SEC_SIZE, sizeof(esp_ota_select_entry_t));
         bootloader_munmap(ota_select_map);
         if(sa.ota_seq == 0xFFFFFFFF && sb.ota_seq == 0xFFFFFFFF) {
-            // init status flash 
+            // init status flash
             if (bs.factory.offset != 0) {        // if have factory bin,boot factory bin
                 load_part_pos = bs.factory;
             } else {
@@ -308,19 +308,19 @@ void bootloader_main()
                 sb.ota_seq = 0x00;
                 sb.crc = ota_select_crc(&sb);
 
-                Cache_Read_Disable(0);  
-                spiRet1 = SPIEraseSector(bs.ota_info.offset/0x1000);
-                spiRet2 = SPIEraseSector(bs.ota_info.offset/0x1000+1);
-                if (spiRet1 != SPI_FLASH_RESULT_OK || spiRet2 != SPI_FLASH_RESULT_OK ) {  
+                Cache_Read_Disable(0);
+                spiRet1 = esp_rom_spiflash_erase_sector(bs.ota_info.offset/0x1000);
+                spiRet2 = esp_rom_spiflash_erase_sector(bs.ota_info.offset/0x1000+1);
+                if (spiRet1 != ESP_ROM_SPIFLASH_RESULT_OK || spiRet2 != ESP_ROM_SPIFLASH_RESULT_OK ) {
                     ESP_LOGE(TAG, SPI_ERROR_LOG);
                     return;
-                } 
-                spiRet1 = SPIWrite(bs.ota_info.offset,(uint32_t *)&sa,sizeof(esp_ota_select_entry_t));
-                spiRet2 = SPIWrite(bs.ota_info.offset + 0x1000,(uint32_t *)&sb,sizeof(esp_ota_select_entry_t));
-                if (spiRet1 != SPI_FLASH_RESULT_OK || spiRet2 != SPI_FLASH_RESULT_OK ) {  
+                }
+                spiRet1 = esp_rom_spiflash_write(bs.ota_info.offset,(uint32_t *)&sa,sizeof(esp_ota_select_entry_t));
+                spiRet2 = esp_rom_spiflash_write(bs.ota_info.offset + 0x1000,(uint32_t *)&sb,sizeof(esp_ota_select_entry_t));
+                if (spiRet1 != ESP_ROM_SPIFLASH_RESULT_OK || spiRet2 != ESP_ROM_SPIFLASH_RESULT_OK ) {
                     ESP_LOGE(TAG, SPI_ERROR_LOG);
                     return;
-                } 
+                }
                 Cache_Read_Enable(0);
             }
             //TODO:write data in ota info
@@ -545,7 +545,7 @@ static void set_cache_and_start_app(
     uint32_t drom_size,
     uint32_t irom_addr,
     uint32_t irom_load_addr,
-    uint32_t irom_size, 
+    uint32_t irom_size,
     uint32_t entry_addr)
 {
     ESP_LOGD(TAG, "configure drom and irom and start");
@@ -602,7 +602,7 @@ static void update_flash_config(const esp_image_header_t* pfhdr)
     }
     Cache_Read_Disable( 0 );
     // Set flash chip size
-    SPIParamCfg(g_rom_flashchip.deviceId, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff);
+    esp_rom_spiflash_config_param(g_rom_flashchip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff);
     // TODO: set mode
     // TODO: set frequency
     Cache_Flush(0);
index b3d3c084f141e948b1804b92843d8c2ec91d6693..d324e1de2480b5055a484fb7ed26f864d587a7be 100644 (file)
@@ -11,6 +11,10 @@ LINKER_SCRIPTS := \
        $(IDF_PATH)/components/esp32/ld/esp32.peripherals.ld \
        esp32.bootloader.rom.ld
 
+ifndef CONFIG_SPI_FLASH_ROM_DRIVER_PATCH
+LINKER_SCRIPTS += $(IDF_PATH)/components/esp32/ld/esp32.rom.spiflash.ld
+endif
+
 COMPONENT_ADD_LDFLAGS := -L $(COMPONENT_PATH) -lmain $(addprefix -T ,$(LINKER_SCRIPTS))
 
 COMPONENT_ADD_LINKER_DEPS := $(LINKER_SCRIPTS)
index c1afc1e03fe8349059f725aab0046148f4a0d3be..4b2ec30883ebac2b8d5693d5d46f91a98672d8aa 100644 (file)
@@ -110,7 +110,7 @@ void bootloader_enable_qio_mode(void)
     int i;
 
     ESP_LOGD(TAG, "Probing for QIO mode enable...");
-    SPI_Wait_Idle(&g_rom_flashchip);
+    esp_rom_spiflash_wait_idle(&g_rom_flashchip);
 
     /* Set up some of the SPIFLASH user/ctrl variables which don't change
        while we're probing using execute_flash_command() */
@@ -150,7 +150,7 @@ static void enable_qio_mode(read_status_fn_t read_status_fn,
 {
     uint32_t status;
 
-    SPI_Wait_Idle(&g_rom_flashchip);
+    esp_rom_spiflash_wait_idle(&g_rom_flashchip);
 
     status = read_status_fn();
     ESP_LOGD(TAG, "Initial flash chip status 0x%x", status);
@@ -159,7 +159,7 @@ static void enable_qio_mode(read_status_fn_t read_status_fn,
         execute_flash_command(CMD_WREN, 0, 0, 0);
         write_status_fn(status | (1<<status_qio_bit));
 
-        SPI_Wait_Idle(&g_rom_flashchip);
+        esp_rom_spiflash_wait_idle(&g_rom_flashchip);
 
         status = read_status_fn();
         ESP_LOGD(TAG, "Updated flash chip status 0x%x", status);
@@ -174,13 +174,13 @@ static void enable_qio_mode(read_status_fn_t read_status_fn,
 
     ESP_LOGD(TAG, "Enabling QIO mode...");
 
-    SpiFlashRdMode mode;
+    esp_rom_spiflash_read_mode_t mode;
 #if CONFIG_FLASHMODE_QOUT
-    mode = SPI_FLASH_QOUT_MODE;
+    mode = ESP_ROM_SPIFLASH_QOUT_MODE;
 #else
-    mode = SPI_FLASH_QIO_MODE;
+    mode = ESP_ROM_SPIFLASH_QIO_MODE;
 #endif
-    SPIMasterReadModeCnfig(mode);
+    esp_rom_spiflash_master_config_readmode(mode);
 }
 
 static unsigned read_status_8b_rdsr()
index da77b1dc28f8f686ba1b61a998ba7cbb7c790d0a..7db9d840cc528814c59daa06384b6a1d4ba3d32f 100644 (file)
@@ -127,14 +127,14 @@ void bootloader_munmap(const void *mapping)
     }
 }
 
-static esp_err_t spi_to_esp_err(SpiFlashOpResult r)
+static esp_err_t spi_to_esp_err(esp_rom_spiflash_result_t r)
 {
     switch(r) {
-    case SPI_FLASH_RESULT_OK:
+    case ESP_ROM_SPIFLASH_RESULT_OK:
         return ESP_OK;
-    case SPI_FLASH_RESULT_ERR:
+    case ESP_ROM_SPIFLASH_RESULT_ERR:
         return ESP_ERR_FLASH_OP_FAIL;
-    case SPI_FLASH_RESULT_TIMEOUT:
+    case ESP_ROM_SPIFLASH_RESULT_TIMEOUT:
         return ESP_ERR_FLASH_OP_TIMEOUT;
     default:
         return ESP_FAIL;
@@ -145,7 +145,7 @@ static esp_err_t bootloader_flash_read_no_decrypt(size_t src_addr, void *dest, s
 {
     Cache_Read_Disable(0);
     Cache_Flush(0);
-    SpiFlashOpResult r = SPIRead(src_addr, dest, size);
+    esp_rom_spiflash_result_t r = esp_rom_spiflash_read(src_addr, dest, size);
     Cache_Read_Enable(0);
 
     return spi_to_esp_err(r);
@@ -221,21 +221,21 @@ esp_err_t bootloader_flash_write(size_t dest_addr, void *src, size_t size, bool
         return ESP_FAIL;
     }
 
-    err = spi_to_esp_err(SPIUnlock());
+    err = spi_to_esp_err(esp_rom_spiflash_unlock());
     if (err != ESP_OK) {
         return err;
     }
 
     if (write_encrypted) {
-        return spi_to_esp_err(SPI_Encrypt_Write(dest_addr, src, size));
+        return spi_to_esp_err(esp_rom_spiflash_write_encrypted(dest_addr, src, size));
     } else {
-        return spi_to_esp_err(SPIWrite(dest_addr, src, size));
+        return spi_to_esp_err(esp_rom_spiflash_write(dest_addr, src, size));
     }
 }
 
 esp_err_t bootloader_flash_erase_sector(size_t sector)
 {
-    return spi_to_esp_err(SPIEraseSector(sector));
+    return spi_to_esp_err(esp_rom_spiflash_erase_sector(sector));
 }
 
 #endif
index ae0f331cdcf9c5e7dff57f8d7683bd3617516dd4..438468b653bf094ade73553fbd2d0815171618cb 100644 (file)
@@ -17,6 +17,10 @@ ifeq ("$(CONFIG_NEWLIB_NANO_FORMAT)","y")
 LINKER_SCRIPTS += esp32.rom.nanofmt.ld
 endif
 
+ifndef CONFIG_SPI_FLASH_ROM_DRIVER_PATCH
+LINKER_SCRIPTS += esp32.rom.spiflash.ld
+endif
+
 COMPONENT_ADD_LDFLAGS := -lesp32 \
                          $(COMPONENT_PATH)/libhal.a \
                          -L$(COMPONENT_PATH)/lib \
index a9d617e7541b91c9f0959a448f829d11427b6a88..bb2da748ba6cbde5e0ec4a74a7d43cf85a9744fe 100644 (file)
@@ -65,81 +65,81 @@ extern "C" {
  *************************************************************
  */
 
-#define PERIPHS_SPI_FLASH_CMD               SPI_CMD(1)
-#define PERIPHS_SPI_FLASH_ADDR              SPI_ADDR(1)
-#define PERIPHS_SPI_FLASH_CTRL              SPI_CTRL(1)
-#define PERIPHS_SPI_FLASH_CTRL1             SPI_CTRL1(1)
-#define PERIPHS_SPI_FLASH_STATUS            SPI_RD_STATUS(1)
-#define PERIPHS_SPI_FLASH_USRREG            SPI_USER(1)
-#define PERIPHS_SPI_FLASH_USRREG1           SPI_USER1(1)
-#define PERIPHS_SPI_FLASH_USRREG2           SPI_USER2(1)
-#define PERIPHS_SPI_FLASH_C0                SPI_W0(1)
-#define PERIPHS_SPI_FLASH_C1                SPI_W1(1)
-#define PERIPHS_SPI_FLASH_C2                SPI_W2(1)
-#define PERIPHS_SPI_FLASH_C3                SPI_W3(1)
-#define PERIPHS_SPI_FLASH_C4                SPI_W4(1)
-#define PERIPHS_SPI_FLASH_C5                SPI_W5(1)
-#define PERIPHS_SPI_FLASH_C6                SPI_W6(1)
-#define PERIPHS_SPI_FLASH_C7                SPI_W7(1)
-#define PERIPHS_SPI_FLASH_TX_CRC            SPI_TX_CRC(1)
-
-#define SPI0_R_QIO_DUMMY_CYCLELEN           3
-#define SPI0_R_QIO_ADDR_BITSLEN             31
-#define SPI0_R_FAST_DUMMY_CYCLELEN          7
-#define SPI0_R_DIO_DUMMY_CYCLELEN           3
-#define SPI0_R_FAST_ADDR_BITSLEN            23
-#define SPI0_R_SIO_ADDR_BITSLEN             23
-
-#define SPI1_R_QIO_DUMMY_CYCLELEN           3
-#define SPI1_R_QIO_ADDR_BITSLEN             31
-#define SPI1_R_FAST_DUMMY_CYCLELEN          7
-#define SPI1_R_DIO_DUMMY_CYCLELEN           3
-#define SPI1_R_DIO_ADDR_BITSLEN             31
-#define SPI1_R_FAST_ADDR_BITSLEN            23
-#define SPI1_R_SIO_ADDR_BITSLEN             23
-
-#define SPI_W_SIO_ADDR_BITSLEN              23
-
-#define TWO_BYTE_STATUS_EN                  SPI_WRSR_2B
+#define PERIPHS_SPI_FLASH_CMD                 SPI_CMD_REG(1)
+#define PERIPHS_SPI_FLASH_ADDR                SPI_ADDR_REG(1)
+#define PERIPHS_SPI_FLASH_CTRL                SPI_CTRL_REG(1)
+#define PERIPHS_SPI_FLASH_CTRL1               SPI_CTRL1_REG(1)
+#define PERIPHS_SPI_FLASH_STATUS              SPI_RD_STATUS_REG(1)
+#define PERIPHS_SPI_FLASH_USRREG              SPI_USER_REG(1)
+#define PERIPHS_SPI_FLASH_USRREG1             SPI_USER1_REG(1)
+#define PERIPHS_SPI_FLASH_USRREG2             SPI_USER2_REG(1)
+#define PERIPHS_SPI_FLASH_C0                  SPI_W0_REG(1)
+#define PERIPHS_SPI_FLASH_C1                  SPI_W1_REG(1)
+#define PERIPHS_SPI_FLASH_C2                  SPI_W2_REG(1)
+#define PERIPHS_SPI_FLASH_C3                  SPI_W3_REG(1)
+#define PERIPHS_SPI_FLASH_C4                  SPI_W4_REG(1)
+#define PERIPHS_SPI_FLASH_C5                  SPI_W5_REG(1)
+#define PERIPHS_SPI_FLASH_C6                  SPI_W6_REG(1)
+#define PERIPHS_SPI_FLASH_C7                  SPI_W7_REG(1)
+#define PERIPHS_SPI_FLASH_TX_CRC              SPI_TX_CRC_REG(1)
+
+#define SPI0_R_QIO_DUMMY_CYCLELEN             3
+#define SPI0_R_QIO_ADDR_BITSLEN               31
+#define SPI0_R_FAST_DUMMY_CYCLELEN            7
+#define SPI0_R_DIO_DUMMY_CYCLELEN             3
+#define SPI0_R_FAST_ADDR_BITSLEN              23
+#define SPI0_R_SIO_ADDR_BITSLEN               23
+
+#define SPI1_R_QIO_DUMMY_CYCLELEN             3
+#define SPI1_R_QIO_ADDR_BITSLEN               31
+#define SPI1_R_FAST_DUMMY_CYCLELEN            7
+#define SPI1_R_DIO_DUMMY_CYCLELEN             3
+#define SPI1_R_DIO_ADDR_BITSLEN               31
+#define SPI1_R_FAST_ADDR_BITSLEN              23
+#define SPI1_R_SIO_ADDR_BITSLEN               23
+
+#define ESP_ROM_SPIFLASH_W_SIO_ADDR_BITSLEN   23
+
+#define ESP_ROM_SPIFLASH_TWO_BYTE_STATUS_EN   SPI_WRSR_2B
 
 //SPI address register
-#define SPI_FLASH_BYTES_LEN                 24
-#define SPI_BUFF_BYTE_WRITE_NUM             32
-#define SPI_BUFF_BYTE_READ_NUM              64
-#define SPI_BUFF_BYTE_READ_BITS             0x3f
+#define ESP_ROM_SPIFLASH_BYTES_LEN            24
+#define ESP_ROM_SPIFLASH_BUFF_BYTE_WRITE_NUM  32
+#define ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM   64
+#define ESP_ROM_SPIFLASH_BUFF_BYTE_READ_BITS  0x3f
 
 //SPI status register
-#define  SPI_FLASH_BUSY_FLAG                BIT0
-#define  SPI_FLASH_WRENABLE_FLAG            BIT1
-#define  SPI_FLASH_BP0                      BIT2
-#define  SPI_FLASH_BP1                      BIT3
-#define  SPI_FLASH_BP2                      BIT4
-#define  FLASH_WR_PROTECT                   (SPI_FLASH_BP0|SPI_FLASH_BP1|SPI_FLASH_BP2)
-#define  SPI_FLASH_QE                       BIT9
+#define  ESP_ROM_SPIFLASH_BUSY_FLAG           BIT0
+#define  ESP_ROM_SPIFLASH_WRENABLE_FLAG       BIT1
+#define  ESP_ROM_SPIFLASH_BP0                 BIT2
+#define  ESP_ROM_SPIFLASH_BP1                 BIT3
+#define  ESP_ROM_SPIFLASH_BP2                 BIT4
+#define  ESP_ROM_SPIFLASH_WR_PROTECT          (ESP_ROM_SPIFLASH_BP0|ESP_ROM_SPIFLASH_BP1|ESP_ROM_SPIFLASH_BP2)
+#define  ESP_ROM_SPIFLASH_QE                  BIT9
 
 typedef enum {
-    SPI_FLASH_QIO_MODE = 0,
-    SPI_FLASH_QOUT_MODE,
-    SPI_FLASH_DIO_MODE,
-    SPI_FLASH_DOUT_MODE,
-    SPI_FLASH_FASTRD_MODE,
-    SPI_FLASH_SLOWRD_MODE
-} SpiFlashRdMode;
+    ESP_ROM_SPIFLASH_QIO_MODE = 0,
+    ESP_ROM_SPIFLASH_QOUT_MODE,
+    ESP_ROM_SPIFLASH_DIO_MODE,
+    ESP_ROM_SPIFLASH_DOUT_MODE,
+    ESP_ROM_SPIFLASH_FASTRD_MODE,
+    ESP_ROM_SPIFLASH_SLOWRD_MODE
+} esp_rom_spiflash_read_mode_t;
 
 typedef enum {
-    SPI_FLASH_RESULT_OK,
-    SPI_FLASH_RESULT_ERR,
-    SPI_FLASH_RESULT_TIMEOUT
-} SpiFlashOpResult;
+    ESP_ROM_SPIFLASH_RESULT_OK,
+    ESP_ROM_SPIFLASH_RESULT_ERR,
+    ESP_ROM_SPIFLASH_RESULT_TIMEOUT
+} esp_rom_spiflash_result_t;
 
 typedef struct {
-    uint32_t deviceId;
+    uint32_t device_id;
     uint32_t chip_size;    // chip size in bytes
     uint32_t block_size;
     uint32_t sector_size;
     uint32_t page_size;
     uint32_t status_mask;
-} SpiFlashChip;
+} esp_rom_spiflash_chip_t;
 
 typedef struct {
     uint8_t  data_length;
@@ -148,7 +148,7 @@ typedef struct {
     uint8_t  write_cmd;
     uint16_t data_mask;
     uint16_t data;
-} SpiCommonCmd;
+} esp_rom_spiflash_common_cmd_t;
 
 /**
   * @brief Fix the bug in SPI hardware communication with Flash/Ext-SRAM in High Speed.
@@ -160,7 +160,7 @@ typedef struct {
   *
   * @return None
   */
-void spi_dummy_len_fix(uint8_t spi, uint8_t freqdiv);
+void esp_rom_spiflash_fix_dummylen(uint8_t spi, uint8_t freqdiv);
 
 /**
   * @brief Select SPI Flash to QIO mode when WP pad is read from Flash.
@@ -173,7 +173,7 @@ void spi_dummy_len_fix(uint8_t spi, uint8_t freqdiv);
   *
   * @return None
   */
-void SelectSpiQIO(uint8_t wp_gpio_num, uint32_t ishspi);
+void esp_rom_spiflash_select_qiomode(uint8_t wp_gpio_num, uint32_t ishspi);
 
 /**
   * @brief Set SPI Flash pad drivers.
@@ -191,7 +191,7 @@ void SelectSpiQIO(uint8_t wp_gpio_num, uint32_t ishspi);
   *
   * @return None
   */
-void SetSpiDrvs(uint8_t wp_gpio_num, uint32_t ishspi, uint8_t *drvs);
+void esp_rom_spiflash_set_drvs(uint8_t wp_gpio_num, uint32_t ishspi, uint8_t *drvs);
 
 /**
   * @brief Select SPI Flash function for pads.
@@ -202,7 +202,7 @@ void SetSpiDrvs(uint8_t wp_gpio_num, uint32_t ishspi, uint8_t *drvs);
   *
   * @return None
   */
-void SelectSpiFunction(uint32_t ishspi);
+void esp_rom_spiflash_select_padsfunc(uint32_t ishspi);
 
 /**
   * @brief SPI Flash init, clock divisor is 4, use 1 line Slow read mode.
@@ -215,89 +215,89 @@ void SelectSpiFunction(uint32_t ishspi);
   *
   * @return None
   */
-void spi_flash_attach(uint32_t ishspi, bool legacy);
+void esp_rom_spiflash_attach(uint32_t ishspi, bool legacy);
 
 /**
   * @brief SPI Read Flash status register. We use CMD 0x05 (RDSR).
   *    Please do not call this function in SDK.
   *
-  * @param  SpiFlashChip *spi : The information for Flash, which is exported from ld file.
+  * @param  esp_rom_spiflash_chip_t *spi : The information for Flash, which is exported from ld file.
   *
   * @param  uint32_t *status : The pointer to which to return the Flash status value.
   *
-  * @return SPI_FLASH_RESULT_OK : read OK.
-  *         SPI_FLASH_RESULT_ERR : read error.
-  *         SPI_FLASH_RESULT_TIMEOUT : read timeout.
+  * @return ESP_ROM_SPIFLASH_RESULT_OK : read OK.
+  *         ESP_ROM_SPIFLASH_RESULT_ERR : read error.
+  *         ESP_ROM_SPIFLASH_RESULT_TIMEOUT : read timeout.
   */
-SpiFlashOpResult SPI_read_status(SpiFlashChip *spi, uint32_t *status);
+esp_rom_spiflash_result_t esp_rom_spiflash_read_status(esp_rom_spiflash_chip_t *spi, uint32_t *status);
 
 /**
   * @brief SPI Read Flash status register bits 8-15. We use CMD 0x35 (RDSR2).
   *        Please do not call this function in SDK.
   *
-  * @param  SpiFlashChip *spi : The information for Flash, which is exported from ld file.
+  * @param  esp_rom_spiflash_chip_t *spi : The information for Flash, which is exported from ld file.
   *
   * @param  uint32_t *status : The pointer to which to return the Flash status value.
   *
-  * @return SPI_FLASH_RESULT_OK : read OK.
-  *         SPI_FLASH_RESULT_ERR : read error.
-  *         SPI_FLASH_RESULT_TIMEOUT : read timeout.
+  * @return ESP_ROM_SPIFLASH_RESULT_OK : read OK.
+  *         ESP_ROM_SPIFLASH_RESULT_ERR : read error.
+  *         ESP_ROM_SPIFLASH_RESULT_TIMEOUT : read timeout.
   */
-SpiFlashOpResult SPI_read_status_high(uint32_t *status);
+esp_rom_spiflash_result_t esp_rom_spiflash_read_statushigh(esp_rom_spiflash_chip_t *spi, uint32_t *status);
 
 /**
   * @brief Write status to Falsh status register.
   *        Please do not call this function in SDK.
   *
-  * @param  SpiFlashChip *spi : The information for Flash, which is exported from ld file.
+  * @param  esp_rom_spiflash_chip_t *spi : The information for Flash, which is exported from ld file.
   *
   * @param  uint32_t status_value : Value to .
   *
-  * @return SPI_FLASH_RESULT_OK : write OK.
-  *         SPI_FLASH_RESULT_ERR : write error.
-  *         SPI_FLASH_RESULT_TIMEOUT : write timeout.
+  * @return ESP_ROM_SPIFLASH_RESULT_OK : write OK.
+  *         ESP_ROM_SPIFLASH_RESULT_ERR : write error.
+  *         ESP_ROM_SPIFLASH_RESULT_TIMEOUT : write timeout.
   */
-SpiFlashOpResult SPI_write_status(SpiFlashChip *spi, uint32_t status_value);
+esp_rom_spiflash_result_t esp_rom_spiflash_write_status(esp_rom_spiflash_chip_t *spi, uint32_t status_value);
 
 /**
   * @brief Use a command to Read Flash status register.
   *        Please do not call this function in SDK.
   *
-  * @param  SpiFlashChip *spi : The information for Flash, which is exported from ld file.
+  * @param  esp_rom_spiflash_chip_t *spi : The information for Flash, which is exported from ld file.
   *
   * @param  uint32_t*status : The pointer to which to return the Flash status value.
   *
-  * @return SPI_FLASH_RESULT_OK : read OK.
-  *         SPI_FLASH_RESULT_ERR : read error.
-  *         SPI_FLASH_RESULT_TIMEOUT : read timeout.
+  * @return ESP_ROM_SPIFLASH_RESULT_OK : read OK.
+  *         ESP_ROM_SPIFLASH_RESULT_ERR : read error.
+  *         ESP_ROM_SPIFLASH_RESULT_TIMEOUT : read timeout.
   */
-SpiFlashOpResult SPI_user_command_read(uint32_t *status, uint8_t cmd);
+esp_rom_spiflash_result_t esp_rom_spiflash_read_user_cmd(uint32_t *status, uint8_t cmd);
 
 /**
   * @brief Config SPI Flash read mode when init.
   *        Please do not call this function in SDK.
   *
-  * @param  SpiFlashRdMode mode : QIO/QOUT/DIO/DOUT/FastRD/SlowRD.
+  * @param  esp_rom_spiflash_read_mode_t mode : QIO/QOUT/DIO/DOUT/FastRD/SlowRD.
   *
   * @param  uint8_t legacy: In legacy mode, more SPI command is used in line.
   *
-  * @return SPI_FLASH_RESULT_OK : config OK.
-  *         SPI_FLASH_RESULT_ERR : config error.
-  *         SPI_FLASH_RESULT_TIMEOUT : config timeout.
+  * @return ESP_ROM_SPIFLASH_RESULT_OK : config OK.
+  *         ESP_ROM_SPIFLASH_RESULT_ERR : config error.
+  *         ESP_ROM_SPIFLASH_RESULT_TIMEOUT : config timeout.
   */
-SpiFlashOpResult SPIReadModeCnfig(SpiFlashRdMode mode, bool legacy);
+esp_rom_spiflash_result_t esp_rom_spiflash_config_readmode(esp_rom_spiflash_read_mode_t mode, bool legacy);
 
 /**
   * @brief Config SPI Flash read mode when Flash is running in some mode.
   *        Please do not call this function in SDK.
   *
-  * @param  SpiFlashRdMode mode : QIO/QOUT/DIO/DOUT/FastRD/SlowRD.
+  * @param  esp_rom_spiflash_read_mode_t mode : QIO/QOUT/DIO/DOUT/FastRD/SlowRD.
   *
-  * @return SPI_FLASH_RESULT_OK : config OK.
-  *         SPI_FLASH_RESULT_ERR : config error.
-  *         SPI_FLASH_RESULT_TIMEOUT : config timeout.
+  * @return ESP_ROM_SPIFLASH_RESULT_OK : config OK.
+  *         ESP_ROM_SPIFLASH_RESULT_ERR : config error.
+  *         ESP_ROM_SPIFLASH_RESULT_TIMEOUT : config timeout.
   */
-SpiFlashOpResult SPIMasterReadModeCnfig(SpiFlashRdMode mode);
+esp_rom_spiflash_result_t esp_rom_spiflash_master_config_readmode(esp_rom_spiflash_read_mode_t mode);
 
 /**
   * @brief Config SPI Flash clock divisor.
@@ -307,23 +307,23 @@ SpiFlashOpResult SPIMasterReadModeCnfig(SpiFlashRdMode mode);
   *
   * @param  uint8_t spi: 0 for SPI0, 1 for SPI1.
   *
-  * @return SPI_FLASH_RESULT_OK : config OK.
-  *         SPI_FLASH_RESULT_ERR : config error.
-  *         SPI_FLASH_RESULT_TIMEOUT : config timeout.
+  * @return ESP_ROM_SPIFLASH_RESULT_OK : config OK.
+  *         ESP_ROM_SPIFLASH_RESULT_ERR : config error.
+  *         ESP_ROM_SPIFLASH_RESULT_TIMEOUT : config timeout.
   */
-SpiFlashOpResult SPIClkConfig(uint8_t freqdiv, uint8_t spi);
+esp_rom_spiflash_result_t esp_rom_spiflash_config_clk(uint8_t freqdiv, uint8_t spi);
 
 /**
   * @brief Send CommonCmd to Flash so that is can go into QIO mode, some Flash use different CMD.
   *        Please do not call this function in SDK.
   *
-  * @param  SpiCommonCmd *cmd : A struct to show the action of a command.
+  * @param  esp_rom_spiflash_common_cmd_t *cmd : A struct to show the action of a command.
   *
   * @return uint16_t  0 : do not send command any more.
   *                   1 : go to the next command.
   *                   n > 1 : skip (n - 1) commands.
   */
-uint16_t SPI_Common_Command(SpiCommonCmd *cmd);
+uint16_t esp_rom_spiflash_common_cmd(esp_rom_spiflash_common_cmd_t *cmd);
 
 /**
   * @brief Unlock SPI write protect.
@@ -331,11 +331,11 @@ uint16_t SPI_Common_Command(SpiCommonCmd *cmd);
   *
   * @param  None.
   *
-  * @return SPI_FLASH_RESULT_OK : Unlock OK.
-  *         SPI_FLASH_RESULT_ERR : Unlock error.
-  *         SPI_FLASH_RESULT_TIMEOUT : Unlock timeout.
+  * @return ESP_ROM_SPIFLASH_RESULT_OK : Unlock OK.
+  *         ESP_ROM_SPIFLASH_RESULT_ERR : Unlock error.
+  *         ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Unlock timeout.
   */
-SpiFlashOpResult SPIUnlock(void);
+esp_rom_spiflash_result_t esp_rom_spiflash_unlock(void);
 
 /**
   * @brief SPI write protect.
@@ -343,11 +343,11 @@ SpiFlashOpResult SPIUnlock(void);
   *
   * @param  None.
   *
-  * @return SPI_FLASH_RESULT_OK : Lock OK.
-  *         SPI_FLASH_RESULT_ERR : Lock error.
-  *         SPI_FLASH_RESULT_TIMEOUT : Lock timeout.
+  * @return ESP_ROM_SPIFLASH_RESULT_OK : Lock OK.
+  *         ESP_ROM_SPIFLASH_RESULT_ERR : Lock error.
+  *         ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Lock timeout.
   */
-SpiFlashOpResult SPILock(void);
+esp_rom_spiflash_result_t esp_rom_spiflash_lock(void);
 
 /**
   * @brief Update SPI Flash parameter.
@@ -365,11 +365,12 @@ SpiFlashOpResult SPILock(void);
   *
   * @param  uint32_t status_mask : The Mask used when read status from Flash(use single CMD).
   *
-  * @return SPI_FLASH_RESULT_OK : Update OK.
-  *         SPI_FLASH_RESULT_ERR : Update error.
-  *         SPI_FLASH_RESULT_TIMEOUT : Update timeout.
+  * @return ESP_ROM_SPIFLASH_RESULT_OK : Update OK.
+  *         ESP_ROM_SPIFLASH_RESULT_ERR : Update error.
+  *         ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Update timeout.
   */
-SpiFlashOpResult SPIParamCfg(uint32_t deviceId, uint32_t chip_size, uint32_t block_size, uint32_t sector_size, uint32_t page_size, uint32_t status_mask);
+esp_rom_spiflash_result_t esp_rom_spiflash_config_param(uint32_t deviceId, uint32_t chip_size, uint32_t block_size, 
+                                                        uint32_t sector_size, uint32_t page_size, uint32_t status_mask);
 
 /**
   * @brief Erase whole flash chip.
@@ -377,11 +378,11 @@ SpiFlashOpResult SPIParamCfg(uint32_t deviceId, uint32_t chip_size, uint32_t blo
   *
   * @param  None
   *
-  * @return SPI_FLASH_RESULT_OK : Erase OK.
-  *         SPI_FLASH_RESULT_ERR : Erase error.
-  *         SPI_FLASH_RESULT_TIMEOUT : Erase timeout.
+  * @return ESP_ROM_SPIFLASH_RESULT_OK : Erase OK.
+  *         ESP_ROM_SPIFLASH_RESULT_ERR : Erase error.
+  *         ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Erase timeout.
   */
-SpiFlashOpResult SPIEraseChip(void);
+esp_rom_spiflash_result_t esp_rom_spiflash_erase_chip(void);
 
 /**
   * @brief Erase a 64KB block of flash
@@ -390,11 +391,11 @@ SpiFlashOpResult SPIEraseChip(void);
   *
   * @param  uint32_t block_num : Which block to erase.
   *
-  * @return SPI_FLASH_RESULT_OK : Erase OK.
-  *         SPI_FLASH_RESULT_ERR : Erase error.
-  *         SPI_FLASH_RESULT_TIMEOUT : Erase timeout.
+  * @return ESP_ROM_SPIFLASH_RESULT_OK : Erase OK.
+  *         ESP_ROM_SPIFLASH_RESULT_ERR : Erase error.
+  *         ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Erase timeout.
   */
-SpiFlashOpResult SPIEraseBlock(uint32_t block_num);
+esp_rom_spiflash_result_t esp_rom_spiflash_erase_block(uint32_t block_num);
 
 /**
   * @brief Erase a sector of flash.
@@ -403,11 +404,11 @@ SpiFlashOpResult SPIEraseBlock(uint32_t block_num);
   *
   * @param  uint32_t sector_num : Which sector to erase.
   *
-  * @return SPI_FLASH_RESULT_OK : Erase OK.
-  *         SPI_FLASH_RESULT_ERR : Erase error.
-  *         SPI_FLASH_RESULT_TIMEOUT : Erase timeout.
+  * @return ESP_ROM_SPIFLASH_RESULT_OK : Erase OK.
+  *         ESP_ROM_SPIFLASH_RESULT_ERR : Erase error.
+  *         ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Erase timeout.
   */
-SpiFlashOpResult SPIEraseSector(uint32_t sector_num);
+esp_rom_spiflash_result_t esp_rom_spiflash_erase_sector(uint32_t sector_num);
 
 /**
   * @brief Erase some sectors.
@@ -417,11 +418,11 @@ SpiFlashOpResult SPIEraseSector(uint32_t sector_num);
   *
   * @param  uint32_t area_len : Length to erase, should be sector aligned.
   *
-  * @return SPI_FLASH_RESULT_OK : Erase OK.
-  *         SPI_FLASH_RESULT_ERR : Erase error.
-  *         SPI_FLASH_RESULT_TIMEOUT : Erase timeout.
+  * @return ESP_ROM_SPIFLASH_RESULT_OK : Erase OK.
+  *         ESP_ROM_SPIFLASH_RESULT_ERR : Erase error.
+  *         ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Erase timeout.
   */
-SpiFlashOpResult SPIEraseArea(uint32_t start_addr, uint32_t area_len);
+esp_rom_spiflash_result_t esp_rom_spiflash_erase_area(uint32_t start_addr, uint32_t area_len);
 
 /**
   * @brief Write Data to Flash, you should Erase it yourself if need.
@@ -433,11 +434,11 @@ SpiFlashOpResult SPIEraseArea(uint32_t start_addr, uint32_t area_len);
   *
   * @param  uint32_t len : Length to write, should be 4 bytes aligned.
   *
-  * @return SPI_FLASH_RESULT_OK : Write OK.
-  *         SPI_FLASH_RESULT_ERR : Write error.
-  *         SPI_FLASH_RESULT_TIMEOUT : Write timeout.
+  * @return ESP_ROM_SPIFLASH_RESULT_OK : Write OK.
+  *         ESP_ROM_SPIFLASH_RESULT_ERR : Write error.
+  *         ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Write timeout.
   */
-SpiFlashOpResult SPIWrite(uint32_t dest_addr, const uint32_t *src, int32_t len);
+esp_rom_spiflash_result_t esp_rom_spiflash_write(uint32_t dest_addr, const uint32_t *src, int32_t len);
 
 /**
   * @brief Read Data from Flash, you should Erase it yourself if need.
@@ -449,11 +450,11 @@ SpiFlashOpResult SPIWrite(uint32_t dest_addr, const uint32_t *src, int32_t len);
   *
   * @param  uint32_t len : Length to read, should be 4 bytes aligned.
   *
-  * @return SPI_FLASH_RESULT_OK : Read OK.
-  *         SPI_FLASH_RESULT_ERR : Read error.
-  *         SPI_FLASH_RESULT_TIMEOUT : Read timeout.
+  * @return ESP_ROM_SPIFLASH_RESULT_OK : Read OK.
+  *         ESP_ROM_SPIFLASH_RESULT_ERR : Read error.
+  *         ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Read timeout.
   */
-SpiFlashOpResult SPIRead(uint32_t src_addr, uint32_t *dest, int32_t len);
+esp_rom_spiflash_result_t esp_rom_spiflash_read(uint32_t src_addr, uint32_t *dest, int32_t len);
 
 /**
   * @brief SPI1 go into encrypto mode.
@@ -463,7 +464,7 @@ SpiFlashOpResult SPIRead(uint32_t src_addr, uint32_t *dest, int32_t len);
   *
   * @return None
   */
-void SPI_Write_Encrypt_Enable(void);
+void esp_rom_spiflash_write_encrypted_enable(void);
 
 /**
   * @brief Prepare 32 Bytes data to encrpto writing, you should Erase it yourself if need.
@@ -473,11 +474,11 @@ void SPI_Write_Encrypt_Enable(void);
   *
   * @param  uint32_t *data : The pointer to data which is to write.
   *
-  * @return SPI_FLASH_RESULT_OK : Prepare OK.
-  *         SPI_FLASH_RESULT_ERR : Prepare error.
-  *         SPI_FLASH_RESULT_TIMEOUT : Prepare timeout.
+  * @return ESP_ROM_SPIFLASH_RESULT_OK : Prepare OK.
+  *         ESP_ROM_SPIFLASH_RESULT_ERR : Prepare error.
+  *         ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Prepare timeout.
   */
-SpiFlashOpResult SPI_Prepare_Encrypt_Data(uint32_t flash_addr, uint32_t *data);
+esp_rom_spiflash_result_t esp_rom_spiflash_prepare_encrypted_data(uint32_t flash_addr, uint32_t *data);
 
 /**
   * @brief SPI1 go out of encrypto mode.
@@ -487,7 +488,7 @@ SpiFlashOpResult SPI_Prepare_Encrypt_Data(uint32_t flash_addr, uint32_t *data);
   *
   * @return None
   */
-void SPI_Write_Encrypt_Disable(void);
+void esp_rom_spiflash_write_encrypted_disable(void);
 
 /**
   * @brief Write data to flash with transparent encryption.
@@ -503,11 +504,11 @@ void SPI_Write_Encrypt_Disable(void);
   *
   * @param  uint32_t len : Length to write, should be 32 bytes aligned.
   *
-  * @return SPI_FLASH_RESULT_OK : Data written successfully.
-  *         SPI_FLASH_RESULT_ERR : Encryption write error.
-  *         SPI_FLASH_RESULT_TIMEOUT : Encrypto write timeout.
+  * @return ESP_ROM_SPIFLASH_RESULT_OK : Data written successfully.
+  *         ESP_ROM_SPIFLASH_RESULT_ERR : Encryption write error.
+  *         ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Encrypto write timeout.
   */
-SpiFlashOpResult SPI_Encrypt_Write(uint32_t flash_addr, uint32_t *data, uint32_t len);
+esp_rom_spiflash_result_t esp_rom_spiflash_write_encrypted(uint32_t flash_addr, uint32_t *data, uint32_t len);
 
 
 /** @brief Wait until SPI flash write operation is complete
@@ -517,16 +518,16 @@ SpiFlashOpResult SPI_Encrypt_Write(uint32_t flash_addr, uint32_t *data, uint32_t
  * Reads the Write In Progress bit of the SPI flash status register,
  * repeats until this bit is zero (indicating write complete).
  *
- * @return SPI_FLASH_RESULT_OK : Write is complete
- *         SPI_FLASH_RESULT_ERR : Error while reading status.
+ * @return ESP_ROM_SPIFLASH_RESULT_OK : Write is complete
+ *         ESP_ROM_SPIFLASH_RESULT_ERR : Error while reading status.
  */
-SpiFlashOpResult SPI_Wait_Idle(SpiFlashChip *spi);
+esp_rom_spiflash_result_t esp_rom_spiflash_wait_idle(esp_rom_spiflash_chip_t *spi);
 
 
-/** @brief Global SpiFlashChip structure used by ROM functions
+/** @brief Global esp_rom_spiflash_chip_t structure used by ROM functions
  *
  */
-extern SpiFlashChip g_rom_flashchip;
+extern esp_rom_spiflash_chip_t g_rom_flashchip;
 
 /**
   * @}
index 8d5a9c4276aadf542cb273f72b0c5f86f2a0ef61..75ac7e328124077bd92b02df78b7207717622d02 100644 (file)
@@ -97,6 +97,7 @@ SECTIONS
     *libnet80211.a:ieee80211_misc.o(.literal .text .literal.* .text.*)
     *libhal.a:(.literal .text .literal.* .text.*)
     *libcoexist.a:(.literal .text .literal.* .text.*)
+    *libspi_flash.a:spi_flash_rom_patch.o(.literal .text .literal.* .text.*)
     _iram_text_end = ABSOLUTE(.);
   } > iram0_0_seg
 
index 6cbd2fc7474b3505e2403d56b2b0ef2d71d305f6..6529e31dfa9c09de63ef715dfa2452e9fa7ac769 100644 (file)
@@ -125,7 +125,7 @@ PROVIDE ( __divdi3 = 0x4000ca84 );
 PROVIDE ( __divsc3 = 0x40064200 );
 PROVIDE ( __divsf3 = 0x4000234c );
 PROVIDE ( __divsi3 = 0x4000c7b8 );
-PROVIDE ( dummy_len_plus = 0x3ffae290 );
+PROVIDE ( g_rom_spiflash_dummy_len_plus = 0x3ffae290 );
 PROVIDE ( __dummy_lock = 0x4000c728 );
 PROVIDE ( __dummy_lock_try = 0x4000c730 );
 PROVIDE ( ecc_env = 0x3ffb8d60 );
@@ -1349,13 +1349,10 @@ PROVIDE ( sbrk = 0x400017f4 );
 PROVIDE ( _sbrk_r = 0x4000bce4 );
 PROVIDE ( __sccl = 0x4000c498 );
 PROVIDE ( __sclose = 0x400011b8 );
-PROVIDE ( SelectSpiFunction = 0x40061f84 );
-PROVIDE ( SelectSpiQIO = 0x40061ddc );
 PROVIDE ( __seofread = 0x40001148 );
 PROVIDE ( setjmp = 0x40056268 );
 PROVIDE ( setlocale = 0x40059568 );
 PROVIDE ( _setlocale_r = 0x4005950c );
-PROVIDE ( SetSpiDrvs = 0x40061e78 );
 PROVIDE ( __sf_fake_stderr = 0x3ff96458 );
 PROVIDE ( __sf_fake_stdin = 0x3ff96498 );
 PROVIDE ( __sf_fake_stdout = 0x3ff96478 );
@@ -1404,40 +1401,6 @@ PROVIDE ( slc_set_host_io_max_window = 0x4000b89c );
 PROVIDE ( slc_to_host_chain_recycle = 0x4000b758 );
 PROVIDE ( __smakebuf_r = 0x40059108 );
 PROVIDE ( specialModP256 = 0x4001600c );
-PROVIDE ( spi_cache_sram_init = 0x400626e4 );
-PROVIDE ( SPIClkConfig = 0x40062bc8 );
-PROVIDE ( SPI_Common_Command = 0x4006246c );
-PROVIDE ( spi_dummy_len_fix = 0x40061d90 );
-PROVIDE ( SPI_Encrypt_Write = 0x40062e78 );
-PROVIDE ( SPIEraseArea = 0x400631ac );
-PROVIDE ( SPIEraseBlock = 0x40062c4c );
-PROVIDE ( SPIEraseChip = 0x40062c14 );
-PROVIDE ( SPIEraseSector = 0x40062ccc );
-PROVIDE ( spi_flash_attach = 0x40062a6c );
-/* NB: SPIUnlock @ 0x400628b0 has been replaced with an updated
-    version in the "spi_flash" component */
-PROVIDE ( SPILock = 0x400628f0 );
-PROVIDE ( SPIMasterReadModeCnfig = 0x40062b64 );
-PROVIDE ( spi_modes = 0x3ff99270 );
-PROVIDE ( SPIParamCfg = 0x40063238 );
-PROVIDE ( SPI_Prepare_Encrypt_Data = 0x40062e1c );
-PROVIDE ( SPIRead = 0x40062ed8 );
-PROVIDE ( SPIReadModeCnfig = 0x40062944 );
-/* This is static function, but can be used, not generated by script*/
-PROVIDE ( SPI_read_status = 0x4006226c );
-/* This is static function, but can be used, not generated by script*/
-PROVIDE ( SPI_read_status_high = 0x40062448 );
-PROVIDE ( SPI_user_command_read = 0x400621b0 );
-PROVIDE ( SPI_flashchip_data = 0x3ffae270 );
-PROVIDE ( SPIWrite = 0x40062d50 );
-/* This is static function, but can be used, not generated by script*/
-PROVIDE ( SPI_write_enable = 0x40062320 );
-PROVIDE ( SPI_Write_Encrypt_Disable = 0x40062e60 );
-PROVIDE ( SPI_Write_Encrypt_Enable = 0x40062df4 );
-/* This is static function, but can be used, not generated by script*/
-PROVIDE ( SPI_write_status = 0x400622f0 );
-/* This is static function, but can be used, not generated by script */
-PROVIDE ( SPI_Wait_Idle = 0x400622c0 );
 PROVIDE ( srand = 0x40001004 );
 PROVIDE ( __sread = 0x40001118 );
 PROVIDE ( __srefill_r = 0x400593d4 );
@@ -1569,6 +1532,12 @@ PROVIDE ( xthal_set_intclear = 0x4000c1ec );
 PROVIDE ( _xtos_set_intlevel = 0x4000bfdc );
 PROVIDE ( g_ticks_per_us_pro = 0x3ffe01e0 );
 PROVIDE ( g_ticks_per_us_app = 0x3ffe40f0 );
+PROVIDE ( esp_rom_spiflash_config_param = 0x40063238 );
+PROVIDE ( esp_rom_spiflash_read_user_cmd = 0x400621b0 );
+PROVIDE ( esp_rom_spiflash_write_encrypted_disable = 0x40062e60 );
+PROVIDE ( esp_rom_spiflash_write_encrypted_enable = 0x40062df4 );
+PROVIDE ( esp_rom_spiflash_prepare_encrypted_data = 0x40062e1c );
+PROVIDE ( g_rom_spiflash_chip = 0x3ffae270 );
 
 /* 
 These functions are xtos-related (or call xtos-related functions) and do not play well 
diff --git a/components/esp32/ld/esp32.rom.spiflash.ld b/components/esp32/ld/esp32.rom.spiflash.ld
new file mode 100644 (file)
index 0000000..64af6a4
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+       Address table for SPI driver functions in ESP32 ROM.
+       These functions are only linked from ROM when SPI_FLASH_ROM_DRIVER_PATCH is not set in configuration.
+*/
+
+PROVIDE ( esp_rom_spiflash_write_encrypted = 0x40062e78 );
+PROVIDE ( esp_rom_spiflash_erase_area = 0x400631ac );
+PROVIDE ( esp_rom_spiflash_erase_block = 0x40062c4c );
+PROVIDE ( esp_rom_spiflash_erase_chip = 0x40062c14 );
+PROVIDE ( esp_rom_spiflash_erase_sector = 0x40062ccc );
+PROVIDE ( esp_rom_spiflash_lock = 0x400628f0 );
+PROVIDE ( esp_rom_spiflash_read = 0x40062ed8 );
+PROVIDE ( esp_rom_spiflash_config_readmode = 0x40062944 );
+PROVIDE ( esp_rom_spiflash_read_status = 0x4006226c );
+PROVIDE ( esp_rom_spiflash_read_statushigh = 0x40062448 );
+PROVIDE ( esp_rom_spiflash_write = 0x40062d50 );
+PROVIDE ( esp_rom_spiflash_enable_write = 0x40062320 );
+PROVIDE ( esp_rom_spiflash_write_status = 0x400622f0 );
+
+/* always using patched versions of these functions 
+PROVIDE ( esp_rom_spiflash_wait_idle = 0x400622c0 );
+PROVIDE ( esp_rom_spiflash_unlock = 0x400????? );
+*/
index 154dc7c30ff1b60f2e229e6cd46a6e255006993d..1aa2d0a4929bf97e0836094131539522acb3c4ee 100644 (file)
@@ -11,6 +11,14 @@ config SPI_FLASH_ENABLE_COUNTERS
         These APIs may be used to collect performance data for spi_flash APIs
         and to help understand behaviour of libraries which use SPI flash.
 
+config SPI_FLASH_ROM_DRIVER_PATCH
+    bool "Enable SPI flash ROM driver patched functions"
+    default y
+    help
+        Enable this flag to use patched versions of SPI flash ROM driver functions.
+        This option is needed to write to flash on ESP32-D2WD, and any configuration
+        where external SPI flash is connected to non-default pins.
+
 endmenu
 
 
index 86101ef04770f5fcbdc2bea9775e6dedc7c37492..725c34be08df2dd6120c89c15a7f24aa54bc8145 100644 (file)
@@ -42,7 +42,7 @@
 #define MAX_READ_CHUNK 16384
 
 #if CONFIG_SPI_FLASH_ENABLE_COUNTERS
-static const charTAG = "spi_flash";
+static const char *TAG = "spi_flash";
 static spi_flash_counters_t s_flash_stats;
 
 #define COUNTER_START()     uint32_t ts_begin = xthal_get_ccount()
@@ -64,20 +64,20 @@ static spi_flash_counters_t s_flash_stats;
 
 #endif //CONFIG_SPI_FLASH_ENABLE_COUNTERS
 
-static esp_err_t spi_flash_translate_rc(SpiFlashOpResult rc);
+static esp_err_t spi_flash_translate_rc(esp_rom_spiflash_result_t rc);
 
 const DRAM_ATTR spi_flash_guard_funcs_t g_flash_guard_default_ops = {
-        .start     = spi_flash_disable_interrupts_caches_and_other_cpu,
-        .end       = spi_flash_enable_interrupts_caches_and_other_cpu,
-        .op_lock   = spi_flash_op_lock,
-        .op_unlock = spi_flash_op_unlock
+    .start     = spi_flash_disable_interrupts_caches_and_other_cpu,
+    .end       = spi_flash_enable_interrupts_caches_and_other_cpu,
+    .op_lock   = spi_flash_op_lock,
+    .op_unlock = spi_flash_op_unlock
 };
 
 const DRAM_ATTR spi_flash_guard_funcs_t g_flash_guard_no_os_ops = {
-        .start      = spi_flash_disable_interrupts_caches_and_other_cpu_no_os,
-        .end        = spi_flash_enable_interrupts_caches_no_os,
-        .op_lock    = 0,
-        .op_unlock  = 0
+    .start      = spi_flash_disable_interrupts_caches_and_other_cpu_no_os,
+    .end        = spi_flash_enable_interrupts_caches_no_os,
+    .op_lock    = 0,
+    .op_unlock  = 0
 };
 
 static const spi_flash_guard_funcs_t *s_flash_guard_ops;
@@ -90,7 +90,7 @@ void spi_flash_init()
 #endif
 }
 
-void IRAM_ATTR spi_flash_guard_set(const spi_flash_guard_funcs_tfuncs)
+void IRAM_ATTR spi_flash_guard_set(const spi_flash_guard_funcs_t *funcs)
 {
     s_flash_guard_ops = funcs;
 }
@@ -128,19 +128,19 @@ static inline void IRAM_ATTR spi_flash_guard_op_unlock()
     }
 }
 
-static SpiFlashOpResult IRAM_ATTR spi_flash_unlock()
+static esp_rom_spiflash_result_t IRAM_ATTR spi_flash_unlock()
 {
     static bool unlocked = false;
     if (!unlocked) {
         spi_flash_guard_start();
-        SpiFlashOpResult rc = SPIUnlock();
+        esp_rom_spiflash_result_t rc = esp_rom_spiflash_unlock();
         spi_flash_guard_end();
-        if (rc != SPI_FLASH_RESULT_OK) {
+        if (rc != ESP_ROM_SPIFLASH_RESULT_OK) {
             return rc;
         }
         unlocked = true;
     }
-    return SPI_FLASH_RESULT_OK;
+    return ESP_ROM_SPIFLASH_RESULT_OK;
 }
 
 esp_err_t IRAM_ATTR spi_flash_erase_sector(size_t sec)
@@ -163,16 +163,17 @@ esp_err_t IRAM_ATTR spi_flash_erase_range(uint32_t start_addr, uint32_t size)
     size_t end = start + size / SPI_FLASH_SEC_SIZE;
     const size_t sectors_per_block = BLOCK_ERASE_SIZE / SPI_FLASH_SEC_SIZE;
     COUNTER_START();
-    SpiFlashOpResult rc = spi_flash_unlock();
-    if (rc == SPI_FLASH_RESULT_OK) {
-        for (size_t sector = start; sector != end && rc == SPI_FLASH_RESULT_OK; ) {
+    esp_rom_spiflash_result_t rc;
+    rc = spi_flash_unlock();
+    if (rc == ESP_ROM_SPIFLASH_RESULT_OK) {
+        for (size_t sector = start; sector != end && rc == ESP_ROM_SPIFLASH_RESULT_OK; ) {
             spi_flash_guard_start();
             if (sector % sectors_per_block == 0 && end - sector > sectors_per_block) {
-                rc = SPIEraseBlock(sector / sectors_per_block);
+                rc = esp_rom_spiflash_erase_block(sector / sectors_per_block);
                 sector += sectors_per_block;
                 COUNTER_ADD_BYTES(erase, sectors_per_block * SPI_FLASH_SEC_SIZE);
             } else {
-                rc = SPIEraseSector(sector);
+                rc = esp_rom_spiflash_erase_sector(sector);
                 ++sector;
                 COUNTER_ADD_BYTES(erase, SPI_FLASH_SEC_SIZE);
             }
@@ -194,7 +195,7 @@ esp_err_t IRAM_ATTR spi_flash_write(size_t dst, const void *srcv, size_t size)
         return ESP_OK;
     }
 
-    SpiFlashOpResult rc = SPI_FLASH_RESULT_OK;
+    esp_rom_spiflash_result_t rc = ESP_ROM_SPIFLASH_RESULT_OK;
     COUNTER_START();
     const char *srcc = (const char *) srcv;
     /*
@@ -210,16 +211,16 @@ esp_err_t IRAM_ATTR spi_flash_write(size_t dst, const void *srcv, size_t size)
     size_t right_off = left_size + mid_size;
     size_t right_size = size - mid_size - left_size;
     rc = spi_flash_unlock();
-    if (rc != SPI_FLASH_RESULT_OK) {
+    if (rc != ESP_ROM_SPIFLASH_RESULT_OK) {
         goto out;
     }
     if (left_size > 0) {
         uint32_t t = 0xffffffff;
         memcpy(((uint8_t *) &t) + (dst - left_off), srcc, left_size);
         spi_flash_guard_start();
-        rc = SPIWrite(left_off, &t, 4);
+        rc = esp_rom_spiflash_write(left_off, &t, 4);
         spi_flash_guard_end();
-        if (rc != SPI_FLASH_RESULT_OK) {
+        if (rc != ESP_ROM_SPIFLASH_RESULT_OK) {
             goto out;
         }
         COUNTER_ADD_BYTES(write, 4);
@@ -234,7 +235,7 @@ esp_err_t IRAM_ATTR spi_flash_write(size_t dst, const void *srcv, size_t size)
 #else
         bool direct_write = true;
 #endif
-        while(mid_size > 0 && rc == SPI_FLASH_RESULT_OK) {
+        while(mid_size > 0 && rc == ESP_ROM_SPIFLASH_RESULT_OK) {
             uint32_t write_buf[8];
             uint32_t write_size;
             const uint32_t *write_src = (const uint32_t *) (srcc + mid_off);
@@ -246,13 +247,13 @@ esp_err_t IRAM_ATTR spi_flash_write(size_t dst, const void *srcv, size_t size)
                 write_src = write_buf;
             }
             spi_flash_guard_start();
-            rc = SPIWrite(dst + mid_off, write_src, write_size);
+            rc = esp_rom_spiflash_write(dst + mid_off, (const uint32_t *) (srcc + mid_off), mid_size);
             spi_flash_guard_end();
             COUNTER_ADD_BYTES(write, write_size);
             mid_size -= write_size;
             mid_off += write_size;
         }
-        if (rc != SPI_FLASH_RESULT_OK) {
+        if (rc != ESP_ROM_SPIFLASH_RESULT_OK) {
             goto out;
         }
     }
@@ -261,9 +262,9 @@ esp_err_t IRAM_ATTR spi_flash_write(size_t dst, const void *srcv, size_t size)
         uint32_t t = 0xffffffff;
         memcpy(&t, srcc + right_off, right_size);
         spi_flash_guard_start();
-        rc = SPIWrite(dst + right_off, &t, 4);
+        rc = esp_rom_spiflash_write(dst + right_off, &t, 4);
         spi_flash_guard_end();
-        if (rc != SPI_FLASH_RESULT_OK) {
+        if (rc != ESP_ROM_SPIFLASH_RESULT_OK) {
             goto out;
         }
         COUNTER_ADD_BYTES(write, 4);
@@ -289,13 +290,13 @@ esp_err_t IRAM_ATTR spi_flash_write_encrypted(size_t dest_addr, const void *src,
     }
 
     COUNTER_START();
-    SpiFlashOpResult rc = spi_flash_unlock();
-
-    if (rc == SPI_FLASH_RESULT_OK) {
-        /* SPI_Encrypt_Write encrypts data in RAM as it writes,
+    esp_rom_spiflash_result_t rc;
+    rc = spi_flash_unlock();
+    if (rc == ESP_ROM_SPIFLASH_RESULT_OK) {
+        /* esp_rom_spiflash_write_encrypted encrypts data in RAM as it writes,
            so copy to a temporary buffer - 32 bytes at a time.
 
-           Each call to SPI_Encrypt_Write takes a 32 byte "row" of
+           Each call to esp_rom_spiflash_write_encrypted takes a 32 byte "row" of
            data to encrypt, and each row is two 16 byte AES blocks
            that share a key (as derived from flash address).
         */
@@ -311,25 +312,23 @@ esp_err_t IRAM_ATTR spi_flash_write_encrypted(size_t dest_addr, const void *src,
                 memcpy(encrypt_buf + 16, ssrc + i, 16);
                 /* decrypt the first block from flash, will reencrypt to same bytes */
                 spi_flash_read_encrypted(row_addr, encrypt_buf, 16);
-            }
-            else if (size - i == 16) {
+            } else if (size - i == 16) {
                 /* 16 bytes left, is first block of a 32 byte row */
                 row_size = 16;
                 /* copy to first block in buffer */
                 memcpy(encrypt_buf, ssrc + i, 16);
                 /* decrypt the second block from flash, will reencrypt to same bytes */
                 spi_flash_read_encrypted(row_addr + 16, encrypt_buf + 16, 16);
-            }
-            else {
+            } else {
                 /* Writing a full 32 byte row (2 blocks) */
                 row_size = 32;
                 memcpy(encrypt_buf, ssrc + i, 32);
             }
 
             spi_flash_guard_start();
-            rc = SPI_Encrypt_Write(row_addr, (uint32_t *)encrypt_buf, 32);
+            rc = esp_rom_spiflash_write_encrypted(row_addr, (uint32_t *)encrypt_buf, 32);
             spi_flash_guard_end();
-            if (rc != SPI_FLASH_RESULT_OK) {
+            if (rc != ESP_ROM_SPIFLASH_RESULT_OK) {
                 break;
             }
         }
@@ -356,7 +355,7 @@ esp_err_t IRAM_ATTR spi_flash_read(size_t src, void *dstv, size_t size)
         return ESP_OK;
     }
 
-    SpiFlashOpResult rc = SPI_FLASH_RESULT_OK;
+    esp_rom_spiflash_result_t rc = ESP_ROM_SPIFLASH_RESULT_OK;
     COUNTER_START();
     spi_flash_guard_start();
     /* To simplify boundary checks below, we handle small reads separately. */
@@ -365,8 +364,8 @@ esp_err_t IRAM_ATTR spi_flash_read(size_t src, void *dstv, size_t size)
         uint32_t read_src = src & ~3U;
         uint32_t left_off = src & 3U;
         uint32_t read_size = (left_off + size + 3) & ~3U;
-        rc = SPIRead(read_src, t, read_size);
-        if (rc != SPI_FLASH_RESULT_OK) {
+        rc = esp_rom_spiflash_read(read_src, t, read_size);
+        if (rc != ESP_ROM_SPIFLASH_RESULT_OK) {
             goto out;
         }
         COUNTER_ADD_BYTES(read, read_size);
@@ -402,8 +401,8 @@ esp_err_t IRAM_ATTR spi_flash_read(size_t src, void *dstv, size_t size)
         uint32_t mid_read = 0;
         while (mid_remaining > 0) {
             uint32_t read_size = MIN(mid_remaining, MAX_READ_CHUNK);
-            rc = SPIRead(src + src_mid_off + mid_read, (uint32_t *) (dstc + dst_mid_off + mid_read), read_size);
-            if (rc != SPI_FLASH_RESULT_OK) {
+            rc = esp_rom_spiflash_read(src + src_mid_off + mid_read, (uint32_t *) (dstc + dst_mid_off + mid_read), read_size);
+            if (rc != ESP_ROM_SPIFLASH_RESULT_OK) {
                 goto out;
             }
             mid_remaining -= read_size;
@@ -426,8 +425,8 @@ esp_err_t IRAM_ATTR spi_flash_read(size_t src, void *dstv, size_t size)
     }
     if (pad_left_size > 0) {
         uint32_t t;
-        rc = SPIRead(pad_left_src, &t, 4);
-        if (rc != SPI_FLASH_RESULT_OK) {
+        rc = esp_rom_spiflash_read(pad_left_src, &t, 4);
+        if (rc != ESP_ROM_SPIFLASH_RESULT_OK) {
             goto out;
         }
         COUNTER_ADD_BYTES(read, 4);
@@ -436,8 +435,8 @@ esp_err_t IRAM_ATTR spi_flash_read(size_t src, void *dstv, size_t size)
     if (pad_right_size > 0) {
         uint32_t t[2];
         int32_t read_size = (pad_right_size <= 4 ? 4 : 8);
-        rc = SPIRead(pad_right_src, t, read_size);
-        if (rc != SPI_FLASH_RESULT_OK) {
+        rc = esp_rom_spiflash_read(pad_right_src, t, read_size);
+        if (rc != ESP_ROM_SPIFLASH_RESULT_OK) {
             goto out;
         }
         COUNTER_ADD_BYTES(read, read_size);
@@ -461,7 +460,7 @@ esp_err_t IRAM_ATTR spi_flash_read_encrypted(size_t src, void *dstv, size_t size
     esp_err_t err;
     const uint8_t *map;
     spi_flash_mmap_handle_t map_handle;
-    size_t map_src = src & ~(SPI_FLASH_MMU_PAGE_SIZE-1);
+    size_t map_src = src & ~(SPI_FLASH_MMU_PAGE_SIZE - 1);
     size_t map_size = size + (src - map_src);
 
     err = spi_flash_mmap(map_src, map_size, SPI_FLASH_MMAP_DATA, (const void **)&map, &map_handle);
@@ -474,14 +473,14 @@ esp_err_t IRAM_ATTR spi_flash_read_encrypted(size_t src, void *dstv, size_t size
 }
 
 
-static esp_err_t IRAM_ATTR spi_flash_translate_rc(SpiFlashOpResult rc)
+static esp_err_t IRAM_ATTR spi_flash_translate_rc(esp_rom_spiflash_result_t rc)
 {
     switch (rc) {
-    case SPI_FLASH_RESULT_OK:
+    case ESP_ROM_SPIFLASH_RESULT_OK:
         return ESP_OK;
-    case SPI_FLASH_RESULT_TIMEOUT:
+    case ESP_ROM_SPIFLASH_RESULT_TIMEOUT:
         return ESP_ERR_FLASH_OP_TIMEOUT;
-    case SPI_FLASH_RESULT_ERR:
+    case ESP_ROM_SPIFLASH_RESULT_ERR:
     default:
         return ESP_ERR_FLASH_OP_FAIL;
     }
@@ -489,13 +488,13 @@ static esp_err_t IRAM_ATTR spi_flash_translate_rc(SpiFlashOpResult rc)
 
 #if CONFIG_SPI_FLASH_ENABLE_COUNTERS
 
-static inline void dump_counter(spi_flash_counter_t* counter, const char* name)
+static inline void dump_counter(spi_flash_counter_t *counter, const char *name)
 {
     ESP_LOGI(TAG, "%s  count=%8d  time=%8dus  bytes=%8d\n", name,
              counter->count, counter->time, counter->bytes);
 }
 
-const spi_flash_counters_tspi_flash_get_counters()
+const spi_flash_counters_t *spi_flash_get_counters()
 {
     return &s_flash_stats;
 }
index 36e5bf823679d147a9c09e197a2d115858ee2c12..0664c748295b90d990c3db34369443e5394e0cad 100644 (file)
 // 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 "rom/spi_flash.h"
-#include "soc/spi_reg.h"
-
-static const uint32_t STATUS_QIE_BIT = (1 << 9); /* Quad Enable */
 
-#define SPI_IDX 1
-#define OTH_IDX 0
+#include "rom/ets_sys.h"
+#include "rom/gpio.h"
+#include "rom/spi_flash.h"
+#include "sdkconfig.h"
 
-#ifndef BOOTLOADER_BUILD
-#define ATTR IRAM_ATTR
-#else
-#define ATTR
-#endif // BOOTLOADER_BUILD
+#define SPI_IDX   1
+#define OTH_IDX   0
 
-extern SpiFlashChip SPI_flashchip_data;
+extern esp_rom_spiflash_chip_t g_rom_spiflash_chip;
 
-static void ATTR Wait_SPI_Idle(void)
+esp_rom_spiflash_result_t esp_rom_spiflash_wait_idle(esp_rom_spiflash_chip_t *spi)
 {
-  /* Wait for SPI state machine to be idle */
-  while((REG_READ(SPI_EXT2_REG(SPI_IDX)) & SPI_ST)) {
-  }
-  while(REG_READ(SPI_EXT2_REG(OTH_IDX)) & SPI_ST) {
-  }
+    uint32_t status;
+
+    //wait for spi control ready
+    while ((REG_READ(SPI_EXT2_REG(1)) & SPI_ST)) {
+    }
+    while ((REG_READ(SPI_EXT2_REG(0)) & SPI_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 SPIUnlock() that replaces version in ROM.
 
-   This works around a bug where SPIUnlock sometimes reads the wrong
+/* 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.
@@ -48,31 +51,680 @@ static void ATTR Wait_SPI_Idle(void)
    about interrupts, CPU coordination, flash mapping. However some of
    the functions in esp_spi_flash.c call it.
  */
-SpiFlashOpResult ATTR SPIUnlock(void)
+esp_rom_spiflash_result_t esp_rom_spiflash_unlock()
+{
+    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_CMD_REG(SPI_IDX), SPI_FLASH_WREN);
+    while (REG_READ(SPI_CMD_REG(SPI_IDX)) != 0) {
+    }
+    esp_rom_spiflash_wait_idle(&g_rom_spiflash_chip);
+
+    SET_PERI_REG_MASK(SPI_CTRL_REG(SPI_IDX), SPI_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);
+static esp_rom_spiflash_result_t esp_rom_spiflash_enable_qmode(esp_rom_spiflash_chip_t *spi);
+static esp_rom_spiflash_result_t esp_rom_spiflash_disable_qmode(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_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)
 {
-  uint32_t status;
+    //check if addr is 4k alignment
+    if (0 != (addr & 0xfff)) {
+        return ESP_ROM_SPIFLASH_RESULT_ERR;
+    }
 
-  Wait_SPI_Idle();
+    esp_rom_spiflash_wait_idle(spi);
 
-  if (SPI_read_status_high(&status) != SPI_FLASH_RESULT_OK) {
-    return SPI_FLASH_RESULT_ERR;
-  }
+    // sector erase  4Kbytes erase is sector erase.
+    WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, addr & 0xffffff);
+    WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_FLASH_SE);
+    while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0);
 
-  /* Clear all bits except QIE, if it is set.
-     (This is different from ROM SPIUnlock, which keeps all bits as-is.)
-   */
-  status &= STATUS_QIE_BIT;
+    esp_rom_spiflash_wait_idle(spi);
 
-  Wait_SPI_Idle();
-  REG_WRITE(SPI_CMD_REG(SPI_IDX), SPI_FLASH_WREN);
-  while(REG_READ(SPI_CMD_REG(SPI_IDX)) != 0) {
-  }
-  Wait_SPI_Idle();
+    return ESP_ROM_SPIFLASH_RESULT_OK;
+}
 
-  SET_PERI_REG_MASK(SPI_CTRL_REG(SPI_IDX), SPI_WRSR_2B);
-  if (SPI_write_status(&SPI_flashchip_data, status) != SPI_FLASH_RESULT_OK) {
-    return SPI_FLASH_RESULT_ERR;
-  }
+//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_FLASH_BE);
+    while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0);
+
+    esp_rom_spiflash_wait_idle(spi);
 
-  return SPI_FLASH_RESULT_OK;
+    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_FLASH_PP);
+        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;
+}
+
+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_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_FLASH_WRSR);
+    while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0);
+    esp_rom_spiflash_wait_idle(spi);
+
+    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_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 esp_rom_spiflash_result_t esp_rom_spiflash_enable_qmode(esp_rom_spiflash_chip_t *spi)
+{
+    uint32_t flash_status;
+    uint32_t status;
+    //read QE bit, not write if QE
+    if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_read_statushigh(spi, &status)) {
+        return ESP_ROM_SPIFLASH_RESULT_ERR;
+    }
+    if (status & ESP_ROM_SPIFLASH_QE) {
+        return ESP_ROM_SPIFLASH_RESULT_OK;
+    }
+
+    //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(spi)) {
+        return ESP_ROM_SPIFLASH_RESULT_ERR;
+    }
+
+    esp_rom_spiflash_read_status(spi, &flash_status);
+
+    if ( ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_write_status(spi, flash_status | ESP_ROM_SPIFLASH_QE)) {
+        return ESP_ROM_SPIFLASH_RESULT_ERR;
+    }
+
+    return ESP_ROM_SPIFLASH_RESULT_OK;
+}
+
+static esp_rom_spiflash_result_t esp_rom_spiflash_disable_qmode(esp_rom_spiflash_chip_t *spi)
+{
+    uint32_t flash_status;
+    uint32_t status;
+
+    //read QE bit, not write if not QE
+    if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_read_statushigh(spi, &status)) {
+        return ESP_ROM_SPIFLASH_RESULT_ERR;
+    }
+    //ets_printf("status %08x, line:%u\n", status, __LINE__);
+
+    if (!(status & ESP_ROM_SPIFLASH_QE)) {
+        return ESP_ROM_SPIFLASH_RESULT_OK;
+    }
+
+    //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(spi)) {
+        return ESP_ROM_SPIFLASH_RESULT_ERR;
+    }
+
+    esp_rom_spiflash_read_status(spi, &flash_status);
+    //keep low 8 bit
+    if ( ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_write_status(spi, flash_status & 0xff)) {
+        return ESP_ROM_SPIFLASH_RESULT_ERR;
+    }
+
+    return ESP_ROM_SPIFLASH_RESULT_OK;
+}
+
+static void spi_cache_mode_switch(uint32_t  modebit)
+{
+    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);
+        REG_SET_FIELD(SPI_USER1_REG(0), SPI_USR_ADDR_BITLEN, SPI0_R_QIO_ADDR_BITSLEN);
+        REG_SET_FIELD(SPI_USER1_REG(0), SPI_USR_DUMMY_CYCLELEN, SPI0_R_QIO_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[0]);
+        REG_SET_FIELD(SPI_USER2_REG(0), SPI_USR_COMMAND_VALUE, 0xEB);
+    } else if (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);
+        REG_SET_FIELD(SPI_USER1_REG(0), SPI_USR_ADDR_BITLEN, SPI0_R_FAST_ADDR_BITSLEN);
+        if ((modebit & SPI_FREAD_QUAD)) {
+            REG_SET_FIELD(SPI_USER2_REG(0), SPI_USR_COMMAND_VALUE, 0x6B);
+            REG_SET_FIELD(SPI_USER1_REG(0), SPI_USR_DUMMY_CYCLELEN, SPI0_R_FAST_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[0]);
+        } else if ((modebit & SPI_FREAD_DIO)) {
+            REG_SET_FIELD(SPI_USER1_REG(0), SPI_USR_DUMMY_CYCLELEN, SPI0_R_DIO_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[0]);
+            REG_SET_FIELD(SPI_USER2_REG(0), SPI_USR_COMMAND_VALUE, 0xBB);
+        } else if ((modebit & SPI_FREAD_DUAL)) {
+            REG_SET_FIELD(SPI_USER1_REG(0), SPI_USR_DUMMY_CYCLELEN, SPI0_R_FAST_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[0]);
+            REG_SET_FIELD(SPI_USER2_REG(0), SPI_USR_COMMAND_VALUE, 0x3B);
+        } else {
+            REG_SET_FIELD(SPI_USER1_REG(0), SPI_USR_DUMMY_CYCLELEN, SPI0_R_FAST_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[0]);
+            REG_SET_FIELD(SPI_USER2_REG(0), SPI_USR_COMMAND_VALUE, 0x0B);
+        }
+    } else {
+        REG_CLR_BIT(SPI_USER_REG(0), SPI_USR_MOSI);
+        if (g_rom_spiflash_dummy_len_plus[0] == 0) {
+            REG_CLR_BIT(SPI_USER_REG(0), SPI_USR_DUMMY);
+        } else {
+            REG_SET_BIT(SPI_USER_REG(0), SPI_USR_DUMMY);
+            REG_SET_FIELD(SPI_USER1_REG(0), SPI_USR_DUMMY_CYCLELEN, g_rom_spiflash_dummy_len_plus[0] - 1);
+        }
+        REG_SET_BIT(SPI_USER_REG(0), SPI_USR_MISO | SPI_USR_ADDR);
+        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);
+    }
+
+}
+
+esp_rom_spiflash_result_t esp_rom_spiflash_lock()
+{
+    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, bool legacy)
+{
+    uint32_t  modebit;
+
+    while ((REG_READ(SPI_EXT2_REG(1)) & SPI_ST)) {
+    }
+    while ((REG_READ(SPI_EXT2_REG(0)) & SPI_ST)) {
+    }
+    //clear old mode bit
+    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);
+    //configure read mode
+    switch (mode) {
+    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;
+    case ESP_ROM_SPIFLASH_SLOWRD_MODE:  modebit = 0; break;
+    default : modebit = 0;
+    }
+
+    if ((ESP_ROM_SPIFLASH_QIO_MODE == mode) || (ESP_ROM_SPIFLASH_QOUT_MODE == mode)) {
+        esp_rom_spiflash_enable_qmode(&g_rom_spiflash_chip);
+    } else {
+        //do not need disable QMode in faster boot
+        if (legacy) {
+            esp_rom_spiflash_disable_qmode(&g_rom_spiflash_chip);
+        }
+    }
+
+    SET_PERI_REG_MASK(PERIPHS_SPI_FLASH_CTRL, modebit);
+    SET_PERI_REG_MASK(SPI_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()
+{
+    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_USR_DUMMY);
+    REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_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_USR_DUMMY);
+    REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_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_USR_DUMMY);
+    REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_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_write_encrypted(uint32_t flash_addr, uint32_t *data, uint32_t len)
+{
+    esp_rom_spiflash_result_t ret = ESP_ROM_SPIFLASH_RESULT_OK;
+    uint32_t i;
+
+    if ((flash_addr & 0x1f) || (len & 0x1f)) {  //check 32 byte alignment
+        return ESP_ROM_SPIFLASH_RESULT_ERR;
+    }
+
+    esp_rom_spiflash_write_encrypted_enable();
+
+    for (i = 0; i < (len >> 5); i++) {
+        if ((ret = esp_rom_spiflash_prepare_encrypted_data(flash_addr + (i << 5), data + (i << 3))) != ESP_ROM_SPIFLASH_RESULT_OK) {
+            break;
+        }
+
+        if ((ret = esp_rom_spiflash_write(flash_addr + (i << 5), data, 32)) != ESP_ROM_SPIFLASH_RESULT_OK) {
+            break;
+        }
+    }
+
+    esp_rom_spiflash_write_encrypted_disable();
+
+    return ret;
+}
+
+
+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 ((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);
+        REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_USR_ADDR_BITLEN, SPI1_R_QIO_ADDR_BITSLEN);
+        REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_USR_DUMMY_CYCLELEN, SPI1_R_QIO_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[1]);
+        //REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG2, SPI_USR_COMMAND_VALUE, 0xEB);
+        REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_USR_COMMAND_BITLEN_S) | 0xEB);
+    } else if (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_ADDR);
+        if (modebit & SPI_FREAD_DIO) {
+            if (g_rom_spiflash_dummy_len_plus[1] == 0) {
+                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);
+            } else {
+                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);
+            }
+        } else {
+            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);
+            } else if ((modebit & SPI_FREAD_DUAL)) {
+                //REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG2, SPI_USR_COMMAND_VALUE, 0x3B);
+                REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_USR_COMMAND_BITLEN_S) | 0x3B);
+            } else {
+                //REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG2, SPI_USR_COMMAND_VALUE, 0x0B);
+                REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_USR_COMMAND_BITLEN_S) | 0x0B);
+            }
+            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]);
+        }
+    } else {
+        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);
+        } else {
+            REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_DUMMY);
+            REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_USR_DUMMY_CYCLELEN,  g_rom_spiflash_dummy_len_plus[1] - 1);
+        }
+        REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_MISO | SPI_USR_ADDR);
+        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);
+    }
+
+    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
+    esp_rom_spiflash_config_readmode(ESP_ROM_SPIFLASH_SLOWRD_MODE, true);
+
+    //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
index 01dd5f4456b2bdd50432e06ee976c7bc68366863..d859d3dd2cc20959e862d543ed7eeffb39f7e140 100644 (file)
@@ -23,6 +23,7 @@
 #include <unity.h>
 #include <test_utils.h>
 #include <esp_partition.h>
+#include <esp_attr.h>
 
 TEST_CASE("Test erase partition", "[spi_flash]")
 {
@@ -40,7 +41,7 @@ TEST_CASE("Test erase partition", "[spi_flash]")
 #endif
 
     // put some dummy data on sector boundaries
-    const char *some_data = "abcdefghijklmn";
+    const static DRAM_ATTR char some_data[] = "abcdefghijklmn";
     for (int i = 0; i < part->size; i+= 4096) {
         ESP_ERROR_CHECK( esp_partition_write(part, i, some_data, strlen(some_data)) );
     }
@@ -64,5 +65,4 @@ TEST_CASE("Test erase partition", "[spi_flash]")
             TEST_ASSERT_EQUAL_HEX8(0xFF, buf[i]);
         }
     }
-
 }
index b9dc820b1ed692dd812956f0fd954b7fcb2c113b..147e4c3c9d1e83fab61c2f262dd1e8a05c3eb32c 100644 (file)
@@ -71,18 +71,18 @@ static void IRAM_ATTR test_read(int src_off, int dst_off, int len)
 {
     uint32_t src_buf[16];
     char dst_buf[64], dst_gold[64];
+
     fprintf(stderr, "src=%d dst=%d len=%d\n", src_off, dst_off, len);
     memset(src_buf, 0xAA, sizeof(src_buf));
     fill(((char *) src_buf) + src_off, src_off, len);
     ESP_ERROR_CHECK(spi_flash_erase_sector((start + src_off) / SPI_FLASH_SEC_SIZE));
     spi_flash_disable_interrupts_caches_and_other_cpu();
-    SpiFlashOpResult rc = SPIWrite(start, src_buf, sizeof(src_buf));
+    esp_rom_spiflash_result_t rc = esp_rom_spiflash_write(start, src_buf, sizeof(src_buf));
     spi_flash_enable_interrupts_caches_and_other_cpu();
-    TEST_ASSERT_EQUAL_INT(rc, SPI_FLASH_RESULT_OK);
+    TEST_ASSERT_EQUAL_INT(rc, ESP_ROM_SPIFLASH_RESULT_OK);
     memset(dst_buf, 0x55, sizeof(dst_buf));
     memset(dst_gold, 0x55, sizeof(dst_gold));
     fill(dst_gold + dst_off, src_off, len);
-
     ESP_ERROR_CHECK(spi_flash_read(start + src_off, dst_buf + dst_off, len));
     TEST_ASSERT_EQUAL_INT(cmp_or_dump(dst_buf, dst_gold, sizeof(dst_buf)), 0);
 }
@@ -159,9 +159,9 @@ static void IRAM_ATTR test_write(int dst_off, int src_off, int len)
     }
     ESP_ERROR_CHECK(spi_flash_write(start + dst_off, src_buf + src_off, len));
     spi_flash_disable_interrupts_caches_and_other_cpu();
-    SpiFlashOpResult rc = SPIRead(start, dst_buf, sizeof(dst_buf));
+    esp_rom_spiflash_result_t rc = esp_rom_spiflash_read(start, dst_buf, sizeof(dst_buf));
     spi_flash_enable_interrupts_caches_and_other_cpu();
-    TEST_ASSERT_EQUAL_INT(rc, SPI_FLASH_RESULT_OK);
+    TEST_ASSERT_EQUAL_INT(rc, ESP_ROM_SPIFLASH_RESULT_OK);
     TEST_ASSERT_EQUAL_INT(cmp_or_dump(dst_buf, dst_gold, sizeof(dst_buf)), 0);
 }
 
index 8448f020bdf51a1d1a76bb71bc7f6ee2c1e9823e..f2f1339d9f6560546f8e5b2a336cc56175531741 100644 (file)
@@ -108,7 +108,7 @@ Where possible, we recommend using the partition write function ``esp_partition_
 
 The ``esp_spi_flash_write`` function will write data when the write_encrypted parameter is set to true. Otherwise, data will be written unencrypted.
 
-The ROM function ``SPI_Encrypt_Write`` will write encrypted data to flash, the ROM function ``SPIWrite`` will write unencrypted to flash. (these function are not supported in esp-idf apps).
+The ROM function ``esp_rom_spiflash_write_encrypted`` will write encrypted data to flash, the ROM function ``SPIWrite`` will write unencrypted to flash. (these function are not supported in esp-idf apps).
 
 The minimum write size for unencrypted data is 4 bytes (and the alignment is 4 bytes). Because data is encrypted in blocks, the minimum write size for encrypted data is 16 bytes (and the alignment is 16 bytes.)