const PSRAM_VADDR: u32 = 0x3F800000;
pub fn psram_vaddr_start() -> usize {
PSRAM_VADDR_START
}
cfg_if::cfg_if! {
if #[cfg(feature = "psram-2m")] {
const PSRAM_SIZE: u32 = 2;
} else if #[cfg(feature = "psram-4m")] {
const PSRAM_SIZE: u32 = 4;
} else if #[cfg(feature = "psram-8m")] {
const PSRAM_SIZE: u32 = 8;
} else {
const PSRAM_SIZE: u32 = 0;
}
}
pub const PSRAM_BYTES: usize = PSRAM_SIZE as usize * 1024 * 1024;
pub const PSRAM_VADDR_START: usize = PSRAM_VADDR as usize;
#[cfg(any(feature = "psram-2m", feature = "psram-4m", feature = "psram-8m"))]
pub fn init_psram(_peripheral: impl crate::peripheral::Peripheral<P = crate::peripherals::PSRAM>) {
utils::psram_init();
utils::s_mapping(PSRAM_VADDR, PSRAM_BYTES as u32);
}
#[cfg(any(feature = "psram-2m", feature = "psram-4m", feature = "psram-8m"))]
pub(crate) mod utils {
use core::ptr::addr_of_mut;
use procmacros::ram;
pub(crate) fn s_mapping(v_start: u32, size: u32) {
cache_sram_mmu_set(0, 0, v_start, 0, 32, size / 1024 / 32);
unsafe {
let dport = &*esp32::DPORT::PTR;
dport
.app_cache_ctrl1()
.modify(|_, w| w.app_cache_mask_dram1().clear_bit());
}
cache_sram_mmu_set(1, 0, v_start, 0, 32, size / 1024 / 32);
}
fn cache_sram_mmu_set(
cpu_no: u32,
pid: u32,
vaddr: u32,
paddr: u32,
psize: u32,
num: u32,
) -> i32 {
unsafe { cache_sram_mmu_set_rom(cpu_no, pid, vaddr, paddr, psize, num) }
}
const D0WD_PSRAM_CLK_IO: u8 = 17;
const D0WD_PSRAM_CS_IO: u8 = 16;
const D2WD_PSRAM_CLK_IO: u8 = 9; const D2WD_PSRAM_CS_IO: u8 = 10;
const PICO_PSRAM_CLK_IO: u8 = 6;
const PICO_PSRAM_CS_IO: u8 = 10;
const ESP_ROM_EFUSE_FLASH_DEFAULT_SPI: u32 = 0;
const ESP_ROM_EFUSE_FLASH_DEFAULT_HSPI: u32 = 1;
const SPI_IOMUX_PIN_NUM_CLK: u8 = 6;
const SPI_IOMUX_PIN_NUM_CS: u8 = 11;
const PSRAM_SPIQ_SD0_IO: u8 = 7;
const PSRAM_SPID_SD1_IO: u8 = 8;
const PSRAM_SPIWP_SD3_IO: u8 = 10;
const PSRAM_SPIHD_SD2_IO: u8 = 9;
const FLASH_HSPI_CLK_IO: u8 = 14;
const FLASH_HSPI_CS_IO: u8 = 15;
const PSRAM_HSPI_SPIQ_SD0_IO: u8 = 12;
const PSRAM_HSPI_SPID_SD1_IO: u8 = 13;
const PSRAM_HSPI_SPIWP_SD3_IO: u8 = 2;
const PSRAM_HSPI_SPIHD_SD2_IO: u8 = 4;
const DR_REG_SPI1_BASE: u32 = 0x3ff42000;
const SPI1_USER_REG: u32 = DR_REG_SPI1_BASE + 0x1C;
const SPI1_SLAVE_REG: u32 = DR_REG_SPI1_BASE + 0x038;
const SPI1_PIN_REG: u32 = DR_REG_SPI1_BASE + 0x34;
const SPI1_CTRL_REG: u32 = DR_REG_SPI1_BASE + 0x8;
const SPI1_USER1_REG: u32 = DR_REG_SPI1_BASE + 0x20;
const SPI1_W0_REG: u32 = DR_REG_SPI1_BASE + 0x80;
const SPI1_CTRL2_REG: u32 = DR_REG_SPI1_BASE + 0x14;
const SPI1_CMD_REG: u32 = DR_REG_SPI1_BASE + 0x0;
const SPI1_USER2_REG: u32 = DR_REG_SPI1_BASE + 0x24;
const SPI1_MOSI_DLEN_REG: u32 = DR_REG_SPI1_BASE + 0x28;
const SPI1_MISO_DLEN_REG: u32 = DR_REG_SPI1_BASE + 0x2C;
const SPI1_ADDR_REG: u32 = DR_REG_SPI1_BASE + 0x4;
const DR_REG_SPI0_BASE: u32 = 0x3ff43000;
const SPI0_EXT2_REG: u32 = DR_REG_SPI0_BASE + 0xf8;
const SPI0_EXT3_REG: u32 = DR_REG_SPI0_BASE + 0xfc;
const SPI0_USER_REG: u32 = DR_REG_SPI0_BASE + 0x1C;
const SPI0_PIN_REG: u32 = DR_REG_SPI0_BASE + 0x34;
const SPI0_CTRL_REG: u32 = DR_REG_SPI0_BASE + 0x8;
const SPI0_USER1_REG: u32 = DR_REG_SPI0_BASE + 0x20;
const SPI0_CTRL2_REG: u32 = DR_REG_SPI0_BASE + 0x14;
const SPI0_DATE_REG: u32 = DR_REG_SPI0_BASE + 0x3FC;
const SPI0_CLOCK_REG: u32 = DR_REG_SPI0_BASE + 0x18;
const SPI0_CACHE_SCTRL_REG: u32 = DR_REG_SPI0_BASE + 0x54;
const SPI0_SRAM_DRD_CMD_REG: u32 = DR_REG_SPI0_BASE + 0x5C;
const SPI0_SRAM_DWR_CMD_REG: u32 = DR_REG_SPI0_BASE + 0x60;
const SPI_USR_PREP_HOLD_M: u32 = 1 << 23;
const SPI_TRANS_DONE: u32 = 1 << 4;
const SPI_CK_IDLE_EDGE: u32 = 1 << 29;
const SPI_CK_OUT_EDGE: u32 = 1 << 7;
const SPI_WR_BIT_ORDER: u32 = 1 << 26;
const SPI_RD_BIT_ORDER: u32 = 1 << 25;
const SPI_DOUTDIN: u32 = 1 << 0;
const SPI_SLAVE_MODE: u32 = 1 << 30;
const SPI_CS_HOLD_M: u32 = 1 << 4;
const SPI_CS_SETUP_M: u32 = 1 << 5;
const SPI_HOLD_TIME_V: u32 = 0xF;
const fn psram_cs_hold_time_from_psram_speed(speed: PsramCacheSpeed) -> u32 {
match speed {
PsramCacheSpeed::PsramCacheF80mS40m => 0,
PsramCacheSpeed::PsramCacheF40mS40m => 0,
PsramCacheSpeed::PsramCacheF80mS80m => 1,
}
}
const SPI_HOLD_TIME_S: u32 = 4;
const SPI_SETUP_TIME_V: u32 = 0xF;
const SPI_SETUP_TIME_S: u32 = 0;
const SPI_USR_DUMMY: u32 = 1 << 29;
const PSRAM_INTERNAL_IO_28: u32 = 28;
const PSRAM_INTERNAL_IO_29: u32 = 29;
const SIG_GPIO_OUT_IDX: u32 = 256;
const SPICLK_OUT_IDX: u32 = 0;
const SIG_IN_FUNC224_IDX: u32 = 224;
const SIG_IN_FUNC225_IDX: u32 = 225;
const SPICS0_OUT_IDX: u32 = 5;
const SPICS1_OUT_IDX: u32 = 6;
const SPIQ_OUT_IDX: u32 = 1;
const SPIQ_IN_IDX: u32 = 1;
const SPID_OUT_IDX: u32 = 2;
const SPID_IN_IDX: u32 = 2;
const SPIWP_OUT_IDX: u32 = 4;
const SPIWP_IN_IDX: u32 = 4;
const SPIHD_OUT_IDX: u32 = 3;
const SPIHD_IN_IDX: u32 = 3;
const FUNC_SD_CLK_SPICLK: u32 = 1;
const PIN_FUNC_GPIO: u32 = 2;
const FUN_DRV_V: u32 = 0x3;
const FUN_DRV_S: u32 = 10;
const FUN_DRV: u32 = 0x3;
const SPI_CLK_EQU_SYSCLK_M: u32 = 1 << 31;
const SPI_CLKDIV_PRE_V: u32 = 0x1FFF;
const SPI_CLKDIV_PRE_S: u32 = 18;
const SPI_CLKCNT_N: u32 = 0x0000003F;
const SPI_CLKCNT_N_S: u32 = 12;
const SPI_CLKCNT_H: u32 = 0x0000003F;
const SPI_CLKCNT_H_S: u32 = 6;
const SPI_CLKCNT_L: u32 = 0x0000003F;
const SPI_CLKCNT_L_S: u32 = 0;
const SPI_USR_SRAM_DIO_M: u32 = 1 << 1;
const SPI_USR_SRAM_QIO_M: u32 = 1 << 2;
const SPI_CACHE_SRAM_USR_RCMD_M: u32 = 1 << 5;
const SPI_CACHE_SRAM_USR_WCMD_M: u32 = 1 << 28;
const SPI_SRAM_ADDR_BITLEN_V: u32 = 0x3F;
const SPI_USR_RD_SRAM_DUMMY_M: u32 = 1 << 4;
const SPI_CACHE_SRAM_USR_RD_CMD_BITLEN_V: u32 = 0xF;
const SPI_CACHE_SRAM_USR_RD_CMD_BITLEN_S: u32 = 28;
const SPI_CACHE_SRAM_USR_RD_CMD_VALUE_V: u32 = 0xFFFF;
const SPI_CACHE_SRAM_USR_RD_CMD_VALUE_S: u32 = 0;
const SPI_CACHE_SRAM_USR_WR_CMD_BITLEN: u32 = 0x0000000F;
const SPI_CACHE_SRAM_USR_WR_CMD_BITLEN_S: u32 = 28;
const SPI_CACHE_SRAM_USR_WR_CMD_VALUE: u32 = 0x0000FFFF;
const PSRAM_QUAD_WRITE: u32 = 0x38;
const SPI_CACHE_SRAM_USR_WR_CMD_VALUE_S: u32 = 0;
const SPI_SRAM_DUMMY_CYCLELEN_V: u32 = 0xFF;
const PSRAM_FAST_READ_QUAD_DUMMY: u32 = 0x5;
const SPI_SRAM_DUMMY_CYCLELEN_S: u32 = 14;
const SPI_SRAM_ADDR_BITLEN_S: u32 = 22;
const PSRAM_FAST_READ_QUAD: u32 = 0xEB;
const SPI_USR: u32 = 1 << 18;
const SPI_USR_COMMAND_BITLEN: u32 = 0x0000000F;
const SPI_USR_COMMAND_BITLEN_S: u32 = 28;
const SPI_USR_COMMAND: u32 = 1 << 31;
const SPI_USR_COMMAND_VALUE: u32 = 0x0000FFFF;
const SPI_USR_COMMAND_VALUE_S: u32 = 0;
const SPI_USR_ADDR_BITLEN: u32 = 0x0000003F;
const SPI_USR_ADDR: u32 = 1 << 30;
const SPI_USR_MOSI: u32 = 1 << 27;
const SPI_USR_MISO_DBITLEN: u32 = 0x00FFFFFF;
const SPI_USR_MOSI_DBITLEN: u32 = 0x00FFFFFF;
const SPI_USR_MOSI_DBITLEN_S: u32 = 0;
const SPI_USR_MISO_DBITLEN_S: u32 = 0;
const SPI_USR_MISO: u32 = 1 << 28;
const SPI_FWRITE_DUAL_S: u32 = 12;
const SPI_FWRITE_DUAL_M: u32 = 1 << 12;
const SPI_CS1_DIS_M: u32 = 1 << 1;
const SPI_CS0_DIS_M: u32 = 1 << 0;
const SPI_FWRITE_QIO: u32 = 1 << 15;
const SPI_FWRITE_DIO: u32 = 1 << 14;
const SPI_FWRITE_QUAD: u32 = 1 << 13;
const SPI_FWRITE_DUAL: u32 = 1 << 12;
const SPI_FREAD_QIO: u32 = 1 << 24;
const SPI_FREAD_QUAD: u32 = 1 << 20;
const SPI_FREAD_DUAL: u32 = 1 << 14;
const SPI_FREAD_DIO: u32 = 1 << 23;
const SPI_FREAD_QIO_M: u32 = 1 << 24;
const SPI0_R_QIO_DUMMY_CYCLELEN: u32 = 3;
const SPI_FREAD_DIO_M: u32 = 1 << 23;
const SPI0_R_DIO_DUMMY_CYCLELEN: u32 = 1;
const SPI_USR_ADDR_BITLEN_V: u32 = 0x3F;
const SPI0_R_DIO_ADDR_BITSLEN: u32 = 27;
const SPI_USR_ADDR_BITLEN_S: u32 = 26;
const SPI_FREAD_QUAD_M: u32 = 1 << 20;
const SPI_FREAD_DUAL_M: u32 = 1 << 14;
const SPI0_R_FAST_DUMMY_CYCLELEN: u32 = 7;
const PSRAM_IO_MATRIX_DUMMY_40M: u8 = 1;
const PSRAM_IO_MATRIX_DUMMY_80M: u8 = 2;
const _SPI_CACHE_PORT: u8 = 0;
const _SPI_FLASH_PORT: u8 = 1;
const SPI_USR_DUMMY_CYCLELEN_V: u32 = 0xFF;
const SPI_USR_DUMMY_CYCLELEN_S: u32 = 0;
const _SPI_80M_CLK_DIV: u8 = 1;
const _SPI_40M_CLK_DIV: u8 = 2;
const FLASH_ID_GD25LQ32C: u32 = 0xC86016;
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
#[allow(unused)]
enum PsramCacheSpeed {
PsramCacheF80mS40m = 0,
PsramCacheF40mS40m,
PsramCacheF80mS80m,
}
#[derive(PartialEq, Eq, Debug, Default)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
struct PsramIo {
flash_clk_io: u8,
flash_cs_io: u8,
psram_clk_io: u8,
psram_cs_io: u8,
psram_spiq_sd0_io: u8,
psram_spid_sd1_io: u8,
psram_spiwp_sd3_io: u8,
psram_spihd_sd2_io: u8,
}
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
enum PsramClkMode {
PsramClkModeNorm = 0, PsramClkModeDclk = 1, }
#[repr(C)]
struct EspRomSpiflashChip {
device_id: u32,
chip_size: u32, block_size: u32,
sector_size: u32,
page_size: u32,
status_mask: u32,
}
extern "C" {
fn esp_rom_efuse_get_flash_gpio_info() -> u32;
fn esp_rom_gpio_connect_out_signal(
gpio_num: u32,
signal_idx: u32,
out_inv: bool,
oen_inv: bool,
);
fn esp_rom_gpio_connect_in_signal(gpio_num: u32, signal_idx: u32, inv: bool);
fn esp_rom_spiflash_config_clk(freqdiv: u8, spi: u8) -> i32;
static mut g_rom_spiflash_dummy_len_plus: u8;
static g_rom_flashchip: EspRomSpiflashChip;
fn cache_sram_mmu_set_rom(
cpu_no: u32,
pid: u32,
vaddr: u32,
paddr: u32,
psize: u32,
num: u32,
) -> i32;
}
pub(crate) fn psram_init() {
let chip = crate::efuse::Efuse::get_chip_type();
let mode = PsramCacheSpeed::PsramCacheF40mS40m; let mut psram_io = PsramIo::default();
let clk_mode;
match chip {
crate::efuse::ChipType::Esp32D0wdq6 | crate::efuse::ChipType::Esp32D0wdq5 => {
clk_mode = PsramClkMode::PsramClkModeNorm;
psram_io.psram_clk_io = D0WD_PSRAM_CLK_IO;
psram_io.psram_cs_io = D0WD_PSRAM_CS_IO;
}
crate::efuse::ChipType::Esp32D2wdq5 => {
clk_mode = PsramClkMode::PsramClkModeDclk;
psram_io.psram_clk_io = D2WD_PSRAM_CLK_IO;
psram_io.psram_cs_io = D2WD_PSRAM_CS_IO;
}
crate::efuse::ChipType::Esp32Picod2 => {
clk_mode = PsramClkMode::PsramClkModeNorm;
psram_io.psram_clk_io = PICO_PSRAM_CLK_IO;
psram_io.psram_cs_io = PICO_PSRAM_CS_IO;
}
crate::efuse::ChipType::Esp32Picod4 => {
panic!("PSRAM is unsupported on this chip");
}
crate::efuse::ChipType::Unknown => {
panic!("Unknown chip type. PSRAM is not supported");
}
}
let spiconfig = unsafe { esp_rom_efuse_get_flash_gpio_info() };
if spiconfig == ESP_ROM_EFUSE_FLASH_DEFAULT_SPI {
psram_io.flash_clk_io = SPI_IOMUX_PIN_NUM_CLK;
psram_io.flash_cs_io = SPI_IOMUX_PIN_NUM_CS;
psram_io.psram_spiq_sd0_io = PSRAM_SPIQ_SD0_IO;
psram_io.psram_spid_sd1_io = PSRAM_SPID_SD1_IO;
psram_io.psram_spiwp_sd3_io = PSRAM_SPIWP_SD3_IO;
psram_io.psram_spihd_sd2_io = PSRAM_SPIHD_SD2_IO;
} else if spiconfig == ESP_ROM_EFUSE_FLASH_DEFAULT_HSPI {
psram_io.flash_clk_io = FLASH_HSPI_CLK_IO;
psram_io.flash_cs_io = FLASH_HSPI_CS_IO;
psram_io.psram_spiq_sd0_io = PSRAM_HSPI_SPIQ_SD0_IO;
psram_io.psram_spid_sd1_io = PSRAM_HSPI_SPID_SD1_IO;
psram_io.psram_spiwp_sd3_io = PSRAM_HSPI_SPIWP_SD3_IO;
psram_io.psram_spihd_sd2_io = PSRAM_HSPI_SPIHD_SD2_IO;
} else {
panic!("Getting Flash/PSRAM pins from efuse is not supported");
}
info!("PS-RAM pins {:?}", &psram_io);
write_peri_reg(SPI0_EXT3_REG, 0x1);
clear_peri_reg_mask(SPI1_USER_REG, SPI_USR_PREP_HOLD_M);
psram_spi_init(mode, clk_mode);
match mode {
PsramCacheSpeed::PsramCacheF80mS80m => unsafe {
esp_rom_gpio_connect_out_signal(
psram_io.psram_clk_io as u32,
SPICLK_OUT_IDX,
false,
false,
);
},
_ => unsafe {
if clk_mode == PsramClkMode::PsramClkModeDclk {
esp_rom_gpio_connect_out_signal(
PSRAM_INTERNAL_IO_28,
SPICLK_OUT_IDX,
false,
false,
);
esp_rom_gpio_connect_in_signal(PSRAM_INTERNAL_IO_28, SIG_IN_FUNC224_IDX, false);
esp_rom_gpio_connect_out_signal(
PSRAM_INTERNAL_IO_29,
SIG_IN_FUNC224_IDX,
false,
false,
);
esp_rom_gpio_connect_in_signal(PSRAM_INTERNAL_IO_29, SIG_IN_FUNC225_IDX, false);
esp_rom_gpio_connect_out_signal(
psram_io.psram_clk_io as u32,
SIG_IN_FUNC225_IDX,
false,
false,
);
} else {
esp_rom_gpio_connect_out_signal(
psram_io.psram_clk_io as u32,
SPICLK_OUT_IDX,
false,
false,
);
}
},
}
let extra_dummy = psram_gpio_config(&psram_io, mode);
unsafe {
esp_rom_gpio_connect_out_signal(PSRAM_INTERNAL_IO_28, SIG_GPIO_OUT_IDX, false, false);
esp_rom_gpio_connect_out_signal(PSRAM_INTERNAL_IO_29, SIG_GPIO_OUT_IDX, false, false);
esp_rom_gpio_connect_out_signal(
psram_io.psram_clk_io as u32,
SPICLK_OUT_IDX,
false,
false,
);
}
psram_set_cs_timing_spi1(mode, clk_mode);
psram_set_cs_timing_spi0(mode, clk_mode); psram_enable_qio_mode_spi1(clk_mode, mode);
info!(
"PS-RAM vaddrmode = {:?}",
PsramVaddrMode::PsramVaddrModeLowhigh
);
psram_cache_init(
mode,
PsramVaddrMode::PsramVaddrModeLowhigh,
clk_mode,
extra_dummy,
);
}
#[allow(unused)]
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
enum PsramVaddrMode {
PsramVaddrModeNormal = 0,
PsramVaddrModeLowhigh,
PsramVaddrModeEvenodd,
}
fn psram_cache_init(
psram_cache_mode: PsramCacheSpeed,
vaddrmode: PsramVaddrMode,
clk_mode: PsramClkMode,
extra_dummy: u32,
) {
info!(
"PS-RAM cache_init, psram_cache_mode={:?}, extra_dummy={}, clk_mode={:?}",
psram_cache_mode, extra_dummy, clk_mode
);
match psram_cache_mode {
PsramCacheSpeed::PsramCacheF80mS80m => {
clear_peri_reg_mask(SPI0_DATE_REG, 1 << 31);
clear_peri_reg_mask(SPI0_DATE_REG, 1 << 30);
}
PsramCacheSpeed::PsramCacheF80mS40m => {
clear_peri_reg_mask(SPI0_CLOCK_REG, SPI_CLK_EQU_SYSCLK_M);
set_peri_reg_bits(SPI0_CLOCK_REG, SPI_CLKDIV_PRE_V, 0, SPI_CLKDIV_PRE_S);
set_peri_reg_bits(SPI0_CLOCK_REG, SPI_CLKCNT_N, 1, SPI_CLKCNT_N_S);
set_peri_reg_bits(SPI0_CLOCK_REG, SPI_CLKCNT_H, 0, SPI_CLKCNT_H_S);
set_peri_reg_bits(SPI0_CLOCK_REG, SPI_CLKCNT_L, 1, SPI_CLKCNT_L_S);
set_peri_reg_mask(SPI0_DATE_REG, 1 << 31);
clear_peri_reg_mask(SPI0_DATE_REG, 1 << 30);
}
_ => {
clear_peri_reg_mask(SPI0_DATE_REG, 1 << 31); clear_peri_reg_mask(SPI0_DATE_REG, 1 << 30); }
}
clear_peri_reg_mask(SPI0_CACHE_SCTRL_REG, SPI_USR_SRAM_DIO_M); set_peri_reg_mask(SPI0_CACHE_SCTRL_REG, SPI_USR_SRAM_QIO_M); set_peri_reg_mask(SPI0_CACHE_SCTRL_REG, SPI_CACHE_SRAM_USR_RCMD_M); set_peri_reg_mask(SPI0_CACHE_SCTRL_REG, SPI_CACHE_SRAM_USR_WCMD_M); set_peri_reg_bits(
SPI0_CACHE_SCTRL_REG,
SPI_SRAM_ADDR_BITLEN_V,
23,
SPI_SRAM_ADDR_BITLEN_S,
); set_peri_reg_mask(SPI0_CACHE_SCTRL_REG, SPI_USR_RD_SRAM_DUMMY_M);
set_peri_reg_bits(
SPI0_SRAM_DRD_CMD_REG,
SPI_CACHE_SRAM_USR_RD_CMD_BITLEN_V,
7,
SPI_CACHE_SRAM_USR_RD_CMD_BITLEN_S,
);
set_peri_reg_bits(
SPI0_SRAM_DRD_CMD_REG,
SPI_CACHE_SRAM_USR_RD_CMD_VALUE_V,
PSRAM_FAST_READ_QUAD,
SPI_CACHE_SRAM_USR_RD_CMD_VALUE_S,
); set_peri_reg_bits(
SPI0_SRAM_DWR_CMD_REG,
SPI_CACHE_SRAM_USR_WR_CMD_BITLEN,
7,
SPI_CACHE_SRAM_USR_WR_CMD_BITLEN_S,
);
set_peri_reg_bits(
SPI0_SRAM_DWR_CMD_REG,
SPI_CACHE_SRAM_USR_WR_CMD_VALUE,
PSRAM_QUAD_WRITE,
SPI_CACHE_SRAM_USR_WR_CMD_VALUE_S,
); set_peri_reg_bits(
SPI0_CACHE_SCTRL_REG,
SPI_SRAM_DUMMY_CYCLELEN_V,
PSRAM_FAST_READ_QUAD_DUMMY + extra_dummy,
SPI_SRAM_DUMMY_CYCLELEN_S,
);
match psram_cache_mode {
PsramCacheSpeed::PsramCacheF80mS80m => (), _ => {
if clk_mode == PsramClkMode::PsramClkModeDclk {
set_peri_reg_bits(
SPI0_SRAM_DRD_CMD_REG,
SPI_CACHE_SRAM_USR_RD_CMD_BITLEN_V,
15,
SPI_CACHE_SRAM_USR_RD_CMD_BITLEN_S,
); set_peri_reg_bits(
SPI0_SRAM_DRD_CMD_REG,
SPI_CACHE_SRAM_USR_RD_CMD_VALUE_V,
(PSRAM_FAST_READ_QUAD) << 8,
SPI_CACHE_SRAM_USR_RD_CMD_VALUE_S,
); set_peri_reg_bits(
SPI0_SRAM_DWR_CMD_REG,
SPI_CACHE_SRAM_USR_WR_CMD_BITLEN,
15,
SPI_CACHE_SRAM_USR_WR_CMD_BITLEN_S,
); set_peri_reg_bits(
SPI0_SRAM_DWR_CMD_REG,
SPI_CACHE_SRAM_USR_WR_CMD_VALUE,
(PSRAM_QUAD_WRITE) << 8,
SPI_CACHE_SRAM_USR_WR_CMD_VALUE_S,
); set_peri_reg_bits(
SPI0_CACHE_SCTRL_REG,
SPI_SRAM_DUMMY_CYCLELEN_V,
PSRAM_FAST_READ_QUAD_DUMMY + extra_dummy,
SPI_SRAM_DUMMY_CYCLELEN_S,
); }
}
}
unsafe {
let dport = &*esp32::DPORT::PTR;
dport
.pro_cache_ctrl()
.modify(|_, w| w.pro_dram_hl().clear_bit().pro_dram_split().clear_bit());
dport
.app_cache_ctrl()
.modify(|_, w| w.app_dram_hl().clear_bit().app_dram_split().clear_bit());
if vaddrmode == PsramVaddrMode::PsramVaddrModeLowhigh {
dport
.pro_cache_ctrl()
.modify(|_, w| w.pro_dram_hl().set_bit());
dport
.app_cache_ctrl()
.modify(|_, w| w.app_dram_hl().set_bit());
} else if vaddrmode == PsramVaddrMode::PsramVaddrModeEvenodd {
dport
.pro_cache_ctrl()
.modify(|_, w| w.pro_dram_split().set_bit());
dport
.app_cache_ctrl()
.modify(|_, w| w.app_dram_split().set_bit());
}
dport.pro_cache_ctrl1().modify(|_, w| {
w.pro_cache_mask_dram1()
.clear_bit()
.pro_cache_mask_opsdram()
.clear_bit()
});
dport
.pro_cache_ctrl1()
.modify(|_, w| w.pro_cmmu_sram_page_mode().variant(0));
dport.app_cache_ctrl1().modify(|_, w| {
w.app_cache_mask_dram1()
.clear_bit()
.app_cache_mask_opsdram()
.clear_bit()
});
dport
.app_cache_ctrl1()
.modify(|_, w| w.app_cmmu_sram_page_mode().variant(0));
}
clear_peri_reg_mask(SPI0_PIN_REG, SPI_CS1_DIS_M);
}
fn psram_spi_init(
mode: PsramCacheSpeed,
clk_mode: PsramClkMode,
) {
clear_peri_reg_mask(SPI1_SLAVE_REG, SPI_TRANS_DONE << 5);
clear_peri_reg_mask(SPI1_PIN_REG, SPI_CK_IDLE_EDGE);
clear_peri_reg_mask(SPI1_USER_REG, SPI_CK_OUT_EDGE);
clear_peri_reg_mask(SPI1_CTRL_REG, SPI_WR_BIT_ORDER);
clear_peri_reg_mask(SPI1_CTRL_REG, SPI_RD_BIT_ORDER);
clear_peri_reg_mask(SPI1_USER_REG, SPI_DOUTDIN);
write_peri_reg(SPI1_USER1_REG, 0);
clear_peri_reg_mask(SPI1_SLAVE_REG, SPI_SLAVE_MODE);
unsafe {
let ptr = SPI1_W0_REG as *mut u32;
for i in 0..16 {
ptr.offset(i).write_volatile(0);
}
}
psram_set_cs_timing_spi1(mode, clk_mode);
}
fn psram_set_cs_timing_spi1(psram_cache_mode: PsramCacheSpeed, clk_mode: PsramClkMode) {
if clk_mode == PsramClkMode::PsramClkModeNorm {
set_peri_reg_mask(SPI1_USER_REG, SPI_CS_HOLD_M | SPI_CS_SETUP_M);
set_peri_reg_bits(
SPI1_CTRL2_REG,
SPI_HOLD_TIME_V,
psram_cs_hold_time_from_psram_speed(psram_cache_mode),
SPI_HOLD_TIME_S,
);
set_peri_reg_bits(SPI1_CTRL2_REG, SPI_SETUP_TIME_V, 0, SPI_SETUP_TIME_S);
} else {
clear_peri_reg_mask(SPI1_USER_REG, SPI_CS_HOLD_M | SPI_CS_SETUP_M);
}
}
fn psram_set_cs_timing_spi0(psram_cache_mode: PsramCacheSpeed, clk_mode: PsramClkMode) {
if clk_mode == PsramClkMode::PsramClkModeNorm {
set_peri_reg_mask(SPI0_USER_REG, SPI_CS_HOLD_M | SPI_CS_SETUP_M);
set_peri_reg_bits(
SPI0_CTRL2_REG,
SPI_HOLD_TIME_V,
psram_cs_hold_time_from_psram_speed(psram_cache_mode),
SPI_HOLD_TIME_S,
);
set_peri_reg_bits(SPI0_CTRL2_REG, SPI_SETUP_TIME_V, 0, SPI_SETUP_TIME_S);
} else {
clear_peri_reg_mask(SPI0_USER_REG, SPI_CS_HOLD_M | SPI_CS_SETUP_M);
}
}
#[derive(Debug, Copy, Clone, PartialEq)]
struct PsramCmd {
cmd: u16, cmd_bit_len: u16, addr: *const u32, addr_bit_len: u16, tx_data: *const u32, tx_data_bit_len: u16, rx_data: *mut u32, rx_data_bit_len: u16, dummy_bit_len: u32,
}
impl Default for PsramCmd {
fn default() -> Self {
Self {
cmd: Default::default(),
cmd_bit_len: Default::default(),
addr: core::ptr::null(),
addr_bit_len: Default::default(),
tx_data: core::ptr::null(),
tx_data_bit_len: Default::default(),
rx_data: core::ptr::null_mut(),
rx_data_bit_len: Default::default(),
dummy_bit_len: Default::default(),
}
}
}
const PSRAM_ENTER_QMODE: u32 = 0x35;
#[ram]
fn psram_enable_qio_mode_spi1(clk_mode: PsramClkMode, psram_mode: PsramCacheSpeed) {
let mut ps_cmd: PsramCmd = PsramCmd::default();
let addr: u32 = (PSRAM_ENTER_QMODE << 24) | 0;
ps_cmd.cmd_bit_len = 0;
if clk_mode == PsramClkMode::PsramClkModeDclk {
match psram_mode {
PsramCacheSpeed::PsramCacheF80mS80m => (),
_ => {
ps_cmd.cmd_bit_len = 2;
}
}
}
ps_cmd.cmd = 0;
ps_cmd.addr = &addr;
ps_cmd.addr_bit_len = 8;
ps_cmd.tx_data = core::ptr::null();
ps_cmd.tx_data_bit_len = 0;
ps_cmd.rx_data = core::ptr::null_mut();
ps_cmd.rx_data_bit_len = 0;
ps_cmd.dummy_bit_len = 0;
let (backup_usr, backup_usr1, backup_usr2) = psram_cmd_config_spi1(&ps_cmd);
psram_cmd_recv_start_spi1(core::ptr::null_mut(), 0, PsramCmdMode::PsramCmdSpi);
psram_cmd_end_spi1(backup_usr, backup_usr1, backup_usr2);
}
#[ram]
fn psram_cmd_end_spi1(backup_usr: u32, backup_usr1: u32, backup_usr2: u32) {
loop {
if read_peri_reg(SPI1_CMD_REG) & SPI_USR == 0 {
break;
}
}
write_peri_reg(SPI1_USER_REG, backup_usr);
write_peri_reg(SPI1_USER1_REG, backup_usr1);
write_peri_reg(SPI1_USER2_REG, backup_usr2);
}
#[ram]
fn psram_cmd_config_spi1(p_in_data: &PsramCmd) -> (u32, u32, u32) {
loop {
if read_peri_reg(SPI1_CMD_REG) & SPI_USR == 0 {
break;
}
}
let backup_usr = read_peri_reg(SPI1_USER_REG);
let backup_usr1 = read_peri_reg(SPI1_USER1_REG);
let backup_usr2 = read_peri_reg(SPI1_USER2_REG);
if p_in_data.cmd_bit_len != 0 {
set_peri_reg_bits(
SPI1_USER2_REG,
SPI_USR_COMMAND_BITLEN,
(p_in_data.cmd_bit_len - 1) as u32,
SPI_USR_COMMAND_BITLEN_S,
);
set_peri_reg_mask(SPI1_USER_REG, SPI_USR_COMMAND);
set_peri_reg_bits(
SPI1_USER2_REG,
SPI_USR_COMMAND_VALUE,
p_in_data.cmd as u32,
SPI_USR_COMMAND_VALUE_S,
);
} else {
clear_peri_reg_mask(SPI1_USER_REG, SPI_USR_COMMAND);
set_peri_reg_bits(
SPI1_USER2_REG,
SPI_USR_COMMAND_BITLEN,
0,
SPI_USR_COMMAND_BITLEN_S,
);
}
if p_in_data.addr_bit_len != 0 {
set_peri_reg_bits(
SPI1_USER1_REG,
SPI_USR_ADDR_BITLEN,
(p_in_data.addr_bit_len - 1) as u32,
SPI_USR_ADDR_BITLEN_S,
);
set_peri_reg_mask(SPI1_USER_REG, SPI_USR_ADDR);
write_peri_reg(SPI1_ADDR_REG, unsafe { p_in_data.addr.read_volatile() });
} else {
clear_peri_reg_mask(SPI1_USER_REG, SPI_USR_ADDR);
set_peri_reg_bits(
SPI1_USER1_REG,
SPI_USR_ADDR_BITLEN,
0,
SPI_USR_ADDR_BITLEN_S,
);
}
let p_tx_val = p_in_data.tx_data;
if p_in_data.tx_data_bit_len != 0 {
clear_peri_reg_mask(SPI1_USER_REG, SPI_USR_MOSI);
let len = (p_in_data.tx_data_bit_len + 31) / 32;
if !p_tx_val.is_null() {
for i in 0..len {
write_peri_reg(SPI1_W0_REG, unsafe {
p_tx_val.offset(i as isize).read_volatile()
});
}
}
set_peri_reg_bits(
SPI1_MOSI_DLEN_REG,
SPI_USR_MOSI_DBITLEN,
(p_in_data.tx_data_bit_len - 1) as u32,
SPI_USR_MOSI_DBITLEN_S,
);
} else {
clear_peri_reg_mask(SPI1_USER_REG, SPI_USR_MOSI);
set_peri_reg_bits(
SPI1_MOSI_DLEN_REG,
SPI_USR_MOSI_DBITLEN,
0,
SPI_USR_MOSI_DBITLEN_S,
);
}
if p_in_data.rx_data_bit_len != 0 {
set_peri_reg_mask(SPI1_USER_REG, SPI_USR_MISO);
set_peri_reg_bits(
SPI1_MISO_DLEN_REG,
SPI_USR_MISO_DBITLEN,
(p_in_data.rx_data_bit_len - 1) as u32,
SPI_USR_MISO_DBITLEN_S,
);
} else {
clear_peri_reg_mask(SPI1_USER_REG, SPI_USR_MISO);
set_peri_reg_bits(
SPI1_MISO_DLEN_REG,
SPI_USR_MISO_DBITLEN,
0,
SPI_USR_MISO_DBITLEN_S,
);
}
if p_in_data.dummy_bit_len != 0 {
set_peri_reg_mask(SPI1_USER_REG, SPI_USR_DUMMY); set_peri_reg_bits(
SPI1_USER1_REG,
SPI_USR_DUMMY_CYCLELEN_V,
p_in_data.dummy_bit_len - 1,
SPI_USR_DUMMY_CYCLELEN_S,
); } else {
clear_peri_reg_mask(SPI1_USER_REG, SPI_USR_DUMMY); set_peri_reg_bits(
SPI1_USER1_REG,
SPI_USR_DUMMY_CYCLELEN_V,
0,
SPI_USR_DUMMY_CYCLELEN_S,
); }
(backup_usr, backup_usr1, backup_usr2)
}
#[derive(Debug, Clone, Copy, PartialEq)]
enum PsramCmdMode {
PsramCmdQpi,
PsramCmdSpi,
}
#[ram]
fn psram_cmd_recv_start_spi1(p_rx_data: *mut u32, rx_byte_len: u16, cmd_mode: PsramCmdMode) {
clear_peri_reg_mask(SPI1_PIN_REG, SPI_CS1_DIS_M);
set_peri_reg_mask(SPI1_PIN_REG, SPI_CS0_DIS_M);
let mode_backup: u32 = (read_peri_reg(SPI1_USER_REG) >> SPI_FWRITE_DUAL_S) & 0xf;
let rd_mode_backup: u32 = read_peri_reg(SPI1_CTRL_REG)
& (SPI_FREAD_DIO_M | SPI_FREAD_DUAL_M | SPI_FREAD_QUAD_M | SPI_FREAD_QIO_M);
if cmd_mode == PsramCmdMode::PsramCmdSpi {
psram_set_basic_write_mode_spi1();
psram_set_basic_read_mode_spi1();
} else if cmd_mode == PsramCmdMode::PsramCmdQpi {
psram_set_qio_write_mode_spi1();
psram_set_qio_read_mode_spi1();
}
loop {
if read_peri_reg(SPI0_EXT2_REG) == 0 {
break;
}
}
unsafe {
let dport = &*esp32::DPORT::PTR;
dport
.host_inf_sel()
.modify(|r, w| w.bits(r.bits() | 1 << 14));
}
set_peri_reg_mask(SPI1_CMD_REG, SPI_USR);
loop {
if read_peri_reg(SPI1_CMD_REG) & SPI_USR == 0 {
break;
}
}
unsafe {
let dport = &*esp32::DPORT::PTR;
dport
.host_inf_sel()
.modify(|r, w| w.bits(r.bits() & !(1 << 14)));
}
set_peri_reg_bits(
SPI1_USER_REG,
if !p_rx_data.is_null() {
SPI_FWRITE_DUAL_M
} else {
0xf
},
mode_backup,
SPI_FWRITE_DUAL_S,
);
clear_peri_reg_mask(
SPI1_CTRL_REG,
SPI_FREAD_DIO_M | SPI_FREAD_DUAL_M | SPI_FREAD_QUAD_M | SPI_FREAD_QIO_M,
);
set_peri_reg_mask(SPI1_CTRL_REG, rd_mode_backup);
set_peri_reg_mask(SPI1_PIN_REG, SPI_CS1_DIS_M);
clear_peri_reg_mask(SPI1_PIN_REG, SPI_CS0_DIS_M);
if !p_rx_data.is_null() {
let mut idx = 0;
loop {
unsafe {
p_rx_data
.offset(idx)
.write_volatile(read_peri_reg(SPI1_W0_REG + ((idx as u32) << 2)));
}
idx += 1;
if idx > ((rx_byte_len / 4) + if (rx_byte_len % 4) != 0 { 1 } else { 0 }) as isize {
break;
}
}
}
}
fn psram_set_basic_write_mode_spi1() {
clear_peri_reg_mask(SPI1_USER_REG, SPI_FWRITE_QIO);
clear_peri_reg_mask(SPI1_USER_REG, SPI_FWRITE_DIO);
clear_peri_reg_mask(SPI1_USER_REG, SPI_FWRITE_QUAD);
clear_peri_reg_mask(SPI1_USER_REG, SPI_FWRITE_DUAL);
}
fn psram_set_qio_write_mode_spi1() {
set_peri_reg_mask(SPI1_USER_REG, SPI_FWRITE_QIO);
clear_peri_reg_mask(SPI1_USER_REG, SPI_FWRITE_DIO);
clear_peri_reg_mask(SPI1_USER_REG, SPI_FWRITE_QUAD);
clear_peri_reg_mask(SPI1_USER_REG, SPI_FWRITE_DUAL);
}
fn psram_set_qio_read_mode_spi1() {
set_peri_reg_mask(SPI1_CTRL_REG, SPI_FREAD_QIO);
clear_peri_reg_mask(SPI1_CTRL_REG, SPI_FREAD_QUAD);
clear_peri_reg_mask(SPI1_CTRL_REG, SPI_FREAD_DUAL);
clear_peri_reg_mask(SPI1_CTRL_REG, SPI_FREAD_DIO);
}
fn psram_set_basic_read_mode_spi1() {
clear_peri_reg_mask(SPI1_CTRL_REG, SPI_FREAD_QIO);
clear_peri_reg_mask(SPI1_CTRL_REG, SPI_FREAD_QUAD);
clear_peri_reg_mask(SPI1_CTRL_REG, SPI_FREAD_DUAL);
clear_peri_reg_mask(SPI1_CTRL_REG, SPI_FREAD_DIO);
}
fn psram_gpio_config(psram_io: &PsramIo, mode: PsramCacheSpeed) -> u32 {
let g_rom_spiflash_dummy_len_plus_ptr =
unsafe { addr_of_mut!(g_rom_spiflash_dummy_len_plus) };
fn gpio_pin_mux_reg(gpio: u8) -> u32 {
crate::gpio::get_io_mux_reg(gpio).as_ptr() as u32
}
fn gpio_hal_iomux_func_sel(reg: u32, function: u32) {
unsafe {
let ptr = reg as *mut u32;
let old = ptr.read_volatile();
ptr.write_volatile((old & !(0b111 << 12)) | (function << 12));
}
}
let spi_cache_dummy;
let rd_mode_reg = read_peri_reg(SPI0_CTRL_REG);
if (rd_mode_reg & SPI_FREAD_QIO_M) != 0 {
spi_cache_dummy = SPI0_R_QIO_DUMMY_CYCLELEN;
} else if (rd_mode_reg & SPI_FREAD_DIO_M) != 0 {
spi_cache_dummy = SPI0_R_DIO_DUMMY_CYCLELEN;
set_peri_reg_bits(
SPI0_USER1_REG,
SPI_USR_ADDR_BITLEN_V,
SPI0_R_DIO_ADDR_BITSLEN,
SPI_USR_ADDR_BITLEN_S,
);
} else if (rd_mode_reg & (SPI_FREAD_QUAD_M | SPI_FREAD_DUAL_M)) != 0 {
spi_cache_dummy = SPI0_R_FAST_DUMMY_CYCLELEN;
} else {
spi_cache_dummy = SPI0_R_FAST_DUMMY_CYCLELEN;
}
let extra_dummy;
match mode {
PsramCacheSpeed::PsramCacheF80mS40m => {
extra_dummy = PSRAM_IO_MATRIX_DUMMY_40M;
unsafe {
g_rom_spiflash_dummy_len_plus_ptr
.offset(_SPI_CACHE_PORT as isize)
.write_volatile(PSRAM_IO_MATRIX_DUMMY_80M);
g_rom_spiflash_dummy_len_plus_ptr
.offset(_SPI_FLASH_PORT as isize)
.write_volatile(PSRAM_IO_MATRIX_DUMMY_40M);
}
set_peri_reg_bits(
SPI0_USER1_REG,
SPI_USR_DUMMY_CYCLELEN_V,
spi_cache_dummy + PSRAM_IO_MATRIX_DUMMY_80M as u32,
SPI_USR_DUMMY_CYCLELEN_S,
); unsafe {
esp_rom_spiflash_config_clk(_SPI_80M_CLK_DIV, _SPI_CACHE_PORT);
esp_rom_spiflash_config_clk(_SPI_40M_CLK_DIV, _SPI_FLASH_PORT);
}
set_peri_reg_bits(
gpio_pin_mux_reg(psram_io.flash_clk_io),
FUN_DRV,
3,
FUN_DRV_S,
);
set_peri_reg_bits(
gpio_pin_mux_reg(psram_io.psram_clk_io),
FUN_DRV,
2,
FUN_DRV_S,
);
}
PsramCacheSpeed::PsramCacheF80mS80m => {
extra_dummy = PSRAM_IO_MATRIX_DUMMY_80M;
unsafe {
g_rom_spiflash_dummy_len_plus_ptr
.offset(_SPI_CACHE_PORT as isize)
.write_volatile(PSRAM_IO_MATRIX_DUMMY_80M);
g_rom_spiflash_dummy_len_plus_ptr
.offset(_SPI_FLASH_PORT as isize)
.write_volatile(PSRAM_IO_MATRIX_DUMMY_80M);
}
set_peri_reg_bits(
SPI0_USER1_REG,
SPI_USR_DUMMY_CYCLELEN_V,
spi_cache_dummy + PSRAM_IO_MATRIX_DUMMY_80M as u32,
SPI_USR_DUMMY_CYCLELEN_S,
); unsafe {
esp_rom_spiflash_config_clk(_SPI_80M_CLK_DIV, _SPI_CACHE_PORT);
esp_rom_spiflash_config_clk(_SPI_80M_CLK_DIV, _SPI_FLASH_PORT);
}
set_peri_reg_bits(
gpio_pin_mux_reg(psram_io.flash_clk_io),
FUN_DRV,
3,
FUN_DRV_S,
);
set_peri_reg_bits(
gpio_pin_mux_reg(psram_io.psram_clk_io),
FUN_DRV,
3,
FUN_DRV_S,
);
}
PsramCacheSpeed::PsramCacheF40mS40m => {
extra_dummy = PSRAM_IO_MATRIX_DUMMY_40M;
unsafe {
g_rom_spiflash_dummy_len_plus_ptr
.offset(_SPI_CACHE_PORT as isize)
.write_volatile(PSRAM_IO_MATRIX_DUMMY_40M);
g_rom_spiflash_dummy_len_plus_ptr
.offset(_SPI_FLASH_PORT as isize)
.write_volatile(PSRAM_IO_MATRIX_DUMMY_40M);
}
set_peri_reg_bits(
SPI0_USER1_REG,
SPI_USR_DUMMY_CYCLELEN_V,
spi_cache_dummy + PSRAM_IO_MATRIX_DUMMY_40M as u32,
SPI_USR_DUMMY_CYCLELEN_S,
); unsafe {
esp_rom_spiflash_config_clk(_SPI_40M_CLK_DIV, _SPI_CACHE_PORT);
esp_rom_spiflash_config_clk(_SPI_40M_CLK_DIV, _SPI_FLASH_PORT);
}
set_peri_reg_bits(
gpio_pin_mux_reg(psram_io.flash_clk_io),
FUN_DRV,
2,
FUN_DRV_S,
);
set_peri_reg_bits(
gpio_pin_mux_reg(psram_io.psram_clk_io),
FUN_DRV,
2,
FUN_DRV_S,
);
}
}
set_peri_reg_mask(SPI0_USER_REG, SPI_USR_DUMMY);
unsafe {
esp_rom_gpio_connect_out_signal(
psram_io.flash_cs_io as u32,
SPICS0_OUT_IDX,
false,
false,
);
esp_rom_gpio_connect_out_signal(
psram_io.psram_cs_io as u32,
SPICS1_OUT_IDX,
false,
false,
);
esp_rom_gpio_connect_out_signal(
psram_io.psram_spiq_sd0_io as u32,
SPIQ_OUT_IDX,
false,
false,
);
esp_rom_gpio_connect_in_signal(psram_io.psram_spiq_sd0_io as u32, SPIQ_IN_IDX, false);
esp_rom_gpio_connect_out_signal(
psram_io.psram_spid_sd1_io as u32,
SPID_OUT_IDX,
false,
false,
);
esp_rom_gpio_connect_in_signal(psram_io.psram_spid_sd1_io as u32, SPID_IN_IDX, false);
esp_rom_gpio_connect_out_signal(
psram_io.psram_spiwp_sd3_io as u32,
SPIWP_OUT_IDX,
false,
false,
);
esp_rom_gpio_connect_in_signal(psram_io.psram_spiwp_sd3_io as u32, SPIWP_IN_IDX, false);
esp_rom_gpio_connect_out_signal(
psram_io.psram_spihd_sd2_io as u32,
SPIHD_OUT_IDX,
false,
false,
);
esp_rom_gpio_connect_in_signal(psram_io.psram_spihd_sd2_io as u32, SPIHD_IN_IDX, false);
}
if (psram_io.flash_clk_io == SPI_IOMUX_PIN_NUM_CLK)
&& (psram_io.flash_clk_io != psram_io.psram_clk_io)
{
gpio_hal_iomux_func_sel(gpio_pin_mux_reg(psram_io.flash_clk_io), FUNC_SD_CLK_SPICLK);
} else {
gpio_hal_iomux_func_sel(gpio_pin_mux_reg(psram_io.flash_clk_io), PIN_FUNC_GPIO);
}
gpio_hal_iomux_func_sel(gpio_pin_mux_reg(psram_io.flash_cs_io), PIN_FUNC_GPIO);
gpio_hal_iomux_func_sel(gpio_pin_mux_reg(psram_io.psram_cs_io), PIN_FUNC_GPIO);
gpio_hal_iomux_func_sel(gpio_pin_mux_reg(psram_io.psram_clk_io), PIN_FUNC_GPIO);
gpio_hal_iomux_func_sel(gpio_pin_mux_reg(psram_io.psram_spiq_sd0_io), PIN_FUNC_GPIO);
gpio_hal_iomux_func_sel(gpio_pin_mux_reg(psram_io.psram_spid_sd1_io), PIN_FUNC_GPIO);
gpio_hal_iomux_func_sel(gpio_pin_mux_reg(psram_io.psram_spihd_sd2_io), PIN_FUNC_GPIO);
gpio_hal_iomux_func_sel(gpio_pin_mux_reg(psram_io.psram_spiwp_sd3_io), PIN_FUNC_GPIO);
let flash_id: u32 = unsafe { g_rom_flashchip.device_id };
info!("Flash-ID = {}", flash_id);
if flash_id == FLASH_ID_GD25LQ32C {
set_peri_reg_bits(
gpio_pin_mux_reg(psram_io.flash_cs_io),
FUN_DRV_V,
3,
FUN_DRV_S,
);
set_peri_reg_bits(
gpio_pin_mux_reg(psram_io.flash_clk_io),
FUN_DRV_V,
3,
FUN_DRV_S,
);
set_peri_reg_bits(
gpio_pin_mux_reg(psram_io.psram_cs_io),
FUN_DRV_V,
3,
FUN_DRV_S,
);
set_peri_reg_bits(
gpio_pin_mux_reg(psram_io.psram_clk_io),
FUN_DRV_V,
3,
FUN_DRV_S,
);
set_peri_reg_bits(
gpio_pin_mux_reg(psram_io.psram_spiq_sd0_io),
FUN_DRV_V,
3,
FUN_DRV_S,
);
set_peri_reg_bits(
gpio_pin_mux_reg(psram_io.psram_spid_sd1_io),
FUN_DRV_V,
3,
FUN_DRV_S,
);
set_peri_reg_bits(
gpio_pin_mux_reg(psram_io.psram_spihd_sd2_io),
FUN_DRV_V,
3,
FUN_DRV_S,
);
set_peri_reg_bits(
gpio_pin_mux_reg(psram_io.psram_spiwp_sd3_io),
FUN_DRV_V,
3,
FUN_DRV_S,
);
}
extra_dummy as u32
}
fn clear_peri_reg_mask(reg: u32, mask: u32) {
unsafe {
(reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() & !mask);
}
}
fn set_peri_reg_mask(reg: u32, mask: u32) {
unsafe {
(reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() | mask);
}
}
fn set_peri_reg_bits(reg: u32, bitmap: u32, value: u32, shift: u32) {
unsafe {
(reg as *mut u32).write_volatile(
((reg as *mut u32).read_volatile() & !(bitmap << shift))
| ((value & bitmap) << shift),
);
}
}
fn write_peri_reg(reg: u32, val: u32) {
unsafe {
(reg as *mut u32).write_volatile(val);
}
}
fn read_peri_reg(reg: u32) -> u32 {
unsafe { (reg as *mut u32).read_volatile() }
}
}