diff --git a/components/soc/soc/esp32/include/soc/spi_caps.h b/components/soc/soc/esp32/include/soc/spi_caps.h index d5b19b4d70..8ccc3e7893 100644 --- a/components/soc/soc/esp32/include/soc/spi_caps.h +++ b/components/soc/soc/esp32/include/soc/spi_caps.h @@ -60,4 +60,9 @@ //#define SOC_SPI_SLAVE_SUPPORT_SEG_TRANS //#define SOC_SPI_SUPPORT_CD_SIG -#define SOC_SPI_PERIPH_SUPPORT_MULTILINE_MODE(SPI_HOST) true +// Peripheral supports DIO, DOUT, QIO, or QOUT +#define SOC_SPI_PERIPH_SUPPORT_MULTILINE_MODE(spi_dev) 1 + +// Peripheral doesn't support output given level during its "dummy phase" +#define SOC_SPI_PERIPH_SUPPORT_CONTROL_DUMMY_OUTPUT(spi_dev) 0 + diff --git a/components/soc/soc/esp32s2/include/soc/spi_caps.h b/components/soc/soc/esp32s2/include/soc/spi_caps.h index 16d5a2252a..66c0999d62 100644 --- a/components/soc/soc/esp32s2/include/soc/spi_caps.h +++ b/components/soc/soc/esp32s2/include/soc/spi_caps.h @@ -45,5 +45,21 @@ #define SOC_SPI_SUPPORT_CD_SIG 1 #define SOC_SPI_SUPPORT_CONTINUOUS_TRANS 1 + +#ifdef __cplusplus +extern "C" { +#endif +struct spi_dev_s; +extern volatile struct spi_dev_s GPSPI3; +struct spi_mem_dev_s; +extern volatile struct spi_mem_dev_s SPIMEM1; +#ifdef __cplusplus +} +#endif + // Peripheral supports DIO, DOUT, QIO, or QOUT -#define SOC_SPI_PERIPH_SUPPORT_MULTILINE_MODE(spi_dev) (!((void*)spi_dev == (void*)&GPSPI3)) +#define SOC_SPI_PERIPH_SUPPORT_MULTILINE_MODE(spi_dev) (!((void*)spi_dev == (void*)&GPSPI3)) + +// Peripheral supports output given level during its "dummy phase" +#define SOC_SPI_PERIPH_SUPPORT_CONTROL_DUMMY_OUTPUT(spi_dev) ((void*)spi_dev == (void*)&SPIMEM1) + diff --git a/components/soc/soc/esp32s2/include/soc/spi_mem_struct.h b/components/soc/soc/esp32s2/include/soc/spi_mem_struct.h index ec9198ac3e..ee318c20f1 100644 --- a/components/soc/soc/esp32s2/include/soc/spi_mem_struct.h +++ b/components/soc/soc/esp32s2/include/soc/spi_mem_struct.h @@ -17,7 +17,7 @@ extern "C" { #endif -typedef volatile struct { +typedef volatile struct spi_mem_dev_s { union { struct { uint32_t reserved0: 17; /*reserved*/ diff --git a/components/soc/soc/esp32s2/include/soc/spi_struct.h b/components/soc/soc/esp32s2/include/soc/spi_struct.h index d1d7ded3b6..2d8f4b373b 100644 --- a/components/soc/soc/esp32s2/include/soc/spi_struct.h +++ b/components/soc/soc/esp32s2/include/soc/spi_struct.h @@ -17,7 +17,7 @@ extern "C" { #endif -typedef volatile struct { +typedef volatile struct spi_dev_s { union { struct { uint32_t conf_bitlen:23; /*Define the spi_clk cycles of SPI_CONF state. Can be configured in CONF state.*/ diff --git a/components/soc/src/hal/spi_flash_hal_common.inc b/components/soc/src/hal/spi_flash_hal_common.inc index 9bf06f31aa..f42a1f6ba2 100644 --- a/components/soc/src/hal/spi_flash_hal_common.inc +++ b/components/soc/src/hal/spi_flash_hal_common.inc @@ -55,12 +55,32 @@ esp_err_t spi_flash_hal_configure_host_io_mode( if (!SOC_SPI_PERIPH_SUPPORT_MULTILINE_MODE(dev) && io_mode > SPI_FLASH_FASTRD) { return ESP_ERR_NOT_SUPPORTED; } + if (addr_bitlen > 24 && SOC_SPI_PERIPH_SUPPORT_CONTROL_DUMMY_OUTPUT(dev)) { + /* + * The extra address bits (24-addr_bitlen) are used to control the M7-M0 bits right after + * the address field, to avoid the flash going into continuous read mode. + * + * On ESP32-S2 the MEMSPI (that SUPPORT_CONTROL_DUMMY_OUTPUT), the least significant + * addr_bitlen bits of the address will be used, instead of the MSBs. The driver is + * required to set the address according to the extra address bits. + * + * To reduce the time consuming for the read() function to calculate the shift of address, + * the addr_bitlen is kept to 24 bits. And the CONTROL_DUMMY_OUTPUT feature is used to + * control those bits instead. + */ + + //This block is only reached when SPI_FLASH_QIO or SPI_FLASH_DIO + assert(io_mode == SPI_FLASH_DIO || io_mode == SPI_FLASH_QIO); + int line_width = (io_mode == SPI_FLASH_DIO? 2: 4); + dummy_cyclelen_base += (addr_bitlen - 24) / line_width; + addr_bitlen = 24; + spi_flash_ll_set_dummy_out(dev, 1, 1); + } spi_flash_ll_set_command8(dev, command); spi_flash_ll_set_addr_bitlen(dev, addr_bitlen); // Add dummy cycles to compensate for latency of GPIO matrix and external delay, if necessary... spi_flash_ll_set_dummy(dev, COMPUTE_DUMMY_CYCLELEN(host, dummy_cyclelen_base)); - spi_flash_ll_set_dummy_out(dev, 1, 1); //disable all data phases, enable them later if needed spi_flash_ll_set_miso_bitlen(dev, 0); spi_flash_ll_set_mosi_bitlen(dev, 0); diff --git a/components/spi_flash/private_include/spi_flash_defs.h b/components/spi_flash/private_include/spi_flash_defs.h index ea6df9a266..e37b9780cb 100644 --- a/components/spi_flash/private_include/spi_flash_defs.h +++ b/components/spi_flash/private_include/spi_flash_defs.h @@ -42,30 +42,15 @@ #define CMD_RST_EN 0x66 #define CMD_RST_DEV 0x99 -#ifdef CONFIG_IDF_TARGET_ESP32S2 -#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_DIO_ADDR_BITLEN (24+4) +#define SPI_FLASH_DIO_DUMMY_BITLEN 2 +#define SPI_FLASH_QIO_ADDR_BITLEN (24+8) +#define SPI_FLASH_QIO_DUMMY_BITLEN 4 #define SPI_FLASH_QOUT_ADDR_BITLEN 24 -#define SPI_FLASH_QOUT_DUMMY_BITLEN 8 +#define SPI_FLASH_QOUT_DUMMY_BITLEN 8 #define SPI_FLASH_DOUT_ADDR_BITLEN 24 -#define SPI_FLASH_DOUT_DUMMY_BITLEN 8 +#define SPI_FLASH_DOUT_DUMMY_BITLEN 8 #define SPI_FLASH_FASTRD_ADDR_BITLEN 24 -#define SPI_FLASH_FASTRD_DUMMY_BITLEN 8 +#define SPI_FLASH_FASTRD_DUMMY_BITLEN 8 #define SPI_FLASH_SLOWRD_ADDR_BITLEN 24 -#define SPI_FLASH_SLOWRD_DUMMY_BITLEN 0 -#else -#define SPI_FLASH_DIO_ADDR_BITLEN 28 -#define SPI_FLASH_DIO_DUMMY_BITLEN 2 -#define SPI_FLASH_QIO_ADDR_BITLEN 32 -#define SPI_FLASH_QIO_DUMMY_BITLEN 4 -#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 -#endif \ No newline at end of file +#define SPI_FLASH_SLOWRD_DUMMY_BITLEN 0