use embedded_hal_1::digital::{InputPin, OutputPin};
use embedded_hal_1::spi::Operation;
use embedded_hal_async::delay::DelayUs;
use embedded_hal_async::digital::Wait;
use embedded_hal_async::spi::SpiDevice;
use crate::error::Error;
use crate::packet::Packet;
use crate::registers::*;
const VERSION_CHECK: u8 = 0x24;
const F_SCALE: u64 = 1_000_000;
const FOSC: u64 = 32_000_000 * F_SCALE;
const FSTEP: u64 = FOSC / 524_288;
pub struct Rfm69<SPI, RESET, DIO0, DELAY> {
spi: SPI,
reset: RESET,
dio0: Option<DIO0>,
delay: DELAY,
pub mode: OpMode,
}
impl<SPI, RESET, DIO0, DELAY, E> Rfm69<SPI, RESET, DIO0, DELAY>
where
SPI: SpiDevice<u8, Error = E>,
RESET: OutputPin,
DIO0: InputPin + Wait,
DELAY: DelayUs,
{
pub fn new(spi: SPI, reset: RESET, dio0: Option<DIO0>, delay: DELAY) -> Self {
Self {
spi,
reset,
dio0,
delay,
mode: OpMode::Standby,
}
}
pub async fn reset(&mut self) -> Result<(), Error<E, RESET::Error, DIO0::Error>> {
self.reset.set_high().map_err(Error::Reset)?;
self.delay.delay_ms(10).await;
self.reset.set_low().map_err(Error::Reset)?;
self.delay.delay_ms(10).await;
log::debug!("Reading version register...");
let version = self.read_register(Register::Version).await?;
log::debug!("Version: {version:#x}");
if version == VERSION_CHECK {
self.set_mode(OpMode::Sleep).await?;
Ok(())
} else {
Err(Error::VersionMismatch(version))
}
}
pub async fn set_mode(&mut self, mode: OpMode) -> Result<(), Error<E, RESET::Error, DIO0::Error>> {
self.write_register(Register::OpMode, mode.value()).await?;
self.mode = mode;
Ok(())
}
pub async fn modulation(&mut self, modulation: Modulation) -> Result<(), Error<E, RESET::Error, DIO0::Error>> {
self.write_register(Register::DataModul, modulation.value()).await
}
pub async fn bit_rate(&mut self, bit_rate: u32) -> Result<(), Error<E, RESET::Error, DIO0::Error>> {
let reg = (FOSC / (bit_rate as u64 * F_SCALE)) as u16;
self.write_registers(Register::BitrateMsb, ®.to_be_bytes()).await
}
pub async fn frequency(&mut self, frequency: u32) -> Result<(), Error<E, RESET::Error, DIO0::Error>> {
let reg = ((frequency as u64 * F_SCALE) / FSTEP) as u32;
self.write_registers(Register::FrfMsb, ®.to_be_bytes()[1..]).await
}
pub async fn fdev(&mut self, fdev: u32) -> Result<(), Error<E, RESET::Error, DIO0::Error>> {
let reg = ((fdev as u64 * F_SCALE) / FSTEP) as u16;
self.write_registers(Register::FdevMsb, ®.to_be_bytes()).await
}
pub async fn rx_bw<RxBwT>(&mut self, rx_bw: RxBw<RxBwT>) -> Result<(), Error<E, RESET::Error, DIO0::Error>>
where
RxBwT: RxBwFreq,
{
self.write_register(Register::RxBw, rx_bw.dcc_cutoff as u8 | rx_bw.rx_bw.value())
.await
}
pub async fn preamble_length(&mut self, length: u16) -> Result<(), Error<E, RESET::Error, DIO0::Error>> {
self.write_registers(Register::PreambleMsb, &length.to_be_bytes()).await
}
pub async fn sync(&mut self, sync: &[u8]) -> Result<(), Error<E, RESET::Error, DIO0::Error>> {
let len = sync.len();
if len == 0 {
return self.update_register(Register::SyncConfig, |r| r & 0x7f).await;
} else if len > 8 {
return Err(Error::SyncSize);
}
let reg = 0x80 | ((len - 1) as u8) << 3;
self.write_register(Register::SyncConfig, reg).await?;
self.write_registers(Register::SyncValue1, sync).await
}
pub async fn packet(&mut self, packet_config: PacketConfig) -> Result<(), Error<E, RESET::Error, DIO0::Error>> {
let len: u8;
let mut reg = 0x00;
match packet_config.format {
PacketFormat::Fixed(size) => len = size,
PacketFormat::Variable(size) => {
len = size;
reg |= 0x80;
}
}
reg |= packet_config.dc as u8 | packet_config.filtering as u8 | (packet_config.crc as u8) << 4;
self.write_registers(Register::PacketConfig1, &[reg, len]).await?;
reg = packet_config.interpacket_rx_delay as u8 | (packet_config.auto_rx_restart as u8) << 1;
self.update_register(Register::PacketConfig2, |r| r & 0x0d | reg).await
}
pub async fn fifo_mode(&mut self, mode: FifoMode) -> Result<(), Error<E, RESET::Error, DIO0::Error>> {
match mode {
FifoMode::NotEmpty => self.update_register(Register::FifoThresh, |r| r | 0x80).await,
FifoMode::Level(level) => self.write_register(Register::FifoThresh, level & 0x7f).await,
}
}
pub async fn lna(&mut self, lna: LnaConfig) -> Result<(), Error<E, RESET::Error, DIO0::Error>> {
let reg = (lna.zin as u8) | (lna.gain_select as u8);
self.update_register(Register::Lna, |r| (r & 0x78) | reg).await
}
pub async fn rssi_threshold(&mut self, threshold: u8) -> Result<(), Error<E, RESET::Error, DIO0::Error>> {
self.write_register(Register::RssiThresh, threshold).await
}
pub async fn continuous_dagc(&mut self, cdagc: ContinuousDagc) -> Result<(), Error<E, RESET::Error, DIO0::Error>> {
self.write_register(Register::TestDagc, cdagc as u8).await
}
pub async fn is_mode_ready(&mut self) -> Result<bool, Error<E, RESET::Error, DIO0::Error>> {
let reg = self.read_register(Register::IrqFlags1).await?;
Ok((reg & IrqFlags1::ModeReady) != 0)
}
pub async fn is_packet_sent(&mut self) -> Result<bool, Error<E, RESET::Error, DIO0::Error>> {
let reg = self.read_register(Register::IrqFlags2).await?;
Ok((reg & IrqFlags2::PacketSent) != 0)
}
pub async fn is_packet_ready(&mut self) -> Result<bool, Error<E, RESET::Error, DIO0::Error>> {
let reg = self.read_register(Register::IrqFlags2).await?;
Ok(reg & IrqFlags2::PayloadReady != 0)
}
async fn reset_fifo(&mut self) -> Result<(), Error<E, RESET::Error, DIO0::Error>> {
self.write_register(Register::IrqFlags2, IrqFlags2::FifoOverrun as u8)
.await
}
async fn read_rssi(&mut self) -> Result<i16, Error<E, RESET::Error, DIO0::Error>> {
let reg = self.read_register(Register::RssiValue).await?;
Ok(-i16::from(reg) >> 1)
}
async fn read_register(&mut self, reg: Register) -> Result<u8, Error<E, RESET::Error, DIO0::Error>> {
let mut buffer = [reg.addr() & 0x7f, 0];
self.spi
.transaction(&mut [Operation::Transfer(&mut buffer, &[reg.addr() & 0x7f])])
.await
.map_err(Error::SPI)?;
Ok(buffer[1])
}
async fn write_register(&mut self, reg: Register, byte: u8) -> Result<(), Error<E, RESET::Error, DIO0::Error>> {
self.spi
.write_transaction(&[&[reg.addr() | 0x80, byte]])
.await
.map_err(Error::SPI)
}
async fn update_register<F>(&mut self, reg: Register, f: F) -> Result<(), Error<E, RESET::Error, DIO0::Error>>
where
F: FnOnce(u8) -> u8,
{
let val = self.read_register(reg).await?;
self.write_register(reg, f(val)).await
}
async fn write_registers(&mut self, reg: Register, data: &[u8]) -> Result<(), Error<E, RESET::Error, DIO0::Error>> {
self.spi
.write_transaction(&[&[reg.addr() | 0x80], data])
.await
.map_err(Error::SPI)
}
async fn read_registers(
&mut self,
reg: Register,
data: &mut [u8],
) -> Result<(), Error<E, RESET::Error, DIO0::Error>> {
self.spi
.transaction(&mut [Operation::Write(&[reg.addr() & 0x7f]), Operation::Read(data)])
.await
.map_err(Error::SPI)
}
pub async fn read_all_regs(&mut self) -> Result<[u8; 0x4f], Error<E, RESET::Error, DIO0::Error>> {
let mut buffer = [0u8; 0x4f];
self.read_registers(Register::OpMode, &mut buffer).await?;
Ok(buffer)
}
pub async fn send(&mut self, packet: &Packet) -> Result<(), Error<E, RESET::Error, DIO0::Error>> {
if self.dio0.is_some() {
self.write_register(Register::DioMapping1, 0).await?;
}
let mode = self.read_register(Register::OpMode).await?;
log::debug!("OpMode 0x{:02x}", mode);
self.set_mode(OpMode::Standby).await?;
self.delay.delay_ms(1).await;
while !self.is_mode_ready().await? {
self.delay.delay_ms(500).await;
let mode = self.read_register(Register::OpMode).await?;
let irq1 = self.read_register(Register::IrqFlags1).await?;
let irq2 = self.read_register(Register::IrqFlags2).await?;
log::info!("OM 0x{:02x} - Irq1 0x{:02x} - Irq2 0x{:02x}", mode, irq1, irq2);
}
self.reset_fifo().await?;
self.delay.delay_ms(1).await;
let mut raw = [0_u8; 65];
let len = packet.to_slice(&mut raw).map_err(|_| Error::WrongPacketFormat)?;
self.write_registers(Register::Fifo, &raw[..len as usize]).await?;
self.set_mode(OpMode::Tx).await?;
if let Some(dio0) = &mut self.dio0 {
dio0.wait_for_high().await.map_err(Error::DIO0)?;
} else {
while !self.is_packet_sent().await? {
}
}
log::debug!("Packet Sent");
self.set_mode(OpMode::Standby).await
}
pub async fn recv(&mut self) -> Result<Packet, Error<E, RESET::Error, DIO0::Error>> {
if self.dio0.is_some() {
self.write_register(Register::DioMapping1, 0x40).await?;
}
self.set_mode(OpMode::Rx).await?;
if let Some(dio0) = &mut self.dio0 {
dio0.wait_for_high().await.map_err(Error::DIO0)?;
} else {
while !self.is_packet_ready().await? {
self.delay.delay_us(500).await;
}
}
self.set_mode(OpMode::Standby).await?;
let len = self.read_register(Register::Fifo).await?;
let mut buffer = [0; 64];
self.read_registers(Register::Fifo, &mut buffer[..len as usize]).await?;
let rssi = self.read_rssi().await?;
let packet = Packet::from_rx_data(len, &buffer, rssi).map_err(|_| Error::WrongPacketFormat)?;
log::debug!("Rx: Rssi {}; Len {}", rssi, len);
Ok(packet)
}
}