mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
psram: put opiram_psram and spiram_psram in internal ram
External memory is accessed via SPI0. When modifying the SPI0 registers, should put the code in internal RAM. Otherwise when there is an ongoing SPI0 transaction, CPU changes the SPI0 registers. This is dangerous. Besides, modifying SPI0 registers may lead external memory to an unstable state. Therefore putting these code in internal RAM is necessary.
This commit is contained in:
parent
7ff9332243
commit
16a91399f1
@ -11,3 +11,8 @@ entries:
|
|||||||
rtc_time (noflash_text)
|
rtc_time (noflash_text)
|
||||||
if IDF_TARGET_ESP32C3 = n && IDF_TARGET_ESP32H2 = n:
|
if IDF_TARGET_ESP32C3 = n && IDF_TARGET_ESP32H2 = n:
|
||||||
rtc_wdt (noflash_text)
|
rtc_wdt (noflash_text)
|
||||||
|
if IDF_TARGET_ESP32S3 = y:
|
||||||
|
if SPIRAM_MODE_QUAD = y:
|
||||||
|
spiram_psram (noflash)
|
||||||
|
if SPIRAM_MODE_OCT = y:
|
||||||
|
opiram_psram (noflash)
|
||||||
|
@ -99,10 +99,10 @@ typedef struct {
|
|||||||
} opi_psram_mode_reg_t;
|
} opi_psram_mode_reg_t;
|
||||||
|
|
||||||
static const char* TAG = "opi psram";
|
static const char* TAG = "opi psram";
|
||||||
static DRAM_ATTR psram_size_t s_psram_size;
|
static psram_size_t s_psram_size;
|
||||||
static void IRAM_ATTR s_config_psram_spi_phases(void);
|
static void s_config_psram_spi_phases(void);
|
||||||
|
|
||||||
uint8_t IRAM_ATTR psram_get_cs_io(void)
|
uint8_t psram_get_cs_io(void)
|
||||||
{
|
{
|
||||||
return OCT_PSRAM_CS1_IO;
|
return OCT_PSRAM_CS1_IO;
|
||||||
}
|
}
|
||||||
@ -110,7 +110,7 @@ uint8_t IRAM_ATTR psram_get_cs_io(void)
|
|||||||
/**
|
/**
|
||||||
* Initialise mode registers of the PSRAM
|
* Initialise mode registers of the PSRAM
|
||||||
*/
|
*/
|
||||||
static void IRAM_ATTR s_init_psram_mode_reg(int spi_num, opi_psram_mode_reg_t *mode_reg_config)
|
static void s_init_psram_mode_reg(int spi_num, opi_psram_mode_reg_t *mode_reg_config)
|
||||||
{
|
{
|
||||||
esp_rom_spiflash_read_mode_t mode = ESP_ROM_SPIFLASH_OPI_DTR_MODE;
|
esp_rom_spiflash_read_mode_t mode = ESP_ROM_SPIFLASH_OPI_DTR_MODE;
|
||||||
int cmd_len = 16;
|
int cmd_len = 16;
|
||||||
@ -145,7 +145,7 @@ static void IRAM_ATTR s_init_psram_mode_reg(int spi_num, opi_psram_mode_reg_t *m
|
|||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void IRAM_ATTR s_get_psram_mode_reg(int spi_num, opi_psram_mode_reg_t *out_reg)
|
static void s_get_psram_mode_reg(int spi_num, opi_psram_mode_reg_t *out_reg)
|
||||||
{
|
{
|
||||||
esp_rom_spiflash_read_mode_t mode = ESP_ROM_SPIFLASH_OPI_DTR_MODE;
|
esp_rom_spiflash_read_mode_t mode = ESP_ROM_SPIFLASH_OPI_DTR_MODE;
|
||||||
int cmd_len = 16;
|
int cmd_len = 16;
|
||||||
@ -192,7 +192,7 @@ static void IRAM_ATTR s_get_psram_mode_reg(int spi_num, opi_psram_mode_reg_t *ou
|
|||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void IRAM_ATTR s_print_psram_info(opi_psram_mode_reg_t *reg_val)
|
static void s_print_psram_info(opi_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, "vendor id : 0x%02x (%s)", reg_val->mr1.vendor_id, reg_val->mr1.vendor_id == 0x0d ? "AP" : "UNKNOWN");
|
||||||
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, "dev id : 0x%02x (generation %d)", reg_val->mr2.dev_id, reg_val->mr2.dev_id + 1);
|
||||||
@ -215,7 +215,7 @@ static void IRAM_ATTR s_print_psram_info(opi_psram_mode_reg_t *reg_val)
|
|||||||
reg_val->mr0.drive_str == 0x02 ? 4 : 8);
|
reg_val->mr0.drive_str == 0x02 ? 4 : 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void IRAM_ATTR psram_set_cs_timing(void)
|
static void psram_set_cs_timing(void)
|
||||||
{
|
{
|
||||||
//SPI0/1 share the cs_hold / cs_setup, cd_hold_time / cd_setup_time, cs_hold_delay registers for PSRAM, so we only need to set SPI0 related registers here
|
//SPI0/1 share the cs_hold / cs_setup, cd_hold_time / cd_setup_time, cs_hold_delay registers for PSRAM, so we only need to set SPI0 related registers here
|
||||||
SET_PERI_REG_MASK(SPI_MEM_SPI_SMEM_AC_REG(0), SPI_MEM_SPI_SMEM_CS_HOLD_M | SPI_MEM_SPI_SMEM_CS_SETUP_M);
|
SET_PERI_REG_MASK(SPI_MEM_SPI_SMEM_AC_REG(0), SPI_MEM_SPI_SMEM_CS_HOLD_M | SPI_MEM_SPI_SMEM_CS_SETUP_M);
|
||||||
@ -225,7 +225,7 @@ static void IRAM_ATTR psram_set_cs_timing(void)
|
|||||||
SET_PERI_REG_BITS(SPI_MEM_SPI_SMEM_AC_REG(0), SPI_MEM_SPI_SMEM_CS_HOLD_DELAY_V, OCT_PSRAM_CS_HOLD_DELAY, SPI_MEM_SPI_SMEM_CS_HOLD_DELAY_S);
|
SET_PERI_REG_BITS(SPI_MEM_SPI_SMEM_AC_REG(0), SPI_MEM_SPI_SMEM_CS_HOLD_DELAY_V, OCT_PSRAM_CS_HOLD_DELAY, SPI_MEM_SPI_SMEM_CS_HOLD_DELAY_S);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void IRAM_ATTR s_init_psram_pins(void)
|
static void s_init_psram_pins(void)
|
||||||
{
|
{
|
||||||
//Set cs1 pin function
|
//Set cs1 pin function
|
||||||
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[OCT_PSRAM_CS1_IO], FUNC_SPICS1_SPICS1);
|
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[OCT_PSRAM_CS1_IO], FUNC_SPICS1_SPICS1);
|
||||||
@ -235,7 +235,7 @@ static void IRAM_ATTR s_init_psram_pins(void)
|
|||||||
REG_SET_FIELD(SPI_MEM_DATE_REG(0), SPI_MEM_SPI_SMEM_SPICLK_FUN_DRV, 3);
|
REG_SET_FIELD(SPI_MEM_DATE_REG(0), SPI_MEM_SPI_SMEM_SPICLK_FUN_DRV, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vaddrmode)
|
esp_err_t psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vaddrmode)
|
||||||
{
|
{
|
||||||
s_init_psram_pins();
|
s_init_psram_pins();
|
||||||
psram_set_cs_timing();
|
psram_set_cs_timing();
|
||||||
@ -248,7 +248,7 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad
|
|||||||
esp_rom_spi_set_dtr_swap_mode(1, false, false);
|
esp_rom_spi_set_dtr_swap_mode(1, false, false);
|
||||||
|
|
||||||
//Set PSRAM read latency and drive strength
|
//Set PSRAM read latency and drive strength
|
||||||
static DRAM_ATTR opi_psram_mode_reg_t mode_reg = {0};
|
static opi_psram_mode_reg_t mode_reg = {0};
|
||||||
mode_reg.mr0.lt = 1;
|
mode_reg.mr0.lt = 1;
|
||||||
mode_reg.mr0.read_latency = 2;
|
mode_reg.mr0.read_latency = 2;
|
||||||
mode_reg.mr0.drive_str = 0;
|
mode_reg.mr0.drive_str = 0;
|
||||||
@ -279,7 +279,7 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Configure PSRAM SPI0 phase related registers here according to the PSRAM chip requirement
|
//Configure PSRAM SPI0 phase related registers here according to the PSRAM chip requirement
|
||||||
static void IRAM_ATTR s_config_psram_spi_phases(void)
|
static void s_config_psram_spi_phases(void)
|
||||||
{
|
{
|
||||||
//Config Write CMD phase for SPI0 to access PSRAM
|
//Config Write CMD phase for SPI0 to access PSRAM
|
||||||
SET_PERI_REG_MASK(SPI_MEM_CACHE_SCTRL_REG(0), SPI_MEM_CACHE_SRAM_USR_WCMD_M);
|
SET_PERI_REG_MASK(SPI_MEM_CACHE_SCTRL_REG(0), SPI_MEM_CACHE_SRAM_USR_WCMD_M);
|
||||||
|
@ -118,7 +118,7 @@ typedef enum {
|
|||||||
typedef esp_rom_spi_cmd_t psram_cmd_t;
|
typedef esp_rom_spi_cmd_t psram_cmd_t;
|
||||||
|
|
||||||
static uint32_t s_psram_id = 0;
|
static uint32_t s_psram_id = 0;
|
||||||
static void IRAM_ATTR config_psram_spi_phases(void);
|
static void config_psram_spi_phases(void);
|
||||||
extern void esp_rom_spi_set_op_mode(int spi_num, esp_rom_spiflash_read_mode_t mode);
|
extern void esp_rom_spi_set_op_mode(int spi_num, esp_rom_spiflash_read_mode_t mode);
|
||||||
|
|
||||||
static uint8_t s_psram_cs_io = (uint8_t)-1;
|
static uint8_t s_psram_cs_io = (uint8_t)-1;
|
||||||
@ -278,7 +278,7 @@ static void psram_read_id(int spi_num, uint32_t* dev_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//enter QPI mode
|
//enter QPI mode
|
||||||
static void IRAM_ATTR psram_enable_qio_mode(int spi_num)
|
static void psram_enable_qio_mode(int spi_num)
|
||||||
{
|
{
|
||||||
psram_exec_cmd(spi_num, PSRAM_CMD_SPI,
|
psram_exec_cmd(spi_num, PSRAM_CMD_SPI,
|
||||||
PSRAM_ENTER_QMODE, 8, /* command and command bit len*/
|
PSRAM_ENTER_QMODE, 8, /* command and command bit len*/
|
||||||
@ -290,7 +290,7 @@ static void IRAM_ATTR psram_enable_qio_mode(int spi_num)
|
|||||||
false); /* whether is program/erase operation */
|
false); /* whether is program/erase operation */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void IRAM_ATTR psram_set_cs_timing(void)
|
static void psram_set_cs_timing(void)
|
||||||
{
|
{
|
||||||
//SPI0/1 share the cs_hold / cs_setup, cd_hold_time / cd_setup_time registers for PSRAM, so we only need to set SPI0 related registers here
|
//SPI0/1 share the cs_hold / cs_setup, cd_hold_time / cd_setup_time registers for PSRAM, so we only need to set SPI0 related registers here
|
||||||
SET_PERI_REG_BITS(SPI_MEM_SPI_SMEM_AC_REG(0), SPI_MEM_SPI_SMEM_CS_HOLD_TIME_V, 0, SPI_MEM_SPI_SMEM_CS_HOLD_TIME_S);
|
SET_PERI_REG_BITS(SPI_MEM_SPI_SMEM_AC_REG(0), SPI_MEM_SPI_SMEM_CS_HOLD_TIME_V, 0, SPI_MEM_SPI_SMEM_CS_HOLD_TIME_S);
|
||||||
@ -298,7 +298,7 @@ static void IRAM_ATTR psram_set_cs_timing(void)
|
|||||||
SET_PERI_REG_MASK(SPI_MEM_SPI_SMEM_AC_REG(0), SPI_MEM_SPI_SMEM_CS_HOLD_M | SPI_MEM_SPI_SMEM_CS_SETUP_M);
|
SET_PERI_REG_MASK(SPI_MEM_SPI_SMEM_AC_REG(0), SPI_MEM_SPI_SMEM_CS_HOLD_M | SPI_MEM_SPI_SMEM_CS_SETUP_M);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void IRAM_ATTR psram_gpio_config(void)
|
static void psram_gpio_config(void)
|
||||||
{
|
{
|
||||||
//CS1
|
//CS1
|
||||||
uint8_t cs1_io = PSRAM_CS_IO;
|
uint8_t cs1_io = PSRAM_CS_IO;
|
||||||
@ -341,7 +341,7 @@ psram_size_t psram_get_size(void)
|
|||||||
* Psram mode init will overwrite original flash speed mode, so that it is possible to change psram and flash speed after OTA.
|
* 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.
|
* 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 psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vaddrmode) //psram init
|
esp_err_t psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vaddrmode) //psram init
|
||||||
{
|
{
|
||||||
assert(mode < PSRAM_CACHE_MAX && "we don't support any other mode for now.");
|
assert(mode < PSRAM_CACHE_MAX && "we don't support any other mode for now.");
|
||||||
|
|
||||||
@ -383,7 +383,7 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Configure PSRAM SPI0 phase related registers here according to the PSRAM chip requirement
|
//Configure PSRAM SPI0 phase related registers here according to the PSRAM chip requirement
|
||||||
static void IRAM_ATTR config_psram_spi_phases(void)
|
static void config_psram_spi_phases(void)
|
||||||
{
|
{
|
||||||
//Config CMD phase
|
//Config CMD phase
|
||||||
CLEAR_PERI_REG_MASK(SPI_MEM_CACHE_SCTRL_REG(0), SPI_MEM_USR_SRAM_DIO_M); //disable dio mode for cache command
|
CLEAR_PERI_REG_MASK(SPI_MEM_CACHE_SCTRL_REG(0), SPI_MEM_USR_SRAM_DIO_M); //disable dio mode for cache command
|
||||||
|
Loading…
Reference in New Issue
Block a user