summaryrefslogtreecommitdiffstats
path: root/ble/src
diff options
context:
space:
mode:
Diffstat (limited to 'ble/src')
-rw-r--r--ble/src/ble.rs28
-rw-r--r--ble/src/i2c.rs2
-rw-r--r--ble/src/logger.rs34
-rw-r--r--ble/src/main.rs47
-rw-r--r--ble/src/uarte1.rs52
5 files changed, 102 insertions, 61 deletions
diff --git a/ble/src/ble.rs b/ble/src/ble.rs
new file mode 100644
index 0000000..e5f16cb
--- /dev/null
+++ b/ble/src/ble.rs
@@ -0,0 +1,28 @@
+use nrf52840_hal::target::{FICR, RADIO, TIMER0};
+use rubble::link::{AddressKind, DeviceAddress, HardwareInterface, LinkLayer, MIN_PDU_BUF};
+use rubble_nrf52::{radio::BleRadio, timer::BleTimer};
+
+struct NRF52840 {}
+impl HardwareInterface for NRF52840 {
+ type Timer = BleTimer<TIMER0>;
+ type Tx = BleRadio;
+}
+
+pub fn setup(radio: RADIO, timer: TIMER0, ficr: FICR) {
+ // make sure hfclock is started for timer0 to work at the right
+ // resolution.
+ let ble_timer = BleTimer::init(timer);
+ let mut devaddr = [0u8; 6];
+ let devaddr_lo = ficr.deviceaddr[0].read().bits();
+ let devaddr_hi = ficr.deviceaddr[1].read().bits();
+ devaddr[..4].clone_from_slice(&devaddr_lo.to_le_bytes());
+ devaddr[4..].clone_from_slice(&devaddr_hi.to_le_bytes());
+
+ let addrkind = if ficr.deviceaddrtype.read().deviceaddrtype().is_public() {
+ AddressKind::Public
+ } else {
+ AddressKind::Random
+ };
+ let addr = DeviceAddress::new(devaddr, addrkind);
+ let mut _ll = LinkLayer::<NRF52840>::new(addr, ble_timer);
+}
diff --git a/ble/src/i2c.rs b/ble/src/i2c.rs
index b5a5114..e95987c 100644
--- a/ble/src/i2c.rs
+++ b/ble/src/i2c.rs
@@ -2,7 +2,7 @@ use log::{error, trace};
use nrf52840_hal::twis::{self, Twis, TwisInterrupt};
use starb::{Reader, RingBuffer, Writer};
-static mut RB: RingBuffer<u8> = RingBuffer::new(0);
+static mut RB: RingBuffer<u8> = RingBuffer::new();
pub fn setup<T>(mut twis: Twis<T>) -> (Reader<'static, u8>, impl FnMut())
where
diff --git a/ble/src/logger.rs b/ble/src/logger.rs
index b4167b2..07790cc 100644
--- a/ble/src/logger.rs
+++ b/ble/src/logger.rs
@@ -30,7 +30,7 @@ impl fmt::Write for JoinedRingBuffer<'_> {
}
}
-static mut LB: RingBuffer<u8> = RingBuffer::<u8>::new(0);
+static mut LB: RingBuffer<u8> = RingBuffer::<u8>::new();
static mut JRB: JoinedRingBuffer = unsafe { JoinedRingBuffer::new(&LB) };
// The UART isn't necessarily Sync, so wrap it in something that
@@ -80,24 +80,36 @@ where
}
let jrb = unsafe { &mut JRB };
- write!(
- jrb,
- "[{}] {} {} -- {}\r\n",
- rtc::millis(),
- record.level(),
- record.target(),
- record.args()
- )
- .ok();
+ if record.target() == "usb" {
+ write!(jrb, "{}", record.args()).ok();
+ } else {
+ write!(
+ jrb,
+ "[{}] {} {} -- {}\r\n",
+ rtc::millis(),
+ record.level(),
+ record.target(),
+ record.args()
+ )
+ .ok();
+ }
}
fn flush(&self) {
+ //let start = rtc::millis();
let jrb = unsafe { &mut JRB };
let writer = unsafe { &mut (*self.writer.get()) };
let mut buf: [u8; 256] = unsafe { MaybeUninit::<[u8; 256]>::uninit().assume_init() };
let len = jrb.lbr.shift_into(&mut buf);
if len > 0 {
- writer.w.write(&buf[0..len]).expect("writing log")
+ writer.w.write(&buf[0..len]).expect("writing log");
+ /*
+ let end = rtc::millis();
+ writer
+ .w
+ .write(&[b' ', b'-', b' ', b'0' + (end as u8 - start as u8)])
+ .ok();
+ */
}
}
}
diff --git a/ble/src/main.rs b/ble/src/main.rs
index 71e3b82..36c3228 100644
--- a/ble/src/main.rs
+++ b/ble/src/main.rs
@@ -3,6 +3,7 @@
#![no_std]
#![no_main]
+mod ble;
mod i2c;
mod logger;
mod macros;
@@ -13,7 +14,7 @@ use clint::HandlerArray;
use core::mem;
use cortex_m::asm::wfi;
use cortex_m_rt::{entry, exception, ExceptionFrame};
-use log::{info, LevelFilter};
+use log::{info, log, Level as LogLevel, LevelFilter};
#[allow(unused_imports)]
extern crate panic_semihosting;
@@ -32,8 +33,7 @@ use nrf52840_mdk_bsp::{
const I2C_ADDR: u8 = 4;
// TODO:
-// * set up serial reader for trinket
-// * and, finally, bluetooth
+// * bluetooth
// Interrupt handler table.
static HANDLERS: HandlerArray = HandlerArray::new();
@@ -48,6 +48,19 @@ fn main() -> ! {
log::set_logger(logger_ref).expect("setting logger");
log::set_max_level(LevelFilter::Trace);
+ // TODO: use hal interface for this.
+ nrf52
+ .CLOCK
+ .tasks_hfclkstart
+ .write(|w| w.tasks_hfclkstart().set_bit());
+ while nrf52
+ .CLOCK
+ .events_hfclkstarted
+ .read()
+ .events_hfclkstarted()
+ .bit_is_clear()
+ {}
+
nrf52.RTC0.intenset.write(|w| w.tick().set());
let mut nvic = nrf52.NVIC;
@@ -70,6 +83,8 @@ fn main() -> ! {
let uarte1 = uarte1(nrf52.UARTE1, txp, rxp);
let (mut uarte1_reader, mut uarte1_handler) = uarte1::setup(uarte1);
+ //ble::setup(nrf52.RADIO, nrf52.TIMER0, nrf52.FICR);
+
HANDLERS.with_overrides(|hs| {
hs.register(0, &mut rtc_handler);
nvic.enable(Interrupt::RTC0);
@@ -80,16 +95,19 @@ fn main() -> ! {
info!("Bootstrap complete.");
- let mut last_tick = rtc::millis();
- last_tick -= last_tick % 1024;
- let mut buf: [u8; 256] = [0; 256];
+ // Buffer is just scratch space that always gets written to
+ // before it's read.
+ let mut buf: [u8; 256] =
+ unsafe { core::mem::MaybeUninit::<[u8; 256]>::uninit().assume_init() };
+
+ // TODO: there's some kind of weird multi-millisecond latency
+ // somewhere. It may be in one of the interrupt handlers, so
+ // maybe stick a counter on them for every time they're fired
+ // and then spit out stats once/second from here.
+ //
+ // May need to keep total-time-spent inside the handlers as
+ // well. This lag is infuriatingly hidden.
loop {
- let tick = rtc::millis();
- if tick >= last_tick + 1024 {
- last_tick = tick;
- last_tick -= last_tick % 1024;
- }
-
let mut len = twis_reader.shift_into(&mut buf);
while len > 0 {
info!("i²c data: {:?}", &buf[0..len]);
@@ -98,9 +116,8 @@ fn main() -> ! {
let mut len = uarte1_reader.shift_into(&mut buf);
while len > 0 {
- info!(
- "serial {}: {}",
- len,
+ log!(target: "usb", LogLevel::Info,
+ "{}",
core::str::from_utf8(&buf[0..len]).expect("utf8conv")
);
len = uarte1_reader.shift_into(&mut buf);
diff --git a/ble/src/uarte1.rs b/ble/src/uarte1.rs
index 1afce29..0beb8cd 100644
--- a/ble/src/uarte1.rs
+++ b/ble/src/uarte1.rs
@@ -2,9 +2,9 @@ use log::info;
use nrf52840_hal::uarte::{self, Uarte};
use starb::{Reader, RingBuffer, Writer};
-static mut RB: RingBuffer<u8> = RingBuffer::new(0);
+static mut RB: RingBuffer<u8> = RingBuffer::new();
-const BUFLEN: usize = 128;
+const BUFLEN: usize = 255;
struct DoubleBuffer {
bank0: [u8; BUFLEN],
@@ -51,6 +51,9 @@ where
w.rxstarted().set_bit()
});
+ // Keep the transmission going constantly.
+ uarte.0.shorts.write(|w| w.endrx_startrx().set_bit());
+
let ptr = unsafe { DBL_BUFF.next_ptr() };
info!("setting up dma: p: {:x}, maxcnt: {}", ptr as u32, BUFLEN);
uarte.0.rxd.ptr.write(|w| unsafe { w.ptr().bits(ptr as _) });
@@ -75,48 +78,29 @@ where
if uarte.0.events_endrx.read().events_endrx().bit_is_set() {
uarte.0.events_endrx.write(|w| w.events_endrx().clear_bit());
- // The buffer should be swapped from the RXSTARTED event, so
- // we can restart the read immediately.
- let optr = uarte.0.rxd.ptr.read().ptr().bits();
- let ptr = unsafe { DBL_BUFF.cur_ptr() as u32 };
- /*
- if optr == ptr {
- uarte
- .0
- .rxd
- .ptr
- .write(|w| unsafe { w.ptr().bits(DBL_BUFF.next_ptr() as _) });
- }
- */
- uarte.0.tasks_startrx.write(|w| w.tasks_startrx().set_bit());
-
// Copy DMA buffer to ring buffer.
let len = uarte.0.rxd.amount.read().amount().bits();
+ let ptr = unsafe { DBL_BUFF.cur_ptr() };
+ /*
+ let optr = uarte.0.rxd.ptr.read().ptr().bits();
let mc = uarte.0.rxd.maxcnt.read().maxcnt().bits();
info!(
- "endrx - l: {}, p: {:x}, mc: {}, b: {:x}",
- len, optr, mc, ptr
+ "ENDRX optr: {:x}, mc: {}, ptr: {:x}, len: {}",
+ optr, mc, ptr as u32, len,
);
- flush_buf(writer, unsafe { DBL_BUFF.cur_ptr() }, len.into());
-
- /*
- uarte
- .0
- .rxd
- .maxcnt
- .write(|w| unsafe { w.maxcnt().bits(BUFLEN as _) });
- */
+ */
+ flush_buf(writer, ptr, len as usize);
} else if uarte.0.events_error.read().events_error().bit_is_set() {
uarte.0.events_error.write(|w| w.events_error().clear_bit());
let len = uarte.0.rxd.amount.read().amount().bits();
- info!("error: {:b} {}b", uarte.0.errorsrc.read().bits(), len,);
+ info!("ERROR {:b} {}b", uarte.0.errorsrc.read().bits(), len);
} else if uarte.0.events_rxto.read().events_rxto().bit_is_set() {
uarte.0.events_rxto.write(|w| w.events_rxto().clear_bit());
let len = uarte.0.rxd.amount.read().amount().bits();
- info!("rxto - {}", len);
- flush_buf(writer, unsafe { DBL_BUFF.cur_ptr() }, len.into());
+ info!("RXTO - {}", len);
+ flush_buf(writer, unsafe { DBL_BUFF.cur_ptr() }, len as usize);
uarte.0.tasks_flushrx.write(|w| w.tasks_flushrx().set_bit());
} else if uarte
.0
@@ -129,7 +113,7 @@ where
.0
.events_rxstarted
.write(|w| w.events_rxstarted().clear_bit());
- info!("rxstarted");
+ //info!("RXSTARTED");
// Swap to the next buffer as soon as the transfer starts to
// try and lose as little data as possible.
@@ -140,7 +124,7 @@ where
fn flush_buf(writer: &mut Writer<u8>, ptr: *mut u8, len: usize) {
let buf = unsafe { core::slice::from_raw_parts(ptr, len) };
- info!("flush start");
+ //info!("flush start");
writer.unshift_from(buf);
- info!("flush end");
+ //info!("flush end");
}