summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Cully <bjc@kublai.com>2019-08-15 20:44:51 -0400
committerBrian Cully <bjc@kublai.com>2019-08-15 20:44:51 -0400
commitda405029113f9c188313b9477f4dc13aa3ab52f9 (patch)
tree058dcca7068d597e572112f0c182fd3b701a9d59
parent101a0859612cbf40364d198eea60b9ae934f721a (diff)
downloadbleusb-da405029113f9c188313b9477f4dc13aa3ab52f9.tar.gz
bleusb-da405029113f9c188313b9477f4dc13aa3ab52f9.zip
More WIP for btle comms.
-rw-r--r--ble/Cargo.lock12
-rw-r--r--ble/Cargo.toml6
-rw-r--r--ble/TODO.org10
-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
8 files changed, 121 insertions, 70 deletions
diff --git a/ble/Cargo.lock b/ble/Cargo.lock
index 41baa15..3855ef7 100644
--- a/ble/Cargo.lock
+++ b/ble/Cargo.lock
@@ -42,7 +42,7 @@ dependencies = [
"clint 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cortex-m 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cortex-m-rt 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "cortex-m-semihosting 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cortex-m-semihosting 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"embedded-hal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"nb 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -51,7 +51,7 @@ dependencies = [
"panic-semihosting 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rubble 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rubble-nrf52 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "starb 0.1.1",
+ "starb 0.2.0",
]
[[package]]
@@ -109,7 +109,7 @@ dependencies = [
[[package]]
name = "cortex-m-semihosting"
-version = "0.3.3"
+version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cortex-m 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -205,7 +205,7 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cortex-m 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cortex-m-semihosting 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cortex-m-semihosting 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -298,7 +298,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "starb"
-version = "0.1.1"
+version = "0.2.0"
[[package]]
name = "syn"
@@ -356,7 +356,7 @@ dependencies = [
"checksum cortex-m 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f3c18719fdc57db65668bfc977db9a0fa1a41d718c5d9cd4f652c9d4b0e0956a"
"checksum cortex-m-rt 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "17805910e3ecf029bdbfcc42b7384d9e3d9e5626153fa810002c1ef9839338ac"
"checksum cortex-m-rt-macros 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d7ae692573e0acccb1579fef1abf5a5bf1d2f3f0149a22b16870ec9309aee25f"
-"checksum cortex-m-semihosting 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "165f3f86f4d1031351a6c9dc8d5a3f8fae2050f9dd6ef925e3d675c232cc0e46"
+"checksum cortex-m-semihosting 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "05bd17c26d344f364eaf7f7ededc848ca8ef762a75d13c0829d4a3e62eb5418a"
"checksum embedded-hal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ee4908a155094da7723c2d60d617b820061e3b4efcc3d9e293d206a5a76c170b"
"checksum fpa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f074479d683e5a8fd0bf1251d0a5d91b0d9178b867b44962191ed0eaaf8d4009"
"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
diff --git a/ble/Cargo.toml b/ble/Cargo.toml
index 7ef4dcf..b624978 100644
--- a/ble/Cargo.toml
+++ b/ble/Cargo.toml
@@ -15,9 +15,9 @@ embedded-hal = "0.2"
panic-semihosting = "~0.5"
nb = "~0.1"
log = "0.4"
-starb = "0.1"
-clint = "0.2"
-cortex-m-semihosting = "0.3"
+starb = "~0.2"
+clint = "~0.2"
+cortex-m-semihosting = "~0.3"
[features]
default = ["rt", "rubble-nrf52/52840"]
diff --git a/ble/TODO.org b/ble/TODO.org
index 69de785..2558566 100644
--- a/ble/TODO.org
+++ b/ble/TODO.org
@@ -44,3 +44,13 @@ try and figure out where the clock cycles are going.
- 0[11141] INFO ble -- - 0i2c data
- 0
#+END
+
+* Maybe swap from UARTE1 to UART for trinket transmission.
+
+It's very difficult to get stuff out of the UARTE until its DMA buffer
+is full, but the trinket is sending us logs of variable sizes that
+we'd like to see immediately.
+
+UART0 and UARTE0 share the same address. I don't see a UART1
+instance. Maybe send console logs on UARTE1 and use UART0 for trinket
+serial comms?
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");
}