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

spi_flash(c3): add boya chip support for suspend feature

Cao Sen Miao 5 лет назад
Родитель
Сommit
f3e79ca166

+ 1 - 9
components/hal/include/hal/spi_flash_hal.h

@@ -166,7 +166,7 @@ esp_err_t spi_flash_hal_set_write_protect(spi_flash_host_inst_t *host, bool wp);
  *
  * @return 0:busy, 1:idle, 2:suspended.
  */
-uint32_t spi_flash_hal_host_idle(spi_flash_host_inst_t *host);
+uint32_t spi_flash_hal_check_status(spi_flash_host_inst_t *host);
 
 /**
  * @brief Configure the SPI host hardware registers for the specified io mode.
@@ -231,14 +231,6 @@ bool spi_flash_hal_supports_direct_write(spi_flash_host_inst_t *host, const void
  */
 bool spi_flash_hal_supports_direct_read(spi_flash_host_inst_t *host, const void *p);
 
-/**
- * @brief Check the suspend status and resume a suspended operation.
- *
- * @param host The driver context.
- *
- */
-bool spi_flash_hal_check_suspend(spi_flash_host_inst_t *host);
-
 /**
  * @brief Resume flash chip status from suspend.
  *

+ 1 - 1
components/hal/spi_flash_hal_gpspi.c

@@ -36,7 +36,7 @@ bool spi_flash_hal_gpspi_supports_direct_read(spi_flash_host_inst_t *host, const
     return true;
 }
 
-uint32_t spi_flash_hal_gpspi_host_idle(spi_flash_host_inst_t *host)
+uint32_t spi_flash_hal_gpspi_check_status(spi_flash_host_inst_t *host)
 {
     spi_dev_t *dev = get_spi_dev(host);
     return spi_flash_ll_host_idle(dev);

+ 8 - 15
components/hal/spi_flash_hal_iram.c

@@ -93,18 +93,22 @@ esp_err_t spi_flash_hal_set_write_protect(spi_flash_host_inst_t *host, bool wp)
     return ESP_OK;
 }
 
-uint32_t spi_flash_hal_host_idle(spi_flash_host_inst_t *host)
+#endif // !CONFIG_SPI_FLASH_ROM_IMPL
+
+uint32_t spi_flash_hal_check_status(spi_flash_host_inst_t *host)
 {
     spi_dev_t *dev = get_spi_dev(host);
     uint32_t status = spi_flash_ll_host_idle(dev);
-    uint32_t sus_status = spi_flash_hal_check_suspend(host) << 1;
+#if SOC_SPI_MEM_SUPPORT_AUTO_WAIT_IDLE
+    uint32_t sus_status = spimem_flash_ll_sus_status((spi_mem_dev_t*)dev) << 1;
+#else
+    uint32_t sus_status = 0;
+#endif
     // Not clear if this is necessary, or only necessary if
     // chip->spi == SPI1. But probably doesn't hurt...
     if ((void*) dev == spi_flash_ll_get_hw(SPI_HOST)) {
 #if CONFIG_IDF_TARGET_ESP32
         status &= spi_flash_ll_host_idle(&SPI0);
-#elif CONFIG_IDF_TARGET_ESP32S2
-        status &= spi_flash_ll_host_idle(&SPIMEM0);
 #endif
     }
 
@@ -112,8 +116,6 @@ uint32_t spi_flash_hal_host_idle(spi_flash_host_inst_t *host)
     return (status | sus_status);
 }
 
-#endif // !CONFIG_SPI_FLASH_ROM_IMPL
-
 esp_err_t spi_flash_hal_setup_read_suspend(spi_flash_host_inst_t *host, const spi_flash_sus_cmd_conf *sus_conf)
 {
 #if SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND
@@ -168,15 +170,6 @@ void spi_flash_hal_disable_auto_resume_mode(spi_flash_host_inst_t *host)
 }
 #endif // SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND
 
-bool spi_flash_hal_check_suspend(spi_flash_host_inst_t *host)
-{
-#if SOC_SPI_MEM_SUPPORT_AUTO_WAIT_IDLE
-    if (spimem_flash_ll_sus_status((spi_mem_dev_t*)(((spi_flash_hal_context_t *)host)->spi))) {
-        return true;
-    }
-#endif
-    return false;
-}
 void spi_flash_hal_resume(spi_flash_host_inst_t *host)
 {
 #if SOC_SPI_MEM_SUPPORT_SW_SUSPEND

+ 1 - 0
components/spi_flash/CMakeLists.txt

@@ -85,6 +85,7 @@ else()
             "spi_flash_chip_mxic.c"
             "spi_flash_chip_gd.c"
             "spi_flash_chip_winbond.c"
+            "spi_flash_chip_boya.c"
             "memspi_host_driver.c")
 
         list(APPEND cache_srcs

+ 9 - 0
components/spi_flash/Kconfig

@@ -219,6 +219,15 @@ menu "SPI Flash driver"
                 given by ``chip_drv`` member of the chip struct. This adds support for variant
                 chips, however will extend detecting time.
 
+        config SPI_FLASH_SUPPORT_BOYA_CHIP
+            bool "BOYA"
+            depends on !IDF_TARGET_ESP32
+            default y
+            help
+                Enable this to support auto detection of BOYA chips if chip vendor not directly
+                given by ``chip_drv`` member of the chip struct. This adds support for variant
+                chips, however will extend detecting time.
+
     endmenu #auto detect flash chips
 
 endmenu

+ 1 - 2
components/spi_flash/include/memspi_host_driver.h

@@ -31,7 +31,7 @@
         .write_data_slicer = memspi_host_write_data_slicer, \
         .read = spi_flash_hal_read, \
         .read_data_slicer = memspi_host_read_data_slicer, \
-        .host_status = spi_flash_hal_host_idle, \
+        .host_status = spi_flash_hal_check_status, \
         .configure_host_io_mode = spi_flash_hal_configure_host_io_mode, \
         .poll_cmd_done = spi_flash_hal_poll_cmd_done, \
         .flush_cache = memspi_host_flush_cache, \
@@ -179,4 +179,3 @@ int memspi_host_read_data_slicer(spi_flash_host_inst_t *host, uint32_t address,
  * @return Length that can actually be written in one `program_page` call in `spi_flash_host_driver_t`.
  */
 int memspi_host_write_data_slicer(spi_flash_host_inst_t *host, uint32_t address, uint32_t len, uint32_t *align_address, uint32_t page_size);
