Add SIO FIFO interface.

This commit is contained in:
Jonathan Pallant 2021-11-19 17:19:04 +00:00
parent 23bafb6980
commit 68014469dd

View file

@ -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> {