Skip to content

Commit

Permalink
feat(stub): Add ESP32-S3 octal flash support
Browse files Browse the repository at this point in the history
Octal flash support tested up to 32MB. Quad flash support is limited to
16MB at this moment.

Closes espressif/esptool#795

Closes espressif/esptool#745

The next release will solve espressif/esp-idf#10323 as well.
  • Loading branch information
dobairoland committed Feb 2, 2023
1 parent 0d2e17f commit 80e1a47
Show file tree
Hide file tree
Showing 7 changed files with 226 additions and 119 deletions.
2 changes: 1 addition & 1 deletion flasher_stub/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ $(STUB_ELF_32S2): $(SRCS) $(BUILD_DIR) ld/stub_32s2.ld

$(STUB_ELF_32S3_BETA_2): $(SRCS) $(BUILD_DIR) ld/stub_32s3_beta_2.ld
@echo " CC(32S3) $^ -> $@"
$(Q) $(CROSS_32S3)gcc $(CFLAGS) -DESP32S3=1 -Tstub_32s3_beta_2.ld -Wl,-Map=$(@:.elf=.map) -o $@ $(filter %.c, $^) $(LDLIBS)
$(Q) $(CROSS_32S3)gcc $(CFLAGS) -DESP32S3=1 -DESP32S3BETA2=1 -Tstub_32s3_beta_2.ld -Wl,-Map=$(@:.elf=.map) -o $@ $(filter %.c, $^) $(LDLIBS)

