mirror of
https://github.com/italicsjenga/rp-hal-boards.git
synced 2024-12-23 20:51:31 +11:00
Add SIO FIFO interface.
This commit is contained in:
parent
23bafb6980
commit
68014469dd
|
@ -24,6 +24,11 @@ pub struct SioGpioBank0 {
|
|||
_private: (),
|
||||
}
|
||||
|
||||
/// Marker struct for ownership of SIO FIFO
|
||||
pub struct SioFifo {
|
||||
_private: (),
|
||||
}
|
||||
|
||||
/// Marker struct for ownership of SIO gpio qspi
|
||||
pub struct SioGpioQspi {
|
||||
_private: (),
|
||||
|
@ -51,6 +56,8 @@ pub struct Sio {
|
|||
pub gpio_qspi: SioGpioQspi,
|
||||
/// 8-cycle hardware divide/modulo module
|
||||
pub hwdivider: HwDivider,
|
||||
/// Inter-core FIFO
|
||||
pub fifo: SioFifo,
|
||||
// we can hand out other things here, for example:
|
||||
// interp0
|
||||
// interp1
|
||||
|
@ -60,15 +67,92 @@ impl Sio {
|
|||
pub fn new(sio: pac::SIO) -> Self {
|
||||
Self {
|
||||
_sio: sio,
|
||||
|
||||
gpio_bank0: SioGpioBank0 { _private: () },
|
||||
gpio_qspi: SioGpioQspi { _private: () },
|
||||
|
||||
fifo: SioFifo { _private: () },
|
||||
hwdivider: HwDivider { _private: () },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SioFifo {
|
||||
/// Check if the inter-core FIFO has valid data for reading.
|
||||
///
|
||||
/// Returning `true` means there is valid data, `false` means it is empty
|
||||
/// and you must not read from it.
|
||||
pub fn is_read_ready(&mut self) -> bool {
|
||||
let sio = unsafe { &(*pac::SIO::ptr()) };
|
||||
sio.fifo_st.read().vld().bit_is_set()
|
||||
}
|
||||
|
||||
/// Check if the inter-core FIFO is ready to receive data.
|
||||
///
|
||||
/// Returning `true` means there is room, `false` means it is full and you
|
||||
/// must not write to it.
|
||||
pub fn is_write_ready(&mut self) -> bool {
|
||||
let sio = unsafe { &(*pac::SIO::ptr()) };
|
||||
sio.fifo_st.read().rdy().bit_is_set()
|
||||
}
|
||||
|
||||
/// Return the FIFO status, as an integer.
|
||||
pub fn status(&self) -> u32 {
|
||||
let sio = unsafe { &(*pac::SIO::ptr()) };
|
||||
sio.fifo_st.read().bits()
|
||||
}
|
||||
|
||||
/// Write to the inter-core FIFO.
|
||||
///
|
||||
/// You must ensure the FIFO has space by calling `is_write_ready`
|
||||
pub fn write(&mut self, value: u32) {
|
||||
let sio = unsafe { &(*pac::SIO::ptr()) };
|
||||
sio.fifo_wr.write(|w| unsafe { w.bits(value) });
|
||||
}
|
||||
|
||||
/// Read from the inter-core FIFO.
|
||||
///
|
||||
/// Will return `Some(data)`, or `None` if the FIFO is empty.
|
||||
pub fn read(&mut self) -> Option<u32> {
|
||||
if self.is_read_ready() {
|
||||
let sio = unsafe { &(*pac::SIO::ptr()) };
|
||||
Some(sio.fifo_rd.read().bits())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Read from the FIFO until it is empty, throwing the contents away.
|
||||
pub fn drain(&mut self) {
|
||||
while let Some(_) = self.read() {
|
||||
// Spin until FIFO empty
|
||||
}
|
||||
}
|
||||
|
||||
/// Push to the FIFO, spinning if there's no space.
|
||||
pub fn write_blocking(&mut self, value: u32) {
|
||||
// We wait for the FIFO to have some space
|
||||
while !self.is_write_ready() {
|
||||
cortex_m::asm::wfe();
|
||||
}
|
||||
|
||||
// Write the value to the FIFO - the other core will now be able to pop it
|
||||
// off its end of the FIFO.
|
||||
self.write(value as u32);
|
||||
|
||||
// Fire off an event to the other core
|
||||
cortex_m::asm::sev();
|
||||
}
|
||||
|
||||
/// Pop from the FIFO, spinning if there's currently no data.
|
||||
pub fn read_blocking(&mut self) -> u32 {
|
||||
// Spin until FIFO has data
|
||||
loop {
|
||||
if let Some(data) = self.read() {
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl HwDivider {
|
||||
/// Perform hardware unsigned divide/modulo operation
|
||||
pub fn unsigned(&self, dividend: u32, divisor: u32) -> DivResult<u32> {
|
||||
|
|
Loading…
Reference in a new issue