Просмотр исходного кода

opi_flash: Add new 16MB opi flash (MXIC25UW12345G) support,
Closes https://github.com/espressif/esp-idf/issues/7996

Cao Sen Miao 4 лет назад
Родитель
Сommit
12e050b38c
1 измененных файлов с 44 добавлено и 3 удалено
  1. 44 3
      components/spi_flash/esp32s3/spi_flash_oct_flash_init.c

+ 44 - 3
components/spi_flash/esp32s3/spi_flash_oct_flash_init.c

@@ -21,6 +21,7 @@
 #define SPI_FLASH_SPI_CMD_RDSR      0x05
 #define SPI_FLASH_SPI_CMD_RDSR      0x05
 #define SPI_FLASH_SPI_CMD_RDCR      0x15
 #define SPI_FLASH_SPI_CMD_RDCR      0x15
 #define SPI_FLASH_SPI_CMD_WRSRCR    0x01
 #define SPI_FLASH_SPI_CMD_WRSRCR    0x01
+#define SPI_FLASH_SPI_CMD_RDSFDP    0x5A
 
 
 /**
 /**
  * Supported Flash chip vendor id
  * Supported Flash chip vendor id
@@ -60,7 +61,8 @@ static esp_err_t s_probe_mxic_chip(uint32_t chip_id, uint8_t *out_vendor_id)
     if (chip_id >> 16 != ESP_FLASH_CHIP_MXIC_OCT) {
     if (chip_id >> 16 != ESP_FLASH_CHIP_MXIC_OCT) {
         return ESP_ERR_NOT_FOUND;
         return ESP_ERR_NOT_FOUND;
     }
     }
-    if (((chip_id >> 8) & 0xff) != 0x80) {
+    if (((chip_id >> 8) & 0xf0) != 0x80) {
+        // We now suppose that middle id of opi flash is 0x8*.
         ESP_EARLY_LOGE(TAG, "Detected MXIC Flash, but memory type is not Octal");
         ESP_EARLY_LOGE(TAG, "Detected MXIC Flash, but memory type is not Octal");
         return ESP_ERR_NOT_FOUND;
         return ESP_ERR_NOT_FOUND;
     }
     }
@@ -69,6 +71,44 @@ static esp_err_t s_probe_mxic_chip(uint32_t chip_id, uint8_t *out_vendor_id)
     return ESP_OK;
     return ESP_OK;
 }
 }
 
 
+#if CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_DTR
+static bool s_mxic_dtr_need_swap(void)
+{
+    // This function is used for judging the data bytes whether need swap.
+    // For some of opi flash chips, the data bytes are ordered by D1-D0-D3-D2. This kinds of order needs swap.
+    // On the contrary, some opi flash chips order the data like D0-D1-D2-D3. This kinds of order doesn't need swap.
+    // Note: this function must be called when flash works under single line mode.
+    // 1. Send 0x5A to read SFDP regs for getting the first address of JEDEC Flash Parameter table.
+    // 2. Add offset with first address to get the order in 8D-8D-8D mode.
+    // 3. Judge whether the BIT(7) is 1, 1 stands for need swap, vice versa.
+    uint8_t JEDEC_first_address = 0;
+    uint8_t byte_order_val = 0;
+    uint8_t dummy = 8;
+    uint8_t cmd_len = 8;
+    uint8_t addr_len = 24;
+    uint8_t miso_bit_len = 8;
+    esp_rom_opiflash_exec_cmd(1, ESP_ROM_SPIFLASH_FASTRD_MODE,
+                              SPI_FLASH_SPI_CMD_RDSFDP, cmd_len,
+                              0x0C, addr_len,
+                              dummy,
+                              NULL, 0,
+                              (uint8_t*)&JEDEC_first_address, miso_bit_len,
+                              ESP_ROM_OPIFLASH_SEL_CS0,
+                              false);
+
+    esp_rom_opiflash_exec_cmd(1, ESP_ROM_SPIFLASH_FASTRD_MODE,
+                              SPI_FLASH_SPI_CMD_RDSFDP, cmd_len,
+                              (JEDEC_first_address + 0x47), addr_len,
+                              dummy,
+                              NULL, 0,
+                              (uint8_t*)&byte_order_val, miso_bit_len,
+                              ESP_ROM_OPIFLASH_SEL_CS0,
+                              false);
+
+    return ((byte_order_val & 0x80) == 0x80) ? true : false;
+}
+#endif // CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_DTR
+
 // 0x00: SPI; 0x01: STR OPI;  0x02: DTR OPI
 // 0x00: SPI; 0x01: STR OPI;  0x02: DTR OPI
 static void s_set_flash_dtr_str_opi_mode(int spi_num, uint8_t val)
 static void s_set_flash_dtr_str_opi_mode(int spi_num, uint8_t val)
 {
 {
@@ -166,10 +206,11 @@ static void s_flash_init_mxic(esp_rom_spiflash_read_mode_t mode)
     esp_rom_spi_set_dtr_swap_mode(1, false, false);
     esp_rom_spi_set_dtr_swap_mode(1, false, false);
 #else //CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_DTR
 #else //CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_DTR
     s_set_pin_drive_capability(3);
     s_set_pin_drive_capability(3);
+    bool need_swap = s_mxic_dtr_need_swap();
     s_set_flash_dtr_str_opi_mode(1, 0x2);
     s_set_flash_dtr_str_opi_mode(1, 0x2);
     esp_rom_opiflash_cache_mode_config(mode, &rom_opiflash_cmd_def->cache_rd_cmd);
     esp_rom_opiflash_cache_mode_config(mode, &rom_opiflash_cmd_def->cache_rd_cmd);
-    esp_rom_spi_set_dtr_swap_mode(0, true, true);
-    esp_rom_spi_set_dtr_swap_mode(1, true, true);
+    esp_rom_spi_set_dtr_swap_mode(0, need_swap, need_swap);
+    esp_rom_spi_set_dtr_swap_mode(1, need_swap, need_swap);
 #endif
 #endif
 
 
     esp_rom_opiflash_wait_idle();
     esp_rom_opiflash_wait_idle();