Skip to content

Commit

Permalink
Merge pull request #10 from jakezhu9/psram/refactor
Browse files Browse the repository at this point in the history
psram: refactor psram initialization code into bouffalo-hal
  • Loading branch information
luojia65 authored Nov 29, 2024
2 parents cb44ca1 + d93bd26 commit 968b949
Show file tree
Hide file tree
Showing 8 changed files with 119 additions and 702 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/Cargo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:
matrix:
TARGET: [riscv64imac-unknown-none-elf]
TOOLCHAIN: [nightly]
EXAMPLES: [gpio-demo, i2c-demo, jtag-demo, lz4d-demo, pwm-demo,
EXAMPLES: [gpio-demo, i2c-demo, jtag-demo, lz4d-demo, psram-demo, pwm-demo,
sdcard-demo, sdcard-gpt-demo, spi-demo, uart-demo]
steps:
- uses: actions/checkout@v4
Expand Down
46 changes: 43 additions & 3 deletions bouffalo-hal/src/glb/v2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,16 @@ pub struct RegisterBlock {
// TODO: clock_config_0, clock_config_2, clock_config_3 registers
/// Clock generation configuration 1.
pub clock_config_1: RW<ClockConfig1>,
_reserved6: [u8; 0x33c],
_reserved6: [u8; 0x148],
/// LDO12UHS config.
pub ldo12uhs_config: RW<Ldo12uhsConfig>,
_reserved7: [u8; 0x1f0],
/// Generic Purpose Input/Output config.
pub gpio_config: [RW<GpioConfig>; 46],
_reserved7: [u8; 0x148],
_reserved8: [u8; 0x148],
/// Read value from Generic Purpose Input/Output pads.
pub gpio_input: [RO<u32>; 2],
_reserved8: [u8; 0x18],
_reserved9: [u8; 0x18],
/// Write value to Generic Purpose Input/Output pads.
pub gpio_output: [RW<u32>; 2],
/// Set pin output value to high.
Expand Down Expand Up @@ -778,6 +781,42 @@ pub enum Pull {
Down = 2,
}

/// Ldo12uhs configuration register.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
#[repr(transparent)]
pub struct Ldo12uhsConfig(u32);

impl Ldo12uhsConfig {
const POWER: u32 = 0x1 << 0;
const VOUT_SEL: u32 = 0xf << 20;

/// Power up LDO12UHS.
#[inline]
pub const fn power_up(self) -> Self {
Self(self.0 | Self::POWER)
}
/// Power down LDO12UHS.
#[inline]
pub const fn power_down(self) -> Self {
Self(self.0 & !Self::POWER)
}
/// Check if LDO12UHS is powered up.
#[inline]
pub const fn is_powered_up(self) -> bool {
self.0 & Self::POWER != 0
}
/// Set output voltage of LDO12UHS.
#[inline]
pub const fn set_output_voltage(self, val: u8) -> Self {
Self((self.0 & !Self::VOUT_SEL) | ((val as u32) << 20))
}
/// Get output voltage of LDO12UHS.
#[inline]
pub const fn get_output_voltage(self) -> u8 {
((self.0 & Self::VOUT_SEL) >> 20) as u8
}
}

#[cfg(test)]
mod tests {
use crate::glb::v2::SpiClockSource;
Expand All @@ -798,6 +837,7 @@ mod tests {
assert_eq!(offset_of!(RegisterBlock, pwm_config), 0x1d0);
assert_eq!(offset_of!(RegisterBlock, param_config), 0x510);
assert_eq!(offset_of!(RegisterBlock, clock_config_1), 0x584);
assert_eq!(offset_of!(RegisterBlock, ldo12uhs_config), 0x6d0);
assert_eq!(offset_of!(RegisterBlock, gpio_config), 0x8c4);
assert_eq!(offset_of!(RegisterBlock, gpio_input), 0xac4);
assert_eq!(offset_of!(RegisterBlock, gpio_output), 0xae4);
Expand Down
1 change: 1 addition & 0 deletions bouffalo-hal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ pub mod i2s;
pub mod ir;
pub mod jtag;
pub mod lz4d;
pub mod psram;
pub mod pwm;
pub mod sdio;
pub mod spi;
Expand Down
65 changes: 65 additions & 0 deletions bouffalo-hal/src/psram.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
//! Pseudo Static Random Access Memory.
use crate::glb;
use volatile_register::RW;

/// Pseudo Static Random Access Memory registers.
#[repr(C)]
pub struct RegisterBlock {
/// Basic configuration register.
pub basic_config: RW<u32>,
_reserved0: [u8; 0x1C],
/// Psram configuration register.
pub psram_config: RW<u32>,
_reserved1: [u8; 0xDC],
/// Phy configuration register.
pub phy_config: [RW<u32>; 21],
}

/// Initializes the PSRAM.
#[inline]
pub fn init_psram(psram: &RegisterBlock, glb: &glb::v2::RegisterBlock) {
unsafe {
glb.ldo12uhs_config
.modify(|w| w.power_up().set_output_voltage(6));

// configuration value reference: https://github.com/bouffalolab/bouffalo_sdk/blob/master/drivers/soc/bl808/std/src/bl808_psram_uhs.c
psram.basic_config.write(0xB03F0403);
psram.psram_config.write(0x00000023);

psram.phy_config[0].write(0x60290200);
psram.phy_config[1].write(0x50205020);
psram.phy_config[2].write(0x50025002);
psram.phy_config[3].write(0x50025002);
psram.phy_config[4].write(0x50025002);
psram.phy_config[5].write(0x50025002);
psram.phy_config[6].write(0x50025002);
psram.phy_config[7].write(0x50025002);
psram.phy_config[8].write(0x50025002);
psram.phy_config[9].write(0x50025002);
psram.phy_config[10].write(0x34000000);
psram.phy_config[11].write(0x34000006);
psram.phy_config[12].write(0x0F271222);
psram.phy_config[13].write(0x09020303);
psram.phy_config[14].write(0x050E0418);
psram.phy_config[15].write(0x0A6A1C1C);
psram.phy_config[16].write(0xA2FF0000);
psram.phy_config[17].write(0x07110710);
psram.phy_config[18].write(0x00208A08);
psram.phy_config[19].write(0x00000000);
psram.phy_config[20].write(0x01334433);
}
}

#[cfg(test)]
mod tests {
use super::RegisterBlock;
use memoffset::offset_of;

#[test]
fn struct_register_block_offset() {
assert_eq!(offset_of!(RegisterBlock, basic_config), 0x0);
assert_eq!(offset_of!(RegisterBlock, psram_config), 0x20);
assert_eq!(offset_of!(RegisterBlock, phy_config), 0x100);
}
}
5 changes: 4 additions & 1 deletion bouffalo-rt/src/soc/bl808.rs
Original file line number Diff line number Diff line change
Expand Up @@ -812,6 +812,8 @@ pub struct Peripherals {
pub plic: PLIC,
/// Multi-media subsystem global peripheral.
pub mmglb: MMGLB,
/// Pseudo Static Random Access Memory controller.
pub psram: PSRAM,
}

soc! {
Expand Down Expand Up @@ -847,7 +849,8 @@ soc! {
pub struct MMGLB => 0x30007000, bouffalo_hal::glb::mm::RegisterBlock;
/// Serial Peripheral Interface peripheral 1.
pub struct SPI1 => 0x30008000, bouffalo_hal::spi::RegisterBlock;

/// Pseudo Static Random Access Memory controller.
pub struct PSRAM => 0x3000F000, bouffalo_hal::psram::RegisterBlock;
/// Platform-local Interrupt Controller.
pub struct PLIC => 0xE0000000, plic::Plic;
}
Expand Down
1 change: 1 addition & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
| `i2c-demo` ||
| `jtag-demo` ||
| `lz4d-demo` ||
| `psram-demo` ||
| `pwm-demo` ||
| `sdcard-demo` ||
| `sdcard-gpt-demo` ||
Expand Down
30 changes: 4 additions & 26 deletions examples/peripherals/psram-demo/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,10 @@

use core::{arch::asm, ptr};

use bouffalo_hal::{prelude::*, uart::Config};
use bouffalo_hal::{prelude::*, psram::init_psram, uart::Config};
use bouffalo_rt::{entry, Clocks, Peripherals};
use embedded_time::rate::*;
use panic_halt as _;
use psram::*;

mod psram;

#[entry]
fn main(p: Peripherals, c: Clocks) -> ! {
Expand All @@ -27,8 +24,7 @@ fn main(p: Peripherals, c: Clocks) -> ! {
let mut serial = p.uart0.freerun(config, ((tx, sig2), (rx, sig3)), &c);
writeln!(serial, "Welcome to psram-demo🦀!").ok();

uhs_psram_init();
writeln!(serial, "uhs_psram_init success").ok();
init_psram(&p.psram, &p.glb);

const MEMORY_SIZE: usize = 64 * 1024 * 1024;
const START_ADDRESS: u32 = 0x50000000;
Expand Down Expand Up @@ -95,29 +91,11 @@ fn main(p: Peripherals, c: Clocks) -> ! {
}

#[inline]
pub(crate) fn read_memory(addr: u32) -> u32 {
pub fn read_memory(addr: u32) -> u32 {
unsafe { ptr::read_volatile(addr as *const u32) }
}

#[inline]
pub(crate) fn write_memory(addr: u32, val: u32) {
pub fn write_memory(addr: u32, val: u32) {
unsafe { ptr::write_volatile(addr as *mut u32, val) }
}

#[inline]
pub(crate) fn set_bits(val: u32, pos: u32, len: u32, val_in: u32) -> u32 {
let mask = ((1 << len) - 1) << pos;
(val & !mask) | ((val_in << pos) & mask)
}

#[inline]
pub(crate) fn sleep_us(_: u32) {
for _ in 0..1000 {
unsafe { asm!("nop") }
}
}

#[inline]
pub(crate) fn sleep_ms(n: u32) {
sleep_us(n);
}
Loading

0 comments on commit 968b949

Please sign in to comment.