diff options
author | Brian Cully <bjc@kublai.com> | 2019-08-15 20:44:51 -0400 |
---|---|---|
committer | Brian Cully <bjc@kublai.com> | 2019-08-15 20:44:51 -0400 |
commit | da405029113f9c188313b9477f4dc13aa3ab52f9 (patch) | |
tree | 058dcca7068d597e572112f0c182fd3b701a9d59 /ble | |
parent | 101a0859612cbf40364d198eea60b9ae934f721a (diff) | |
download | bleusb-da405029113f9c188313b9477f4dc13aa3ab52f9.tar.gz bleusb-da405029113f9c188313b9477f4dc13aa3ab52f9.zip |
More WIP for btle comms.
Diffstat (limited to 'ble')
-rw-r--r-- | ble/Cargo.lock | 12 | ||||
-rw-r--r-- | ble/Cargo.toml | 6 | ||||
-rw-r--r-- | ble/TODO.org | 10 | ||||
-rw-r--r-- | ble/src/ble.rs | 28 | ||||
-rw-r--r-- | ble/src/i2c.rs | 2 | ||||
-rw-r--r-- | ble/src/logger.rs | 34 | ||||
-rw-r--r-- | ble/src/main.rs | 47 | ||||
-rw-r--r-- | ble/src/uarte1.rs | 52 |
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"); } |