소스 검색

spi_flash: add caps for dummy output control

michael 6 년 전
부모
커밋
3b1fa7b8f0

+ 6 - 1
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
+

+ 17 - 1
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)
+

+ 1 - 1
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*/

+ 1 - 1
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.*/

+ 21 - 1
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);

+ 8 - 23
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
+#define SPI_FLASH_SLOWRD_DUMMY_BITLEN   0