Merge branch 'bugfix/esp32s2beta_flash_cache' into 'master'

Bugfix/esp32s2beta flash cache

See merge request espressif/esp-idf!6561
This commit is contained in:
Jiang Jiang Jian 2019-11-18 14:16:16 +08:00
commit 45944da8ae
9 changed files with 686 additions and 249 deletions

View file

@ -211,12 +211,12 @@ void bootloader_enable_qio_mode(void)
if (i == NUM_CHIPS - 1) {
ESP_LOGI(TAG, "Enabling default flash chip QIO");
}
#if CONFIG_IDF_TARGET_ESP32S2BETA
spi_flash_wrap_set(FLASH_WRAP_MODE_DISABLE);
#endif
enable_qio_mode(chip_data[i].read_status_fn,
chip_data[i].write_status_fn,
chip_data[i].status_qio_bit);
#if CONFIG_IDF_TARGET_ESP32S2BETA
spi_flash_wrap_set(FLASH_WRAP_MODE_DISABLE);
#endif
}
static esp_err_t enable_qio_mode(read_status_fn_t read_status_fn,

View file

@ -189,7 +189,7 @@ extern void esp_switch_rodata_to_dcache(void);
extern void esp_spiram_enable_instruction_access(void);
esp_spiram_enable_instruction_access();
#endif
#if SPIRAM_RODATA
#if CONFIG_SPIRAM_RODATA
extern void esp_spiram_enable_rodata_access(void);
esp_spiram_enable_rodata_access();
#endif

View file

@ -12,8 +12,6 @@ PROVIDE ( g_ticks_per_us_pro = g_ticks_per_us );
PROVIDE ( g_rom_flashchip = SPI_flashchip_data );
PROVIDE ( g_rom_spiflash_chip = SPI_flashchip_data );
PROVIDE ( esp_rom_spiflash_config_param = SPIParamCfg );
PROVIDE ( esp_rom_spiflash_read = SPIRead );
PROVIDE ( esp_rom_spiflash_read_status = SPI_read_status );
PROVIDE ( esp_rom_spiflash_read_statushigh = SPI_read_status_high );
PROVIDE ( esp_rom_spiflash_read_user_cmd = SPI_user_command_read );
PROVIDE ( esp_rom_spiflash_write = SPIWrite );

View file

@ -105,8 +105,8 @@ extern "C" {
//SPI address register
#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
#define ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM 16
#define ESP_ROM_SPIFLASH_BUFF_BYTE_READ_BITS 0xf
//SPI status register
#define ESP_ROM_SPIFLASH_BUSY_FLAG BIT0

View file

@ -3,7 +3,9 @@ if(BOOTLOADER_BUILD)
if (CONFIG_IDF_TARGET_ESP32)
# ESP32 Bootloader needs SPIUnlock from this file, but doesn't
# need other parts of this component
set(srcs "spi_flash_rom_patch.c")
set(srcs "esp32/spi_flash_rom_patch.c")
elseif (CONFIG_IDF_TARGET_ESP32S2BETA)
set(srcs "esp32s2beta/spi_flash_rom_patch.c")
else()
# but on other platforms no source files are needed for bootloader
set(srcs)
@ -20,7 +22,10 @@ else()
if (CONFIG_IDF_TARGET_ESP32)
list(APPEND srcs
"spi_flash_rom_patch.c")
"esp32/spi_flash_rom_patch.c")
elseif (CONFIG_IDF_TARGET_ESP32S2BETA)
list(APPEND srcs
"esp32s2beta/spi_flash_rom_patch.c")
endif()
# New implementation after IDF v4.0

View file

@ -511,6 +511,7 @@ extern uint32_t esp_spiram_rodata_access_enabled();
spiram_wrap_sizes[0] = icache_wrap_size;
} else {
spiram_wrap_sizes[1] = dcache_wrap_size;
flash_wrap_sizes[1] = dcache_wrap_size;
}
#ifdef CONFIG_EXT_RODATA_SUPPORT
spiram_wrap_sizes[1] = dcache_wrap_size;

View file

@ -7,5 +7,5 @@ COMPONENT_ADD_LDFRAGMENTS += linker.lf
ifdef IS_BOOTLOADER_BUILD
# Bootloader needs updated SPIUnlock from this file
COMPONENT_OBJS := spi_flash_rom_patch.o
COMPONENT_OBJS := esp32/spi_flash_rom_patch.o
endif

View file

