feature(spiram): Add spiram support on esp32c61

This commit is contained in:
C.S.M 2024-08-09 10:03:03 +08:00
parent 66b8c33308
commit b676f6080d
10 changed files with 328 additions and 7 deletions

View File

@ -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

View File

@ -3,6 +3,10 @@
components/esp_psram/test_apps/psram: components/esp_psram/test_apps/psram:
disable: disable:
- if: SOC_SPIRAM_SUPPORTED != 1 - if: SOC_SPIRAM_SUPPORTED != 1
disable_test:
- if: IDF_TARGET in ["esp32c61"]
temporary: true
reason: No runner
depends_components: depends_components:
- esp_psram - esp_psram
- esp_mm - esp_mm

View File

@ -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 This test app is used to test PSRAM

View File

@ -242,8 +242,8 @@ static inline void psram_ctrlr_ll_common_transaction_base(uint32_t mspi_id, esp_
__attribute__((always_inline)) __attribute__((always_inline))
static inline void psram_ctrlr_ll_set_cs_pin(uint32_t mspi_id, psram_ll_cs_id_t cs_id) 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.cs0_dis = (cs_id == PSRAM_LL_CS_ID_0) ? 0 : 1;
SPIMEM1.misc.cs1_dis = (cs_id == 1) ? 0 : 1; SPIMEM1.misc.cs1_dis = (cs_id == PSRAM_LL_CS_ID_1) ? 0 : 1;
} }
/** /**

View File

@ -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 <stdint.h>
#include <stdbool.h>
#include <sys/param.h>
#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

View File

@ -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) 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.cs0_dis = (cs_id == PSRAM_LL_CS_ID_0) ? 0 : 1;
SPIMEM0.misc.cs1_dis = (cs_id == 1) ? 0 : 1; SPIMEM0.misc.cs1_dis = (cs_id == PSRAM_LL_CS_ID_1) ? 0 : 1;
} }
/** /**

View File

@ -103,6 +103,10 @@ config SOC_ECDSA_SUPPORTED
bool bool
default y default y
config SOC_SPIRAM_SUPPORTED
bool
default y
config SOC_XTAL_SUPPORT_40M config SOC_XTAL_SUPPORT_40M
bool bool
default y default y

View File

@ -130,6 +130,7 @@ extern "C" {
#define SPI_CLK_GPIO_NUM 20 #define SPI_CLK_GPIO_NUM 20
#define SPI_D_GPIO_NUM 21 #define SPI_D_GPIO_NUM 21
#define SPI_Q_GPIO_NUM 16 #define SPI_Q_GPIO_NUM 16
#define SPI_CS1_GPIO_NUM 14
#define USB_INT_PHY0_DM_GPIO_NUM 12 #define USB_INT_PHY0_DM_GPIO_NUM 12
#define USB_INT_PHY0_DP_GPIO_NUM 13 #define USB_INT_PHY0_DP_GPIO_NUM 13

View File

@ -192,7 +192,7 @@
#define SOC_MEM_INTERNAL_LOW1 0x40800000 #define SOC_MEM_INTERNAL_LOW1 0x40800000
#define SOC_MEM_INTERNAL_HIGH1 0x40850000 #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 // Region of address space that holds peripherals
#define SOC_PERIPHERAL_LOW 0x60000000 #define SOC_PERIPHERAL_LOW 0x60000000

View File

@ -68,6 +68,7 @@
// \#define SOC_LP_I2C_SUPPORTED 0 //TODO: [ESP32C61] IDF-9330, IDF-9337 // \#define SOC_LP_I2C_SUPPORTED 0 //TODO: [ESP32C61] IDF-9330, IDF-9337
// \#define SOC_PM_SUPPORTED 1 // \#define SOC_PM_SUPPORTED 1
#define SOC_ECDSA_SUPPORTED 1 #define SOC_ECDSA_SUPPORTED 1
#define SOC_SPIRAM_SUPPORTED 1
/*-------------------------- XTAL CAPS ---------------------------------------*/ /*-------------------------- XTAL CAPS ---------------------------------------*/
#define SOC_XTAL_SUPPORT_40M 1 #define SOC_XTAL_SUPPORT_40M 1