diff --git a/components/hal/include/hal/spi_flash_hal.h b/components/hal/include/hal/spi_flash_hal.h index aacd6868979..5122689191d 100644 --- a/components/hal/include/hal/spi_flash_hal.h +++ b/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. * diff --git a/components/hal/spi_flash_hal_gpspi.c b/components/hal/spi_flash_hal_gpspi.c index 89d1697f18a..3393cd21961 100644 --- a/components/hal/spi_flash_hal_gpspi.c +++ b/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); diff --git a/components/hal/spi_flash_hal_iram.c b/components/hal/spi_flash_hal_iram.c index b2451f44132..8fe43a3e1a0 100644 --- a/components/hal/spi_flash_hal_iram.c +++ b/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 diff --git a/components/spi_flash/CMakeLists.txt b/components/spi_flash/CMakeLists.txt index 0c2d20a81c7..27d900b20c1 100644 --- a/components/spi_flash/CMakeLists.txt +++ b/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 diff --git a/components/spi_flash/Kconfig b/components/spi_flash/Kconfig index 040b6e2dd8c..1317e34b2c3 100644 --- a/components/spi_flash/Kconfig +++ b/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 diff --git a/components/spi_flash/include/memspi_host_driver.h b/components/spi_flash/include/memspi_host_driver.h index 3424b43cb9a..269bd991d00 100644 --- a/components/spi_flash/include/memspi_host_driver.h +++ b/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); - diff --git a/components/spi_flash/include/spi_flash_chip_boya.h b/components/spi_flash/include/spi_flash_chip_boya.h new file mode 100644 index 00000000000..58139b3c941 --- /dev/null +++ b/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 +#include "esp_flash.h" +#include "spi_flash_chip_driver.h" + +extern const spi_flash_chip_t esp_flash_chip_boya; diff --git a/components/spi_flash/linker.lf b/components/spi_flash/linker.lf index 6691173e549..800d2e1683d 100644 --- a/components/spi_flash/linker.lf +++ b/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) diff --git a/components/spi_flash/memspi_host_driver.c b/components/spi_flash/memspi_host_driver.c index 47b66348613..f713df829fb 100644 --- a/components/spi_flash/memspi_host_driver.c +++ b/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, diff --git a/components/spi_flash/private_include/spi_flash_defs.h b/components/spi_flash/private_include/spi_flash_defs.h index 7bd2358c440..79e06669f34 100644 --- a/components/spi_flash/private_include/spi_flash_defs.h +++ b/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 diff --git a/components/spi_flash/spi_flash_chip_boya.c b/components/spi_flash/spi_flash_chip_boya.c new file mode 100644 index 00000000000..57e20e7b837 --- /dev/null +++ b/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 +#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, +}; diff --git a/components/spi_flash/spi_flash_chip_drivers.c b/components/spi_flash/spi_flash_chip_drivers.c index ab5ad1b653d..a7f68e895f8 100644 --- a/components/spi_flash/spi_flash_chip_drivers.c +++ b/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. diff --git a/components/spi_flash/spi_flash_chip_gd.c b/components/spi_flash/spi_flash_chip_gd.c index 9e1e580b754..54a22555661 100644 --- a/components/spi_flash/spi_flash_chip_gd.c +++ b/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, }; diff --git a/components/spi_flash/spi_flash_chip_generic.c b/components/spi_flash/spi_flash_chip_generic.c index c7047794a63..e4011ff67ba 100644 --- a/components/spi_flash/spi_flash_chip_generic.c +++ b/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, diff --git a/components/spi_flash/spi_flash_chip_issi.c b/components/spi_flash/spi_flash_chip_issi.c index 6bb13f9e442..b5cdbcb326c 100644 --- a/components/spi_flash/spi_flash_chip_issi.c +++ b/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, }; diff --git a/components/spi_flash/spi_flash_chip_mxic.c b/components/spi_flash/spi_flash_chip_mxic.c index 750e765221c..ed19db7611f 100644 --- a/components/spi_flash/spi_flash_chip_mxic.c +++ b/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, }; diff --git a/components/spi_flash/spi_flash_chip_winbond.c b/components/spi_flash/spi_flash_chip_winbond.c index c2f52e0ad15..74ca36735ee 100644 --- a/components/spi_flash/spi_flash_chip_winbond.c +++ b/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, diff --git a/tools/ci/check_public_headers_exceptions.txt b/tools/ci/check_public_headers_exceptions.txt index 68a736e87ba..10285dee3b1 100644 --- a/tools/ci/check_public_headers_exceptions.txt +++ b/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