$(STUB_ELF_32S3): $(SRCS) $(BUILD_DIR) ld/stub_32s3.ld
@echo " CC(32S3) $^ -> $@"
Expand Down
158 changes: 136 additions & 22 deletions flasher_stub/include/rom_functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,22 +177,8 @@ typedef struct {
UartDevice * GetUartDevice();
#endif // WITH_USB_JTAG_SERIAL || WITH_USB_OTG

/* Enabling 32-bit flash memory addressing for ESP32S3 */
#if defined(ESP32S3)
#define BIT(nr) (1UL << (nr))

// GigaDevice Flash read commands
#define ROM_FLASH_CMD_RD4B_GD 0x13
#define ROM_FLASH_CMD_FSTRD4B_GD 0x0C
#define ROM_FLASH_CMD_FSTRD4B_OOUT_GD 0x7C
#define ROM_FLASH_CMD_FSTRD4B_OIOSTR_GD 0xCC
#define ROM_FLASH_CMD_FSTRD4B_OIODTR_GD 0xFD

// GigaDevice Flash page program commands
#define ROM_FLASH_CMD_PP4B_GD 0x12
#define ROM_FLASH_CMD_PP4B_OOUT_GD 0x84
#define ROM_FLASH_CMD_PP4B_OIOSTR_GD 0x8E

#define ESP_ROM_OPIFLASH_SEL_CS0 (BIT(0))

typedef enum {
Expand All @@ -216,7 +202,137 @@ typedef enum {
ESP_ROM_SPIFLASH_RESULT_TIMEOUT
} esp_rom_spiflash_result_t;

/* Stub doesn't currently support OPI flash mode, following functions are used for 32-bit addressing only */
#define CMD_RDID 0x9F
#define CMD_RDSR 0x05
#define CMD_WREN 0x06
#define CMD_SECTOR_ERASE_4B 0x21
#define CMD_FSTRD4B 0x0C
#define CMD_LARGE_BLOCK_ERASE_4B 0xDC
#define CMD_PROGRAM_PAGE_4B 0x12

#define OPIFLASH_DRIVER() { \
.rdid = { \
.mode = SPI_FLASH_FASTRD_MODE, \
.cmd_bit_len = 8, \
.cmd = CMD_RDID, \
.addr = 0, \
.addr_bit_len = 32, \
.dummy_bit_len = 4*2, \
.data_bit_len = 32, \
.cs_sel = 0x1, \
.is_pe = 0, \
}, \
.rdsr = { \
.mode = SPI_FLASH_FASTRD_MODE, \
.cmd_bit_len = 8, \
.cmd = CMD_RDSR, \
.addr = 0, \
.addr_bit_len = 32, \
.dummy_bit_len = 4*2, \
.data_bit_len = 16, \
.cs_sel = 0x1, \
.is_pe = 0, \
}, \
.wren = { \
.mode = SPI_FLASH_FASTRD_MODE, \
.cmd_bit_len = 8, \
.cmd = CMD_WREN, \
.addr = 0, \
.addr_bit_len = 0, \
.dummy_bit_len = 0, \
.data_bit_len = 0, \
.cs_sel = 0x1, \
.is_pe = 0, \
}, \
.se = { \
.mode = SPI_FLASH_FASTRD_MODE, \
.cmd_bit_len = 8, \
.cmd = CMD_SECTOR_ERASE_4B, \
.addr = 0, \
.addr_bit_len = 32, \
.dummy_bit_len = 0, \
.data_bit_len = 0, \
.cs_sel = 0x1, \
.is_pe = 1, \
}, \
.be64k = { \
.mode = SPI_FLASH_FASTRD_MODE, \
.cmd_bit_len = 8, \
.cmd = CMD_LARGE_BLOCK_ERASE_4B, \
.addr = 0, \
.addr_bit_len = 32, \
.dummy_bit_len = 0, \
.data_bit_len = 0, \
.cs_sel = 0x1, \
.is_pe = 1, \
}, \
.read = { \
.mode = SPI_FLASH_FASTRD_MODE, \
.cmd_bit_len = 8, \
.cmd = CMD_FSTRD4B, \
.addr = 0, \
.addr_bit_len = 32, \
.dummy_bit_len = 20*2, \
.data_bit_len = 0, \
.cs_sel = 0x1, \
.is_pe = 0, \
}, \
.pp = { \
.mode = SPI_FLASH_FASTRD_MODE, \
.cmd_bit_len = 8, \
.cmd = CMD_PROGRAM_PAGE_4B, \
.addr = 0, \
.addr_bit_len = 32, \
.dummy_bit_len = 0, \
.data_bit_len = 0, \
.cs_sel = 0x1, \
.is_pe = 1, \
}, \
.cache_rd_cmd = { \
.addr_bit_len = 32, \
.dummy_bit_len = 20*2, \
.cmd = CMD_FSTRD4B, \
.cmd_bit_len = 16, \
.var_dummy_en = 1, \
} \
}

#ifndef ESP32S3BETA2
typedef struct {
uint8_t mode;
uint8_t cmd_bit_len;
uint16_t cmd;
uint32_t addr;
uint8_t addr_bit_len;
uint8_t dummy_bit_len;
uint8_t data_bit_len;
uint8_t cs_sel: 4;
uint8_t is_pe: 4;
} esp_rom_opiflash_cmd_t;

typedef struct {
uint8_t addr_bit_len;
uint8_t dummy_bit_len;
uint16_t cmd;
uint8_t cmd_bit_len;
uint8_t var_dummy_en;
} esp_rom_opiflash_spi0rd_t;

typedef struct {
esp_rom_opiflash_cmd_t rdid;
esp_rom_opiflash_cmd_t rdsr;
esp_rom_opiflash_cmd_t wren;
esp_rom_opiflash_cmd_t se;
esp_rom_opiflash_cmd_t be64k;
esp_rom_opiflash_cmd_t read;
esp_rom_opiflash_cmd_t pp;
esp_rom_opiflash_spi0rd_t cache_rd_cmd;
} esp_rom_opiflash_def_t;

void esp_rom_opiflash_legacy_driver_init(const esp_rom_opiflash_def_t *flash_cmd_def);
bool ets_efuse_flash_octal_mode(void);
#endif //ESP32S3BETA2

void esp_rom_opiflash_exec_cmd(int spi_num, SpiFlashRdMode mode,
uint32_t cmd, int cmd_bit_len,
uint32_t addr, int addr_bit_len,
Expand All @@ -226,11 +342,9 @@ void esp_rom_opiflash_exec_cmd(int spi_num, SpiFlashRdMode mode,
uint32_t cs_mask,
bool is_write_erase_operation);

esp_rom_spiflash_result_t esp_rom_opiflash_wait_idle(int spi_num, SpiFlashRdMode mode);

esp_rom_spiflash_result_t opi_flash_wren(int spi_num, SpiFlashRdMode mode);

esp_rom_spiflash_result_t esp_rom_opiflash_erase_sector(int spi_num, uint32_t sector_num, SpiFlashRdMode mode);

esp_rom_spiflash_result_t esp_rom_opiflash_erase_block_64k(int spi_num, uint32_t block_num, SpiFlashRdMode mode);
esp_rom_spiflash_result_t esp_rom_opiflash_wait_idle();
esp_rom_spiflash_result_t esp_rom_opiflash_wren();
esp_rom_spiflash_result_t esp_rom_opiflash_erase_sector(uint32_t sector_num);
esp_rom_spiflash_result_t esp_rom_opiflash_erase_block_64k(uint32_t block_num);
SpiFlashOpResult SPI_write_enable(esp_rom_spiflash_chip_t *spi);
#endif // ESP32S3
5 changes: 0 additions & 5 deletions flasher_stub/include/stub_commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,6 @@ typedef struct {

esp_command_error handle_write_reg(const write_reg_args_t *cmd_buf, uint32_t num_commands);

/* Enabling 32-bit flash memory addressing for ESP32S3 */
#if defined(ESP32S3)
esp_rom_spiflash_result_t SPIRead4B(int spi_num, SpiFlashRdMode mode, uint32_t flash_addr, uint8_t* buf, int len);
#endif // ESP32S3

/* Get security info command only on ESP32S2 and later */
#if ESP32S2_OR_LATER
esp_command_error handle_get_security_info(void);
Expand Down
7 changes: 0 additions & 7 deletions flasher_stub/include/stub_write_flash.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,3 @@ void handle_flash_deflated_data(void *data_buf, uint32_t length);

/* same command used for deflated or non-deflated mode */
esp_command_error handle_flash_end(void);

/* Enabling 32-bit flash memory addressing for ESP32S3 */
#if defined(ESP32S3)
esp_rom_spiflash_result_t page_program_internal(int spi_num, SpiFlashRdMode mode, uint32_t spi_addr, uint8_t* addr_source, uint32_t byte_length);

esp_rom_spiflash_result_t SPIWrite4B(int spi_num, SpiFlashRdMode mode, uint32_t target, uint8_t *src_addr, int32_t len);
#endif // ESP32S3
69 changes: 32 additions & 37 deletions flasher_stub/stub_commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,33 +12,23 @@
#include "soc_support.h"
#include "stub_io.h"

#if defined(ESP32S3)
esp_rom_spiflash_result_t SPIRead4B(int spi_num, SpiFlashRdMode mode, uint32_t flash_addr, uint8_t* buf, int len)
#if defined(ESP32S3) && !defined(ESP32S3BETA2)
static esp_rom_spiflash_result_t SPIRead4B(int spi_num, uint32_t flash_addr, uint8_t* buf, int len)
{
uint8_t cmd = mode == SPI_FLASH_FASTRD_MODE ? ROM_FLASH_CMD_FSTRD4B_GD :
mode == SPI_FLASH_OOUT_MODE ? ROM_FLASH_CMD_FSTRD4B_OOUT_GD :
mode == SPI_FLASH_OIO_STR_MODE ? ROM_FLASH_CMD_FSTRD4B_OIOSTR_GD :
mode == SPI_FLASH_OIO_DTR_MODE ? ROM_FLASH_CMD_FSTRD4B_OIODTR_GD :
mode == SPI_FLASH_SLOWRD_MODE ? ROM_FLASH_CMD_RD4B_GD : ROM_FLASH_CMD_RD4B_GD;
int dummy = mode == SPI_FLASH_FASTRD_MODE ? 8 :
mode == SPI_FLASH_OOUT_MODE ? 8 :
mode == SPI_FLASH_OIO_STR_MODE ? 16 :
mode == SPI_FLASH_OIO_DTR_MODE ? 32 :
mode == SPI_FLASH_SLOWRD_MODE ? 0 : 0;
uint8_t cmd_len = 8;

esp_rom_opiflash_wait_idle(spi_num, SPI_FLASH_FASTRD_MODE);
esp_rom_opiflash_wait_idle();
while (len > 0) {
int rd_length;
if (len > 16 ) { //16 = read_sub_len
rd_length = 16;
} else {
rd_length = len;
}
esp_rom_opiflash_exec_cmd(spi_num, mode,
cmd, cmd_len,
esp_rom_opiflash_exec_cmd(spi_num, SPI_FLASH_FASTRD_MODE,
CMD_FSTRD4B, cmd_len,
flash_addr, 32,
dummy,
8,
NULL, 0,
buf, 8 * rd_length,
ESP_ROM_OPIFLASH_SEL_CS0,
Expand All @@ -58,11 +48,12 @@ int handle_flash_erase(uint32_t addr, uint32_t len) {
if (SPIUnlock() != 0) return 0x34;

while (len > 0 && (addr % FLASH_BLOCK_SIZE != 0)) {
#if defined(ESP32S3)
if (addr > 0x00ffffff) {
if (esp_rom_opiflash_erase_sector(1, addr / FLASH_SECTOR_SIZE, SPI_FLASH_FASTRD_MODE) != 0) return 0x35; }
else
if (SPIEraseSector(addr / FLASH_SECTOR_SIZE) != 0) return 0x35;
#if defined(ESP32S3) && !defined(ESP32S3BETA2)
if (ets_efuse_flash_octal_mode()) {
if (esp_rom_opiflash_erase_sector(addr / FLASH_SECTOR_SIZE) != 0) return 0x35;
} else {
if (SPIEraseSector(addr / FLASH_SECTOR_SIZE) != 0) return 0x35;
}
#else
if (SPIEraseSector(addr / FLASH_SECTOR_SIZE) != 0) return 0x35;
#endif // ESP32S3
Expand All @@ -71,11 +62,12 @@ int handle_flash_erase(uint32_t addr, uint32_t len) {
}

while (len > FLASH_BLOCK_SIZE) {
#if defined(ESP32S3)
if (addr > 0x00ffffff) {
if (esp_rom_opiflash_erase_block_64k(1, addr / FLASH_BLOCK_SIZE, SPI_FLASH_FASTRD_MODE) != 0) return 0x36; }
else
#if defined(ESP32S3) && !defined(ESP32S3BETA2)
if (ets_efuse_flash_octal_mode()) {
if (esp_rom_opiflash_erase_block_64k(addr / FLASH_BLOCK_SIZE) != 0) return 0x36;
} else {
if (SPIEraseBlock(addr / FLASH_BLOCK_SIZE) != 0) return 0x36;
}
#else
if (SPIEraseBlock(addr / FLASH_BLOCK_SIZE) != 0) return 0x36;
#endif // ESP32S3
Expand All @@ -84,11 +76,12 @@ int handle_flash_erase(uint32_t addr, uint32_t len) {
}

while (len > 0) {
#if defined(ESP32S3)
if (addr > 0x00ffffff) {
if (esp_rom_opiflash_erase_sector(1, addr / FLASH_SECTOR_SIZE, SPI_FLASH_FASTRD_MODE) != 0) return 0x37; }
else
#if defined(ESP32S3) && !defined(ESP32S3BETA2)
if (ets_efuse_flash_octal_mode()) {
if (esp_rom_opiflash_erase_sector(addr / FLASH_SECTOR_SIZE) != 0) return 0x37;
} else {
if (SPIEraseSector(addr / FLASH_SECTOR_SIZE) != 0) return 0x37;
}
#else
if (SPIEraseSector(addr / FLASH_SECTOR_SIZE) != 0) return 0x37;
#endif // ESP32S3
Expand Down Expand Up @@ -118,11 +111,12 @@ void handle_flash_read(uint32_t addr, uint32_t len, uint32_t block_size,
while (num_sent < len && num_sent - num_acked < max_in_flight) {
uint32_t n = len - num_sent;
if (n > block_size) n = block_size;
#if defined(ESP32S3)
if (addr + n > 0x01000000)
res = SPIRead4B(1, SPI_FLASH_FASTRD_MODE, addr, buf, n);
else
#if defined(ESP32S3) && !defined(ESP32S3BETA2)
if (ets_efuse_flash_octal_mode()) {
res = SPIRead4B(1, addr, buf, n);
} else {
res = SPIRead(addr, (uint32_t *)buf, n);
}
#else
res = SPIRead(addr, (uint32_t *)buf, n);
#endif // ESP32S3
Expand Down Expand Up @@ -157,11 +151,12 @@ int handle_flash_get_md5sum(uint32_t addr, uint32_t len) {
if (n > FLASH_SECTOR_SIZE) {
n = FLASH_SECTOR_SIZE;
}
#if defined(ESP32S3)
if (addr + n > 0x01000000)
res = SPIRead4B(1, SPI_FLASH_FASTRD_MODE, addr, buf, n);
else
#if defined(ESP32S3) && !defined(ESP32S3BETA2)
if (ets_efuse_flash_octal_mode()) {
res = SPIRead4B(1, addr, buf, n);
} else {
res = SPIRead(addr, (uint32_t *)buf, n);
}
#else
res = SPIRead(addr, (uint32_t *)buf, n);
#endif // ESP32S3
Expand Down
7 changes: 7 additions & 0 deletions flasher_stub/stub_flasher.c
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,13 @@ void stub_main()
}
spi_flash_attach(spiconfig, 0);
#endif
#if ESP32S3 && !ESP32S3BETA2
// OPI calls are used only for octal chips. However, driver is initialized in all cases in order to avoid
// potentional misterious errors originating from ROM assertions.
static const esp_rom_opiflash_def_t flash_driver = OPIFLASH_DRIVER();
esp_rom_opiflash_legacy_driver_init(&flash_driver);
esp_rom_opiflash_wait_idle();
#endif //ESP32S3 && !ESP32S3BETA2
SPIParamCfg(0, FLASH_MAX_SIZE, FLASH_BLOCK_SIZE, FLASH_SECTOR_SIZE,
FLASH_PAGE_SIZE, FLASH_STATUS_MASK);

Expand Down
Loading

0 comments on commit 80e1a47

Please sign in to comment.