summaryrefslogtreecommitdiffstats
path: root/ble/src/uarte1.rs
diff options
context:
space:
mode:
Diffstat (limited to 'ble/src/uarte1.rs')
-rw-r--r--ble/src/uarte1.rs85
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");
+ }
+}