1#![cfg_attr(not(feature = "std"), no_std)]
11
12use core::convert::TryFrom;
13use core::fmt::Debug;
14
15pub mod blocking;
16pub mod config;
17
18#[cfg(feature = "helpers")]
19pub mod helpers;
20#[cfg(feature = "mock")]
21pub mod mock;
22#[cfg(feature = "nonblocking")]
23pub mod nonblocking;
24
25pub trait Radio: Transmit + Receive + State {}
27
28pub trait Transmit {
33 type Error: Debug;
35
36 fn start_transmit(&mut self, data: &[u8]) -> Result<(), Self::Error>;
40
41 fn check_transmit(&mut self) -> Result<bool, Self::Error>;
45}
46
47pub trait Receive {
53 type Error: Debug;
55 type Info: ReceiveInfo;
57
58 fn start_receive(&mut self) -> Result<(), Self::Error>;
62
63 fn check_receive(&mut self, restart: bool) -> Result<bool, Self::Error>;
70
71 fn get_received(&mut self, buff: &mut [u8]) -> Result<(usize, Self::Info), Self::Error>;
76}
77
78pub trait ReceiveInfo: Debug + Default {
83 fn rssi(&self) -> i16;
84}
85
86#[derive(Debug, Clone, PartialEq)]
89pub struct BasicInfo {
90 rssi: i16,
92 lqi: u16,
94}
95
96impl Default for BasicInfo {
97 fn default() -> Self {
98 Self {
99 rssi: core::i16::MIN,
100 lqi: core::u16::MIN,
101 }
102 }
103}
104
105impl BasicInfo {
106 pub fn new(rssi: i16, lqi: u16) -> Self {
107 Self { rssi, lqi }
108 }
109}
110
111impl ReceiveInfo for BasicInfo {
113 fn rssi(&self) -> i16 {
114 self.rssi
115 }
116}
117
118#[derive(Debug, Clone, PartialEq)]
120pub struct BasicChannel(pub u16);
121
122impl From<u16> for BasicChannel {
123 fn from(u: u16) -> Self {
124 BasicChannel(u)
125 }
126}
127
128impl From<BasicChannel> for u16 {
129 fn from(val: BasicChannel) -> Self {
130 val.0
131 }
132}
133
134pub trait Channel {
136 type Channel: Debug;
138 type Error: Debug;
140
141 fn set_channel(&mut self, channel: &Self::Channel) -> Result<(), Self::Error>;
143}
144
145pub trait Power {
147 type Error: Debug;
149
150 fn set_power(&mut self, power: i8) -> Result<(), Self::Error>;
152}
153
154pub trait Rssi {
158 type Error: Debug;
160
161 fn poll_rssi(&mut self) -> Result<i16, Self::Error>;
165}
166
167pub trait State {
172 type State: RadioState;
174 type Error: Debug;
176
177 fn set_state(&mut self, state: Self::State) -> Result<(), Self::Error>;
179
180 fn get_state(&mut self) -> Result<Self::State, Self::Error>;
182}
183
184pub trait RadioState: Debug {
185 fn idle() -> Self;
186
187 fn sleep() -> Self;
188}
189
190pub trait Busy {
193 type Error: Debug;
195
196 fn is_busy(&mut self) -> Result<bool, Self::Error>;
199}
200
201pub trait Interrupts {
207 type Irq: Debug;
209 type Error: Debug;
211
212 fn get_interrupts(&mut self, clear: bool) -> Result<Self::Irq, Self::Error>;
215}
216
217pub trait Register:
221 Copy + TryFrom<Self::Word, Error = <Self as Register>::Error> + Into<Self::Word>
222{
223 type Word;
224 type Error;
225 const ADDRESS: u8;
226}
227
228pub trait Registers<Word> {
233 type Error: Debug;
234
235 fn read_register<R: Register<Word = Word>>(&mut self) -> Result<R, Self::Error>;
237
238 fn write_register<R: Register<Word = Word>>(&mut self, value: R) -> Result<(), Self::Error>;
240
241 fn update_register<R: Register<Word = Word>, F: Fn(R) -> R>(
243 &mut self,
244 f: F,
245 ) -> Result<R, Self::Error> {
246 let existing = self.read_register()?;
247 let updated = f(existing);
248 self.write_register(updated)?;
249 Ok(updated)
250 }
251}
252
253#[cfg(feature = "std")]
254use std::str::FromStr;
255
256#[cfg(feature = "std")]
257fn duration_from_str(s: &str) -> Result<core::time::Duration, humantime::DurationError> {
258 let d = humantime::Duration::from_str(s)?;
259 Ok(*d)
260}
261
262#[cfg(test)]
263mod tests {
264 use crate::{Register, Registers};
265
266 use core::convert::{Infallible, TryInto};
267
268 #[derive(Clone, Copy, Debug, PartialEq)]
269 struct TestRegister1 {
270 value: u8,
271 }
272
273 impl From<u8> for TestRegister1 {
274 fn from(value: u8) -> Self {
275 Self { value }
276 }
277 }
278
279 impl From<TestRegister1> for u8 {
280 fn from(reg: TestRegister1) -> Self {
281 reg.value
282 }
283 }
284
285 impl Register for TestRegister1 {
286 type Word = u8;
287 type Error = Infallible;
288 const ADDRESS: u8 = 0;
289 }
290
291 #[derive(Clone, Copy, Debug, PartialEq)]
292 struct TestRegister2 {
293 value: [u8; 2],
294 }
295
296 impl From<[u8; 2]> for TestRegister2 {
297 fn from(value: [u8; 2]) -> Self {
298 Self { value }
299 }
300 }
301
302 impl From<TestRegister2> for [u8; 2] {
303 fn from(reg: TestRegister2) -> Self {
304 reg.value
305 }
306 }
307
308 impl Register for TestRegister2 {
309 type Word = [u8; 2];
310 type Error = Infallible;
311 const ADDRESS: u8 = 1;
312 }
313
314 struct TestDevice {
315 device_register: [u8; 3],
316 }
317
318 impl Registers<u8> for TestDevice {
319 type Error = ();
320 fn read_register<R: Register<Word = u8>>(&mut self) -> Result<R, Self::Error> {
321 self.device_register[R::ADDRESS as usize]
322 .try_into()
323 .map_err(|_| ())
324 }
325
326 fn write_register<R: Register<Word = u8>>(&mut self, value: R) -> Result<(), Self::Error> {
327 self.device_register[R::ADDRESS as usize] = value.into();
328 Ok(())
329 }
330 }
331
332 impl Registers<[u8; 2]> for TestDevice {
333 type Error = ();
334 fn read_register<R: Register<Word = [u8; 2]>>(&mut self) -> Result<R, Self::Error> {
335 let addr = R::ADDRESS as usize;
336 let mut result = [0u8; 2];
337 result.copy_from_slice(&self.device_register[addr..addr + 2]);
338 result.try_into().map_err(|_| ())
339 }
340
341 fn write_register<R: Register<Word = [u8; 2]>>(
342 &mut self,
343 value: R,
344 ) -> Result<(), Self::Error> {
345 let addr = R::ADDRESS as usize;
346 self.device_register[addr..addr + 2].copy_from_slice(&value.into());
347 Ok(())
348 }
349 }
350
351 #[test]
352 fn update_register1() {
353 let mut device = TestDevice {
354 device_register: [0; 3],
355 };
356 device.write_register(TestRegister1 { value: 1 }).unwrap();
357 device
358 .update_register(|r: TestRegister1| (if r.value == 1 { 2 } else { 3 }).into())
359 .unwrap();
360 assert_eq!(
361 device.read_register::<TestRegister1>().unwrap(),
362 TestRegister1 { value: 2 }
363 );
364 }
365
366 #[test]
367 fn update_register2() {
368 let mut device = TestDevice {
369 device_register: [0; 3],
370 };
371 device
372 .write_register(TestRegister2 { value: [1, 2] })
373 .unwrap();
374 device
375 .update_register(|r: TestRegister2| {
376 (if r.value == [1, 2] { [2, 3] } else { [3, 4] }).into()
377 })
378 .unwrap();
379 assert_eq!(
380 device.read_register::<TestRegister2>().unwrap(),
381 TestRegister2 { value: [2, 3] }
382 );
383 }
384}