stm32wb_hci/vendor/command/
hal.rs

1//! Vendor-specific HCI commands and types needed for those commands.
2
3extern crate byteorder;
4
5use byteorder::{ByteOrder, LittleEndian};
6
7use crate::Controller;
8
9/// Vendor-specific HCI commands.
10pub trait HalCommands {
11    /// This command is intended to retrieve the firmware revision number.
12    ///
13    /// # Errors
14    ///
15    /// Only underlying communication errors are reported.
16    ///
17    /// # Generated events
18    ///
19    /// The controller will generate a
20    /// [command complete](crate::event::command::CommandComplete) event.
21    async fn get_firmware_revision(&mut self);
22
23    /// This command writes a value to a low level configure data structure. It is useful to setup
24    /// directly some low level parameters for the system in the runtime.
25    ///
26    /// # Errors
27    ///
28    /// Only underlying communication errors are reported.
29    ///
30    /// # Generated events
31    ///
32    /// The controller will generate a [command complete](crate::event::command::CommandComplete) event.
33    async fn write_config_data(&mut self, config: &ConfigData);
34
35    /// This command requests the value in the low level configure data structure.
36    ///
37    /// # Errors
38    ///
39    /// Only underlying communication errors are reported.
40    ///
41    /// # Generated events
42    ///
43    /// The controller will generate a [command complete](crate::event::command::CommandComplete) event.
44    async fn read_config_data(&mut self, param: ConfigParameter);
45
46    /// This command sets the TX power level of the BlueNRG-MS.
47    ///
48    /// When the system starts up or reboots, the default TX power level will be used, which is the
49    /// maximum value of [8 dBm](PowerLevel::Dbm8_0). Once this command is given, the output power
50    /// will be changed instantly, regardless if there is Bluetooth communication going on or
51    /// not. For example, for debugging purpose, the BlueNRG-MS can be set to advertise all the
52    /// time. And use this command to observe the signal strength changing.
53    ///
54    /// The system will keep the last received TX power level from the command, i.e. the 2nd
55    /// command overwrites the previous TX power level. The new TX power level remains until
56    /// another Set TX Power command, or the system reboots.
57    ///
58    /// # Errors
59    ///
60    /// Only underlying communication errors are reported.
61    ///
62    /// # Generated events
63    ///
64    /// The controller will generate a [command complete](crate::event::command::CommandComplete) event.
65    async fn set_tx_power_level(&mut self, level: PowerLevel);
66
67    /// Retrieve the number of packets sent in the last TX direct test.
68    ///
69    /// During the Direct Test mode, in the TX tests, the number of packets sent in the test is not
70    /// returned when executing the Direct Test End command. This command implements this feature.
71    ///
72    /// If the Direct TX test is started, a 16-bit counter will be used to count how many packets
73    /// have been transmitted. After the Direct Test End, this command can be used to check how many
74    /// packets were sent during the Direct TX test.
75    ///
76    /// The counter starts from 0 and counts upwards. As would be the case if 16-bits are all used,
77    /// the counter wraps back and starts from 0 again. The counter is not cleared until the next
78    /// Direct TX test starts.
79    ///
80    /// # Errors
81    ///
82    /// Only underlying communication errors are reported.
83    ///
84    /// # Generated events
85    ///
86    /// The controller will generate a [command complete](crate::event::command::CommandComplete) event.
87    async fn get_tx_test_packet_count(&mut self);
88
89    /// This command starts a carrier frequency, i.e. a tone, on a specific channel.
90    ///
91    /// The frequency sine wave at the specific channel may be used for debugging purpose only. The
92    /// channel ID is a parameter from 0 to 39 for the 40 BLE channels, e.g. 0 for 2.402 GHz, 1 for
93    /// 2.404 GHz etc.
94    ///
95    /// This command should not be used when normal Bluetooth activities are ongoing.
96    /// The tone should be stopped by [`stop_tone`](HalCommands::stop_tone) command.
97    ///
98    /// # Errors
99    ///
100    /// - [InvalidChannel](Error::InvalidChannel) if the channel is greater than 39.
101    /// - Underlying communication errors
102    ///
103    /// # Generated events
104    ///
105    /// The controller will generate a [command complete](crate::event::command::CommandComplete) event.
106    async fn start_tone(&mut self, channel: u8, freq_offset: u8) -> Result<(), Error>;
107
108    /// Stops the previously started by the [`start_tone`](HalCommands::start_tone) command.
109    ///
110    /// # Errors
111    ///
112    /// Only underlying communication errors are reported.
113    ///
114    /// # Generated events
115    ///
116    /// The controller will generate a [command complete](crate::event::command::CommandComplete) event.
117    async fn stop_tone(&mut self);
118
119    /// This command is intended to return the Link Layer Status and Connection Handles.
120    ///
121    /// # Errors
122    ///
123    /// Only underlying communication errors are reported.
124    ///
125    /// # Generated events
126    ///
127    /// The controller will generate a [command complete](crate::event::command::CommandComplete) event.
128    async fn get_link_status(&mut self);
129
130    /// This command sets the bitmask associated to
131    /// [End of Radio Activity](crate::vendor::event::VendorEvent::EndOfRadioActivity) event.
132    ///
133    /// Only the radio activities enabled in the mask will be reported to the application by the
134    /// [End of Radio Activity](crate::vendor::event::VendorEvent::EndOfRadioActivity) event.
135    async fn set_radio_activity_mask(&mut self, mask: RadioActivityFlags);
136
137    /// This command is intended to retrieve information about the current Anchor Interval and
138    /// allocable timing slots.
139    ///
140    /// # Errors
141    ///
142    /// Only underlying communication errors are reported.
143    ///
144    /// # Generated events
145    ///
146    /// The controller will generate a [command complete](crate::event::command::CommandComplete) event.
147    async fn get_anchor_period(&mut self);
148
149    /// This command is used to enable/disable the generation of HAL events.
150    ///
151    /// If the bit in the [HAL Event Mask](HalEventFlags) is set to one, then the event associated with
152    /// that will be enabled.
153    async fn set_event_mask(&mut self, mask: HalEventFlags);
154
155    /// This command is used to retreive Tx, Rx, and total buffer count allocated for ACL packets.
156    async fn get_pm_debug_info(&mut self);
157
158    /// This command is used to disable/enable the Peripheral latencyy feature during a connection.
159    ///
160    /// Note that, by default, the Peripheral latency is enabled at connection time.
161    async fn set_peripheral_latency(&mut self, enabled: bool);
162
163    /// This command returns the value of the RSSI.
164    async fn read_rssi(&mut self);
165
166    /// This command reads a register value from the RF module
167    async fn read_radio_reg(&mut self, address: u8);
168
169    /// This command returns the raw value of the RSSI
170    async fn read_raw_rssi(&mut self);
171
172    /// This command does set up the RF to listen to a specific RF Channel.
173    ///
174    /// `rf_channel`: BLE Channel Id, from 0x00 to 0x27 meaning `(2.402 + 0.002 * 0xXX) GHz`.
175    /// The device will continously emit 0s, meaning that the tone will be at the channel center
176    /// frequency minus the maximum frequency deviation (250 KHz).
177    async fn rx_start(&mut self, rf_channel: u8);
178
179    /// This command stops a previous [HAL Rx Start](HalCommands::rx_start) command
180    async fn rx_stop(&mut self);
181
182    /// This command is equivalent to [HCI Reset](crate::host::HostHci::reset) but ensures
183    /// the sleep mode is entered immediately after its completion.
184    async fn stack_reset(&mut self);
185}
186
187impl<T: Controller> HalCommands for T {
188    async fn get_firmware_revision(&mut self) {
189        self.controller_write(crate::vendor::opcode::HAL_GET_FIRMWARE_REVISION, &[])
190            .await
191    }
192
193    impl_variable_length_params!(
194        write_config_data,
195        ConfigData,
196        crate::vendor::opcode::HAL_WRITE_CONFIG_DATA
197    );
198
199    async fn read_config_data(&mut self, param: ConfigParameter) {
200        self.controller_write(crate::vendor::opcode::HAL_READ_CONFIG_DATA, &[param as u8])
201            .await
202    }
203
204    async fn set_tx_power_level(&mut self, level: PowerLevel) {
205        // Byte 0: enable high power mode - deprecated and ignored on STM32WB
206        // Byte 1: PA level
207        let mut bytes = [0; 2];
208        bytes[1] = level as u8;
209
210        self.controller_write(crate::vendor::opcode::HAL_SET_TX_POWER_LEVEL, &bytes)
211            .await
212    }
213
214    async fn get_tx_test_packet_count(&mut self) {
215        self.controller_write(crate::vendor::opcode::HAL_TX_TEST_PACKET_COUNT, &[])
216            .await
217    }
218
219    async fn start_tone(&mut self, channel: u8, freq_offset: u8) -> Result<(), Error> {
220        const MAX_CHANNEL: u8 = 39;
221        if channel > MAX_CHANNEL {
222            return Err(Error::InvalidChannel(channel));
223        }
224
225        self.controller_write(
226            crate::vendor::opcode::HAL_START_TONE,
227            &[channel, freq_offset],
228        )
229        .await;
230
231        Ok(())
232    }
233
234    async fn stop_tone(&mut self) {
235        self.controller_write(crate::vendor::opcode::HAL_STOP_TONE, &[])
236            .await
237    }
238
239    async fn get_link_status(&mut self) {
240        self.controller_write(crate::vendor::opcode::HAL_GET_LINK_STATUS, &[])
241            .await
242    }
243
244    async fn get_anchor_period(&mut self) {
245        self.controller_write(crate::vendor::opcode::HAL_GET_ANCHOR_PERIOD, &[])
246            .await
247    }
248
249    async fn set_radio_activity_mask(&mut self, mask: RadioActivityFlags) {
250        let mut payload = [0; 2];
251        LittleEndian::write_u16(&mut payload, mask.bits());
252        self.controller_write(crate::vendor::opcode::HAL_SET_RADIO_ACTIVITY_MASK, &payload)
253            .await;
254    }
255
256    async fn set_event_mask(&mut self, mask: HalEventFlags) {
257        let mut payload = [0; 4];
258        LittleEndian::write_u32(&mut payload, mask.bits());
259        self.controller_write(crate::vendor::opcode::HAL_SET_EVENT_MASK, &payload)
260            .await;
261    }
262
263    async fn get_pm_debug_info(&mut self) {
264        self.controller_write(crate::vendor::opcode::HAL_GET_PM_DEBUG_INFO, &[])
265            .await;
266    }
267
268    async fn set_peripheral_latency(&mut self, enabled: bool) {
269        self.controller_write(
270            crate::vendor::opcode::HAL_SET_PERIPHERAL_LATENCY,
271            &[enabled as u8],
272        )
273        .await;
274    }
275
276    async fn read_rssi(&mut self) {
277        self.controller_write(crate::vendor::opcode::HAL_READ_RSSI, &[])
278            .await;
279    }
280
281    async fn read_radio_reg(&mut self, address: u8) {
282        self.controller_write(crate::vendor::opcode::HAL_READ_RADIO_REG, &[address])
283            .await;
284    }
285
286    async fn read_raw_rssi(&mut self) {
287        self.controller_write(crate::vendor::opcode::HAL_READ_RAW_RSSI, &[])
288            .await;
289    }
290
291    async fn rx_start(&mut self, rf_channel: u8) {
292        self.controller_write(crate::vendor::opcode::HAL_RX_START, &[rf_channel])
293            .await;
294    }
295
296    async fn rx_stop(&mut self) {
297        self.controller_write(crate::vendor::opcode::HAL_RX_STOP, &[])
298            .await;
299    }
300
301    async fn stack_reset(&mut self) {
302        self.controller_write(crate::vendor::opcode::HAL_STACK_RESET, &[])
303            .await;
304    }
305}
306
307/// Potential errors from parameter validation.
308///
309/// Before some commands are sent to the controller, the parameters are validated. This type
310/// enumerates the potential validation errors. Must be specialized on the types of communication
311/// errors.
312#[derive(Copy, Clone, Debug, PartialEq)]
313#[cfg_attr(feature = "defmt", derive(defmt::Format))]
314pub enum Error {
315    /// For the [Start Tone](HalCommands::start_tone) command, the channel was greater than the maximum
316    /// allowed channel (39). The invalid channel is returned.
317    InvalidChannel(u8),
318}
319
320/// Low-level configuration parameters for the controller.
321pub struct ConfigData {
322    /// Offset of the element in the configuration data structure which has to be written.
323    ///
324    /// Values:
325    ///- 0x00: CONFIG_DATA_PUBADDR_OFFSET;
326    ///  Bluetooth public address; 6 bytes
327    ///- 0x08: CONFIG_DATA_ER_OFFSET;
328    ///  Encryption root key used to derive LTK (legacy) and CSRK; 16 bytes
329    ///- 0x18: CONFIG_DATA_IR_OFFSET;
330    ///  Identity root key used to derive DHK (legacy) and IRK; 16 bytes
331    ///- 0x2E: CONFIG_DATA_RANDOM_ADDRESS_OFFSET;
332    ///  Static Random Address; 6 bytes
333    ///- 0x34: CONFIG_DATA_GAP_ADD_REC_NBR_OFFSET;
334    ///  GAP service additional record number; 1 byte
335    ///- 0x35: CONFIG_DATA_SC_KEY_TYPE_OFFSET;
336    ///  Secure Connection key type (0: "normal", 1: "debug"); 1 byte
337    ///- 0xB0: CONFIG_DATA_SMP_MODE_OFFSET;
338    ///  SMP mode (0: "normal", 1: "bypass", 2: "no blacklist"); 1 byte
339    ///- 0xC0: CONFIG_DATA_LL_SCAN_CHAN_MAP_OFFSET (only for STM32WB);
340    ///  LL scan channel map (same format as Primary_Adv_Channel_Map); 1
341    ///  byte
342    ///- 0xC1: CONFIG_DATA_LL_BG_SCAN_MODE_OFFSET (only for STM32WB);
343    ///  LL background scan mode (0: "BG scan disabled", 1: "BG scan
344    ///  enabled"); 1 byte
345    offset: u8,
346    /// Length of the value to be written
347    length: u8,
348    /// Data to be written
349    value_buf: [u8; ConfigData::MAX_LENGTH],
350}
351
352impl ConfigData {
353    /// Maximum length needed to serialize the data.
354    pub const MAX_LENGTH: usize = 0x2E;
355
356    /// Serializes the data into the given buffer.
357    ///
358    /// Returns the number of valid bytes in the buffer.
359    ///
360    /// # Panics
361    ///
362    /// The buffer must be large enough to support the serialized data (at least
363    /// [`MAX_LENGTH`](ConfigData::MAX_LENGTH) bytes).
364    pub fn copy_into_slice(&self, bytes: &mut [u8]) -> usize {
365        bytes[0] = self.offset;
366        bytes[1] = self.length;
367
368        let len = self.length as usize;
369        bytes[2..2 + len].copy_from_slice(&self.value_buf[..len]);
370
371        2 + len
372    }
373
374    /// Builder for [ConfigData].
375    ///
376    /// The controller allows us to write any _contiguous_ portion of the [ConfigData] structure in
377    /// [`write_config_data`](HalCommands::write_config_data).  The builder associated functions allow
378    /// us to start with any field, and the returned builder allows only either chaining the next
379    /// field or building the structure to write.
380    pub fn public_address(addr: crate::BdAddr) -> ConfigDataDiversifierBuilder {
381        let mut data = Self {
382            offset: 0,
383            length: 6,
384            value_buf: [0; Self::MAX_LENGTH],
385        };
386
387        data.value_buf[0..6].copy_from_slice(&addr.0);
388
389        ConfigDataDiversifierBuilder { data }
390    }
391
392    /// Builder for [ConfigData].
393    ///
394    /// The controller allows us to write any _contiguous_ portion of the [ConfigData] structure in
395    /// [`write_config_data`](HalCommands::write_config_data).  The builder associated functions allow
396    /// us to start with any field, and the returned builder allows only either chaining the next
397    /// field or building the structure to write.
398    pub fn random_address(addr: crate::BdAddr) -> ConfigDataDiversifierBuilder {
399        let mut data = Self {
400            offset: 0x2E,
401            length: 6,
402            value_buf: [0; Self::MAX_LENGTH],
403        };
404
405        data.value_buf[0..6].copy_from_slice(&addr.0);
406
407        ConfigDataDiversifierBuilder { data }
408    }
409
410    /// Builder for [ConfigData].
411    ///
412    /// The controller allows us to write any _contiguous_ portion of the [ConfigData] structure in
413    /// [`write_config_data`](HalCommands::write_config_data).  The builder associated functions allow
414    /// us to start with any field, and the returned builder allows only either chaining the next
415    /// field or building the structure to write.
416    pub fn diversifier(d: u16) -> ConfigDataEncryptionRootBuilder {
417        let mut data = Self {
418            offset: 6,
419            length: 2,
420            value_buf: [0; Self::MAX_LENGTH],
421        };
422        LittleEndian::write_u16(&mut data.value_buf[0..2], d);
423
424        ConfigDataEncryptionRootBuilder { data }
425    }
426
427    /// Builder for [ConfigData].
428    ///
429    /// The controller allows us to write any _contiguous_ portion of the [ConfigData] structure in
430    /// [`write_config_data`](HalCommands::write_config_data).  The builder associated functions allow
431    /// us to start with any field, and the returned builder allows only either chaining the next
432    /// field or building the structure to write.
433    pub fn encryption_root(key: &crate::host::EncryptionKey) -> ConfigDataIdentityRootBuilder {
434        let mut data = Self {
435            offset: 8,
436            length: 16,
437            value_buf: [0; Self::MAX_LENGTH],
438        };
439        data.value_buf[0..16].copy_from_slice(&key.0);
440
441        ConfigDataIdentityRootBuilder { data }
442    }
443
444    /// Builder for [ConfigData].
445    ///
446    /// The controller allows us to write any _contiguous_ portion of the [ConfigData] structure in
447    /// [`write_config_data`](HalCommands::write_config_data).  The builder associated functions allow
448    /// us to start with any field, and the returned builder allows only either chaining the next
449    /// field or building the structure to write.
450    pub fn identity_root(key: &crate::host::EncryptionKey) -> ConfigDataLinkLayerOnlyBuilder {
451        let mut data = Self {
452            offset: 24,
453            length: 16,
454            value_buf: [0; Self::MAX_LENGTH],
455        };
456        data.value_buf[0..16].copy_from_slice(&key.0);
457        ConfigDataLinkLayerOnlyBuilder { data }
458    }
459
460    /// Builder for [ConfigData].
461    ///
462    /// The controller allows us to write any _contiguous_ portion of the [ConfigData] structure in
463    /// [`write_config_data`](HalCommands::write_config_data).  The builder associated functions allow
464    /// us to start with any field, and the returned builder allows only either chaining the next
465    /// field or building the structure to write.
466    pub fn link_layer_only(ll_only: bool) -> ConfigDataRoleBuilder {
467        let mut data = Self {
468            offset: 40,
469            length: 1,
470            value_buf: [0; Self::MAX_LENGTH],
471        };
472        data.value_buf[0] = ll_only as u8;
473        ConfigDataRoleBuilder { data }
474    }
475
476    /// Builder for [ConfigData].
477    ///
478    /// The controller allows us to write any _contiguous_ portion of the [ConfigData] structure in
479    /// [`write_config_data`](HalCommands::write_config_data).  The builder associated functions allow
480    /// us to start with any field, and the returned builder allows only either chaining the next
481    /// field or building the structure to write.
482    pub fn role(role: Role) -> ConfigDataCompleteBuilder {
483        let mut data = Self {
484            offset: 41,
485            length: 1,
486            value_buf: [0; Self::MAX_LENGTH],
487        };
488        data.value_buf[0] = role as u8;
489        ConfigDataCompleteBuilder { data }
490    }
491}
492
493/// Builder for [`ConfigData`].
494pub struct ConfigDataDiversifierBuilder {
495    data: ConfigData,
496}
497
498impl ConfigDataDiversifierBuilder {
499    /// Specify the diversifier and continue building.
500    pub fn diversifier(mut self, d: u16) -> ConfigDataEncryptionRootBuilder {
501        let len = self.data.length as usize;
502        LittleEndian::write_u16(&mut self.data.value_buf[len..2 + len], d);
503        self.data.length += 2;
504
505        ConfigDataEncryptionRootBuilder { data: self.data }
506    }
507
508    /// Build the [ConfigData] as-is. It includes only the public address.
509    pub fn build(self) -> ConfigData {
510        self.data
511    }
512}
513
514/// Builder for [`ConfigData`].
515pub struct ConfigDataEncryptionRootBuilder {
516    data: ConfigData,
517}
518
519impl ConfigDataEncryptionRootBuilder {
520    /// Specify the encryption root and continue building.
521    pub fn encryption_root(
522        mut self,
523        key: &crate::host::EncryptionKey,
524    ) -> ConfigDataIdentityRootBuilder {
525        let len = self.data.length as usize;
526        self.data.value_buf[len..16 + len].copy_from_slice(&key.0);
527        self.data.length += 16;
528
529        ConfigDataIdentityRootBuilder { data: self.data }
530    }
531
532    /// Build the [ConfigData] as-is. It includes the diversifier, and may include fields before it,
533    /// but does not include any fields after it (including the encryption root).
534    pub fn build(self) -> ConfigData {
535        self.data
536    }
537}
538
539/// Builder for [`ConfigData`].
540pub struct ConfigDataIdentityRootBuilder {
541    data: ConfigData,
542}
543
544impl ConfigDataIdentityRootBuilder {
545    /// Specify the identity root and continue building.
546    pub fn identity_root(
547        mut self,
548        key: &crate::host::EncryptionKey,
549    ) -> ConfigDataLinkLayerOnlyBuilder {
550        let len = self.data.length as usize;
551        self.data.value_buf[len..16 + len].copy_from_slice(&key.0);
552        self.data.length += 16;
553
554        ConfigDataLinkLayerOnlyBuilder { data: self.data }
555    }
556
557    /// Build the [ConfigData] as-is. It includes the encryption root, and may include fields before
558    /// it, but does not include any fields after it (including the identity root).
559    pub fn build(self) -> ConfigData {
560        self.data
561    }
562}
563
564/// Builder for [`ConfigData`].
565pub struct ConfigDataLinkLayerOnlyBuilder {
566    data: ConfigData,
567}
568
569impl ConfigDataLinkLayerOnlyBuilder {
570    /// Specify whether to use the link layer only and continue building.
571    pub fn link_layer_only(mut self, ll_only: bool) -> ConfigDataRoleBuilder {
572        self.data.value_buf[self.data.length as usize] = ll_only as u8;
573        self.data.length += 1;
574        ConfigDataRoleBuilder { data: self.data }
575    }
576
577    /// Build the [ConfigData] as-is. It includes the identity root, and may include fields before
578    /// it, but does not include any fields after it (including the link layer only flag).
579    pub fn build(self) -> ConfigData {
580        self.data
581    }
582}
583
584/// Builder for [`ConfigData`].
585pub struct ConfigDataRoleBuilder {
586    data: ConfigData,
587}
588
589impl ConfigDataRoleBuilder {
590    /// Specify the device role and continue building.
591    pub fn role(mut self, role: Role) -> ConfigDataCompleteBuilder {
592        self.data.value_buf[self.data.length as usize] = role as u8;
593        self.data.length += 1;
594        ConfigDataCompleteBuilder { data: self.data }
595    }
596
597    /// Build the [ConfigData] as-is. It includes the link layer only flag, and may include fields
598    /// before it, but does not include any fields after it (including the role).
599    pub fn build(self) -> ConfigData {
600        self.data
601    }
602}
603
604/// Builder for [`ConfigData`].
605pub struct ConfigDataCompleteBuilder {
606    data: ConfigData,
607}
608
609impl ConfigDataCompleteBuilder {
610    /// Build the [ConfigData] as-is. It includes the role field, and may include fields before it.
611    pub fn build(self) -> ConfigData {
612        self.data
613    }
614}
615
616/// Roles that the server can adopt.
617#[repr(u8)]
618#[cfg_attr(feature = "defmt", derive(defmt::Format))]
619pub enum Role {
620    /// Peripheral and primary device.
621    /// - Only one connection.
622    /// - 6 KB of RAM retention.
623    Peripheral6Kb = 1,
624
625    /// Peripheral and primary device.
626    /// - Only one connection.
627    /// - 12 KB of RAM retention.
628    Peripheral12Kb = 2,
629
630    /// Primary device and peripheral
631    /// - Up to 8 connections
632    /// - 12 KB of RAM retention
633    Primary12Kb = 3,
634
635    /// Primary device and peripheral.
636    /// - Simultaneous advertising and scanning
637    /// - Up to 4 connections
638    /// - This mode is available starting from BlueNRG-MS FW stack version 7.1.b
639    SimultaneousAdvertisingScanning = 4,
640}
641
642/// Configuration parameters that are readable by the
643/// [`read_config_data`](HalCommands::read_config_data) command.
644#[repr(u8)]
645#[cfg_attr(feature = "defmt", derive(defmt::Format))]
646pub enum ConfigParameter {
647    /// Bluetooth public address.
648    PublicAddress = 0,
649
650    /// Bluetooth random address.
651    RandomAddress = 0x2E,
652
653    /// Diversifier used to derive CSRK (connection signature resolving key).
654    Diversifier = 6,
655
656    /// Encryption root key used to derive the LTK (long-term key) and CSRK (connection signature
657    /// resolving key).
658    EncryptionRoot = 8,
659
660    /// Identity root key used to derive the LTK (long-term key) and CSRK (connection signature
661    /// resolving key).
662    IdentityRoot = 24,
663
664    /// Switch on/off Link Layer only mode.
665    LinkLayerOnly = 40,
666
667    /// BlueNRG-MS roles and mode configuration.
668    Role = 41,
669}
670
671/// Transmitter power levels available for the system.
672///
673/// STM32WB5x uses single byte parameter for PA level.
674#[repr(u8)]
675#[cfg_attr(feature = "defmt", derive(defmt::Format))]
676pub enum PowerLevel {
677    /// -40 dBm.
678    Minus40dBm = 0x00,
679
680    /// -20.85 dBm.
681    Minus20_85dBm = 0x01,
682
683    /// -19.75 dBm.
684    Minus19_75dBm = 0x02,
685
686    /// -18.85 dBm.
687    Minus18_85dBm = 0x03,
688
689    /// 17.6 dBm.
690    Minus17_6dBm = 0x04,
691
692    /// -16.5 dBm.
693    Minus16_5dBm = 0x05,
694
695    /// -15.25 dBm.
696    Minus15_25dBm = 0x06,
697
698    /// -14.1 dBm.
699    Minus14_1dBm = 0x07,
700
701    /// -13.15 dBm.
702    Minus13_15dBm = 0x08,
703
704    /// -12.05 dBm.
705    Minus12_05dBm = 0x09,
706
707    /// -10.9 dBm.
708    Minus10_9dBm = 0x0A,
709
710    /// -9.9 dBm.
711    Minus9_9dBm = 0x0B,
712
713    /// -8.85 dBm.
714    Minus8_85dBm = 0x0C,
715
716    /// -7.8 dBm.
717    Minus7_8dBm = 0x0D,
718
719    /// -6.9 dBm.
720    Minus6_9dBm = 0x0E,
721
722    /// -5.9 dBm.
723    Minus5_9dBm = 0x0F,
724
725    /// -4.95 dBm.
726    Minus4_95dBm = 0x10,
727
728    /// -4 dBm.
729    Minus4dBm = 0x11,
730
731    /// -3.15 dBm.
732    Minus3_15dBm = 0x12,
733
734    /// -2.45 dBm.
735    Minus2_45dBm = 0x13,
736
737    /// -1.8 dBm.
738    Minus1_8dBm = 0x14,
739
740    /// -1.3 dBm.
741    Minus1_3dBm = 0x15,
742
743    /// -0.85 dBm.
744    Minus0_85dBm = 0x16,
745
746    /// -0.5 dBm.
747    Minus0_5dBm = 0x17,
748
749    /// -0.15 dBm.
750    Minus0_15dBm = 0x18,
751
752    /// 0 dBm.
753    ZerodBm = 0x19,
754
755    /// 1 dBm.
756    Plus1dBm = 0x1A,
757
758    /// 2 dBm.
759    Plus2dBm = 0x1B,
760
761    /// 3 dBm.
762    Plus3dBm = 0x1C,
763
764    /// 4 dBm.
765    Plus4dBm = 0x1D,
766
767    /// 5 dBm.
768    Plus5dBm = 0x1E,
769
770    /// 6 dBm.
771    Plus6dBm = 0x1F,
772}
773
774#[cfg(not(feature = "defmt"))]
775bitflags::bitflags! {
776    #[derive(Debug, Clone, Copy)]
777    pub struct RadioActivityFlags: u16 {
778        /// Idle
779        const IDLE = 0x0001;
780        /// Advertising
781        const ADVERTISING = 0x0002;
782        /// Peripheral connection
783        const PERIPHERAL_CONN = 0x0004;
784        /// Scanning
785        const SCANNING = 0x0008;
786        /// Central connection
787        const CENTRAL_CONN = 0x0020;
788        /// Tx test mode
789        const TX_TEST = 0x0040;
790        /// Rx test mode
791        const RX_TEST = 0x0080;
792    }
793}
794
795#[cfg(feature = "defmt")]
796defmt::bitflags! {
797    pub struct RadioActivityFlags: u16 {
798        /// Idle
799        const IDLE = 0x0001;
800        /// Advertising
801        const ADVERTISING = 0x0002;
802        /// Peripheral connection
803        const PERIPHERAL_CONN = 0x0004;
804        /// Scanning
805        const SCANNING = 0x0008;
806        /// Central connection
807        const CENTRAL_CONN = 0x0020;
808        /// Tx test mode
809        const TX_TEST = 0x0040;
810        /// Rx test mode
811        const RX_TEST = 0x0080;
812    }
813}
814
815#[cfg(not(feature = "defmt"))]
816bitflags::bitflags! {
817    #[derive(Debug, Clone, Copy)]
818    pub struct HalEventFlags: u32 {
819        /// [HAL Scan Request Report](crate::vendor::event::VendorEvent::HalScanReqReport) event
820        const SCAN_REQ_REPORT = 0x00000001;
821    }
822}
823
824#[cfg(feature = "defmt")]
825defmt::bitflags! {
826    pub struct HalEventFlags: u32 {
827        /// [HAL Scan Request Report](crate::vendor::event::VendorEvent::HalScanReqReport) event
828        const SCAN_REQ_REPORT = 0x00000001;
829    }
830}