diff --git a/esp-hal/src/soc/esp32/psram.rs b/esp-hal/src/soc/esp32/psram.rs index fbd23bab3..83c684e38 100644 --- a/esp-hal/src/soc/esp32/psram.rs +++ b/esp-hal/src/soc/esp32/psram.rs @@ -18,8 +18,7 @@ //! //! NOTE: If you want to use `PSRAM` on `ESP32` or `ESP32-S3`, it'll work only //! in `release` mode. - -const PSRAM_VADDR: u32 = 0x3F800000; +pub const PSRAM_VADDR_START: usize = 0x3F800000; pub fn psram_vaddr_start() -> usize { PSRAM_VADDR_START @@ -39,12 +38,10 @@ cfg_if::cfg_if! { 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
) { utils::psram_init(); - utils::s_mapping(PSRAM_VADDR, PSRAM_BYTES as u32); + utils::s_mapping(PSRAM_VADDR_START as u32, PSRAM_BYTES as u32); } #[cfg(any(feature = "psram-2m", feature = "psram-4m", feature = "psram-8m"))] @@ -124,43 +121,7 @@ pub(crate) mod utils { 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; - 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 { @@ -170,10 +131,7 @@ pub(crate) mod utils { } } - 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 SPI_USR: u32 = 1 << 18; const PSRAM_INTERNAL_IO_28: u32 = 28; const PSRAM_INTERNAL_IO_29: u32 = 29; @@ -194,75 +152,18 @@ pub(crate) mod utils { 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; @@ -271,8 +172,6 @@ pub(crate) mod utils { 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; @@ -448,8 +347,13 @@ pub(crate) mod utils { } 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); + unsafe { + let spi0 = &*crate::peripherals::SPI0::PTR; + let spi1 = &*crate::peripherals::SPI1::PTR; + + spi0.ext3().modify(|_, w| w.bits(0x1)); + spi1.user().modify(|_, w| w.usr_prep_hold().clear_bit()); + } psram_spi_init(mode, clk_mode); @@ -549,121 +453,106 @@ pub(crate) mod utils { 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 => { - // flash 1 div clk,80+40; - clear_peri_reg_mask(SPI0_DATE_REG, 1 << 31); + unsafe { + let spi = &*crate::peripherals::SPI0::PTR; + 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 => { + // flash 1 div clk,80+40; + // There's no register on bit 31. No information about it in IDF, nor TRM, + // so just doing it in this way. + spi.date().modify(|r, w| { + let current_bits = r.bits(); + let new_bits = current_bits & !((1 << 31) | (1 << 30)); + w.bits(new_bits) + }); + // pre clk div , ONLY IF SPI/ SRAM@ DIFFERENT SPEED,JUST + // FOR SPI0. FLASH DIV + // 2+SRAM DIV4 + } + PsramCacheSpeed::PsramCacheF80mS40m => { + spi.clock().modify(|_, w| w.clk_equ_sysclk().clear_bit()); + spi.clock().modify(|_, w| w.clkdiv_pre().bits(0)); + spi.clock().modify(|_, w| w.clkcnt_n().bits(1)); + spi.clock().modify(|_, w| w.clkcnt_h().bits(0)); + spi.clock().modify(|_, w| w.clkcnt_l().bits(1)); - // pre clk div , ONLY IF SPI/ SRAM@ DIFFERENT SPEED,JUST FOR SPI0. FLASH DIV - // 2+SRAM DIV4 - 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); - - // flash 1 div clk - set_peri_reg_mask(SPI0_DATE_REG, 1 << 31); - - // pre clk div ONLY IF SPI/SRAM@ DIFFERENT SPEED,JUST FOR SPI0. - clear_peri_reg_mask(SPI0_DATE_REG, 1 << 30); - } - _ => { - clear_peri_reg_mask(SPI0_DATE_REG, 1 << 31); // flash 1 div clk - clear_peri_reg_mask(SPI0_DATE_REG, 1 << 30); // pre clk div - } - } - - clear_peri_reg_mask(SPI0_CACHE_SCTRL_REG, SPI_USR_SRAM_DIO_M); // disable dio mode for cache command - set_peri_reg_mask(SPI0_CACHE_SCTRL_REG, SPI_USR_SRAM_QIO_M); // enable qio mode for cache command - set_peri_reg_mask(SPI0_CACHE_SCTRL_REG, SPI_CACHE_SRAM_USR_RCMD_M); // enable cache read command - set_peri_reg_mask(SPI0_CACHE_SCTRL_REG, SPI_CACHE_SRAM_USR_WCMD_M); // enable cache write command - set_peri_reg_bits( - SPI0_CACHE_SCTRL_REG, - SPI_SRAM_ADDR_BITLEN_V, - 23, - SPI_SRAM_ADDR_BITLEN_S, - ); // write address for cache command. - set_peri_reg_mask(SPI0_CACHE_SCTRL_REG, SPI_USR_RD_SRAM_DUMMY_M); // enable cache read dummy - - // config sram cache r/w command - 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, - ); // 0xEB - 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, - ); // 0x38 - 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, - ); // dummy, psram cache : 40m--+1dummy; 80m--+2dummy - - match psram_cache_mode { - PsramCacheSpeed::PsramCacheF80mS80m => (), // in this mode , no delay is needed - _ => { - 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, - ); // read command length, 2 bytes(1byte for delay),sending in qio mode in cache - 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, - ); // 0xEB, read command value,(0x00 for delay,0xeb for cmd) - 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, - ); // write command length,2 bytes(1byte for delay,send in qio mode in cache) - 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, - ); // 0x38, write command value,(0x00 for delay) - 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, - ); // dummy, psram cache : 40m--+1dummy; 80m--+2dummy + spi.date().modify(|r, w| { + let current_bits = r.bits(); + let new_bits = (current_bits | (1 << 31)) & !(1 << 30); + w.bits(new_bits) + }); + } + _ => { + spi.date().modify(|r, w| { + let current_bits = r.bits(); + let new_bits = current_bits & !((1 << 31) | (1 << 30)); + w.bits(new_bits) + }); + } + } + + spi.cache_sctrl() + .modify(|_, w| w.usr_sram_dio().clear_bit()); // disable dio mode for cache command + spi.cache_sctrl().modify(|_, w| w.usr_sram_qio().set_bit()); // enable qio mode for cache command + spi.cache_sctrl() + .modify(|_, w| w.cache_sram_usr_rcmd().set_bit()); // enable cache read command + spi.cache_sctrl() + .modify(|_, w| w.cache_sram_usr_wcmd().set_bit()); // enable cache write command + spi.cache_sctrl() + .modify(|_, w| w.sram_addr_bitlen().bits(23)); // write address for cache command. + spi.cache_sctrl() + .modify(|_, w| w.usr_rd_sram_dummy().set_bit()); // enable cache read dummy + + // config sram cache r/w command + spi.sram_drd_cmd() + .modify(|_, w| w.cache_sram_usr_rd_cmd_bitlen().bits(7)); + spi.sram_drd_cmd().modify(|_, w| { + w.cache_sram_usr_rd_cmd_value() + .bits(PSRAM_FAST_READ_QUAD as u16) + }); + spi.sram_dwr_cmd() + .modify(|_, w| w.cache_sram_usr_wr_cmd_bitlen().bits(7)); + spi.sram_dwr_cmd().modify(|_, w| { + w.cache_sram_usr_wr_cmd_value() + .bits(PSRAM_QUAD_WRITE as u16) + }); + + // dummy, psram cache : 40m--+1dummy; 80m--+2dummy + spi.cache_sctrl().modify(|_, w| { + w.sram_dummy_cyclelen() + .bits((PSRAM_FAST_READ_QUAD_DUMMY + extra_dummy) as u8) + }); + + match psram_cache_mode { + PsramCacheSpeed::PsramCacheF80mS80m => (), // in this mode , no delay is needed + _ => { + if clk_mode == PsramClkMode::PsramClkModeDclk { + spi.sram_drd_cmd() + .modify(|_, w| w.cache_sram_usr_rd_cmd_bitlen().bits(15)); // read command length, 2 bytes(1byte for delay),sending in qio mode in + // cache + spi.sram_drd_cmd().modify(|_, w| { + w.cache_sram_usr_rd_cmd_value() + .bits((PSRAM_FAST_READ_QUAD << 8) as u16) + }); // read command value,(0x00 for delay,0xeb for cmd) + + spi.sram_dwr_cmd() + .modify(|_, w| w.cache_sram_usr_wr_cmd_bitlen().bits(15)); // write command length,2 bytes(1byte for delay,send in qio mode in cache) + spi.sram_dwr_cmd().modify(|_, w| { + w.cache_sram_usr_wr_cmd_value() + .bits((PSRAM_QUAD_WRITE << 8) as u16) + }); // write command value,(0x00 for delay) + spi.cache_sctrl().modify(|_, w| { + w.sram_dummy_cyclelen() + .bits((PSRAM_FAST_READ_QUAD_DUMMY + extra_dummy) as u8) + }); // dummy, psram cache : 40m--+1dummy; 80m--+2dummy + } } } - } - unsafe { let dport = &*esp32::DPORT::PTR; dport @@ -711,10 +600,10 @@ pub(crate) mod utils { dport .app_cache_ctrl1() .modify(|_, w| w.app_cmmu_sram_page_mode().bits(0)); - } - // ENABLE SPI0 CS1 TO PSRAM(CS0--FLASH; CS1--SRAM) - clear_peri_reg_mask(SPI0_PIN_REG, SPI_CS1_DIS_M); + // ENABLE SPI0 CS1 TO PSRAM(CS0--FLASH; CS1--SRAM) + spi.pin().modify(|_, w| w.cs1_dis().clear_bit()); + } } // spi param init for psram @@ -723,57 +612,76 @@ pub(crate) mod utils { mode: PsramCacheSpeed, clk_mode: PsramClkMode, ) { - clear_peri_reg_mask(SPI1_SLAVE_REG, SPI_TRANS_DONE << 5); - // SPI_CPOL & SPI_CPHA - clear_peri_reg_mask(SPI1_PIN_REG, SPI_CK_IDLE_EDGE); - clear_peri_reg_mask(SPI1_USER_REG, SPI_CK_OUT_EDGE); - // SPI bit order - clear_peri_reg_mask(SPI1_CTRL_REG, SPI_WR_BIT_ORDER); - clear_peri_reg_mask(SPI1_CTRL_REG, SPI_RD_BIT_ORDER); - // SPI bit order - clear_peri_reg_mask(SPI1_USER_REG, SPI_DOUTDIN); - // May be not must to do. - write_peri_reg(SPI1_USER1_REG, 0); - // SPI mode type - clear_peri_reg_mask(SPI1_SLAVE_REG, SPI_SLAVE_MODE); unsafe { + let spi = &*crate::peripherals::SPI1::PTR; + // We need to clear last bit of INT_EN field here. + // clear_peri_reg_mask(SPI1_SLAVE_REG, SPI_TRANS_DONE << 5); + spi.slave().modify(|r, w| { + let current_bits = r.int_en().bits(); + let new_bits = current_bits & !(1 << 4); + w.int_en().bits(new_bits) + }); + // SPI_CPOL & SPI_CPHA + spi.pin().modify(|_, w| w.ck_idle_edge().clear_bit()); + spi.user().modify(|_, w| w.ck_out_edge().clear_bit()); + // SPI bit order + spi.ctrl().modify(|_, w| w.wr_bit_order().clear_bit()); + spi.ctrl().modify(|_, w| w.rd_bit_order().clear_bit()); + // SPI bit order + spi.user().modify(|_, w| w.doutdin().clear_bit()); + // May be not must to do. + spi.user1().modify(|_, w| w.bits(0)); + // SPI mode type + spi.slave().modify(|_, w| w.mode().clear_bit()); + 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); } - 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 cs time. - 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); + unsafe { + let spi = &*crate::peripherals::SPI1::PTR; + if clk_mode == PsramClkMode::PsramClkModeNorm { + spi.user().modify(|_, w| w.cs_hold().set_bit()); + spi.user().modify(|_, w| w.cs_setup().set_bit()); + + spi.ctrl2().modify(|_, w| { + w.hold_time() + .bits(psram_cs_hold_time_from_psram_speed(psram_cache_mode) as u8) + }); + + // Set cs time. + spi.ctrl2().modify(|_, w| w.setup_time().bits(0)); + } else { + spi.user().modify(|_, w| w.cs_hold().clear_bit()); + spi.user().modify(|_, w| w.cs_setup().clear_bit()); + } } } 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 cs time. - 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); + unsafe { + let spi = &*crate::peripherals::SPI0::PTR; + if clk_mode == PsramClkMode::PsramClkModeNorm { + spi.user().modify(|_, w| w.cs_hold().set_bit()); + spi.user().modify(|_, w| w.cs_setup().set_bit()); + + spi.ctrl2().modify(|_, w| { + w.hold_time() + .bits(psram_cs_hold_time_from_psram_speed(psram_cache_mode) as u8) + }); + + // Set cs time. + spi.ctrl2().modify(|_, w| w.setup_time().bits(0)); + } else { + spi.user().modify(|_, w| w.cs_hold().clear_bit()); + spi.user().modify(|_, w| w.cs_setup().clear_bit()); + } } } @@ -832,153 +740,118 @@ pub(crate) mod utils { 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_recv_start_spi1(core::ptr::null_mut(), 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; + unsafe { + let spi = &*crate::peripherals::SPI1::PTR; + loop { + if spi.cmd().read().bits() & 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); + spi.user().modify(|_, w| w.bits(backup_usr)); + spi.user1().modify(|_, w| w.bits(backup_usr1)); + spi.user2().modify(|_, w| w.bits(backup_usr2)); + } } // setup spi command/addr/data/dummy in user mode #[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); - - // Set command by user. - if p_in_data.cmd_bit_len != 0 { - // Max command length 16 bits. - 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, - ); - // Enable command - set_peri_reg_mask(SPI1_USER_REG, SPI_USR_COMMAND); - // Load command,bit15-0 is cmd value. - 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, - ); - } - // Set Address by user. - 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, - ); - // Enable address - set_peri_reg_mask(SPI1_USER_REG, SPI_USR_ADDR); - // Set address - 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, - ); - } - // Set data by user. - let p_tx_val = p_in_data.tx_data; - if p_in_data.tx_data_bit_len != 0 { - // Enable MOSI - clear_peri_reg_mask(SPI1_USER_REG, SPI_USR_MOSI); - // Load send buffer - 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() - }); + unsafe { + let spi = &*crate::peripherals::SPI1::PTR; + loop { + if spi.cmd().read().bits() & SPI_USR == 0 { + break; } } - // Set data send buffer length.Max data length 64 bytes. - 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, - ); - } - // Set rx data by user. - if p_in_data.rx_data_bit_len != 0 { - // Enable MOSI - set_peri_reg_mask(SPI1_USER_REG, SPI_USR_MISO); - // Set data send buffer length.Max data length 64 bytes. - 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); // dummy en - set_peri_reg_bits( - SPI1_USER1_REG, - SPI_USR_DUMMY_CYCLELEN_V, - p_in_data.dummy_bit_len - 1, - SPI_USR_DUMMY_CYCLELEN_S, - ); // DUMMY - } else { - clear_peri_reg_mask(SPI1_USER_REG, SPI_USR_DUMMY); // dummy en - set_peri_reg_bits( - SPI1_USER1_REG, - SPI_USR_DUMMY_CYCLELEN_V, - 0, - SPI_USR_DUMMY_CYCLELEN_S, - ); // DUMMY - } - (backup_usr, backup_usr1, backup_usr2) + let backup_usr = spi.user().read().bits(); + let backup_usr1 = spi.user1().read().bits(); + let backup_usr2 = spi.user2().read().bits(); + + // Set command by user. + if p_in_data.cmd_bit_len != 0 { + // Max command length 16 bits. + spi.user2().modify(|_, w| { + w.usr_command_bitlen() + .bits((p_in_data.cmd_bit_len - 1) as u8) + }); + // Enable command + spi.user().modify(|_, w| w.usr_command().set_bit()); + // Load command,bit15-0 is cmd value. + spi.user2() + .modify(|_, w| w.usr_command_value().bits(p_in_data.cmd)); + } else { + spi.user().modify(|_, w| w.usr_command().clear_bit()); + spi.user2().modify(|_, w| w.usr_command_bitlen().bits(0)); + } + // Set Address by user. + if p_in_data.addr_bit_len != 0 { + spi.user1() + .modify(|_, w| w.usr_addr_bitlen().bits((p_in_data.addr_bit_len - 1) as u8)); + // Enable address + spi.user().modify(|_, w| w.usr_addr().set_bit()); + // Set address + spi.addr() + .modify(|_, w| w.bits(p_in_data.addr.read_volatile())); + } else { + spi.user().modify(|_, w| w.usr_addr().clear_bit()); + spi.user1().modify(|_, w| w.usr_addr_bitlen().bits(0)); + } + // Set data by user. + let p_tx_val = p_in_data.tx_data; + if p_in_data.tx_data_bit_len != 0 { + // Enable MOSI + spi.user().modify(|_, w| w.usr_mosi().clear_bit()); + // Load send buffer + let len = (p_in_data.tx_data_bit_len + 31) / 32; + if !p_tx_val.is_null() { + for i in 0..len { + spi.w(0) + .modify(|_, w| w.bits(p_tx_val.offset(i as isize).read_volatile())); + } + } + // Set data send buffer length.Max data length 64 bytes. + spi.mosi_dlen().modify(|_, w| { + w.usr_mosi_dbitlen() + .bits((p_in_data.tx_data_bit_len - 1) as u32) + }); + } else { + spi.user().modify(|_, w| w.usr_mosi().clear_bit()); + spi.mosi_dlen().modify(|_, w| w.usr_mosi_dbitlen().bits(0)); + } + // Set rx data by user. + if p_in_data.rx_data_bit_len != 0 { + // Enable MISO + spi.user().modify(|_, w| w.usr_miso().set_bit()); + // Set data send buffer length.Max data length 64 bytes. + spi.miso_dlen().modify(|_, w| { + w.usr_miso_dbitlen() + .bits((p_in_data.rx_data_bit_len - 1) as u32) + }); + } else { + spi.user().modify(|_, w| w.usr_miso().clear_bit()); + spi.miso_dlen().modify(|_, w| w.usr_miso_dbitlen().bits(0)); + } + if p_in_data.dummy_bit_len != 0 { + spi.user().modify(|_, w| w.usr_dummy().set_bit()); // dummy en + spi.user1().modify(|_, w| { + w.usr_dummy_cyclelen() + .bits((p_in_data.dummy_bit_len - 1) as u8) + }); // DUMMY + } else { + spi.user().modify(|_, w| w.usr_dummy().clear_bit()); // dummy dis + spi.user1().modify(|_, w| w.usr_dummy_cyclelen().bits(0)); // DUMMY + } + + (backup_usr, backup_usr1, backup_usr2) + } } #[derive(Debug, Clone, Copy, PartialEq)] @@ -989,85 +862,80 @@ pub(crate) mod utils { // start sending cmd/addr and optionally, receiving data #[ram] - fn psram_cmd_recv_start_spi1(p_rx_data: *mut u32, rx_byte_len: u16, cmd_mode: PsramCmdMode) { - // get cs1 - 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(); - } - - // Wait for SPI0 to idle - loop { - if read_peri_reg(SPI0_EXT2_REG) == 0 { - break; - } - } + fn psram_cmd_recv_start_spi1(p_rx_data: *mut u32, cmd_mode: PsramCmdMode) { unsafe { + let spi = &*crate::peripherals::SPI1::PTR; + // get cs1 + spi.pin().modify(|_, w| w.cs1_dis().clear_bit()); + spi.pin().modify(|_, w| w.cs0_dis().clear_bit()); + + let mode_backup: u32 = (spi.user().read().bits() >> SPI_FWRITE_DUAL_S) & 0xf; + let rd_mode_backup: u32 = spi.ctrl().read().bits() + & (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(); + } + + // Wait for SPI0 to idle + loop { + if spi.ext2().read().bits() == 0 { + break; + } + } + // DPORT_SET_PERI_REG_MASK(DPORT_HOST_INF_SEL_REG, 1 << 14); let dport = &*esp32::DPORT::PTR; dport .host_inf_sel() .modify(|r, w| w.bits(r.bits() | 1 << 14)); - } - // Start send data - set_peri_reg_mask(SPI1_CMD_REG, SPI_USR); - loop { - if read_peri_reg(SPI1_CMD_REG) & SPI_USR == 0 { - break; + // Start send data + spi.cmd().modify(|_, w| w.usr().set_bit()); + loop { + if spi.cmd().read().bits() & SPI_USR == 0 { + break; + } } - } - unsafe { + // DPORT_CLEAR_PERI_REG_MASK(DPORT_HOST_INF_SEL_REG, 1 << 14); let dport = &*esp32::DPORT::PTR; dport .host_inf_sel() .modify(|r, w| w.bits(r.bits() & !(1 << 14))); - } - // recover spi mode - set_peri_reg_bits( - SPI1_USER_REG, + // recover spi mode + // TODO: get back to this, why writing on `0xf` address? + 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, + ); + + spi.ctrl().modify(|_, w| w.fread_dio().clear_bit()); + spi.ctrl().modify(|_, w| w.fread_dual().clear_bit()); + spi.ctrl().modify(|_, w| w.fread_quad().clear_bit()); + spi.ctrl().modify(|_, w| w.fread_qio().clear_bit()); + + spi.ctrl().modify(|_, w| w.bits(rd_mode_backup)); + + // return cs to cs0 + spi.pin().modify(|_, w| w.cs1_dis().set_bit()); + spi.pin().modify(|_, w| w.cs0_dis().clear_bit()); + 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); - - // return cs to cs0 - 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; - // Read data out - 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; + // Read data out + loop { + p_rx_data.write_volatile(spi.w(0).read().bits()); } } } @@ -1075,177 +943,165 @@ pub(crate) mod utils { // set basic SPI write mode 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); + unsafe { + let spi = &*crate::peripherals::SPI1::PTR; + + spi.user().modify(|_, w| w.fwrite_qio().clear_bit()); + spi.user().modify(|_, w| w.fwrite_dio().clear_bit()); + spi.user().modify(|_, w| w.fwrite_quad().clear_bit()); + spi.user().modify(|_, w| w.fwrite_dual().clear_bit()); + } } // set QPI write mode 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); + unsafe { + let spi = &*crate::peripherals::SPI1::PTR; + + spi.user().modify(|_, w| w.fwrite_qio().set_bit()); + spi.user().modify(|_, w| w.fwrite_dio().clear_bit()); + spi.user().modify(|_, w| w.fwrite_quad().clear_bit()); + spi.user().modify(|_, w| w.fwrite_dual().clear_bit()); + } } // set QPI read mode 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); + unsafe { + let spi = &*crate::peripherals::SPI1::PTR; + + spi.ctrl().modify(|_, w| w.fread_qio().set_bit()); + spi.ctrl().modify(|_, w| w.fread_quad().clear_bit()); + spi.ctrl().modify(|_, w| w.fread_dual().clear_bit()); + spi.ctrl().modify(|_, w| w.fread_dio().clear_bit()); + } } // set SPI read mode 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); + unsafe { + let spi = &*crate::peripherals::SPI1::PTR; + + spi.ctrl().modify(|_, w| w.fread_qio().clear_bit()); + spi.ctrl().modify(|_, w| w.fread_quad().clear_bit()); + spi.ctrl().modify(|_, w| w.fread_dual().clear_bit()); + spi.ctrl().modify(|_, w| w.fread_dio().clear_bit()); + } } // psram gpio init , different working frequency we have different solutions 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) }; + unsafe { + let spi = &*crate::peripherals::SPI0::PTR; + let g_rom_spiflash_dummy_len_plus_ptr = 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)); + #[derive(Debug, Clone, Copy)] + enum Field { + McuSel, + FunDrv, } - } - 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 { - spi_cache_dummy = SPI0_R_FAST_DUMMY_CYCLELEN; - } + macro_rules! apply_to_field { + ($w:ident, $field:expr, $bits:expr) => { + match $field { + Field::McuSel => $w.mcu_sel().bits($bits), + Field::FunDrv => $w.fun_drv().bits($bits), + } + }; + } - let extra_dummy; - - match mode { - PsramCacheSpeed::PsramCacheF80mS40m => { - extra_dummy = PSRAM_IO_MATRIX_DUMMY_40M; + fn configure_gpio(gpio: u8, field: Field, bits: u8) { unsafe { + let ptr = crate::gpio::get_io_mux_reg(gpio); + ptr.modify(|_, w| apply_to_field!(w, field, bits)); + } + } + + let spi_cache_dummy; + let rd_mode_reg = spi.ctrl().read().bits(); + 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; + spi.user1() + .modify(|_, w| w.usr_addr_bitlen().bits(SPI0_R_DIO_ADDR_BITSLEN as u8)); + } else { + spi_cache_dummy = SPI0_R_FAST_DUMMY_CYCLELEN; + } + + let extra_dummy; + + match mode { + PsramCacheSpeed::PsramCacheF80mS40m => { + extra_dummy = PSRAM_IO_MATRIX_DUMMY_40M; + 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, - ); // DUMMY - unsafe { + + spi.user1().modify(|_, w| { + w.usr_dummy_cyclelen() + .bits(spi_cache_dummy as u8 + PSRAM_IO_MATRIX_DUMMY_80M) + }); // DUMMY + 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 drive ability for clock + + configure_gpio(psram_io.flash_clk_io, Field::FunDrv, 3); + configure_gpio(psram_io.psram_clk_io, Field::FunDrv, 2); } - // set drive ability for clock - 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 { + PsramCacheSpeed::PsramCacheF80mS80m => { + extra_dummy = PSRAM_IO_MATRIX_DUMMY_80M; 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, - ); // DUMMY - unsafe { + + spi.user1().modify(|_, w| { + w.usr_dummy_cyclelen() + .bits(spi_cache_dummy as u8 + PSRAM_IO_MATRIX_DUMMY_80M) + }); // DUMMY + 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 drive ability for clock + configure_gpio(psram_io.flash_clk_io, Field::FunDrv, 3); + configure_gpio(psram_io.psram_clk_io, Field::FunDrv, 3); } - // set drive ability for clock - 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 { + PsramCacheSpeed::PsramCacheF40mS40m => { + extra_dummy = PSRAM_IO_MATRIX_DUMMY_40M; + 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, - ); // DUMMY - unsafe { + + spi.user1().modify(|_, w| { + w.usr_dummy_cyclelen() + .bits(spi_cache_dummy as u8 + PSRAM_IO_MATRIX_DUMMY_40M) + }); // DUMMY + 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 drive ability for clock - 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); // dummy enable - // In bootloader, all the signals are already configured, - // We keep the following code in case the bootloader is some older version. - unsafe { + // set drive ability for clock + configure_gpio(psram_io.flash_clk_io, Field::FunDrv, 2); + configure_gpio(psram_io.psram_clk_io, Field::FunDrv, 2); + } + } + + spi.user().modify(|_, w| w.usr_dummy().set_bit()); // dummy enable + + // In bootloader, all the signals are already configured, + // We keep the following code in case the bootloader is some older version. + esp_rom_gpio_connect_out_signal( psram_io.flash_cs_io as u32, SPICS0_OUT_IDX, @@ -1286,93 +1142,61 @@ pub(crate) mod utils { false, ); esp_rom_gpio_connect_in_signal(psram_io.psram_spihd_sd2_io as u32, SPIHD_IN_IDX, false); - } - // select pin function gpio - if (psram_io.flash_clk_io == SPI_IOMUX_PIN_NUM_CLK) - && (psram_io.flash_clk_io != psram_io.psram_clk_io) - { - // flash clock signal should come from IO MUX. - gpio_hal_iomux_func_sel(gpio_pin_mux_reg(psram_io.flash_clk_io), FUNC_SD_CLK_SPICLK); - } else { - // flash clock signal should come from GPIO matrix. - 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); + // select pin function gpio + if (psram_io.flash_clk_io == SPI_IOMUX_PIN_NUM_CLK) + && (psram_io.flash_clk_io != psram_io.psram_clk_io) + { + // flash clock signal should come from IO MUX. + configure_gpio( + psram_io.flash_clk_io, + Field::McuSel, + FUNC_SD_CLK_SPICLK as u8, + ); + } else { + // flash clock signal should come from GPIO matrix. + configure_gpio(psram_io.flash_clk_io, Field::McuSel, PIN_FUNC_GPIO as u8); + } + configure_gpio(psram_io.flash_cs_io, Field::McuSel, PIN_FUNC_GPIO as u8); + configure_gpio(psram_io.psram_cs_io, Field::McuSel, PIN_FUNC_GPIO as u8); + configure_gpio(psram_io.psram_clk_io, Field::McuSel, PIN_FUNC_GPIO as u8); + configure_gpio( + psram_io.psram_spiq_sd0_io, + Field::McuSel, + PIN_FUNC_GPIO as u8, + ); + configure_gpio( + psram_io.psram_spid_sd1_io, + Field::McuSel, + PIN_FUNC_GPIO as u8, + ); + configure_gpio( + psram_io.psram_spihd_sd2_io, + Field::McuSel, + PIN_FUNC_GPIO as u8, + ); + configure_gpio( + psram_io.psram_spiwp_sd3_io, + Field::McuSel, + PIN_FUNC_GPIO as u8, + ); - let flash_id: u32 = unsafe { g_rom_flashchip.device_id }; - info!("Flash-ID = {}", flash_id); + let flash_id: u32 = g_rom_flashchip.device_id; + info!("Flash-ID = {}", flash_id); - if flash_id == FLASH_ID_GD25LQ32C { - // Set drive ability for 1.8v flash in 80Mhz. - 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, - ); - } + if flash_id == FLASH_ID_GD25LQ32C { + // Set drive ability for 1.8v flash in 80Mhz. + configure_gpio(psram_io.flash_cs_io, Field::FunDrv, 3); + configure_gpio(psram_io.flash_clk_io, Field::FunDrv, 3); + configure_gpio(psram_io.psram_cs_io, Field::FunDrv, 3); + configure_gpio(psram_io.psram_clk_io, Field::FunDrv, 3); + configure_gpio(psram_io.psram_spiq_sd0_io, Field::FunDrv, 3); + configure_gpio(psram_io.psram_spid_sd1_io, Field::FunDrv, 3); + configure_gpio(psram_io.psram_spihd_sd2_io, Field::FunDrv, 3); + configure_gpio(psram_io.psram_spiwp_sd3_io, Field::FunDrv, 3); + } - 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); + extra_dummy as u32 } } @@ -1384,14 +1208,4 @@ pub(crate) mod utils { ); } } - - 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() } - } } diff --git a/esp-hal/src/soc/esp32s2/psram.rs b/esp-hal/src/soc/esp32s2/psram.rs index daf9c44ea..a47fcbd6d 100644 --- a/esp-hal/src/soc/esp32s2/psram.rs +++ b/esp-hal/src/soc/esp32s2/psram.rs @@ -480,128 +480,83 @@ pub(crate) mod utils { } } - const REG_SPI_MEM_BASE: u32 = 0x3f403000; - const SPI_MEM_CACHE_SCTRL_REG: u32 = REG_SPI_MEM_BASE + 0x40; - const SPI_MEM_SRAM_DWR_CMD_REG: u32 = REG_SPI_MEM_BASE + 0x4c; - const SPI_MEM_SRAM_DRD_CMD_REG: u32 = REG_SPI_MEM_BASE + 0x48; - const SPI_MEM_MISC_REG: u32 = REG_SPI_MEM_BASE + 0x34; - - const SPI_MEM_USR_SRAM_DIO_M: u32 = 1 << 1; - const SPI_MEM_USR_SRAM_QIO_M: u32 = 1 << 2; - const SPI_MEM_CACHE_SRAM_USR_RCMD_M: u32 = 1 << 5; - const SPI_MEM_CACHE_SRAM_USR_WCMD_M: u32 = 1 << 20; - const SPI_MEM_SRAM_ADDR_BITLEN_V: u32 = 0x3f; - const SPI_MEM_SRAM_ADDR_BITLEN_S: u32 = 14; - const SPI_MEM_USR_RD_SRAM_DUMMY_M: u32 = 1 << 4; - const SPI_MEM_CACHE_SRAM_USR_WR_CMD_BITLEN: u32 = 0x0000000F; - const SPI_MEM_CACHE_SRAM_USR_WR_CMD_BITLEN_S: u32 = 28; - const SPI_MEM_CACHE_SRAM_USR_WR_CMD_VALUE: u32 = 0x0000FFFF; const PSRAM_QUAD_WRITE: u32 = 0x38; - const SPI_MEM_CACHE_SRAM_USR_WR_CMD_VALUE_S: u32 = 0; - const SPI_MEM_CACHE_SRAM_USR_RD_CMD_BITLEN_V: u32 = 0xF; - const SPI_MEM_CACHE_SRAM_USR_RD_CMD_BITLEN_S: u32 = 28; - const SPI_MEM_CACHE_SRAM_USR_RD_CMD_VALUE_V: u32 = 0xFFFF; const PSRAM_FAST_READ_QUAD: u32 = 0xEB; - const SPI_MEM_CACHE_SRAM_USR_RD_CMD_VALUE_S: u32 = 0; - const SPI_MEM_SRAM_RDUMMY_CYCLELEN_V: u32 = 0xFF; const PSRAM_FAST_READ_QUAD_DUMMY: u32 = 0x5; - const SPI_MEM_SRAM_RDUMMY_CYCLELEN_S: u32 = 6; - const SPI_MEM_CS1_DIS_M: u32 = 1 << 1; - fn clear_peri_reg_mask(reg: u32, mask: u32) { - unsafe { - (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() & !mask); - } + unsafe { + let spi = &*crate::peripherals::SPI0::PTR; + + spi.cache_sctrl() + .modify(|_, w| w.usr_sram_dio().clear_bit()); // disable dio mode for cache command + + spi.cache_sctrl().modify(|_, w| w.usr_sram_qio().set_bit()); // enable qio mode for cache command + + spi.cache_sctrl() + .modify(|_, w| w.cache_sram_usr_rcmd().set_bit()); // enable cache read command + + spi.cache_sctrl() + .modify(|_, w| w.cache_sram_usr_wcmd().set_bit()); // enable cache write command + + // write address for cache command. + spi.cache_sctrl() + .modify(|_, w| w.sram_addr_bitlen().bits(23)); + + spi.cache_sctrl() + .modify(|_, w| w.usr_rd_sram_dummy().set_bit()); // enable cache read dummy + + // config sram cache r/w command + spi.sram_dwr_cmd() + .modify(|_, w| w.cache_sram_usr_wr_cmd_bitlen().bits(7)); + + spi.sram_dwr_cmd().modify(|_, w| { + w.cache_sram_usr_wr_cmd_bitlen() + .bits(PSRAM_QUAD_WRITE as u8) + }); + + spi.sram_dwr_cmd().modify(|_, w| { + w.cache_sram_usr_wr_cmd_value() + .bits(PSRAM_QUAD_WRITE as u16) + }); + + spi.sram_drd_cmd() + .modify(|_, w| w.cache_sram_usr_rd_cmd_bitlen().bits(7)); + + spi.sram_drd_cmd().modify(|_, w| { + w.cache_sram_usr_rd_cmd_value() + .bits(PSRAM_FAST_READ_QUAD as u16) + }); + + // dummy, psram cache : 40m--+1dummy,80m--+2dummy + spi.cache_sctrl().modify(|_, w| { + w.sram_rdummy_cyclelen() + .bits((PSRAM_FAST_READ_QUAD_DUMMY + extra_dummy) as u8) + }); + + // ESP-IDF has some code here to deal with `!CONFIG_FREERTOS_UNICORE` - not + // needed for ESP32-S2 + + // ENABLE SPI0 CS1 TO PSRAM(CS0--FLASH; CS1--SRAM) + spi.misc().modify(|_, w| w.cs1_dis().clear_bit()); } - - 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), - ); - } - } - - clear_peri_reg_mask(SPI_MEM_CACHE_SCTRL_REG, SPI_MEM_USR_SRAM_DIO_M); // disable dio mode for cache command - set_peri_reg_mask(SPI_MEM_CACHE_SCTRL_REG, SPI_MEM_USR_SRAM_QIO_M); // enable qio mode for cache command - set_peri_reg_mask(SPI_MEM_CACHE_SCTRL_REG, SPI_MEM_CACHE_SRAM_USR_RCMD_M); // enable cache read command - set_peri_reg_mask(SPI_MEM_CACHE_SCTRL_REG, SPI_MEM_CACHE_SRAM_USR_WCMD_M); // enable cache write command - set_peri_reg_bits( - SPI_MEM_CACHE_SCTRL_REG, - SPI_MEM_SRAM_ADDR_BITLEN_V, - 23, - SPI_MEM_SRAM_ADDR_BITLEN_S, - ); // write address for cache command. - set_peri_reg_mask(SPI_MEM_CACHE_SCTRL_REG, SPI_MEM_USR_RD_SRAM_DUMMY_M); // enable cache read dummy - - // config sram cache r/w command - set_peri_reg_bits( - SPI_MEM_SRAM_DWR_CMD_REG, - SPI_MEM_CACHE_SRAM_USR_WR_CMD_BITLEN, - 7, - SPI_MEM_CACHE_SRAM_USR_WR_CMD_BITLEN_S, - ); - set_peri_reg_bits( - SPI_MEM_SRAM_DWR_CMD_REG, - SPI_MEM_CACHE_SRAM_USR_WR_CMD_VALUE, - PSRAM_QUAD_WRITE, - SPI_MEM_CACHE_SRAM_USR_WR_CMD_VALUE_S, - ); // 0x38 - set_peri_reg_bits( - SPI_MEM_SRAM_DRD_CMD_REG, - SPI_MEM_CACHE_SRAM_USR_RD_CMD_BITLEN_V, - 7, - SPI_MEM_CACHE_SRAM_USR_RD_CMD_BITLEN_S, - ); - set_peri_reg_bits( - SPI_MEM_SRAM_DRD_CMD_REG, - SPI_MEM_CACHE_SRAM_USR_RD_CMD_VALUE_V, - PSRAM_FAST_READ_QUAD, - SPI_MEM_CACHE_SRAM_USR_RD_CMD_VALUE_S, - ); // 0x0b - set_peri_reg_bits( - SPI_MEM_CACHE_SCTRL_REG, - SPI_MEM_SRAM_RDUMMY_CYCLELEN_V, - PSRAM_FAST_READ_QUAD_DUMMY + extra_dummy, - SPI_MEM_SRAM_RDUMMY_CYCLELEN_S, - ); // dummy, psram cache : 40m--+1dummy,80m--+2dummy - - // ESP-IDF has some code here to deal with `!CONFIG_FREERTOS_UNICORE` - not - // needed for ESP32-S2 - - // ENABLE SPI0 CS1 TO PSRAM(CS0--FLASH; CS1--SRAM) - clear_peri_reg_mask(SPI_MEM_MISC_REG, SPI_MEM_CS1_DIS_M); } fn psram_clock_set(freqdiv: i8) { - const REG_SPI_MEM_BASE: u32 = 0x3f403000; - const SPI_MEM_SRAM_CLK_REG: u32 = REG_SPI_MEM_BASE + 0x50; - - const SPI_MEM_SCLK_EQU_SYSCLK: u32 = 1 << 31; const SPI_MEM_SCLKCNT_N_S: u32 = 16; const SPI_MEM_SCLKCNT_H_S: u32 = 8; const SPI_MEM_SCLKCNT_L_S: u32 = 0; - fn write_peri_reg(reg: u32, val: u32) { - unsafe { - (reg as *mut u32).write_volatile(val); - } - } + let spi = unsafe { &*crate::peripherals::SPI0::PTR }; if 1 >= freqdiv { - write_peri_reg(SPI_MEM_SRAM_CLK_REG, SPI_MEM_SCLK_EQU_SYSCLK); + spi.sram_clk().modify(|_, w| w.sclk_equ_sysclk().set_bit()); } else { let freqbits: u32 = (((freqdiv - 1) as u32) << SPI_MEM_SCLKCNT_N_S) | (((freqdiv / 2 - 1) as u32) << SPI_MEM_SCLKCNT_H_S) | (((freqdiv - 1) as u32) << SPI_MEM_SCLKCNT_L_S); - write_peri_reg(SPI_MEM_SRAM_CLK_REG, freqbits); + unsafe { + spi.sram_clk().modify(|_, w| w.bits(freqbits)); + } } } } diff --git a/esp-hal/src/soc/esp32s3/psram.rs b/esp-hal/src/soc/esp32s3/psram.rs index bf8e4dd46..f9f986af9 100644 --- a/esp-hal/src/soc/esp32s3/psram.rs +++ b/esp-hal/src/soc/esp32s3/psram.rs @@ -244,47 +244,9 @@ pub(crate) mod utils { const ESP_ROM_EFUSE_FLASH_DEFAULT_SPI: u32 = 0; const SPICS1_OUT_IDX: u8 = 6; - const DR_REG_SPI0_BASE: u32 = 0x60003000; - const SPI0_MEM_SPI_SMEM_AC_REG: u32 = DR_REG_SPI0_BASE + 0xDC; - const SPI_MEM_SPI_SMEM_CS_HOLD_TIME_V: u32 = 0x1F; - const SPI_MEM_SPI_SMEM_CS_HOLD_TIME_S: u32 = 7; - const SPI_MEM_SPI_SMEM_CS_SETUP_TIME_V: u32 = 0x1F; - const SPI_MEM_SPI_SMEM_CS_SETUP_TIME_S: u32 = 2; - const SPI_MEM_SPI_SMEM_CS_HOLD_M: u32 = 1 << 1; - const SPI_MEM_SPI_SMEM_CS_SETUP_M: u32 = 1 << 0; - const SPI0_MEM_CACHE_SCTRL_REG: u32 = DR_REG_SPI0_BASE + 0x40; - const SPI0_MEM_SRAM_DWR_CMD_REG: u32 = DR_REG_SPI0_BASE + 0x4C; - const SPI0_MEM_SRAM_DRD_CMD_REG: u32 = DR_REG_SPI0_BASE + 0x48; - const SPI_MEM_USR_SRAM_DIO_M: u32 = 1 << 1; - const SPI_MEM_USR_SRAM_QIO_M: u32 = 1 << 2; - const SPI_MEM_CACHE_SRAM_USR_RCMD_M: u32 = 1 << 5; - const SPI_MEM_CACHE_SRAM_USR_WCMD_M: u32 = 1 << 20; - const SPI_MEM_CACHE_SRAM_USR_WR_CMD_BITLEN: u32 = 0x0000000F; - const SPI_MEM_CACHE_SRAM_USR_WR_CMD_BITLEN_S: u32 = 28; - const SPI_MEM_CACHE_SRAM_USR_WR_CMD_VALUE: u32 = 0x0000FFFF; - const SPI_MEM_CACHE_SRAM_USR_WR_CMD_VALUE_S: u32 = 0; const PSRAM_QUAD_WRITE: u32 = 0x38; - const SPI_MEM_CACHE_SRAM_USR_RD_CMD_BITLEN_V: u32 = 0xF; - const SPI_MEM_CACHE_SRAM_USR_RD_CMD_BITLEN_S: u32 = 28; - const SPI_MEM_CACHE_SRAM_USR_RD_CMD_VALUE_V: u32 = 0xFFFF; const PSRAM_FAST_READ_QUAD: u32 = 0xEB; - const SPI_MEM_CACHE_SRAM_USR_RD_CMD_VALUE_S: u32 = 0; - const SPI_MEM_SRAM_ADDR_BITLEN_V: u32 = 0x3F; - const SPI_MEM_SRAM_ADDR_BITLEN_S: u32 = 14; - const SPI_MEM_USR_RD_SRAM_DUMMY_M: u32 = 1 << 4; - const SPI_MEM_SRAM_RDUMMY_CYCLELEN_V: u32 = 0x3F; const PSRAM_FAST_READ_QUAD_DUMMY: u32 = 6; - const SPI_MEM_SRAM_RDUMMY_CYCLELEN_S: u32 = 6; - const SPI0_MEM_MISC_REG: u32 = DR_REG_SPI0_BASE + 0x34; - const SPI_MEM_CS1_DIS_M: u32 = 1 << 1; - const SPI0_MEM_CORE_CLK_SEL_REG: u32 = DR_REG_SPI0_BASE + 0xEC; - const SPI_MEM_CORE_CLK_SEL: u32 = 0x00000003; - const DR_REG_SPI1_BASE: u32 = 0x60002000; - const SPI0_MEM_CLOCK_REG: u32 = DR_REG_SPI0_BASE + 0x14; - const SPI1_MEM_CLOCK_REG: u32 = DR_REG_SPI1_BASE + 0x14; - const SPI0_MEM_SRAM_CLK_REG: u32 = DR_REG_SPI0_BASE + 0x50; - const SPI_MEM_CLK_EQU_SYSCLK: u32 = 1 << 31; - const SPI_MEM_SCLK_EQU_SYSCLK: u32 = 1 << 31; const SPI_MEM_CLKCNT_N_S: u32 = 16; const SPI_MEM_SCLKCNT_N_S: u32 = 16; const SPI_MEM_CLKCNT_H_S: u32 = 8; @@ -327,57 +289,55 @@ pub(crate) mod utils { // requirement #[ram] fn config_psram_spi_phases() { - // Config CMD phase - clear_peri_reg_mask(SPI0_MEM_CACHE_SCTRL_REG, SPI_MEM_USR_SRAM_DIO_M); // disable dio mode for cache command - set_peri_reg_mask(SPI0_MEM_CACHE_SCTRL_REG, SPI_MEM_USR_SRAM_QIO_M); // enable qio mode for cache command - set_peri_reg_mask(SPI0_MEM_CACHE_SCTRL_REG, SPI_MEM_CACHE_SRAM_USR_RCMD_M); // enable cache read command - set_peri_reg_mask(SPI0_MEM_CACHE_SCTRL_REG, SPI_MEM_CACHE_SRAM_USR_WCMD_M); // enable cache write command - set_peri_reg_bits( - SPI0_MEM_SRAM_DWR_CMD_REG, - SPI_MEM_CACHE_SRAM_USR_WR_CMD_BITLEN, - 7, - SPI_MEM_CACHE_SRAM_USR_WR_CMD_BITLEN_S, - ); - set_peri_reg_bits( - SPI0_MEM_SRAM_DWR_CMD_REG, - SPI_MEM_CACHE_SRAM_USR_WR_CMD_VALUE, - PSRAM_QUAD_WRITE, - SPI_MEM_CACHE_SRAM_USR_WR_CMD_VALUE_S, - ); // 0x38 - set_peri_reg_bits( - SPI0_MEM_SRAM_DRD_CMD_REG, - SPI_MEM_CACHE_SRAM_USR_RD_CMD_BITLEN_V, - 7, - SPI_MEM_CACHE_SRAM_USR_RD_CMD_BITLEN_S, - ); - set_peri_reg_bits( - SPI0_MEM_SRAM_DRD_CMD_REG, - SPI_MEM_CACHE_SRAM_USR_RD_CMD_VALUE_V, - PSRAM_FAST_READ_QUAD, - SPI_MEM_CACHE_SRAM_USR_RD_CMD_VALUE_S, - ); // 0xEB + unsafe { + let spi = &*crate::peripherals::SPI0::PTR; + // Config CMD phase + spi.cache_sctrl() + .modify(|_, w| w.usr_sram_dio().clear_bit()); // disable dio mode for cache command - // Config ADDR phase - set_peri_reg_bits( - SPI0_MEM_CACHE_SCTRL_REG, - SPI_MEM_SRAM_ADDR_BITLEN_V, - 23, - SPI_MEM_SRAM_ADDR_BITLEN_S, - ); + spi.cache_sctrl().modify(|_, w| w.usr_sram_qio().set_bit()); // enable qio mode for cache command - // Dummy - // We set the PSRAM chip required dummy here. If timing tuning is - // needed, the dummy length will be updated in - // `mspi_timing_enter_high_speed_mode()` - set_peri_reg_mask(SPI0_MEM_CACHE_SCTRL_REG, SPI_MEM_USR_RD_SRAM_DUMMY_M); // enable cache read dummy - set_peri_reg_bits( - SPI0_MEM_CACHE_SCTRL_REG, - SPI_MEM_SRAM_RDUMMY_CYCLELEN_V, - PSRAM_FAST_READ_QUAD_DUMMY - 1, - SPI_MEM_SRAM_RDUMMY_CYCLELEN_S, - ); // dummy + spi.cache_sctrl() + .modify(|_, w| w.cache_sram_usr_rcmd().set_bit()); // enable cache read command - clear_peri_reg_mask(SPI0_MEM_MISC_REG, SPI_MEM_CS1_DIS_M); // ENABLE SPI0 CS1 TO PSRAM(CS0--FLASH; CS1--SRAM) + spi.cache_sctrl() + .modify(|_, w| w.cache_sram_usr_wcmd().set_bit()); // enable cache write command + + spi.sram_dwr_cmd() + .modify(|_, w| w.cache_sram_usr_wr_cmd_bitlen().bits(7)); + + spi.sram_dwr_cmd().modify(|_, w| { + w.cache_sram_usr_wr_cmd_value() + .bits(PSRAM_QUAD_WRITE as u16) + }); + + spi.sram_drd_cmd() + .modify(|_, w| w.cache_sram_usr_rd_cmd_bitlen().bits(7)); + + spi.sram_drd_cmd().modify(|_, w| { + w.cache_sram_usr_rd_cmd_value() + .bits(PSRAM_FAST_READ_QUAD as u16) + }); + + // Config ADDR phase + spi.cache_sctrl() + .modify(|_, w| w.sram_addr_bitlen().bits(23)); + + // Dummy + // We set the PSRAM chip required dummy here. If timing tuning is + // needed, the dummy length will be updated in + // `mspi_timing_enter_high_speed_mode()` + spi.cache_sctrl() + .modify(|_, w| w.usr_rd_sram_dummy().set_bit()); // enable cache read dummy + + spi.cache_sctrl().modify(|_, w| { + w.sram_rdummy_cyclelen() + .bits((PSRAM_FAST_READ_QUAD_DUMMY - 1) as u8) + }); + + // ENABLE SPI0 CS1 TO PSRAM(CS0--FLASH; CS1--SRAM) + spi.misc().modify(|_, w| w.cs1_dis().clear_bit()); + } } #[ram] @@ -424,49 +384,61 @@ pub(crate) mod utils { #[ram] fn spi0_timing_config_set_core_clock(core_clock: SpiTimingConfigCoreClock) { - let reg_val = match core_clock { - SpiTimingConfigCoreClock::SpiTimingConfigCoreClock80m => 0, - SpiTimingConfigCoreClock::SpiTimingConfigCoreClock120m => 1, - SpiTimingConfigCoreClock::SpiTimingConfigCoreClock160m => 2, - SpiTimingConfigCoreClock::SpiTimingConfigCoreClock240m => 3, - }; - - set_peri_reg_bits(SPI0_MEM_CORE_CLK_SEL_REG, SPI_MEM_CORE_CLK_SEL, reg_val, 0); + unsafe { + let spi = &*crate::peripherals::SPI0::PTR; + spi.core_clk_sel().modify(|_, w| { + w.core_clk_sel().bits(match core_clock { + SpiTimingConfigCoreClock::SpiTimingConfigCoreClock80m => 0, + SpiTimingConfigCoreClock::SpiTimingConfigCoreClock120m => 1, + SpiTimingConfigCoreClock::SpiTimingConfigCoreClock160m => 2, + SpiTimingConfigCoreClock::SpiTimingConfigCoreClock240m => 3, + }) + }); + } } #[ram] fn spi0_timing_config_set_flash_clock(freqdiv: u32) { + let spi = unsafe { &*crate::peripherals::SPI0::PTR }; if freqdiv == 1 { - write_peri_reg(SPI0_MEM_CLOCK_REG, SPI_MEM_CLK_EQU_SYSCLK); + spi.clock().modify(|_, w| w.clk_equ_sysclk().set_bit()); } else { let freqbits: u32 = ((freqdiv - 1) << SPI_MEM_CLKCNT_N_S) | ((freqdiv / 2 - 1) << SPI_MEM_CLKCNT_H_S) | ((freqdiv - 1) << SPI_MEM_CLKCNT_L_S); - write_peri_reg(SPI0_MEM_CLOCK_REG, freqbits); + unsafe { + spi.clock().modify(|_, w| w.bits(freqbits)); + } } } #[ram] fn spi1_timing_config_set_flash_clock(freqdiv: u32) { + let spi = unsafe { &*crate::peripherals::SPI1::PTR }; if freqdiv == 1 { - write_peri_reg(SPI1_MEM_CLOCK_REG, SPI_MEM_CLK_EQU_SYSCLK); + spi.clock().modify(|_, w| w.clk_equ_sysclk().set_bit()); } else { let freqbits: u32 = ((freqdiv - 1) << SPI_MEM_CLKCNT_N_S) | ((freqdiv / 2 - 1) << SPI_MEM_CLKCNT_H_S) | ((freqdiv - 1) << SPI_MEM_CLKCNT_L_S); - write_peri_reg(SPI1_MEM_CLOCK_REG, freqbits); + unsafe { + spi.clock().modify(|_, w| w.bits(freqbits)); + } } } #[ram] fn spi0_timing_config_set_psram_clock(freqdiv: u32) { + let spi = unsafe { &*crate::peripherals::SPI0::PTR }; if freqdiv == 1 { - write_peri_reg(SPI0_MEM_SRAM_CLK_REG, SPI_MEM_SCLK_EQU_SYSCLK); + spi.sram_clk().modify(|_, w| w.sclk_equ_sysclk().set_bit()); } else { let freqbits: u32 = ((freqdiv - 1) << SPI_MEM_SCLKCNT_N_S) | ((freqdiv / 2 - 1) << SPI_MEM_SCLKCNT_H_S) | ((freqdiv - 1) << SPI_MEM_SCLKCNT_L_S); - write_peri_reg(SPI0_MEM_SRAM_CLK_REG, freqbits); + unsafe { + spi.sram_clk().modify(|_, w| w.bits(freqbits)); + } } } @@ -702,24 +674,19 @@ pub(crate) mod utils { #[ram] fn psram_set_cs_timing() { - // 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( - SPI0_MEM_SPI_SMEM_AC_REG, - SPI_MEM_SPI_SMEM_CS_HOLD_TIME_V, - 0, - SPI_MEM_SPI_SMEM_CS_HOLD_TIME_S, - ); - set_peri_reg_bits( - SPI0_MEM_SPI_SMEM_AC_REG, - SPI_MEM_SPI_SMEM_CS_SETUP_TIME_V, - 0, - SPI_MEM_SPI_SMEM_CS_SETUP_TIME_S, - ); - set_peri_reg_mask( - SPI0_MEM_SPI_SMEM_AC_REG, - SPI_MEM_SPI_SMEM_CS_HOLD_M | SPI_MEM_SPI_SMEM_CS_SETUP_M, - ); + unsafe { + let spi = &*crate::peripherals::SPI0::PTR; + // 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 + spi.spi_smem_ac() + .modify(|_, w| w.spi_smem_cs_hold_time().bits(0)); + spi.spi_smem_ac() + .modify(|_, w| w.spi_smem_cs_setup_time().bits(0)); + spi.spi_smem_ac() + .modify(|_, w| w.spi_smem_cs_hold().set_bit()); + spi.spi_smem_ac() + .modify(|_, w| w.spi_smem_cs_setup().set_bit()); + } } #[ram] @@ -760,37 +727,6 @@ pub(crate) mod utils { esp_rom_spiflash_select_qio_pins(wp_io, spiconfig); } } - - #[inline(always)] - fn clear_peri_reg_mask(reg: u32, mask: u32) { - unsafe { - (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() & !mask); - } - } - - #[inline(always)] - fn set_peri_reg_mask(reg: u32, mask: u32) { - unsafe { - (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() | mask); - } - } - - #[inline(always)] - 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), - ); - } - } - - #[inline(always)] - fn write_peri_reg(reg: u32, val: u32) { - unsafe { - (reg as *mut u32).write_volatile(val); - } - } } #[cfg(any( @@ -877,71 +813,12 @@ pub(crate) mod utils { const SPI_CS1_GPIO_NUM: u8 = 26; const FUNC_SPICS1_SPICS1: u8 = 0; - const SPI1_MEM_DDR_REG: u32 = DR_REG_SPI1_BASE + 0xe0; - const SPI_MEM_SPI_FMEM_VAR_DUMMY: u32 = 1 << 1; - - const DR_REG_SPI0_BASE: u32 = 0x60003000; - const SPI0_MEM_SPI_SMEM_AC_REG: u32 = DR_REG_SPI0_BASE + 0xDC; - const SPI_MEM_SPI_SMEM_CS_HOLD_TIME_V: u32 = 0x1F; - const SPI_MEM_SPI_SMEM_CS_HOLD_TIME_S: u32 = 7; - const SPI_MEM_SPI_SMEM_CS_SETUP_TIME_V: u32 = 0x1F; - const SPI_MEM_SPI_SMEM_CS_SETUP_TIME_S: u32 = 2; - const SPI_MEM_SPI_SMEM_CS_HOLD_M: u32 = 1 << 1; - const SPI_MEM_SPI_SMEM_CS_SETUP_M: u32 = 1 << 0; - const SPI0_MEM_CACHE_SCTRL_REG: u32 = DR_REG_SPI0_BASE + 0x40; - const SPI0_MEM_SRAM_DWR_CMD_REG: u32 = DR_REG_SPI0_BASE + 0x4C; - const SPI0_MEM_SRAM_DRD_CMD_REG: u32 = DR_REG_SPI0_BASE + 0x48; - const SPI_MEM_CACHE_SRAM_USR_RCMD_M: u32 = 1 << 5; - const SPI_MEM_CACHE_SRAM_USR_WCMD_M: u32 = 1 << 20; - const SPI_MEM_CACHE_SRAM_USR_WR_CMD_BITLEN: u32 = 0x0000000F; - const SPI_MEM_CACHE_SRAM_USR_WR_CMD_BITLEN_S: u32 = 28; - const SPI_MEM_CACHE_SRAM_USR_WR_CMD_VALUE: u32 = 0x0000FFFF; - const SPI_MEM_CACHE_SRAM_USR_WR_CMD_VALUE_S: u32 = 0; - const SPI_MEM_CACHE_SRAM_USR_RD_CMD_BITLEN_V: u32 = 0xF; - const SPI_MEM_CACHE_SRAM_USR_RD_CMD_BITLEN_S: u32 = 28; - const SPI_MEM_CACHE_SRAM_USR_RD_CMD_VALUE_V: u32 = 0xFFFF; - const SPI_MEM_CACHE_SRAM_USR_RD_CMD_VALUE_S: u32 = 0; - const SPI_MEM_SRAM_ADDR_BITLEN_V: u32 = 0x3F; - const SPI_MEM_SRAM_ADDR_BITLEN_S: u32 = 14; - const SPI_MEM_USR_RD_SRAM_DUMMY_M: u32 = 1 << 4; - const SPI_MEM_SRAM_RDUMMY_CYCLELEN_V: u32 = 0x3F; - const SPI_MEM_SRAM_RDUMMY_CYCLELEN_S: u32 = 6; - const SPI0_MEM_CORE_CLK_SEL_REG: u32 = DR_REG_SPI0_BASE + 0xEC; - const SPI_MEM_CORE_CLK_SEL: u32 = 0x00000003; - const DR_REG_SPI1_BASE: u32 = 0x60002000; - const SPI0_MEM_DATE_REG: u32 = DR_REG_SPI0_BASE + 0x3FC; - const SPI0_MEM_CLOCK_REG: u32 = DR_REG_SPI0_BASE + 0x14; - const SPI1_MEM_CLOCK_REG: u32 = DR_REG_SPI1_BASE + 0x14; - const SPI0_MEM_SRAM_CLK_REG: u32 = DR_REG_SPI0_BASE + 0x50; - const SPI_MEM_CLK_EQU_SYSCLK: u32 = 1 << 31; - const SPI_MEM_SCLK_EQU_SYSCLK: u32 = 1 << 31; const SPI_MEM_CLKCNT_N_S: u32 = 16; const SPI_MEM_SCLKCNT_N_S: u32 = 16; const SPI_MEM_CLKCNT_H_S: u32 = 8; const SPI_MEM_SCLKCNT_H_S: u32 = 8; const SPI_MEM_CLKCNT_L_S: u32 = 0; const SPI_MEM_SCLKCNT_L_S: u32 = 0; - const SPI_MEM_CACHE_USR_SCMD_4BYTE_M: u32 = 1 << 0; - const SPI_MEM_USR_WR_SRAM_DUMMY_M: u32 = 1 << 3; - const SPI0_MEM_SPI_SMEM_DDR_REG: u32 = DR_REG_SPI0_BASE + 0xE4; - const SPI0_MEM_SRAM_CMD_REG: u32 = DR_REG_SPI0_BASE + 0x44; - const SPI_MEM_SPI_SMEM_VAR_DUMMY_M: u32 = 1 << 1; - const SPI_MEM_SRAM_WDUMMY_CYCLELEN_V: u32 = 0x3F; - const SPI_MEM_SRAM_WDUMMY_CYCLELEN_S: u32 = 22; - const SPI_MEM_SPI_SMEM_DDR_WDAT_SWP_M: u32 = 1 << 3; - const SPI_MEM_SPI_SMEM_DDR_RDAT_SWP_M: u32 = 1 << 2; - const SPI_MEM_SPI_SMEM_DDR_EN_M: u32 = 1 << 0; - const SPI_MEM_SDUMMY_OUT_M: u32 = 1 << 22; - const SPI_MEM_SCMD_OCT_M: u32 = 1 << 21; - const SPI_MEM_SADDR_OCT_M: u32 = 1 << 20; - const SPI_MEM_SDOUT_OCT_M: u32 = 1 << 19; - const SPI_MEM_SDIN_OCT_M: u32 = 1 << 18; - const SPI_MEM_SRAM_OCT_M: u32 = 1 << 21; - const SPI_MEM_SPI_SMEM_CS_HOLD_DELAY_V: u32 = 0x3F; - const SPI_MEM_SPI_SMEM_CS_HOLD_DELAY_S: u32 = 25; - const SPI_MEM_SPI_SMEM_SPICLK_FUN_DRV: u32 = 0x00000003; - const SPI_MEM_SPI_SMEM_SPICLK_FUN_DRV_V: u32 = 0x3; - const SPI_MEM_SPI_SMEM_SPICLK_FUN_DRV_S: u32 = 0; const ESP_ROM_SPIFLASH_OPI_DTR_MODE: u8 = 7; extern "C" { @@ -1200,9 +1077,10 @@ pub(crate) mod utils { // enter MSPI slow mode to init PSRAM device registers spi_timing_enter_mspi_low_speed_mode(true); - // set to variable dummy mode - set_peri_reg_mask(SPI1_MEM_DDR_REG, SPI_MEM_SPI_FMEM_VAR_DUMMY); unsafe { + // set to variable dummy mode + let spi = &*crate::peripherals::SPI1::PTR; + spi.ddr().modify(|_, w| w.spi_fmem_var_dummy().set_bit()); esp_rom_spi_set_dtr_swap_mode(1, false, false); } @@ -1258,85 +1136,67 @@ pub(crate) mod utils { // Configure PSRAM SPI0 phase related registers here according to the PSRAM chip // requirement fn config_psram_spi_phases() { - // Config Write CMD phase for SPI0 to access PSRAM - set_peri_reg_mask(SPI0_MEM_CACHE_SCTRL_REG, SPI_MEM_CACHE_SRAM_USR_WCMD_M); - set_peri_reg_bits( - SPI0_MEM_SRAM_DWR_CMD_REG, - SPI_MEM_CACHE_SRAM_USR_WR_CMD_BITLEN, - (OCT_PSRAM_WR_CMD_BITLEN - 1) as u32, - SPI_MEM_CACHE_SRAM_USR_WR_CMD_BITLEN_S, - ); - set_peri_reg_bits( - SPI0_MEM_SRAM_DWR_CMD_REG, - SPI_MEM_CACHE_SRAM_USR_WR_CMD_VALUE, - OPI_PSRAM_SYNC_WRITE as u32, - SPI_MEM_CACHE_SRAM_USR_WR_CMD_VALUE_S, - ); + unsafe { + let spi = &*crate::peripherals::SPI0::PTR; + // Config Write CMD phase for SPI0 to access PSRAM + spi.cache_sctrl() + .modify(|_, w| w.cache_sram_usr_wcmd().set_bit()); - // Config Read CMD phase for SPI0 to access PSRAM - set_peri_reg_mask(SPI0_MEM_CACHE_SCTRL_REG, SPI_MEM_CACHE_SRAM_USR_RCMD_M); - set_peri_reg_bits( - SPI0_MEM_SRAM_DRD_CMD_REG, - SPI_MEM_CACHE_SRAM_USR_RD_CMD_BITLEN_V, - (OCT_PSRAM_RD_CMD_BITLEN - 1) as u32, - SPI_MEM_CACHE_SRAM_USR_RD_CMD_BITLEN_S, - ); - set_peri_reg_bits( - SPI0_MEM_SRAM_DRD_CMD_REG, - SPI_MEM_CACHE_SRAM_USR_RD_CMD_VALUE_V, - OPI_PSRAM_SYNC_READ as u32, - SPI_MEM_CACHE_SRAM_USR_RD_CMD_VALUE_S, - ); + spi.sram_dwr_cmd().modify(|_, w| { + w.cache_sram_usr_wr_cmd_bitlen() + .bits(OCT_PSRAM_WR_CMD_BITLEN - 1) + }); + spi.sram_dwr_cmd() + .modify(|_, w| w.cache_sram_usr_wr_cmd_value().bits(OPI_PSRAM_SYNC_WRITE)); - // Config ADDR phase - set_peri_reg_bits( - SPI0_MEM_CACHE_SCTRL_REG, - SPI_MEM_SRAM_ADDR_BITLEN_V, - (OCT_PSRAM_ADDR_BITLEN - 1) as u32, - SPI_MEM_SRAM_ADDR_BITLEN_S, - ); - set_peri_reg_mask(SPI0_MEM_CACHE_SCTRL_REG, SPI_MEM_CACHE_USR_SCMD_4BYTE_M); + // Config Read CMD phase for SPI0 to access PSRAM + spi.cache_sctrl() + .modify(|_, w| w.cache_sram_usr_rcmd().set_bit()); - // Config RD/WR Dummy phase - set_peri_reg_mask( - SPI0_MEM_CACHE_SCTRL_REG, - SPI_MEM_USR_RD_SRAM_DUMMY_M | SPI_MEM_USR_WR_SRAM_DUMMY_M, - ); - set_peri_reg_bits( - SPI0_MEM_CACHE_SCTRL_REG, - SPI_MEM_SRAM_RDUMMY_CYCLELEN_V, - (OCT_PSRAM_RD_DUMMY_BITLEN - 1) as u32, - SPI_MEM_SRAM_RDUMMY_CYCLELEN_S, - ); - set_peri_reg_mask(SPI0_MEM_SPI_SMEM_DDR_REG, SPI_MEM_SPI_SMEM_VAR_DUMMY_M); - set_peri_reg_bits( - SPI0_MEM_CACHE_SCTRL_REG, - SPI_MEM_SRAM_WDUMMY_CYCLELEN_V, - (OCT_PSRAM_WR_DUMMY_BITLEN - 1) as u32, - SPI_MEM_SRAM_WDUMMY_CYCLELEN_S, - ); + spi.sram_drd_cmd().modify(|_, w| { + w.cache_sram_usr_rd_cmd_bitlen() + .bits(OCT_PSRAM_RD_CMD_BITLEN - 1) + }); + spi.sram_drd_cmd() + .modify(|_, w| w.cache_sram_usr_rd_cmd_value().bits(OPI_PSRAM_SYNC_READ)); - clear_peri_reg_mask( - SPI0_MEM_SPI_SMEM_DDR_REG, - SPI_MEM_SPI_SMEM_DDR_WDAT_SWP_M | SPI_MEM_SPI_SMEM_DDR_RDAT_SWP_M, - ); - set_peri_reg_mask(SPI0_MEM_SPI_SMEM_DDR_REG, SPI_MEM_SPI_SMEM_DDR_EN_M); + // Config ADDR phase + spi.cache_sctrl() + .modify(|_, w| w.sram_addr_bitlen().bits(OCT_PSRAM_ADDR_BITLEN - 1)); + spi.cache_sctrl() + .modify(|_, w| w.cache_usr_scmd_4byte().set_bit()); - set_peri_reg_mask( - SPI0_MEM_SRAM_CMD_REG, - SPI_MEM_SDUMMY_OUT_M - | SPI_MEM_SCMD_OCT_M - | SPI_MEM_SADDR_OCT_M - | SPI_MEM_SDOUT_OCT_M - | SPI_MEM_SDIN_OCT_M, - ); - set_peri_reg_mask(SPI0_MEM_CACHE_SCTRL_REG, SPI_MEM_SRAM_OCT_M); + // Config RD/WR Dummy phase + spi.cache_sctrl() + .modify(|_, w| w.usr_rd_sram_dummy().set_bit()); + spi.cache_sctrl() + .modify(|_, w| w.usr_wr_sram_dummy().set_bit()); + spi.cache_sctrl() + .modify(|_, w| w.sram_rdummy_cyclelen().bits(OCT_PSRAM_RD_DUMMY_BITLEN - 1)); + spi.spi_smem_ddr() + .modify(|_, w| w.spi_smem_var_dummy().set_bit()); + spi.cache_sctrl() + .modify(|_, w| w.sram_wdummy_cyclelen().bits(OCT_PSRAM_WR_DUMMY_BITLEN - 1)); + + spi.spi_smem_ddr().modify(|_, w| w.wdat_swp().clear_bit()); + spi.spi_smem_ddr().modify(|_, w| w.rdat_swp().clear_bit()); + spi.spi_smem_ddr().modify(|_, w| w.en().set_bit()); + + spi.sram_cmd().modify(|_, w| w.sdummy_out().set_bit()); + spi.sram_cmd().modify(|_, w| w.scmd_oct().set_bit()); + spi.sram_cmd().modify(|_, w| w.saddr_oct().set_bit()); + spi.sram_cmd().modify(|_, w| w.sdout_oct().set_bit()); + spi.sram_cmd().modify(|_, w| w.sdin_oct().set_bit()); + + spi.cache_sctrl().modify(|_, w| w.sram_oct().set_bit()) + } } #[ram] fn spi_flash_set_rom_required_regs() { // Disable the variable dummy mode when doing timing tuning - clear_peri_reg_mask(SPI1_MEM_DDR_REG, SPI_MEM_SPI_FMEM_VAR_DUMMY); + let spi = unsafe { &*crate::peripherals::SPI1::PTR }; + spi.ddr().modify(|_, w| w.spi_fmem_var_dummy().clear_bit()) // STR /DTR mode setting is done every time when // `esp_rom_opiflash_exec_cmd` is called // @@ -1357,33 +1217,25 @@ pub(crate) mod utils { fn spi_timing_set_pin_drive_strength() { // For now, set them all to 3. Need to check after QVL test results are out. // TODO: IDF-3663 Set default clk - set_peri_reg_mask(SPI0_MEM_DATE_REG, SPI_MEM_SPICLK_PAD_DRV_CTL_EN); - set_peri_reg_bits( - SPI0_MEM_DATE_REG, - SPI_MEM_SPI_SMEM_SPICLK_FUN_DRV, - 3, - SPI_MEM_SPI_SMEM_SPICLK_FUN_DRV_S, - ); - set_peri_reg_bits( - SPI0_MEM_DATE_REG, - SPI_MEM_SPI_FMEM_SPICLK_FUN_DRV, - 3, - SPI_MEM_SPI_FMEM_SPICLK_FUN_DRV_S, - ); - // Set default mspi d0 ~ d7, dqs pin drive strength - let pins = &[27usize, 28, 31, 32, 33, 34, 35, 36, 37]; - for pin in pins { - unsafe { + unsafe { + let spi = &*crate::peripherals::SPI0::PTR; + + spi.date() + .modify(|_, w| w.spi_spiclk_pad_drv_ctl_en().set_bit()); + spi.date() + .modify(|_, w| w.spi_smem_spiclk_fun_drv().bits(3)); + spi.date() + .modify(|_, w| w.spi_fmem_spiclk_fun_drv().bits(3)); + + // Set default mspi d0 ~ d7, dqs pin drive strength + let pins = &[27usize, 28, 31, 32, 33, 34, 35, 36, 37]; + for pin in pins { let iomux = &*esp32s3::IO_MUX::PTR; iomux.gpio(*pin).modify(|_, w| w.fun_drv().bits(3)) } } } - const SPI_MEM_SPICLK_PAD_DRV_CTL_EN: u32 = 1 << 4; - const SPI_MEM_SPI_FMEM_SPICLK_FUN_DRV: u32 = 0x00000003; - const SPI_MEM_SPI_FMEM_SPICLK_FUN_DRV_S: u32 = 2; - fn spi_timing_enter_mspi_low_speed_mode(control_spi1: bool) { // Here we are going to slow the SPI1 frequency to 20Mhz, so we need to // set SPI1 din_num and din_mode regs. @@ -1439,33 +1291,26 @@ pub(crate) mod utils { } fn set_psram_cs_timing() { - // 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( - SPI0_MEM_SPI_SMEM_AC_REG, - SPI_MEM_SPI_SMEM_CS_HOLD_M | SPI_MEM_SPI_SMEM_CS_SETUP_M, - ); - set_peri_reg_bits( - SPI0_MEM_SPI_SMEM_AC_REG, - SPI_MEM_SPI_SMEM_CS_HOLD_TIME_V, - OCT_PSRAM_CS_HOLD_TIME as u32, - SPI_MEM_SPI_SMEM_CS_HOLD_TIME_S, - ); - set_peri_reg_bits( - SPI0_MEM_SPI_SMEM_AC_REG, - SPI_MEM_SPI_SMEM_CS_SETUP_TIME_V, - OCT_PSRAM_CS_SETUP_TIME as u32, - SPI_MEM_SPI_SMEM_CS_SETUP_TIME_S, - ); - // CONFIG_SPIRAM_ECC_ENABLE unsupported for now - // CS1 high time - set_peri_reg_bits( - SPI0_MEM_SPI_SMEM_AC_REG, - SPI_MEM_SPI_SMEM_CS_HOLD_DELAY_V, - OCT_PSRAM_CS_HOLD_DELAY as u32, - SPI_MEM_SPI_SMEM_CS_HOLD_DELAY_S, - ); + unsafe { + let spi = &*crate::peripherals::SPI0::PTR; + // 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 + spi.spi_smem_ac() + .modify(|_, w| w.spi_smem_cs_hold().set_bit()); + spi.spi_smem_ac() + .modify(|_, w| w.spi_smem_cs_setup().set_bit()); + + spi.spi_smem_ac() + .modify(|_, w| w.spi_smem_cs_hold_time().bits(OCT_PSRAM_CS_HOLD_TIME)); + spi.spi_smem_ac() + .modify(|_, w| w.spi_smem_cs_setup_time().bits(OCT_PSRAM_CS_SETUP_TIME)); + + // CONFIG_SPIRAM_ECC_ENABLE unsupported for now + // CS1 high time + spi.spi_smem_ac() + .modify(|_, w| w.spi_smem_cs_hold_delay().bits(OCT_PSRAM_CS_HOLD_DELAY)); + } } fn init_psram_pins() { @@ -1486,12 +1331,11 @@ pub(crate) mod utils { } // Set psram clock pin drive strength - set_peri_reg_bits( - SPI0_MEM_DATE_REG, - SPI_MEM_SPI_SMEM_SPICLK_FUN_DRV_V, - 3, - SPI_MEM_SPI_SMEM_SPICLK_FUN_DRV_S, - ); + unsafe { + let spi = &*crate::peripherals::SPI0::PTR; + spi.date() + .modify(|_, w| w.spi_smem_spiclk_fun_drv().bits(3)); + } } fn get_psram_mode_reg(spi_num: u32, out_reg: &mut OpiPsramModeReg) { @@ -1729,49 +1573,62 @@ pub(crate) mod utils { #[ram] fn spi0_timing_config_set_core_clock(core_clock: SpiTimingConfigCoreClock) { - let reg_val = match core_clock { - SpiTimingConfigCoreClock::SpiTimingConfigCoreClock80m => 0, - SpiTimingConfigCoreClock::SpiTimingConfigCoreClock120m => 1, - SpiTimingConfigCoreClock::SpiTimingConfigCoreClock160m => 2, - SpiTimingConfigCoreClock::SpiTimingConfigCoreClock240m => 3, - }; + let spi = unsafe { &*crate::peripherals::SPI0::PTR }; - set_peri_reg_bits(SPI0_MEM_CORE_CLK_SEL_REG, SPI_MEM_CORE_CLK_SEL, reg_val, 0); + unsafe { + spi.core_clk_sel().modify(|_, w| { + w.core_clk_sel().bits(match core_clock { + SpiTimingConfigCoreClock::SpiTimingConfigCoreClock80m => 0, + SpiTimingConfigCoreClock::SpiTimingConfigCoreClock120m => 1, + SpiTimingConfigCoreClock::SpiTimingConfigCoreClock160m => 2, + SpiTimingConfigCoreClock::SpiTimingConfigCoreClock240m => 3, + }) + }); + } } #[ram] fn spi0_timing_config_set_flash_clock(freqdiv: u32) { + let spi = unsafe { &*crate::peripherals::SPI0::PTR }; if freqdiv == 1 { - write_peri_reg(SPI0_MEM_CLOCK_REG, SPI_MEM_CLK_EQU_SYSCLK); + spi.clock().modify(|_, w| w.clk_equ_sysclk().set_bit()); } else { let freqbits: u32 = ((freqdiv - 1) << SPI_MEM_CLKCNT_N_S) | ((freqdiv / 2 - 1) << SPI_MEM_CLKCNT_H_S) | ((freqdiv - 1) << SPI_MEM_CLKCNT_L_S); - write_peri_reg(SPI0_MEM_CLOCK_REG, freqbits); + unsafe { + spi.clock().modify(|_, w| w.bits(freqbits)); + } } } #[ram] fn spi1_timing_config_set_flash_clock(freqdiv: u32) { + let spi = unsafe { &*crate::peripherals::SPI1::PTR }; if freqdiv == 1 { - write_peri_reg(SPI1_MEM_CLOCK_REG, SPI_MEM_CLK_EQU_SYSCLK); + spi.clock().modify(|_, w| w.clk_equ_sysclk().set_bit()); } else { let freqbits: u32 = ((freqdiv - 1) << SPI_MEM_CLKCNT_N_S) | ((freqdiv / 2 - 1) << SPI_MEM_CLKCNT_H_S) | ((freqdiv - 1) << SPI_MEM_CLKCNT_L_S); - write_peri_reg(SPI1_MEM_CLOCK_REG, freqbits); + unsafe { + spi.clock().modify(|_, w| w.bits(freqbits)); + } } } #[ram] fn spi0_timing_config_set_psram_clock(freqdiv: u32) { + let spi = unsafe { &*crate::peripherals::SPI0::PTR }; if freqdiv == 1 { - write_peri_reg(SPI0_MEM_SRAM_CLK_REG, SPI_MEM_SCLK_EQU_SYSCLK); + spi.sram_clk().modify(|_, w| w.sclk_equ_sysclk().set_bit()); } else { let freqbits: u32 = ((freqdiv - 1) << SPI_MEM_SCLKCNT_N_S) | ((freqdiv / 2 - 1) << SPI_MEM_SCLKCNT_H_S) | ((freqdiv - 1) << SPI_MEM_SCLKCNT_L_S); - write_peri_reg(SPI0_MEM_SRAM_CLK_REG, freqbits); + unsafe { + spi.sram_clk().modify(|_, w| w.bits(freqbits)); + } } } @@ -1793,35 +1650,4 @@ pub(crate) mod utils { SpiRamFreq::Freq120m => SPI_TIMING_CORE_CLOCK.mhz() / 120, } } - - #[inline(always)] - fn clear_peri_reg_mask(reg: u32, mask: u32) { - unsafe { - (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() & !mask); - } - } - - #[inline(always)] - fn set_peri_reg_mask(reg: u32, mask: u32) { - unsafe { - (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() | mask); - } - } - - #[inline(always)] - 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), - ); - } - } - - #[inline(always)] - fn write_peri_reg(reg: u32, val: u32) { - unsafe { - (reg as *mut u32).write_volatile(val); - } - } } diff --git a/esp-hal/src/soc/esp32s3/trng.rs b/esp-hal/src/soc/esp32s3/trng.rs index 2b194225b..c67933c8f 100644 --- a/esp-hal/src/soc/esp32s3/trng.rs +++ b/esp-hal/src/soc/esp32s3/trng.rs @@ -1,5 +1,3 @@ -const DR_REG_SYSCON_BASE: u32 = 0x60026000; -const SYSTEM_WIFI_CLK_EN_REG: u32 = DR_REG_SYSCON_BASE + 0x14; const SYSTEM_WIFI_CLK_RNG_EN: u32 = 1 << 15; const I2C_SAR_ADC: u8 = 0x69; @@ -20,14 +18,20 @@ const ADC_SARADC_DTEST_RTC_ADDR_LSB: u32 = 0; use crate::regi2c_write_mask; pub(crate) fn ensure_randomness() { - let rtc_cntl = unsafe { &*crate::peripherals::RTC_CNTL::ptr() }; - let system = unsafe { &*crate::peripherals::SYSTEM::ptr() }; - let apb_saradc = unsafe { &*crate::peripherals::APB_SARADC::ptr() }; - let sens = unsafe { &*crate::peripherals::SENS::ptr() }; - unsafe { - // Temporarily `WIFI_CLK_RNG_EN` is not in PACs - set_peri_reg_mask(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_RNG_EN); + let rtc_cntl = &*crate::peripherals::RTC_CNTL::ptr(); + let system = &*crate::peripherals::SYSTEM::ptr(); + let apb_saradc = &*crate::peripherals::APB_SARADC::ptr(); + let sens = &*crate::peripherals::SENS::ptr(); + let syscon = &*crate::peripherals::APB_CTRL::ptr(); + + // `wifi_clk_en` register is defined in a really weird way, for now just simple + // bit edit + syscon.wifi_clk_en().modify(|r, w| { + let current_bits = r.bits(); + let new_bits = current_bits | SYSTEM_WIFI_CLK_RNG_EN; + w.bits(new_bits) + }); // Enable 8M clock source for RNG (this is actually enough to produce strong // random results, but enabling the SAR ADC as well adds some insurance.) @@ -141,9 +145,3 @@ pub fn revert_trng() { .modify(|_, w| w.apb_saradc_rst().set_bit()); } } - -fn set_peri_reg_mask(reg: u32, mask: u32) { - unsafe { - (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() | mask); - } -}