spi_flash: Support flash wrap (burst read), flash driver side

pull/10747/head
Cao Sen Miao 2023-02-10 14:51:11 +08:00
rodzic 254efe402e
commit 0d37436f36
34 zmienionych plików z 343 dodań i 581 usunięć

Wyświetl plik

@ -25,16 +25,6 @@ extern "C" {
*/ */
uint32_t bootloader_read_flash_id(void); uint32_t bootloader_read_flash_id(void);
#if SOC_CACHE_SUPPORT_WRAP
/**
* @brief Set the burst mode setting command for specified wrap mode.
*
* @param mode The specified warp mode.
* @return always ESP_OK
*/
esp_err_t bootloader_flash_wrap_set(spi_flash_wrap_mode_t mode);
#endif
/** /**
* @brief Startup flow recommended by XMC. Call at startup before any erase/write operation. * @brief Startup flow recommended by XMC. Call at startup before any erase/write operation.
* *

Wyświetl plik

@ -49,7 +49,6 @@ extern "C" {
#define CMD_RDSR3 0x15 /* Not all SPI flash uses this command */ #define CMD_RDSR3 0x15 /* Not all SPI flash uses this command */
#define CMD_OTPEN 0x3A /* Enable OTP mode, not all SPI flash uses this command */ #define CMD_OTPEN 0x3A /* Enable OTP mode, not all SPI flash uses this command */
#define CMD_RDSFDP 0x5A /* Read the SFDP of the flash */ #define CMD_RDSFDP 0x5A /* Read the SFDP of the flash */
#define CMD_WRAP 0x77 /* Set burst with wrap command */
#define CMD_RESUME 0x7A /* Resume command to clear flash suspend bit */ #define CMD_RESUME 0x7A /* Resume command to clear flash suspend bit */
#define CMD_RESETEN 0x66 #define CMD_RESETEN 0x66
#define CMD_RESET 0x99 #define CMD_RESET 0x99

Wyświetl plik

@ -606,38 +606,6 @@ void bootloader_spi_flash_reset(void)
bootloader_execute_flash_command(CMD_RESET, 0, 0, 0); bootloader_execute_flash_command(CMD_RESET, 0, 0, 0);
} }
#if SOC_CACHE_SUPPORT_WRAP
esp_err_t bootloader_flash_wrap_set(spi_flash_wrap_mode_t mode)
{
uint32_t reg_bkp_ctrl = SPIFLASH.ctrl.val;
uint32_t reg_bkp_usr = SPIFLASH.user.val;
SPIFLASH.user.fwrite_dio = 0;
SPIFLASH.user.fwrite_dual = 0;
SPIFLASH.user.fwrite_qio = 1;
SPIFLASH.user.fwrite_quad = 0;
SPIFLASH.ctrl.fcmd_dual = 0;
SPIFLASH.ctrl.fcmd_quad = 0;
SPIFLASH.user.usr_dummy = 0;
SPIFLASH.user.usr_addr = 1;
SPIFLASH.user.usr_command = 1;
SPIFLASH.user2.usr_command_bitlen = 7;
SPIFLASH.user2.usr_command_value = CMD_WRAP;
SPIFLASH.user1.usr_addr_bitlen = 23;
SPIFLASH.addr = 0;
SPIFLASH.user.usr_miso = 0;
SPIFLASH.user.usr_mosi = 1;
SPIFLASH.mosi_dlen.usr_mosi_bit_len = 7;
SPIFLASH.data_buf[0] = (uint32_t) mode << 4;;
SPIFLASH.cmd.usr = 1;
while(SPIFLASH.cmd.usr != 0)
{ }
SPIFLASH.ctrl.val = reg_bkp_ctrl;
SPIFLASH.user.val = reg_bkp_usr;
return ESP_OK;
}
#endif //SOC_CACHE_SUPPORT_WRAP
/******************************************************************************* /*******************************************************************************
* XMC startup flow * XMC startup flow
******************************************************************************/ ******************************************************************************/

Wyświetl plik

@ -17,6 +17,7 @@
#include "flash_qio_mode.h" #include "flash_qio_mode.h"
#include "soc/efuse_periph.h" #include "soc/efuse_periph.h"
#include "soc/io_mux_reg.h" #include "soc/io_mux_reg.h"
#include "esp_private/spi_flash_os.h"
static const char *TAG = "qio_mode"; static const char *TAG = "qio_mode";
@ -96,7 +97,8 @@ void bootloader_enable_qio_mode(void)
bootloader_flash_qe_support_list[i].write_status_fn, bootloader_flash_qe_support_list[i].write_status_fn,
bootloader_flash_qe_support_list[i].status_qio_bit); bootloader_flash_qe_support_list[i].status_qio_bit);
#if SOC_CACHE_SUPPORT_WRAP #if SOC_CACHE_SUPPORT_WRAP
bootloader_flash_wrap_set(FLASH_WRAP_MODE_DISABLE); spi_flash_wrap_probe();
spi_flash_wrap_disable();
#endif #endif
} }

Wyświetl plik

@ -443,6 +443,10 @@ config SOC_SPI_MEM_SUPPORT_CHECK_SUS
bool bool
default y default y
config SOC_SPI_MEM_SUPPORT_WRAP
bool
default y
config SOC_MEMSPI_SRC_FREQ_60M_SUPPORTED config SOC_MEMSPI_SRC_FREQ_60M_SUPPORTED
bool bool
default y default y

Wyświetl plik

@ -222,6 +222,7 @@
#define SOC_SPI_MEM_SUPPORT_IDLE_INTR (1) #define SOC_SPI_MEM_SUPPORT_IDLE_INTR (1)
#define SOC_SPI_MEM_SUPPORT_SW_SUSPEND (1) #define SOC_SPI_MEM_SUPPORT_SW_SUSPEND (1)
#define SOC_SPI_MEM_SUPPORT_CHECK_SUS (1) #define SOC_SPI_MEM_SUPPORT_CHECK_SUS (1)
#define SOC_SPI_MEM_SUPPORT_WRAP (1)
#define SOC_MEMSPI_SRC_FREQ_60M_SUPPORTED 1 #define SOC_MEMSPI_SRC_FREQ_60M_SUPPORTED 1
#define SOC_MEMSPI_SRC_FREQ_30M_SUPPORTED 1 #define SOC_MEMSPI_SRC_FREQ_30M_SUPPORTED 1

Wyświetl plik

@ -659,6 +659,10 @@ config SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE
bool bool
default y default y
config SOC_SPI_MEM_SUPPORT_WRAP
bool
default y
config SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED config SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED
bool bool
default y default y

Wyświetl plik

