use log::info; use nrf52840_hal::uarte::{self, Uarte}; use starb::{Reader, RingBuffer, Writer}; static mut RB: RingBuffer = RingBuffer::new(0); pub fn setup(mut uarte: Uarte) -> (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(uarte: &mut Uarte, writer: &mut Writer, 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"); } }