This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 622355b5c318de7c2e03690de1d6164f2d241117
Author: Tiago Medicci Serrano <tiago.medi...@espressif.com>
AuthorDate: Wed Feb 26 14:12:43 2025 -0300
arch/xtensa/esp32s3: Fix bug regarding SPI flash operation mode
SPI flash operation modes - Dual Output (dout), Dual I/O (dio),
Quad Output (qout), Quad I/O (qio) and Octal (opi) were not being
properly selected. This commit fixes this behavior and the device
is now able to boot and initialize the proper SPI flash mode.
Signed-off-by: Tiago Medicci Serrano <tiago.medi...@espressif.com>
---
arch/xtensa/src/esp32s3/Kconfig | 1 +
arch/xtensa/src/esp32s3/Make.defs | 2 +-
arch/xtensa/src/esp32s3/esp32s3_psram_octal.c | 68 +-----
arch/xtensa/src/esp32s3/esp32s3_spiflash.c | 233 +++++++++++++++++----
arch/xtensa/src/esp32s3/esp32s3_start.c | 44 +++-
arch/xtensa/src/esp32s3/hal.mk | 10 +-
.../esp32s3/common/scripts/esp32s3_rom_aliases.ld | 5 +
.../esp32s3/common/scripts/esp32s3_sections.ld | 8 +
tools/esp32s3/Config.mk | 2 +
9 files changed, 253 insertions(+), 120 deletions(-)
diff --git a/arch/xtensa/src/esp32s3/Kconfig b/arch/xtensa/src/esp32s3/Kconfig
index 33c94255a3..3e51869676 100644
--- a/arch/xtensa/src/esp32s3/Kconfig
+++ b/arch/xtensa/src/esp32s3/Kconfig
@@ -1789,6 +1789,7 @@ config ESP32S3_FLASH_MODE_QOUT
bool "Quad Output (QOUT)"
config ESP32S3_FLASH_MODE_OCT
+ select ESP32S3_SPI_FLASH_DONT_USE_ROM_CODE
bool "Octal"
endchoice # ESP32S3_FLASH_MODE
diff --git a/arch/xtensa/src/esp32s3/Make.defs
b/arch/xtensa/src/esp32s3/Make.defs
index 8504a61fb2..bf64bb80aa 100644
--- a/arch/xtensa/src/esp32s3/Make.defs
+++ b/arch/xtensa/src/esp32s3/Make.defs
@@ -225,7 +225,7 @@ endif
ESP_HAL_3RDPARTY_REPO = esp-hal-3rdparty
ifndef ESP_HAL_3RDPARTY_VERSION
- ESP_HAL_3RDPARTY_VERSION = 5d4868f08b94efbe76383382f7a843c6cdeaf811
+ ESP_HAL_3RDPARTY_VERSION = 0b15e1a642d7005ad11c3c0394c784959f478f5f
endif
ifndef ESP_HAL_3RDPARTY_URL
diff --git a/arch/xtensa/src/esp32s3/esp32s3_psram_octal.c
b/arch/xtensa/src/esp32s3/esp32s3_psram_octal.c
index c126097edb..fbc75823c9 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_psram_octal.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_psram_octal.c
@@ -586,72 +586,6 @@ static void IRAM_ATTR config_psram_spi_phases(void)
cache_resume_dcache(0);
}
-/****************************************************************************
- * Name: spi_flash_set_rom_required_regs
- *
- * Description:
- * Set flash ROM required register.
- *
- * Input Parameters:
- * None
- *
- * Returned Value:
- * None.
- *
- ****************************************************************************/
-
-void IRAM_ATTR spi_flash_set_rom_required_regs(void)
-{
-#ifdef CONFIG_ESP32S3_FLASH_MODE_OCT
-
- /* Disable the variable dummy mode when doing timing tuning.
- * STR /DTR mode setting is done every time when
- * "esp_rom_opiflash_exec_cmd" is called.
- * Add any registers that are not set in ROM SPI flash functions here
- * in the future.
- */
-
- CLEAR_PERI_REG_MASK(SPI_MEM_DDR_REG(1), SPI_MEM_SPI_FMEM_VAR_DUMMY);
-#endif
-}
-
-/****************************************************************************
- * Name: flash_set_vendor_required_regs
- *
- * Description:
- * Set flash vendor required register.
- *
- * Input Parameters:
- * None
- *
- * Returned Value:
- * None.
- *
- ****************************************************************************/
-
-static inline void flash_set_vendor_required_regs(void)
-{
-#ifdef CONFIG_ESP32S3_FLASH_MODE_OCT
- /* Set MSPI specifical configuration,
- * "esp32s3_bsp_opiflash_set_required_regs" is board defined function.
- */
-
- esp32s3_bsp_opiflash_set_required_regs();
-
- SET_PERI_REG_BITS(SPI_MEM_CACHE_FCTRL_REG(1),
- SPI_MEM_CACHE_USR_CMD_4BYTE_V,
- 1,
- SPI_MEM_CACHE_USR_CMD_4BYTE_S);
-#else
- /* Restore MSPI registers after Octal PSRAM initialization. */
-
- SET_PERI_REG_BITS(SPI_MEM_CACHE_FCTRL_REG(1),
- SPI_MEM_CACHE_USR_CMD_4BYTE_V,
- 0,
- SPI_MEM_CACHE_USR_CMD_4BYTE_S);
-#endif
-}
-
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -722,7 +656,7 @@ int IRAM_ATTR psram_enable(int mode, int vaddrmode)
/* Flash chip requires MSPI specifically, call this function to set them */
- flash_set_vendor_required_regs();
+ spi_flash_set_vendor_required_regs();
config_psram_spi_phases();
diff --git a/arch/xtensa/src/esp32s3/esp32s3_spiflash.c
b/arch/xtensa/src/esp32s3/esp32s3_spiflash.c
index bf86049c8b..f34aa60114 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_spiflash.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_spiflash.c
@@ -37,6 +37,7 @@
#include <nuttx/init.h>
#include <nuttx/kthread.h>
#include <nuttx/signal.h>
+#include <nuttx/kmalloc.h>
#include "sched/sched.h"
@@ -48,6 +49,7 @@
#include "esp32s3_irq.h"
#include "esp32s3_spiflash.h"
+#include "spi_flash_defs.h"
#include "hal/cache_hal.h"
#include "soc/extmem_reg.h"
#include "soc/spi_mem_reg.h"
@@ -121,27 +123,90 @@
# define FLASH_SR1_BUSY ESP_ROM_SPIFLASH_BUSY_FLAG
# define FLASH_SR1_WREN ESP_ROM_SPIFLASH_WRENABLE_FLAG
+#define SPI_FLASH_DIO_ADDR_BITLEN 24
+#define SPI_FLASH_DIO_DUMMY_BITLEN 4
+#define SPI_FLASH_QIO_ADDR_BITLEN 24
+#define SPI_FLASH_QIO_DUMMY_BITLEN 6
+#define SPI_FLASH_QOUT_ADDR_BITLEN 24
+#define SPI_FLASH_QOUT_DUMMY_BITLEN 8
+#define SPI_FLASH_DOUT_ADDR_BITLEN 24
+#define SPI_FLASH_DOUT_DUMMY_BITLEN 8
+#define SPI_FLASH_FASTRD_ADDR_BITLEN 24
+#define SPI_FLASH_FASTRD_DUMMY_BITLEN 8
+#define SPI_FLASH_SLOWRD_ADDR_BITLEN 24
+#define SPI_FLASH_SLOWRD_DUMMY_BITLEN 0
+#define SPI_FLASH_OPISTR_ADDR_BITLEN 32
+#define SPI_FLASH_OPISTR_DUMMY_BITLEN 20
+#define SPI_FLASH_OPIDTR_ADDR_BITLEN 32
+#define SPI_FLASH_OPIDTR_DUMMY_BITLEN 40
+#define SPI_FLASH_QIO_HPM_DUMMY_BITLEN 10
+#define SPI_FLASH_DIO_HPM_DUMMY_BITLEN 8
+
/* SPI flash operation */
-# ifdef CONFIG_ESP32S3_SPI_FLASH_USE_32BIT_ADDRESS
-# define ADDR_BITS(addr) (((addr) & 0xff000000) ? 32 : 24)
+#ifndef CONFIG_ESP32S3_FLASH_MODE_OCT
+# define CMD_OPI_FLASH_MXIC(cmd) (cmd)
+# define CMD_BITLEN(cmd) (8)
+# ifdef CONFIG_ESP32S3_FLASH_MODE_QIO
+# define READ_DUMMY(addr) SPI_FLASH_QIO_DUMMY_BITLEN
+# define READ_CMD(addr) (ADDR_BITS(addr) == 32 ? CMD_FASTRD_QIO_4B
: \
+ CMD_FASTRD_QIO)
+# elif CONFIG_ESP32S3_FLASH_MODE_QOUT
+# define READ_DUMMY(addr) SPI_FLASH_QOUT_DUMMY_BITLEN
+# define READ_CMD(addr) (ADDR_BITS(addr) == 32 ?
CMD_FASTRD_QUAD_4B : \
+ CMD_FASTRD_QUAD)
+# elif CONFIG_ESP32S3_FLASH_MODE_DIO
+# define READ_DUMMY(addr) SPI_FLASH_DIO_DUMMY_BITLEN
+# define READ_CMD(addr) (ADDR_BITS(addr) == 32 ? CMD_FASTRD_DIO_4B
: \
+ CMD_FASTRD_DIO)
+# elif CONFIG_ESP32S3_FLASH_MODE_DOUT
+# define READ_DUMMY(addr) SPI_FLASH_DOUT_DUMMY_BITLEN
+# define READ_CMD(addr) (ADDR_BITS(addr) == 32 ?
CMD_FASTRD_DUAL_4B : \
+ CMD_FASTRD_DUAL)
+# else /* SPI_FLASH_FASTRD */
+# define READ_DUMMY(addr) SPI_FLASH_FASTRD_DUMMY_BITLEN
# define READ_CMD(addr) (ADDR_BITS(addr) == 32 ? FLASH_CMD_FSTRD4B
: \
FLASH_CMD_FSTRD)
+# endif
+# ifdef CONFIG_ESP32S3_SPI_FLASH_USE_32BIT_ADDRESS
+# define ADDR_BITS(addr) (((addr) & 0xff000000) ? 32 : 24)
# define WRITE_CMD(addr) (ADDR_BITS(addr) == 32 ? FLASH_CMD_PP4B : \
FLASH_CMD_PP)
# define ERASE_CMD(addr) (ADDR_BITS(addr) == 32 ? FLASH_CMD_SE4B : \
FLASH_CMD_SE)
-# define READ_DUMMY(addr) (8)
# else
# define ADDR_BITS(addr) 24
-# define READ_CMD(addr) FLASH_CMD_FSTRD
# define WRITE_CMD(addr) FLASH_CMD_PP
# define ERASE_CMD(addr) FLASH_CMD_SE
-# define READ_DUMMY(addr) (8)
# endif
+# define READ_REG_DUMMY(addr) (0)
+#else /* CONFIG_ESP32S3_FLASH_MODE_OCT */
+# define CMD_OPI_FLASH_MXIC(cmd) ((((~(cmd) & 0xff) << 8)) | ((cmd) & 0xff))
+# define CMD_OPI_FLASH_MXIC_CHIP_ERASE 0x9F60
+# define CMD_OPI_FLASH_MXIC_READ_STR 0x13EC
+# define CMD_OPI_FLASH_MXIC_READ_DTR 0x11EE
+# define CMD_OPI_FLASH_MXIC_RDCR2 0x8E71
+# define CMD_OPI_FLASH_MXIC_WRCR2 0x8D72
+# define CMD_BITLEN(cmd) (cmd >= 0x100 ? 16 : 8)
+# define ADDR_BITS(addr) (32)
+# ifdef CONFIG_ESP32S3_FLASH_SAMPLE_MODE_STR
+# define READ_CMD(addr) CMD_OPI_FLASH_MXIC_READ_STR
+# else
+# define READ_CMD(addr) CMD_OPI_FLASH_MXIC_READ_DTR
+# endif
+# define WRITE_CMD(addr) CMD_OPI_FLASH_MXIC(FLASH_CMD_PP4B)
+# define ERASE_CMD(addr) CMD_OPI_FLASH_MXIC(FLASH_CMD_SE4B)
+# ifdef CONFIG_ESP32S3_FLASH_SAMPLE_MODE_STR
+# define READ_DUMMY(addr) SPI_FLASH_OPISTR_DUMMY_BITLEN
+# define READ_REG_DUMMY(addr) 4
+# else /* CONFIG_ESP32S3_FLASH_SAMPLE_MODE_DTR */
+# define READ_DUMMY(addr) CMD_OPI_FLASH_MXIC_READ_DTR
+# define READ_REG_DUMMY(addr) 8
+# endif
+#endif /* !CONFIG_ESP32S3_FLASH_MODE_OCT*/
# define SEND_CMD8_TO_FLASH(cmd) \
- esp32s3_spi_trans((cmd), 8, \
+ esp32s3_spi_trans((cmd), CMD_BITLEN(cmd), \
0, 0, \
NULL, 0, \
NULL, 0, \
@@ -149,15 +214,16 @@
false)
# define READ_SR1_FROM_FLASH(cmd, status) \
- esp32s3_spi_trans((cmd), 8, \
- 0, 0, \
+ esp32s3_spi_trans((cmd), CMD_BITLEN(cmd), \
+ 0, ADDR_BITS(0), \
NULL, 0, \
(status), 1, \
- 0, \
+ READ_REG_DUMMY(0), \
false)
# define ERASE_FLASH_SECTOR(addr) \
- esp32s3_spi_trans(ERASE_CMD(addr), 8, \
+ esp32s3_spi_trans(ERASE_CMD(addr), \
+ CMD_BITLEN(ERASE_CMD(addr)), \
(addr), ADDR_BITS(addr), \
NULL, 0, \
NULL, 0, \
@@ -165,7 +231,8 @@
true)
# define WRITE_DATA_TO_FLASH(addr, buffer, size) \
- esp32s3_spi_trans(WRITE_CMD(addr), 8, \
+ esp32s3_spi_trans(WRITE_CMD(addr), \
+ CMD_BITLEN(WRITE_CMD(addr)), \
(addr), ADDR_BITS(addr), \
buffer, size, \
NULL, 0, \
@@ -173,7 +240,8 @@
true)
# define READ_DATA_FROM_FLASH(addr, buffer, size) \
- esp32s3_spi_trans(READ_CMD(addr), 8, \
+ esp32s3_spi_trans(READ_CMD(addr), \
+ CMD_BITLEN(READ_CMD(addr)), \
(addr), ADDR_BITS(addr), \
NULL, 0, \
buffer, size, \
@@ -206,6 +274,12 @@ extern void cache_resume_dcache(uint32_t val);
extern int cache_invalidate_addr(uint32_t addr, uint32_t size);
extern void cache_invalidate_icache_all(void);
+#ifndef CONFIG_ESP32S3_SPI_FLASH_DONT_USE_ROM_CODE
+extern void spi_flash_mmap_os_func_set(void *(*func1)(size_t size),
+ void (*func2)(void *p));
+extern esp_err_t spi_flash_mmap_page_num_init(uint32_t page_num);
+#endif
+
/****************************************************************************
* Private Data
****************************************************************************/
@@ -223,6 +297,7 @@ static volatile bool g_flash_op_can_start = false;
static volatile bool g_flash_op_complete = false;
static volatile bool g_spi_flash_cache_suspended = false;
static volatile bool g_sched_suspended[CONFIG_SMP_NCPUS];
+static volatile bool g_flash_chip_busy = false;
#ifdef CONFIG_SMP
static sem_t g_disable_non_iram_isr_on_core[CONFIG_SMP_NCPUS];
#endif
@@ -402,8 +477,8 @@ static void esp32s3_spi_trans(uint32_t command,
/* Initiliaze SPI user register */
- user_reg &= ~(SPI_MEM_USR_ADDR_M | SPI_MEM_USR_DUMMY_M |
- SPI_MEM_USR_MOSI_M | SPI_MEM_USR_MISO_M);
+ user_reg &= ~(SPI_MEM_USR_DUMMY_M | SPI_MEM_USR_MOSI_M |
+ SPI_MEM_USR_MISO_M | SPI_MEM_USR_ADDR_M);
user_reg |= SPI_MEM_USR_COMMAND_M;
/* Wait until SPI is idle */
@@ -424,36 +499,40 @@ static void esp32s3_spi_trans(uint32_t command,
/* Set address bits and value */
- if (address_bits)
- {
- user1_reg &= ~SPI_MEM_USR_ADDR_BITLEN_M;
- user1_reg |= (address_bits - 1) << SPI_MEM_USR_ADDR_BITLEN_S;
-
- putreg32(address, SPI_MEM_ADDR_REG(SPI_PORT));
+ user1_reg &= ~SPI_MEM_USR_ADDR_BITLEN_M;
+ user1_reg |= (address_bits - 1) << SPI_MEM_USR_ADDR_BITLEN_S;
- user_reg |= SPI_MEM_USR_ADDR_M;
+ putreg32(address, SPI_MEM_ADDR_REG(SPI_PORT));
- regval = getreg32(SPI_MEM_CACHE_FCTRL_REG(SPI_PORT));
- if (address_bits > 24)
- {
- regval |= SPI_MEM_CACHE_USR_CMD_4BYTE_M;
- }
- else
- {
- regval &= ~SPI_MEM_CACHE_USR_CMD_4BYTE_M;
- }
+ regval = getreg32(SPI_MEM_CACHE_FCTRL_REG(SPI_PORT));
+ if (address_bits > 24)
+ {
+ regval |= SPI_MEM_CACHE_USR_CMD_4BYTE_M;
+ }
+ else
+ {
+ regval &= ~SPI_MEM_CACHE_USR_CMD_4BYTE_M;
+ }
- putreg32(regval, SPI_MEM_CACHE_FCTRL_REG(SPI_PORT));
+ if (address_bits)
+ {
+ user_reg |= SPI_MEM_USR_ADDR_M;
}
+ putreg32(regval, SPI_MEM_CACHE_FCTRL_REG(SPI_PORT));
+
/* Set dummy */
+ user1_reg &= ~SPI_MEM_USR_DUMMY_CYCLELEN_M;
+
if (dummy_bits)
{
- user1_reg &= ~SPI_MEM_USR_DUMMY_CYCLELEN_M;
- user1_reg |= (dummy_bits - 1) << SPI_MEM_USR_DUMMY_CYCLELEN_S;
-
user_reg |= SPI_MEM_USR_DUMMY_M;
+ user1_reg |= (dummy_bits - 1) << SPI_MEM_USR_DUMMY_CYCLELEN_S;
+ }
+ else
+ {
+ user1_reg |= SPI_MEM_USR_DUMMY_CYCLELEN_M;
}
/* Set TX data */
@@ -474,9 +553,12 @@ static void esp32s3_spi_trans(uint32_t command,
if (rx_bytes)
{
putreg32(rx_bytes * 8 - 1, SPI_MEM_MISO_DLEN_REG(SPI_PORT));
-
user_reg |= SPI_MEM_USR_MISO_M;
}
+ else
+ {
+ putreg32(0, SPI_MEM_MISO_DLEN_REG(SPI_PORT));
+ }
putreg32(user_reg, SPI_MEM_USER_REG(SPI_PORT));
putreg32(user1_reg, SPI_MEM_USER1_REG(SPI_PORT));
@@ -490,15 +572,54 @@ static void esp32s3_spi_trans(uint32_t command,
SPI_MEM_FCMD_DUAL_M | SPI_MEM_FADDR_OCT_M |
SPI_MEM_FDIN_OCT_M | SPI_MEM_FDOUT_OCT_M |
SPI_MEM_FDUMMY_OUT_M | SPI_MEM_RESANDRES_M |
- SPI_MEM_WP_REG_M | SPI_MEM_WRSR_2B_M);
+ SPI_MEM_WP_REG_M | SPI_MEM_WRSR_2B_M |
+ SPI_MEM_FASTRD_MODE_M);
+ regval |= (SPI_MEM_Q_POL_M | SPI_MEM_D_POL_M);
+#ifdef CONFIG_ESP32S3_FLASH_MODE_QIO
+ if (command == READ_CMD(address))
+ {
+ regval |= SPI_MEM_FREAD_QIO_M;
+ regval |= SPI_MEM_FASTRD_MODE_M;
+ regval |= SPI_MEM_FDUMMY_OUT_M;
+ }
+#elif CONFIG_ESP32S3_FLASH_MODE_QOUT
+ if (command == READ_CMD(address))
+ {
+ regval |= SPI_MEM_FREAD_QUAD_M;
+ regval |= SPI_MEM_FASTRD_MODE_M;
+ }
+#elif CONFIG_ESP32S3_FLASH_MODE_DIO
+ if (command == READ_CMD(address))
+ {
+ regval |= SPI_MEM_FREAD_DIO_M;
+ regval |= SPI_MEM_FASTRD_MODE_M;
+ regval |= SPI_MEM_FDUMMY_OUT_M;
+ }
+#elif CONFIG_ESP32S3_FLASH_MODE_DOUT
+ if (command == READ_CMD(address))
+ {
+ regval |= SPI_MEM_FREAD_DUAL_M;
+ regval |= SPI_MEM_FASTRD_MODE_M;
+ }
+#elif CONFIG_ESP32S3_FLASH_MODE_OCT
regval |= SPI_MEM_FASTRD_MODE_M;
+# ifdef CONFIG_ESP32S3_FLASH_SAMPLE_MODE_STR
+ regval |= (SPI_MEM_FADDR_OCT_M | SPI_MEM_FCMD_OCT_M |
+ SPI_MEM_FDIN_OCT_M | SPI_MEM_FDOUT_OCT_M);
+# elif CONFIG_ESP32S3_FLASH_SAMPLE_MODE_DTR
+# error "Not yet implemented"
+# endif
+#else /* SPI_FLASH_FASTRD */
+ if (command == READ_CMD(address))
+ {
+ regval |= SPI_MEM_FASTRD_MODE_M;
+ }
+#endif
+
putreg32(regval, SPI_MEM_CTRL_REG(SPI_PORT));
/* Set clock and delay */
- regval = SPI_MEM_FLASH_PES_WAIT_EN_M |
- SPI_MEM_FLASH_PER_WAIT_EN_M;
- putreg32(regval, SPI_MEM_FLASH_SUS_CMD_REG(SPI_PORT));
putreg32(0, SPI_MEM_CLOCK_GATE_REG(SPI_PORT));
/* Set if this is program or erase operation */
@@ -548,9 +669,21 @@ static void wait_flash_idle(void)
do
{
- READ_SR1_FROM_FLASH(FLASH_CMD_RDSR, &status);
+ READ_SR1_FROM_FLASH(CMD_OPI_FLASH_MXIC(FLASH_CMD_RDSR), &status);
if ((status & FLASH_SR1_BUSY) == 0)
{
+ if (g_flash_chip_busy == true)
+ {
+ g_flash_chip_busy = 0;
+ if ((status & FLASH_SR1_WREN) != 0)
+ {
+ /* The previous command is not accepted, leaving the WEL
+ * bit still set.
+ */
+
+ return;
+ }
+ }
break;
}
}
@@ -574,8 +707,8 @@ static void enable_flash_write(void)
do
{
- SEND_CMD8_TO_FLASH(FLASH_CMD_WREN);
- READ_SR1_FROM_FLASH(FLASH_CMD_RDSR, &status);
+ SEND_CMD8_TO_FLASH(CMD_OPI_FLASH_MXIC(FLASH_CMD_WREN));
+ READ_SR1_FROM_FLASH(CMD_OPI_FLASH_MXIC(FLASH_CMD_RDSR), &status);
if ((status & FLASH_SR1_WREN) != 0)
{
break;
@@ -601,8 +734,8 @@ static void disable_flash_write(void)
do
{
- SEND_CMD8_TO_FLASH(FLASH_CMD_WRDI);
- READ_SR1_FROM_FLASH(FLASH_CMD_RDSR, &status);
+ SEND_CMD8_TO_FLASH(CMD_OPI_FLASH_MXIC(FLASH_CMD_WRDI));
+ READ_SR1_FROM_FLASH(CMD_OPI_FLASH_MXIC(FLASH_CMD_RDSR), &status);
if ((status & FLASH_SR1_WREN) == 0)
{
break;
@@ -1103,6 +1236,7 @@ int spi_flash_erase_sector(uint32_t sector)
enable_flash_write();
ERASE_FLASH_SECTOR(addr);
+ g_flash_chip_busy = true;
wait_flash_idle();
disable_flash_write();
@@ -1144,8 +1278,10 @@ int spi_flash_erase_range(uint32_t start_address,
uint32_t size)
spiflash_start();
wait_flash_idle();
enable_flash_write();
+ wait_flash_idle();
ERASE_FLASH_SECTOR(addr);
+ g_flash_chip_busy = true;
addr += FLASH_SECTOR_SIZE;
wait_flash_idle();
disable_flash_write();
@@ -1219,6 +1355,7 @@ int spi_flash_write(uint32_t dest_addr, const void
*buffer, uint32_t size)
enable_flash_write();
WRITE_DATA_TO_FLASH(tx_addr, spi_buffer, n);
+ g_flash_chip_busy = true;
tx_bytes -= n;
tx_buf += n;
@@ -1341,6 +1478,14 @@ int esp32s3_spiflash_init(void)
spi_flash_guard_set(&g_spi_flash_guard_funcs);
+#ifndef CONFIG_ESP32S3_SPI_FLASH_DONT_USE_ROM_CODE
+
+ /* These two functions are in ROM only */
+
+ spi_flash_mmap_os_func_set(malloc, free);
+ spi_flash_mmap_page_num_init(128);
+#endif
+
return ret;
}
diff --git a/arch/xtensa/src/esp32s3/esp32s3_start.c
b/arch/xtensa/src/esp32s3/esp32s3_start.c
index ce685a7c4e..09c4119c6b 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_start.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_start.c
@@ -57,6 +57,7 @@
#include "hal/cache_types.h"
#include "hal/cache_ll.h"
#include "hal/cache_hal.h"
+#include "hal/efuse_ll.h"
#include "soc/extmem_reg.h"
#include "rom/cache.h"
#include "spi_flash_mmap.h"
@@ -64,6 +65,7 @@
#ifdef CONFIG_ESPRESSIF_SIMPLE_BOOT
# include "bootloader_init.h"
#endif
+#include "bootloader_flash_config.h"
#include "esp_clk_internal.h"
#include "periph_ctrl.h"
@@ -135,6 +137,7 @@ extern void cache_set_idrom_mmu_info(uint32_t
instr_page_num,
#ifdef CONFIG_ESP32S3_DATA_CACHE_16KB
extern int cache_occupy_addr(uint32_t addr, uint32_t size);
#endif
+extern int ets_printf(const char *fmt, ...);
/****************************************************************************
* Private Function Prototypes
@@ -380,12 +383,6 @@ noinstrument_function void noreturn_function IRAM_ATTR
__esp32s3_start(void)
showprogress('A');
-#if defined(CONFIG_ESP32S3_FLASH_MODE_OCT) || \
- defined(CONFIG_ESP32S3_SPIRAM_MODE_OCT)
- esp_rom_opiflash_pin_config();
- esp32s3_spi_timing_set_pin_drive_strength();
-#endif
-
/* The PLL provided by bootloader is not stable enough, do calibration
* again here so that we can use better clock for the timing tuning.
*/
@@ -509,6 +506,41 @@ noinstrument_function void IRAM_ATTR __start(void)
configure_cpu_caches();
+ if (efuse_ll_get_flash_type())
+ {
+#ifndef CONFIG_ESP32S3_FLASH_MODE_OCT
+ ets_printf("Octal Flash chip detected!\n"
+ "Select CONFIG_ESP32S3_FLASH_MODE_OCT on menuconfig\n");
+ abort();
+#endif
+ }
+ else
+ {
+#ifdef CONFIG_ESP32S3_FLASH_MODE_OCT
+ ets_printf("Octal Flash option selected, but EFUSE not configured!\n");
+ abort();
+#endif
+ }
+
+ esp_mspi_pin_init();
+
+ /* At this point, the Flash chip is still in one of the DOUT, DIO, QOUT
+ * or QIO modes. It's hard to implement a read_id function in OPI mode,
+ * so the Flash chip ID is read here, before entering the OPI mode (if
+ * applicable).
+ */
+
+ bootloader_flash_update_id();
+
+ /* The following function initializes the Flash chip to the user-defined
+ * settings. Please note that the Flash chip is initialized with temporary
+ * settings during the boot phase to enable using different chips. In this
+ * stage, the Flash chip and the MSPI are reconfigured to the required
+ * final settings.
+ */
+
+ spi_flash_init_chip_state();
+
__esp32s3_start();
while (true); /* Should not return */
diff --git a/arch/xtensa/src/esp32s3/hal.mk b/arch/xtensa/src/esp32s3/hal.mk
index d3637d21f3..b7d441d6ce 100644
--- a/arch/xtensa/src/esp32s3/hal.mk
+++ b/arch/xtensa/src/esp32s3/hal.mk
@@ -73,6 +73,8 @@ ARCHSCRIPT +=
$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)
# Source files
+CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)bootloader_flash$(DELIM)src$(DELIM)bootloader_flash_config_${CHIP_SERIES}.c
+CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)bootloader_flash$(DELIM)src$(DELIM)bootloader_flash.c
CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)src$(DELIM)esp_efuse_api.c
CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)src$(DELIM)esp_efuse_utility.c
CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)$(CHIP_SERIES)$(DELIM)esp_efuse_fields.c
@@ -101,6 +103,7 @@ CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_
CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hw_support$(DELIM)mspi_timing_tuning.c
CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_rom$(DELIM)patches$(DELIM)esp_rom_wdt.c
CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_rom$(DELIM)patches$(DELIM)esp_rom_cache_esp32s2_esp32s3.c
+CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_rom$(DELIM)patches$(DELIM)esp_rom_efuse.c
CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_system$(DELIM)port$(DELIM)soc$(DELIM)$(CHIP_SERIES)$(DELIM)clk.c
CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_system$(DELIM)port$(DELIM)soc$(DELIM)$(CHIP_SERIES)$(DELIM)system_internal.c
CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)$(CHIP_SERIES)$(DELIM)clk_tree_hal.c
@@ -129,6 +132,10 @@ CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)soc$
CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)soc$(DELIM)$(CHIP_SERIES)$(DELIM)i2c_periph.c
CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)soc$(DELIM)$(CHIP_SERIES)$(DELIM)mcpwm_periph.c
CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)soc$(DELIM)$(CHIP_SERIES)$(DELIM)temperature_sensor_periph.c
+CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)spi_flash$(DELIM)spi_flash_wrap.c
+CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)spi_flash$(DELIM)flash_ops.c
+CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)spi_flash$(DELIM)spi_flash_hpm_enable.c
+CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)spi_flash$(DELIM)${CHIP_SERIES}$(DELIM)spi_flash_oct_flash_init.c
ifeq ($(CONFIG_ESPRESSIF_SIMPLE_BOOT),y)
CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)src$(DELIM)bootloader_banner_wrap.c
@@ -138,8 +145,7 @@ ifeq ($(CONFIG_ESPRESSIF_SIMPLE_BOOT),y)
CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)src$(DELIM)bootloader_init.c
CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)src$(DELIM)bootloader_common.c
CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)src$(DELIM)bootloader_common_loader.c
- CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)bootloader_flash$(DELIM)src$(DELIM)bootloader_flash.c
- CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)bootloader_flash$(DELIM)src$(DELIM)bootloader_flash_config_${CHIP_SERIES}.c
+ CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)bootloader_flash$(DELIM)src$(DELIM)flash_qio_mode.c
CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)src$(DELIM)bootloader_clock_init.c
CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)src$(DELIM)bootloader_clock_loader.c
CHIP_CSRCS +=
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)src$(DELIM)bootloader_efuse.c
diff --git a/boards/xtensa/esp32s3/common/scripts/esp32s3_rom_aliases.ld
b/boards/xtensa/esp32s3/common/scripts/esp32s3_rom_aliases.ld
index 245e941f9f..46c451c1f7 100644
--- a/boards/xtensa/esp32s3/common/scripts/esp32s3_rom_aliases.ld
+++ b/boards/xtensa/esp32s3/common/scripts/esp32s3_rom_aliases.ld
@@ -39,3 +39,8 @@ PROVIDE( cache_suspend_icache = Cache_Suspend_ICache );
PROVIDE( cache_writeback_all = Cache_WriteBack_All );
PROVIDE( cache_writeback_items = Cache_WriteBack_Items );
PROVIDE( cache_writeback_addr = Cache_WriteBack_Addr );
+
+#ifndef CONFIG_ESP32S3_SPI_FLASH_DONT_USE_ROM_CODE
+spi_flash_guard_set = 0x40000b04;
+spi_flash_guard_get = 0x40000b10;
+#endif
diff --git a/boards/xtensa/esp32s3/common/scripts/esp32s3_sections.ld
b/boards/xtensa/esp32s3/common/scripts/esp32s3_sections.ld
index 221345ff07..b9714deae3 100644
--- a/boards/xtensa/esp32s3/common/scripts/esp32s3_sections.ld
+++ b/boards/xtensa/esp32s3/common/scripts/esp32s3_sections.ld
@@ -236,6 +236,10 @@ SECTIONS
*libarch.a:*cpu_region_protect.*(.text .text.* .literal .literal.*)
*libarch.a:*mspi_timing_tuning.*(.text .text.* .literal .literal.*)
*libarch.a:*esp_rom_cache_esp32s2_esp32s3.*(.literal .text .literal.*
.text.*)
+ *libarch.a:*flash_qio_mode.*(.text .text.* .literal .literal.*)
+ *libarch.a:*spi_flash_wrap.*(.text .text.* .literal .literal.*)
+ *libarch.a:*spi_flash_oct_flash_init.*(.text .text.* .literal .literal.*)
+ *libarch.a:*spi_flash_hpm_enable.*(.text .text.* .literal .literal.*)
*libc.a:*lib_instrument.*(.text .text.* .literal .literal.*)
@@ -432,6 +436,10 @@ SECTIONS
#ifdef CONFIG_ESP32S3_SPIRAM_MODE_OCT
*libarch.a:esp32s3_psram_octal.*(.rodata .rodata.*)
#endif
+ *libarch.a:*flash_qio_mode.*(.rodata .rodata.*)
+ *libarch.a:*spi_flash_wrap.*(.rodata .rodata.*)
+ *libarch.a:*spi_flash_oct_flash_init.*(.rodata .rodata.*)
+ *libarch.a:*spi_flash_hpm_enable.*(.rodata .rodata.*)
. = ALIGN(4);
_edata = ABSOLUTE(.);
diff --git a/tools/esp32s3/Config.mk b/tools/esp32s3/Config.mk
index 4e3aa20fcf..9d2dbf980e 100644
--- a/tools/esp32s3/Config.mk
+++ b/tools/esp32s3/Config.mk
@@ -42,6 +42,8 @@ else ifeq ($(CONFIG_ESP32S3_FLASH_MODE_QIO),y)
FLASH_MODE := qio
else ifeq ($(CONFIG_ESP32S3_FLASH_MODE_QOUT),y)
FLASH_MODE := qout
+else ifeq ($(CONFIG_ESP32S3_FLASH_MODE_OCT),y)
+ FLASH_MODE := qio
endif
FLASH_FREQ := $(CONFIG_ESPRESSIF_FLASH_FREQ)