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}