-

+ 21 - 0
components/spi_flash/include/spi_flash_chip_boya.h

@@ -0,0 +1,21 @@
+// Copyright 2015-2021 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma once
+
+#include <stdint.h>
+#include "esp_flash.h"
+#include "spi_flash_chip_driver.h"
+
+extern const spi_flash_chip_t esp_flash_chip_boya;

+ 3 - 0
components/spi_flash/linker.lf

@@ -8,3 +8,6 @@ entries:
     spi_flash_chip_gd (noflash)
     spi_flash_chip_winbond (noflash)
     memspi_host_driver (noflash)
+
+    if IDF_TARGET_ESP32 = n:
+            spi_flash_chip_boya (noflash)

+ 2 - 2
components/spi_flash/memspi_host_driver.c

@@ -37,7 +37,7 @@ esp_err_t spi_flash_hal_gpspi_configure_host_io_mode(
     esp_flash_io_mode_t io_mode);
 extern esp_err_t spi_flash_hal_gpspi_common_command(spi_flash_host_inst_t *host, spi_flash_trans_t *trans);
 extern esp_err_t spi_flash_hal_gpspi_read(spi_flash_host_inst_t *host, void *buffer, uint32_t address, uint32_t read_len);
-extern uint32_t spi_flash_hal_gpspi_host_idle(spi_flash_host_inst_t *host);
+extern uint32_t spi_flash_hal_gpspi_check_status(spi_flash_host_inst_t *host);
 extern bool spi_flash_hal_gpspi_supports_direct_write(spi_flash_host_inst_t *host, const void *p);
 extern bool spi_flash_hal_gpspi_supports_direct_read(spi_flash_host_inst_t *host, const void *p);
 
