aboutsummaryrefslogtreecommitdiff
path: root/embassy-hal-common
diff options
context:
space:
mode:
authorUlf Lilleengen <[email protected]>2021-08-31 14:32:48 +0200
committerUlf Lilleengen <[email protected]>2021-09-02 10:39:56 +0200
commit7ad6280e6575fc400f84caa5c26eb3ba9770877f (patch)
tree4a888ee84f7c5c59a713e08e53d41fdd6a21f020 /embassy-hal-common
parentdb3cb02032fd6b861b2c39a0a354767cc72af1df (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.toml1
-rw-r--r--embassy-hal-common/src/lib.rs1
-rw-r--r--embassy-hal-common/src/ratio.rs128
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 }
18log = { version = "0.4.11", optional = true } 18log = { version = "0.4.11", optional = true }
19cortex-m = "0.7.1" 19cortex-m = "0.7.1"
20usb-device = "0.2.7" 20usb-device = "0.2.7"
21num-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;
8pub mod peripheral; 8pub mod peripheral;
9pub mod ring_buffer; 9pub mod ring_buffer;
10pub mod usb; 10pub mod usb;
11pub mod ratio;
11 12
12/// Low power blocking wait loop using WFE/SEV. 13/// Low power blocking wait loop using WFE/SEV.
13pub fn low_power_wait_until(mut condition: impl FnMut() -> bool) { 14pub 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 @@
1use core::ops::{Add, Div, Mul};
2use 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))]
7pub struct Ratio<T> {
8 /// Numerator.
9 numer: T,
10 /// Denominator.
11 denom: T,
12}
13
14impl<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
34impl<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
42impl<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
52impl<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
62impl<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
72macro_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
90impl_from_for_float!(u8);
91impl_from_for_float!(u16);
92impl_from_for_float!(u32);
93impl_from_for_float!(u64);
94impl_from_for_float!(u128);
95impl_from_for_float!(i8);
96impl_from_for_float!(i16);
97impl_from_for_float!(i32);
98impl_from_for_float!(i64);
99impl_from_for_float!(i128);
100
101impl<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)]
108mod 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}