#![cfg_attr(not(feature = "std"), no_std)]
use core::convert::TryFrom;
use core::fmt::Debug;
pub mod blocking;
pub mod config;
#[cfg(feature = "helpers")]
pub mod helpers;
#[cfg(feature = "mock")]
pub mod mock;
#[cfg(feature = "nonblocking")]
pub mod nonblocking;
pub trait Radio: Transmit + Receive + State {}
pub trait Transmit {
type Error: Debug;
fn start_transmit(&mut self, data: &[u8]) -> Result<(), Self::Error>;
fn check_transmit(&mut self) -> Result<bool, Self::Error>;
}
pub trait Receive {
type Error: Debug;
type Info: ReceiveInfo;
fn start_receive(&mut self) -> Result<(), Self::Error>;
fn check_receive(&mut self, restart: bool) -> Result<bool, Self::Error>;
fn get_received(&mut self, buff: &mut [u8]) -> Result<(usize, Self::Info), Self::Error>;
}
pub trait ReceiveInfo: Debug + Default {
fn rssi(&self) -> i16;
}
#[derive(Debug, Clone, PartialEq)]
pub struct BasicInfo {
rssi: i16,
lqi: u16,
}
impl Default for BasicInfo {
fn default() -> Self {
Self {
rssi: core::i16::MIN,
lqi: core::u16::MIN,
}
}
}
impl BasicInfo {
pub fn new(rssi: i16, lqi: u16) -> Self {
Self { rssi, lqi }
}
}
impl ReceiveInfo for BasicInfo {
fn rssi(&self) -> i16 {
self.rssi
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct BasicChannel(pub u16);
impl From<u16> for BasicChannel {
fn from(u: u16) -> Self {
BasicChannel(u)
}
}
impl From<BasicChannel> for u16 {
fn from(val: BasicChannel) -> Self {
val.0
}
}
pub trait Channel {
type Channel: Debug;
type Error: Debug;
fn set_channel(&mut self, channel: &Self::Channel) -> Result<(), Self::Error>;
}
pub trait Power {
type Error: Debug;
fn set_power(&mut self, power: i8) -> Result<(), Self::Error>;
}
pub trait Rssi {
type Error: Debug;
fn poll_rssi(&mut self) -> Result<i16, Self::Error>;
}
pub trait State {
type State: RadioState;
type Error: Debug;
fn set_state(&mut self, state: Self::State) -> Result<(), Self::Error>;
fn get_state(&mut self) -> Result<Self::State, Self::Error>;
}
pub trait RadioState: Debug {
fn idle() -> Self;
fn sleep() -> Self;
}
pub trait Busy {
type Error: Debug;
fn is_busy(&mut self) -> Result<bool, Self::Error>;
}
pub trait Interrupts {
type Irq: Debug;
type Error: Debug;
fn get_interrupts(&mut self, clear: bool) -> Result<Self::Irq, Self::Error>;
}
pub trait Register:
Copy + TryFrom<Self::Word, Error = <Self as Register>::Error> + Into<Self::Word>
{
type Word;
type Error;
const ADDRESS: u8;
}
pub trait Registers<Word> {
type Error: Debug;
fn read_register<R: Register<Word = Word>>(&mut self) -> Result<R, Self::Error>;
fn write_register<R: Register<Word = Word>>(&mut self, value: R) -> Result<(), Self::Error>;
fn update_register<R: Register<Word = Word>, F: Fn(R) -> R>(
&mut self,
f: F,
) -> Result<R, Self::Error> {
let existing = self.read_register()?;
let updated = f(existing);
self.write_register(updated)?;
Ok(updated)
}
}
#[cfg(feature = "std")]
use std::str::FromStr;
#[cfg(feature = "std")]
fn duration_from_str(s: &str) -> Result<core::time::Duration, humantime::DurationError> {
let d = humantime::Duration::from_str(s)?;
Ok(*d)
}
#[cfg(test)]
mod tests {
use crate::{Register, Registers};
use core::convert::{Infallible, TryInto};
#[derive(Clone, Copy, Debug, PartialEq)]
struct TestRegister1 {
value: u8,
}
impl From<u8> for TestRegister1 {
fn from(value: u8) -> Self {
Self { value }
}
}
impl From<TestRegister1> for u8 {
fn from(reg: TestRegister1) -> Self {
reg.value
}
}
impl Register for TestRegister1 {
type Word = u8;
type Error = Infallible;
const ADDRESS: u8 = 0;
}
#[derive(Clone, Copy, Debug, PartialEq)]
struct TestRegister2 {
value: [u8; 2],
}
impl From<[u8; 2]> for TestRegister2 {
fn from(value: [u8; 2]) -> Self {
Self { value }
}
}
impl From<TestRegister2> for [u8; 2] {
fn from(reg: TestRegister2) -> Self {
reg.value
}
}
impl Register for TestRegister2 {
type Word = [u8; 2];
type Error = Infallible;
const ADDRESS: u8 = 1;
}
struct TestDevice {
device_register: [u8; 3],
}
impl Registers<u8> for TestDevice {
type Error = ();
fn read_register<R: Register<Word = u8>>(&mut self) -> Result<R, Self::Error> {
self.device_register[R::ADDRESS as usize]
.try_into()
.map_err(|_| ())
}
fn write_register<R: Register<Word = u8>>(&mut self, value: R) -> Result<(), Self::Error> {
self.device_register[R::ADDRESS as usize] = value.into();
Ok(())
}
}
impl Registers<[u8; 2]> for TestDevice {
type Error = ();
fn read_register<R: Register<Word = [u8; 2]>>(&mut self) -> Result<R, Self::Error> {
let addr = R::ADDRESS as usize;
let mut result = [0u8; 2];
result.copy_from_slice(&self.device_register[addr..addr + 2]);
result.try_into().map_err(|_| ())
}
fn write_register<R: Register<Word = [u8; 2]>>(
&mut self,
value: R,
) -> Result<(), Self::Error> {
let addr = R::ADDRESS as usize;
self.device_register[addr..addr + 2].copy_from_slice(&value.into());
Ok(())
}
}
#[test]
fn update_register1() {
let mut device = TestDevice {
device_register: [0; 3],
};
device.write_register(TestRegister1 { value: 1 }).unwrap();
device
.update_register(|r: TestRegister1| (if r.value == 1 { 2 } else { 3 }).into())
.unwrap();
assert_eq!(
device.read_register::<TestRegister1>().unwrap(),
TestRegister1 { value: 2 }
);
}
#[test]
fn update_register2() {
let mut device = TestDevice {
device_register: [0; 3],
};
device
.write_register(TestRegister2 { value: [1, 2] })
.unwrap();
device
.update_register(|r: TestRegister2| {
(if r.value == [1, 2] { [2, 3] } else { [3, 4] }).into()
})
.unwrap();
assert_eq!(
device.read_register::<TestRegister2>().unwrap(),
TestRegister2 { value: [2, 3] }
);
}
}