diff options
| author | Ulf Lilleengen <[email protected]> | 2021-08-31 14:32:48 +0200 |
|---|---|---|
| committer | Ulf Lilleengen <[email protected]> | 2021-09-02 10:39:56 +0200 |
| commit | 7ad6280e6575fc400f84caa5c26eb3ba9770877f (patch) | |
| tree | 4a888ee84f7c5c59a713e08e53d41fdd6a21f020 /embassy-hal-common | |
| parent | db3cb02032fd6b861b2c39a0a354767cc72af1df (diff) | |
Add HAL for SubGhz peripheral for STM32 WL series
Based on the HAL from stm32wl, the peripheral driver has been
modified to fit into embassy, using the embassy APIs, providing
operation of the radio peripheral.
The initial version does not offer any async APIs, but the example
shows how the radio IRQ can be used to perform async TX of the radio.
Diffstat (limited to 'embassy-hal-common')
| -rw-r--r-- | embassy-hal-common/Cargo.toml | 1 | ||||
| -rw-r--r-- | embassy-hal-common/src/lib.rs | 1 | ||||
| -rw-r--r-- | embassy-hal-common/src/ratio.rs | 128 |
3 files changed, 130 insertions, 0 deletions
diff --git a/embassy-hal-common/Cargo.toml b/embassy-hal-common/Cargo.toml index 4db536de4..0e28085ff 100644 --- a/embassy-hal-common/Cargo.toml +++ b/embassy-hal-common/Cargo.toml | |||
| @@ -18,3 +18,4 @@ defmt = { version = "0.2.0", optional = true } | |||
| 18 | log = { version = "0.4.11", optional = true } | 18 | log = { version = "0.4.11", optional = true } |
| 19 | cortex-m = "0.7.1" | 19 | cortex-m = "0.7.1" |
| 20 | usb-device = "0.2.7" | 20 | usb-device = "0.2.7" |
| 21 | num-traits = { version = "0.2.14", default-features = false } | ||
diff --git a/embassy-hal-common/src/lib.rs b/embassy-hal-common/src/lib.rs index b62ae8b98..d2f6daba5 100644 --- a/embassy-hal-common/src/lib.rs +++ b/embassy-hal-common/src/lib.rs | |||
| @@ -8,6 +8,7 @@ mod macros; | |||
| 8 | pub mod peripheral; | 8 | pub mod peripheral; |
| 9 | pub mod ring_buffer; | 9 | pub mod ring_buffer; |
| 10 | pub mod usb; | 10 | pub mod usb; |
| 11 | pub mod ratio; | ||
| 11 | 12 | ||
| 12 | /// Low power blocking wait loop using WFE/SEV. | 13 | /// Low power blocking wait loop using WFE/SEV. |
| 13 | pub fn low_power_wait_until(mut condition: impl FnMut() -> bool) { | 14 | pub fn low_power_wait_until(mut condition: impl FnMut() -> bool) { |
diff --git a/embassy-hal-common/src/ratio.rs b/embassy-hal-common/src/ratio.rs new file mode 100644 index 000000000..ce7e4b1b9 --- /dev/null +++ b/embassy-hal-common/src/ratio.rs | |||
| @@ -0,0 +1,128 @@ | |||
| 1 | use core::ops::{Add, Div, Mul}; | ||
| 2 | use num_traits::{CheckedAdd, CheckedDiv, CheckedMul}; | ||
| 3 | |||
| 4 | /// Represents the ratio between two numbers. | ||
| 5 | #[derive(Copy, Clone, Debug)] | ||
| 6 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 7 | pub struct Ratio<T> { | ||
| 8 | /// Numerator. | ||
| 9 | numer: T, | ||
| 10 | /// Denominator. | ||
| 11 | denom: T, | ||
| 12 | } | ||
| 13 | |||
| 14 | impl<T> Ratio<T> { | ||
| 15 | /// Creates a new `Ratio`. | ||
| 16 | #[inline(always)] | ||
| 17 | pub const fn new_raw(numer: T, denom: T) -> Ratio<T> { | ||
| 18 | Ratio { numer, denom } | ||
| 19 | } | ||
| 20 | |||
| 21 | /// Gets an immutable reference to the numerator. | ||
| 22 | #[inline(always)] | ||
| 23 | pub const fn numer(&self) -> &T { | ||
| 24 | &self.numer | ||
| 25 | } | ||
| 26 | |||
| 27 | /// Gets an immutable reference to the denominator. | ||
| 28 | #[inline(always)] | ||
| 29 | pub const fn denom(&self) -> &T { | ||
| 30 | &self.denom | ||
| 31 | } | ||
| 32 | } | ||
| 33 | |||
| 34 | impl<T: CheckedDiv> Ratio<T> { | ||
| 35 | /// Converts to an integer, rounding towards zero. | ||
| 36 | #[inline(always)] | ||
| 37 | pub fn to_integer(&self) -> T { | ||
| 38 | unwrap!(self.numer().checked_div(self.denom())) | ||
| 39 | } | ||
| 40 | } | ||
| 41 | |||
| 42 | impl<T: CheckedMul> Div<T> for Ratio<T> { | ||
| 43 | type Output = Self; | ||
| 44 | |||
| 45 | #[inline(always)] | ||
| 46 | fn div(mut self, rhs: T) -> Self::Output { | ||
| 47 | self.denom = unwrap!(self.denom().checked_mul(&rhs)); | ||
| 48 | self | ||
| 49 | } | ||
| 50 | } | ||
| 51 | |||
| 52 | impl<T: CheckedMul> Mul<T> for Ratio<T> { | ||
| 53 | type Output = Self; | ||
| 54 | |||
| 55 | #[inline(always)] | ||
| 56 | fn mul(mut self, rhs: T) -> Self::Output { | ||
| 57 | self.numer = unwrap!(self.numer().checked_mul(&rhs)); | ||
| 58 | self | ||
| 59 | } | ||
| 60 | } | ||
| 61 | |||
| 62 | impl<T: CheckedMul + CheckedAdd> Add<T> for Ratio<T> { | ||
| 63 | type Output = Self; | ||
| 64 | |||
| 65 | #[inline(always)] | ||
| 66 | fn add(mut self, rhs: T) -> Self::Output { | ||
| 67 | self.numer = unwrap!(unwrap!(self.denom().checked_mul(&rhs)).checked_add(self.numer())); | ||
| 68 | self | ||
| 69 | } | ||
| 70 | } | ||
| 71 | |||
| 72 | macro_rules! impl_from_for_float { | ||
| 73 | ($from:ident) => { | ||
| 74 | impl From<Ratio<$from>> for f32 { | ||
| 75 | #[inline(always)] | ||
| 76 | fn from(r: Ratio<$from>) -> Self { | ||
| 77 | (r.numer as f32) / (r.denom as f32) | ||
| 78 | } | ||
| 79 | } | ||
| 80 | |||
| 81 | impl From<Ratio<$from>> for f64 { | ||
| 82 | #[inline(always)] | ||
| 83 | fn from(r: Ratio<$from>) -> Self { | ||
| 84 | (r.numer as f64) / (r.denom as f64) | ||
| 85 | } | ||
| 86 | } | ||
| 87 | }; | ||
| 88 | } | ||
| 89 | |||
| 90 | impl_from_for_float!(u8); | ||
| 91 | impl_from_for_float!(u16); | ||
| 92 | impl_from_for_float!(u32); | ||
| 93 | impl_from_for_float!(u64); | ||
| 94 | impl_from_for_float!(u128); | ||
| 95 | impl_from_for_float!(i8); | ||
| 96 | impl_from_for_float!(i16); | ||
| 97 | impl_from_for_float!(i32); | ||
| 98 | impl_from_for_float!(i64); | ||
| 99 | impl_from_for_float!(i128); | ||
| 100 | |||
| 101 | impl<T: core::fmt::Display> core::fmt::Display for Ratio<T> { | ||
| 102 | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { | ||
| 103 | core::write!(f, "{} / {}", self.numer(), self.denom()) | ||
| 104 | } | ||
| 105 | } | ||
| 106 | |||
| 107 | #[cfg(test)] | ||
| 108 | mod tests { | ||
| 109 | use super::Ratio; | ||
| 110 | |||
| 111 | #[test] | ||
| 112 | fn basics() { | ||
| 113 | let mut r = Ratio::new_raw(1, 2) + 2; | ||
| 114 | assert_eq!(*r.numer(), 5); | ||
| 115 | assert_eq!(*r.denom(), 2); | ||
| 116 | assert_eq!(r.to_integer(), 2); | ||
| 117 | |||
| 118 | r = r * 2; | ||
| 119 | assert_eq!(*r.numer(), 10); | ||
| 120 | assert_eq!(*r.denom(), 2); | ||
| 121 | assert_eq!(r.to_integer(), 5); | ||
| 122 | |||
| 123 | r = r / 2; | ||
| 124 | assert_eq!(*r.numer(), 10); | ||
| 125 | assert_eq!(*r.denom(), 4); | ||
| 126 | assert_eq!(r.to_integer(), 2); | ||
| 127 | } | ||
| 128 | } | ||
