diff options
| author | Thales <[email protected]> | 2021-06-24 20:39:51 -0300 |
|---|---|---|
| committer | GitHub <[email protected]> | 2021-06-24 20:39:51 -0300 |
| commit | e1880a19df2f91757aa34a21b670da22ccb81440 (patch) | |
| tree | 6dc183d0885fb65a07e636ee18a5ca60702b056e | |
| parent | 9e5406f761a5a71e8a634796a60f1148b7d96ec1 (diff) | |
| parent | 013792b9442b4ef6ca4d6ddc6ee631d4491dbfbd (diff) | |
Merge pull request #254 from thalesfragoso/f0-rcc
F0 rcc
| -rw-r--r-- | embassy-stm32/Cargo.toml | 73 | ||||
| -rw-r--r-- | embassy-stm32/gen.py | 4 | ||||
| -rw-r--r-- | embassy-stm32/gen_features.py | 1 | ||||
| -rw-r--r-- | embassy-stm32/src/exti/mod.rs | 111 | ||||
| -rw-r--r-- | embassy-stm32/src/exti/v1.rs (renamed from embassy-stm32/src/exti.rs) | 103 | ||||
| -rw-r--r-- | embassy-stm32/src/exti/v2.rs | 1 | ||||
| -rw-r--r-- | embassy-stm32/src/lib.rs | 6 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/f0/mod.rs | 231 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/mod.rs | 8 | ||||
| m--------- | stm32-data | 0 | ||||
| -rw-r--r-- | stm32-metapac/gen/src/lib.rs | 1 |
11 files changed, 427 insertions, 112 deletions
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 8163624f3..4e37c94fe 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml | |||
| @@ -45,6 +45,79 @@ net = ["embassy-net", "vcell"] | |||
| 45 | 45 | ||
| 46 | # BEGIN GENERATED FEATURES | 46 | # BEGIN GENERATED FEATURES |
| 47 | # Generated by gen_features.py. DO NOT EDIT. | 47 | # Generated by gen_features.py. DO NOT EDIT. |
| 48 | stm32f030c6 = [ "stm32-metapac/stm32f030c6",] | ||
| 49 | stm32f030c8 = [ "stm32-metapac/stm32f030c8",] | ||
| 50 | stm32f030cc = [ "stm32-metapac/stm32f030cc",] | ||
| 51 | stm32f030f4 = [ "stm32-metapac/stm32f030f4",] | ||
| 52 | stm32f030k6 = [ "stm32-metapac/stm32f030k6",] | ||
| 53 | stm32f030r8 = [ "stm32-metapac/stm32f030r8",] | ||
| 54 | stm32f030rc = [ "stm32-metapac/stm32f030rc",] | ||
| 55 | stm32f031c4 = [ "stm32-metapac/stm32f031c4",] | ||
| 56 | stm32f031c6 = [ "stm32-metapac/stm32f031c6",] | ||
| 57 | stm32f031e6 = [ "stm32-metapac/stm32f031e6",] | ||
| 58 | stm32f031f4 = [ "stm32-metapac/stm32f031f4",] | ||
| 59 | stm32f031f6 = [ "stm32-metapac/stm32f031f6",] | ||
| 60 | stm32f031g4 = [ "stm32-metapac/stm32f031g4",] | ||
| 61 | stm32f031g6 = [ "stm32-metapac/stm32f031g6",] | ||
| 62 | stm32f031k4 = [ "stm32-metapac/stm32f031k4",] | ||
| 63 | stm32f031k6 = [ "stm32-metapac/stm32f031k6",] | ||
| 64 | stm32f038c6 = [ "stm32-metapac/stm32f038c6",] | ||
| 65 | stm32f038e6 = [ "stm32-metapac/stm32f038e6",] | ||
| 66 | stm32f038f6 = [ "stm32-metapac/stm32f038f6",] | ||
| 67 | stm32f038g6 = [ "stm32-metapac/stm32f038g6",] | ||
| 68 | stm32f038k6 = [ "stm32-metapac/stm32f038k6",] | ||
| 69 | stm32f042c4 = [ "stm32-metapac/stm32f042c4",] | ||
| 70 | stm32f042c6 = [ "stm32-metapac/stm32f042c6",] | ||
| 71 | stm32f042f4 = [ "stm32-metapac/stm32f042f4",] | ||
| 72 | stm32f042f6 = [ "stm32-metapac/stm32f042f6",] | ||
| 73 | stm32f042g4 = [ "stm32-metapac/stm32f042g4",] | ||
| 74 | stm32f042g6 = [ "stm32-metapac/stm32f042g6",] | ||
| 75 | stm32f042k4 = [ "stm32-metapac/stm32f042k4",] | ||
| 76 | stm32f042k6 = [ "stm32-metapac/stm32f042k6",] | ||
| 77 | stm32f042t6 = [ "stm32-metapac/stm32f042t6",] | ||
| 78 | stm32f048c6 = [ "stm32-metapac/stm32f048c6",] | ||
| 79 | stm32f048g6 = [ "stm32-metapac/stm32f048g6",] | ||
| 80 | stm32f048t6 = [ "stm32-metapac/stm32f048t6",] | ||
| 81 | stm32f051c4 = [ "stm32-metapac/stm32f051c4",] | ||
| 82 | stm32f051c6 = [ "stm32-metapac/stm32f051c6",] | ||
| 83 | stm32f051c8 = [ "stm32-metapac/stm32f051c8",] | ||
| 84 | stm32f051k4 = [ "stm32-metapac/stm32f051k4",] | ||
| 85 | stm32f051k6 = [ "stm32-metapac/stm32f051k6",] | ||
| 86 | stm32f051k8 = [ "stm32-metapac/stm32f051k8",] | ||
| 87 | stm32f051r4 = [ "stm32-metapac/stm32f051r4",] | ||
| 88 | stm32f051r6 = [ "stm32-metapac/stm32f051r6",] | ||
| 89 | stm32f051r8 = [ "stm32-metapac/stm32f051r8",] | ||
| 90 | stm32f051t8 = [ "stm32-metapac/stm32f051t8",] | ||
| 91 | stm32f058c8 = [ "stm32-metapac/stm32f058c8",] | ||
| 92 | stm32f058r8 = [ "stm32-metapac/stm32f058r8",] | ||
| 93 | stm32f058t8 = [ "stm32-metapac/stm32f058t8",] | ||
| 94 | stm32f070c6 = [ "stm32-metapac/stm32f070c6",] | ||
| 95 | stm32f070cb = [ "stm32-metapac/stm32f070cb",] | ||
| 96 | stm32f070f6 = [ "stm32-metapac/stm32f070f6",] | ||
| 97 | stm32f070rb = [ "stm32-metapac/stm32f070rb",] | ||
| 98 | stm32f071c8 = [ "stm32-metapac/stm32f071c8",] | ||
| 99 | stm32f071cb = [ "stm32-metapac/stm32f071cb",] | ||
| 100 | stm32f071rb = [ "stm32-metapac/stm32f071rb",] | ||
| 101 | stm32f071v8 = [ "stm32-metapac/stm32f071v8",] | ||
| 102 | stm32f071vb = [ "stm32-metapac/stm32f071vb",] | ||
| 103 | stm32f072c8 = [ "stm32-metapac/stm32f072c8",] | ||
| 104 | stm32f072cb = [ "stm32-metapac/stm32f072cb",] | ||
| 105 | stm32f072r8 = [ "stm32-metapac/stm32f072r8",] | ||
| 106 | stm32f072rb = [ "stm32-metapac/stm32f072rb",] | ||
| 107 | stm32f072v8 = [ "stm32-metapac/stm32f072v8",] | ||
| 108 | stm32f072vb = [ "stm32-metapac/stm32f072vb",] | ||
| 109 | stm32f078cb = [ "stm32-metapac/stm32f078cb",] | ||
| 110 | stm32f078rb = [ "stm32-metapac/stm32f078rb",] | ||
| 111 | stm32f078vb = [ "stm32-metapac/stm32f078vb",] | ||
| 112 | stm32f091cb = [ "stm32-metapac/stm32f091cb",] | ||
| 113 | stm32f091cc = [ "stm32-metapac/stm32f091cc",] | ||
| 114 | stm32f091rb = [ "stm32-metapac/stm32f091rb",] | ||
| 115 | stm32f091rc = [ "stm32-metapac/stm32f091rc",] | ||
| 116 | stm32f091vb = [ "stm32-metapac/stm32f091vb",] | ||
| 117 | stm32f091vc = [ "stm32-metapac/stm32f091vc",] | ||
| 118 | stm32f098cc = [ "stm32-metapac/stm32f098cc",] | ||
| 119 | stm32f098rc = [ "stm32-metapac/stm32f098rc",] | ||
| 120 | stm32f098vc = [ "stm32-metapac/stm32f098vc",] | ||
| 48 | stm32f401cb = [ "stm32-metapac/stm32f401cb",] | 121 | stm32f401cb = [ "stm32-metapac/stm32f401cb",] |
| 49 | stm32f401cc = [ "stm32-metapac/stm32f401cc",] | 122 | stm32f401cc = [ "stm32-metapac/stm32f401cc",] |
| 50 | stm32f401cd = [ "stm32-metapac/stm32f401cd",] | 123 | stm32f401cd = [ "stm32-metapac/stm32f401cd",] |
diff --git a/embassy-stm32/gen.py b/embassy-stm32/gen.py index b9391d309..386c5ce17 100644 --- a/embassy-stm32/gen.py +++ b/embassy-stm32/gen.py | |||
| @@ -33,10 +33,6 @@ if len(c) > 1: | |||
| 33 | with open(f'{data_path}/chips/{chip_name}.yaml', 'r') as f: | 33 | with open(f'{data_path}/chips/{chip_name}.yaml', 'r') as f: |
| 34 | chip = yaml.load(f, Loader=SafeLoader) | 34 | chip = yaml.load(f, Loader=SafeLoader) |
| 35 | 35 | ||
| 36 | # ======= load GPIO AF | ||
| 37 | with open(f'{data_path}/gpio_af/{chip["gpio_af"]}.yaml', 'r') as f: | ||
| 38 | af = yaml.load(f, Loader=SafeLoader) | ||
| 39 | |||
| 40 | # ======= Generate! | 36 | # ======= Generate! |
| 41 | with open(output_file, 'w') as f: | 37 | with open(output_file, 'w') as f: |
| 42 | singletons = [] # USART1, PA5, EXTI8 | 38 | singletons = [] # USART1, PA5, EXTI8 |
diff --git a/embassy-stm32/gen_features.py b/embassy-stm32/gen_features.py index 10dfd7884..4eb57e2a3 100644 --- a/embassy-stm32/gen_features.py +++ b/embassy-stm32/gen_features.py | |||
| @@ -13,6 +13,7 @@ dname = os.path.dirname(abspath) | |||
| 13 | os.chdir(dname) | 13 | os.chdir(dname) |
| 14 | 14 | ||
| 15 | supported_families = [ | 15 | supported_families = [ |
| 16 | "STM32F0", | ||
| 16 | 'STM32F4', | 17 | 'STM32F4', |
| 17 | 'STM32L0', | 18 | 'STM32L0', |
| 18 | 'STM32L4', | 19 | 'STM32L4', |
diff --git a/embassy-stm32/src/exti/mod.rs b/embassy-stm32/src/exti/mod.rs new file mode 100644 index 000000000..126a6fb64 --- /dev/null +++ b/embassy-stm32/src/exti/mod.rs | |||
| @@ -0,0 +1,111 @@ | |||
| 1 | #![macro_use] | ||
| 2 | |||
| 3 | macro_rules! foreach_exti_irq { | ||
| 4 | ($action:ident) => { | ||
| 5 | crate::pac::interrupts!( | ||
| 6 | (EXTI0) => { $action!(EXTI0); }; | ||
| 7 | (EXTI1) => { $action!(EXTI1); }; | ||
| 8 | (EXTI2) => { $action!(EXTI2); }; | ||
| 9 | (EXTI3) => { $action!(EXTI3); }; | ||
| 10 | (EXTI4) => { $action!(EXTI4); }; | ||
| 11 | (EXTI5) => { $action!(EXTI5); }; | ||
| 12 | (EXTI6) => { $action!(EXTI6); }; | ||
| 13 | (EXTI7) => { $action!(EXTI7); }; | ||
| 14 | (EXTI8) => { $action!(EXTI8); }; | ||
| 15 | (EXTI9) => { $action!(EXTI9); }; | ||
| 16 | (EXTI10) => { $action!(EXTI10); }; | ||
| 17 | (EXTI11) => { $action!(EXTI11); }; | ||
| 18 | (EXTI12) => { $action!(EXTI12); }; | ||
| 19 | (EXTI13) => { $action!(EXTI13); }; | ||
| 20 | (EXTI14) => { $action!(EXTI14); }; | ||
| 21 | (EXTI15) => { $action!(EXTI15); }; | ||
| 22 | |||
| 23 | // plus the weird ones | ||
| 24 | (EXTI0_1) => { $action!( EXTI0_1 ); }; | ||
| 25 | (EXTI15_10) => { $action!(EXTI15_10); }; | ||
| 26 | (EXTI15_4) => { $action!(EXTI15_4); }; | ||
| 27 | (EXTI1_0) => { $action!(EXTI1_0); }; | ||
| 28 | (EXTI2_3) => { $action!(EXTI2_3); }; | ||
| 29 | (EXTI2_TSC) => { $action!(EXTI2_TSC); }; | ||
| 30 | (EXTI3_2) => { $action!(EXTI3_2); }; | ||
| 31 | (EXTI4_15) => { $action!(EXTI4_15); }; | ||
| 32 | (EXTI9_5) => { $action!(EXTI9_5); }; | ||
| 33 | ); | ||
| 34 | }; | ||
| 35 | } | ||
| 36 | |||
| 37 | #[cfg_attr(exti_v1, path = "v1.rs")] | ||
| 38 | #[cfg_attr(exti_wb55, path = "v2.rs")] | ||
| 39 | mod _version; | ||
| 40 | |||
| 41 | #[allow(unused)] | ||
| 42 | pub use _version::*; | ||
| 43 | |||
| 44 | use crate::peripherals; | ||
| 45 | use embassy_extras::unsafe_impl_unborrow; | ||
| 46 | |||
| 47 | pub(crate) mod sealed { | ||
| 48 | pub trait Channel {} | ||
| 49 | } | ||
| 50 | |||
| 51 | pub trait Channel: sealed::Channel + Sized { | ||
| 52 | fn number(&self) -> usize; | ||
| 53 | fn degrade(self) -> AnyChannel { | ||
| 54 | AnyChannel { | ||
| 55 | number: self.number() as u8, | ||
| 56 | } | ||
| 57 | } | ||
| 58 | } | ||
| 59 | |||
| 60 | pub struct AnyChannel { | ||
| 61 | number: u8, | ||
| 62 | } | ||
| 63 | unsafe_impl_unborrow!(AnyChannel); | ||
| 64 | impl sealed::Channel for AnyChannel {} | ||
| 65 | impl Channel for AnyChannel { | ||
| 66 | fn number(&self) -> usize { | ||
| 67 | self.number as usize | ||
| 68 | } | ||
| 69 | } | ||
| 70 | |||
| 71 | macro_rules! impl_exti { | ||
| 72 | ($type:ident, $number:expr) => { | ||
| 73 | impl sealed::Channel for peripherals::$type {} | ||
| 74 | impl Channel for peripherals::$type { | ||
| 75 | fn number(&self) -> usize { | ||
| 76 | $number as usize | ||
| 77 | } | ||
| 78 | } | ||
| 79 | }; | ||
| 80 | } | ||
| 81 | |||
| 82 | impl_exti!(EXTI0, 0); | ||
| 83 | impl_exti!(EXTI1, 1); | ||
| 84 | impl_exti!(EXTI2, 2); | ||
| 85 | impl_exti!(EXTI3, 3); | ||
| 86 | impl_exti!(EXTI4, 4); | ||
| 87 | impl_exti!(EXTI5, 5); | ||
| 88 | impl_exti!(EXTI6, 6); | ||
| 89 | impl_exti!(EXTI7, 7); | ||
| 90 | impl_exti!(EXTI8, 8); | ||
| 91 | impl_exti!(EXTI9, 9); | ||
| 92 | impl_exti!(EXTI10, 10); | ||
| 93 | impl_exti!(EXTI11, 11); | ||
| 94 | impl_exti!(EXTI12, 12); | ||
| 95 | impl_exti!(EXTI13, 13); | ||
| 96 | impl_exti!(EXTI14, 14); | ||
| 97 | impl_exti!(EXTI15, 15); | ||
| 98 | |||
| 99 | macro_rules! enable_irq { | ||
| 100 | ($e:ident) => { | ||
| 101 | crate::interrupt::$e::steal().enable(); | ||
| 102 | }; | ||
| 103 | } | ||
| 104 | |||
| 105 | /// safety: must be called only once | ||
| 106 | pub(crate) unsafe fn init() { | ||
| 107 | use embassy::interrupt::Interrupt; | ||
| 108 | use embassy::interrupt::InterruptExt; | ||
| 109 | |||
| 110 | foreach_exti_irq!(enable_irq); | ||
| 111 | } | ||
diff --git a/embassy-stm32/src/exti.rs b/embassy-stm32/src/exti/v1.rs index 90d4afd56..caf457605 100644 --- a/embassy-stm32/src/exti.rs +++ b/embassy-stm32/src/exti/v1.rs | |||
| @@ -1,4 +1,3 @@ | |||
| 1 | #![macro_use] | ||
| 2 | use core::convert::Infallible; | 1 | use core::convert::Infallible; |
| 3 | use core::future::Future; | 2 | use core::future::Future; |
| 4 | use core::marker::PhantomData; | 3 | use core::marker::PhantomData; |
| @@ -6,14 +5,12 @@ use core::pin::Pin; | |||
| 6 | use core::task::{Context, Poll}; | 5 | use core::task::{Context, Poll}; |
| 7 | use embassy::traits::gpio::{WaitForAnyEdge, WaitForFallingEdge, WaitForRisingEdge}; | 6 | use embassy::traits::gpio::{WaitForAnyEdge, WaitForFallingEdge, WaitForRisingEdge}; |
| 8 | use embassy::util::{AtomicWaker, Unborrow}; | 7 | use embassy::util::{AtomicWaker, Unborrow}; |
| 9 | use embassy_extras::unsafe_impl_unborrow; | ||
| 10 | use embedded_hal::digital::v2::InputPin; | 8 | use embedded_hal::digital::v2::InputPin; |
| 11 | use pac::exti::{regs, vals}; | 9 | use pac::exti::{regs, vals}; |
| 12 | 10 | ||
| 13 | use crate::gpio::{AnyPin, Input, Pin as GpioPin}; | 11 | use crate::gpio::{AnyPin, Input, Pin as GpioPin}; |
| 14 | use crate::pac; | 12 | use crate::pac; |
| 15 | use crate::pac::{EXTI, SYSCFG}; | 13 | use crate::pac::{EXTI, SYSCFG}; |
| 16 | use crate::peripherals; | ||
| 17 | 14 | ||
| 18 | const EXTI_COUNT: usize = 16; | 15 | const EXTI_COUNT: usize = 16; |
| 19 | const NEW_AW: AtomicWaker = AtomicWaker::new(); | 16 | const NEW_AW: AtomicWaker = AtomicWaker::new(); |
| @@ -160,106 +157,6 @@ impl<'a> Future for ExtiInputFuture<'a> { | |||
| 160 | } | 157 | } |
| 161 | } | 158 | } |
| 162 | 159 | ||
| 163 | pub(crate) mod sealed { | ||
| 164 | pub trait Channel {} | ||
| 165 | } | ||
| 166 | |||
| 167 | pub trait Channel: sealed::Channel + Sized { | ||
| 168 | fn number(&self) -> usize; | ||
| 169 | fn degrade(self) -> AnyChannel { | ||
| 170 | AnyChannel { | ||
| 171 | number: self.number() as u8, | ||
| 172 | } | ||
| 173 | } | ||
| 174 | } | ||
| 175 | |||
| 176 | pub struct AnyChannel { | ||
| 177 | number: u8, | ||
| 178 | } | ||
| 179 | unsafe_impl_unborrow!(AnyChannel); | ||
| 180 | impl sealed::Channel for AnyChannel {} | ||
| 181 | impl Channel for AnyChannel { | ||
| 182 | fn number(&self) -> usize { | ||
| 183 | self.number as usize | ||
| 184 | } | ||
| 185 | } | ||
| 186 | |||
| 187 | macro_rules! impl_exti { | ||
| 188 | ($type:ident, $number:expr) => { | ||
| 189 | impl sealed::Channel for peripherals::$type {} | ||
| 190 | impl Channel for peripherals::$type { | ||
| 191 | fn number(&self) -> usize { | ||
| 192 | $number as usize | ||
| 193 | } | ||
| 194 | } | ||
| 195 | }; | ||
| 196 | } | ||
| 197 | |||
| 198 | impl_exti!(EXTI0, 0); | ||
| 199 | impl_exti!(EXTI1, 1); | ||
| 200 | impl_exti!(EXTI2, 2); | ||
| 201 | impl_exti!(EXTI3, 3); | ||
| 202 | impl_exti!(EXTI4, 4); | ||
| 203 | impl_exti!(EXTI5, 5); | ||
| 204 | impl_exti!(EXTI6, 6); | ||
| 205 | impl_exti!(EXTI7, 7); | ||
| 206 | impl_exti!(EXTI8, 8); | ||
| 207 | impl_exti!(EXTI9, 9); | ||
| 208 | impl_exti!(EXTI10, 10); | ||
| 209 | impl_exti!(EXTI11, 11); | ||
| 210 | impl_exti!(EXTI12, 12); | ||
| 211 | impl_exti!(EXTI13, 13); | ||
| 212 | impl_exti!(EXTI14, 14); | ||
| 213 | impl_exti!(EXTI15, 15); | ||
| 214 | |||
| 215 | macro_rules! foreach_exti_irq { | ||
| 216 | ($action:ident) => { | ||
| 217 | crate::pac::interrupts!( | ||
| 218 | (EXTI0) => { $action!(EXTI0); }; | ||
| 219 | (EXTI1) => { $action!(EXTI1); }; | ||
| 220 | (EXTI2) => { $action!(EXTI2); }; | ||
| 221 | (EXTI3) => { $action!(EXTI3); }; | ||
| 222 | (EXTI4) => { $action!(EXTI4); }; | ||
| 223 | (EXTI5) => { $action!(EXTI5); }; | ||
| 224 | (EXTI6) => { $action!(EXTI6); }; | ||
| 225 | (EXTI7) => { $action!(EXTI7); }; | ||
| 226 | (EXTI8) => { $action!(EXTI8); }; | ||
| 227 | (EXTI9) => { $action!(EXTI9); }; | ||
| 228 | (EXTI10) => { $action!(EXTI10); }; | ||
| 229 | (EXTI11) => { $action!(EXTI11); }; | ||
| 230 | (EXTI12) => { $action!(EXTI12); }; | ||
| 231 | (EXTI13) => { $action!(EXTI13); }; | ||
| 232 | (EXTI14) => { $action!(EXTI14); }; | ||
| 233 | (EXTI15) => { $action!(EXTI15); }; | ||
| 234 | |||
| 235 | // plus the weird ones | ||
| 236 | (EXTI0_1) => { $action!( EXTI0_1 ); }; | ||
| 237 | (EXTI15_10) => { $action!(EXTI15_10); }; | ||
| 238 | (EXTI15_4) => { $action!(EXTI15_4); }; | ||
| 239 | (EXTI1_0) => { $action!(EXTI1_0); }; | ||
| 240 | (EXTI2_3) => { $action!(EXTI2_3); }; | ||
| 241 | (EXTI2_TSC) => { $action!(EXTI2_TSC); }; | ||
| 242 | (EXTI3_2) => { $action!(EXTI3_2); }; | ||
| 243 | (EXTI4_15) => { $action!(EXTI4_15); }; | ||
| 244 | (EXTI9_5) => { $action!(EXTI9_5); }; | ||
| 245 | ); | ||
| 246 | }; | ||
| 247 | } | ||
| 248 | |||
| 249 | macro_rules! enable_irq { | ||
| 250 | ($e:ident) => { | ||
| 251 | crate::interrupt::$e::steal().enable(); | ||
| 252 | }; | ||
| 253 | } | ||
| 254 | |||
| 255 | /// safety: must be called only once | ||
| 256 | pub(crate) unsafe fn init() { | ||
| 257 | use embassy::interrupt::Interrupt; | ||
| 258 | use embassy::interrupt::InterruptExt; | ||
| 259 | |||
| 260 | foreach_exti_irq!(enable_irq); | ||
| 261 | } | ||
| 262 | |||
| 263 | use crate::interrupt; | 160 | use crate::interrupt; |
| 264 | 161 | ||
| 265 | macro_rules! impl_irq { | 162 | macro_rules! impl_irq { |
diff --git a/embassy-stm32/src/exti/v2.rs b/embassy-stm32/src/exti/v2.rs new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/embassy-stm32/src/exti/v2.rs | |||
| @@ -0,0 +1 @@ | |||
diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index 39ccd54f0..9ba7bbe4c 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs | |||
| @@ -16,7 +16,6 @@ pub mod interrupt; | |||
| 16 | pub mod time; | 16 | pub mod time; |
| 17 | 17 | ||
| 18 | // Always-present hardware | 18 | // Always-present hardware |
| 19 | pub mod exti; | ||
| 20 | pub mod gpio; | 19 | pub mod gpio; |
| 21 | pub mod rcc; | 20 | pub mod rcc; |
| 22 | 21 | ||
| @@ -31,6 +30,8 @@ pub mod dac; | |||
| 31 | pub mod dma; | 30 | pub mod dma; |
| 32 | #[cfg(all(eth, feature = "net"))] | 31 | #[cfg(all(eth, feature = "net"))] |
| 33 | pub mod eth; | 32 | pub mod eth; |
| 33 | #[cfg(exti)] | ||
| 34 | pub mod exti; | ||
| 34 | #[cfg(i2c)] | 35 | #[cfg(i2c)] |
| 35 | pub mod i2c; | 36 | pub mod i2c; |
| 36 | #[cfg(pwr)] | 37 | #[cfg(pwr)] |
| @@ -83,10 +84,9 @@ pub fn init(config: Config) -> Peripherals { | |||
| 83 | let p = Peripherals::take(); | 84 | let p = Peripherals::take(); |
| 84 | 85 | ||
| 85 | unsafe { | 86 | unsafe { |
| 86 | exti::init(); | ||
| 87 | |||
| 88 | #[cfg(dma)] | 87 | #[cfg(dma)] |
| 89 | dma::init(); | 88 | dma::init(); |
| 89 | #[cfg(exti)] | ||
| 90 | exti::init(); | 90 | exti::init(); |
| 91 | rcc::init(config.rcc); | 91 | rcc::init(config.rcc); |
| 92 | } | 92 | } |
diff --git a/embassy-stm32/src/rcc/f0/mod.rs b/embassy-stm32/src/rcc/f0/mod.rs new file mode 100644 index 000000000..8ddacb8ef --- /dev/null +++ b/embassy-stm32/src/rcc/f0/mod.rs | |||
| @@ -0,0 +1,231 @@ | |||
| 1 | use core::marker::PhantomData; | ||
| 2 | |||
| 3 | use embassy::util::Unborrow; | ||
| 4 | |||
| 5 | use crate::pac::{DBGMCU, FLASH, RCC}; | ||
| 6 | use crate::peripherals; | ||
| 7 | use crate::time::Hertz; | ||
| 8 | |||
| 9 | use super::{set_freqs, Clocks}; | ||
| 10 | |||
| 11 | const HSI: u32 = 8_000_000; | ||
| 12 | |||
| 13 | /// Configuration of the clocks | ||
| 14 | /// | ||
| 15 | /// hse takes precedence over hsi48 if both are enabled | ||
| 16 | #[non_exhaustive] | ||
| 17 | #[derive(Default)] | ||
| 18 | pub struct Config { | ||
| 19 | pub hse: Option<Hertz>, | ||
| 20 | pub bypass_hse: bool, | ||
| 21 | pub usb_pll: bool, | ||
| 22 | |||
| 23 | #[cfg(rcc_f0)] | ||
| 24 | pub hsi48: bool, | ||
| 25 | |||
| 26 | pub sys_ck: Option<Hertz>, | ||
| 27 | pub hclk: Option<Hertz>, | ||
| 28 | pub pclk: Option<Hertz>, | ||
| 29 | pub enable_debug_wfe: bool, | ||
| 30 | } | ||
| 31 | |||
| 32 | pub struct Rcc<'d> { | ||
| 33 | inner: PhantomData<&'d ()>, | ||
| 34 | config: Config, | ||
| 35 | } | ||
| 36 | |||
| 37 | impl<'d> Rcc<'d> { | ||
| 38 | pub fn new(_rcc: impl Unborrow<Target = peripherals::RCC> + 'd, config: Config) -> Self { | ||
| 39 | Self { | ||
| 40 | inner: PhantomData, | ||
| 41 | config, | ||
| 42 | } | ||
| 43 | } | ||
| 44 | |||
| 45 | pub fn freeze(self) -> Clocks { | ||
| 46 | use crate::pac::rcc::vals::{Hpre, Hsebyp, Pllmul, Pllsrc, Ppre, Sw, Usbsw}; | ||
| 47 | |||
| 48 | let sysclk = self.config.sys_ck.map(|v| v.0).unwrap_or(HSI); | ||
| 49 | |||
| 50 | let (src_clk, use_hsi48) = self.config.hse.map(|v| (v.0, false)).unwrap_or_else(|| { | ||
| 51 | #[cfg(rcc_f0)] | ||
| 52 | if self.config.hsi48 { | ||
| 53 | return (48_000_000, true); | ||
| 54 | } | ||
| 55 | (HSI, false) | ||
| 56 | }); | ||
| 57 | |||
| 58 | let (pllmul_bits, real_sysclk) = if sysclk == src_clk { | ||
| 59 | (None, sysclk) | ||
| 60 | } else { | ||
| 61 | let prediv = if self.config.hse.is_some() { 1 } else { 2 }; | ||
| 62 | let pllmul = (2 * prediv * sysclk + src_clk) / src_clk / 2; | ||
| 63 | let pllmul = pllmul.max(2).min(16); | ||
| 64 | |||
| 65 | let pllmul_bits = pllmul as u8 - 2; | ||
| 66 | let real_sysclk = pllmul * src_clk / prediv; | ||
| 67 | (Some(pllmul_bits), real_sysclk) | ||
| 68 | }; | ||
| 69 | |||
| 70 | let hpre_bits = self | ||
| 71 | .config | ||
| 72 | .hclk | ||
| 73 | .map(|hclk| match real_sysclk / hclk.0 { | ||
| 74 | 0 => unreachable!(), | ||
| 75 | 1 => 0b0111, | ||
| 76 | 2 => 0b1000, | ||
| 77 | 3..=5 => 0b1001, | ||
| 78 | 6..=11 => 0b1010, | ||
| 79 | 12..=39 => 0b1011, | ||
| 80 | 40..=95 => 0b1100, | ||
| 81 | 96..=191 => 0b1101, | ||
| 82 | 192..=383 => 0b1110, | ||
| 83 | _ => 0b1111, | ||
| 84 | }) | ||
| 85 | .unwrap_or(0b0111); | ||
| 86 | let hclk = real_sysclk / (1 << (hpre_bits - 0b0111)); | ||
| 87 | |||
| 88 | let ppre_bits = self | ||
| 89 | .config | ||
| 90 | .pclk | ||
| 91 | .map(|pclk| match hclk / pclk.0 { | ||
| 92 | 0 => unreachable!(), | ||
| 93 | 1 => 0b011, | ||
| 94 | 2 => 0b100, | ||
| 95 | 3..=5 => 0b101, | ||
| 96 | 6..=11 => 0b110, | ||
| 97 | _ => 0b111, | ||
| 98 | }) | ||
| 99 | .unwrap_or(0b011); | ||
| 100 | |||
| 101 | let ppre: u8 = 1 << (ppre_bits - 0b011); | ||
| 102 | let pclk = hclk / u32::from(ppre); | ||
| 103 | |||
| 104 | let timer_mul = if ppre == 1 { 1 } else { 2 }; | ||
| 105 | |||
| 106 | // NOTE(safety) Atomic write | ||
| 107 | unsafe { | ||
| 108 | FLASH.acr().write(|w| { | ||
| 109 | let latency = if real_sysclk <= 24_000_000 { | ||
| 110 | 0 | ||
| 111 | } else if real_sysclk <= 48_000_000 { | ||
| 112 | 1 | ||
| 113 | } else { | ||
| 114 | 2 | ||
| 115 | }; | ||
| 116 | w.latency().0 = latency; | ||
| 117 | }); | ||
| 118 | } | ||
| 119 | |||
| 120 | // NOTE(unsafe) We have exclusive access to the RCC | ||
| 121 | unsafe { | ||
| 122 | match (self.config.hse.is_some(), use_hsi48) { | ||
| 123 | (true, _) => { | ||
| 124 | RCC.cr().modify(|w| { | ||
| 125 | w.set_csson(true); | ||
| 126 | w.set_hseon(true); | ||
| 127 | |||
| 128 | if self.config.bypass_hse { | ||
| 129 | w.set_hsebyp(Hsebyp::BYPASSED); | ||
| 130 | } | ||
| 131 | }); | ||
| 132 | while !RCC.cr().read().hserdy() {} | ||
| 133 | |||
| 134 | if pllmul_bits.is_some() { | ||
| 135 | RCC.cfgr().modify(|w| w.set_pllsrc(Pllsrc::HSE_DIV_PREDIV)) | ||
| 136 | } | ||
| 137 | } | ||
| 138 | (false, true) => { | ||
| 139 | // use_hsi48 will always be false for rcc_f0x0 | ||
| 140 | #[cfg(rcc_f0)] | ||
| 141 | RCC.cr2().modify(|w| w.set_hsi48on(true)); | ||
| 142 | #[cfg(rcc_f0)] | ||
| 143 | while !RCC.cr2().read().hsi48rdy() {} | ||
| 144 | |||
| 145 | #[cfg(rcc_f0)] | ||
| 146 | if pllmul_bits.is_some() { | ||
| 147 | RCC.cfgr() | ||
| 148 | .modify(|w| w.set_pllsrc(Pllsrc::HSI48_DIV_PREDIV)) | ||
| 149 | } | ||
| 150 | } | ||
| 151 | _ => { | ||
| 152 | RCC.cr().modify(|w| w.set_hsion(true)); | ||
| 153 | while !RCC.cr().read().hsirdy() {} | ||
| 154 | |||
| 155 | if pllmul_bits.is_some() { | ||
| 156 | RCC.cfgr().modify(|w| w.set_pllsrc(Pllsrc::HSI_DIV2)) | ||
| 157 | } | ||
| 158 | } | ||
| 159 | } | ||
| 160 | |||
| 161 | if self.config.usb_pll { | ||
| 162 | RCC.cfgr3().modify(|w| w.set_usbsw(Usbsw::PLLCLK)); | ||
| 163 | } | ||
| 164 | // TODO: Option to use CRS (Clock Recovery) | ||
| 165 | |||
| 166 | if let Some(pllmul_bits) = pllmul_bits { | ||
| 167 | RCC.cfgr().modify(|w| w.set_pllmul(Pllmul(pllmul_bits))); | ||
| 168 | |||
| 169 | RCC.cr().modify(|w| w.set_pllon(true)); | ||
| 170 | while !RCC.cr().read().pllrdy() {} | ||
| 171 | |||
| 172 | RCC.cfgr().modify(|w| { | ||
| 173 | w.set_ppre(Ppre(ppre_bits)); | ||
| 174 | w.set_hpre(Hpre(hpre_bits)); | ||
| 175 | w.set_sw(Sw::PLL) | ||
| 176 | }); | ||
| 177 | } else { | ||
| 178 | RCC.cfgr().modify(|w| { | ||
| 179 | w.set_ppre(Ppre(ppre_bits)); | ||
| 180 | w.set_hpre(Hpre(hpre_bits)); | ||
| 181 | |||
| 182 | if self.config.hse.is_some() { | ||
| 183 | w.set_sw(Sw::HSE); | ||
| 184 | } else if use_hsi48 { | ||
| 185 | #[cfg(rcc_f0)] | ||
| 186 | w.set_sw(Sw::HSI48); | ||
| 187 | } else { | ||
| 188 | w.set_sw(Sw::HSI) | ||
| 189 | } | ||
| 190 | }) | ||
| 191 | } | ||
| 192 | |||
| 193 | if self.config.enable_debug_wfe { | ||
| 194 | RCC.ahbenr().modify(|w| w.set_dmaen(true)); | ||
| 195 | |||
| 196 | critical_section::with(|_| { | ||
| 197 | DBGMCU.cr().modify(|w| { | ||
| 198 | w.set_dbg_standby(true); | ||
| 199 | w.set_dbg_stop(true); | ||
| 200 | }); | ||
| 201 | }); | ||
| 202 | } | ||
| 203 | } | ||
| 204 | |||
| 205 | Clocks { | ||
| 206 | sys: Hertz(real_sysclk), | ||
| 207 | apb1: Hertz(pclk), | ||
| 208 | apb1_tim: Hertz(pclk * timer_mul), | ||
| 209 | apb2_tim: Hertz(0), | ||
| 210 | ahb: Hertz(hclk), | ||
| 211 | } | ||
| 212 | } | ||
| 213 | } | ||
| 214 | |||
| 215 | pub unsafe fn init(config: Config) { | ||
| 216 | RCC.ahbenr().modify(|w| { | ||
| 217 | w.set_iopaen(true); | ||
| 218 | w.set_iopben(true); | ||
| 219 | w.set_iopcen(true); | ||
| 220 | w.set_iopden(true); | ||
| 221 | |||
| 222 | #[cfg(rcc_f0)] | ||
| 223 | w.set_iopeen(true); | ||
| 224 | |||
| 225 | w.set_iopfen(true); | ||
| 226 | }); | ||
| 227 | |||
| 228 | let rcc = Rcc::new(<peripherals::RCC as embassy::util::Steal>::steal(), config); | ||
| 229 | let clocks = rcc.freeze(); | ||
| 230 | set_freqs(clocks); | ||
| 231 | } | ||
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index e84021272..91e8b5bef 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs | |||
| @@ -9,11 +9,14 @@ mod types; | |||
| 9 | pub struct Clocks { | 9 | pub struct Clocks { |
| 10 | pub sys: Hertz, | 10 | pub sys: Hertz, |
| 11 | pub apb1: Hertz, | 11 | pub apb1: Hertz, |
| 12 | |||
| 13 | #[cfg(not(any(rcc_f0, rcc_f0x0)))] | ||
| 12 | pub apb2: Hertz, | 14 | pub apb2: Hertz, |
| 15 | |||
| 13 | pub apb1_tim: Hertz, | 16 | pub apb1_tim: Hertz, |
| 14 | pub apb2_tim: Hertz, | 17 | pub apb2_tim: Hertz, |
| 15 | 18 | ||
| 16 | #[cfg(any(rcc_l0))] | 19 | #[cfg(any(rcc_l0, rcc_f0, rcc_f0x0))] |
| 17 | pub ahb: Hertz, | 20 | pub ahb: Hertz, |
| 18 | 21 | ||
| 19 | #[cfg(any(rcc_l4, rcc_f4, rcc_h7, rcc_wb55, rcc_wl5x))] | 22 | #[cfg(any(rcc_l4, rcc_f4, rcc_h7, rcc_wb55, rcc_wl5x))] |
| @@ -65,6 +68,9 @@ cfg_if::cfg_if! { | |||
| 65 | } else if #[cfg(rcc_wl5x)] { | 68 | } else if #[cfg(rcc_wl5x)] { |
| 66 | mod wl5x; | 69 | mod wl5x; |
| 67 | pub use wl5x::*; | 70 | pub use wl5x::*; |
| 71 | } else if #[cfg(any(rcc_f0, rcc_f0x0))] { | ||
| 72 | mod f0; | ||
| 73 | pub use f0::*; | ||
| 68 | } | 74 | } |
| 69 | } | 75 | } |
| 70 | 76 | ||
diff --git a/stm32-data b/stm32-data | |||
| Subproject 18f86c83123771048f971350c99c4f810385d7d | Subproject eb76ee900ac67b51497196572250323e82666b4 | ||
diff --git a/stm32-metapac/gen/src/lib.rs b/stm32-metapac/gen/src/lib.rs index a5c061009..9e7add452 100644 --- a/stm32-metapac/gen/src/lib.rs +++ b/stm32-metapac/gen/src/lib.rs | |||
| @@ -19,7 +19,6 @@ pub struct Chip { | |||
| 19 | pub cores: Vec<Core>, | 19 | pub cores: Vec<Core>, |
| 20 | pub flash: u32, | 20 | pub flash: u32, |
| 21 | pub ram: u32, | 21 | pub ram: u32, |
| 22 | pub gpio_af: String, | ||
| 23 | pub packages: Vec<Package>, | 22 | pub packages: Vec<Package>, |
| 24 | } | 23 | } |
| 25 | 24 | ||
