diff --git a/src/ble.rs b/src/ble.rs
index 94be06c7afc0514e2ca9394699d270495244c215..81effee4a89fd87cc05081633378a7c7b2cb3c45 100644
--- a/src/ble.rs
+++ b/src/ble.rs
@@ -44,15 +44,6 @@ static mut BLE_BUFFERS: BleBuffers = BleBuffers {
rx_queue: SimpleQueue::new(),
};
-pub struct Ble {
- pub radio: BleRadio,
- pub ble_ll: LinkLayer<AppConfig>,
- // pub ble_r: Responder<AppConfig>,
- // pub beacon: Beacon,
-
-}
-static BLE: Mutex<OnceCell<Ble>> = Mutex::new(OnceCell::uninitialized());
-
pub enum AppConfig {}
impl Config for AppConfig {
@@ -62,132 +53,114 @@ impl Config for AppConfig {
type PacketQueue = &'static mut SimpleQueue;
}
+struct Ble {
+ radio: BleRadio,
+ ble_ll: LinkLayer<AppConfig>,
+ ble_r: Responder<AppConfig>,
+}
+
+static BLE: Mutex<OnceCell<Ble>> = Mutex::new(OnceCell::uninitialized());
+
pub(crate) fn initialize(radio: RADIO, ficr: &FICR, timer: TIMER0, clock: CLOCK, nvic: &mut NVIC) {
+ // On reset, the internal high frequency clock is already used, but we
+ // also need to switch to the external HF oscillator. This is needed
+ // for Bluetooth to work.
let _clocks = Clocks::new(clock).enable_ext_hfosc();
+ let ble_timer = BleTimer::init(timer);
let buffers: &'static mut BleBuffers = unsafe { &mut BLE_BUFFERS };
+
+ // Determine device address
let device_address = get_device_address();
- let ble_timer = BleTimer::init(timer);
+ // Rubble currently requires an RX buffer even though the radio is only used as a TX-only beacon.
let mut radio = BleRadio::new(
radio,
- &ficr,
+ ficr,
&mut buffers.ble_tx_buf,
&mut buffers.ble_rx_buf,
);
+
+ // Create TX/RX queues
+ let (tx, tx_cons) = buffers.tx_queue.split();
+ let (rx_prod, rx) = buffers.rx_queue.split();
+
+ // Create the actual BLE stack objects
let mut ble_ll = LinkLayer::<AppConfig>::new(device_address, ble_timer);
- // let (tx, tx_cons) = buffers.tx_queue.split();
- // let (rx_prod, rx) = buffers.rx_queue.split();
- // let ble_r: Responder<AppConfig> = Responder::new(
- // tx,
- // rx,
- // L2CAPState::new(BleChannelMap::with_attributes(DemoAttrs::new())),
- // );
+ let ble_r = Responder::new(
+ tx,
+ rx,
+ L2CAPState::new(BleChannelMap::with_attributes(DemoAttrs::new())),
+ );
// Send advertisement and set up regular interrupt
- // let next_update = ble_ll
- // .start_advertise(
- // Duration::from_millis(200),
- // &[AdStructure::CompleteLocalName("RUSTY TRANSMITTER")],
- // &mut radio,
- // tx_cons,
- // rx_prod,
- // )
- // .unwrap();
- // ble_ll.timer().configure_interrupt(next_update);
-
- // let beacon = Beacon::new(device_address, &[AdStructure::CompleteLocalName("RUSTY TRANSMITTER")]).unwrap();
-
- BLE.lock().initialize(Ble {
+ let next_update = ble_ll
+ .start_advertise(
+ Duration::from_millis(100),
+ &[AdStructure::CompleteLocalName("Rusty Transmitter")],
+ &mut radio,
+ tx_cons,
+ rx_prod,
+ )
+ .unwrap();
+
+ ble_ll.timer().configure_interrupt(next_update);
+
+ unsafe {
+ NVIC::unpend(Interrupt::RADIO);
+ NVIC::unpend(Interrupt::TIMER0);
+ nvic.set_priority(Interrupt::RADIO, 3);
+ nvic.set_priority(Interrupt::TIMER0, 3);
+ NVIC::unmask(Interrupt::RADIO);
+ NVIC::unmask(Interrupt::TIMER0);
+ }
+
+ BLE.modify(|ble| ble.initialize(Ble {
radio,
- // beacon
ble_ll,
- // ble_r
- });
+ ble_r
+ }))
+}
- //Enable interrupts
- unsafe {
- // nvic.set_priority(Interrupt::TIMER0, 3);
- // NVIC::unpend(Interrupt::TIMER0);
- // NVIC::unmask(Interrupt::TIMER0);
- // nvic.set_priority(Interrupt::RADIO, 3);
- // NVIC::unpend(Interrupt::RADIO);
- // NVIC::unmask(Interrupt::RADIO);
+#[interrupt]
+fn RADIO() {
+ let ble: &mut Ble = unsafe { BLE.no_critical_section_lock_mut() };
+ if let Some(cmd) = ble
+ .radio
+ .recv_interrupt(ble.ble_ll.timer().now(), &mut ble.ble_ll) {
+ ble.radio.configure_receiver(cmd.radio);
+ ble.ble_ll.timer().configure_interrupt(cmd.next_update);
}
}
-pub fn update_ble() {
- let ble = &mut **BLE.lock();
- // let _ = ble.ble_ll.update_timer(&mut ble.radio);
+#[interrupt]
+fn TIMER0() {
+ let ble: &mut Ble = unsafe { BLE.no_critical_section_lock_mut() };
- let addr = get_device_address();
- let data = &[AdStructure::CompleteLocalName("RUSTY TRANSMITTER")];
- let tx = &mut ble.radio;
+ let timer = ble.ble_ll.timer();
+ if !timer.is_interrupt_pending() {
+ return;
+ }
+ timer.clear_interrupt();
- // let pdu = PduBuf::beacon(addr, data).unwrap();
- let pdu = PduBuf::discoverable(addr, data).unwrap();
- let payload = pdu.payload();
- let buf = tx.tx_payload_buf();
- buf[..payload.len()].copy_from_slice(payload);
+ let cmd = ble.ble_ll.update_timer(&mut ble.radio);
+ ble.radio.configure_receiver(cmd.radio);
- for channel in AdvertisingChannel::iter_all() {
- tx.transmit_advertising(pdu.header(), channel);
- }
+ ble
+ .ble_ll
+ .timer()
+ .configure_interrupt(cmd.next_update);
+}
- // ble.beacon.broadcast(&mut ble.radio);
+pub fn update_ble() {
+ BLE.modify(|ble: &mut OnceCell<Ble> | {
+ while ble.ble_r.has_work() {
+ ble.ble_r.process_one().unwrap();
+ }
+
+ Green.set(ble.ble_ll.is_connected());
+ });
}
-// #[interrupt]
-// fn RADIO() {
- // let ble = &mut **BLE.lock();
- // Green.toggle();
-
- // let ble_ll: &mut LinkLayer<AppConfig> = &mut ble.ble_ll;
- // if let Some(cmd) = ble
- // .radio
- // .recv_interrupt(ble_ll.timer().now(), ble_ll)
- // {
- // ble.radio.configure_receiver(cmd.radio);
- // ble_ll.timer().configure_interrupt(cmd.next_update);
- //
- // if cmd.queued_work {
- // while ble.ble_r.has_work() {
- // ble.ble_r.process_one().unwrap();
- // }
- // }
- // }
-// }
-
-// #[interrupt]
-// fn TIMER0() {
-// let ble = &mut **BLE.lock();
-// let ble_ll: &mut LinkLayer<AppConfig> = &mut ble.ble_ll;
-//
-// let timer = ble_ll.timer();
-// if !timer.is_interrupt_pending() {
-// return;
-// }
-// timer.clear_interrupt();
-//
-// let cmd = ble.ble_ll.update_timer(&mut ble.radio);
-// ble.radio.configure_receiver(cmd.radio);
-//
-// if ble.ble_ll.is_advertising() {
-// Green.toggle();
-// }
-//
-// ble
-// .ble_ll
-// .timer()
-// .configure_interrupt(cmd.next_update);
-//
-//
-//
-// if cmd.queued_work {
-// while ble.ble_r.has_work() {
-// ble.ble_r.process_one().unwrap();
-// }
-// }
-// }
\ No newline at end of file
diff --git a/src/initialize.rs b/src/initialize.rs
index cb4b5e2f4b3d65a31547732d6680891ac2a53ea7..e60139ea7c539b93983207f9e49fc5906caad03a 100644
--- a/src/initialize.rs
+++ b/src/initialize.rs
@@ -115,7 +115,7 @@ pub fn initialize(heap_memory: &'static mut [MaybeUninit<u8>], debug: bool) {
&mut cortex_m_peripherals.NVIC,
);
if debug {
- send_bytes(b"BLE driver initialized\n");
+ let _ = send_bytes(b"BLE driver initialized\n");
}
// done with initialization sequence
diff --git a/src/lib.rs b/src/lib.rs
index 568adad735cabf286b9d0ced2da64fefa0a7dff2..95b003aca306045c9e7ea0d6ed209aef5fe1338d 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,9 +1,9 @@
#![no_std]
#![feature(strict_provenance)]
-#![deny(missing_docs)]
+// #![deny(missing_docs)]
// #![deny(warnings)]
-#![deny(unused_import_braces)]
-#![deny(unused_results)]
+// #![deny(unused_import_braces)]
+// #![deny(unused_results)]
// #![deny(trivial_casts)]
// #![deny(trivial_numeric_casts)]
// #![deny(unused_qualifications)]
@@ -84,6 +84,8 @@ pub mod time;
/// Utilities to read from and write to UART
pub mod uart;
+
+/// Utilities to read and write using BLE
pub mod ble;
/// Internal utilities to read out TWI (I2C) devices