diff options
97 files changed, 1440 insertions, 371 deletions
| @@ -35,8 +35,8 @@ rm -rf out/tests/nrf5340-dk | |||
| 35 | # disabled because these boards are not on the shelf | 35 | # disabled because these boards are not on the shelf |
| 36 | rm -rf out/tests/mspm0g3507 | 36 | rm -rf out/tests/mspm0g3507 |
| 37 | 37 | ||
| 38 | # rm out/tests/stm32wb55rg/wpan_mac | 38 | rm out/tests/stm32wb55rg/wpan_mac |
| 39 | # rm out/tests/stm32wb55rg/wpan_ble | 39 | rm out/tests/stm32wb55rg/wpan_ble |
| 40 | 40 | ||
| 41 | # unstable, I think it's running out of RAM? | 41 | # unstable, I think it's running out of RAM? |
| 42 | rm out/tests/stm32f207zg/eth | 42 | rm out/tests/stm32f207zg/eth |
diff --git a/cyw43/Cargo.toml b/cyw43/Cargo.toml index 6d7647697..c4f5c0ebd 100644 --- a/cyw43/Cargo.toml +++ b/cyw43/Cargo.toml | |||
| @@ -10,7 +10,7 @@ repository = "https://github.com/embassy-rs/embassy" | |||
| 10 | documentation = "https://docs.embassy.dev/cyw43" | 10 | documentation = "https://docs.embassy.dev/cyw43" |
| 11 | 11 | ||
| 12 | [features] | 12 | [features] |
| 13 | defmt = ["dep:defmt", "heapless/defmt-03", "embassy-time/defmt", "bt-hci?/defmt", "embedded-io-async?/defmt-03"] | 13 | defmt = ["dep:defmt", "heapless/defmt-03", "embassy-time/defmt", "bt-hci?/defmt", "embedded-io-async?/defmt"] |
| 14 | log = ["dep:log"] | 14 | log = ["dep:log"] |
| 15 | bluetooth = ["dep:bt-hci", "dep:embedded-io-async"] | 15 | bluetooth = ["dep:bt-hci", "dep:embedded-io-async"] |
| 16 | 16 | ||
| @@ -35,8 +35,8 @@ num_enum = { version = "0.5.7", default-features = false } | |||
| 35 | heapless = "0.8.0" | 35 | heapless = "0.8.0" |
| 36 | 36 | ||
| 37 | # Bluetooth deps | 37 | # Bluetooth deps |
| 38 | embedded-io-async = { version = "0.6.0", optional = true } | 38 | embedded-io-async = { version = "0.7.0", optional = true } |
| 39 | bt-hci = { version = "0.6.0", optional = true } | 39 | bt-hci = { git = "https://github.com/embassy-rs/bt-hci", rev = "51791fd4d422449dd0eca5ddead32886101215f7", optional = true } |
| 40 | 40 | ||
| 41 | [package.metadata.embassy] | 41 | [package.metadata.embassy] |
| 42 | build = [ | 42 | build = [ |
diff --git a/cyw43/src/bluetooth.rs b/cyw43/src/bluetooth.rs index 332b7048d..256451fae 100644 --- a/cyw43/src/bluetooth.rs +++ b/cyw43/src/bluetooth.rs | |||
| @@ -490,6 +490,14 @@ impl From<FromHciBytesError> for Error { | |||
| 490 | } | 490 | } |
| 491 | } | 491 | } |
| 492 | 492 | ||
| 493 | impl core::fmt::Display for Error { | ||
| 494 | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { | ||
| 495 | core::fmt::Debug::fmt(self, f) | ||
| 496 | } | ||
| 497 | } | ||
| 498 | |||
| 499 | impl core::error::Error for Error {} | ||
| 500 | |||
| 493 | impl<'d> embedded_io_async::ErrorType for BtDriver<'d> { | 501 | impl<'d> embedded_io_async::ErrorType for BtDriver<'d> { |
| 494 | type Error = Error; | 502 | type Error = Error; |
| 495 | } | 503 | } |
diff --git a/embassy-imxrt/Cargo.toml b/embassy-imxrt/Cargo.toml index 81377579b..5ffa054f1 100644 --- a/embassy-imxrt/Cargo.toml +++ b/embassy-imxrt/Cargo.toml | |||
| @@ -85,8 +85,8 @@ cfg-if = "1.0.0" | |||
| 85 | cortex-m-rt = ">=0.7.3,<0.8" | 85 | cortex-m-rt = ">=0.7.3,<0.8" |
| 86 | cortex-m = "0.7.6" | 86 | cortex-m = "0.7.6" |
| 87 | critical-section = "1.1" | 87 | critical-section = "1.1" |
| 88 | embedded-io = { version = "0.6.1" } | 88 | embedded-io = { version = "0.7.1" } |
| 89 | embedded-io-async = { version = "0.6.1" } | 89 | embedded-io-async = { version = "0.7.0" } |
| 90 | fixed = "1.23.1" | 90 | fixed = "1.23.1" |
| 91 | 91 | ||
| 92 | rand-core-06 = { package = "rand_core", version = "0.6" } | 92 | rand-core-06 = { package = "rand_core", version = "0.6" } |
diff --git a/embassy-mcxa/Cargo.toml b/embassy-mcxa/Cargo.toml index 76ce59f5a..0d9663879 100644 --- a/embassy-mcxa/Cargo.toml +++ b/embassy-mcxa/Cargo.toml | |||
| @@ -36,8 +36,8 @@ embedded-hal-1 = { package = "embedded-hal", version = "1.0" } | |||
| 36 | embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] } | 36 | embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] } |
| 37 | embedded-hal-async = { version = "1.0" } | 37 | embedded-hal-async = { version = "1.0" } |
| 38 | embedded-hal-nb = { version = "1.0" } | 38 | embedded-hal-nb = { version = "1.0" } |
| 39 | embedded-io = "0.6" | 39 | embedded-io = "0.7" |
| 40 | embedded-io-async = { version = "0.6.1" } | 40 | embedded-io-async = { version = "0.7.0" } |
| 41 | heapless = "0.8" | 41 | heapless = "0.8" |
| 42 | mcxa-pac = { version = "0.1.0", features = ["rt", "critical-section"] } | 42 | mcxa-pac = { version = "0.1.0", features = ["rt", "critical-section"] } |
| 43 | nb = "1.1.0" | 43 | nb = "1.1.0" |
diff --git a/embassy-mcxa/src/clkout.rs b/embassy-mcxa/src/clkout.rs index 5b21f24b0..3495eb886 100644 --- a/embassy-mcxa/src/clkout.rs +++ b/embassy-mcxa/src/clkout.rs | |||
| @@ -20,6 +20,7 @@ pub struct ClockOut<'a> { | |||
| 20 | } | 20 | } |
| 21 | 21 | ||
| 22 | /// Selected clock source to output | 22 | /// Selected clock source to output |
| 23 | #[derive(Copy, Clone)] | ||
| 23 | pub enum ClockOutSel { | 24 | pub enum ClockOutSel { |
| 24 | /// 12MHz Internal Oscillator | 25 | /// 12MHz Internal Oscillator |
| 25 | Fro12M, | 26 | Fro12M, |
| @@ -36,6 +37,7 @@ pub enum ClockOutSel { | |||
| 36 | } | 37 | } |
| 37 | 38 | ||
| 38 | /// Configuration for the ClockOut | 39 | /// Configuration for the ClockOut |
| 40 | #[derive(Copy, Clone)] | ||
| 39 | pub struct Config { | 41 | pub struct Config { |
| 40 | /// Selected Source Clock | 42 | /// Selected Source Clock |
| 41 | pub sel: ClockOutSel, | 43 | pub sel: ClockOutSel, |
| @@ -157,6 +159,12 @@ mod sealed { | |||
| 157 | fn mux(&self) { | 159 | fn mux(&self) { |
| 158 | self.set_function(crate::pac::port0::pcr0::Mux::$func); | 160 | self.set_function(crate::pac::port0::pcr0::Mux::$func); |
| 159 | self.set_pull(Pull::Disabled); | 161 | self.set_pull(Pull::Disabled); |
| 162 | |||
| 163 | // TODO: we may want to expose these as options to allow the slew rate | ||
| 164 | // and drive strength for clocks if they are particularly high speed. | ||
| 165 | // | ||
| 166 | // self.set_drive_strength(crate::pac::port0::pcr0::Dse::Dse1); | ||
| 167 | // self.set_slew_rate(crate::pac::port0::pcr0::Sre::Sre0); | ||
| 160 | } | 168 | } |
| 161 | } | 169 | } |
| 162 | }; | 170 | }; |
diff --git a/embassy-mcxa/src/clocks/config.rs b/embassy-mcxa/src/clocks/config.rs index 0563b8917..4beca5f27 100644 --- a/embassy-mcxa/src/clocks/config.rs +++ b/embassy-mcxa/src/clocks/config.rs | |||
| @@ -119,6 +119,140 @@ pub struct ClocksConfig { | |||
| 119 | pub sirc: SircConfig, | 119 | pub sirc: SircConfig, |
| 120 | /// FRO16K clock source | 120 | /// FRO16K clock source |
| 121 | pub fro16k: Option<Fro16KConfig>, | 121 | pub fro16k: Option<Fro16KConfig>, |
| 122 | /// SOSC, clk_in clock source | ||
| 123 | pub sosc: Option<SoscConfig>, | ||
| 124 | /// SPLL | ||
| 125 | pub spll: Option<SpllConfig>, | ||
| 126 | } | ||
| 127 | |||
| 128 | // SOSC | ||
| 129 | |||
| 130 | /// The mode of the external reference clock | ||
| 131 | #[derive(Copy, Clone)] | ||
| 132 | pub enum SoscMode { | ||
| 133 | /// Passive crystal oscillators | ||
| 134 | CrystalOscillator, | ||
| 135 | /// Active external reference clock | ||
| 136 | ActiveClock, | ||
| 137 | } | ||
| 138 | |||
| 139 | /// SOSC/clk_in configuration | ||
| 140 | #[derive(Copy, Clone)] | ||
| 141 | pub struct SoscConfig { | ||
| 142 | /// Mode of the external reference clock | ||
| 143 | pub mode: SoscMode, | ||
| 144 | /// Specific frequency of the external reference clock | ||
| 145 | pub frequency: u32, | ||
| 146 | /// Power state of the external reference clock | ||
| 147 | pub power: PoweredClock, | ||
| 148 | } | ||
| 149 | |||
| 150 | // SPLL | ||
| 151 | |||
| 152 | /// PLL1/SPLL configuration | ||
| 153 | pub struct SpllConfig { | ||
| 154 | /// Input clock source for the PLL1/SPLL | ||
| 155 | pub source: SpllSource, | ||
| 156 | /// Mode of operation for the PLL1/SPLL | ||
| 157 | pub mode: SpllMode, | ||
| 158 | /// Power state of the SPLL | ||
| 159 | pub power: PoweredClock, | ||
| 160 | /// Is the "pll1_clk_div" clock enabled? | ||
| 161 | pub pll1_clk_div: Option<Div8>, | ||
| 162 | } | ||
| 163 | |||
| 164 | /// Input clock source for the PLL1/SPLL | ||
| 165 | pub enum SpllSource { | ||
| 166 | /// External Oscillator (8-50MHz) | ||
| 167 | Sosc, | ||
| 168 | /// Fast Internal Oscillator (45MHz) | ||
| 169 | // NOTE: Figure 69 says "firc_45mhz"/"clk_45m", not "fro_hf_gated", | ||
| 170 | // so this is is always 45MHz. | ||
| 171 | Firc, | ||
| 172 | /// S Internal Oscillator (12M) | ||
| 173 | Sirc, | ||
| 174 | // TODO: the reference manual hints that ROSC is possible, | ||
| 175 | // however the minimum input frequency is 32K, but ROSC is 16K. | ||
| 176 | // Some diagrams show this option, and some diagrams omit it. | ||
| 177 | // SVD shows it as "reserved". | ||
| 178 | // | ||
| 179 | // /// Realtime Internal Oscillator (16K Osc) | ||
| 180 | // Rosc, | ||
| 181 | } | ||
| 182 | |||
| 183 | /// Mode of operation for the SPLL/PLL1 | ||
| 184 | /// | ||
| 185 | /// NOTE: Currently, only "Mode 1" normal operational modes are implemented, | ||
| 186 | /// as described in the Reference Manual. | ||
| 187 | #[non_exhaustive] | ||
| 188 | pub enum SpllMode { | ||
| 189 | /// Mode 1a does not use the Pre/Post dividers. | ||
| 190 | /// | ||
| 191 | /// `Fout = m_mult x SpllSource` | ||
| 192 | /// | ||
| 193 | /// Both of the following constraints must be met: | ||
| 194 | /// | ||
| 195 | /// * Fout: 275MHz to 550MHz | ||
| 196 | /// * Fout: 4.3MHz to 2x Max CPU Frequency | ||
| 197 | Mode1a { | ||
| 198 | /// PLL Multiplier. Must be in the range 1..=65535. | ||
| 199 | m_mult: u16, | ||
| 200 | }, | ||
| 201 | |||
| 202 | /// Mode 1b does not use the Pre-divider. | ||
| 203 | /// | ||
| 204 | /// * `if !bypass_p2_div: Fout = (M / (2 x P)) x Fin` | ||
| 205 | /// * `if bypass_p2_div: Fout = (M / P ) x Fin` | ||
| 206 | /// | ||
| 207 | /// Both of the following constraints must be met: | ||
| 208 | /// | ||
| 209 | /// * Fcco: 275MHz to 550MHz | ||
| 210 | /// * `Fcco = m_mult x SpllSource` | ||
| 211 | /// * Fout: 4.3MHz to 2x Max CPU Frequency | ||
| 212 | Mode1b { | ||
| 213 | /// PLL Multiplier. `m_mult` must be in the range 1..=65535. | ||
| 214 | m_mult: u16, | ||
| 215 | /// Post Divider. `p_div` must be in the range 1..=31. | ||
| 216 | p_div: u8, | ||
| 217 | /// Bonus post divider | ||
| 218 | bypass_p2_div: bool, | ||
| 219 | }, | ||
| 220 | |||
| 221 | /// Mode 1c does use the Pre-divider, but does not use the Post-divider | ||
| 222 | /// | ||
| 223 | /// `Fout = (M / N) x Fin` | ||
| 224 | /// | ||
| 225 | /// Both of the following constraints must be met: | ||
| 226 | /// | ||
| 227 | /// * Fout: 275MHz to 550MHz | ||
| 228 | /// * Fout: 4.3MHz to 2x Max CPU Frequency | ||
| 229 | Mode1c { | ||
| 230 | /// PLL Multiplier. `m_mult` must be in the range 1..=65535. | ||
| 231 | m_mult: u16, | ||
| 232 | /// Pre Divider. `n_div` must be in the range 1..=255. | ||
| 233 | n_div: u8, | ||
| 234 | }, | ||
| 235 | |||
| 236 | /// Mode 1b uses both the Pre and Post dividers. | ||
| 237 | /// | ||
| 238 | /// * `if !bypass_p2_div: Fout = (M / (N x 2 x P)) x Fin` | ||
| 239 | /// * `if bypass_p2_div: Fout = (M / ( N x P )) x Fin` | ||
| 240 | /// | ||
| 241 | /// Both of the following constraints must be met: | ||
| 242 | /// | ||
| 243 | /// * Fcco: 275MHz to 550MHz | ||
| 244 | /// * `Fcco = (m_mult x SpllSource) / (n_div x p_div (x 2))` | ||
| 245 | /// * Fout: 4.3MHz to 2x Max CPU Frequency | ||
| 246 | Mode1d { | ||
| 247 | /// PLL Multiplier. `m_mult` must be in the range 1..=65535. | ||
| 248 | m_mult: u16, | ||
| 249 | /// Pre Divider. `n_div` must be in the range 1..=255. | ||
| 250 | n_div: u8, | ||
| 251 | /// Post Divider. `p_div` must be in the range 1..=31. | ||
| 252 | p_div: u8, | ||
| 253 | /// Bonus post divider | ||
| 254 | bypass_p2_div: bool, | ||
| 255 | }, | ||
| 122 | } | 256 | } |
| 123 | 257 | ||
| 124 | // FIRC/FRO180M | 258 | // FIRC/FRO180M |
| @@ -199,6 +333,8 @@ impl Default for ClocksConfig { | |||
| 199 | vsys_domain_active: true, | 333 | vsys_domain_active: true, |
| 200 | vdd_core_domain_active: true, | 334 | vdd_core_domain_active: true, |
| 201 | }), | 335 | }), |
| 336 | sosc: None, | ||
| 337 | spll: None, | ||
| 202 | } | 338 | } |
| 203 | } | 339 | } |
| 204 | } | 340 | } |
diff --git a/embassy-mcxa/src/clocks/mod.rs b/embassy-mcxa/src/clocks/mod.rs index 037f0a656..04559fd04 100644 --- a/embassy-mcxa/src/clocks/mod.rs +++ b/embassy-mcxa/src/clocks/mod.rs | |||
| @@ -87,6 +87,8 @@ pub fn init(settings: ClocksConfig) -> Result<(), ClockError> { | |||
| 87 | operator.configure_firc_clocks()?; | 87 | operator.configure_firc_clocks()?; |
| 88 | operator.configure_sirc_clocks()?; | 88 | operator.configure_sirc_clocks()?; |
| 89 | operator.configure_fro16k_clocks()?; | 89 | operator.configure_fro16k_clocks()?; |
| 90 | operator.configure_sosc()?; | ||
| 91 | operator.configure_spll()?; | ||
| 90 | 92 | ||
| 91 | // For now, just use FIRC as the main/cpu clock, which should already be | 93 | // For now, just use FIRC as the main/cpu clock, which should already be |
| 92 | // the case on reset | 94 | // the case on reset |
| @@ -136,6 +138,7 @@ pub fn with_clocks<R: 'static, F: FnOnce(&Clocks) -> R>(f: F) -> Option<R> { | |||
| 136 | #[non_exhaustive] | 138 | #[non_exhaustive] |
| 137 | pub struct Clocks { | 139 | pub struct Clocks { |
| 138 | /// The `clk_in` is a clock provided by an external oscillator | 140 | /// The `clk_in` is a clock provided by an external oscillator |
| 141 | /// AKA SOSC | ||
| 139 | pub clk_in: Option<Clock>, | 142 | pub clk_in: Option<Clock>, |
| 140 | 143 | ||
| 141 | // FRO180M stuff | 144 | // FRO180M stuff |
| @@ -197,6 +200,9 @@ pub struct Clocks { | |||
| 197 | 200 | ||
| 198 | /// `pll1_clk` is the output of the main system PLL, `pll1`. | 201 | /// `pll1_clk` is the output of the main system PLL, `pll1`. |
| 199 | pub pll1_clk: Option<Clock>, | 202 | pub pll1_clk: Option<Clock>, |
| 203 | |||
| 204 | /// `pll1_clk_div` is a configurable frequency clock, sourced from `pll1_clk` | ||
| 205 | pub pll1_clk_div: Option<Clock>, | ||
| 200 | } | 206 | } |
| 201 | 207 | ||
| 202 | /// `ClockError` is the main error returned when configuring or checking clock state | 208 | /// `ClockError` is the main error returned when configuring or checking clock state |
| @@ -433,60 +439,49 @@ pub unsafe fn pulse_reset<G: Gate>() { | |||
| 433 | /// selected clocks are active at a suitable level at time of construction. These methods | 439 | /// selected clocks are active at a suitable level at time of construction. These methods |
| 434 | /// return the frequency of the requested clock, in Hertz, or a [`ClockError`]. | 440 | /// return the frequency of the requested clock, in Hertz, or a [`ClockError`]. |
| 435 | impl Clocks { | 441 | impl Clocks { |
| 436 | /// Ensure the `fro_lf_div` clock is active and valid at the given power state. | 442 | fn ensure_clock_active( |
| 437 | pub fn ensure_fro_lf_div_active(&self, at_level: &PoweredClock) -> Result<u32, ClockError> { | 443 | &self, |
| 438 | let Some(clk) = self.fro_lf_div.as_ref() else { | 444 | clock: &Option<Clock>, |
| 445 | name: &'static str, | ||
| 446 | at_level: &PoweredClock, | ||
| 447 | ) -> Result<u32, ClockError> { | ||
| 448 | let Some(clk) = clock.as_ref() else { | ||
| 439 | return Err(ClockError::BadConfig { | 449 | return Err(ClockError::BadConfig { |
| 440 | clock: "fro_lf_div", | 450 | clock: name, |
| 441 | reason: "required but not active", | 451 | reason: "required but not active", |
| 442 | }); | 452 | }); |
| 443 | }; | 453 | }; |
| 444 | if !clk.power.meets_requirement_of(at_level) { | 454 | if !clk.power.meets_requirement_of(at_level) { |
| 445 | return Err(ClockError::BadConfig { | 455 | return Err(ClockError::BadConfig { |
| 446 | clock: "fro_lf_div", | 456 | clock: name, |
| 447 | reason: "not low power active", | 457 | reason: "not low power active", |
| 448 | }); | 458 | }); |
| 449 | } | 459 | } |
| 450 | Ok(clk.frequency) | 460 | Ok(clk.frequency) |
| 451 | } | 461 | } |
| 452 | 462 | ||
| 463 | /// Ensure the `fro_lf_div` clock is active and valid at the given power state. | ||
| 464 | #[inline] | ||
| 465 | pub fn ensure_fro_lf_div_active(&self, at_level: &PoweredClock) -> Result<u32, ClockError> { | ||
| 466 | self.ensure_clock_active(&self.fro_lf_div, "fro_lf_div", at_level) | ||
| 467 | } | ||
| 468 | |||
| 453 | /// Ensure the `fro_hf` clock is active and valid at the given power state. | 469 | /// Ensure the `fro_hf` clock is active and valid at the given power state. |
| 470 | #[inline] | ||
| 454 | pub fn ensure_fro_hf_active(&self, at_level: &PoweredClock) -> Result<u32, ClockError> { | 471 | pub fn ensure_fro_hf_active(&self, at_level: &PoweredClock) -> Result<u32, ClockError> { |
| 455 | let Some(clk) = self.fro_hf.as_ref() else { | 472 | self.ensure_clock_active(&self.fro_hf, "fro_hf", at_level) |
| 456 | return Err(ClockError::BadConfig { | ||
| 457 | clock: "fro_hf", | ||
| 458 | reason: "required but not active", | ||
| 459 | }); | ||
| 460 | }; | ||
| 461 | if !clk.power.meets_requirement_of(at_level) { | ||
| 462 | return Err(ClockError::BadConfig { | ||
| 463 | clock: "fro_hf", | ||
| 464 | reason: "not low power active", | ||
| 465 | }); | ||
| 466 | } | ||
| 467 | Ok(clk.frequency) | ||
| 468 | } | 473 | } |
| 469 | 474 | ||
| 470 | /// Ensure the `fro_hf_div` clock is active and valid at the given power state. | 475 | /// Ensure the `fro_hf_div` clock is active and valid at the given power state. |
| 476 | #[inline] | ||
| 471 | pub fn ensure_fro_hf_div_active(&self, at_level: &PoweredClock) -> Result<u32, ClockError> { | 477 | pub fn ensure_fro_hf_div_active(&self, at_level: &PoweredClock) -> Result<u32, ClockError> { |
| 472 | let Some(clk) = self.fro_hf_div.as_ref() else { | 478 | self.ensure_clock_active(&self.fro_hf_div, "fro_hf_div", at_level) |
| 473 | return Err(ClockError::BadConfig { | ||
| 474 | clock: "fro_hf_div", | ||
| 475 | reason: "required but not active", | ||
| 476 | }); | ||
| 477 | }; | ||
| 478 | if !clk.power.meets_requirement_of(at_level) { | ||
| 479 | return Err(ClockError::BadConfig { | ||
| 480 | clock: "fro_hf_div", | ||
| 481 | reason: "not low power active", | ||
| 482 | }); | ||
| 483 | } | ||
| 484 | Ok(clk.frequency) | ||
| 485 | } | 479 | } |
| 486 | 480 | ||
| 487 | /// Ensure the `clk_in` clock is active and valid at the given power state. | 481 | /// Ensure the `clk_in` clock is active and valid at the given power state. |
| 488 | pub fn ensure_clk_in_active(&self, _at_level: &PoweredClock) -> Result<u32, ClockError> { | 482 | #[inline] |
| 489 | Err(ClockError::NotImplemented { clock: "clk_in" }) | 483 | pub fn ensure_clk_in_active(&self, at_level: &PoweredClock) -> Result<u32, ClockError> { |
| 484 | self.ensure_clock_active(&self.clk_in, "clk_in", at_level) | ||
| 490 | } | 485 | } |
| 491 | 486 | ||
| 492 | /// Ensure the `clk_16k_vsys` clock is active and valid at the given power state. | 487 | /// Ensure the `clk_16k_vsys` clock is active and valid at the given power state. |
| @@ -516,30 +511,21 @@ impl Clocks { | |||
| 516 | } | 511 | } |
| 517 | 512 | ||
| 518 | /// Ensure the `clk_1m` clock is active and valid at the given power state. | 513 | /// Ensure the `clk_1m` clock is active and valid at the given power state. |
| 514 | #[inline] | ||
| 519 | pub fn ensure_clk_1m_active(&self, at_level: &PoweredClock) -> Result<u32, ClockError> { | 515 | pub fn ensure_clk_1m_active(&self, at_level: &PoweredClock) -> Result<u32, ClockError> { |
| 520 | let Some(clk) = self.clk_1m.as_ref() else { | 516 | self.ensure_clock_active(&self.clk_1m, "clk_1m", at_level) |
| 521 | return Err(ClockError::BadConfig { | ||
| 522 | clock: "clk_1m", | ||
| 523 | reason: "required but not active", | ||
| 524 | }); | ||
| 525 | }; | ||
| 526 | if !clk.power.meets_requirement_of(at_level) { | ||
| 527 | return Err(ClockError::BadConfig { | ||
| 528 | clock: "clk_1m", | ||
| 529 | reason: "not low power active", | ||
| 530 | }); | ||
| 531 | } | ||
| 532 | Ok(clk.frequency) | ||
| 533 | } | 517 | } |
| 534 | 518 | ||
| 535 | /// Ensure the `pll1_clk` clock is active and valid at the given power state. | 519 | /// Ensure the `pll1_clk` clock is active and valid at the given power state. |
| 536 | pub fn ensure_pll1_clk_active(&self, _at_level: &PoweredClock) -> Result<u32, ClockError> { | 520 | #[inline] |
| 537 | Err(ClockError::NotImplemented { clock: "pll1_clk" }) | 521 | pub fn ensure_pll1_clk_active(&self, at_level: &PoweredClock) -> Result<u32, ClockError> { |
| 522 | self.ensure_clock_active(&self.pll1_clk, "pll1_clk", at_level) | ||
| 538 | } | 523 | } |
| 539 | 524 | ||
| 540 | /// Ensure the `pll1_clk_div` clock is active and valid at the given power state. | 525 | /// Ensure the `pll1_clk_div` clock is active and valid at the given power state. |
| 541 | pub fn ensure_pll1_clk_div_active(&self, _at_level: &PoweredClock) -> Result<u32, ClockError> { | 526 | #[inline] |
| 542 | Err(ClockError::NotImplemented { clock: "pll1_clk_div" }) | 527 | pub fn ensure_pll1_clk_div_active(&self, at_level: &PoweredClock) -> Result<u32, ClockError> { |
| 528 | self.ensure_clock_active(&self.pll1_clk_div, "pll1_clk_div", at_level) | ||
| 543 | } | 529 | } |
| 544 | 530 | ||
| 545 | /// Ensure the `CPU_CLK` or `SYSTEM_CLK` is active | 531 | /// Ensure the `CPU_CLK` or `SYSTEM_CLK` is active |
| @@ -811,7 +797,7 @@ impl ClockOperator<'_> { | |||
| 811 | Ok(()) | 797 | Ok(()) |
| 812 | } | 798 | } |
| 813 | 799 | ||
| 814 | /// Configure the FRO16K/clk_16k clock family | 800 | /// Configure the ROSC/FRO16K/clk_16k clock family |
| 815 | fn configure_fro16k_clocks(&mut self) -> Result<(), ClockError> { | 801 | fn configure_fro16k_clocks(&mut self) -> Result<(), ClockError> { |
| 816 | let Some(fro16k) = self.config.fro16k.as_ref() else { | 802 | let Some(fro16k) = self.config.fro16k.as_ref() else { |
| 817 | return Ok(()); | 803 | return Ok(()); |
| @@ -851,6 +837,485 @@ impl ClockOperator<'_> { | |||
| 851 | 837 | ||
| 852 | Ok(()) | 838 | Ok(()) |
| 853 | } | 839 | } |
| 840 | |||
| 841 | fn ensure_ldo_active(&mut self) { | ||
| 842 | // TODO: Config for the LDO? For now, just enable | ||
| 843 | // using the default settings: | ||
| 844 | // LDOBYPASS: 0/not bypassed | ||
| 845 | // VOUT_SEL: 0b100: 1.1v | ||
| 846 | // LDOEN: 0/Disabled | ||
| 847 | let already_enabled = { | ||
| 848 | let ldocsr = self.scg0.ldocsr().read(); | ||
| 849 | ldocsr.ldoen().is_enabled() && ldocsr.vout_ok().is_enabled() | ||
| 850 | }; | ||
| 851 | if !already_enabled { | ||
| 852 | self.scg0.ldocsr().modify(|_r, w| w.ldoen().enabled()); | ||
| 853 | while self.scg0.ldocsr().read().vout_ok().is_disabled() {} | ||
| 854 | } | ||
| 855 | } | ||
| 856 | |||
| 857 | /// Configure the SOSC/clk_in oscillator | ||
| 858 | fn configure_sosc(&mut self) -> Result<(), ClockError> { | ||
| 859 | let Some(parts) = self.config.sosc.as_ref() else { | ||
| 860 | return Ok(()); | ||
| 861 | }; | ||
| 862 | |||
| 863 | // Enable (and wait for) LDO to be active | ||
| 864 | self.ensure_ldo_active(); | ||
| 865 | |||
| 866 | // TODO: something something pins? This seems to work when the pins are | ||
| 867 | // not enabled, even if GPIO hasn't been initialized at all yet. | ||
| 868 | let eref = match parts.mode { | ||
| 869 | config::SoscMode::CrystalOscillator => pac::scg0::sosccfg::Erefs::Internal, | ||
| 870 | config::SoscMode::ActiveClock => pac::scg0::sosccfg::Erefs::External, | ||
| 871 | }; | ||
| 872 | let freq = parts.frequency; | ||
| 873 | |||
| 874 | // TODO: Fix PAC names here | ||
| 875 | // | ||
| 876 | // #[doc = "0: Frequency range select of 8-16 MHz."] | ||
| 877 | // Freq16to20mhz = 0, | ||
| 878 | // #[doc = "1: Frequency range select of 16-25 MHz."] | ||
| 879 | // LowFreq = 1, | ||
| 880 | // #[doc = "2: Frequency range select of 25-40 MHz."] | ||
| 881 | // MediumFreq = 2, | ||
| 882 | // #[doc = "3: Frequency range select of 40-50 MHz."] | ||
| 883 | // HighFreq = 3, | ||
| 884 | let range = match freq { | ||
| 885 | 0..8_000_000 => { | ||
| 886 | return Err(ClockError::BadConfig { | ||
| 887 | clock: "clk_in", | ||
| 888 | reason: "freq too low", | ||
| 889 | }); | ||
| 890 | } | ||
| 891 | 8_000_000..16_000_000 => pac::scg0::sosccfg::Range::Freq16to20mhz, | ||
| 892 | 16_000_000..25_000_000 => pac::scg0::sosccfg::Range::LowFreq, | ||
| 893 | 25_000_000..40_000_000 => pac::scg0::sosccfg::Range::MediumFreq, | ||
| 894 | 40_000_000..50_000_001 => pac::scg0::sosccfg::Range::HighFreq, | ||
| 895 | 50_000_001.. => { | ||
| 896 | return Err(ClockError::BadConfig { | ||
| 897 | clock: "clk_in", | ||
| 898 | reason: "freq too high", | ||
| 899 | }); | ||
| 900 | } | ||
| 901 | }; | ||
| 902 | |||
| 903 | // Set source/erefs and range | ||
| 904 | self.scg0.sosccfg().modify(|_r, w| { | ||
| 905 | w.erefs().variant(eref); | ||
| 906 | w.range().variant(range); | ||
| 907 | w | ||
| 908 | }); | ||
| 909 | |||
| 910 | // Disable lock | ||
| 911 | self.scg0.sosccsr().modify(|_r, w| w.lk().clear_bit()); | ||
| 912 | |||
| 913 | // TODO: We could enable the SOSC clock monitor. There are some things to | ||
| 914 | // figure out first: | ||
| 915 | // | ||
| 916 | // * This requires SIRC to be enabled, not sure which branch. Maybe fro12m_root? | ||
| 917 | // * If SOSC needs to work in deep sleep, AND the monitor is enabled: | ||
| 918 | // * SIRC also need needs to be low power | ||
| 919 | // * We need to decide if we need an interrupt or a reset if the monitor trips | ||
| 920 | |||
| 921 | // Apply remaining config | ||
| 922 | self.scg0.sosccsr().modify(|_r, w| { | ||
| 923 | // For now, just disable the monitor. See above. | ||
| 924 | w.sosccm().disabled(); | ||
| 925 | |||
| 926 | // Set deep sleep mode | ||
| 927 | match parts.power { | ||
| 928 | PoweredClock::NormalEnabledDeepSleepDisabled => { | ||
| 929 | w.soscsten().clear_bit(); | ||
| 930 | } | ||
| 931 | PoweredClock::AlwaysEnabled => { | ||
| 932 | w.soscsten().set_bit(); | ||
| 933 | } | ||
| 934 | } | ||
| 935 | |||
| 936 | // Enable SOSC | ||
| 937 | w.soscen().enabled() | ||
| 938 | }); | ||
| 939 | |||
| 940 | // Wait for SOSC to be valid, check for errors | ||
| 941 | while !self.scg0.sosccsr().read().soscvld().bit_is_set() {} | ||
| 942 | if self.scg0.sosccsr().read().soscerr().is_enabled_and_error() { | ||
| 943 | return Err(ClockError::BadConfig { | ||
| 944 | clock: "clk_in", | ||
| 945 | reason: "soscerr is set", | ||
| 946 | }); | ||
| 947 | } | ||
| 948 | |||
| 949 | // Re-lock the sosc | ||
| 950 | self.scg0.sosccsr().modify(|_r, w| w.lk().set_bit()); | ||
| 951 | |||
| 952 | self.clocks.clk_in = Some(Clock { | ||
| 953 | frequency: freq, | ||
| 954 | power: parts.power, | ||
| 955 | }); | ||
| 956 | |||
| 957 | Ok(()) | ||
| 958 | } | ||
| 959 | |||
| 960 | fn configure_spll(&mut self) -> Result<(), ClockError> { | ||
| 961 | // # Vocab | ||
| 962 | // | ||
| 963 | // | Name | Meaning | | ||
| 964 | // | :--- | :--- | | ||
| 965 | // | Fin | Frequency of clkin | | ||
| 966 | // | clkout | Output clock of the PLL | | ||
| 967 | // | Fout | Frequency of clkout (depends on mode) | | ||
| 968 | // | clkref | PLL Reference clock, the input clock to the PFD | | ||
| 969 | // | Fref | Frequency of clkref, Fref = Fin / N | | ||
| 970 | // | Fcco | Frequency of the output clock of the CCO, Fcco = M * Fref | | ||
| 971 | // | N | Predivider value | | ||
| 972 | // | M | Feedback divider value | | ||
| 973 | // | P | Postdivider value | | ||
| 974 | // | Tpon | PLL start-up time | | ||
| 975 | |||
| 976 | // No PLL? Nothing to do! | ||
| 977 | let Some(cfg) = self.config.spll.as_ref() else { | ||
| 978 | return Ok(()); | ||
| 979 | }; | ||
| 980 | |||
| 981 | // Ensure the LDO is active | ||
| 982 | self.ensure_ldo_active(); | ||
| 983 | |||
| 984 | // match on the source, ensure it is active already | ||
| 985 | let res = match cfg.source { | ||
| 986 | config::SpllSource::Sosc => self | ||
| 987 | .clocks | ||
| 988 | .clk_in | ||
| 989 | .as_ref() | ||
| 990 | .map(|c| (c, pac::scg0::spllctrl::Source::Sosc)) | ||
| 991 | .ok_or("sosc not active"), | ||
| 992 | config::SpllSource::Firc => self | ||
| 993 | .clocks | ||
| 994 | .clk_45m | ||
| 995 | .as_ref() | ||
| 996 | .map(|c| (c, pac::scg0::spllctrl::Source::Firc)) | ||
| 997 | .ok_or("firc not active"), | ||
| 998 | config::SpllSource::Sirc => self | ||
| 999 | .clocks | ||
| 1000 | .fro_12m | ||
| 1001 | .as_ref() | ||
| 1002 | .map(|c| (c, pac::scg0::spllctrl::Source::Sirc)) | ||
| 1003 | .ok_or("sirc not active"), | ||
| 1004 | }; | ||
| 1005 | // This checks if active | ||
| 1006 | let (clk, variant) = res.map_err(|s| ClockError::BadConfig { | ||
| 1007 | clock: "spll", | ||
| 1008 | reason: s, | ||
| 1009 | })?; | ||
| 1010 | // This checks the correct power reqs | ||
| 1011 | if !clk.power.meets_requirement_of(&cfg.power) { | ||
| 1012 | return Err(ClockError::BadConfig { | ||
| 1013 | clock: "spll", | ||
| 1014 | reason: "needs low power source", | ||
| 1015 | }); | ||
| 1016 | } | ||
| 1017 | |||
| 1018 | // Bandwidth calc | ||
| 1019 | // | ||
| 1020 | // > In normal applications, you must calculate the bandwidth manually by using the feedback divider M (ranging from 1 to 216-1), | ||
| 1021 | // > Equation 1, and Equation 2. The PLL is automatically stable in such case. In normal applications, SPLLCTRL[BANDDIRECT] must | ||
| 1022 | // > be 0; in this case, the bandwidth changes as a function of M. | ||
| 1023 | if clk.frequency == 0 { | ||
| 1024 | return Err(ClockError::BadConfig { | ||
| 1025 | clock: "spll", | ||
| 1026 | reason: "internal error", | ||
| 1027 | }); | ||
| 1028 | } | ||
| 1029 | |||
| 1030 | // These are calculated differently depending on the mode. | ||
| 1031 | let f_in = clk.frequency; | ||
| 1032 | let bp_pre: bool; | ||
| 1033 | let bp_post: bool; | ||
| 1034 | let bp_post2: bool; | ||
| 1035 | let m: u16; | ||
| 1036 | let p: Option<u8>; | ||
| 1037 | let n: Option<u8>; | ||
| 1038 | |||
| 1039 | // Calculate both Fout and Fcco so we can ensure they don't overflow | ||
| 1040 | // and are in range | ||
| 1041 | let fout: Option<u32>; | ||
| 1042 | let fcco: Option<u32>; | ||
| 1043 | |||
| 1044 | let m_check = |m: u16| { | ||
| 1045 | if !(1..=u16::MAX).contains(&m) { | ||
| 1046 | Err(ClockError::BadConfig { | ||
| 1047 | clock: "spll", | ||
| 1048 | reason: "m_mult out of range", | ||
| 1049 | }) | ||
| 1050 | } else { | ||
| 1051 | Ok(m) | ||
| 1052 | } | ||
| 1053 | }; | ||
| 1054 | let p_check = |p: u8| { | ||
| 1055 | if !(1..=31).contains(&p) { | ||
| 1056 | Err(ClockError::BadConfig { | ||
| 1057 | clock: "spll", | ||
| 1058 | reason: "p_div out of range", | ||
| 1059 | }) | ||
| 1060 | } else { | ||
| 1061 | Ok(p) | ||
| 1062 | } | ||
| 1063 | }; | ||
| 1064 | let n_check = |n: u8| { | ||
| 1065 | if !(1..=u8::MAX).contains(&n) { | ||
| 1066 | Err(ClockError::BadConfig { | ||
| 1067 | clock: "spll", | ||
| 1068 | reason: "n_div out of range", | ||
| 1069 | }) | ||
| 1070 | } else { | ||
| 1071 | Ok(n) | ||
| 1072 | } | ||
| 1073 | }; | ||
| 1074 | |||
| 1075 | match cfg.mode { | ||
| 1076 | // Fout = M x Fin | ||
| 1077 | config::SpllMode::Mode1a { m_mult } => { | ||
| 1078 | bp_pre = true; | ||
| 1079 | bp_post = true; | ||
| 1080 | bp_post2 = false; | ||
| 1081 | m = m_check(m_mult)?; | ||
| 1082 | p = None; | ||
| 1083 | n = None; | ||
| 1084 | fcco = f_in.checked_mul(m_mult as u32); | ||
| 1085 | fout = fcco; | ||
| 1086 | } | ||
| 1087 | // if !bypass_p2_div: Fout = (M / (2 x P)) x Fin | ||
| 1088 | // if bypass_p2_div: Fout = (M / P ) x Fin | ||
| 1089 | config::SpllMode::Mode1b { | ||
| 1090 | m_mult, | ||
| 1091 | p_div, | ||
| 1092 | bypass_p2_div, | ||
| 1093 | } => { | ||
| 1094 | bp_pre = true; | ||
| 1095 | bp_post = false; | ||
| 1096 | bp_post2 = bypass_p2_div; | ||
| 1097 | m = m_check(m_mult)?; | ||
| 1098 | p = Some(p_check(p_div)?); | ||
| 1099 | n = None; | ||
| 1100 | let mut div = p_div as u32; | ||
| 1101 | if !bypass_p2_div { | ||
| 1102 | div *= 2; | ||
| 1103 | } | ||
| 1104 | fcco = f_in.checked_mul(m_mult as u32); | ||
| 1105 | fout = (f_in / div).checked_mul(m_mult as u32); | ||
| 1106 | } | ||
| 1107 | // Fout = (M / N) x Fin | ||
| 1108 | config::SpllMode::Mode1c { m_mult, n_div } => { | ||
| 1109 | bp_pre = false; | ||
| 1110 | bp_post = true; | ||
| 1111 | bp_post2 = false; | ||
| 1112 | m = m_check(m_mult)?; | ||
| 1113 | p = None; | ||
| 1114 | n = Some(n_check(n_div)?); | ||
| 1115 | fcco = (f_in / (n_div as u32)).checked_mul(m_mult as u32); | ||
| 1116 | fout = fcco; | ||
| 1117 | } | ||
| 1118 | // if !bypass_p2_div: Fout = (M / (N x 2 x P)) x Fin | ||
| 1119 | // if bypass_p2_div: Fout = (M / ( N x P )) x Fin | ||
| 1120 | config::SpllMode::Mode1d { | ||
| 1121 | m_mult, | ||
| 1122 | n_div, | ||
| 1123 | p_div, | ||
| 1124 | bypass_p2_div, | ||
| 1125 | } => { | ||
| 1126 | bp_pre = false; | ||
| 1127 | bp_post = false; | ||
| 1128 | bp_post2 = bypass_p2_div; | ||
| 1129 | m = m_check(m_mult)?; | ||
| 1130 | p = Some(p_check(p_div)?); | ||
| 1131 | n = Some(n_check(n_div)?); | ||
| 1132 | // This can't overflow: u8 x u8 (x 2) always fits in u32 | ||
| 1133 | let mut div = (p_div as u32) * (n_div as u32); | ||
| 1134 | if !bypass_p2_div { | ||
| 1135 | div *= 2; | ||
| 1136 | } | ||
| 1137 | fcco = (f_in / (n_div as u32)).checked_mul(m_mult as u32); | ||
| 1138 | fout = (f_in / div).checked_mul(m_mult as u32); | ||
| 1139 | } | ||
| 1140 | }; | ||
| 1141 | |||
| 1142 | // Dump all the PLL calcs if needed for debugging | ||
| 1143 | #[cfg(feature = "defmt")] | ||
| 1144 | { | ||
| 1145 | defmt::debug!("f_in: {:?}", f_in); | ||
| 1146 | defmt::debug!("bp_pre: {:?}", bp_pre); | ||
| 1147 | defmt::debug!("bp_post: {:?}", bp_post); | ||
| 1148 | defmt::debug!("bp_post2: {:?}", bp_post2); | ||
| 1149 | defmt::debug!("m: {:?}", m); | ||
| 1150 | defmt::debug!("p: {:?}", p); | ||
| 1151 | defmt::debug!("n: {:?}", n); | ||
| 1152 | defmt::debug!("fout: {:?}", fout); | ||
| 1153 | defmt::debug!("fcco: {:?}", fcco); | ||
| 1154 | } | ||
| 1155 | |||
| 1156 | // Ensure the Fcco and Fout calcs didn't overflow | ||
| 1157 | let fcco = fcco.ok_or(ClockError::BadConfig { | ||
| 1158 | clock: "spll", | ||
| 1159 | reason: "fcco invalid1", | ||
| 1160 | })?; | ||
| 1161 | let fout = fout.ok_or(ClockError::BadConfig { | ||
| 1162 | clock: "spll", | ||
| 1163 | reason: "fout invalid", | ||
| 1164 | })?; | ||
| 1165 | |||
| 1166 | // Fcco: 275MHz to 550MHz | ||
| 1167 | if !(275_000_000..=550_000_000).contains(&fcco) { | ||
| 1168 | return Err(ClockError::BadConfig { | ||
| 1169 | clock: "spll", | ||
| 1170 | reason: "fcco invalid2", | ||
| 1171 | }); | ||
| 1172 | } | ||
| 1173 | |||
| 1174 | // TODO: Different for different CPUs? | ||
| 1175 | const CPU_MAX_FREQ: u32 = 180_000_000; | ||
| 1176 | |||
| 1177 | // Fout: 4.3MHz to 2x Max CPU Frequency | ||
| 1178 | if !(4_300_000..=(2 * CPU_MAX_FREQ)).contains(&fout) { | ||
| 1179 | return Err(ClockError::BadConfig { | ||
| 1180 | clock: "spll", | ||
| 1181 | reason: "fout invalid", | ||
| 1182 | }); | ||
| 1183 | } | ||
| 1184 | |||
| 1185 | // A = floor(m / 4) + 1 | ||
| 1186 | let selp_a = (m / 4) + 1; | ||
| 1187 | // SELP = A if A < 31 | ||
| 1188 | // = 31 if A >= 31 | ||
| 1189 | let selp = selp_a.min(31); | ||
| 1190 | |||
| 1191 | // A = 1 if M >= 8000 | ||
| 1192 | // = floor(8000 / M) if 8000 > M >= 122 | ||
| 1193 | // = 2 x floor(M / 4) / 3 if 122 > M >= 1 | ||
| 1194 | let seli_a = if m >= 8000 { | ||
| 1195 | 1 | ||
| 1196 | } else if m >= 122 { | ||
| 1197 | 8000 / m | ||
| 1198 | } else { | ||
| 1199 | (2 * (m / 4)) / 3 | ||
| 1200 | }; | ||
| 1201 | // SELI = A if A < 63 | ||
| 1202 | // = 63 if A >= 63 | ||
| 1203 | let seli = seli_a.min(63); | ||
| 1204 | // SELR must be 0. | ||
| 1205 | let selr = 0; | ||
| 1206 | |||
| 1207 | self.scg0.spllctrl().modify(|_r, w| { | ||
| 1208 | w.source().variant(variant); | ||
| 1209 | unsafe { | ||
| 1210 | w.selp().bits(selp as u8); | ||
| 1211 | w.seli().bits(seli as u8); | ||
| 1212 | w.selr().bits(selr); | ||
| 1213 | } | ||
| 1214 | w | ||
| 1215 | }); | ||
| 1216 | |||
| 1217 | if let Some(n) = n { | ||
| 1218 | self.scg0.spllndiv().modify(|_r, w| unsafe { w.ndiv().bits(n) }); | ||
| 1219 | } | ||
| 1220 | if let Some(p) = p { | ||
| 1221 | self.scg0.spllpdiv().modify(|_r, w| unsafe { w.pdiv().bits(p) }); | ||
| 1222 | } | ||
| 1223 | self.scg0.spllmdiv().modify(|_r, w| unsafe { w.mdiv().bits(m) }); | ||
| 1224 | |||
| 1225 | self.scg0.spllctrl().modify(|_r, w| { | ||
| 1226 | w.bypassprediv().bit(bp_pre); | ||
| 1227 | w.bypasspostdiv().bit(bp_post); | ||
| 1228 | w.bypasspostdiv2().bit(bp_post2); | ||
| 1229 | |||
| 1230 | // TODO: support FRM? | ||
| 1231 | w.frm().disabled(); | ||
| 1232 | |||
| 1233 | w | ||
| 1234 | }); | ||
| 1235 | |||
| 1236 | // Unlock | ||
| 1237 | self.scg0.spllcsr().modify(|_r, w| w.lk().write_enabled()); | ||
| 1238 | |||
| 1239 | // TODO: Support clock monitors? | ||
| 1240 | // self.scg0.spllcsr().modify(|_r, w| w.spllcm().?); | ||
| 1241 | |||
| 1242 | self.scg0.trim_lock().write(|w| unsafe { | ||
| 1243 | w.trim_lock_key().bits(0x5a5a); | ||
| 1244 | w.trim_unlock().not_locked() | ||
| 1245 | }); | ||
| 1246 | |||
| 1247 | // SPLLLOCK_CNFG: The lock time programmed in this register must be | ||
| 1248 | // equal to meet the PLL 500μs lock time plus the 300 refclk count startup. | ||
| 1249 | // | ||
| 1250 | // LOCK_TIME = 500μs/T ref + 300, F ref = F in /N (input frequency divided by pre-divider ratio). | ||
| 1251 | // | ||
| 1252 | // 500us is 1/2000th of a second, therefore Fref / 2000 is the number of cycles in 500us. | ||
| 1253 | let f_ref = if let Some(n) = n { f_in / (n as u32) } else { f_in }; | ||
| 1254 | let lock_time = f_ref.div_ceil(2000) + 300; | ||
| 1255 | self.scg0 | ||
| 1256 | .splllock_cnfg() | ||
| 1257 | .write(|w| unsafe { w.lock_time().bits(lock_time) }); | ||
| 1258 | |||
| 1259 | // TODO: Support Spread spectrum? | ||
| 1260 | |||
| 1261 | self.scg0.spllcsr().modify(|_r, w| { | ||
| 1262 | w.spllclken().enabled(); | ||
| 1263 | w.spllpwren().enabled(); | ||
| 1264 | w.spllsten().bit(matches!(cfg.power, PoweredClock::AlwaysEnabled)); | ||
| 1265 | w | ||
| 1266 | }); | ||
| 1267 | |||
| 1268 | // Wait for SPLL to set up | ||
| 1269 | loop { | ||
| 1270 | let csr = self.scg0.spllcsr().read(); | ||
| 1271 | if csr.spll_lock().is_enabled_and_valid() { | ||
| 1272 | if csr.spllerr().is_enabled_and_error() { | ||
| 1273 | return Err(ClockError::BadConfig { | ||
| 1274 | clock: "spll", | ||
| 1275 | reason: "spllerr is set", | ||
| 1276 | }); | ||
| 1277 | } | ||
| 1278 | break; | ||
| 1279 | } | ||
| 1280 | } | ||
| 1281 | |||
| 1282 | // Re-lock SPLL CSR | ||
| 1283 | self.scg0.spllcsr().modify(|_r, w| w.lk().write_disabled()); | ||
| 1284 | |||
| 1285 | // Store clock state | ||
| 1286 | self.clocks.pll1_clk = Some(Clock { | ||
| 1287 | frequency: fout, | ||
| 1288 | power: cfg.power, | ||
| 1289 | }); | ||
| 1290 | |||
| 1291 | // Do we enable the `pll1_clk_div` output? | ||
| 1292 | if let Some(d) = cfg.pll1_clk_div.as_ref() { | ||
| 1293 | // Halt and reset the div; then set our desired div. | ||
| 1294 | self.syscon.pll1clkdiv().write(|w| { | ||
| 1295 | w.halt().halt(); | ||
| 1296 | w.reset().asserted(); | ||
| 1297 | unsafe { w.div().bits(d.into_bits()) }; | ||
| 1298 | w | ||
| 1299 | }); | ||
| 1300 | // Then unhalt it, and reset it | ||
| 1301 | self.syscon.pll1clkdiv().write(|w| { | ||
| 1302 | w.halt().run(); | ||
| 1303 | w.reset().released(); | ||
| 1304 | w | ||
| 1305 | }); | ||
| 1306 | |||
| 1307 | // Wait for clock to stabilize | ||
| 1308 | while self.syscon.pll1clkdiv().read().unstab().is_ongoing() {} | ||
| 1309 | |||
| 1310 | // Store off the clock info | ||
| 1311 | self.clocks.pll1_clk_div = Some(Clock { | ||
| 1312 | frequency: fout / d.into_divisor(), | ||
| 1313 | power: cfg.power, | ||
| 1314 | }); | ||
| 1315 | } | ||
| 1316 | |||
| 1317 | Ok(()) | ||
| 1318 | } | ||
| 854 | } | 1319 | } |
| 855 | 1320 | ||
| 856 | // | 1321 | // |
diff --git a/embassy-mcxa/src/dma.rs b/embassy-mcxa/src/dma.rs index 8d519d99b..b68f55e65 100644 --- a/embassy-mcxa/src/dma.rs +++ b/embassy-mcxa/src/dma.rs | |||
| @@ -1924,7 +1924,7 @@ impl Iterator for TransferErrorRawIter { | |||
| 1924 | 1924 | ||
| 1925 | for (mask, var) in TransferErrorRaw::MAP { | 1925 | for (mask, var) in TransferErrorRaw::MAP { |
| 1926 | // If the bit is set... | 1926 | // If the bit is set... |
| 1927 | if self.0 | mask != 0 { | 1927 | if self.0 & mask != 0 { |
| 1928 | // clear the bit | 1928 | // clear the bit |
| 1929 | self.0 &= !mask; | 1929 | self.0 &= !mask; |
| 1930 | // and return the answer | 1930 | // and return the answer |
diff --git a/embassy-mcxa/src/gpio.rs b/embassy-mcxa/src/gpio.rs index 65f8df985..29d66656d 100644 --- a/embassy-mcxa/src/gpio.rs +++ b/embassy-mcxa/src/gpio.rs | |||
| @@ -81,7 +81,7 @@ fn GPIO4() { | |||
| 81 | irq_handler(4, crate::pac::Gpio4::ptr()); | 81 | irq_handler(4, crate::pac::Gpio4::ptr()); |
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | pub(crate) unsafe fn init() { | 84 | pub(crate) unsafe fn interrupt_init() { |
| 85 | use embassy_hal_internal::interrupt::InterruptExt; | 85 | use embassy_hal_internal::interrupt::InterruptExt; |
| 86 | 86 | ||
| 87 | crate::pac::interrupt::GPIO0.enable(); | 87 | crate::pac::interrupt::GPIO0.enable(); |
| @@ -320,8 +320,12 @@ impl GpioPin for AnyPin {} | |||
| 320 | 320 | ||
| 321 | macro_rules! impl_pin { | 321 | macro_rules! impl_pin { |
| 322 | ($peri:ident, $port:expr, $pin:expr, $block:ident) => { | 322 | ($peri:ident, $port:expr, $pin:expr, $block:ident) => { |
| 323 | impl_pin!(crate::peripherals, $peri, $port, $pin, $block); | ||
| 324 | }; | ||
| 325 | |||
| 326 | ($perip:path, $peri:ident, $port:expr, $pin:expr, $block:ident) => { | ||
| 323 | paste! { | 327 | paste! { |
| 324 | impl SealedPin for crate::peripherals::$peri { | 328 | impl SealedPin for $perip::$peri { |
| 325 | fn pin_port(&self) -> usize { | 329 | fn pin_port(&self) -> usize { |
| 326 | $port * 32 + $pin | 330 | $port * 32 + $pin |
| 327 | } | 331 | } |
| @@ -372,15 +376,15 @@ macro_rules! impl_pin { | |||
| 372 | } | 376 | } |
| 373 | } | 377 | } |
| 374 | 378 | ||
| 375 | impl GpioPin for crate::peripherals::$peri {} | 379 | impl GpioPin for $perip::$peri {} |
| 376 | 380 | ||
| 377 | impl From<crate::peripherals::$peri> for AnyPin { | 381 | impl From<$perip::$peri> for AnyPin { |
| 378 | fn from(value: crate::peripherals::$peri) -> Self { | 382 | fn from(value: $perip::$peri) -> Self { |
| 379 | value.degrade() | 383 | value.degrade() |
| 380 | } | 384 | } |
| 381 | } | 385 | } |
| 382 | 386 | ||
| 383 | impl crate::peripherals::$peri { | 387 | impl $perip::$peri { |
| 384 | /// Convenience helper to obtain a type-erased handle to this pin. | 388 | /// Convenience helper to obtain a type-erased handle to this pin. |
| 385 | pub fn degrade(&self) -> AnyPin { | 389 | pub fn degrade(&self) -> AnyPin { |
| 386 | AnyPin::new(self.port(), self.pin(), self.gpio(), self.port_reg(), self.pcr_reg()) | 390 | AnyPin::new(self.port(), self.pin(), self.gpio(), self.port_reg(), self.pcr_reg()) |
| @@ -453,8 +457,8 @@ impl_pin!(P1_26, 1, 26, Gpio1); | |||
| 453 | impl_pin!(P1_27, 1, 27, Gpio1); | 457 | impl_pin!(P1_27, 1, 27, Gpio1); |
| 454 | impl_pin!(P1_28, 1, 28, Gpio1); | 458 | impl_pin!(P1_28, 1, 28, Gpio1); |
| 455 | impl_pin!(P1_29, 1, 29, Gpio1); | 459 | impl_pin!(P1_29, 1, 29, Gpio1); |
| 456 | impl_pin!(P1_30, 1, 30, Gpio1); | 460 | impl_pin!(crate::internal_peripherals, P1_30, 1, 30, Gpio1); |
| 457 | impl_pin!(P1_31, 1, 31, Gpio1); | 461 | impl_pin!(crate::internal_peripherals, P1_31, 1, 31, Gpio1); |
| 458 | 462 | ||
| 459 | impl_pin!(P2_0, 2, 0, Gpio2); | 463 | impl_pin!(P2_0, 2, 0, Gpio2); |
| 460 | impl_pin!(P2_1, 2, 1, Gpio2); | 464 | impl_pin!(P2_1, 2, 1, Gpio2); |
diff --git a/embassy-mcxa/src/i2c/mod.rs b/embassy-mcxa/src/i2c/mod.rs index 9a014224a..55c933f71 100644 --- a/embassy-mcxa/src/i2c/mod.rs +++ b/embassy-mcxa/src/i2c/mod.rs | |||
| @@ -180,8 +180,11 @@ impl_pin!(P1_12, LPI2C1, Mux2, SdaPin); | |||
| 180 | impl_pin!(P1_13, LPI2C1, Mux2, SclPin); | 180 | impl_pin!(P1_13, LPI2C1, Mux2, SclPin); |
| 181 | impl_pin!(P1_14, LPI2C1, Mux2, SclPin); | 181 | impl_pin!(P1_14, LPI2C1, Mux2, SclPin); |
| 182 | impl_pin!(P1_15, LPI2C1, Mux2, SdaPin); | 182 | impl_pin!(P1_15, LPI2C1, Mux2, SdaPin); |
| 183 | impl_pin!(P1_30, LPI2C0, Mux3, SdaPin); | 183 | // NOTE: P1_30 and P1_31 are typically used for the external oscillator |
| 184 | impl_pin!(P1_31, LPI2C0, Mux3, SclPin); | 184 | // For now, we just don't give users these pins. |
| 185 | // | ||
| 186 | // impl_pin!(P1_30, LPI2C0, Mux3, SdaPin); | ||
| 187 | // impl_pin!(P1_31, LPI2C0, Mux3, SclPin); | ||
| 185 | impl_pin!(P3_27, LPI2C3, Mux2, SclPin); | 188 | impl_pin!(P3_27, LPI2C3, Mux2, SclPin); |
| 186 | impl_pin!(P3_28, LPI2C3, Mux2, SdaPin); | 189 | impl_pin!(P3_28, LPI2C3, Mux2, SdaPin); |
| 187 | // impl_pin!(P3_29, LPI2C3, Mux2, HreqPin); What is this HREQ pin? | 190 | // impl_pin!(P3_29, LPI2C3, Mux2, HreqPin); What is this HREQ pin? |
diff --git a/embassy-mcxa/src/lib.rs b/embassy-mcxa/src/lib.rs index 6383353db..76fd58210 100644 --- a/embassy-mcxa/src/lib.rs +++ b/embassy-mcxa/src/lib.rs | |||
| @@ -175,8 +175,18 @@ embassy_hal_internal::peripherals!( | |||
| 175 | P1_27, | 175 | P1_27, |
| 176 | P1_28, | 176 | P1_28, |
| 177 | P1_29, | 177 | P1_29, |
| 178 | P1_30, | 178 | // TODO: These pins are optionally used as the clock sources for SOSC. |
| 179 | P1_31, | 179 | // Ideally, we'd want to have a custom version of the `peripheral!` macro |
| 180 | // that presented these as `Option<Peri<'_, P1_30>>` instead of `Peri<'_, P1_30>` | ||
| 181 | // when the user DOES enable the external SOSC. For now, I'm guessing MOST designs | ||
| 182 | // will have an external clock sitting on these pins anyway, so we just notch them | ||
| 183 | // out from the `Peripherals` struct given to users. | ||
| 184 | // | ||
| 185 | // If you find this and want your extra two pins to be available: please open an | ||
| 186 | // embassy issue to discuss how we could do this. | ||
| 187 | // | ||
| 188 | // P1_30, | ||
| 189 | // P1_31, | ||
| 180 | 190 | ||
| 181 | P2_0, | 191 | P2_0, |
| 182 | P2_1, | 192 | P2_1, |
| @@ -337,6 +347,14 @@ embassy_hal_internal::peripherals!( | |||
| 337 | WWDT0, | 347 | WWDT0, |
| 338 | ); | 348 | ); |
| 339 | 349 | ||
| 350 | // See commented out items above to understand why we create the instances | ||
| 351 | // here but don't give them to the user. | ||
| 352 | pub(crate) mod internal_peripherals { | ||
| 353 | embassy_hal_internal::peripherals_definition!(P1_30, P1_31,); | ||
| 354 | |||
| 355 | pub(crate) use peripherals::*; | ||
| 356 | } | ||
| 357 | |||
| 340 | // Use cortex-m-rt's #[interrupt] attribute directly; PAC does not re-export it. | 358 | // Use cortex-m-rt's #[interrupt] attribute directly; PAC does not re-export it. |
| 341 | 359 | ||
| 342 | // Re-export interrupt traits and types | 360 | // Re-export interrupt traits and types |
| @@ -369,7 +387,7 @@ pub fn init(cfg: crate::config::Config) -> Peripherals { | |||
| 369 | crate::clocks::init(cfg.clock_cfg).unwrap(); | 387 | crate::clocks::init(cfg.clock_cfg).unwrap(); |
| 370 | 388 | ||
| 371 | unsafe { | 389 | unsafe { |
| 372 | crate::gpio::init(); | 390 | crate::gpio::interrupt_init(); |
| 373 | } | 391 | } |
| 374 | 392 | ||
| 375 | // Initialize DMA controller (clock, reset, configuration) | 393 | // Initialize DMA controller (clock, reset, configuration) |
diff --git a/embassy-mcxa/src/lpuart/mod.rs b/embassy-mcxa/src/lpuart/mod.rs index bce3986b5..ae511e8d3 100644 --- a/embassy-mcxa/src/lpuart/mod.rs +++ b/embassy-mcxa/src/lpuart/mod.rs | |||
| @@ -568,6 +568,27 @@ pub enum Error { | |||
| 568 | ClockSetup(ClockError), | 568 | ClockSetup(ClockError), |
| 569 | } | 569 | } |
| 570 | 570 | ||
| 571 | impl core::fmt::Display for Error { | ||
| 572 | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { | ||
| 573 | match self { | ||
| 574 | Error::Read => write!(f, "Read error"), | ||
| 575 | Error::Overrun => write!(f, "Buffer overflow"), | ||
| 576 | Error::Noise => write!(f, "Noise error"), | ||
| 577 | Error::Framing => write!(f, "Framing error"), | ||
| 578 | Error::Parity => write!(f, "Parity error"), | ||
| 579 | Error::Fail => write!(f, "Failure"), | ||
| 580 | Error::InvalidArgument => write!(f, "Invalid argument"), | ||
| 581 | Error::UnsupportedBaudrate => write!(f, "Unsupported baud rate"), | ||
| 582 | Error::RxFifoEmpty => write!(f, "RX FIFO empty"), | ||
| 583 | Error::TxFifoFull => write!(f, "TX FIFO full"), | ||
| 584 | Error::TxBusy => write!(f, "TX busy"), | ||
| 585 | Error::ClockSetup(e) => write!(f, "Clock setup error: {:?}", e), | ||
| 586 | } | ||
| 587 | } | ||
| 588 | } | ||
| 589 | |||
| 590 | impl core::error::Error for Error {} | ||
| 591 | |||
| 571 | /// A specialized Result type for LPUART operations | 592 | /// A specialized Result type for LPUART operations |
| 572 | pub type Result<T> = core::result::Result<T, Error>; | 593 | pub type Result<T> = core::result::Result<T, Error>; |
| 573 | 594 | ||
diff --git a/embassy-mcxa/src/reset_reason.rs b/embassy-mcxa/src/reset_reason.rs index f9a9ce096..1787690a7 100644 --- a/embassy-mcxa/src/reset_reason.rs +++ b/embassy-mcxa/src/reset_reason.rs | |||
| @@ -6,45 +6,158 @@ | |||
| 6 | 6 | ||
| 7 | /// Reads the most recent reset reason from the Core Mode Controller | 7 | /// Reads the most recent reset reason from the Core Mode Controller |
| 8 | /// (CMC). | 8 | /// (CMC). |
| 9 | pub fn reset_reason() -> ResetReason { | 9 | pub fn reset_reason() -> ResetReasonRaw { |
| 10 | let regs = unsafe { &*crate::pac::Cmc::steal() }; | 10 | let regs = unsafe { &*crate::pac::Cmc::steal() }; |
| 11 | let srs = regs.srs().read().bits(); | ||
| 12 | ResetReasonRaw(srs) | ||
| 13 | } | ||
| 14 | |||
| 15 | /// Raw reset reason bits. Can be queried or all reasons can be iterated over | ||
| 16 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 17 | #[derive(Copy, Clone, Debug)] | ||
| 18 | pub struct ResetReasonRaw(u32); | ||
| 19 | |||
| 20 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 21 | #[derive(Copy, Clone, Debug)] | ||
| 22 | pub struct ResetReasonRawIter(u32); | ||
| 23 | |||
| 24 | impl ResetReasonRaw { | ||
| 25 | const MAP: &[(u32, ResetReason)] = &[ | ||
| 26 | (1 << 0, ResetReason::WakeUp), | ||
| 27 | (1 << 1, ResetReason::Por), | ||
| 28 | (1 << 2, ResetReason::VoltageDetect), | ||
| 29 | (1 << 4, ResetReason::Warm), | ||
| 30 | (1 << 5, ResetReason::Fatal), | ||
| 31 | (1 << 8, ResetReason::Pin), | ||
| 32 | (1 << 9, ResetReason::Dap), | ||
| 33 | (1 << 10, ResetReason::ResetAckTimeout), | ||
| 34 | (1 << 11, ResetReason::LowPowerAckTimeout), | ||
| 35 | (1 << 12, ResetReason::SystemClockGeneration), | ||
| 36 | (1 << 13, ResetReason::Wwdt0), | ||
| 37 | (1 << 14, ResetReason::Software), | ||
| 38 | (1 << 15, ResetReason::Lockup), | ||
| 39 | (1 << 26, ResetReason::Cdog0), | ||
| 40 | (1 << 27, ResetReason::Cdog1), | ||
| 41 | (1 << 28, ResetReason::Jtag), | ||
| 42 | ]; | ||
| 43 | |||
| 44 | /// Convert to an iterator of contained reset reasons | ||
| 45 | pub fn into_iter(self) -> ResetReasonRawIter { | ||
| 46 | ResetReasonRawIter(self.0) | ||
| 47 | } | ||
| 48 | |||
| 49 | /// Wake up | ||
| 50 | #[inline] | ||
| 51 | pub fn is_wakeup(&self) -> bool { | ||
| 52 | (self.0 & (1 << 0)) != 0 | ||
| 53 | } | ||
| 54 | |||
| 55 | /// Power-on Reset | ||
| 56 | #[inline] | ||
| 57 | pub fn is_por(&self) -> bool { | ||
| 58 | (self.0 & (1 << 1)) != 0 | ||
| 59 | } | ||
| 60 | |||
| 61 | /// Voltage detect | ||
| 62 | #[inline] | ||
| 63 | pub fn is_voltage_detect(&self) -> bool { | ||
| 64 | (self.0 & (1 << 2)) != 0 | ||
| 65 | } | ||
| 66 | |||
| 67 | /// Warm | ||
| 68 | #[inline] | ||
| 69 | pub fn is_warm(&self) -> bool { | ||
| 70 | (self.0 & (1 << 4)) != 0 | ||
| 71 | } | ||
| 72 | |||
| 73 | /// Fatal | ||
| 74 | #[inline] | ||
| 75 | pub fn is_fatal(&self) -> bool { | ||
| 76 | (self.0 & (1 << 5)) != 0 | ||
| 77 | } | ||
| 78 | |||
| 79 | /// Pin | ||
| 80 | #[inline] | ||
| 81 | pub fn is_pin(&self) -> bool { | ||
| 82 | (self.0 & (1 << 8)) != 0 | ||
| 83 | } | ||
| 84 | |||
| 85 | /// DAP | ||
| 86 | #[inline] | ||
| 87 | pub fn is_dap(&self) -> bool { | ||
| 88 | (self.0 & (1 << 9)) != 0 | ||
| 89 | } | ||
| 90 | |||
| 91 | /// Reset ack timeout | ||
| 92 | #[inline] | ||
| 93 | pub fn is_reset_ack_timeout(&self) -> bool { | ||
| 94 | (self.0 & (1 << 10)) != 0 | ||
| 95 | } | ||
| 96 | |||
| 97 | /// Low power ack timeout | ||
| 98 | #[inline] | ||
| 99 | pub fn is_low_power_ack_timeout(&self) -> bool { | ||
| 100 | (self.0 & (1 << 11)) != 0 | ||
| 101 | } | ||
| 102 | |||
| 103 | /// System clock generation | ||
| 104 | #[inline] | ||
| 105 | pub fn is_system_clock_generation(&self) -> bool { | ||
| 106 | (self.0 & (1 << 12)) != 0 | ||
| 107 | } | ||
| 108 | |||
| 109 | /// Watchdog 0 | ||
| 110 | #[inline] | ||
| 111 | pub fn is_watchdog0(&self) -> bool { | ||
| 112 | (self.0 & (1 << 13)) != 0 | ||
| 113 | } | ||
| 114 | |||
| 115 | /// Software | ||
| 116 | pub fn is_software(&self) -> bool { | ||
| 117 | (self.0 & (1 << 14)) != 0 | ||
| 118 | } | ||
| 119 | |||
| 120 | /// Lockup | ||
| 121 | pub fn is_lockup(&self) -> bool { | ||
| 122 | (self.0 & (1 << 15)) != 0 | ||
| 123 | } | ||
| 124 | |||
| 125 | /// Code watchdog 0 | ||
| 126 | pub fn is_code_watchdog0(&self) -> bool { | ||
| 127 | (self.0 & (1 << 26)) != 0 | ||
| 128 | } | ||
| 129 | |||
| 130 | /// Code watchdog 1 | ||
| 131 | pub fn is_code_watchdog1(&self) -> bool { | ||
| 132 | (self.0 & (1 << 27)) != 0 | ||
| 133 | } | ||
| 134 | |||
| 135 | /// JTAG | ||
| 136 | pub fn is_jtag(&self) -> bool { | ||
| 137 | (self.0 & (1 << 28)) != 0 | ||
| 138 | } | ||
| 139 | } | ||
| 11 | 140 | ||
| 12 | let srs = regs.srs().read(); | 141 | impl Iterator for ResetReasonRawIter { |
| 13 | 142 | type Item = ResetReason; | |
| 14 | if srs.wakeup().is_enabled() { | 143 | |
| 15 | ResetReason::WakeUp | 144 | fn next(&mut self) -> Option<Self::Item> { |
| 16 | } else if srs.por().bit_is_set() { | 145 | if self.0 == 0 { |
| 17 | ResetReason::Por | 146 | return None; |
| 18 | } else if srs.vd().bit_is_set() { | 147 | } |
| 19 | ResetReason::VoltageDetect | 148 | |
| 20 | } else if srs.warm().bit_is_set() { | 149 | for (mask, var) in ResetReasonRaw::MAP { |
| 21 | ResetReason::Warm | 150 | // If the bit is set... |
| 22 | } else if srs.fatal().bit_is_set() { | 151 | if self.0 & mask != 0 { |
| 23 | ResetReason::Fatal | 152 | // clear the bit |
| 24 | } else if srs.pin().bit_is_set() { | 153 | self.0 &= !mask; |
| 25 | ResetReason::Pin | 154 | // and return the answer |
| 26 | } else if srs.dap().bit_is_set() { | 155 | return Some(*var); |
| 27 | ResetReason::Dap | 156 | } |
| 28 | } else if srs.rstack().bit_is_set() { | 157 | } |
| 29 | ResetReason::ResetAckTimeout | 158 | |
| 30 | } else if srs.lpack().bit_is_set() { | 159 | // Shouldn't happen, but oh well. |
| 31 | ResetReason::LowPowerAckTimeout | 160 | None |
| 32 | } else if srs.scg().bit_is_set() { | ||
| 33 | ResetReason::SystemClockGeneration | ||
| 34 | } else if srs.wwdt0().bit_is_set() { | ||
| 35 | ResetReason::Wwdt0 | ||
| 36 | } else if srs.sw().bit_is_set() { | ||
| 37 | ResetReason::Software | ||
| 38 | } else if srs.lockup().bit_is_set() { | ||
| 39 | ResetReason::Lockup | ||
| 40 | } else if srs.cdog0().bit_is_set() { | ||
| 41 | ResetReason::Cdog0 | ||
| 42 | } else if srs.cdog1().bit_is_set() { | ||
| 43 | ResetReason::Cdog1 | ||
| 44 | } else if srs.jtag().bit_is_set() { | ||
| 45 | ResetReason::Jtag | ||
| 46 | } else { | ||
| 47 | ResetReason::Tamper | ||
| 48 | } | 161 | } |
| 49 | } | 162 | } |
| 50 | 163 | ||
diff --git a/embassy-mspm0/Cargo.toml b/embassy-mspm0/Cargo.toml index cf2346328..c7f5de6a1 100644 --- a/embassy-mspm0/Cargo.toml +++ b/embassy-mspm0/Cargo.toml | |||
| @@ -61,8 +61,8 @@ embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["un | |||
| 61 | embedded-hal = { version = "1.0" } | 61 | embedded-hal = { version = "1.0" } |
| 62 | embedded-hal-nb = { version = "1.0" } | 62 | embedded-hal-nb = { version = "1.0" } |
| 63 | embedded-hal-async = { version = "1.0" } | 63 | embedded-hal-async = { version = "1.0" } |
| 64 | embedded-io = "0.6.1" | 64 | embedded-io = { version = "0.7.1" } |
| 65 | embedded-io-async = "0.6.1" | 65 | embedded-io-async = { version = "0.7.0" } |
| 66 | 66 | ||
| 67 | defmt = { version = "1.0.1", optional = true } | 67 | defmt = { version = "1.0.1", optional = true } |
| 68 | fixed = "1.29" | 68 | fixed = "1.29" |
diff --git a/embassy-mspm0/src/uart/buffered.rs b/embassy-mspm0/src/uart/buffered.rs index 89e6bcc7b..d1b75b177 100644 --- a/embassy-mspm0/src/uart/buffered.rs +++ b/embassy-mspm0/src/uart/buffered.rs | |||
| @@ -436,6 +436,10 @@ impl embedded_io_async::Write for BufferedUart<'_> { | |||
| 436 | async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { | 436 | async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { |
| 437 | self.tx.write_inner(buf).await | 437 | self.tx.write_inner(buf).await |
| 438 | } | 438 | } |
| 439 | |||
| 440 | async fn flush(&mut self) -> Result<(), Self::Error> { | ||
| 441 | self.tx.flush_inner().await | ||
| 442 | } | ||
| 439 | } | 443 | } |
| 440 | 444 | ||
| 441 | impl embedded_io_async::Write for BufferedUartTx<'_> { | 445 | impl embedded_io_async::Write for BufferedUartTx<'_> { |
diff --git a/embassy-net-nrf91/Cargo.toml b/embassy-net-nrf91/Cargo.toml index 349ff2880..c5c582fc3 100644 --- a/embassy-net-nrf91/Cargo.toml +++ b/embassy-net-nrf91/Cargo.toml | |||
| @@ -27,7 +27,7 @@ embassy-futures = { version = "0.1.2", path = "../embassy-futures" } | |||
| 27 | embassy-net-driver-channel = { version = "0.3.2", path = "../embassy-net-driver-channel" } | 27 | embassy-net-driver-channel = { version = "0.3.2", path = "../embassy-net-driver-channel" } |
| 28 | 28 | ||
| 29 | heapless = "0.8" | 29 | heapless = "0.8" |
| 30 | embedded-io = "0.6.1" | 30 | embedded-io = { version = "0.7.1" } |
| 31 | at-commands = "0.5.4" | 31 | at-commands = "0.5.4" |
| 32 | 32 | ||
| 33 | [package.metadata.embassy] | 33 | [package.metadata.embassy] |
diff --git a/embassy-net-ppp/Cargo.toml b/embassy-net-ppp/Cargo.toml index 45ee2f6b5..1dda5017f 100644 --- a/embassy-net-ppp/Cargo.toml +++ b/embassy-net-ppp/Cargo.toml | |||
| @@ -17,7 +17,7 @@ log = ["dep:log", "ppproto/log"] | |||
| 17 | defmt = { version = "1.0.1", optional = true } | 17 | defmt = { version = "1.0.1", optional = true } |
| 18 | log = { version = "0.4.14", optional = true } | 18 | log = { version = "0.4.14", optional = true } |
| 19 | 19 | ||
| 20 | embedded-io-async = { version = "0.6.1" } | 20 | embedded-io-async = { version = "0.7.0" } |
| 21 | embassy-net-driver-channel = { version = "0.3.2", path = "../embassy-net-driver-channel" } | 21 | embassy-net-driver-channel = { version = "0.3.2", path = "../embassy-net-driver-channel" } |
| 22 | embassy-futures = { version = "0.1.2", path = "../embassy-futures" } | 22 | embassy-futures = { version = "0.1.2", path = "../embassy-futures" } |
| 23 | ppproto = { version = "0.2.1"} | 23 | ppproto = { version = "0.2.1"} |
diff --git a/embassy-net/Cargo.toml b/embassy-net/Cargo.toml index 4c8075c43..d66ba1133 100644 --- a/embassy-net/Cargo.toml +++ b/embassy-net/Cargo.toml | |||
| @@ -109,9 +109,9 @@ smoltcp = { version = "0.12.0", default-features = false, features = [ | |||
| 109 | embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver" } | 109 | embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver" } |
| 110 | embassy-time = { version = "0.5.0", path = "../embassy-time" } | 110 | embassy-time = { version = "0.5.0", path = "../embassy-time" } |
| 111 | embassy-sync = { version = "0.7.2", path = "../embassy-sync" } | 111 | embassy-sync = { version = "0.7.2", path = "../embassy-sync" } |
| 112 | embedded-io-async = { version = "0.6.1" } | 112 | embedded-io-async = { version = "0.7.0" } |
| 113 | 113 | ||
| 114 | managed = { version = "0.8.0", default-features = false, features = [ "map" ] } | 114 | managed = { version = "0.8.0", default-features = false, features = [ "map" ] } |
| 115 | heapless = { version = "0.8", default-features = false } | 115 | heapless = { version = "0.8", default-features = false } |
| 116 | embedded-nal-async = "0.8.0" | 116 | embedded-nal-async = "0.9.0" |
| 117 | document-features = "0.2.7" | 117 | document-features = "0.2.7" |
diff --git a/embassy-net/src/tcp.rs b/embassy-net/src/tcp.rs index b4db7b88c..74672df1c 100644 --- a/embassy-net/src/tcp.rs +++ b/embassy-net/src/tcp.rs | |||
| @@ -670,6 +670,13 @@ impl<'d> TcpIo<'d> { | |||
| 670 | mod embedded_io_impls { | 670 | mod embedded_io_impls { |
| 671 | use super::*; | 671 | use super::*; |
| 672 | 672 | ||
| 673 | impl core::fmt::Display for ConnectError { | ||
| 674 | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { | ||
| 675 | f.write_str("ConnectError") | ||
| 676 | } | ||
| 677 | } | ||
| 678 | impl core::error::Error for ConnectError {} | ||
| 679 | |||
| 673 | impl embedded_io_async::Error for ConnectError { | 680 | impl embedded_io_async::Error for ConnectError { |
| 674 | fn kind(&self) -> embedded_io_async::ErrorKind { | 681 | fn kind(&self) -> embedded_io_async::ErrorKind { |
| 675 | match self { | 682 | match self { |
| @@ -681,6 +688,15 @@ mod embedded_io_impls { | |||
| 681 | } | 688 | } |
| 682 | } | 689 | } |
| 683 | 690 | ||
| 691 | impl core::fmt::Display for Error { | ||
| 692 | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { | ||
| 693 | match self { | ||
| 694 | Self::ConnectionReset => f.write_str("ConnectionReset"), | ||
| 695 | } | ||
| 696 | } | ||
| 697 | } | ||
| 698 | impl core::error::Error for Error {} | ||
| 699 | |||
| 684 | impl embedded_io_async::Error for Error { | 700 | impl embedded_io_async::Error for Error { |
| 685 | fn kind(&self) -> embedded_io_async::ErrorKind { | 701 | fn kind(&self) -> embedded_io_async::ErrorKind { |
| 686 | match self { | 702 | match self { |
diff --git a/embassy-nrf/CHANGELOG.md b/embassy-nrf/CHANGELOG.md index 0d7bfb5f0..921835417 100644 --- a/embassy-nrf/CHANGELOG.md +++ b/embassy-nrf/CHANGELOG.md | |||
| @@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |||
| 8 | <!-- next-header --> | 8 | <!-- next-header --> |
| 9 | ## Unreleased - ReleaseDate | 9 | ## Unreleased - ReleaseDate |
| 10 | 10 | ||
| 11 | - bugfix: avoid hang if calling now() before syscounter is enabled on nrf54 | ||
| 12 | |||
| 11 | ## 0.9.0 - 2025-12-15 | 13 | ## 0.9.0 - 2025-12-15 |
| 12 | 14 | ||
| 13 | - changed: apply trimming values from FICR.TRIMCNF on nrf53/54l | 15 | - changed: apply trimming values from FICR.TRIMCNF on nrf53/54l |
diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml index f8a6ef864..a8070aa45 100644 --- a/embassy-nrf/Cargo.toml +++ b/embassy-nrf/Cargo.toml | |||
| @@ -217,8 +217,8 @@ embassy-futures = { version = "0.1.2", path = "../embassy-futures", optional = t | |||
| 217 | embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] } | 217 | embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] } |
| 218 | embedded-hal-1 = { package = "embedded-hal", version = "1.0" } | 218 | embedded-hal-1 = { package = "embedded-hal", version = "1.0" } |
| 219 | embedded-hal-async = { version = "1.0" } | 219 | embedded-hal-async = { version = "1.0" } |
| 220 | embedded-io = { version = "0.6.0" } | 220 | embedded-io = { version = "0.7.1" } |
| 221 | embedded-io-async = { version = "0.6.1" } | 221 | embedded-io-async = { version = "0.7.0" } |
| 222 | 222 | ||
| 223 | rand-core-06 = { package = "rand_core", version = "0.6" } | 223 | rand-core-06 = { package = "rand_core", version = "0.6" } |
| 224 | rand-core-09 = { package = "rand_core", version = "0.9" } | 224 | rand-core-09 = { package = "rand_core", version = "0.9" } |
diff --git a/embassy-nrf/src/buffered_uarte/v1.rs b/embassy-nrf/src/buffered_uarte/v1.rs index ec360f7d0..c14cdfadb 100644 --- a/embassy-nrf/src/buffered_uarte/v1.rs +++ b/embassy-nrf/src/buffered_uarte/v1.rs | |||
| @@ -874,6 +874,15 @@ impl<'a> Drop for BufferedUarteRx<'a> { | |||
| 874 | } | 874 | } |
| 875 | } | 875 | } |
| 876 | 876 | ||
| 877 | impl core::fmt::Display for Error { | ||
| 878 | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { | ||
| 879 | match *self { | ||
| 880 | Error::Overrun => write!(f, "Buffer Overrun"), | ||
| 881 | } | ||
| 882 | } | ||
| 883 | } | ||
| 884 | impl core::error::Error for Error {} | ||
| 885 | |||
| 877 | mod _embedded_io { | 886 | mod _embedded_io { |
| 878 | use super::*; | 887 | use super::*; |
| 879 | 888 | ||
diff --git a/embassy-nrf/src/buffered_uarte/v2.rs b/embassy-nrf/src/buffered_uarte/v2.rs index d0d2d97d1..4a6360b69 100644 --- a/embassy-nrf/src/buffered_uarte/v2.rs +++ b/embassy-nrf/src/buffered_uarte/v2.rs | |||
| @@ -50,6 +50,14 @@ pub enum Error { | |||
| 50 | // No errors for now | 50 | // No errors for now |
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | impl core::fmt::Display for Error { | ||
| 54 | fn fmt(&self, _f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { | ||
| 55 | match *self {} | ||
| 56 | } | ||
| 57 | } | ||
| 58 | |||
| 59 | impl core::error::Error for Error {} | ||
| 60 | |||
| 53 | impl State { | 61 | impl State { |
| 54 | pub(crate) const fn new() -> Self { | 62 | pub(crate) const fn new() -> Self { |
| 55 | Self { | 63 | Self { |
diff --git a/embassy-nrf/src/time_driver.rs b/embassy-nrf/src/time_driver.rs index 35f65bd64..21d94cc30 100644 --- a/embassy-nrf/src/time_driver.rs +++ b/embassy-nrf/src/time_driver.rs | |||
| @@ -79,6 +79,10 @@ fn calc_now(period: u32, counter: u32) -> u64 { | |||
| 79 | #[cfg(feature = "_grtc")] | 79 | #[cfg(feature = "_grtc")] |
| 80 | fn syscounter() -> u64 { | 80 | fn syscounter() -> u64 { |
| 81 | let r = rtc(); | 81 | let r = rtc(); |
| 82 | if !r.mode().read().syscounteren() { | ||
| 83 | return 0; | ||
| 84 | } | ||
| 85 | |||
| 82 | r.syscounter(0).active().write(|w| w.set_active(true)); | 86 | r.syscounter(0).active().write(|w| w.set_active(true)); |
| 83 | loop { | 87 | loop { |
| 84 | let countl: u32 = r.syscounter(0).syscounterl().read(); | 88 | let countl: u32 = r.syscounter(0).syscounterl().read(); |
diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs index 049830aed..ef5d6c6d1 100644 --- a/embassy-nrf/src/uarte.rs +++ b/embassy-nrf/src/uarte.rs | |||
| @@ -1092,6 +1092,20 @@ mod eh02 { | |||
| 1092 | } | 1092 | } |
| 1093 | } | 1093 | } |
| 1094 | 1094 | ||
| 1095 | impl core::fmt::Display for Error { | ||
| 1096 | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { | ||
| 1097 | match *self { | ||
| 1098 | Self::BufferTooLong => f.write_str("BufferTooLong"), | ||
| 1099 | Self::BufferNotInRAM => f.write_str("BufferNotInRAM"), | ||
| 1100 | Self::Framing => f.write_str("Framing"), | ||
| 1101 | Self::Parity => f.write_str("Parity"), | ||
| 1102 | Self::Overrun => f.write_str("Overrun"), | ||
| 1103 | Self::Break => f.write_str("Break"), | ||
| 1104 | } | ||
| 1105 | } | ||
| 1106 | } | ||
| 1107 | impl core::error::Error for Error {} | ||
| 1108 | |||
| 1095 | mod _embedded_io { | 1109 | mod _embedded_io { |
| 1096 | use super::*; | 1110 | use super::*; |
| 1097 | 1111 | ||
| @@ -1121,6 +1135,9 @@ mod _embedded_io { | |||
| 1121 | self.write(buf).await?; | 1135 | self.write(buf).await?; |
| 1122 | Ok(buf.len()) | 1136 | Ok(buf.len()) |
| 1123 | } | 1137 | } |
| 1138 | async fn flush(&mut self) -> Result<(), Self::Error> { | ||
| 1139 | Ok(()) | ||
| 1140 | } | ||
| 1124 | } | 1141 | } |
| 1125 | 1142 | ||
| 1126 | impl<'d> embedded_io_async::Write for UarteTx<'d> { | 1143 | impl<'d> embedded_io_async::Write for UarteTx<'d> { |
| @@ -1128,5 +1145,8 @@ mod _embedded_io { | |||
| 1128 | self.write(buf).await?; | 1145 | self.write(buf).await?; |
| 1129 | Ok(buf.len()) | 1146 | Ok(buf.len()) |
| 1130 | } | 1147 | } |
| 1148 | async fn flush(&mut self) -> Result<(), Self::Error> { | ||
| 1149 | Ok(()) | ||
| 1150 | } | ||
| 1131 | } | 1151 | } |
| 1132 | } | 1152 | } |
diff --git a/embassy-nxp/Cargo.toml b/embassy-nxp/Cargo.toml index b78c26c77..d5ef38531 100644 --- a/embassy-nxp/Cargo.toml +++ b/embassy-nxp/Cargo.toml | |||
| @@ -35,7 +35,7 @@ log = { version = "0.4.27", optional = true } | |||
| 35 | embassy-time = { version = "0.5.0", path = "../embassy-time", optional = true } | 35 | embassy-time = { version = "0.5.0", path = "../embassy-time", optional = true } |
| 36 | embassy-time-driver = { version = "0.2.1", path = "../embassy-time-driver", optional = true } | 36 | embassy-time-driver = { version = "0.2.1", path = "../embassy-time-driver", optional = true } |
| 37 | embassy-time-queue-utils = { version = "0.3.0", path = "../embassy-time-queue-utils", optional = true } | 37 | embassy-time-queue-utils = { version = "0.3.0", path = "../embassy-time-queue-utils", optional = true } |
| 38 | embedded-io = "0.6.1" | 38 | embedded-io = { version = "0.7.1" } |
| 39 | embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] } | 39 | embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] } |
| 40 | ## Chip dependencies | 40 | ## Chip dependencies |
| 41 | nxp-pac = { version = "0.1.0", optional = true, git = "https://github.com/i509VCB/nxp-pac", rev = "af5122e1cbe1483833c5d2e5af96b26a34ed5d62"} | 41 | nxp-pac = { version = "0.1.0", optional = true, git = "https://github.com/i509VCB/nxp-pac", rev = "af5122e1cbe1483833c5d2e5af96b26a34ed5d62"} |
diff --git a/embassy-nxp/src/usart/lpc55.rs b/embassy-nxp/src/usart/lpc55.rs index d77f08fd8..319e29054 100644 --- a/embassy-nxp/src/usart/lpc55.rs +++ b/embassy-nxp/src/usart/lpc55.rs | |||
| @@ -51,6 +51,15 @@ impl embedded_io::Error for Error { | |||
| 51 | } | 51 | } |
| 52 | } | 52 | } |
| 53 | } | 53 | } |
| 54 | |||
| 55 | impl core::fmt::Display for Error { | ||
| 56 | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { | ||
| 57 | core::fmt::Debug::fmt(self, f) | ||
| 58 | } | ||
| 59 | } | ||
| 60 | |||
| 61 | impl core::error::Error for Error {} | ||
| 62 | |||
| 54 | /// Word length. | 63 | /// Word length. |
| 55 | #[derive(Clone, Copy, PartialEq, Eq, Debug)] | 64 | #[derive(Clone, Copy, PartialEq, Eq, Debug)] |
| 56 | pub enum DataBits { | 65 | pub enum DataBits { |
diff --git a/embassy-rp/Cargo.toml b/embassy-rp/Cargo.toml index 8e4bb927f..585acc064 100644 --- a/embassy-rp/Cargo.toml +++ b/embassy-rp/Cargo.toml | |||
| @@ -167,8 +167,8 @@ cortex-m-rt = ">=0.6.15,<0.8" | |||
| 167 | cortex-m = "0.7.6" | 167 | cortex-m = "0.7.6" |
| 168 | critical-section = "1.2.0" | 168 | critical-section = "1.2.0" |
| 169 | chrono = { version = "0.4", default-features = false, optional = true } | 169 | chrono = { version = "0.4", default-features = false, optional = true } |
| 170 | embedded-io = { version = "0.6.1" } | 170 | embedded-io = { version = "0.7.1" } |
| 171 | embedded-io-async = { version = "0.6.1" } | 171 | embedded-io-async = { version = "0.7.0" } |
| 172 | embedded-storage = { version = "0.3" } | 172 | embedded-storage = { version = "0.3" } |
| 173 | embedded-storage-async = { version = "0.4.1" } | 173 | embedded-storage-async = { version = "0.4.1" } |
| 174 | fixed = "1.28.0" | 174 | fixed = "1.28.0" |
diff --git a/embassy-rp/src/pio_programs/uart.rs b/embassy-rp/src/pio_programs/uart.rs index d59596dd1..a16d89a75 100644 --- a/embassy-rp/src/pio_programs/uart.rs +++ b/embassy-rp/src/pio_programs/uart.rs | |||
| @@ -90,6 +90,10 @@ impl<PIO: Instance, const SM: usize> Write for PioUartTx<'_, PIO, SM> { | |||
| 90 | } | 90 | } |
| 91 | Ok(buf.len()) | 91 | Ok(buf.len()) |
| 92 | } | 92 | } |
| 93 | |||
| 94 | async fn flush(&mut self) -> Result<(), Infallible> { | ||
| 95 | Ok(()) | ||
| 96 | } | ||
| 93 | } | 97 | } |
| 94 | 98 | ||
| 95 | /// This struct represents a Uart Rx program loaded into pio instruction memory. | 99 | /// This struct represents a Uart Rx program loaded into pio instruction memory. |
diff --git a/embassy-rp/src/uart/mod.rs b/embassy-rp/src/uart/mod.rs index b7b569dd5..f53b2f88e 100644 --- a/embassy-rp/src/uart/mod.rs +++ b/embassy-rp/src/uart/mod.rs | |||
| @@ -118,6 +118,14 @@ pub enum Error { | |||
| 118 | Framing, | 118 | Framing, |
| 119 | } | 119 | } |
| 120 | 120 | ||
| 121 | impl core::fmt::Display for Error { | ||
| 122 | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { | ||
| 123 | core::fmt::Debug::fmt(self, f) | ||
| 124 | } | ||
| 125 | } | ||
| 126 | |||
| 127 | impl core::error::Error for Error {} | ||
| 128 | |||
| 121 | /// Read To Break error | 129 | /// Read To Break error |
| 122 | #[derive(Debug, Eq, PartialEq, Copy, Clone)] | 130 | #[derive(Debug, Eq, PartialEq, Copy, Clone)] |
| 123 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 131 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
diff --git a/embassy-stm32-wpan/src/wb55/mod.rs b/embassy-stm32-wpan/src/wb55/mod.rs index 95cfe09f1..814303a05 100644 --- a/embassy-stm32-wpan/src/wb55/mod.rs +++ b/embassy-stm32-wpan/src/wb55/mod.rs | |||
| @@ -176,7 +176,7 @@ impl<'d> TlMbox<'d> { | |||
| 176 | let mm = sub::mm::MemoryManager::new(ipcc_mm_release_buffer_channel); | 176 | let mm = sub::mm::MemoryManager::new(ipcc_mm_release_buffer_channel); |
| 177 | let mut sys = sub::sys::Sys::new(ipcc_system_cmd_rsp_channel, ipcc_system_event_channel); | 177 | let mut sys = sub::sys::Sys::new(ipcc_system_cmd_rsp_channel, ipcc_system_event_channel); |
| 178 | 178 | ||
| 179 | debug!("sys event: {}", sys.read().await.payload()); | 179 | debug!("sys event: {}", sys.read_ready().await); |
| 180 | 180 | ||
| 181 | Self { | 181 | Self { |
| 182 | sys_subsystem: sys, | 182 | sys_subsystem: sys, |
diff --git a/embassy-stm32-wpan/src/wb55/shci.rs b/embassy-stm32-wpan/src/wb55/shci.rs index 3faa79209..3eb9525d3 100644 --- a/embassy-stm32-wpan/src/wb55/shci.rs +++ b/embassy-stm32-wpan/src/wb55/shci.rs | |||
| @@ -12,6 +12,28 @@ const fn opcode(ogf: u16, ocf: u16) -> isize { | |||
| 12 | ((ogf << 10) + ocf) as isize | 12 | ((ogf << 10) + ocf) as isize |
| 13 | } | 13 | } |
| 14 | 14 | ||
| 15 | pub(crate) trait SealedSchiFromPacket: Sized { | ||
| 16 | unsafe fn from_packet(cmd_buf: *const CmdPacket) -> Result<Self, ()>; | ||
| 17 | } | ||
| 18 | |||
| 19 | #[allow(private_bounds)] | ||
| 20 | pub trait SchiFromPacket: SealedSchiFromPacket {} | ||
| 21 | impl<T: SealedSchiFromPacket> SchiFromPacket for T {} | ||
| 22 | |||
| 23 | trait ShciFromEventSerial: TryFrom<u8, Error = ()> {} | ||
| 24 | |||
| 25 | impl<T: ShciFromEventSerial> SealedSchiFromPacket for T { | ||
| 26 | unsafe fn from_packet(cmd_buf: *const CmdPacket) -> Result<Self, ()> { | ||
| 27 | let p_cmd_serial = (cmd_buf as *mut u8).add(size_of::<PacketHeader>()); | ||
| 28 | let p_evt_payload = p_cmd_serial.add(size_of::<EvtStub>()); | ||
| 29 | |||
| 30 | compiler_fence(Ordering::Acquire); | ||
| 31 | let cc_evt = ptr::read_unaligned(p_evt_payload as *const CcEvt); | ||
| 32 | |||
| 33 | cc_evt.payload[0].try_into() | ||
| 34 | } | ||
| 35 | } | ||
| 36 | |||
| 15 | #[allow(dead_code)] | 37 | #[allow(dead_code)] |
| 16 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 38 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 17 | pub enum SchiCommandStatus { | 39 | pub enum SchiCommandStatus { |
| @@ -25,37 +47,20 @@ pub enum SchiCommandStatus { | |||
| 25 | ShciFusCmdNotSupported = 0xFF, | 47 | ShciFusCmdNotSupported = 0xFF, |
| 26 | } | 48 | } |
| 27 | 49 | ||
| 28 | impl SchiCommandStatus { | 50 | impl ShciFromEventSerial for SchiCommandStatus {} |
| 29 | pub unsafe fn from_packet(cmd_buf: *const CmdPacket) -> Result<Self, ()> { | ||
| 30 | let p_cmd_serial = (cmd_buf as *mut u8).add(size_of::<PacketHeader>()); | ||
| 31 | let p_evt_payload = p_cmd_serial.add(size_of::<EvtStub>()); | ||
| 32 | |||
| 33 | compiler_fence(Ordering::Acquire); | ||
| 34 | let cc_evt = ptr::read_unaligned(p_evt_payload as *const CcEvt); | ||
| 35 | |||
| 36 | cc_evt.payload[0].try_into() | ||
| 37 | } | ||
| 38 | } | ||
| 39 | |||
| 40 | impl TryFrom<u8> for SchiCommandStatus { | 51 | impl TryFrom<u8> for SchiCommandStatus { |
| 41 | type Error = (); | 52 | type Error = (); |
| 42 | 53 | ||
| 43 | fn try_from(v: u8) -> Result<Self, Self::Error> { | 54 | fn try_from(v: u8) -> Result<Self, Self::Error> { |
| 44 | match v { | 55 | match v { |
| 45 | x if x == SchiCommandStatus::ShciSuccess as u8 => Ok(SchiCommandStatus::ShciSuccess), | 56 | 0x00 => Ok(Self::ShciSuccess), |
| 46 | x if x == SchiCommandStatus::ShciUnknownCmd as u8 => Ok(SchiCommandStatus::ShciUnknownCmd), | 57 | 0x01 => Ok(Self::ShciUnknownCmd), |
| 47 | x if x == SchiCommandStatus::ShciMemoryCapacityExceededErrCode as u8 => { | 58 | 0x07 => Ok(Self::ShciMemoryCapacityExceededErrCode), |
| 48 | Ok(SchiCommandStatus::ShciMemoryCapacityExceededErrCode) | 59 | 0x11 => Ok(Self::ShciErrUnsupportedFeature), |
| 49 | } | 60 | 0x12 => Ok(Self::ShciErrInvalidHciCmdParams), |
| 50 | x if x == SchiCommandStatus::ShciErrUnsupportedFeature as u8 => { | 61 | 0x42 => Ok(Self::ShciErrInvalidParams), /* only used for release < v1.13.0 */ |
| 51 | Ok(SchiCommandStatus::ShciErrUnsupportedFeature) | 62 | 0x92 => Ok(Self::ShciErrInvalidParamsV2), /* available for release >= v1.13.0 */ |
| 52 | } | 63 | 0xFF => Ok(Self::ShciFusCmdNotSupported), |
| 53 | x if x == SchiCommandStatus::ShciErrInvalidHciCmdParams as u8 => { | ||
| 54 | Ok(SchiCommandStatus::ShciErrInvalidHciCmdParams) | ||
| 55 | } | ||
| 56 | x if x == SchiCommandStatus::ShciErrInvalidParams as u8 => Ok(SchiCommandStatus::ShciErrInvalidParams), /* only used for release < v1.13.0 */ | ||
| 57 | x if x == SchiCommandStatus::ShciErrInvalidParamsV2 as u8 => Ok(SchiCommandStatus::ShciErrInvalidParamsV2), /* available for release >= v1.13.0 */ | ||
| 58 | x if x == SchiCommandStatus::ShciFusCmdNotSupported as u8 => Ok(SchiCommandStatus::ShciFusCmdNotSupported), | ||
| 59 | _ => Err(()), | 64 | _ => Err(()), |
| 60 | } | 65 | } |
| 61 | } | 66 | } |
| @@ -107,6 +112,71 @@ pub enum ShciOpcode { | |||
| 107 | Mac802_15_4DeInit = opcode(SHCI_OGF, 0x78), | 112 | Mac802_15_4DeInit = opcode(SHCI_OGF, 0x78), |
| 108 | } | 113 | } |
| 109 | 114 | ||
| 115 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 116 | pub enum ShciFusGetStateErrorCode { | ||
| 117 | FusStateErrorNoError = 0x00, | ||
| 118 | FusStateErrorImgNotFound = 0x01, | ||
| 119 | FusStateErrorImgCorrupt = 0x02, | ||
| 120 | FusStateErrorImgNotAuthentic = 0x03, | ||
| 121 | FusStateErrorImgNotEnoughSpace = 0x04, | ||
| 122 | FusStateErrorImageUsrAbort = 0x05, | ||
| 123 | FusStateErrorImageErsError = 0x06, | ||
| 124 | FusStateErrorImageWrtError = 0x07, | ||
| 125 | FusStateErrorAuthTagStNotFound = 0x08, | ||
| 126 | FusStateErrorAuthTagCustNotFound = 0x09, | ||
| 127 | FusStateErrorAuthKeyLocked = 0x0A, | ||
| 128 | FusStateErrorFwRollbackError = 0x11, | ||
| 129 | FusStateErrorStateNotRunning = 0xFE, | ||
| 130 | FusStateErrorErrUnknown = 0xFF, | ||
| 131 | } | ||
| 132 | |||
| 133 | impl ShciFromEventSerial for ShciFusGetStateErrorCode {} | ||
| 134 | impl TryFrom<u8> for ShciFusGetStateErrorCode { | ||
| 135 | type Error = (); | ||
| 136 | |||
| 137 | fn try_from(v: u8) -> Result<Self, Self::Error> { | ||
| 138 | match v { | ||
| 139 | 0x00 => Ok(Self::FusStateErrorNoError), | ||
| 140 | 0x01 => Ok(Self::FusStateErrorImgNotFound), | ||
| 141 | 0x02 => Ok(Self::FusStateErrorImgCorrupt), | ||
| 142 | 0x03 => Ok(Self::FusStateErrorImgNotAuthentic), | ||
| 143 | 0x04 => Ok(Self::FusStateErrorImgNotEnoughSpace), | ||
| 144 | 0x05 => Ok(Self::FusStateErrorImageUsrAbort), | ||
| 145 | 0x06 => Ok(Self::FusStateErrorImageErsError), | ||
| 146 | 0x07 => Ok(Self::FusStateErrorImageWrtError), | ||
| 147 | 0x08 => Ok(Self::FusStateErrorAuthTagStNotFound), | ||
| 148 | 0x09 => Ok(Self::FusStateErrorAuthTagCustNotFound), | ||
| 149 | 0x0A => Ok(Self::FusStateErrorAuthKeyLocked), | ||
| 150 | 0x11 => Ok(Self::FusStateErrorFwRollbackError), | ||
| 151 | 0xFE => Ok(Self::FusStateErrorStateNotRunning), | ||
| 152 | 0xFF => Ok(Self::FusStateErrorErrUnknown), | ||
| 153 | _ => Err(()), | ||
| 154 | } | ||
| 155 | } | ||
| 156 | } | ||
| 157 | |||
| 158 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 159 | pub enum SchiSysEventReady { | ||
| 160 | WirelessFwRunning = 0x00, | ||
| 161 | FusFwRunning = 0x01, | ||
| 162 | NvmBackupRunning = 0x10, | ||
| 163 | NvmRestoreRunning = 0x11, | ||
| 164 | } | ||
| 165 | |||
| 166 | impl TryFrom<u8> for SchiSysEventReady { | ||
| 167 | type Error = (); | ||
| 168 | |||
| 169 | fn try_from(v: u8) -> Result<Self, Self::Error> { | ||
| 170 | match v { | ||
| 171 | 0x00 => Ok(Self::WirelessFwRunning), | ||
| 172 | 0x01 => Ok(Self::FusFwRunning), | ||
| 173 | 0x10 => Ok(Self::NvmBackupRunning), | ||
| 174 | 0x11 => Ok(Self::NvmRestoreRunning), | ||
| 175 | _ => Err(()), | ||
| 176 | } | ||
| 177 | } | ||
| 178 | } | ||
| 179 | |||
| 110 | pub const SHCI_C2_CONFIG_EVTMASK1_BIT0_ERROR_NOTIF_ENABLE: u8 = 1 << 0; | 180 | pub const SHCI_C2_CONFIG_EVTMASK1_BIT0_ERROR_NOTIF_ENABLE: u8 = 1 << 0; |
| 111 | pub const SHCI_C2_CONFIG_EVTMASK1_BIT1_BLE_NVM_RAM_UPDATE_ENABLE: u8 = 1 << 1; | 181 | pub const SHCI_C2_CONFIG_EVTMASK1_BIT1_BLE_NVM_RAM_UPDATE_ENABLE: u8 = 1 << 1; |
| 112 | pub const SHCI_C2_CONFIG_EVTMASK1_BIT2_THREAD_NVM_RAM_UPDATE_ENABLE: u8 = 1 << 2; | 182 | pub const SHCI_C2_CONFIG_EVTMASK1_BIT2_THREAD_NVM_RAM_UPDATE_ENABLE: u8 = 1 << 2; |
diff --git a/embassy-stm32-wpan/src/wb55/sub/sys.rs b/embassy-stm32-wpan/src/wb55/sub/sys.rs index 2e625a677..3d774eeb7 100644 --- a/embassy-stm32-wpan/src/wb55/sub/sys.rs +++ b/embassy-stm32-wpan/src/wb55/sub/sys.rs | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | use core::slice; | ||
| 2 | |||
| 1 | use embassy_stm32::ipcc::{IpccRxChannel, IpccTxChannel}; | 3 | use embassy_stm32::ipcc::{IpccRxChannel, IpccTxChannel}; |
| 2 | 4 | ||
| 3 | use crate::cmd::CmdPacket; | 5 | use crate::cmd::CmdPacket; |
| @@ -5,12 +7,17 @@ use crate::consts::TlPacketType; | |||
| 5 | use crate::evt::EvtBox; | 7 | use crate::evt::EvtBox; |
| 6 | #[cfg(feature = "wb55_ble")] | 8 | #[cfg(feature = "wb55_ble")] |
| 7 | use crate::shci::ShciBleInitCmdParam; | 9 | use crate::shci::ShciBleInitCmdParam; |
| 8 | use crate::shci::{SchiCommandStatus, ShciOpcode}; | 10 | use crate::shci::{SchiCommandStatus, SchiFromPacket, SchiSysEventReady, ShciFusGetStateErrorCode, ShciOpcode}; |
| 9 | use crate::sub::mm; | 11 | use crate::sub::mm; |
| 10 | use crate::tables::{SysTable, WirelessFwInfoTable}; | 12 | use crate::tables::{SysTable, WirelessFwInfoTable}; |
| 11 | use crate::unsafe_linked_list::LinkedListNode; | 13 | use crate::unsafe_linked_list::LinkedListNode; |
| 12 | use crate::wb55::{SYS_CMD_BUF, SYSTEM_EVT_QUEUE, TL_DEVICE_INFO_TABLE, TL_SYS_TABLE}; | 14 | use crate::wb55::{SYS_CMD_BUF, SYSTEM_EVT_QUEUE, TL_DEVICE_INFO_TABLE, TL_SYS_TABLE}; |
| 13 | 15 | ||
| 16 | const fn slice8_ref(x: &[u32]) -> &[u8] { | ||
| 17 | let len = x.len() * 4; | ||
| 18 | unsafe { slice::from_raw_parts(x.as_ptr() as *const u8, len) } | ||
| 19 | } | ||
| 20 | |||
| 14 | /// A guard that, once constructed, allows for sys commands to be sent to CPU2. | 21 | /// A guard that, once constructed, allows for sys commands to be sent to CPU2. |
| 15 | pub struct Sys<'a> { | 22 | pub struct Sys<'a> { |
| 16 | ipcc_system_cmd_rsp_channel: IpccTxChannel<'a>, | 23 | ipcc_system_cmd_rsp_channel: IpccTxChannel<'a>, |
| @@ -55,15 +62,15 @@ impl<'a> Sys<'a> { | |||
| 55 | } | 62 | } |
| 56 | 63 | ||
| 57 | /// `HW_IPCC_SYS_CmdEvtNot` | 64 | /// `HW_IPCC_SYS_CmdEvtNot` |
| 58 | pub async fn write_and_get_response( | 65 | pub async fn write_and_get_response<T: SchiFromPacket>( |
| 59 | &mut self, | 66 | &mut self, |
| 60 | opcode: ShciOpcode, | 67 | opcode: ShciOpcode, |
| 61 | payload: &[u8], | 68 | payload: &[u8], |
| 62 | ) -> Result<SchiCommandStatus, ()> { | 69 | ) -> Result<T, ()> { |
| 63 | self.write(opcode, payload).await; | 70 | self.write(opcode, payload).await; |
| 64 | self.ipcc_system_cmd_rsp_channel.flush().await; | 71 | self.ipcc_system_cmd_rsp_channel.flush().await; |
| 65 | 72 | ||
| 66 | unsafe { SchiCommandStatus::from_packet(SYS_CMD_BUF.as_ptr()) } | 73 | unsafe { T::from_packet(SYS_CMD_BUF.as_ptr()) } |
| 67 | } | 74 | } |
| 68 | 75 | ||
| 69 | #[cfg(feature = "wb55_mac")] | 76 | #[cfg(feature = "wb55_mac")] |
| @@ -82,6 +89,36 @@ impl<'a> Sys<'a> { | |||
| 82 | self.write_and_get_response(ShciOpcode::BleInit, param.payload()).await | 89 | self.write_and_get_response(ShciOpcode::BleInit, param.payload()).await |
| 83 | } | 90 | } |
| 84 | 91 | ||
| 92 | pub async fn shci_c2_fus_getstate(&mut self) -> Result<ShciFusGetStateErrorCode, ()> { | ||
| 93 | self.write_and_get_response(ShciOpcode::FusStartWirelessStack, &[]) | ||
| 94 | .await | ||
| 95 | } | ||
| 96 | |||
| 97 | /// Send a request to CPU2 to start the wireless stack | ||
| 98 | pub async fn shci_c2_fus_startws(&mut self) -> Result<SchiCommandStatus, ()> { | ||
| 99 | self.write_and_get_response(ShciOpcode::FusStartWirelessStack, &[]) | ||
| 100 | .await | ||
| 101 | } | ||
| 102 | |||
| 103 | /// Send a request to CPU2 to upgrade the firmware | ||
| 104 | pub async fn shci_c2_fus_fwupgrade(&mut self, fw_src_add: u32, fw_dst_add: u32) -> Result<SchiCommandStatus, ()> { | ||
| 105 | let buf = [fw_src_add, fw_dst_add]; | ||
| 106 | let len = if fw_dst_add != 0 { | ||
| 107 | 2 | ||
| 108 | } else if fw_src_add != 0 { | ||
| 109 | 1 | ||
| 110 | } else { | ||
| 111 | 0 | ||
| 112 | }; | ||
| 113 | |||
| 114 | self.write_and_get_response(ShciOpcode::FusFirmwareUpgrade, slice8_ref(&buf[..len])) | ||
| 115 | .await | ||
| 116 | } | ||
| 117 | |||
| 118 | pub async fn read_ready(&mut self) -> Result<SchiSysEventReady, ()> { | ||
| 119 | self.read().await.payload()[0].try_into() | ||
| 120 | } | ||
| 121 | |||
| 85 | /// `HW_IPCC_SYS_EvtNot` | 122 | /// `HW_IPCC_SYS_EvtNot` |
| 86 | /// | 123 | /// |
| 87 | /// This method takes the place of the `HW_IPCC_SYS_EvtNot`/`SysUserEvtRx`/`APPE_SysUserEvtRx`, | 124 | /// This method takes the place of the `HW_IPCC_SYS_EvtNot`/`SysUserEvtRx`/`APPE_SysUserEvtRx`, |
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index e96933b78..27f26df28 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml | |||
| @@ -184,8 +184,8 @@ vcell = "0.1.3" | |||
| 184 | nb = "1.0.0" | 184 | nb = "1.0.0" |
| 185 | stm32-fmc = "0.4.0" | 185 | stm32-fmc = "0.4.0" |
| 186 | cfg-if = "1.0.0" | 186 | cfg-if = "1.0.0" |
| 187 | embedded-io = { version = "0.6.0" } | 187 | embedded-io = { version = "0.7.1" } |
| 188 | embedded-io-async = { version = "0.6.1" } | 188 | embedded-io-async = { version = "0.7.0" } |
| 189 | chrono = { version = "^0.4", default-features = false, optional = true } | 189 | chrono = { version = "^0.4", default-features = false, optional = true } |
| 190 | bit_field = "0.10.2" | 190 | bit_field = "0.10.2" |
| 191 | trait-set = "0.3.0" | 191 | trait-set = "0.3.0" |
| @@ -228,7 +228,7 @@ defmt = [ | |||
| 228 | "embassy-sync/defmt", | 228 | "embassy-sync/defmt", |
| 229 | "embassy-embedded-hal/defmt", | 229 | "embassy-embedded-hal/defmt", |
| 230 | "embassy-hal-internal/defmt", | 230 | "embassy-hal-internal/defmt", |
| 231 | "embedded-io-async/defmt-03", | 231 | "embedded-io-async/defmt", |
| 232 | "embassy-usb-driver/defmt", | 232 | "embassy-usb-driver/defmt", |
| 233 | "embassy-net-driver/defmt", | 233 | "embassy-net-driver/defmt", |
| 234 | "embassy-time?/defmt", | 234 | "embassy-time?/defmt", |
| @@ -241,9 +241,9 @@ log = ["dep:log"] | |||
| 241 | chrono = ["dep:chrono"] | 241 | chrono = ["dep:chrono"] |
| 242 | 242 | ||
| 243 | exti = [] | 243 | exti = [] |
| 244 | low-power = [ "dep:embassy-executor", "time" ] | 244 | low-power = [ "dep:embassy-executor", "time", "chrono" ] |
| 245 | low-power-pender = [ ] | 245 | low-power-pender = [ "low-power" ] |
| 246 | low-power-debug-with-sleep = [] | 246 | low-power-debug-with-sleep = [ "low-power" ] |
| 247 | 247 | ||
| 248 | ## Automatically generate `memory.x` file based on the memory map from [`stm32-metapac`](https://docs.rs/stm32-metapac/) | 248 | ## Automatically generate `memory.x` file based on the memory map from [`stm32-metapac`](https://docs.rs/stm32-metapac/) |
| 249 | memory-x = [] | 249 | memory-x = [] |
diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index 2f783bf64..a0b2f045c 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs | |||
| @@ -138,6 +138,9 @@ pub mod wdg; | |||
| 138 | #[cfg(xspi)] | 138 | #[cfg(xspi)] |
| 139 | pub mod xspi; | 139 | pub mod xspi; |
| 140 | 140 | ||
| 141 | #[cfg(feature = "low-power")] | ||
| 142 | pub use low_power::Executor; | ||
| 143 | |||
| 141 | // This must go last, so that it sees all the impl_foo! macros defined earlier. | 144 | // This must go last, so that it sees all the impl_foo! macros defined earlier. |
| 142 | pub(crate) mod _generated { | 145 | pub(crate) mod _generated { |
| 143 | #![allow(dead_code)] | 146 | #![allow(dead_code)] |
diff --git a/embassy-stm32/src/low_power.rs b/embassy-stm32/src/low_power.rs index 5c10c1a5d..02116e08a 100644 --- a/embassy-stm32/src/low_power.rs +++ b/embassy-stm32/src/low_power.rs | |||
| @@ -3,31 +3,31 @@ | |||
| 3 | //! The STM32 line of microcontrollers support various deep-sleep modes which exploit clock-gating | 3 | //! The STM32 line of microcontrollers support various deep-sleep modes which exploit clock-gating |
| 4 | //! to reduce power consumption. `embassy-stm32` provides a low-power executor, [`Executor`] which | 4 | //! to reduce power consumption. `embassy-stm32` provides a low-power executor, [`Executor`] which |
| 5 | //! can use knowledge of which peripherals are currently blocked upon to transparently and safely | 5 | //! can use knowledge of which peripherals are currently blocked upon to transparently and safely |
| 6 | //! enter such low-power modes (currently, only `STOP2`) when idle. | 6 | //! enter such low-power modes including `STOP1` and `STOP2` when idle. |
| 7 | //! | 7 | //! |
| 8 | //! The executor determines which peripherals are active by their RCC state; consequently, | 8 | //! The executor determines which peripherals are active by their RCC state; consequently, |
| 9 | //! low-power states can only be entered if all peripherals have been `drop`'d. There are a few | 9 | //! low-power states can only be entered if peripherals which block stop have been `drop`'d and if |
| 10 | //! exceptions to this rule: | 10 | //! peripherals that do not block stop are busy. Peripherals which never block stop include: |
| 11 | //! | 11 | //! |
| 12 | //! * `GPIO` | 12 | //! * `GPIO` |
| 13 | //! * `RTC` | 13 | //! * `RTC` |
| 14 | //! | 14 | //! |
| 15 | //! Other peripherals which block stop when busy include (this list may be stale): | ||
| 16 | //! | ||
| 17 | //! * `I2C` | ||
| 18 | //! * `USART` | ||
| 19 | //! | ||
| 15 | //! Since entering and leaving low-power modes typically incurs a significant latency, the | 20 | //! Since entering and leaving low-power modes typically incurs a significant latency, the |
| 16 | //! low-power executor will only attempt to enter when the next timer event is at least | 21 | //! low-power executor will only attempt to enter when the next timer event is at least |
| 17 | //! [`time_driver::min_stop_pause`] in the future. | 22 | //! [`config.min_stop_pause`] in the future. |
| 18 | //! | 23 | //! |
| 19 | //! Currently there is no macro analogous to `embassy_executor::main` for this executor; | ||
| 20 | //! consequently one must define their entrypoint manually. Moreover, you must relinquish control | ||
| 21 | //! of the `RTC` peripheral to the executor. This will typically look like | ||
| 22 | //! | 24 | //! |
| 23 | //! ```rust,no_run | 25 | //! ```rust,no_run |
| 24 | //! use embassy_executor::Spawner; | 26 | //! use embassy_executor::Spawner; |
| 25 | //! use embassy_stm32::low_power; | ||
| 26 | //! use embassy_stm32::rtc::{Rtc, RtcConfig}; | ||
| 27 | //! use embassy_time::Duration; | 27 | //! use embassy_time::Duration; |
| 28 | //! | 28 | //! |
| 29 | //! #[embassy_executor::main(executor = "low_power::Executor")] | 29 | //! #[embassy_executor::main(executor = "embassy_stm32::Executor", entry = "cortex_m_rt::entry")] |
| 30 | //! async fn async_main(spawner: Spawner) { | 30 | //! async fn main(spawner: Spawner) { |
| 31 | //! // initialize the platform... | 31 | //! // initialize the platform... |
| 32 | //! let mut config = embassy_stm32::Config::default(); | 32 | //! let mut config = embassy_stm32::Config::default(); |
| 33 | //! // the default value, but can be adjusted | 33 | //! // the default value, but can be adjusted |
| @@ -210,7 +210,7 @@ impl Executor { | |||
| 210 | w.set_c1cssf(false); | 210 | w.set_c1cssf(false); |
| 211 | }); | 211 | }); |
| 212 | 212 | ||
| 213 | let has_stopped2 = { | 213 | let _has_stopped2 = { |
| 214 | #[cfg(stm32wb)] | 214 | #[cfg(stm32wb)] |
| 215 | { | 215 | { |
| 216 | es.c2stopf() | 216 | es.c2stopf() |
| @@ -222,10 +222,11 @@ impl Executor { | |||
| 222 | } | 222 | } |
| 223 | }; | 223 | }; |
| 224 | 224 | ||
| 225 | if es.c1stopf() || has_stopped2 { | 225 | #[cfg(not(stm32wb))] |
| 226 | if es.c1stopf() || _has_stopped2 { | ||
| 226 | // when we wake from any stop mode we need to re-initialize the rcc | 227 | // when we wake from any stop mode we need to re-initialize the rcc |
| 227 | crate::rcc::init(RCC_CONFIG.unwrap()); | 228 | crate::rcc::init(RCC_CONFIG.unwrap()); |
| 228 | if has_stopped2 { | 229 | if _has_stopped2 { |
| 229 | // when we wake from STOP2, we need to re-initialize the time driver | 230 | // when we wake from STOP2, we need to re-initialize the time driver |
| 230 | get_driver().init_timer(cs); | 231 | get_driver().init_timer(cs); |
| 231 | // reset the refcounts for STOP2 and STOP1 (initializing the time driver will increment one of them for the timer) | 232 | // reset the refcounts for STOP2 and STOP1 (initializing the time driver will increment one of them for the timer) |
diff --git a/embassy-stm32/src/rcc/c0.rs b/embassy-stm32/src/rcc/c0.rs index 99f22273d..7801078c3 100644 --- a/embassy-stm32/src/rcc/c0.rs +++ b/embassy-stm32/src/rcc/c0.rs | |||
| @@ -185,6 +185,12 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 185 | RCC.cr().modify(|w| w.set_hsion(false)); | 185 | RCC.cr().modify(|w| w.set_hsion(false)); |
| 186 | } | 186 | } |
| 187 | 187 | ||
| 188 | // Disable the HSI48, if not used | ||
| 189 | #[cfg(crs)] | ||
| 190 | if config.hsi48.is_none() { | ||
| 191 | super::disable_hsi48(); | ||
| 192 | } | ||
| 193 | |||
| 188 | config.mux.init(); | 194 | config.mux.init(); |
| 189 | 195 | ||
| 190 | set_clocks!( | 196 | set_clocks!( |
diff --git a/embassy-stm32/src/rcc/f013.rs b/embassy-stm32/src/rcc/f013.rs index 1155b6acd..92cf9fca7 100644 --- a/embassy-stm32/src/rcc/f013.rs +++ b/embassy-stm32/src/rcc/f013.rs | |||
| @@ -480,6 +480,12 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 480 | }; | 480 | }; |
| 481 | */ | 481 | */ |
| 482 | 482 | ||
| 483 | // Disable the HSI48, if not used | ||
| 484 | #[cfg(crs)] | ||
| 485 | if config.hsi48.is_none() { | ||
| 486 | super::disable_hsi48(); | ||
| 487 | } | ||
| 488 | |||
| 483 | config.mux.init(); | 489 | config.mux.init(); |
| 484 | 490 | ||
| 485 | set_clocks!( | 491 | set_clocks!( |
diff --git a/embassy-stm32/src/rcc/g0.rs b/embassy-stm32/src/rcc/g0.rs index ce6398afd..2665c20f9 100644 --- a/embassy-stm32/src/rcc/g0.rs +++ b/embassy-stm32/src/rcc/g0.rs | |||
| @@ -294,6 +294,12 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 294 | RCC.cr().modify(|w| w.set_hsion(false)); | 294 | RCC.cr().modify(|w| w.set_hsion(false)); |
| 295 | } | 295 | } |
| 296 | 296 | ||
| 297 | // Disable the HSI48, if not used | ||
| 298 | #[cfg(crs)] | ||
| 299 | if config.hsi48.is_none() { | ||
| 300 | super::disable_hsi48(); | ||
| 301 | } | ||
| 302 | |||
| 297 | if config.low_power_run { | 303 | if config.low_power_run { |
| 298 | assert!(sys <= Hertz(2_000_000)); | 304 | assert!(sys <= Hertz(2_000_000)); |
| 299 | PWR.cr1().modify(|w| w.set_lpr(true)); | 305 | PWR.cr1().modify(|w| w.set_lpr(true)); |
diff --git a/embassy-stm32/src/rcc/g4.rs b/embassy-stm32/src/rcc/g4.rs index da13e16aa..0dd3713c8 100644 --- a/embassy-stm32/src/rcc/g4.rs +++ b/embassy-stm32/src/rcc/g4.rs | |||
| @@ -300,6 +300,12 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 300 | RCC.cr().modify(|w| w.set_hsion(false)); | 300 | RCC.cr().modify(|w| w.set_hsion(false)); |
| 301 | } | 301 | } |
| 302 | 302 | ||
| 303 | // Disable the HSI48, if not used | ||
| 304 | #[cfg(crs)] | ||
| 305 | if config.hsi48.is_none() { | ||
| 306 | super::disable_hsi48(); | ||
| 307 | } | ||
| 308 | |||
| 303 | if config.low_power_run { | 309 | if config.low_power_run { |
| 304 | assert!(sys <= Hertz(2_000_000)); | 310 | assert!(sys <= Hertz(2_000_000)); |
| 305 | PWR.cr1().modify(|w| w.set_lpr(true)); | 311 | PWR.cr1().modify(|w| w.set_lpr(true)); |
diff --git a/embassy-stm32/src/rcc/h.rs b/embassy-stm32/src/rcc/h.rs index 485edd390..2fe2a435c 100644 --- a/embassy-stm32/src/rcc/h.rs +++ b/embassy-stm32/src/rcc/h.rs | |||
| @@ -671,6 +671,12 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 671 | RCC.cr().modify(|w| w.set_hsion(false)); | 671 | RCC.cr().modify(|w| w.set_hsion(false)); |
| 672 | } | 672 | } |
| 673 | 673 | ||
| 674 | // Disable the HSI48, if not used | ||
| 675 | #[cfg(crs)] | ||
| 676 | if config.hsi48.is_none() { | ||
| 677 | super::disable_hsi48(); | ||
| 678 | } | ||
| 679 | |||
| 674 | // IO compensation cell - Requires CSI clock and SYSCFG | 680 | // IO compensation cell - Requires CSI clock and SYSCFG |
| 675 | #[cfg(any(stm32h7))] // TODO h5, h7rs | 681 | #[cfg(any(stm32h7))] // TODO h5, h7rs |
| 676 | if csi.is_some() { | 682 | if csi.is_some() { |
diff --git a/embassy-stm32/src/rcc/hsi48.rs b/embassy-stm32/src/rcc/hsi48.rs index 49be4af5e..50ac162a4 100644 --- a/embassy-stm32/src/rcc/hsi48.rs +++ b/embassy-stm32/src/rcc/hsi48.rs | |||
| @@ -66,3 +66,24 @@ pub(crate) fn init_hsi48(config: Hsi48Config) -> Hertz { | |||
| 66 | 66 | ||
| 67 | HSI48_FREQ | 67 | HSI48_FREQ |
| 68 | } | 68 | } |
| 69 | |||
| 70 | pub(crate) fn disable_hsi48() { | ||
| 71 | // disable CRS if it is enabled | ||
| 72 | rcc::disable::<crate::peripherals::CRS>(); | ||
| 73 | |||
| 74 | // Disable HSI48 | ||
| 75 | #[cfg(not(any(stm32u5, stm32g0, stm32h5, stm32h7, stm32h7rs, stm32u5, stm32wba, stm32f0, stm32c071)))] | ||
| 76 | let r = RCC.crrcr(); | ||
| 77 | #[cfg(any(stm32u5, stm32g0, stm32h5, stm32h7, stm32h7rs, stm32u5, stm32wba, stm32c071))] | ||
| 78 | let r = RCC.cr(); | ||
| 79 | #[cfg(any(stm32f0))] | ||
| 80 | let r = RCC.cr2(); | ||
| 81 | |||
| 82 | r.modify(|w| w.set_hsi48on(false)); | ||
| 83 | |||
| 84 | // Disable VREFINT reference for HSI48 oscillator | ||
| 85 | #[cfg(stm32l0)] | ||
| 86 | crate::pac::SYSCFG.cfgr3().modify(|w| { | ||
| 87 | w.set_enref_hsi48(false); | ||
| 88 | }); | ||
| 89 | } | ||
diff --git a/embassy-stm32/src/rcc/l.rs b/embassy-stm32/src/rcc/l.rs index 0d668103c..55f383374 100644 --- a/embassy-stm32/src/rcc/l.rs +++ b/embassy-stm32/src/rcc/l.rs | |||
| @@ -385,6 +385,17 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 385 | while !RCC.extcfgr().read().c2hpref() {} | 385 | while !RCC.extcfgr().read().c2hpref() {} |
| 386 | } | 386 | } |
| 387 | 387 | ||
| 388 | // Disable HSI if not used | ||
| 389 | if !config.hsi { | ||
| 390 | RCC.cr().modify(|w| w.set_hsion(false)); | ||
| 391 | } | ||
| 392 | |||
| 393 | // Disable the HSI48, if not used | ||
| 394 | #[cfg(crs)] | ||
| 395 | if config.hsi48.is_none() { | ||
| 396 | super::disable_hsi48(); | ||
| 397 | } | ||
| 398 | |||
| 388 | config.mux.init(); | 399 | config.mux.init(); |
| 389 | 400 | ||
| 390 | set_clocks!( | 401 | set_clocks!( |
diff --git a/embassy-stm32/src/rcc/u5.rs b/embassy-stm32/src/rcc/u5.rs index 47cc29c6f..9f37107a3 100644 --- a/embassy-stm32/src/rcc/u5.rs +++ b/embassy-stm32/src/rcc/u5.rs | |||
| @@ -467,6 +467,17 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 467 | let lse = config.ls.lse.map(|l| l.frequency); | 467 | let lse = config.ls.lse.map(|l| l.frequency); |
| 468 | let lsi = config.ls.lsi.then_some(LSI_FREQ); | 468 | let lsi = config.ls.lsi.then_some(LSI_FREQ); |
| 469 | 469 | ||
| 470 | // Disable HSI if not used | ||
| 471 | if !config.hsi { | ||
| 472 | RCC.cr().modify(|w| w.set_hsion(false)); | ||
| 473 | } | ||
| 474 | |||
| 475 | // Disable the HSI48, if not used | ||
| 476 | #[cfg(crs)] | ||
| 477 | if config.hsi48.is_none() { | ||
| 478 | super::disable_hsi48(); | ||
| 479 | } | ||
| 480 | |||
| 470 | config.mux.init(); | 481 | config.mux.init(); |
| 471 | 482 | ||
| 472 | set_clocks!( | 483 | set_clocks!( |
diff --git a/embassy-stm32/src/rcc/wba.rs b/embassy-stm32/src/rcc/wba.rs index 2528996d5..4ab3067bc 100644 --- a/embassy-stm32/src/rcc/wba.rs +++ b/embassy-stm32/src/rcc/wba.rs | |||
| @@ -269,6 +269,11 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 269 | 269 | ||
| 270 | let lsi = config.ls.lsi.then_some(LSI_FREQ); | 270 | let lsi = config.ls.lsi.then_some(LSI_FREQ); |
| 271 | 271 | ||
| 272 | // Disable HSI if not used | ||
| 273 | if !config.hsi { | ||
| 274 | RCC.cr().modify(|w| w.set_hsion(false)); | ||
| 275 | } | ||
| 276 | |||
| 272 | config.mux.init(); | 277 | config.mux.init(); |
| 273 | 278 | ||
| 274 | set_clocks!( | 279 | set_clocks!( |
diff --git a/embassy-stm32/src/rtc/low_power.rs b/embassy-stm32/src/rtc/low_power.rs index f049d6b12..cd5cea081 100644 --- a/embassy-stm32/src/rtc/low_power.rs +++ b/embassy-stm32/src/rtc/low_power.rs | |||
| @@ -1,64 +1,12 @@ | |||
| 1 | #[cfg(feature = "time")] | 1 | use chrono::{DateTime, NaiveDateTime, TimeDelta, Utc}; |
| 2 | use embassy_time::{Duration, TICK_HZ}; | 2 | use embassy_time::{Duration, Instant, TICK_HZ}; |
| 3 | 3 | ||
| 4 | use super::{DateTimeError, Rtc, RtcError, bcd2_to_byte}; | 4 | use super::Rtc; |
| 5 | use crate::interrupt::typelevel::Interrupt; | 5 | use crate::interrupt::typelevel::Interrupt; |
| 6 | use crate::pac::rtc::vals::Wucksel; | 6 | use crate::pac::rtc::vals::Wucksel; |
| 7 | use crate::peripherals::RTC; | 7 | use crate::peripherals::RTC; |
| 8 | use crate::rtc::{RtcTimeProvider, SealedInstance}; | 8 | use crate::rtc::{RtcTimeProvider, SealedInstance}; |
| 9 | 9 | ||
| 10 | /// Represents an instant in time that can be substracted to compute a duration | ||
| 11 | pub(super) struct RtcInstant { | ||
| 12 | /// 0..59 | ||
| 13 | second: u8, | ||
| 14 | /// 0..256 | ||
| 15 | subsecond: u16, | ||
| 16 | } | ||
| 17 | |||
| 18 | impl RtcInstant { | ||
| 19 | #[cfg(not(rtc_v2_f2))] | ||
| 20 | const fn from(second: u8, subsecond: u16) -> Result<Self, DateTimeError> { | ||
| 21 | if second > 59 { | ||
| 22 | Err(DateTimeError::InvalidSecond) | ||
| 23 | } else { | ||
| 24 | Ok(Self { second, subsecond }) | ||
| 25 | } | ||
| 26 | } | ||
| 27 | } | ||
| 28 | |||
| 29 | #[cfg(feature = "defmt")] | ||
| 30 | impl defmt::Format for RtcInstant { | ||
| 31 | fn format(&self, fmt: defmt::Formatter) { | ||
| 32 | defmt::write!( | ||
| 33 | fmt, | ||
| 34 | "{}:{}", | ||
| 35 | self.second, | ||
| 36 | RTC::regs().prer().read().prediv_s() - self.subsecond, | ||
| 37 | ) | ||
| 38 | } | ||
| 39 | } | ||
| 40 | |||
| 41 | #[cfg(feature = "time")] | ||
| 42 | impl core::ops::Sub for RtcInstant { | ||
| 43 | type Output = embassy_time::Duration; | ||
| 44 | |||
| 45 | fn sub(self, rhs: Self) -> Self::Output { | ||
| 46 | let second = if self.second < rhs.second { | ||
| 47 | self.second + 60 | ||
| 48 | } else { | ||
| 49 | self.second | ||
| 50 | }; | ||
| 51 | |||
| 52 | let psc = RTC::regs().prer().read().prediv_s() as u32; | ||
| 53 | |||
| 54 | let self_ticks = second as u32 * (psc + 1) + (psc - self.subsecond as u32); | ||
| 55 | let other_ticks = rhs.second as u32 * (psc + 1) + (psc - rhs.subsecond as u32); | ||
| 56 | let rtc_ticks = self_ticks - other_ticks; | ||
| 57 | |||
| 58 | Duration::from_ticks(((rtc_ticks * TICK_HZ as u32) / (psc + 1)) as u64) | ||
| 59 | } | ||
| 60 | } | ||
| 61 | |||
| 62 | fn wucksel_compute_min(val: u32) -> (Wucksel, u32) { | 10 | fn wucksel_compute_min(val: u32) -> (Wucksel, u32) { |
| 63 | *[ | 11 | *[ |
| 64 | (Wucksel::DIV2, 2), | 12 | (Wucksel::DIV2, 2), |
| @@ -72,22 +20,15 @@ fn wucksel_compute_min(val: u32) -> (Wucksel, u32) { | |||
| 72 | } | 20 | } |
| 73 | 21 | ||
| 74 | impl Rtc { | 22 | impl Rtc { |
| 75 | /// Return the current instant. | 23 | pub(super) fn calc_epoch(&self) -> DateTime<Utc> { |
| 76 | fn instant(&self) -> Result<RtcInstant, RtcError> { | 24 | let now: NaiveDateTime = RtcTimeProvider::new().now().unwrap().into(); |
| 77 | RtcTimeProvider::new().read(|_, tr, ss| { | ||
| 78 | let second = bcd2_to_byte((tr.st(), tr.su())); | ||
| 79 | 25 | ||
| 80 | RtcInstant::from(second, ss).map_err(RtcError::InvalidDateTime) | 26 | now.and_utc() - TimeDelta::microseconds(Instant::now().as_micros().try_into().unwrap()) |
| 81 | }) | ||
| 82 | } | 27 | } |
| 83 | 28 | ||
| 84 | /// start the wakeup alarm and with a duration that is as close to but less than | 29 | /// start the wakeup alarm and with a duration that is as close to but less than |
| 85 | /// the requested duration, and record the instant the wakeup alarm was started | 30 | /// the requested duration, and record the instant the wakeup alarm was started |
| 86 | pub(crate) fn start_wakeup_alarm( | 31 | pub(crate) fn start_wakeup_alarm(&mut self, requested_duration: embassy_time::Duration) { |
| 87 | &mut self, | ||
| 88 | requested_duration: embassy_time::Duration, | ||
| 89 | cs: critical_section::CriticalSection, | ||
| 90 | ) { | ||
| 91 | // Panic if the rcc mod knows we're not using low-power rtc | 32 | // Panic if the rcc mod knows we're not using low-power rtc |
| 92 | #[cfg(any(rcc_wb, rcc_f4, rcc_f410))] | 33 | #[cfg(any(rcc_wb, rcc_f4, rcc_f410))] |
| 93 | unsafe { crate::rcc::get_freqs() }.rtc.to_hertz().unwrap(); | 34 | unsafe { crate::rcc::get_freqs() }.rtc.to_hertz().unwrap(); |
| @@ -122,27 +63,19 @@ impl Rtc { | |||
| 122 | regs.cr().modify(|w| w.set_wutie(true)); | 63 | regs.cr().modify(|w| w.set_wutie(true)); |
| 123 | }); | 64 | }); |
| 124 | 65 | ||
| 125 | let instant = self.instant().unwrap(); | ||
| 126 | trace!( | 66 | trace!( |
| 127 | "rtc: start wakeup alarm for {} ms (psc: {}, ticks: {}) at {}", | 67 | "rtc: start wakeup alarm for {} ms (psc: {}, ticks: {})", |
| 128 | Duration::from_ticks(rtc_ticks as u64 * TICK_HZ * prescaler as u64 / rtc_hz).as_millis(), | 68 | Duration::from_ticks(rtc_ticks as u64 * TICK_HZ * prescaler as u64 / rtc_hz).as_millis(), |
| 129 | prescaler as u32, | 69 | prescaler as u32, |
| 130 | rtc_ticks, | 70 | rtc_ticks, |
| 131 | instant, | ||
| 132 | ); | 71 | ); |
| 133 | |||
| 134 | assert!(self.stop_time.borrow(cs).replace(Some(instant)).is_none()) | ||
| 135 | } | 72 | } |
| 136 | 73 | ||
| 137 | /// stop the wakeup alarm and return the time elapsed since `start_wakeup_alarm` | 74 | /// stop the wakeup alarm and return the time elapsed since `start_wakeup_alarm` |
| 138 | /// was called, otherwise none | 75 | /// was called, otherwise none |
| 139 | pub(crate) fn stop_wakeup_alarm( | 76 | pub(crate) fn stop_wakeup_alarm(&mut self) -> embassy_time::Instant { |
| 140 | &mut self, | ||
| 141 | cs: critical_section::CriticalSection, | ||
| 142 | ) -> Option<embassy_time::Duration> { | ||
| 143 | let instant = self.instant().unwrap(); | ||
| 144 | if RTC::regs().cr().read().wute() { | 77 | if RTC::regs().cr().read().wute() { |
| 145 | trace!("rtc: stop wakeup alarm at {}", instant); | 78 | trace!("rtc: stop wakeup alarm"); |
| 146 | 79 | ||
| 147 | self.write(false, |regs| { | 80 | self.write(false, |regs| { |
| 148 | regs.cr().modify(|w| w.set_wutie(false)); | 81 | regs.cr().modify(|w| w.set_wutie(false)); |
| @@ -166,10 +99,13 @@ impl Rtc { | |||
| 166 | }); | 99 | }); |
| 167 | } | 100 | } |
| 168 | 101 | ||
| 169 | self.stop_time.borrow(cs).take().map(|stop_time| instant - stop_time) | 102 | let datetime: NaiveDateTime = RtcTimeProvider::new().now().expect("failed to read now").into(); |
| 103 | let offset = datetime.and_utc() - self.epoch; | ||
| 104 | |||
| 105 | Instant::from_micros(offset.num_microseconds().unwrap().try_into().unwrap()) | ||
| 170 | } | 106 | } |
| 171 | 107 | ||
| 172 | pub(crate) fn enable_wakeup_line(&self) { | 108 | pub(super) fn enable_wakeup_line(&mut self) { |
| 173 | <RTC as crate::rtc::SealedInstance>::WakeupInterrupt::unpend(); | 109 | <RTC as crate::rtc::SealedInstance>::WakeupInterrupt::unpend(); |
| 174 | unsafe { <RTC as crate::rtc::SealedInstance>::WakeupInterrupt::enable() }; | 110 | unsafe { <RTC as crate::rtc::SealedInstance>::WakeupInterrupt::enable() }; |
| 175 | 111 | ||
diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs index e88bd7ab2..94ba13ae1 100644 --- a/embassy-stm32/src/rtc/mod.rs +++ b/embassy-stm32/src/rtc/mod.rs | |||
| @@ -5,7 +5,7 @@ mod datetime; | |||
| 5 | mod low_power; | 5 | mod low_power; |
| 6 | 6 | ||
| 7 | #[cfg(feature = "low-power")] | 7 | #[cfg(feature = "low-power")] |
| 8 | use core::cell::{Cell, RefCell, RefMut}; | 8 | use core::cell::{RefCell, RefMut}; |
| 9 | #[cfg(feature = "low-power")] | 9 | #[cfg(feature = "low-power")] |
| 10 | use core::ops; | 10 | use core::ops; |
| 11 | 11 | ||
| @@ -163,7 +163,7 @@ impl<'a> ops::DerefMut for RtcBorrow<'a> { | |||
| 163 | /// RTC driver. | 163 | /// RTC driver. |
| 164 | pub struct Rtc { | 164 | pub struct Rtc { |
| 165 | #[cfg(feature = "low-power")] | 165 | #[cfg(feature = "low-power")] |
| 166 | stop_time: Mutex<CriticalSectionRawMutex, Cell<Option<low_power::RtcInstant>>>, | 166 | epoch: chrono::DateTime<chrono::Utc>, |
| 167 | _private: (), | 167 | _private: (), |
| 168 | } | 168 | } |
| 169 | 169 | ||
| @@ -225,7 +225,7 @@ impl Rtc { | |||
| 225 | 225 | ||
| 226 | let mut this = Self { | 226 | let mut this = Self { |
| 227 | #[cfg(feature = "low-power")] | 227 | #[cfg(feature = "low-power")] |
| 228 | stop_time: Mutex::const_new(CriticalSectionRawMutex::new(), Cell::new(None)), | 228 | epoch: chrono::DateTime::from_timestamp_secs(0).unwrap(), |
| 229 | _private: (), | 229 | _private: (), |
| 230 | }; | 230 | }; |
| 231 | 231 | ||
| @@ -243,7 +243,10 @@ impl Rtc { | |||
| 243 | } | 243 | } |
| 244 | 244 | ||
| 245 | #[cfg(feature = "low-power")] | 245 | #[cfg(feature = "low-power")] |
| 246 | this.enable_wakeup_line(); | 246 | { |
| 247 | this.enable_wakeup_line(); | ||
| 248 | this.epoch = this.calc_epoch(); | ||
| 249 | } | ||
| 247 | 250 | ||
| 248 | this | 251 | this |
| 249 | } | 252 | } |
| @@ -293,6 +296,11 @@ impl Rtc { | |||
| 293 | }); | 296 | }); |
| 294 | }); | 297 | }); |
| 295 | 298 | ||
| 299 | #[cfg(feature = "low-power")] | ||
| 300 | { | ||
| 301 | self.epoch = self.calc_epoch(); | ||
| 302 | } | ||
| 303 | |||
| 296 | Ok(()) | 304 | Ok(()) |
| 297 | } | 305 | } |
| 298 | 306 | ||
diff --git a/embassy-stm32/src/time_driver.rs b/embassy-stm32/src/time_driver.rs index ed5d902bd..59ec58575 100644 --- a/embassy-stm32/src/time_driver.rs +++ b/embassy-stm32/src/time_driver.rs | |||
| @@ -251,8 +251,8 @@ impl RtcDriver { | |||
| 251 | 251 | ||
| 252 | #[cfg(feature = "low-power")] | 252 | #[cfg(feature = "low-power")] |
| 253 | /// Add the given offset to the current time | 253 | /// Add the given offset to the current time |
| 254 | fn add_time(&self, offset: embassy_time::Duration, cs: CriticalSection) { | 254 | fn set_time(&self, instant: u64, cs: CriticalSection) { |
| 255 | let (period, counter) = calc_period_counter(self.now() + offset.as_ticks()); | 255 | let (period, counter) = calc_period_counter(core::cmp::max(self.now(), instant)); |
| 256 | 256 | ||
| 257 | self.period.store(period, Ordering::SeqCst); | 257 | self.period.store(period, Ordering::SeqCst); |
| 258 | regs_gp16().cnt().write(|w| w.set_cnt(counter)); | 258 | regs_gp16().cnt().write(|w| w.set_cnt(counter)); |
| @@ -269,10 +269,17 @@ impl RtcDriver { | |||
| 269 | #[cfg(feature = "low-power")] | 269 | #[cfg(feature = "low-power")] |
| 270 | /// Stop the wakeup alarm, if enabled, and add the appropriate offset | 270 | /// Stop the wakeup alarm, if enabled, and add the appropriate offset |
| 271 | fn stop_wakeup_alarm(&self, cs: CriticalSection) { | 271 | fn stop_wakeup_alarm(&self, cs: CriticalSection) { |
| 272 | if !regs_gp16().cr1().read().cen() | 272 | if !regs_gp16().cr1().read().cen() { |
| 273 | && let Some(offset) = self.rtc.borrow(cs).borrow_mut().as_mut().unwrap().stop_wakeup_alarm(cs) | 273 | self.set_time( |
| 274 | { | 274 | self.rtc |
| 275 | self.add_time(offset, cs); | 275 | .borrow(cs) |
| 276 | .borrow_mut() | ||
| 277 | .as_mut() | ||
| 278 | .unwrap() | ||
| 279 | .stop_wakeup_alarm() | ||
| 280 | .as_ticks(), | ||
| 281 | cs, | ||
| 282 | ); | ||
| 276 | } | 283 | } |
| 277 | } | 284 | } |
| 278 | 285 | ||
| @@ -287,7 +294,7 @@ impl RtcDriver { | |||
| 287 | #[cfg(feature = "low-power")] | 294 | #[cfg(feature = "low-power")] |
| 288 | /// Set the rtc but panic if it's already been set | 295 | /// Set the rtc but panic if it's already been set |
| 289 | pub(crate) fn set_rtc(&self, cs: CriticalSection, mut rtc: Rtc) { | 296 | pub(crate) fn set_rtc(&self, cs: CriticalSection, mut rtc: Rtc) { |
| 290 | rtc.stop_wakeup_alarm(cs); | 297 | rtc.stop_wakeup_alarm(); |
| 291 | 298 | ||
| 292 | assert!(self.rtc.borrow(cs).replace(Some(rtc)).is_none()); | 299 | assert!(self.rtc.borrow(cs).replace(Some(rtc)).is_none()); |
| 293 | } | 300 | } |
| @@ -310,7 +317,7 @@ impl RtcDriver { | |||
| 310 | .borrow_mut() | 317 | .borrow_mut() |
| 311 | .as_mut() | 318 | .as_mut() |
| 312 | .unwrap() | 319 | .unwrap() |
| 313 | .start_wakeup_alarm(time_until_next_alarm, cs); | 320 | .start_wakeup_alarm(time_until_next_alarm); |
| 314 | 321 | ||
| 315 | regs_gp16().cr1().modify(|w| w.set_cen(false)); | 322 | regs_gp16().cr1().modify(|w| w.set_cen(false)); |
| 316 | // save the count for the timer as its lost in STOP2 for stm32wlex | 323 | // save the count for the timer as its lost in STOP2 for stm32wlex |
diff --git a/embassy-sync/Cargo.toml b/embassy-sync/Cargo.toml index 0c28cec7d..86c87b7b1 100644 --- a/embassy-sync/Cargo.toml +++ b/embassy-sync/Cargo.toml | |||
| @@ -41,7 +41,7 @@ futures-core = { version = "0.3.31", default-features = false } | |||
| 41 | critical-section = "1.1" | 41 | critical-section = "1.1" |
| 42 | heapless = "0.8" | 42 | heapless = "0.8" |
| 43 | cfg-if = "1.0.0" | 43 | cfg-if = "1.0.0" |
| 44 | embedded-io-async = { version = "0.6.1" } | 44 | embedded-io-async = { version = "0.7.0" } |
| 45 | 45 | ||
| 46 | [dev-dependencies] | 46 | [dev-dependencies] |
| 47 | futures-executor = { version = "0.3.17", features = [ "thread-pool" ] } | 47 | futures-executor = { version = "0.3.17", features = [ "thread-pool" ] } |
diff --git a/embassy-usb-driver/Cargo.toml b/embassy-usb-driver/Cargo.toml index 3f43f60a3..a11658213 100644 --- a/embassy-usb-driver/Cargo.toml +++ b/embassy-usb-driver/Cargo.toml | |||
| @@ -19,6 +19,7 @@ target = "thumbv7em-none-eabi" | |||
| 19 | features = ["defmt"] | 19 | features = ["defmt"] |
| 20 | 20 | ||
| 21 | [dependencies] | 21 | [dependencies] |
| 22 | # TODO: remove before releasing embassy-usb-driver v0.3 | ||
| 22 | embedded-io-async = "0.6.1" | 23 | embedded-io-async = "0.6.1" |
| 23 | defmt = { version = "1", optional = true } | 24 | defmt = { version = "1", optional = true } |
| 24 | 25 | ||
diff --git a/embassy-usb-driver/src/lib.rs b/embassy-usb-driver/src/lib.rs index f19e0a401..782f130f6 100644 --- a/embassy-usb-driver/src/lib.rs +++ b/embassy-usb-driver/src/lib.rs | |||
| @@ -429,6 +429,7 @@ pub enum EndpointError { | |||
| 429 | Disabled, | 429 | Disabled, |
| 430 | } | 430 | } |
| 431 | 431 | ||
| 432 | // TODO: remove before releasing embassy-usb-driver v0.3 | ||
| 432 | impl embedded_io_async::Error for EndpointError { | 433 | impl embedded_io_async::Error for EndpointError { |
| 433 | fn kind(&self) -> embedded_io_async::ErrorKind { | 434 | fn kind(&self) -> embedded_io_async::ErrorKind { |
| 434 | match self { | 435 | match self { |
diff --git a/embassy-usb/Cargo.toml b/embassy-usb/Cargo.toml index 3d1e005e4..6c3ddc1db 100644 --- a/embassy-usb/Cargo.toml +++ b/embassy-usb/Cargo.toml | |||
| @@ -66,7 +66,7 @@ embassy-net-driver-channel = { version = "0.3.2", path = "../embassy-net-driver- | |||
| 66 | defmt = { version = "1", optional = true } | 66 | defmt = { version = "1", optional = true } |
| 67 | log = { version = "0.4.14", optional = true } | 67 | log = { version = "0.4.14", optional = true } |
| 68 | heapless = "0.8" | 68 | heapless = "0.8" |
| 69 | embedded-io-async = "0.6.1" | 69 | embedded-io-async = { version = "0.7.0" } |
| 70 | 70 | ||
| 71 | # for HID | 71 | # for HID |
| 72 | usbd-hid = { version = "0.9.0", optional = true } | 72 | usbd-hid = { version = "0.9.0", optional = true } |
diff --git a/embassy-usb/src/class/cdc_acm.rs b/embassy-usb/src/class/cdc_acm.rs index ab2311f4e..56acdb2a6 100644 --- a/embassy-usb/src/class/cdc_acm.rs +++ b/embassy-usb/src/class/cdc_acm.rs | |||
| @@ -33,6 +33,30 @@ const REQ_SET_LINE_CODING: u8 = 0x20; | |||
| 33 | const REQ_GET_LINE_CODING: u8 = 0x21; | 33 | const REQ_GET_LINE_CODING: u8 = 0x21; |
| 34 | const REQ_SET_CONTROL_LINE_STATE: u8 = 0x22; | 34 | const REQ_SET_CONTROL_LINE_STATE: u8 = 0x22; |
| 35 | 35 | ||
| 36 | /// CDC ACM error. | ||
| 37 | #[derive(Clone, Debug)] | ||
| 38 | pub enum CdcAcmError { | ||
| 39 | /// USB is not connected. | ||
| 40 | NotConnected, | ||
| 41 | } | ||
| 42 | |||
| 43 | impl core::fmt::Display for CdcAcmError { | ||
| 44 | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { | ||
| 45 | match *self { | ||
| 46 | Self::NotConnected => f.write_str("NotConnected"), | ||
| 47 | } | ||
| 48 | } | ||
| 49 | } | ||
| 50 | |||
| 51 | impl core::error::Error for CdcAcmError {} | ||
| 52 | impl embedded_io_async::Error for CdcAcmError { | ||
| 53 | fn kind(&self) -> embedded_io_async::ErrorKind { | ||
| 54 | match *self { | ||
| 55 | Self::NotConnected => embedded_io_async::ErrorKind::NotConnected, | ||
| 56 | } | ||
| 57 | } | ||
| 58 | } | ||
| 59 | |||
| 36 | /// Internal state for CDC-ACM | 60 | /// Internal state for CDC-ACM |
| 37 | pub struct State<'a> { | 61 | pub struct State<'a> { |
| 38 | control: MaybeUninit<Control<'a>>, | 62 | control: MaybeUninit<Control<'a>>, |
| @@ -421,14 +445,21 @@ impl<'d, D: Driver<'d>> Sender<'d, D> { | |||
| 421 | } | 445 | } |
| 422 | 446 | ||
| 423 | impl<'d, D: Driver<'d>> embedded_io_async::ErrorType for Sender<'d, D> { | 447 | impl<'d, D: Driver<'d>> embedded_io_async::ErrorType for Sender<'d, D> { |
| 424 | type Error = EndpointError; | 448 | type Error = CdcAcmError; |
| 425 | } | 449 | } |
| 426 | 450 | ||
| 427 | impl<'d, D: Driver<'d>> embedded_io_async::Write for Sender<'d, D> { | 451 | impl<'d, D: Driver<'d>> embedded_io_async::Write for Sender<'d, D> { |
| 428 | async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { | 452 | async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { |
| 429 | let len = core::cmp::min(buf.len(), self.max_packet_size() as usize); | 453 | let len = core::cmp::min(buf.len(), self.max_packet_size() as usize); |
| 430 | self.write_packet(&buf[..len]).await?; | 454 | match self.write_packet(&buf[..len]).await { |
| 431 | Ok(len) | 455 | Ok(()) => Ok(len), |
| 456 | Err(EndpointError::BufferOverflow) => unreachable!(), | ||
| 457 | Err(EndpointError::Disabled) => Err(CdcAcmError::NotConnected), | ||
| 458 | } | ||
| 459 | } | ||
| 460 | |||
| 461 | async fn flush(&mut self) -> Result<(), Self::Error> { | ||
| 462 | Ok(()) | ||
| 432 | } | 463 | } |
| 433 | } | 464 | } |
| 434 | 465 | ||
| @@ -539,7 +570,7 @@ impl<'d, D: Driver<'d>> BufferedReceiver<'d, D> { | |||
| 539 | } | 570 | } |
| 540 | 571 | ||
| 541 | impl<'d, D: Driver<'d>> embedded_io_async::ErrorType for BufferedReceiver<'d, D> { | 572 | impl<'d, D: Driver<'d>> embedded_io_async::ErrorType for BufferedReceiver<'d, D> { |
| 542 | type Error = EndpointError; | 573 | type Error = CdcAcmError; |
| 543 | } | 574 | } |
| 544 | 575 | ||
| 545 | impl<'d, D: Driver<'d>> embedded_io_async::Read for BufferedReceiver<'d, D> { | 576 | impl<'d, D: Driver<'d>> embedded_io_async::Read for BufferedReceiver<'d, D> { |
| @@ -552,14 +583,22 @@ impl<'d, D: Driver<'d>> embedded_io_async::Read for BufferedReceiver<'d, D> { | |||
| 552 | // If the caller's buffer is large enough to contain an entire packet, read directly into | 583 | // If the caller's buffer is large enough to contain an entire packet, read directly into |
| 553 | // that instead of buffering the packet internally. | 584 | // that instead of buffering the packet internally. |
| 554 | if buf.len() > self.receiver.max_packet_size() as usize { | 585 | if buf.len() > self.receiver.max_packet_size() as usize { |
| 555 | return self.receiver.read_packet(buf).await; | 586 | return match self.receiver.read_packet(buf).await { |
| 587 | Ok(n) => Ok(n), | ||
| 588 | Err(EndpointError::BufferOverflow) => unreachable!(), | ||
| 589 | Err(EndpointError::Disabled) => Err(CdcAcmError::NotConnected), | ||
| 590 | }; | ||
| 556 | } | 591 | } |
| 557 | 592 | ||
| 558 | // Otherwise read a packet into the internal buffer, and return some of it to the caller. | 593 | // Otherwise read a packet into the internal buffer, and return some of it to the caller. |
| 559 | // | 594 | // |
| 560 | // It's important that `start` and `end` be updated in this order so they're left in a | 595 | // It's important that `start` and `end` be updated in this order so they're left in a |
| 561 | // consistent state if the `read` future is dropped mid-execution, e.g. from a timeout. | 596 | // consistent state if the `read` future is dropped mid-execution, e.g. from a timeout. |
| 562 | self.end = self.receiver.read_packet(&mut self.buffer).await?; | 597 | match self.receiver.read_packet(&mut self.buffer).await { |
| 598 | Ok(n) => self.end = n, | ||
| 599 | Err(EndpointError::BufferOverflow) => unreachable!(), | ||
| 600 | Err(EndpointError::Disabled) => return Err(CdcAcmError::NotConnected), | ||
| 601 | } | ||
| 563 | self.start = 0; | 602 | self.start = 0; |
| 564 | return Ok(self.read_from_buffer(buf)); | 603 | return Ok(self.read_from_buffer(buf)); |
| 565 | } | 604 | } |
diff --git a/examples/mcxa/Cargo.toml b/examples/mcxa/Cargo.toml index 347659f5b..29d319375 100644 --- a/examples/mcxa/Cargo.toml +++ b/examples/mcxa/Cargo.toml | |||
| @@ -18,7 +18,7 @@ embassy-mcxa = { path = "../../embassy-mcxa", features = ["defmt", "unstable-pac | |||
| 18 | embassy-sync = "0.7.2" | 18 | embassy-sync = "0.7.2" |
| 19 | embassy-time = "0.5.0" | 19 | embassy-time = "0.5.0" |
| 20 | embassy-time-driver = "0.2.1" | 20 | embassy-time-driver = "0.2.1" |
| 21 | embedded-io-async = "0.6.1" | 21 | embedded-io-async = "0.7.0" |
| 22 | heapless = "0.9.2" | 22 | heapless = "0.9.2" |
| 23 | panic-probe = { version = "1.0", features = ["print-defmt"] } | 23 | panic-probe = { version = "1.0", features = ["print-defmt"] } |
| 24 | rand_core = "0.9" | 24 | rand_core = "0.9" |
diff --git a/examples/mcxa/src/bin/clkout.rs b/examples/mcxa/src/bin/clkout.rs index 1e52912d3..c0e8c330d 100644 --- a/examples/mcxa/src/bin/clkout.rs +++ b/examples/mcxa/src/bin/clkout.rs | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | use embassy_executor::Spawner; | 4 | use embassy_executor::Spawner; |
| 5 | use embassy_mcxa::clkout::{ClockOut, ClockOutSel, Config, Div4}; | 5 | use embassy_mcxa::clkout::{ClockOut, ClockOutSel, Config, Div4}; |
| 6 | use embassy_mcxa::clocks::PoweredClock; | 6 | use embassy_mcxa::clocks::PoweredClock; |
| 7 | use embassy_mcxa::clocks::config::{SoscConfig, SoscMode, SpllConfig, SpllMode, SpllSource}; | ||
| 7 | use embassy_mcxa::gpio::{DriveStrength, Level, Output, SlewRate}; | 8 | use embassy_mcxa::gpio::{DriveStrength, Level, Output, SlewRate}; |
| 8 | use embassy_time::Timer; | 9 | use embassy_time::Timer; |
| 9 | use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; | 10 | use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; |
| @@ -11,58 +12,81 @@ use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; | |||
| 11 | /// Demonstrate CLKOUT, using Pin P4.2 | 12 | /// Demonstrate CLKOUT, using Pin P4.2 |
| 12 | #[embassy_executor::main] | 13 | #[embassy_executor::main] |
| 13 | async fn main(_spawner: Spawner) { | 14 | async fn main(_spawner: Spawner) { |
| 14 | let p = hal::init(hal::config::Config::default()); | 15 | let mut cfg = hal::config::Config::default(); |
| 16 | cfg.clock_cfg.sosc = Some(SoscConfig { | ||
| 17 | mode: SoscMode::CrystalOscillator, | ||
| 18 | frequency: 8_000_000, | ||
| 19 | power: PoweredClock::NormalEnabledDeepSleepDisabled, | ||
| 20 | }); | ||
| 21 | cfg.clock_cfg.spll = Some(SpllConfig { | ||
| 22 | source: SpllSource::Sirc, | ||
| 23 | // 12MHz | ||
| 24 | // 12 x 32 => 384MHz | ||
| 25 | // 384 / (16 x 2) => 12.0MHz | ||
| 26 | mode: SpllMode::Mode1b { | ||
| 27 | m_mult: 32, | ||
| 28 | p_div: 16, | ||
| 29 | bypass_p2_div: false, | ||
| 30 | }, | ||
| 31 | power: PoweredClock::NormalEnabledDeepSleepDisabled, | ||
| 32 | pll1_clk_div: None, | ||
| 33 | }); | ||
| 34 | |||
| 35 | let p = hal::init(cfg); | ||
| 36 | |||
| 15 | let mut pin = p.P4_2; | 37 | let mut pin = p.P4_2; |
| 16 | let mut clkout = p.CLKOUT; | 38 | let mut clkout = p.CLKOUT; |
| 17 | 39 | ||
| 18 | loop { | 40 | const K16_CONFIG: Config = Config { |
| 19 | defmt::info!("Set Low..."); | 41 | sel: ClockOutSel::Clk16K, |
| 20 | let mut output = Output::new(pin.reborrow(), Level::Low, DriveStrength::Normal, SlewRate::Slow); | 42 | div: Div4::no_div(), |
| 21 | Timer::after_millis(500).await; | 43 | level: PoweredClock::NormalEnabledDeepSleepDisabled, |
| 44 | }; | ||
| 45 | const M4_CONFIG: Config = Config { | ||
| 46 | sel: ClockOutSel::Fro12M, | ||
| 47 | div: const { Div4::from_divisor(3).unwrap() }, | ||
| 48 | level: PoweredClock::NormalEnabledDeepSleepDisabled, | ||
| 49 | }; | ||
| 50 | const K512_CONFIG: Config = Config { | ||
| 51 | sel: ClockOutSel::ClkIn, | ||
| 52 | div: const { Div4::from_divisor(16).unwrap() }, | ||
| 53 | level: PoweredClock::NormalEnabledDeepSleepDisabled, | ||
| 54 | }; | ||
| 55 | const M1_CONFIG: Config = Config { | ||
| 56 | sel: ClockOutSel::Pll1Clk, | ||
| 57 | div: const { Div4::from_divisor(12).unwrap() }, | ||
| 58 | level: PoweredClock::NormalEnabledDeepSleepDisabled, | ||
| 59 | }; | ||
| 22 | 60 | ||
| 61 | #[rustfmt::skip] | ||
| 62 | let configs = [ | ||
| 63 | ("16K -> /1 = 16K", K16_CONFIG), | ||
| 64 | ("12M -> /3 = 4M", M4_CONFIG), | ||
| 65 | ("8M -> /16 = 512K", K512_CONFIG), | ||
| 66 | ("12M-> /12 = 1M", M1_CONFIG), | ||
| 67 | ]; | ||
| 68 | |||
| 69 | loop { | ||
| 23 | defmt::info!("Set High..."); | 70 | defmt::info!("Set High..."); |
| 24 | output.set_high(); | 71 | let mut output = Output::new(pin.reborrow(), Level::High, DriveStrength::Normal, SlewRate::Slow); |
| 25 | Timer::after_millis(400).await; | 72 | Timer::after_millis(250).await; |
| 26 | 73 | ||
| 27 | defmt::info!("Set Low..."); | 74 | defmt::info!("Set Low..."); |
| 28 | output.set_low(); | 75 | output.set_low(); |
| 29 | Timer::after_millis(500).await; | 76 | Timer::after_millis(750).await; |
| 30 | 77 | ||
| 31 | defmt::info!("16k..."); | 78 | for (name, conf) in configs.iter() { |
| 32 | // Run Clock Out with the 16K clock | 79 | defmt::info!("Running {=str}", name); |
| 33 | let _clock_out = ClockOut::new( | ||
| 34 | clkout.reborrow(), | ||
| 35 | pin.reborrow(), | ||
| 36 | Config { | ||
| 37 | sel: ClockOutSel::Clk16K, | ||
| 38 | div: Div4::no_div(), | ||
| 39 | level: PoweredClock::NormalEnabledDeepSleepDisabled, | ||
| 40 | }, | ||
| 41 | ) | ||
| 42 | .unwrap(); | ||
| 43 | 80 | ||
| 44 | Timer::after_millis(3000).await; | 81 | let _clock_out = ClockOut::new(clkout.reborrow(), pin.reborrow(), *conf).unwrap(); |
| 45 | |||
| 46 | defmt::info!("Set Low..."); | ||
| 47 | drop(_clock_out); | ||
| 48 | 82 | ||
| 49 | let _output = Output::new(pin.reborrow(), Level::Low, DriveStrength::Normal, SlewRate::Slow); | 83 | Timer::after_millis(3000).await; |
| 50 | Timer::after_millis(500).await; | ||
| 51 | 84 | ||
| 52 | // Run Clock Out with the 12M clock, divided by 3 | 85 | defmt::info!("Set Low..."); |
| 53 | defmt::info!("4M..."); | 86 | drop(_clock_out); |
| 54 | let _clock_out = ClockOut::new( | ||
| 55 | clkout.reborrow(), | ||
| 56 | pin.reborrow(), | ||
| 57 | Config { | ||
| 58 | sel: ClockOutSel::Fro12M, | ||
| 59 | div: const { Div4::from_divisor(3).unwrap() }, | ||
| 60 | level: PoweredClock::NormalEnabledDeepSleepDisabled, | ||
| 61 | }, | ||
| 62 | ) | ||
| 63 | .unwrap(); | ||
| 64 | 87 | ||
| 65 | // Let it run for 3 seconds... | 88 | let _output = Output::new(pin.reborrow(), Level::Low, DriveStrength::Normal, SlewRate::Slow); |
| 66 | Timer::after_millis(3000).await; | 89 | Timer::after_millis(500).await; |
| 90 | } | ||
| 67 | } | 91 | } |
| 68 | } | 92 | } |
diff --git a/examples/mcxa/src/bin/reset-reason.rs b/examples/mcxa/src/bin/reset-reason.rs index c244fbe04..2d48a92b1 100644 --- a/examples/mcxa/src/bin/reset-reason.rs +++ b/examples/mcxa/src/bin/reset-reason.rs | |||
| @@ -11,5 +11,7 @@ async fn main(_spawner: Spawner) { | |||
| 11 | let config = Config::default(); | 11 | let config = Config::default(); |
| 12 | let _p = hal::init(config); | 12 | let _p = hal::init(config); |
| 13 | 13 | ||
| 14 | defmt::info!("Reset Reason: '{}'", reset_reason()); | 14 | for reason in reset_reason().into_iter() { |
| 15 | defmt::info!("Reset Reason: '{}'", reason); | ||
| 16 | } | ||
| 15 | } | 17 | } |
diff --git a/examples/mspm0g3507/Cargo.toml b/examples/mspm0g3507/Cargo.toml index 8c230f038..f4fc7e09f 100644 --- a/examples/mspm0g3507/Cargo.toml +++ b/examples/mspm0g3507/Cargo.toml | |||
| @@ -18,7 +18,7 @@ defmt-rtt = "1.0.0" | |||
| 18 | panic-probe = { version = "1.0.0", features = ["print-defmt"] } | 18 | panic-probe = { version = "1.0.0", features = ["print-defmt"] } |
| 19 | panic-semihosting = "0.6.0" | 19 | panic-semihosting = "0.6.0" |
| 20 | 20 | ||
| 21 | embedded-io-async = "0.6.1" | 21 | embedded-io-async = { version = "0.7.0" } |
| 22 | 22 | ||
| 23 | [profile.release] | 23 | [profile.release] |
| 24 | debug = 2 | 24 | debug = 2 |
diff --git a/examples/nrf52840/Cargo.toml b/examples/nrf52840/Cargo.toml index a57bd7b24..15c187328 100644 --- a/examples/nrf52840/Cargo.toml +++ b/examples/nrf52840/Cargo.toml | |||
| @@ -13,8 +13,8 @@ embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["de | |||
| 13 | embassy-nrf = { version = "0.9.0", path = "../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac", "time", "net-driver"] } | 13 | embassy-nrf = { version = "0.9.0", path = "../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac", "time", "net-driver"] } |
| 14 | embassy-net = { version = "0.7.1", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet","udp", "medium-ieee802154", "proto-ipv6"] } | 14 | embassy-net = { version = "0.7.1", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet","udp", "medium-ieee802154", "proto-ipv6"] } |
| 15 | embassy-usb = { version = "0.5.1", path = "../../embassy-usb", features = ["defmt"] } | 15 | embassy-usb = { version = "0.5.1", path = "../../embassy-usb", features = ["defmt"] } |
| 16 | embedded-io = { version = "0.6.0", features = ["defmt-03"] } | 16 | embedded-io = { version = "0.7.1", features = ["defmt"] } |
| 17 | embedded-io-async = { version = "0.6.1", features = ["defmt-03"] } | 17 | embedded-io-async = { version = "0.7.0", features = ["defmt"] } |
| 18 | embassy-net-esp-hosted = { version = "0.2.1", path = "../../embassy-net-esp-hosted", features = ["defmt"] } | 18 | embassy-net-esp-hosted = { version = "0.2.1", path = "../../embassy-net-esp-hosted", features = ["defmt"] } |
| 19 | embassy-net-enc28j60 = { version = "0.2.1", path = "../../embassy-net-enc28j60", features = ["defmt"] } | 19 | embassy-net-enc28j60 = { version = "0.2.1", path = "../../embassy-net-enc28j60", features = ["defmt"] } |
| 20 | 20 | ||
diff --git a/examples/nrf5340/Cargo.toml b/examples/nrf5340/Cargo.toml index b8d5dbfb1..c54a84d22 100644 --- a/examples/nrf5340/Cargo.toml +++ b/examples/nrf5340/Cargo.toml | |||
| @@ -13,7 +13,7 @@ embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["de | |||
| 13 | embassy-nrf = { version = "0.9.0", path = "../../embassy-nrf", features = ["defmt", "nrf5340-app-s", "time-driver-rtc1", "gpiote", "unstable-pac"] } | 13 | embassy-nrf = { version = "0.9.0", path = "../../embassy-nrf", features = ["defmt", "nrf5340-app-s", "time-driver-rtc1", "gpiote", "unstable-pac"] } |
| 14 | embassy-net = { version = "0.7.1", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"] } | 14 | embassy-net = { version = "0.7.1", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"] } |
| 15 | embassy-usb = { version = "0.5.1", path = "../../embassy-usb", features = ["defmt"] } | 15 | embassy-usb = { version = "0.5.1", path = "../../embassy-usb", features = ["defmt"] } |
| 16 | embedded-io-async = { version = "0.6.1" } | 16 | embedded-io-async = { version = "0.7.0" } |
| 17 | 17 | ||
| 18 | defmt = "1.0.1" | 18 | defmt = "1.0.1" |
| 19 | defmt-rtt = "1.0.0" | 19 | defmt-rtt = "1.0.0" |
diff --git a/examples/nrf54l15/Cargo.toml b/examples/nrf54l15/Cargo.toml index 353d1b46e..9940443ff 100644 --- a/examples/nrf54l15/Cargo.toml +++ b/examples/nrf54l15/Cargo.toml | |||
| @@ -11,8 +11,8 @@ embassy-executor = { version = "0.9.0", path = "../../embassy-executor", feature | |||
| 11 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } | 11 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } |
| 12 | embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = ["defmt"] } | 12 | embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = ["defmt"] } |
| 13 | embassy-nrf = { version = "0.9.0", path = "../../embassy-nrf", features = ["defmt", "nrf54l15-app-s", "time-driver-grtc", "gpiote", "unstable-pac", "time"] } | 13 | embassy-nrf = { version = "0.9.0", path = "../../embassy-nrf", features = ["defmt", "nrf54l15-app-s", "time-driver-grtc", "gpiote", "unstable-pac", "time"] } |
| 14 | embedded-io = { version = "0.6.0", features = ["defmt-03"] } | 14 | embedded-io = { version = "0.7.0", features = ["defmt"] } |
| 15 | embedded-io-async = { version = "0.6.1", features = ["defmt-03"] } | 15 | embedded-io-async = { version = "0.7.0", features = ["defmt"] } |
| 16 | 16 | ||
| 17 | rand = { version = "0.9.0", default-features = false } | 17 | rand = { version = "0.9.0", default-features = false } |
| 18 | 18 | ||
diff --git a/examples/nrf54lm20/Cargo.toml b/examples/nrf54lm20/Cargo.toml index e3bf22b25..78ce60596 100644 --- a/examples/nrf54lm20/Cargo.toml +++ b/examples/nrf54lm20/Cargo.toml | |||
| @@ -11,8 +11,8 @@ embassy-executor = { version = "0.9.0", path = "../../embassy-executor", feature | |||
| 11 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } | 11 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } |
| 12 | embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = ["defmt"] } | 12 | embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = ["defmt"] } |
| 13 | embassy-nrf = { version = "0.9.0", path = "../../embassy-nrf", features = ["defmt", "nrf54lm20-app-s", "time-driver-grtc", "gpiote", "unstable-pac", "time"] } | 13 | embassy-nrf = { version = "0.9.0", path = "../../embassy-nrf", features = ["defmt", "nrf54lm20-app-s", "time-driver-grtc", "gpiote", "unstable-pac", "time"] } |
| 14 | embedded-io = { version = "0.6.0", features = ["defmt-03"] } | 14 | embedded-io = { version = "0.7.0", features = ["defmt"] } |
| 15 | embedded-io-async = { version = "0.6.1", features = ["defmt-03"] } | 15 | embedded-io-async = { version = "0.7.0", features = ["defmt"] } |
| 16 | 16 | ||
| 17 | rand = { version = "0.9.0", default-features = false } | 17 | rand = { version = "0.9.0", default-features = false } |
| 18 | 18 | ||
diff --git a/examples/nrf9160/Cargo.toml b/examples/nrf9160/Cargo.toml index 907b06e6d..bad7fdc79 100644 --- a/examples/nrf9160/Cargo.toml +++ b/examples/nrf9160/Cargo.toml | |||
| @@ -20,8 +20,8 @@ cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-sing | |||
| 20 | cortex-m-rt = "0.7.0" | 20 | cortex-m-rt = "0.7.0" |
| 21 | panic-probe = { version = "1.0.0", features = ["print-defmt"] } | 21 | panic-probe = { version = "1.0.0", features = ["print-defmt"] } |
| 22 | static_cell = { version = "2" } | 22 | static_cell = { version = "2" } |
| 23 | embedded-io = "0.6.1" | 23 | embedded-io = { version = "0.7.1" } |
| 24 | embedded-io-async = { version = "0.6.1", features = ["defmt-03"] } | 24 | embedded-io-async = { version = "0.7.0", features = ["defmt"] } |
| 25 | 25 | ||
| 26 | [profile.release] | 26 | [profile.release] |
| 27 | debug = 2 | 27 | debug = 2 |
diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml index e247f6f7a..1a5712dd3 100644 --- a/examples/rp/Cargo.toml +++ b/examples/rp/Cargo.toml | |||
| @@ -26,7 +26,7 @@ fixed = "1.23.1" | |||
| 26 | fixed-macro = "1.2" | 26 | fixed-macro = "1.2" |
| 27 | 27 | ||
| 28 | # for web request example | 28 | # for web request example |
| 29 | reqwless = { version = "0.13.0", features = ["defmt"] } | 29 | reqwless = { git = "https://github.com/drogue-iot/reqwless", rev = "68f703dfc16e6f7f964b7238c922c0d433118872", features = ["defmt"] } |
| 30 | serde = { version = "1.0.203", default-features = false, features = ["derive"] } | 30 | serde = { version = "1.0.203", default-features = false, features = ["derive"] } |
| 31 | serde-json-core = "0.5.1" | 31 | serde-json-core = "0.5.1" |
| 32 | 32 | ||
| @@ -50,7 +50,7 @@ usbd-hid = "0.9.0" | |||
| 50 | embedded-hal-1 = { package = "embedded-hal", version = "1.0" } | 50 | embedded-hal-1 = { package = "embedded-hal", version = "1.0" } |
| 51 | embedded-hal-async = "1.0" | 51 | embedded-hal-async = "1.0" |
| 52 | embedded-hal-bus = { version = "0.1", features = ["async"] } | 52 | embedded-hal-bus = { version = "0.1", features = ["async"] } |
| 53 | embedded-io-async = { version = "0.6.1", features = ["defmt-03"] } | 53 | embedded-io-async = { version = "0.7.0", features = ["defmt"] } |
| 54 | embedded-storage = { version = "0.3" } | 54 | embedded-storage = { version = "0.3" } |
| 55 | static_cell = "2.1" | 55 | static_cell = "2.1" |
| 56 | portable-atomic = { version = "1.5", features = ["critical-section"] } | 56 | portable-atomic = { version = "1.5", features = ["critical-section"] } |
diff --git a/examples/rp235x/Cargo.toml b/examples/rp235x/Cargo.toml index 16dfb5b77..bc2bcf5b6 100644 --- a/examples/rp235x/Cargo.toml +++ b/examples/rp235x/Cargo.toml | |||
| @@ -51,7 +51,7 @@ usbd-hid = "0.9.0" | |||
| 51 | embedded-hal-1 = { package = "embedded-hal", version = "1.0" } | 51 | embedded-hal-1 = { package = "embedded-hal", version = "1.0" } |
| 52 | embedded-hal-async = "1.0" | 52 | embedded-hal-async = "1.0" |
| 53 | embedded-hal-bus = { version = "0.1", features = ["async"] } | 53 | embedded-hal-bus = { version = "0.1", features = ["async"] } |
| 54 | embedded-io-async = { version = "0.6.1", features = ["defmt-03"] } | 54 | embedded-io-async = { version = "0.7.0", features = ["defmt"] } |
| 55 | embedded-storage = { version = "0.3" } | 55 | embedded-storage = { version = "0.3" } |
| 56 | static_cell = "2.1" | 56 | static_cell = "2.1" |
| 57 | portable-atomic = { version = "1.5", features = ["critical-section"] } | 57 | portable-atomic = { version = "1.5", features = ["critical-section"] } |
diff --git a/examples/std/Cargo.toml b/examples/std/Cargo.toml index 0e3b3c6d5..06f1ba67e 100644 --- a/examples/std/Cargo.toml +++ b/examples/std/Cargo.toml | |||
| @@ -12,8 +12,8 @@ embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["lo | |||
| 12 | embassy-net = { version = "0.7.1", path = "../../embassy-net", features=[ "log", "medium-ethernet", "medium-ip", "tcp", "udp", "dns", "dhcpv4", "proto-ipv6"] } | 12 | embassy-net = { version = "0.7.1", path = "../../embassy-net", features=[ "log", "medium-ethernet", "medium-ip", "tcp", "udp", "dns", "dhcpv4", "proto-ipv6"] } |
| 13 | embassy-net-tuntap = { version = "0.1.1", path = "../../embassy-net-tuntap" } | 13 | embassy-net-tuntap = { version = "0.1.1", path = "../../embassy-net-tuntap" } |
| 14 | embassy-net-ppp = { version = "0.2.1", path = "../../embassy-net-ppp", features = ["log"]} | 14 | embassy-net-ppp = { version = "0.2.1", path = "../../embassy-net-ppp", features = ["log"]} |
| 15 | embedded-io-async = { version = "0.6.1" } | 15 | embedded-io-async = { version = "0.7.0" } |
| 16 | embedded-io-adapters = { version = "0.6.1", features = ["futures-03"] } | 16 | embedded-io-adapters = { version = "0.7.0", features = ["futures-03"] } |
| 17 | critical-section = { version = "1.1", features = ["std"] } | 17 | critical-section = { version = "1.1", features = ["std"] } |
| 18 | 18 | ||
| 19 | async-io = "1.6.0" | 19 | async-io = "1.6.0" |
diff --git a/examples/stm32f4/Cargo.toml b/examples/stm32f4/Cargo.toml index b4555045a..5bcf66ade 100644 --- a/examples/stm32f4/Cargo.toml +++ b/examples/stm32f4/Cargo.toml | |||
| @@ -23,8 +23,8 @@ cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-sing | |||
| 23 | cortex-m-rt = "0.7.0" | 23 | cortex-m-rt = "0.7.0" |
| 24 | embedded-hal = "0.2.6" | 24 | embedded-hal = "0.2.6" |
| 25 | embedded-hal-bus = { version = "0.2", features = ["async"] } | 25 | embedded-hal-bus = { version = "0.2", features = ["async"] } |
| 26 | embedded-io = { version = "0.6.0" } | 26 | embedded-io = { version = "0.7.1" } |
| 27 | embedded-io-async = { version = "0.6.1" } | 27 | embedded-io-async = { version = "0.7.0" } |
| 28 | panic-probe = { version = "1.0.0", features = ["print-defmt"] } | 28 | panic-probe = { version = "1.0.0", features = ["print-defmt"] } |
| 29 | futures-util = { version = "0.3.30", default-features = false } | 29 | futures-util = { version = "0.3.30", default-features = false } |
| 30 | heapless = { version = "0.8", default-features = false } | 30 | heapless = { version = "0.8", default-features = false } |
diff --git a/examples/stm32f7/Cargo.toml b/examples/stm32f7/Cargo.toml index 565277394..a952b770b 100644 --- a/examples/stm32f7/Cargo.toml +++ b/examples/stm32f7/Cargo.toml | |||
| @@ -12,7 +12,7 @@ embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = ["de | |||
| 12 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] } | 12 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] } |
| 13 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } | 13 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 14 | embassy-net = { version = "0.7.1", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"] } | 14 | embassy-net = { version = "0.7.1", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"] } |
| 15 | embedded-io-async = { version = "0.6.1" } | 15 | embedded-io-async = { version = "0.7.0" } |
| 16 | embassy-usb = { version = "0.5.0", path = "../../embassy-usb", features = ["defmt"] } | 16 | embassy-usb = { version = "0.5.0", path = "../../embassy-usb", features = ["defmt"] } |
| 17 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | 17 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } |
| 18 | 18 | ||
diff --git a/examples/stm32g0/Cargo.toml b/examples/stm32g0/Cargo.toml index 16f28500d..a25a01e59 100644 --- a/examples/stm32g0/Cargo.toml +++ b/examples/stm32g0/Cargo.toml | |||
| @@ -24,7 +24,7 @@ panic-probe = { version = "1.0.0", features = ["print-defmt"] } | |||
| 24 | heapless = { version = "0.8", default-features = false } | 24 | heapless = { version = "0.8", default-features = false } |
| 25 | portable-atomic = { version = "1.5", features = ["unsafe-assume-single-core"] } | 25 | portable-atomic = { version = "1.5", features = ["unsafe-assume-single-core"] } |
| 26 | 26 | ||
| 27 | embedded-io-async = { version = "0.6.1" } | 27 | embedded-io-async = { version = "0.7.0" } |
| 28 | 28 | ||
| 29 | [profile.release] | 29 | [profile.release] |
| 30 | debug = 2 | 30 | debug = 2 |
diff --git a/examples/stm32h5/Cargo.toml b/examples/stm32h5/Cargo.toml index 512186c3d..f674a2936 100644 --- a/examples/stm32h5/Cargo.toml +++ b/examples/stm32h5/Cargo.toml | |||
| @@ -23,8 +23,8 @@ cortex-m-rt = "0.7.0" | |||
| 23 | embedded-hal = "0.2.6" | 23 | embedded-hal = "0.2.6" |
| 24 | embedded-hal-1 = { package = "embedded-hal", version = "1.0" } | 24 | embedded-hal-1 = { package = "embedded-hal", version = "1.0" } |
| 25 | embedded-hal-async = { version = "1.0" } | 25 | embedded-hal-async = { version = "1.0" } |
| 26 | embedded-io-async = { version = "0.6.1" } | 26 | embedded-io-async = { version = "0.7.0" } |
| 27 | embedded-nal-async = "0.8.0" | 27 | embedded-nal-async = "0.9.0" |
| 28 | panic-probe = { version = "1.0.0", features = ["print-defmt"] } | 28 | panic-probe = { version = "1.0.0", features = ["print-defmt"] } |
| 29 | heapless = { version = "0.8", default-features = false } | 29 | heapless = { version = "0.8", default-features = false } |
| 30 | critical-section = "1.1" | 30 | critical-section = "1.1" |
diff --git a/examples/stm32h7/Cargo.toml b/examples/stm32h7/Cargo.toml index 09b734054..8f4b2bf4f 100644 --- a/examples/stm32h7/Cargo.toml +++ b/examples/stm32h7/Cargo.toml | |||
| @@ -24,8 +24,8 @@ cortex-m-rt = "0.7.0" | |||
| 24 | embedded-hal = "0.2.6" | 24 | embedded-hal = "0.2.6" |
| 25 | embedded-hal-1 = { package = "embedded-hal", version = "1.0" } | 25 | embedded-hal-1 = { package = "embedded-hal", version = "1.0" } |
| 26 | embedded-hal-async = { version = "1.0" } | 26 | embedded-hal-async = { version = "1.0" } |
| 27 | embedded-nal-async = "0.8.0" | 27 | embedded-nal-async = "0.9.0" |
| 28 | embedded-io-async = { version = "0.6.1" } | 28 | embedded-io-async = { version = "0.7.0" } |
| 29 | panic-probe = { version = "1.0.0", features = ["print-defmt"] } | 29 | panic-probe = { version = "1.0.0", features = ["print-defmt"] } |
| 30 | heapless = { version = "0.8", default-features = false } | 30 | heapless = { version = "0.8", default-features = false } |
| 31 | critical-section = "1.1" | 31 | critical-section = "1.1" |
diff --git a/examples/stm32h723/Cargo.toml b/examples/stm32h723/Cargo.toml index 93a5109e2..8b3f8dc55 100644 --- a/examples/stm32h723/Cargo.toml +++ b/examples/stm32h723/Cargo.toml | |||
| @@ -21,8 +21,8 @@ cortex-m-rt = "0.7.0" | |||
| 21 | embedded-hal = "0.2.6" | 21 | embedded-hal = "0.2.6" |
| 22 | embedded-hal-1 = { package = "embedded-hal", version = "1.0" } | 22 | embedded-hal-1 = { package = "embedded-hal", version = "1.0" } |
| 23 | embedded-hal-async = { version = "1.0" } | 23 | embedded-hal-async = { version = "1.0" } |
| 24 | embedded-nal-async = "0.8.0" | 24 | embedded-nal-async = "0.9.0" |
| 25 | embedded-io-async = { version = "0.6.1" } | 25 | embedded-io-async = { version = "0.7.0" } |
| 26 | panic-probe = { version = "1.0.0", features = ["print-defmt"] } | 26 | panic-probe = { version = "1.0.0", features = ["print-defmt"] } |
| 27 | heapless = { version = "0.8", default-features = false } | 27 | heapless = { version = "0.8", default-features = false } |
| 28 | critical-section = "1.1" | 28 | critical-section = "1.1" |
diff --git a/examples/stm32h742/Cargo.toml b/examples/stm32h742/Cargo.toml index 9b5e5d93d..7ff4dfbe4 100644 --- a/examples/stm32h742/Cargo.toml +++ b/examples/stm32h742/Cargo.toml | |||
| @@ -33,7 +33,7 @@ embassy-net = { version = "0.7.1", path = "../../embassy-net", features = [ | |||
| 33 | "dhcpv4", | 33 | "dhcpv4", |
| 34 | "medium-ethernet", | 34 | "medium-ethernet", |
| 35 | ] } | 35 | ] } |
| 36 | embedded-io-async = { version = "0.6.1" } | 36 | embedded-io-async = { version = "0.7.0" } |
| 37 | embassy-usb = { version = "0.5.1", path = "../../embassy-usb", features = [ | 37 | embassy-usb = { version = "0.5.1", path = "../../embassy-usb", features = [ |
| 38 | "defmt", | 38 | "defmt", |
| 39 | ] } | 39 | ] } |
diff --git a/examples/stm32h755cm4/Cargo.toml b/examples/stm32h755cm4/Cargo.toml index d69f0228e..e5be0056f 100644 --- a/examples/stm32h755cm4/Cargo.toml +++ b/examples/stm32h755cm4/Cargo.toml | |||
| @@ -24,8 +24,8 @@ cortex-m-rt = "0.7.0" | |||
| 24 | embedded-hal = "0.2.6" | 24 | embedded-hal = "0.2.6" |
| 25 | embedded-hal-1 = { package = "embedded-hal", version = "1.0" } | 25 | embedded-hal-1 = { package = "embedded-hal", version = "1.0" } |
| 26 | embedded-hal-async = { version = "1.0" } | 26 | embedded-hal-async = { version = "1.0" } |
| 27 | embedded-nal-async = "0.8.0" | 27 | embedded-nal-async = "0.9.0" |
| 28 | embedded-io-async = { version = "0.6.1" } | 28 | embedded-io-async = { version = "0.7.0" } |
| 29 | panic-probe = { version = "1.0.0", features = ["print-defmt"] } | 29 | panic-probe = { version = "1.0.0", features = ["print-defmt"] } |
| 30 | heapless = { version = "0.8", default-features = false } | 30 | heapless = { version = "0.8", default-features = false } |
| 31 | critical-section = "1.1" | 31 | critical-section = "1.1" |
diff --git a/examples/stm32h755cm7/Cargo.toml b/examples/stm32h755cm7/Cargo.toml index f4e1e53b7..42c05549b 100644 --- a/examples/stm32h755cm7/Cargo.toml +++ b/examples/stm32h755cm7/Cargo.toml | |||
| @@ -24,8 +24,8 @@ cortex-m-rt = "0.7.0" | |||
| 24 | embedded-hal = "0.2.6" | 24 | embedded-hal = "0.2.6" |
| 25 | embedded-hal-1 = { package = "embedded-hal", version = "1.0" } | 25 | embedded-hal-1 = { package = "embedded-hal", version = "1.0" } |
| 26 | embedded-hal-async = { version = "1.0" } | 26 | embedded-hal-async = { version = "1.0" } |
| 27 | embedded-nal-async = "0.8.0" | 27 | embedded-nal-async = "0.9.0" |
| 28 | embedded-io-async = { version = "0.6.1" } | 28 | embedded-io-async = { version = "0.7.0" } |
| 29 | panic-probe = { version = "1.0.0", features = ["print-defmt"] } | 29 | panic-probe = { version = "1.0.0", features = ["print-defmt"] } |
| 30 | heapless = { version = "0.8", default-features = false } | 30 | heapless = { version = "0.8", default-features = false } |
| 31 | critical-section = "1.1" | 31 | critical-section = "1.1" |
diff --git a/examples/stm32h7b0/Cargo.toml b/examples/stm32h7b0/Cargo.toml index 0509d394d..434bfebce 100644 --- a/examples/stm32h7b0/Cargo.toml +++ b/examples/stm32h7b0/Cargo.toml | |||
| @@ -23,8 +23,8 @@ cortex-m-rt = "0.7.0" | |||
| 23 | embedded-hal = "0.2.6" | 23 | embedded-hal = "0.2.6" |
| 24 | embedded-hal-1 = { package = "embedded-hal", version = "1.0" } | 24 | embedded-hal-1 = { package = "embedded-hal", version = "1.0" } |
| 25 | embedded-hal-async = { version = "1.0" } | 25 | embedded-hal-async = { version = "1.0" } |
| 26 | embedded-nal-async = "0.8.0" | 26 | embedded-nal-async = "0.9.0" |
| 27 | embedded-io-async = { version = "0.6.1" } | 27 | embedded-io-async = { version = "0.7.0" } |
| 28 | panic-probe = { version = "1.0.0", features = ["print-defmt"] } | 28 | panic-probe = { version = "1.0.0", features = ["print-defmt"] } |
| 29 | heapless = { version = "0.8", default-features = false } | 29 | heapless = { version = "0.8", default-features = false } |
| 30 | critical-section = "1.1" | 30 | critical-section = "1.1" |
diff --git a/examples/stm32h7rs/Cargo.toml b/examples/stm32h7rs/Cargo.toml index ab525ad91..74664432f 100644 --- a/examples/stm32h7rs/Cargo.toml +++ b/examples/stm32h7rs/Cargo.toml | |||
| @@ -23,8 +23,8 @@ cortex-m-rt = "0.7.0" | |||
| 23 | embedded-hal = "0.2.6" | 23 | embedded-hal = "0.2.6" |
| 24 | embedded-hal-1 = { package = "embedded-hal", version = "1.0" } | 24 | embedded-hal-1 = { package = "embedded-hal", version = "1.0" } |
| 25 | embedded-hal-async = { version = "1.0" } | 25 | embedded-hal-async = { version = "1.0" } |
| 26 | embedded-nal-async = "0.8.0" | 26 | embedded-nal-async = "0.9.0" |
| 27 | embedded-io-async = { version = "0.6.1" } | 27 | embedded-io-async = { version = "0.7.0" } |
| 28 | panic-probe = { version = "1.0.0", features = ["print-defmt"] } | 28 | panic-probe = { version = "1.0.0", features = ["print-defmt"] } |
| 29 | heapless = { version = "0.8", default-features = false } | 29 | heapless = { version = "0.8", default-features = false } |
| 30 | critical-section = "1.1" | 30 | critical-section = "1.1" |
diff --git a/examples/stm32l0/Cargo.toml b/examples/stm32l0/Cargo.toml index a9c71d655..c06c761c9 100644 --- a/examples/stm32l0/Cargo.toml +++ b/examples/stm32l0/Cargo.toml | |||
| @@ -18,8 +18,8 @@ defmt = "1.0.1" | |||
| 18 | defmt-rtt = "1.0.0" | 18 | defmt-rtt = "1.0.0" |
| 19 | 19 | ||
| 20 | embedded-storage = "0.3.1" | 20 | embedded-storage = "0.3.1" |
| 21 | embedded-io = { version = "0.6.0" } | 21 | embedded-io = { version = "0.7.1" } |
| 22 | embedded-io-async = { version = "0.6.1" } | 22 | embedded-io-async = { version = "0.7.0" } |
| 23 | 23 | ||
| 24 | cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } | 24 | cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } |
| 25 | cortex-m-rt = "0.7.0" | 25 | cortex-m-rt = "0.7.0" |
diff --git a/examples/stm32l4/Cargo.toml b/examples/stm32l4/Cargo.toml index 936472199..995c8c694 100644 --- a/examples/stm32l4/Cargo.toml +++ b/examples/stm32l4/Cargo.toml | |||
| @@ -16,8 +16,8 @@ embassy-usb = { version = "0.5.0", path = "../../embassy-usb", features = ["defm | |||
| 16 | embassy-net-adin1110 = { version = "0.3.1", path = "../../embassy-net-adin1110" } | 16 | embassy-net-adin1110 = { version = "0.3.1", path = "../../embassy-net-adin1110" } |
| 17 | embassy-net = { version = "0.7.1", path = "../../embassy-net", features = ["defmt", "udp", "tcp", "dhcpv4", "medium-ethernet"] } | 17 | embassy-net = { version = "0.7.1", path = "../../embassy-net", features = ["defmt", "udp", "tcp", "dhcpv4", "medium-ethernet"] } |
| 18 | embassy-futures = { version = "0.1.2", path = "../../embassy-futures" } | 18 | embassy-futures = { version = "0.1.2", path = "../../embassy-futures" } |
| 19 | embedded-io-async = { version = "0.6.1", features = ["defmt-03"] } | 19 | embedded-io-async = { version = "0.7.0", features = ["defmt"] } |
| 20 | embedded-io = { version = "0.6.0", features = ["defmt-03"] } | 20 | embedded-io = { version = "0.7.1", features = ["defmt"] } |
| 21 | 21 | ||
| 22 | defmt = "1.0.1" | 22 | defmt = "1.0.1" |
| 23 | defmt-rtt = "1.0.0" | 23 | defmt-rtt = "1.0.0" |
diff --git a/examples/stm32l5/Cargo.toml b/examples/stm32l5/Cargo.toml index 586b00836..b6d14ce25 100644 --- a/examples/stm32l5/Cargo.toml +++ b/examples/stm32l5/Cargo.toml | |||
| @@ -24,7 +24,7 @@ cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-sing | |||
| 24 | cortex-m-rt = "0.7.0" | 24 | cortex-m-rt = "0.7.0" |
| 25 | embedded-hal = "0.2.6" | 25 | embedded-hal = "0.2.6" |
| 26 | heapless = { version = "0.8", default-features = false } | 26 | heapless = { version = "0.8", default-features = false } |
| 27 | embedded-io-async = { version = "0.6.1" } | 27 | embedded-io-async = { version = "0.7.0" } |
| 28 | static_cell = "2" | 28 | static_cell = "2" |
| 29 | 29 | ||
| 30 | [profile.release] | 30 | [profile.release] |
diff --git a/examples/stm32n6/Cargo.toml b/examples/stm32n6/Cargo.toml index 5ad5b97ce..fdfaed531 100644 --- a/examples/stm32n6/Cargo.toml +++ b/examples/stm32n6/Cargo.toml | |||
| @@ -23,7 +23,7 @@ cortex-m-rt = "0.7.0" | |||
| 23 | embedded-hal = "0.2.6" | 23 | embedded-hal = "0.2.6" |
| 24 | embedded-hal-1 = { package = "embedded-hal", version = "1.0" } | 24 | embedded-hal-1 = { package = "embedded-hal", version = "1.0" } |
| 25 | embedded-hal-async = { version = "1.0" } | 25 | embedded-hal-async = { version = "1.0" } |
| 26 | embedded-io-async = { version = "0.6.1" } | 26 | embedded-io-async = { version = "0.7.0" } |
| 27 | embedded-nal-async = "0.8.0" | 27 | embedded-nal-async = "0.8.0" |
| 28 | panic-probe = { version = "1.0.0", features = ["print-defmt"] } | 28 | panic-probe = { version = "1.0.0", features = ["print-defmt"] } |
| 29 | heapless = { version = "0.8", default-features = false } | 29 | heapless = { version = "0.8", default-features = false } |
diff --git a/examples/stm32wb/Cargo.toml b/examples/stm32wb/Cargo.toml index 83f7cb56b..496500f75 100644 --- a/examples/stm32wb/Cargo.toml +++ b/examples/stm32wb/Cargo.toml | |||
| @@ -7,10 +7,10 @@ publish = false | |||
| 7 | 7 | ||
| 8 | [dependencies] | 8 | [dependencies] |
| 9 | # Change stm32wb55rg to your chip name in both dependencies, if necessary. | 9 | # Change stm32wb55rg to your chip name in both dependencies, if necessary. |
| 10 | embassy-stm32 = { version = "0.4.0", path = "../../embassy-stm32", features = [ "defmt", "stm32wb55rg", "time-driver-any", "memory-x", "exti", "low-power"] } | 10 | embassy-stm32 = { version = "0.4.0", path = "../../embassy-stm32", features = [ "defmt", "stm32wb55rg", "time-driver-any", "memory-x", "exti", "low-power-pender"] } |
| 11 | embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", features = ["defmt", "stm32wb55rg"] } | 11 | embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", features = ["defmt", "stm32wb55rg"] } |
| 12 | embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = ["defmt"] } | 12 | embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = ["defmt"] } |
| 13 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] } | 13 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["defmt"] } |
| 14 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } | 14 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 15 | embassy-net = { version = "0.7.1", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", ], optional = true } | 15 | embassy-net = { version = "0.7.1", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", ], optional = true } |
| 16 | 16 | ||
diff --git a/examples/stm32wb/src/bin/blinky.rs b/examples/stm32wb/src/bin/blinky.rs index f37e8b1d8..e2737fcd5 100644 --- a/examples/stm32wb/src/bin/blinky.rs +++ b/examples/stm32wb/src/bin/blinky.rs | |||
| @@ -7,7 +7,7 @@ use embassy_stm32::gpio::{Level, Output, Speed}; | |||
| 7 | use embassy_time::Timer; | 7 | use embassy_time::Timer; |
| 8 | use {defmt_rtt as _, panic_probe as _}; | 8 | use {defmt_rtt as _, panic_probe as _}; |
| 9 | 9 | ||
| 10 | #[embassy_executor::main] | 10 | #[embassy_executor::main(executor = "embassy_stm32::Executor", entry = "cortex_m_rt::entry")] |
| 11 | async fn main(_spawner: Spawner) { | 11 | async fn main(_spawner: Spawner) { |
| 12 | let p = embassy_stm32::init(Default::default()); | 12 | let p = embassy_stm32::init(Default::default()); |
| 13 | info!("Hello World!"); | 13 | info!("Hello World!"); |
diff --git a/examples/stm32wb/src/bin/button_exti.rs b/examples/stm32wb/src/bin/button_exti.rs index 3c58eb556..37a207519 100644 --- a/examples/stm32wb/src/bin/button_exti.rs +++ b/examples/stm32wb/src/bin/button_exti.rs | |||
| @@ -13,7 +13,7 @@ bind_interrupts!( | |||
| 13 | EXTI4 => exti::InterruptHandler<interrupt::typelevel::EXTI4>; | 13 | EXTI4 => exti::InterruptHandler<interrupt::typelevel::EXTI4>; |
| 14 | }); | 14 | }); |
| 15 | 15 | ||
| 16 | #[embassy_executor::main] | 16 | #[embassy_executor::main(executor = "embassy_stm32::Executor", entry = "cortex_m_rt::entry")] |
| 17 | async fn main(_spawner: Spawner) { | 17 | async fn main(_spawner: Spawner) { |
| 18 | let p = embassy_stm32::init(Default::default()); | 18 | let p = embassy_stm32::init(Default::default()); |
| 19 | info!("Hello World!"); | 19 | info!("Hello World!"); |
diff --git a/examples/stm32wb/src/bin/eddystone_beacon.rs b/examples/stm32wb/src/bin/eddystone_beacon.rs index 413b1ac8f..a679e6fb1 100644 --- a/examples/stm32wb/src/bin/eddystone_beacon.rs +++ b/examples/stm32wb/src/bin/eddystone_beacon.rs | |||
| @@ -26,7 +26,7 @@ bind_interrupts!(struct Irqs{ | |||
| 26 | 26 | ||
| 27 | const BLE_GAP_DEVICE_NAME_LENGTH: u8 = 7; | 27 | const BLE_GAP_DEVICE_NAME_LENGTH: u8 = 7; |
| 28 | 28 | ||
| 29 | #[embassy_executor::main] | 29 | #[embassy_executor::main(executor = "embassy_stm32::Executor", entry = "cortex_m_rt::entry")] |
| 30 | async fn main(_spawner: Spawner) { | 30 | async fn main(_spawner: Spawner) { |
| 31 | /* | 31 | /* |
| 32 | How to make this work: | 32 | How to make this work: |
diff --git a/examples/stm32wb/src/bin/gatt_server.rs b/examples/stm32wb/src/bin/gatt_server.rs index 3484f1844..10c7fd0ba 100644 --- a/examples/stm32wb/src/bin/gatt_server.rs +++ b/examples/stm32wb/src/bin/gatt_server.rs | |||
| @@ -38,7 +38,7 @@ bind_interrupts!(struct Irqs{ | |||
| 38 | 38 | ||
| 39 | const BLE_GAP_DEVICE_NAME_LENGTH: u8 = 7; | 39 | const BLE_GAP_DEVICE_NAME_LENGTH: u8 = 7; |
| 40 | 40 | ||
| 41 | #[embassy_executor::main] | 41 | #[embassy_executor::main(executor = "embassy_stm32::Executor", entry = "cortex_m_rt::entry")] |
| 42 | async fn main(spawner: Spawner) { | 42 | async fn main(spawner: Spawner) { |
| 43 | /* | 43 | /* |
| 44 | How to make this work: | 44 | How to make this work: |
diff --git a/examples/stm32wb/src/bin/mac_ffd.rs b/examples/stm32wb/src/bin/mac_ffd.rs index 4bab6ea9f..cd15968d2 100644 --- a/examples/stm32wb/src/bin/mac_ffd.rs +++ b/examples/stm32wb/src/bin/mac_ffd.rs | |||
| @@ -23,7 +23,7 @@ async fn run_mm_queue(mut memory_manager: mm::MemoryManager<'static>) { | |||
| 23 | memory_manager.run_queue().await; | 23 | memory_manager.run_queue().await; |
| 24 | } | 24 | } |
| 25 | 25 | ||
| 26 | #[embassy_executor::main] | 26 | #[embassy_executor::main(executor = "embassy_stm32::Executor", entry = "cortex_m_rt::entry")] |
| 27 | async fn main(spawner: Spawner) { | 27 | async fn main(spawner: Spawner) { |
| 28 | /* | 28 | /* |
| 29 | How to make this work: | 29 | How to make this work: |
diff --git a/examples/stm32wb/src/bin/mac_ffd_net.rs b/examples/stm32wb/src/bin/mac_ffd_net.rs index b4789e3ee..244b35243 100644 --- a/examples/stm32wb/src/bin/mac_ffd_net.rs +++ b/examples/stm32wb/src/bin/mac_ffd_net.rs | |||
| @@ -41,7 +41,7 @@ async fn run_net(mut runner: embassy_net::Runner<'static, Driver<'static>>) -> ! | |||
| 41 | runner.run().await | 41 | runner.run().await |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | #[embassy_executor::main] | 44 | #[embassy_executor::main(executor = "embassy_stm32::Executor", entry = "cortex_m_rt::entry")] |
| 45 | async fn main(spawner: Spawner) { | 45 | async fn main(spawner: Spawner) { |
| 46 | /* | 46 | /* |
| 47 | How to make this work: | 47 | How to make this work: |
diff --git a/examples/stm32wb/src/bin/mac_rfd.rs b/examples/stm32wb/src/bin/mac_rfd.rs index dae3c5200..f3e65c66b 100644 --- a/examples/stm32wb/src/bin/mac_rfd.rs +++ b/examples/stm32wb/src/bin/mac_rfd.rs | |||
| @@ -25,7 +25,7 @@ async fn run_mm_queue(mut memory_manager: mm::MemoryManager<'static>) { | |||
| 25 | memory_manager.run_queue().await; | 25 | memory_manager.run_queue().await; |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | #[embassy_executor::main] | 28 | #[embassy_executor::main(executor = "embassy_stm32::Executor", entry = "cortex_m_rt::entry")] |
| 29 | async fn main(spawner: Spawner) { | 29 | async fn main(spawner: Spawner) { |
| 30 | /* | 30 | /* |
| 31 | How to make this work: | 31 | How to make this work: |
diff --git a/examples/stm32wb/src/bin/tl_mbox.rs b/examples/stm32wb/src/bin/tl_mbox.rs index 0902e28e8..adb6eff7b 100644 --- a/examples/stm32wb/src/bin/tl_mbox.rs +++ b/examples/stm32wb/src/bin/tl_mbox.rs | |||
| @@ -15,7 +15,7 @@ bind_interrupts!(struct Irqs{ | |||
| 15 | IPCC_C1_TX => TransmitInterruptHandler; | 15 | IPCC_C1_TX => TransmitInterruptHandler; |
| 16 | }); | 16 | }); |
| 17 | 17 | ||
| 18 | #[embassy_executor::main] | 18 | #[embassy_executor::main(executor = "embassy_stm32::Executor", entry = "cortex_m_rt::entry")] |
| 19 | async fn main(_spawner: Spawner) { | 19 | async fn main(_spawner: Spawner) { |
| 20 | /* | 20 | /* |
| 21 | How to make this work: | 21 | How to make this work: |
diff --git a/examples/stm32wb/src/bin/tl_mbox_ble.rs b/examples/stm32wb/src/bin/tl_mbox_ble.rs index 763dc32cd..376b808de 100644 --- a/examples/stm32wb/src/bin/tl_mbox_ble.rs +++ b/examples/stm32wb/src/bin/tl_mbox_ble.rs | |||
| @@ -20,7 +20,7 @@ async fn run_mm_queue(mut memory_manager: mm::MemoryManager<'static>) { | |||
| 20 | memory_manager.run_queue().await; | 20 | memory_manager.run_queue().await; |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | #[embassy_executor::main] | 23 | #[embassy_executor::main(executor = "embassy_stm32::Executor", entry = "cortex_m_rt::entry")] |
| 24 | async fn main(spawner: Spawner) { | 24 | async fn main(spawner: Spawner) { |
| 25 | /* | 25 | /* |
| 26 | How to make this work: | 26 | How to make this work: |
diff --git a/examples/stm32wb/src/bin/tl_mbox_mac.rs b/examples/stm32wb/src/bin/tl_mbox_mac.rs index 235a48241..697e061c1 100644 --- a/examples/stm32wb/src/bin/tl_mbox_mac.rs +++ b/examples/stm32wb/src/bin/tl_mbox_mac.rs | |||
| @@ -20,7 +20,7 @@ async fn run_mm_queue(mut memory_manager: mm::MemoryManager<'static>) { | |||
| 20 | memory_manager.run_queue().await; | 20 | memory_manager.run_queue().await; |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | #[embassy_executor::main] | 23 | #[embassy_executor::main(executor = "embassy_stm32::Executor", entry = "cortex_m_rt::entry")] |
| 24 | async fn main(spawner: Spawner) { | 24 | async fn main(spawner: Spawner) { |
| 25 | /* | 25 | /* |
| 26 | How to make this work: | 26 | How to make this work: |
diff --git a/examples/stm32wle5/Cargo.toml b/examples/stm32wle5/Cargo.toml index f2fc4dd3d..64c81c761 100644 --- a/examples/stm32wle5/Cargo.toml +++ b/examples/stm32wle5/Cargo.toml | |||
| @@ -15,7 +15,7 @@ embassy-embedded-hal = { version = "0.5.0", path = "../../embassy-embedded-hal" | |||
| 15 | 15 | ||
| 16 | defmt = "1.0.1" | 16 | defmt = "1.0.1" |
| 17 | defmt-rtt = { version = "1.1.0", optional = true } | 17 | defmt-rtt = { version = "1.1.0", optional = true } |
| 18 | defmt-serial = { version = "0.10.0", optional = true } | 18 | defmt-serial = { git = "https://github.com/gauteh/defmt-serial", rev = "411ae7fa909b4fd2667885aff687e009b9108190", optional = true } |
| 19 | 19 | ||
| 20 | cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } | 20 | cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } |
| 21 | cortex-m-rt = "0.7.0" | 21 | cortex-m-rt = "0.7.0" |
diff --git a/tests/mspm0/Cargo.toml b/tests/mspm0/Cargo.toml index df52b538d..56b027feb 100644 --- a/tests/mspm0/Cargo.toml +++ b/tests/mspm0/Cargo.toml | |||
| @@ -26,8 +26,8 @@ cortex-m = { version = "0.7.6", features = [ "inline-asm", "critical-section-sin | |||
| 26 | cortex-m-rt = "0.7.0" | 26 | cortex-m-rt = "0.7.0" |
| 27 | embedded-hal = { package = "embedded-hal", version = "1.0" } | 27 | embedded-hal = { package = "embedded-hal", version = "1.0" } |
| 28 | embedded-hal-async = { version = "1.0" } | 28 | embedded-hal-async = { version = "1.0" } |
| 29 | embedded-io = { version = "0.6.1", features = ["defmt-03"] } | 29 | embedded-io = { version = "0.7.1", features = ["defmt"] } |
| 30 | embedded-io-async = { version = "0.6.1", features = ["defmt-03"] } | 30 | embedded-io-async = { version = "0.7.0", features = ["defmt"] } |
| 31 | panic-probe = { version = "1.0.0", features = ["print-defmt"] } | 31 | panic-probe = { version = "1.0.0", features = ["print-defmt"] } |
| 32 | static_cell = "2" | 32 | static_cell = "2" |
| 33 | portable-atomic = { version = "1.5", features = ["critical-section"] } | 33 | portable-atomic = { version = "1.5", features = ["critical-section"] } |
diff --git a/tests/nrf/Cargo.toml b/tests/nrf/Cargo.toml index 50f059b34..b1e0a68c2 100644 --- a/tests/nrf/Cargo.toml +++ b/tests/nrf/Cargo.toml | |||
| @@ -13,7 +13,7 @@ embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = ["de | |||
| 13 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] } | 13 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] } |
| 14 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } | 14 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } |
| 15 | embassy-nrf = { version = "0.9.0", path = "../../embassy-nrf", features = ["defmt", "time-driver-rtc1", "gpiote", "unstable-pac"] } | 15 | embassy-nrf = { version = "0.9.0", path = "../../embassy-nrf", features = ["defmt", "time-driver-rtc1", "gpiote", "unstable-pac"] } |
| 16 | embedded-io-async = { version = "0.6.1", features = ["defmt-03"] } | 16 | embedded-io-async = { version = "0.7.0", features = ["defmt"] } |
| 17 | embassy-net = { version = "0.7.1", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", ] } | 17 | embassy-net = { version = "0.7.1", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", ] } |
| 18 | embassy-net-esp-hosted = { version = "0.2.1", path = "../../embassy-net-esp-hosted", features = ["defmt"] } | 18 | embassy-net-esp-hosted = { version = "0.2.1", path = "../../embassy-net-esp-hosted", features = ["defmt"] } |
| 19 | embassy-net-enc28j60 = { version = "0.2.1", path = "../../embassy-net-enc28j60", features = ["defmt"] } | 19 | embassy-net-enc28j60 = { version = "0.2.1", path = "../../embassy-net-enc28j60", features = ["defmt"] } |
diff --git a/tests/rp/Cargo.toml b/tests/rp/Cargo.toml index 4dfe6904e..375a613d2 100644 --- a/tests/rp/Cargo.toml +++ b/tests/rp/Cargo.toml | |||
| @@ -35,7 +35,7 @@ embedded-hal-1 = { package = "embedded-hal", version = "1.0" } | |||
| 35 | embedded-hal-async = { version = "1.0" } | 35 | embedded-hal-async = { version = "1.0" } |
| 36 | embedded-hal-bus = { version = "0.1", features = ["async"] } | 36 | embedded-hal-bus = { version = "0.1", features = ["async"] } |
| 37 | panic-probe = { version = "1.0.0", features = ["print-defmt"] } | 37 | panic-probe = { version = "1.0.0", features = ["print-defmt"] } |
| 38 | embedded-io-async = { version = "0.6.1" } | 38 | embedded-io-async = { version = "0.7.0" } |
| 39 | embedded-storage = { version = "0.3" } | 39 | embedded-storage = { version = "0.3" } |
| 40 | static_cell = "2" | 40 | static_cell = "2" |
| 41 | portable-atomic = { version = "1.5", features = ["critical-section"] } | 41 | portable-atomic = { version = "1.5", features = ["critical-section"] } |
diff --git a/tests/stm32/src/bin/stop.rs b/tests/stm32/src/bin/stop.rs index 83c375bc5..75dacbe7e 100644 --- a/tests/stm32/src/bin/stop.rs +++ b/tests/stm32/src/bin/stop.rs | |||
| @@ -60,10 +60,12 @@ async fn async_main(spawner: Spawner) { | |||
| 60 | 60 | ||
| 61 | let (rtc, _time_provider) = Rtc::new(p.RTC); | 61 | let (rtc, _time_provider) = Rtc::new(p.RTC); |
| 62 | 62 | ||
| 63 | info!("set datetime"); | ||
| 63 | critical_section::with(|cs| { | 64 | critical_section::with(|cs| { |
| 64 | rtc.borrow_mut(cs).set_datetime(now.into()).expect("datetime not set"); | 65 | rtc.borrow_mut(cs).set_datetime(now.into()).expect("datetime not set"); |
| 65 | }); | 66 | }); |
| 66 | 67 | ||
| 68 | info!("spawn"); | ||
| 67 | spawner.spawn(task_1().unwrap()); | 69 | spawner.spawn(task_1().unwrap()); |
| 68 | spawner.spawn(task_2().unwrap()); | 70 | spawner.spawn(task_2().unwrap()); |
| 69 | } | 71 | } |
