From 7f3e61cf636d811f295b63c4e76f55c45b8773a3 Mon Sep 17 00:00:00 2001 From: "Michael (XIAO Xufeng)" Date: Wed, 16 Dec 2020 14:21:06 +0800 Subject: [PATCH] esp_flash: add support for external flash on C3 --- components/hal/CMakeLists.txt | 1 + .../hal/esp32c3/include/hal/gpspi_flash_ll.h | 39 ++++++++++++++----- components/spi_flash/esp_flash_spi_init.c | 5 ++- components/spi_flash/memspi_host_driver.c | 14 +++---- 4 files changed, 41 insertions(+), 18 deletions(-) diff --git a/components/hal/CMakeLists.txt b/components/hal/CMakeLists.txt index 2814e70494..2c7fff2c4c 100644 --- a/components/hal/CMakeLists.txt +++ b/components/hal/CMakeLists.txt @@ -85,6 +85,7 @@ if(NOT BOOTLOADER_BUILD) "esp32c3/brownout_hal.c" "esp32c3/systimer_hal.c" "esp32c3/hmac_hal.c" + "spi_flash_hal_gpspi.c" "spi_slave_hd_hal.c") endif() endif() diff --git a/components/hal/esp32c3/include/hal/gpspi_flash_ll.h b/components/hal/esp32c3/include/hal/gpspi_flash_ll.h index fac9668353..66c78989a2 100644 --- a/components/hal/esp32c3/include/hal/gpspi_flash_ll.h +++ b/components/hal/esp32c3/include/hal/gpspi_flash_ll.h @@ -60,6 +60,15 @@ static inline void gpspi_flash_ll_reset(spi_dev_t *dev) { dev->user.val = 0; dev->ctrl.val = 0; + + dev->clk_gate.clk_en = 1; + dev->clk_gate.mst_clk_active = 1; + dev->clk_gate.mst_clk_sel = 1; + + dev->dma_conf.val = 0; + dev->dma_conf.tx_seg_trans_clr_en = 1; + dev->dma_conf.rx_seg_trans_clr_en = 1; + dev->dma_conf.dma_seg_trans_en = 0; } /** @@ -71,7 +80,7 @@ static inline void gpspi_flash_ll_reset(spi_dev_t *dev) */ static inline bool gpspi_flash_ll_cmd_is_done(const spi_dev_t *dev) { - return (dev->cmd.val == 0); + return (dev->cmd.usr == 0); } /** @@ -139,6 +148,8 @@ static inline void gpspi_flash_ll_set_buffer_data(spi_dev_t *dev, const void *bu */ static inline void gpspi_flash_ll_user_start(spi_dev_t *dev) { + dev->cmd.update = 1; + while (dev->cmd.update); dev->cmd.usr = 1; } @@ -151,7 +162,7 @@ static inline void gpspi_flash_ll_user_start(spi_dev_t *dev) */ static inline bool gpspi_flash_ll_host_idle(const spi_dev_t *dev) { - abort(); //TODO ESP32-C3 IDF-2204 + return dev->cmd.usr == 0; } /** @@ -198,10 +209,10 @@ static inline void gpspi_flash_ll_set_read_mode(spi_dev_t *dev, esp_flash_io_mod ctrl.val &= ~(SPI_FCMD_QUAD_M | SPI_FADDR_QUAD_M | SPI_FREAD_QUAD_M | SPI_FCMD_DUAL_M | SPI_FADDR_DUAL_M | SPI_FREAD_DUAL_M); user.val &= ~(SPI_FWRITE_QUAD_M | SPI_FWRITE_DUAL_M); - // ctrl.val |= SPI_FAST_RD_MODE_M; switch (read_mode) { case SPI_FLASH_FASTRD: //the default option + case SPI_FLASH_SLOWRD: break; case SPI_FLASH_QIO: ctrl.fread_quad = 1; @@ -221,9 +232,6 @@ static inline void gpspi_flash_ll_set_read_mode(spi_dev_t *dev, esp_flash_io_mod ctrl.fread_dual = 1; user.fwrite_dual = 1; break; - // case SPI_FLASH_SLOWRD: - // ctrl.fast_rd_mode = 0; - // break; default: abort(); } @@ -251,7 +259,10 @@ static inline void gpspi_flash_ll_set_clock(spi_dev_t *dev, gpspi_flash_ll_clock */ static inline void gpspi_flash_ll_set_miso_bitlen(spi_dev_t *dev, uint32_t bitlen) { - abort(); //TODO ESP32-C3 IDF-2204 + dev->user.usr_miso = bitlen > 0; + if (bitlen) { + dev->ms_dlen.ms_data_bitlen = bitlen - 1; + } } /** @@ -263,7 +274,10 @@ static inline void gpspi_flash_ll_set_miso_bitlen(spi_dev_t *dev, uint32_t bitle */ static inline void gpspi_flash_ll_set_mosi_bitlen(spi_dev_t *dev, uint32_t bitlen) { - abort(); //TODO ESP32-C3 IDF-2204 + dev->user.usr_mosi = bitlen > 0; + if (bitlen) { + dev->ms_dlen.ms_data_bitlen = bitlen - 1; + } } /** @@ -356,9 +370,16 @@ static inline void gpspi_flash_ll_set_dummy_out(spi_dev_t *dev, uint32_t out_en, dev->ctrl.d_pol = out_lev; } +/** + * Set extra hold time of CS after the clocks. + * + * @param dev Beginning address of the peripheral registers. + * @param hold_n Cycles of clocks before CS is inactive + */ static inline void gpspi_flash_ll_set_hold(spi_dev_t *dev, uint32_t hold_n) { - abort(); //TODO ESP32-C3 IDF-2204 + dev->user1.cs_hold_time = hold_n - 1; + dev->user.cs_hold = (hold_n > 0? 1: 0); } #ifdef __cplusplus diff --git a/components/spi_flash/esp_flash_spi_init.c b/components/spi_flash/esp_flash_spi_init.c index d362b7b354..73eaf6dad4 100644 --- a/components/spi_flash/esp_flash_spi_init.c +++ b/components/spi_flash/esp_flash_spi_init.c @@ -117,7 +117,7 @@ static IRAM_ATTR NOINLINE_ATTR void cs_initialize(esp_flash_t *chip, const esp_f if (use_iomux) { PIN_FUNC_SELECT(iomux_reg, spics_func); } else { -#if CONFIG_IDF_TARGET_ESP32C3 +#if SOC_GPIO_PIN_COUNT <= 32 GPIO.enable_w1ts.val = (0x1 << cs_io_num); #else if (cs_io_num < 32) { @@ -141,6 +141,9 @@ esp_err_t spi_bus_add_flash_device(esp_flash_t **out_chip, const esp_flash_spi_d if (out_chip == NULL) { return ESP_ERR_INVALID_ARG; } + if (!GPIO_IS_VALID_OUTPUT_GPIO(config->cs_io_num)) { + return ESP_ERR_INVALID_ARG; + } esp_flash_t *chip = NULL; memspi_host_inst_t *host = NULL; esp_err_t ret = ESP_OK; diff --git a/components/spi_flash/memspi_host_driver.c b/components/spi_flash/memspi_host_driver.c index d9f5b6b757..edbfc00325 100644 --- a/components/spi_flash/memspi_host_driver.c +++ b/components/spi_flash/memspi_host_driver.c @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "soc/soc_caps.h" #include "spi_flash_defs.h" #include "memspi_host_driver.h" #include "string.h" @@ -19,12 +20,13 @@ #include "cache_utils.h" #include "esp_flash_partitions.h" + #define SPI_FLASH_HAL_MAX_WRITE_BYTES 64 #define SPI_FLASH_HAL_MAX_READ_BYTES 64 DRAM_ATTR static const spi_flash_host_driver_t esp_flash_default_host = ESP_FLASH_DEFAULT_HOST_DRIVER(); -#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 +#if SOC_MEMSPI_IS_INDEPENDENT extern void spi_flash_hal_gpspi_poll_cmd_done(spi_flash_host_inst_t *host); extern esp_err_t spi_flash_hal_gpspi_device_config(spi_flash_host_inst_t *host); esp_err_t spi_flash_hal_gpspi_configure_host_io_mode( @@ -64,18 +66,14 @@ static const spi_flash_host_driver_t esp_flash_gpspi_host = { esp_err_t memspi_host_init_pointers(memspi_host_inst_t *host, const memspi_host_config_t *cfg) { -#ifdef CONFIG_IDF_TARGET_ESP32 - host->inst.driver = &esp_flash_default_host; -#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 +#if SOC_MEMSPI_IS_INDEPENDENT if (cfg->host_id == SPI_HOST) host->inst.driver = &esp_flash_default_host; else { host->inst.driver = &esp_flash_gpspi_host; } -#elif CONFIG_IDF_TARGET_ESP32C3 - if (cfg->host_id == SPI_HOST) { - host->inst.driver = &esp_flash_default_host; - } +#else + host->inst.driver = &esp_flash_default_host; #endif esp_err_t err = spi_flash_hal_init(host, cfg);