@ -305,6 +305,7 @@
#define SOC_SPI_MEM_SUPPORT_SW_SUSPEND (1) #define SOC_SPI_MEM_SUPPORT_SW_SUSPEND (1)
#define SOC_SPI_MEM_SUPPORT_CHECK_SUS (1) #define SOC_SPI_MEM_SUPPORT_CHECK_SUS (1)
#define SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE (1) #define SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE (1)
#define SOC_SPI_MEM_SUPPORT_WRAP (1)
#define SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED 1 #define SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED 1
#define SOC_MEMSPI_SRC_FREQ_40M_SUPPORTED 1 #define SOC_MEMSPI_SRC_FREQ_40M_SUPPORTED 1

Wyświetl plik

@ -795,6 +795,10 @@ config SOC_SPI_MEM_SUPPORT_CHECK_SUS
bool bool
default y default y
config SOC_SPI_MEM_SUPPORT_WRAP
bool
default y
config SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED config SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED
bool bool
default y default y

Wyświetl plik

@ -340,6 +340,7 @@
#define SOC_SPI_MEM_SUPPORT_IDLE_INTR (1) #define SOC_SPI_MEM_SUPPORT_IDLE_INTR (1)
#define SOC_SPI_MEM_SUPPORT_SW_SUSPEND (1) #define SOC_SPI_MEM_SUPPORT_SW_SUSPEND (1)
#define SOC_SPI_MEM_SUPPORT_CHECK_SUS (1) #define SOC_SPI_MEM_SUPPORT_CHECK_SUS (1)
#define SOC_SPI_MEM_SUPPORT_WRAP (1)
#define SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED 1 #define SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED 1
#define SOC_MEMSPI_SRC_FREQ_40M_SUPPORTED 1 #define SOC_MEMSPI_SRC_FREQ_40M_SUPPORTED 1

Wyświetl plik

@ -691,6 +691,10 @@ config SOC_SPI_MEM_SUPPORT_CHECK_SUS
bool bool
default y default y
config SOC_SPI_MEM_SUPPORT_WRAP
bool
default y
config SOC_MEMSPI_SRC_FREQ_48M_SUPPORTED config SOC_MEMSPI_SRC_FREQ_48M_SUPPORTED
bool bool
default y default y

Wyświetl plik

@ -338,6 +338,7 @@
#define SOC_SPI_MEM_SUPPORT_IDLE_INTR (1) #define SOC_SPI_MEM_SUPPORT_IDLE_INTR (1)
#define SOC_SPI_MEM_SUPPORT_SW_SUSPEND (1) #define SOC_SPI_MEM_SUPPORT_SW_SUSPEND (1)
#define SOC_SPI_MEM_SUPPORT_CHECK_SUS (1) #define SOC_SPI_MEM_SUPPORT_CHECK_SUS (1)
#define SOC_SPI_MEM_SUPPORT_WRAP (1)
#define SOC_MEMSPI_SRC_FREQ_48M_SUPPORTED 1 #define SOC_MEMSPI_SRC_FREQ_48M_SUPPORTED 1

Wyświetl plik

@ -627,6 +627,10 @@ config SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE
bool bool
default y default y
config SOC_SPI_MEM_SUPPORT_WRAP
bool
default y
config SOC_MEMSPI_SRC_FREQ_48M_SUPPORTED config SOC_MEMSPI_SRC_FREQ_48M_SUPPORTED
bool bool
default y default y

Wyświetl plik

@ -310,6 +310,7 @@
#define SOC_SPI_MEM_SUPPORT_SW_SUSPEND (1) #define SOC_SPI_MEM_SUPPORT_SW_SUSPEND (1)
#define SOC_SPI_MEM_SUPPORT_CHECK_SUS (1) #define SOC_SPI_MEM_SUPPORT_CHECK_SUS (1)
#define SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE (1) #define SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE (1)
#define SOC_SPI_MEM_SUPPORT_WRAP (1)
#define SOC_MEMSPI_SRC_FREQ_48M_SUPPORTED 1 #define SOC_MEMSPI_SRC_FREQ_48M_SUPPORTED 1
#define SOC_MEMSPI_SRC_FREQ_24M_SUPPORTED 1 #define SOC_MEMSPI_SRC_FREQ_24M_SUPPORTED 1

Wyświetl plik

@ -931,6 +931,10 @@ config SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE
bool bool
default y default y
config SOC_SPI_MEM_SUPPORT_WRAP
bool
default y
config SOC_PM_SUPPORT_EXT_WAKEUP config SOC_PM_SUPPORT_EXT_WAKEUP
bool bool
default y default y

Wyświetl plik

@ -407,6 +407,7 @@
#define SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND (1) #define SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND (1)
#define SOC_SPI_MEM_SUPPORT_SW_SUSPEND (1) #define SOC_SPI_MEM_SUPPORT_SW_SUSPEND (1)
#define SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE (1) #define SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE (1)
#define SOC_SPI_MEM_SUPPORT_WRAP (1)
/*-------------------------- Power Management CAPS ---------------------------*/ /*-------------------------- Power Management CAPS ---------------------------*/
#define SOC_PM_SUPPORT_EXT_WAKEUP (1) #define SOC_PM_SUPPORT_EXT_WAKEUP (1)

Wyświetl plik

@ -1143,6 +1143,10 @@ config SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE
bool bool
default y default y
config SOC_SPI_MEM_SUPPORT_WRAP
bool
default y
config SOC_COEX_HW_PTI config SOC_COEX_HW_PTI
bool bool
default y default y

Wyświetl plik

@ -465,6 +465,7 @@
#define SOC_SPI_MEM_SUPPORT_OPI_MODE (1) #define SOC_SPI_MEM_SUPPORT_OPI_MODE (1)
#define SOC_SPI_MEM_SUPPORT_TIME_TUNING (1) #define SOC_SPI_MEM_SUPPORT_TIME_TUNING (1)
#define SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE (1) #define SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE (1)
#define SOC_SPI_MEM_SUPPORT_WRAP (1)
/*-------------------------- COEXISTENCE HARDWARE PTI CAPS -------------------------------*/ /*-------------------------- COEXISTENCE HARDWARE PTI CAPS -------------------------------*/
#define SOC_COEX_HW_PTI (1) #define SOC_COEX_HW_PTI (1)

Wyświetl plik

