-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add shared modulation types for gfsk, lora #24
Open
ryankurte
wants to merge
2
commits into
main
Choose a base branch
from
modulation-types
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
//! Common GFSK modulation options | ||
|
||
use super::Freq; | ||
|
||
/// Basic GFSK channel configuration | ||
#[derive(Clone, PartialEq, Debug)] | ||
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] | ||
pub struct GfskChannel { | ||
/// Channel frequency | ||
pub freq: Freq, | ||
|
||
/// Channel bandwidth | ||
pub bw_khz: Freq, | ||
|
||
/// Bitrate in bps | ||
pub bitrate_bps: u32, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
//! Common LoRa modulation options | ||
|
||
use super::Freq; | ||
|
||
/// LoRa mode channel configuration | ||
#[derive(Clone, PartialEq, Debug)] | ||
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] | ||
|
||
pub struct LoRaChannel { | ||
/// LoRa frequency in kHz | ||
pub freq: Freq, | ||
/// LoRa channel bandwidth | ||
pub bw: Freq, | ||
/// LoRa Spreading Factor | ||
pub sf: SpreadingFactor, | ||
/// LoRa Coding rate | ||
pub cr: CodingRate, | ||
} | ||
|
||
/// Spreading factor for LoRa mode | ||
#[derive(Copy, Clone, PartialEq, Debug)] | ||
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] | ||
#[non_exhaustive] | ||
pub enum SpreadingFactor { | ||
/// LoRa Spreading Factor 5, 32 chips / symbol | ||
Sf5, | ||
/// LoRa Spreading Factor 6, 64 chips / symbol | ||
Sf6, | ||
/// LoRa Spreading Factor 7, 128 chips / symbol | ||
Sf7, | ||
/// LoRa Spreading Factor 8, 256 chips / symbol | ||
Sf8, | ||
/// LoRa Spreading Factor 9, 512 chips / symbol | ||
Sf9, | ||
/// LoRa Spreading Factor 10 1024 chips / symbol | ||
Sf10, | ||
/// LoRa Spreading Factor 11 2048 chips / symbol | ||
Sf11, | ||
/// LoRa Spreading Factor 12 4096 chips / symbol | ||
Sf12, | ||
} | ||
|
||
#[derive(Copy, Clone, PartialEq, Debug)] | ||
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] | ||
#[non_exhaustive] | ||
pub enum CodingRate { | ||
/// LoRa Coding rate 4/5 | ||
Cr4_5, | ||
/// LoRa Coding rate 4/6 | ||
Cr4_6, | ||
/// LoRa Coding rate 4/7 | ||
Cr4_7, | ||
/// LoRa Coding rate 4/8 | ||
Cr4_8, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
//! Shared types for radio channel / modulation configuration | ||
|
||
use core::fmt::Debug; | ||
|
||
pub mod gfsk; | ||
|
||
pub mod lora; | ||
|
||
/// Common modulation configuration errors | ||
/// | ||
/// These are provided as a helper for `TryFrom` implementations, | ||
/// and not intended to be prescriptive. | ||
#[derive(Copy, Clone, Debug, PartialEq)] | ||
#[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
#[non_exhaustive] | ||
pub enum ModError { | ||
UnsupportedBitrate, | ||
UnsupportedFreq, | ||
UnsupportedBandwidth, | ||
} | ||
|
||
/// Basic frequency type for use in radio definitions. | ||
/// | ||
/// This splits frequencies into integer `khz` and `hz` components to achieve Hz granularity with >>GHz range. | ||
/// Users above ~4 GHz should prefer [`Freq::parts`] over integer conversions. | ||
/// ```rust | ||
/// # use radio::modulation::{Freq, Frequency}; | ||
/// // Freq objects can be constructed from numeric types | ||
/// let freq = 434.mhz(); | ||
/// assert_eq!(freq, 434_000.khz()); | ||
/// // And converted back into these numeric types as required | ||
/// assert_eq!(434, freq.mhz()); | ||
/// ``` | ||
#[derive(Copy, Clone, Debug, PartialEq)] | ||
pub struct Freq { | ||
/// kHz component | ||
khz: u32, | ||
/// Hz portion (0-1000) | ||
hz: u32, | ||
} | ||
|
||
/// Frequency trait for type conversions. | ||
/// See [`Freq`] implementations for details | ||
pub trait Frequency<T> { | ||
fn hz(&self) -> T; | ||
fn khz(&self) -> T; | ||
fn mhz(&self) -> T; | ||
fn ghz(&self) -> T; | ||
} | ||
|
||
impl Freq { | ||
/// Create a new frequency from kHz and Hz components | ||
pub const fn from_parts(khz: u32, hz: u32) -> Option<Self> { | ||
if hz >= 1000 { | ||
return None; | ||
} | ||
Some(Self { khz, hz }) | ||
} | ||
|
||
/// Fetch frequency kHz and Hz components | ||
pub const fn parts(&self) -> (u32, u32) { | ||
(self.khz, self.hz) | ||
} | ||
} | ||
|
||
/// Fetch u32 values from [`Freq`] types | ||
impl Frequency<u32> for Freq { | ||
/// Convert [`Freq`] to u32 Hz, note this will panic for frequencies over ~4GHz | ||
/// ``` | ||
/// # use radio::modulation::{Freq, Frequency}; | ||
/// let f = Freq::from_parts(433_100, 200).unwrap(); | ||
/// assert_eq!(f.hz(), 433_100_200); | ||
/// ``` | ||
fn hz(&self) -> u32 { | ||
self.khz * 1000 + self.hz | ||
} | ||
|
||
/// Convert [`Freq`] to integer kHz | ||
/// ``` | ||
/// # use radio::modulation::{Freq, Frequency}; | ||
/// let f = Freq::from_parts(433_100, 200).unwrap(); | ||
/// assert_eq!(f.khz(), 433_100); | ||
/// ``` | ||
fn khz(&self) -> u32 { | ||
self.khz | ||
} | ||
|
||
/// Convert [`Freq`] to integer MHz | ||
/// ``` | ||
/// # use radio::modulation::{Freq, Frequency}; | ||
/// let f = Freq::from_parts(2_400_100, 200).unwrap(); | ||
/// assert_eq!(f.mhz(), 2_400); | ||
/// ``` | ||
fn mhz(&self) -> u32 { | ||
self.khz() / 1000 | ||
} | ||
|
||
/// Convert [`Freq`] to integer GHz | ||
/// ``` | ||
/// # use radio::modulation::{Freq, Frequency}; | ||
/// let f = Freq::from_parts(20_000_000, 200).unwrap(); | ||
/// assert_eq!(f.ghz(), 20); | ||
/// ``` | ||
fn ghz(&self) -> u32 { | ||
self.mhz() / 1000 | ||
} | ||
} | ||
|
||
/// Create [`Freq`] objects from [`u32`] frequencies | ||
impl Frequency<Freq> for u32 { | ||
/// Create [`Freq`] from integer Hz | ||
/// ``` | ||
/// # use radio::modulation::{Freq, Frequency}; | ||
/// let f = 434_100_200.hz(); | ||
/// assert_eq!(f.khz(), 434_100); | ||
/// assert_eq!(f.hz(), 434_100_200); | ||
/// ``` | ||
fn hz(&self) -> Freq { | ||
Freq { | ||
khz: self / 1000, | ||
hz: self % 1000, | ||
} | ||
} | ||
|
||
/// Create [`Freq`] from integer kHz | ||
/// ``` | ||
/// # use radio::modulation::{Freq, Frequency}; | ||
/// let f = 434_100.khz(); | ||
/// assert_eq!(f.hz(), 434_100_000); | ||
/// ``` | ||
fn khz(&self) -> Freq { | ||
Freq { khz: *self, hz: 0 } | ||
} | ||
|
||
/// Create [`Freq`] from integer MHz | ||
/// ``` | ||
/// # use radio::modulation::{Freq, Frequency}; | ||
/// let f = 2_450.mhz(); | ||
/// assert_eq!(f.khz(), 2_450_000); | ||
/// ``` | ||
fn mhz(&self) -> Freq { | ||
Freq { | ||
khz: self * 1000, | ||
hz: 0, | ||
} | ||
} | ||
|
||
/// Create [`Freq`] from integer GHz | ||
/// ``` | ||
/// # use radio::modulation::{Freq, Frequency}; | ||
/// let f = 2.ghz(); | ||
/// assert_eq!(f.mhz(), 2_000); | ||
/// ``` | ||
fn ghz(&self) -> Freq { | ||
Freq { | ||
khz: self * 1000 * 1000, | ||
hz: 0, | ||
} | ||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is
#[non_exhaustive]
necessary here and aboveCodingRate
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it means that adding additional spreading factors / coding rates in the future (what if we missed one!) would not be a breaking change and forces consumers to handle the unsupported case, i think it's worth it.