From b676f6080df710b49f5bc0dfc97364732d74ceda Mon Sep 17 00:00:00 2001 From: "C.S.M" Date: Fri, 9 Aug 2024 10:03:03 +0800 Subject: [PATCH] feature(spiram): Add spiram support on esp32c61 --- components/esp_psram/esp32c61/Kconfig.spiram | 48 ++++ .../esp_psram/test_apps/.build-test-rules.yml | 4 + .../esp_psram/test_apps/psram/README.md | 4 +- .../hal/esp32c5/include/hal/psram_ctrlr_ll.h | 4 +- .../hal/esp32c61/include/hal/psram_ctrlr_ll.h | 263 ++++++++++++++++++ .../hal/esp32s3/include/hal/psram_ctrlr_ll.h | 4 +- .../esp32c61/include/soc/Kconfig.soc_caps.in | 4 + .../soc/esp32c61/include/soc/io_mux_reg.h | 1 + components/soc/esp32c61/include/soc/soc.h | 2 +- .../soc/esp32c61/include/soc/soc_caps.h | 1 + 10 files changed, 328 insertions(+), 7 deletions(-) create mode 100644 components/esp_psram/esp32c61/Kconfig.spiram create mode 100644 components/hal/esp32c61/include/hal/psram_ctrlr_ll.h diff --git a/components/esp_psram/esp32c61/Kconfig.spiram b/components/esp_psram/esp32c61/Kconfig.spiram new file mode 100644 index 0000000000..725b456a3c --- /dev/null +++ b/components/esp_psram/esp32c61/Kconfig.spiram @@ -0,0 +1,48 @@ +config SPIRAM + bool "Support for external, SPI-connected RAM" + default "n" + help + This enables support for an external SPI RAM chip, connected in parallel with the + main SPI flash chip. + +menu "SPI RAM config" + depends on SPIRAM + + choice SPIRAM_MODE + prompt "Mode of SPI RAM chip in use" + default SPIRAM_MODE_QUAD + + config SPIRAM_MODE_QUAD + bool "Quad Mode PSRAM" + + endchoice + + config SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY + bool "Allow external memory as an argument to xTaskCreateStatic" + default y + help + Accessing memory in SPIRAM has certain restrictions, so task stacks allocated by xTaskCreate + are by default allocated from internal RAM. + + This option allows for passing memory allocated from SPIRAM to be passed to xTaskCreateStatic. + This should only be used for tasks where the stack is never accessed while the cache is disabled. + + choice SPIRAM_SPEED + prompt "Set RAM clock speed" + default SPIRAM_SPEED_40M + help + Select the speed for the SPI RAM chip. + + config SPIRAM_SPEED_80M + bool "80MHz clock speed" + config SPIRAM_SPEED_40M + bool "40Mhz clock speed" + endchoice + + config SPIRAM_SPEED + int + default 80 if SPIRAM_SPEED_80M + default 40 if SPIRAM_SPEED_40M + + source "$IDF_PATH/components/esp_psram/Kconfig.spiram.common" # insert non-chip-specific items here +endmenu diff --git a/components/esp_psram/test_apps/.build-test-rules.yml b/components/esp_psram/test_apps/.build-test-rules.yml index 88e2708734..b815394dba 100644 --- a/components/esp_psram/test_apps/.build-test-rules.yml +++ b/components/esp_psram/test_apps/.build-test-rules.yml @@ -3,6 +3,10 @@ components/esp_psram/test_apps/psram: disable: - if: SOC_SPIRAM_SUPPORTED != 1 + disable_test: + - if: IDF_TARGET in ["esp32c61"] + temporary: true + reason: No runner depends_components: - esp_psram - esp_mm diff --git a/components/esp_psram/test_apps/psram/README.md b/components/esp_psram/test_apps/psram/README.md index fe5c904716..6f2974f7f5 100644 --- a/components/esp_psram/test_apps/psram/README.md +++ b/components/esp_psram/test_apps/psram/README.md @@ -1,4 +1,4 @@ -| Supported Targets | ESP32 | ESP32-C5 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C5 | ESP32-C61 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | --------- | -------- | -------- | -------- | This test app is used to test PSRAM diff --git a/components/hal/esp32c5/include/hal/psram_ctrlr_ll.h b/components/hal/esp32c5/include/hal/psram_ctrlr_ll.h index 7d9624c581..0a9946ff57 100644 --- a/components/hal/esp32c5/include/hal/psram_ctrlr_ll.h +++ b/components/hal/esp32c5/include/hal/psram_ctrlr_ll.h @@ -242,8 +242,8 @@ static inline void psram_ctrlr_ll_common_transaction_base(uint32_t mspi_id, esp_ __attribute__((always_inline)) static inline void psram_ctrlr_ll_set_cs_pin(uint32_t mspi_id, psram_ll_cs_id_t cs_id) { - SPIMEM1.misc.cs0_dis = (cs_id == 0) ? 0 : 1; - SPIMEM1.misc.cs1_dis = (cs_id == 1) ? 0 : 1; + SPIMEM1.misc.cs0_dis = (cs_id == PSRAM_LL_CS_ID_0) ? 0 : 1; + SPIMEM1.misc.cs1_dis = (cs_id == PSRAM_LL_CS_ID_1) ? 0 : 1; } /** diff --git a/components/hal/esp32c61/include/hal/psram_ctrlr_ll.h b/components/hal/esp32c61/include/hal/psram_ctrlr_ll.h new file mode 100644 index 0000000000..f5e799c400 --- /dev/null +++ b/components/hal/esp32c61/include/hal/psram_ctrlr_ll.h @@ -0,0 +1,263 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/******************************************************************************* + * NOTICE + * The ll is not public api, don't use in application code. + * See readme.md in hal/include/hal/readme.md + ******************************************************************************/ + +#pragma once + +#include +#include +#include +#include "hal/assert.h" +#include "hal/misc.h" +#include "soc/spi_mem_struct.h" +#include "soc/spi_mem_reg.h" +#include "soc/clk_tree_defs.h" +#include "rom/opi_flash.h" +#include "hal/psram_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define PSRAM_CTRLR_LL_MSPI_ID_0 0 +#define PSRAM_CTRLR_LL_MSPI_ID_1 1 + +#define PSRAM_LL_CS_SEL SPI_MEM_CS1_DIS_M + +/** + * @brief PSRAM enum for cs id. + */ +typedef enum { + PSRAM_LL_CS_ID_0 = 0, + PSRAM_LL_CS_ID_1 = 1, +} psram_ll_cs_id_t; + +/** + * @brief Set PSRAM write cmd + * + * @param mspi_id mspi_id + * @param cmd_bitlen command bitlen + * @param cmd_val command value + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_set_wr_cmd(uint32_t mspi_id, uint32_t cmd_bitlen, uint32_t cmd_val) +{ + (void)mspi_id; + HAL_ASSERT(cmd_bitlen > 0); + SPIMEM0.mem_cache_sctrl.mem_cache_sram_usr_wcmd = 1; + SPIMEM0.mem_sram_dwr_cmd.mem_cache_sram_usr_wr_cmd_bitlen = cmd_bitlen - 1; + HAL_FORCE_MODIFY_U32_REG_FIELD(SPIMEM0.mem_sram_dwr_cmd, mem_cache_sram_usr_wr_cmd_value, cmd_val); +} + +/** + * @brief Set PSRAM read cmd + * + * @param mspi_id mspi_id + * @param cmd_bitlen command bitlen + * @param cmd_val command value + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_set_rd_cmd(uint32_t mspi_id, uint32_t cmd_bitlen, uint32_t cmd_val) +{ + (void)mspi_id; + HAL_ASSERT(cmd_bitlen > 0); + SPIMEM0.mem_cache_sctrl.mem_cache_sram_usr_rcmd = 1; + SPIMEM0.mem_sram_drd_cmd.mem_cache_sram_usr_rd_cmd_bitlen = cmd_bitlen - 1; + HAL_FORCE_MODIFY_U32_REG_FIELD(SPIMEM0.mem_sram_drd_cmd, mem_cache_sram_usr_rd_cmd_value, cmd_val); +} + +/** + * @brief Set PSRAM addr bitlen + * + * @param mspi_id mspi_id + * @param addr_bitlen address bitlen + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_set_addr_bitlen(uint32_t mspi_id, uint32_t addr_bitlen) +{ + (void)mspi_id; + HAL_ASSERT(addr_bitlen > 0); + SPIMEM0.mem_cache_sctrl.mem_sram_addr_bitlen = addr_bitlen - 1; +} + +/** + * @brief Set PSRAM read dummy + * + * @param mspi_id mspi_id + * @param dummy_n dummy number + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_set_rd_dummy(uint32_t mspi_id, uint32_t dummy_n) +{ + (void)mspi_id; + HAL_ASSERT(dummy_n > 0); + SPIMEM0.mem_cache_sctrl.mem_usr_rd_sram_dummy = 1; + SPIMEM0.mem_cache_sctrl.mem_sram_rdummy_cyclelen = dummy_n - 1; +} + +/** + * @brief Set PSRAM bus clock + * + * @param mspi_id mspi_id + * @param clock_conf Configuration value for psram clock + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_set_bus_clock(uint32_t mspi_id, uint32_t clock_conf) +{ + SPIMEM0.mem_sram_clk.val = clock_conf; +} + +/** + * Calculate spi_flash clock frequency division parameters for register. + * + * @param clkdiv frequency division factor + * + * @return Register setting for the given clock division factor. + */ +static inline uint32_t psram_ctrlr_ll_calculate_clock_reg(uint8_t clkdiv) +{ + uint32_t div_parameter; + // See comments of `clock` in `spi_mem_struct.h` + if (clkdiv == 1) { + div_parameter = (1 << 31); + } else { + div_parameter = ((clkdiv - 1) | (((clkdiv - 1) / 2 & 0xff) << 8 ) | (((clkdiv - 1) & 0xff) << 16)); + } + return div_parameter; +} + +/** + * Configure the psram read mode + * + * @param mspi_id mspi_id + * @param read_mode read mode + */ +static inline void psram_ctrlr_ll_set_read_mode(uint32_t mspi_id, psram_hal_cmd_mode_t read_mode) +{ + typeof (SPIMEM0.mem_cache_sctrl) mem_cache_sctrl; + mem_cache_sctrl.val = SPIMEM0.mem_cache_sctrl.val; + + mem_cache_sctrl.val &= ~(SPI_MEM_USR_SRAM_DIO_M | SPI_MEM_USR_SRAM_QIO_M); + switch (read_mode) { + case PSRAM_HAL_CMD_SPI: + mem_cache_sctrl.mem_usr_sram_dio = 1; + break; + case PSRAM_HAL_CMD_QPI: + mem_cache_sctrl.mem_usr_sram_qio = 1; + break; + default: + abort(); + } + SPIMEM0.mem_cache_sctrl.val = mem_cache_sctrl.val; +} + +/** + * @brief Set CS setup + * + * @param mspi_id mspi_id + * @param setup_n cs setup time + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_set_cs_setup(uint32_t mspi_id, uint32_t setup_n) +{ + (void)mspi_id; + HAL_ASSERT(setup_n > 0); + SPIMEM0.smem_ac.smem_cs_setup = 1; + SPIMEM0.smem_ac.smem_cs_setup_time = setup_n - 1; +} + +/** + * @brief Set CS hold + * + * @param mspi_id mspi_id + * @param hold_n cs hold time + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_set_cs_hold(uint32_t mspi_id, uint32_t hold_n) +{ + (void)mspi_id; + HAL_ASSERT(hold_n > 0); + SPIMEM0.smem_ac.smem_cs_hold = 1; + SPIMEM0.smem_ac.smem_cs_hold_time = hold_n - 1; +} + +/** + * @brief Set CS hold delay + * + * @param mspi_id mspi_id + * @param hold_delay_n cs hold delay time + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_set_cs_hold_delay(uint32_t mspi_id, uint32_t hold_delay_n) +{ + (void)mspi_id; + HAL_ASSERT(hold_delay_n > 0); + SPIMEM0.smem_ac.smem_cs_hold_delay = hold_delay_n - 1; +} + +/** + * @brief PSRAM common transaction + * + * See `opi_flash.h` for parameters + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_common_transaction_base(uint32_t mspi_id, esp_rom_spiflash_read_mode_t mode, + uint32_t cmd, uint32_t cmd_bitlen, + uint32_t addr, uint32_t addr_bitlen, + uint32_t dummy_bits, + uint8_t* mosi_data, uint32_t mosi_bitlen, + uint8_t* miso_data, uint32_t miso_bitlen, + uint32_t cs_mask, + bool is_write_erase_operation) +{ + esp_rom_spi_cmd_t conf = { + .cmd = cmd, + .cmdBitLen = cmd_bitlen, + .addr = &addr, + .addrBitLen = addr_bitlen, + .txData = (uint32_t *)mosi_data, + .txDataBitLen = mosi_bitlen, + .rxData = (uint32_t *)miso_data, + .rxDataBitLen = miso_bitlen, + .dummyBitLen = dummy_bits, + }; + esp_rom_spi_cmd_config(mspi_id, &conf); + esp_rom_spi_cmd_start(mspi_id, miso_data, miso_bitlen / 8, cs_mask, is_write_erase_operation); +} + +/** + * Select which pin to use for the psram + * + * @param mspi_id mspi_id + * @param cs_id cs_id for psram to use. + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_set_cs_pin(uint32_t mspi_id, psram_ll_cs_id_t cs_id) +{ + SPIMEM0.mem_misc.cs0_dis = (cs_id == PSRAM_LL_CS_ID_0) ? 0 : 1; + SPIMEM0.mem_misc.cs1_dis = (cs_id == PSRAM_LL_CS_ID_1) ? 0 : 1; +} + +/** + * Enable the psram quad command + * + * @param mspi_id mspi_id + * @param ena true if enable, otherwise false + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_enable_quad_command(uint32_t mspi_id, bool ena) +{ + SPIMEM1.ctrl.fcmd_quad = ena; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32s3/include/hal/psram_ctrlr_ll.h b/components/hal/esp32s3/include/hal/psram_ctrlr_ll.h index 8de7d5b3d1..ff8245bdf7 100644 --- a/components/hal/esp32s3/include/hal/psram_ctrlr_ll.h +++ b/components/hal/esp32s3/include/hal/psram_ctrlr_ll.h @@ -210,8 +210,8 @@ static inline void psram_ctrlr_ll_common_transaction_base(uint32_t mspi_id, esp_ */ static inline void psram_ctrlr_ll_set_cs_pin(uint32_t mspi_id, psram_ll_cs_id_t cs_id) { - SPIMEM0.misc.cs0_dis = (cs_id == 0) ? 0 : 1; - SPIMEM0.misc.cs1_dis = (cs_id == 1) ? 0 : 1; + SPIMEM0.misc.cs0_dis = (cs_id == PSRAM_LL_CS_ID_0) ? 0 : 1; + SPIMEM0.misc.cs1_dis = (cs_id == PSRAM_LL_CS_ID_1) ? 0 : 1; } /** diff --git a/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in index 0284406515..40acf52bf0 100644 --- a/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in @@ -103,6 +103,10 @@ config SOC_ECDSA_SUPPORTED bool default y +config SOC_SPIRAM_SUPPORTED + bool + default y + config SOC_XTAL_SUPPORT_40M bool default y diff --git a/components/soc/esp32c61/include/soc/io_mux_reg.h b/components/soc/esp32c61/include/soc/io_mux_reg.h index ea9dcaf0fc..ef551d6861 100644 --- a/components/soc/esp32c61/include/soc/io_mux_reg.h +++ b/components/soc/esp32c61/include/soc/io_mux_reg.h @@ -130,6 +130,7 @@ extern "C" { #define SPI_CLK_GPIO_NUM 20 #define SPI_D_GPIO_NUM 21 #define SPI_Q_GPIO_NUM 16 +#define SPI_CS1_GPIO_NUM 14 #define USB_INT_PHY0_DM_GPIO_NUM 12 #define USB_INT_PHY0_DP_GPIO_NUM 13 diff --git a/components/soc/esp32c61/include/soc/soc.h b/components/soc/esp32c61/include/soc/soc.h index c2317dec73..97d0eafd5c 100644 --- a/components/soc/esp32c61/include/soc/soc.h +++ b/components/soc/esp32c61/include/soc/soc.h @@ -192,7 +192,7 @@ #define SOC_MEM_INTERNAL_LOW1 0x40800000 #define SOC_MEM_INTERNAL_HIGH1 0x40850000 -#define SOC_MAX_CONTIGUOUS_RAM_SIZE (SOC_IRAM_HIGH - SOC_IRAM_LOW) ///< Largest span of contiguous memory (DRAM or IRAM) in the address space +#define SOC_MAX_CONTIGUOUS_RAM_SIZE (SOC_EXTRAM_DATA_HIGH - SOC_EXTRAM_DATA_LOW) ///< Largest span of contiguous memory in the address space // Region of address space that holds peripherals #define SOC_PERIPHERAL_LOW 0x60000000 diff --git a/components/soc/esp32c61/include/soc/soc_caps.h b/components/soc/esp32c61/include/soc/soc_caps.h index f3bedfa321..fc316f7ef5 100644 --- a/components/soc/esp32c61/include/soc/soc_caps.h +++ b/components/soc/esp32c61/include/soc/soc_caps.h @@ -68,6 +68,7 @@ // \#define SOC_LP_I2C_SUPPORTED 0 //TODO: [ESP32C61] IDF-9330, IDF-9337 // \#define SOC_PM_SUPPORTED 1 #define SOC_ECDSA_SUPPORTED 1 +#define SOC_SPIRAM_SUPPORTED 1 /*-------------------------- XTAL CAPS ---------------------------------------*/ #define SOC_XTAL_SUPPORT_40M 1