From 784db2bc6ca1dac88a60fcf5919ae5f7fa98f688 Mon Sep 17 00:00:00 2001 From: Brian Cully Date: Mon, 19 Aug 2019 21:06:42 -0400 Subject: Clumsy, but BLE advertising is up. --- ble/Cargo.lock | 7 ++-- ble/Cargo.toml | 4 +- ble/src/ble.rs | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++----- ble/src/main.rs | 9 ++++- 4 files changed, 126 insertions(+), 16 deletions(-) (limited to 'ble') diff --git a/ble/Cargo.lock b/ble/Cargo.lock index 3855ef7..3003e13 100644 --- a/ble/Cargo.lock +++ b/ble/Cargo.lock @@ -39,6 +39,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "ble" version = "0.1.0" dependencies = [ + "bbqueue 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "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)", @@ -49,7 +50,7 @@ dependencies = [ "nrf52840-hal 0.8.1", "nrf52840-mdk-bsp 0.1.0", "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 0.0.3", "rubble-nrf52 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "starb 0.2.0", ] @@ -253,7 +254,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rubble" version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bbqueue 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -267,7 +267,7 @@ version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "nrf52840-hal 0.8.1", - "rubble 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rubble 0.0.3", ] [[package]] @@ -370,7 +370,6 @@ dependencies = [ "checksum rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" "checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" -"checksum rubble 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "56df8ee793ccbd8ea2fd174a71dbb410c7bfc308d94ad9bdc7ba36a0522da4f7" "checksum rubble-nrf52 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a5316700fe451281c7dd96b8769768c9fabe87bbd084f8ec507a142b76cff4f2" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" diff --git a/ble/Cargo.toml b/ble/Cargo.toml index b624978..865834c 100644 --- a/ble/Cargo.toml +++ b/ble/Cargo.toml @@ -18,14 +18,16 @@ log = "0.4" starb = "~0.2" clint = "~0.2" cortex-m-semihosting = "~0.3" +bbqueue = "~0.3" [features] -default = ["rt", "rubble-nrf52/52840"] +default = ["rt", "rubble-nrf52/52840", "cortex-m/const-fn", "cortex-m/inline-asm"] rt = ["nrf52840-hal/rt"] [patch.crates-io] nrf52840-hal = { path = "../../nrf52-hal/nrf52840-hal" } starb = { path = "../../usbh/starb" } +rubble = { path = "../../rubble/rubble" } [profile.dev] incremental = false diff --git a/ble/src/ble.rs b/ble/src/ble.rs index e5f16cb..ac3542f 100644 --- a/ble/src/ble.rs +++ b/ble/src/ble.rs @@ -1,6 +1,22 @@ -use nrf52840_hal::target::{FICR, RADIO, TIMER0}; -use rubble::link::{AddressKind, DeviceAddress, HardwareInterface, LinkLayer, MIN_PDU_BUF}; -use rubble_nrf52::{radio::BleRadio, timer::BleTimer}; +use bbqueue::{bbq, BBQueue}; +use core::{cell::RefCell, ops::DerefMut}; +use cortex_m::{self, interrupt::Mutex}; +use log::info; +use nrf52840_hal::target::{interrupt, FICR, RADIO, TIMER0}; +use rubble::{ + gatt::BatteryServiceAttrs, + l2cap::{BleChannelMap, L2CAPState}, + link::{ + ad_structure::AdStructure, queue, AddressKind, DeviceAddress, HardwareInterface, LinkLayer, + Responder, MIN_PDU_BUF, + }, + security_manager::NoSecurity, + time::{Duration, Timer}, +}; +use rubble_nrf52::{ + radio::{BleRadio, PacketBuffer}, + timer::BleTimer, +}; struct NRF52840 {} impl HardwareInterface for NRF52840 { @@ -8,15 +24,31 @@ impl HardwareInterface for NRF52840 { type Tx = BleRadio; } -pub fn setup(radio: RADIO, timer: TIMER0, ficr: FICR) { +type Global = Mutex>>; + +static BLE_LL: Global> = Mutex::new(RefCell::new(None)); +static BLE_RADIO: Global = Mutex::new(RefCell::new(None)); + +pub fn setup( + radio: RADIO, + timer: TIMER0, + ficr: FICR, +) -> Responder> { // 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 devaddr_lo: &[u8] = &ficr.deviceaddr[0].read().bits().to_le_bytes(); + let devaddr_hi: &[u8] = &(ficr.deviceaddr[1].read().bits() as u16).to_le_bytes(); + + let mut devaddr: [u8; 6] = [0; 6]; + for (i, a) in [devaddr_lo, devaddr_hi] + .iter() + .copied() + .flatten() + .enumerate() + { + devaddr[i] = *a; + } let addrkind = if ficr.deviceaddrtype.read().deviceaddrtype().is_public() { AddressKind::Public @@ -24,5 +56,75 @@ pub fn setup(radio: RADIO, timer: TIMER0, ficr: FICR) { AddressKind::Random }; let addr = DeviceAddress::new(devaddr, addrkind); - let mut _ll = LinkLayer::::new(addr, ble_timer); + info!("my address: {:?}", addr); + + static mut TX_BUF: PacketBuffer = [0; MIN_PDU_BUF]; + static mut RX_BUF: PacketBuffer = [0; MIN_PDU_BUF]; + + let (tx_prod, tx_cons) = queue::create(bbq![MIN_PDU_BUF * 2].expect("creating tx queue")); + let (rx_prod, rx_cons) = queue::create(bbq![MIN_PDU_BUF * 2].expect("creating rx queue")); + + // `responder` used on main loop. + let resp = Responder::new( + tx_prod, + rx_cons, + L2CAPState::new(BleChannelMap::with_attributes(BatteryServiceAttrs::new())), + ); + + // `ble_radio` and `ll` used on both `timer` and `radio` + // interrupts. + // may be able to use ring buffer to avoid sharing? + let mut ble_radio = unsafe { BleRadio::new(radio, &mut TX_BUF, &mut RX_BUF) }; + + let mut ble_ll = LinkLayer::::new(addr, ble_timer); + let next_update = ble_ll + .start_advertise( + Duration::from_millis(200), + &[AdStructure::CompleteLocalName("bleusb")], + &mut ble_radio, + tx_cons, + rx_prod, + ) + .expect("scheduling link layer update"); + ble_ll.timer().configure_interrupt(next_update); + + cortex_m::interrupt::free(|cs| { + BLE_LL.borrow(cs).replace(Some(ble_ll)); + BLE_RADIO.borrow(cs).replace(Some(ble_radio)); + }); + + resp +} + +#[interrupt] +fn TIMER0() { + cortex_m::interrupt::free(|cs| { + if let (Some(ref mut ble_ll), Some(ref mut ble_radio)) = ( + BLE_LL.borrow(cs).borrow_mut().deref_mut(), + BLE_RADIO.borrow(cs).borrow_mut().deref_mut(), + ) { + if !ble_ll.timer().is_interrupt_pending() { + return; + } + ble_ll.timer().clear_interrupt(); + + let cmd = ble_ll.update(ble_radio); + ble_radio.configure_receiver(cmd.radio); + + ble_ll.timer().configure_interrupt(cmd.next_update); + } + }) +} + +#[interrupt] +fn RADIO() { + cortex_m::interrupt::free(|cs| { + if let (Some(ref mut ble_ll), Some(ref mut ble_radio)) = ( + BLE_LL.borrow(cs).borrow_mut().deref_mut(), + BLE_RADIO.borrow(cs).borrow_mut().deref_mut(), + ) { + let next_update = ble_radio.recv_interrupt(ble_ll.timer().now(), ble_ll); + ble_ll.timer().configure_interrupt(next_update); + } + }) } diff --git a/ble/src/main.rs b/ble/src/main.rs index 36c3228..137c8a7 100644 --- a/ble/src/main.rs +++ b/ble/src/main.rs @@ -83,7 +83,7 @@ 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); + let mut resp = ble::setup(nrf52.RADIO, nrf52.TIMER0, nrf52.FICR); HANDLERS.with_overrides(|hs| { hs.register(0, &mut rtc_handler); @@ -93,6 +93,9 @@ fn main() -> ! { hs.register(2, &mut uarte1_handler); nvic.enable(Interrupt::UARTE1); + nvic.enable(Interrupt::TIMER0); + nvic.enable(Interrupt::RADIO); + info!("Bootstrap complete."); // Buffer is just scratch space that always gets written to @@ -122,6 +125,10 @@ fn main() -> ! { ); len = uarte1_reader.shift_into(&mut buf); } + + if resp.has_work() { + resp.process_one().expect("ble response processing"); + } wfi(); } }); -- cgit v1.2.3