diff options
Diffstat (limited to 'ble/src/uarte1.rs')
-rw-r--r-- | ble/src/uarte1.rs | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/ble/src/uarte1.rs b/ble/src/uarte1.rs new file mode 100644 index 0000000..61d631e --- /dev/null +++ b/ble/src/uarte1.rs @@ -0,0 +1,85 @@ +use log::info; +use nrf52840_hal::uarte::{self, Uarte}; +use starb::{Reader, RingBuffer, Writer}; + +static mut RB: RingBuffer<u8> = RingBuffer::new(0); + +pub fn setup<I>(mut uarte: Uarte<I>) -> (Reader<'static, u8>, impl FnMut()) +where + I: uarte::Instance, +{ + uarte.0.intenset.write(|w| { + w.endrx().set_bit(); + w.error().set_bit(); + w.rxto().set_bit(); + w.rxstarted().set_bit() + }); + + let mut buf: [u8; 255] = [0; 255]; + uarte + .0 + .rxd + .ptr + .write(|w| unsafe { w.ptr().bits(buf.as_mut_ptr() as _) }); + uarte + .0 + .rxd + .maxcnt + .write(|w| unsafe { w.maxcnt().bits(buf.len() as _) }); + uarte.0.tasks_startrx.write(|w| w.tasks_startrx().set_bit()); + let (rbr, mut rbw) = unsafe { RB.split() }; + + // start rx into a buffer. it would be nice if we could do this + // with rxrdy or something like i2c does. + let cl = move || handler(&mut uarte, &mut rbw, &mut buf); + (rbr, cl) +} + +fn handler<I>(uarte: &mut Uarte<I>, writer: &mut Writer<u8>, buf: &mut [u8]) +where + I: uarte::Instance, +{ + if uarte.0.events_endrx.read().events_endrx().bit_is_set() { + uarte.0.events_endrx.write(|w| w.events_endrx().clear_bit()); + + // Copy DMA buffer to ring buffer. + let len = uarte.0.rxd.amount.read().amount().bits(); + info!("endrx - {}", len); + for i in 0..len { + writer.unshift(buf[i as usize]).ok(); + } + + // Reset the DMA buffer. TODO: this is probably unneccesary. + uarte + .0 + .rxd + .ptr + .write(|w| unsafe { w.ptr().bits(buf.as_mut_ptr() as _) }); + uarte + .0 + .rxd + .maxcnt + .write(|w| unsafe { w.maxcnt().bits(buf.len() as _) }); + + // restart the read. + uarte.0.tasks_startrx.write(|w| w.tasks_startrx().set_bit()); + } else if uarte.0.events_error.read().events_error().bit_is_set() { + uarte.0.events_error.write(|w| w.events_error().clear_bit()); + info!("error: {:b}", uarte.0.errorsrc.read().bits()); + } else if uarte.0.events_rxto.read().events_rxto().bit_is_set() { + uarte.0.events_rxto.write(|w| w.events_rxto().clear_bit()); + info!("rxto"); + } else if uarte + .0 + .events_rxstarted + .read() + .events_rxstarted() + .bit_is_set() + { + uarte + .0 + .events_rxstarted + .write(|w| w.events_rxstarted().clear_bit()); + info!("rxstarted"); + } +} |