Compare commits

...

66 Commits

Author SHA1 Message Date
8911a4d855 stm32/rcc: switch to modern api for l0, l1. 2023-11-05 03:06:13 +01:00
056c409443 Merge pull request #2140 from xoviat/low-power
stm32: compute stop mode and workaround rtt test bug
2023-11-04 18:57:44 +00:00
3f2abd4fd5 Merge branch 'main' of github.com:embassy-rs/embassy into low-power 2023-11-04 13:51:11 -05:00
dc467e89a0 stm32: compute stop mode and workaround rtt test bug 2023-11-04 13:49:54 -05:00
655ed3aa88 Merge pull request #2122 from bgamari/wip/low-power-docs
stm32: Add some documentation to `low_power`
2023-11-04 16:26:41 +00:00
14ec0d27bf Merge pull request #2138 from kalkyl/pwm-input
rp: Add PWM input example
2023-11-02 23:42:31 +00:00
649f1a122a Cleanup 2023-11-03 00:41:16 +01:00
413b394d31 rp: Add PWM input example 2023-11-03 00:37:58 +01:00
7ea2c3508a Merge pull request #2137 from kalkyl/pio-rotary-encoder
rp: Add PIO rotary encoder example
2023-11-02 21:52:01 +00:00
ec744558b2 Cleanup 2023-11-02 22:37:03 +01:00
1b9292dbcd Merge pull request #2136 from embassy-rs/static-cell-v2
Upgrade static-cell to v2.0
2023-11-02 21:00:21 +00:00
44486c5b39 rp: Add PIO rotary encoder example 2023-11-02 21:54:20 +01:00
1f51367eb9 Upgrade static-cell to v2.0 2023-11-02 21:52:07 +01:00
d6f42eafad Merge pull request #2135 from newAM/update-ehm
embedded-hal-mock: git -> 0.10.0-rc.1
2023-11-02 01:05:56 +00:00
dcce8945af embedded-hal-mock: git -> 0.10.0-rc.1 2023-11-01 16:46:15 -07:00
d98c064bfe Merge pull request #2134 from xoviat/revert-rcc
stm32/rcc: revert part of #2106
2023-11-01 22:31:43 +00:00
a904538555 stm32/rcc: revert part of #2106 2023-11-01 17:27:33 -05:00
4ef3dc5b90 Merge pull request #2099 from xoviat/rtc
stm32/rtc: misc and low-power cleanup
2023-11-01 22:19:03 +00:00
bab61f9665 stm32/rtc: misc. cleanup and move to bps by default 2023-11-01 17:17:14 -05:00
2765f0978f Merge pull request #2133 from Radiator-Labs/main
Reinstate rcc::Config adc_clock_source field
2023-11-01 20:35:03 +00:00
bc07539133 Fix missed field in cfg'd code 2023-11-01 13:30:04 -07:00
b4a82b7ed4 Correct adc_clock_source for all µprocs in l4l5.rs 2023-11-01 13:22:50 -07:00
e2688dda22 Eliminates redefinition of AdcClockSource 2023-11-01 12:06:19 -07:00
d0d8585e4c Reinstate rcc::Config adc_clock_source field 2023-11-01 11:46:17 -07:00
729d69246a Merge pull request #2131 from adamgreig/stm32-exti-high-channels
stm32: Don't try handle EXTI inputs above 16
2023-11-01 04:35:31 +00:00
e78a6db151 stm32: Don't try handle EXTI inputs above 16 2023-11-01 05:23:34 +01:00
f8721c3786 Merge pull request #2132 from embassy-rs/update-nightly
Update Rust nightly.
2023-11-01 04:10:03 +00:00
e519e00265 Update Rust nightly. 2023-11-01 04:56:56 +01:00
35bb20abe7 Merge pull request #2130 from andresovela/time-mock-driver-fix
time: fix MockDriver::now()
2023-10-31 23:36:56 +00:00
dd6a29adb2 Release embassy-executor v0.3.1 2023-11-01 00:17:44 +01:00
5f9602d28b time: fix MockDriver::now() 2023-10-31 22:48:52 +01:00
74683c706b Merge pull request #2127 from bugadani/release
Prepare embassy-net 0.2.1 and embassy-sync 0.4.0
2023-10-31 15:57:51 +00:00
2795e1350d Merge pull request #2128 from bugadani/poll
Drop `futures` dependency in `embassy-nrf`
2023-10-31 15:53:54 +00:00
aed3e5674f Drop futures dependency in embassy-nrf 2023-10-31 10:13:27 +01:00
d941882066 Prepare embassy-net 0.2.1 and embassy-sync 0.4.0 2023-10-31 09:33:27 +01:00
3f74ff7235 Merge pull request #2123 from bugadani/feature
Re-add impl_trait_projections
2023-10-31 02:26:51 +01:00
9cead47212 Merge pull request #2124 from kalkyl/pio-stepper
rp: Add PIO stepper motor driver example
2023-10-31 02:26:38 +01:00
78739d4aa9 Merge pull request #2120 from andresovela/time-mock-driver
time: add `MockDriver` for testing purposes
2023-10-31 01:10:19 +00:00
e07e790613 Merge pull request #2125 from MabezDev/fix-rtc-dow
stm32: RTC fix DoW range off-by-one error
2023-10-30 23:20:45 +00:00
ca283eed0c Merge pull request #2126 from embassy-rs/disable-stop-test
stm32/tests: disable stop test.
2023-10-30 23:17:53 +00:00
57edf289ea stm32/tests: disable stop test. 2023-10-31 00:04:15 +01:00
3912f5d67b Fix dow range off-by-one error 2023-10-30 20:26:08 +00:00
c9b50e46a5 rp: Add PIO stepper motor driver example 2023-10-30 20:50:37 +01:00
aa97fe7cbd stm32: Add some documentation to low_power
This begins to explain the operation of the low-power executor.
2023-10-30 14:36:08 -04:00
ad07ea0290 Re-add impl_trait_projections 2023-10-30 19:10:45 +01:00
573734008a Fix test 2023-10-29 20:03:11 +01:00
f4a78e00a7 Remove set_current_time API 2023-10-29 19:52:35 +01:00
0d6094c8b1 time: add MockDriver for testing purposes 2023-10-29 19:49:52 +01:00
b6fc682117 Merge pull request #2117 from xoviat/rtc-3
stm32/rtc: more rtc cleanup
2023-10-26 00:55:32 +00:00
0beb84768e stm32/rtc: more rtc cleanup 2023-10-25 19:50:30 -05:00
b98a279367 Merge pull request #2116 from xoviat/rtc-2
stm32/low-power: refactor refcount
2023-10-26 00:11:21 +00:00
e8a3cfaed6 stm32/low-power: refactor refcount 2023-10-25 19:07:31 -05:00
0cc3e18db6 Merge pull request #2112 from AzazKamaz/patch-1
Fix #2100 - function address comparison
2023-10-25 11:53:52 +00:00
6b19c0abd1 Fix #2100 - function address comparison 2023-10-25 11:01:35 +03:00
f956d19e6e Merge pull request #2111 from yodaldevoid/more-ticks
time: Add tick rates in multiples of 10 kHz
2023-10-24 19:51:24 +00:00
ceb0d0bf08 time: Add tick rates in multiples of 10 kHz 2023-10-24 15:34:39 -04:00
b3879ec223 Merge pull request #2105 from andresv/fix-stm32-uart-set-config
Fix stm32 uart set_config
2023-10-24 13:13:42 +00:00
bda99e59ec stm32: fix uart parity, add comment why it is so 2023-10-24 15:57:03 +03:00
25c2a9baaa stm32 uart: remove redundant set_fifoen(true) 2023-10-24 10:11:54 +03:00
1e362c750b stm32 uart: use ConfigError instead of () as error 2023-10-24 09:54:17 +03:00
1a51a84313 Merge pull request #2109 from rmja/stm32-remove-unsafe-warning
stm32: Remove unneeded unsafe
2023-10-24 06:32:22 +00:00
7f72dbdaf2 stm32: fix set_config for buffered uart
In reconfigure() cr1 register is initialised with write (not modify) which means rxneie and idleneie are disabled after reconfiguration.
2023-10-24 09:09:33 +03:00
e8c162ac03 stm32: Remove unneeded unsafe 2023-10-24 07:44:04 +02:00
1aaa19748a Merge pull request #2107 from embassy-rs/hil-test
stm32/build: deterministically generate data
2023-10-23 23:42:38 +00:00
188ee59ba6 stm32: fix setting uart databits 2023-10-23 22:40:24 +03:00
591612db7e stm32 uart: return error if rx and tx not enabled 2023-10-23 22:39:24 +03:00
131 changed files with 1224 additions and 568 deletions

1
ci.sh
View File

@ -218,6 +218,7 @@ cargo batch \
rm out/tests/stm32wb55rg/wpan_mac
rm out/tests/stm32wb55rg/wpan_ble
# unstable, I think it's running out of RAM?
rm out/tests/stm32f207zg/eth

View File

@ -1,6 +1,6 @@
#![no_std]
#![allow(incomplete_features)]
#![feature(async_fn_in_trait)]
#![allow(stable_features, unknown_lints, async_fn_in_trait)]
use core::slice;

View File

@ -12,7 +12,7 @@ firmware-logs = []
[dependencies]
embassy-time = { version = "0.1.5", path = "../embassy-time"}
embassy-sync = { version = "0.3.0", path = "../embassy-sync"}
embassy-sync = { version = "0.4.0", path = "../embassy-sync"}
embassy-futures = { version = "0.1.0", path = "../embassy-futures"}
embassy-net-driver-channel = { version = "0.2.0", path = "../embassy-net-driver-channel"}

View File

@ -4,7 +4,6 @@ use embassy_net_driver_channel as ch;
use embassy_net_driver_channel::driver::{HardwareAddress, LinkState};
use embassy_time::Timer;
pub use crate::bus::SpiBusCyw43;
use crate::consts::*;
use crate::events::{Event, EventSubscriber, Events};
use crate::fmt::Bytes;

View File

@ -1,7 +1,7 @@
#![no_std]
#![no_main]
#![allow(incomplete_features)]
#![feature(async_fn_in_trait, type_alias_impl_trait, concat_bytes)]
#![allow(stable_features, unknown_lints, async_fn_in_trait)]
#![deny(unused_must_use)]
// This mod MUST go first, so that the others see its macros.

View File

@ -28,7 +28,7 @@ digest = "0.10"
log = { version = "0.4", optional = true }
ed25519-dalek = { version = "1.0.1", default_features = false, features = ["u32_backend"], optional = true }
embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal" }
embassy-sync = { version = "0.3.0", path = "../../embassy-sync" }
embassy-sync = { version = "0.4.0", path = "../../embassy-sync" }
embedded-storage = "0.3.0"
embedded-storage-async = { version = "0.4.0", optional = true }
salty = { git = "https://github.com/ycrypto/salty.git", rev = "a9f17911a5024698406b75c0fac56ab5ccf6a8c7", optional = true }

View File

@ -1,4 +1,5 @@
#![cfg_attr(feature = "nightly", feature(async_fn_in_trait))]
#![cfg_attr(feature = "nightly", allow(stable_features, unknown_lints, async_fn_in_trait))]
#![no_std]
#![warn(missing_docs)]
#![doc = include_str!("../README.md")]

View File

@ -16,7 +16,7 @@ target = "thumbv7em-none-eabi"
[dependencies]
defmt = { version = "0.3", optional = true }
embassy-sync = { path = "../../embassy-sync" }
embassy-sync = { version = "0.4.0", path = "../../embassy-sync" }
embassy-nrf = { path = "../../embassy-nrf" }
embassy-boot = { path = "../boot", default-features = false }
cortex-m = { version = "0.7.6" }

View File

@ -17,7 +17,7 @@ defmt = { version = "0.3", optional = true }
defmt-rtt = { version = "0.4", optional = true }
log = { version = "0.4", optional = true }
embassy-sync = { path = "../../embassy-sync" }
embassy-sync = { version = "0.4.0", path = "../../embassy-sync" }
embassy-rp = { path = "../../embassy-rp", default-features = false }
embassy-boot = { path = "../boot", default-features = false }
embassy-time = { path = "../../embassy-time" }

View File

@ -18,7 +18,7 @@ defmt = { version = "0.3", optional = true }
defmt-rtt = { version = "0.4", optional = true }
log = { version = "0.4", optional = true }
embassy-sync = { path = "../../embassy-sync" }
embassy-sync = { version = "0.4.0", path = "../../embassy-sync" }
embassy-stm32 = { path = "../../embassy-stm32", default-features = false }
embassy-boot = { path = "../boot", default-features = false }
cortex-m = { version = "0.7.6" }

View File

@ -20,7 +20,7 @@ default = ["time"]
[dependencies]
embassy-futures = { version = "0.1.0", path = "../embassy-futures", optional = true }
embassy-sync = { version = "0.3.0", path = "../embassy-sync" }
embassy-sync = { version = "0.4.0", path = "../embassy-sync" }
embassy-time = { version = "0.1.5", path = "../embassy-time", optional = true }
embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = [
"unproven",

View File

@ -1,5 +1,6 @@
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(feature = "nightly", feature(async_fn_in_trait, try_blocks))]
#![cfg_attr(feature = "nightly", feature(async_fn_in_trait, impl_trait_projections, try_blocks))]
#![cfg_attr(feature = "nightly", allow(stable_features, unknown_lints, async_fn_in_trait))]
#![warn(missing_docs)]
//! Utilities to use `embedded-hal` traits with Embassy.

View File

@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## 0.3.1 - 2023-11-01
- Fix spurious "Found waker not created by the Embassy executor" error in recent nightlies.
## 0.3.0 - 2023-08-25
- Replaced Pender. Implementations now must define an extern function called `__pender`.

View File

@ -1,6 +1,6 @@
[package]
name = "embassy-executor"
version = "0.3.0"
version = "0.3.1"
edition = "2021"
license = "MIT OR Apache-2.0"
description = "async/await executor designed for embedded usage"
@ -62,7 +62,6 @@ embassy-macros = { version = "0.2.1", path = "../embassy-macros" }
embassy-time = { version = "0.1.5", path = "../embassy-time", optional = true}
atomic-polyfill = "1.0.1"
critical-section = "1.1"
static_cell = "1.1"
# arch-cortex-m dependencies
cortex-m = { version = "0.7.6", optional = true }

