1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
use core::future::Future;
use crate::error::Error;
use crate::frame::parameters::mfglib::{
end, get_channel, get_power, send_packet, set_channel, set_power, start, start_stream,
start_tone, stop_stream, stop_tone,
};
use crate::transport::Transport;
use crate::types::ByteSizedVec;
/// The `Mfglib` trait provides an interface for the
/// Manufacturing and Functional Test Library (`MfgLib`) test routines.
pub trait Mfglib {
/// Deactivate use of `Mfglib` test routines; restores the hardware to the state it was in prior
/// to [`start()`](Self::start) and stops receiving packets started by [`start()`](Self::start)
/// at the same time.
fn end(&mut self) -> impl Future<Output = Result<(), Error>> + Send;
/// Returns the current radio channel, as previously set via [`set_channel()`](Self::set_channel).
fn get_channel(&mut self) -> impl Future<Output = Result<u8, Error>> + Send;
/// Returns the current radio power setting, as previously set via [`set_power()`](Self::set_power).
fn get_power(&mut self) -> impl Future<Output = Result<i8, Error>> + Send;
/// Sends a single packet consisting of the following bytes:
/// * `packetLength`
/// * `packetContents[0]`
/// * ...
/// * `packetContents[packetLength - 3]`
/// * `CRC[0]`
/// * `CRC[1]`
///
/// The total number of bytes sent is packetLength + 1.
/// The radio replaces the last two bytes of `content` with the 16-bit CRC for the packet.
fn send_packet(
&mut self,
content: ByteSizedVec<u8>,
) -> impl Future<Output = Result<(), Error>> + Send;
/// Sets the radio channel.
///
/// Calibration occurs if this is the first time the channel has been used.
fn set_channel(&mut self, channel: u8) -> impl Future<Output = Result<(), Error>> + Send;
/// First select the transmit power mode, and then include a method for selecting the radio transmit power.
///
/// The valid power settings depend upon the specific radio in use.
/// Ember radios have discrete power settings, and then requested power is rounded to a valid
/// power setting; the actual power output is available to the caller via [`get_power()`](Self::get_power).
fn set_power(
&mut self,
tx_power_mode: u16,
power: i8,
) -> impl Future<Output = Result<(), Error>> + Send;
/// Activate use of mfglib test routines and enables the radio receiver to report packets it
/// receives to the [`Rx`](crate::frame::parameters::mfglib::handler::Rx) callback.
///
/// These packets will not be passed up with a CRC failure.
/// All other mfglib functions will return an error until the [`start()`](Self::start) has been called.
fn start(&mut self, rx_callback: bool) -> impl Future<Output = Result<(), Error>> + Send;
/// Starts transmitting a random stream of characters.
///
/// This is so that the radio modulation can be measured.
fn start_stream(&mut self) -> impl Future<Output = Result<(), Error>> + Send;
/// Starts transmitting an unmodulated tone on the currently set channel and power level.
///
/// Upon successful return, the tone will be transmitting.
/// To stop transmitting tone, application must call [`stop_tone()`](Self::stop_tone), allowing
/// it the flexibility to determine its own criteria or tone duration (time, event, etc.).
fn start_tone(&mut self) -> impl Future<Output = Result<(), Error>> + Send;
/// Stops transmitting a random stream of characters started by [`start_stream()`](Self::start_stream).
fn stop_stream(&mut self) -> impl Future<Output = Result<(), Error>> + Send;
/// Stops transmitting tone started by [`start_tone()`](Self::start_tone).
fn stop_tone(&mut self) -> impl Future<Output = Result<(), Error>> + Send;
}
impl<T> Mfglib for T
where
T: Transport,
{
async fn end(&mut self) -> Result<(), Error> {
self.communicate(end::Command).await?.try_into()
}
async fn get_channel(&mut self) -> Result<u8, Error> {
self.communicate(get_channel::Command)
.await
.map(|response| response.channel())
}
async fn get_power(&mut self) -> Result<i8, Error> {
self.communicate(get_power::Command)
.await
.map(|response| response.power())
}
async fn send_packet(&mut self, content: ByteSizedVec<u8>) -> Result<(), Error> {
self.communicate(send_packet::Command::new(content))
.await?
.try_into()
}
async fn set_channel(&mut self, channel: u8) -> Result<(), Error> {
self.communicate(set_channel::Command::new(channel))
.await?
.try_into()
}
async fn set_power(&mut self, tx_power_mode: u16, power: i8) -> Result<(), Error> {
self.communicate(set_power::Command::new(tx_power_mode, power))
.await?
.try_into()
}
async fn start(&mut self, rx_callback: bool) -> Result<(), Error> {
self.communicate(start::Command::new(rx_callback))
.await?
.try_into()
}
async fn start_stream(&mut self) -> Result<(), Error> {
self.communicate(start_stream::Command).await?.try_into()
}
async fn start_tone(&mut self) -> Result<(), Error> {
self.communicate(start_tone::Command).await?.try_into()
}
async fn stop_stream(&mut self) -> Result<(), Error> {
self.communicate(stop_stream::Command).await?.try_into()
}
async fn stop_tone(&mut self) -> Result<(), Error> {
self.communicate(stop_tone::Command).await?.try_into()
}
}