فهرست منبع

spi_flash: 32M bits address flash map, (for customer use only)

Cao Sen Miao 3 سال پیش
والد
کامیت
c7053641bc

+ 7 - 0
components/bootloader_support/bootloader_flash/include/bootloader_flash.h

@@ -54,6 +54,13 @@ esp_err_t bootloader_flash_reset_chip(void);
  */
 bool bootloader_flash_is_octal_mode_enabled(void);
 
+/**
+ * @brief Get the spi flash working mode.
+ *
+ * @return The mode of flash working mode, see `esp_rom_spiflash_read_mode_t`
+ */
+esp_rom_spiflash_read_mode_t bootloader_flash_get_spi_mode(void);
+
 #ifdef __cplusplus
 }
 #endif

+ 11 - 0
components/bootloader_support/bootloader_flash/include/bootloader_flash_override.h

@@ -109,6 +109,17 @@ extern const bootloader_qio_info_t __attribute__((weak)) bootloader_flash_qe_sup
   */
 esp_err_t __attribute__((weak)) bootloader_flash_unlock(void);
 
+#if CONFIG_SPI_FLASH_32BIT_ADDR_ENABLE
+/**
+ * @brief Enable 32bits address flash(larger than 16MB) can map to cache.
+ *
+ * @param flash_mode SPI flash working mode.
+ *
+ * @note This can be overridden because it's attribute weak.
+ */
+void __attribute__((weak)) bootloader_flash_32bits_address_map_enable(esp_rom_spiflash_read_mode_t flash_mode);
+#endif
+
 #ifdef __cplusplus
 }
 #endif

+ 4 - 0
components/bootloader_support/bootloader_flash/include/bootloader_flash_priv.h