View File

@ -33,6 +33,7 @@ check_at_most_one!("arch-cortex-m", "arch-riscv32", "arch-xtensa", "arch-std", "
mod arch;
#[cfg(feature = "_arch")]
#[allow(unused_imports)] // don't warn if the module is empty.
pub use arch::*;
pub mod raw;
@ -46,7 +47,6 @@ pub use spawner::*;
pub mod _export {
#[cfg(feature = "rtos-trace")]
pub use rtos_trace::trace;
pub use static_cell::StaticCell;
/// Expands the given block of code when `embassy-executor` is compiled with
/// the `rtos-trace-interrupt` feature.

View File

@ -3,7 +3,7 @@ use core::task::{RawWaker, RawWakerVTable, Waker};
use super::{wake_task, TaskHeader, TaskRef};
const VTABLE: RawWakerVTable = RawWakerVTable::new(clone, wake, wake, drop);
static VTABLE: RawWakerVTable = RawWakerVTable::new(clone, wake, wake, drop);
unsafe fn clone(p: *const ()) -> RawWaker {
RawWaker::new(p, &VTABLE)

View File

@ -21,7 +21,7 @@ defmt = { version = "0.3", optional = true }
log = { version = "0.4.14", optional = true }
embassy-time = { version = "0.1.5", path = "../embassy-time", optional = true }
embassy-sync = { version = "0.3.0", path = "../embassy-sync" }
embassy-sync = { version = "0.4.0", path = "../embassy-sync" }
embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32", default-features = false, optional = true }
embedded-hal-async = { version = "=1.0.0-rc.1" }
embedded-hal = { version = "0.2", features = ["unproven"] }

View File

@ -1,5 +1,6 @@
#![no_std]
#![feature(async_fn_in_trait)]
#![feature(async_fn_in_trait, impl_trait_projections)]
#![allow(stable_features, unknown_lints, async_fn_in_trait)]
//! embassy-lora holds LoRa-specific functionality.
pub(crate) mod fmt;

View File

@ -53,8 +53,7 @@ pub fn wasm() -> TokenStream {
quote! {
#[wasm_bindgen::prelude::wasm_bindgen(start)]
pub fn main() -> Result<(), wasm_bindgen::JsValue> {
static EXECUTOR: ::embassy_executor::_export::StaticCell<::embassy_executor::Executor> = ::embassy_executor::_export::StaticCell::new();
let executor = EXECUTOR.init(::embassy_executor::Executor::new());
let executor = ::std::boxed::Box::leak(::std::boxed::Box::new(::embassy_executor::Executor::new()));
executor.start(|spawner| {
spawner.spawn(__embassy_main(spawner)).unwrap();

View File

@ -22,9 +22,7 @@ embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
bitfield = "0.14.0"
[dev-dependencies]
# reenable when https://github.com/dbrgn/embedded-hal-mock/pull/86 is merged.
#embedded-hal-mock = { git = "https://github.com/dbrgn/embedded-hal-mock", branch = "1-alpha", features = ["embedded-hal-async", "eh1"] }] }
embedded-hal-mock = { git = "https://github.com/newAM/embedded-hal-mock", branch = "eh1-rc.1", features = ["embedded-hal-async", "eh1"] }
embedded-hal-mock = { version = "=0.10.0-rc.1", features = ["embedded-hal-async", "eh1"] }
crc = "3.0.1"
env_logger = "0.10"
critical-section = { version = "1.1.2", features = ["std"] }

View File

@ -1,5 +1,6 @@
#![deny(clippy::pedantic)]
#![feature(async_fn_in_trait)]
#![allow(stable_features, unknown_lints, async_fn_in_trait)]
#![cfg_attr(not(any(test, feature = "std")), no_std)]
#![allow(clippy::module_name_repetitions)]
#![allow(clippy::missing_errors_doc)]

View File

@ -24,6 +24,6 @@ features = ["defmt"]
defmt = { version = "0.3", optional = true }
log = { version = "0.4.14", optional = true }
embassy-sync = { version = "0.3.0", path = "../embassy-sync" }
embassy-sync = { version = "0.4.0", path = "../embassy-sync" }
embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver" }

View File

@ -8,7 +8,7 @@ defmt = { version = "0.3", optional = true }
log = { version = "0.4.14", optional = true }
embassy-time = { version = "0.1.5", path = "../embassy-time" }
embassy-sync = { version = "0.3.0", path = "../embassy-sync"}
embassy-sync = { version = "0.4.0", path = "../embassy-sync"}
embassy-futures = { version = "0.1.0", path = "../embassy-futures"}
embassy-net-driver-channel = { version = "0.2.0", path = "../embassy-net-driver-channel"}

View File

@ -19,7 +19,7 @@ embedded-io-async = { version = "0.6.0" }
embassy-net-driver-channel = { version = "0.2.0", path = "../embassy-net-driver-channel" }
embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
ppproto = { version = "0.1.2"}
embassy-sync = { version = "0.3.0", path = "../embassy-sync" }
embassy-sync = { version = "0.4.0", path = "../embassy-sync" }
[package.metadata.embassy_docs]
src_base = "https://github.com/embassy-rs/embassy/blob/embassy-net-ppp-v$VERSION/embassy-net-ppp/src/"

View File

@ -1,5 +1,6 @@
#![no_std]
#![feature(async_fn_in_trait)]
#![allow(stable_features, unknown_lints, async_fn_in_trait)]
#![doc = include_str!("../README.md")]
pub mod chip;

View File

@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## 0.2.1 - 2023-10-31
- Re-add impl_trait_projections
- Fix: Reset DHCP socket when the link up is detected
## 0.2.0 - 2023-10-18
- Re-export `smoltcp::wire::IpEndpoint`

View File

@ -1,6 +1,6 @@
[package]
name = "embassy-net"
version = "0.2.0"
version = "0.2.1"
edition = "2021"
license = "MIT OR Apache-2.0"
description = "Async TCP/IP network stack for embedded systems"
@ -53,7 +53,7 @@ smoltcp = { version = "0.10.0", default-features = false, features = [
embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver" }
embassy-time = { version = "0.1.5", path = "../embassy-time" }
embassy-sync = { version = "0.3.0", path = "../embassy-sync" }
embassy-sync = { version = "0.4.0", path = "../embassy-sync" }
embedded-io-async = { version = "0.6.0", optional = true }
managed = { version = "0.8.0", default-features = false, features = [ "map" ] }

View File

@ -1,5 +1,6 @@
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(feature = "nightly", feature(async_fn_in_trait))]
#![cfg_attr(feature = "nightly", feature(async_fn_in_trait, impl_trait_projections))]
#![cfg_attr(feature = "nightly", allow(stable_features, unknown_lints, async_fn_in_trait))]
#![warn(missing_docs)]
#![doc = include_str!("../README.md")]

View File

@ -95,7 +95,7 @@ _nrf52832_anomaly_109 = []
[dependencies]
embassy-time = { version = "0.1.5", path = "../embassy-time", optional = true }
embassy-sync = { version = "0.3.0", path = "../embassy-sync" }
embassy-sync = { version = "0.4.0", path = "../embassy-sync" }
embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-3"] }
embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" }
embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optional=true }
@ -110,7 +110,6 @@ defmt = { version = "0.3", optional = true }
log = { version = "0.4.14", optional = true }
cortex-m-rt = ">=0.6.15,<0.8"
cortex-m = "0.7.6"
futures = { version = "0.3.17", default-features = false }
critical-section = "1.1"
rand_core = "0.6.3"
fixed = "1.10.0"

View File

@ -1,5 +1,6 @@
#![no_std]
#![cfg_attr(feature = "nightly", feature(async_fn_in_trait))]
#![cfg_attr(feature = "nightly", feature(async_fn_in_trait, impl_trait_projections))]
#![cfg_attr(feature = "nightly", allow(stable_features, unknown_lints, async_fn_in_trait))]
#![doc = include_str!("../README.md")]
#![warn(missing_docs)]

View File

@ -2,6 +2,7 @@
#![macro_use]
use core::future::poll_fn;
use core::marker::PhantomData;
use core::sync::atomic::{compiler_fence, Ordering};
use core::task::Poll;
@ -9,7 +10,6 @@ use core::task::Poll;
use embassy_hal_internal::drop::OnDrop;
use embassy_hal_internal::{into_ref, PeripheralRef};
use fixed::types::I7F1;
use futures::future::poll_fn;
use crate::chip::EASY_DMA_SIZE;
use crate::gpio::sealed::Pin;

View File

@ -59,7 +59,7 @@ nightly = ["embedded-hal-1", "embedded-hal-async", "embedded-storage-async", "em
unstable-traits = ["embedded-hal-1", "embedded-hal-nb"]
[dependencies]
embassy-sync = { version = "0.3.0", path = "../embassy-sync" }
embassy-sync = { version = "0.4.0", path = "../embassy-sync" }
embassy-time = { version = "0.1.5", path = "../embassy-time", features = [ "tick-hz-1_000_000" ] }
embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-2"] }
@ -94,5 +94,5 @@ pio = {version= "0.2.1" }
rp2040-boot2 = "0.3"
[dev-dependencies]
embassy-executor = { version = "0.3.0", path = "../embassy-executor", features = ["nightly", "arch-std", "executor-thread"] }
static_cell = "1.1"
embassy-executor = { version = "0.3.1", path = "../embassy-executor", features = ["nightly", "arch-std", "executor-thread"] }
static_cell = { version = "2" }

View File

@ -1,5 +1,6 @@
#![no_std]
#![cfg_attr(feature = "nightly", feature(async_fn_in_trait))]
#![cfg_attr(feature = "nightly", feature(async_fn_in_trait, impl_trait_projections))]
#![cfg_attr(feature = "nightly", allow(stable_features, unknown_lints, async_fn_in_trait))]
// This mod MUST go first, so that the others see its macros.
pub(crate) mod fmt;

View File

@ -12,7 +12,7 @@ features = ["stm32wb55rg"]
[dependencies]
embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32" }
embassy-sync = { version = "0.3.0", path = "../embassy-sync" }
embassy-sync = { version = "0.4.0", path = "../embassy-sync" }
embassy-time = { version = "0.1.5", path = "../embassy-time", optional = true }
embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
embassy-hal-internal = { version = "0.1.0", path = "../embassy-hal-internal" }

View File

@ -1,5 +1,9 @@
#![no_std]
#![cfg_attr(any(feature = "ble", feature = "mac"), feature(async_fn_in_trait))]
#![cfg_attr(
any(feature = "ble", feature = "mac"),
allow(stable_features, unknown_lints, async_fn_in_trait)
)]
#![cfg_attr(feature = "mac", feature(type_alias_impl_trait, concat_bytes))]
// This must go FIRST so that all the other modules see its macros.

View File

@ -1,4 +1,3 @@
#![allow(incomplete_features)]
#![deny(unused_must_use)]
use core::task::Context;

View File

@ -32,14 +32,14 @@ flavors = [
]
[dependencies]
embassy-sync = { version = "0.3.0", path = "../embassy-sync" }
embassy-sync = { version = "0.4.0", path = "../embassy-sync" }
embassy-time = { version = "0.1.5", path = "../embassy-time", optional = true }
embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-4"] }
embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" }
embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver" }
embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optional = true }
embassy-executor = { version = "0.3.0", path = "../embassy-executor", optional = true }
embassy-executor = { version = "0.3.1", path = "../embassy-executor", optional = true }
embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] }
embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-rc.1", optional = true}
@ -58,7 +58,7 @@ rand_core = "0.6.3"
sdio-host = "0.5.0"
embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true }
critical-section = "1.1"
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-bcc9b6bf9fa195e91625849efc4ba473d9ace4e9" }
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-73b8c37ae74fc28b247188c989fd99400611bd6b" }
vcell = "0.1.3"
bxcan = "0.7.0"
nb = "1.0.0"
@ -76,7 +76,7 @@ critical-section = { version = "1.1", features = ["std"] }
[build-dependencies]
proc-macro2 = "1.0.36"
quote = "1.0.15"
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-bcc9b6bf9fa195e91625849efc4ba473d9ace4e9", default-features = false, features = ["metadata"]}
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-73b8c37ae74fc28b247188c989fd99400611bd6b", default-features = false, features = ["metadata"]}
[features]
@ -90,6 +90,7 @@ defmt = ["dep:defmt", "bxcan/unstable-defmt", "embassy-sync/defmt", "embassy-emb
exti = []
low-power = [ "dep:embassy-executor", "embassy-executor/arch-cortex-m" ]
low-power-debug-with-sleep = []
embassy-executor = []
## Automatically generate `memory.x` file using [`stm32-metapac`](https://docs.rs/stm32-metapac/)

View File

@ -556,6 +556,32 @@ fn main() {
},
};
/*
If LP and non-LP peripherals share the same RCC enable bit, then a refcount leak will result.
This should be checked in stm32-data-gen.
*/
let stop_refcount = if p.name.starts_with("LP") {
quote! { REFCOUNT_STOP2 }
} else {
quote! { REFCOUNT_STOP1 }
};
let (incr_stop_refcount, decr_stop_refcount) = if p.name != "RTC" {
(
quote! {
#[cfg(feature = "low-power")]
unsafe { crate::rcc::#stop_refcount += 1 };
},
quote! {
#[cfg(feature = "low-power")]
unsafe { crate::rcc::#stop_refcount -= 1 };
},
)
} else {
(quote! {}, quote! {})
};
g.extend(quote! {
impl crate::rcc::sealed::RccPeripheral for peripherals::#pname {
fn frequency() -> crate::time::Hertz {
@ -563,8 +589,7 @@ fn main() {
}
fn enable_and_reset_with_cs(_cs: critical_section::CriticalSection) {
#before_enable
#[cfg(feature = "low-power")]
crate::rcc::clock_refcount_add(_cs);
#incr_stop_refcount
crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(true));
#after_enable
#rst
@ -572,8 +597,7 @@ fn main() {
fn disable_with_cs(_cs: critical_section::CriticalSection) {
#before_disable
crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(false));
#[cfg(feature = "low-power")]
crate::rcc::clock_refcount_sub(_cs);
#decr_stop_refcount
}
}

View File

@ -47,6 +47,9 @@ pub unsafe fn on_irq() {
#[cfg(any(exti_c0, exti_g0, exti_l5, exti_u5, exti_h5, exti_h50))]
let bits = EXTI.rpr(0).read().0 | EXTI.fpr(0).read().0;
// We don't handle or change any EXTI lines above 16.
let bits = bits & 0x0000FFFF;
// Mask all the channels that fired.
cpu_regs().imr(0).modify(|w| w.0 &= !bits);

View File

@ -465,7 +465,7 @@ pub(crate) fn assert_not_corrupted_read(end_address: u32) {
feature = "stm32f439vg",
feature = "stm32f439zg",
))]
if second_bank_read && unsafe { pac::DBGMCU.idcode().read().rev_id() < REVISION_3 && !pa12_is_output_pull_low() } {
if second_bank_read && pac::DBGMCU.idcode().read().rev_id() < REVISION_3 && !pa12_is_output_pull_low() {
panic!("Read corruption for stm32f42xxG and stm32f43xxG in dual bank mode when PA12 is in use for chips below revision 3, see errata 2.2.11");
}
}

View File

@ -1,5 +1,6 @@
#![cfg_attr(not(test), no_std)]
#![cfg_attr(feature = "nightly", feature(async_fn_in_trait))]
#![cfg_attr(feature = "nightly", feature(async_fn_in_trait, impl_trait_projections))]
#![cfg_attr(feature = "nightly", allow(stable_features, unknown_lints, async_fn_in_trait))]
//! ## Feature flags
#![doc = document_features::document_features!(feature_label = r#"<span class="stab portability"><code>{feature}</code></span>"#)]
@ -226,8 +227,9 @@ pub fn init(config: Config) -> Peripherals {
time_driver::init(cs);
#[cfg(feature = "low-power")]
while !crate::rcc::low_power_ready() {
crate::rcc::clock_refcount_sub(cs);
{
crate::rcc::REFCOUNT_STOP2 = 0;
crate::rcc::REFCOUNT_STOP1 = 0;
}
}

View File

@ -1,3 +1,50 @@
/// The STM32 line of microcontrollers support various deep-sleep modes which exploit clock-gating
/// to reduce power consumption. `embassy-stm32` provides a low-power executor, [`Executor`] which
/// can use knowledge of which peripherals are currently blocked upon to transparently and safely
/// enter such low-power modes (currently, only `STOP2`) when idle.
///
/// The executor determines which peripherals are active by their RCC state; consequently,
/// low-power states can only be entered if all peripherals have been `drop`'d. There are a few
/// exceptions to this rule:
///
/// * `GPIO`
/// * `RCC`
///
/// Since entering and leaving low-power modes typically incurs a significant latency, the
/// low-power executor will only attempt to enter when the next timer event is at least
/// [`time_driver::MIN_STOP_PAUSE`] in the future.
///
/// Currently there is no macro analogous to `embassy_executor::main` for this executor;
/// consequently one must define their entrypoint manually. Moveover, you must relinquish control
/// of the `RTC` peripheral to the executor. This will typically look like
///
/// ```rust,no_run
/// use embassy_executor::Spawner;
/// use embassy_stm32::low_power::Executor;
/// use embassy_stm32::rtc::{Rtc, RtcConfig};
/// use static_cell::make_static;
///
/// #[cortex_m_rt::entry]
/// fn main() -> ! {
/// Executor::take().run(|spawner| {
/// unwrap!(spawner.spawn(async_main(spawner)));
/// });
/// }
///
/// #[embassy_executor::task]
/// async fn async_main(spawner: Spawner) {
/// // initialize the platform...
/// let mut config = embassy_stm32::Config::default();
/// let p = embassy_stm32::init(config);
///
/// // give the RTC to the executor...
/// let mut rtc = Rtc::new(p.RTC, RtcConfig::default());
/// let rtc = make_static!(rtc);
/// embassy_stm32::low_power::stop_with_rtc(rtc);
///
/// // your application here...
/// }
/// ```
use core::arch::asm;
use core::marker::PhantomData;
use core::sync::atomic::{compiler_fence, Ordering};
@ -6,7 +53,6 @@ use cortex_m::peripheral::SCB;
use embassy_executor::*;
use crate::interrupt;
use crate::rcc::low_power_ready;
use crate::time_driver::{get_driver, RtcDriver};
const THREAD_PENDER: usize = usize::MAX;
@ -33,6 +79,21 @@ pub fn stop_with_rtc(rtc: &'static Rtc) {
unsafe { EXECUTOR.as_mut().unwrap() }.stop_with_rtc(rtc)
}
pub fn stop_ready(stop_mode: StopMode) -> bool {
match unsafe { EXECUTOR.as_mut().unwrap() }.stop_mode() {
Some(StopMode::Stop2) => true,
Some(StopMode::Stop1) => stop_mode == StopMode::Stop1,
None => false,
}
}
#[non_exhaustive]
#[derive(PartialEq)]
pub enum StopMode {
Stop1,
Stop2,
}
/// Thread mode executor, using WFE/SEV.
///
/// This is the simplest and most common kind of executor. It runs on
@ -53,7 +114,7 @@ pub struct Executor {
impl Executor {
/// Create a new Executor.
pub fn take() -> &'static mut Self {
unsafe {
critical_section::with(|_| unsafe {
assert!(EXECUTOR.is_none());
EXECUTOR = Some(Self {
@ -64,7 +125,7 @@ impl Executor {
});
EXECUTOR.as_mut().unwrap()
}
})
}
unsafe fn on_wakeup_irq(&mut self) {
@ -80,17 +141,39 @@ impl Executor {
trace!("low power: stop with rtc configured");
}
fn stop_mode(&self) -> Option<StopMode> {
if unsafe { crate::rcc::REFCOUNT_STOP2 == 0 } && unsafe { crate::rcc::REFCOUNT_STOP1 == 0 } {
Some(StopMode::Stop2)
} else if unsafe { crate::rcc::REFCOUNT_STOP1 == 0 } {
Some(StopMode::Stop1)
} else {
None
}
}
fn configure_stop(&mut self, _stop_mode: StopMode) {
// TODO: configure chip-specific settings for stop
}
fn configure_pwr(&mut self) {
self.scb.clear_sleepdeep();
compiler_fence(Ordering::SeqCst);
if !low_power_ready() {
let stop_mode = self.stop_mode();
if stop_mode.is_none() {
trace!("low power: not ready to stop");
} else if self.time_driver.pause_time().is_err() {
trace!("low power: failed to pause time");
} else {
trace!("low power: stop");
let stop_mode = stop_mode.unwrap();
match stop_mode {
StopMode::Stop1 => trace!("low power: stop 1"),
StopMode::Stop2 => trace!("low power: stop 2"),
}
self.configure_stop(stop_mode);
#[cfg(not(feature = "low-power-debug-with-sleep"))]
self.scb.set_sleepdeep();
}
}

View File

@ -152,9 +152,9 @@ pub(crate) unsafe fn init(config: Config) {
source: config.pll_src,
};
let pll = init_pll(PllInstance::Pll, config.pll, &pll_input);
#[cfg(any(all(stm32f4, not(any(stm32f410, stm32f429))), stm32f7))]
#[cfg(any(all(stm32f4, not(stm32f410)), stm32f7))]
let _plli2s = init_pll(PllInstance::Plli2s, config.plli2s, &pll_input);
#[cfg(all(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7), not(stm32f429)))]
#[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))]
let _pllsai = init_pll(PllInstance::Pllsai, config.pllsai, &pll_input);
// Configure sysclk
@ -197,25 +197,15 @@ pub(crate) unsafe fn init(config: Config) {
pclk2_tim,
rtc,
pll1_q: pll.q,
#[cfg(all(rcc_f4, not(any(stm32f410, stm32f429))))]
#[cfg(all(rcc_f4, not(stm32f410)))]
plli2s1_q: _plli2s.q,
#[cfg(all(rcc_f4, not(any(stm32f410, stm32f429))))]
#[cfg(all(rcc_f4, not(stm32f410)))]
plli2s1_r: _plli2s.r,
#[cfg(stm32f429)]
plli2s1_q: None,
#[cfg(stm32f429)]
plli2s1_r: None,
#[cfg(any(stm32f427, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))]
#[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))]
pllsai1_q: _pllsai.q,
#[cfg(any(stm32f427, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))]
#[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))]
pllsai1_r: _pllsai.r,
#[cfg(stm32f429)]
pllsai1_q: None,
#[cfg(stm32f429)]
pllsai1_r: None,
});
}
@ -233,7 +223,6 @@ struct PllOutput {
r: Option<Hertz>,
}
#[allow(dead_code)]
#[derive(PartialEq, Eq, Clone, Copy)]
enum PllInstance {
Pll,

View File

@ -1,8 +1,8 @@
pub use crate::pac::pwr::vals::Vos as VoltageScale;
pub use crate::pac::rcc::vals::{
Hpre as AHBPrescaler, Msirange as MSIRange, Plldiv as PLLDiv, Pllmul as PLLMul, Ppre as APBPrescaler,
Hpre as AHBPrescaler, Msirange as MSIRange, Plldiv as PLLDiv, Plldiv as PllDiv, Pllmul as PLLMul, Pllmul as PllMul,
Pllsrc as PLLSource, Ppre as APBPrescaler, Sw as ClockSrc,
};
use crate::pac::rcc::vals::{Pllsrc, Sw};
#[cfg(crs)]
use crate::pac::{crs, CRS, SYSCFG};
use crate::pac::{FLASH, PWR, RCC};
@ -12,39 +12,50 @@ use crate::time::Hertz;
/// HSI speed
pub const HSI_FREQ: Hertz = Hertz(16_000_000);
/// System clock mux source
#[derive(Clone, Copy)]
pub enum ClockSrc {
MSI(MSIRange),
PLL(PLLSource, PLLMul, PLLDiv),
HSE(Hertz),
HSI,
#[derive(Clone, Copy, Eq, PartialEq)]
pub enum HseMode {
/// crystal/ceramic oscillator (HSEBYP=0)
Oscillator,
/// external analog clock (low swing) (HSEBYP=1)
Bypass,
}
/// PLL clock input source
#[derive(Clone, Copy)]
pub enum PLLSource {
HSI,
HSE(Hertz),
#[derive(Clone, Copy, Eq, PartialEq)]
pub struct Hse {
/// HSE frequency.
pub freq: Hertz,
/// HSE mode.
pub mode: HseMode,
}
impl From<PLLSource> for Pllsrc {
fn from(val: PLLSource) -> Pllsrc {
match val {
PLLSource::HSI => Pllsrc::HSI,
PLLSource::HSE(_) => Pllsrc::HSE,
}
}
#[derive(Clone, Copy)]
pub struct Pll {
/// PLL source
pub source: PLLSource,
/// PLL multiplication factor.
pub mul: PllMul,
/// PLL main output division factor.
pub div: PllDiv,
}
/// Clocks configutation
pub struct Config {
// base clock sources
pub msi: Option<MSIRange>,
pub hsi: bool,
pub hse: Option<Hse>,
#[cfg(crs)]
pub hsi48: bool,
pub pll: Option<Pll>,
pub mux: ClockSrc,
pub ahb_pre: AHBPrescaler,
pub apb1_pre: APBPrescaler,
pub apb2_pre: APBPrescaler,
#[cfg(crs)]
pub enable_hsi48: bool,
pub ls: super::LsConfig,
pub voltage_scale: VoltageScale,
}
@ -53,12 +64,18 @@ impl Default for Config {
#[inline]
fn default() -> Config {
Config {
mux: ClockSrc::MSI(MSIRange::RANGE5),
msi: Some(MSIRange::RANGE5),
hse: None,
hsi: false,
#[cfg(crs)]
hsi48: false,
pll: None,
mux: ClockSrc::MSI,
ahb_pre: AHBPrescaler::DIV1,
apb1_pre: APBPrescaler::DIV1,
apb2_pre: APBPrescaler::DIV1,
#[cfg(crs)]
enable_hsi48: false,
voltage_scale: VoltageScale::RANGE1,
ls: Default::default(),
}
@ -71,72 +88,68 @@ pub(crate) unsafe fn init(config: Config) {
PWR.cr().write(|w| w.set_vos(config.voltage_scale));
while PWR.csr().read().vosf() {}
let (sys_clk, sw) = match config.mux {
ClockSrc::MSI(range) => {
// Set MSI range
RCC.icscr().write(|w| w.set_msirange(range));
// Enable MSI
RCC.cr().write(|w| w.set_msion(true));
while !RCC.cr().read().msirdy() {}
let freq = 32_768 * (1 << (range as u8 + 1));
(Hertz(freq), Sw::MSI)
}
ClockSrc::HSI => {
// Enable HSI
RCC.cr().write(|w| w.set_hsion(true));
while !RCC.cr().read().hsirdy() {}
(HSI_FREQ, Sw::HSI)
}
ClockSrc::HSE(freq) => {
// Enable HSE
RCC.cr().write(|w| w.set_hseon(true));
while !RCC.cr().read().hserdy() {}
(freq, Sw::HSE)
}
ClockSrc::PLL(src, mul, div) => {
let freq = match src {
PLLSource::HSE(freq) => {
// Enable HSE
RCC.cr().write(|w| w.set_hseon(true));
while !RCC.cr().read().hserdy() {}
freq
}
PLLSource::HSI => {
// Enable HSI
RCC.cr().write(|w| w.set_hsion(true));
while !RCC.cr().read().hsirdy() {}
HSI_FREQ
}
};
// Disable PLL
RCC.cr().modify(|w| w.set_pllon(false));
while RCC.cr().read().pllrdy() {}
let freq = freq * mul / div;
assert!(freq <= Hertz(32_000_000));
RCC.cfgr().write(move |w| {
w.set_pllmul(mul);
w.set_plldiv(div);
w.set_pllsrc(src.into());
});
// Enable PLL
RCC.cr().modify(|w| w.set_pllon(true));
while !RCC.cr().read().pllrdy() {}
(freq, Sw::PLL1_P)
}
};
let rtc = config.ls.init();
let msi = config.msi.map(|range| {
RCC.icscr().modify(|w| w.set_msirange(range));
RCC.cr().modify(|w| w.set_msion(true));
while !RCC.cr().read().msirdy() {}
Hertz(32_768 * (1 << (range as u8 + 1)))
});
let hsi = config.hsi.then(|| {
RCC.cr().modify(|w| w.set_hsion(true));
while !RCC.cr().read().hsirdy() {}
HSI_FREQ
});
let hse = config.hse.map(|hse| {
RCC.cr().modify(|w| {
w.set_hsebyp(hse.mode == HseMode::Bypass);
w.set_hseon(true);
});
while !RCC.cr().read().hserdy() {}
hse.freq
});
let pll = config.pll.map(|pll| {
let freq = match pll.source {
PLLSource::HSE => hse.unwrap(),
PLLSource::HSI => hsi.unwrap(),
};
// Disable PLL
RCC.cr().modify(|w| w.set_pllon(false));
while RCC.cr().read().pllrdy() {}
let freq = freq * pll.mul / pll.div;
assert!(freq <= Hertz(32_000_000));
RCC.cfgr().write(move |w| {
w.set_pllmul(pll.mul);
w.set_plldiv(pll.div);
w.set_pllsrc(pll.source);
});
// Enable PLL
RCC.cr().modify(|w| w.set_pllon(true));
while !RCC.cr().read().pllrdy() {}
freq
});
let sys_clk = match config.mux {
ClockSrc::HSE => hse.unwrap(),
ClockSrc::HSI => hsi.unwrap(),
ClockSrc::MSI => msi.unwrap(),
ClockSrc::PLL1_P => pll.unwrap(),
};
let wait_states = match (config.voltage_scale, sys_clk.0) {
(VoltageScale::RANGE1, ..=16_000_000) => 0,
(VoltageScale::RANGE2, ..=8_000_000) => 0,
@ -150,7 +163,7 @@ pub(crate) unsafe fn init(config: Config) {
FLASH.acr().modify(|w| w.set_latency(wait_states != 0));
RCC.cfgr().modify(|w| {
w.set_sw(sw);
w.set_sw(config.mux);
w.set_hpre(config.ahb_pre);
w.set_ppre1(config.apb1_pre);
w.set_ppre2(config.apb2_pre);
@ -161,7 +174,7 @@ pub(crate) unsafe fn init(config: Config) {
let (pclk2, pclk2_tim) = super::util::calc_pclk(hclk1, config.apb2_pre);
#[cfg(crs)]
if config.enable_hsi48 {
if config.hsi48 {
// Reset CRS peripheral
RCC.apb1rstr().modify(|w| w.set_crsrst(true));
RCC.apb1rstr().modify(|w| w.set_crsrst(false));

View File

@ -4,8 +4,8 @@ pub use crate::pac::rcc::vals::Clk48sel as Clk48Src;
#[cfg(any(stm32wb, stm32wl))]
pub use crate::pac::rcc::vals::Hsepre as HsePrescaler;
pub use crate::pac::rcc::vals::{
Hpre as AHBPrescaler, Msirange as MSIRange, Pllm as PllPreDiv, Plln as PllMul, Pllp as PllPDiv, Pllq as PllQDiv,
Pllr as PllRDiv, Pllsrc as PLLSource, Ppre as APBPrescaler, Sw as ClockSrc,
Adcsel as AdcClockSource, Hpre as AHBPrescaler, Msirange as MSIRange, Pllm as PllPreDiv, Plln as PllMul,
Pllp as PllPDiv, Pllq as PllQDiv, Pllr as PllRDiv, Pllsrc as PLLSource, Ppre as APBPrescaler, Sw as ClockSrc,
};
use crate::pac::{FLASH, RCC};
use crate::rcc::{set_freqs, Clocks};
@ -52,7 +52,7 @@ pub struct Pll {
pub divr: Option<PllRDiv>,
}
/// Clocks configutation
/// Clocks configuration
pub struct Config {
// base clock sources
pub msi: Option<MSIRange>,
@ -84,6 +84,8 @@ pub struct Config {
// low speed LSI/LSE/RTC
pub ls: super::LsConfig,
pub adc_clock_source: AdcClockSource,
}
impl Default for Config {
@ -111,6 +113,7 @@ impl Default for Config {
#[cfg(any(stm32l4, stm32l5, stm32wb))]
clk48_src: Clk48Src::HSI48,
ls: Default::default(),
adc_clock_source: AdcClockSource::SYS,
}
}
}
@ -145,6 +148,7 @@ pub const WPAN_DEFAULT: Config = Config {
shared_ahb_pre: AHBPrescaler::DIV1,
apb1_pre: APBPrescaler::DIV1,
apb2_pre: APBPrescaler::DIV1,
adc_clock_source: AdcClockSource::SYS,
};
pub(crate) unsafe fn init(config: Config) {
@ -189,9 +193,6 @@ pub(crate) unsafe fn init(config: Config) {
});
while !RCC.cr().read().msirdy() {}
// Enable as clock source for USB, RNG if running at 48 MHz
if range == MSIRange::RANGE48M {}
msirange_to_hertz(range)
});
@ -344,6 +345,11 @@ pub(crate) unsafe fn init(config: Config) {
});
while RCC.cfgr().read().sws() != config.mux {}
#[cfg(stm32l5)]
RCC.ccipr1().modify(|w| w.set_adcsel(config.adc_clock_source));
#[cfg(not(stm32l5))]
RCC.ccipr().modify(|w| w.set_adcsel(config.adc_clock_source));
#[cfg(any(stm32wl, stm32wb))]
{
RCC.extcfgr().modify(|w| {

View File

@ -23,8 +23,6 @@ pub use mco::*;
#[cfg_attr(rcc_u5, path = "u5.rs")]
#[cfg_attr(rcc_wba, path = "wba.rs")]
mod _version;
#[cfg(feature = "low-power")]
use core::sync::atomic::{AtomicU32, Ordering};
pub use _version::*;
@ -183,27 +181,16 @@ pub struct Clocks {
}
#[cfg(feature = "low-power")]
static CLOCK_REFCOUNT: AtomicU32 = AtomicU32::new(0);
/// Must be written within a critical section
///
/// May be read without a critical section
pub(crate) static mut REFCOUNT_STOP1: u32 = 0;
#[cfg(feature = "low-power")]
pub fn low_power_ready() -> bool {
// trace!("clock refcount: {}", CLOCK_REFCOUNT.load(Ordering::SeqCst));
CLOCK_REFCOUNT.load(Ordering::SeqCst) == 0
}
#[cfg(feature = "low-power")]
pub(crate) fn clock_refcount_add(_cs: critical_section::CriticalSection) {
// We don't check for overflow because constructing more than u32 peripherals is unlikely
let n = CLOCK_REFCOUNT.load(Ordering::Relaxed);
CLOCK_REFCOUNT.store(n + 1, Ordering::Relaxed);
}
#[cfg(feature = "low-power")]
pub(crate) fn clock_refcount_sub(_cs: critical_section::CriticalSection) {
let n = CLOCK_REFCOUNT.load(Ordering::Relaxed);
assert!(n != 0);
CLOCK_REFCOUNT.store(n - 1, Ordering::Relaxed);
}
/// Must be written within a critical section
///
/// May be read without a critical section
pub(crate) static mut REFCOUNT_STOP2: u32 = 0;
/// Frozen clock frequencies
///

View File

@ -4,8 +4,64 @@ use core::convert::From;
#[cfg(feature = "chrono")]
use chrono::{self, Datelike, NaiveDate, Timelike, Weekday};
use super::byte_to_bcd2;
use crate::pac::rtc::Rtc;
#[cfg(any(feature = "defmt", feature = "time"))]
use crate::peripherals::RTC;
#[cfg(any(feature = "defmt", feature = "time"))]
use crate::rtc::sealed::Instance;
/// Represents an instant in time that can be substracted to compute a duration
pub struct RtcInstant {
/// 0..59
pub second: u8,
/// 0..256
pub subsecond: u16,
}
impl RtcInstant {
#[cfg(not(rtc_v2f2))]
pub(super) const fn from(second: u8, subsecond: u16) -> Result<Self, Error> {
if second > 59 {
Err(Error::InvalidSecond)
} else {
Ok(Self { second, subsecond })
}
}
}
#[cfg(feature = "defmt")]
impl defmt::Format for RtcInstant {
fn format(&self, fmt: defmt::Formatter) {
defmt::write!(
fmt,
"{}:{}",
self.second,
RTC::regs().prer().read().prediv_s() - self.subsecond,
)
}
}
#[cfg(feature = "time")]
impl core::ops::Sub for RtcInstant {
type Output = embassy_time::Duration;
fn sub(self, rhs: Self) -> Self::Output {
use embassy_time::{Duration, TICK_HZ};
let second = if self.second < rhs.second {
self.second + 60
} else {
self.second
};
let psc = RTC::regs().prer().read().prediv_s() as u32;
let self_ticks = second as u32 * (psc + 1) + (psc - self.subsecond as u32);
let other_ticks = rhs.second as u32 * (psc + 1) + (psc - rhs.subsecond as u32);
let rtc_ticks = self_ticks - other_ticks;
Duration::from_ticks(((rtc_ticks * TICK_HZ as u32) / (psc + 1)) as u64)
}
}
/// Errors regarding the [`DateTime`] struct.
#[derive(Clone, Debug, PartialEq, Eq)]
@ -32,19 +88,85 @@ pub enum Error {
/// Structure containing date and time information
pub struct DateTime {
/// 0..4095
pub year: u16,
year: u16,
/// 1..12, 1 is January
pub month: u8,
month: u8,
/// 1..28,29,30,31 depending on month
pub day: u8,
day: u8,
///
pub day_of_week: DayOfWeek,
day_of_week: DayOfWeek,
/// 0..23
pub hour: u8,
hour: u8,
/// 0..59
pub minute: u8,
minute: u8,
/// 0..59
pub second: u8,
second: u8,
}
impl DateTime {
pub const fn year(&self) -> u16 {
self.year
}
pub const fn month(&self) -> u8 {
self.month
}
pub const fn day(&self) -> u8 {
self.day
}
pub const fn day_of_week(&self) -> DayOfWeek {
self.day_of_week
}
pub const fn hour(&self) -> u8 {
self.hour
}
pub const fn minute(&self) -> u8 {
self.minute
}
pub const fn second(&self) -> u8 {
self.second
}
pub fn from(
year: u16,
month: u8,
day: u8,
day_of_week: u8,
hour: u8,
minute: u8,
second: u8,
) -> Result<Self, Error> {
let day_of_week = day_of_week_from_u8(day_of_week)?;
if year > 4095 {
Err(Error::InvalidYear)
} else if month < 1 || month > 12 {
Err(Error::InvalidMonth)
} else if day < 1 || day > 31 {
Err(Error::InvalidDay)
} else if hour > 23 {
Err(Error::InvalidHour)
} else if minute > 59 {
Err(Error::InvalidMinute)
} else if second > 59 {
Err(Error::InvalidSecond)
} else {
Ok(Self {
year,
month,
day,
day_of_week,
hour,
minute,
second,
})
}
}
}
#[cfg(feature = "chrono")]
@ -77,13 +199,13 @@ impl From<DateTime> for chrono::NaiveDateTime {
#[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash)]
#[allow(missing_docs)]
pub enum DayOfWeek {
Monday = 0,
Tuesday = 1,
Wednesday = 2,
Thursday = 3,
Friday = 4,
Saturday = 5,
Sunday = 6,
Monday = 1,
Tuesday = 2,
Wednesday = 3,
Thursday = 4,
Friday = 5,
Saturday = 6,
Sunday = 7,
}
#[cfg(feature = "chrono")]
@ -108,92 +230,19 @@ impl From<DayOfWeek> for chrono::Weekday {
}
}
fn day_of_week_from_u8(v: u8) -> Result<DayOfWeek, Error> {
pub(super) const fn day_of_week_from_u8(v: u8) -> Result<DayOfWeek, Error> {
Ok(match v {
0 => DayOfWeek::Monday,
1 => DayOfWeek::Tuesday,
2 => DayOfWeek::Wednesday,
3 => DayOfWeek::Thursday,
4 => DayOfWeek::Friday,
5 => DayOfWeek::Saturday,
6 => DayOfWeek::Sunday,
1 => DayOfWeek::Monday,
2 => DayOfWeek::Tuesday,
3 => DayOfWeek::Wednesday,
4 => DayOfWeek::Thursday,
5 => DayOfWeek::Friday,
6 => DayOfWeek::Saturday,
7 => DayOfWeek::Sunday,
x => return Err(Error::InvalidDayOfWeek(x)),
})
}
pub(super) fn day_of_week_to_u8(dotw: DayOfWeek) -> u8 {
pub(super) const fn day_of_week_to_u8(dotw: DayOfWeek) -> u8 {
dotw as u8
}
pub(super) fn validate_datetime(dt: &DateTime) -> Result<(), Error> {
if dt.year > 4095 {
Err(Error::InvalidYear)
} else if dt.month < 1 || dt.month > 12 {
Err(Error::InvalidMonth)
} else if dt.day < 1 || dt.day > 31 {
Err(Error::InvalidDay)
} else if dt.hour > 23 {
Err(Error::InvalidHour)
} else if dt.minute > 59 {
Err(Error::InvalidMinute)
} else if dt.second > 59 {
Err(Error::InvalidSecond)
} else {
Ok(())
}
}
pub(super) fn write_date_time(rtc: &Rtc, t: DateTime) {
let (ht, hu) = byte_to_bcd2(t.hour as u8);
let (mnt, mnu) = byte_to_bcd2(t.minute as u8);
let (st, su) = byte_to_bcd2(t.second as u8);
let (dt, du) = byte_to_bcd2(t.day as u8);
let (mt, mu) = byte_to_bcd2(t.month as u8);
let yr = t.year as u16;
let yr_offset = (yr - 1970_u16) as u8;
let (yt, yu) = byte_to_bcd2(yr_offset);
use crate::pac::rtc::vals::Ampm;
rtc.tr().write(|w| {
w.set_ht(ht);
w.set_hu(hu);
w.set_mnt(mnt);
w.set_mnu(mnu);
w.set_st(st);
w.set_su(su);
w.set_pm(Ampm::AM);
});
rtc.dr().write(|w| {
w.set_dt(dt);
w.set_du(du);
w.set_mt(mt > 0);
w.set_mu(mu);
w.set_yt(yt);
w.set_yu(yu);
w.set_wdu(day_of_week_to_u8(t.day_of_week));
});
}
pub(super) fn datetime(
year: u16,
month: u8,
day: u8,
day_of_week: u8,
hour: u8,
minute: u8,
second: u8,
) -> Result<DateTime, Error> {
let day_of_week = day_of_week_from_u8(day_of_week)?;
Ok(DateTime {
year,
month,
day,
day_of_week,
hour,
minute,
second,
})
}

View File

@ -9,7 +9,11 @@ use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
#[cfg(feature = "low-power")]
use embassy_sync::blocking_mutex::Mutex;
use self::datetime::day_of_week_to_u8;
#[cfg(not(rtc_v2f2))]
use self::datetime::RtcInstant;
pub use self::datetime::{DateTime, DayOfWeek, Error as DateTimeError};
use crate::pac::rtc::regs::{Dr, Tr};
use crate::time::Hertz;
/// refer to AN4759 to compare features of RTC2 and RTC3
@ -30,112 +34,77 @@ use crate::peripherals::RTC;
use crate::rtc::sealed::Instance;
/// Errors that can occur on methods on [RtcClock]
#[non_exhaustive]
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum RtcError {
/// An invalid DateTime was given or stored on the hardware.
InvalidDateTime(DateTimeError),
/// The current time could not be read
ReadFailure,
/// The RTC clock is not running
NotRunning,
}
#[cfg(feature = "low-power")]
/// Represents an instant in time that can be substracted to compute a duration
struct RtcInstant {
second: u8,
subsecond: u16,
}
#[cfg(all(feature = "low-power", feature = "defmt"))]
impl defmt::Format for RtcInstant {
fn format(&self, fmt: defmt::Formatter) {
defmt::write!(
fmt,
"{}:{}",
self.second,
RTC::regs().prer().read().prediv_s() - self.subsecond,
)
}
}
#[cfg(feature = "low-power")]
impl core::ops::Sub for RtcInstant {
type Output = embassy_time::Duration;
fn sub(self, rhs: Self) -> Self::Output {
use embassy_time::{Duration, TICK_HZ};
let second = if self.second < rhs.second {
self.second + 60
} else {
self.second
};
let psc = RTC::regs().prer().read().prediv_s() as u32;
let self_ticks = second as u32 * (psc + 1) + (psc - self.subsecond as u32);
let other_ticks = rhs.second as u32 * (psc + 1) + (psc - rhs.subsecond as u32);
let rtc_ticks = self_ticks - other_ticks;
Duration::from_ticks(((rtc_ticks * TICK_HZ as u32) / (psc + 1)) as u64)
}
}
pub struct RtcTimeProvider {
_private: (),
}
impl RtcTimeProvider {
#[cfg(not(rtc_v2f2))]
pub(crate) fn instant(&self) -> Result<RtcInstant, RtcError> {
self.read(|_, tr, ss| {
let second = bcd2_to_byte((tr.st(), tr.su()));
RtcInstant::from(second, ss).map_err(RtcError::InvalidDateTime)
})
}
/// Return the current datetime.
///
/// # Errors
///
/// Will return an `RtcError::InvalidDateTime` if the stored value in the system is not a valid [`DayOfWeek`].
pub fn now(&self) -> Result<DateTime, RtcError> {
// For RM0433 we use BYPSHAD=1 to work around errata ES0392 2.19.1
#[cfg(rcc_h7rm0433)]
loop {
let r = RTC::regs();
let ss = r.ssr().read().ss();
let dr = r.dr().read();
let tr = r.tr().read();
// If an RTCCLK edge occurs during read we may see inconsistent values
// so read ssr again and see if it has changed. (see RM0433 Rev 7 46.3.9)
let ss_after = r.ssr().read().ss();
if ss == ss_after {
let second = bcd2_to_byte((tr.st(), tr.su()));
let minute = bcd2_to_byte((tr.mnt(), tr.mnu()));
let hour = bcd2_to_byte((tr.ht(), tr.hu()));
let weekday = dr.wdu();
let day = bcd2_to_byte((dr.dt(), dr.du()));
let month = bcd2_to_byte((dr.mt() as u8, dr.mu()));
let year = bcd2_to_byte((dr.yt(), dr.yu())) as u16 + 1970_u16;
return self::datetime::datetime(year, month, day, weekday, hour, minute, second)
.map_err(RtcError::InvalidDateTime);
}
}
#[cfg(not(rcc_h7rm0433))]
{
let r = RTC::regs();
let tr = r.tr().read();
self.read(|dr, tr, _| {
let second = bcd2_to_byte((tr.st(), tr.su()));
let minute = bcd2_to_byte((tr.mnt(), tr.mnu()));
let hour = bcd2_to_byte((tr.ht(), tr.hu()));
// Reading either RTC_SSR or RTC_TR locks the values in the higher-order
// calendar shadow registers until RTC_DR is read.
let dr = r.dr().read();
let weekday = dr.wdu();
let day = bcd2_to_byte((dr.dt(), dr.du()));
let month = bcd2_to_byte((dr.mt() as u8, dr.mu()));
let year = bcd2_to_byte((dr.yt(), dr.yu())) as u16 + 1970_u16;
self::datetime::datetime(year, month, day, weekday, hour, minute, second).map_err(RtcError::InvalidDateTime)
DateTime::from(year, month, day, weekday, hour, minute, second).map_err(RtcError::InvalidDateTime)
})
}
fn read<R>(&self, mut f: impl FnMut(Dr, Tr, u16) -> Result<R, RtcError>) -> Result<R, RtcError> {
let r = RTC::regs();
#[cfg(not(rtc_v2f2))]
let read_ss = || r.ssr().read().ss();
#[cfg(rtc_v2f2)]
let read_ss = || 0;
let mut ss = read_ss();
for _ in 0..5 {
let tr = r.tr().read();
let dr = r.dr().read();
let ss_after = read_ss();
// If an RTCCLK edge occurs during read we may see inconsistent values
// so read ssr again and see if it has changed. (see RM0433 Rev 7 46.3.9)
if ss == ss_after {
return f(dr, tr, ss.try_into().unwrap());
} else {
ss = ss_after
}
}
return Err(RtcError::ReadFailure);
}
}
@ -184,11 +153,7 @@ impl Default for RtcCalibrationCyclePeriod {
impl Rtc {
pub fn new(_rtc: impl Peripheral<P = RTC>, rtc_config: RtcConfig) -> Self {
#[cfg(not(any(stm32l0, stm32f3, stm32l1, stm32f0, stm32f2)))]
critical_section::with(|cs| {
<RTC as crate::rcc::sealed::RccPeripheral>::enable_and_reset_with_cs(cs);
#[cfg(feature = "low-power")]
crate::rcc::clock_refcount_sub(cs);
});
<RTC as crate::rcc::sealed::RccPeripheral>::enable_and_reset();
let mut this = Self {
#[cfg(feature = "low-power")]
@ -203,6 +168,14 @@ impl Rtc {
this.configure(async_psc, sync_psc);
// Wait for the clock to update after initialization
#[cfg(not(rtc_v2f2))]
{
let now = this.instant().unwrap();
while this.instant().unwrap().subsecond == now.subsecond {}
}
this
}
@ -222,24 +195,47 @@ impl Rtc {
///
/// Will return `RtcError::InvalidDateTime` if the datetime is not a valid range.
pub fn set_datetime(&mut self, t: DateTime) -> Result<(), RtcError> {
self::datetime::validate_datetime(&t).map_err(RtcError::InvalidDateTime)?;
self.write(true, |rtc| self::datetime::write_date_time(rtc, t));
self.write(true, |rtc| {
let (ht, hu) = byte_to_bcd2(t.hour() as u8);
let (mnt, mnu) = byte_to_bcd2(t.minute() as u8);
let (st, su) = byte_to_bcd2(t.second() as u8);
let (dt, du) = byte_to_bcd2(t.day() as u8);
let (mt, mu) = byte_to_bcd2(t.month() as u8);
let yr = t.year() as u16;
let yr_offset = (yr - 1970_u16) as u8;
let (yt, yu) = byte_to_bcd2(yr_offset);
use crate::pac::rtc::vals::Ampm;
rtc.tr().write(|w| {
w.set_ht(ht);
w.set_hu(hu);
w.set_mnt(mnt);
w.set_mnu(mnu);
w.set_st(st);
w.set_su(su);
w.set_pm(Ampm::AM);
});
rtc.dr().write(|w| {
w.set_dt(dt);
w.set_du(du);
w.set_mt(mt > 0);
w.set_mu(mu);
w.set_yt(yt);
w.set_yu(yu);
w.set_wdu(day_of_week_to_u8(t.day_of_week()));
});
});
Ok(())
}
#[cfg(feature = "low-power")]
#[cfg(not(rtc_v2f2))]
/// Return the current instant.
fn instant(&self) -> RtcInstant {
let r = RTC::regs();
let tr = r.tr().read();
let subsecond = r.ssr().read().ss();
let second = bcd2_to_byte((tr.st(), tr.su()));
// Unlock the registers
r.dr().read();
RtcInstant { second, subsecond }
fn instant(&self) -> Result<RtcInstant, RtcError> {
self.time_provider().instant()
}
/// Return the current datetime.

View File

@ -95,15 +95,16 @@ impl super::Rtc {
regs.cr().modify(|w| w.set_wutie(true));
});
let instant = self.instant().unwrap();
trace!(
"rtc: start wakeup alarm for {} ms (psc: {}, ticks: {}) at {}",
Duration::from_ticks(rtc_ticks as u64 * TICK_HZ * prescaler as u64 / rtc_hz).as_millis(),
prescaler as u32,
rtc_ticks,
self.instant(),
instant,
);
assert!(self.stop_time.borrow(cs).replace(Some(self.instant())).is_none())
assert!(self.stop_time.borrow(cs).replace(Some(instant)).is_none())
}
#[cfg(feature = "low-power")]
@ -112,8 +113,9 @@ impl super::Rtc {
pub(crate) fn stop_wakeup_alarm(&self, cs: critical_section::CriticalSection) -> Option<embassy_time::Duration> {
use crate::interrupt::typelevel::Interrupt;
let instant = self.instant().unwrap();
if RTC::regs().cr().read().wute() {
trace!("rtc: stop wakeup alarm at {}", self.instant());
trace!("rtc: stop wakeup alarm at {}", instant);
self.write(false, |regs| {
regs.cr().modify(|w| w.set_wutie(false));
@ -128,10 +130,7 @@ impl super::Rtc {
});
}
self.stop_time
.borrow(cs)
.take()
.map(|stop_time| self.instant() - stop_time)
self.stop_time.borrow(cs).take().map(|stop_time| instant - stop_time)
}
#[cfg(feature = "low-power")]
@ -151,14 +150,14 @@ impl super::Rtc {
pub(super) fn configure(&mut self, async_psc: u8, sync_psc: u16) {
self.write(true, |rtc| {
rtc.cr().modify(|w| {
#[cfg(not(rtc_v2f2))]
w.set_bypshad(true);
#[cfg(rtc_v2f2)]
w.set_fmt(false);
#[cfg(not(rtc_v2f2))]
w.set_fmt(stm32_metapac::rtc::vals::Fmt::TWENTY_FOUR_HOUR);
w.set_osel(Osel::DISABLED);
w.set_pol(Pol::HIGH);
#[cfg(rcc_h7rm0433)]
w.set_bypshad(true);
});
rtc.prer().modify(|w| {

View File

@ -11,6 +11,7 @@ impl super::Rtc {
pub(super) fn configure(&mut self, async_psc: u8, sync_psc: u16) {
self.write(true, |rtc| {
rtc.cr().modify(|w| {
w.set_bypshad(true);
w.set_fmt(Fmt::TWENTYFOURHOUR);
w.set_osel(Osel::DISABLED);
w.set_pol(Pol::HIGH);

View File

@ -345,6 +345,10 @@ impl RtcDriver {
});
}
#[cfg(feature = "low-power")]
/// The minimum pause time beyond which the executor will enter a low-power state.
pub(crate) const MIN_STOP_PAUSE: embassy_time::Duration = embassy_time::Duration::from_millis(250);
#[cfg(feature = "low-power")]
/// Pause the timer if ready; return err if not
pub(crate) fn pause_time(&self) -> Result<(), ()> {
@ -357,7 +361,7 @@ impl RtcDriver {
self.stop_wakeup_alarm(cs);
let time_until_next_alarm = self.time_until_next_alarm(cs);
if time_until_next_alarm < embassy_time::Duration::from_millis(250) {
if time_until_next_alarm < Self::MIN_STOP_PAUSE {
Err(())
} else {
self.rtc

View File

@ -116,28 +116,28 @@ pub struct BufferedUartRx<'d, T: BasicInstance> {
impl<'d, T: BasicInstance> SetConfig for BufferedUart<'d, T> {
type Config = Config;
type ConfigError = ();
type ConfigError = ConfigError;
fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> {
self.set_config(config).map_err(|_| ())
fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
self.set_config(config)
}
}
impl<'d, T: BasicInstance> SetConfig for BufferedUartRx<'d, T> {
type Config = Config;
type ConfigError = ();
type ConfigError = ConfigError;
fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> {
self.set_config(config).map_err(|_| ())
fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
self.set_config(config)
}
}
impl<'d, T: BasicInstance> SetConfig for BufferedUartTx<'d, T> {
type Config = Config;
type ConfigError = ();
type ConfigError = ConfigError;
fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> {
self.set_config(config).map_err(|_| ())
fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
self.set_config(config)
}
}
@ -233,9 +233,6 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> {
configure(r, &config, T::frequency(), T::KIND, true, true)?;
r.cr1().modify(|w| {
#[cfg(lpuart_v2)]
w.set_fifoen(true);
w.set_rxneie(true);
w.set_idleie(true);
});
@ -254,7 +251,14 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> {
}
pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
reconfigure::<T>(config)
reconfigure::<T>(config)?;
T::regs().cr1().modify(|w| {
w.set_rxneie(true);
w.set_idleie(true);
});
Ok(())
}
}
@ -334,7 +338,14 @@ impl<'d, T: BasicInstance> BufferedUartRx<'d, T> {
}
pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
reconfigure::<T>(config)
reconfigure::<T>(config)?;
T::regs().cr1().modify(|w| {
w.set_rxneie(true);
w.set_idleie(true);
});
Ok(())
}
}
@ -408,7 +419,14 @@ impl<'d, T: BasicInstance> BufferedUartTx<'d, T> {
}
pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
reconfigure::<T>(config)
reconfigure::<T>(config)?;
T::regs().cr1().modify(|w| {
w.set_rxneie(true);
w.set_idleie(true);
});
Ok(())
}
}

View File

@ -108,6 +108,7 @@ pub enum StopBits {
pub enum ConfigError {
BaudrateTooLow,
BaudrateTooHigh,
RxOrTxNotEnabled,
}
#[non_exhaustive]
@ -181,11 +182,11 @@ pub struct Uart<'d, T: BasicInstance, TxDma = NoDma, RxDma = NoDma> {
impl<'d, T: BasicInstance, TxDma, RxDma> SetConfig for Uart<'d, T, TxDma, RxDma> {
type Config = Config;
type ConfigError = ();
type ConfigError = ConfigError;
fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> {
self.tx.set_config(config).map_err(|_| ())?;
self.rx.set_config(config).map_err(|_| ())
fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
self.tx.set_config(config)?;
self.rx.set_config(config)
}
}
@ -196,10 +197,10 @@ pub struct UartTx<'d, T: BasicInstance, TxDma = NoDma> {
impl<'d, T: BasicInstance, TxDma> SetConfig for UartTx<'d, T, TxDma> {
type Config = Config;
type ConfigError = ();
type ConfigError = ConfigError;
fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> {
self.set_config(config).map_err(|_| ())
fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
self.set_config(config)
}
}
@ -213,10 +214,10 @@ pub struct UartRx<'d, T: BasicInstance, RxDma = NoDma> {
impl<'d, T: BasicInstance, RxDma> SetConfig for UartRx<'d, T, RxDma> {
type Config = Config;
type ConfigError = ();
type ConfigError = ConfigError;
fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> {
self.set_config(config).map_err(|_| ())
fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
self.set_config(config)
}
}
@ -866,7 +867,7 @@ fn configure(
enable_tx: bool,
) -> Result<(), ConfigError> {
if !enable_rx && !enable_tx {
panic!("USART: At least one of RX or TX should be enabled");
return Err(ConfigError::RxOrTxNotEnabled);
}
#[cfg(not(usart_v4))]
@ -909,6 +910,11 @@ fn configure(
brr + rounding
}
// UART must be disabled during configuration.
r.cr1().modify(|w| {
w.set_ue(false);
});
#[cfg(not(usart_v1))]
let mut over8 = false;
let mut found_brr = None;
@ -968,6 +974,12 @@ fn configure(
#[cfg(any(usart_v3, usart_v4))]
w.set_swap(config.swap_rx_tx);
});
#[cfg(not(usart_v1))]
r.cr3().modify(|w| {
w.set_onebit(config.assume_noise_free);
});
r.cr1().write(|w| {
// enable uart
w.set_ue(true);
@ -976,6 +988,7 @@ fn configure(
// enable receiver
w.set_re(enable_rx);
// configure word size
// if using odd or even parity it must be configured to 9bits
w.set_m0(if config.parity != Parity::ParityNone {
vals::M0::BIT9
} else {
@ -994,11 +1007,6 @@ fn configure(
w.set_fifoen(true);
});
#[cfg(not(usart_v1))]
r.cr3().modify(|w| {
w.set_onebit(config.assume_noise_free);
});
Ok(())
}

View File

@ -18,10 +18,10 @@ pub struct RingBufferedUartRx<'d, T: BasicInstance, RxDma: super::RxDma<T>> {
impl<'d, T: BasicInstance, RxDma: super::RxDma<T>> SetConfig for RingBufferedUartRx<'d, T, RxDma> {
type Config = Config;
type ConfigError = ();
type ConfigError = ConfigError;
fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> {
self.set_config(config).map_err(|_| ())
fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
self.set_config(config)
}
}

View File

@ -5,9 +5,14 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## 0.4.0 - 2023-10-31
- Re-add impl_trait_projections
- switch to `embedded-io 0.6`
## 0.3.0 - 2023-09-14
- switch to embedded-io 0.5
- switch to `embedded-io 0.5`
- add api for polling channels with context
- standardise fn names on channels
- add zero-copy channel

View File

@ -1,6 +1,6 @@
[package]
name = "embassy-sync"
version = "0.3.0"
version = "0.4.0"
edition = "2021"
description = "no-std, no-alloc synchronization primitives with async support"
repository = "https://github.com/embassy-rs/embassy"
@ -45,4 +45,4 @@ futures-util = { version = "0.3.17", features = [ "channel" ] }
# Enable critical-section implementation for std, for tests
critical-section = { version = "1.1", features = ["std"] }
static_cell = "1.1"
static_cell = { version = "2" }

View File

@ -1,5 +1,6 @@
#![cfg_attr(not(any(feature = "std", feature = "wasm")), no_std)]
#![cfg_attr(feature = "nightly", feature(async_fn_in_trait))]
#![cfg_attr(feature = "nightly", feature(async_fn_in_trait, impl_trait_projections))]
#![cfg_attr(feature = "nightly", allow(stable_features, unknown_lints, async_fn_in_trait))]
#![allow(clippy::new_without_default)]
#![doc = include_str!("../README.md")]
#![warn(missing_docs)]

View File

@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## 0.1.6 - ???
- Added tick rates in multiples of 10 kHz
## 0.1.5 - 2023-10-16
- Added `links` key to Cargo.toml, to prevent multiple copies of this crate in the same binary.

View File

@ -59,6 +59,9 @@ generic-queue-32 = ["generic-queue"]
generic-queue-64 = ["generic-queue"]
generic-queue-128 = ["generic-queue"]
# Create a `MockDriver` that can be manually advanced for testing purposes.
mock-driver = ["tick-hz-1_000_000"]
# Set the `embassy_time` tick rate.
#
# At most 1 `tick-*` feature can be enabled. If none is enabled, a default of 1MHz is used.
@ -126,6 +129,25 @@ tick-hz-65_536_000 = []
tick-hz-131_072_000 = []
tick-hz-262_144_000 = []
tick-hz-524_288_000 = []
tick-hz-20_000 = []
tick-hz-40_000 = []
tick-hz-80_000 = []
tick-hz-160_000 = []
tick-hz-320_000 = []
tick-hz-640_000 = []
tick-hz-1_280_000 = []
tick-hz-2_560_000 = []
tick-hz-5_120_000 = []
tick-hz-10_240_000 = []
tick-hz-20_480_000 = []
tick-hz-40_960_000 = []
tick-hz-81_920_000 = []
tick-hz-163_840_000 = []
tick-hz-327_680_000 = []
tick-hz-655_360_000 = []
tick-hz-1_310_720_000 = []
tick-hz-2_621_440_000 = []
tick-hz-5_242_880_000 = []
tick-hz-2_000_000 = []
tick-hz-3_000_000 = []
tick-hz-4_000_000 = []
@ -236,4 +258,4 @@ wasm-timer = { version = "0.2.5", optional = true }
[dev-dependencies]
serial_test = "0.9"
critical-section = { version = "1.1", features = ["std"] }
embassy-executor = { version = "0.3.0", path = "../embassy-executor", features = ["nightly"] }
embassy-executor = { version = "0.3.1", path = "../embassy-executor", features = ["nightly"] }

View File

@ -13,6 +13,8 @@ for i in range(1, 25):
ticks.append(2**i)
for i in range(1, 20):
ticks.append(2**i * 1000)
for i in range(1, 20):
ticks.append(2**i * 10000)
for i in range(1, 10):
ticks.append(2**i * 1000000)
ticks.append(2**i * 9 // 8 * 1000000)

View File

@ -0,0 +1,68 @@
use core::cell::Cell;
use critical_section::Mutex as CsMutex;
use crate::driver::{AlarmHandle, Driver};
use crate::{Duration, Instant};
/// A mock driver that can be manually advanced.
/// This is useful for testing code that works with [`Instant`] and [`Duration`].
///
/// This driver cannot currently be used to test runtime functionality, such as
/// timers, delays, etc.
///
/// # Example
///
/// ```ignore
/// fn has_a_second_passed(reference: Instant) -> bool {
/// Instant::now().duration_since(reference) >= Duration::from_secs(1)
/// }
///
/// fn test_second_passed() {
/// let driver = embassy_time::MockDriver::get();
/// let reference = Instant::now();
/// assert_eq!(false, has_a_second_passed(reference));
/// driver.advance(Duration::from_secs(1));
/// assert_eq!(true, has_a_second_passed(reference));
/// }
/// ```
pub struct MockDriver {
now: CsMutex<Cell<Instant>>,
}
crate::time_driver_impl!(static DRIVER: MockDriver = MockDriver {
now: CsMutex::new(Cell::new(Instant::from_ticks(0))),
});
impl MockDriver {
/// Gets a reference to the global mock driver.
pub fn get() -> &'static MockDriver {
&DRIVER
}
/// Advances the time by the specified [`Duration`].
pub fn advance(&self, duration: Duration) {
critical_section::with(|cs| {
let now = self.now.borrow(cs).get().as_ticks();
self.now.borrow(cs).set(Instant::from_ticks(now + duration.as_ticks()));
});
}
}
impl Driver for MockDriver {
fn now(&self) -> u64 {
critical_section::with(|cs| self.now.borrow(cs).get().as_ticks() as u64)
}
unsafe fn allocate_alarm(&self) -> Option<AlarmHandle> {
unimplemented!("MockDriver does not support runtime features that require an executor");
}
fn set_alarm_callback(&self, _alarm: AlarmHandle, _callback: fn(*mut ()), _ctx: *mut ()) {
unimplemented!("MockDriver does not support runtime features that require an executor");
}
fn set_alarm(&self, _alarm: AlarmHandle, _timestamp: u64) -> bool {
unimplemented!("MockDriver does not support runtime features that require an executor");
}
}

View File

@ -1,5 +1,6 @@
#![cfg_attr(not(any(feature = "std", feature = "wasm", test)), no_std)]
#![cfg_attr(feature = "nightly", feature(async_fn_in_trait))]
#![cfg_attr(feature = "nightly", allow(stable_features, unknown_lints, async_fn_in_trait))]
#![doc = include_str!("../README.md")]
#![allow(clippy::new_without_default)]
#![warn(missing_docs)]
@ -15,6 +16,12 @@ pub mod queue;
mod tick;
mod timer;
#[cfg(feature = "mock-driver")]
mod driver_mock;
#[cfg(feature = "mock-driver")]
pub use driver_mock::MockDriver;
#[cfg(feature = "std")]
mod driver_std;
#[cfg(feature = "wasm")]

View File

@ -106,6 +106,44 @@ pub const TICK_HZ: u64 = 131_072_000;
pub const TICK_HZ: u64 = 262_144_000;
#[cfg(feature = "tick-hz-524_288_000")]
pub const TICK_HZ: u64 = 524_288_000;
#[cfg(feature = "tick-hz-20_000")]
pub const TICK_HZ: u64 = 20_000;
#[cfg(feature = "tick-hz-40_000")]
pub const TICK_HZ: u64 = 40_000;
#[cfg(feature = "tick-hz-80_000")]
pub const TICK_HZ: u64 = 80_000;
#[cfg(feature = "tick-hz-160_000")]
pub const TICK_HZ: u64 = 160_000;
#[cfg(feature = "tick-hz-320_000")]
pub const TICK_HZ: u64 = 320_000;
#[cfg(feature = "tick-hz-640_000")]
pub const TICK_HZ: u64 = 640_000;
#[cfg(feature = "tick-hz-1_280_000")]
pub const TICK_HZ: u64 = 1_280_000;
#[cfg(feature = "tick-hz-2_560_000")]
pub const TICK_HZ: u64 = 2_560_000;
#[cfg(feature = "tick-hz-5_120_000")]
pub const TICK_HZ: u64 = 5_120_000;
#[cfg(feature = "tick-hz-10_240_000")]
pub const TICK_HZ: u64 = 10_240_000;
#[cfg(feature = "tick-hz-20_480_000")]
pub const TICK_HZ: u64 = 20_480_000;
#[cfg(feature = "tick-hz-40_960_000")]
pub const TICK_HZ: u64 = 40_960_000;
#[cfg(feature = "tick-hz-81_920_000")]
pub const TICK_HZ: u64 = 81_920_000;
#[cfg(feature = "tick-hz-163_840_000")]
pub const TICK_HZ: u64 = 163_840_000;
#[cfg(feature = "tick-hz-327_680_000")]
pub const TICK_HZ: u64 = 327_680_000;
#[cfg(feature = "tick-hz-655_360_000")]
pub const TICK_HZ: u64 = 655_360_000;
#[cfg(feature = "tick-hz-1_310_720_000")]
pub const TICK_HZ: u64 = 1_310_720_000;
#[cfg(feature = "tick-hz-2_621_440_000")]
pub const TICK_HZ: u64 = 2_621_440_000;
#[cfg(feature = "tick-hz-5_242_880_000")]
pub const TICK_HZ: u64 = 5_242_880_000;
#[cfg(feature = "tick-hz-2_000_000")]
pub const TICK_HZ: u64 = 2_000_000;
#[cfg(feature = "tick-hz-3_000_000")]
@ -334,6 +372,25 @@ pub const TICK_HZ: u64 = 980_000_000;
feature = "tick-hz-131_072_000",
feature = "tick-hz-262_144_000",
feature = "tick-hz-524_288_000",
feature = "tick-hz-20_000",
feature = "tick-hz-40_000",
feature = "tick-hz-80_000",
feature = "tick-hz-160_000",
feature = "tick-hz-320_000",
feature = "tick-hz-640_000",
feature = "tick-hz-1_280_000",
feature = "tick-hz-2_560_000",
feature = "tick-hz-5_120_000",
feature = "tick-hz-10_240_000",
feature = "tick-hz-20_480_000",
feature = "tick-hz-40_960_000",
feature = "tick-hz-81_920_000",
feature = "tick-hz-163_840_000",
feature = "tick-hz-327_680_000",
feature = "tick-hz-655_360_000",
feature = "tick-hz-1_310_720_000",
feature = "tick-hz-2_621_440_000",
feature = "tick-hz-5_242_880_000",
feature = "tick-hz-2_000_000",
feature = "tick-hz-3_000_000",
feature = "tick-hz-4_000_000",

View File

@ -1,5 +1,6 @@
#![no_std]
#![feature(async_fn_in_trait)]
#![allow(stable_features, unknown_lints, async_fn_in_trait)]
#![doc = include_str!("../README.md")]
#![warn(missing_docs)]

View File

@ -10,9 +10,9 @@ target = "thumbv7em-none-eabi"
[dependencies]
embassy-usb = { version = "0.1.0", path = "../embassy-usb" }
embassy-sync = { version = "0.3.0", path = "../embassy-sync" }
embassy-sync = { version = "0.4.0", path = "../embassy-sync" }
embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
futures = { version = "0.3", default-features = false }
static_cell = "1"
static_cell = { version = "2" }
usbd-hid = "0.6.0"
log = "0.4"

View File

@ -41,7 +41,7 @@ max-handler-count-8 = []
[dependencies]
embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
embassy-usb-driver = { version = "0.1.0", path = "../embassy-usb-driver" }
embassy-sync = { version = "0.3.0", path = "../embassy-sync" }
embassy-sync = { version = "0.4.0", path = "../embassy-sync" }
embassy-net-driver-channel = { version = "0.2.0", path = "../embassy-net-driver-channel" }
defmt = { version = "0.3", optional = true }

View File

@ -5,8 +5,8 @@ version = "0.1.0"
license = "MIT OR Apache-2.0"
[dependencies]
embassy-sync = { version = "0.3.0", path = "../../../../embassy-sync" }
embassy-executor = { version = "0.3.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers", "arch-cortex-m", "executor-thread"] }
embassy-sync = { version = "0.4.0", path = "../../../../embassy-sync" }
embassy-executor = { version = "0.3.1", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers", "arch-cortex-m", "executor-thread"] }
embassy-time = { version = "0.1.5", path = "../../../../embassy-time", features = ["nightly"] }
embassy-nrf = { version = "0.1.0", path = "../../../../embassy-nrf", features = ["time-driver-rtc1", "gpiote", "nightly"] }
embassy-boot = { version = "0.1.0", path = "../../../../embassy-boot/boot", features = ["nightly"] }

View File

@ -5,8 +5,8 @@ version = "0.1.0"
license = "MIT OR Apache-2.0"
[dependencies]
embassy-sync = { version = "0.3.0", path = "../../../../embassy-sync" }
embassy-executor = { version = "0.3.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers", "arch-cortex-m", "executor-thread"] }
embassy-sync = { version = "0.4.0", path = "../../../../embassy-sync" }
embassy-executor = { version = "0.3.1", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers", "arch-cortex-m", "executor-thread"] }
embassy-time = { version = "0.1.5", path = "../../../../embassy-time", features = ["nightly"] }
embassy-rp = { version = "0.1.0", path = "../../../../embassy-rp", features = ["time-driver", "unstable-traits", "nightly"] }
embassy-boot-rp = { version = "0.1.0", path = "../../../../embassy-boot/rp", features = ["nightly"] }

View File

@ -5,8 +5,8 @@ version = "0.1.0"
license = "MIT OR Apache-2.0"
[dependencies]
embassy-sync = { version = "0.3.0", path = "../../../../embassy-sync" }
embassy-executor = { version = "0.3.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] }
embassy-sync = { version = "0.4.0", path = "../../../../embassy-sync" }
embassy-executor = { version = "0.3.1", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] }
embassy-time = { version = "0.1.5", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] }
embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32f303re", "time-driver-any", "exti"] }
embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32", features = ["nightly"] }

View File

@ -5,8 +5,8 @@ version = "0.1.0"
license = "MIT OR Apache-2.0"
[dependencies]
embassy-sync = { version = "0.3.0", path = "../../../../embassy-sync" }
embassy-executor = { version = "0.3.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] }
embassy-sync = { version = "0.4.0", path = "../../../../embassy-sync" }
embassy-executor = { version = "0.3.1", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] }
embassy-time = { version = "0.1.5", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] }
embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32f767zi", "time-driver-any", "exti"] }
embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32", features = ["nightly"] }

View File

@ -5,8 +5,8 @@ version = "0.1.0"
license = "MIT OR Apache-2.0"
[dependencies]
embassy-sync = { version = "0.3.0", path = "../../../../embassy-sync" }
embassy-executor = { version = "0.3.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] }
embassy-sync = { version = "0.4.0", path = "../../../../embassy-sync" }
embassy-executor = { version = "0.3.1", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] }
embassy-time = { version = "0.1.5", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] }
embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32h743zi", "time-driver-any", "exti"] }
embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32", features = ["nightly"] }

View File

@ -5,8 +5,8 @@ version = "0.1.0"
license = "MIT OR Apache-2.0"
[dependencies]
embassy-sync = { version = "0.3.0", path = "../../../../embassy-sync" }
embassy-executor = { version = "0.3.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] }
embassy-sync = { version = "0.4.0", path = "../../../../embassy-sync" }
embassy-executor = { version = "0.3.1", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] }
embassy-time = { version = "0.1.5", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] }
embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32l072cz", "time-driver-any", "exti", "memory-x"] }
embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32", features = ["nightly"] }

View File

@ -5,8 +5,8 @@ version = "0.1.0"
license = "MIT OR Apache-2.0"
[dependencies]
embassy-sync = { version = "0.3.0", path = "../../../../embassy-sync" }
embassy-executor = { version = "0.3.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] }
embassy-sync = { version = "0.4.0", path = "../../../../embassy-sync" }
embassy-executor = { version = "0.3.1", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] }
embassy-time = { version = "0.1.5", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] }
embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32l151cb-a", "time-driver-any", "exti"] }
embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32", features = ["nightly"] }

View File

@ -5,8 +5,8 @@ version = "0.1.0"
license = "MIT OR Apache-2.0"
[dependencies]
embassy-sync = { version = "0.3.0", path = "../../../../embassy-sync" }
embassy-executor = { version = "0.3.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] }
embassy-sync = { version = "0.4.0", path = "../../../../embassy-sync" }
embassy-executor = { version = "0.3.1", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] }
embassy-time = { version = "0.1.5", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] }
embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32l475vg", "time-driver-any", "exti"] }
embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32", features = ["nightly"] }

View File

@ -5,8 +5,8 @@ version = "0.1.0"
license = "MIT OR Apache-2.0"
[dependencies]
embassy-sync = { version = "0.3.0", path = "../../../../embassy-sync" }
embassy-executor = { version = "0.3.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] }
embassy-sync = { version = "0.4.0", path = "../../../../embassy-sync" }
embassy-executor = { version = "0.3.1", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] }
embassy-time = { version = "0.1.5", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] }
embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32wl55jc-cm4", "time-driver-any", "exti"] }
embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32", features = ["nightly"] }

View File

@ -12,7 +12,7 @@ defmt-rtt = { version = "0.4", optional = true }
embassy-nrf = { path = "../../../../embassy-nrf", features = ["nightly"] }
embassy-boot-nrf = { path = "../../../../embassy-boot/nrf" }
cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
embassy-sync = { path = "../../../../embassy-sync" }
embassy-sync = { version = "0.4.0", path = "../../../../embassy-sync" }
cortex-m-rt = { version = "0.7" }
cfg-if = "1.0.0"

View File

@ -11,7 +11,7 @@ defmt-rtt = { version = "0.4", optional = true }
embassy-rp = { path = "../../../../embassy-rp", features = ["nightly"] }
embassy-boot-rp = { path = "../../../../embassy-boot/rp" }
embassy-sync = { path = "../../../../embassy-sync" }
embassy-sync = { version = "0.4.0", path = "../../../../embassy-sync" }
embassy-time = { path = "../../../../embassy-time", features = ["nightly"] }
cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }

View File

@ -12,7 +12,7 @@ defmt-rtt = { version = "0.4", optional = true }
embassy-stm32 = { path = "../../../../embassy-stm32", features = ["nightly"] }
embassy-boot-stm32 = { path = "../../../../embassy-boot/stm32" }
cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
embassy-sync = { path = "../../../../embassy-sync" }
embassy-sync = { version = "0.4.0", path = "../../../../embassy-sync" }
cortex-m-rt = { version = "0.7" }
embedded-storage = "0.3.0"
embedded-storage-async = "0.4.0"

View File

@ -16,8 +16,8 @@ log = [
]
[dependencies]
embassy-sync = { version = "0.3.0", path = "../../embassy-sync" }
embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "rtos-trace", "rtos-trace-interrupt", "integrated-timers"] }
embassy-sync = { version = "0.4.0", path = "../../embassy-sync" }
embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "rtos-trace", "rtos-trace-interrupt", "integrated-timers"] }
embassy-time = { version = "0.1.5", path = "../../embassy-time" }
embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac"] }

View File

@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0"
rtic = { version = "2", features = ["thumbv7-backend"] }
embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] }
embassy-sync = { version = "0.4.0", path = "../../embassy-sync", features = ["defmt"] }
embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["nightly", "unstable-traits", "defmt", "defmt-timestamp-uptime", "generic-queue"] }
embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["nightly", "unstable-traits", "defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] }

View File

@ -29,8 +29,8 @@ nightly = [
[dependencies]
embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] }
embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] }
embassy-sync = { version = "0.4.0", path = "../../embassy-sync", features = ["defmt"] }
embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] }
embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] }
embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"], optional = true }
@ -48,7 +48,7 @@ defmt = "0.3"
defmt-rtt = "0.4"
fixed = "1.10.0"
static_cell = "1.1"
static_cell = { version = "2" }
cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
cortex-m-rt = "0.7.0"
panic-probe = { version = "0.3", features = ["print-defmt"] }

View File

@ -6,10 +6,10 @@ license = "MIT OR Apache-2.0"
[dependencies]
embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = [
embassy-sync = { version = "0.4.0", path = "../../embassy-sync", features = [
"defmt",
] }
embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread",
embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread",
"nightly",
"defmt",
"integrated-timers",
@ -42,7 +42,7 @@ embedded-io-async = { version = "0.6.0" }
defmt = "0.3"
defmt-rtt = "0.4"
static_cell = { version = "1.1", features = ["nightly"]}
static_cell = { version = "2", features = ["nightly"]}
cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
cortex-m-rt = "0.7.0"
panic-probe = { version = "0.3", features = ["print-defmt"] }

View File

@ -7,8 +7,8 @@ license = "MIT OR Apache-2.0"
[dependencies]
embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal", features = ["defmt"] }
embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] }
embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] }
embassy-sync = { version = "0.4.0", path = "../../embassy-sync", features = ["defmt"] }
embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] }
embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["nightly", "unstable-traits", "defmt", "defmt-timestamp-uptime"] }
embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = ["defmt", "unstable-traits", "nightly", "unstable-pac", "time-driver", "critical-section-impl"] }
embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
@ -47,7 +47,8 @@ embedded-hal-async = "1.0.0-rc.1"
embedded-hal-bus = { version = "0.1.0-rc.1", features = ["async"] }
embedded-io-async = { version = "0.6.0", features = ["defmt-03"] }
embedded-storage = { version = "0.3" }
static_cell = { version = "1.1", features = ["nightly"]}
static_cell = { version = "2", features = ["nightly"]}
portable-atomic = { version = "1.5", features = ["critical-section"] }
log = "0.4"
pio-proc = "0.2"
pio = "0.2.1"

View File

@ -0,0 +1,81 @@
//! This example shows how to use the PIO module in the RP2040 to read a quadrature rotary encoder.
#![no_std]
#![no_main]
#![feature(type_alias_impl_trait)]
use defmt::info;
use embassy_executor::Spawner;
use embassy_rp::gpio::Pull;
use embassy_rp::peripherals::PIO0;
use embassy_rp::{bind_interrupts, pio};
use fixed::traits::ToFixed;
use pio::{Common, Config, FifoJoin, Instance, InterruptHandler, Pio, PioPin, ShiftDirection, StateMachine};
use {defmt_rtt as _, panic_probe as _};
bind_interrupts!(struct Irqs {
PIO0_IRQ_0 => InterruptHandler<PIO0>;
});
pub struct PioEncoder<'d, T: Instance, const SM: usize> {
sm: StateMachine<'d, T, SM>,
}
impl<'d, T: Instance, const SM: usize> PioEncoder<'d, T, SM> {
pub fn new(
pio: &mut Common<'d, T>,
mut sm: StateMachine<'d, T, SM>,
pin_a: impl PioPin,
pin_b: impl PioPin,
) -> Self {
let mut pin_a = pio.make_pio_pin(pin_a);
let mut pin_b = pio.make_pio_pin(pin_b);
pin_a.set_pull(Pull::Up);
pin_b.set_pull(Pull::Up);
sm.set_pin_dirs(pio::Direction::In, &[&pin_a, &pin_b]);
let prg = pio_proc::pio_asm!("wait 1 pin 1", "wait 0 pin 1", "in pins, 2", "push",);
let mut cfg = Config::default();
cfg.set_in_pins(&[&pin_a, &pin_b]);
cfg.fifo_join = FifoJoin::RxOnly;
cfg.shift_in.direction = ShiftDirection::Left;
cfg.clock_divider = 10_000.to_fixed();
cfg.use_program(&pio.load_program(&prg.program), &[]);
sm.set_config(&cfg);
sm.set_enable(true);
Self { sm }
}
pub async fn read(&mut self) -> Direction {
loop {
match self.sm.rx().wait_pull().await {
0 => return Direction::CounterClockwise,
1 => return Direction::Clockwise,
_ => {}
}
}
}
}
pub enum Direction {
Clockwise,
CounterClockwise,
}
#[embassy_executor::main]
async fn main(_spawner: Spawner) {
let p = embassy_rp::init(Default::default());
let Pio { mut common, sm0, .. } = Pio::new(p.PIO0, Irqs);
let mut encoder = PioEncoder::new(&mut common, sm0, p.PIN_4, p.PIN_5);
let mut count = 0;
loop {
info!("Count: {}", count);
count += match encoder.read().await {
Direction::Clockwise => 1,
Direction::CounterClockwise => -1,
};
}
}

View File

@ -0,0 +1,169 @@
//! This example shows how to use the PIO module in the RP2040 to implement a stepper motor driver
//! for a 5-wire stepper such as the 28BYJ-48. You can halt an ongoing rotation by dropping the future.
#![no_std]
#![no_main]
#![feature(type_alias_impl_trait)]
use core::mem::{self, MaybeUninit};
use defmt::info;
use embassy_executor::Spawner;
use embassy_rp::bind_interrupts;
use embassy_rp::peripherals::PIO0;
use embassy_rp::pio::{Common, Config, Direction, Instance, InterruptHandler, Irq, Pio, PioPin, StateMachine};
use embassy_time::{with_timeout, Duration, Timer};
use fixed::traits::ToFixed;
use fixed::types::extra::U8;
use fixed::FixedU32;
use {defmt_rtt as _, panic_probe as _};
bind_interrupts!(struct Irqs {
PIO0_IRQ_0 => InterruptHandler<PIO0>;
});
pub struct PioStepper<'d, T: Instance, const SM: usize> {
irq: Irq<'d, T, SM>,
sm: StateMachine<'d, T, SM>,
}
impl<'d, T: Instance, const SM: usize> PioStepper<'d, T, SM> {
pub fn new(
pio: &mut Common<'d, T>,
mut sm: StateMachine<'d, T, SM>,
irq: Irq<'d, T, SM>,
pin0: impl PioPin,
pin1: impl PioPin,
pin2: impl PioPin,
pin3: impl PioPin,
) -> Self {
let prg = pio_proc::pio_asm!(
"pull block",
"mov x, osr",
"pull block",
"mov y, osr",
"jmp !x end",
"loop:",
"jmp !osre step",
"mov osr, y",
"step:",
"out pins, 4 [31]"
"jmp x-- loop",
"end:",
"irq 0 rel"
);
let pin0 = pio.make_pio_pin(pin0);
let pin1 = pio.make_pio_pin(pin1);
let pin2 = pio.make_pio_pin(pin2);
let pin3 = pio.make_pio_pin(pin3);
sm.set_pin_dirs(Direction::Out, &[&pin0, &pin1, &pin2, &pin3]);
let mut cfg = Config::default();
cfg.set_out_pins(&[&pin0, &pin1, &pin2, &pin3]);
cfg.clock_divider = (125_000_000 / (100 * 136)).to_fixed();
cfg.use_program(&pio.load_program(&prg.program), &[]);
sm.set_config(&cfg);
sm.set_enable(true);
Self { irq, sm }
}
// Set pulse frequency
pub fn set_frequency(&mut self, freq: u32) {
let clock_divider: FixedU32<U8> = (125_000_000 / (freq * 136)).to_fixed();
assert!(clock_divider <= 65536, "clkdiv must be <= 65536");
assert!(clock_divider >= 1, "clkdiv must be >= 1");
T::PIO.sm(SM).clkdiv().write(|w| w.0 = clock_divider.to_bits() << 8);
self.sm.clkdiv_restart();
}
// Full step, one phase
pub async fn step(&mut self, steps: i32) {
if steps > 0 {
self.run(steps, 0b1000_0100_0010_0001_1000_0100_0010_0001).await
} else {
self.run(-steps, 0b0001_0010_0100_1000_0001_0010_0100_1000).await
}
}
// Full step, two phase
pub async fn step2(&mut self, steps: i32) {
if steps > 0 {
self.run(steps, 0b1001_1100_0110_0011_1001_1100_0110_0011).await
} else {
self.run(-steps, 0b0011_0110_1100_1001_0011_0110_1100_1001).await
}
}
// Half step
pub async fn step_half(&mut self, steps: i32) {
if steps > 0 {
self.run(steps, 0b1001_1000_1100_0100_0110_0010_0011_0001).await
} else {
self.run(-steps, 0b0001_0011_0010_0110_0100_1100_1000_1001).await
}
}
async fn run(&mut self, steps: i32, pattern: u32) {
self.sm.tx().wait_push(steps as u32).await;
self.sm.tx().wait_push(pattern).await;
let drop = OnDrop::new(|| {
self.sm.clear_fifos();
unsafe {
self.sm.exec_instr(
pio::InstructionOperands::JMP {
address: 0,
condition: pio::JmpCondition::Always,
}
.encode(),
);
}
});
self.irq.wait().await;
drop.defuse();
}
}
struct OnDrop<F: FnOnce()> {
f: MaybeUninit<F>,
}
impl<F: FnOnce()> OnDrop<F> {
pub fn new(f: F) -> Self {
Self { f: MaybeUninit::new(f) }
}
pub fn defuse(self) {
mem::forget(self)
}
}
impl<F: FnOnce()> Drop for OnDrop<F> {
fn drop(&mut self) {
unsafe { self.f.as_ptr().read()() }
}
}
#[embassy_executor::main]
async fn main(_spawner: Spawner) {
let p = embassy_rp::init(Default::default());
let Pio {
mut common, irq0, sm0, ..
} = Pio::new(p.PIO0, Irqs);
let mut stepper = PioStepper::new(&mut common, sm0, irq0, p.PIN_4, p.PIN_5, p.PIN_6, p.PIN_7);
stepper.set_frequency(120);
loop {
info!("CW full steps");
stepper.step(1000).await;
info!("CCW full steps, drop after 1 sec");
if let Err(_) = with_timeout(Duration::from_secs(1), stepper.step(i32::MIN)).await {
info!("Time's up!");
Timer::after(Duration::from_secs(1)).await;
}
info!("CW half steps");
stepper.step_half(1000).await;
info!("CCW half steps");
stepper.step_half(-1000).await;
}
}

View File

@ -10,6 +10,7 @@
#![no_main]
#![feature(type_alias_impl_trait)]
#![feature(async_fn_in_trait)]
#![allow(stable_features, unknown_lints, async_fn_in_trait)]
use defmt::{info, panic, trace};
use embassy_executor::Spawner;

View File

@ -0,0 +1,26 @@
//! This example shows how to use the PWM module to measure the frequency of an input signal.
#![no_std]
#![no_main]
#![feature(type_alias_impl_trait)]
use defmt::*;
use embassy_executor::Spawner;
use embassy_rp::pwm::{Config, InputMode, Pwm};
use embassy_time::{Duration, Ticker};
use {defmt_rtt as _, panic_probe as _};
#[embassy_executor::main]
async fn main(_spawner: Spawner) {
let p = embassy_rp::init(Default::default());
let cfg: Config = Default::default();
let pwm = Pwm::new_input(p.PWM_CH2, p.PIN_5, InputMode::RisingEdge, cfg);
let mut ticker = Ticker::every(Duration::from_secs(1));
loop {
info!("Input frequency: {} Hz", pwm.counter());
pwm.set_counter(0);
ticker.next().await;
}
}

View File

@ -5,7 +5,7 @@
#![no_main]
#![feature(type_alias_impl_trait)]
#![feature(async_fn_in_trait)]
#![allow(incomplete_features)]
#![allow(stable_features, unknown_lints, async_fn_in_trait)]
use core::str::from_utf8;

View File

@ -5,7 +5,7 @@
#![no_main]
#![feature(type_alias_impl_trait)]
#![feature(async_fn_in_trait)]
#![allow(incomplete_features)]
#![allow(stable_features, unknown_lints, async_fn_in_trait)]
use core::str;

View File

@ -5,7 +5,7 @@
#![no_main]
#![feature(type_alias_impl_trait)]
#![feature(async_fn_in_trait)]
#![allow(incomplete_features)]
#![allow(stable_features, unknown_lints, async_fn_in_trait)]
use core::str::from_utf8;

View File

@ -5,8 +5,8 @@ version = "0.1.0"
license = "MIT OR Apache-2.0"
[dependencies]
embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["log"] }
embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["arch-std", "executor-thread", "log", "nightly", "integrated-timers"] }
embassy-sync = { version = "0.4.0", path = "../../embassy-sync", features = ["log"] }
embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["arch-std", "executor-thread", "log", "nightly", "integrated-timers"] }
embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["log", "std", "nightly"] }
embassy-net = { version = "0.2.0", path = "../../embassy-net", features=[ "std", "nightly", "log", "medium-ethernet", "medium-ip", "tcp", "udp", "dns", "dhcpv4", "proto-ipv6"] }
embassy-net-tuntap = { version = "0.1.0", path = "../../embassy-net-tuntap" }
@ -24,7 +24,7 @@ nix = "0.26.2"
clap = { version = "3.0.0-beta.5", features = ["derive"] }
rand_core = { version = "0.6.3", features = ["std"] }
heapless = { version = "0.7.5", default-features = false }
static_cell = { version = "1.1", features = ["nightly"]}
static_cell = { version = "2", features = ["nightly"]}
[profile.release]
debug = 2

View File

@ -8,7 +8,8 @@
//! nc 192.168.7.10 1234
#![feature(type_alias_impl_trait)]
#![feature(async_fn_in_trait)]
#![feature(async_fn_in_trait, impl_trait_projections)]
#![allow(stable_features, unknown_lints, async_fn_in_trait)]
#[path = "../serial_port.rs"]
mod serial_port;

View File

@ -7,8 +7,8 @@ license = "MIT OR Apache-2.0"
[dependencies]
# Change stm32c031c6 to your chip name, if necessary.
embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "time-driver-any", "stm32c031c6", "memory-x", "unstable-pac", "exti"] }
embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] }
embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
embassy-sync = { version = "0.4.0", path = "../../embassy-sync", features = ["defmt"] }
embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
defmt = "0.3"

View File

@ -14,10 +14,11 @@ cortex-m-rt = "0.7.0"
defmt = "0.3"
defmt-rtt = "0.4"
panic-probe = "0.3"
embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] }
embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] }
embassy-sync = { version = "0.4.0", path = "../../embassy-sync", features = ["defmt"] }
embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] }
embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
static_cell = { version = "1.1", features = ["nightly"]}
static_cell = { version = "2", features = ["nightly"]}
portable-atomic = { version = "1.5", features = ["unsafe-assume-single-core"] }
[profile.release]
debug = 2

View File

@ -7,8 +7,8 @@ license = "MIT OR Apache-2.0"
[dependencies]
# Change stm32f103c8 to your chip name, if necessary.
embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f103c8", "unstable-pac", "memory-x", "time-driver-any", "unstable-traits" ] }
embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] }
embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
embassy-sync = { version = "0.4.0", path = "../../embassy-sync", features = ["defmt"] }
embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }

