summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Cully <bjc@kublai.com>2019-08-19 21:06:42 -0400
committerBrian Cully <bjc@kublai.com>2019-08-19 21:06:42 -0400
commit784db2bc6ca1dac88a60fcf5919ae5f7fa98f688 (patch)
treeaa8a5e5ca7ae0af26d03f4bc98c2fa4905d56a80
parenta3b976df4b1214c6f4e2a053724398b1a5e1767b (diff)
downloadbleusb-784db2bc6ca1dac88a60fcf5919ae5f7fa98f688.tar.gz
bleusb-784db2bc6ca1dac88a60fcf5919ae5f7fa98f688.zip
Clumsy, but BLE advertising is up.
-rw-r--r--ble/Cargo.lock7
-rw-r--r--ble/Cargo.toml4
-rw-r--r--ble/src/ble.rs122
-rw-r--r--ble/src/main.rs9
-rw-r--r--usb/Cargo.lock5
-rw-r--r--usb/Cargo.toml1
6 files changed, 132 insertions, 16 deletions
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<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();
}
});
diff --git a/usb/Cargo.lock b/usb/Cargo.lock
index f9d17e8..a360037 100644
--- a/usb/Cargo.lock
+++ b/usb/Cargo.lock
@@ -423,6 +423,11 @@ dependencies = [
"vcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[patch.unused]]
+name = "atsamd-hal"
+version = "0.6.0"
+source = "git+https://github.com/atsamd-rs/atsamd?rev=97d55c19#97d55c19f0e5234cf9766311477bc696357271fd"
+
[metadata]
"checksum aligned 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d39da9b88ae1a81c03c9c082b8db83f1d0e93914126041962af61034ab44c4a5"
"checksum aligned 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d3a316c7ea8e1e9ece54862c992def5a7ac14de9f5832b69d71760680efeeefa"
diff --git a/usb/Cargo.toml b/usb/Cargo.toml
index 248d017..4d23e6e 100644
--- a/usb/Cargo.toml
+++ b/usb/Cargo.toml
@@ -25,6 +25,7 @@ bootkbd = "0.2"
atsamd-usb-host = { path = "../../usbh/atsamd-usb-host" }
[patch.crates-io]
+atsamd-hal = { git = "https://github.com/atsamd-rs/atsamd", rev = "97d55c19" }
#bootkbd = { git = "https://github.com/bjc/bootkbd.git", rev = "49827fce5adbaf636b893919f31c0dbd97bb3eb4" }
#usb-host = { git = "https://github.com/bjc/usb-host.git", rev = "b0be48424e81384de3280b5a5ac521d694b82e15" }
#trinket_m0 = { git = "https://github.com/atsamd-rs/atsamd.git", rev = "53f8d846e40715c8592d171d9a57b66ee303207a" }