@@ -52,6 +52,10 @@ extern "C" {
 #define CMD_RESUME     0x7A /* Resume command to clear flash suspend bit */
 #define CMD_RESETEN    0x66
 #define CMD_RESET      0x99
+#define CMD_FASTRD_QIO_4B   0xEC
+#define CMD_FASTRD_QUAD_4B  0x6C
+#define CMD_FASTRD_DIO_4B   0xBC
+#define CMD_FASTRD_DUAL_4B  0x3C
 
 
 /* Provide a Flash API for bootloader_support code,

+ 80 - 0
components/bootloader_support/bootloader_flash/src/bootloader_flash.c

@@ -123,6 +123,10 @@ esp_err_t bootloader_flash_erase_range(uint32_t start_addr, uint32_t size)
 #include "hal/mmu_hal.h"
 #include "hal/mmu_ll.h"
 #include "hal/cache_hal.h"
+
+#if CONFIG_IDF_TARGET_ESP32S3
+#include "esp32s3/rom/opi_flash.h"
+#endif
 static const char *TAG = "bootloader_flash";
 
 #if CONFIG_IDF_TARGET_ESP32
@@ -409,6 +413,45 @@ esp_err_t bootloader_flash_erase_range(uint32_t start_addr, uint32_t size)
     return spi_to_esp_err(rc);
 }
 
+#if CONFIG_SPI_FLASH_32BIT_ADDR_ENABLE
+void bootloader_flash_32bits_address_map_enable(esp_rom_spiflash_read_mode_t flash_mode)
+{
+    esp_rom_opiflash_spi0rd_t cache_rd = {};
+    switch (flash_mode) {
+    case ESP_ROM_SPIFLASH_DOUT_MODE:
+        cache_rd.addr_bit_len = 32;
+        cache_rd.dummy_bit_len = 8;
+        cache_rd.cmd = CMD_FASTRD_DUAL_4B;
+        cache_rd.cmd_bit_len = 8;
+        break;
+    case ESP_ROM_SPIFLASH_DIO_MODE:
+        cache_rd.addr_bit_len = 32;
+        cache_rd.dummy_bit_len = 4;
+        cache_rd.cmd = CMD_FASTRD_DIO_4B;
+        cache_rd.cmd_bit_len = 8;
+        break;
+    case ESP_ROM_SPIFLASH_QOUT_MODE:
+        cache_rd.addr_bit_len = 32;
+        cache_rd.dummy_bit_len = 8;
+        cache_rd.cmd = CMD_FASTRD_QUAD_4B;
+        cache_rd.cmd_bit_len = 8;
+        break;
+    case ESP_ROM_SPIFLASH_QIO_MODE:
+        cache_rd.addr_bit_len = 32;
+        cache_rd.dummy_bit_len = 6;
+        cache_rd.cmd = CMD_FASTRD_QIO_4B;
+        cache_rd.cmd_bit_len = 8;
+        break;
+    default:
+        assert(false);
+        break;
+    }
+    cache_hal_disable(CACHE_TYPE_ALL);
+    esp_rom_opiflash_cache_mode_config(flash_mode, &cache_rd);
+    cache_hal_enable(CACHE_TYPE_ALL);
+}
+#endif
+
 #endif // BOOTLOADER_BUILD
 
 
@@ -755,3 +798,40 @@ bool IRAM_ATTR bootloader_flash_is_octal_mode_enabled(void)
     return false;
 #endif
 }
+
+esp_rom_spiflash_read_mode_t bootloader_flash_get_spi_mode(void)
+{
+    esp_rom_spiflash_read_mode_t spi_mode = ESP_ROM_SPIFLASH_FASTRD_MODE;
+#if CONFIG_IDF_TARGET_ESP32
+    uint32_t spi_ctrl = REG_READ(SPI_CTRL_REG(0));
+    if (spi_ctrl & SPI_FREAD_QIO) {
+        spi_mode = ESP_ROM_SPIFLASH_QIO_MODE;
+    } else if (spi_ctrl & SPI_FREAD_QUAD) {
+        spi_mode = ESP_ROM_SPIFLASH_QOUT_MODE;
+    } else if (spi_ctrl & SPI_FREAD_DIO) {
+        spi_mode = ESP_ROM_SPIFLASH_DIO_MODE;
+    } else if (spi_ctrl & SPI_FREAD_DUAL) {
+        spi_mode = ESP_ROM_SPIFLASH_DOUT_MODE;
+    } else if (spi_ctrl & SPI_FASTRD_MODE) {
+        spi_mode = ESP_ROM_SPIFLASH_FASTRD_MODE;
+    } else {
+        spi_mode = ESP_ROM_SPIFLASH_SLOWRD_MODE;
+    }
+#else
+    uint32_t spi_ctrl = REG_READ(SPI_MEM_CTRL_REG(0));
+    if (spi_ctrl & SPI_MEM_FREAD_QIO) {
+        spi_mode = ESP_ROM_SPIFLASH_QIO_MODE;
+    } else if (spi_ctrl & SPI_MEM_FREAD_QUAD) {
+        spi_mode = ESP_ROM_SPIFLASH_QOUT_MODE;
+    } else if (spi_ctrl & SPI_MEM_FREAD_DIO) {
+        spi_mode = ESP_ROM_SPIFLASH_DIO_MODE;
+    } else if (spi_ctrl & SPI_MEM_FREAD_DUAL) {
+        spi_mode = ESP_ROM_SPIFLASH_DOUT_MODE;
+    } else if (spi_ctrl & SPI_MEM_FASTRD_MODE) {
+        spi_mode = ESP_ROM_SPIFLASH_FASTRD_MODE;
+    } else {
+        spi_mode = ESP_ROM_SPIFLASH_SLOWRD_MODE;
+    }
+#endif
+    return spi_mode;
+}

+ 14 - 7
components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32.c

@@ -308,19 +308,26 @@ static void print_flash_info(const esp_image_header_t *bootloader_hdr)
 
     /* SPI mode could have been set to QIO during boot already,
        so test the SPI registers not the flash header */
-    uint32_t spi_ctrl = REG_READ(SPI_CTRL_REG(0));
-    if (spi_ctrl & SPI_FREAD_QIO) {
+    esp_rom_spiflash_read_mode_t spi_mode = bootloader_flash_get_spi_mode();
+    switch (spi_mode) {
+    case ESP_ROM_SPIFLASH_QIO_MODE:
         str = "QIO";
-    } else if (spi_ctrl & SPI_FREAD_QUAD) {
+        break;
+    case ESP_ROM_SPIFLASH_QOUT_MODE:
         str = "QOUT";
-    } else if (spi_ctrl & SPI_FREAD_DIO) {
+        break;
+    case ESP_ROM_SPIFLASH_DIO_MODE:
         str = "DIO";
-    } else if (spi_ctrl & SPI_FREAD_DUAL) {
+        break;
+    case ESP_ROM_SPIFLASH_DOUT_MODE:
         str = "DOUT";
-    } else if (spi_ctrl & SPI_FASTRD_MODE) {
+        break;
+    case ESP_ROM_SPIFLASH_FASTRD_MODE:
         str = "FAST READ";
-    } else {
+        break;
+    default:
         str = "SLOW READ";
+        break;
     }
     ESP_EARLY_LOGI(TAG, "SPI Mode       : %s", str);
 

+ 14 - 7
components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c2.c

@@ -163,19 +163,26 @@ static void print_flash_info(const esp_image_header_t *bootloader_hdr)
 
     /* SPI mode could have been set to QIO during boot already,
        so test the SPI registers not the flash header */
-    uint32_t spi_ctrl = REG_READ(SPI_MEM_CTRL_REG(0));
-    if (spi_ctrl & SPI_MEM_FREAD_QIO) {
+    esp_rom_spiflash_read_mode_t spi_mode = bootloader_flash_get_spi_mode();
+    switch (spi_mode) {
+    case ESP_ROM_SPIFLASH_QIO_MODE:
         str = "QIO";
-    } else if (spi_ctrl & SPI_MEM_FREAD_QUAD) {
+        break;
+    case ESP_ROM_SPIFLASH_QOUT_MODE:
         str = "QOUT";
-    } else if (spi_ctrl & SPI_MEM_FREAD_DIO) {
+        break;
+    case ESP_ROM_SPIFLASH_DIO_MODE:
         str = "DIO";
-    } else if (spi_ctrl & SPI_MEM_FREAD_DUAL) {
+        break;
+    case ESP_ROM_SPIFLASH_DOUT_MODE:
         str = "DOUT";
-    } else if (spi_ctrl & SPI_MEM_FASTRD_MODE) {
+        break;
+    case ESP_ROM_SPIFLASH_FASTRD_MODE:
         str = "FAST READ";
-    } else {
+        break;
+    default:
         str = "SLOW READ";
+        break;
     }
     ESP_EARLY_LOGI(TAG, "SPI Mode       : %s", str);
 

+ 14 - 7
components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c3.c

@@ -174,19 +174,26 @@ static void print_flash_info(const esp_image_header_t *bootloader_hdr)
 
     /* SPI mode could have been set to QIO during boot already,
        so test the SPI registers not the flash header */
-    uint32_t spi_ctrl = REG_READ(SPI_MEM_CTRL_REG(0));
-    if (spi_ctrl & SPI_MEM_FREAD_QIO) {
+    esp_rom_spiflash_read_mode_t spi_mode = bootloader_flash_get_spi_mode();
+    switch (spi_mode) {
+    case ESP_ROM_SPIFLASH_QIO_MODE:
         str = "QIO";
-    } else if (spi_ctrl & SPI_MEM_FREAD_QUAD) {
+        break;
+    case ESP_ROM_SPIFLASH_QOUT_MODE:
         str = "QOUT";
-    } else if (spi_ctrl & SPI_MEM_FREAD_DIO) {
+        break;
+    case ESP_ROM_SPIFLASH_DIO_MODE:
         str = "DIO";
-    } else if (spi_ctrl & SPI_MEM_FREAD_DUAL) {
+        break;
+    case ESP_ROM_SPIFLASH_DOUT_MODE:
         str = "DOUT";
-    } else if (spi_ctrl & SPI_MEM_FASTRD_MODE) {
+        break;
+    case ESP_ROM_SPIFLASH_FASTRD_MODE:
         str = "FAST READ";
-    } else {
+        break;
+    default:
         str = "SLOW READ";
+        break;
     }
     ESP_EARLY_LOGI(TAG, "SPI Mode       : %s", str);
 

+ 14 - 7
components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c6.c

@@ -139,19 +139,26 @@ static void print_flash_info(const esp_image_header_t *bootloader_hdr)
 
     /* SPI mode could have been set to QIO during boot already,
        so test the SPI registers not the flash header */
-    uint32_t spi_ctrl = REG_READ(SPI_MEM_CTRL_REG(0));
-    if (spi_ctrl & SPI_MEM_FREAD_QIO) {
+    esp_rom_spiflash_read_mode_t spi_mode = bootloader_flash_get_spi_mode();
+    switch (spi_mode) {
+    case ESP_ROM_SPIFLASH_QIO_MODE:
         str = "QIO";
-    } else if (spi_ctrl & SPI_MEM_FREAD_QUAD) {
+        break;
+    case ESP_ROM_SPIFLASH_QOUT_MODE:
         str = "QOUT";
-    } else if (spi_ctrl & SPI_MEM_FREAD_DIO) {
+        break;
+    case ESP_ROM_SPIFLASH_DIO_MODE:
         str = "DIO";
-    } else if (spi_ctrl & SPI_MEM_FREAD_DUAL) {
+        break;
+    case ESP_ROM_SPIFLASH_DOUT_MODE:
         str = "DOUT";
-    } else if (spi_ctrl & SPI_MEM_FASTRD_MODE) {
+        break;
+    case ESP_ROM_SPIFLASH_FASTRD_MODE:
         str = "FAST READ";
-    } else {
+        break;
+    default:
         str = "SLOW READ";
+        break;
     }
     ESP_EARLY_LOGI(TAG, "SPI Mode       : %s", str);
 

+ 14 - 7
components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32h2.c

@@ -146,19 +146,26 @@ static void print_flash_info(const esp_image_header_t *bootloader_hdr)
 
     /* SPI mode could have been set to QIO during boot already,
        so test the SPI registers not the flash header */
-    uint32_t spi_ctrl = REG_READ(SPI_MEM_CTRL_REG(0));
-    if (spi_ctrl & SPI_MEM_FREAD_QIO) {
+    esp_rom_spiflash_read_mode_t spi_mode = bootloader_flash_get_spi_mode();
+    switch (spi_mode) {
+    case ESP_ROM_SPIFLASH_QIO_MODE:
         str = "QIO";
-    } else if (spi_ctrl & SPI_MEM_FREAD_QUAD) {
+        break;
+    case ESP_ROM_SPIFLASH_QOUT_MODE:
         str = "QOUT";
-    } else if (spi_ctrl & SPI_MEM_FREAD_DIO) {
+        break;
+    case ESP_ROM_SPIFLASH_DIO_MODE:
         str = "DIO";
-    } else if (spi_ctrl & SPI_MEM_FREAD_DUAL) {
+        break;
+    case ESP_ROM_SPIFLASH_DOUT_MODE:
         str = "DOUT";
-    } else if (spi_ctrl & SPI_MEM_FASTRD_MODE) {
+        break;
+    case ESP_ROM_SPIFLASH_FASTRD_MODE:
         str = "FAST READ";
-    } else {
+        break;
+    default:
         str = "SLOW READ";
+        break;
     }
     ESP_EARLY_LOGI(TAG, "SPI Mode       : %s", str);
 

+ 14 - 7
components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32h4.c

@@ -173,19 +173,26 @@ static void print_flash_info(const esp_image_header_t *bootloader_hdr)
 
     /* SPI mode could have been set to QIO during boot already,
        so test the SPI registers not the flash header */
-    uint32_t spi_ctrl = REG_READ(SPI_MEM_CTRL_REG(0));
-    if (spi_ctrl & SPI_MEM_FREAD_QIO) {
+    esp_rom_spiflash_read_mode_t spi_mode = bootloader_flash_get_spi_mode();
+    switch (spi_mode) {
+    case ESP_ROM_SPIFLASH_QIO_MODE:
         str = "QIO";
-    } else if (spi_ctrl & SPI_MEM_FREAD_QUAD) {
+        break;
+    case ESP_ROM_SPIFLASH_QOUT_MODE:
         str = "QOUT";
-    } else if (spi_ctrl & SPI_MEM_FREAD_DIO) {
+        break;
+    case ESP_ROM_SPIFLASH_DIO_MODE:
         str = "DIO";
-    } else if (spi_ctrl & SPI_MEM_FREAD_DUAL) {
+        break;
+    case ESP_ROM_SPIFLASH_DOUT_MODE:
         str = "DOUT";
-    } else if (spi_ctrl & SPI_MEM_FASTRD_MODE) {
+        break;
+    case ESP_ROM_SPIFLASH_FASTRD_MODE:
         str = "FAST READ";
-    } else {
+        break;
+    default:
         str = "SLOW READ";
+        break;
     }
     ESP_EARLY_LOGI(TAG, "SPI Mode       : %s", str);
 

+ 14 - 7
components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s2.c

@@ -188,19 +188,26 @@ static void print_flash_info(const esp_image_header_t *bootloader_hdr)
 
     /* SPI mode could have been set to QIO during boot already,
        so test the SPI registers not the flash header */
-    uint32_t spi_ctrl = REG_READ(SPI_MEM_CTRL_REG(0));
-    if (spi_ctrl & SPI_MEM_FREAD_QIO) {
+    esp_rom_spiflash_read_mode_t spi_mode = bootloader_flash_get_spi_mode();
+    switch (spi_mode) {
+    case ESP_ROM_SPIFLASH_QIO_MODE:
         str = "QIO";
-    } else if (spi_ctrl & SPI_MEM_FREAD_QUAD) {
+        break;
+    case ESP_ROM_SPIFLASH_QOUT_MODE:
         str = "QOUT";
-    } else if (spi_ctrl & SPI_MEM_FREAD_DIO) {
+        break;
+    case ESP_ROM_SPIFLASH_DIO_MODE:
         str = "DIO";
-    } else if (spi_ctrl & SPI_MEM_FREAD_DUAL) {
+        break;
+    case ESP_ROM_SPIFLASH_DOUT_MODE:
         str = "DOUT";
-    } else if (spi_ctrl & SPI_MEM_FASTRD_MODE) {
+        break;
+    case ESP_ROM_SPIFLASH_FASTRD_MODE:
         str = "FAST READ";
-    } else {
+        break;
+    default:
         str = "SLOW READ";
+        break;
     }
     ESP_EARLY_LOGI(TAG, "SPI Mode       : %s", str);
 

+ 17 - 8
components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s3.c

@@ -195,19 +195,26 @@ static void print_flash_info(const esp_image_header_t *bootloader_hdr)
 
     /* SPI mode could have been set to QIO during boot already,
        so test the SPI registers not the flash header */
-    uint32_t spi_ctrl = REG_READ(SPI_MEM_CTRL_REG(0));
-    if (spi_ctrl & SPI_MEM_FREAD_QIO) {
+    esp_rom_spiflash_read_mode_t spi_mode = bootloader_flash_get_spi_mode();
+    switch (spi_mode) {
+    case ESP_ROM_SPIFLASH_QIO_MODE:
         str = "QIO";
-    } else if (spi_ctrl & SPI_MEM_FREAD_QUAD) {
+        break;
+    case ESP_ROM_SPIFLASH_QOUT_MODE:
         str = "QOUT";
-    } else if (spi_ctrl & SPI_MEM_FREAD_DIO) {
+        break;
+    case ESP_ROM_SPIFLASH_DIO_MODE:
         str = "DIO";
-    } else if (spi_ctrl & SPI_MEM_FREAD_DUAL) {
+        break;
+    case ESP_ROM_SPIFLASH_DOUT_MODE:
         str = "DOUT";
-    } else if (spi_ctrl & SPI_MEM_FASTRD_MODE) {
+        break;
+    case ESP_ROM_SPIFLASH_FASTRD_MODE:
         str = "FAST READ";
-    } else {
+        break;
+    default:
         str = "SLOW READ";
+        break;
     }
     ESP_EARLY_LOGI(TAG, "SPI Mode       : %s", str);
 
@@ -272,7 +279,9 @@ esp_err_t bootloader_init_spi_flash(void)
         bootloader_enable_qio_mode();
     }
 #endif
-
+#if CONFIG_SPI_FLASH_32BIT_ADDR_ENABLE
+    bootloader_flash_32bits_address_map_enable(bootloader_flash_get_spi_mode());
+#endif
     print_flash_info(&bootloader_image_hdr);
     update_flash_config(&bootloader_image_hdr);
     //ensure the flash is write-protected

+ 18 - 0
components/spi_flash/Kconfig

@@ -310,4 +310,22 @@ menu "SPI Flash driver"
         help
             This option is invisible, and will be selected automatically
             when ``ESPTOOLPY_FLASHFREQ_120M`` is selected.
+
+    config SPI_FLASH_32BIT_ADDRESS
+        bool
+        default y if ESPTOOLPY_FLASHSIZE_32MB || ESPTOOLPY_FLASHSIZE_64MB || ESPTOOLPY_FLASHSIZE_128MB
+        default n
+        help
+            This is a helper config for 32bits address flash. Invisible for users.
+
+    config SPI_FLASH_32BIT_ADDR_ENABLE
+        bool "Enable 32-bit-address (over 16MB) SPI Flash access"
+        depends on SPI_FLASH_32BIT_ADDRESS && !ESPTOOLPY_OCT_FLASH && IDF_TARGET_ESP32S3 && IDF_EXPERIMENTAL_FEATURES
+        default n
+        help
+            Enabling this option allows the CPU to access 32-bit-address flash beyond 16M range.
+            1. This option only valid for 4-line flash. Octal flash doesn't need this.
+            2. This option is experimental, which means it can't use on all flash chips stable, for more
+            information, please contact Espressif Business support.
+
 endmenu