View File

@ -7,8 +7,8 @@ license = "MIT OR Apache-2.0"
[dependencies]
# Change stm32f207zg to your chip name, if necessary.
embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f207zg", "unstable-pac", "memory-x", "time-driver-any", "exti"] }
embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] }
embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
embassy-sync = { version = "0.4.0", path = "../../embassy-sync", features = ["defmt"] }
embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
defmt = "0.3"

View File

@ -7,8 +7,8 @@ license = "MIT OR Apache-2.0"
[dependencies]
# Change stm32f303ze to your chip name, if necessary.
embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f303ze", "unstable-pac", "memory-x", "time-driver-any", "exti"] }
embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] }
embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] }
embassy-sync = { version = "0.4.0", path = "../../embassy-sync", features = ["defmt"] }
embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] }
embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
@ -24,7 +24,7 @@ futures = { version = "0.3.17", default-features = false, features = ["async-awa
heapless = { version = "0.7.5", default-features = false }
nb = "1.0.0"
embedded-storage = "0.3.0"
static_cell = { version = "1.1", features = ["nightly"]}
static_cell = { version = "2", features = ["nightly"]}
[profile.release]
debug = 2

View File

@ -5,8 +5,8 @@ version = "0.1.0"
license = "MIT OR Apache-2.0"
[dependencies]
embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] }
embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] }
embassy-sync = { version = "0.4.0", path = "../../embassy-sync", features = ["defmt"] }
embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] }
embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f334r8", "unstable-pac", "memory-x", "time-driver-any", "exti"] }
embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
@ -23,4 +23,4 @@ futures = { version = "0.3.17", default-features = false, features = ["async-awa
heapless = { version = "0.7.5", default-features = false }
nb = "1.0.0"
embedded-storage = "0.3.0"
static_cell = { version = "1.1", features = ["nightly"]}
static_cell = { version = "2", features = ["nightly"]}

View File

@ -7,8 +7,8 @@ license = "MIT OR Apache-2.0"
[dependencies]
# Change stm32f429zi to your chip name, if necessary.
embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "unstable-traits", "defmt", "stm32f429zi", "unstable-pac", "memory-x", "time-driver-any", "exti", "embedded-sdmmc", "chrono"] }
embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] }
embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] }
embassy-sync = { version = "0.4.0", path = "../../embassy-sync", features = ["defmt"] }
embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] }
embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] }
embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "nightly"] }
@ -27,7 +27,7 @@ heapless = { version = "0.7.5", default-features = false }
nb = "1.0.0"
embedded-storage = "0.3.0"
micromath = "2.0.0"
static_cell = { version = "1.1", features = ["nightly"]}
static_cell = { version = "2", features = ["nightly"]}
chrono = { version = "^0.4", default-features = false}
[profile.release]

View File

@ -7,8 +7,8 @@ license = "MIT OR Apache-2.0"
[dependencies]
# Change stm32f767zi to your chip name, if necessary.
embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f767zi", "memory-x", "unstable-pac", "time-driver-any", "exti"] }
embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] }
embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
embassy-sync = { version = "0.4.0", path = "../../embassy-sync", features = ["defmt"] }
embassy-executor = { version = "0.3.1", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
embassy-time = { version = "0.1.5", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet"] }
embedded-io-async = { version = "0.6.0" }
@ -27,7 +27,7 @@ nb = "1.0.0"
rand_core = "0.6.3"
critical-section = "1.1"
embedded-storage = "0.3.0"
static_cell = { version = "1.1", features = ["nightly"]}
static_cell = { version = "2", features = ["nightly"]}
[profile.release]
debug = 2

Some files were not shown because too many files have changed in this diff Show More