#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum Cc1101Band {
Band315,
#[default]
Band433,
Band868,
Band915,
}
impl Cc1101Band {
pub fn frequency_mhz(self) -> u16 {
match self {
Self::Band315 => 315,
Self::Band433 => 433,
Self::Band868 => 868,
Self::Band915 => 915,
}
}
pub fn freq_registers(self) -> (u8, u8, u8) {
match self {
Self::Band315 => (0x0C, 0x1D, 0x89),
Self::Band433 => (0x10, 0xB1, 0x3B),
Self::Band868 => (0x21, 0x62, 0x76),
Self::Band915 => (0x23, 0x31, 0x3B),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum Cc1101DataRate {
Rate1k2,
Rate2k4,
Rate10k,
#[default]
Rate38k4,
Rate76k8,
Rate100k,
Rate250k,
}
impl Cc1101DataRate {
pub fn bps(self) -> u32 {
match self {
Self::Rate1k2 => 1200,
Self::Rate2k4 => 2400,
Self::Rate10k => 10000,
Self::Rate38k4 => 38400,
Self::Rate76k8 => 76800,
Self::Rate100k => 100_000,
Self::Rate250k => 250_000,
}
}
pub fn modem_registers(self) -> (u8, u8) {
match self {
Self::Rate1k2 => (0xF5, 0x83),
Self::Rate2k4 => (0xF6, 0x83),
Self::Rate10k => (0xC8, 0x93),
Self::Rate38k4 => (0xCA, 0x83),
Self::Rate76k8 => (0x7B, 0x83),
Self::Rate100k => (0x5B, 0xF8),
Self::Rate250k => (0x3D, 0x3B),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum Cc1101Power {
Minus30dBm,
Minus20dBm,
Minus15dBm,
Minus10dBm,
Zero,
Plus5dBm,
Plus7dBm,
#[default]
Plus10dBm,
}
impl Cc1101Power {
pub fn dbm(self) -> i8 {
match self {
Self::Minus30dBm => -30,
Self::Minus20dBm => -20,
Self::Minus15dBm => -15,
Self::Minus10dBm => -10,
Self::Zero => 0,
Self::Plus5dBm => 5,
Self::Plus7dBm => 7,
Self::Plus10dBm => 10,
}
}
pub fn register(self) -> u8 {
match self {
Self::Minus30dBm => 0x00,
Self::Minus20dBm => 0x01,
Self::Minus15dBm => 0x02,
Self::Minus10dBm => 0x03,
Self::Zero => 0x04,
Self::Plus5dBm => 0x05,
Self::Plus7dBm => 0x06,
Self::Plus10dBm => 0x07,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum Cc1101Modulation {
#[default]
Fsk2,
Gfsk,
Ask,
Fsk4,
Msk,
}
impl Cc1101Modulation {
pub fn register(self) -> u8 {
match self {
Self::Fsk2 => 0x00,
Self::Gfsk => 0x10,
Self::Ask => 0x30,
Self::Fsk4 => 0x40,
Self::Msk => 0x70,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum Cc1101SyncMode {
None,
Bits15of16,
#[default]
Bits16of16,
Bits30of32,
CarrierSense,
Bits15of16Cs,
Bits16of16Cs,
Bits30of32Cs,
}
impl Cc1101SyncMode {
pub fn register(self) -> u8 {
match self {
Self::None => 0x00,
Self::Bits15of16 => 0x01,
Self::Bits16of16 => 0x02,
Self::Bits30of32 => 0x03,
Self::CarrierSense => 0x04,
Self::Bits15of16Cs => 0x05,
Self::Bits16of16Cs => 0x06,
Self::Bits30of32Cs => 0x07,
}
}
}
#[derive(Debug, Clone, Default)]
pub struct Cc1101Config {
pub band: Cc1101Band,
pub data_rate: Cc1101DataRate,
pub power: Cc1101Power,
pub modulation: Cc1101Modulation,
pub sync_mode: Cc1101SyncMode,
}
impl Cc1101Config {
pub fn long_range() -> Self {
Self {
data_rate: Cc1101DataRate::Rate1k2,
power: Cc1101Power::Plus10dBm,
..Default::default()
}
}
pub fn high_speed() -> Self {
Self {
data_rate: Cc1101DataRate::Rate250k,
power: Cc1101Power::Plus10dBm,
..Default::default()
}
}
pub fn low_power() -> Self {
Self {
data_rate: Cc1101DataRate::Rate1k2,
power: Cc1101Power::Minus10dBm,
..Default::default()
}
}
pub fn europe_868() -> Self {
Self {
band: Cc1101Band::Band868,
..Default::default()
}
}
pub fn americas_915() -> Self {
Self {
band: Cc1101Band::Band915,
..Default::default()
}
}
pub fn band_315() -> Self {
Self {
band: Cc1101Band::Band315,
..Default::default()
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_band_frequency() {
assert_eq!(Cc1101Band::Band315.frequency_mhz(), 315);
assert_eq!(Cc1101Band::Band433.frequency_mhz(), 433);
assert_eq!(Cc1101Band::Band868.frequency_mhz(), 868);
assert_eq!(Cc1101Band::Band915.frequency_mhz(), 915);
}
#[test]
fn test_band_registers() {
let (f2, f1, f0) = Cc1101Band::Band433.freq_registers();
assert_eq!(f2, 0x10);
assert_eq!(f1, 0xB1);
assert_eq!(f0, 0x3B);
}
#[test]
fn test_data_rate_bps() {
assert_eq!(Cc1101DataRate::Rate1k2.bps(), 1200);
assert_eq!(Cc1101DataRate::Rate38k4.bps(), 38400);
assert_eq!(Cc1101DataRate::Rate250k.bps(), 250_000);
}
#[test]
fn test_power_dbm() {
assert_eq!(Cc1101Power::Minus30dBm.dbm(), -30);
assert_eq!(Cc1101Power::Zero.dbm(), 0);
assert_eq!(Cc1101Power::Plus10dBm.dbm(), 10);
}
#[test]
fn test_modulation_register() {
assert_eq!(Cc1101Modulation::Fsk2.register(), 0x00);
assert_eq!(Cc1101Modulation::Gfsk.register(), 0x10);
assert_eq!(Cc1101Modulation::Ask.register(), 0x30);
}
#[test]
fn test_sync_mode_register() {
assert_eq!(Cc1101SyncMode::None.register(), 0x00);
assert_eq!(Cc1101SyncMode::Bits16of16.register(), 0x02);
}
#[test]
fn test_config_presets() {
let lr = Cc1101Config::long_range();
assert_eq!(lr.data_rate, Cc1101DataRate::Rate1k2);
let hs = Cc1101Config::high_speed();
assert_eq!(hs.data_rate, Cc1101DataRate::Rate250k);
let eu = Cc1101Config::europe_868();
assert_eq!(eu.band, Cc1101Band::Band868);
let us = Cc1101Config::americas_915();
assert_eq!(us.band, Cc1101Band::Band915);
}
#[test]
fn test_default_config() {
let config = Cc1101Config::default();
assert_eq!(config.band, Cc1101Band::Band433);
assert_eq!(config.data_rate, Cc1101DataRate::Rate38k4);
assert_eq!(config.power, Cc1101Power::Plus10dBm);
assert_eq!(config.modulation, Cc1101Modulation::Fsk2);
assert_eq!(config.sync_mode, Cc1101SyncMode::Bits16of16);
}
}