mirror of
https://github.com/italicsjenga/rp-hal-boards.git
synced 2025-02-02 14:36:34 +11:00
Hardware divide/modulo support (#40)
* Initial SIO div/mod implementation * Implement signed/unsigned methods for HwDivider
This commit is contained in:
parent
9bef0821d9
commit
a14cbb5819
1 changed files with 61 additions and 7 deletions
|
@ -12,22 +12,34 @@
|
|||
//! let pins = pac.IO_BANK0.split(pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS);
|
||||
//! ```
|
||||
use super::*;
|
||||
use core::marker::PhantomData;
|
||||
|
||||
/// Marker struct for ownership of SIO gpio bank0
|
||||
pub struct SioGpioBank0 {
|
||||
_private: PhantomData<u32>,
|
||||
_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,
|
||||
}
|
||||
|
||||
/// Struct containing ownership markers for managing ownership of the SIO registers.
|
||||
pub struct Sio {
|
||||
_sio: pac::SIO,
|
||||
|
||||
/// GPIO Bank 0 registers
|
||||
pub gpio_bank0: SioGpioBank0,
|
||||
/// 8-cycle hardware divide/modulo module
|
||||
pub hwdivider: HwDivider,
|
||||
// we can hand out other things here, for example:
|
||||
// gpio_qspi
|
||||
// divider
|
||||
// interp0
|
||||
// interp1
|
||||
}
|
||||
|
@ -37,9 +49,51 @@ impl Sio {
|
|||
Self {
|
||||
_sio: sio,
|
||||
|
||||
gpio_bank0: SioGpioBank0 {
|
||||
_private: PhantomData,
|
||||
},
|
||||
gpio_bank0: SioGpioBank0 { _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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue