kopia lustrzana https://github.com/espressif/esp-idf
spi_flash: Support flash wrap (burst read), flash driver side
rodzic
254efe402e
commit
0d37436f36
|
@ -25,16 +25,6 @@ extern "C" {
|
|||
*/
|
||||
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.
|
||||
*
|
||||
|
|
|
@ -49,7 +49,6 @@ extern "C" {
|
|||
#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_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_RESETEN 0x66
|
||||
#define CMD_RESET 0x99
|
||||
|
|
|
@ -606,38 +606,6 @@ void bootloader_spi_flash_reset(void)
|
|||
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
|
||||
******************************************************************************/
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "flash_qio_mode.h"
|
||||
#include "soc/efuse_periph.h"
|
||||
#include "soc/io_mux_reg.h"
|
||||
#include "esp_private/spi_flash_os.h"
|
||||
|
||||
|
||||
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].status_qio_bit);
|
||||
#if SOC_CACHE_SUPPORT_WRAP
|
||||
bootloader_flash_wrap_set(FLASH_WRAP_MODE_DISABLE);
|
||||
spi_flash_wrap_probe();
|
||||
spi_flash_wrap_disable();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -443,6 +443,10 @@ config SOC_SPI_MEM_SUPPORT_CHECK_SUS
|
|||
bool
|
||||
default y
|
||||
|
||||
config SOC_SPI_MEM_SUPPORT_WRAP
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_MEMSPI_SRC_FREQ_60M_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
|
|
@ -222,6 +222,7 @@
|
|||
#define SOC_SPI_MEM_SUPPORT_IDLE_INTR (1)
|
||||
#define SOC_SPI_MEM_SUPPORT_SW_SUSPEND (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_30M_SUPPORTED 1
|
||||
|
|
|
@ -659,6 +659,10 @@ config SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE
|
|||
bool
|
||||
default y
|
||||
|
||||
config SOC_SPI_MEM_SUPPORT_WRAP
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
|
|
@ -305,6 +305,7 @@
|
|||
#define SOC_SPI_MEM_SUPPORT_SW_SUSPEND (1)
|
||||
#define SOC_SPI_MEM_SUPPORT_CHECK_SUS (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_40M_SUPPORTED 1
|
||||
|
|
|
@ -795,6 +795,10 @@ config SOC_SPI_MEM_SUPPORT_CHECK_SUS
|
|||
bool
|
||||
default y
|
||||
|
||||
config SOC_SPI_MEM_SUPPORT_WRAP
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
|
|
@ -340,6 +340,7 @@
|
|||
#define SOC_SPI_MEM_SUPPORT_IDLE_INTR (1)
|
||||
#define SOC_SPI_MEM_SUPPORT_SW_SUSPEND (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_40M_SUPPORTED 1
|
||||
|
|
|
@ -691,6 +691,10 @@ config SOC_SPI_MEM_SUPPORT_CHECK_SUS
|
|||
bool
|
||||
default y
|
||||
|
||||
config SOC_SPI_MEM_SUPPORT_WRAP
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_MEMSPI_SRC_FREQ_48M_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
|
|
@ -338,6 +338,7 @@
|
|||
#define SOC_SPI_MEM_SUPPORT_IDLE_INTR (1)
|
||||
#define SOC_SPI_MEM_SUPPORT_SW_SUSPEND (1)
|
||||
#define SOC_SPI_MEM_SUPPORT_CHECK_SUS (1)
|
||||
#define SOC_SPI_MEM_SUPPORT_WRAP (1)
|
||||
|
||||
#define SOC_MEMSPI_SRC_FREQ_48M_SUPPORTED 1
|
||||
|
||||
|
|
|
@ -627,6 +627,10 @@ config SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE
|
|||
bool
|
||||
default y
|
||||
|
||||
config SOC_SPI_MEM_SUPPORT_WRAP
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_MEMSPI_SRC_FREQ_48M_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
|
|
@ -310,6 +310,7 @@
|
|||
#define SOC_SPI_MEM_SUPPORT_SW_SUSPEND (1)
|
||||
#define SOC_SPI_MEM_SUPPORT_CHECK_SUS (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_24M_SUPPORTED 1
|
||||
|
|
|
@ -931,6 +931,10 @@ config SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE
|
|||
bool
|
||||
default y
|
||||
|
||||
config SOC_SPI_MEM_SUPPORT_WRAP
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_PM_SUPPORT_EXT_WAKEUP
|
||||
bool
|
||||
default y
|
||||
|
|
|
@ -407,6 +407,7 @@
|
|||
#define SOC_SPI_MEM_SUPPORT_AUTO_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_WRAP (1)
|
||||
|
||||
/*-------------------------- Power Management CAPS ---------------------------*/
|
||||
#define SOC_PM_SUPPORT_EXT_WAKEUP (1)
|
||||
|
|
|
@ -1143,6 +1143,10 @@ config SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE
|
|||
bool
|
||||
default y
|
||||
|
||||
config SOC_SPI_MEM_SUPPORT_WRAP
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_COEX_HW_PTI
|
||||
bool
|
||||
default y
|
||||
|
|
|
@ -465,6 +465,7 @@
|
|||
#define SOC_SPI_MEM_SUPPORT_OPI_MODE (1)
|
||||
#define SOC_SPI_MEM_SUPPORT_TIME_TUNING (1)
|
||||
#define SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE (1)
|
||||
#define SOC_SPI_MEM_SUPPORT_WRAP (1)
|
||||
|
||||
/*-------------------------- COEXISTENCE HARDWARE PTI CAPS -------------------------------*/
|
||||
#define SOC_COEX_HW_PTI (1)
|
||||
|
|
|
@ -4,7 +4,7 @@ if(${target} STREQUAL "linux")
|
|||
endif()
|
||||
|
||||
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)
|
||||
else()
|
||||
set(srcs "flash_brownout_hook.c")
|
||||
|
@ -35,7 +35,7 @@ else()
|
|||
"cache_utils.c"
|
||||
"flash_mmap.c"
|
||||
"flash_ops.c"
|
||||
"${target}/flash_ops_${target}.c"
|
||||
"spi_flash_wrap.c"
|
||||
)
|
||||
|
||||
list(APPEND cache_srcs
|
||||
|
|
|
@ -55,6 +55,8 @@
|
|||
#include "esp_memory_utils.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "spi_flash_mmap.h"
|
||||
#include "spi_flash_override.h"
|
||||
#include "esp_private/spi_flash_os.h"
|
||||
#include "esp_log.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 CONFIG_ESP32S2_INSTRUCTION_CACHE_LINE_16B || CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_16B
|
||||
icache_wrap_size = 16;
|
||||
icache_wrap_size = FLASH_WRAP_SIZE_16B;
|
||||
#else
|
||||
icache_wrap_size = 32;
|
||||
icache_wrap_size = FLASH_WRAP_SIZE_32B;
|
||||
#endif
|
||||
}
|
||||
if (dcache_wrap_enable) {
|
||||
#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
|
||||
dcache_wrap_size = 32;
|
||||
dcache_wrap_size = FLASH_WRAP_SIZE_32B;
|
||||
#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
|
||||
flash_support_wrap = true;
|
||||
extern bool spi_flash_support_wrap_size(uint32_t wrap_size);
|
||||
if (!spi_flash_support_wrap_size(flash_wrap_size)) {
|
||||
flash_support_wrap = false;
|
||||
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;
|
||||
}
|
||||
|
||||
extern esp_err_t spi_flash_enable_wrap(uint32_t wrap_size);
|
||||
if (flash_support_wrap && flash_wrap_size > 0) {
|
||||
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));
|
||||
}
|
||||
#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 CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_16B
|
||||
icache_wrap_size = 16;
|
||||
icache_wrap_size = FLASH_WRAP_SIZE_16B;
|
||||
#elif CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_32B
|
||||
icache_wrap_size = 32;
|
||||
icache_wrap_size = FLASH_WRAP_SIZE_32B;
|
||||
#else
|
||||
icache_wrap_size = 64;
|
||||
icache_wrap_size = FLASH_WRAP_SIZE_64B;
|
||||
#endif
|
||||
}
|
||||
if (dcache_wrap_enable) {
|
||||
#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
|
||||
dcache_wrap_size = 32;
|
||||
dcache_wrap_size = FLASH_WRAP_SIZE_32B;
|
||||
#else
|
||||
dcache_wrap_size = 64;
|
||||
dcache_wrap_size = FLASH_WRAP_SIZE_64B;
|
||||
#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
|
||||
flash_support_wrap = true;
|
||||
extern bool spi_flash_support_wrap_size(uint32_t wrap_size);
|
||||
if (!spi_flash_support_wrap_size(flash_wrap_size)) {
|
||||
flash_support_wrap = false;
|
||||
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;
|
||||
}
|
||||
|
||||
extern esp_err_t spi_flash_enable_wrap(uint32_t wrap_size);
|
||||
if (flash_support_wrap && flash_wrap_size > 0) {
|
||||
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));
|
||||
}
|
||||
#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
|
||||
flash_support_wrap = true;
|
||||
extern bool spi_flash_support_wrap_size(uint32_t wrap_size);
|
||||
if (!spi_flash_support_wrap_size(flash_wrap_size)) {
|
||||
flash_support_wrap = false;
|
||||
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.");
|
||||
#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) {
|
||||
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));
|
||||
}
|
||||
return ESP_OK;
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
// TODO: IDF-6020
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -135,23 +135,38 @@ const spi_flash_hpm_dummy_conf_t *spi_flash_hpm_get_dummy(void);
|
|||
*/
|
||||
bool spi_flash_hpm_dummy_adjust(void);
|
||||
|
||||
typedef enum {
|
||||
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;
|
||||
|
||||
#if SOC_SPI_MEM_SUPPORT_WRAP
|
||||
/**
|
||||
* @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.
|
||||
*
|
||||
*/
|
||||
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.
|
||||
|
|
|
@ -47,6 +47,8 @@
|
|||
#define CMD_SUSPEND 0x75
|
||||
#define CMD_RESUME 0x7A
|
||||
#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_DEV 0x99
|
||||
|
|
|
@ -50,6 +50,49 @@ typedef struct __attribute__((packed))
|
|||
spi_flash_get_chip_dummy_fn_t flash_get_dummy;
|
||||
} 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.
|
||||
*
|
||||
|
|
|
@ -11,6 +11,7 @@ entries:
|
|||
spi_flash_chip_th (noflash)
|
||||
memspi_host_driver (noflash)
|
||||
flash_brownout_hook (noflash)
|
||||
spi_flash_wrap (noflash)
|
||||
|
||||
if IDF_TARGET_ESP32S3 = y:
|
||||
spi_flash_chip_mxic_opi (noflash)
|
||||
|
|
|
@ -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
|
|
@ -30,6 +30,7 @@
|
|||
#include "esp_timer.h"
|
||||
#include "test_esp_flash_def.h"
|
||||
#include "spi_flash_mmap.h"
|
||||
#include "esp_private/spi_flash_os.h"
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32S2
|
||||
#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_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] = {
|
||||
203, // first byte
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
|
||||
|
|
Ładowanie…
Reference in New Issue