diff options
author | Brian Cully <bjc@kublai.com> | 2019-08-19 21:06:42 -0400 |
---|---|---|
committer | Brian Cully <bjc@kublai.com> | 2019-08-19 21:06:42 -0400 |
commit | 784db2bc6ca1dac88a60fcf5919ae5f7fa98f688 (patch) | |
tree | aa8a5e5ca7ae0af26d03f4bc98c2fa4905d56a80 /ble/src | |
parent | a3b976df4b1214c6f4e2a053724398b1a5e1767b (diff) | |
download | bleusb-784db2bc6ca1dac88a60fcf5919ae5f7fa98f688.tar.gz bleusb-784db2bc6ca1dac88a60fcf5919ae5f7fa98f688.zip |
Clumsy, but BLE advertising is up.
Diffstat (limited to 'ble/src')
-rw-r--r-- | ble/src/ble.rs | 122 | ||||
-rw-r--r-- | ble/src/main.rs | 9 |
2 files changed, 120 insertions, 11 deletions
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<T> = Mutex<RefCell<Option<T>>>; + +static BLE_LL: Global<LinkLayer<NRF52840>> = Mutex::new(RefCell::new(None)); +static BLE_RADIO: Global<BleRadio> = Mutex::new(RefCell::new(None)); + +pub fn setup( + radio: RADIO, + timer: TIMER0, + ficr: FICR, +) -> Responder<BleChannelMap<BatteryServiceAttrs, NoSecurity>> { // 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::<NRF52840>::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::<NRF52840>::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(); } }); |