mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
spi_flash: Fixed bug in SPI flash ROM driver to work with embedded flash chip
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
This commit is contained in:
parent
375b28650b
commit
0860f46220
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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 \
|
||||
|
@ -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 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 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 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 ESP_ROM_SPIFLASH_W_SIO_ADDR_BITSLEN 23
|
||||
|
||||
#define TWO_BYTE_STATUS_EN SPI_WRSR_2B
|
||||
#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;
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
23
components/esp32/ld/esp32.rom.spiflash.ld
Normal file
23
components/esp32/ld/esp32.rom.spiflash.ld
Normal file
@ -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????? );
|
||||
*/
|
@ -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
|
||||
|
||||
|
||||
|
@ -42,7 +42,7 @@
|
||||
#define MAX_READ_CHUNK 16384
|
||||
|
||||
#if CONFIG_SPI_FLASH_ENABLE_COUNTERS
|
||||
static const char* TAG = "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_t* funcs)
|
||||
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_t* spi_flash_get_counters()
|
||||
const spi_flash_counters_t *spi_flash_get_counters()
|
||||
{
|
||||
return &s_flash_stats;
|
||||
}
|
||||
|
@ -11,34 +11,37 @@
|
||||
// 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/ets_sys.h"
|
||||
#include "rom/gpio.h"
|
||||
#include "rom/spi_flash.h"
|
||||
#include "soc/spi_reg.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
static const uint32_t STATUS_QIE_BIT = (1 << 9); /* Quad Enable */
|
||||
#define SPI_IDX 1
|
||||
#define OTH_IDX 0
|
||||
|
||||
#define SPI_IDX 1
|
||||
#define OTH_IDX 0
|
||||
extern esp_rom_spiflash_chip_t g_rom_spiflash_chip;
|
||||
|
||||
#ifndef BOOTLOADER_BUILD
|
||||
#define ATTR IRAM_ATTR
|
||||
#else
|
||||
#define ATTR
|
||||
#endif // BOOTLOADER_BUILD
|
||||
|
||||
extern SpiFlashChip SPI_flashchip_data;
|
||||
|
||||
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;
|
||||
uint32_t status;
|
||||
|
||||
Wait_SPI_Idle();
|
||||
esp_rom_spiflash_wait_idle(&g_rom_spiflash_chip);
|
||||
|
||||
if (SPI_read_status_high(&status) != SPI_FLASH_RESULT_OK) {
|
||||
return SPI_FLASH_RESULT_ERR;
|
||||
}
|
||||
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 SPIUnlock, which keeps all bits as-is.)
|
||||
*/
|
||||
status &= STATUS_QIE_BIT;
|
||||
/* 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;
|
||||
|
||||
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();
|
||||
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 (SPI_write_status(&SPI_flashchip_data, status) != SPI_FLASH_RESULT_OK) {
|
||||
return SPI_FLASH_RESULT_ERR;
|
||||
}
|
||||
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 SPI_FLASH_RESULT_OK;
|
||||
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)
|
||||
{
|
||||
//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_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_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_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
|
||||
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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.)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user