summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ble/src/main.rs53
-rw-r--r--ble/src/uarte1.rs85
2 files changed, 131 insertions, 7 deletions
diff --git a/ble/src/main.rs b/ble/src/main.rs
index 2da6de9..3c98b7e 100644
--- a/ble/src/main.rs
+++ b/ble/src/main.rs
@@ -7,13 +7,13 @@ mod i2c;
mod logger;
mod macros;
mod rtc;
+mod uarte1;
use clint::HandlerArray;
-use core::fmt::Write;
use core::mem;
use cortex_m::asm::wfi;
use cortex_m_rt::{entry, exception, ExceptionFrame};
-use log::{info, trace, LevelFilter};
+use log::{info, LevelFilter};
#[allow(unused_imports)]
extern crate panic_semihosting;
@@ -33,7 +33,6 @@ const I2C_ADDR: u8 = 4;
// TODO:
// * set up serial reader for trinket
-// * set up i²c interface for keyboard reports
// * and, finally, bluetooth
// Interrupt handler table.
@@ -53,7 +52,7 @@ fn main() -> ! {
let mut nvic = nrf52.NVIC;
let mut rtc_handler = rtc::setup(Rtc::new(nrf52.RTC0), Clocks::new(nrf52.CLOCK));
- let mut twis_handler = i2c::setup(Twis::new(
+ let (mut twis_reader, mut twis_handler) = i2c::setup(Twis::new(
I2C_ADDR,
nrf52.TWIS0,
twis::Pins {
@@ -68,27 +67,62 @@ fn main() -> ! {
.into_push_pull_output(Level::High)
.degrade();
let rxp = nrf52.pins.P0_25.into_floating_input().degrade();
- let mut uarte1 = uarte1(nrf52.UARTE1, txp, rxp);
+ let uarte1 = uarte1(nrf52.UARTE1, txp, rxp);
+ let (mut uarte1_reader, mut uarte1_handler) = uarte1::setup(uarte1);
HANDLERS.with_overrides(|hs| {
hs.register(0, &mut rtc_handler);
nvic.enable(Interrupt::RTC0);
hs.register(1, &mut twis_handler);
nvic.enable(Interrupt::SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0);
+ hs.register(2, &mut uarte1_handler);
+ nvic.enable(Interrupt::UARTE1);
info!("Bootstrap complete.");
let mut last_tick = rtc::millis();
last_tick -= last_tick % 1024;
+ let mut buf: [u8; 256] = [0; 256];
loop {
let tick = rtc::millis();
if tick >= last_tick + 1024 {
last_tick = tick;
last_tick -= last_tick % 1024;
- trace!(".");
- write!(uarte1, "!").expect("uarte1 write");
}
+ if !twis_reader.is_empty() {
+ let mut i = 0;
+ for b in &mut twis_reader {
+ if i == buf.len() {
+ info!("i²c data: {:?}", &buf[0..i]);
+ i = 0;
+ }
+ buf[i] = b;
+ i += 1;
+ }
+ info!("i²c data: {:?}", &buf[0..i]);
+ }
+
+ if !uarte1_reader.is_empty() {
+ let mut i = 0;
+ for b in &mut uarte1_reader {
+ if i == buf.len() {
+ info!(
+ "serial - {}: {}",
+ i,
+ core::str::from_utf8(&buf[0..i]).expect("utf8conv")
+ );
+ i = 0;
+ }
+ buf[i] = b;
+ i += 1;
+ }
+ info!(
+ "serial - {}: {}",
+ i,
+ core::str::from_utf8(&buf[0..i]).expect("utf8conv")
+ );
+ }
wfi();
}
});
@@ -132,3 +166,8 @@ fn RTC0() {
fn SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0() {
HANDLERS.call(1);
}
+
+#[interrupt]
+fn UARTE1() {
+ HANDLERS.call(2);
+}
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");
+ }
+}