diff options
163 files changed, 3045 insertions, 1072 deletions
diff --git a/.vscode/settings.json b/.vscode/settings.json index 73dfa53a4..2b99a313d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | // "examples/mspm0c1104/Cargo.toml", | 34 | // "examples/mspm0c1104/Cargo.toml", |
| 35 | // "examples/mspm0g3507/Cargo.toml", | 35 | // "examples/mspm0g3507/Cargo.toml", |
| 36 | // "examples/mspm0g3519/Cargo.toml", | 36 | // "examples/mspm0g3519/Cargo.toml", |
| 37 | // "examples/mspm0g5187/Cargo.toml", | ||
| 37 | // "examples/mspm0l1306/Cargo.toml", | 38 | // "examples/mspm0l1306/Cargo.toml", |
| 38 | // "examples/mspm0l2228/Cargo.toml", | 39 | // "examples/mspm0l2228/Cargo.toml", |
| 39 | // "examples/nrf52840-rtic/Cargo.toml", | 40 | // "examples/nrf52840-rtic/Cargo.toml", |
| @@ -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/docs/examples/basic/Cargo.toml b/docs/examples/basic/Cargo.toml index fadda102b..495e484f8 100644 --- a/docs/examples/basic/Cargo.toml +++ b/docs/examples/basic/Cargo.toml | |||
| @@ -9,7 +9,7 @@ publish = false | |||
| 9 | [dependencies] | 9 | [dependencies] |
| 10 | embassy-executor = { version = "0.9.0", path = "../../../embassy-executor", features = ["defmt", "arch-cortex-m", "executor-thread"] } | 10 | embassy-executor = { version = "0.9.0", path = "../../../embassy-executor", features = ["defmt", "arch-cortex-m", "executor-thread"] } |
| 11 | embassy-time = { version = "0.5.0", path = "../../../embassy-time", features = ["defmt"] } | 11 | embassy-time = { version = "0.5.0", path = "../../../embassy-time", features = ["defmt"] } |
| 12 | embassy-nrf = { version = "0.8.0", path = "../../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote"] } | 12 | embassy-nrf = { version = "0.9.0", path = "../../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote"] } |
| 13 | 13 | ||
| 14 | defmt = "1.0.1" | 14 | defmt = "1.0.1" |
| 15 | defmt-rtt = "1.0.0" | 15 | defmt-rtt = "1.0.0" |
diff --git a/embassy-boot-nrf/CHANGELOG.md b/embassy-boot-nrf/CHANGELOG.md index 54b7c8067..5bf8cf4b0 100644 --- a/embassy-boot-nrf/CHANGELOG.md +++ b/embassy-boot-nrf/CHANGELOG.md | |||
| @@ -8,6 +8,10 @@ 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 | ## 0.10.0 - 2025-12-15 | ||
| 12 | |||
| 13 | - Bumped embassy-nrf to 0.9.0 | ||
| 14 | |||
| 11 | ## 0.9.0 - 2025-09-30 | 15 | ## 0.9.0 - 2025-09-30 |
| 12 | 16 | ||
| 13 | - Bumped embassy-nrf to 0.8.0 | 17 | - Bumped embassy-nrf to 0.8.0 |
diff --git a/embassy-boot-nrf/Cargo.toml b/embassy-boot-nrf/Cargo.toml index 787a28d70..4f6d9ed2e 100644 --- a/embassy-boot-nrf/Cargo.toml +++ b/embassy-boot-nrf/Cargo.toml | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | [package] | 1 | [package] |
| 2 | edition = "2024" | 2 | edition = "2024" |
| 3 | name = "embassy-boot-nrf" | 3 | name = "embassy-boot-nrf" |
| 4 | version = "0.9.0" | 4 | version = "0.10.0" |
| 5 | description = "Bootloader lib for nRF chips" | 5 | description = "Bootloader lib for nRF chips" |
| 6 | license = "MIT OR Apache-2.0" | 6 | license = "MIT OR Apache-2.0" |
| 7 | repository = "https://github.com/embassy-rs/embassy" | 7 | repository = "https://github.com/embassy-rs/embassy" |
| @@ -36,7 +36,7 @@ defmt = { version = "1.0.1", optional = true } | |||
| 36 | log = { version = "0.4.17", optional = true } | 36 | log = { version = "0.4.17", optional = true } |
| 37 | 37 | ||
| 38 | embassy-sync = { version = "0.7.2", path = "../embassy-sync" } | 38 | embassy-sync = { version = "0.7.2", path = "../embassy-sync" } |
| 39 | embassy-nrf = { version = "0.8.0", path = "../embassy-nrf", default-features = false } | 39 | embassy-nrf = { version = "0.9.0", path = "../embassy-nrf", default-features = false } |
| 40 | embassy-boot = { version = "0.6.1", path = "../embassy-boot" } | 40 | embassy-boot = { version = "0.6.1", path = "../embassy-boot" } |
| 41 | cortex-m = { version = "0.7.6" } | 41 | cortex-m = { version = "0.7.6" } |
| 42 | cortex-m-rt = { version = "0.7" } | 42 | cortex-m-rt = { version = "0.7" } |
diff --git a/embassy-executor/CHANGELOG.md b/embassy-executor/CHANGELOG.md index 8f1db7de7..cc4027fca 100644 --- a/embassy-executor/CHANGELOG.md +++ b/embassy-executor/CHANGELOG.md | |||
| @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |||
| 16 | - Migrate `cortex-ar` to `aarch32-cpu`. The feature name `arch-cortex-ar` remains the same and | 16 | - Migrate `cortex-ar` to `aarch32-cpu`. The feature name `arch-cortex-ar` remains the same and |
| 17 | legacy ARM architectures are not supported. | 17 | legacy ARM architectures are not supported. |
| 18 | - Added `run_until` to `arch-std` variant of `Executor`. | 18 | - Added `run_until` to `arch-std` variant of `Executor`. |
| 19 | - Added `__try_embassy_time_queue_item_from_waker` | ||
| 19 | 20 | ||
| 20 | ## 0.9.1 - 2025-08-31 | 21 | ## 0.9.1 - 2025-08-31 |
| 21 | 22 | ||
diff --git a/embassy-executor/src/raw/mod.rs b/embassy-executor/src/raw/mod.rs index ab845ed3b..2b7560de6 100644 --- a/embassy-executor/src/raw/mod.rs +++ b/embassy-executor/src/raw/mod.rs | |||
| @@ -49,6 +49,7 @@ use self::run_queue::{RunQueue, RunQueueItem}; | |||
| 49 | use self::state::State; | 49 | use self::state::State; |
| 50 | use self::util::{SyncUnsafeCell, UninitCell}; | 50 | use self::util::{SyncUnsafeCell, UninitCell}; |
| 51 | pub use self::waker::task_from_waker; | 51 | pub use self::waker::task_from_waker; |
| 52 | use self::waker::try_task_from_waker; | ||
| 52 | use super::SpawnToken; | 53 | use super::SpawnToken; |
| 53 | use crate::{Metadata, SpawnError}; | 54 | use crate::{Metadata, SpawnError}; |
| 54 | 55 | ||
| @@ -57,6 +58,11 @@ extern "Rust" fn __embassy_time_queue_item_from_waker(waker: &Waker) -> &'static | |||
| 57 | unsafe { task_from_waker(waker).timer_queue_item() } | 58 | unsafe { task_from_waker(waker).timer_queue_item() } |
| 58 | } | 59 | } |
| 59 | 60 | ||
| 61 | #[unsafe(no_mangle)] | ||
| 62 | extern "Rust" fn __try_embassy_time_queue_item_from_waker(waker: &Waker) -> Option<&'static mut TimerQueueItem> { | ||
| 63 | unsafe { try_task_from_waker(waker).map(|task| task.timer_queue_item()) } | ||
| 64 | } | ||
| 65 | |||
| 60 | /// Raw task header for use in task pointers. | 66 | /// Raw task header for use in task pointers. |
| 61 | /// | 67 | /// |
| 62 | /// A task can be in one of the following states: | 68 | /// A task can be in one of the following states: |
diff --git a/embassy-executor/src/raw/waker.rs b/embassy-executor/src/raw/waker.rs index 2706f0fdf..8416f9f93 100644 --- a/embassy-executor/src/raw/waker.rs +++ b/embassy-executor/src/raw/waker.rs | |||
| @@ -32,13 +32,18 @@ pub(crate) unsafe fn from_task(p: TaskRef) -> Waker { | |||
| 32 | /// | 32 | /// |
| 33 | /// Panics if the waker is not created by the Embassy executor. | 33 | /// Panics if the waker is not created by the Embassy executor. |
| 34 | pub fn task_from_waker(waker: &Waker) -> TaskRef { | 34 | pub fn task_from_waker(waker: &Waker) -> TaskRef { |
| 35 | unwrap!( | ||
| 36 | try_task_from_waker(waker), | ||
| 37 | "Found waker not created by the Embassy executor. Unless the generic timer queue is enabled, `embassy_time::Timer` only works with the Embassy executor." | ||
| 38 | ) | ||
| 39 | } | ||
| 40 | |||
| 41 | pub(crate) fn try_task_from_waker(waker: &Waker) -> Option<TaskRef> { | ||
| 35 | // make sure to compare vtable addresses. Doing `==` on the references | 42 | // make sure to compare vtable addresses. Doing `==` on the references |
| 36 | // will compare the contents, which is slower. | 43 | // will compare the contents, which is slower. |
| 37 | if waker.vtable() as *const _ != &VTABLE as *const _ { | 44 | if waker.vtable() as *const _ != &VTABLE as *const _ { |
| 38 | panic!( | 45 | return None; |
| 39 | "Found waker not created by the Embassy executor. `embassy_time::Timer` only works with the Embassy executor." | ||
| 40 | ) | ||
| 41 | } | 46 | } |
| 42 | // safety: our wakers are always created with `TaskRef::as_ptr` | 47 | // safety: our wakers are always created with `TaskRef::as_ptr` |
| 43 | unsafe { TaskRef::from_ptr(waker.data() as *const TaskHeader) } | 48 | Some(unsafe { TaskRef::from_ptr(waker.data() as *const TaskHeader) }) |
| 44 | } | 49 | } |
diff --git a/embassy-executor/src/raw/waker_turbo.rs b/embassy-executor/src/raw/waker_turbo.rs index 919bcc61a..ee33e7633 100644 --- a/embassy-executor/src/raw/waker_turbo.rs +++ b/embassy-executor/src/raw/waker_turbo.rs | |||
| @@ -25,6 +25,10 @@ pub fn task_from_waker(waker: &Waker) -> TaskRef { | |||
| 25 | unsafe { TaskRef::from_ptr(ptr as *const TaskHeader) } | 25 | unsafe { TaskRef::from_ptr(ptr as *const TaskHeader) } |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | pub(crate) fn try_task_from_waker(waker: &Waker) -> Option<TaskRef> { | ||
| 29 | Some(task_from_waker(waker)) | ||
| 30 | } | ||
| 31 | |||
| 28 | #[inline(never)] | 32 | #[inline(never)] |
| 29 | #[unsafe(no_mangle)] | 33 | #[unsafe(no_mangle)] |
| 30 | fn _turbo_wake(ptr: NonNull<()>) { | 34 | fn _turbo_wake(ptr: NonNull<()>) { |
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-imxrt/src/dma.rs b/embassy-imxrt/src/dma.rs index e71a27e0e..eaa09870d 100644 --- a/embassy-imxrt/src/dma.rs +++ b/embassy-imxrt/src/dma.rs | |||
| @@ -16,6 +16,8 @@ use crate::peripherals::DMA0; | |||
| 16 | use crate::sealed::Sealed; | 16 | use crate::sealed::Sealed; |
| 17 | use crate::{BitIter, interrupt, pac, peripherals}; | 17 | use crate::{BitIter, interrupt, pac, peripherals}; |
| 18 | 18 | ||
| 19 | pub(crate) const MAX_CHUNK_SIZE: usize = 1024; | ||
| 20 | |||
| 19 | #[cfg(feature = "rt")] | 21 | #[cfg(feature = "rt")] |
| 20 | #[interrupt] | 22 | #[interrupt] |
| 21 | fn DMA0() { | 23 | fn DMA0() { |
| @@ -69,7 +71,7 @@ pub(crate) unsafe fn init() { | |||
| 69 | /// | 71 | /// |
| 70 | /// SAFETY: Slice must point to a valid location reachable by DMA. | 72 | /// SAFETY: Slice must point to a valid location reachable by DMA. |
| 71 | pub unsafe fn read<'a, C: Channel, W: Word>(ch: Peri<'a, C>, from: *const W, to: *mut [W]) -> Transfer<'a, C> { | 73 | pub unsafe fn read<'a, C: Channel, W: Word>(ch: Peri<'a, C>, from: *const W, to: *mut [W]) -> Transfer<'a, C> { |
| 72 | let count = ((to.len() / W::size() as usize) - 1) as isize; | 74 | let count = (to.len().div_ceil(W::size() as usize) - 1) as isize; |
| 73 | 75 | ||
| 74 | copy_inner( | 76 | copy_inner( |
| 75 | ch, | 77 | ch, |
| @@ -87,7 +89,7 @@ pub unsafe fn read<'a, C: Channel, W: Word>(ch: Peri<'a, C>, from: *const W, to: | |||
| 87 | /// | 89 | /// |
| 88 | /// SAFETY: Slice must point to a valid location reachable by DMA. | 90 | /// SAFETY: Slice must point to a valid location reachable by DMA. |
| 89 | pub unsafe fn write<'a, C: Channel, W: Word>(ch: Peri<'a, C>, from: *const [W], to: *mut W) -> Transfer<'a, C> { | 91 | pub unsafe fn write<'a, C: Channel, W: Word>(ch: Peri<'a, C>, from: *const [W], to: *mut W) -> Transfer<'a, C> { |
| 90 | let count = ((from.len() / W::size() as usize) - 1) as isize; | 92 | let count = (from.len().div_ceil(W::size() as usize) - 1) as isize; |
| 91 | 93 | ||
| 92 | copy_inner( | 94 | copy_inner( |
| 93 | ch, | 95 | ch, |
| @@ -109,7 +111,7 @@ pub unsafe fn copy<'a, C: Channel, W: Word>(ch: Peri<'a, C>, from: &[W], to: &mu | |||
| 109 | let to_len = to.len(); | 111 | let to_len = to.len(); |
| 110 | assert_eq!(from_len, to_len); | 112 | assert_eq!(from_len, to_len); |
| 111 | 113 | ||
| 112 | let count = ((from_len / W::size() as usize) - 1) as isize; | 114 | let count = (from_len.div_ceil(W::size() as usize) - 1) as isize; |
| 113 | 115 | ||
| 114 | copy_inner( | 116 | copy_inner( |
| 115 | ch, | 117 | ch, |
diff --git a/embassy-imxrt/src/flexcomm/uart.rs b/embassy-imxrt/src/flexcomm/uart.rs index 2b759ba84..d13b32e93 100644 --- a/embassy-imxrt/src/flexcomm/uart.rs +++ b/embassy-imxrt/src/flexcomm/uart.rs | |||
| @@ -598,7 +598,7 @@ impl<'a> UartTx<'a, Async> { | |||
| 598 | regs.fifocfg().modify(|_, w| w.dmatx().disabled()); | 598 | regs.fifocfg().modify(|_, w| w.dmatx().disabled()); |
| 599 | }); | 599 | }); |
| 600 | 600 | ||
| 601 | for chunk in buf.chunks(1024) { | 601 | for chunk in buf.chunks(dma::MAX_CHUNK_SIZE) { |
| 602 | regs.fifocfg().modify(|_, w| w.dmatx().enabled()); | 602 | regs.fifocfg().modify(|_, w| w.dmatx().enabled()); |
| 603 | 603 | ||
| 604 | let ch = self.tx_dma.as_mut().unwrap().reborrow(); | 604 | let ch = self.tx_dma.as_mut().unwrap().reborrow(); |
| @@ -726,7 +726,7 @@ impl<'a> UartRx<'a, Async> { | |||
| 726 | regs.fifocfg().modify(|_, w| w.dmarx().disabled()); | 726 | regs.fifocfg().modify(|_, w| w.dmarx().disabled()); |
| 727 | }); | 727 | }); |
| 728 | 728 | ||
| 729 | for chunk in buf.chunks_mut(1024) { | 729 | for chunk in buf.chunks_mut(dma::MAX_CHUNK_SIZE) { |
| 730 | regs.fifocfg().modify(|_, w| w.dmarx().enabled()); | 730 | regs.fifocfg().modify(|_, w| w.dmarx().enabled()); |
| 731 | 731 | ||
| 732 | let ch = self.rx_dma.as_mut().unwrap().reborrow(); | 732 | let ch = self.rx_dma.as_mut().unwrap().reborrow(); |
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/CHANGELOG.md b/embassy-mspm0/CHANGELOG.md index 6972a8472..19275f35a 100644 --- a/embassy-mspm0/CHANGELOG.md +++ b/embassy-mspm0/CHANGELOG.md | |||
| @@ -19,4 +19,5 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |||
| 19 | - feat: Add i2c target implementation (#4605) | 19 | - feat: Add i2c target implementation (#4605) |
| 20 | - fix: group irq handlers must check for NO_INTR (#4785) | 20 | - fix: group irq handlers must check for NO_INTR (#4785) |
| 21 | - feat: Add read_reset_cause function | 21 | - feat: Add read_reset_cause function |
| 22 | - feat: Add module Mathacl & example for mspm0g3507 (#4897) \ No newline at end of file | 22 | - feat: Add module Mathacl & example for mspm0g3507 (#4897) |
| 23 | - feat: Add MSPM0G5187 supportt | ||
diff --git a/embassy-mspm0/Cargo.toml b/embassy-mspm0/Cargo.toml index 254e0209b..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" |
| @@ -73,7 +73,7 @@ critical-section = "1.2.0" | |||
| 73 | micromath = "2.0.0" | 73 | micromath = "2.0.0" |
| 74 | 74 | ||
| 75 | # mspm0-metapac = { version = "" } | 75 | # mspm0-metapac = { version = "" } |
| 76 | mspm0-metapac = { git = "https://github.com/mspm0-rs/mspm0-data-generated/", tag = "mspm0-data-f21b04e9de074af4965bf67ec3646cb9fe1b9852" } | 76 | mspm0-metapac = { git = "https://github.com/mspm0-rs/mspm0-data-generated/", tag = "mspm0-data-e91edd86813aa94cbb6737d34e4f1d22b8487cb6" } |
| 77 | 77 | ||
| 78 | [build-dependencies] | 78 | [build-dependencies] |
| 79 | proc-macro2 = "1.0.94" | 79 | proc-macro2 = "1.0.94" |
| @@ -81,7 +81,7 @@ quote = "1.0.40" | |||
| 81 | cfg_aliases = "0.2.1" | 81 | cfg_aliases = "0.2.1" |
| 82 | 82 | ||
| 83 | # mspm0-metapac = { version = "", default-features = false, features = ["metadata"] } | 83 | # mspm0-metapac = { version = "", default-features = false, features = ["metadata"] } |
| 84 | mspm0-metapac = { git = "https://github.com/mspm0-rs/mspm0-data-generated/", tag = "mspm0-data-f21b04e9de074af4965bf67ec3646cb9fe1b9852", default-features = false, features = ["metadata"] } | 84 | mspm0-metapac = { git = "https://github.com/mspm0-rs/mspm0-data-generated/", tag = "mspm0-data-e91edd86813aa94cbb6737d34e4f1d22b8487cb6", default-features = false, features = ["metadata"] } |
| 85 | 85 | ||
| 86 | [features] | 86 | [features] |
| 87 | default = ["rt"] | 87 | default = ["rt"] |
| @@ -153,15 +153,14 @@ time-driver-tima1 = ["_time-driver"] | |||
| 153 | #! | 153 | #! |
| 154 | #! **Important:** Do not forget to adapt the target chip in your toolchain, | 154 | #! **Important:** Do not forget to adapt the target chip in your toolchain, |
| 155 | #! e.g. in `.cargo/config.toml`. | 155 | #! e.g. in `.cargo/config.toml`. |
| 156 | |||
| 157 | mspm0c1103dgs20 = ["mspm0-metapac/mspm0c1103dgs20"] | 156 | mspm0c1103dgs20 = ["mspm0-metapac/mspm0c1103dgs20"] |
| 158 | mspm0c1103dsg = ["mspm0-metapac/mspm0c1103dsg"] | ||
| 159 | mspm0c1103dyy = ["mspm0-metapac/mspm0c1103dyy"] | ||
| 160 | mspm0c1103ruk = ["mspm0-metapac/mspm0c1103ruk"] | 157 | mspm0c1103ruk = ["mspm0-metapac/mspm0c1103ruk"] |
| 158 | mspm0c1103dyy = ["mspm0-metapac/mspm0c1103dyy"] | ||
| 159 | mspm0c1103dsg = ["mspm0-metapac/mspm0c1103dsg"] | ||
| 161 | mspm0c1104dgs20 = ["mspm0-metapac/mspm0c1104dgs20"] | 160 | mspm0c1104dgs20 = ["mspm0-metapac/mspm0c1104dgs20"] |
| 162 | mspm0c1104dsg = ["mspm0-metapac/mspm0c1104dsg"] | ||
| 163 | mspm0c1104dyy = ["mspm0-metapac/mspm0c1104dyy"] | ||
| 164 | mspm0c1104ruk = ["mspm0-metapac/mspm0c1104ruk"] | 161 | mspm0c1104ruk = ["mspm0-metapac/mspm0c1104ruk"] |
| 162 | mspm0c1104dyy = ["mspm0-metapac/mspm0c1104dyy"] | ||
| 163 | mspm0c1104dsg = ["mspm0-metapac/mspm0c1104dsg"] | ||
| 165 | mspm0c1104ycj = ["mspm0-metapac/mspm0c1104ycj"] | 164 | mspm0c1104ycj = ["mspm0-metapac/mspm0c1104ycj"] |
| 166 | mspm0c1105pt = ["mspm0-metapac/mspm0c1105pt"] | 165 | mspm0c1105pt = ["mspm0-metapac/mspm0c1105pt"] |
| 167 | mspm0c1105rgz = ["mspm0-metapac/mspm0c1105rgz"] | 166 | mspm0c1105rgz = ["mspm0-metapac/mspm0c1105rgz"] |
| @@ -181,43 +180,54 @@ mspm0c1106rge = ["mspm0-metapac/mspm0c1106rge"] | |||
| 181 | mspm0c1106dgs20 = ["mspm0-metapac/mspm0c1106dgs20"] | 180 | mspm0c1106dgs20 = ["mspm0-metapac/mspm0c1106dgs20"] |
| 182 | mspm0c1106ruk = ["mspm0-metapac/mspm0c1106ruk"] | 181 | mspm0c1106ruk = ["mspm0-metapac/mspm0c1106ruk"] |
| 183 | mspm0c1106zcm = ["mspm0-metapac/mspm0c1106zcm"] | 182 | mspm0c1106zcm = ["mspm0-metapac/mspm0c1106zcm"] |
| 184 | mspm0g1105dgs28 = ["mspm0-metapac/mspm0g1105dgs28"] | ||
| 185 | mspm0g1105pm = ["mspm0-metapac/mspm0g1105pm"] | ||
| 186 | mspm0g1105pt = ["mspm0-metapac/mspm0g1105pt"] | ||
| 187 | mspm0g1105rge = ["mspm0-metapac/mspm0g1105rge"] | 183 | mspm0g1105rge = ["mspm0-metapac/mspm0g1105rge"] |
| 188 | mspm0g1105rgz = ["mspm0-metapac/mspm0g1105rgz"] | 184 | mspm0g1105dgs28 = ["mspm0-metapac/mspm0g1105dgs28"] |
| 189 | mspm0g1105rhb = ["mspm0-metapac/mspm0g1105rhb"] | 185 | mspm0g1105rhb = ["mspm0-metapac/mspm0g1105rhb"] |
| 190 | mspm0g1106dgs28 = ["mspm0-metapac/mspm0g1106dgs28"] | 186 | mspm0g1105rgz = ["mspm0-metapac/mspm0g1105rgz"] |
| 191 | mspm0g1106pm = ["mspm0-metapac/mspm0g1106pm"] | 187 | mspm0g1105pt = ["mspm0-metapac/mspm0g1105pt"] |
| 192 | mspm0g1106pt = ["mspm0-metapac/mspm0g1106pt"] | 188 | mspm0g1105pm = ["mspm0-metapac/mspm0g1105pm"] |
| 193 | mspm0g1106rge = ["mspm0-metapac/mspm0g1106rge"] | 189 | mspm0g1106rge = ["mspm0-metapac/mspm0g1106rge"] |
| 194 | mspm0g1106rgz = ["mspm0-metapac/mspm0g1106rgz"] | 190 | mspm0g1106dgs28 = ["mspm0-metapac/mspm0g1106dgs28"] |
| 195 | mspm0g1106rhb = ["mspm0-metapac/mspm0g1106rhb"] | 191 | mspm0g1106rhb = ["mspm0-metapac/mspm0g1106rhb"] |
| 196 | mspm0g1107dgs28 = ["mspm0-metapac/mspm0g1107dgs28"] | 192 | mspm0g1106rgz = ["mspm0-metapac/mspm0g1106rgz"] |
| 197 | mspm0g1107pm = ["mspm0-metapac/mspm0g1107pm"] | 193 | mspm0g1106pt = ["mspm0-metapac/mspm0g1106pt"] |
| 198 | mspm0g1107pt = ["mspm0-metapac/mspm0g1107pt"] | 194 | mspm0g1106pm = ["mspm0-metapac/mspm0g1106pm"] |
| 199 | mspm0g1107rge = ["mspm0-metapac/mspm0g1107rge"] | 195 | mspm0g1107rge = ["mspm0-metapac/mspm0g1107rge"] |
| 200 | mspm0g1107rgz = ["mspm0-metapac/mspm0g1107rgz"] | 196 | mspm0g1107dgs28 = ["mspm0-metapac/mspm0g1107dgs28"] |
| 201 | mspm0g1107rhb = ["mspm0-metapac/mspm0g1107rhb"] | 197 | mspm0g1107rhb = ["mspm0-metapac/mspm0g1107rhb"] |
| 198 | mspm0g1107rgz = ["mspm0-metapac/mspm0g1107rgz"] | ||
| 199 | mspm0g1107pt = ["mspm0-metapac/mspm0g1107pt"] | ||
| 200 | mspm0g1107pm = ["mspm0-metapac/mspm0g1107pm"] | ||
| 202 | mspm0g1107ycj = ["mspm0-metapac/mspm0g1107ycj"] | 201 | mspm0g1107ycj = ["mspm0-metapac/mspm0g1107ycj"] |
| 203 | mspm0g1505pm = ["mspm0-metapac/mspm0g1505pm"] | ||
| 204 | mspm0g1505pt = ["mspm0-metapac/mspm0g1505pt"] | ||
| 205 | mspm0g1505rge = ["mspm0-metapac/mspm0g1505rge"] | 202 | mspm0g1505rge = ["mspm0-metapac/mspm0g1505rge"] |
| 206 | mspm0g1505rgz = ["mspm0-metapac/mspm0g1505rgz"] | ||
| 207 | mspm0g1505rhb = ["mspm0-metapac/mspm0g1505rhb"] | 203 | mspm0g1505rhb = ["mspm0-metapac/mspm0g1505rhb"] |
| 208 | mspm0g1506pm = ["mspm0-metapac/mspm0g1506pm"] | 204 | mspm0g1505rgz = ["mspm0-metapac/mspm0g1505rgz"] |
| 209 | mspm0g1506pt = ["mspm0-metapac/mspm0g1506pt"] | 205 | mspm0g1505pt = ["mspm0-metapac/mspm0g1505pt"] |
| 206 | mspm0g1505pm = ["mspm0-metapac/mspm0g1505pm"] | ||
| 210 | mspm0g1506rge = ["mspm0-metapac/mspm0g1506rge"] | 207 | mspm0g1506rge = ["mspm0-metapac/mspm0g1506rge"] |
| 211 | mspm0g1506rgz = ["mspm0-metapac/mspm0g1506rgz"] | ||
| 212 | mspm0g1506rhb = ["mspm0-metapac/mspm0g1506rhb"] | 208 | mspm0g1506rhb = ["mspm0-metapac/mspm0g1506rhb"] |
| 213 | mspm0g1507pm = ["mspm0-metapac/mspm0g1507pm"] | 209 | mspm0g1506rgz = ["mspm0-metapac/mspm0g1506rgz"] |
| 214 | mspm0g1507pt = ["mspm0-metapac/mspm0g1507pt"] | 210 | mspm0g1506pt = ["mspm0-metapac/mspm0g1506pt"] |
| 211 | mspm0g1506pm = ["mspm0-metapac/mspm0g1506pm"] | ||
| 215 | mspm0g1507rge = ["mspm0-metapac/mspm0g1507rge"] | 212 | mspm0g1507rge = ["mspm0-metapac/mspm0g1507rge"] |
| 216 | mspm0g1507rgz = ["mspm0-metapac/mspm0g1507rgz"] | ||
| 217 | mspm0g1507rhb = ["mspm0-metapac/mspm0g1507rhb"] | 213 | mspm0g1507rhb = ["mspm0-metapac/mspm0g1507rhb"] |
| 214 | mspm0g1507rgz = ["mspm0-metapac/mspm0g1507rgz"] | ||
| 215 | mspm0g1507pt = ["mspm0-metapac/mspm0g1507pt"] | ||
| 216 | mspm0g1507pm = ["mspm0-metapac/mspm0g1507pm"] | ||
| 218 | mspm0g1507ycj = ["mspm0-metapac/mspm0g1507ycj"] | 217 | mspm0g1507ycj = ["mspm0-metapac/mspm0g1507ycj"] |
| 219 | mspm0g1519rgz = ["mspm0-metapac/mspm0g1519rgz"] | 218 | mspm0g1518rhb = ["mspm0-metapac/mspm0g1518rhb"] |
| 219 | mspm0g1518rgz = ["mspm0-metapac/mspm0g1518rgz"] | ||
| 220 | mspm0g1518pt = ["mspm0-metapac/mspm0g1518pt"] | ||
| 221 | mspm0g1518pm = ["mspm0-metapac/mspm0g1518pm"] | ||
| 222 | mspm0g1518pz = ["mspm0-metapac/mspm0g1518pz"] | ||
| 223 | mspm0g1518pn = ["mspm0-metapac/mspm0g1518pn"] | ||
| 224 | mspm0g1518zaw = ["mspm0-metapac/mspm0g1518zaw"] | ||
| 220 | mspm0g1519rhb = ["mspm0-metapac/mspm0g1519rhb"] | 225 | mspm0g1519rhb = ["mspm0-metapac/mspm0g1519rhb"] |
| 226 | mspm0g1519rgz = ["mspm0-metapac/mspm0g1519rgz"] | ||
| 227 | mspm0g1519pt = ["mspm0-metapac/mspm0g1519pt"] | ||
| 228 | mspm0g1519pm = ["mspm0-metapac/mspm0g1519pm"] | ||
| 229 | mspm0g1519pz = ["mspm0-metapac/mspm0g1519pz"] | ||
| 230 | mspm0g1519pn = ["mspm0-metapac/mspm0g1519pn"] | ||
| 221 | mspm0g3105dgs20 = ["mspm0-metapac/mspm0g3105dgs20"] | 231 | mspm0g3105dgs20 = ["mspm0-metapac/mspm0g3105dgs20"] |
| 222 | mspm0g3105dgs28 = ["mspm0-metapac/mspm0g3105dgs28"] | 232 | mspm0g3105dgs28 = ["mspm0-metapac/mspm0g3105dgs28"] |
| 223 | mspm0g3105rhb = ["mspm0-metapac/mspm0g3105rhb"] | 233 | mspm0g3105rhb = ["mspm0-metapac/mspm0g3105rhb"] |
| @@ -228,77 +238,92 @@ mspm0g3107dgs20 = ["mspm0-metapac/mspm0g3107dgs20"] | |||
| 228 | mspm0g3107dgs28 = ["mspm0-metapac/mspm0g3107dgs28"] | 238 | mspm0g3107dgs28 = ["mspm0-metapac/mspm0g3107dgs28"] |
| 229 | mspm0g3107rhb = ["mspm0-metapac/mspm0g3107rhb"] | 239 | mspm0g3107rhb = ["mspm0-metapac/mspm0g3107rhb"] |
| 230 | mspm0g3505dgs28 = ["mspm0-metapac/mspm0g3505dgs28"] | 240 | mspm0g3505dgs28 = ["mspm0-metapac/mspm0g3505dgs28"] |
| 231 | mspm0g3505pm = ["mspm0-metapac/mspm0g3505pm"] | ||
| 232 | mspm0g3505pt = ["mspm0-metapac/mspm0g3505pt"] | ||
| 233 | mspm0g3505rgz = ["mspm0-metapac/mspm0g3505rgz"] | ||
| 234 | mspm0g3505rhb = ["mspm0-metapac/mspm0g3505rhb"] | 241 | mspm0g3505rhb = ["mspm0-metapac/mspm0g3505rhb"] |
| 242 | mspm0g3505rgz = ["mspm0-metapac/mspm0g3505rgz"] | ||
| 243 | mspm0g3505pt = ["mspm0-metapac/mspm0g3505pt"] | ||
| 244 | mspm0g3505pm = ["mspm0-metapac/mspm0g3505pm"] | ||
| 235 | mspm0g3506dgs28 = ["mspm0-metapac/mspm0g3506dgs28"] | 245 | mspm0g3506dgs28 = ["mspm0-metapac/mspm0g3506dgs28"] |
| 236 | mspm0g3506pm = ["mspm0-metapac/mspm0g3506pm"] | ||
| 237 | mspm0g3506pt = ["mspm0-metapac/mspm0g3506pt"] | ||
| 238 | mspm0g3506rgz = ["mspm0-metapac/mspm0g3506rgz"] | ||
| 239 | mspm0g3506rhb = ["mspm0-metapac/mspm0g3506rhb"] | 246 | mspm0g3506rhb = ["mspm0-metapac/mspm0g3506rhb"] |
| 247 | mspm0g3506rgz = ["mspm0-metapac/mspm0g3506rgz"] | ||
| 248 | mspm0g3506pt = ["mspm0-metapac/mspm0g3506pt"] | ||
| 249 | mspm0g3506pm = ["mspm0-metapac/mspm0g3506pm"] | ||
| 240 | mspm0g3507dgs28 = ["mspm0-metapac/mspm0g3507dgs28"] | 250 | mspm0g3507dgs28 = ["mspm0-metapac/mspm0g3507dgs28"] |
| 241 | mspm0g3507pm = ["mspm0-metapac/mspm0g3507pm"] | ||
| 242 | mspm0g3507pt = ["mspm0-metapac/mspm0g3507pt"] | ||
| 243 | mspm0g3507rgz = ["mspm0-metapac/mspm0g3507rgz"] | ||
| 244 | mspm0g3507rhb = ["mspm0-metapac/mspm0g3507rhb"] | 251 | mspm0g3507rhb = ["mspm0-metapac/mspm0g3507rhb"] |
| 252 | mspm0g3507rgz = ["mspm0-metapac/mspm0g3507rgz"] | ||
| 253 | mspm0g3507pt = ["mspm0-metapac/mspm0g3507pt"] | ||
| 254 | mspm0g3507pm = ["mspm0-metapac/mspm0g3507pm"] | ||
| 255 | mspm0g3518rhb = ["mspm0-metapac/mspm0g3518rhb"] | ||
| 256 | mspm0g3518rgz = ["mspm0-metapac/mspm0g3518rgz"] | ||
| 257 | mspm0g3518pt = ["mspm0-metapac/mspm0g3518pt"] | ||
| 258 | mspm0g3518pm = ["mspm0-metapac/mspm0g3518pm"] | ||
| 259 | mspm0g3518pz = ["mspm0-metapac/mspm0g3518pz"] | ||
| 260 | mspm0g3518pn = ["mspm0-metapac/mspm0g3518pn"] | ||
| 261 | mspm0g3519rhb = ["mspm0-metapac/mspm0g3519rhb"] | ||
| 262 | mspm0g3519rgz = ["mspm0-metapac/mspm0g3519rgz"] | ||
| 263 | mspm0g3519pt = ["mspm0-metapac/mspm0g3519pt"] | ||
| 245 | mspm0g3519pm = ["mspm0-metapac/mspm0g3519pm"] | 264 | mspm0g3519pm = ["mspm0-metapac/mspm0g3519pm"] |
| 246 | mspm0g3519pn = ["mspm0-metapac/mspm0g3519pn"] | ||
| 247 | mspm0g3519pz = ["mspm0-metapac/mspm0g3519pz"] | 265 | mspm0g3519pz = ["mspm0-metapac/mspm0g3519pz"] |
| 248 | mspm0g3519rgz = ["mspm0-metapac/mspm0g3519rgz"] | 266 | mspm0g3519pn = ["mspm0-metapac/mspm0g3519pn"] |
| 249 | mspm0g3519rhb = ["mspm0-metapac/mspm0g3519rhb"] | 267 | mspm0g3519zaw = ["mspm0-metapac/mspm0g3519zaw"] |
| 268 | mspm0g5187rhb = ["mspm0-metapac/mspm0g5187rhb"] | ||
| 269 | mspm0g5187rgz = ["mspm0-metapac/mspm0g5187rgz"] | ||
| 270 | mspm0g5187pt = ["mspm0-metapac/mspm0g5187pt"] | ||
| 271 | mspm0g5187pm = ["mspm0-metapac/mspm0g5187pm"] | ||
| 272 | mspm0g5187ruy = ["mspm0-metapac/mspm0g5187ruy"] | ||
| 273 | mspm0g5187ycj = ["mspm0-metapac/mspm0g5187ycj"] | ||
| 274 | mspm0g5187rge = ["mspm0-metapac/mspm0g5187rge"] | ||
| 250 | mspm0h3216pt = ["mspm0-metapac/mspm0h3216pt"] | 275 | mspm0h3216pt = ["mspm0-metapac/mspm0h3216pt"] |
| 251 | mspm0l1105dgs20 = ["mspm0-metapac/mspm0l1105dgs20"] | 276 | mspm0l1105dgs20 = ["mspm0-metapac/mspm0l1105dgs20"] |
| 252 | mspm0l1105dgs28 = ["mspm0-metapac/mspm0l1105dgs28"] | 277 | mspm0l1105dgs28 = ["mspm0-metapac/mspm0l1105dgs28"] |
| 253 | mspm0l1105dyy = ["mspm0-metapac/mspm0l1105dyy"] | ||
| 254 | mspm0l1105rge = ["mspm0-metapac/mspm0l1105rge"] | 278 | mspm0l1105rge = ["mspm0-metapac/mspm0l1105rge"] |
| 255 | mspm0l1105rtr = ["mspm0-metapac/mspm0l1105rtr"] | 279 | mspm0l1105rtr = ["mspm0-metapac/mspm0l1105rtr"] |
| 280 | mspm0l1105dyy = ["mspm0-metapac/mspm0l1105dyy"] | ||
| 281 | mspm0l1106rhb = ["mspm0-metapac/mspm0l1106rhb"] | ||
| 256 | mspm0l1106dgs20 = ["mspm0-metapac/mspm0l1106dgs20"] | 282 | mspm0l1106dgs20 = ["mspm0-metapac/mspm0l1106dgs20"] |
| 257 | mspm0l1106dgs28 = ["mspm0-metapac/mspm0l1106dgs28"] | 283 | mspm0l1106dgs28 = ["mspm0-metapac/mspm0l1106dgs28"] |
| 258 | mspm0l1106dyy = ["mspm0-metapac/mspm0l1106dyy"] | ||
| 259 | mspm0l1106rge = ["mspm0-metapac/mspm0l1106rge"] | 284 | mspm0l1106rge = ["mspm0-metapac/mspm0l1106rge"] |
| 260 | mspm0l1106rhb = ["mspm0-metapac/mspm0l1106rhb"] | ||
| 261 | mspm0l1106rtr = ["mspm0-metapac/mspm0l1106rtr"] | 285 | mspm0l1106rtr = ["mspm0-metapac/mspm0l1106rtr"] |
| 262 | mspm0l1227pm = ["mspm0-metapac/mspm0l1227pm"] | 286 | mspm0l1106dyy = ["mspm0-metapac/mspm0l1106dyy"] |
| 287 | mspm0l1227rhb = ["mspm0-metapac/mspm0l1227rhb"] | ||
| 263 | mspm0l1227pn = ["mspm0-metapac/mspm0l1227pn"] | 288 | mspm0l1227pn = ["mspm0-metapac/mspm0l1227pn"] |
| 289 | mspm0l1227rgz = ["mspm0-metapac/mspm0l1227rgz"] | ||
| 264 | mspm0l1227pt = ["mspm0-metapac/mspm0l1227pt"] | 290 | mspm0l1227pt = ["mspm0-metapac/mspm0l1227pt"] |
| 291 | mspm0l1227pm = ["mspm0-metapac/mspm0l1227pm"] | ||
| 265 | mspm0l1227rge = ["mspm0-metapac/mspm0l1227rge"] | 292 | mspm0l1227rge = ["mspm0-metapac/mspm0l1227rge"] |
| 266 | mspm0l1227rgz = ["mspm0-metapac/mspm0l1227rgz"] | 293 | mspm0l1228rhb = ["mspm0-metapac/mspm0l1228rhb"] |
| 267 | mspm0l1227rhb = ["mspm0-metapac/mspm0l1227rhb"] | ||
| 268 | mspm0l1228pm = ["mspm0-metapac/mspm0l1228pm"] | ||
| 269 | mspm0l1228pn = ["mspm0-metapac/mspm0l1228pn"] | 294 | mspm0l1228pn = ["mspm0-metapac/mspm0l1228pn"] |
| 295 | mspm0l1228rgz = ["mspm0-metapac/mspm0l1228rgz"] | ||
| 270 | mspm0l1228pt = ["mspm0-metapac/mspm0l1228pt"] | 296 | mspm0l1228pt = ["mspm0-metapac/mspm0l1228pt"] |
| 297 | mspm0l1228pm = ["mspm0-metapac/mspm0l1228pm"] | ||
| 271 | mspm0l1228rge = ["mspm0-metapac/mspm0l1228rge"] | 298 | mspm0l1228rge = ["mspm0-metapac/mspm0l1228rge"] |
| 272 | mspm0l1228rgz = ["mspm0-metapac/mspm0l1228rgz"] | ||
| 273 | mspm0l1228rhb = ["mspm0-metapac/mspm0l1228rhb"] | ||
| 274 | mspm0l1303rge = ["mspm0-metapac/mspm0l1303rge"] | 299 | mspm0l1303rge = ["mspm0-metapac/mspm0l1303rge"] |
| 300 | mspm0l1304rhb = ["mspm0-metapac/mspm0l1304rhb"] | ||
| 275 | mspm0l1304dgs20 = ["mspm0-metapac/mspm0l1304dgs20"] | 301 | mspm0l1304dgs20 = ["mspm0-metapac/mspm0l1304dgs20"] |
| 276 | mspm0l1304dgs28 = ["mspm0-metapac/mspm0l1304dgs28"] | 302 | mspm0l1304dgs28 = ["mspm0-metapac/mspm0l1304dgs28"] |
| 277 | mspm0l1304dyy = ["mspm0-metapac/mspm0l1304dyy"] | ||
| 278 | mspm0l1304rge = ["mspm0-metapac/mspm0l1304rge"] | 303 | mspm0l1304rge = ["mspm0-metapac/mspm0l1304rge"] |
| 279 | mspm0l1304rhb = ["mspm0-metapac/mspm0l1304rhb"] | ||
| 280 | mspm0l1304rtr = ["mspm0-metapac/mspm0l1304rtr"] | 304 | mspm0l1304rtr = ["mspm0-metapac/mspm0l1304rtr"] |
| 305 | mspm0l1304dyy = ["mspm0-metapac/mspm0l1304dyy"] | ||
| 281 | mspm0l1305dgs20 = ["mspm0-metapac/mspm0l1305dgs20"] | 306 | mspm0l1305dgs20 = ["mspm0-metapac/mspm0l1305dgs20"] |
| 282 | mspm0l1305dgs28 = ["mspm0-metapac/mspm0l1305dgs28"] | 307 | mspm0l1305dgs28 = ["mspm0-metapac/mspm0l1305dgs28"] |
| 283 | mspm0l1305dyy = ["mspm0-metapac/mspm0l1305dyy"] | ||
| 284 | mspm0l1305rge = ["mspm0-metapac/mspm0l1305rge"] | 308 | mspm0l1305rge = ["mspm0-metapac/mspm0l1305rge"] |
| 285 | mspm0l1305rtr = ["mspm0-metapac/mspm0l1305rtr"] | 309 | mspm0l1305rtr = ["mspm0-metapac/mspm0l1305rtr"] |
| 310 | mspm0l1305dyy = ["mspm0-metapac/mspm0l1305dyy"] | ||
| 311 | mspm0l1306rhb = ["mspm0-metapac/mspm0l1306rhb"] | ||
| 286 | mspm0l1306dgs20 = ["mspm0-metapac/mspm0l1306dgs20"] | 312 | mspm0l1306dgs20 = ["mspm0-metapac/mspm0l1306dgs20"] |
| 287 | mspm0l1306dgs28 = ["mspm0-metapac/mspm0l1306dgs28"] | 313 | mspm0l1306dgs28 = ["mspm0-metapac/mspm0l1306dgs28"] |
| 288 | mspm0l1306dyy = ["mspm0-metapac/mspm0l1306dyy"] | ||
| 289 | mspm0l1306rge = ["mspm0-metapac/mspm0l1306rge"] | 314 | mspm0l1306rge = ["mspm0-metapac/mspm0l1306rge"] |
| 290 | mspm0l1306rhb = ["mspm0-metapac/mspm0l1306rhb"] | 315 | mspm0l1306dyy = ["mspm0-metapac/mspm0l1306dyy"] |
| 291 | mspm0l1343dgs20 = ["mspm0-metapac/mspm0l1343dgs20"] | 316 | mspm0l1343dgs20 = ["mspm0-metapac/mspm0l1343dgs20"] |
| 292 | mspm0l1344dgs20 = ["mspm0-metapac/mspm0l1344dgs20"] | 317 | mspm0l1344dgs20 = ["mspm0-metapac/mspm0l1344dgs20"] |
| 293 | mspm0l1345dgs28 = ["mspm0-metapac/mspm0l1345dgs28"] | 318 | mspm0l1345dgs28 = ["mspm0-metapac/mspm0l1345dgs28"] |
| 294 | mspm0l1346dgs28 = ["mspm0-metapac/mspm0l1346dgs28"] | 319 | mspm0l1346dgs28 = ["mspm0-metapac/mspm0l1346dgs28"] |
| 320 | mspm0l2227rgz = ["mspm0-metapac/mspm0l2227rgz"] | ||
| 321 | mspm0l2227pt = ["mspm0-metapac/mspm0l2227pt"] | ||
| 295 | mspm0l2227pm = ["mspm0-metapac/mspm0l2227pm"] | 322 | mspm0l2227pm = ["mspm0-metapac/mspm0l2227pm"] |
| 296 | mspm0l2227pn = ["mspm0-metapac/mspm0l2227pn"] | 323 | mspm0l2227pn = ["mspm0-metapac/mspm0l2227pn"] |
| 297 | mspm0l2227pt = ["mspm0-metapac/mspm0l2227pt"] | 324 | mspm0l2228rgz = ["mspm0-metapac/mspm0l2228rgz"] |
| 298 | mspm0l2227rgz = ["mspm0-metapac/mspm0l2227rgz"] | 325 | mspm0l2228pt = ["mspm0-metapac/mspm0l2228pt"] |
| 299 | mspm0l2228pm = ["mspm0-metapac/mspm0l2228pm"] | 326 | mspm0l2228pm = ["mspm0-metapac/mspm0l2228pm"] |
| 300 | mspm0l2228pn = ["mspm0-metapac/mspm0l2228pn"] | 327 | mspm0l2228pn = ["mspm0-metapac/mspm0l2228pn"] |
| 301 | mspm0l2228pt = ["mspm0-metapac/mspm0l2228pt"] | ||
| 302 | mspm0l2228rgz = ["mspm0-metapac/mspm0l2228rgz"] | ||
| 303 | msps003f3pw20 = ["mspm0-metapac/msps003f3pw20"] | 328 | msps003f3pw20 = ["mspm0-metapac/msps003f3pw20"] |
| 304 | msps003f4pw20 = ["mspm0-metapac/msps003f4pw20"] | 329 | msps003f4pw20 = ["mspm0-metapac/msps003f4pw20"] \ No newline at end of file |
diff --git a/embassy-mspm0/build.rs b/embassy-mspm0/build.rs index 0fe056c4e..ac40adbdf 100644 --- a/embassy-mspm0/build.rs +++ b/embassy-mspm0/build.rs | |||
| @@ -31,7 +31,7 @@ fn generate_code(cfgs: &mut CfgSet) { | |||
| 31 | PathBuf::from(env::var_os("OUT_DIR").unwrap()).display(), | 31 | PathBuf::from(env::var_os("OUT_DIR").unwrap()).display(), |
| 32 | ); | 32 | ); |
| 33 | 33 | ||
| 34 | cfgs.declare_all(&["gpio_pb", "gpio_pc", "int_group1"]); | 34 | cfgs.declare_all(&["gpio_pb", "gpio_pc", "int_group1", "unicomm"]); |
| 35 | 35 | ||
| 36 | let chip_name = match env::vars() | 36 | let chip_name = match env::vars() |
| 37 | .map(|(a, _)| a) | 37 | .map(|(a, _)| a) |
| @@ -116,6 +116,10 @@ fn get_chip_cfgs(chip_name: &str) -> Vec<String> { | |||
| 116 | cfgs.push("mspm0g351x".to_string()); | 116 | cfgs.push("mspm0g351x".to_string()); |
| 117 | } | 117 | } |
| 118 | 118 | ||
| 119 | if chip_name.starts_with("mspm0g518") { | ||
| 120 | cfgs.push("mspm0g518x".to_string()); | ||
| 121 | } | ||
| 122 | |||
| 119 | if chip_name.starts_with("mspm0h321") { | 123 | if chip_name.starts_with("mspm0h321") { |
| 120 | cfgs.push("mspm0h321x".to_string()); | 124 | cfgs.push("mspm0h321x".to_string()); |
| 121 | } | 125 | } |
| @@ -300,6 +304,15 @@ fn get_singletons(cfgs: &mut common::CfgSet) -> Vec<Singleton> { | |||
| 300 | // by the HAL. | 304 | // by the HAL. |
| 301 | "iomux" | "cpuss" => true, | 305 | "iomux" | "cpuss" => true, |
| 302 | 306 | ||
| 307 | // Unicomm instances get their own singletons, but we need to enable a cfg for unicomm drivers. | ||
| 308 | "unicomm" => { | ||
| 309 | cfgs.enable("unicomm"); | ||
| 310 | false | ||
| 311 | } | ||
| 312 | |||
| 313 | // TODO: Remove after TIMB is fixed | ||
| 314 | "tim" if peripheral.name.starts_with("TIMB") => true, | ||
| 315 | |||
| 303 | _ => false, | 316 | _ => false, |
| 304 | }; | 317 | }; |
| 305 | 318 | ||
| @@ -423,6 +436,8 @@ fn time_driver(singletons: &mut Vec<Singleton>, cfgs: &mut CfgSet) { | |||
| 423 | // Verify the selected timer is available | 436 | // Verify the selected timer is available |
| 424 | let selected_timer = match time_driver.as_ref().map(|x| x.as_ref()) { | 437 | let selected_timer = match time_driver.as_ref().map(|x| x.as_ref()) { |
| 425 | None => "", | 438 | None => "", |
| 439 | // TODO: Fix TIMB0 | ||
| 440 | // Some("timb0") => "TIMB0", | ||
| 426 | Some("timg0") => "TIMG0", | 441 | Some("timg0") => "TIMG0", |
| 427 | Some("timg1") => "TIMG1", | 442 | Some("timg1") => "TIMG1", |
| 428 | Some("timg2") => "TIMG2", | 443 | Some("timg2") => "TIMG2", |
| @@ -440,16 +455,17 @@ fn time_driver(singletons: &mut Vec<Singleton>, cfgs: &mut CfgSet) { | |||
| 440 | Some("tima1") => "TIMA1", | 455 | Some("tima1") => "TIMA1", |
| 441 | Some("any") => { | 456 | Some("any") => { |
| 442 | // Order of timer candidates: | 457 | // Order of timer candidates: |
| 443 | // 1. 16-bit, 2 channel | 458 | // 1. Basic timers |
| 444 | // 2. 16-bit, 2 channel with shadow registers | 459 | // 2. 16-bit, 2 channel |
| 445 | // 3. 16-bit, 4 channel | 460 | // 3. 16-bit, 2 channel with shadow registers |
| 446 | // 4. 16-bit with QEI | 461 | // 4. 16-bit, 4 channel |
| 447 | // 5. Advanced timers | 462 | // 5. 16-bit with QEI |
| 463 | // 6. Advanced timers | ||
| 448 | // | 464 | // |
| 449 | // TODO: Select RTC first if available | ||
| 450 | // TODO: 32-bit timers are not considered yet | 465 | // TODO: 32-bit timers are not considered yet |
| 451 | [ | 466 | [ |
| 452 | // 16-bit, 2 channel | 467 | // basic timers. No PWM pins |
| 468 | // "TIMB0", // 16-bit, 2 channel | ||
| 453 | "TIMG0", "TIMG1", "TIMG2", "TIMG3", // 16-bit, 2 channel with shadow registers | 469 | "TIMG0", "TIMG1", "TIMG2", "TIMG3", // 16-bit, 2 channel with shadow registers |
| 454 | "TIMG4", "TIMG5", "TIMG6", "TIMG7", // 16-bit, 4 channel | 470 | "TIMG4", "TIMG5", "TIMG6", "TIMG7", // 16-bit, 4 channel |
| 455 | "TIMG14", // 16-bit with QEI | 471 | "TIMG14", // 16-bit with QEI |
| @@ -519,6 +535,8 @@ fn generate_timers() -> TokenStream { | |||
| 519 | .peripherals | 535 | .peripherals |
| 520 | .iter() | 536 | .iter() |
| 521 | .filter(|p| p.name.starts_with("TIM")) | 537 | .filter(|p| p.name.starts_with("TIM")) |
| 538 | // TODO: Fix TIMB when used at time driver. | ||
| 539 | .filter(|p| !p.name.starts_with("TIMB")) | ||
| 522 | .map(|peripheral| { | 540 | .map(|peripheral| { |
| 523 | let name = Ident::new(&peripheral.name, Span::call_site()); | 541 | let name = Ident::new(&peripheral.name, Span::call_site()); |
| 524 | let timers = &*TIMERS; | 542 | let timers = &*TIMERS; |
| @@ -730,6 +748,24 @@ struct TimerDesc { | |||
| 730 | const TIMERS: LazyLock<HashMap<String, TimerDesc>> = LazyLock::new(|| { | 748 | const TIMERS: LazyLock<HashMap<String, TimerDesc>> = LazyLock::new(|| { |
| 731 | let mut map = HashMap::new(); | 749 | let mut map = HashMap::new(); |
| 732 | map.insert( | 750 | map.insert( |
| 751 | "TIMB0".into(), | ||
| 752 | TimerDesc { | ||
| 753 | bits: 16, | ||
| 754 | prescaler: true, | ||
| 755 | repeat_counter: false, | ||
| 756 | ccp_channels_internal: 2, | ||
| 757 | ccp_channels_external: 2, | ||
| 758 | external_pwm_channels: 0, | ||
| 759 | phase_load: false, | ||
| 760 | shadow_load: false, | ||
| 761 | shadow_ccs: false, | ||
| 762 | deadband: false, | ||
| 763 | fault_handler: false, | ||
| 764 | qei_hall: false, | ||
| 765 | }, | ||
| 766 | ); | ||
| 767 | |||
| 768 | map.insert( | ||
| 733 | "TIMG0".into(), | 769 | "TIMG0".into(), |
| 734 | TimerDesc { | 770 | TimerDesc { |
| 735 | bits: 16, | 771 | bits: 16, |
diff --git a/embassy-mspm0/src/gpio.rs b/embassy-mspm0/src/gpio.rs index d8eb42dc2..709102c59 100644 --- a/embassy-mspm0/src/gpio.rs +++ b/embassy-mspm0/src/gpio.rs | |||
| @@ -841,6 +841,7 @@ impl<'d> embedded_hal_async::digital::Wait for OutputOpenDrain<'d> { | |||
| 841 | } | 841 | } |
| 842 | } | 842 | } |
| 843 | 843 | ||
| 844 | #[cfg_attr(mspm0g518x, allow(dead_code))] | ||
| 844 | #[derive(Copy, Clone)] | 845 | #[derive(Copy, Clone)] |
| 845 | pub struct PfType { | 846 | pub struct PfType { |
| 846 | pull: Pull, | 847 | pull: Pull, |
| @@ -948,6 +949,7 @@ pub(crate) trait SealedPin { | |||
| 948 | }); | 949 | }); |
| 949 | } | 950 | } |
| 950 | 951 | ||
| 952 | #[cfg_attr(mspm0g518x, allow(dead_code))] | ||
| 951 | fn update_pf(&self, ty: PfType) { | 953 | fn update_pf(&self, ty: PfType) { |
| 952 | let pincm = pac::IOMUX.pincm(self._pin_cm() as usize); | 954 | let pincm = pac::IOMUX.pincm(self._pin_cm() as usize); |
| 953 | let pf = pincm.read().pf(); | 955 | let pf = pincm.read().pf(); |
| @@ -955,6 +957,7 @@ pub(crate) trait SealedPin { | |||
| 955 | set_pf(self._pin_cm() as usize, pf, ty); | 957 | set_pf(self._pin_cm() as usize, pf, ty); |
| 956 | } | 958 | } |
| 957 | 959 | ||
| 960 | #[cfg_attr(mspm0g518x, allow(dead_code))] | ||
| 958 | fn set_as_pf(&self, pf: u8, ty: PfType) { | 961 | fn set_as_pf(&self, pf: u8, ty: PfType) { |
| 959 | set_pf(self._pin_cm() as usize, pf, ty) | 962 | set_pf(self._pin_cm() as usize, pf, ty) |
| 960 | } | 963 | } |
| @@ -967,6 +970,7 @@ pub(crate) trait SealedPin { | |||
| 967 | /// | 970 | /// |
| 968 | /// Note that this also disables the internal weak pull-up and pull-down resistors. | 971 | /// Note that this also disables the internal weak pull-up and pull-down resistors. |
| 969 | #[inline] | 972 | #[inline] |
| 973 | #[cfg_attr(mspm0g518x, allow(dead_code))] | ||
| 970 | fn set_as_disconnected(&self) { | 974 | fn set_as_disconnected(&self) { |
| 971 | self.set_as_analog(); | 975 | self.set_as_analog(); |
| 972 | } | 976 | } |
diff --git a/embassy-mspm0/src/i2c_target.rs b/embassy-mspm0/src/i2c_target.rs index 86be91415..e371fa903 100644 --- a/embassy-mspm0/src/i2c_target.rs +++ b/embassy-mspm0/src/i2c_target.rs | |||
| @@ -12,12 +12,13 @@ use embassy_embedded_hal::SetConfig; | |||
| 12 | use mspm0_metapac::i2c::vals::CpuIntIidxStat; | 12 | use mspm0_metapac::i2c::vals::CpuIntIidxStat; |
| 13 | 13 | ||
| 14 | use crate::gpio::{AnyPin, SealedPin}; | 14 | use crate::gpio::{AnyPin, SealedPin}; |
| 15 | use crate::interrupt::InterruptExt; | ||
| 16 | use crate::mode::{Async, Blocking, Mode}; | ||
| 17 | use crate::pac::{self, i2c::vals}; | ||
| 18 | use crate::{i2c, i2c_target, interrupt, Peri}; | ||
| 19 | // Re-use I2c controller types | 15 | // Re-use I2c controller types |
| 20 | use crate::i2c::{ClockSel, ConfigError, Info, Instance, InterruptHandler, SclPin, SdaPin, State}; | 16 | use crate::i2c::{ClockSel, ConfigError, Info, Instance, InterruptHandler, SclPin, SdaPin, State}; |
| 17 | use crate::interrupt::InterruptExt; | ||
| 18 | use crate::mode::{Async, Blocking, Mode}; | ||
| 19 | use crate::pac::i2c::vals; | ||
| 20 | use crate::pac::{self}; | ||
| 21 | use crate::{Peri, i2c, i2c_target, interrupt}; | ||
| 21 | 22 | ||
| 22 | #[non_exhaustive] | 23 | #[non_exhaustive] |
| 23 | #[derive(Clone, Copy, PartialEq, Eq, Debug)] | 24 | #[derive(Clone, Copy, PartialEq, Eq, Debug)] |
diff --git a/embassy-mspm0/src/lib.rs b/embassy-mspm0/src/lib.rs index c43c81853..548fb33ca 100644 --- a/embassy-mspm0/src/lib.rs +++ b/embassy-mspm0/src/lib.rs | |||
| @@ -8,20 +8,23 @@ | |||
| 8 | )] | 8 | )] |
| 9 | #![doc = include_str!("../README.md")] | 9 | #![doc = include_str!("../README.md")] |
| 10 | 10 | ||
| 11 | // This mod MUST go first, so that the others see its macros. | 11 | // These mods MUST go first, so that the others see the macros. |
| 12 | pub(crate) mod fmt; | 12 | pub(crate) mod fmt; |
| 13 | |||
| 14 | // This must be declared early as well for | ||
| 15 | mod macros; | 13 | mod macros; |
| 16 | 14 | ||
| 17 | pub mod adc; | 15 | pub mod adc; |
| 18 | pub mod dma; | 16 | pub mod dma; |
| 19 | pub mod gpio; | 17 | pub mod gpio; |
| 18 | // TODO: I2C unicomm | ||
| 19 | #[cfg(not(unicomm))] | ||
| 20 | pub mod i2c; | 20 | pub mod i2c; |
| 21 | #[cfg(not(unicomm))] | ||
| 21 | pub mod i2c_target; | 22 | pub mod i2c_target; |
| 22 | #[cfg(any(mspm0g150x, mspm0g151x, mspm0g350x, mspm0g351x))] | 23 | #[cfg(any(mspm0g150x, mspm0g151x, mspm0g350x, mspm0g351x))] |
| 23 | pub mod mathacl; | 24 | pub mod mathacl; |
| 24 | pub mod timer; | 25 | pub mod timer; |
| 26 | // TODO: UART unicomm | ||
| 27 | #[cfg(not(unicomm))] | ||
| 25 | pub mod uart; | 28 | pub mod uart; |
| 26 | pub mod wwdt; | 29 | pub mod wwdt; |
| 27 | 30 | ||
| @@ -276,7 +279,7 @@ pub enum ResetCause { | |||
| 276 | /// WWDT0 violation | 279 | /// WWDT0 violation |
| 277 | BootrstWwdt0Violation, | 280 | BootrstWwdt0Violation, |
| 278 | /// WWDT1 violation (G-series only) | 281 | /// WWDT1 violation (G-series only) |
| 279 | #[cfg(any(mspm0g110x, mspm0g150x, mspm0g151x, mspm0g310x, mspm0g350x, mspm0g351x))] | 282 | #[cfg(any(mspm0g110x, mspm0g150x, mspm0g151x, mspm0g310x, mspm0g350x, mspm0g351x, mspm0g518x))] |
| 280 | SysrstWwdt1Violation, | 283 | SysrstWwdt1Violation, |
| 281 | /// BSL exit (if present) | 284 | /// BSL exit (if present) |
| 282 | SysrstBslExit, | 285 | SysrstBslExit, |
| @@ -326,7 +329,8 @@ pub fn read_reset_cause() -> Result<ResetCause, u8> { | |||
| 326 | mspm0g151x, | 329 | mspm0g151x, |
| 327 | mspm0g310x, | 330 | mspm0g310x, |
| 328 | mspm0g350x, | 331 | mspm0g350x, |
| 329 | mspm0g351x | 332 | mspm0g351x, |
| 333 | mspm0g518x, | ||
| 330 | )))] | 334 | )))] |
| 331 | Id::BOOTNONPMUPARITY => Ok(BootrstNonPmuParityFault), | 335 | Id::BOOTNONPMUPARITY => Ok(BootrstNonPmuParityFault), |
| 332 | Id::BOOTCLKFAIL => Ok(BootrstClockFault), | 336 | Id::BOOTCLKFAIL => Ok(BootrstClockFault), |
| @@ -335,7 +339,7 @@ pub fn read_reset_cause() -> Result<ResetCause, u8> { | |||
| 335 | Id::BOOTWWDT0 => Ok(BootrstWwdt0Violation), | 339 | Id::BOOTWWDT0 => Ok(BootrstWwdt0Violation), |
| 336 | Id::SYSBSLEXIT => Ok(SysrstBslExit), | 340 | Id::SYSBSLEXIT => Ok(SysrstBslExit), |
| 337 | Id::SYSBSLENTRY => Ok(SysrstBslEntry), | 341 | Id::SYSBSLENTRY => Ok(SysrstBslEntry), |
| 338 | #[cfg(any(mspm0g110x, mspm0g150x, mspm0g151x, mspm0g310x, mspm0g350x, mspm0g351x))] | 342 | #[cfg(any(mspm0g110x, mspm0g150x, mspm0g151x, mspm0g310x, mspm0g350x, mspm0g351x, mspm0g518x))] |
| 339 | Id::SYSWWDT1 => Ok(SysrstWwdt1Violation), | 343 | Id::SYSWWDT1 => Ok(SysrstWwdt1Violation), |
| 340 | #[cfg(not(any(mspm0c110x, mspm0c1105_c1106, mspm0g351x, mspm0g151x)))] | 344 | #[cfg(not(any(mspm0c110x, mspm0c1105_c1106, mspm0g351x, mspm0g151x)))] |
| 341 | Id::SYSFLASHECC => Ok(SysrstFlashEccError), | 345 | Id::SYSFLASHECC => Ok(SysrstFlashEccError), |
diff --git a/embassy-mspm0/src/macros.rs b/embassy-mspm0/src/macros.rs index 5355e7d59..3a12a528a 100644 --- a/embassy-mspm0/src/macros.rs +++ b/embassy-mspm0/src/macros.rs | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | 2 | ||
| 3 | #[allow(unused)] | ||
| 3 | macro_rules! new_pin { | 4 | macro_rules! new_pin { |
| 4 | ($name: ident, $pf_type: expr) => {{ | 5 | ($name: ident, $pf_type: expr) => {{ |
| 5 | let pin = $name; | 6 | let pin = $name; |
diff --git a/embassy-mspm0/src/time_driver.rs b/embassy-mspm0/src/time_driver.rs index 0743c667b..b42ff61c2 100644 --- a/embassy-mspm0/src/time_driver.rs +++ b/embassy-mspm0/src/time_driver.rs | |||
| @@ -16,6 +16,8 @@ use crate::timer::SealedTimer; | |||
| 16 | compile_error!("TIMG12 and TIMG13 are not supported by the time driver yet"); | 16 | compile_error!("TIMG12 and TIMG13 are not supported by the time driver yet"); |
| 17 | 17 | ||
| 18 | // Currently TIMG12 and TIMG13 are excluded because those are 32-bit timers. | 18 | // Currently TIMG12 and TIMG13 are excluded because those are 32-bit timers. |
| 19 | #[cfg(time_driver_timb0)] | ||
| 20 | type T = peripherals::TIMB0; | ||
| 19 | #[cfg(time_driver_timg0)] | 21 | #[cfg(time_driver_timg0)] |
| 20 | type T = peripherals::TIMG0; | 22 | type T = peripherals::TIMG0; |
| 21 | #[cfg(time_driver_timg1)] | 23 | #[cfg(time_driver_timg1)] |
| @@ -333,6 +335,8 @@ pub(crate) fn init(cs: CriticalSection) { | |||
| 333 | DRIVER.init(cs); | 335 | DRIVER.init(cs); |
| 334 | } | 336 | } |
| 335 | 337 | ||
| 338 | // TODO: TIMB0 | ||
| 339 | |||
| 336 | #[cfg(time_driver_timg0)] | 340 | #[cfg(time_driver_timg0)] |
| 337 | #[interrupt] | 341 | #[interrupt] |
| 338 | fn TIMG0() { | 342 | fn TIMG0() { |
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/CHANGELOG.md b/embassy-net-nrf91/CHANGELOG.md index 11974ac04..66a576b72 100644 --- a/embassy-net-nrf91/CHANGELOG.md +++ b/embassy-net-nrf91/CHANGELOG.md | |||
| @@ -8,8 +8,6 @@ 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 | - changed: updated to nrf-pac with nrf52/nrf53/nrf91 register layout more similar to nrf54 | 11 | ## 0.1.0 - 2025-12-15 |
| 12 | 12 | ||
| 13 | ## 0.1.1 - 2025-08-14 | 13 | - Initial release |
| 14 | |||
| 15 | - First release with changelog. | ||
diff --git a/embassy-net-nrf91/Cargo.toml b/embassy-net-nrf91/Cargo.toml index cd9bf2987..c5c582fc3 100644 --- a/embassy-net-nrf91/Cargo.toml +++ b/embassy-net-nrf91/Cargo.toml | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | [package] | 1 | [package] |
| 2 | name = "embassy-net-nrf91" | 2 | name = "embassy-net-nrf91" |
| 3 | version = "0.1.1" | 3 | version = "0.1.0" |
| 4 | edition = "2024" | 4 | edition = "2024" |
| 5 | description = "embassy-net driver for Nordic nRF91-series cellular modems" | 5 | description = "embassy-net driver for Nordic nRF91-series cellular modems" |
| 6 | keywords = ["embedded", "nrf91", "embassy-net", "cellular"] | 6 | keywords = ["embedded", "nrf91", "embassy-net", "cellular"] |
| @@ -8,7 +8,7 @@ categories = ["embedded", "hardware-support", "no-std", "network-programming", " | |||
| 8 | license = "MIT OR Apache-2.0" | 8 | license = "MIT OR Apache-2.0" |
| 9 | repository = "https://github.com/embassy-rs/embassy" | 9 | repository = "https://github.com/embassy-rs/embassy" |
| 10 | documentation = "https://docs.embassy.dev/embassy-net-nrf91" | 10 | documentation = "https://docs.embassy.dev/embassy-net-nrf91" |
| 11 | publish = false | 11 | publish = true |
| 12 | 12 | ||
| 13 | [features] | 13 | [features] |
| 14 | defmt = ["dep:defmt", "heapless/defmt-03"] | 14 | defmt = ["dep:defmt", "heapless/defmt-03"] |
| @@ -18,7 +18,7 @@ log = ["dep:log"] | |||
| 18 | defmt = { version = "1.0.1", optional = true } | 18 | defmt = { version = "1.0.1", optional = true } |
| 19 | log = { version = "0.4.14", optional = true } | 19 | log = { version = "0.4.14", optional = true } |
| 20 | 20 | ||
| 21 | nrf-pac = { version = "0.1.0", git = "https://github.com/embassy-rs/nrf-pac.git", rev = "52fd51ce762a3d3a81660dea62947e6d2d1e9d91" } | 21 | nrf-pac = { version = "0.2.0", git = "https://github.com/embassy-rs/nrf-pac.git", rev = "7f450696f95591ce42f4da6e7d0402750ab1e50a" } |
| 22 | cortex-m = "0.7.7" | 22 | cortex-m = "0.7.7" |
| 23 | 23 | ||
| 24 | embassy-time = { version = "0.5.0", path = "../embassy-time" } | 24 | embassy-time = { version = "0.5.0", path = "../embassy-time" } |
| @@ -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-nrf91/src/lib.rs b/embassy-net-nrf91/src/lib.rs index dd4812aae..2ffa2890f 100644 --- a/embassy-net-nrf91/src/lib.rs +++ b/embassy-net-nrf91/src/lib.rs | |||
| @@ -311,7 +311,7 @@ struct PendingRequest { | |||
| 311 | waker: Waker, | 311 | waker: Waker, |
| 312 | } | 312 | } |
| 313 | 313 | ||
| 314 | #[derive(Copy, Clone, PartialEq, Eq)] | 314 | #[derive(Copy, Clone, PartialEq, Eq, Debug)] |
| 315 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 315 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 316 | struct NoFreeBufs; | 316 | struct NoFreeBufs; |
| 317 | 317 | ||
| @@ -1061,7 +1061,8 @@ struct ListItem { | |||
| 1061 | } | 1061 | } |
| 1062 | 1062 | ||
| 1063 | #[repr(C)] | 1063 | #[repr(C)] |
| 1064 | #[derive(defmt::Format, Clone, Copy)] | 1064 | #[derive(Clone, Copy)] |
| 1065 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 1065 | struct Message { | 1066 | struct Message { |
| 1066 | id: u32, | 1067 | id: u32, |
| 1067 | 1068 | ||
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-tuntap/Cargo.toml b/embassy-net-tuntap/Cargo.toml index 77668b445..95dc1e1f0 100644 --- a/embassy-net-tuntap/Cargo.toml +++ b/embassy-net-tuntap/Cargo.toml | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | [package] | 1 | [package] |
| 2 | name = "embassy-net-tuntap" | 2 | name = "embassy-net-tuntap" |
| 3 | version = "0.1.0" | 3 | version = "0.1.1" |
| 4 | description = "embassy-net driver for Linux TUN/TAP interfaces." | 4 | description = "embassy-net driver for Linux TUN/TAP interfaces." |
| 5 | keywords = ["embedded", "tuntap", "embassy-net", "ethernet", "async"] | 5 | keywords = ["embedded", "tuntap", "embassy-net", "ethernet", "async"] |
| 6 | categories = ["embedded", "hardware-support", "network-programming", "asynchronous"] | 6 | categories = ["embedded", "hardware-support", "network-programming", "asynchronous"] |
| @@ -11,7 +11,7 @@ documentation = "https://docs.embassy.dev/embassy-net-tuntap" | |||
| 11 | 11 | ||
| 12 | [dependencies] | 12 | [dependencies] |
| 13 | embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver" } | 13 | embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver" } |
| 14 | async-io = "1.6.0" | 14 | async-io = "2.6.0" |
| 15 | log = "0.4.14" | 15 | log = "0.4.14" |
| 16 | libc = "0.2.101" | 16 | libc = "0.2.101" |
| 17 | 17 | ||
diff --git a/embassy-net-tuntap/src/lib.rs b/embassy-net-tuntap/src/lib.rs index 2ff23f462..33a251248 100644 --- a/embassy-net-tuntap/src/lib.rs +++ b/embassy-net-tuntap/src/lib.rs | |||
| @@ -2,7 +2,9 @@ | |||
| 2 | #![doc = include_str!("../README.md")] | 2 | #![doc = include_str!("../README.md")] |
| 3 | use std::io; | 3 | use std::io; |
| 4 | use std::io::{Read, Write}; | 4 | use std::io::{Read, Write}; |
| 5 | use std::os::fd::AsFd; | ||
| 5 | use std::os::unix::io::{AsRawFd, RawFd}; | 6 | use std::os::unix::io::{AsRawFd, RawFd}; |
| 7 | use std::os::unix::prelude::BorrowedFd; | ||
| 6 | use std::task::Context; | 8 | use std::task::Context; |
| 7 | 9 | ||
| 8 | use async_io::Async; | 10 | use async_io::Async; |
| @@ -69,6 +71,12 @@ impl AsRawFd for TunTap { | |||
| 69 | } | 71 | } |
| 70 | } | 72 | } |
| 71 | 73 | ||
| 74 | impl AsFd for TunTap { | ||
| 75 | fn as_fd(&self) -> BorrowedFd<'_> { | ||
| 76 | unsafe { BorrowedFd::borrow_raw(self.fd) } | ||
| 77 | } | ||
| 78 | } | ||
| 79 | |||
| 72 | impl TunTap { | 80 | impl TunTap { |
| 73 | /// Create a new TUN/TAP device. | 81 | /// Create a new TUN/TAP device. |
| 74 | pub fn new(name: &str) -> io::Result<TunTap> { | 82 | pub fn new(name: &str) -> io::Result<TunTap> { |
| @@ -164,7 +172,7 @@ impl Driver for TunTapDevice { | |||
| 164 | fn receive(&mut self, cx: &mut Context) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> { | 172 | fn receive(&mut self, cx: &mut Context) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> { |
| 165 | let mut buf = vec![0; self.device.get_ref().mtu]; | 173 | let mut buf = vec![0; self.device.get_ref().mtu]; |
| 166 | loop { | 174 | loop { |
| 167 | match self.device.get_mut().read(&mut buf) { | 175 | match unsafe { self.device.get_mut() }.read(&mut buf) { |
| 168 | Ok(n) => { | 176 | Ok(n) => { |
| 169 | buf.truncate(n); | 177 | buf.truncate(n); |
| 170 | return Some(( | 178 | return Some(( |
| @@ -233,7 +241,7 @@ impl<'a> embassy_net_driver::TxToken for TxToken<'a> { | |||
| 233 | let result = f(&mut buffer); | 241 | let result = f(&mut buffer); |
| 234 | 242 | ||
| 235 | // todo handle WouldBlock with async | 243 | // todo handle WouldBlock with async |
| 236 | match self.device.get_mut().write(&buffer) { | 244 | match unsafe { self.device.get_mut() }.write(&buffer) { |
| 237 | Ok(_) => {} | 245 | Ok(_) => {} |
| 238 | Err(e) if e.kind() == io::ErrorKind::WouldBlock => info!("transmit WouldBlock"), | 246 | Err(e) if e.kind() == io::ErrorKind::WouldBlock => info!("transmit WouldBlock"), |
| 239 | Err(e) => panic!("transmit error: {:?}", e), | 247 | Err(e) => panic!("transmit error: {:?}", e), |
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 56bb15f42..921835417 100644 --- a/embassy-nrf/CHANGELOG.md +++ b/embassy-nrf/CHANGELOG.md | |||
| @@ -8,6 +8,10 @@ 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 | |||
| 13 | ## 0.9.0 - 2025-12-15 | ||
| 14 | |||
| 11 | - changed: apply trimming values from FICR.TRIMCNF on nrf53/54l | 15 | - changed: apply trimming values from FICR.TRIMCNF on nrf53/54l |
| 12 | - changed: do not panic on BufferedUarte overrun | 16 | - changed: do not panic on BufferedUarte overrun |
| 13 | - added: allow direct access to the input pin of `gpiote::InputChannel` | 17 | - added: allow direct access to the input pin of `gpiote::InputChannel` |
diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml index ee070f0c0..a8070aa45 100644 --- a/embassy-nrf/Cargo.toml +++ b/embassy-nrf/Cargo.toml | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | [package] | 1 | [package] |
| 2 | name = "embassy-nrf" | 2 | name = "embassy-nrf" |
| 3 | version = "0.8.0" | 3 | version = "0.9.0" |
| 4 | edition = "2024" | 4 | edition = "2024" |
| 5 | license = "MIT OR Apache-2.0" | 5 | license = "MIT OR Apache-2.0" |
| 6 | description = "Embassy Hardware Abstraction Layer (HAL) for nRF series microcontrollers" | 6 | description = "Embassy Hardware Abstraction Layer (HAL) for nRF series microcontrollers" |
| @@ -217,16 +217,16 @@ 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" } |
| 225 | 225 | ||
| 226 | nrf-pac = { version = "0.1.0", git = "https://github.com/embassy-rs/nrf-pac.git", rev = "52fd51ce762a3d3a81660dea62947e6d2d1e9d91" } | 226 | nrf-pac = { version = "0.2.0", git = "https://github.com/embassy-rs/nrf-pac.git", rev = "7f450696f95591ce42f4da6e7d0402750ab1e50a" } |
| 227 | 227 | ||
| 228 | defmt = { version = "1.0.1", optional = true } | 228 | defmt = { version = "1.0.1", optional = true } |
| 229 | bitflags = "2.4.2" | 229 | bitflags = "2.10.0" |
| 230 | log = { version = "0.4.14", optional = true } | 230 | log = { version = "0.4.14", optional = true } |
| 231 | cortex-m-rt = ">=0.6.15,<0.8" | 231 | cortex-m-rt = ">=0.6.15,<0.8" |
| 232 | cortex-m = "0.7.6" | 232 | cortex-m = "0.7.6" |
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/gpiote.rs b/embassy-nrf/src/gpiote.rs index 1f6000b13..6b9d2d1da 100644 --- a/embassy-nrf/src/gpiote.rs +++ b/embassy-nrf/src/gpiote.rs | |||
| @@ -29,17 +29,14 @@ const CHANNEL_COUNT: usize = 12; | |||
| 29 | /// Max channels per port | 29 | /// Max channels per port |
| 30 | const CHANNELS_PER_PORT: usize = 8; | 30 | const CHANNELS_PER_PORT: usize = 8; |
| 31 | 31 | ||
| 32 | #[cfg(any( | 32 | #[cfg(any(feature = "nrf52833", feature = "nrf52840", feature = "_nrf5340"))] |
| 33 | feature = "nrf52833", | ||
| 34 | feature = "nrf52840", | ||
| 35 | feature = "_nrf5340", | ||
| 36 | feature = "_nrf54l15", | ||
| 37 | feature = "_nrf54l10", | ||
| 38 | feature = "_nrf54l05" | ||
| 39 | ))] | ||
| 40 | const PIN_COUNT: usize = 48; | 33 | const PIN_COUNT: usize = 48; |
| 34 | #[cfg(any(feature = "_nrf54l15", feature = "_nrf54l10", feature = "_nrf54l05"))] | ||
| 35 | // Highest pin index is P2.10 => (2 * 32 + 10) = 74 | ||
| 36 | const PIN_COUNT: usize = 75; | ||
| 41 | #[cfg(feature = "_nrf54lm20")] | 37 | #[cfg(feature = "_nrf54lm20")] |
| 42 | const PIN_COUNT: usize = 66; | 38 | // Highest pin index is P3.12 => (3 * 32 + 12) = 108 |
| 39 | const PIN_COUNT: usize = 109; | ||
| 43 | #[cfg(not(any( | 40 | #[cfg(not(any( |
| 44 | feature = "nrf52833", | 41 | feature = "nrf52833", |
| 45 | feature = "nrf52840", | 42 | feature = "nrf52840", |
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/Cargo.toml b/embassy-stm32-wpan/Cargo.toml index 9624c7932..acf977ed5 100644 --- a/embassy-stm32-wpan/Cargo.toml +++ b/embassy-stm32-wpan/Cargo.toml | |||
| @@ -46,7 +46,7 @@ critical-section = "1.2" | |||
| 46 | 46 | ||
| 47 | bit_field = "0.10.2" | 47 | bit_field = "0.10.2" |
| 48 | stm32-device-signature = { version = "0.3.3", features = ["stm32wb5x"] } | 48 | stm32-device-signature = { version = "0.3.3", features = ["stm32wb5x"] } |
| 49 | stm32wb-hci = { version = "0.17.0", optional = true } | 49 | stm32wb-hci = { version = "0.17.3", optional = true } |
| 50 | futures-util = { version = "0.3.30", default-features = false } | 50 | futures-util = { version = "0.3.30", default-features = false } |
| 51 | bitflags = { version = "2.3.3", optional = true } | 51 | bitflags = { version = "2.3.3", optional = true } |
| 52 | 52 | ||
| @@ -57,7 +57,7 @@ wb55 = [] | |||
| 57 | wb55_ble = ["dep:stm32wb-hci"] | 57 | wb55_ble = ["dep:stm32wb-hci"] |
| 58 | wb55_mac = ["dep:bitflags", "dep:embassy-net-driver", "dep:smoltcp", "smoltcp/medium-ieee802154"] | 58 | wb55_mac = ["dep:bitflags", "dep:embassy-net-driver", "dep:smoltcp", "smoltcp/medium-ieee802154"] |
| 59 | 59 | ||
| 60 | wba = [ "dep:stm32-bindings" ] | 60 | wba = [ "dep:stm32-bindings", "dep:embassy-time" ] |
| 61 | wba_ble = [ "stm32-bindings/wba_wpan_mac" , "stm32-bindings/wba_wpan" ] | 61 | wba_ble = [ "stm32-bindings/wba_wpan_mac" , "stm32-bindings/wba_wpan" ] |
| 62 | wba_mac = [ "stm32-bindings/wba_wpan_mac", "stm32-bindings/wba_wpan_ble" , "stm32-bindings/lib_wba5_linklayer15_4", "stm32-bindings/lib_wba_mac_lib" , "stm32-bindings/wba_wpan" ] | 62 | wba_mac = [ "stm32-bindings/wba_wpan_mac", "stm32-bindings/wba_wpan_ble" , "stm32-bindings/lib_wba5_linklayer15_4", "stm32-bindings/lib_wba_mac_lib" , "stm32-bindings/wba_wpan" ] |
| 63 | 63 | ||
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/ble.rs b/embassy-stm32-wpan/src/wb55/sub/ble.rs index a2558d735..a822d6530 100644 --- a/embassy-stm32-wpan/src/wb55/sub/ble.rs +++ b/embassy-stm32-wpan/src/wb55/sub/ble.rs | |||
| @@ -130,12 +130,8 @@ impl<'a> hci::Controller for Ble<'a> { | |||
| 130 | self.tl_write(opcode.0, payload).await; | 130 | self.tl_write(opcode.0, payload).await; |
| 131 | } | 131 | } |
| 132 | 132 | ||
| 133 | #[allow(invalid_reference_casting)] | 133 | async fn controller_read_into(&mut self, buf: &mut [u8]) { |
| 134 | async fn controller_read_into(&self, buf: &mut [u8]) { | 134 | let evt_box = self.tl_read().await; |
| 135 | // A complete hack since I cannot update the trait | ||
| 136 | let s = unsafe { &mut *(self as *const _ as *mut Ble) }; | ||
| 137 | |||
| 138 | let evt_box = s.tl_read().await; | ||
| 139 | let evt_serial = evt_box.serial(); | 135 | let evt_serial = evt_box.serial(); |
| 140 | 136 | ||
| 141 | buf[..evt_serial.len()].copy_from_slice(evt_serial); | 137 | buf[..evt_serial.len()].copy_from_slice(evt_serial); |
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-wpan/src/wba/linklayer_plat.rs b/embassy-stm32-wpan/src/wba/linklayer_plat.rs index c011b3bcb..e6a342b52 100644 --- a/embassy-stm32-wpan/src/wba/linklayer_plat.rs +++ b/embassy-stm32-wpan/src/wba/linklayer_plat.rs | |||
| @@ -1,6 +1,3 @@ | |||
| 1 | #[allow(dead_code)] | ||
| 2 | fn test_fn() {} | ||
| 3 | |||
| 4 | // /* USER CODE BEGIN Header */ | 1 | // /* USER CODE BEGIN Header */ |
| 5 | // /** | 2 | // /** |
| 6 | // ****************************************************************************** | 3 | // ****************************************************************************** |
| @@ -72,131 +69,339 @@ fn test_fn() {} | |||
| 72 | // uint8_t AHB5_SwitchedOff = 0; | 69 | // uint8_t AHB5_SwitchedOff = 0; |
| 73 | // uint32_t radio_sleep_timer_val = 0; | 70 | // uint32_t radio_sleep_timer_val = 0; |
| 74 | // | 71 | // |
| 72 | // /* USER CODE BEGIN LINKLAYER_PLAT 0 */ | ||
| 73 | // | ||
| 74 | // /* USER CODE END LINKLAYER_PLAT 0 */ | ||
| 75 | #![cfg(feature = "wba")] | ||
| 76 | #![allow(clippy::missing_safety_doc)] | ||
| 77 | |||
| 78 | use core::hint::spin_loop; | ||
| 79 | use core::ptr; | ||
| 80 | use core::sync::atomic::{AtomicBool, AtomicI32, AtomicPtr, AtomicU32, Ordering}; | ||
| 81 | |||
| 82 | use cortex_m::asm::{dsb, isb}; | ||
| 83 | use cortex_m::interrupt::InterruptNumber; | ||
| 84 | use cortex_m::peripheral::NVIC; | ||
| 85 | use cortex_m::register::basepri; | ||
| 86 | use critical_section; | ||
| 87 | #[cfg(feature = "defmt")] | ||
| 88 | use defmt::trace; | ||
| 89 | use embassy_stm32::NVIC_PRIO_BITS; | ||
| 90 | use embassy_time::{Duration, block_for}; | ||
| 91 | |||
| 92 | use super::bindings::{link_layer, mac}; | ||
| 93 | |||
| 94 | // Missing constant from stm32-bindings - RADIO_SW_LOW interrupt number | ||
| 95 | // For STM32WBA, this is typically RADIO_IRQ_BUSY (interrupt 43) | ||
| 96 | const RADIO_SW_LOW_INTR_NUM: u32 = 43; | ||
| 97 | |||
| 98 | type Callback = unsafe extern "C" fn(); | ||
| 99 | |||
| 100 | #[derive(Clone, Copy, Debug, Eq, PartialEq)] | ||
| 101 | #[repr(transparent)] | ||
| 102 | struct RawInterrupt(u16); | ||
| 103 | |||
| 104 | impl RawInterrupt { | ||
| 105 | fn new(irq: u32) -> Self { | ||
| 106 | debug_assert!(irq <= u16::MAX as u32); | ||
| 107 | Self(irq as u16) | ||
| 108 | } | ||
| 109 | } | ||
| 110 | |||
| 111 | impl From<u32> for RawInterrupt { | ||
| 112 | fn from(value: u32) -> Self { | ||
| 113 | Self::new(value) | ||
| 114 | } | ||
| 115 | } | ||
| 116 | |||
| 117 | unsafe impl InterruptNumber for RawInterrupt { | ||
| 118 | fn number(self) -> u16 { | ||
| 119 | self.0 | ||
| 120 | } | ||
| 121 | } | ||
| 122 | |||
| 123 | static RADIO_CALLBACK: AtomicPtr<()> = AtomicPtr::new(ptr::null_mut()); | ||
| 124 | static LOW_ISR_CALLBACK: AtomicPtr<()> = AtomicPtr::new(ptr::null_mut()); | ||
| 125 | |||
| 126 | static IRQ_COUNTER: AtomicI32 = AtomicI32::new(0); | ||
| 127 | |||
| 128 | static PRIO_HIGH_ISR_COUNTER: AtomicI32 = AtomicI32::new(0); | ||
| 129 | static PRIO_LOW_ISR_COUNTER: AtomicI32 = AtomicI32::new(0); | ||
| 130 | static PRIO_SYS_ISR_COUNTER: AtomicI32 = AtomicI32::new(0); | ||
| 131 | static LOCAL_BASEPRI_VALUE: AtomicU32 = AtomicU32::new(0); | ||
| 132 | |||
| 133 | static RADIO_SW_LOW_ISR_RUNNING_HIGH_PRIO: AtomicBool = AtomicBool::new(false); | ||
| 134 | static AHB5_SWITCHED_OFF: AtomicBool = AtomicBool::new(false); | ||
| 135 | static RADIO_SLEEP_TIMER_VAL: AtomicU32 = AtomicU32::new(0); | ||
| 136 | |||
| 137 | static PRNG_STATE: AtomicU32 = AtomicU32::new(0); | ||
| 138 | static PRNG_INIT: AtomicBool = AtomicBool::new(false); | ||
| 139 | |||
| 140 | // Critical-section restore token for IRQ enable/disable pairing. | ||
| 141 | // Only written when the IRQ disable counter transitions 0->1, and consumed when it transitions 1->0. | ||
| 142 | static mut CS_RESTORE_STATE: Option<critical_section::RestoreState> = None; | ||
| 143 | |||
| 144 | fn read_system_core_clock() -> u32 { | ||
| 145 | 0 | ||
| 146 | } | ||
| 147 | |||
| 148 | fn store_callback(slot: &AtomicPtr<()>, cb: Option<Callback>) { | ||
| 149 | let ptr = cb.map_or(ptr::null_mut(), |f| f as *mut ()); | ||
| 150 | slot.store(ptr, Ordering::Release); | ||
| 151 | } | ||
| 152 | |||
| 153 | fn load_callback(slot: &AtomicPtr<()>) -> Option<Callback> { | ||
| 154 | let ptr = slot.load(Ordering::Acquire); | ||
| 155 | if ptr.is_null() { | ||
| 156 | None | ||
| 157 | } else { | ||
| 158 | Some(unsafe { core::mem::transmute::<*mut (), Callback>(ptr) }) | ||
| 159 | } | ||
| 160 | } | ||
| 161 | |||
| 162 | fn priority_shift() -> u8 { | ||
| 163 | 8 - NVIC_PRIO_BITS as u8 | ||
| 164 | } | ||
| 165 | |||
| 166 | fn pack_priority(raw: u32) -> u8 { | ||
| 167 | let shift = priority_shift(); | ||
| 168 | let priority_bits = NVIC_PRIO_BITS as u32; | ||
| 169 | let mask = if priority_bits >= 32 { | ||
| 170 | u32::MAX | ||
| 171 | } else { | ||
| 172 | (1u32 << priority_bits) - 1 | ||
| 173 | }; | ||
| 174 | let clamped = raw & mask; | ||
| 175 | (clamped << u32::from(shift)) as u8 | ||
| 176 | } | ||
| 177 | |||
| 178 | fn counter_release(counter: &AtomicI32) -> bool { | ||
| 179 | counter.fetch_sub(1, Ordering::SeqCst) <= 1 | ||
| 180 | } | ||
| 181 | |||
| 182 | fn counter_acquire(counter: &AtomicI32) -> bool { | ||
| 183 | counter.fetch_add(1, Ordering::SeqCst) == 0 | ||
| 184 | } | ||
| 185 | |||
| 186 | unsafe fn nvic_enable(irq: u32) { | ||
| 187 | NVIC::unmask(RawInterrupt::new(irq)); | ||
| 188 | dsb(); | ||
| 189 | isb(); | ||
| 190 | } | ||
| 191 | |||
| 192 | unsafe fn nvic_disable(irq: u32) { | ||
| 193 | NVIC::mask(RawInterrupt::new(irq)); | ||
| 194 | dsb(); | ||
| 195 | isb(); | ||
| 196 | } | ||
| 197 | |||
| 198 | unsafe fn nvic_set_pending(irq: u32) { | ||
| 199 | NVIC::pend(RawInterrupt::new(irq)); | ||
| 200 | dsb(); | ||
| 201 | isb(); | ||
| 202 | } | ||
| 203 | |||
| 204 | unsafe fn nvic_get_active(irq: u32) -> bool { | ||
| 205 | NVIC::is_active(RawInterrupt::new(irq)) | ||
| 206 | } | ||
| 207 | |||
| 208 | unsafe fn nvic_set_priority(irq: u32, priority: u8) { | ||
| 209 | // STM32WBA is ARMv8-M, which uses byte-accessible IPR registers | ||
| 210 | let nvic = &*NVIC::PTR; | ||
| 211 | nvic.ipr[irq as usize].write(priority); | ||
| 212 | |||
| 213 | dsb(); | ||
| 214 | isb(); | ||
| 215 | } | ||
| 216 | |||
| 217 | fn set_basepri_max(value: u8) { | ||
| 218 | unsafe { | ||
| 219 | if basepri::read() < value { | ||
| 220 | basepri::write(value); | ||
| 221 | } | ||
| 222 | } | ||
| 223 | } | ||
| 224 | |||
| 225 | fn prng_next() -> u32 { | ||
| 226 | #[inline] | ||
| 227 | fn xorshift(mut x: u32) -> u32 { | ||
| 228 | x ^= x << 13; | ||
| 229 | x ^= x >> 17; | ||
| 230 | x ^= x << 5; | ||
| 231 | x | ||
| 232 | } | ||
| 233 | |||
| 234 | if !PRNG_INIT.load(Ordering::Acquire) { | ||
| 235 | let seed = unsafe { | ||
| 236 | let timer = link_layer::ll_intf_cmn_get_slptmr_value(); | ||
| 237 | let core_clock = read_system_core_clock(); | ||
| 238 | timer ^ core_clock ^ 0x6C8E_9CF5 | ||
| 239 | }; | ||
| 240 | PRNG_STATE.store(seed, Ordering::Relaxed); | ||
| 241 | PRNG_INIT.store(true, Ordering::Release); | ||
| 242 | } | ||
| 243 | |||
| 244 | let mut current = PRNG_STATE.load(Ordering::Relaxed); | ||
| 245 | loop { | ||
| 246 | let next = xorshift(current); | ||
| 247 | match PRNG_STATE.compare_exchange_weak(current, next, Ordering::AcqRel, Ordering::Relaxed) { | ||
| 248 | Ok(_) => return next, | ||
| 249 | Err(v) => current = v, | ||
| 250 | } | ||
| 251 | } | ||
| 252 | } | ||
| 253 | |||
| 254 | pub unsafe fn run_radio_high_isr() { | ||
| 255 | if let Some(cb) = load_callback(&RADIO_CALLBACK) { | ||
| 256 | cb(); | ||
| 257 | } | ||
| 258 | } | ||
| 259 | |||
| 260 | pub unsafe fn run_radio_sw_low_isr() { | ||
| 261 | if let Some(cb) = load_callback(&LOW_ISR_CALLBACK) { | ||
| 262 | cb(); | ||
| 263 | } | ||
| 264 | |||
| 265 | if RADIO_SW_LOW_ISR_RUNNING_HIGH_PRIO.swap(false, Ordering::AcqRel) { | ||
| 266 | nvic_set_priority(RADIO_SW_LOW_INTR_NUM, pack_priority(mac::RADIO_SW_LOW_INTR_PRIO)); | ||
| 267 | } | ||
| 268 | } | ||
| 269 | |||
| 75 | // /** | 270 | // /** |
| 76 | // * @brief Configure the necessary clock sources for the radio. | 271 | // * @brief Configure the necessary clock sources for the radio. |
| 77 | // * @param None | 272 | // * @param None |
| 78 | // * @retval None | 273 | // * @retval None |
| 79 | // */ | 274 | // */ |
| 80 | // void LINKLAYER_PLAT_ClockInit() | 275 | #[unsafe(no_mangle)] |
| 81 | // { | 276 | pub unsafe extern "C" fn LINKLAYER_PLAT_ClockInit() { |
| 82 | // uint32_t linklayer_slp_clk_src = LL_RCC_RADIOSLEEPSOURCE_NONE; | 277 | // uint32_t linklayer_slp_clk_src = LL_RCC_RADIOSLEEPSOURCE_NONE; |
| 83 | // | 278 | // |
| 84 | // /* Get the Link Layer sleep timer clock source */ | 279 | // /* Get the Link Layer sleep timer clock source */ |
| 85 | // linklayer_slp_clk_src = LL_RCC_RADIO_GetSleepTimerClockSource(); | 280 | // linklayer_slp_clk_src = LL_RCC_RADIO_GetSleepTimerClockSource(); |
| 86 | // if(linklayer_slp_clk_src == LL_RCC_RADIOSLEEPSOURCE_NONE) | 281 | // if(linklayer_slp_clk_src == LL_RCC_RADIOSLEEPSOURCE_NONE) |
| 87 | // { | 282 | // { |
| 88 | // /* If there is no clock source defined, should be selected before */ | 283 | // /* If there is no clock source defined, should be selected before */ |
| 89 | // assert_param(0); | 284 | // assert_param(0); |
| 90 | // } | 285 | // } |
| 91 | // | 286 | // |
| 92 | // /* Enable AHB5ENR peripheral clock (bus CLK) */ | 287 | // /* Enable AHB5ENR peripheral clock (bus CLK) */ |
| 93 | // __HAL_RCC_RADIO_CLK_ENABLE(); | 288 | // __HAL_RCC_RADIO_CLK_ENABLE(); |
| 94 | // } | 289 | trace!("LINKLAYER_PLAT_ClockInit: get_slptmr_value"); |
| 95 | // | 290 | let _ = link_layer::ll_intf_cmn_get_slptmr_value(); |
| 291 | } | ||
| 292 | |||
| 96 | // /** | 293 | // /** |
| 97 | // * @brief Link Layer active waiting loop. | 294 | // * @brief Link Layer active waiting loop. |
| 98 | // * @param delay: delay in us | 295 | // * @param delay: delay in us |
| 99 | // * @retval None | 296 | // * @retval None |
| 100 | // */ | 297 | // */ |
| 101 | // void LINKLAYER_PLAT_DelayUs(uint32_t delay) | 298 | #[unsafe(no_mangle)] |
| 102 | // { | 299 | pub unsafe extern "C" fn LINKLAYER_PLAT_DelayUs(delay: u32) { |
| 103 | // static uint8_t lock = 0; | 300 | // static uint8_t lock = 0; |
| 104 | // uint32_t t0; | 301 | // uint32_t t0; |
| 105 | // uint32_t primask_bit; | 302 | // uint32_t primask_bit; |
| 106 | // | 303 | // |
| 107 | // /* Enter critical section */ | 304 | // /* Enter critical section */ |
| 108 | // primask_bit= __get_PRIMASK(); | 305 | // primask_bit= __get_PRIMASK(); |
| 109 | // __disable_irq(); | 306 | // __disable_irq(); |
| 110 | // | 307 | // |
| 111 | // if (lock == 0U) | 308 | // if (lock == 0U) |
| 112 | // { | 309 | // { |
| 113 | // /* Initialize counter */ | 310 | // /* Initialize counter */ |
| 114 | // /* Reset cycle counter to prevent overflow | 311 | // /* Reset cycle counter to prevent overflow |
| 115 | // As a us counter, it is assumed than even with re-entrancy, | 312 | // As a us counter, it is assumed than even with re-entrancy, |
| 116 | // overflow will never happen before re-initializing this counter */ | 313 | // overflow will never happen before re-initializing this counter */ |
| 117 | // DWT->CYCCNT = 0U; | 314 | // DWT->CYCCNT = 0U; |
| 118 | // /* Enable DWT by safety but should be useless (as already set) */ | 315 | // /* Enable DWT by safety but should be useless (as already set) */ |
| 119 | // SET_BIT(DCB->DEMCR, DCB_DEMCR_TRCENA_Msk); | 316 | // SET_BIT(DCB->DEMCR, DCB_DEMCR_TRCENA_Msk); |
| 120 | // /* Enable counter */ | 317 | // /* Enable counter */ |
| 121 | // SET_BIT(DWT->CTRL, DWT_CTRL_CYCCNTENA_Msk); | 318 | // SET_BIT(DWT->CTRL, DWT_CTRL_CYCCNTENA_Msk); |
| 122 | // } | 319 | // } |
| 123 | // /* Increment 're-entrance' counter */ | 320 | // /* Increment 're-entrance' counter */ |
| 124 | // lock++; | 321 | // lock++; |
| 125 | // /* Get starting time stamp */ | 322 | // /* Get starting time stamp */ |
| 126 | // t0 = DWT->CYCCNT; | 323 | // t0 = DWT->CYCCNT; |
| 127 | // /* Exit critical section */ | 324 | // /* Exit critical section */ |
| 128 | // __set_PRIMASK(primask_bit); | 325 | // __set_PRIMASK(primask_bit); |
| 129 | // | 326 | // |
| 130 | // /* Turn us into cycles */ | 327 | // /* Turn us into cycles */ |
| 131 | // delay = delay * (SystemCoreClock / 1000000U); | 328 | // delay = delay * (SystemCoreClock / 1000000U); |
| 132 | // delay += t0; | 329 | // delay += t0; |
| 133 | // | 330 | // |
| 134 | // /* Busy waiting loop */ | 331 | // /* Busy waiting loop */ |
| 135 | // while (DWT->CYCCNT < delay) | 332 | // while (DWT->CYCCNT < delay) |
| 136 | // { | 333 | // { |
| 137 | // }; | 334 | // }; |
| 138 | // | 335 | // |
| 139 | // /* Enter critical section */ | 336 | // /* Enter critical section */ |
| 140 | // primask_bit= __get_PRIMASK(); | 337 | // primask_bit= __get_PRIMASK(); |
| 141 | // __disable_irq(); | 338 | // __disable_irq(); |
| 142 | // if (lock == 1U) | 339 | // if (lock == 1U) |
| 143 | // { | 340 | // { |
| 144 | // /* Disable counter */ | 341 | // /* Disable counter */ |
| 145 | // CLEAR_BIT(DWT->CTRL, DWT_CTRL_CYCCNTENA_Msk); | 342 | // CLEAR_BIT(DWT->CTRL, DWT_CTRL_CYCCNTENA_Msk); |
| 146 | // } | 343 | // } |
| 147 | // /* Decrement 're-entrance' counter */ | 344 | // /* Decrement 're-entrance' counter */ |
| 148 | // lock--; | 345 | // lock--; |
| 149 | // /* Exit critical section */ | 346 | // /* Exit critical section */ |
| 150 | // __set_PRIMASK(primask_bit); | 347 | // __set_PRIMASK(primask_bit); |
| 151 | // | 348 | // |
| 152 | // } | 349 | trace!("LINKLAYER_PLAT_DelayUs: delay={}", delay); |
| 153 | // | 350 | block_for(Duration::from_micros(u64::from(delay))); |
| 351 | } | ||
| 352 | |||
| 154 | // /** | 353 | // /** |
| 155 | // * @brief Link Layer assertion API | 354 | // * @brief Link Layer assertion API |
| 156 | // * @param condition: conditional statement to be checked. | 355 | // * @param condition: conditional statement to be checked. |
| 157 | // * @retval None | 356 | // * @retval None |
| 158 | // */ | 357 | // */ |
| 159 | // void LINKLAYER_PLAT_Assert(uint8_t condition) | 358 | #[unsafe(no_mangle)] |
| 160 | // { | 359 | pub unsafe extern "C" fn LINKLAYER_PLAT_Assert(condition: u8) { |
| 161 | // assert_param(condition); | 360 | if condition == 0 { |
| 162 | // } | 361 | panic!("LINKLAYER_PLAT assertion failed"); |
| 163 | // | 362 | } |
| 363 | } | ||
| 364 | |||
| 164 | // /** | 365 | // /** |
| 165 | // * @brief Enable/disable the Link Layer active clock (baseband clock). | 366 | // * @brief Enable/disable the Link Layer active clock (baseband clock). |
| 166 | // * @param enable: boolean value to enable (1) or disable (0) the clock. | 367 | // * @param enable: boolean value to enable (1) or disable (0) the clock. |
| 167 | // * @retval None | 368 | // * @retval None |
| 168 | // */ | 369 | // */ |
| 169 | // void LINKLAYER_PLAT_WaitHclkRdy(void) | 370 | #[unsafe(no_mangle)] |
| 170 | // { | 371 | pub unsafe extern "C" fn LINKLAYER_PLAT_WaitHclkRdy() { |
| 171 | // /* Wait on radio bus clock readiness if it has been turned of */ | 372 | trace!("LINKLAYER_PLAT_WaitHclkRdy"); |
| 172 | // if (AHB5_SwitchedOff == 1) | 373 | if AHB5_SWITCHED_OFF.swap(false, Ordering::AcqRel) { |
| 173 | // { | 374 | let reference = RADIO_SLEEP_TIMER_VAL.load(Ordering::Acquire); |
| 174 | // AHB5_SwitchedOff = 0; | 375 | trace!("LINKLAYER_PLAT_WaitHclkRdy: reference={}", reference); |
| 175 | // while (radio_sleep_timer_val == ll_intf_cmn_get_slptmr_value()); | 376 | while reference == link_layer::ll_intf_cmn_get_slptmr_value() { |
| 176 | // } | 377 | spin_loop(); |
| 177 | // } | 378 | } |
| 178 | // | 379 | } |
| 380 | } | ||
| 381 | |||
| 179 | // /** | 382 | // /** |
| 180 | // * @brief Notify the Link Layer platform layer the system will enter in WFI | 383 | // * @brief Notify the Link Layer platform layer the system will enter in WFI |
| 181 | // * and AHB5 clock may be turned of regarding the 2.4Ghz radio state. | 384 | // * and AHB5 clock may be turned of regarding the 2.4Ghz radio state. |
| 182 | // * @param None | 385 | // * @param None |
| 183 | // * @retval None | 386 | // * @retval None |
| 184 | // */ | 387 | // */ |
| 185 | // void LINKLAYER_PLAT_NotifyWFIEnter(void) | 388 | #[unsafe(no_mangle)] |
| 186 | // { | 389 | pub unsafe extern "C" fn LINKLAYER_PLAT_NotifyWFIEnter() { |
| 187 | // /* Check if Radio state will allow the AHB5 clock to be cut */ | 390 | // /* Check if Radio state will allow the AHB5 clock to be cut */ |
| 188 | // | 391 | // |
| 189 | // /* AHB5 clock will be cut in the following cases: | 392 | // /* AHB5 clock will be cut in the following cases: |
| 190 | // * - 2.4GHz radio is not in ACTIVE mode (in SLEEP or DEEPSLEEP mode). | 393 | // * - 2.4GHz radio is not in ACTIVE mode (in SLEEP or DEEPSLEEP mode). |
| 191 | // * - RADIOSMEN and STRADIOCLKON bits are at 0. | 394 | // * - RADIOSMEN and STRADIOCLKON bits are at 0. |
| 192 | // */ | 395 | // */ |
| 193 | // if((LL_PWR_GetRadioMode() != LL_PWR_RADIO_ACTIVE_MODE) || | 396 | // if((LL_PWR_GetRadioMode() != LL_PWR_RADIO_ACTIVE_MODE) || |
| 194 | // ((__HAL_RCC_RADIO_IS_CLK_SLEEP_ENABLED() == 0) && (LL_RCC_RADIO_IsEnabledSleepTimerClock() == 0))) | 397 | // ((__HAL_RCC_RADIO_IS_CLK_SLEEP_ENABLED() == 0) && (LL_RCC_RADIO_IsEnabledSleepTimerClock() == 0))) |
| 195 | // { | 398 | // { |
| 196 | // AHB5_SwitchedOff = 1; | 399 | // AHB5_SwitchedOff = 1; |
| 197 | // } | 400 | // } |
| 198 | // } | 401 | trace!("LINKLAYER_PLAT_NotifyWFIEnter"); |
| 199 | // | 402 | AHB5_SWITCHED_OFF.store(true, Ordering::Release); |
| 403 | } | ||
| 404 | |||
| 200 | // /** | 405 | // /** |
| 201 | // * @brief Notify the Link Layer platform layer the system exited WFI and AHB5 | 406 | // * @brief Notify the Link Layer platform layer the system exited WFI and AHB5 |
| 202 | // * clock may be resynchronized as is may have been turned of during | 407 | // * clock may be resynchronized as is may have been turned of during |
| @@ -204,172 +409,202 @@ fn test_fn() {} | |||
| 204 | // * @param None | 409 | // * @param None |
| 205 | // * @retval None | 410 | // * @retval None |
| 206 | // */ | 411 | // */ |
| 207 | // void LINKLAYER_PLAT_NotifyWFIExit(void) | 412 | #[unsafe(no_mangle)] |
| 208 | // { | 413 | pub unsafe extern "C" fn LINKLAYER_PLAT_NotifyWFIExit() { |
| 209 | // /* Check if AHB5 clock has been turned of and needs resynchronisation */ | 414 | trace!("LINKLAYER_PLAT_NotifyWFIExit"); |
| 210 | // if (AHB5_SwitchedOff) | 415 | // /* Check if AHB5 clock has been turned of and needs resynchronisation */ |
| 211 | // { | 416 | if AHB5_SWITCHED_OFF.load(Ordering::Acquire) { |
| 212 | // /* Read sleep register as earlier as possible */ | 417 | // /* Read sleep register as earlier as possible */ |
| 213 | // radio_sleep_timer_val = ll_intf_cmn_get_slptmr_value(); | 418 | let value = link_layer::ll_intf_cmn_get_slptmr_value(); |
| 214 | // } | 419 | RADIO_SLEEP_TIMER_VAL.store(value, Ordering::Release); |
| 215 | // } | 420 | } |
| 216 | // | 421 | } |
| 422 | |||
| 217 | // /** | 423 | // /** |
| 218 | // * @brief Active wait on bus clock readiness. | 424 | // * @brief Active wait on bus clock readiness. |
| 219 | // * @param None | 425 | // * @param None |
| 220 | // * @retval None | 426 | // * @retval None |
| 221 | // */ | 427 | // */ |
| 222 | // void LINKLAYER_PLAT_AclkCtrl(uint8_t enable) | 428 | #[unsafe(no_mangle)] |
| 223 | // { | 429 | pub unsafe extern "C" fn LINKLAYER_PLAT_AclkCtrl(_enable: u8) { |
| 224 | // if(enable != 0u) | 430 | trace!("LINKLAYER_PLAT_AclkCtrl: enable={}", _enable); |
| 225 | // { | 431 | if _enable != 0 { |
| 226 | // #if (CFG_SCM_SUPPORTED == 1) | 432 | // #if (CFG_SCM_SUPPORTED == 1) |
| 227 | // /* SCM HSE BEGIN */ | 433 | // /* SCM HSE BEGIN */ |
| 228 | // /* Polling on HSE32 activation */ | 434 | // /* Polling on HSE32 activation */ |
| 229 | // SCM_HSE_WaitUntilReady(); | 435 | // SCM_HSE_WaitUntilReady(); |
| 230 | // /* Enable RADIO baseband clock (active CLK) */ | 436 | // /* Enable RADIO baseband clock (active CLK) */ |
| 231 | // HAL_RCCEx_EnableRadioBBClock(); | 437 | // HAL_RCCEx_EnableRadioBBClock(); |
| 232 | // /* SCM HSE END */ | 438 | // /* SCM HSE END */ |
| 233 | // #else | 439 | // #else |
| 234 | // /* Enable RADIO baseband clock (active CLK) */ | 440 | // /* Enable RADIO baseband clock (active CLK) */ |
| 235 | // HAL_RCCEx_EnableRadioBBClock(); | 441 | // HAL_RCCEx_EnableRadioBBClock(); |
| 236 | // /* Polling on HSE32 activation */ | 442 | // /* Polling on HSE32 activation */ |
| 237 | // while ( LL_RCC_HSE_IsReady() == 0); | 443 | // while ( LL_RCC_HSE_IsReady() == 0); |
| 238 | // #endif /* CFG_SCM_SUPPORTED */ | 444 | // #endif /* CFG_SCM_SUPPORTED */ |
| 239 | // } | 445 | // NOTE: Add a proper assertion once a typed `Radio` peripheral exists in embassy-stm32 |
| 240 | // else | 446 | // that exposes the baseband clock enable status via RCC. |
| 241 | // { | 447 | } else { |
| 242 | // /* Disable RADIO baseband clock (active CLK) */ | 448 | // /* Disable RADIO baseband clock (active CLK) */ |
| 243 | // HAL_RCCEx_DisableRadioBBClock(); | 449 | // HAL_RCCEx_DisableRadioBBClock(); |
| 244 | // } | 450 | } |
| 245 | // } | 451 | } |
| 246 | // | 452 | |
| 247 | // /** | 453 | // /** |
| 248 | // * @brief Link Layer RNG request. | 454 | // * @brief Link Layer RNG request. |
| 249 | // * @param ptr_rnd: pointer to the variable that hosts the number. | 455 | // * @param ptr_rnd: pointer to the variable that hosts the number. |
| 250 | // * @param len: number of byte of anthropy to get. | 456 | // * @param len: number of byte of anthropy to get. |
| 251 | // * @retval None | 457 | // * @retval None |
| 252 | // */ | 458 | // */ |
| 253 | // void LINKLAYER_PLAT_GetRNG(uint8_t *ptr_rnd, uint32_t len) | 459 | #[unsafe(no_mangle)] |
| 254 | // { | 460 | pub unsafe extern "C" fn LINKLAYER_PLAT_GetRNG(ptr_rnd: *mut u8, len: u32) { |
| 255 | // uint32_t nb_remaining_rng = len; | 461 | // uint32_t nb_remaining_rng = len; |
| 256 | // uint32_t generated_rng; | 462 | // uint32_t generated_rng; |
| 257 | // | 463 | // |
| 258 | // /* Get the requested RNGs (4 bytes by 4bytes) */ | 464 | // /* Get the requested RNGs (4 bytes by 4bytes) */ |
| 259 | // while(nb_remaining_rng >= 4) | 465 | // while(nb_remaining_rng >= 4) |
| 260 | // { | 466 | // { |
| 261 | // generated_rng = 0; | 467 | // generated_rng = 0; |
| 262 | // HW_RNG_Get(1, &generated_rng); | 468 | // HW_RNG_Get(1, &generated_rng); |
| 263 | // memcpy((ptr_rnd+(len-nb_remaining_rng)), &generated_rng, 4); | 469 | // memcpy((ptr_rnd+(len-nb_remaining_rng)), &generated_rng, 4); |
| 264 | // nb_remaining_rng -=4; | 470 | // nb_remaining_rng -=4; |
| 265 | // } | 471 | // } |
| 266 | // | 472 | // |
| 267 | // /* Get the remaining number of RNGs */ | 473 | // /* Get the remaining number of RNGs */ |
| 268 | // if(nb_remaining_rng>0){ | 474 | // if(nb_remaining_rng>0){ |
| 269 | // generated_rng = 0; | 475 | // generated_rng = 0; |
| 270 | // HW_RNG_Get(1, &generated_rng); | 476 | // HW_RNG_Get(1, &generated_rng); |
| 271 | // memcpy((ptr_rnd+(len-nb_remaining_rng)), &generated_rng, nb_remaining_rng); | 477 | // memcpy((ptr_rnd+(len-nb_remaining_rng)), &generated_rng, nb_remaining_rng); |
| 272 | // } | 478 | // } |
| 273 | // } | 479 | trace!("LINKLAYER_PLAT_GetRNG: ptr_rnd={:?}, len={}", ptr_rnd, len); |
| 274 | // | 480 | if ptr_rnd.is_null() || len == 0 { |
| 481 | return; | ||
| 482 | } | ||
| 483 | |||
| 484 | for i in 0..len { | ||
| 485 | let byte = (prng_next() >> ((i & 3) * 8)) as u8; | ||
| 486 | ptr::write_volatile(ptr_rnd.add(i as usize), byte); | ||
| 487 | } | ||
| 488 | } | ||
| 489 | |||
| 275 | // /** | 490 | // /** |
| 276 | // * @brief Initialize Link Layer radio high priority interrupt. | 491 | // * @brief Initialize Link Layer radio high priority interrupt. |
| 277 | // * @param intr_cb: function pointer to assign for the radio high priority ISR routine. | 492 | // * @param intr_cb: function pointer to assign for the radio high priority ISR routine. |
| 278 | // * @retval None | 493 | // * @retval None |
| 279 | // */ | 494 | // */ |
| 280 | // void LINKLAYER_PLAT_SetupRadioIT(void (*intr_cb)()) | 495 | #[unsafe(no_mangle)] |
| 281 | // { | 496 | pub unsafe extern "C" fn LINKLAYER_PLAT_SetupRadioIT(intr_cb: Option<Callback>) { |
| 282 | // radio_callback = intr_cb; | 497 | trace!("LINKLAYER_PLAT_SetupRadioIT: intr_cb={:?}", intr_cb); |
| 283 | // HAL_NVIC_SetPriority((IRQn_Type) RADIO_INTR_NUM, RADIO_INTR_PRIO_HIGH, 0); | 498 | store_callback(&RADIO_CALLBACK, intr_cb); |
| 284 | // HAL_NVIC_EnableIRQ((IRQn_Type) RADIO_INTR_NUM); | 499 | |
| 285 | // } | 500 | if intr_cb.is_some() { |
| 286 | // | 501 | nvic_set_priority(mac::RADIO_INTR_NUM, pack_priority(mac::RADIO_INTR_PRIO_HIGH)); |
| 502 | nvic_enable(mac::RADIO_INTR_NUM); | ||
| 503 | } else { | ||
| 504 | nvic_disable(mac::RADIO_INTR_NUM); | ||
| 505 | } | ||
| 506 | } | ||
| 507 | |||
| 287 | // /** | 508 | // /** |
| 288 | // * @brief Initialize Link Layer SW low priority interrupt. | 509 | // * @brief Initialize Link Layer SW low priority interrupt. |
| 289 | // * @param intr_cb: function pointer to assign for the SW low priority ISR routine. | 510 | // * @param intr_cb: function pointer to assign for the SW low priority ISR routine. |
| 290 | // * @retval None | 511 | // * @retval None |
| 291 | // */ | 512 | // */ |
| 292 | // void LINKLAYER_PLAT_SetupSwLowIT(void (*intr_cb)()) | 513 | #[unsafe(no_mangle)] |
| 293 | // { | 514 | pub unsafe extern "C" fn LINKLAYER_PLAT_SetupSwLowIT(intr_cb: Option<Callback>) { |
| 294 | // low_isr_callback = intr_cb; | 515 | trace!("LINKLAYER_PLAT_SetupSwLowIT: intr_cb={:?}", intr_cb); |
| 295 | // | 516 | store_callback(&LOW_ISR_CALLBACK, intr_cb); |
| 296 | // HAL_NVIC_SetPriority((IRQn_Type) RADIO_SW_LOW_INTR_NUM, RADIO_SW_LOW_INTR_PRIO, 0); | 517 | |
| 297 | // HAL_NVIC_EnableIRQ((IRQn_Type) RADIO_SW_LOW_INTR_NUM); | 518 | if intr_cb.is_some() { |
| 298 | // } | 519 | nvic_set_priority(RADIO_SW_LOW_INTR_NUM, pack_priority(mac::RADIO_SW_LOW_INTR_PRIO)); |
| 299 | // | 520 | nvic_enable(RADIO_SW_LOW_INTR_NUM); |
| 521 | } else { | ||
| 522 | nvic_disable(RADIO_SW_LOW_INTR_NUM); | ||
| 523 | } | ||
| 524 | } | ||
| 525 | |||
| 300 | // /** | 526 | // /** |
| 301 | // * @brief Trigger the link layer SW low interrupt. | 527 | // * @brief Trigger the link layer SW low interrupt. |
| 302 | // * @param None | 528 | // * @param None |
| 303 | // * @retval None | 529 | // * @retval None |
| 304 | // */ | 530 | // */ |
| 305 | // void LINKLAYER_PLAT_TriggerSwLowIT(uint8_t priority) | 531 | #[unsafe(no_mangle)] |
| 306 | // { | 532 | pub unsafe extern "C" fn LINKLAYER_PLAT_TriggerSwLowIT(priority: u8) { |
| 307 | // uint8_t low_isr_priority = RADIO_INTR_PRIO_LOW; | 533 | trace!("LINKLAYER_PLAT_TriggerSwLowIT: priority={}", priority); |
| 308 | // | 534 | let active = nvic_get_active(RADIO_SW_LOW_INTR_NUM); |
| 309 | // /* Check if a SW low interrupt as already been raised. | 535 | |
| 310 | // * Nested call far radio low isr are not supported | 536 | // /* Check if a SW low interrupt as already been raised. |
| 311 | // **/ | 537 | // * Nested call far radio low isr are not supported |
| 312 | // | 538 | // **/ |
| 313 | // if(NVIC_GetActive(RADIO_SW_LOW_INTR_NUM) == 0) | 539 | if !active { |
| 314 | // { | 540 | let prio = if priority == 0 { |
| 315 | // /* No nested SW low ISR, default behavior */ | 541 | // /* No nested SW low ISR, default behavior */ |
| 316 | // | 542 | pack_priority(mac::RADIO_SW_LOW_INTR_PRIO) |
| 317 | // if(priority == 0) | 543 | } else { |
| 318 | // { | 544 | pack_priority(mac::RADIO_INTR_PRIO_LOW) |
| 319 | // low_isr_priority = RADIO_SW_LOW_INTR_PRIO; | 545 | }; |
| 320 | // } | 546 | nvic_set_priority(RADIO_SW_LOW_INTR_NUM, prio); |
| 321 | // | 547 | } else if priority != 0 { |
| 322 | // HAL_NVIC_SetPriority((IRQn_Type) RADIO_SW_LOW_INTR_NUM, low_isr_priority, 0); | 548 | // /* Nested call detected */ |
| 323 | // } | 549 | // /* No change for SW radio low interrupt priority for the moment */ |
| 324 | // else | 550 | // |
| 325 | // { | 551 | // if(priority != 0) |
| 326 | // /* Nested call detected */ | 552 | // { |
| 327 | // /* No change for SW radio low interrupt priority for the moment */ | 553 | // /* At the end of current SW radio low ISR, this pending SW low interrupt |
| 328 | // | 554 | // * will run with RADIO_INTR_PRIO_LOW priority |
| 329 | // if(priority != 0) | 555 | // **/ |
| 330 | // { | 556 | // radio_sw_low_isr_is_running_high_prio = 1; |
| 331 | // /* At the end of current SW radio low ISR, this pending SW low interrupt | 557 | // } |
| 332 | // * will run with RADIO_INTR_PRIO_LOW priority | 558 | RADIO_SW_LOW_ISR_RUNNING_HIGH_PRIO.store(true, Ordering::Release); |
| 333 | // **/ | 559 | } |
| 334 | // radio_sw_low_isr_is_running_high_prio = 1; | 560 | |
| 335 | // } | 561 | nvic_set_pending(RADIO_SW_LOW_INTR_NUM); |
| 336 | // } | 562 | } |
| 337 | // | 563 | |
| 338 | // HAL_NVIC_SetPendingIRQ((IRQn_Type) RADIO_SW_LOW_INTR_NUM); | ||
| 339 | // } | ||
| 340 | // | ||
| 341 | // /** | 564 | // /** |
| 342 | // * @brief Enable interrupts. | 565 | // * @brief Enable interrupts. |
| 343 | // * @param None | 566 | // * @param None |
| 344 | // * @retval None | 567 | // * @retval None |
| 345 | // */ | 568 | // */ |
| 346 | // void LINKLAYER_PLAT_EnableIRQ(void) | 569 | #[unsafe(no_mangle)] |
| 347 | // { | 570 | pub unsafe extern "C" fn LINKLAYER_PLAT_EnableIRQ() { |
| 348 | // irq_counter = max(0,irq_counter-1); | 571 | trace!("LINKLAYER_PLAT_EnableIRQ"); |
| 349 | // | 572 | // irq_counter = max(0,irq_counter-1); |
| 350 | // if(irq_counter == 0) | 573 | // |
| 351 | // { | 574 | // if(irq_counter == 0) |
| 352 | // /* When irq_counter reaches 0, restore primask bit */ | 575 | // { |
| 353 | // __set_PRIMASK(primask_bit); | 576 | // /* When irq_counter reaches 0, restore primask bit */ |
| 354 | // } | 577 | // __set_PRIMASK(primask_bit); |
| 355 | // } | 578 | // } |
| 356 | // | 579 | if counter_release(&IRQ_COUNTER) { |
| 580 | // When the counter reaches zero, restore prior interrupt state using the captured token. | ||
| 581 | if let Some(token) = CS_RESTORE_STATE.take() { | ||
| 582 | critical_section::release(token); | ||
| 583 | } | ||
| 584 | } | ||
| 585 | } | ||
| 586 | |||
| 357 | // /** | 587 | // /** |
| 358 | // * @brief Disable interrupts. | 588 | // * @brief Disable interrupts. |
| 359 | // * @param None | 589 | // * @param None |
| 360 | // * @retval None | 590 | // * @retval None |
| 361 | // */ | 591 | // */ |
| 362 | // void LINKLAYER_PLAT_DisableIRQ(void) | 592 | #[unsafe(no_mangle)] |
| 363 | // { | 593 | pub unsafe extern "C" fn LINKLAYER_PLAT_DisableIRQ() { |
| 364 | // if(irq_counter == 0) | 594 | trace!("LINKLAYER_PLAT_DisableIRQ"); |
| 365 | // { | 595 | // if(irq_counter == 0) |
| 366 | // /* Save primask bit at first interrupt disablement */ | 596 | // { |
| 367 | // primask_bit= __get_PRIMASK(); | 597 | // /* Save primask bit at first interrupt disablement */ |
| 368 | // } | 598 | // primask_bit= __get_PRIMASK(); |
| 369 | // __disable_irq(); | 599 | // } |
| 370 | // irq_counter ++; | 600 | // __disable_irq(); |
| 371 | // } | 601 | // irq_counter ++; |
| 372 | // | 602 | if counter_acquire(&IRQ_COUNTER) { |
| 603 | // Capture and disable using critical-section API on first disable. | ||
| 604 | CS_RESTORE_STATE = Some(critical_section::acquire()); | ||
| 605 | } | ||
| 606 | } | ||
| 607 | |||
| 373 | // /** | 608 | // /** |
| 374 | // * @brief Enable specific interrupt group. | 609 | // * @brief Enable specific interrupt group. |
| 375 | // * @param isr_type: mask for interrupt group to enable. | 610 | // * @param isr_type: mask for interrupt group to enable. |
| @@ -380,43 +615,62 @@ fn test_fn() {} | |||
| 380 | // * lower priority that link layer SW low interrupt. | 615 | // * lower priority that link layer SW low interrupt. |
| 381 | // * @retval None | 616 | // * @retval None |
| 382 | // */ | 617 | // */ |
| 383 | // void LINKLAYER_PLAT_EnableSpecificIRQ(uint8_t isr_type) | 618 | #[unsafe(no_mangle)] |
| 384 | // { | 619 | pub unsafe extern "C" fn LINKLAYER_PLAT_EnableSpecificIRQ(isr_type: u8) { |
| 385 | // if( (isr_type & LL_HIGH_ISR_ONLY) != 0 ) | 620 | trace!("LINKLAYER_PLAT_EnableSpecificIRQ: isr_type={}", isr_type); |
| 386 | // { | 621 | // if( (isr_type & LL_HIGH_ISR_ONLY) != 0 ) |
| 387 | // prio_high_isr_counter--; | 622 | // { |
| 388 | // if(prio_high_isr_counter == 0) | 623 | // prio_high_isr_counter--; |
| 389 | // { | 624 | // if(prio_high_isr_counter == 0) |
| 390 | // /* When specific counter for link layer high ISR reaches 0, interrupt is enabled */ | 625 | // { |
| 391 | // HAL_NVIC_EnableIRQ(RADIO_INTR_NUM); | 626 | // /* When specific counter for link layer high ISR reaches 0, interrupt is enabled */ |
| 392 | // /* USER CODE BEGIN LINKLAYER_PLAT_EnableSpecificIRQ_1 */ | 627 | // HAL_NVIC_EnableIRQ(RADIO_INTR_NUM); |
| 393 | // | 628 | // /* USER CODE BEGIN LINKLAYER_PLAT_EnableSpecificIRQ_1 */ |
| 394 | // /* USER CODE END LINKLAYER_PLAT_EnableSpecificIRQ_1 */ | 629 | // |
| 395 | // } | 630 | // /* USER CODE END LINKLAYER_PLAT_EnableSpecificIRQ_1 */ |
| 396 | // } | 631 | // } |
| 397 | // | 632 | // } |
| 398 | // if( (isr_type & LL_LOW_ISR_ONLY) != 0 ) | 633 | // |
| 399 | // { | 634 | // if( (isr_type & LL_LOW_ISR_ONLY) != 0 ) |
| 400 | // prio_low_isr_counter--; | 635 | // { |
| 401 | // if(prio_low_isr_counter == 0) | 636 | // prio_low_isr_counter--; |
| 402 | // { | 637 | // if(prio_low_isr_counter == 0) |
| 403 | // /* When specific counter for link layer SW low ISR reaches 0, interrupt is enabled */ | 638 | // { |
| 404 | // HAL_NVIC_EnableIRQ(RADIO_SW_LOW_INTR_NUM); | 639 | // /* When specific counter for link layer SW low ISR reaches 0, interrupt is enabled */ |
| 405 | // } | 640 | // HAL_NVIC_EnableIRQ(RADIO_SW_LOW_INTR_NUM); |
| 406 | // | 641 | // } |
| 407 | // } | 642 | // |
| 408 | // | 643 | // } |
| 409 | // if( (isr_type & SYS_LOW_ISR) != 0 ) | 644 | // |
| 410 | // { | 645 | // if( (isr_type & SYS_LOW_ISR) != 0 ) |
| 411 | // prio_sys_isr_counter--; | 646 | // { |
| 412 | // if(prio_sys_isr_counter == 0) | 647 | // prio_sys_isr_counter--; |
| 413 | // { | 648 | // if(prio_sys_isr_counter == 0) |
| 414 | // /* Restore basepri value */ | 649 | // { |
| 415 | // __set_BASEPRI(local_basepri_value); | 650 | // /* Restore basepri value */ |
| 416 | // } | 651 | // __set_BASEPRI(local_basepri_value); |
| 417 | // } | 652 | // } |
| 418 | // } | 653 | // } |
| 419 | // | 654 | if (isr_type & link_layer::LL_HIGH_ISR_ONLY as u8) != 0 { |
| 655 | if counter_release(&PRIO_HIGH_ISR_COUNTER) { | ||
| 656 | nvic_enable(mac::RADIO_INTR_NUM); | ||
| 657 | } | ||
| 658 | } | ||
| 659 | |||
| 660 | if (isr_type & link_layer::LL_LOW_ISR_ONLY as u8) != 0 { | ||
| 661 | if counter_release(&PRIO_LOW_ISR_COUNTER) { | ||
| 662 | nvic_enable(RADIO_SW_LOW_INTR_NUM); | ||
| 663 | } | ||
| 664 | } | ||
| 665 | |||
| 666 | if (isr_type & link_layer::SYS_LOW_ISR as u8) != 0 { | ||
| 667 | if counter_release(&PRIO_SYS_ISR_COUNTER) { | ||
| 668 | let stored = LOCAL_BASEPRI_VALUE.load(Ordering::Relaxed) as u8; | ||
| 669 | basepri::write(stored); | ||
| 670 | } | ||
| 671 | } | ||
| 672 | } | ||
| 673 | |||
| 420 | // /** | 674 | // /** |
| 421 | // * @brief Disable specific interrupt group. | 675 | // * @brief Disable specific interrupt group. |
| 422 | // * @param isr_type: mask for interrupt group to disable. | 676 | // * @param isr_type: mask for interrupt group to disable. |
| @@ -427,219 +681,240 @@ fn test_fn() {} | |||
| 427 | // * lower priority that link layer SW low interrupt. | 681 | // * lower priority that link layer SW low interrupt. |
| 428 | // * @retval None | 682 | // * @retval None |
| 429 | // */ | 683 | // */ |
| 430 | // void LINKLAYER_PLAT_DisableSpecificIRQ(uint8_t isr_type) | 684 | #[unsafe(no_mangle)] |
| 431 | // { | 685 | pub unsafe extern "C" fn LINKLAYER_PLAT_DisableSpecificIRQ(isr_type: u8) { |
| 432 | // if( (isr_type & LL_HIGH_ISR_ONLY) != 0 ) | 686 | // if( (isr_type & LL_HIGH_ISR_ONLY) != 0 ) |
| 433 | // { | 687 | // { |
| 434 | // prio_high_isr_counter++; | 688 | // prio_high_isr_counter++; |
| 435 | // if(prio_high_isr_counter == 1) | 689 | // if(prio_high_isr_counter == 1) |
| 436 | // { | 690 | // { |
| 437 | // /* USER CODE BEGIN LINKLAYER_PLAT_DisableSpecificIRQ_1 */ | 691 | // /* USER CODE BEGIN LINKLAYER_PLAT_DisableSpecificIRQ_1 */ |
| 438 | // | 692 | // |
| 439 | // /* USER CODE END LINKLAYER_PLAT_DisableSpecificIRQ_1 */ | 693 | // /* USER CODE END LINKLAYER_PLAT_DisableSpecificIRQ_1 */ |
| 440 | // /* When specific counter for link layer high ISR value is 1, interrupt is disabled */ | 694 | // /* When specific counter for link layer high ISR value is 1, interrupt is disabled */ |
| 441 | // HAL_NVIC_DisableIRQ(RADIO_INTR_NUM); | 695 | // HAL_NVIC_DisableIRQ(RADIO_INTR_NUM); |
| 442 | // } | 696 | // } |
| 443 | // } | 697 | // } |
| 444 | // | 698 | // |
| 445 | // if( (isr_type & LL_LOW_ISR_ONLY) != 0 ) | 699 | // if( (isr_type & LL_LOW_ISR_ONLY) != 0 ) |
| 446 | // { | 700 | // { |
| 447 | // prio_low_isr_counter++; | 701 | // prio_low_isr_counter++; |
| 448 | // if(prio_low_isr_counter == 1) | 702 | // if(prio_low_isr_counter == 1) |
| 449 | // { | 703 | // { |
| 450 | // /* When specific counter for link layer SW low ISR value is 1, interrupt is disabled */ | 704 | // /* When specific counter for link layer SW low ISR value is 1, interrupt is disabled */ |
| 451 | // HAL_NVIC_DisableIRQ(RADIO_SW_LOW_INTR_NUM); | 705 | // HAL_NVIC_DisableIRQ(RADIO_SW_LOW_INTR_NUM); |
| 452 | // } | 706 | // } |
| 453 | // } | 707 | // } |
| 454 | // | 708 | // |
| 455 | // if( (isr_type & SYS_LOW_ISR) != 0 ) | 709 | // if( (isr_type & SYS_LOW_ISR) != 0 ) |
| 456 | // { | 710 | // { |
| 457 | // prio_sys_isr_counter++; | 711 | // prio_sys_isr_counter++; |
| 458 | // if(prio_sys_isr_counter == 1) | 712 | // if(prio_sys_isr_counter == 1) |
| 459 | // { | 713 | // { |
| 460 | // /* Save basepri register value */ | 714 | // /* Save basepri register value */ |
| 461 | // local_basepri_value = __get_BASEPRI(); | 715 | // local_basepri_value = __get_BASEPRI(); |
| 462 | // | 716 | // |
| 463 | // /* Mask all other interrupts with lower priority that link layer SW low ISR */ | 717 | // /* Mask all other interrupts with lower priority that link layer SW low ISR */ |
| 464 | // __set_BASEPRI_MAX(RADIO_INTR_PRIO_LOW<<4); | 718 | // __set_BASEPRI_MAX(RADIO_INTR_PRIO_LOW<<4); |
| 465 | // } | 719 | // } |
| 466 | // } | 720 | // } |
| 467 | // } | 721 | trace!("LINKLAYER_PLAT_DisableSpecificIRQ: isr_type={}", isr_type); |
| 468 | // | 722 | if (isr_type & link_layer::LL_HIGH_ISR_ONLY as u8) != 0 { |
| 723 | if counter_acquire(&PRIO_HIGH_ISR_COUNTER) { | ||
| 724 | nvic_disable(mac::RADIO_INTR_NUM); | ||
| 725 | } | ||
| 726 | } | ||
| 727 | |||
| 728 | if (isr_type & link_layer::LL_LOW_ISR_ONLY as u8) != 0 { | ||
| 729 | if counter_acquire(&PRIO_LOW_ISR_COUNTER) { | ||
| 730 | nvic_disable(RADIO_SW_LOW_INTR_NUM); | ||
| 731 | } | ||
| 732 | } | ||
| 733 | |||
| 734 | if (isr_type & link_layer::SYS_LOW_ISR as u8) != 0 { | ||
| 735 | if counter_acquire(&PRIO_SYS_ISR_COUNTER) { | ||
| 736 | let current = basepri::read(); | ||
| 737 | LOCAL_BASEPRI_VALUE.store(current.into(), Ordering::Relaxed); | ||
| 738 | set_basepri_max(pack_priority(mac::RADIO_INTR_PRIO_LOW)); | ||
| 739 | } | ||
| 740 | } | ||
| 741 | } | ||
| 742 | |||
| 469 | // /** | 743 | // /** |
| 470 | // * @brief Enable link layer high priority ISR only. | 744 | // * @brief Enable link layer high priority ISR only. |
| 471 | // * @param None | 745 | // * @param None |
| 472 | // * @retval None | 746 | // * @retval None |
| 473 | // */ | 747 | // */ |
| 474 | // void LINKLAYER_PLAT_EnableRadioIT(void) | 748 | #[unsafe(no_mangle)] |
| 475 | // { | 749 | pub unsafe extern "C" fn LINKLAYER_PLAT_EnableRadioIT() { |
| 476 | // /* USER CODE BEGIN LINKLAYER_PLAT_EnableRadioIT_1 */ | 750 | trace!("LINKLAYER_PLAT_EnableRadioIT"); |
| 477 | // | 751 | nvic_enable(mac::RADIO_INTR_NUM); |
| 478 | // /* USER CODE END LINKLAYER_PLAT_EnableRadioIT_1 */ | 752 | } |
| 479 | // | 753 | |
| 480 | // HAL_NVIC_EnableIRQ((IRQn_Type) RADIO_INTR_NUM); | ||
| 481 | // | ||
| 482 | // /* USER CODE BEGIN LINKLAYER_PLAT_EnableRadioIT_2 */ | ||
| 483 | // | ||
| 484 | // /* USER CODE END LINKLAYER_PLAT_EnableRadioIT_2 */ | ||
| 485 | // } | ||
| 486 | // | ||
| 487 | // /** | 754 | // /** |
| 488 | // * @brief Disable link layer high priority ISR only. | 755 | // * @brief Disable link layer high priority ISR only. |
| 489 | // * @param None | 756 | // * @param None |
| 490 | // * @retval None | 757 | // * @retval None |
| 491 | // */ | 758 | // */ |
| 492 | // void LINKLAYER_PLAT_DisableRadioIT(void) | 759 | #[unsafe(no_mangle)] |
| 493 | // { | 760 | pub unsafe extern "C" fn LINKLAYER_PLAT_DisableRadioIT() { |
| 494 | // /* USER CODE BEGIN LINKLAYER_PLAT_DisableRadioIT_1 */ | 761 | trace!("LINKLAYER_PLAT_DisableRadioIT"); |
| 495 | // | 762 | nvic_disable(mac::RADIO_INTR_NUM); |
| 496 | // /* USER CODE END LINKLAYER_PLAT_DisableRadioIT_1 */ | 763 | } |
| 497 | // | 764 | |
| 498 | // HAL_NVIC_DisableIRQ((IRQn_Type) RADIO_INTR_NUM); | ||
| 499 | // | ||
| 500 | // /* USER CODE BEGIN LINKLAYER_PLAT_DisableRadioIT_2 */ | ||
| 501 | // | ||
| 502 | // /* USER CODE END LINKLAYER_PLAT_DisableRadioIT_2 */ | ||
| 503 | // } | ||
| 504 | // | ||
| 505 | // /** | 765 | // /** |
| 506 | // * @brief Link Layer notification for radio activity start. | 766 | // * @brief Link Layer notification for radio activity start. |
| 507 | // * @param None | 767 | // * @param None |
| 508 | // * @retval None | 768 | // * @retval None |
| 509 | // */ | 769 | // */ |
| 510 | // void LINKLAYER_PLAT_StartRadioEvt(void) | 770 | #[unsafe(no_mangle)] |
| 511 | // { | 771 | pub unsafe extern "C" fn LINKLAYER_PLAT_StartRadioEvt() { |
| 512 | // __HAL_RCC_RADIO_CLK_SLEEP_ENABLE(); | 772 | trace!("LINKLAYER_PLAT_StartRadioEvt"); |
| 513 | // NVIC_SetPriority(RADIO_INTR_NUM, RADIO_INTR_PRIO_HIGH); | 773 | // __HAL_RCC_RADIO_CLK_SLEEP_ENABLE(); |
| 514 | // #if (CFG_SCM_SUPPORTED == 1) | 774 | // NVIC_SetPriority(RADIO_INTR_NUM, RADIO_INTR_PRIO_HIGH); |
| 515 | // scm_notifyradiostate(SCM_RADIO_ACTIVE); | 775 | // #if (CFG_SCM_SUPPORTED == 1) |
| 516 | // #endif /* CFG_SCM_SUPPORTED */ | 776 | // scm_notifyradiostate(SCM_RADIO_ACTIVE); |
| 517 | // } | 777 | // #endif /* CFG_SCM_SUPPORTED */ |
| 518 | // | 778 | nvic_set_priority(mac::RADIO_INTR_NUM, pack_priority(mac::RADIO_INTR_PRIO_HIGH)); |
| 779 | nvic_enable(mac::RADIO_INTR_NUM); | ||
| 780 | } | ||
| 781 | |||
| 519 | // /** | 782 | // /** |
| 520 | // * @brief Link Layer notification for radio activity end. | 783 | // * @brief Link Layer notification for radio activity end. |
| 521 | // * @param None | 784 | // * @param None |
| 522 | // * @retval None | 785 | // * @retval None |
| 523 | // */ | 786 | // */ |
| 524 | // void LINKLAYER_PLAT_StopRadioEvt(void) | 787 | #[unsafe(no_mangle)] |
| 525 | // { | 788 | pub unsafe extern "C" fn LINKLAYER_PLAT_StopRadioEvt() { |
| 526 | // __HAL_RCC_RADIO_CLK_SLEEP_DISABLE(); | 789 | trace!("LINKLAYER_PLAT_StopRadioEvt"); |
| 527 | // NVIC_SetPriority(RADIO_INTR_NUM, RADIO_INTR_PRIO_LOW); | 790 | // { |
| 528 | // #if (CFG_SCM_SUPPORTED == 1) | 791 | // __HAL_RCC_RADIO_CLK_SLEEP_DISABLE(); |
| 529 | // scm_notifyradiostate(SCM_RADIO_NOT_ACTIVE); | 792 | // NVIC_SetPriority(RADIO_INTR_NUM, RADIO_INTR_PRIO_LOW); |
| 530 | // #endif /* CFG_SCM_SUPPORTED */ | 793 | // #if (CFG_SCM_SUPPORTED == 1) |
| 531 | // } | 794 | // scm_notifyradiostate(SCM_RADIO_NOT_ACTIVE); |
| 532 | // | 795 | // #endif /* CFG_SCM_SUPPORTED */ |
| 796 | nvic_set_priority(mac::RADIO_INTR_NUM, pack_priority(mac::RADIO_INTR_PRIO_LOW)); | ||
| 797 | } | ||
| 798 | |||
| 533 | // /** | 799 | // /** |
| 534 | // * @brief Link Layer notification for RCO calibration start. | 800 | // * @brief Link Layer notification for RCO calibration start. |
| 535 | // * @param None | 801 | // * @param None |
| 536 | // * @retval None | 802 | // * @retval None |
| 537 | // */ | 803 | // */ |
| 538 | // void LINKLAYER_PLAT_RCOStartClbr(void) | 804 | #[unsafe(no_mangle)] |
| 539 | // { | 805 | pub unsafe extern "C" fn LINKLAYER_PLAT_RCOStartClbr() { |
| 540 | // #if (CFG_LPM_LEVEL != 0) | 806 | trace!("LINKLAYER_PLAT_RCOStartClbr"); |
| 541 | // PWR_DisableSleepMode(); | 807 | // #if (CFG_LPM_LEVEL != 0) |
| 542 | // /* Disabling stop mode prevents also from entering in standby */ | 808 | // PWR_DisableSleepMode(); |
| 543 | // UTIL_LPM_SetStopMode(1U << CFG_LPM_LL_HW_RCO_CLBR, UTIL_LPM_DISABLE); | 809 | // /* Disabling stop mode prevents also from entering in standby */ |
| 544 | // #endif /* (CFG_LPM_LEVEL != 0) */ | 810 | // UTIL_LPM_SetStopMode(1U << CFG_LPM_LL_HW_RCO_CLBR, UTIL_LPM_DISABLE); |
| 545 | // #if (CFG_SCM_SUPPORTED == 1) | 811 | // #endif /* (CFG_LPM_LEVEL != 0) */ |
| 546 | // scm_setsystemclock(SCM_USER_LL_HW_RCO_CLBR, HSE_32MHZ); | 812 | // #if (CFG_SCM_SUPPORTED == 1) |
| 547 | // while (LL_PWR_IsActiveFlag_VOS() == 0); | 813 | // scm_setsystemclock(SCM_USER_LL_HW_RCO_CLBR, HSE_32MHZ); |
| 548 | // #endif /* (CFG_SCM_SUPPORTED == 1) */ | 814 | // while (LL_PWR_IsActiveFlag_VOS() == 0); |
| 549 | // } | 815 | // #endif /* (CFG_SCM_SUPPORTED == 1) */ |
| 550 | // | 816 | } |
| 817 | |||
| 551 | // /** | 818 | // /** |
| 552 | // * @brief Link Layer notification for RCO calibration end. | 819 | // * @brief Link Layer notification for RCO calibration end. |
| 553 | // * @param None | 820 | // * @param None |
| 554 | // * @retval None | 821 | // * @retval None |
| 555 | // */ | 822 | // */ |
| 556 | // void LINKLAYER_PLAT_RCOStopClbr(void) | 823 | #[unsafe(no_mangle)] |
| 557 | // { | 824 | pub unsafe extern "C" fn LINKLAYER_PLAT_RCOStopClbr() { |
| 558 | // #if (CFG_LPM_LEVEL != 0) | 825 | trace!("LINKLAYER_PLAT_RCOStopClbr"); |
| 559 | // PWR_EnableSleepMode(); | 826 | // #if (CFG_LPM_LEVEL != 0) |
| 560 | // UTIL_LPM_SetStopMode(1U << CFG_LPM_LL_HW_RCO_CLBR, UTIL_LPM_ENABLE); | 827 | // PWR_EnableSleepMode(); |
| 561 | // #endif /* (CFG_LPM_LEVEL != 0) */ | 828 | // UTIL_LPM_SetStopMode(1U << CFG_LPM_LL_HW_RCO_CLBR, UTIL_LPM_ENABLE); |
| 562 | // #if (CFG_SCM_SUPPORTED == 1) | 829 | // #endif /* (CFG_LPM_LEVEL != 0) */ |
| 563 | // scm_setsystemclock(SCM_USER_LL_HW_RCO_CLBR, HSE_16MHZ); | 830 | // #if (CFG_SCM_SUPPORTED == 1) |
| 564 | // #endif /* (CFG_SCM_SUPPORTED == 1) */ | 831 | // scm_setsystemclock(SCM_USER_LL_HW_RCO_CLBR, HSE_16MHZ); |
| 565 | // } | 832 | // #endif /* (CFG_SCM_SUPPORTED == 1) */ |
| 566 | // | 833 | } |
| 834 | |||
| 567 | // /** | 835 | // /** |
| 568 | // * @brief Link Layer requests temperature. | 836 | // * @brief Link Layer requests temperature. |
| 569 | // * @param None | 837 | // * @param None |
| 570 | // * @retval None | 838 | // * @retval None |
| 571 | // */ | 839 | // */ |
| 572 | // void LINKLAYER_PLAT_RequestTemperature(void) | 840 | #[unsafe(no_mangle)] |
| 573 | // { | 841 | pub unsafe extern "C" fn LINKLAYER_PLAT_RequestTemperature() { |
| 574 | // #if (USE_TEMPERATURE_BASED_RADIO_CALIBRATION == 1) | 842 | trace!("LINKLAYER_PLAT_RequestTemperature"); |
| 575 | // ll_sys_bg_temperature_measurement(); | 843 | // #if (USE_TEMPERATURE_BASED_RADIO_CALIBRATION == 1) |
| 576 | // #endif /* USE_TEMPERATURE_BASED_RADIO_CALIBRATION */ | 844 | // ll_sys_bg_temperature_measurement(); |
| 577 | // } | 845 | // #endif /* USE_TEMPERATURE_BASED_RADIO_CALIBRATION */ |
| 578 | // | 846 | } |
| 847 | |||
| 579 | // /** | 848 | // /** |
| 580 | // * @brief PHY Start calibration. | 849 | // * @brief PHY Start calibration. |
| 581 | // * @param None | 850 | // * @param None |
| 582 | // * @retval None | 851 | // * @retval None |
| 583 | // */ | 852 | // */ |
| 584 | // void LINKLAYER_PLAT_PhyStartClbr(void) | 853 | #[unsafe(no_mangle)] |
| 585 | // { | 854 | pub unsafe extern "C" fn LINKLAYER_PLAT_PhyStartClbr() { |
| 586 | // /* USER CODE BEGIN LINKLAYER_PLAT_PhyStartClbr_0 */ | 855 | trace!("LINKLAYER_PLAT_PhyStartClbr"); |
| 587 | // | 856 | } |
| 588 | // /* USER CODE END LINKLAYER_PLAT_PhyStartClbr_0 */ | 857 | |
| 589 | // | ||
| 590 | // /* USER CODE BEGIN LINKLAYER_PLAT_PhyStartClbr_1 */ | ||
| 591 | // | ||
| 592 | // /* USER CODE END LINKLAYER_PLAT_PhyStartClbr_1 */ | ||
| 593 | // } | ||
| 594 | // | ||
| 595 | // /** | 858 | // /** |
| 596 | // * @brief PHY Stop calibration. | 859 | // * @brief PHY Stop calibration. |
| 597 | // * @param None | 860 | // * @param None |
| 598 | // * @retval None | 861 | // * @retval None |
| 599 | // */ | 862 | // */ |
| 600 | // void LINKLAYER_PLAT_PhyStopClbr(void) | 863 | #[unsafe(no_mangle)] |
| 601 | // { | 864 | pub unsafe extern "C" fn LINKLAYER_PLAT_PhyStopClbr() { |
| 602 | // /* USER CODE BEGIN LINKLAYER_PLAT_PhyStopClbr_0 */ | 865 | trace!("LINKLAYER_PLAT_PhyStopClbr"); |
| 603 | // | 866 | } |
| 604 | // /* USER CODE END LINKLAYER_PLAT_PhyStopClbr_0 */ | 867 | |
| 605 | // | ||
| 606 | // /* USER CODE BEGIN LINKLAYER_PLAT_PhyStopClbr_1 */ | ||
| 607 | // | ||
| 608 | // /* USER CODE END LINKLAYER_PLAT_PhyStopClbr_1 */ | ||
| 609 | // } | ||
| 610 | // | ||
| 611 | // /** | 868 | // /** |
| 612 | // * @brief Notify the upper layer that new Link Layer timings have been applied. | 869 | // * @brief Notify the upper layer that new Link Layer timings have been applied. |
| 613 | // * @param evnt_timing[in]: Evnt_timing_t pointer to structure contains drift time , execution time and scheduling time | 870 | // * @param evnt_timing[in]: Evnt_timing_t pointer to structure contains drift time , execution time and scheduling time |
| 614 | // * @retval None. | 871 | // * @retval None. |
| 615 | // */ | 872 | // */ |
| 616 | // void LINKLAYER_PLAT_SCHLDR_TIMING_UPDATE_NOT(Evnt_timing_t * p_evnt_timing) | 873 | #[unsafe(no_mangle)] |
| 617 | // { | 874 | pub unsafe extern "C" fn LINKLAYER_PLAT_SCHLDR_TIMING_UPDATE_NOT(_timings: *const link_layer::Evnt_timing_t) { |
| 618 | // /* USER CODE BEGIN LINKLAYER_PLAT_SCHLDR_TIMING_UPDATE_NOT_0 */ | 875 | trace!("LINKLAYER_PLAT_SCHLDR_TIMING_UPDATE_NOT: timings={:?}", _timings); |
| 619 | // | 876 | } |
| 620 | // /* USER CODE END LINKLAYER_PLAT_SCHLDR_TIMING_UPDATE_NOT_0 */ | 877 | |
| 621 | // } | ||
| 622 | // | ||
| 623 | // /** | 878 | // /** |
| 624 | // * @brief Get the ST company ID. | 879 | // * @brief Get the ST company ID. |
| 625 | // * @param None | 880 | // * @param None |
| 626 | // * @retval Company ID | 881 | // * @retval Company ID |
| 627 | // */ | 882 | // */ |
| 628 | // uint32_t LINKLAYER_PLAT_GetSTCompanyID(void) | 883 | #[unsafe(no_mangle)] |
| 629 | // { | 884 | pub unsafe extern "C" fn LINKLAYER_PLAT_GetSTCompanyID() -> u32 { |
| 630 | // return LL_FLASH_GetSTCompanyID(); | 885 | trace!("LINKLAYER_PLAT_GetSTCompanyID"); |
| 631 | // } | 886 | // STMicroelectronics Bluetooth SIG Company Identifier |
| 632 | // | 887 | // TODO: Pull in update from latest stm32-generated-data |
| 888 | 0x0030 | ||
| 889 | } | ||
| 890 | |||
| 633 | // /** | 891 | // /** |
| 634 | // * @brief Get the Unique Device Number (UDN). | 892 | // * @brief Get the Unique Device Number (UDN). |
| 635 | // * @param None | 893 | // * @param None |
| 636 | // * @retval UDN | 894 | // * @retval UDN |
| 637 | // */ | 895 | // */ |
| 638 | // uint32_t LINKLAYER_PLAT_GetUDN(void) | 896 | #[unsafe(no_mangle)] |
| 639 | // { | 897 | pub unsafe extern "C" fn LINKLAYER_PLAT_GetUDN() -> u32 { |
| 640 | // return LL_FLASH_GetUDN(); | 898 | trace!("LINKLAYER_PLAT_GetUDN"); |
| 641 | // } | 899 | // Read the first 32 bits of the STM32 unique 96-bit ID |
| 642 | // | 900 | let uid = embassy_stm32::uid::uid(); |
| 643 | // /* USER CODE BEGIN LINKLAYER_PLAT 0 */ | 901 | u32::from_le_bytes([uid[0], uid[1], uid[2], uid[3]]) |
| 644 | // | 902 | } |
| 645 | // /* USER CODE END LINKLAYER_PLAT 0 */ | 903 | |
| 904 | #[unsafe(no_mangle)] | ||
| 905 | pub unsafe extern "C" fn LINKLAYER_DEBUG_SIGNAL_SET() { | ||
| 906 | trace!("LINKLAYER_DEBUG_SIGNAL_SET"); | ||
| 907 | todo!() | ||
| 908 | } | ||
| 909 | |||
| 910 | #[unsafe(no_mangle)] | ||
| 911 | pub unsafe extern "C" fn LINKLAYER_DEBUG_SIGNAL_RESET() { | ||
| 912 | trace!("LINKLAYER_DEBUG_SIGNAL_RESET"); | ||
| 913 | todo!() | ||
| 914 | } | ||
| 915 | |||
| 916 | #[unsafe(no_mangle)] | ||
| 917 | pub unsafe extern "C" fn LINKLAYER_DEBUG_SIGNAL_TOGGLE() { | ||
| 918 | trace!("LINKLAYER_DEBUG_SIGNAL_TOGGLE"); | ||
| 919 | todo!() | ||
| 920 | } | ||
diff --git a/embassy-stm32/CHANGELOG.md b/embassy-stm32/CHANGELOG.md index 38f22b1c3..ae2c0168b 100644 --- a/embassy-stm32/CHANGELOG.md +++ b/embassy-stm32/CHANGELOG.md | |||
| @@ -6,6 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), | |||
| 6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). | 6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). |
| 7 | 7 | ||
| 8 | ## Unreleased - ReleaseDate | 8 | ## Unreleased - ReleaseDate |
| 9 | - Add `receive_waveform` method in `InputCapture`, allowing asynchronous input capture with DMA. | ||
| 9 | 10 | ||
| 10 | - fix: stm32: GPDMA driver reset ignored during channel configuration | 11 | - fix: stm32: GPDMA driver reset ignored during channel configuration |
| 11 | - fix: stm32: SPI driver SSOE and SSM manegment, add `nss_output_disable` to SPI Config | 12 | - fix: stm32: SPI driver SSOE and SSM manegment, add `nss_output_disable` to SPI Config |
| @@ -72,6 +73,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |||
| 72 | - low-power: update rtc api to allow reconfig | 73 | - low-power: update rtc api to allow reconfig |
| 73 | - adc: consolidate ringbuffer | 74 | - adc: consolidate ringbuffer |
| 74 | - feat: Added RTC low-power support for STM32WLEx ([#4716](https://github.com/embassy-rs/embassy/pull/4716)) | 75 | - feat: Added RTC low-power support for STM32WLEx ([#4716](https://github.com/embassy-rs/embassy/pull/4716)) |
| 76 | - feat: Added low-power support for STM32WL5x ([#5108](https://github.com/embassy-rs/embassy/pull/5108)) | ||
| 75 | - fix: Correct STM32WBA VREFBUFTRIM values | 77 | - fix: Correct STM32WBA VREFBUFTRIM values |
| 76 | - low_power: remove stop_with rtc and initialize in init if low-power feature enabled. | 78 | - low_power: remove stop_with rtc and initialize in init if low-power feature enabled. |
| 77 | - feat: stm32/dsi support zero parameter commands in `write_cmd` ([#4847](https://github.com/embassy-rs/embassy/pull/4847)) | 79 | - feat: stm32/dsi support zero parameter commands in `write_cmd` ([#4847](https://github.com/embassy-rs/embassy/pull/4847)) |
| @@ -93,6 +95,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |||
| 93 | - stm32: Add blocking_listen for blocking I2C driver | 95 | - stm32: Add blocking_listen for blocking I2C driver |
| 94 | - fix: stm32l47*/stm32l48* adc analog pin setup | 96 | - fix: stm32l47*/stm32l48* adc analog pin setup |
| 95 | - fix: keep stm32/sai: make NODIV independent of MCKDIV | 97 | - fix: keep stm32/sai: make NODIV independent of MCKDIV |
| 98 | - fix: Source system clock from MSIS before (de)configuring PLLs on STM32U5 | ||
| 99 | - feat: adc: allow DMA reads to loop through enabled channels | ||
| 96 | 100 | ||
| 97 | ## 0.4.0 - 2025-08-26 | 101 | ## 0.4.0 - 2025-08-26 |
| 98 | 102 | ||
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 7989fc5d7..55eba2695 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" |
| @@ -193,18 +193,20 @@ document-features = "0.2.7" | |||
| 193 | 193 | ||
| 194 | static_assertions = { version = "1.1" } | 194 | static_assertions = { version = "1.1" } |
| 195 | volatile-register = { version = "0.2.1" } | 195 | volatile-register = { version = "0.2.1" } |
| 196 | bitflags = "2.4.2" | 196 | bitflags = "2.10.0" |
| 197 | 197 | ||
| 198 | block-device-driver = { version = "0.2" } | 198 | block-device-driver = { version = "0.2" } |
| 199 | aligned = "0.4.1" | 199 | aligned = "0.4.1" |
| 200 | heapless = "0.9.1" | 200 | heapless = "0.9.1" |
| 201 | 201 | ||
| 202 | #stm32-metapac = { version = "18" } | 202 | #stm32-metapac = { version = "18" } |
| 203 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-497fb3042b49b765d8974aac87b8ab4fa3566d74" } | 203 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-c0123f4251e21282c3f26114d2f6f9360c1191f1" } |
| 204 | #stm32-metapac = { path = "../../stm32-data/build/stm32-metapac" } | ||
| 204 | 205 | ||
| 205 | [build-dependencies] | 206 | [build-dependencies] |
| 206 | #stm32-metapac = { version = "18", default-features = false, features = ["metadata"]} | 207 | #stm32-metapac = { version = "18", default-features = false, features = ["metadata"]} |
| 207 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-497fb3042b49b765d8974aac87b8ab4fa3566d74", default-features = false, features = ["metadata"] } | 208 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-c0123f4251e21282c3f26114d2f6f9360c1191f1", default-features = false, features = ["metadata"] } |
| 209 | #stm32-metapac = { path = "../../stm32-data/build/stm32-metapac", default-features = false, features = ["metadata"] } | ||
| 208 | 210 | ||
| 209 | proc-macro2 = "1.0.36" | 211 | proc-macro2 = "1.0.36" |
| 210 | quote = "1.0.15" | 212 | quote = "1.0.15" |
| @@ -228,7 +230,7 @@ defmt = [ | |||
| 228 | "embassy-sync/defmt", | 230 | "embassy-sync/defmt", |
| 229 | "embassy-embedded-hal/defmt", | 231 | "embassy-embedded-hal/defmt", |
| 230 | "embassy-hal-internal/defmt", | 232 | "embassy-hal-internal/defmt", |
| 231 | "embedded-io-async/defmt-03", | 233 | "embedded-io-async/defmt", |
| 232 | "embassy-usb-driver/defmt", | 234 | "embassy-usb-driver/defmt", |
| 233 | "embassy-net-driver/defmt", | 235 | "embassy-net-driver/defmt", |
| 234 | "embassy-time?/defmt", | 236 | "embassy-time?/defmt", |
| @@ -241,8 +243,9 @@ log = ["dep:log"] | |||
| 241 | chrono = ["dep:chrono"] | 243 | chrono = ["dep:chrono"] |
| 242 | 244 | ||
| 243 | exti = [] | 245 | exti = [] |
| 244 | low-power = [ "dep:embassy-executor", "embassy-executor?/arch-cortex-m", "time" ] | 246 | low-power = [ "dep:embassy-executor", "time", "chrono" ] |
| 245 | low-power-debug-with-sleep = [] | 247 | low-power-pender = [ "low-power" ] |
| 248 | low-power-debug-with-sleep = [ "low-power" ] | ||
| 246 | 249 | ||
| 247 | ## Automatically generate `memory.x` file based on the memory map from [`stm32-metapac`](https://docs.rs/stm32-metapac/) | 250 | ## Automatically generate `memory.x` file based on the memory map from [`stm32-metapac`](https://docs.rs/stm32-metapac/) |
| 248 | memory-x = [] | 251 | memory-x = [] |
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 46d6290e7..a3b863340 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs | |||
| @@ -950,6 +950,60 @@ fn main() { | |||
| 950 | } | 950 | } |
| 951 | } | 951 | } |
| 952 | 952 | ||
| 953 | if kind == "gpio" { | ||
| 954 | for p in METADATA.peripherals { | ||
| 955 | // set all GPIOs to analog mode except for PA13 and PA14 which are SWDIO and SWDCLK | ||
| 956 | if p.registers.is_some() | ||
| 957 | && p.registers.as_ref().unwrap().kind == "gpio" | ||
| 958 | && p.registers.as_ref().unwrap().version != "v1" | ||
| 959 | { | ||
| 960 | let port = format_ident!("{}", p.name); | ||
| 961 | if p.name == "GPIOA" { | ||
| 962 | gg.extend(quote! { | ||
| 963 | // leave PA13 and PA14 as unchanged | ||
| 964 | crate::pac::#port.moder().modify(|w| { | ||
| 965 | w.set_moder(0, crate::pac::gpio::vals::Moder::ANALOG); | ||
| 966 | w.set_moder(1, crate::pac::gpio::vals::Moder::ANALOG); | ||
| 967 | w.set_moder(2, crate::pac::gpio::vals::Moder::ANALOG); | ||
| 968 | w.set_moder(3, crate::pac::gpio::vals::Moder::ANALOG); | ||
| 969 | w.set_moder(4, crate::pac::gpio::vals::Moder::ANALOG); | ||
| 970 | w.set_moder(5, crate::pac::gpio::vals::Moder::ANALOG); | ||
| 971 | w.set_moder(6, crate::pac::gpio::vals::Moder::ANALOG); | ||
| 972 | w.set_moder(7, crate::pac::gpio::vals::Moder::ANALOG); | ||
| 973 | w.set_moder(8, crate::pac::gpio::vals::Moder::ANALOG); | ||
| 974 | w.set_moder(9, crate::pac::gpio::vals::Moder::ANALOG); | ||
| 975 | w.set_moder(10, crate::pac::gpio::vals::Moder::ANALOG); | ||
| 976 | w.set_moder(11, crate::pac::gpio::vals::Moder::ANALOG); | ||
| 977 | w.set_moder(12, crate::pac::gpio::vals::Moder::ANALOG); | ||
| 978 | w.set_moder(15, crate::pac::gpio::vals::Moder::ANALOG); | ||
| 979 | }); | ||
| 980 | }); | ||
| 981 | } else { | ||
| 982 | gg.extend(quote! { | ||
| 983 | crate::pac::#port.moder().modify(|w| { | ||
| 984 | w.set_moder(0, crate::pac::gpio::vals::Moder::ANALOG); | ||
| 985 | w.set_moder(1, crate::pac::gpio::vals::Moder::ANALOG); | ||
| 986 | w.set_moder(2, crate::pac::gpio::vals::Moder::ANALOG); | ||
| 987 | w.set_moder(3, crate::pac::gpio::vals::Moder::ANALOG); | ||
| 988 | w.set_moder(4, crate::pac::gpio::vals::Moder::ANALOG); | ||
| 989 | w.set_moder(5, crate::pac::gpio::vals::Moder::ANALOG); | ||
| 990 | w.set_moder(6, crate::pac::gpio::vals::Moder::ANALOG); | ||
| 991 | w.set_moder(7, crate::pac::gpio::vals::Moder::ANALOG); | ||
| 992 | w.set_moder(8, crate::pac::gpio::vals::Moder::ANALOG); | ||
| 993 | w.set_moder(9, crate::pac::gpio::vals::Moder::ANALOG); | ||
| 994 | w.set_moder(10, crate::pac::gpio::vals::Moder::ANALOG); | ||
| 995 | w.set_moder(11, crate::pac::gpio::vals::Moder::ANALOG); | ||
| 996 | w.set_moder(12, crate::pac::gpio::vals::Moder::ANALOG); | ||
| 997 | w.set_moder(13, crate::pac::gpio::vals::Moder::ANALOG); | ||
| 998 | w.set_moder(14, crate::pac::gpio::vals::Moder::ANALOG); | ||
| 999 | w.set_moder(15, crate::pac::gpio::vals::Moder::ANALOG); | ||
| 1000 | }); | ||
| 1001 | }); | ||
| 1002 | } | ||
| 1003 | } | ||
| 1004 | } | ||
| 1005 | } | ||
| 1006 | |||
| 953 | let fname = format_ident!("init_{}", kind); | 1007 | let fname = format_ident!("init_{}", kind); |
| 954 | g.extend(quote! { | 1008 | g.extend(quote! { |
| 955 | pub unsafe fn #fname(){ | 1009 | pub unsafe fn #fname(){ |
diff --git a/embassy-stm32/src/adc/mod.rs b/embassy-stm32/src/adc/mod.rs index da432f6ce..17b1dae77 100644 --- a/embassy-stm32/src/adc/mod.rs +++ b/embassy-stm32/src/adc/mod.rs | |||
| @@ -214,7 +214,7 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 214 | #[cfg(any(adc_g4, adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0, adc_v4, adc_u5, adc_wba, adc_c0))] | 214 | #[cfg(any(adc_g4, adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0, adc_v4, adc_u5, adc_wba, adc_c0))] |
| 215 | /// Read one or multiple ADC regular channels using DMA. | 215 | /// Read one or multiple ADC regular channels using DMA. |
| 216 | /// | 216 | /// |
| 217 | /// `sequence` iterator and `readings` must have the same length. | 217 | /// `readings` must have a length that is a multiple of the length of the `sequence` iterator. |
| 218 | /// | 218 | /// |
| 219 | /// Example | 219 | /// Example |
| 220 | /// ```rust,ignore | 220 | /// ```rust,ignore |
| @@ -253,8 +253,8 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 253 | ) { | 253 | ) { |
| 254 | assert!(sequence.len() != 0, "Asynchronous read sequence cannot be empty"); | 254 | assert!(sequence.len() != 0, "Asynchronous read sequence cannot be empty"); |
| 255 | assert!( | 255 | assert!( |
| 256 | sequence.len() == readings.len(), | 256 | readings.len() % sequence.len() == 0, |
| 257 | "Sequence length must be equal to readings length" | 257 | "Readings length must be a multiple of sequence length" |
| 258 | ); | 258 | ); |
| 259 | assert!( | 259 | assert!( |
| 260 | sequence.len() <= 16, | 260 | sequence.len() <= 16, |
diff --git a/embassy-stm32/src/hsem/mod.rs b/embassy-stm32/src/hsem/mod.rs index b5fa3c897..e5c68acbd 100644 --- a/embassy-stm32/src/hsem/mod.rs +++ b/embassy-stm32/src/hsem/mod.rs | |||
| @@ -94,17 +94,14 @@ pub struct HardwareSemaphoreInterruptHandler<T: Instance> { | |||
| 94 | impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for HardwareSemaphoreInterruptHandler<T> { | 94 | impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for HardwareSemaphoreInterruptHandler<T> { |
| 95 | unsafe fn on_interrupt() { | 95 | unsafe fn on_interrupt() { |
| 96 | let core_id = CoreId::current(); | 96 | let core_id = CoreId::current(); |
| 97 | let isr = T::regs().isr(core_id.to_index()).read(); | ||
| 97 | 98 | ||
| 98 | for number in 0..5 { | 99 | for number in 0..5 { |
| 99 | if T::regs().isr(core_id.to_index()).read().isf(number as usize) { | 100 | if isr.isf(number as usize) { |
| 100 | T::regs() | 101 | T::regs() |
| 101 | .icr(core_id.to_index()) | 102 | .icr(core_id.to_index()) |
| 102 | .write(|w| w.set_isc(number as usize, true)); | 103 | .write(|w| w.set_isc(number as usize, true)); |
| 103 | 104 | ||
| 104 | T::regs() | ||
| 105 | .ier(core_id.to_index()) | ||
| 106 | .modify(|w| w.set_ise(number as usize, false)); | ||
| 107 | |||
| 108 | T::state().waker_for(number).wake(); | 105 | T::state().waker_for(number).wake(); |
| 109 | } | 106 | } |
| 110 | } | 107 | } |
| @@ -120,6 +117,18 @@ pub struct HardwareSemaphoreMutex<'a, T: Instance> { | |||
| 120 | 117 | ||
| 121 | impl<'a, T: Instance> Drop for HardwareSemaphoreMutex<'a, T> { | 118 | impl<'a, T: Instance> Drop for HardwareSemaphoreMutex<'a, T> { |
| 122 | fn drop(&mut self) { | 119 | fn drop(&mut self) { |
| 120 | let core_id = CoreId::current(); | ||
| 121 | |||
| 122 | T::regs() | ||
| 123 | .icr(core_id.to_index()) | ||
| 124 | .write(|w| w.set_isc(self.index as usize, true)); | ||
| 125 | |||
| 126 | critical_section::with(|_| { | ||
| 127 | T::regs() | ||
| 128 | .ier(core_id.to_index()) | ||
| 129 | .modify(|w| w.set_ise(self.index as usize, false)); | ||
| 130 | }); | ||
| 131 | |||
| 123 | HardwareSemaphoreChannel::<'a, T> { | 132 | HardwareSemaphoreChannel::<'a, T> { |
| 124 | index: self.index, | 133 | index: self.index, |
| 125 | _lifetime: PhantomData, | 134 | _lifetime: PhantomData, |
| @@ -156,9 +165,11 @@ impl<'a, T: Instance> HardwareSemaphoreChannel<'a, T> { | |||
| 156 | 165 | ||
| 157 | compiler_fence(Ordering::SeqCst); | 166 | compiler_fence(Ordering::SeqCst); |
| 158 | 167 | ||
| 159 | T::regs() | 168 | critical_section::with(|_| { |
| 160 | .ier(core_id.to_index()) | 169 | T::regs() |
| 161 | .modify(|w| w.set_ise(self.index as usize, true)); | 170 | .ier(core_id.to_index()) |
| 171 | .modify(|w| w.set_ise(self.index as usize, true)); | ||
| 172 | }); | ||
| 162 | 173 | ||
| 163 | match self.try_lock(process_id) { | 174 | match self.try_lock(process_id) { |
| 164 | Some(mutex) => Poll::Ready(mutex), | 175 | Some(mutex) => Poll::Ready(mutex), |
diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs index 0bf430ffc..0aa2d1da9 100644 --- a/embassy-stm32/src/i2c/mod.rs +++ b/embassy-stm32/src/i2c/mod.rs | |||
| @@ -129,7 +129,7 @@ impl<'d> Drop for I2CDropGuard<'d> { | |||
| 129 | x.set_as_disconnected() | 129 | x.set_as_disconnected() |
| 130 | } | 130 | } |
| 131 | 131 | ||
| 132 | self.info.rcc.disable(); | 132 | self.info.rcc.disable_without_stop(); |
| 133 | } | 133 | } |
| 134 | } | 134 | } |
| 135 | 135 | ||
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 2388abe3c..71befcf34 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 |
| @@ -43,7 +43,7 @@ | |||
| 43 | use core::arch::asm; | 43 | use core::arch::asm; |
| 44 | use core::marker::PhantomData; | 44 | use core::marker::PhantomData; |
| 45 | use core::mem; | 45 | use core::mem; |
| 46 | use core::sync::atomic::{Ordering, compiler_fence}; | 46 | use core::sync::atomic::{AtomicBool, Ordering, compiler_fence}; |
| 47 | 47 | ||
| 48 | use cortex_m::peripheral::SCB; | 48 | use cortex_m::peripheral::SCB; |
| 49 | use critical_section::CriticalSection; | 49 | use critical_section::CriticalSection; |
| @@ -56,7 +56,27 @@ use crate::time_driver::get_driver; | |||
| 56 | 56 | ||
| 57 | const THREAD_PENDER: usize = usize::MAX; | 57 | const THREAD_PENDER: usize = usize::MAX; |
| 58 | 58 | ||
| 59 | static mut EXECUTOR_TAKEN: bool = false; | 59 | static EXECUTOR_TAKEN: AtomicBool = AtomicBool::new(false); |
| 60 | #[cfg(feature = "low-power-pender")] | ||
| 61 | static TASKS_PENDING: AtomicBool = AtomicBool::new(false); | ||
| 62 | |||
| 63 | #[cfg(feature = "low-power-pender")] | ||
| 64 | #[unsafe(export_name = "__pender")] | ||
| 65 | fn __pender(context: *mut ()) { | ||
| 66 | unsafe { | ||
| 67 | // Safety: `context` is either `usize::MAX` created by `Executor::run`, or a valid interrupt | ||
| 68 | // request number given to `InterruptExecutor::start`. | ||
| 69 | |||
| 70 | let context = context as usize; | ||
| 71 | |||
| 72 | // Try to make Rust optimize the branching away if we only use thread mode. | ||
| 73 | if context == THREAD_PENDER { | ||
| 74 | TASKS_PENDING.store(true, Ordering::Release); | ||
| 75 | core::arch::asm!("sev"); | ||
| 76 | return; | ||
| 77 | } | ||
| 78 | } | ||
| 79 | } | ||
| 60 | 80 | ||
| 61 | /// Prevent the device from going into the stop mode if held | 81 | /// Prevent the device from going into the stop mode if held |
| 62 | pub struct DeviceBusy { | 82 | pub struct DeviceBusy { |
| @@ -116,17 +136,17 @@ pub fn stop_ready(stop_mode: StopMode) -> bool { | |||
| 116 | }) | 136 | }) |
| 117 | } | 137 | } |
| 118 | 138 | ||
| 119 | #[cfg(any(stm32l4, stm32l5, stm32u5, stm32wba, stm32wb, stm32wlex, stm32u0))] | 139 | #[cfg(any(stm32l4, stm32l5, stm32u5, stm32wba, stm32wb, stm32wl, stm32u0))] |
| 120 | use crate::pac::pwr::vals::Lpms; | 140 | use crate::pac::pwr::vals::Lpms; |
| 121 | 141 | ||
| 122 | #[cfg(any(stm32l4, stm32l5, stm32u5, stm32wba, stm32wb, stm32wlex, stm32u0))] | 142 | #[cfg(any(stm32l4, stm32l5, stm32u5, stm32wba, stm32wb, stm32wl, stm32u0))] |
| 123 | impl Into<Lpms> for StopMode { | 143 | impl Into<Lpms> for StopMode { |
| 124 | fn into(self) -> Lpms { | 144 | fn into(self) -> Lpms { |
| 125 | match self { | 145 | match self { |
| 126 | StopMode::Stop1 => Lpms::STOP1, | 146 | StopMode::Stop1 => Lpms::STOP1, |
| 127 | #[cfg(not(any(stm32wb, stm32wba)))] | 147 | #[cfg(not(stm32wba))] |
| 128 | StopMode::Standby | StopMode::Stop2 => Lpms::STOP2, | 148 | StopMode::Standby | StopMode::Stop2 => Lpms::STOP2, |
| 129 | #[cfg(any(stm32wb, stm32wba))] | 149 | #[cfg(stm32wba)] |
| 130 | StopMode::Standby | StopMode::Stop2 => Lpms::STOP1, // TODO: WBA has no STOP2? | 150 | StopMode::Standby | StopMode::Stop2 => Lpms::STOP1, // TODO: WBA has no STOP2? |
| 131 | } | 151 | } |
| 132 | } | 152 | } |
| @@ -150,12 +170,10 @@ pub struct Executor { | |||
| 150 | impl Executor { | 170 | impl Executor { |
| 151 | /// Create a new Executor. | 171 | /// Create a new Executor. |
| 152 | pub fn new() -> Self { | 172 | pub fn new() -> Self { |
| 153 | unsafe { | 173 | if EXECUTOR_TAKEN.load(Ordering::Acquire) { |
| 154 | if EXECUTOR_TAKEN { | 174 | panic!("Low power executor can only be taken once."); |
| 155 | panic!("Low power executor can only be taken once."); | 175 | } else { |
| 156 | } else { | 176 | EXECUTOR_TAKEN.store(true, Ordering::Release); |
| 157 | EXECUTOR_TAKEN = true; | ||
| 158 | } | ||
| 159 | } | 177 | } |
| 160 | 178 | ||
| 161 | Self { | 179 | Self { |
| @@ -166,28 +184,61 @@ impl Executor { | |||
| 166 | 184 | ||
| 167 | pub(crate) unsafe fn on_wakeup_irq_or_event() { | 185 | pub(crate) unsafe fn on_wakeup_irq_or_event() { |
| 168 | if !get_driver().is_stopped() { | 186 | if !get_driver().is_stopped() { |
| 187 | trace!("low power: time driver not stopped!"); | ||
| 169 | return; | 188 | return; |
| 170 | } | 189 | } |
| 171 | 190 | ||
| 172 | critical_section::with(|cs| { | 191 | critical_section::with(|cs| { |
| 173 | #[cfg(stm32wlex)] | 192 | #[cfg(any(stm32wl, stm32wb))] |
| 174 | { | 193 | { |
| 175 | let es = crate::pac::PWR.extscr().read(); | 194 | let es = crate::pac::PWR.extscr().read(); |
| 195 | #[cfg(stm32wl)] | ||
| 176 | match (es.c1stopf(), es.c1stop2f()) { | 196 | match (es.c1stopf(), es.c1stop2f()) { |
| 177 | (true, false) => debug!("low power: wake from STOP1"), | 197 | (true, false) => debug!("low power: cpu1 wake from STOP1"), |
| 178 | (false, true) => debug!("low power: wake from STOP2"), | 198 | (false, true) => debug!("low power: cpu1 wake from STOP2"), |
| 179 | (true, true) => debug!("low power: wake from STOP1 and STOP2 ???"), | 199 | (true, true) => debug!("low power: cpu1 wake from STOP1 and STOP2 ???"), |
| 200 | (false, false) => trace!("low power: cpu1 stop mode not entered"), | ||
| 201 | }; | ||
| 202 | #[cfg(stm32wl5x)] | ||
| 203 | // TODO: only for the current cpu | ||
| 204 | match (es.c2stopf(), es.c2stop2f()) { | ||
| 205 | (true, false) => debug!("low power: cpu2 wake from STOP1"), | ||
| 206 | (false, true) => debug!("low power: cpu2 wake from STOP2"), | ||
| 207 | (true, true) => debug!("low power: cpu2 wake from STOP1 and STOP2 ???"), | ||
| 208 | (false, false) => trace!("low power: cpu2 stop mode not entered"), | ||
| 209 | }; | ||
| 210 | |||
| 211 | #[cfg(stm32wb)] | ||
| 212 | match (es.c1stopf(), es.c2stopf()) { | ||
| 213 | (true, false) => debug!("low power: cpu1 wake from STOP"), | ||
| 214 | (false, true) => debug!("low power: cpu2 wake from STOP"), | ||
| 215 | (true, true) => debug!("low power: cpu1 and cpu2 wake from STOP"), | ||
| 180 | (false, false) => trace!("low power: stop mode not entered"), | 216 | (false, false) => trace!("low power: stop mode not entered"), |
| 181 | }; | 217 | }; |
| 182 | crate::pac::PWR.extscr().modify(|w| { | ||
| 183 | w.set_c1cssf(false); | ||
| 184 | }); | ||
| 185 | 218 | ||
| 186 | if es.c1stop2f() || es.c1stopf() { | 219 | let _has_stopped2 = { |
| 220 | #[cfg(stm32wb)] | ||
| 221 | { | ||
| 222 | es.c2stopf() | ||
| 223 | } | ||
| 224 | |||
| 225 | #[cfg(stm32wlex)] | ||
| 226 | { | ||
| 227 | es.c1stop2f() | ||
| 228 | } | ||
| 229 | |||
| 230 | #[cfg(stm32wl5x)] | ||
| 231 | { | ||
| 232 | // TODO: I think we could just use c1stop2f() here as it won't enter a stop mode unless BOTH cpus will enter it. | ||
| 233 | es.c1stop2f() | es.c2stop2f() | ||
| 234 | } | ||
| 235 | }; | ||
| 236 | |||
| 237 | #[cfg(not(stm32wb))] | ||
| 238 | if es.c1stopf() || _has_stopped2 { | ||
| 187 | // when we wake from any stop mode we need to re-initialize the rcc | 239 | // when we wake from any stop mode we need to re-initialize the rcc |
| 188 | crate::rcc::init(RCC_CONFIG.unwrap()); | 240 | crate::rcc::init(RCC_CONFIG.unwrap()); |
| 189 | 241 | if _has_stopped2 { | |
| 190 | if es.c1stop2f() { | ||
| 191 | // when we wake from STOP2, we need to re-initialize the time driver | 242 | // when we wake from STOP2, we need to re-initialize the time driver |
| 192 | get_driver().init_timer(cs); | 243 | get_driver().init_timer(cs); |
| 193 | // reset the refcounts for STOP2 and STOP1 (initializing the time driver will increment one of them for the timer) | 244 | // reset the refcounts for STOP2 and STOP1 (initializing the time driver will increment one of them for the timer) |
| @@ -196,6 +247,13 @@ impl Executor { | |||
| 196 | REFCOUNT_STOP1 = 0; | 247 | REFCOUNT_STOP1 = 0; |
| 197 | } | 248 | } |
| 198 | } | 249 | } |
| 250 | // Clear all stop flags | ||
| 251 | #[cfg(stm32wl)] | ||
| 252 | crate::pac::PWR.extscr().modify(|w| { | ||
| 253 | w.set_c1cssf(true); | ||
| 254 | #[cfg(stm32wl5x)] | ||
| 255 | w.set_c2cssf(true); | ||
| 256 | }); | ||
| 199 | } | 257 | } |
| 200 | get_driver().resume_time(cs); | 258 | get_driver().resume_time(cs); |
| 201 | 259 | ||
| @@ -276,6 +334,20 @@ impl Executor { | |||
| 276 | 334 | ||
| 277 | drop(sem3_mutex); | 335 | drop(sem3_mutex); |
| 278 | 336 | ||
| 337 | // on PWR | ||
| 338 | RCC.apb1enr1().modify(|r| r.0 |= 1 << 28); | ||
| 339 | cortex_m::asm::dsb(); | ||
| 340 | |||
| 341 | // off SMPS, on Bypass | ||
| 342 | PWR.cr5().modify(|r| { | ||
| 343 | let mut val = r.0; | ||
| 344 | val &= !(1 << 15); // sdeb = 0 (off SMPS) | ||
| 345 | val |= 1 << 14; // sdben = 1 (on Bypass) | ||
| 346 | r.0 = val | ||
| 347 | }); | ||
| 348 | |||
| 349 | cortex_m::asm::delay(1000); | ||
| 350 | |||
| 279 | Ok(()) | 351 | Ok(()) |
| 280 | } | 352 | } |
| 281 | 353 | ||
| @@ -284,7 +356,7 @@ impl Executor { | |||
| 284 | #[cfg(all(stm32wb, feature = "low-power"))] | 356 | #[cfg(all(stm32wb, feature = "low-power"))] |
| 285 | self.configure_stop_stm32wb(_cs)?; | 357 | self.configure_stop_stm32wb(_cs)?; |
| 286 | 358 | ||
| 287 | #[cfg(any(stm32l4, stm32l5, stm32u5, stm32u0, stm32wb, stm32wba, stm32wlex))] | 359 | #[cfg(any(stm32l4, stm32l5, stm32u5, stm32u0, stm32wb, stm32wba, stm32wl))] |
| 288 | crate::pac::PWR.cr1().modify(|m| m.set_lpms(stop_mode.into())); | 360 | crate::pac::PWR.cr1().modify(|m| m.set_lpms(stop_mode.into())); |
| 289 | #[cfg(stm32h5)] | 361 | #[cfg(stm32h5)] |
| 290 | crate::pac::PWR.pmcr().modify(|v| { | 362 | crate::pac::PWR.pmcr().modify(|v| { |
| @@ -299,12 +371,21 @@ impl Executor { | |||
| 299 | fn configure_pwr(&self) { | 371 | fn configure_pwr(&self) { |
| 300 | Self::get_scb().clear_sleepdeep(); | 372 | Self::get_scb().clear_sleepdeep(); |
| 301 | // Clear any previous stop flags | 373 | // Clear any previous stop flags |
| 302 | #[cfg(stm32wlex)] | 374 | #[cfg(stm32wl)] |
| 303 | crate::pac::PWR.extscr().modify(|w| { | 375 | crate::pac::PWR.extscr().modify(|w| { |
| 304 | w.set_c1cssf(true); | 376 | w.set_c1cssf(true); |
| 377 | #[cfg(stm32wl5x)] | ||
| 378 | w.set_c2cssf(true); | ||
| 305 | }); | 379 | }); |
| 306 | 380 | ||
| 307 | compiler_fence(Ordering::SeqCst); | 381 | #[cfg(feature = "low-power-pender")] |
| 382 | if TASKS_PENDING.load(Ordering::Acquire) { | ||
| 383 | TASKS_PENDING.store(false, Ordering::Release); | ||
| 384 | |||
| 385 | return; | ||
| 386 | } | ||
| 387 | |||
| 388 | compiler_fence(Ordering::Acquire); | ||
| 308 | 389 | ||
| 309 | critical_section::with(|cs| { | 390 | critical_section::with(|cs| { |
| 310 | let _ = unsafe { RCC_CONFIG }?; | 391 | let _ = unsafe { RCC_CONFIG }?; |
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/mod.rs b/embassy-stm32/src/rcc/mod.rs index 2a9a1595a..c0a50615e 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs | |||
| @@ -312,6 +312,15 @@ impl RccInfo { | |||
| 312 | } | 312 | } |
| 313 | 313 | ||
| 314 | #[allow(dead_code)] | 314 | #[allow(dead_code)] |
| 315 | fn increment_minimum_stop_refcount_with_cs(&self, _cs: CriticalSection) { | ||
| 316 | #[cfg(all(any(stm32wl, stm32wb), feature = "low-power"))] | ||
| 317 | match self.stop_mode { | ||
| 318 | StopMode::Stop1 | StopMode::Stop2 => increment_stop_refcount(_cs, StopMode::Stop2), | ||
| 319 | _ => {} | ||
| 320 | } | ||
| 321 | } | ||
| 322 | |||
| 323 | #[allow(dead_code)] | ||
| 315 | pub(crate) fn increment_stop_refcount(&self) { | 324 | pub(crate) fn increment_stop_refcount(&self) { |
| 316 | #[cfg(feature = "low-power")] | 325 | #[cfg(feature = "low-power")] |
| 317 | critical_section::with(|cs| self.increment_stop_refcount_with_cs(cs)) | 326 | critical_section::with(|cs| self.increment_stop_refcount_with_cs(cs)) |
| @@ -324,6 +333,15 @@ impl RccInfo { | |||
| 324 | } | 333 | } |
| 325 | 334 | ||
| 326 | #[allow(dead_code)] | 335 | #[allow(dead_code)] |
| 336 | fn decrement_minimum_stop_refcount_with_cs(&self, _cs: CriticalSection) { | ||
| 337 | #[cfg(all(any(stm32wl, stm32wb), feature = "low-power"))] | ||
| 338 | match self.stop_mode { | ||
| 339 | StopMode::Stop1 | StopMode::Stop2 => decrement_stop_refcount(_cs, StopMode::Stop2), | ||
| 340 | _ => {} | ||
| 341 | } | ||
| 342 | } | ||
| 343 | |||
| 344 | #[allow(dead_code)] | ||
| 327 | pub(crate) fn decrement_stop_refcount(&self) { | 345 | pub(crate) fn decrement_stop_refcount(&self) { |
| 328 | #[cfg(feature = "low-power")] | 346 | #[cfg(feature = "low-power")] |
| 329 | critical_section::with(|cs| self.decrement_stop_refcount_with_cs(cs)) | 347 | critical_section::with(|cs| self.decrement_stop_refcount_with_cs(cs)) |
| @@ -339,7 +357,10 @@ impl RccInfo { | |||
| 339 | 357 | ||
| 340 | #[allow(dead_code)] | 358 | #[allow(dead_code)] |
| 341 | pub(crate) fn enable_and_reset_without_stop(&self) { | 359 | pub(crate) fn enable_and_reset_without_stop(&self) { |
| 342 | critical_section::with(|cs| self.enable_and_reset_with_cs(cs)) | 360 | critical_section::with(|cs| { |
| 361 | self.enable_and_reset_with_cs(cs); | ||
| 362 | self.increment_minimum_stop_refcount_with_cs(cs); | ||
| 363 | }) | ||
| 343 | } | 364 | } |
| 344 | 365 | ||
| 345 | // TODO: should this be `unsafe`? | 366 | // TODO: should this be `unsafe`? |
| @@ -353,7 +374,10 @@ impl RccInfo { | |||
| 353 | // TODO: should this be `unsafe`? | 374 | // TODO: should this be `unsafe`? |
| 354 | #[allow(dead_code)] | 375 | #[allow(dead_code)] |
| 355 | pub(crate) fn disable_without_stop(&self) { | 376 | pub(crate) fn disable_without_stop(&self) { |
| 356 | critical_section::with(|cs| self.disable_with_cs(cs)) | 377 | critical_section::with(|cs| { |
| 378 | self.disable_with_cs(cs); | ||
| 379 | self.decrement_minimum_stop_refcount_with_cs(cs); | ||
| 380 | }) | ||
| 357 | } | 381 | } |
| 358 | 382 | ||
| 359 | #[allow(dead_code)] | 383 | #[allow(dead_code)] |
diff --git a/embassy-stm32/src/rcc/u5.rs b/embassy-stm32/src/rcc/u5.rs index 7b0dcb63f..9f37107a3 100644 --- a/embassy-stm32/src/rcc/u5.rs +++ b/embassy-stm32/src/rcc/u5.rs | |||
| @@ -343,6 +343,16 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 343 | 343 | ||
| 344 | let hsi48 = config.hsi48.map(super::init_hsi48); | 344 | let hsi48 = config.hsi48.map(super::init_hsi48); |
| 345 | 345 | ||
| 346 | // There's a possibility that a bootloader that ran before us has configured the system clock | ||
| 347 | // source to be PLL1_R. In that case we'd get forever stuck on (de)configuring PLL1 as the chip | ||
| 348 | // prohibits disabling PLL1 when it's used as a source for system clock. Change the system | ||
| 349 | // clock source to MSIS which doesn't suffer from this conflict. The correct source per the | ||
| 350 | // provided config is then set further down. | ||
| 351 | // See https://github.com/embassy-rs/embassy/issues/5072 | ||
| 352 | let default_system_clock_source = Config::default().sys; | ||
| 353 | RCC.cfgr1().modify(|w| w.set_sw(default_system_clock_source)); | ||
| 354 | while RCC.cfgr1().read().sws() != default_system_clock_source {} | ||
| 355 | |||
| 346 | let pll_input = PllInput { hse, hsi, msi: msis }; | 356 | let pll_input = PllInput { hse, hsi, msi: msis }; |
| 347 | let pll1 = init_pll(PllInstance::Pll1, config.pll1, &pll_input, config.voltage_range); | 357 | let pll1 = init_pll(PllInstance::Pll1, config.pll1, &pll_input, config.voltage_range); |
| 348 | let pll2 = init_pll(PllInstance::Pll2, config.pll2, &pll_input, config.voltage_range); | 358 | let pll2 = init_pll(PllInstance::Pll2, config.pll2, &pll_input, config.voltage_range); |
| @@ -457,6 +467,17 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 457 | let lse = config.ls.lse.map(|l| l.frequency); | 467 | let lse = config.ls.lse.map(|l| l.frequency); |
| 458 | let lsi = config.ls.lsi.then_some(LSI_FREQ); | 468 | let lsi = config.ls.lsi.then_some(LSI_FREQ); |
| 459 | 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 | |||
| 460 | config.mux.init(); | 481 | config.mux.init(); |
| 461 | 482 | ||
| 462 | 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/rng.rs b/embassy-stm32/src/rng.rs index dada9bda1..b8dfc7ecf 100644 --- a/embassy-stm32/src/rng.rs +++ b/embassy-stm32/src/rng.rs | |||
| @@ -13,6 +13,23 @@ use crate::{Peri, interrupt, pac, peripherals, rcc}; | |||
| 13 | 13 | ||
| 14 | static RNG_WAKER: AtomicWaker = AtomicWaker::new(); | 14 | static RNG_WAKER: AtomicWaker = AtomicWaker::new(); |
| 15 | 15 | ||
| 16 | /// WBA-specific health test configuration values for RNG | ||
| 17 | #[derive(Clone, Copy)] | ||
| 18 | #[allow(dead_code)] | ||
| 19 | enum Htcfg { | ||
| 20 | /// WBA-specific health test configuration (0x0000AAC7) | ||
| 21 | /// Corresponds to configuration A, B, and C thresholds as recommended in the reference manual | ||
| 22 | WbaRecommended = 0x0000_AAC7, | ||
| 23 | } | ||
| 24 | |||
| 25 | impl Htcfg { | ||
| 26 | /// Convert to the raw u32 value for register access | ||
| 27 | #[allow(dead_code)] | ||
| 28 | fn value(self) -> u32 { | ||
| 29 | self as u32 | ||
| 30 | } | ||
| 31 | } | ||
| 32 | |||
| 16 | /// RNG error | 33 | /// RNG error |
| 17 | #[derive(Debug, PartialEq, Eq, Clone, Copy)] | 34 | #[derive(Debug, PartialEq, Eq, Clone, Copy)] |
| 18 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 35 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| @@ -100,7 +117,7 @@ impl<'d, T: Instance> Rng<'d, T> { | |||
| 100 | // wait for CONDRST to be set | 117 | // wait for CONDRST to be set |
| 101 | while !T::regs().cr().read().condrst() {} | 118 | while !T::regs().cr().read().condrst() {} |
| 102 | 119 | ||
| 103 | // TODO for WBA6, the HTCR reg is different | 120 | // Set health test configuration values |
| 104 | #[cfg(not(rng_wba6))] | 121 | #[cfg(not(rng_wba6))] |
| 105 | { | 122 | { |
| 106 | // magic number must be written immediately before every read or write access to HTCR | 123 | // magic number must be written immediately before every read or write access to HTCR |
| @@ -111,6 +128,12 @@ impl<'d, T: Instance> Rng<'d, T> { | |||
| 111 | .htcr() | 128 | .htcr() |
| 112 | .write(|w| w.set_htcfg(pac::rng::vals::Htcfg::RECOMMENDED)); | 129 | .write(|w| w.set_htcfg(pac::rng::vals::Htcfg::RECOMMENDED)); |
| 113 | } | 130 | } |
| 131 | #[cfg(rng_wba6)] | ||
| 132 | { | ||
| 133 | // For WBA6, set RNG_HTCR0 to the recommended value for configurations A, B, and C | ||
| 134 | // This value corresponds to the health test thresholds specified in the reference manual | ||
| 135 | T::regs().htcr(0).write(|w| w.0 = Htcfg::WbaRecommended.value()); | ||
| 136 | } | ||
| 114 | 137 | ||
| 115 | // finish conditioning | 138 | // finish conditioning |
| 116 | T::regs().cr().modify(|reg| { | 139 | T::regs().cr().modify(|reg| { |
diff --git a/embassy-stm32/src/rtc/low_power.rs b/embassy-stm32/src/rtc/low_power.rs index f049d6b12..e15eddc22 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 | ||
| @@ -178,11 +114,11 @@ impl Rtc { | |||
| 178 | use crate::pac::EXTI; | 114 | use crate::pac::EXTI; |
| 179 | EXTI.rtsr(0).modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true)); | 115 | EXTI.rtsr(0).modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true)); |
| 180 | 116 | ||
| 181 | #[cfg(not(stm32wb))] | 117 | #[cfg(not(any(stm32wb, stm32wl5x)))] |
| 182 | { | 118 | { |
| 183 | EXTI.imr(0).modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true)); | 119 | EXTI.imr(0).modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true)); |
| 184 | } | 120 | } |
| 185 | #[cfg(stm32wb)] | 121 | #[cfg(any(stm32wb, stm32wl5x))] |
| 186 | { | 122 | { |
| 187 | EXTI.cpu(0).imr(0).modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true)); | 123 | EXTI.cpu(0).imr(0).modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true)); |
| 188 | } | 124 | } |
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/rtc/v3.rs b/embassy-stm32/src/rtc/v3.rs index f7ebea73e..49c9778df 100644 --- a/embassy-stm32/src/rtc/v3.rs +++ b/embassy-stm32/src/rtc/v3.rs | |||
| @@ -131,7 +131,7 @@ impl SealedInstance for crate::peripherals::RTC { | |||
| 131 | 131 | ||
| 132 | #[cfg(feature = "low-power")] | 132 | #[cfg(feature = "low-power")] |
| 133 | cfg_if::cfg_if!( | 133 | cfg_if::cfg_if!( |
| 134 | if #[cfg(any(stm32g4, stm32wlex))] { | 134 | if #[cfg(any(stm32g4, stm32wl))] { |
| 135 | const EXTI_WAKEUP_LINE: usize = 20; | 135 | const EXTI_WAKEUP_LINE: usize = 20; |
| 136 | } else if #[cfg(stm32g0)] { | 136 | } else if #[cfg(stm32g0)] { |
| 137 | const EXTI_WAKEUP_LINE: usize = 19; | 137 | const EXTI_WAKEUP_LINE: usize = 19; |
| @@ -142,7 +142,7 @@ impl SealedInstance for crate::peripherals::RTC { | |||
| 142 | 142 | ||
| 143 | #[cfg(feature = "low-power")] | 143 | #[cfg(feature = "low-power")] |
| 144 | cfg_if::cfg_if!( | 144 | cfg_if::cfg_if!( |
| 145 | if #[cfg(any(stm32g4, stm32wlex))] { | 145 | if #[cfg(any(stm32g4, stm32wl))] { |
| 146 | type WakeupInterrupt = crate::interrupt::typelevel::RTC_WKUP; | 146 | type WakeupInterrupt = crate::interrupt::typelevel::RTC_WKUP; |
| 147 | } else if #[cfg(any(stm32g0, stm32u0))] { | 147 | } else if #[cfg(any(stm32g0, stm32u0))] { |
| 148 | type WakeupInterrupt = crate::interrupt::typelevel::RTC_TAMP; | 148 | type WakeupInterrupt = crate::interrupt::typelevel::RTC_TAMP; |
diff --git a/embassy-stm32/src/sdmmc/mod.rs b/embassy-stm32/src/sdmmc/mod.rs index e716fc348..cfe18ef52 100644 --- a/embassy-stm32/src/sdmmc/mod.rs +++ b/embassy-stm32/src/sdmmc/mod.rs | |||
| @@ -142,34 +142,34 @@ impl Default for Signalling { | |||
| 142 | 142 | ||
| 143 | const fn aligned_mut(x: &mut [u32]) -> &mut Aligned<A4, [u8]> { | 143 | const fn aligned_mut(x: &mut [u32]) -> &mut Aligned<A4, [u8]> { |
| 144 | let len = x.len() * 4; | 144 | let len = x.len() * 4; |
| 145 | unsafe { core::mem::transmute(slice::from_raw_parts_mut(x.as_mut_ptr() as _, len)) } | 145 | unsafe { core::mem::transmute(slice::from_raw_parts_mut(x.as_mut_ptr() as *mut u8, len)) } |
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | const fn slice8_mut(x: &mut [u32]) -> &mut [u8] { | 148 | const fn slice8_mut(x: &mut [u32]) -> &mut [u8] { |
| 149 | let len = x.len() * 4; | 149 | let len = x.len() * 4; |
| 150 | unsafe { slice::from_raw_parts_mut(x.as_mut_ptr() as _, len) } | 150 | unsafe { slice::from_raw_parts_mut(x.as_mut_ptr() as *mut u8, len) } |
| 151 | } | 151 | } |
| 152 | 152 | ||
| 153 | #[allow(unused)] | 153 | #[allow(unused)] |
| 154 | const fn slice32_mut(x: &mut Aligned<A4, [u8]>) -> &mut [u32] { | 154 | const fn slice32_mut(x: &mut Aligned<A4, [u8]>) -> &mut [u32] { |
| 155 | let len = (size_of_val(x) + 4 - 1) / 4; | 155 | let len = (size_of_val(x) + 4 - 1) / 4; |
| 156 | unsafe { slice::from_raw_parts_mut(x as *mut Aligned<A4, [u8]> as *mut _, len) } | 156 | unsafe { slice::from_raw_parts_mut(x as *mut Aligned<A4, [u8]> as *mut u32, len) } |
| 157 | } | 157 | } |
| 158 | 158 | ||
| 159 | const fn aligned_ref(x: &[u32]) -> &Aligned<A4, [u8]> { | 159 | const fn aligned_ref(x: &[u32]) -> &Aligned<A4, [u8]> { |
| 160 | let len = x.len() * 4; | 160 | let len = x.len() * 4; |
| 161 | unsafe { core::mem::transmute(slice::from_raw_parts(x.as_ptr() as _, len)) } | 161 | unsafe { core::mem::transmute(slice::from_raw_parts(x.as_ptr() as *const u8, len)) } |
| 162 | } | 162 | } |
| 163 | 163 | ||
| 164 | const fn slice8_ref(x: &[u32]) -> &[u8] { | 164 | const fn slice8_ref(x: &[u32]) -> &[u8] { |
| 165 | let len = x.len() * 4; | 165 | let len = x.len() * 4; |
| 166 | unsafe { slice::from_raw_parts(x.as_ptr() as _, len) } | 166 | unsafe { slice::from_raw_parts(x.as_ptr() as *const u8, len) } |
| 167 | } | 167 | } |
| 168 | 168 | ||
| 169 | #[allow(unused)] | 169 | #[allow(unused)] |
| 170 | const fn slice32_ref(x: &Aligned<A4, [u8]>) -> &[u32] { | 170 | const fn slice32_ref(x: &Aligned<A4, [u8]>) -> &[u32] { |
| 171 | let len = (size_of_val(x) + 4 - 1) / 4; | 171 | let len = (size_of_val(x) + 4 - 1) / 4; |
| 172 | unsafe { slice::from_raw_parts(x as *const Aligned<A4, [u8]> as *const _, len) } | 172 | unsafe { slice::from_raw_parts(x as *const Aligned<A4, [u8]> as *const u32, len) } |
| 173 | } | 173 | } |
| 174 | 174 | ||
| 175 | /// Errors | 175 | /// Errors |
| @@ -1179,6 +1179,7 @@ impl<'d> Drop for Sdmmc<'d> { | |||
| 1179 | fn drop(&mut self) { | 1179 | fn drop(&mut self) { |
| 1180 | // T::Interrupt::disable(); | 1180 | // T::Interrupt::disable(); |
| 1181 | self.on_drop(); | 1181 | self.on_drop(); |
| 1182 | self.info.rcc.disable_without_stop(); | ||
| 1182 | 1183 | ||
| 1183 | critical_section::with(|_| { | 1184 | critical_section::with(|_| { |
| 1184 | self.clk.set_as_disconnected(); | 1185 | self.clk.set_as_disconnected(); |
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index af51b79b4..13ff31a34 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs | |||
| @@ -1126,7 +1126,7 @@ impl<'d, M: PeriMode, CM: CommunicationMode> Drop for Spi<'d, M, CM> { | |||
| 1126 | self.miso.as_ref().map(|x| x.set_as_disconnected()); | 1126 | self.miso.as_ref().map(|x| x.set_as_disconnected()); |
| 1127 | self.nss.as_ref().map(|x| x.set_as_disconnected()); | 1127 | self.nss.as_ref().map(|x| x.set_as_disconnected()); |
| 1128 | 1128 | ||
| 1129 | self.info.rcc.disable(); | 1129 | self.info.rcc.disable_without_stop(); |
| 1130 | } | 1130 | } |
| 1131 | } | 1131 | } |
| 1132 | 1132 | ||
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-stm32/src/timer/input_capture.rs b/embassy-stm32/src/timer/input_capture.rs index 3e1482b67..905f2de1a 100644 --- a/embassy-stm32/src/timer/input_capture.rs +++ b/embassy-stm32/src/timer/input_capture.rs | |||
| @@ -156,6 +156,48 @@ impl<'d, T: GeneralInstance4Channel> InputCapture<'d, T> { | |||
| 156 | self.new_future(channel, InputCaptureMode::BothEdges, InputTISelection::Alternate) | 156 | self.new_future(channel, InputCaptureMode::BothEdges, InputTISelection::Alternate) |
| 157 | .await | 157 | .await |
| 158 | } | 158 | } |
| 159 | |||
| 160 | /// Capture a sequence of timer input edges into a buffer using DMA | ||
| 161 | pub async fn receive_waveform<M>(&mut self, dma: Peri<'_, impl super::Dma<T, M>>, buf: &mut [u16]) | ||
| 162 | where | ||
| 163 | M: TimerChannel, | ||
| 164 | { | ||
| 165 | #[allow(clippy::let_unit_value)] // eg. stm32f334 | ||
| 166 | let req = dma.request(); | ||
| 167 | |||
| 168 | let original_enable_state = self.is_enabled(M::CHANNEL); | ||
| 169 | let original_cc_dma_enable_state = self.inner.get_cc_dma_enable_state(M::CHANNEL); | ||
| 170 | |||
| 171 | self.inner.set_input_ti_selection(M::CHANNEL, InputTISelection::Normal); | ||
| 172 | self.inner | ||
| 173 | .set_input_capture_mode(M::CHANNEL, InputCaptureMode::BothEdges); | ||
| 174 | |||
| 175 | if !original_cc_dma_enable_state { | ||
| 176 | self.inner.set_cc_dma_enable_state(M::CHANNEL, true); | ||
| 177 | } | ||
| 178 | |||
| 179 | if !original_enable_state { | ||
| 180 | self.enable(M::CHANNEL); | ||
| 181 | } | ||
| 182 | |||
| 183 | unsafe { | ||
| 184 | use crate::dma::{Transfer, TransferOptions}; | ||
| 185 | |||
| 186 | Transfer::new_read( | ||
| 187 | dma, | ||
| 188 | req, | ||
| 189 | self.inner.regs_gp16().ccr(M::CHANNEL.index()).as_ptr() as *mut u16, | ||
| 190 | buf, | ||
| 191 | TransferOptions::default(), | ||
| 192 | ) | ||
| 193 | .await | ||
| 194 | }; | ||
| 195 | |||
| 196 | // restore output compare state | ||
| 197 | if !original_enable_state { | ||
| 198 | self.disable(M::CHANNEL); | ||
| 199 | } | ||
| 200 | } | ||
| 159 | } | 201 | } |
| 160 | 202 | ||
| 161 | #[must_use = "futures do nothing unless you `.await` or poll them"] | 203 | #[must_use = "futures do nothing unless you `.await` or poll them"] |
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-sync/src/pipe.rs b/embassy-sync/src/pipe.rs index 215a556d9..d6c21299a 100644 --- a/embassy-sync/src/pipe.rs +++ b/embassy-sync/src/pipe.rs | |||
| @@ -393,7 +393,7 @@ where | |||
| 393 | /// Attempt to immediately write some bytes to the pipe. | 393 | /// Attempt to immediately write some bytes to the pipe. |
| 394 | /// | 394 | /// |
| 395 | /// This method will either write a nonzero amount of bytes to the pipe immediately, | 395 | /// This method will either write a nonzero amount of bytes to the pipe immediately, |
| 396 | /// or return an error if the pipe is empty. See [`write`](Self::write) for a variant | 396 | /// or return an error if the pipe is full. See [`write`](Self::write) for a variant |
| 397 | /// that waits instead of returning an error. | 397 | /// that waits instead of returning an error. |
| 398 | pub fn try_write(&self, buf: &[u8]) -> Result<usize, TryWriteError> { | 398 | pub fn try_write(&self, buf: &[u8]) -> Result<usize, TryWriteError> { |
| 399 | self.try_write_with_context(None, buf) | 399 | self.try_write_with_context(None, buf) |
diff --git a/embassy-usb-dfu/Cargo.toml b/embassy-usb-dfu/Cargo.toml index 8b32582c0..4f952a047 100644 --- a/embassy-usb-dfu/Cargo.toml +++ b/embassy-usb-dfu/Cargo.toml | |||
| @@ -35,7 +35,7 @@ features = ["defmt", "cortex-m", "dfu"] | |||
| 35 | defmt = { version = "1.0.1", optional = true } | 35 | defmt = { version = "1.0.1", optional = true } |
| 36 | log = { version = "0.4.17", optional = true } | 36 | log = { version = "0.4.17", optional = true } |
| 37 | 37 | ||
| 38 | bitflags = "2.4.1" | 38 | bitflags = "2.10.0" |
| 39 | cortex-m = { version = "0.7.7", features = ["inline-asm"], optional = true } | 39 | cortex-m = { version = "0.7.7", features = ["inline-asm"], optional = true } |
| 40 | embassy-boot = { version = "0.6.1", path = "../embassy-boot" } | 40 | embassy-boot = { version = "0.6.1", path = "../embassy-boot" } |
| 41 | embassy-futures = { version = "0.1.2", path = "../embassy-futures" } | 41 | embassy-futures = { version = "0.1.2", path = "../embassy-futures" } |
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/embassy-usb/src/msos.rs b/embassy-usb/src/msos.rs index 66689871e..6d7f87061 100644 --- a/embassy-usb/src/msos.rs +++ b/embassy-usb/src/msos.rs | |||
| @@ -110,10 +110,6 @@ impl<'d> MsOsDescriptorWriter<'d> { | |||
| 110 | !self.is_empty(), | 110 | !self.is_empty(), |
| 111 | "device features may only be added after the header is written" | 111 | "device features may only be added after the header is written" |
| 112 | ); | 112 | ); |
| 113 | assert!( | ||
| 114 | self.config_mark.is_none(), | ||
| 115 | "device features must be added before the first configuration subset" | ||
| 116 | ); | ||
| 117 | self.write(desc); | 113 | self.write(desc); |
| 118 | } | 114 | } |
| 119 | 115 | ||
diff --git a/examples/boot/application/nrf/Cargo.toml b/examples/boot/application/nrf/Cargo.toml index 79286e295..ccaa24e3e 100644 --- a/examples/boot/application/nrf/Cargo.toml +++ b/examples/boot/application/nrf/Cargo.toml | |||
| @@ -9,9 +9,9 @@ publish = false | |||
| 9 | embassy-sync = { version = "0.7.2", path = "../../../../embassy-sync" } | 9 | embassy-sync = { version = "0.7.2", path = "../../../../embassy-sync" } |
| 10 | embassy-executor = { version = "0.9.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "arch-cortex-m", "executor-thread"] } | 10 | embassy-executor = { version = "0.9.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "arch-cortex-m", "executor-thread"] } |
| 11 | embassy-time = { version = "0.5.0", path = "../../../../embassy-time", features = [] } | 11 | embassy-time = { version = "0.5.0", path = "../../../../embassy-time", features = [] } |
| 12 | embassy-nrf = { version = "0.8.0", path = "../../../../embassy-nrf", features = ["gpiote", ] } | 12 | embassy-nrf = { version = "0.9.0", path = "../../../../embassy-nrf", features = ["gpiote", ] } |
| 13 | embassy-boot = { version = "0.6.1", path = "../../../../embassy-boot", features = [] } | 13 | embassy-boot = { version = "0.6.1", path = "../../../../embassy-boot", features = [] } |
| 14 | embassy-boot-nrf = { version = "0.9.0", path = "../../../../embassy-boot-nrf", features = [] } | 14 | embassy-boot-nrf = { version = "0.10.0", path = "../../../../embassy-boot-nrf", features = [] } |
| 15 | embassy-embedded-hal = { version = "0.5.0", path = "../../../../embassy-embedded-hal" } | 15 | embassy-embedded-hal = { version = "0.5.0", path = "../../../../embassy-embedded-hal" } |
| 16 | 16 | ||
| 17 | defmt = { version = "1.0.1", optional = true } | 17 | defmt = { version = "1.0.1", optional = true } |
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/mspm0g5187/.cargo/config.toml b/examples/mspm0g5187/.cargo/config.toml new file mode 100644 index 000000000..ea407b411 --- /dev/null +++ b/examples/mspm0g5187/.cargo/config.toml | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | [target.'cfg(all(target_arch = "arm", target_os = "none"))'] | ||
| 2 | # replace MSPM0G5187 with your chip as listed in `probe-rs chip list` | ||
| 3 | runner = "probe-rs run --restore-unwritten --verify --chip MSPM0G5187 --protocol=swd" | ||
| 4 | |||
| 5 | [build] | ||
| 6 | target = "thumbv6m-none-eabi" | ||
| 7 | |||
| 8 | [env] | ||
| 9 | DEFMT_LOG = "trace" | ||
diff --git a/examples/mspm0g5187/Cargo.toml b/examples/mspm0g5187/Cargo.toml new file mode 100644 index 000000000..3d64a127a --- /dev/null +++ b/examples/mspm0g5187/Cargo.toml | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | [package] | ||
| 2 | edition = "2024" | ||
| 3 | name = "embassy-mspm0-g5187-examples" | ||
| 4 | version = "0.1.0" | ||
| 5 | license = "MIT OR Apache-2.0" | ||
| 6 | publish = false | ||
| 7 | |||
| 8 | [dependencies] | ||
| 9 | embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = ["mspm0g5187pm", "defmt", "rt", "time-driver-any"] } | ||
| 10 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt"] } | ||
| 11 | embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = ["defmt"] } | ||
| 12 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt"] } | ||
| 13 | panic-halt = "1.0.0" | ||
| 14 | cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } | ||
| 15 | cortex-m-rt = { version = "0.7.0"} | ||
| 16 | defmt = "1.0.1" | ||
| 17 | defmt-rtt = "1.0.0" | ||
| 18 | panic-probe = { version = "1.0.0", features = ["print-defmt"] } | ||
| 19 | panic-semihosting = "0.6.0" | ||
| 20 | |||
| 21 | [profile.release] | ||
| 22 | debug = 2 | ||
| 23 | |||
| 24 | [package.metadata.embassy] | ||
| 25 | build = [ | ||
| 26 | { target = "thumbv6m-none-eabi", artifact-dir = "out/examples/mspm0g5187" } | ||
| 27 | ] | ||
diff --git a/examples/mspm0g5187/README.md b/examples/mspm0g5187/README.md new file mode 100644 index 000000000..12e7846fb --- /dev/null +++ b/examples/mspm0g5187/README.md | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | # Examples for MSPM0G5187 | ||
| 2 | |||
| 3 | Run individual examples with | ||
| 4 | ``` | ||
| 5 | cargo run --bin <module-name> | ||
| 6 | ``` | ||
| 7 | for example | ||
| 8 | ``` | ||
| 9 | cargo run --bin blinky | ||
| 10 | ``` | ||
| 11 | |||
| 12 | ## Checklist before running examples | ||
| 13 | A large number of the examples are written for the [LP-MSPM0G5187](https://www.ti.com/tool/LP-MSPM0G5187) board. | ||
| 14 | |||
| 15 | You might need to adjust `.cargo/config.toml`, `Cargo.toml` and possibly update pin numbers or peripherals to match the specific MCU or board you are using. | ||
| 16 | |||
| 17 | * [ ] Update .cargo/config.toml with the correct probe-rs command to use your specific MCU. For example for G5187 it should be `probe-rs run --chip MSPM0G5187`. (use `probe-rs chip list` to find your chip) | ||
| 18 | * [ ] Update Cargo.toml to have the correct `embassy-mspm0` feature. For the LP-MSPM0G3519 it should be `mspm0g3519pz`. Look in the `Cargo.toml` file of the `embassy-mspm0` project to find the correct feature flag for your chip. | ||
| 19 | * [ ] If your board has a special clock or power configuration, make sure that it is set up appropriately. | ||
| 20 | * [ ] If your board has different pin mapping, update any pin numbers or peripherals in the given example code to match your schematic | ||
| 21 | |||
| 22 | If you are unsure, please drop by the Embassy Matrix chat for support, and let us know: | ||
| 23 | |||
| 24 | * Which example you are trying to run | ||
| 25 | * Which chip and board you are using | ||
| 26 | |||
| 27 | Embassy Chat: https://matrix.to/#/#embassy-rs:matrix.org | ||
diff --git a/examples/mspm0g5187/build.rs b/examples/mspm0g5187/build.rs new file mode 100644 index 000000000..2d777c2d3 --- /dev/null +++ b/examples/mspm0g5187/build.rs | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | //! This build script copies the `memory.x` file from the crate root into | ||
| 2 | //! a directory where the linker can always find it at build time. | ||
| 3 | //! For many projects this is optional, as the linker always searches the | ||
| 4 | //! project root directory -- wherever `Cargo.toml` is. However, if you | ||
| 5 | //! are using a workspace or have a more complicated build setup, this | ||
| 6 | //! build script becomes required. Additionally, by requesting that | ||
| 7 | //! Cargo re-run the build script whenever `memory.x` is changed, | ||
| 8 | //! updating `memory.x` ensures a rebuild of the application with the | ||
| 9 | //! new memory settings. | ||
| 10 | |||
| 11 | use std::env; | ||
| 12 | use std::fs::File; | ||
| 13 | use std::io::Write; | ||
| 14 | use std::path::PathBuf; | ||
| 15 | |||
| 16 | fn main() { | ||
| 17 | // Put `memory.x` in our output directory and ensure it's | ||
| 18 | // on the linker search path. | ||
| 19 | let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); | ||
| 20 | File::create(out.join("memory.x")) | ||
| 21 | .unwrap() | ||
| 22 | .write_all(include_bytes!("memory.x")) | ||
| 23 | .unwrap(); | ||
| 24 | println!("cargo:rustc-link-search={}", out.display()); | ||
| 25 | |||
| 26 | // By default, Cargo will re-run a build script whenever | ||
| 27 | // any file in the project changes. By specifying `memory.x` | ||
| 28 | // here, we ensure the build script is only re-run when | ||
| 29 | // `memory.x` is changed. | ||
| 30 | println!("cargo:rerun-if-changed=memory.x"); | ||
| 31 | |||
| 32 | println!("cargo:rustc-link-arg-bins=--nmagic"); | ||
| 33 | println!("cargo:rustc-link-arg-bins=-Tlink.x"); | ||
| 34 | println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); | ||
| 35 | // You must tell cargo to link interrupt groups if the rt feature is enabled. | ||
| 36 | println!("cargo:rustc-link-arg-bins=-Tinterrupt_group.x"); | ||
| 37 | } | ||
diff --git a/examples/mspm0g5187/memory.x b/examples/mspm0g5187/memory.x new file mode 100644 index 000000000..37e381fbd --- /dev/null +++ b/examples/mspm0g5187/memory.x | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | MEMORY | ||
| 2 | { | ||
| 3 | FLASH : ORIGIN = 0x00000000, LENGTH = 128K | ||
| 4 | /* Select non-parity range of SRAM due to SRAM_ERR_01 errata in SLAZ758 */ | ||
| 5 | RAM : ORIGIN = 0x20200000, LENGTH = 32K | ||
| 6 | } | ||
diff --git a/examples/mspm0g5187/src/bin/blinky.rs b/examples/mspm0g5187/src/bin/blinky.rs new file mode 100644 index 000000000..47eaf1535 --- /dev/null +++ b/examples/mspm0g5187/src/bin/blinky.rs | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::*; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_mspm0::Config; | ||
| 7 | use embassy_mspm0::gpio::{Level, Output}; | ||
| 8 | use embassy_time::Timer; | ||
| 9 | use {defmt_rtt as _, panic_halt as _}; | ||
| 10 | |||
| 11 | #[embassy_executor::main] | ||
| 12 | async fn main(_spawner: Spawner) -> ! { | ||
| 13 | info!("Hello world!"); | ||
| 14 | let p = embassy_mspm0::init(Config::default()); | ||
| 15 | |||
| 16 | let mut led1 = Output::new(p.PA0, Level::Low); | ||
| 17 | led1.set_inversion(true); | ||
| 18 | |||
| 19 | loop { | ||
| 20 | Timer::after_millis(400).await; | ||
| 21 | |||
| 22 | info!("Toggle"); | ||
| 23 | led1.toggle(); | ||
| 24 | } | ||
| 25 | } | ||
diff --git a/examples/mspm0g5187/src/bin/button.rs b/examples/mspm0g5187/src/bin/button.rs new file mode 100644 index 000000000..2ed15e354 --- /dev/null +++ b/examples/mspm0g5187/src/bin/button.rs | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::*; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_mspm0::Config; | ||
| 7 | use embassy_mspm0::gpio::{Input, Level, Output, Pull}; | ||
| 8 | use {defmt_rtt as _, panic_halt as _}; | ||
| 9 | |||
| 10 | #[embassy_executor::main] | ||
| 11 | async fn main(_spawner: Spawner) -> ! { | ||
| 12 | info!("Hello world!"); | ||
| 13 | |||
| 14 | let p = embassy_mspm0::init(Config::default()); | ||
| 15 | |||
| 16 | let led1 = p.PA0; | ||
| 17 | let s2 = p.PA7; | ||
| 18 | |||
| 19 | let mut led1 = Output::new(led1, Level::Low); | ||
| 20 | |||
| 21 | let mut s2 = Input::new(s2, Pull::Up); | ||
| 22 | |||
| 23 | // led1 is active low | ||
| 24 | led1.set_high(); | ||
| 25 | |||
| 26 | loop { | ||
| 27 | s2.wait_for_falling_edge().await; | ||
| 28 | |||
| 29 | info!("Switch 2 was pressed"); | ||
| 30 | |||
| 31 | led1.toggle(); | ||
| 32 | } | ||
| 33 | } | ||
diff --git a/examples/mspm0g5187/src/bin/wwdt.rs b/examples/mspm0g5187/src/bin/wwdt.rs new file mode 100644 index 000000000..a5de781f3 --- /dev/null +++ b/examples/mspm0g5187/src/bin/wwdt.rs | |||
| @@ -0,0 +1,54 @@ | |||
| 1 | //! Example of using window watchdog timer in the MSPM0G5187 chip. | ||
| 2 | //! | ||
| 3 | //! It tests the use case when watchdog timer is expired and when watchdog is pet too early. | ||
| 4 | |||
| 5 | #![no_std] | ||
| 6 | #![no_main] | ||
| 7 | |||
| 8 | use defmt::*; | ||
| 9 | use embassy_executor::Spawner; | ||
| 10 | use embassy_mspm0::gpio::{Level, Output}; | ||
| 11 | use embassy_mspm0::wwdt::{ClosedWindowPercentage, Config, Timeout, Watchdog}; | ||
| 12 | use embassy_time::Timer; | ||
| 13 | use {defmt_rtt as _, panic_halt as _}; | ||
| 14 | |||
| 15 | #[embassy_executor::main] | ||
| 16 | async fn main(_spawner: Spawner) -> ! { | ||
| 17 | info!("Hello world!"); | ||
| 18 | |||
| 19 | let p = embassy_mspm0::init(Default::default()); | ||
| 20 | let mut conf = Config::default(); | ||
| 21 | conf.timeout = Timeout::Sec1; | ||
| 22 | |||
| 23 | // watchdog also resets the system if the pet comes too early, | ||
| 24 | // less than 250 msec == 25% from 1 sec | ||
| 25 | conf.closed_window = ClosedWindowPercentage::TwentyFive; | ||
| 26 | let mut wdt = Watchdog::new(p.WWDT0, conf); | ||
| 27 | info!("Started the watchdog timer"); | ||
| 28 | |||
| 29 | let mut led1 = Output::new(p.PA0, Level::High); | ||
| 30 | led1.set_inversion(true); | ||
| 31 | Timer::after_millis(900).await; | ||
| 32 | |||
| 33 | for _ in 1..=5 { | ||
| 34 | info!("pet watchdog"); | ||
| 35 | led1.toggle(); | ||
| 36 | wdt.pet(); | ||
| 37 | Timer::after_millis(500).await; | ||
| 38 | } | ||
| 39 | |||
| 40 | // watchdog timeout test | ||
| 41 | info!("Stopped the pet command, device will reset in less than 1 second"); | ||
| 42 | loop { | ||
| 43 | led1.toggle(); | ||
| 44 | Timer::after_millis(500).await; | ||
| 45 | } | ||
| 46 | |||
| 47 | // watchdog "too early" test | ||
| 48 | // info!("Device will reset when the pet comes too early"); | ||
| 49 | // loop { | ||
| 50 | // led1.toggle(); | ||
| 51 | // wdt.pet(); | ||
| 52 | // Timer::after_millis(200).await; | ||
| 53 | // } | ||
| 54 | } | ||
diff --git a/examples/nrf-rtos-trace/Cargo.toml b/examples/nrf-rtos-trace/Cargo.toml index 5caabf228..3d6b5e60a 100644 --- a/examples/nrf-rtos-trace/Cargo.toml +++ b/examples/nrf-rtos-trace/Cargo.toml | |||
| @@ -19,7 +19,7 @@ log = [ | |||
| 19 | embassy-sync = { version = "0.7.2", path = "../../embassy-sync" } | 19 | embassy-sync = { version = "0.7.2", path = "../../embassy-sync" } |
| 20 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "rtos-trace"] } | 20 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "rtos-trace"] } |
| 21 | embassy-time = { version = "0.5.0", path = "../../embassy-time" } | 21 | embassy-time = { version = "0.5.0", path = "../../embassy-time" } |
| 22 | embassy-nrf = { version = "0.8.0", path = "../../embassy-nrf", features = ["nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac"] } | 22 | embassy-nrf = { version = "0.9.0", path = "../../embassy-nrf", features = ["nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac"] } |
| 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/nrf51/Cargo.toml b/examples/nrf51/Cargo.toml index c7492f562..e8375952b 100644 --- a/examples/nrf51/Cargo.toml +++ b/examples/nrf51/Cargo.toml | |||
| @@ -8,7 +8,7 @@ publish = false | |||
| 8 | [dependencies] | 8 | [dependencies] |
| 9 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } | 9 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } |
| 10 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } | 10 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } |
| 11 | embassy-nrf = { version = "0.8.0", path = "../../embassy-nrf", features = ["defmt", "nrf51", "gpiote", "time-driver-rtc1", "unstable-pac", "time", "rt"] } | 11 | embassy-nrf = { version = "0.9.0", path = "../../embassy-nrf", features = ["defmt", "nrf51", "gpiote", "time-driver-rtc1", "unstable-pac", "time", "rt"] } |
| 12 | 12 | ||
| 13 | defmt = "1.0.1" | 13 | defmt = "1.0.1" |
| 14 | defmt-rtt = "1.0.0" | 14 | defmt-rtt = "1.0.0" |
diff --git a/examples/nrf52810/Cargo.toml b/examples/nrf52810/Cargo.toml index 1711a3d8d..73d129f91 100644 --- a/examples/nrf52810/Cargo.toml +++ b/examples/nrf52810/Cargo.toml | |||
| @@ -10,7 +10,7 @@ embassy-futures = { version = "0.1.2", path = "../../embassy-futures" } | |||
| 10 | embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = ["defmt"] } | 10 | embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = ["defmt"] } |
| 11 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } | 11 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } |
| 12 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } | 12 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } |
| 13 | embassy-nrf = { version = "0.8.0", path = "../../embassy-nrf", features = ["defmt", "nrf52810", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } | 13 | embassy-nrf = { version = "0.9.0", path = "../../embassy-nrf", features = ["defmt", "nrf52810", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } |
| 14 | 14 | ||
| 15 | defmt = "1.0.1" | 15 | defmt = "1.0.1" |
| 16 | defmt-rtt = "1.0.0" | 16 | defmt-rtt = "1.0.0" |
diff --git a/examples/nrf52840-edf/Cargo.toml b/examples/nrf52840-edf/Cargo.toml index 8b1db4652..8066a1150 100644 --- a/examples/nrf52840-edf/Cargo.toml +++ b/examples/nrf52840-edf/Cargo.toml | |||
| @@ -9,7 +9,7 @@ publish = false | |||
| 9 | # NOTE: "scheduler-deadline" and "embassy-time-driver" features are enabled | 9 | # NOTE: "scheduler-deadline" and "embassy-time-driver" features are enabled |
| 10 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "scheduler-deadline", "embassy-time-driver"] } | 10 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "scheduler-deadline", "embassy-time-driver"] } |
| 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-nrf = { version = "0.8.0", path = "../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } | 12 | embassy-nrf = { version = "0.9.0", path = "../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } |
| 13 | 13 | ||
| 14 | defmt = "1.0.1" | 14 | defmt = "1.0.1" |
| 15 | defmt-rtt = "1.0.0" | 15 | defmt-rtt = "1.0.0" |
diff --git a/examples/nrf52840-rtic/Cargo.toml b/examples/nrf52840-rtic/Cargo.toml index 26b21598f..13a7724fa 100644 --- a/examples/nrf52840-rtic/Cargo.toml +++ b/examples/nrf52840-rtic/Cargo.toml | |||
| @@ -12,7 +12,7 @@ embassy-futures = { version = "0.1.2", path = "../../embassy-futures" } | |||
| 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-time = { version = "0.5.0", path = "../../embassy-time", features = [ "defmt", "defmt-timestamp-uptime"] } | 13 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = [ "defmt", "defmt-timestamp-uptime"] } |
| 14 | embassy-time-queue-utils = { version = "0.3.0", path = "../../embassy-time-queue-utils", features = ["generic-queue-8"] } | 14 | embassy-time-queue-utils = { version = "0.3.0", path = "../../embassy-time-queue-utils", features = ["generic-queue-8"] } |
| 15 | embassy-nrf = { version = "0.8.0", path = "../../embassy-nrf", features = [ "defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } | 15 | embassy-nrf = { version = "0.9.0", path = "../../embassy-nrf", features = [ "defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } |
| 16 | 16 | ||
| 17 | defmt = "1.0.1" | 17 | defmt = "1.0.1" |
| 18 | defmt-rtt = "1.0.0" | 18 | defmt-rtt = "1.0.0" |
diff --git a/examples/nrf52840/Cargo.toml b/examples/nrf52840/Cargo.toml index 1fe3d2419..15c187328 100644 --- a/examples/nrf52840/Cargo.toml +++ b/examples/nrf52840/Cargo.toml | |||
| @@ -10,11 +10,11 @@ embassy-futures = { version = "0.1.2", path = "../../embassy-futures" } | |||
| 10 | embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = ["defmt"] } | 10 | embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = ["defmt"] } |
| 11 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } | 11 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } |
| 12 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } | 12 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } |
| 13 | embassy-nrf = { version = "0.8.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 97efe58e8..c54a84d22 100644 --- a/examples/nrf5340/Cargo.toml +++ b/examples/nrf5340/Cargo.toml | |||
| @@ -10,10 +10,10 @@ embassy-futures = { version = "0.1.2", path = "../../embassy-futures" } | |||
| 10 | embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = ["defmt"] } | 10 | embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = ["defmt"] } |
| 11 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] } | 11 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] } |
| 12 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } | 12 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } |
| 13 | embassy-nrf = { version = "0.8.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 f34df0f26..9940443ff 100644 --- a/examples/nrf54l15/Cargo.toml +++ b/examples/nrf54l15/Cargo.toml | |||
| @@ -10,9 +10,9 @@ embassy-futures = { version = "0.1.2", path = "../../embassy-futures" } | |||
| 10 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } | 10 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } |
| 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.8.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 5482fc77a..78ce60596 100644 --- a/examples/nrf54lm20/Cargo.toml +++ b/examples/nrf54lm20/Cargo.toml | |||
| @@ -10,9 +10,9 @@ embassy-futures = { version = "0.1.2", path = "../../embassy-futures" } | |||
| 10 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } | 10 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } |
| 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.8.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/nrf9151/ns/Cargo.toml b/examples/nrf9151/ns/Cargo.toml index 7f1f5239a..f6d6aab6f 100644 --- a/examples/nrf9151/ns/Cargo.toml +++ b/examples/nrf9151/ns/Cargo.toml | |||
| @@ -8,7 +8,7 @@ publish = false | |||
| 8 | [dependencies] | 8 | [dependencies] |
| 9 | embassy-executor = { version = "0.9.0", path = "../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } | 9 | embassy-executor = { version = "0.9.0", path = "../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } |
| 10 | embassy-time = { version = "0.5.0", path = "../../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } | 10 | embassy-time = { version = "0.5.0", path = "../../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } |
| 11 | embassy-nrf = { version = "0.8.0", path = "../../../embassy-nrf", features = ["defmt", "nrf9120-ns", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } | 11 | embassy-nrf = { version = "0.9.0", path = "../../../embassy-nrf", features = ["defmt", "nrf9120-ns", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } |
| 12 | 12 | ||
| 13 | defmt = "1.0.1" | 13 | defmt = "1.0.1" |
| 14 | defmt-rtt = "1.0.0" | 14 | defmt-rtt = "1.0.0" |
diff --git a/examples/nrf9151/s/Cargo.toml b/examples/nrf9151/s/Cargo.toml index ce71cc456..1c9e7fb35 100644 --- a/examples/nrf9151/s/Cargo.toml +++ b/examples/nrf9151/s/Cargo.toml | |||
| @@ -8,7 +8,7 @@ publish = false | |||
| 8 | [dependencies] | 8 | [dependencies] |
| 9 | embassy-executor = { version = "0.9.0", path = "../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } | 9 | embassy-executor = { version = "0.9.0", path = "../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } |
| 10 | embassy-time = { version = "0.5.0", path = "../../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } | 10 | embassy-time = { version = "0.5.0", path = "../../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } |
| 11 | embassy-nrf = { version = "0.8.0", path = "../../../embassy-nrf", features = ["defmt", "nrf9120-s", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } | 11 | embassy-nrf = { version = "0.9.0", path = "../../../embassy-nrf", features = ["defmt", "nrf9120-s", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } |
| 12 | 12 | ||
| 13 | defmt = "1.0.1" | 13 | defmt = "1.0.1" |
| 14 | defmt-rtt = "1.0.0" | 14 | defmt-rtt = "1.0.0" |
diff --git a/examples/nrf9160/Cargo.toml b/examples/nrf9160/Cargo.toml index ae3b2eeb1..bad7fdc79 100644 --- a/examples/nrf9160/Cargo.toml +++ b/examples/nrf9160/Cargo.toml | |||
| @@ -8,7 +8,7 @@ publish = false | |||
| 8 | [dependencies] | 8 | [dependencies] |
| 9 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } | 9 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } |
| 10 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } | 10 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } |
| 11 | embassy-nrf = { version = "0.8.0", path = "../../embassy-nrf", features = ["defmt", "nrf9160-s", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } | 11 | embassy-nrf = { version = "0.9.0", path = "../../embassy-nrf", features = ["defmt", "nrf9160-s", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } |
| 12 | embassy-net-nrf91 = { version = "0.1.0", path = "../../embassy-net-nrf91", features = ["defmt"] } | 12 | embassy-net-nrf91 = { version = "0.1.0", path = "../../embassy-net-nrf91", features = ["defmt"] } |
| 13 | embassy-net = { version = "0.7.1", path = "../../embassy-net", features = ["defmt", "tcp", "proto-ipv4", "medium-ip"] } | 13 | embassy-net = { version = "0.7.1", path = "../../embassy-net", features = ["defmt", "tcp", "proto-ipv4", "medium-ip"] } |
| 14 | 14 | ||
| @@ -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/rp/src/bin/usb_webusb.rs b/examples/rp/src/bin/usb_webusb.rs index 5cecb92f0..edc9a0c52 100644 --- a/examples/rp/src/bin/usb_webusb.rs +++ b/examples/rp/src/bin/usb_webusb.rs | |||
| @@ -26,6 +26,7 @@ use embassy_rp::usb::{Driver as UsbDriver, InterruptHandler}; | |||
| 26 | use embassy_usb::class::web_usb::{Config as WebUsbConfig, State, Url, WebUsb}; | 26 | use embassy_usb::class::web_usb::{Config as WebUsbConfig, State, Url, WebUsb}; |
| 27 | use embassy_usb::driver::{Driver, Endpoint, EndpointIn, EndpointOut}; | 27 | use embassy_usb::driver::{Driver, Endpoint, EndpointIn, EndpointOut}; |
| 28 | use embassy_usb::msos::{self, windows_version}; | 28 | use embassy_usb::msos::{self, windows_version}; |
| 29 | use embassy_usb::types::InterfaceNumber; | ||
| 29 | use embassy_usb::{Builder, Config}; | 30 | use embassy_usb::{Builder, Config}; |
| 30 | use {defmt_rtt as _, panic_probe as _}; | 31 | use {defmt_rtt as _, panic_probe as _}; |
| 31 | 32 | ||
| @@ -56,7 +57,7 @@ async fn main(_spawner: Spawner) { | |||
| 56 | let mut config_descriptor = [0; 256]; | 57 | let mut config_descriptor = [0; 256]; |
| 57 | let mut bos_descriptor = [0; 256]; | 58 | let mut bos_descriptor = [0; 256]; |
| 58 | let mut control_buf = [0; 64]; | 59 | let mut control_buf = [0; 64]; |
| 59 | let mut msos_descriptor = [0; 256]; | 60 | let mut msos_descriptor = [0; 512]; |
| 60 | 61 | ||
| 61 | let webusb_config = WebUsbConfig { | 62 | let webusb_config = WebUsbConfig { |
| 62 | max_packet_size: 64, | 63 | max_packet_size: 64, |
| @@ -83,6 +84,14 @@ async fn main(_spawner: Spawner) { | |||
| 83 | // In principle you might want to call msos_feature() just on a specific function, | 84 | // In principle you might want to call msos_feature() just on a specific function, |
| 84 | // if your device also has other functions that still use standard class drivers. | 85 | // if your device also has other functions that still use standard class drivers. |
| 85 | builder.msos_descriptor(windows_version::WIN8_1, 0); | 86 | builder.msos_descriptor(windows_version::WIN8_1, 0); |
| 87 | builder.msos_writer().configuration(0); | ||
| 88 | builder.msos_writer().function(InterfaceNumber(0)); | ||
| 89 | builder.msos_feature(msos::CompatibleIdFeatureDescriptor::new("WINUSB", "")); | ||
| 90 | builder.msos_feature(msos::RegistryPropertyFeatureDescriptor::new( | ||
| 91 | "DeviceInterfaceGUIDs", | ||
| 92 | msos::PropertyData::RegMultiSz(DEVICE_INTERFACE_GUIDS), | ||
| 93 | )); | ||
| 94 | builder.msos_writer().function(InterfaceNumber(1)); | ||
| 86 | builder.msos_feature(msos::CompatibleIdFeatureDescriptor::new("WINUSB", "")); | 95 | builder.msos_feature(msos::CompatibleIdFeatureDescriptor::new("WINUSB", "")); |
| 87 | builder.msos_feature(msos::RegistryPropertyFeatureDescriptor::new( | 96 | builder.msos_feature(msos::RegistryPropertyFeatureDescriptor::new( |
| 88 | "DeviceInterfaceGUIDs", | 97 | "DeviceInterfaceGUIDs", |
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 6dc6a353d..06f1ba67e 100644 --- a/examples/std/Cargo.toml +++ b/examples/std/Cargo.toml | |||
| @@ -10,10 +10,10 @@ embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = ["lo | |||
| 10 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-std", "executor-thread", "log"] } | 10 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-std", "executor-thread", "log"] } |
| 11 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["log", "std", ] } | 11 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["log", "std", ] } |
| 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.0", 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/stm32wba/src/bin/mac_ffd.rs b/examples/stm32wba/src/bin/mac_ffd.rs index b15fb3452..329a73c6d 100644 --- a/examples/stm32wba/src/bin/mac_ffd.rs +++ b/examples/stm32wba/src/bin/mac_ffd.rs | |||
| @@ -5,7 +5,7 @@ use defmt::*; | |||
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::Config; | 6 | use embassy_stm32::Config; |
| 7 | use embassy_stm32::rcc::{Sysclk, mux}; | 7 | use embassy_stm32::rcc::{Sysclk, mux}; |
| 8 | use embassy_stm32_wpan::bindings::mac::ST_MAC_callbacks_t; | 8 | use embassy_stm32_wpan::bindings::mac::{ST_MAC_callbacks_t, ST_MAC_init}; |
| 9 | use {defmt_rtt as _, panic_probe as _}; | 9 | use {defmt_rtt as _, panic_probe as _}; |
| 10 | 10 | ||
| 11 | static _MAC_CALLBACKS: ST_MAC_callbacks_t = ST_MAC_callbacks_t { | 11 | static _MAC_CALLBACKS: ST_MAC_callbacks_t = ST_MAC_callbacks_t { |
| @@ -50,9 +50,9 @@ async fn main(_spawner: Spawner) { | |||
| 50 | let _p = embassy_stm32::init(config); | 50 | let _p = embassy_stm32::init(config); |
| 51 | info!("Hello World!"); | 51 | info!("Hello World!"); |
| 52 | 52 | ||
| 53 | // let status = unsafe { ST_MAC_init(&_MAC_CALLBACKS as *const _ as *mut _) }; | 53 | let status = unsafe { ST_MAC_init(&_MAC_CALLBACKS as *const _ as *mut _) }; |
| 54 | // | 54 | |
| 55 | // info!("mac init: {}", status); | 55 | info!("mac init: {}", status); |
| 56 | 56 | ||
| 57 | cortex_m::asm::bkpt(); | 57 | cortex_m::asm::bkpt(); |
| 58 | } | 58 | } |
diff --git a/examples/stm32wl5x-lp/.cargo/config.toml b/examples/stm32wl5x-lp/.cargo/config.toml new file mode 100644 index 000000000..969068656 --- /dev/null +++ b/examples/stm32wl5x-lp/.cargo/config.toml | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | [target.'cfg(all(target_arch = "arm", target_os = "none"))'] | ||
| 2 | # replace your chip as listed in `probe-rs chip list` | ||
| 3 | runner = "probe-rs run --chip STM32WLE5JCIx --connect-under-reset" | ||
| 4 | |||
| 5 | [build] | ||
| 6 | target = "thumbv7em-none-eabi" | ||
| 7 | |||
| 8 | [env] | ||
| 9 | DEFMT_LOG = "debug" | ||
diff --git a/examples/stm32wl5x-lp/Cargo.toml b/examples/stm32wl5x-lp/Cargo.toml new file mode 100644 index 000000000..b1823fb8a --- /dev/null +++ b/examples/stm32wl5x-lp/Cargo.toml | |||
| @@ -0,0 +1,39 @@ | |||
| 1 | [package] | ||
| 2 | edition = "2024" | ||
| 3 | name = "embassy-stm32wl5x-lp" | ||
| 4 | version = "0.1.0" | ||
| 5 | license = "MIT OR Apache-2.0" | ||
| 6 | publish = false | ||
| 7 | |||
| 8 | [dependencies] | ||
| 9 | # Change stm32wl55jc-cm4 to your chip name, if necessary. | ||
| 10 | embassy-stm32 = { version = "0.4.0", path = "../../embassy-stm32", features = ["defmt", "stm32wl55jc-cm4", "time-driver-any", "memory-x", "unstable-pac", "exti", "chrono", "low-power-pender"] } | ||
| 11 | embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = ["defmt"] } | ||
| 12 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["defmt"] } | ||
| 13 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } | ||
| 14 | embassy-embedded-hal = { version = "0.5.0", path = "../../embassy-embedded-hal" } | ||
| 15 | |||
| 16 | defmt = "1.0.1" | ||
| 17 | defmt-rtt = { version = "1.1.0", optional = true } | ||
| 18 | defmt-serial = { git = "https://github.com/gauteh/defmt-serial", rev = "411ae7fa909b4fd2667885aff687e009b9108190", optional = true } | ||
| 19 | |||
| 20 | cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } | ||
| 21 | cortex-m-rt = "0.7.0" | ||
| 22 | embedded-hal = "1.0.0" | ||
| 23 | embedded-storage = "0.3.1" | ||
| 24 | panic-probe = { version = "1.0.0", features = ["print-defmt"] } | ||
| 25 | chrono = { version = "^0.4", default-features = false } | ||
| 26 | static_cell = { version = "2.1.1", default-features = false } | ||
| 27 | |||
| 28 | [profile.release] | ||
| 29 | debug = 2 | ||
| 30 | |||
| 31 | [package.metadata.embassy] | ||
| 32 | build = [ | ||
| 33 | { target = "thumbv7em-none-eabi", artifact-dir = "out/examples/stm32wl" } | ||
| 34 | ] | ||
| 35 | |||
| 36 | [features] | ||
| 37 | default = ["defmt-serial"] | ||
| 38 | defmt-rtt = ["dep:defmt-rtt"] | ||
| 39 | defmt-serial = ["dep:defmt-serial"] | ||
diff --git a/examples/stm32wl5x-lp/build.rs b/examples/stm32wl5x-lp/build.rs new file mode 100644 index 000000000..8cd32d7ed --- /dev/null +++ b/examples/stm32wl5x-lp/build.rs | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | fn main() { | ||
| 2 | println!("cargo:rustc-link-arg-bins=--nmagic"); | ||
| 3 | println!("cargo:rustc-link-arg-bins=-Tlink.x"); | ||
| 4 | println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); | ||
| 5 | } | ||
diff --git a/examples/stm32wl5x-lp/memory.x b/examples/stm32wl5x-lp/memory.x new file mode 100644 index 000000000..4590867a8 --- /dev/null +++ b/examples/stm32wl5x-lp/memory.x | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | MEMORY | ||
| 2 | { | ||
| 3 | /* NOTE 1 K = 1 KiBi = 1024 bytes */ | ||
| 4 | FLASH : ORIGIN = 0x08000000, LENGTH = 256K | ||
| 5 | SHARED_RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 128 | ||
| 6 | RAM (rwx) : ORIGIN = 0x20000080, LENGTH = 64K - 128 | ||
| 7 | } | ||
| 8 | |||
| 9 | SECTIONS | ||
| 10 | { | ||
| 11 | .shared_data : | ||
| 12 | { | ||
| 13 | *(.shared_data) | ||
| 14 | } > SHARED_RAM | ||
| 15 | } | ||
diff --git a/examples/stm32wl5x-lp/src/bin/blinky.rs b/examples/stm32wl5x-lp/src/bin/blinky.rs new file mode 100644 index 000000000..60b671a77 --- /dev/null +++ b/examples/stm32wl5x-lp/src/bin/blinky.rs | |||
| @@ -0,0 +1,57 @@ | |||
| 1 | // This example is configured for the nucleo-wl55jc board. Curret monitor should show just a few microamps when the device is in stop2 mode. | ||
| 2 | #![no_std] | ||
| 3 | #![no_main] | ||
| 4 | |||
| 5 | use core::mem::MaybeUninit; | ||
| 6 | |||
| 7 | use defmt::*; | ||
| 8 | #[cfg(feature = "defmt-rtt")] | ||
| 9 | use defmt_rtt as _; | ||
| 10 | use embassy_executor::Spawner; | ||
| 11 | use embassy_stm32::SharedData; | ||
| 12 | use embassy_stm32::gpio::{Level, Output, Speed}; | ||
| 13 | use embassy_time::Timer; | ||
| 14 | use panic_probe as _; | ||
| 15 | |||
| 16 | #[unsafe(link_section = ".shared_data")] | ||
| 17 | static SHARED_DATA: MaybeUninit<SharedData> = MaybeUninit::uninit(); | ||
| 18 | |||
| 19 | #[embassy_executor::main(executor = "embassy_stm32::Executor", entry = "cortex_m_rt::entry")] | ||
| 20 | async fn async_main(_spawner: Spawner) { | ||
| 21 | let mut config = embassy_stm32::Config::default(); | ||
| 22 | config.rcc.ls = embassy_stm32::rcc::LsConfig::default_lsi(); | ||
| 23 | config.rcc.msi = Some(embassy_stm32::rcc::MSIRange::RANGE4M); | ||
| 24 | config.rcc.sys = embassy_stm32::rcc::Sysclk::MSI; | ||
| 25 | #[cfg(feature = "defmt-serial")] | ||
| 26 | { | ||
| 27 | // disable debug during sleep to reduce power consumption since we are | ||
| 28 | // using defmt-serial on LPUART1. | ||
| 29 | config.enable_debug_during_sleep = false; | ||
| 30 | } | ||
| 31 | let p = embassy_stm32::init_primary(config, &SHARED_DATA); | ||
| 32 | |||
| 33 | #[cfg(feature = "defmt-serial")] | ||
| 34 | { | ||
| 35 | use embassy_stm32::mode::Blocking; | ||
| 36 | use embassy_stm32::usart::Uart; | ||
| 37 | use static_cell::StaticCell; | ||
| 38 | let config = embassy_stm32::usart::Config::default(); | ||
| 39 | let uart = Uart::new_blocking(p.LPUART1, p.PA3, p.PA2, config).expect("failed to configure UART!"); | ||
| 40 | static SERIAL: StaticCell<Uart<'static, Blocking>> = StaticCell::new(); | ||
| 41 | defmt_serial::defmt_serial(SERIAL.init(uart)); | ||
| 42 | } | ||
| 43 | |||
| 44 | info!("Hello World!"); | ||
| 45 | |||
| 46 | let mut led = Output::new(p.PB15, Level::High, Speed::Low); | ||
| 47 | |||
| 48 | loop { | ||
| 49 | info!("low"); | ||
| 50 | led.set_low(); | ||
| 51 | Timer::after_millis(5000).await; | ||
| 52 | |||
| 53 | info!("high"); | ||
| 54 | led.set_high(); | ||
| 55 | Timer::after_millis(5000).await; | ||
| 56 | } | ||
| 57 | } | ||
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/examples/stm32wle5/src/bin/adc.rs b/examples/stm32wle5/src/bin/adc.rs index ea91fb063..8cc84ccdf 100644 --- a/examples/stm32wle5/src/bin/adc.rs +++ b/examples/stm32wle5/src/bin/adc.rs | |||
| @@ -34,24 +34,6 @@ async fn async_main(_spawner: Spawner) { | |||
| 34 | // Initialize STM32WL peripherals (use default config like wio-e5-async example) | 34 | // Initialize STM32WL peripherals (use default config like wio-e5-async example) |
| 35 | let p = embassy_stm32::init(config); | 35 | let p = embassy_stm32::init(config); |
| 36 | 36 | ||
| 37 | // start with all GPIOs as analog to reduce power consumption | ||
| 38 | for r in [ | ||
| 39 | embassy_stm32::pac::GPIOA, | ||
| 40 | embassy_stm32::pac::GPIOB, | ||
| 41 | embassy_stm32::pac::GPIOC, | ||
| 42 | embassy_stm32::pac::GPIOH, | ||
| 43 | ] { | ||
| 44 | r.moder().modify(|w| { | ||
| 45 | for i in 0..16 { | ||
| 46 | // don't reset these if probe-rs should stay connected! | ||
| 47 | #[cfg(feature = "defmt-rtt")] | ||
| 48 | if config.enable_debug_during_sleep && r == embassy_stm32::pac::GPIOA && [13, 14].contains(&i) { | ||
| 49 | continue; | ||
| 50 | } | ||
| 51 | w.set_moder(i, embassy_stm32::pac::gpio::vals::Moder::ANALOG); | ||
| 52 | } | ||
| 53 | }); | ||
| 54 | } | ||
| 55 | #[cfg(feature = "defmt-serial")] | 37 | #[cfg(feature = "defmt-serial")] |
| 56 | { | 38 | { |
| 57 | use embassy_stm32::mode::Blocking; | 39 | use embassy_stm32::mode::Blocking; |
diff --git a/examples/stm32wle5/src/bin/blinky.rs b/examples/stm32wle5/src/bin/blinky.rs index 9f0c04672..3b7eb7761 100644 --- a/examples/stm32wle5/src/bin/blinky.rs +++ b/examples/stm32wle5/src/bin/blinky.rs | |||
| @@ -32,24 +32,6 @@ async fn async_main(_spawner: Spawner) { | |||
| 32 | // Initialize STM32WL peripherals (use default config like wio-e5-async example) | 32 | // Initialize STM32WL peripherals (use default config like wio-e5-async example) |
| 33 | let p = embassy_stm32::init(config); | 33 | let p = embassy_stm32::init(config); |
| 34 | 34 | ||
| 35 | // start with all GPIOs as analog to reduce power consumption | ||
| 36 | for r in [ | ||
| 37 | embassy_stm32::pac::GPIOA, | ||
| 38 | embassy_stm32::pac::GPIOB, | ||
| 39 | embassy_stm32::pac::GPIOC, | ||
| 40 | embassy_stm32::pac::GPIOH, | ||
| 41 | ] { | ||
| 42 | r.moder().modify(|w| { | ||
| 43 | for i in 0..16 { | ||
| 44 | // don't reset these if probe-rs should stay connected! | ||
| 45 | #[cfg(feature = "defmt-rtt")] | ||
| 46 | if config.enable_debug_during_sleep && r == embassy_stm32::pac::GPIOA && [13, 14].contains(&i) { | ||
| 47 | continue; | ||
| 48 | } | ||
| 49 | w.set_moder(i, embassy_stm32::pac::gpio::vals::Moder::ANALOG); | ||
| 50 | } | ||
| 51 | }); | ||
| 52 | } | ||
| 53 | #[cfg(feature = "defmt-serial")] | 35 | #[cfg(feature = "defmt-serial")] |
| 54 | { | 36 | { |
| 55 | use embassy_stm32::mode::Blocking; | 37 | use embassy_stm32::mode::Blocking; |
| @@ -67,10 +49,10 @@ async fn async_main(_spawner: Spawner) { | |||
| 67 | loop { | 49 | loop { |
| 68 | info!("low"); | 50 | info!("low"); |
| 69 | led.set_low(); | 51 | led.set_low(); |
| 70 | Timer::after_millis(500).await; | 52 | Timer::after_millis(15000).await; |
| 71 | 53 | ||
| 72 | info!("high"); | 54 | info!("high"); |
| 73 | led.set_high(); | 55 | led.set_high(); |
| 74 | Timer::after_millis(500).await; | 56 | Timer::after_millis(15000).await; |
| 75 | } | 57 | } |
| 76 | } | 58 | } |
diff --git a/examples/stm32wle5/src/bin/button_exti.rs b/examples/stm32wle5/src/bin/button_exti.rs index f248b6147..9ffc39948 100644 --- a/examples/stm32wle5/src/bin/button_exti.rs +++ b/examples/stm32wle5/src/bin/button_exti.rs | |||
| @@ -39,24 +39,6 @@ async fn async_main(_spawner: Spawner) { | |||
| 39 | // Initialize STM32WL peripherals (use default config like wio-e5-async example) | 39 | // Initialize STM32WL peripherals (use default config like wio-e5-async example) |
| 40 | let p = embassy_stm32::init(config); | 40 | let p = embassy_stm32::init(config); |
| 41 | 41 | ||
| 42 | // start with all GPIOs as analog to reduce power consumption | ||
| 43 | for r in [ | ||
| 44 | embassy_stm32::pac::GPIOA, | ||
| 45 | embassy_stm32::pac::GPIOB, | ||
| 46 | embassy_stm32::pac::GPIOC, | ||
| 47 | embassy_stm32::pac::GPIOH, | ||
| 48 | ] { | ||
| 49 | r.moder().modify(|w| { | ||
| 50 | for i in 0..16 { | ||
| 51 | // don't reset these if probe-rs should stay connected! | ||
| 52 | #[cfg(feature = "defmt-rtt")] | ||
| 53 | if config.enable_debug_during_sleep && r == embassy_stm32::pac::GPIOA && [13, 14].contains(&i) { | ||
| 54 | continue; | ||
| 55 | } | ||
| 56 | w.set_moder(i, embassy_stm32::pac::gpio::vals::Moder::ANALOG); | ||
| 57 | } | ||
| 58 | }); | ||
| 59 | } | ||
| 60 | #[cfg(feature = "defmt-serial")] | 42 | #[cfg(feature = "defmt-serial")] |
| 61 | { | 43 | { |
| 62 | use embassy_stm32::mode::Blocking; | 44 | use embassy_stm32::mode::Blocking; |
diff --git a/examples/stm32wle5/src/bin/i2c.rs b/examples/stm32wle5/src/bin/i2c.rs index 68c17a672..8e7a6e2d8 100644 --- a/examples/stm32wle5/src/bin/i2c.rs +++ b/examples/stm32wle5/src/bin/i2c.rs | |||
| @@ -40,24 +40,6 @@ async fn async_main(_spawner: Spawner) { | |||
| 40 | // Initialize STM32WL peripherals (use default config like wio-e5-async example) | 40 | // Initialize STM32WL peripherals (use default config like wio-e5-async example) |
| 41 | let p = embassy_stm32::init(config); | 41 | let p = embassy_stm32::init(config); |
| 42 | 42 | ||
| 43 | // start with all GPIOs as analog to reduce power consumption | ||
| 44 | for r in [ | ||
| 45 | embassy_stm32::pac::GPIOA, | ||
| 46 | embassy_stm32::pac::GPIOB, | ||
| 47 | embassy_stm32::pac::GPIOC, | ||
| 48 | embassy_stm32::pac::GPIOH, | ||
| 49 | ] { | ||
| 50 | r.moder().modify(|w| { | ||
| 51 | for i in 0..16 { | ||
| 52 | // don't reset these if probe-rs should stay connected! | ||
| 53 | #[cfg(feature = "defmt-rtt")] | ||
| 54 | if config.enable_debug_during_sleep && r == embassy_stm32::pac::GPIOA && [13, 14].contains(&i) { | ||
| 55 | continue; | ||
| 56 | } | ||
| 57 | w.set_moder(i, embassy_stm32::pac::gpio::vals::Moder::ANALOG); | ||
| 58 | } | ||
| 59 | }); | ||
| 60 | } | ||
| 61 | #[cfg(feature = "defmt-serial")] | 43 | #[cfg(feature = "defmt-serial")] |
| 62 | { | 44 | { |
| 63 | use embassy_stm32::mode::Blocking; | 45 | use embassy_stm32::mode::Blocking; |
| @@ -79,7 +61,7 @@ async fn async_main(_spawner: Spawner) { | |||
| 79 | let mut i2c = I2c::new(p.I2C2, p.PB15, p.PA15, IrqsI2C, p.DMA1_CH6, p.DMA1_CH7, { | 61 | let mut i2c = I2c::new(p.I2C2, p.PB15, p.PA15, IrqsI2C, p.DMA1_CH6, p.DMA1_CH7, { |
| 80 | let mut config = i2c::Config::default(); | 62 | let mut config = i2c::Config::default(); |
| 81 | config.frequency = Hertz::khz(100); | 63 | config.frequency = Hertz::khz(100); |
| 82 | config.timeout = Duration::from_millis(500); | 64 | config.timeout = Duration::from_millis(1000); |
| 83 | config | 65 | config |
| 84 | }); | 66 | }); |
| 85 | 67 | ||
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 3a9b86cef..b1e0a68c2 100644 --- a/tests/nrf/Cargo.toml +++ b/tests/nrf/Cargo.toml | |||
| @@ -12,8 +12,8 @@ embassy-futures = { version = "0.1.2", path = "../../embassy-futures" } | |||
| 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 = ["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.8.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 | } |
