mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
feat(psram): esp32p4 psram device driver support
This commit is contained in:
parent
bc4bdd6169
commit
712c0c0075
@ -3,3 +3,6 @@
|
||||
components/esp_common/test_apps/esp_common:
|
||||
disable:
|
||||
- if: CONFIG_NAME == "psram" and SOC_SPIRAM_SUPPORTED != 1
|
||||
- if: CONFIG_NAME == "psram" and IDF_TARGET in ["esp32p4"]
|
||||
temporary: true
|
||||
reason: esp32p4 is not supported yet # TODO: IDF-7557
|
||||
|
@ -25,6 +25,10 @@ if(CONFIG_SPIRAM)
|
||||
elseif(CONFIG_SPIRAM_MODE_OCT)
|
||||
list(APPEND srcs "${target}/esp_psram_impl_octal.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_SPIRAM_MODE_HEX)
|
||||
list(APPEND srcs "device/esp_psram_impl_ap_hex.c")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
idf_component_register(SRCS ${srcs}
|
||||
|
@ -107,12 +107,3 @@ config SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY
|
||||
|
||||
Note the values placed into this section will not be initialized at startup and should keep its value
|
||||
after software restart.
|
||||
|
||||
config SPIRAM_ECC_ENABLE
|
||||
bool "Enable SPI RAM ECC"
|
||||
default n
|
||||
depends on SPIRAM_MODE_OCT && IDF_TARGET_ESP32S3
|
||||
help
|
||||
Enable MSPI Error-Correcting Code function when accessing SPIRAM.
|
||||
|
||||
If enabled, 1/16 of the SPI RAM total size will be reserved for error-correcting code.
|
||||
|
398
components/esp_psram/device/esp_psram_impl_ap_hex.c
Normal file
398
components/esp_psram/device/esp_psram_impl_ap_hex.c
Normal file
@ -0,0 +1,398 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
#include "../esp_psram_impl.h"
|
||||
#include "rom/opi_flash.h"
|
||||
#include "hal/psram_ctrlr_ll.h"
|
||||
|
||||
#define AP_HEX_PSRAM_SYNC_READ 0x0000
|
||||
#define AP_HEX_PSRAM_SYNC_WRITE 0x8080
|
||||
#define AP_HEX_PSRAM_BURST_READ 0x2020
|
||||
#define AP_HEX_PSRAM_BURST_WRITE 0xA0A0
|
||||
#define AP_HEX_PSRAM_REG_READ 0x4040
|
||||
#define AP_HEX_PSRAM_REG_WRITE 0xC0C0
|
||||
#define AP_HEX_PSRAM_RD_CMD_BITLEN 16
|
||||
#define AP_HEX_PSRAM_WR_CMD_BITLEN 16
|
||||
#define AP_HEX_PSRAM_ADDR_BITLEN 32
|
||||
#define AP_HEX_PSRAM_RD_DUMMY_BITLEN (2*(10-1))
|
||||
#define AP_HEX_PSRAM_WR_DUMMY_BITLEN (2*(5-1))
|
||||
#define AP_HEX_PSRAM_VENDOR_ID 0xD
|
||||
|
||||
#define AP_HEX_PSRAM_CS_SETUP_TIME 4
|
||||
#define AP_HEX_PSRAM_CS_HOLD_TIME 4
|
||||
#define AP_HEX_PSRAM_CS_ECC_HOLD_TIME 4
|
||||
#define AP_HEX_PSRAM_CS_HOLD_DELAY 3
|
||||
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
struct {
|
||||
uint8_t drive_str: 2;
|
||||
uint8_t read_latency: 3;
|
||||
uint8_t lt: 1;
|
||||
uint8_t rsvd6: 1;
|
||||
uint8_t tso: 1;
|
||||
};
|
||||
uint8_t val;
|
||||
} mr0;
|
||||
union {
|
||||
struct {
|
||||
uint8_t vendor_id: 5;
|
||||
uint8_t rsvd0_2: 2;
|
||||
uint8_t ulp: 1;
|
||||
};
|
||||
uint8_t val;
|
||||
} mr1;
|
||||
union {
|
||||
struct {
|
||||
uint8_t density: 3;
|
||||
uint8_t dev_id: 2;
|
||||
uint8_t kgd: 3;
|
||||
};
|
||||
uint8_t val;
|
||||
} mr2;
|
||||
union {
|
||||
struct {
|
||||
uint8_t rsvd3_7: 4;
|
||||
uint8_t srf: 2;
|
||||
uint8_t rsvd0: 1;
|
||||
uint8_t rbx_en: 1;
|
||||
};
|
||||
uint8_t val;
|
||||
} mr3;
|
||||
union {
|
||||
struct {
|
||||
uint8_t pasr: 3;
|
||||
uint8_t rf: 2;
|
||||
uint8_t wr_latency: 3;
|
||||
};
|
||||
uint8_t val;
|
||||
} mr4;
|
||||
union {
|
||||
struct {
|
||||
uint8_t bl: 2;
|
||||
uint8_t bt: 1;
|
||||
uint8_t rbx: 1;
|
||||
uint8_t rsvd5: 2;
|
||||
uint8_t x16: 1;
|
||||
uint8_t rsvd7: 1;
|
||||
};
|
||||
uint8_t val;
|
||||
} mr8;
|
||||
} hex_psram_mode_reg_t;
|
||||
|
||||
static const char* TAG = "hex_psram";
|
||||
static uint32_t s_psram_size; //this stands for physical psram size in bytes
|
||||
|
||||
|
||||
/**
|
||||
* Common psram transaction
|
||||
*/
|
||||
static void s_psram_common_transaction(uint32_t mspi_id,
|
||||
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,
|
||||
bool is_write_erase_operation)
|
||||
{
|
||||
psram_ctrlr_ll_common_transaction(mspi_id, cmd, cmd_bitlen, addr, addr_bitlen, dummy_bits,
|
||||
mosi_data, mosi_bitlen, miso_data, miso_bitlen,
|
||||
is_write_erase_operation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise mode registers of the PSRAM
|
||||
*/
|
||||
static void s_init_psram_mode_reg(int spi_num, hex_psram_mode_reg_t *mode_reg_config)
|
||||
{
|
||||
int cmd_len = 16;
|
||||
uint32_t addr = 0x0;
|
||||
int addr_bit_len = 32;
|
||||
int dummy = AP_HEX_PSRAM_RD_DUMMY_BITLEN;
|
||||
hex_psram_mode_reg_t mode_reg = {0};
|
||||
int data_bit_len = 16;
|
||||
|
||||
//read
|
||||
s_psram_common_transaction(spi_num,
|
||||
AP_HEX_PSRAM_REG_READ, cmd_len,
|
||||
addr, addr_bit_len,
|
||||
dummy,
|
||||
NULL, 0,
|
||||
&mode_reg.mr0.val, data_bit_len,
|
||||
false);
|
||||
|
||||
//modify
|
||||
mode_reg.mr0.lt = mode_reg_config->mr0.lt;
|
||||
mode_reg.mr0.read_latency = mode_reg_config->mr0.read_latency;
|
||||
mode_reg.mr0.drive_str = mode_reg_config->mr0.drive_str;
|
||||
|
||||
//write
|
||||
s_psram_common_transaction(spi_num,
|
||||
AP_HEX_PSRAM_REG_WRITE, cmd_len,
|
||||
addr, addr_bit_len,
|
||||
0,
|
||||
&mode_reg.mr0.val, 16,
|
||||
NULL, 0,
|
||||
false);
|
||||
|
||||
addr = 0x8;
|
||||
data_bit_len = 8;
|
||||
//read
|
||||
s_psram_common_transaction(spi_num,
|
||||
AP_HEX_PSRAM_REG_READ, cmd_len,
|
||||
addr, addr_bit_len,
|
||||
dummy,
|
||||
NULL, 0,
|
||||
&mode_reg.mr8.val, data_bit_len,
|
||||
false);
|
||||
|
||||
//modify
|
||||
mode_reg.mr8.bt = mode_reg_config->mr8.bt;
|
||||
mode_reg.mr8.bl = mode_reg_config->mr8.bl;
|
||||
mode_reg.mr8.rbx = mode_reg_config->mr8.rbx;
|
||||
mode_reg.mr8.x16 = mode_reg_config->mr8.x16;
|
||||
|
||||
//write
|
||||
s_psram_common_transaction(spi_num,
|
||||
AP_HEX_PSRAM_REG_WRITE, cmd_len,
|
||||
addr, addr_bit_len,
|
||||
0,
|
||||
&mode_reg.mr8.val, 16,
|
||||
NULL, 0,
|
||||
false);
|
||||
}
|
||||
|
||||
static void s_get_psram_mode_reg(int spi_num, hex_psram_mode_reg_t *out_reg)
|
||||
{
|
||||
int cmd_len = 16;
|
||||
int addr_bit_len = 32;
|
||||
int dummy = AP_HEX_PSRAM_RD_DUMMY_BITLEN;
|
||||
int data_bit_len = 16;
|
||||
|
||||
//Read MR0~1 register
|
||||
s_psram_common_transaction(spi_num,
|
||||
AP_HEX_PSRAM_REG_READ, cmd_len,
|
||||
0x0, addr_bit_len,
|
||||
dummy,
|
||||
NULL, 0,
|
||||
&out_reg->mr0.val, data_bit_len,
|
||||
false);
|
||||
//Read MR2~3 register
|
||||
s_psram_common_transaction(spi_num,
|
||||
AP_HEX_PSRAM_REG_READ, cmd_len,
|
||||
0x2, addr_bit_len,
|
||||
dummy,
|
||||
NULL, 0,
|
||||
&out_reg->mr2.val, data_bit_len,
|
||||
false);
|
||||
data_bit_len = 8;
|
||||
//Read MR4 register
|
||||
s_psram_common_transaction(spi_num,
|
||||
AP_HEX_PSRAM_REG_READ, cmd_len,
|
||||
0x4, addr_bit_len,
|
||||
dummy,
|
||||
NULL, 0,
|
||||
&out_reg->mr4.val, data_bit_len,
|
||||
false);
|
||||
//Read MR8 register
|
||||
s_psram_common_transaction(spi_num,
|
||||
AP_HEX_PSRAM_REG_READ, cmd_len,
|
||||
0x8, addr_bit_len,
|
||||
dummy,
|
||||
NULL, 0,
|
||||
&out_reg->mr8.val, data_bit_len,
|
||||
false);
|
||||
}
|
||||
|
||||
static void s_print_psram_info(hex_psram_mode_reg_t *reg_val)
|
||||
{
|
||||
ESP_EARLY_LOGI(TAG, "vendor id : 0x%02x (%s)", reg_val->mr1.vendor_id, reg_val->mr1.vendor_id == 0x0d ? "AP" : "UNKNOWN");
|
||||
ESP_EARLY_LOGI(TAG, "Latency : 0x%02x (%s)", reg_val->mr0.lt, reg_val->mr0.lt == 1 ? "Fixed" : "Variable");
|
||||
ESP_EARLY_LOGI(TAG, "DriveStr. : 0x%02x (%d Ohm)", reg_val->mr0.drive_str, reg_val->mr0.drive_str < 2 ? 25*(reg_val->mr0.drive_str + 1): 100*(reg_val->mr0.drive_str-1));
|
||||
ESP_EARLY_LOGI(TAG, "dev id : 0x%02x (generation %d)", reg_val->mr2.dev_id, reg_val->mr2.dev_id + 1);
|
||||
ESP_EARLY_LOGI(TAG, "density : 0x%02x (%d Mbit)", reg_val->mr2.density, reg_val->mr2.density == 0x1 ? 32 :
|
||||
reg_val->mr2.density == 0X3 ? 64 :
|
||||
reg_val->mr2.density == 0x5 ? 128 :
|
||||
reg_val->mr2.density == 0x7 ? 256 : 0);
|
||||
ESP_EARLY_LOGI(TAG, "good-die : 0x%02x (%s)", reg_val->mr2.kgd, reg_val->mr2.kgd == 6 ? "Pass" : "Fail");
|
||||
ESP_EARLY_LOGI(TAG, "SRF : 0x%02x (%s Refresh)", reg_val->mr3.srf, reg_val->mr3.srf == 0x1 ? "Fast" : "Slow");
|
||||
ESP_EARLY_LOGI(TAG, "BurstType : 0x%02x (%s Wrap)", reg_val->mr8.bt, reg_val->mr8.bt == 1 && reg_val->mr8.bl != 3 ? "Hybrid" : "");
|
||||
ESP_EARLY_LOGI(TAG, "BurstLen : 0x%02x (%d Byte)", reg_val->mr8.bl, reg_val->mr8.bl == 0x00 ? 16 :
|
||||
reg_val->mr8.bl == 0x01 ? 32 :
|
||||
reg_val->mr8.bl == 0x10 ? 64 : 2048);
|
||||
ESP_EARLY_LOGI(TAG, "BitMode : 0x%02x (%s Mode)", reg_val->mr8.x16, reg_val->mr8.x16 == 1 ? "X16" : "X8");
|
||||
|
||||
|
||||
ESP_EARLY_LOGI(TAG, "Readlatency : 0x%02x (%d cycles@%s)", reg_val->mr0.read_latency, reg_val->mr0.read_latency * 2 + 6,
|
||||
reg_val->mr0.lt == 1 ? "Fixed" : "Variable");
|
||||
ESP_EARLY_LOGI(TAG, "DriveStrength: 0x%02x (1/%d)", reg_val->mr0.drive_str, reg_val->mr0.drive_str == 0x00 ? 1 :
|
||||
reg_val->mr0.drive_str == 0x01 ? 2 :
|
||||
reg_val->mr0.drive_str == 0x02 ? 4 : 8);
|
||||
}
|
||||
|
||||
static void s_config_mspi_for_psram(void)
|
||||
{
|
||||
//Config Write CMD phase for SPI0 to access PSRAM
|
||||
psram_ctrlr_ll_set_wr_cmd(PSRAM_CTRLR_LL_MSPI_ID_2, AP_HEX_PSRAM_WR_CMD_BITLEN, AP_HEX_PSRAM_BURST_WRITE);
|
||||
|
||||
//Config Read CMD phase for SPI0 to access PSRAM
|
||||
psram_ctrlr_ll_set_rd_cmd(PSRAM_CTRLR_LL_MSPI_ID_2, AP_HEX_PSRAM_RD_CMD_BITLEN, AP_HEX_PSRAM_BURST_READ);
|
||||
|
||||
//Config ADDR phase
|
||||
psram_ctrlr_ll_set_addr_bitlen(PSRAM_CTRLR_LL_MSPI_ID_2, AP_HEX_PSRAM_ADDR_BITLEN);
|
||||
psram_ctrlr_ll_enable_4byte_addr(PSRAM_CTRLR_LL_MSPI_ID_2, true);
|
||||
|
||||
//Config RD/WR Dummy phase
|
||||
psram_ctrlr_ll_set_wr_dummy(PSRAM_CTRLR_LL_MSPI_ID_2, AP_HEX_PSRAM_WR_DUMMY_BITLEN);
|
||||
psram_ctrlr_ll_set_rd_dummy(PSRAM_CTRLR_LL_MSPI_ID_2, AP_HEX_PSRAM_RD_DUMMY_BITLEN);
|
||||
psram_ctrlr_ll_enable_variable_dummy(PSRAM_CTRLR_LL_MSPI_ID_2, true);
|
||||
psram_ctrlr_ll_enable_wr_dummy_level_control(PSRAM_CTRLR_LL_MSPI_ID_2, true);
|
||||
|
||||
//DDR
|
||||
psram_ctrlr_ll_enable_ddr_wr_data_swap(PSRAM_CTRLR_LL_MSPI_ID_2, false);
|
||||
psram_ctrlr_ll_enable_ddr_rd_data_swap(PSRAM_CTRLR_LL_MSPI_ID_2, false);
|
||||
psram_ctrlr_ll_enable_ddr_mode(PSRAM_CTRLR_LL_MSPI_ID_2, true);
|
||||
|
||||
//Line mode
|
||||
psram_ctrlr_ll_enable_oct_line_mode(PSRAM_CTRLR_LL_MSPI_ID_2, true);
|
||||
psram_ctrlr_ll_enable_hex_data_line_mode(PSRAM_CTRLR_LL_MSPI_ID_2, true);
|
||||
#if CONFIG_SPIRAM_USE_8LINE_MODE
|
||||
psram_ctrlr_ll_enable_hex_data_line_mode(PSRAM_CTRLR_LL_MSPI_ID_2, false);
|
||||
#endif
|
||||
|
||||
//AXI
|
||||
psram_ctrlr_ll_enable_axi_access(PSRAM_CTRLR_LL_MSPI_ID_2, true);
|
||||
psram_ctrlr_ll_enable_wr_splice(PSRAM_CTRLR_LL_MSPI_ID_2, true);
|
||||
psram_ctrlr_ll_enable_rd_splice(PSRAM_CTRLR_LL_MSPI_ID_2, true);
|
||||
}
|
||||
|
||||
static void s_set_psram_cs_timing(void)
|
||||
{
|
||||
psram_ctrlr_ll_set_cs_setup(PSRAM_CTRLR_LL_MSPI_ID_2, AP_HEX_PSRAM_CS_SETUP_TIME);
|
||||
psram_ctrlr_ll_set_cs_hold(PSRAM_CTRLR_LL_MSPI_ID_2, AP_HEX_PSRAM_CS_HOLD_TIME);
|
||||
psram_ctrlr_ll_set_cs_hold_delay(PSRAM_CTRLR_LL_MSPI_ID_2, AP_HEX_PSRAM_CS_HOLD_DELAY);
|
||||
#if CONFIG_SPIRAM_ECC_ENABLE
|
||||
psram_ctrlr_ll_set_cs_hold_ecc(PSRAM_CTRLR_LL_MSPI_ID_2, AP_HEX_PSRAM_CS_ECC_HOLD_TIME);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if CONFIG_SPIRAM_ECC_ENABLE
|
||||
static void s_mspi_ecc_show_info(void)
|
||||
{
|
||||
for (int i = 0; i < PSRAM_CTRLR_LL_PMS_REGION_NUMS; i++) {
|
||||
ESP_EARLY_LOGV(TAG, "region[%d] addr: 0x%08x", i, psram_ctrlr_ll_get_pms_region_start_addr(PSRAM_CTRLR_LL_MSPI_ID_2, i));
|
||||
ESP_EARLY_LOGV(TAG, "region[%d] size: 0x%08x", i, psram_ctrlr_ll_get_pms_region_size(PSRAM_CTRLR_LL_MSPI_ID_2, i));
|
||||
}
|
||||
|
||||
uint32_t page_size = psram_ctrlr_ll_get_page_size(PSRAM_CTRLR_LL_MSPI_ID_2);
|
||||
ESP_EARLY_LOGV(TAG, "ECC page size: %d", page_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable error correcting code feature
|
||||
*
|
||||
* Can add an input parameter for selecting ECC mode if needed
|
||||
*/
|
||||
static void s_configure_psram_ecc(void)
|
||||
{
|
||||
psram_ctrlr_ll_enable_16to18_ecc(PSRAM_CTRLR_LL_MSPI_ID_2, true);
|
||||
psram_ctrlr_ll_enable_skip_page_corner(PSRAM_CTRLR_LL_MSPI_ID_2, true);
|
||||
psram_ctrlr_ll_enable_split_trans(PSRAM_CTRLR_LL_MSPI_ID_2, true);
|
||||
psram_ctrlr_ll_set_page_size(PSRAM_CTRLR_LL_MSPI_ID_2, 2048);
|
||||
psram_ctrlr_ll_enable_ecc_addr_conversion(PSRAM_CTRLR_LL_MSPI_ID_2, 2048);
|
||||
|
||||
/**
|
||||
* Enable ECC region 0 (ACE0)
|
||||
* Default: ACE0 range: 0 ~ 256MB
|
||||
* Current Hex PSRAM is 8MB, ACE0 is enough
|
||||
*/
|
||||
psram_ctrlr_ll_enable_pms_region_ecc(PSRAM_CTRLR_LL_MSPI_ID_2, 0, true);
|
||||
|
||||
ESP_EARLY_LOGI(TAG, "ECC is enabled");
|
||||
s_mspi_ecc_show_info();
|
||||
}
|
||||
#endif //#if CONFIG_SPIRAM_ECC_ENABLE
|
||||
|
||||
|
||||
esp_err_t esp_psram_impl_enable(void)
|
||||
{
|
||||
s_set_psram_cs_timing();
|
||||
#if CONFIG_SPIRAM_ECC_ENABLE
|
||||
s_configure_psram_ecc();
|
||||
#endif
|
||||
//enter MSPI slow mode to init PSRAM device registers
|
||||
psram_ctrlr_ll_select_clk_source(PSRAM_CTRLR_LL_MSPI_ID_2, PSRAM_CLK_SRC_XTAL);
|
||||
psram_ctrlr_ll_set_bus_clock(PSRAM_CTRLR_LL_MSPI_ID_2, 2);
|
||||
psram_ctrlr_ll_enable_dll(PSRAM_CTRLR_LL_MSPI_ID_2, true);
|
||||
psram_ctrlr_ll_enable_dll(PSRAM_CTRLR_LL_MSPI_ID_3, true);
|
||||
|
||||
static hex_psram_mode_reg_t mode_reg = {};
|
||||
mode_reg.mr0.lt = 1;
|
||||
mode_reg.mr0.read_latency = 2;
|
||||
mode_reg.mr0.drive_str = 0;
|
||||
mode_reg.mr8.bl = 3;
|
||||
mode_reg.mr8.bt = 0;
|
||||
mode_reg.mr8.rbx = 1;
|
||||
mode_reg.mr8.x16 = 1;
|
||||
#if CONFIG_SPIRAM_USE_8LINE_MODE
|
||||
mode_reg.mr8.x16 = 0;
|
||||
#endif
|
||||
s_init_psram_mode_reg(PSRAM_CTRLR_LL_MSPI_ID_3, &mode_reg);
|
||||
//Print PSRAM info
|
||||
s_get_psram_mode_reg(PSRAM_CTRLR_LL_MSPI_ID_3, &mode_reg);
|
||||
if (mode_reg.mr1.vendor_id != AP_HEX_PSRAM_VENDOR_ID) {
|
||||
ESP_EARLY_LOGE(TAG, "PSRAM ID read error: 0x%08x, PSRAM chip not found or not supported, or wrong PSRAM line mode", mode_reg.mr1.vendor_id);
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
s_print_psram_info(&mode_reg);
|
||||
s_psram_size = mode_reg.mr2.density == 0x1 ? PSRAM_SIZE_4MB :
|
||||
mode_reg.mr2.density == 0X3 ? PSRAM_SIZE_8MB :
|
||||
mode_reg.mr2.density == 0x5 ? PSRAM_SIZE_16MB :
|
||||
mode_reg.mr2.density == 0x7 ? PSRAM_SIZE_32MB :
|
||||
mode_reg.mr2.density == 0x6 ? PSRAM_SIZE_64MB : 0;
|
||||
|
||||
s_config_mspi_for_psram();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
uint8_t esp_psram_impl_get_cs_io(void)
|
||||
{
|
||||
ESP_EARLY_LOGI(TAG, "psram CS IO is dedicated");
|
||||
return -1;
|
||||
}
|
||||
|
||||
esp_err_t esp_psram_impl_get_physical_size(uint32_t *out_size_bytes)
|
||||
{
|
||||
if (!out_size_bytes) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
*out_size_bytes = s_psram_size;
|
||||
return (s_psram_size ? ESP_OK : ESP_ERR_INVALID_STATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is to get the available physical psram size in bytes.
|
||||
* If ECC is enabled, available PSRAM size will be 7/8 times its physical size.
|
||||
*/
|
||||
esp_err_t esp_psram_impl_get_available_size(uint32_t *out_size_bytes)
|
||||
{
|
||||
if (!out_size_bytes) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
#if CONFIG_SPIRAM_ECC_ENABLE
|
||||
*out_size_bytes = s_psram_size * 7 / 8;
|
||||
#else
|
||||
*out_size_bytes = s_psram_size;
|
||||
#endif
|
||||
return (s_psram_size ? ESP_OK : ESP_ERR_INVALID_STATE);
|
||||
}
|
@ -189,6 +189,25 @@ typedef struct {
|
||||
#define PSRAM_SPICLKEN DPORT_SPI01_CLK_EN
|
||||
#endif
|
||||
|
||||
/*
|
||||
See the TRM, chapter PID/MPU/MMU, header 'External RAM' for the definitions of these modes.
|
||||
|
||||
Important is that NORMAL works with the app CPU cache disabled, but gives huge cache coherency
|
||||
issues when both app and pro CPU are enabled. LOWHIGH and EVENODD do not have these coherency
|
||||
issues but cannot be used when the app CPU cache is disabled.
|
||||
*/
|
||||
typedef enum {
|
||||
PSRAM_VADDR_MODE_NORMAL = 0, ///< App and pro CPU use their own flash cache for external RAM access
|
||||
PSRAM_VADDR_MODE_LOWHIGH, ///< App and pro CPU share external RAM caches: pro CPU has low 2M, app CPU has high 2M
|
||||
PSRAM_VADDR_MODE_EVENODD, ///< App and pro CPU share external RAM caches: pro CPU does even 32yte ranges, app does odd ones.
|
||||
} psram_vaddr_mode_t;
|
||||
|
||||
#if CONFIG_FREERTOS_UNICORE
|
||||
#define PSRAM_MODE PSRAM_VADDR_MODE_NORMAL
|
||||
#else
|
||||
#define PSRAM_MODE PSRAM_VADDR_MODE_LOWHIGH
|
||||
#endif
|
||||
|
||||
static const char *TAG = "quad_psram";
|
||||
typedef enum {
|
||||
PSRAM_SPI_1 = 0x1,
|
||||
@ -832,8 +851,9 @@ bool psram_is_32mbit_ver0(void)
|
||||
* Psram mode init will overwrite original flash speed mode, so that it is possible to change psram and flash speed after OTA.
|
||||
* Flash read mode(QIO/QOUT/DIO/DOUT) will not be changed in app bin. It is decided by bootloader, OTA can not change this mode.
|
||||
*/
|
||||
esp_err_t IRAM_ATTR esp_psram_impl_enable(psram_vaddr_mode_t vaddrmode) //psram init
|
||||
esp_err_t IRAM_ATTR esp_psram_impl_enable(void) //psram init
|
||||
{
|
||||
psram_vaddr_mode_t vaddrmode = PSRAM_MODE;
|
||||
psram_cache_speed_t mode = PSRAM_SPEED;
|
||||
psram_io_t psram_io = {0};
|
||||
uint32_t pkg_ver = efuse_ll_get_chip_ver_pkg();
|
||||
|
62
components/esp_psram/esp32p4/Kconfig.spiram
Normal file
62
components/esp_psram/esp32p4/Kconfig.spiram
Normal file
@ -0,0 +1,62 @@
|
||||
config SPIRAM
|
||||
bool "Support for external PSRAM"
|
||||
default "n"
|
||||
help
|
||||
This enables support for an external PSRAM chip, connected in parallel with the
|
||||
main SPI flash chip.
|
||||
|
||||
menu "PSRAM config"
|
||||
depends on SPIRAM
|
||||
|
||||
choice SPIRAM_MODE
|
||||
prompt "Line Mode of PSRAM chip in use"
|
||||
default SPIRAM_MODE_HEX
|
||||
|
||||
config SPIRAM_MODE_HEX
|
||||
bool "16-Line-Mode PSRAM"
|
||||
endchoice
|
||||
|
||||
config SPIRAM_USE_8LINE_MODE
|
||||
bool
|
||||
depends on SPIRAM_MODE_HEX
|
||||
default n
|
||||
|
||||
help
|
||||
Enable 8-Line-Mode of the AP HEX PSRAM
|
||||
|
||||
choice SPIRAM_SPEED
|
||||
prompt "Set PSRAM clock speed"
|
||||
default SPIRAM_SPEED_20M
|
||||
help
|
||||
Select the speed for the PSRAM chip.
|
||||
|
||||
config SPIRAM_SPEED_20M
|
||||
bool "20MHz clock speed"
|
||||
endchoice
|
||||
|
||||
config SPIRAM_SPEED
|
||||
int
|
||||
default 20 if SPIRAM_SPEED_20M
|
||||
|
||||
config SPIRAM_ECC_ENABLE
|
||||
bool "Enable PSRAM ECC"
|
||||
default n
|
||||
help
|
||||
Enable Error-Correcting Code function when accessing PSRAM.
|
||||
|
||||
If enabled, 1/8 of the PSRAM total size will be reserved for error-correcting code.
|
||||
|
||||
config SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY
|
||||
bool "Allow external memory as an argument to xTaskCreateStatic"
|
||||
default y
|
||||
help
|
||||
Accessing memory in PSRAM has certain restrictions, so task stacks allocated by xTaskCreate
|
||||
are by default allocated from internal RAM.
|
||||
|
||||
This option allows for passing memory allocated from PSRAM to be passed to xTaskCreateStatic.
|
||||
This should only be used for tasks where the stack is never accessed while the L2Cache is
|
||||
disabled, e.g. during SPI Flash operations
|
||||
|
||||
source "$IDF_PATH/components/esp_psram/Kconfig.spiram.common" # insert non-chip-specific items here
|
||||
|
||||
endmenu
|
@ -3,7 +3,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2013-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2013-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -93,6 +93,10 @@ static const char* TAG = "quad_psram";
|
||||
#define _SPI_40M_CLK_DIV 2
|
||||
#define _SPI_20M_CLK_DIV 4
|
||||
|
||||
typedef enum {
|
||||
PSRAM_VADDR_MODE_NORMAL = 0,
|
||||
} psram_vaddr_mode_t;
|
||||
|
||||
typedef enum {
|
||||
PSRAM_CLK_MODE_NORM = 0, /*!< Normal SPI mode */
|
||||
PSRAM_CLK_MODE_A1C, /*!< ONE extra clock cycles after CS is set high level */
|
||||
@ -410,8 +414,9 @@ static void psram_set_clk_mode(int spi_num, psram_clk_mode_t clk_mode)
|
||||
* Psram mode init will overwrite original flash speed mode, so that it is possible to change psram and flash speed after OTA.
|
||||
* Flash read mode(QIO/QOUT/DIO/DOUT) will not be changed in app bin. It is decided by bootloader, OTA can not change this mode.
|
||||
*/
|
||||
esp_err_t IRAM_ATTR esp_psram_impl_enable(psram_vaddr_mode_t vaddrmode) //psram init
|
||||
esp_err_t IRAM_ATTR esp_psram_impl_enable(void) //psram init
|
||||
{
|
||||
psram_vaddr_mode_t vaddrmode = PSRAM_VADDR_MODE_NORMAL;
|
||||
psram_cache_speed_t mode = PSRAM_SPEED;
|
||||
assert(mode < PSRAM_CACHE_MAX && "we don't support any other mode for now.");
|
||||
// GPIO related settings
|
||||
|
@ -108,5 +108,14 @@ menu "SPI RAM config"
|
||||
default 80 if SPIRAM_SPEED_80M
|
||||
default 40 if SPIRAM_SPEED_40M
|
||||
|
||||
config SPIRAM_ECC_ENABLE
|
||||
bool "Enable SPI RAM ECC"
|
||||
default n
|
||||
depends on SPIRAM_MODE_OCT
|
||||
help
|
||||
Enable MSPI Error-Correcting Code function when accessing SPIRAM.
|
||||
|
||||
If enabled, 1/16 of the SPI RAM total size will be reserved for error-correcting code.
|
||||
|
||||
source "$IDF_PATH/components/esp_psram/Kconfig.spiram.common" # insert non-chip-specific items here
|
||||
endmenu
|
||||
|
@ -294,7 +294,7 @@ static void s_configure_psram_ecc(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
esp_err_t esp_psram_impl_enable(psram_vaddr_mode_t vaddrmode)
|
||||
esp_err_t esp_psram_impl_enable(void)
|
||||
{
|
||||
s_init_psram_pins();
|
||||
s_set_psram_cs_timing();
|
||||
|
@ -303,7 +303,7 @@ static void psram_gpio_config(void)
|
||||
esp_gpio_reserve_pins(BIT64(cs1_io) | BIT64(wp_io));
|
||||
}
|
||||
|
||||
esp_err_t esp_psram_impl_enable(psram_vaddr_mode_t vaddrmode) //psram init
|
||||
esp_err_t esp_psram_impl_enable(void) //psram init
|
||||
{
|
||||
psram_gpio_config();
|
||||
psram_set_cs_timing();
|
||||
|
@ -17,9 +17,9 @@
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/xtensa_api.h"
|
||||
#include "esp_heap_caps_init.h"
|
||||
#include "hal/mmu_hal.h"
|
||||
#include "hal/mmu_ll.h"
|
||||
#include "hal/cache_ll.h"
|
||||
#include "esp_private/esp_psram_io.h"
|
||||
#include "esp_private/esp_psram_extram.h"
|
||||
@ -36,16 +36,6 @@
|
||||
#endif
|
||||
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#if CONFIG_FREERTOS_UNICORE
|
||||
#define PSRAM_MODE PSRAM_VADDR_MODE_NORMAL
|
||||
#else
|
||||
#define PSRAM_MODE PSRAM_VADDR_MODE_LOWHIGH
|
||||
#endif
|
||||
#else
|
||||
#define PSRAM_MODE PSRAM_VADDR_MODE_NORMAL
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Two types of PSRAM memory regions for now:
|
||||
* - 8bit aligned
|
||||
@ -123,7 +113,7 @@ esp_err_t esp_psram_init(void)
|
||||
}
|
||||
|
||||
esp_err_t ret = ESP_FAIL;
|
||||
ret = esp_psram_impl_enable(PSRAM_MODE);
|
||||
ret = esp_psram_impl_enable();
|
||||
if (ret != ESP_OK) {
|
||||
#if CONFIG_SPIRAM_IGNORE_NOTFOUND
|
||||
ESP_EARLY_LOGE(TAG, "PSRAM enabled but initialization failed. Bailing out.");
|
||||
@ -139,10 +129,11 @@ esp_err_t esp_psram_init(void)
|
||||
ESP_EARLY_LOGI(TAG, "Found %dMB PSRAM device", psram_physical_size / (1024 * 1024));
|
||||
ESP_EARLY_LOGI(TAG, "Speed: %dMHz", CONFIG_SPIRAM_SPEED);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
ESP_EARLY_LOGI(TAG, "PSRAM initialized, cache is in %s mode.", \
|
||||
(PSRAM_MODE==PSRAM_VADDR_MODE_EVENODD)?"even/odd (2-core)": \
|
||||
(PSRAM_MODE==PSRAM_VADDR_MODE_LOWHIGH)?"low/high (2-core)": \
|
||||
(PSRAM_MODE==PSRAM_VADDR_MODE_NORMAL)?"normal (1-core)":"ERROR");
|
||||
#if CONFIG_FREERTOS_UNICORE
|
||||
ESP_EARLY_LOGI(TAG, "PSRAM initialized, cache is in normal (1-core) mode.");
|
||||
#else
|
||||
ESP_EARLY_LOGI(TAG, "PSRAM initialized, cache is in low/high (2-core) mode.");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
uint32_t psram_available_size = 0;
|
||||
@ -196,30 +187,19 @@ esp_err_t esp_psram_init(void)
|
||||
size_t total_mapped_size = 0;
|
||||
size_t size_to_map = 0;
|
||||
size_t byte_aligned_size = 0;
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
//TODO: IDF-7495
|
||||
ret = esp_mmu_map_get_max_consecutive_free_block_size(MMU_MEM_CAP_PSRAM, MMU_TARGET_PSRAM0, &byte_aligned_size);
|
||||
#else
|
||||
ret = esp_mmu_map_get_max_consecutive_free_block_size(MMU_MEM_CAP_READ | MMU_MEM_CAP_WRITE | MMU_MEM_CAP_8BIT | MMU_MEM_CAP_32BIT, MMU_TARGET_PSRAM0, &byte_aligned_size);
|
||||
#endif
|
||||
assert(ret == ESP_OK);
|
||||
size_to_map = MIN(byte_aligned_size, psram_available_size);
|
||||
|
||||
const void *v_start_8bit_aligned = NULL;
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
//TODO: IDF-7495
|
||||
ret = esp_mmu_map_reserve_block_with_caps(size_to_map, MMU_MEM_CAP_PSRAM, MMU_TARGET_PSRAM0, &v_start_8bit_aligned);
|
||||
#else
|
||||
ret = esp_mmu_map_reserve_block_with_caps(size_to_map, MMU_MEM_CAP_READ | MMU_MEM_CAP_WRITE | MMU_MEM_CAP_8BIT | MMU_MEM_CAP_32BIT, MMU_TARGET_PSRAM0, &v_start_8bit_aligned);
|
||||
#endif
|
||||
assert(ret == ESP_OK);
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
s_mapping((int)v_start_8bit_aligned, size_to_map);
|
||||
#else
|
||||
uint32_t actual_mapped_len = 0;
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
//TODO: IDF-7495
|
||||
#if MMU_LL_MMU_PER_TARGET
|
||||
mmu_hal_map_region(1, MMU_TARGET_PSRAM0, (intptr_t)v_start_8bit_aligned, MMU_PAGE_TO_BYTES(start_page), size_to_map, &actual_mapped_len);
|
||||
#else
|
||||
mmu_hal_map_region(0, MMU_TARGET_PSRAM0, (intptr_t)v_start_8bit_aligned, MMU_PAGE_TO_BYTES(start_page), size_to_map, &actual_mapped_len);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -20,20 +20,6 @@ extern "C" {
|
||||
#define PSRAM_SIZE_32MB (32 * 1024 * 1024)
|
||||
#define PSRAM_SIZE_64MB (64 * 1024 * 1024)
|
||||
|
||||
|
||||
/*
|
||||
See the TRM, chapter PID/MPU/MMU, header 'External RAM' for the definitions of these modes.
|
||||
|
||||
Important is that NORMAL works with the app CPU cache disabled, but gives huge cache coherency
|
||||
issues when both app and pro CPU are enabled. LOWHIGH and EVENODD do not have these coherency
|
||||
issues but cannot be used when the app CPU cache is disabled.
|
||||
*/
|
||||
typedef enum {
|
||||
PSRAM_VADDR_MODE_NORMAL=0, ///< App and pro CPU use their own flash cache for external RAM access
|
||||
PSRAM_VADDR_MODE_LOWHIGH, ///< App and pro CPU share external RAM caches: pro CPU has low 2M, app CPU has high 2M
|
||||
PSRAM_VADDR_MODE_EVENODD, ///< App and pro CPU share external RAM caches: pro CPU does even 32yte ranges, app does odd ones.
|
||||
} psram_vaddr_mode_t;
|
||||
|
||||
/**
|
||||
* @brief To get the physical psram size in bytes.
|
||||
*
|
||||
@ -51,13 +37,12 @@ esp_err_t esp_psram_impl_get_available_size(uint32_t *out_size_bytes);
|
||||
/**
|
||||
* @brief Enable psram and configure it to a ready state
|
||||
*
|
||||
* @param vaddrmode Mode the psram cache works in.
|
||||
* @return
|
||||
* - ESP_OK: On success
|
||||
* - ESP_ERR_NOT_SUPPORTED: PSRAM ID / vendor ID check fail
|
||||
* - ESP_ERR_INVALID_STATE: On esp32, when VSPI peripheral is needed but cannot be claimed
|
||||
*/
|
||||
esp_err_t esp_psram_impl_enable(psram_vaddr_mode_t vaddrmode);
|
||||
esp_err_t esp_psram_impl_enable(void);
|
||||
|
||||
/**
|
||||
* @brief get psram CS IO
|
||||
|
@ -13,3 +13,6 @@ entries:
|
||||
|
||||
if IDF_TARGET_ESP32S2 = y || IDF_TARGET_ESP32S3 = y:
|
||||
mmu_psram_flash (noflash)
|
||||
|
||||
if SPIRAM_MODE_HEX = y:
|
||||
esp_psram_impl_ap_hex (noflash)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
692
components/hal/esp32p4/include/hal/psram_ctrlr_ll.h
Normal file
692
components/hal/esp32p4/include/hal/psram_ctrlr_ll.h
Normal file
@ -0,0 +1,692 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 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 "soc/spi_mem_s_struct.h"
|
||||
#include "soc/spi_mem_s_reg.h"
|
||||
#include "soc/hp_sys_clkrst_struct.h"
|
||||
#include "soc/clk_tree_defs.h"
|
||||
#include "rom/opi_flash.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define PSRAM_CTRLR_LL_MSPI_ID_2 2
|
||||
#define PSRAM_CTRLR_LL_MSPI_ID_3 3
|
||||
|
||||
#define PSRAM_CTRLR_LL_PMS_REGION_NUMS 4
|
||||
#define PSRAM_CTRLR_LL_PMS_ATTR_WRITABLE (1<<0)
|
||||
#define PSRAM_CTRLR_LL_PMS_ATTR_READABLE (1<<1)
|
||||
|
||||
|
||||
/**
|
||||
* @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);
|
||||
SPIMEM2.mem_cache_sctrl.mem_cache_sram_usr_wcmd = 1;
|
||||
SPIMEM2.mem_sram_dwr_cmd.mem_cache_sram_usr_wr_cmd_bitlen = cmd_bitlen - 1;
|
||||
SPIMEM2.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);
|
||||
SPIMEM2.mem_cache_sctrl.mem_cache_sram_usr_rcmd = 1;
|
||||
SPIMEM2.mem_sram_drd_cmd.mem_cache_sram_usr_rd_cmd_bitlen = cmd_bitlen - 1;
|
||||
SPIMEM2.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);
|
||||
SPIMEM2.mem_cache_sctrl.mem_sram_addr_bitlen = addr_bitlen - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable PSRAM 4B addr
|
||||
*
|
||||
* @param mspi_id mspi_id
|
||||
* @param en enable / disable
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void psram_ctrlr_ll_enable_4byte_addr(uint32_t mspi_id, bool en)
|
||||
{
|
||||
(void)mspi_id;
|
||||
SPIMEM2.mem_cache_sctrl.mem_cache_usr_saddr_4byte = en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set PSRAM write dummy
|
||||
*
|
||||
* @param mspi_id mspi_id
|
||||
* @param dummy_n dummy number
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void psram_ctrlr_ll_set_wr_dummy(uint32_t mspi_id, uint32_t dummy_n)
|
||||
{
|
||||
(void)mspi_id;
|
||||
HAL_ASSERT(dummy_n > 0);
|
||||
SPIMEM2.mem_cache_sctrl.mem_usr_wr_sram_dummy = 1;
|
||||
SPIMEM2.mem_cache_sctrl.mem_sram_wdummy_cyclelen = dummy_n - 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);
|
||||
SPIMEM2.mem_cache_sctrl.mem_usr_rd_sram_dummy = 1;
|
||||
SPIMEM2.mem_cache_sctrl.mem_sram_rdummy_cyclelen = dummy_n - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable PSRAM variable dummy
|
||||
*
|
||||
* @param mspi_id mspi_id
|
||||
* @param en enable / disable
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void psram_ctrlr_ll_enable_variable_dummy(uint32_t mspi_id, bool en)
|
||||
{
|
||||
(void)mspi_id;
|
||||
SPIMEM2.smem_ddr.smem_var_dummy = en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable PSRAM write dummy level control
|
||||
*
|
||||
* @param mspi_id mspi_id
|
||||
* @param en enable / disable
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void psram_ctrlr_ll_enable_wr_dummy_level_control(uint32_t mspi_id, bool en)
|
||||
{
|
||||
(void)mspi_id;
|
||||
SPIMEM2.mem_sram_cmd.mem_sdummy_wout = en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable PSRAM read dummy level control
|
||||
*
|
||||
* @param mspi_id mspi_id
|
||||
* @param en enable / disable
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void psram_ctrlr_ll_enable_rd_dummy_level_control(uint32_t mspi_id, bool en)
|
||||
{
|
||||
(void)mspi_id;
|
||||
SPIMEM2.mem_sram_cmd.mem_sdummy_rin = en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable PSRAM ddr mode
|
||||
*
|
||||
* @param mspi_id mspi_id
|
||||
* @param en enable / disable
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void psram_ctrlr_ll_enable_ddr_mode(uint32_t mspi_id, bool en)
|
||||
{
|
||||
(void)mspi_id;
|
||||
SPIMEM2.smem_ddr.smem_ddr_en = en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable PSRAM ddr write data swap
|
||||
*
|
||||
* @param mspi_id mspi_id
|
||||
* @param en enable / disable
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void psram_ctrlr_ll_enable_ddr_wr_data_swap(uint32_t mspi_id, bool en)
|
||||
{
|
||||
(void)mspi_id;
|
||||
SPIMEM2.smem_ddr.smem_ddr_wdat_swp = en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable PSRAM ddr read data swap
|
||||
*
|
||||
* @param mspi_id mspi_id
|
||||
* @param en enable / disable
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void psram_ctrlr_ll_enable_ddr_rd_data_swap(uint32_t mspi_id, bool en)
|
||||
{
|
||||
(void)mspi_id;
|
||||
SPIMEM2.smem_ddr.smem_ddr_rdat_swp = en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable PSRAM octal mode
|
||||
*
|
||||
* @param mspi_id mspi_id
|
||||
* @param en enable / disable
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void psram_ctrlr_ll_enable_oct_line_mode(uint32_t mspi_id, bool en)
|
||||
{
|
||||
(void)mspi_id;
|
||||
SPIMEM2.mem_cache_sctrl.mem_sram_oct = en;
|
||||
SPIMEM2.mem_sram_cmd.mem_scmd_oct = en;
|
||||
SPIMEM2.mem_sram_cmd.mem_saddr_oct = en;
|
||||
SPIMEM2.mem_sram_cmd.mem_sdout_oct = en;
|
||||
SPIMEM2.mem_sram_cmd.mem_sdin_oct = en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable PSRAM hex data line mode
|
||||
*
|
||||
* @param mspi_id mspi_id
|
||||
* @param en enable / disable
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void psram_ctrlr_ll_enable_hex_data_line_mode(uint32_t mspi_id, bool en)
|
||||
{
|
||||
(void)mspi_id;
|
||||
SPIMEM2.mem_sram_cmd.mem_sdin_hex = en;
|
||||
SPIMEM2.mem_sram_cmd.mem_sdout_hex = en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable PSRAM AXI master access
|
||||
*
|
||||
* @param mspi_id mspi_id
|
||||
* @param en enable / disable
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void psram_ctrlr_ll_enable_axi_access(uint32_t mspi_id, bool en)
|
||||
{
|
||||
(void)mspi_id;
|
||||
SPIMEM2.mem_cache_fctrl.mem_axi_req_en = en;
|
||||
SPIMEM2.mem_cache_fctrl.close_axi_inf_en = !en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable PSRAM write splice transfer
|
||||
*
|
||||
* @param mspi_id mspi_id
|
||||
* @param en enable / disable
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void psram_ctrlr_ll_enable_wr_splice(uint32_t mspi_id, bool en)
|
||||
{
|
||||
(void)mspi_id;
|
||||
SPIMEM2.mem_ctrl1.mem_aw_splice_en = en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable PSRAM read splice transfer
|
||||
*
|
||||
* @param mspi_id mspi_id
|
||||
* @param en enable / disable
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void psram_ctrlr_ll_enable_rd_splice(uint32_t mspi_id, bool en)
|
||||
{
|
||||
(void)mspi_id;
|
||||
SPIMEM2.mem_ctrl1.mem_ar_splice_en = en;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enable PSRAM module clock
|
||||
*
|
||||
* @param mspi_id mspi_id
|
||||
* @param en enable / disable
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void psram_ctrlr_ll_enable_module_clock(uint32_t mspi_id, bool en)
|
||||
{
|
||||
(void)mspi_id;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl00.reg_psram_pll_clk_en = en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Select PSRAM clock source
|
||||
*
|
||||
* @param mspi_id mspi_id
|
||||
* @param clk_src clock source, see valid sources in type `soc_periph_psram_clk_src_t`
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void psram_ctrlr_ll_select_clk_source(uint32_t mspi_id, soc_periph_psram_clk_src_t clk_src)
|
||||
{
|
||||
(void)mspi_id;
|
||||
uint32_t clk_val = 0;
|
||||
switch (clk_src) {
|
||||
case PSRAM_CLK_SRC_XTAL:
|
||||
clk_val = 0;
|
||||
break;
|
||||
case PSRAM_CLK_SRC_MPLL:
|
||||
clk_val = 1;
|
||||
break;
|
||||
case PSRAM_CLK_SRC_SPLL:
|
||||
clk_val = 2;
|
||||
break;
|
||||
case PSRAM_CLK_SRC_CPLL:
|
||||
clk_val = 3;
|
||||
break;
|
||||
default:
|
||||
HAL_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
HP_SYS_CLKRST.peri_clk_ctrl00.reg_psram_clk_src_sel = clk_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set PSRAM core clock
|
||||
*
|
||||
* @param mspi_id mspi_id
|
||||
* @param core_clk_mhz core clock mhz
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void psram_ctrlr_ll_set_core_clock(uint8_t spi_num, uint32_t core_clk_mhz)
|
||||
{
|
||||
//TODO: IDF-7517
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set PSRAM bus clock
|
||||
*
|
||||
* @param mspi_id mspi_id
|
||||
* @param freqdiv Divider value
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void psram_ctrlr_ll_set_bus_clock(uint32_t mspi_id, uint32_t freqdiv)
|
||||
{
|
||||
(void)mspi_id;
|
||||
if (freqdiv == 1) {
|
||||
WRITE_PERI_REG(SPI_MEM_S_SRAM_CLK_REG, SPI_MEM_S_SCLK_EQU_SYSCLK);
|
||||
} else {
|
||||
uint32_t freqbits = (((freqdiv - 1) << SPI_MEM_S_SCLKCNT_N_S)) | (((freqdiv / 2 - 1) << SPI_MEM_S_SCLKCNT_H_S)) | ((freqdiv - 1) << SPI_MEM_S_SCLKCNT_L_S);
|
||||
WRITE_PERI_REG(SPI_MEM_S_SRAM_CLK_REG, freqbits);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable PSRAM DLL
|
||||
*
|
||||
* @param mspi_id mspi_id
|
||||
* @param en enable / disable
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void psram_ctrlr_ll_enable_dll(uint32_t mspi_id, bool en)
|
||||
{
|
||||
if (mspi_id == PSRAM_CTRLR_LL_MSPI_ID_2) {
|
||||
SPIMEM2.smem_timing_cali.smem_dll_timing_cali = en;
|
||||
} else if (mspi_id == PSRAM_CTRLR_LL_MSPI_ID_3) {
|
||||
SPIMEM2.mem_timing_cali.mem_dll_timing_cali = en;
|
||||
} else {
|
||||
HAL_ASSERT(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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);
|
||||
SPIMEM2.smem_ac.smem_cs_setup = 1;
|
||||
SPIMEM2.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);
|
||||
SPIMEM2.smem_ac.smem_cs_hold = 1;
|
||||
SPIMEM2.smem_ac.smem_cs_hold_time = hold_n - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set CS hold delay
|
||||
*
|
||||
* @param mspi_id mspi_id
|
||||
* @param hold_n cs hold 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);
|
||||
SPIMEM2.smem_ac.smem_cs_hold_delay = hold_delay_n - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set ECC 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_ecc(uint32_t mspi_id, uint32_t hold_n)
|
||||
{
|
||||
(void)mspi_id;
|
||||
HAL_ASSERT(hold_n > 0);
|
||||
SPIMEM2.smem_ac.smem_ecc_cs_hold_time = hold_n - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable 16to18 ECC
|
||||
*
|
||||
* @param mspi_id mspi_id
|
||||
* @param en enable / disable
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void psram_ctrlr_ll_enable_16to18_ecc(uint32_t mspi_id, bool en)
|
||||
{
|
||||
(void)mspi_id;
|
||||
SPIMEM2.smem_ac.smem_ecc_16to18_byte_en = en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable ECC skip page corner
|
||||
*
|
||||
* @param mspi_id mspi_id
|
||||
* @param en enable / disable
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void psram_ctrlr_ll_enable_skip_page_corner(uint32_t mspi_id, bool en)
|
||||
{
|
||||
(void)mspi_id;
|
||||
SPIMEM2.smem_ac.smem_ecc_skip_page_corner = en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable spliting transactions
|
||||
*
|
||||
* @param mspi_id mspi_id
|
||||
* @param en enable / disable
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void psram_ctrlr_ll_enable_split_trans(uint32_t mspi_id, bool en)
|
||||
{
|
||||
(void)mspi_id;
|
||||
SPIMEM2.smem_ac.smem_split_trans_en = en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable ECC address conversion
|
||||
*
|
||||
* @param mspi_id mspi_id
|
||||
* @param en enable / disable
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void psram_ctrlr_ll_enable_ecc_addr_conversion(uint32_t mspi_id, bool en)
|
||||
{
|
||||
(void)mspi_id;
|
||||
SPIMEM2.smem_ecc_ctrl.smem_ecc_addr_en = en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set page size
|
||||
*
|
||||
* @param mspi_id mspi_id
|
||||
* @param page_size page size
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void psram_ctrlr_ll_set_page_size(uint32_t mspi_id, uint32_t page_size)
|
||||
{
|
||||
(void)mspi_id;
|
||||
switch(page_size) {
|
||||
case 256:
|
||||
SPIMEM2.smem_ecc_ctrl.smem_page_size = 0;
|
||||
break;
|
||||
case 512:
|
||||
SPIMEM2.smem_ecc_ctrl.smem_page_size = 1;
|
||||
break;
|
||||
case 1024:
|
||||
SPIMEM2.smem_ecc_ctrl.smem_page_size = 2;
|
||||
break;
|
||||
case 2048:
|
||||
SPIMEM2.smem_ecc_ctrl.smem_page_size = 3;
|
||||
break;
|
||||
default:
|
||||
HAL_ASSERT(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get page size
|
||||
*
|
||||
* @param mspi_id mspi_id
|
||||
*
|
||||
* @return page size
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t psram_ctrlr_ll_get_page_size(uint32_t mspi_id)
|
||||
{
|
||||
(void)mspi_id;
|
||||
uint32_t page_size = 0;
|
||||
|
||||
uint32_t reg_val = SPIMEM2.smem_ecc_ctrl.smem_page_size;
|
||||
switch(reg_val) {
|
||||
case 0:
|
||||
page_size = 256;
|
||||
break;
|
||||
case 1:
|
||||
page_size = 512;
|
||||
break;
|
||||
case 2:
|
||||
page_size = 1024;
|
||||
break;
|
||||
case 3:
|
||||
page_size = 2048;
|
||||
break;
|
||||
default:
|
||||
HAL_ASSERT(false);
|
||||
}
|
||||
|
||||
return page_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable PMS ECC
|
||||
*
|
||||
* @param mspi_id mspi_id
|
||||
* @param region_id region_id
|
||||
* @param en enable / disable
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void psram_ctrlr_ll_enable_pms_region_ecc(uint32_t mspi_id, uint32_t region_id, bool en)
|
||||
{
|
||||
(void)mspi_id;
|
||||
HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS);
|
||||
SPIMEM2.smem_pmsn_attr[region_id].smem_pms_ecc = en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set PMS attr
|
||||
*
|
||||
* @param mspi_id mspi_id
|
||||
* @param region_id region_id
|
||||
* @param attr_mask attribute mask
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void psram_ctrlr_ll_set_pms_region_attr(uint32_t mspi_id, uint32_t region_id, uint32_t attr_mask)
|
||||
{
|
||||
(void)mspi_id;
|
||||
HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS);
|
||||
SPIMEM2.smem_pmsn_attr[region_id].smem_pms_wr_attr = 0;
|
||||
SPIMEM2.smem_pmsn_attr[region_id].smem_pms_rd_attr = 0;
|
||||
if (attr_mask & PSRAM_CTRLR_LL_PMS_ATTR_WRITABLE) {
|
||||
SPIMEM2.smem_pmsn_attr[region_id].smem_pms_wr_attr = 1;
|
||||
}
|
||||
if (attr_mask & PSRAM_CTRLR_LL_PMS_ATTR_READABLE) {
|
||||
SPIMEM2.smem_pmsn_attr[region_id].smem_pms_rd_attr = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set PMS address
|
||||
*
|
||||
* @param mspi_id mspi_id
|
||||
* @param region_id region_id
|
||||
* @param addr start addr
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void psram_ctrlr_ll_set_pms_region_start_addr(uint32_t mspi_id, uint32_t region_id, uint32_t addr)
|
||||
{
|
||||
(void)mspi_id;
|
||||
HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS);
|
||||
SPIMEM2.smem_pmsn_addr[region_id].smem_pms_addr_s = addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set PMS size
|
||||
*
|
||||
* @param mspi_id mspi_id
|
||||
* @param region_id region_id
|
||||
* @param size size
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void psram_ctrlr_ll_set_pms_region_size(uint32_t mspi_id, uint32_t region_id, uint32_t size)
|
||||
{
|
||||
(void)mspi_id;
|
||||
HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS);
|
||||
SPIMEM2.smem_pmsn_size[region_id].smem_pms_size = size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get PMS address
|
||||
*
|
||||
* @param mspi_id mspi_id
|
||||
* @param region_id region_id
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t psram_ctrlr_ll_get_pms_region_start_addr(uint32_t mspi_id, uint32_t region_id)
|
||||
{
|
||||
(void)mspi_id;
|
||||
HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS);
|
||||
return SPIMEM2.smem_pmsn_addr[region_id].smem_pms_addr_s;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get PMS size
|
||||
*
|
||||
* @param mspi_id mspi_id
|
||||
* @param region_id region_id
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t psram_ctrlr_ll_get_pms_region_size(uint32_t mspi_id, uint32_t region_id)
|
||||
{
|
||||
(void)mspi_id;
|
||||
HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS);
|
||||
return SPIMEM2.smem_pmsn_size[region_id].smem_pms_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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_set_op_mode(mspi_id, mode);
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief PSRAM common transaction
|
||||
*
|
||||
* See `opi_flash.h` for parameters
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void psram_ctrlr_ll_common_transaction(uint32_t mspi_id,
|
||||
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,
|
||||
bool is_write_erase_operation)
|
||||
{
|
||||
esp_rom_spiflash_read_mode_t mode = ESP_ROM_SPIFLASH_OPI_DTR_MODE;
|
||||
uint32_t cs_mask = 1<<1;
|
||||
psram_ctrlr_ll_common_transaction_base(mspi_id, mode, cmd, cmd_bitlen, addr, addr_bitlen, dummy_bits,
|
||||
mosi_data, mosi_bitlen, miso_data, miso_bitlen, cs_mask,
|
||||
is_write_erase_operation);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -30,8 +30,9 @@ enum {
|
||||
SOC_MEMORY_TYPE_STACK_DRAM = 1,
|
||||
SOC_MEMORY_TYPE_DIRAM = 2,
|
||||
SOC_MEMORY_TYPE_STACK_DIRAM = 3,
|
||||
SOC_MEMORY_TYPE_RTCRAM = 4,
|
||||
SOC_MEMORY_TYPE_TCM = 5,
|
||||
SOC_MEMORY_TYPE_SPIRAM = 4,
|
||||
SOC_MEMORY_TYPE_RTCRAM = 5,
|
||||
SOC_MEMORY_TYPE_TCM = 6,
|
||||
SOC_MEMORY_TYPE_NUM,
|
||||
};
|
||||
|
||||
@ -44,9 +45,11 @@ const soc_memory_type_desc_t soc_memory_types[SOC_MEMORY_TYPE_NUM] = {
|
||||
[SOC_MEMORY_TYPE_DIRAM] = { "D/IRAM", { 0, MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL | MALLOC_CAP_DEFAULT, MALLOC_CAP_32BIT | MALLOC_CAP_EXEC }, true, false},
|
||||
// Type 3: DIRAM used for startup stacks
|
||||
[SOC_MEMORY_TYPE_STACK_DIRAM] = { "STACK/DIRAM", { MALLOC_CAP_8BIT | MALLOC_CAP_DEFAULT | MALLOC_CAP_RETENTION, MALLOC_CAP_EXEC | MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA | MALLOC_CAP_32BIT, 0 }, true, true},
|
||||
// Type 4: RTCRAM // TODO: IDF-5667 Better to rename to LPRAM
|
||||
// Type 4: SPI SRAM data
|
||||
[SOC_MEMORY_TYPE_SPIRAM] = { "SPIRAM", { MALLOC_CAP_SPIRAM | MALLOC_CAP_DEFAULT, 0, MALLOC_CAP_8BIT | MALLOC_CAP_32BIT}, false, false},
|
||||
// Type 5: RTCRAM // TODO: IDF-5667 Better to rename to LPRAM
|
||||
[SOC_MEMORY_TYPE_RTCRAM] = { "RTCRAM", { MALLOC_CAP_RTCRAM, MALLOC_CAP_8BIT | MALLOC_CAP_DEFAULT, MALLOC_CAP_INTERNAL | MALLOC_CAP_32BIT }, false, false},
|
||||
// Type 5: TCM
|
||||
// Type 6: TCM
|
||||
[SOC_MEMORY_TYPE_TCM] = {"TCM", {MALLOC_CAP_TCM, MALLOC_CAP_8BIT | MALLOC_CAP_DEFAULT, MALLOC_CAP_INTERNAL | MALLOC_CAP_32BIT}, false, false},
|
||||
};
|
||||
|
||||
@ -75,7 +78,7 @@ const size_t soc_memory_type_count = sizeof(soc_memory_types) / sizeof(soc_memor
|
||||
|
||||
const soc_memory_region_t soc_memory_regions[] = {
|
||||
#ifdef CONFIG_SPIRAM
|
||||
{ SOC_EXTRAM_LOW, SOC_EXTRAM_HIGH, SOC_MEMORY_TYPE_SPIRAM, 0}, //PSRAM, if available
|
||||
{ SOC_EXTRAM_LOW, SOC_EXTRAM_SIZE, SOC_MEMORY_TYPE_SPIRAM, 0}, //PSRAM, if available
|
||||
#endif
|
||||
// base 192k is always avaible, even if we config l2 cache size to 512k
|
||||
{ 0x4ff00000, 0x30000, SOC_MEMORY_TYPE_DEFAULT, 0x4ff00000},
|
||||
|
@ -80,6 +80,9 @@
|
||||
#include "lwip/sys.h"
|
||||
#include <string.h>
|
||||
#include "esp_rom_md5.h"
|
||||
#ifdef CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY
|
||||
#include "esp_memory_utils.h"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT
|
||||
|
||||
|
@ -79,6 +79,10 @@ config SOC_FLASH_ENC_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_SPIRAM_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_XTAL_SUPPORT_40M
|
||||
bool
|
||||
default y
|
||||
|
@ -48,7 +48,7 @@ extern "C" {
|
||||
* PLL Clocks:
|
||||
*
|
||||
* from 40MHz XTAL oscillator frequency multipliers:
|
||||
* 1) CPLL (400MHz), used for CPU clock source
|
||||
* 1) CPLL (400MHz), used for CPU, MSPI-Flash, MSPI-PSRAM clock source
|
||||
* 2) MPLL (500MHz), used for MSPI-PSRAM clock source; and is further divided to PLL_F50M, PLL_F25M, to be used for peripheral's clock sources
|
||||
* 3) SPLL (480MHz), directly used for MSPI-Flash, MSPI-PSRAM, GPSPI clock sources; and is further divided to PLL_F240M, PLL_F160M, PLL_F120M, PLL_F80M, PLL_F20M, to be used for peripherals' clock sources
|
||||
* 4) APLL (configurable), can be the clock source for peripherals (GPSPI, I2S, LCD, CAM, etc.)
|
||||
@ -144,6 +144,9 @@ typedef enum {
|
||||
SOC_MOD_CLK_PLL_F80M, /*!< PLL_F80M_CLK is derived from SPLL (clock gating + fixed divider of 6), it has a fixed frequency of 80MHz */
|
||||
SOC_MOD_CLK_PLL_F160M, /*!< PLL_F160M_CLK is derived from SPLL (clock gating + fixed divider of 3), it has a fixed frequency of 160MHz */
|
||||
SOC_MOD_CLK_PLL_F240M, /*!< PLL_F240M_CLK is derived from SPLL (clock gating + fixed divider of 2), it has a fixed frequency of 240MHz */
|
||||
SOC_MOD_CLK_CPLL, /*!< CPLL is from 40MHz XTAL oscillator frequency multipliers, it has a fixed frequency of 400MHz */
|
||||
SOC_MOD_CLK_SPLL, /*!< SPLL is from 40MHz XTAL oscillator frequency multipliers, it has a fixed frequency of 480MHz */
|
||||
SOC_MOD_CLK_MPLL, /*!< MPLL is from 40MHz XTAL oscillator frequency multipliers, it has a fixed frequency of 500MHz */
|
||||
SOC_MOD_CLK_XTAL32K, /*!< XTAL32K_CLK comes from the external 32kHz crystal, passing a clock gating to the peripherals */
|
||||
SOC_MOD_CLK_RC_FAST, /*!< RC_FAST_CLK comes from the internal 20MHz rc oscillator, passing a clock gating to the peripherals */
|
||||
SOC_MOD_CLK_XTAL, /*!< XTAL_CLK comes from the external 40MHz crystal */
|
||||
@ -328,6 +331,41 @@ typedef enum {
|
||||
SPI_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as SPI source clock */
|
||||
} soc_periph_spi_clk_src_t;
|
||||
|
||||
/////////////////////////////////////////////////PSRAM////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* @brief Array initializer for all supported clock sources of PSRAM
|
||||
*/
|
||||
#define SOC_PSRAM_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_CPLL, SOC_MOD_CLK_SPLL, SOC_MOD_CLK_MPLL}
|
||||
|
||||
/**
|
||||
* @brief Type of PSRAM clock source.
|
||||
*/
|
||||
typedef enum {
|
||||
PSRAM_CLK_SRC_DEFAULT = SOC_MOD_CLK_SPLL, /*!< Select SOC_MOD_CLK_SPLL as PSRAM source clock */
|
||||
PSRAM_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select SOC_MOD_CLK_XTAL as PSRAM source clock */
|
||||
PSRAM_CLK_SRC_CPLL = SOC_MOD_CLK_CPLL, /*!< Select SOC_MOD_CLK_CPLL as PSRAM source clock */
|
||||
PSRAM_CLK_SRC_SPLL = SOC_MOD_CLK_SPLL, /*!< Select SOC_MOD_CLK_SPLL as PSRAM source clock */
|
||||
PSRAM_CLK_SRC_MPLL = SOC_MOD_CLK_MPLL, /*!< Select SOC_MOD_CLK_MPLL as PSRAM source clock */
|
||||
} soc_periph_psram_clk_src_t;
|
||||
|
||||
/////////////////////////////////////////////////FLASH////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* @brief Array initializer for all supported clock sources of FLASH
|
||||
*/
|
||||
#define SOC_FLASH_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_CPLL, SOC_MOD_CLK_SPLL}
|
||||
|
||||
/**
|
||||
* @brief Type of FLASH clock source.
|
||||
*/
|
||||
typedef enum {
|
||||
FLASH_CLK_SRC_DEFAULT = SOC_MOD_CLK_SPLL, /*!< Select SOC_MOD_CLK_SPLL as FLASH source clock */
|
||||
FLASH_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select SOC_MOD_CLK_XTAL as FLASH source clock */
|
||||
FLASH_CLK_SRC_CPLL = SOC_MOD_CLK_CPLL, /*!< Select SOC_MOD_CLK_CPLL as FLASH source clock */
|
||||
FLASH_CLK_SRC_SPLL = SOC_MOD_CLK_SPLL, /*!< Select SOC_MOD_CLK_SPLL as FLASH source clock */
|
||||
} soc_periph_flash_clk_src_t;
|
||||
|
||||
//////////////////////////////////////////////////SDM//////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////GPIO Glitch Filter////////////////////////////////////////////////////
|
||||
|
@ -158,12 +158,9 @@
|
||||
#define SOC_DROM_LOW 0x40000000
|
||||
#define SOC_DROM_HIGH 0x44000000
|
||||
|
||||
#define SOC_SINGLE_BANK_LOW 0x40000000
|
||||
#define SOC_SINGLE_BANK_HIGH 0x44000000
|
||||
#define SOC_EXTRAM_LOW 0x48000000
|
||||
#define SOC_EXTRAM_HIGH 0x4c000000
|
||||
#define SOC_EXT_DBRAM_DATA_LOW 0x4a000000
|
||||
#define SOC_EXT_DBRAM_DATA_HIGH 0x4c000000
|
||||
#define SOC_EXTRAM_SIZE (SOC_EXTRAM_HIGH - SOC_EXTRAM_LOW)
|
||||
|
||||
#define SOC_IROM_MASK_LOW 0x4fc00000
|
||||
#define SOC_IROM_MASK_HIGH 0x4fc20000
|
||||
|
@ -69,7 +69,7 @@
|
||||
// #define SOC_PMU_SUPPORTED 1 //TODO: IDF-7531
|
||||
// #define SOC_PAU_SUPPORTED 1 //TODO: IDF-7531
|
||||
// #define SOC_LP_TIMER_SUPPORTED 1 //TODO: IDF-7532
|
||||
// #define SOC_SPIRAM_SUPPORTED 1 //TODO: IDF-7495
|
||||
#define SOC_SPIRAM_SUPPORTED 1
|
||||
// #define SOC_ULP_SUPPORTED 1 //TODO: IDF-7534
|
||||
// #define SOC_SDMMC_HOST_SUPPORTED 1 //TODO: IDF-6502
|
||||
// #define SOC_CLK_TREE_SUPPORTED 1 //TODO: IDF-7526
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -314,7 +314,49 @@ typedef union {
|
||||
*/
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t reserved_0:30;
|
||||
/** mem_axi_req_en : R/W; bitpos: [0]; default: 0;
|
||||
* For SPI0, AXI master access enable, 1: enable, 0:disable.
|
||||
*/
|
||||
uint32_t mem_axi_req_en:1;
|
||||
/** mem_cache_usr_addr_4byte : R/W; bitpos: [1]; default: 0;
|
||||
* For SPI0, cache read flash with 4 bytes address, 1: enable, 0:disable.
|
||||
*/
|
||||
uint32_t mem_cache_usr_addr_4byte:1;
|
||||
/** mem_cache_flash_usr_cmd : R/W; bitpos: [2]; default: 0;
|
||||
* For SPI0, cache read flash for user define command, 1: enable, 0:disable.
|
||||
*/
|
||||
uint32_t mem_cache_flash_usr_cmd:1;
|
||||
/** mem_fdin_dual : R/W; bitpos: [3]; default: 0;
|
||||
* For SPI0 flash, din phase apply 2 signals. 1: enable 0: disable. The bit is the
|
||||
* same with spi_mem_s_fread_dio.
|
||||
*/
|
||||
uint32_t mem_fdin_dual:1;
|
||||
/** mem_fdout_dual : R/W; bitpos: [4]; default: 0;
|
||||
* For SPI0 flash, dout phase apply 2 signals. 1: enable 0: disable. The bit is the
|
||||
* same with spi_mem_s_fread_dio.
|
||||
*/
|
||||
uint32_t mem_fdout_dual:1;
|
||||
/** mem_faddr_dual : R/W; bitpos: [5]; default: 0;
|
||||
* For SPI0 flash, address phase apply 2 signals. 1: enable 0: disable. The bit is
|
||||
* the same with spi_mem_s_fread_dio.
|
||||
*/
|
||||
uint32_t mem_faddr_dual:1;
|
||||
/** mem_fdin_quad : R/W; bitpos: [6]; default: 0;
|
||||
* For SPI0 flash, din phase apply 4 signals. 1: enable 0: disable. The bit is the
|
||||
* same with spi_mem_s_fread_qio.
|
||||
*/
|
||||
uint32_t mem_fdin_quad:1;
|
||||
/** mem_fdout_quad : R/W; bitpos: [7]; default: 0;
|
||||
* For SPI0 flash, dout phase apply 4 signals. 1: enable 0: disable. The bit is the
|
||||
* same with spi_mem_s_fread_qio.
|
||||
*/
|
||||
uint32_t mem_fdout_quad:1;
|
||||
/** mem_faddr_quad : R/W; bitpos: [8]; default: 0;
|
||||
* For SPI0 flash, address phase apply 4 signals. 1: enable 0: disable. The bit is
|
||||
* the same with spi_mem_s_fread_qio.
|
||||
*/
|
||||
uint32_t mem_faddr_quad:1;
|
||||
uint32_t reserved_9:21;
|
||||
/** same_aw_ar_addr_chk_en : R/W; bitpos: [30]; default: 1;
|
||||
* Set this bit to check AXI read/write the same address region.
|
||||
*/
|
||||
@ -442,6 +484,34 @@ typedef union {
|
||||
uint32_t val;
|
||||
} spi_mem_s_clock_reg_t;
|
||||
|
||||
/** Type of mem_sram_clk register
|
||||
* SPI0 external RAM clock control register
|
||||
*/
|
||||
typedef union {
|
||||
struct {
|
||||
/** mem_sclkcnt_l : R/W; bitpos: [7:0]; default: 3;
|
||||
* For SPI0 external RAM interface, it must be equal to spi_mem_s_clkcnt_N.
|
||||
*/
|
||||
uint32_t mem_sclkcnt_l:8;
|
||||
/** mem_sclkcnt_h : R/W; bitpos: [15:8]; default: 1;
|
||||
* For SPI0 external RAM interface, it must be floor((spi_mem_s_clkcnt_N+1)/2-1).
|
||||
*/
|
||||
uint32_t mem_sclkcnt_h:8;
|
||||
/** mem_sclkcnt_n : R/W; bitpos: [23:16]; default: 3;
|
||||
* For SPI0 external RAM interface, it is the divider of spi_mem_s_clk. So spi_mem_s_clk
|
||||
* frequency is system/(spi_mem_s_clkcnt_N+1)
|
||||
*/
|
||||
uint32_t mem_sclkcnt_n:8;
|
||||
uint32_t reserved_24:7;
|
||||
/** mem_sclk_equ_sysclk : R/W; bitpos: [31]; default: 0;
|
||||
* For SPI0 external RAM interface, 1: spi_mem_s_clk is eqaul to system 0: spi_mem_s_clk
|
||||
* is divided from system clock.
|
||||
*/
|
||||
uint32_t mem_sclk_equ_sysclk:1;
|
||||
};
|
||||
uint32_t val;
|
||||
} spi_mem_s_sram_clk_reg_t;
|
||||
|
||||
/** Type of mem_clock_gate register
|
||||
* SPI0 clock gate register
|
||||
*/
|
||||
@ -533,14 +603,162 @@ typedef union {
|
||||
uint32_t val;
|
||||
} spi_mem_s_user2_reg_t;
|
||||
|
||||
/** Type of mem_rd_status register
|
||||
* SPI0 read control register.
|
||||
*/
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t reserved_0:16;
|
||||
/** mem_wb_mode : R/W; bitpos: [23:16]; default: 0;
|
||||
* Mode bits in the flash fast read mode it is combined with spi_mem_s_fastrd_mode bit.
|
||||
*/
|
||||
uint32_t mem_wb_mode:8;
|
||||
uint32_t reserved_24:8;
|
||||
};
|
||||
uint32_t val;
|
||||
} spi_mem_s_rd_status_reg_t;
|
||||
|
||||
|
||||
/** Group: External RAM Control and configuration registers */
|
||||
/** Type of mem_cache_sctrl register
|
||||
* SPI0 external RAM control register
|
||||
*/
|
||||
typedef union {
|
||||
struct {
|
||||
/** mem_cache_usr_saddr_4byte : R/W; bitpos: [0]; default: 0;
|
||||
* For SPI0, In the external RAM mode, cache read flash with 4 bytes command, 1:
|
||||
* enable, 0:disable.
|
||||
*/
|
||||
uint32_t mem_cache_usr_saddr_4byte:1;
|
||||
/** mem_usr_sram_dio : R/W; bitpos: [1]; default: 0;
|
||||
* For SPI0, In the external RAM mode, spi dual I/O mode enable, 1: enable, 0:disable
|
||||
*/
|
||||
uint32_t mem_usr_sram_dio:1;
|
||||
/** mem_usr_sram_qio : R/W; bitpos: [2]; default: 0;
|
||||
* For SPI0, In the external RAM mode, spi quad I/O mode enable, 1: enable, 0:disable
|
||||
*/
|
||||
uint32_t mem_usr_sram_qio:1;
|
||||
/** mem_usr_wr_sram_dummy : R/W; bitpos: [3]; default: 0;
|
||||
* For SPI0, In the external RAM mode, it is the enable bit of dummy phase for write
|
||||
* operations.
|
||||
*/
|
||||
uint32_t mem_usr_wr_sram_dummy:1;
|
||||
/** mem_usr_rd_sram_dummy : R/W; bitpos: [4]; default: 1;
|
||||
* For SPI0, In the external RAM mode, it is the enable bit of dummy phase for read
|
||||
* operations.
|
||||
*/
|
||||
uint32_t mem_usr_rd_sram_dummy:1;
|
||||
/** mem_cache_sram_usr_rcmd : R/W; bitpos: [5]; default: 1;
|
||||
* For SPI0, In the external RAM mode cache read external RAM for user define command.
|
||||
*/
|
||||
uint32_t mem_cache_sram_usr_rcmd:1;
|
||||
/** mem_sram_rdummy_cyclelen : R/W; bitpos: [11:6]; default: 1;
|
||||
* For SPI0, In the external RAM mode, it is the length in bits of read dummy phase.
|
||||
* The register value shall be (bit_num-1).
|
||||
*/
|
||||
uint32_t mem_sram_rdummy_cyclelen:6;
|
||||
uint32_t reserved_12:2;
|
||||
/** mem_sram_addr_bitlen : R/W; bitpos: [19:14]; default: 23;
|
||||
* For SPI0, In the external RAM mode, it is the length in bits of address phase. The
|
||||
* register value shall be (bit_num-1).
|
||||
*/
|
||||
uint32_t mem_sram_addr_bitlen:6;
|
||||
/** mem_cache_sram_usr_wcmd : R/W; bitpos: [20]; default: 1;
|
||||
* For SPI0, In the external RAM mode cache write sram for user define command
|
||||
*/
|
||||
uint32_t mem_cache_sram_usr_wcmd:1;
|
||||
/** mem_sram_oct : R/W; bitpos: [21]; default: 0;
|
||||
* reserved
|
||||
*/
|
||||
uint32_t mem_sram_oct:1;
|
||||
/** mem_sram_wdummy_cyclelen : R/W; bitpos: [27:22]; default: 1;
|
||||
* For SPI0, In the external RAM mode, it is the length in bits of write dummy phase.
|
||||
* The register value shall be (bit_num-1).
|
||||
*/
|
||||
uint32_t mem_sram_wdummy_cyclelen:6;
|
||||
uint32_t reserved_28:4;
|
||||
};
|
||||
uint32_t val;
|
||||
} spi_mem_s_cache_sctrl_reg_t;
|
||||
|
||||
/** Type of mem_sram_cmd register
|
||||
* SPI0 external RAM mode control register
|
||||
*/
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t reserved_0:24;
|
||||
/** mem_sclk_mode : R/W; bitpos: [1:0]; default: 0;
|
||||
* SPI clock mode bits. 0: SPI clock is off when CS inactive 1: SPI clock is delayed
|
||||
* one cycle after CS inactive 2: SPI clock is delayed two cycles after CS inactive 3:
|
||||
* SPI clock is always on.
|
||||
*/
|
||||
uint32_t mem_sclk_mode:2;
|
||||
/** mem_swb_mode : R/W; bitpos: [9:2]; default: 0;
|
||||
* Mode bits in the external RAM fast read mode it is combined with
|
||||
* spi_mem_s_fastrd_mode bit.
|
||||
*/
|
||||
uint32_t mem_swb_mode:8;
|
||||
/** mem_sdin_dual : R/W; bitpos: [10]; default: 0;
|
||||
* For SPI0 external RAM , din phase apply 2 signals. 1: enable 0: disable. The bit is
|
||||
* the same with spi_mem_s_usr_sram_dio.
|
||||
*/
|
||||
uint32_t mem_sdin_dual:1;
|
||||
/** mem_sdout_dual : R/W; bitpos: [11]; default: 0;
|
||||
* For SPI0 external RAM , dout phase apply 2 signals. 1: enable 0: disable. The bit
|
||||
* is the same with spi_mem_s_usr_sram_dio.
|
||||
*/
|
||||
uint32_t mem_sdout_dual:1;
|
||||
/** mem_saddr_dual : R/W; bitpos: [12]; default: 0;
|
||||
* For SPI0 external RAM , address phase apply 2 signals. 1: enable 0: disable. The
|
||||
* bit is the same with spi_mem_s_usr_sram_dio.
|
||||
*/
|
||||
uint32_t mem_saddr_dual:1;
|
||||
uint32_t reserved_13:1;
|
||||
/** mem_sdin_quad : R/W; bitpos: [14]; default: 0;
|
||||
* For SPI0 external RAM , din phase apply 4 signals. 1: enable 0: disable. The bit is
|
||||
* the same with spi_mem_s_usr_sram_qio.
|
||||
*/
|
||||
uint32_t mem_sdin_quad:1;
|
||||
/** mem_sdout_quad : R/W; bitpos: [15]; default: 0;
|
||||
* For SPI0 external RAM , dout phase apply 4 signals. 1: enable 0: disable. The bit
|
||||
* is the same with spi_mem_s_usr_sram_qio.
|
||||
*/
|
||||
uint32_t mem_sdout_quad:1;
|
||||
/** mem_saddr_quad : R/W; bitpos: [16]; default: 0;
|
||||
* For SPI0 external RAM , address phase apply 4 signals. 1: enable 0: disable. The
|
||||
* bit is the same with spi_mem_s_usr_sram_qio.
|
||||
*/
|
||||
uint32_t mem_saddr_quad:1;
|
||||
/** mem_scmd_quad : R/W; bitpos: [17]; default: 0;
|
||||
* For SPI0 external RAM , cmd phase apply 4 signals. 1: enable 0: disable. The bit is
|
||||
* the same with spi_mem_s_usr_sram_qio.
|
||||
*/
|
||||
uint32_t mem_scmd_quad:1;
|
||||
/** mem_sdin_oct : R/W; bitpos: [18]; default: 0;
|
||||
* For SPI0 external RAM , din phase apply 8 signals. 1: enable 0: disable.
|
||||
*/
|
||||
uint32_t mem_sdin_oct:1;
|
||||
/** mem_sdout_oct : R/W; bitpos: [19]; default: 0;
|
||||
* For SPI0 external RAM , dout phase apply 8 signals. 1: enable 0: disable.
|
||||
*/
|
||||
uint32_t mem_sdout_oct:1;
|
||||
/** mem_saddr_oct : R/W; bitpos: [20]; default: 0;
|
||||
* For SPI0 external RAM , address phase apply 4 signals. 1: enable 0: disable.
|
||||
*/
|
||||
uint32_t mem_saddr_oct:1;
|
||||
/** mem_scmd_oct : R/W; bitpos: [21]; default: 0;
|
||||
* For SPI0 external RAM , cmd phase apply 8 signals. 1: enable 0: disable.
|
||||
*/
|
||||
uint32_t mem_scmd_oct:1;
|
||||
/** mem_sdummy_rin : R/W; bitpos: [22]; default: 1;
|
||||
* In the dummy phase of a MSPI read data transfer when accesses to external RAM, the
|
||||
* signal level of SPI bus is output by the MSPI controller.
|
||||
*/
|
||||
uint32_t mem_sdummy_rin:1;
|
||||
/** mem_sdummy_wout : R/W; bitpos: [23]; default: 1;
|
||||
* In the dummy phase of a MSPI write data transfer when accesses to external RAM, the
|
||||
* signal level of SPI bus is output by the MSPI controller.
|
||||
*/
|
||||
uint32_t mem_sdummy_wout:1;
|
||||
/** smem_wdummy_dqs_always_out : R/W; bitpos: [24]; default: 0;
|
||||
* In the dummy phase of an MSPI write data transfer when accesses to external RAM,
|
||||
* the level of SPI_DQS is output by the MSPI controller.
|
||||
@ -551,7 +769,15 @@ typedef union {
|
||||
* the level of SPI_IO[7:0] is output by the MSPI controller.
|
||||
*/
|
||||
uint32_t smem_wdummy_always_out:1;
|
||||
uint32_t reserved_26:4;
|
||||
/** mem_sdin_hex : R/W; bitpos: [26]; default: 0;
|
||||
* For SPI0 external RAM , din phase apply 16 signals. 1: enable 0: disable.
|
||||
*/
|
||||
uint32_t mem_sdin_hex:1;
|
||||
/** mem_sdout_hex : R/W; bitpos: [27]; default: 0;
|
||||
* For SPI0 external RAM , dout phase apply 16 signals. 1: enable 0: disable.
|
||||
*/
|
||||
uint32_t mem_sdout_hex:1;
|
||||
uint32_t reserved_28:2;
|
||||
/** smem_dqs_ie_always_on : R/W; bitpos: [30]; default: 0;
|
||||
* When accesses to external RAM, 1: the IE signals of pads connected to SPI_DQS are
|
||||
* always 1. 0: Others.
|
||||
@ -566,6 +792,46 @@ typedef union {
|
||||
uint32_t val;
|
||||
} spi_mem_s_sram_cmd_reg_t;
|
||||
|
||||
/** Type of mem_sram_drd_cmd register
|
||||
* SPI0 external RAM DDR read command control register
|
||||
*/
|
||||
typedef union {
|
||||
struct {
|
||||
/** mem_cache_sram_usr_rd_cmd_value : R/W; bitpos: [15:0]; default: 0;
|
||||
* For SPI0,When cache mode is enable it is the read command value of command phase
|
||||
* for sram.
|
||||
*/
|
||||
uint32_t mem_cache_sram_usr_rd_cmd_value:16;
|
||||
uint32_t reserved_16:12;
|
||||
/** mem_cache_sram_usr_rd_cmd_bitlen : R/W; bitpos: [31:28]; default: 0;
|
||||
* For SPI0,When cache mode is enable it is the length in bits of command phase for
|
||||
* sram. The register value shall be (bit_num-1).
|
||||
*/
|
||||
uint32_t mem_cache_sram_usr_rd_cmd_bitlen:4;
|
||||
};
|
||||
uint32_t val;
|
||||
} spi_mem_s_sram_drd_cmd_reg_t;
|
||||
|
||||
/** Type of mem_sram_dwr_cmd register
|
||||
* SPI0 external RAM DDR write command control register
|
||||
*/
|
||||
typedef union {
|
||||
struct {
|
||||
/** mem_cache_sram_usr_wr_cmd_value : R/W; bitpos: [15:0]; default: 0;
|
||||
* For SPI0,When cache mode is enable it is the write command value of command phase
|
||||
* for sram.
|
||||
*/
|
||||
uint32_t mem_cache_sram_usr_wr_cmd_value:16;
|
||||
uint32_t reserved_16:12;
|
||||
/** mem_cache_sram_usr_wr_cmd_bitlen : R/W; bitpos: [31:28]; default: 0;
|
||||
* For SPI0,When cache mode is enable it is the in bits of command phase for sram.
|
||||
* The register value shall be (bit_num-1).
|
||||
*/
|
||||
uint32_t mem_cache_sram_usr_wr_cmd_bitlen:4;
|
||||
};
|
||||
uint32_t val;
|
||||
} spi_mem_s_sram_dwr_cmd_reg_t;
|
||||
|
||||
/** Type of smem_ddr register
|
||||
* SPI0 external RAM DDR mode control register
|
||||
*/
|
||||
@ -969,106 +1235,106 @@ typedef union {
|
||||
|
||||
/** Group: PMS control and configuration registers */
|
||||
/** Type of fmem_pmsn_attr register
|
||||
* MSPI flash PMS section n attribute register
|
||||
* MSPI flash PMS section $n attribute register
|
||||
*/
|
||||
typedef union {
|
||||
struct {
|
||||
/** fmem_pmsn_rd_attr : R/W; bitpos: [0]; default: 1;
|
||||
* 1: SPI1 flash PMS section n read accessible. 0: Not allowed.
|
||||
/** fmem_pms_rd_attr : R/W; bitpos: [0]; default: 1;
|
||||
* 1: SPI1 flash PMS section $n read accessible. 0: Not allowed.
|
||||
*/
|
||||
uint32_t fmem_pmsn_rd_attr:1;
|
||||
/** fmem_pmsn_wr_attr : R/W; bitpos: [1]; default: 1;
|
||||
* 1: SPI1 flash PMS section n write accessible. 0: Not allowed.
|
||||
uint32_t fmem_pms_rd_attr:1;
|
||||
/** fmem_pms_wr_attr : R/W; bitpos: [1]; default: 1;
|
||||
* 1: SPI1 flash PMS section $n write accessible. 0: Not allowed.
|
||||
*/
|
||||
uint32_t fmem_pmsn_wr_attr:1;
|
||||
/** fmem_pmsn_ecc : R/W; bitpos: [2]; default: 0;
|
||||
* SPI1 flash PMS section n ECC mode, 1: enable ECC mode. 0: Disable it. The flash PMS
|
||||
* section n is configured by registers SPI_MEM_S_FMEM_PMSn_ADDR_REG and
|
||||
* SPI_MEM_S_FMEM_PMSn_SIZE_REG.
|
||||
uint32_t fmem_pms_wr_attr:1;
|
||||
/** fmem_pms_ecc : R/W; bitpos: [2]; default: 0;
|
||||
* SPI1 flash PMS section $n ECC mode, 1: enable ECC mode. 0: Disable it. The flash
|
||||
* PMS section $n is configured by registers SPI_MEM_S_FMEM_PMS$n_ADDR_REG and
|
||||
* SPI_MEM_S_FMEM_PMS$n_SIZE_REG.
|
||||
*/
|
||||
uint32_t fmem_pmsn_ecc:1;
|
||||
uint32_t fmem_pms_ecc:1;
|
||||
uint32_t reserved_3:29;
|
||||
};
|
||||
uint32_t val;
|
||||
} spi_mem_s_fmem_pmsn_attr_reg_t;
|
||||
|
||||
/** Type of fmem_pmsn_addr register
|
||||
* SPI1 flash PMS section n start address register
|
||||
* SPI1 flash PMS section $n start address register
|
||||
*/
|
||||
typedef union {
|
||||
struct {
|
||||
/** fmem_pmsn_addr_s : R/W; bitpos: [26:0]; default: 0;
|
||||
* SPI1 flash PMS section n start address value
|
||||
/** fmem_pms_addr_s : R/W; bitpos: [26:0]; default: 0;
|
||||
* SPI1 flash PMS section $n start address value
|
||||
*/
|
||||
uint32_t fmem_pmsn_addr_s:27;
|
||||
uint32_t fmem_pms_addr_s:27;
|
||||
uint32_t reserved_27:5;
|
||||
};
|
||||
uint32_t val;
|
||||
} spi_mem_s_fmem_pmsn_addr_reg_t;
|
||||
|
||||
/** Type of fmem_pmsn_size register
|
||||
* SPI1 flash PMS section n start address register
|
||||
* SPI1 flash PMS section $n start address register
|
||||
*/
|
||||
typedef union {
|
||||
struct {
|
||||
/** fmem_pmsn_size : R/W; bitpos: [14:0]; default: 4096;
|
||||
* SPI1 flash PMS section n address region is (SPI_MEM_S_FMEM_PMSn_ADDR_S,
|
||||
* SPI_MEM_S_FMEM_PMSn_ADDR_S + SPI_MEM_S_FMEM_PMSn_SIZE)
|
||||
/** fmem_pms_size : R/W; bitpos: [14:0]; default: 4096;
|
||||
* SPI1 flash PMS section $n address region is (SPI_MEM_S_FMEM_PMS$n_ADDR_S,
|
||||
* SPI_MEM_S_FMEM_PMS$n_ADDR_S + SPI_MEM_S_FMEM_PMS$n_SIZE)
|
||||
*/
|
||||
uint32_t fmem_pmsn_size:15;
|
||||
uint32_t fmem_pms_size:15;
|
||||
uint32_t reserved_15:17;
|
||||
};
|
||||
uint32_t val;
|
||||
} spi_mem_s_fmem_pmsn_size_reg_t;
|
||||
|
||||
/** Type of smem_pmsn_attr register
|
||||
* SPI1 flash PMS section n start address register
|
||||
* SPI1 flash PMS section $n start address register
|
||||
*/
|
||||
typedef union {
|
||||
struct {
|
||||
/** smem_pmsn_rd_attr : R/W; bitpos: [0]; default: 1;
|
||||
* 1: SPI1 external RAM PMS section n read accessible. 0: Not allowed.
|
||||
/** smem_pms_rd_attr : R/W; bitpos: [0]; default: 1;
|
||||
* 1: SPI1 external RAM PMS section $n read accessible. 0: Not allowed.
|
||||
*/
|
||||
uint32_t smem_pmsn_rd_attr:1;
|
||||
/** smem_pmsn_wr_attr : R/W; bitpos: [1]; default: 1;
|
||||
* 1: SPI1 external RAM PMS section n write accessible. 0: Not allowed.
|
||||
uint32_t smem_pms_rd_attr:1;
|
||||
/** smem_pms_wr_attr : R/W; bitpos: [1]; default: 1;
|
||||
* 1: SPI1 external RAM PMS section $n write accessible. 0: Not allowed.
|
||||
*/
|
||||
uint32_t smem_pmsn_wr_attr:1;
|
||||
/** smem_pmsn_ecc : R/W; bitpos: [2]; default: 0;
|
||||
* SPI1 external RAM PMS section n ECC mode, 1: enable ECC mode. 0: Disable it. The
|
||||
* external RAM PMS section n is configured by registers SPI_MEM_S_SMEM_PMSn_ADDR_REG and
|
||||
* SPI_MEM_S_SMEM_PMSn_SIZE_REG.
|
||||
uint32_t smem_pms_wr_attr:1;
|
||||
/** smem_pms_ecc : R/W; bitpos: [2]; default: 0;
|
||||
* SPI1 external RAM PMS section $n ECC mode, 1: enable ECC mode. 0: Disable it. The
|
||||
* external RAM PMS section $n is configured by registers SPI_MEM_S_SMEM_PMS$n_ADDR_REG and
|
||||
* SPI_MEM_S_SMEM_PMS$n_SIZE_REG.
|
||||
*/
|
||||
uint32_t smem_pmsn_ecc:1;
|
||||
uint32_t smem_pms_ecc:1;
|
||||
uint32_t reserved_3:29;
|
||||
};
|
||||
uint32_t val;
|
||||
} spi_mem_s_smem_pmsn_attr_reg_t;
|
||||
|
||||
/** Type of smem_pmsn_addr register
|
||||
* SPI1 external RAM PMS section n start address register
|
||||
* SPI1 external RAM PMS section $n start address register
|
||||
*/
|
||||
typedef union {
|
||||
struct {
|
||||
/** smem_pmsn_addr_s : R/W; bitpos: [26:0]; default: 0;
|
||||
* SPI1 external RAM PMS section n start address value
|
||||
/** smem_pms_addr_s : R/W; bitpos: [26:0]; default: 0;
|
||||
* SPI1 external RAM PMS section $n start address value
|
||||
*/
|
||||
uint32_t smem_pmsn_addr_s:27;
|
||||
uint32_t smem_pms_addr_s:27;
|
||||
uint32_t reserved_27:5;
|
||||
};
|
||||
uint32_t val;
|
||||
} spi_mem_s_smem_pmsn_addr_reg_t;
|
||||
|
||||
/** Type of smem_pmsn_size register
|
||||
* SPI1 external RAM PMS section n start address register
|
||||
* SPI1 external RAM PMS section $n start address register
|
||||
*/
|
||||
typedef union {
|
||||
struct {
|
||||
/** smem_pmsn_size : R/W; bitpos: [14:0]; default: 4096;
|
||||
* SPI1 external RAM PMS section n address region is (SPI_MEM_S_SMEM_PMSn_ADDR_S,
|
||||
* SPI_MEM_S_SMEM_PMSn_ADDR_S + SPI_MEM_S_SMEM_PMSn_SIZE)
|
||||
/** smem_pms_size : R/W; bitpos: [14:0]; default: 4096;
|
||||
* SPI1 external RAM PMS section $n address region is (SPI_MEM_S_SMEM_PMS$n_ADDR_S,
|
||||
* SPI_MEM_S_SMEM_PMS$n_ADDR_S + SPI_MEM_S_SMEM_PMS$n_SIZE)
|
||||
*/
|
||||
uint32_t smem_pmsn_size:15;
|
||||
uint32_t smem_pms_size:15;
|
||||
uint32_t reserved_15:17;
|
||||
};
|
||||
uint32_t val;
|
||||
@ -2160,7 +2426,14 @@ typedef union {
|
||||
* MMU PSRAM aux control register
|
||||
*/
|
||||
uint32_t mem_aux_ctrl:14;
|
||||
uint32_t reserved_30:2;
|
||||
/** mem_rdn_ena : R/W; bitpos: [30]; default: 0;
|
||||
* ECO register enable bit
|
||||
*/
|
||||
uint32_t mem_rdn_ena:1;
|
||||
/** mem_rdn_result : RO; bitpos: [31]; default: 0;
|
||||
* MSPI module clock domain and AXI clock domain ECO register result register
|
||||
*/
|
||||
uint32_t mem_rdn_result:1;
|
||||
};
|
||||
uint32_t val;
|
||||
} spi_mem_s_mmu_power_ctrl_reg_t;
|
||||
@ -2195,6 +2468,34 @@ typedef union {
|
||||
} spi_mem_s_dpa_ctrl_reg_t;
|
||||
|
||||
|
||||
/** Group: ECO registers */
|
||||
/** Type of mem_registerrnd_eco_high register
|
||||
* MSPI ECO high register
|
||||
*/
|
||||
typedef union {
|
||||
struct {
|
||||
/** mem_registerrnd_eco_high : R/W; bitpos: [31:0]; default: 892;
|
||||
* ECO high register
|
||||
*/
|
||||
uint32_t mem_registerrnd_eco_high:32;
|
||||
};
|
||||
uint32_t val;
|
||||
} spi_mem_s_registerrnd_eco_high_reg_t;
|
||||
|
||||
/** Type of mem_registerrnd_eco_low register
|
||||
* MSPI ECO low register
|
||||
*/
|
||||
typedef union {
|
||||
struct {
|
||||
/** mem_registerrnd_eco_low : R/W; bitpos: [31:0]; default: 892;
|
||||
* ECO low register
|
||||
*/
|
||||
uint32_t mem_registerrnd_eco_low:32;
|
||||
};
|
||||
uint32_t val;
|
||||
} spi_mem_s_registerrnd_eco_low_reg_t;
|
||||
|
||||
|
||||
/** Group: Version control register */
|
||||
/** Type of mem_date register
|
||||
* SPI0 version control register
|
||||
@ -2211,7 +2512,7 @@ typedef union {
|
||||
} spi_mem_s_date_reg_t;
|
||||
|
||||
|
||||
typedef struct spi_mem_s_dev_s {
|
||||
typedef struct spi_mem_s_dev_t {
|
||||
volatile spi_mem_s_cmd_reg_t mem_cmd;
|
||||
uint32_t reserved_004;
|
||||
volatile spi_mem_s_ctrl_reg_t mem_ctrl;
|
||||
@ -2221,13 +2522,17 @@ typedef struct spi_mem_s_dev_s {
|
||||
volatile spi_mem_s_user_reg_t mem_user;
|
||||
volatile spi_mem_s_user1_reg_t mem_user1;
|
||||
volatile spi_mem_s_user2_reg_t mem_user2;
|
||||
uint32_t reserved_024[4];
|
||||
uint32_t reserved_024[2];
|
||||
volatile spi_mem_s_rd_status_reg_t mem_rd_status;
|
||||
uint32_t reserved_030;
|
||||
volatile spi_mem_s_misc_reg_t mem_misc;
|
||||
uint32_t reserved_038;
|
||||
volatile spi_mem_s_cache_fctrl_reg_t mem_cache_fctrl;
|
||||
uint32_t reserved_040;
|
||||
volatile spi_mem_s_cache_sctrl_reg_t mem_cache_sctrl;
|
||||
volatile spi_mem_s_sram_cmd_reg_t mem_sram_cmd;
|
||||
uint32_t reserved_048[3];
|
||||
volatile spi_mem_s_sram_drd_cmd_reg_t mem_sram_drd_cmd;
|
||||
volatile spi_mem_s_sram_dwr_cmd_reg_t mem_sram_dwr_cmd;
|
||||
volatile spi_mem_s_sram_clk_reg_t mem_sram_clk;
|
||||
volatile spi_mem_s_fsm_reg_t mem_fsm;
|
||||
uint32_t reserved_058[26];
|
||||
volatile spi_mem_s_int_ena_reg_t mem_int_ena;
|
||||
@ -2282,10 +2587,14 @@ typedef struct spi_mem_s_dev_s {
|
||||
volatile spi_mem_s_mmu_item_index_reg_t mem_mmu_item_index;
|
||||
volatile spi_mem_s_mmu_power_ctrl_reg_t mem_mmu_power_ctrl;
|
||||
volatile spi_mem_s_dpa_ctrl_reg_t mem_dpa_ctrl;
|
||||
uint32_t reserved_38c[28];
|
||||
uint32_t reserved_38c[25];
|
||||
volatile spi_mem_s_registerrnd_eco_high_reg_t mem_registerrnd_eco_high;
|
||||
volatile spi_mem_s_registerrnd_eco_low_reg_t mem_registerrnd_eco_low;
|
||||
uint32_t reserved_3f8;
|
||||
volatile spi_mem_s_date_reg_t mem_date;
|
||||
} spi_mem_s_dev_t;
|
||||
|
||||
extern spi_mem_s_dev_t SPIMEM2;
|
||||
|
||||
#ifndef __cplusplus
|
||||
_Static_assert(sizeof(spi_mem_s_dev_t) == 0x400, "Invalid size of spi_mem_s_dev_t structure");
|
||||
|
@ -12,6 +12,8 @@ PROVIDE ( UART3 = 0x500CD000 );
|
||||
PROVIDE ( UART4 = 0x500CE000 );
|
||||
PROVIDE ( SPIMEM0 = 0x5008C000 );
|
||||
PROVIDE ( SPIMEM1 = 0x5008D000 );
|
||||
PROVIDE ( SPIMEM2 = 0x5008E000 );
|
||||
PROVIDE ( SPIMEM3 = 0x5008F000 );
|
||||
PROVIDE ( I2C0 = 0x500C4000 );
|
||||
PROVIDE ( I2C1 = 0x500C5000 );
|
||||
PROVIDE ( UHCI0 = 0x500DF000 );
|
||||
|
@ -31,3 +31,9 @@ components/spi_flash/test_apps/mspi_test:
|
||||
disable:
|
||||
- if: CONFIG_NAME == "psram" and SOC_SPIRAM_SUPPORTED != 1
|
||||
- if: CONFIG_NAME == "xip_psram" and SOC_SPIRAM_SUPPORTED != 1
|
||||
- if: CONFIG_NAME == "psram" and IDF_TARGET in ["esp32p4"]
|
||||
temporary: true
|
||||
reason: not supported yet #TODO: IDF-7499 for p4
|
||||
- if: CONFIG_NAME == "xip_psram" and IDF_TARGET in ["esp32p4"]
|
||||
temporary: true
|
||||
reason: not supported yet #TODO: IDF-7556 for p4
|
||||
|
@ -254,3 +254,6 @@ examples/system/xip_from_psram:
|
||||
disable:
|
||||
- if: IDF_TARGET == "esp32"
|
||||
reason: target esp32 doesn't support this feature.
|
||||
- if: IDF_TARGET == "esp32p4"
|
||||
temporary: true
|
||||
reason: not supported on p4 #TODO: IDF-7556
|
||||
|
Loading…
Reference in New Issue
Block a user