//! Single Cycle Input and Output (SIO) //! //! To be able to partition parts of the SIO block to other modules: //! //! ```no_run //! use rp2040_hal::{gpio::Pins, pac, sio::Sio}; //! //! let mut peripherals = pac::Peripherals::take().unwrap(); //! let sio = Sio::new(peripherals.SIO); //! ``` //! //! And then for example //! //! ```no_run //! # use rp2040_hal::{gpio::Pins, pac, sio::Sio}; //! # let mut peripherals = pac::Peripherals::take().unwrap(); //! # let sio = Sio::new(peripherals.SIO); //! let pins = Pins::new(peripherals.IO_BANK0, peripherals.PADS_BANK0, sio.gpio_bank0, &mut peripherals.RESETS); //! ``` use super::*; /// Marker struct for ownership of SIO gpio bank0 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 { /// 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, /// 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. 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 { let sio = unsafe { &(*pac::SIO::ptr()) }; sio.div_udividend.write(|w| unsafe { w.bits(dividend) }); sio.div_udivisor.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 { 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, } } }