-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ASIC-specific SysCtrl drivers & examples (#60)
BSP: * Add -Fasic * Add ASIC specific UART memory map * impl UART for ASIC (untested) * Fancy HALs for soc_ctrl, gpio * Organize SysCtrl HAL & mmaps Examples: * LED: refactor for HAL * SysCtrl: give nops/sec calibration value * UART: use HAL * rm unused unsafe
- Loading branch information
Showing
12 changed files
with
349 additions
and
49 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,8 +2,26 @@ | |
pub(crate) const UART0_ADDR: usize = 0x1FFF00000; | ||
#[cfg(not(feature = "hpc"))] | ||
pub(crate) const UART0_ADDR: usize = 0xFFF00000; | ||
pub(crate) const UART0_THR: usize = UART0_ADDR; | ||
|
||
// NOTE: (20240614 [email protected]) This applies to renode NS16550 uart, but might not apply to headsail ASIC | ||
pub(crate) const UART_DATA_READY_OFFSET: usize = 5; | ||
|
||
#[cfg(feature = "asic")] | ||
mod asic_uart { | ||
use super::UART0_ADDR; | ||
|
||
pub(crate) const UART0_DIV_LSB: usize = UART0_ADDR + 0; | ||
pub(crate) const UART0_DIV_MSB: usize = UART0_ADDR + 1; | ||
pub(crate) const UART0_INTERRUPT_ENABLE: usize = UART0_ADDR + 1; | ||
pub(crate) const UART0_FIFO_CONTROL: usize = UART0_ADDR + 2; | ||
pub(crate) const UART0_LINE_CONTROL: usize = UART0_ADDR + 3; | ||
pub(crate) const UART0_MODEM_CONTROL: usize = UART0_ADDR + 4; | ||
pub(crate) const UART0_LINE_STATUS: usize = UART0_ADDR + 5; | ||
} | ||
#[cfg(feature = "asic")] | ||
pub(crate) use self::asic_uart::*; | ||
|
||
pub(crate) const TIMER0_ADDR: usize = 0x5_0000; | ||
pub(crate) const TIMER1_ADDR: usize = 0x5_0010; | ||
pub(crate) const TIMER2_ADDR: usize = 0x5_0020; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
use core::marker::PhantomData; | ||
|
||
use super::{mmap, soc_ctrl}; | ||
use crate::{mask_u32, toggle_u32, unmask_u32}; | ||
|
||
/// Type-state trait for GPIO in different states | ||
pub trait GpioState {} | ||
|
||
pub struct Uninit; | ||
impl GpioState for Uninit {} | ||
|
||
pub struct Input; | ||
impl GpioState for Input {} | ||
|
||
pub struct Output; | ||
impl GpioState for Output {} | ||
|
||
/// To obtain an instance: | ||
/// | ||
/// 1. Obtain [Pads] with [sysctrl::soc_ctrl::Pads::take] | ||
/// 2. Pick pin: `pads.p9` | ||
/// 3. Convert pin into GPIO [systcrl::soc_ctrl::Pad::into_gpio] | ||
pub struct Gpio<const IDX: u32, State: GpioState = Uninit> { | ||
_pd: PhantomData<State>, | ||
} | ||
|
||
pub type Gpio9<S> = Gpio<9, S>; | ||
|
||
#[repr(u32)] | ||
enum Dir { | ||
In = 0, | ||
Out = 1, | ||
} | ||
|
||
impl<const IDX: u32> Gpio<IDX, Uninit> { | ||
pub(crate) fn new() -> Self { | ||
Self { _pd: PhantomData } | ||
} | ||
|
||
pub fn into_input(self) -> Gpio<IDX, Input> { | ||
mask_u32(mmap::GPIO_DIR, Dir::In as u32); | ||
|
||
Gpio { _pd: PhantomData } | ||
} | ||
|
||
pub fn into_output(self) -> Gpio<IDX, Output> { | ||
mask_u32(mmap::GPIO_DIR, Dir::Out as u32); | ||
|
||
Gpio { _pd: PhantomData } | ||
} | ||
} | ||
|
||
impl<const IDX: u32> Gpio<IDX, Output> { | ||
pub fn toggle(&mut self) { | ||
toggle_u32(mmap::GPIO_OUT, 1 << IDX); | ||
} | ||
|
||
pub fn set_high(&mut self) { | ||
mask_u32(mmap::GPIO_OUT, 1 << IDX); | ||
} | ||
|
||
pub fn set_low(&mut self) { | ||
unmask_u32(mmap::GPIO_OUT, 1 << IDX); | ||
} | ||
} | ||
|
||
impl<const IDX: u32, S: GpioState> Gpio<IDX, S> { | ||
/// Release pad back to its original function | ||
/// | ||
/// Pins can be released in any state. GPIO register configurations will | ||
/// retain their state (until overridden again by HAL methods). | ||
pub fn release(self) -> soc_ctrl::Pad<IDX> { | ||
unmask_u32( | ||
if IDX <= 15 { | ||
mmap::PADMUX0 | ||
} else { | ||
mmap::PADMUX1 | ||
}, | ||
(soc_ctrl::PadFn::Gpio as u32) << (IDX * 2), | ||
); | ||
|
||
soc_ctrl::Pad::<IDX> {} | ||
} | ||
|
||
/// # Safety | ||
/// | ||
/// This will not configure the pin in any way (i.e., for use as GPIO or | ||
/// direction). | ||
pub unsafe fn steal() -> Self { | ||
Self { _pd: PhantomData } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
/// SysCtrl-specific memory maps | ||
pub(crate) const SYSCTRL_ADDR: usize = 0x1a10_0000; | ||
|
||
pub(crate) const GPIO_ADDR: usize = SYSCTRL_ADDR + 0x1000; | ||
pub(crate) const GPIO_DIR: usize = GPIO_ADDR + 0x0; | ||
pub(crate) const GPIO_OUT: usize = GPIO_ADDR + 0xc; | ||
|
||
pub(crate) const SOC_CONTROL_ADDR: usize = SYSCTRL_ADDR + 0x4000; | ||
pub(crate) const PADMUX0: usize = SOC_CONTROL_ADDR + 0x10; | ||
pub(crate) const PADMUX1: usize = SOC_CONTROL_ADDR + 0x14; | ||
|
||
pub(crate) const SS_RESET_EN: usize = SOC_CONTROL_ADDR + 0xb0; | ||
pub(crate) const SS_CLK_CTRL2: usize = SOC_CONTROL_ADDR + 0x9c; | ||
pub(crate) const SS_CLK_CTRL3: usize = SOC_CONTROL_ADDR + 0xb8; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,6 @@ | ||
//! Abstractions that only exist on SysCtrl | ||
pub mod gpio; | ||
pub mod soc_ctrl; | ||
|
||
mod interrupt; | ||
mod mmap; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
use riscv::interrupt; | ||
|
||
use super::{gpio::Gpio, mmap}; | ||
use crate::{mask_u32, write_u32}; | ||
|
||
#[repr(u32)] | ||
pub(crate) enum PadFn { | ||
//Default = 0, | ||
Gpio = 1, | ||
} | ||
|
||
/// ~Pin | ||
pub struct Pad<const IDX: u32> {} | ||
|
||
pub struct Pads { | ||
pub p0: Pad<0>, | ||
pub p1: Pad<1>, | ||
pub p2: Pad<2>, | ||
pub p3: Pad<3>, | ||
pub p4: Pad<4>, | ||
pub p5: Pad<5>, | ||
pub p6: Pad<6>, | ||
pub p7: Pad<7>, | ||
pub p8: Pad<8>, | ||
pub p9: Pad<9>, | ||
pub p10: Pad<10>, | ||
pub p11: Pad<11>, | ||
pub p12: Pad<12>, | ||
pub p13: Pad<13>, | ||
pub p14: Pad<14>, | ||
pub p15: Pad<15>, | ||
pub p16: Pad<16>, | ||
pub p17: Pad<17>, | ||
pub p18: Pad<18>, | ||
} | ||
|
||
/// Set to `true` when `take` or `steal` was called to make `Peripherals` a singleton. | ||
static mut PADS_TAKEN: bool = false; | ||
|
||
impl Pads { | ||
#[inline] | ||
pub fn take() -> Option<Self> { | ||
interrupt::free(|| { | ||
if unsafe { PADS_TAKEN } { | ||
None | ||
} else { | ||
Some(unsafe { Self::steal() }) | ||
} | ||
}) | ||
} | ||
|
||
#[inline] | ||
pub unsafe fn steal() -> Self { | ||
Self { | ||
p0: Pad {}, | ||
p1: Pad {}, | ||
p2: Pad {}, | ||
p3: Pad {}, | ||
p4: Pad {}, | ||
p5: Pad {}, | ||
p6: Pad {}, | ||
p7: Pad {}, | ||
p8: Pad {}, | ||
p9: Pad {}, | ||
p10: Pad {}, | ||
p11: Pad {}, | ||
p12: Pad {}, | ||
p13: Pad {}, | ||
p14: Pad {}, | ||
p15: Pad {}, | ||
p16: Pad {}, | ||
p17: Pad {}, | ||
p18: Pad {}, | ||
} | ||
} | ||
} | ||
|
||
impl<const IDX: u32> Pad<IDX> { | ||
pub fn into_gpio(self) -> Gpio<IDX> { | ||
mask_u32( | ||
if IDX <= 15 { | ||
mmap::PADMUX0 | ||
} else { | ||
mmap::PADMUX1 | ||
}, | ||
(PadFn::Gpio as u32) << (IDX * 2), | ||
); | ||
|
||
Gpio::<IDX>::new() | ||
} | ||
} | ||
|
||
pub fn ss_enable(ss_bits: u32) { | ||
write_u32(mmap::SS_RESET_EN, ss_bits); | ||
} | ||
|
||
pub fn clk2_set(conf_val: u32) { | ||
write_u32(mmap::SS_CLK_CTRL2, conf_val); | ||
} | ||
|
||
pub fn clk3_set(conf_val: u32) { | ||
write_u32(mmap::SS_CLK_CTRL3, conf_val); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.