rp-hal-boards/rp2040-hal/src/sio.rs

108 lines
2.8 KiB
Rust
Raw Normal View History

2021-05-10 23:29:59 +10:00
//! Single Cycle Input and Output (SIO)
//!
//! To be able to partition parts of the SIO block to other modules:
//!
//! ```rust
//! let mut peripherals = pac::Peripherals::take().unwrap();
//! let sio = Sio::new(peripherals.SIO);
//! ```
//!
//! And then for example
//!
//! ```rust
//! let pins = gpio:Pins::new(pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS);
//! ```
use super::*;
/// Marker struct for ownership of SIO gpio bank0
2021-05-10 23:29:59 +10:00
pub struct SioGpioBank0 {
_private: (),
}
/// Marker struct for ownership of SIO gpio qspi
pub struct SioGpioQspi {
_private: (),
}
/// Marker struct for ownership of divide/modulo module
pub struct HwDivider {
_private: (),
}
/// Result of divide/modulo operation
pub struct DivResult<T> {
/// The remainder of divide/modulo operation
pub remainder: T,
/// The quotient of divide/modulo operation
pub quotient: T,
2021-05-10 23:29:59 +10:00
}
/// Struct containing ownership markers for managing ownership of the SIO registers.
pub struct Sio {
2021-05-10 23:29:59 +10:00
_sio: pac::SIO,
/// GPIO Bank 0 registers
2021-05-10 23:29:59 +10:00
pub gpio_bank0: SioGpioBank0,
/// GPIO QSPI registers
pub gpio_qspi: SioGpioQspi,
/// 8-cycle hardware divide/modulo module
pub hwdivider: HwDivider,
// we can hand out other things here, for example:
// interp0
// interp1
}
impl Sio {
/// Create `Sio` from the PAC.
2021-05-10 23:29:59 +10:00
pub fn new(sio: pac::SIO) -> Self {
Self {
_sio: sio,
gpio_bank0: SioGpioBank0 { _private: () },
gpio_qspi: SioGpioQspi { _private: () },
hwdivider: HwDivider { _private: () },
}
}
}
impl HwDivider {
/// Perform hardware unsigned divide/modulo operation
pub fn unsigned(&self, dividend: u32, divisor: u32) -> DivResult<u32> {
let sio = unsafe { &(*pac::SIO::ptr()) };
sio.div_sdividend.write(|w| unsafe { w.bits(dividend) });
sio.div_sdivisor.write(|w| unsafe { w.bits(divisor) });
cortex_m::asm::delay(8);
// Note: quotient must be read last
let remainder = sio.div_remainder.read().bits();
let quotient = sio.div_quotient.read().bits();
DivResult {
remainder,
quotient,
}
}
/// Perform hardware signed divide/modulo operation
pub fn signed(&self, dividend: i32, divisor: i32) -> DivResult<i32> {
let sio = unsafe { &(*pac::SIO::ptr()) };
sio.div_sdividend
.write(|w| unsafe { w.bits(dividend as u32) });
sio.div_sdivisor
.write(|w| unsafe { w.bits(divisor as u32) });
cortex_m::asm::delay(8);
// Note: quotient must be read last
let remainder = sio.div_remainder.read().bits() as i32;
let quotient = sio.div_quotient.read().bits() as i32;
DivResult {
remainder,
quotient,
}
}
2021-05-10 23:29:59 +10:00
}