components/
ble.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! Component for creating a ble_advertising_driver.
6//!
7//! Usage
8//! -----
9//! ```rust
10//! let ble_radio = BLEComponent::new(board_kernel, &nrf52::ble_radio::RADIO, mux_alarm).finalize();
11//! ```
12
13use capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm;
14use core::mem::MaybeUninit;
15use kernel::capabilities;
16use kernel::component::Component;
17use kernel::create_capability;
18use kernel::hil::ble_advertising::BleConfig;
19use kernel::hil::time::Alarm;
20
21#[macro_export]
22macro_rules! ble_component_static {
23    ($A:ty, $B:ty $(,)?) => {{
24        let alarm = kernel::static_buf!(
25            capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<'static, $A>
26        );
27        let ble = kernel::static_buf!(
28            capsules_extra::ble_advertising_driver::BLE<
29                'static,
30                $B,
31                capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<'static, $A>,
32            >
33        );
34        let buffer =
35            kernel::static_buf!([u8; capsules_extra::ble_advertising_driver::PACKET_LENGTH]);
36        (alarm, ble, buffer)
37    }};
38}
39
40pub struct BLEComponent<
41    A: kernel::hil::time::Alarm<'static> + 'static,
42    B: kernel::hil::ble_advertising::BleAdvertisementDriver<'static> + BleConfig + 'static,
43> {
44    board_kernel: &'static kernel::Kernel,
45    driver_num: usize,
46    radio: &'static B,
47    mux_alarm: &'static capsules_core::virtualizers::virtual_alarm::MuxAlarm<'static, A>,
48}
49
50impl<
51        A: kernel::hil::time::Alarm<'static> + 'static,
52        B: kernel::hil::ble_advertising::BleAdvertisementDriver<'static> + BleConfig + 'static,
53    > BLEComponent<A, B>
54{
55    pub fn new(
56        board_kernel: &'static kernel::Kernel,
57        driver_num: usize,
58        radio: &'static B,
59        mux_alarm: &'static capsules_core::virtualizers::virtual_alarm::MuxAlarm<'static, A>,
60    ) -> Self {
61        Self {
62            board_kernel,
63            driver_num,
64            radio,
65            mux_alarm,
66        }
67    }
68}
69
70impl<
71        A: kernel::hil::time::Alarm<'static> + 'static,
72        B: kernel::hil::ble_advertising::BleAdvertisementDriver<'static> + BleConfig + 'static,
73    > Component for BLEComponent<A, B>
74{
75    type StaticInput = (
76        &'static mut MaybeUninit<
77            capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<'static, A>,
78        >,
79        &'static mut MaybeUninit<
80            capsules_extra::ble_advertising_driver::BLE<'static, B, VirtualMuxAlarm<'static, A>>,
81        >,
82        &'static mut MaybeUninit<[u8; capsules_extra::ble_advertising_driver::PACKET_LENGTH]>,
83    );
84    type Output = &'static capsules_extra::ble_advertising_driver::BLE<
85        'static,
86        B,
87        VirtualMuxAlarm<'static, A>,
88    >;
89
90    fn finalize(self, s: Self::StaticInput) -> Self::Output {
91        let grant_cap = create_capability!(capabilities::MemoryAllocationCapability);
92
93        let ble_radio_virtual_alarm = s.0.write(
94            capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm::new(self.mux_alarm),
95        );
96        ble_radio_virtual_alarm.setup();
97        let buffer =
98            s.2.write([0; capsules_extra::ble_advertising_driver::PACKET_LENGTH]);
99
100        let ble_radio = s.1.write(capsules_extra::ble_advertising_driver::BLE::new(
101            self.radio,
102            self.board_kernel.create_grant(self.driver_num, &grant_cap),
103            buffer,
104            ble_radio_virtual_alarm,
105        ));
106        kernel::hil::ble_advertising::BleAdvertisementDriver::set_receive_client(
107            self.radio, ble_radio,
108        );
109        kernel::hil::ble_advertising::BleAdvertisementDriver::set_transmit_client(
110            self.radio, ble_radio,
111        );
112        ble_radio_virtual_alarm.set_alarm_client(ble_radio);
113
114        ble_radio
115    }
116}