@ -12,15 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "sdkconfig.h"
#if CONFIG_IDF_TARGET_ESP32
#include "esp32/rom/ets_sys.h"
#include "esp32/rom/gpio.h"
#include "esp32/rom/spi_flash.h"
#elif CONFIG_IDF_TARGET_ESP32S2BETA
#include "esp32s2beta/rom/ets_sys.h"
#include "esp32s2beta/rom/gpio.h"
#include "esp32s2beta/rom/spi_flash.h"
#endif
#include "soc/spi_periph.h"
@ -80,21 +74,11 @@ esp_rom_spiflash_result_t esp_rom_spiflash_unlock(void)
status &= ESP_ROM_SPIFLASH_QE;
esp_rom_spiflash_wait_idle(&g_rom_spiflash_chip);
#if CONFIG_IDF_TARGET_ESP32
REG_WRITE(SPI_CMD_REG(SPI_IDX), SPI_FLASH_WREN);
while (REG_READ(SPI_CMD_REG(SPI_IDX)) != 0) {
}
#elif CONFIG_IDF_TARGET_ESP32S2BETA
REG_WRITE(SPI_MEM_CMD_REG(SPI_IDX), SPI_MEM_FLASH_WREN);
while (REG_READ(SPI_MEM_CMD_REG(SPI_IDX)) != 0) {
}
#endif
esp_rom_spiflash_wait_idle(&g_rom_spiflash_chip);
#if CONFIG_IDF_TARGET_ESP32
SET_PERI_REG_MASK(SPI_CTRL_REG(SPI_IDX), SPI_WRSR_2B);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
SET_PERI_REG_MASK(SPI_MEM_CTRL_REG(SPI_IDX), SPI_MEM_WRSR_2B);
#endif
if (esp_rom_spiflash_write_status(&g_rom_spiflash_chip, status) != ESP_ROM_SPIFLASH_RESULT_OK) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
@ -102,7 +86,6 @@ esp_rom_spiflash_result_t esp_rom_spiflash_unlock(void)
return ESP_ROM_SPIFLASH_RESULT_OK;
}
#if CONFIG_SPI_FLASH_ROM_DRIVER_PATCH
extern uint8_t g_rom_spiflash_dummy_len_plus[];
@ -116,11 +99,7 @@ static esp_rom_spiflash_result_t esp_rom_spiflash_erase_chip_internal(esp_rom_sp
esp_rom_spiflash_wait_idle(spi);
// Chip erase.
#if CONFIG_IDF_TARGET_ESP32
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_FLASH_CE);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_CE);
#endif
while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0);
// check erase is finished.
@ -141,11 +120,7 @@ static esp_rom_spiflash_result_t esp_rom_spiflash_erase_sector_internal(esp_rom_
// sector erase 4Kbytes erase is sector erase.
WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, addr & 0xffffff);
#if CONFIG_IDF_TARGET_ESP32
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_FLASH_SE);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_SE);
#endif
while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0);
esp_rom_spiflash_wait_idle(spi);
@ -160,11 +135,7 @@ static esp_rom_spiflash_result_t esp_rom_spiflash_erase_block_internal(esp_rom_s
// sector erase 4Kbytes erase is sector erase.
WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, addr & 0xffffff);
#if CONFIG_IDF_TARGET_ESP32
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_FLASH_BE);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_BE);
#endif
while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0);
esp_rom_spiflash_wait_idle(spi);
@ -218,11 +189,7 @@ static esp_rom_spiflash_result_t esp_rom_spiflash_program_page_internal(esp_rom_
}
temp_bl = 0;
}
#if CONFIG_IDF_TARGET_ESP32
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_FLASH_PP);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_PP);
#endif
while ( READ_PERI_REG(PERIPHS_SPI_FLASH_CMD ) != 0 );
esp_rom_spiflash_wait_idle(spi);
@ -231,67 +198,6 @@ static esp_rom_spiflash_result_t esp_rom_spiflash_program_page_internal(esp_rom_
return ESP_ROM_SPIFLASH_RESULT_OK;
}
//only support spi1
static esp_rom_spiflash_result_t esp_rom_spiflash_read_data(esp_rom_spiflash_chip_t *spi, uint32_t flash_addr,
uint32_t *addr_dest, int32_t byte_length)
{
uint32_t temp_addr;
int32_t temp_length;
uint8_t i;
uint8_t remain_word_num;
//address range check
if ((flash_addr + byte_length) > (spi->chip_size)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
temp_addr = flash_addr;
temp_length = byte_length;
esp_rom_spiflash_wait_idle(spi);
while (temp_length > 0) {
if (temp_length >= ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM) {
//WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, temp_addr |(ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM << ESP_ROM_SPIFLASH_BYTES_LEN));
#if CONFIG_IDF_TARGET_ESP32
REG_WRITE(SPI_MISO_DLEN_REG(1), ((ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM << 3) - 1) << SPI_USR_MISO_DBITLEN_S);
WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, temp_addr << 8);
REG_WRITE(PERIPHS_SPI_FLASH_CMD, SPI_USR);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
REG_WRITE(SPI_MEM_MISO_DLEN_REG(1), ((ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM << 3) - 1) << SPI_MEM_USR_MISO_DBITLEN_S);
WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, temp_addr << 8);
REG_WRITE(PERIPHS_SPI_FLASH_CMD, SPI_MEM_USR);
#endif
while (REG_READ(PERIPHS_SPI_FLASH_CMD) != 0);
for (i = 0; i < (ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM >> 2); i++) {
*addr_dest++ = READ_PERI_REG(PERIPHS_SPI_FLASH_C0 + i * 4);
}
temp_length = temp_length - ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM;
temp_addr = temp_addr + ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM;
} else {
//WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, temp_addr |(temp_length << ESP_ROM_SPIFLASH_BYTES_LEN ));
WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, temp_addr << 8);
#if CONFIG_IDF_TARGET_ESP32
REG_WRITE(SPI_MISO_DLEN_REG(1), ((ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM << 3) - 1) << SPI_USR_MISO_DBITLEN_S);
REG_WRITE(PERIPHS_SPI_FLASH_CMD, SPI_USR);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
REG_WRITE(SPI_MEM_MISO_DLEN_REG(1), ((ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM << 3) - 1) << SPI_MEM_USR_MISO_DBITLEN_S);
REG_WRITE(PERIPHS_SPI_FLASH_CMD, SPI_MEM_USR);
#endif
while (REG_READ(PERIPHS_SPI_FLASH_CMD) != 0);
remain_word_num = (0 == (temp_length & 0x3)) ? (temp_length >> 2) : (temp_length >> 2) + 1;
for (i = 0; i < remain_word_num; i++) {
*addr_dest++ = READ_PERI_REG(PERIPHS_SPI_FLASH_C0 + i * 4);
}
temp_length = 0;
}
}
return ESP_ROM_SPIFLASH_RESULT_OK;
}
esp_rom_spiflash_result_t esp_rom_spiflash_read_status(esp_rom_spiflash_chip_t *spi, uint32_t *status)
{
uint32_t status_value = ESP_ROM_SPIFLASH_BUSY_FLAG;
@ -299,11 +205,7 @@ esp_rom_spiflash_result_t esp_rom_spiflash_read_status(esp_rom_spiflash_chip_t *
if (g_rom_spiflash_dummy_len_plus[1] == 0) {
while (ESP_ROM_SPIFLASH_BUSY_FLAG == (status_value & ESP_ROM_SPIFLASH_BUSY_FLAG)) {
WRITE_PERI_REG(PERIPHS_SPI_FLASH_STATUS, 0); // clear regisrter
#if CONFIG_IDF_TARGET_ESP32
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_FLASH_RDSR);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_RDSR);
#endif
while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0);
status_value = READ_PERI_REG(PERIPHS_SPI_FLASH_STATUS) & (spi->status_mask);
@ -333,17 +235,63 @@ esp_rom_spiflash_result_t esp_rom_spiflash_write_status(esp_rom_spiflash_chip_t
// update status value by status_value
WRITE_PERI_REG(PERIPHS_SPI_FLASH_STATUS, status_value); // write status regisrter
#if CONFIG_IDF_TARGET_ESP32
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_FLASH_WRSR);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_WRSR);
#endif
while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0);
esp_rom_spiflash_wait_idle(spi);
return ESP_ROM_SPIFLASH_RESULT_OK;
}
//only support spi1
static esp_rom_spiflash_result_t esp_rom_spiflash_read_data(esp_rom_spiflash_chip_t *spi, uint32_t flash_addr,
uint32_t *addr_dest, int32_t byte_length)
{
uint32_t temp_addr;
int32_t temp_length;
uint8_t i;
uint8_t remain_word_num;
//address range check
if ((flash_addr + byte_length) > (spi->chip_size)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
temp_addr = flash_addr;
temp_length = byte_length;
esp_rom_spiflash_wait_idle(spi);
while (temp_length > 0) {
if (temp_length >= ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM) {
//WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, temp_addr |(ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM << ESP_ROM_SPIFLASH_BYTES_LEN));
REG_WRITE(SPI_MISO_DLEN_REG(1), ((ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM << 3) - 1) << SPI_USR_MISO_DBITLEN_S);
WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, temp_addr << 8);
REG_WRITE(PERIPHS_SPI_FLASH_CMD, SPI_USR);
while (REG_READ(PERIPHS_SPI_FLASH_CMD) != 0);
for (i = 0; i < (ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM >> 2); i++) {
*addr_dest++ = READ_PERI_REG(PERIPHS_SPI_FLASH_C0 + i * 4);
}
temp_length = temp_length - ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM;
temp_addr = temp_addr + ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM;
} else {
//WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, temp_addr |(temp_length << ESP_ROM_SPIFLASH_BYTES_LEN ));
WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, temp_addr << 8);
REG_WRITE(SPI_MISO_DLEN_REG(1), ((ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM << 3) - 1) << SPI_USR_MISO_DBITLEN_S);
REG_WRITE(PERIPHS_SPI_FLASH_CMD, SPI_USR);
while (REG_READ(PERIPHS_SPI_FLASH_CMD) != 0);
remain_word_num = (0 == (temp_length & 0x3)) ? (temp_length >> 2) : (temp_length >> 2) + 1;
for (i = 0; i < remain_word_num; i++) {
*addr_dest++ = READ_PERI_REG(PERIPHS_SPI_FLASH_C0 + i * 4);
}
temp_length = 0;
}
}
return ESP_ROM_SPIFLASH_RESULT_OK;
}
static esp_rom_spiflash_result_t esp_rom_spiflash_enable_write(esp_rom_spiflash_chip_t *spi)
{
uint32_t flash_status = 0;
@ -351,11 +299,7 @@ static esp_rom_spiflash_result_t esp_rom_spiflash_enable_write(esp_rom_spiflash_
esp_rom_spiflash_wait_idle(spi);
//enable write
#if CONFIG_IDF_TARGET_ESP32
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_FLASH_WREN); // enable write operation
#elif CONFIG_IDF_TARGET_ESP32S2BETA
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_WREN); // enable write operation
#endif
while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0);
// make sure the flash is ready for writing
@ -368,7 +312,6 @@ static esp_rom_spiflash_result_t esp_rom_spiflash_enable_write(esp_rom_spiflash_
static void spi_cache_mode_switch(uint32_t modebit)
{
#if CONFIG_IDF_TARGET_ESP32
if ((modebit & SPI_FREAD_QIO) && (modebit & SPI_FASTRD_MODE)) {
REG_CLR_BIT(SPI_USER_REG(0), SPI_USR_MOSI);
REG_SET_BIT(SPI_USER_REG(0), SPI_USR_MISO | SPI_USR_DUMMY | SPI_USR_ADDR);
@ -405,43 +348,6 @@ static void spi_cache_mode_switch(uint32_t modebit)
REG_SET_FIELD(SPI_USER1_REG(0), SPI_USR_ADDR_BITLEN, SPI0_R_SIO_ADDR_BITSLEN);
REG_SET_FIELD(SPI_USER2_REG(0), SPI_USR_COMMAND_VALUE, 0x03);
}
#elif CONFIG_IDF_TARGET_ESP32S2BETA
if ((modebit & SPI_MEM_FREAD_QIO) && (modebit & SPI_MEM_FASTRD_MODE)) {
REG_CLR_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_MOSI);
REG_SET_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_MISO | SPI_MEM_USR_DUMMY | SPI_MEM_USR_ADDR);
REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_ADDR_BITLEN, SPI0_R_QIO_ADDR_BITSLEN);
REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN, SPI0_R_QIO_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[0]);
REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_VALUE, 0xEB);
} else if (modebit & SPI_MEM_FASTRD_MODE) {
REG_CLR_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_MOSI);
REG_SET_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_MISO | SPI_MEM_USR_DUMMY | SPI_MEM_USR_ADDR);
REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_ADDR_BITLEN, SPI0_R_FAST_ADDR_BITSLEN);
if ((modebit & SPI_MEM_FREAD_QUAD)) {
REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_VALUE, 0x6B);
REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN, SPI0_R_FAST_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[0]);
} else if ((modebit & SPI_MEM_FREAD_DIO)) {
REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN, SPI0_R_DIO_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[0]);
REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_VALUE, 0xBB);
} else if ((modebit & SPI_MEM_FREAD_DUAL)) {
REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN, SPI0_R_FAST_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[0]);
REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_VALUE, 0x3B);
} else{
REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN, SPI0_R_FAST_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[0]);
REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_VALUE, 0x0B);
}
} else {
REG_CLR_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_MOSI);
if (g_rom_spiflash_dummy_len_plus[0] == 0) {
REG_CLR_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_DUMMY);
} else {
REG_SET_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_DUMMY);
REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN, g_rom_spiflash_dummy_len_plus[0] - 1);
}
REG_SET_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_MISO | SPI_MEM_USR_ADDR);
REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_ADDR_BITLEN, SPI0_R_SIO_ADDR_BITSLEN);
REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_VALUE, 0x03);
}
#endif
}
esp_rom_spiflash_result_t esp_rom_spiflash_lock(void)
@ -470,50 +376,26 @@ esp_rom_spiflash_result_t esp_rom_spiflash_lock(void)
esp_rom_spiflash_result_t esp_rom_spiflash_config_readmode(esp_rom_spiflash_read_mode_t mode)
{
uint32_t modebit;
#if CONFIG_IDF_TARGET_ESP32
while ((REG_READ(SPI_EXT2_REG(1)) & SPI_ST)) {
}
while ((REG_READ(SPI_EXT2_REG(0)) & SPI_ST)) {
}
#elif CONFIG_IDF_TARGET_ESP32S2BETA
while ((REG_READ(SPI_MEM_FSM_REG(1)) & SPI_MEM_ST)) {
}
while ((REG_READ(SPI_MEM_FSM_REG(0)) & SPI_MEM_ST)) {
}
#endif
//clear old mode bit
#if CONFIG_IDF_TARGET_ESP32
CLEAR_PERI_REG_MASK(PERIPHS_SPI_FLASH_CTRL, SPI_FREAD_QIO | SPI_FREAD_QUAD | SPI_FREAD_DIO | SPI_FREAD_DUAL | SPI_FASTRD_MODE);
CLEAR_PERI_REG_MASK(SPI_CTRL_REG(0), SPI_FREAD_QIO | SPI_FREAD_QUAD | SPI_FREAD_DIO | SPI_FREAD_DUAL | SPI_FASTRD_MODE);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
CLEAR_PERI_REG_MASK(PERIPHS_SPI_FLASH_CTRL, SPI_MEM_FREAD_QIO | SPI_MEM_FREAD_QUAD | SPI_MEM_FREAD_DIO | SPI_MEM_FREAD_DUAL | SPI_MEM_FASTRD_MODE);
CLEAR_PERI_REG_MASK(SPI_MEM_CTRL_REG(0), SPI_MEM_FREAD_QIO | SPI_MEM_FREAD_QUAD | SPI_MEM_FREAD_DIO | SPI_MEM_FREAD_DUAL | SPI_MEM_FASTRD_MODE);
#endif
//configure read mode
switch (mode) {
#if CONFIG_IDF_TARGET_ESP32
case ESP_ROM_SPIFLASH_QIO_MODE : modebit = SPI_FREAD_QIO | SPI_FASTRD_MODE; break;
case ESP_ROM_SPIFLASH_QOUT_MODE : modebit = SPI_FREAD_QUAD | SPI_FASTRD_MODE; break;
case ESP_ROM_SPIFLASH_DIO_MODE : modebit = SPI_FREAD_DIO | SPI_FASTRD_MODE; break;
case ESP_ROM_SPIFLASH_DOUT_MODE : modebit = SPI_FREAD_DUAL | SPI_FASTRD_MODE; break;
case ESP_ROM_SPIFLASH_FASTRD_MODE: modebit = SPI_FASTRD_MODE; break;
#elif CONFIG_IDF_TARGET_ESP32S2BETA
case ESP_ROM_SPIFLASH_QIO_MODE : modebit = SPI_MEM_FREAD_QIO | SPI_MEM_FASTRD_MODE; break;
case ESP_ROM_SPIFLASH_QOUT_MODE : modebit = SPI_MEM_FREAD_QUAD | SPI_MEM_FASTRD_MODE; break;
case ESP_ROM_SPIFLASH_DIO_MODE : modebit = SPI_MEM_FREAD_DIO | SPI_MEM_FASTRD_MODE; break;
case ESP_ROM_SPIFLASH_DOUT_MODE : modebit = SPI_MEM_FREAD_DUAL | SPI_MEM_FASTRD_MODE; break;
case ESP_ROM_SPIFLASH_FASTRD_MODE: modebit = SPI_MEM_FASTRD_MODE; break;
#endif
case ESP_ROM_SPIFLASH_SLOWRD_MODE: modebit = 0; break;
default : modebit = 0;
}
SET_PERI_REG_MASK(PERIPHS_SPI_FLASH_CTRL, modebit);
#if CONFIG_IDF_TARGET_ESP32
SET_PERI_REG_MASK(SPI_CTRL_REG(0), modebit);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
SET_PERI_REG_MASK(SPI_MEM_CTRL_REG(0), modebit);
#endif
spi_cache_mode_switch(modebit);
return ESP_ROM_SPIFLASH_RESULT_OK;
@ -535,13 +417,8 @@ esp_rom_spiflash_result_t esp_rom_spiflash_erase_chip(void)
esp_rom_spiflash_result_t esp_rom_spiflash_erase_block(uint32_t block_num)
{
// flash write is always 1 line currently
#if CONFIG_IDF_TARGET_ESP32
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_DUMMY);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_USR_ADDR_BITLEN, ESP_ROM_SPIFLASH_W_SIO_ADDR_BITSLEN);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, ESP_ROM_SPIFLASH_W_SIO_ADDR_BITSLEN);
#endif
//check program size
if (block_num >= ((g_rom_spiflash_chip.chip_size) / (g_rom_spiflash_chip.block_size))) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
@ -560,13 +437,8 @@ esp_rom_spiflash_result_t esp_rom_spiflash_erase_block(uint32_t block_num)
esp_rom_spiflash_result_t esp_rom_spiflash_erase_sector(uint32_t sector_num)
{
// flash write is always 1 line currently
#if CONFIG_IDF_TARGET_ESP32
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_DUMMY);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_USR_ADDR_BITLEN, ESP_ROM_SPIFLASH_W_SIO_ADDR_BITSLEN);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, ESP_ROM_SPIFLASH_W_SIO_ADDR_BITSLEN);
#endif
//check program size
if (sector_num >= ((g_rom_spiflash_chip.chip_size) / (g_rom_spiflash_chip.sector_size))) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
@ -590,13 +462,8 @@ esp_rom_spiflash_result_t esp_rom_spiflash_write(uint32_t target, const uint32_t
uint8_t i;
// flash write is always 1 line currently
#if CONFIG_IDF_TARGET_ESP32
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_DUMMY);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_USR_ADDR_BITLEN, ESP_ROM_SPIFLASH_W_SIO_ADDR_BITSLEN);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, ESP_ROM_SPIFLASH_W_SIO_ADDR_BITSLEN);
#endif
//check program size
if ( (target + len) > (g_rom_spiflash_chip.chip_size)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
@ -634,7 +501,6 @@ esp_rom_spiflash_result_t esp_rom_spiflash_write(uint32_t target, const uint32_t
return ESP_ROM_SPIFLASH_RESULT_OK;
}
#if CONFIG_IDF_TARGET_ESP32
esp_rom_spiflash_result_t esp_rom_spiflash_write_encrypted(uint32_t flash_addr, uint32_t *data, uint32_t len)
{
esp_rom_spiflash_result_t ret = ESP_ROM_SPIFLASH_RESULT_OK;
@ -660,14 +526,12 @@ esp_rom_spiflash_result_t esp_rom_spiflash_write_encrypted(uint32_t flash_addr,
return ret;
}
#endif
esp_rom_spiflash_result_t esp_rom_spiflash_read(uint32_t target, uint32_t *dest_addr, int32_t len)
{
// QIO or SIO, non-QIO regard as SIO
uint32_t modebit;
modebit = READ_PERI_REG(PERIPHS_SPI_FLASH_CTRL);
#if CONFIG_IDF_TARGET_ESP32
if ((modebit & SPI_FREAD_QIO) && (modebit & SPI_FASTRD_MODE)) {
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_MOSI);
REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_MISO | SPI_USR_DUMMY | SPI_USR_ADDR);
@ -679,44 +543,17 @@ esp_rom_spiflash_result_t esp_rom_spiflash_read(uint32_t target, uint32_t *dest_
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_MOSI);
REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_MISO | SPI_USR_ADDR);
if (modebit & SPI_FREAD_DIO) {
#elif CONFIG_IDF_TARGET_ESP32S2BETA
if ((modebit & SPI_MEM_FREAD_QIO) && (modebit & SPI_MEM_FASTRD_MODE)) {
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_MOSI);
REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_MISO | SPI_MEM_USR_DUMMY | SPI_MEM_USR_ADDR);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, SPI1_R_QIO_ADDR_BITSLEN);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_DUMMY_CYCLELEN, SPI1_R_QIO_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[1]);
//REG_SET_FIELD(PERIPHS_SPI_SPI_MEM_H_USRREG2, SPI_USR_COMMAND_VALUE, 0xEB);
REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_MEM_USR_COMMAND_BITLEN_S) | 0xEB);
} else if (modebit & SPI_MEM_FASTRD_MODE) {
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_MOSI);
REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_MISO | SPI_MEM_USR_ADDR);
if (modebit & SPI_MEM_FREAD_DIO) {
#endif
if (g_rom_spiflash_dummy_len_plus[1] == 0) {
#if CONFIG_IDF_TARGET_ESP32
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_DUMMY);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_USR_ADDR_BITLEN, SPI1_R_DIO_ADDR_BITSLEN);
REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_USR_COMMAND_BITLEN_S) | 0xBB);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, SPI1_R_DIO_ADDR_BITSLEN);
REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_MEM_USR_COMMAND_BITLEN_S) | 0xBB);
#endif
} else {
#if CONFIG_IDF_TARGET_ESP32
REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_DUMMY);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_USR_ADDR_BITLEN, SPI1_R_DIO_ADDR_BITSLEN);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_USR_DUMMY_CYCLELEN, g_rom_spiflash_dummy_len_plus[1] - 1);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG2, SPI_USR_COMMAND_VALUE, 0xBB);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, SPI1_R_DIO_ADDR_BITSLEN);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_DUMMY_CYCLELEN, g_rom_spiflash_dummy_len_plus[1] - 1);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG2, SPI_MEM_USR_COMMAND_VALUE, 0xBB);
#endif
}
} else {
#if CONFIG_IDF_TARGET_ESP32
if ((modebit & SPI_FREAD_QUAD)) {
//REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG2, SPI_USR_COMMAND_VALUE, 0x6B);
REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_USR_COMMAND_BITLEN_S) | 0x6B);
@ -730,21 +567,8 @@ esp_rom_spiflash_result_t esp_rom_spiflash_read(uint32_t target, uint32_t *dest_
REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_DUMMY);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_USR_ADDR_BITLEN, SPI1_R_FAST_ADDR_BITSLEN);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_USR_DUMMY_CYCLELEN, SPI1_R_FAST_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[1]);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
if ((modebit & SPI_MEM_FREAD_QUAD)) {
REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_MEM_USR_COMMAND_BITLEN_S) | 0x6B);
} else if ((modebit & SPI_MEM_FREAD_DUAL)) {
REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_MEM_USR_COMMAND_BITLEN_S) | 0x3B);
} else {
REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_MEM_USR_COMMAND_BITLEN_S) | 0x0B);
}
REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, SPI1_R_FAST_ADDR_BITSLEN);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_DUMMY_CYCLELEN, SPI1_R_FAST_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[1]);
#endif
}
} else {
#if CONFIG_IDF_TARGET_ESP32
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_MOSI);
if (g_rom_spiflash_dummy_len_plus[1] == 0) {
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_DUMMY);
@ -756,18 +580,6 @@ esp_rom_spiflash_result_t esp_rom_spiflash_read(uint32_t target, uint32_t *dest_
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_USR_ADDR_BITLEN, SPI1_R_SIO_ADDR_BITSLEN);
//REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG2, SPI_USR_COMMAND_VALUE, 0x03);
REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_USR_COMMAND_BITLEN_S) | 0x03);
#elif CONFIG_IDF_TARGET_ESP32S2BETA
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_MOSI);
if (g_rom_spiflash_dummy_len_plus[1] == 0) {
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY);
} else {
REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_DUMMY_CYCLELEN, g_rom_spiflash_dummy_len_plus[1] - 1);
}
REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_MISO | SPI_MEM_USR_ADDR);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, SPI1_R_SIO_ADDR_BITSLEN);
REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_MEM_USR_COMMAND_BITLEN_S) | 0x03);
#endif
}
if ( ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_read_data(&g_rom_spiflash_chip, target, dest_addr, len)) {

View file

@ -0,0 +1,621 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "sdkconfig.h"
#include "esp32s2beta/rom/ets_sys.h"
#include "esp32s2beta/rom/gpio.h"
#include "esp32s2beta/rom/spi_flash.h"
#include "soc/spi_periph.h"
#define SPI_IDX 1
#define OTH_IDX 0
extern esp_rom_spiflash_chip_t g_rom_spiflash_chip;
esp_rom_spiflash_result_t esp_rom_spiflash_wait_idle(esp_rom_spiflash_chip_t *spi)
{
uint32_t status;
while ((REG_READ(SPI_MEM_FSM_REG(1)) & SPI_MEM_ST)) {
}
while ((REG_READ(SPI_MEM_FSM_REG(0)) & SPI_MEM_ST)) {
}
//wait for flash status ready
if ( ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_read_status(spi, &status)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
return ESP_ROM_SPIFLASH_RESULT_OK;
}
/* Modified version of esp_rom_spiflash_unlock() that replaces version in ROM.
This works around a bug where esp_rom_spiflash_unlock sometimes reads the wrong
high status byte (RDSR2 result) and then copies it back to the
flash status, which can cause the CMP bit or Status Register
Protect bit to become set.
Like other ROM SPI functions, this function is not designed to be
called directly from an RTOS environment without taking precautions
about interrupts, CPU coordination, flash mapping. However some of
the functions in esp_spi_flash.c call it.
*/
esp_rom_spiflash_result_t esp_rom_spiflash_unlock(void)
{
uint32_t status;
esp_rom_spiflash_wait_idle(&g_rom_spiflash_chip);
if (esp_rom_spiflash_read_statushigh(&g_rom_spiflash_chip, &status) != ESP_ROM_SPIFLASH_RESULT_OK) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
/* Clear all bits except QIE, if it is set.
(This is different from ROM esp_rom_spiflash_unlock, which keeps all bits as-is.)
*/
status &= ESP_ROM_SPIFLASH_QE;
esp_rom_spiflash_wait_idle(&g_rom_spiflash_chip);
REG_WRITE(SPI_MEM_CMD_REG(SPI_IDX), SPI_MEM_FLASH_WREN);
while (REG_READ(SPI_MEM_CMD_REG(SPI_IDX)) != 0) {
}
esp_rom_spiflash_wait_idle(&g_rom_spiflash_chip);
SET_PERI_REG_MASK(SPI_MEM_CTRL_REG(SPI_IDX), SPI_MEM_WRSR_2B);
if (esp_rom_spiflash_write_status(&g_rom_spiflash_chip, status) != ESP_ROM_SPIFLASH_RESULT_OK) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
return ESP_ROM_SPIFLASH_RESULT_OK;
}
#if CONFIG_SPI_FLASH_ROM_DRIVER_PATCH
extern uint8_t g_rom_spiflash_dummy_len_plus[];
static esp_rom_spiflash_result_t esp_rom_spiflash_enable_write(esp_rom_spiflash_chip_t *spi);
//only support spi1
static esp_rom_spiflash_result_t esp_rom_spiflash_erase_chip_internal(esp_rom_spiflash_chip_t *spi)
{
esp_rom_spiflash_wait_idle(spi);
// Chip erase.
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_CE);
while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0);
// check erase is finished.
esp_rom_spiflash_wait_idle(spi);
return ESP_ROM_SPIFLASH_RESULT_OK;
}
//only support spi1
static esp_rom_spiflash_result_t esp_rom_spiflash_erase_sector_internal(esp_rom_spiflash_chip_t *spi, uint32_t addr)
{
//check if addr is 4k alignment
if (0 != (addr & 0xfff)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
esp_rom_spiflash_wait_idle(spi);
// sector erase 4Kbytes erase is sector erase.
WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, addr & 0xffffff);
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_SE);
while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0);
esp_rom_spiflash_wait_idle(spi);
return ESP_ROM_SPIFLASH_RESULT_OK;
}
//only support spi1
static esp_rom_spiflash_result_t esp_rom_spiflash_erase_block_internal(esp_rom_spiflash_chip_t *spi, uint32_t addr)
{
esp_rom_spiflash_wait_idle(spi);
// sector erase 4Kbytes erase is sector erase.
WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, addr & 0xffffff);
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_BE);
while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0);
esp_rom_spiflash_wait_idle(spi);
return ESP_ROM_SPIFLASH_RESULT_OK;
}
//only support spi1
static esp_rom_spiflash_result_t esp_rom_spiflash_program_page_internal(esp_rom_spiflash_chip_t *spi, uint32_t spi_addr,
uint32_t *addr_source, int32_t byte_length)
{
uint32_t temp_addr;
int32_t temp_bl;
uint8_t i;
uint8_t remain_word_num;
//check 4byte alignment
if (0 != (byte_length & 0x3)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
//check if write in one page
if ((spi->page_size) < ((spi_addr % (spi->page_size)) + byte_length)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
esp_rom_spiflash_wait_idle(spi);
temp_addr = spi_addr;
temp_bl = byte_length;
while (temp_bl > 0 ) {
if ( ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_enable_write(spi)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
if ( temp_bl >= ESP_ROM_SPIFLASH_BUFF_BYTE_WRITE_NUM ) {
WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, (temp_addr & 0xffffff) | ( ESP_ROM_SPIFLASH_BUFF_BYTE_WRITE_NUM << ESP_ROM_SPIFLASH_BYTES_LEN )); // 32 byte a block
for (i = 0; i < (ESP_ROM_SPIFLASH_BUFF_BYTE_WRITE_NUM >> 2); i++) {
WRITE_PERI_REG(PERIPHS_SPI_FLASH_C0 + i * 4, *addr_source++);
}
temp_bl = temp_bl - 32;
temp_addr = temp_addr + 32;
} else {
WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, (temp_addr & 0xffffff) | (temp_bl << ESP_ROM_SPIFLASH_BYTES_LEN ));
remain_word_num = (0 == (temp_bl & 0x3)) ? (temp_bl >> 2) : (temp_bl >> 2) + 1;
for (i = 0; i < remain_word_num; i++) {
WRITE_PERI_REG(PERIPHS_SPI_FLASH_C0 + i * 4, *addr_source++);
temp_bl = temp_bl - 4;
}
temp_bl = 0;
}
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_PP);
while ( READ_PERI_REG(PERIPHS_SPI_FLASH_CMD ) != 0 );
esp_rom_spiflash_wait_idle(spi);
}
return ESP_ROM_SPIFLASH_RESULT_OK;
}
esp_rom_spiflash_result_t esp_rom_spiflash_read_status(esp_rom_spiflash_chip_t *spi, uint32_t *status)
{
uint32_t status_value = ESP_ROM_SPIFLASH_BUSY_FLAG;
if (g_rom_spiflash_dummy_len_plus[1] == 0) {
while (ESP_ROM_SPIFLASH_BUSY_FLAG == (status_value & ESP_ROM_SPIFLASH_BUSY_FLAG)) {
WRITE_PERI_REG(PERIPHS_SPI_FLASH_STATUS, 0); // clear regisrter
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_RDSR);
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY);
while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0);
status_value = READ_PERI_REG(PERIPHS_SPI_FLASH_STATUS) & (spi->status_mask);
}
} else {
while (ESP_ROM_SPIFLASH_BUSY_FLAG == (status_value & ESP_ROM_SPIFLASH_BUSY_FLAG)) {
esp_rom_spiflash_read_user_cmd(&status_value, 0x05);
}
}
*status = status_value;
return ESP_ROM_SPIFLASH_RESULT_OK;
}
esp_rom_spiflash_result_t esp_rom_spiflash_read_statushigh(esp_rom_spiflash_chip_t *spi, uint32_t *status)
{
esp_rom_spiflash_result_t ret;
esp_rom_spiflash_wait_idle(&g_rom_spiflash_chip);
ret = esp_rom_spiflash_read_user_cmd(status, 0x35);
*status = *status << 8;
return ret;
}
esp_rom_spiflash_result_t esp_rom_spiflash_write_status(esp_rom_spiflash_chip_t *spi, uint32_t status_value)
{
esp_rom_spiflash_wait_idle(spi);
// update status value by status_value
WRITE_PERI_REG(PERIPHS_SPI_FLASH_STATUS, status_value); // write status regisrter
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_WRSR);
while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0);
esp_rom_spiflash_wait_idle(spi);
return ESP_ROM_SPIFLASH_RESULT_OK;
}
//only support spi1
static esp_rom_spiflash_result_t esp_rom_spiflash_read_data(esp_rom_spiflash_chip_t *spi, uint32_t flash_addr,
uint32_t *addr_dest, int32_t byte_length)
{
uint32_t temp_addr;
int32_t temp_length;
uint8_t i;
uint8_t remain_word_num;
//address range check
if ((flash_addr + byte_length) > (spi->chip_size)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
temp_addr = flash_addr;
temp_length = byte_length;
while (temp_length > 0) {
if (temp_length >= ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM) {
//WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, temp_addr |(ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM << ESP_ROM_SPIFLASH_BYTES_LEN));
REG_WRITE(SPI_MEM_MISO_DLEN_REG(1), ((ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM << 3) - 1) << SPI_MEM_USR_MISO_DBITLEN_S);
WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, temp_addr << 8);
REG_WRITE(PERIPHS_SPI_FLASH_CMD, SPI_MEM_USR);
while (REG_READ(PERIPHS_SPI_FLASH_CMD) != 0);
for (i = 0; i < (ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM >> 2); i++) {
*addr_dest++ = READ_PERI_REG(PERIPHS_SPI_FLASH_C0 + i * 4);
}
temp_length = temp_length - ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM;
temp_addr = temp_addr + ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM;
} else {
//WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, temp_addr |(temp_length << ESP_ROM_SPIFLASH_BYTES_LEN ));
WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, temp_addr << 8);
REG_WRITE(SPI_MEM_MISO_DLEN_REG(1), ((ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM << 3) - 1) << SPI_MEM_USR_MISO_DBITLEN_S);
REG_WRITE(PERIPHS_SPI_FLASH_CMD, SPI_MEM_USR);
while (REG_READ(PERIPHS_SPI_FLASH_CMD) != 0);
remain_word_num = (0 == (temp_length & 0x3)) ? (temp_length >> 2) : (temp_length >> 2) + 1;
for (i = 0; i < remain_word_num; i++) {
*addr_dest++ = READ_PERI_REG(PERIPHS_SPI_FLASH_C0 + i * 4);
}
temp_length = 0;
}
}
return ESP_ROM_SPIFLASH_RESULT_OK;
}
static esp_rom_spiflash_result_t esp_rom_spiflash_enable_write(esp_rom_spiflash_chip_t *spi)
{
uint32_t flash_status = 0;
esp_rom_spiflash_wait_idle(spi);
//enable write
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_WREN); // enable write operation
while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0);
// make sure the flash is ready for writing
while (ESP_ROM_SPIFLASH_WRENABLE_FLAG != (flash_status & ESP_ROM_SPIFLASH_WRENABLE_FLAG)) {
esp_rom_spiflash_read_status(spi, &flash_status);
}
return ESP_ROM_SPIFLASH_RESULT_OK;
}
static void spi_cache_mode_switch(uint32_t modebit)
{
if ((modebit & SPI_MEM_FREAD_QIO) && (modebit & SPI_MEM_FASTRD_MODE)) {
REG_CLR_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_MOSI);
REG_SET_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_MISO | SPI_MEM_USR_DUMMY | SPI_MEM_USR_ADDR);
REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_ADDR_BITLEN, SPI0_R_QIO_ADDR_BITSLEN);
REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN, SPI0_R_QIO_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[0]);
REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_VALUE, 0xEB);
} else if (modebit & SPI_MEM_FASTRD_MODE) {
REG_CLR_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_MOSI);
REG_SET_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_MISO | SPI_MEM_USR_DUMMY | SPI_MEM_USR_ADDR);
REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_ADDR_BITLEN, SPI0_R_FAST_ADDR_BITSLEN);
if ((modebit & SPI_MEM_FREAD_QUAD)) {
REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_VALUE, 0x6B);
REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN, SPI0_R_FAST_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[0]);
} else if ((modebit & SPI_MEM_FREAD_DIO)) {
REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN, SPI0_R_DIO_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[0]);
REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_VALUE, 0xBB);
} else if ((modebit & SPI_MEM_FREAD_DUAL)) {
REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN, SPI0_R_FAST_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[0]);
REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_VALUE, 0x3B);
} else{
REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN, SPI0_R_FAST_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[0]);
REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_VALUE, 0x0B);
}
} else {
REG_CLR_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_MOSI);
if (g_rom_spiflash_dummy_len_plus[0] == 0) {
REG_CLR_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_DUMMY);
} else {
REG_SET_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_DUMMY);
REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN, g_rom_spiflash_dummy_len_plus[0] - 1);
}
REG_SET_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_MISO | SPI_MEM_USR_ADDR);
REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_ADDR_BITLEN, SPI0_R_SIO_ADDR_BITSLEN);
REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_VALUE, 0x03);
}
}
esp_rom_spiflash_result_t esp_rom_spiflash_lock(void)
{
uint32_t status;
//read QE bit, not write if not QE
if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_read_statushigh(&g_rom_spiflash_chip, &status)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
//enable 2 byte status writing
SET_PERI_REG_MASK(PERIPHS_SPI_FLASH_CTRL, ESP_ROM_SPIFLASH_TWO_BYTE_STATUS_EN);
if ( ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_enable_write(&g_rom_spiflash_chip)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
if ( ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_write_status(&g_rom_spiflash_chip, status | ESP_ROM_SPIFLASH_WR_PROTECT)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
return ESP_ROM_SPIFLASH_RESULT_OK;
}
esp_rom_spiflash_result_t esp_rom_spiflash_config_readmode(esp_rom_spiflash_read_mode_t mode)
{
uint32_t modebit;
while ((REG_READ(SPI_MEM_FSM_REG(1)) & SPI_MEM_ST)) {
}
while ((REG_READ(SPI_MEM_FSM_REG(0)) & SPI_MEM_ST)) {
}
//clear old mode bit
CLEAR_PERI_REG_MASK(PERIPHS_SPI_FLASH_CTRL, SPI_MEM_FREAD_QIO | SPI_MEM_FREAD_QUAD | SPI_MEM_FREAD_DIO | SPI_MEM_FREAD_DUAL | SPI_MEM_FASTRD_MODE);
CLEAR_PERI_REG_MASK(SPI_MEM_CTRL_REG(0), SPI_MEM_FREAD_QIO | SPI_MEM_FREAD_QUAD | SPI_MEM_FREAD_DIO | SPI_MEM_FREAD_DUAL | SPI_MEM_FASTRD_MODE);
//configure read mode
switch (mode) {
case ESP_ROM_SPIFLASH_QIO_MODE : modebit = SPI_MEM_FREAD_QIO | SPI_MEM_FASTRD_MODE; break;
case ESP_ROM_SPIFLASH_QOUT_MODE : modebit = SPI_MEM_FREAD_QUAD | SPI_MEM_FASTRD_MODE; break;
case ESP_ROM_SPIFLASH_DIO_MODE : modebit = SPI_MEM_FREAD_DIO | SPI_MEM_FASTRD_MODE; break;
case ESP_ROM_SPIFLASH_DOUT_MODE : modebit = SPI_MEM_FREAD_DUAL | SPI_MEM_FASTRD_MODE; break;
case ESP_ROM_SPIFLASH_FASTRD_MODE: modebit = SPI_MEM_FASTRD_MODE; break;
case ESP_ROM_SPIFLASH_SLOWRD_MODE: modebit = 0; break;
default : modebit = 0;
}
SET_PERI_REG_MASK(PERIPHS_SPI_FLASH_CTRL, modebit);
SET_PERI_REG_MASK(SPI_MEM_CTRL_REG(0), modebit);
spi_cache_mode_switch(modebit);
return ESP_ROM_SPIFLASH_RESULT_OK;
}
esp_rom_spiflash_result_t esp_rom_spiflash_erase_chip(void)
{
if ( ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_enable_write(&g_rom_spiflash_chip)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_erase_chip_internal(&g_rom_spiflash_chip)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
return ESP_ROM_SPIFLASH_RESULT_OK;
}
esp_rom_spiflash_result_t esp_rom_spiflash_erase_block(uint32_t block_num)
{
// flash write is always 1 line currently
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, ESP_ROM_SPIFLASH_W_SIO_ADDR_BITSLEN);
//check program size
if (block_num >= ((g_rom_spiflash_chip.chip_size) / (g_rom_spiflash_chip.block_size))) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
if ( ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_enable_write(&g_rom_spiflash_chip)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_erase_block_internal(&g_rom_spiflash_chip, block_num * (g_rom_spiflash_chip.block_size))) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
return ESP_ROM_SPIFLASH_RESULT_OK;
}
esp_rom_spiflash_result_t esp_rom_spiflash_erase_sector(uint32_t sector_num)
{
// flash write is always 1 line currently
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, ESP_ROM_SPIFLASH_W_SIO_ADDR_BITSLEN);
//check program size
if (sector_num >= ((g_rom_spiflash_chip.chip_size) / (g_rom_spiflash_chip.sector_size))) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
if ( ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_enable_write(&g_rom_spiflash_chip)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_erase_sector_internal(&g_rom_spiflash_chip, sector_num * (g_rom_spiflash_chip.sector_size))) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
return ESP_ROM_SPIFLASH_RESULT_OK;
}
esp_rom_spiflash_result_t esp_rom_spiflash_write(uint32_t target, const uint32_t *src_addr, int32_t len)
{
uint32_t page_size;
uint32_t pgm_len, pgm_num;
uint8_t i;
// flash write is always 1 line currently
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, ESP_ROM_SPIFLASH_W_SIO_ADDR_BITSLEN);
//check program size
if ( (target + len) > (g_rom_spiflash_chip.chip_size)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
page_size = g_rom_spiflash_chip.page_size;
pgm_len = page_size - (target % page_size);
if (len < pgm_len) {
if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_program_page_internal(&g_rom_spiflash_chip,
target, (uint32_t *)src_addr, len)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
} else {
if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_program_page_internal(&g_rom_spiflash_chip,
target, (uint32_t *)src_addr, pgm_len)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
//whole page program
pgm_num = (len - pgm_len) / page_size;
for (i = 0; i < pgm_num; i++) {
if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_program_page_internal(&g_rom_spiflash_chip,
target + pgm_len, (uint32_t *)src_addr + (pgm_len >> 2), page_size)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
pgm_len += page_size;
}
//remain parts to program
if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_program_page_internal(&g_rom_spiflash_chip,
target + pgm_len, (uint32_t *)src_addr + (pgm_len >> 2), len - pgm_len)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
}
return ESP_ROM_SPIFLASH_RESULT_OK;
}
esp_rom_spiflash_result_t esp_rom_spiflash_read(uint32_t target, uint32_t *dest_addr, int32_t len)
{
// QIO or SIO, non-QIO regard as SIO
uint32_t modebit;
esp_rom_spiflash_wait_idle(&g_rom_spiflash_chip);
modebit = READ_PERI_REG(PERIPHS_SPI_FLASH_CTRL);
if ((modebit & SPI_MEM_FREAD_QIO) && (modebit & SPI_MEM_FASTRD_MODE)) {
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_MOSI);
REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_MISO | SPI_MEM_USR_DUMMY | SPI_MEM_USR_ADDR);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, SPI1_R_QIO_ADDR_BITSLEN);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_DUMMY_CYCLELEN, SPI1_R_QIO_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[1]);
//REG_SET_FIELD(PERIPHS_SPI_SPI_MEM_H_USRREG2, SPI_USR_COMMAND_VALUE, 0xEB);
REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_MEM_USR_COMMAND_BITLEN_S) | 0xEB);
} else if (modebit & SPI_MEM_FASTRD_MODE) {
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_MOSI);
REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_MISO | SPI_MEM_USR_ADDR);
if (modebit & SPI_MEM_FREAD_DIO) {
if (g_rom_spiflash_dummy_len_plus[1] == 0) {
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, SPI1_R_DIO_ADDR_BITSLEN);
REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_MEM_USR_COMMAND_BITLEN_S) | 0xBB);
} else {
REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, SPI1_R_DIO_ADDR_BITSLEN);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_DUMMY_CYCLELEN, g_rom_spiflash_dummy_len_plus[1] - 1);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG2, SPI_MEM_USR_COMMAND_VALUE, 0xBB);
}
} else {
if ((modebit & SPI_MEM_FREAD_QUAD)) {
REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_MEM_USR_COMMAND_BITLEN_S) | 0x6B);
} else if ((modebit & SPI_MEM_FREAD_DUAL)) {
REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_MEM_USR_COMMAND_BITLEN_S) | 0x3B);
} else {
REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_MEM_USR_COMMAND_BITLEN_S) | 0x0B);
}
REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, SPI1_R_FAST_ADDR_BITSLEN);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_DUMMY_CYCLELEN, SPI1_R_FAST_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[1]);
}
} else {
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_MOSI);
if (g_rom_spiflash_dummy_len_plus[1] == 0) {
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY);
} else {
REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_DUMMY_CYCLELEN, g_rom_spiflash_dummy_len_plus[1] - 1);
}
REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_MISO | SPI_MEM_USR_ADDR);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, SPI1_R_SIO_ADDR_BITSLEN);
REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_MEM_USR_COMMAND_BITLEN_S) | 0x03);
}
if ( ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_read_data(&g_rom_spiflash_chip, target, dest_addr, len)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
return ESP_ROM_SPIFLASH_RESULT_OK;
}
esp_rom_spiflash_result_t esp_rom_spiflash_erase_area(uint32_t start_addr, uint32_t area_len)
{
int32_t total_sector_num;
int32_t head_sector_num;
uint32_t sector_no;
uint32_t sector_num_per_block;
//set read mode to Fastmode ,not QDIO mode for erase
//
// TODO: this is probably a bug as it doesn't re-enable QIO mode, not serious as this
// function is not used in IDF.
esp_rom_spiflash_config_readmode(ESP_ROM_SPIFLASH_SLOWRD_MODE);
//check if area is oversize of flash
if ((start_addr + area_len) > g_rom_spiflash_chip.chip_size) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
//start_addr is aligned as sector boundary
if (0 != (start_addr % g_rom_spiflash_chip.sector_size)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
//Unlock flash to enable erase
if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_unlock(/*&g_rom_spiflash_chip*/)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
sector_no = start_addr / g_rom_spiflash_chip.sector_size;
sector_num_per_block = g_rom_spiflash_chip.block_size / g_rom_spiflash_chip.sector_size;
total_sector_num = (0 == (area_len % g_rom_spiflash_chip.sector_size)) ? area_len / g_rom_spiflash_chip.sector_size :
1 + (area_len / g_rom_spiflash_chip.sector_size);
//check if erase area reach over block boundary
head_sector_num = sector_num_per_block - (sector_no % sector_num_per_block);
head_sector_num = (head_sector_num >= total_sector_num) ? total_sector_num : head_sector_num;
//JJJ, BUG of 6.0 erase
//middle part of area is aligned by blocks
total_sector_num -= head_sector_num;
//head part of area is erased
while (0 != head_sector_num) {
if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_erase_sector(sector_no)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
sector_no++;
head_sector_num--;
}
while (total_sector_num > sector_num_per_block) {
if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_erase_block(sector_no / sector_num_per_block)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
sector_no += sector_num_per_block;
total_sector_num -= sector_num_per_block;
}
//tail part of area burn
while (0 < total_sector_num) {
if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_erase_sector(sector_no)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
sector_no++;
total_sector_num--;
}
return ESP_ROM_SPIFLASH_RESULT_OK;
}
#endif