@@ -57,7 +57,7 @@ static const spi_flash_host_driver_t esp_flash_gpspi_host = {
         .write_data_slicer = memspi_host_write_data_slicer,
         .read = spi_flash_hal_gpspi_read,
         .read_data_slicer = memspi_host_read_data_slicer,
-        .host_status = spi_flash_hal_gpspi_host_idle,
+        .host_status = spi_flash_hal_gpspi_check_status,
         .configure_host_io_mode = spi_flash_hal_gpspi_configure_host_io_mode,
         .poll_cmd_done = spi_flash_hal_gpspi_poll_cmd_done,
         .flush_cache = NULL,

+ 2 - 0
components/spi_flash/private_include/spi_flash_defs.h

@@ -26,6 +26,8 @@
 #define CMD_WRDI       0x04
 #define CMD_RDSR       0x05
 #define CMD_RDSR2      0x35 /* Not all SPI flash uses this command */
+#define CMD_RDSCUR     0x2B /* on specific(MXIC) board, read security register */
+#define CMD_RDFR       0x48 /* on specific(ISSI) board, read function register */
 
 #define CMD_FASTRD_QIO      0xEB
 #define CMD_FASTRD_QIO_4B   0xEC

+ 80 - 0
components/spi_flash/spi_flash_chip_boya.c

@@ -0,0 +1,80 @@
+// Copyright 2015-2021 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <stdlib.h>
+#include "spi_flash_chip_generic.h"
+#include "spi_flash_chip_gd.h"
+#include "spi_flash_defs.h"
+
+/* Driver for BOYA flash chip */
+esp_err_t spi_flash_chip_gd_suspend_cmd_conf(esp_flash_t *chip);
+
+// Use the same implementation as GD chips
+#define spi_flash_chip_boya_suspend_cmd_conf spi_flash_chip_gd_suspend_cmd_conf
+
+esp_err_t spi_flash_chip_boya_probe(esp_flash_t *chip, uint32_t flash_id)
+{
+    /* Check manufacturer and product IDs match our desired masks */
+    const uint8_t MFG_ID = 0x68;
+    if (flash_id >> 16 != MFG_ID) {
+        return ESP_ERR_NOT_FOUND;
+    }
+
+    const uint16_t FLASH_ID_MASK = 0xFF00;
+    const uint16_t FLASH_ID_VALUE = 0x4000;
+    if ((flash_id & FLASH_ID_MASK) != FLASH_ID_VALUE) {
+        return ESP_ERR_NOT_FOUND;
+    }
+
+    return ESP_OK;
+}
+
+static const char chip_name[] = "boya";
+
+// The BOYA chip can use the functions for generic chips except from set read mode and probe,
+// So we only replace these two functions.
+const spi_flash_chip_t esp_flash_chip_boya = {
+    .name = chip_name,
+    .timeout = &spi_flash_chip_generic_timeout,
+    .probe = spi_flash_chip_boya_probe,
+    .reset = spi_flash_chip_generic_reset,
+    .detect_size = spi_flash_chip_generic_detect_size,
+    .erase_chip = spi_flash_chip_generic_erase_chip,
+    .erase_sector = spi_flash_chip_generic_erase_sector,
+    .erase_block = spi_flash_chip_generic_erase_block,
+    .sector_size = 4 * 1024,
+    .block_erase_size = 64 * 1024,
+
+    .get_chip_write_protect = spi_flash_chip_generic_get_write_protect,
+    .set_chip_write_protect = spi_flash_chip_generic_set_write_protect,
+
+    .num_protectable_regions = 0,
+    .protectable_regions = NULL,
+    .get_protected_regions = NULL,
+    .set_protected_regions = NULL,
+
+    .read = spi_flash_chip_generic_read,
+    .write = spi_flash_chip_generic_write,
+    .program_page = spi_flash_chip_generic_page_program,
+    .page_size = 256,
+    .write_encrypted = spi_flash_chip_generic_write_encrypted,
+
+    .wait_idle = spi_flash_chip_generic_wait_idle,
+    .set_io_mode = spi_flash_chip_generic_set_io_mode,
+    .get_io_mode = spi_flash_chip_generic_get_io_mode,
+
+    .read_reg = spi_flash_chip_generic_read_reg,
+    .yield = spi_flash_chip_generic_yield,
+    .sus_setup = spi_flash_chip_boya_suspend_cmd_conf,
+};

+ 4 - 0
components/spi_flash/spi_flash_chip_drivers.c

@@ -19,6 +19,7 @@
 #include "spi_flash_chip_mxic.h"
 #include "spi_flash_chip_gd.h"
 #include "spi_flash_chip_winbond.h"
+#include "spi_flash_chip_boya.h"
 #include "sdkconfig.h"
 
 /*
@@ -42,6 +43,9 @@ static const spi_flash_chip_t *default_registered_chips[] = {
 #endif
 #ifdef CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP
     &esp_flash_chip_winbond,
+#endif
+#ifdef CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP
+    &esp_flash_chip_boya,
 #endif
     // Default chip drivers that will accept all chip ID.
     // FM, Winbond and XMC chips are supposed to be supported by this chip driver.

+ 13 - 1
components/spi_flash/spi_flash_chip_gd.c

@@ -75,6 +75,18 @@ esp_err_t spi_flash_chip_gd_get_io_mode(esp_flash_t *chip, esp_flash_io_mode_t*
 }
 #endif //CONFIG_SPI_FLASH_ROM_IMPL
 
+esp_err_t spi_flash_chip_gd_suspend_cmd_conf(esp_flash_t *chip)
+{
+    spi_flash_sus_cmd_conf sus_conf = {
+        .sus_mask = 0x84,
+        .cmd_rdsr = CMD_RDSR2,
+        .sus_cmd = CMD_SUSPEND,
+        .res_cmd = CMD_RESUME,
+    };
+
+    return chip->host->driver->sus_setup(chip->host, &sus_conf);
+}
+
 static const char chip_name[] = "gd";
 
 // The issi chip can use the functions for generic chips except from set read mode and probe,
@@ -111,5 +123,5 @@ const spi_flash_chip_t esp_flash_chip_gd = {
 
     .read_reg = spi_flash_chip_generic_read_reg,
     .yield = spi_flash_chip_generic_yield,
-    .sus_setup = spi_flash_chip_generic_suspend_cmd_conf,
+    .sus_setup = spi_flash_chip_gd_suspend_cmd_conf,
 };

+ 1 - 1
components/spi_flash/spi_flash_chip_generic.c

@@ -646,7 +646,7 @@ esp_err_t spi_flash_common_set_io_mode(esp_flash_t *chip, esp_flash_wrsr_func_t
 esp_err_t spi_flash_chip_generic_suspend_cmd_conf(esp_flash_t *chip)
 {
     spi_flash_sus_cmd_conf sus_conf = {
-        .sus_mask = 0x84,
+        .sus_mask = 0x80,
         .cmd_rdsr = CMD_RDSR2,
         .sus_cmd = CMD_SUSPEND,
         .res_cmd = CMD_RESUME,

+ 12 - 0
components/spi_flash/spi_flash_chip_issi.c

@@ -58,6 +58,17 @@ esp_err_t spi_flash_chip_issi_get_io_mode(esp_flash_t *chip, esp_flash_io_mode_t
     return ret;
 }
 
+esp_err_t spi_flash_chip_issi_suspend_cmd_conf(esp_flash_t *chip)
+{
+    spi_flash_sus_cmd_conf sus_conf = {
+        .sus_mask = 0x06,
+        .cmd_rdsr = CMD_RDFR,
+        .sus_cmd = CMD_SUSPEND,
+        .res_cmd = CMD_RESUME,
+    };
+
+    return chip->host->driver->sus_setup(chip->host, &sus_conf);
+}
 
 static const char chip_name[] = "issi";
 
@@ -95,4 +106,5 @@ const spi_flash_chip_t esp_flash_chip_issi = {
 
     .read_reg = spi_flash_chip_generic_read_reg,
     .yield = spi_flash_chip_generic_yield,
+    .sus_setup = spi_flash_chip_issi_suspend_cmd_conf,
 };

+ 13 - 0
components/spi_flash/spi_flash_chip_mxic.c

@@ -39,6 +39,18 @@ esp_err_t spi_flash_chip_issi_get_io_mode(esp_flash_t *chip, esp_flash_io_mode_t
 
 static const char chip_name[] = "mxic";
 
+esp_err_t spi_flash_chip_mxic_suspend_cmd_conf(esp_flash_t *chip)
+{
+    spi_flash_sus_cmd_conf sus_conf = {
+        .sus_mask = 0x06,
+        .cmd_rdsr = CMD_RDSCUR,
+        .sus_cmd = CMD_SUSPEND,
+        .res_cmd = CMD_RESUME,
+    };
+
+    return chip->host->driver->sus_setup(chip->host, &sus_conf);
+}
+
 // The mxic chip can use the functions for generic chips except from set read mode and probe,
 // So we only replace these two functions.
 const spi_flash_chip_t esp_flash_chip_mxic = {
@@ -73,4 +85,5 @@ const spi_flash_chip_t esp_flash_chip_mxic = {
 
     .read_reg = spi_flash_chip_mxic_read_reg,
     .yield = spi_flash_chip_generic_yield,
+    .sus_setup = spi_flash_chip_mxic_suspend_cmd_conf,
 };

+ 0 - 12
components/spi_flash/spi_flash_chip_winbond.c

@@ -140,18 +140,6 @@ esp_err_t spi_flash_chip_winbond_erase_block(esp_flash_t *chip, uint32_t start_a
     return err;
 }
 
-esp_err_t spi_flash_chip_winbond_suspend_cmd_conf(esp_flash_t *chip)
-{
-    spi_flash_sus_cmd_conf sus_conf = {
-        .sus_mask = 0x80,
-        .cmd_rdsr = CMD_RDSR2,
-        .sus_cmd = CMD_SUSPEND,
-        .res_cmd = CMD_RESUME,
-    };
-
-    return chip->host->driver->sus_setup(chip->host, &sus_conf);
-}
-
 static const char chip_name[] = "winbond";
 
 // The issi chip can use the functions for generic chips except from set read mode and probe,

+ 1 - 0
tools/ci/check_public_headers_exceptions.txt

@@ -42,6 +42,7 @@ components/spi_flash/include/spi_flash_chip_issi.h
 components/spi_flash/include/spi_flash_chip_mxic.h
 components/spi_flash/include/spi_flash_chip_gd.h
 components/spi_flash/include/spi_flash_chip_winbond.h
+components/spi_flash/include/spi_flash_chip_boya.h
 components/spi_flash/include/memspi_host_driver.h
 components/spi_flash/include/spi_flash_chip_driver.h
 components/spi_flash/include/spi_flash_chip_generic.h