@ -4,7 +4,7 @@ if(${target} STREQUAL "linux")
endif() endif()
if(BOOTLOADER_BUILD OR CONFIG_APP_BUILD_TYPE_PURE_RAM_APP) if(BOOTLOADER_BUILD OR CONFIG_APP_BUILD_TYPE_PURE_RAM_APP)
set(cache_srcs "") set(srcs "spi_flash_wrap.c")
set(priv_requires bootloader_support soc) set(priv_requires bootloader_support soc)
else() else()
set(srcs "flash_brownout_hook.c") set(srcs "flash_brownout_hook.c")
@ -35,7 +35,7 @@ else()
"cache_utils.c" "cache_utils.c"
"flash_mmap.c" "flash_mmap.c"
"flash_ops.c" "flash_ops.c"
"${target}/flash_ops_${target}.c" "spi_flash_wrap.c"
) )
list(APPEND cache_srcs list(APPEND cache_srcs

Wyświetl plik

@ -55,6 +55,8 @@
#include "esp_memory_utils.h" #include "esp_memory_utils.h"
#include "esp_intr_alloc.h" #include "esp_intr_alloc.h"
#include "spi_flash_mmap.h" #include "spi_flash_mmap.h"
#include "spi_flash_override.h"
#include "esp_private/spi_flash_os.h"
#include "esp_log.h" #include "esp_log.h"
#include "esp_cpu.h" #include "esp_cpu.h"
@ -555,16 +557,16 @@ esp_err_t esp_enable_cache_wrap(bool icache_wrap_enable, bool dcache_wrap_enable
if (icache_wrap_enable) { if (icache_wrap_enable) {
#if CONFIG_ESP32S2_INSTRUCTION_CACHE_LINE_16B || CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_16B #if CONFIG_ESP32S2_INSTRUCTION_CACHE_LINE_16B || CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_16B
icache_wrap_size = 16; icache_wrap_size = FLASH_WRAP_SIZE_16B;
#else #else
icache_wrap_size = 32; icache_wrap_size = FLASH_WRAP_SIZE_32B;
#endif #endif
} }
if (dcache_wrap_enable) { if (dcache_wrap_enable) {
#if CONFIG_ESP32S2_DATA_CACHE_LINE_16B || CONFIG_ESP32S3_DATA_CACHE_LINE_16B #if CONFIG_ESP32S2_DATA_CACHE_LINE_16B || CONFIG_ESP32S3_DATA_CACHE_LINE_16B
dcache_wrap_size = 16; dcache_wrap_size = FLASH_WRAP_SIZE_16B;
#else #else
dcache_wrap_size = 32; dcache_wrap_size = FLASH_WRAP_SIZE_32B;
#endif #endif
} }
@ -647,7 +649,6 @@ esp_err_t esp_enable_cache_wrap(bool icache_wrap_enable, bool dcache_wrap_enable
#ifdef CONFIG_ESPTOOLPY_FLASHMODE_QIO #ifdef CONFIG_ESPTOOLPY_FLASHMODE_QIO
flash_support_wrap = true; flash_support_wrap = true;
extern bool spi_flash_support_wrap_size(uint32_t wrap_size);
if (!spi_flash_support_wrap_size(flash_wrap_size)) { if (!spi_flash_support_wrap_size(flash_wrap_size)) {
flash_support_wrap = false; flash_support_wrap = false;
ESP_EARLY_LOGW(TAG, "Flash do not support wrap size %d.", flash_wrap_size); ESP_EARLY_LOGW(TAG, "Flash do not support wrap size %d.", flash_wrap_size);
@ -669,10 +670,9 @@ esp_err_t esp_enable_cache_wrap(bool icache_wrap_enable, bool dcache_wrap_enable
return ESP_FAIL; return ESP_FAIL;
} }
extern esp_err_t spi_flash_enable_wrap(uint32_t wrap_size);
if (flash_support_wrap && flash_wrap_size > 0) { if (flash_support_wrap && flash_wrap_size > 0) {
ESP_EARLY_LOGI(TAG, "Flash wrap enabled, size = %d.", flash_wrap_size); ESP_EARLY_LOGI(TAG, "Flash wrap enabled, size = %d.", flash_wrap_size);
spi_flash_enable_wrap(flash_wrap_size); spI_flash_wrap_enable(flash_wrap_size);
esp_enable_cache_flash_wrap((flash_wrap_sizes[0] > 0), (flash_wrap_sizes[1] > 0)); esp_enable_cache_flash_wrap((flash_wrap_sizes[0] > 0), (flash_wrap_sizes[1] > 0));
} }
#if (CONFIG_IDF_TARGET_ESP32S2 && CONFIG_SPIRAM) #if (CONFIG_IDF_TARGET_ESP32S2 && CONFIG_SPIRAM)
@ -801,20 +801,20 @@ esp_err_t esp_enable_cache_wrap(bool icache_wrap_enable, bool dcache_wrap_enable
if (icache_wrap_enable) { if (icache_wrap_enable) {
#if CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_16B #if CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_16B
icache_wrap_size = 16; icache_wrap_size = FLASH_WRAP_SIZE_16B;
#elif CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_32B #elif CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_32B
icache_wrap_size = 32; icache_wrap_size = FLASH_WRAP_SIZE_32B;
#else #else
icache_wrap_size = 64; icache_wrap_size = FLASH_WRAP_SIZE_64B;
#endif #endif
} }
if (dcache_wrap_enable) { if (dcache_wrap_enable) {
#if CONFIG_ESP32S3_DATA_CACHE_LINE_16B #if CONFIG_ESP32S3_DATA_CACHE_LINE_16B
dcache_wrap_size = 16; dcache_wrap_size = FLASH_WRAP_SIZE_16B;
#elif CONFIG_ESP32S3_DATA_CACHE_LINE_32B #elif CONFIG_ESP32S3_DATA_CACHE_LINE_32B
dcache_wrap_size = 32; dcache_wrap_size = FLASH_WRAP_SIZE_32B;
#else #else
dcache_wrap_size = 64; dcache_wrap_size = FLASH_WRAP_SIZE_64B;
#endif #endif
} }
@ -895,7 +895,6 @@ esp_err_t esp_enable_cache_wrap(bool icache_wrap_enable, bool dcache_wrap_enable
#ifdef CONFIG_ESPTOOLPY_FLASHMODE_QIO #ifdef CONFIG_ESPTOOLPY_FLASHMODE_QIO
flash_support_wrap = true; flash_support_wrap = true;
extern bool spi_flash_support_wrap_size(uint32_t wrap_size);
if (!spi_flash_support_wrap_size(flash_wrap_size)) { if (!spi_flash_support_wrap_size(flash_wrap_size)) {
flash_support_wrap = false; flash_support_wrap = false;
ESP_EARLY_LOGW(TAG, "Flash do not support wrap size %d.", flash_wrap_size); ESP_EARLY_LOGW(TAG, "Flash do not support wrap size %d.", flash_wrap_size);
@ -918,10 +917,9 @@ esp_err_t esp_enable_cache_wrap(bool icache_wrap_enable, bool dcache_wrap_enable
return ESP_FAIL; return ESP_FAIL;
} }
extern esp_err_t spi_flash_enable_wrap(uint32_t wrap_size);
if (flash_support_wrap && flash_wrap_size > 0) { if (flash_support_wrap && flash_wrap_size > 0) {
ESP_EARLY_LOGI(TAG, "Flash wrap enabled, size = %d.", flash_wrap_size); ESP_EARLY_LOGI(TAG, "Flash wrap enabled, size = %d.", flash_wrap_size);
spi_flash_enable_wrap(flash_wrap_size); spI_flash_wrap_enable(flash_wrap_size);
esp_enable_cache_flash_wrap((flash_wrap_sizes[0] > 0), (flash_wrap_sizes[1] > 0)); esp_enable_cache_flash_wrap((flash_wrap_sizes[0] > 0), (flash_wrap_sizes[1] > 0));
} }
#if (CONFIG_IDF_TARGET_ESP32S3 && CONFIG_SPIRAM) #if (CONFIG_IDF_TARGET_ESP32S3 && CONFIG_SPIRAM)
@ -963,7 +961,6 @@ esp_err_t esp_enable_cache_wrap(bool icache_wrap_enable)
#ifdef CONFIG_ESPTOOLPY_FLASHMODE_QIO #ifdef CONFIG_ESPTOOLPY_FLASHMODE_QIO
flash_support_wrap = true; flash_support_wrap = true;
extern bool spi_flash_support_wrap_size(uint32_t wrap_size);
if (!spi_flash_support_wrap_size(flash_wrap_size)) { if (!spi_flash_support_wrap_size(flash_wrap_size)) {
flash_support_wrap = false; flash_support_wrap = false;
ESP_EARLY_LOGW(TAG, "Flash do not support wrap size %d.", flash_wrap_size); ESP_EARLY_LOGW(TAG, "Flash do not support wrap size %d.", flash_wrap_size);
@ -972,10 +969,9 @@ esp_err_t esp_enable_cache_wrap(bool icache_wrap_enable)
ESP_EARLY_LOGW(TAG, "Flash is not in QIO mode, do not support wrap."); ESP_EARLY_LOGW(TAG, "Flash is not in QIO mode, do not support wrap.");
#endif // CONFIG_ESPTOOLPY_FLASHMODE_QIO #endif // CONFIG_ESPTOOLPY_FLASHMODE_QIO
extern esp_err_t spi_flash_enable_wrap(uint32_t wrap_size);
if (flash_support_wrap && flash_wrap_size > 0) { if (flash_support_wrap && flash_wrap_size > 0) {
ESP_EARLY_LOGI(TAG, "Flash wrap enabled, size = %d.", flash_wrap_size); ESP_EARLY_LOGI(TAG, "Flash wrap enabled, size = %d.", flash_wrap_size);
spi_flash_enable_wrap(flash_wrap_size); spI_flash_wrap_enable(flash_wrap_size);
esp_enable_cache_flash_wrap((flash_wrap_size > 0)); esp_enable_cache_flash_wrap((flash_wrap_size > 0));
} }
return ESP_OK; return ESP_OK;

Wyświetl plik

@ -1,5 +0,0 @@
/*
* SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/

Wyświetl plik

@ -1,91 +0,0 @@
/*
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include <sys/param.h>
#include "spi_flash_mmap.h"
#include "soc/system_reg.h"
#include "soc/soc_memory_layout.h"
#include "esp32c2/rom/cache.h"
#include "hal/spi_flash_hal.h"
#include "esp_flash.h"
#include "esp_log.h"
#include "esp_attr.h"
#include "esp_rom_spiflash.h"
#include "esp_private/spi_flash_os.h"
#define SPICACHE SPIMEM0
#define SPIFLASH SPIMEM1
#define FLASH_WRAP_CMD 0x77
esp_err_t spi_flash_wrap_set(spi_flash_wrap_mode_t mode)
{
uint32_t reg_bkp_ctrl = SPIFLASH.ctrl.val;
uint32_t reg_bkp_usr = SPIFLASH.user.val;
SPIFLASH.user.fwrite_dio = 0;
SPIFLASH.user.fwrite_dual = 0;
SPIFLASH.user.fwrite_qio = 1;
SPIFLASH.user.fwrite_quad = 0;
SPIFLASH.ctrl.fcmd_dual = 0;
SPIFLASH.ctrl.fcmd_quad = 0;
SPIFLASH.user.usr_dummy = 0;
SPIFLASH.user.usr_addr = 1;
SPIFLASH.user.usr_command = 1;
SPIFLASH.user2.usr_command_bitlen = 7;
SPIFLASH.user2.usr_command_value = FLASH_WRAP_CMD;
SPIFLASH.user1.usr_addr_bitlen = 23;
SPIFLASH.addr = 0;
SPIFLASH.user.usr_miso = 0;
SPIFLASH.user.usr_mosi = 1;
SPIFLASH.mosi_dlen.usr_mosi_bit_len = 7;
SPIFLASH.data_buf[0] = (uint32_t) mode << 4;;
SPIFLASH.cmd.usr = 1;
while (SPIFLASH.cmd.usr != 0)
{ }
SPIFLASH.ctrl.val = reg_bkp_ctrl;
SPIFLASH.user.val = reg_bkp_usr;
return ESP_OK;
}
esp_err_t spi_flash_enable_wrap(uint32_t wrap_size)
{
switch (wrap_size) {
case 8:
return spi_flash_wrap_set(FLASH_WRAP_MODE_8B);
case 16:
return spi_flash_wrap_set(FLASH_WRAP_MODE_16B);
case 32:
return spi_flash_wrap_set(FLASH_WRAP_MODE_32B);
case 64:
return spi_flash_wrap_set(FLASH_WRAP_MODE_64B);
default:
return ESP_FAIL;
}
}
void spi_flash_disable_wrap(void)
{
spi_flash_wrap_set(FLASH_WRAP_MODE_DISABLE);
}
bool spi_flash_support_wrap_size(uint32_t wrap_size)
{
if (!REG_GET_BIT(SPI_MEM_CTRL_REG(0), SPI_MEM_FREAD_QIO) || !REG_GET_BIT(SPI_MEM_CTRL_REG(0), SPI_MEM_FASTRD_MODE)) {
return ESP_FAIL;
}
switch (wrap_size) {
case 0:
case 8:
case 16:
case 32:
case 64:
return true;
default:
return false;
}
}

Wyświetl plik

@ -1,91 +0,0 @@
/*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include <sys/param.h>
#include "spi_flash_mmap.h"
#include "soc/system_reg.h"
#include "soc/soc_memory_layout.h"
#include "esp32c3/rom/cache.h"
#include "hal/spi_flash_hal.h"
#include "esp_flash.h"
#include "esp_log.h"
#include "esp_attr.h"
#include "esp_rom_spiflash.h"
#include "esp_private/spi_flash_os.h"
#define SPICACHE SPIMEM0
#define SPIFLASH SPIMEM1
#define FLASH_WRAP_CMD 0x77
esp_err_t spi_flash_wrap_set(spi_flash_wrap_mode_t mode)
{
uint32_t reg_bkp_ctrl = SPIFLASH.ctrl.val;
uint32_t reg_bkp_usr = SPIFLASH.user.val;
SPIFLASH.user.fwrite_dio = 0;
SPIFLASH.user.fwrite_dual = 0;
SPIFLASH.user.fwrite_qio = 1;
SPIFLASH.user.fwrite_quad = 0;
SPIFLASH.ctrl.fcmd_dual = 0;
SPIFLASH.ctrl.fcmd_quad = 0;
SPIFLASH.user.usr_dummy = 0;
SPIFLASH.user.usr_addr = 1;
SPIFLASH.user.usr_command = 1;
SPIFLASH.user2.usr_command_bitlen = 7;
SPIFLASH.user2.usr_command_value = FLASH_WRAP_CMD;
SPIFLASH.user1.usr_addr_bitlen = 23;
SPIFLASH.addr = 0;
SPIFLASH.user.usr_miso = 0;
SPIFLASH.user.usr_mosi = 1;
SPIFLASH.mosi_dlen.usr_mosi_bit_len = 7;
SPIFLASH.data_buf[0] = (uint32_t) mode << 4;;
SPIFLASH.cmd.usr = 1;
while (SPIFLASH.cmd.usr != 0)
{ }
SPIFLASH.ctrl.val = reg_bkp_ctrl;
SPIFLASH.user.val = reg_bkp_usr;
return ESP_OK;
}
esp_err_t spi_flash_enable_wrap(uint32_t wrap_size)
{
switch (wrap_size) {
case 8:
return spi_flash_wrap_set(FLASH_WRAP_MODE_8B);
case 16:
return spi_flash_wrap_set(FLASH_WRAP_MODE_16B);
case 32:
return spi_flash_wrap_set(FLASH_WRAP_MODE_32B);
case 64:
return spi_flash_wrap_set(FLASH_WRAP_MODE_64B);
default:
return ESP_FAIL;
}
}
void spi_flash_disable_wrap(void)
{
spi_flash_wrap_set(FLASH_WRAP_MODE_DISABLE);
}
bool spi_flash_support_wrap_size(uint32_t wrap_size)
{
if (!REG_GET_BIT(SPI_MEM_CTRL_REG(0), SPI_MEM_FREAD_QIO) || !REG_GET_BIT(SPI_MEM_CTRL_REG(0), SPI_MEM_FASTRD_MODE)) {
return ESP_FAIL;
}
switch (wrap_size) {
case 0:
case 8:
case 16:
case 32:
case 64:
return true;
default:
return false;
}
}

Wyświetl plik

@ -1,91 +0,0 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include <sys/param.h>
#include "spi_flash_mmap.h"
#include "soc/soc_memory_layout.h"
#include "esp32c6/rom/cache.h"
#include "hal/spi_flash_hal.h"
#include "esp_flash.h"
#include "esp_log.h"
#include "esp_attr.h"
#include "esp_rom_spiflash.h"
#include "esp_private/spi_flash_os.h"
#define SPICACHE SPIMEM0
#define SPIFLASH SPIMEM1
#define FLASH_WRAP_CMD 0x77
esp_err_t spi_flash_wrap_set(spi_flash_wrap_mode_t mode)
{
uint32_t reg_bkp_ctrl = SPIFLASH.ctrl.val;
uint32_t reg_bkp_usr = SPIFLASH.user.val;
SPIFLASH.user.fwrite_dio = 0;
SPIFLASH.user.fwrite_dual = 0;
SPIFLASH.user.fwrite_qio = 1;
SPIFLASH.user.fwrite_quad = 0;
SPIFLASH.ctrl.fcmd_quad = 0;
SPIFLASH.user.usr_dummy = 0;
SPIFLASH.user.usr_addr = 1;
SPIFLASH.user.usr_command = 1;
SPIFLASH.user2.usr_command_bitlen = 7;
SPIFLASH.user2.usr_command_value = FLASH_WRAP_CMD;
SPIFLASH.user1.usr_addr_bitlen = 23;
SPIFLASH.addr = 0;
SPIFLASH.user.usr_miso = 0;
SPIFLASH.user.usr_mosi = 1;
SPIFLASH.mosi_dlen.usr_mosi_bit_len = 7;
SPIFLASH.data_buf[0] = (uint32_t) mode << 4;;
SPIFLASH.cmd.usr = 1;
while (SPIFLASH.cmd.usr != 0)
{ }
SPIFLASH.ctrl.val = reg_bkp_ctrl;
SPIFLASH.user.val = reg_bkp_usr;
return ESP_OK;
}
esp_err_t spi_flash_enable_wrap(uint32_t wrap_size)
{
// IDF-6198 TODO: support wrap on esp32-c6
CLEAR_PERI_REG_MASK(SPI_MEM_CTRL2_REG(0), SPI_MEM_SPLIT_TRANS_EN_M);
switch (wrap_size) {
case 8:
return spi_flash_wrap_set(FLASH_WRAP_MODE_8B);
case 16:
return spi_flash_wrap_set(FLASH_WRAP_MODE_16B);
case 32:
return spi_flash_wrap_set(FLASH_WRAP_MODE_32B);
case 64:
return spi_flash_wrap_set(FLASH_WRAP_MODE_64B);
default:
return ESP_FAIL;
}
}
void spi_flash_disable_wrap(void)
{
spi_flash_wrap_set(FLASH_WRAP_MODE_DISABLE);
}
bool spi_flash_support_wrap_size(uint32_t wrap_size)
{
if (!REG_GET_BIT(SPI_MEM_CTRL_REG(0), SPI_MEM_FREAD_QIO) || !REG_GET_BIT(SPI_MEM_CTRL_REG(0), SPI_MEM_FASTRD_MODE)) {
return ESP_FAIL;
}
switch (wrap_size) {
case 0:
case 8:
case 16:
case 32:
case 64:
return true;
default:
return false;
}
}

Wyświetl plik

@ -1,8 +0,0 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
// TODO: IDF-6020

Wyświetl plik

@ -1,91 +0,0 @@
/*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include <sys/param.h>
#include "spi_flash_mmap.h"
#include "soc/system_reg.h"
#include "soc/soc_memory_layout.h"
#include "esp32h4/rom/cache.h"
#include "hal/spi_flash_hal.h"
#include "esp_flash.h"
#include "esp_log.h"
#include "esp_attr.h"
#include "esp_rom_spiflash.h"
#include "esp_private/spi_flash_os.h"
#define SPICACHE SPIMEM0
#define SPIFLASH SPIMEM1
#define FLASH_WRAP_CMD 0x77
esp_err_t spi_flash_wrap_set(spi_flash_wrap_mode_t mode)
{
uint32_t reg_bkp_ctrl = SPIFLASH.ctrl.val;
uint32_t reg_bkp_usr = SPIFLASH.user.val;
SPIFLASH.user.fwrite_dio = 0;
SPIFLASH.user.fwrite_dual = 0;
SPIFLASH.user.fwrite_qio = 1;
SPIFLASH.user.fwrite_quad = 0;
SPIFLASH.ctrl.fcmd_dual = 0;
SPIFLASH.ctrl.fcmd_quad = 0;
SPIFLASH.user.usr_dummy = 0;
SPIFLASH.user.usr_addr = 1;
SPIFLASH.user.usr_command = 1;
SPIFLASH.user2.usr_command_bitlen = 7;
SPIFLASH.user2.usr_command_value = FLASH_WRAP_CMD;
SPIFLASH.user1.usr_addr_bitlen = 23;
SPIFLASH.addr = 0;
SPIFLASH.user.usr_miso = 0;
SPIFLASH.user.usr_mosi = 1;
SPIFLASH.mosi_dlen.usr_mosi_bit_len = 7;
SPIFLASH.data_buf[0] = (uint32_t) mode << 4;;
SPIFLASH.cmd.usr = 1;
while (SPIFLASH.cmd.usr != 0)
{ }
SPIFLASH.ctrl.val = reg_bkp_ctrl;
SPIFLASH.user.val = reg_bkp_usr;
return ESP_OK;
}
esp_err_t spi_flash_enable_wrap(uint32_t wrap_size)
{
switch (wrap_size) {
case 8:
return spi_flash_wrap_set(FLASH_WRAP_MODE_8B);
case 16:
return spi_flash_wrap_set(FLASH_WRAP_MODE_16B);
case 32:
return spi_flash_wrap_set(FLASH_WRAP_MODE_32B);
case 64:
return spi_flash_wrap_set(FLASH_WRAP_MODE_64B);
default:
return ESP_FAIL;
}
}
void spi_flash_disable_wrap(void)
{
spi_flash_wrap_set(FLASH_WRAP_MODE_DISABLE);
}
bool spi_flash_support_wrap_size(uint32_t wrap_size)
{
if (!REG_GET_BIT(SPI_MEM_CTRL_REG(0), SPI_MEM_FREAD_QIO) || !REG_GET_BIT(SPI_MEM_CTRL_REG(0), SPI_MEM_FASTRD_MODE)) {
return ESP_FAIL;
}
switch (wrap_size) {
case 0:
case 8:
case 16:
case 32:
case 64:
return true;
default:
return false;
}
}

Wyświetl plik

@ -1,64 +0,0 @@
/*
* SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include <sys/param.h>
#include "spi_flash_mmap.h"
#include "soc/system_reg.h"
#include "soc/soc_memory_layout.h"
#include "esp32s2/rom/cache.h"
#include "bootloader_flash.h"
#include "hal/spi_flash_hal.h"
#include "esp_flash.h"
#include "esp_log.h"
#include "esp_rom_spiflash.h"
#define SPICACHE SPIMEM0
#define SPIFLASH SPIMEM1
esp_err_t spi_flash_wrap_set(spi_flash_wrap_mode_t mode)
{
return bootloader_flash_wrap_set(mode);
}
esp_err_t spi_flash_enable_wrap(uint32_t wrap_size)
{
switch(wrap_size) {
case 8:
return bootloader_flash_wrap_set(FLASH_WRAP_MODE_8B);
case 16:
return bootloader_flash_wrap_set(FLASH_WRAP_MODE_16B);
case 32:
return bootloader_flash_wrap_set(FLASH_WRAP_MODE_32B);
case 64:
return bootloader_flash_wrap_set(FLASH_WRAP_MODE_64B);
default:
return ESP_FAIL;
}
}
void spi_flash_disable_wrap(void)
{
bootloader_flash_wrap_set(FLASH_WRAP_MODE_DISABLE);
}
bool spi_flash_support_wrap_size(uint32_t wrap_size)
{
if (!REG_GET_BIT(SPI_MEM_CTRL_REG(0), SPI_MEM_FREAD_QIO) || !REG_GET_BIT(SPI_MEM_CTRL_REG(0), SPI_MEM_FASTRD_MODE)){
return ESP_FAIL;
}
switch(wrap_size) {
case 0:
case 8:
case 16:
case 32:
case 64:
return true;
default:
return false;
}
}

Wyświetl plik

@ -1,64 +0,0 @@
/*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include <sys/param.h>
#include "spi_flash_mmap.h"
#include "soc/system_reg.h"
#include "soc/soc_memory_layout.h"
#include "esp32s3/rom/cache.h"
#include "bootloader_flash.h"
#include "hal/spi_flash_hal.h"
#include "esp_flash.h"
#include "esp_log.h"
#include "esp_rom_spiflash.h"
#define SPICACHE SPIMEM0
#define SPIFLASH SPIMEM1
esp_err_t spi_flash_wrap_set(spi_flash_wrap_mode_t mode)
{
return bootloader_flash_wrap_set(mode);
}
esp_err_t spi_flash_enable_wrap(uint32_t wrap_size)
{
switch (wrap_size) {
case 8:
return bootloader_flash_wrap_set(FLASH_WRAP_MODE_8B);
case 16:
return bootloader_flash_wrap_set(FLASH_WRAP_MODE_16B);
case 32:
return bootloader_flash_wrap_set(FLASH_WRAP_MODE_32B);
case 64:
return bootloader_flash_wrap_set(FLASH_WRAP_MODE_64B);
default:
return ESP_FAIL;
}
}
void spi_flash_disable_wrap(void)
{
bootloader_flash_wrap_set(FLASH_WRAP_MODE_DISABLE);
}
bool spi_flash_support_wrap_size(uint32_t wrap_size)
{
if (!REG_GET_BIT(SPI_MEM_CTRL_REG(0), SPI_MEM_FREAD_QIO) || !REG_GET_BIT(SPI_MEM_CTRL_REG(0), SPI_MEM_FASTRD_MODE)) {
return ESP_FAIL;
}
switch (wrap_size) {
case 0:
case 8:
case 16:
case 32:
case 64:
return true;
default:
return false;
}
}

Wyświetl plik

@ -135,23 +135,38 @@ const spi_flash_hpm_dummy_conf_t *spi_flash_hpm_get_dummy(void);
*/ */
bool spi_flash_hpm_dummy_adjust(void); bool spi_flash_hpm_dummy_adjust(void);
typedef enum { #if SOC_SPI_MEM_SUPPORT_WRAP
FLASH_WRAP_MODE_8B = 0,
FLASH_WRAP_MODE_16B = 2,
FLASH_WRAP_MODE_32B = 4,
FLASH_WRAP_MODE_64B = 6,
FLASH_WRAP_MODE_DISABLE = 1
} spi_flash_wrap_mode_t;
/** /**
* @brief set wrap mode of flash * @brief set wrap size of flash
* *
* @param mode: wrap mode support disable, 16 32, 64 byte * @param wrap_size: wrap mode support disable, 16 32, 64 byte
* *
* @return esp_err_t : ESP_OK for successful. * @return esp_err_t : ESP_OK for successful.
* *
*/ */
esp_err_t spi_flash_wrap_set(spi_flash_wrap_mode_t mode); esp_err_t spI_flash_wrap_enable(spi_flash_wrap_size_t wrap_size);
/**
* @brief Probe flash wrap method
*
* @return esp_err_t: ESP_OK for success
*/
esp_err_t spi_flash_wrap_probe(void);
/**
* @brief disable cache wrap
*/
esp_err_t spi_flash_wrap_disable(void);
/**
* @brief Check whether flash and esp chip supports wrap mode.
*
* @param wrap_size wrap size.
* @return true: wrap support, otherwise, false.
*/
bool spi_flash_support_wrap_size(uint32_t wrap_size);
#endif //SOC_SPI_MEM_SUPPORT_WRAP
/** /**
* @brief SPI flash critical section enter function. * @brief SPI flash critical section enter function.

Wyświetl plik

@ -47,6 +47,8 @@
#define CMD_SUSPEND 0x75 #define CMD_SUSPEND 0x75
#define CMD_RESUME 0x7A #define CMD_RESUME 0x7A
#define CMD_HPMEN 0xA3 /* Enable High Performance mode on flash */ #define CMD_HPMEN 0xA3 /* Enable High Performance mode on flash */
#define CMD_WRAP 0x77
#define CMD_BURST_RD 0xC0 /* wrap(0x77) and burst read are functionally same. But commands and formats is different */
#define CMD_RST_EN 0x66 #define CMD_RST_EN 0x66
#define CMD_RST_DEV 0x99 #define CMD_RST_DEV 0x99

Wyświetl plik

@ -50,6 +50,49 @@ typedef struct __attribute__((packed))
spi_flash_get_chip_dummy_fn_t flash_get_dummy; spi_flash_get_chip_dummy_fn_t flash_get_dummy;
} spi_flash_hpm_info_t; } spi_flash_hpm_info_t;
/**
* @brief Enum for user to select valid wrap size.
*/
typedef enum {
FLASH_WRAP_SIZE_8B = 8,
FLASH_WRAP_SIZE_16B = 16,
FLASH_WRAP_SIZE_32B = 32,
FLASH_WRAP_SIZE_64B = 64,
} spi_flash_wrap_size_t;
/**
* @brief Probe flash wrap method
*
* @param flash_id Flash chip ID
*
* @return ESP_OK: If succeed
*/
typedef esp_err_t (*spi_flash_wrap_probe_fn_t)(uint32_t flash_id);
/**
* @brief Set flash wrap
*
* @param wrap_size: wrap_size
*
* @return ESP_OK: If succeed
*/
typedef esp_err_t (*spi_flash_wrap_set_fn_t)(spi_flash_wrap_size_t wrap_size);
/**
* @brief Clear flash wrap.
*
* @return ESP_OK: If succeed
*/
typedef esp_err_t (*spi_flash_wrap_clr_fn_t)(void);
typedef struct __attribute__((packed))
{
const char *method;
spi_flash_wrap_probe_fn_t probe;
spi_flash_wrap_set_fn_t chip_wrap_set;
spi_flash_wrap_clr_fn_t chip_wrap_clr;
} spi_flash_wrap_info_t;
/** /**
* Array of known flash chips and method to enable flash high performance mode. * Array of known flash chips and method to enable flash high performance mode.
* *

Wyświetl plik

@ -11,6 +11,7 @@ entries:
spi_flash_chip_th (noflash) spi_flash_chip_th (noflash)
memspi_host_driver (noflash) memspi_host_driver (noflash)
flash_brownout_hook (noflash) flash_brownout_hook (noflash)
spi_flash_wrap (noflash)
if IDF_TARGET_ESP32S3 = y: if IDF_TARGET_ESP32S3 = y:
spi_flash_chip_mxic_opi (noflash) spi_flash_chip_mxic_opi (noflash)

Wyświetl plik

@ -0,0 +1,175 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include <stdbool.h>
#include "sdkconfig.h"
#include "esp_err.h"
#include "esp_log.h"
#include "spi_flash_defs.h"
#include "esp_rom_sys.h"
#include "esp_rom_spiflash.h"
#include "spi_flash_override.h"
#include "esp_private/spi_flash_os.h"
// TODO: These dependencies will be removed after remove bootloader_flash to G0.IDF-4609
#include "bootloader_flash_override.h"
#include "bootloader_flash_priv.h"
/***********************************************************************************
* Flash wrap feature (also called burst read on some flash chips)
*
* Different flash chips enter wrap (burst read) mode in different strategies.
* 1. Command 0xC0 + 8 Bytes.
* 2. Command 0x77 + 24 dummy + 8 Bytes.
**********************************************************************************/
#if SOC_SPI_MEM_SUPPORT_WRAP
const static char *FLASH_WRAP_TAG = "flash wrap";
// TODO: This function will be changed after remove bootloader_flash to G0.IDF-4609
extern uint32_t bootloader_flash_execute_command_common(
uint8_t command,
uint32_t addr_len, uint32_t address,
uint8_t dummy_len,
uint8_t mosi_len, uint32_t mosi_data,
uint8_t miso_len);
esp_err_t spi_flash_wrap_probe_c0(uint32_t flash_id)
{
esp_err_t ret = ESP_OK;
switch (flash_id) {
/* The flash listed here should enter the wrap with command 0xC0 */
case 0xC22018:
break;
default:
ret = ESP_ERR_NOT_FOUND;
break;
}
return ret;
}
/**
* @brief Burst read with command 0xC0 + 8 Bytes
*
* |------------|-----------------------------|
* | data | wrap depth |
* | 00h | 8 |
* | 01h | 16 |
* | 02h | 32 |
* | 03h | 64 |
* |------------|-----------------------------|
*/
esp_err_t spi_flash_wrap_enable_c0(spi_flash_wrap_size_t wrap_size)
{
uint8_t wrap_code = (uint8_t) (__builtin_ctz(wrap_size) - 3);
bootloader_flash_execute_command_common(CMD_BURST_RD, 0, 0, 0, 8, wrap_code, 0);
return ESP_OK;
}
/**
* @brief Burst read with command 0x77 + 24 Dummy + 8 Bytes
*
* |-------------------|-----------------------------|
* | data(W6,W5) | wrap depth |
* | 00h | 8 |
* | 01h | 16 |
* | 02h | 32 |
* | 03h | 64 |
* |-------------------|-----------------------------|
*/
esp_err_t spi_flash_wrap_enable_77(spi_flash_wrap_size_t wrap_size)
{
uint8_t wrap_code = (uint8_t) (((__builtin_ctz(wrap_size) - 3) * 2) << 4);
// According to the special format, we need enable QIO_FWRITE for command 77h and clear it after this command is done.
REG_SET_BIT(SPI_MEM_USER_REG(1), SPI_MEM_FWRITE_QIO);
bootloader_flash_execute_command_common(CMD_WRAP, 0, 0, 6, 8, wrap_code, 0);
REG_CLR_BIT(SPI_MEM_USER_REG(1), SPI_MEM_FWRITE_QIO);
return ESP_OK;
}
/**
* @brief Burst read is cleared by setting 0x1xh,
* so we set 0x10 to disable this feature.
*/
esp_err_t spi_flash_wrap_clear_c0(void)
{
bootloader_flash_execute_command_common(CMD_BURST_RD, 0, 0, 0, 8, 0x10, 0);
return ESP_OK;
}
/**
* @brief Burst read is cleared by setting W4 bit 1,
* so we set 0x10 to disable this feature.
*/
esp_err_t spi_flash_wrap_clear_77(void)
{
// According to the special format, we need enable QIO_FWRITE for command 77h and clear it after this command is done.
REG_SET_BIT(SPI_MEM_USER_REG(1), SPI_MEM_FWRITE_QIO);
bootloader_flash_execute_command_common(CMD_WRAP, 0, 0, 6, 8, 0x10, 0);
REG_CLR_BIT(SPI_MEM_USER_REG(1), SPI_MEM_FWRITE_QIO);
return ESP_OK;
}
const spi_flash_wrap_info_t __attribute__((weak)) spi_flash_wrap_list[] = {
/* method probe chip wrap set chip wrap clear */
{"C0H+8B", spi_flash_wrap_probe_c0, spi_flash_wrap_enable_c0, spi_flash_wrap_clear_c0},
{"default", NULL, spi_flash_wrap_enable_77, spi_flash_wrap_clear_77},
};
static const spi_flash_wrap_info_t *chip_wrap = NULL;
esp_err_t spi_flash_wrap_probe(void)
{
uint32_t flash_chip_id = g_rom_flashchip.device_id;
const spi_flash_wrap_info_t *chip = spi_flash_wrap_list;
esp_err_t ret = ESP_OK;
while (chip->probe) {
ret = chip->probe(flash_chip_id);
if (ret == ESP_OK) {
break;
}
chip++;
}
chip_wrap = chip;
return ret;
}
esp_err_t spI_flash_wrap_enable(spi_flash_wrap_size_t wrap_size)
{
// Calculate pre_code. pre_code equals log(2)(wrap_size) - 3
// So the wrap_size:pre_code is 8:0, 16:1, 32:2, 64:3.
return chip_wrap->chip_wrap_set(wrap_size);
}
esp_err_t spi_flash_wrap_disable(void)
{
return chip_wrap->chip_wrap_clr();
}
bool spi_flash_support_wrap_size(uint32_t wrap_size)
{
// Only QIO mode supports wrap.
if (!REG_GET_BIT(SPI_MEM_CTRL_REG(0), SPI_MEM_FREAD_QIO)) {
ESP_EARLY_LOGE(FLASH_WRAP_TAG, "flash wrap is only supported in QIO mode");
abort();
}
// Only following size can be wrapped.
switch (wrap_size) {
case 0:
case 8:
case 16:
case 32:
case 64:
return true;
default:
return false;
}
}
#endif // SOC_SPI_MEM_SUPPORT_WRAP

Wyświetl plik

@ -30,6 +30,7 @@
#include "esp_timer.h" #include "esp_timer.h"
#include "test_esp_flash_def.h" #include "test_esp_flash_def.h"
#include "spi_flash_mmap.h" #include "spi_flash_mmap.h"
#include "esp_private/spi_flash_os.h"
#if CONFIG_IDF_TARGET_ESP32S2 #if CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/rom/cache.h" #include "esp32s2/rom/cache.h"
@ -533,6 +534,46 @@ static void test_write_protection(const esp_partition_t* part)
TEST_CASE_FLASH("Test esp_flash can enable/disable write protetion", test_write_protection); TEST_CASE_FLASH("Test esp_flash can enable/disable write protetion", test_write_protection);
TEST_CASE_MULTI_FLASH("Test esp_flash can enable/disable write protetion", test_write_protection); TEST_CASE_MULTI_FLASH("Test esp_flash can enable/disable write protetion", test_write_protection);
#if CONFIG_ESPTOOLPY_FLASHMODE_QIO && SOC_SPI_MEM_SUPPORT_WRAP
// Only under QIO mode and mspi support wrap this feature makes sense.
static uint8_t wrap_buf[32];
void test_flash_wrap(const esp_partition_t* part)
{
esp_flash_t* chip = part->flash_chip;
uint32_t offs = erase_test_region(part, 1);
const int test_seed = 778;
srand(test_seed);
for (int i = 0 ; i < sizeof(wrap_buf); i++) {
wrap_buf[i] = rand();
}
printf("Write %p...\n", (void *)offs);
TEST_ASSERT_EQUAL(ESP_OK, esp_flash_write(chip, wrap_buf, offs + 3, sizeof(wrap_buf)) );
bzero(wrap_buf, sizeof(wrap_buf));
printf("Read back...\n");
spi_flash_wrap_probe();
spI_flash_wrap_enable(FLASH_WRAP_SIZE_32B);
esp_flash_read(chip, wrap_buf, offs + 3, sizeof(wrap_buf));
spi_flash_wrap_disable();
printf("Buffer starts 0x%02x 0x%02x 0x%02x 0x%02x\n", wrap_buf[0], wrap_buf[1], wrap_buf[2], wrap_buf[3]);
srand(test_seed);
for (int i = 0; i < sizeof(wrap_buf) - 3; i++) {
uint8_t data = rand();
TEST_ASSERT_EQUAL_HEX8(data, wrap_buf[i]);
}
for (int i = sizeof(wrap_buf) - 3; i < sizeof(wrap_buf); i++) {
TEST_ASSERT_EQUAL_HEX8(0xFF, wrap_buf[i]);
}
}
TEST_CASE_FLASH("SPI flash wrap test", test_flash_wrap);
#endif
static const uint8_t large_const_buffer[16400] = { static const uint8_t large_const_buffer[16400] = {
203, // first byte 203, // first byte
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,