for Vbat {
fn channel(&self) -> u8 {
18
}
@@ -164,21 +183,19 @@ where
{
pub fn new(_peri: impl Peripheral + 'd, delay: &mut impl DelayUs) -> Self {
into_ref!(_peri);
- enable();
+ T::enable();
+ T::reset();
- let presc = unsafe { Prescaler::from_pclk2(crate::rcc::get_freqs().apb2) };
+ let presc = Prescaler::from_pclk2(T::frequency());
unsafe {
T::common_regs().ccr().modify(|w| w.set_adcpre(presc.adcpre()));
- }
- unsafe {
- // disable before config is set
T::regs().cr2().modify(|reg| {
- reg.set_adon(crate::pac::adc::vals::Adon::DISABLED);
+ reg.set_adon(crate::pac::adc::vals::Adon::ENABLED);
});
}
- delay.delay_us(20); // TODO?
+ delay.delay_us(ADC_POWERUP_TIME_US);
Self {
sample_time: Default::default(),
@@ -208,6 +225,45 @@ where
((u32::from(sample) * self.vref_mv) / self.resolution.to_max_count()) as u16
}
+ /// Enables internal voltage reference and returns [VrefInt], which can be used in
+ /// [Adc::read_internal()] to perform conversion.
+ pub fn enable_vrefint(&self) -> VrefInt {
+ unsafe {
+ T::common_regs().ccr().modify(|reg| {
+ reg.set_tsvrefe(crate::pac::adccommon::vals::Tsvrefe::ENABLED);
+ });
+ }
+
+ VrefInt {}
+ }
+
+ /// Enables internal temperature sensor and returns [Temperature], which can be used in
+ /// [Adc::read_internal()] to perform conversion.
+ ///
+ /// On STM32F42 and STM32F43 this can not be used together with [Vbat]. If both are enabled,
+ /// temperature sensor will return vbat value.
+ pub fn enable_temperature(&self) -> Temperature {
+ unsafe {
+ T::common_regs().ccr().modify(|reg| {
+ reg.set_tsvrefe(crate::pac::adccommon::vals::Tsvrefe::ENABLED);
+ });
+ }
+
+ Temperature {}
+ }
+
+ /// Enables vbat input and returns [Vbat], which can be used in
+ /// [Adc::read_internal()] to perform conversion.
+ pub fn enable_vbat(&self) -> Vbat {
+ unsafe {
+ T::common_regs().ccr().modify(|reg| {
+ reg.set_vbate(crate::pac::adccommon::vals::Vbate::ENABLED);
+ });
+ }
+
+ Vbat {}
+ }
+
/// Perform a single conversion.
fn convert(&mut self) -> u16 {
unsafe {
@@ -238,44 +294,31 @@ where
P: crate::gpio::sealed::Pin,
{
unsafe {
- // dissable ADC
- T::regs().cr2().modify(|reg| {
- reg.set_swstart(false);
- });
- T::regs().cr2().modify(|reg| {
- reg.set_adon(crate::pac::adc::vals::Adon::DISABLED);
- });
-
pin.set_as_analog();
- // Configure ADC
- T::regs().cr1().modify(|reg| reg.set_res(self.resolution.res()));
-
- // Select channel
- T::regs().sqr3().write(|reg| reg.set_sq(0, pin.channel()));
-
- // Configure channel
- Self::set_channel_sample_time(pin.channel(), self.sample_time);
-
- // enable adc
- T::regs().cr2().modify(|reg| {
- reg.set_adon(crate::pac::adc::vals::Adon::ENABLED);
- });
-
- let val = self.convert();
-
- // dissable ADC
- T::regs().cr2().modify(|reg| {
- reg.set_swstart(false);
- });
- T::regs().cr2().modify(|reg| {
- reg.set_adon(crate::pac::adc::vals::Adon::DISABLED);
- });
-
- val
+ self.read_channel(pin.channel())
}
}
+ pub fn read_internal(&mut self, channel: &mut impl InternalChannel) -> u16 {
+ unsafe { self.read_channel(channel.channel()) }
+ }
+
+ unsafe fn read_channel(&mut self, channel: u8) -> u16 {
+ // Configure ADC
+ T::regs().cr1().modify(|reg| reg.set_res(self.resolution.res()));
+
+ // Select channel
+ T::regs().sqr3().write(|reg| reg.set_sq(0, channel));
+
+ // Configure channel
+ Self::set_channel_sample_time(channel, self.sample_time);
+
+ let val = self.convert();
+
+ val
+ }
+
unsafe fn set_channel_sample_time(ch: u8, sample_time: SampleTime) {
if ch <= 9 {
T::regs()
@@ -288,3 +331,9 @@ where
}
}
}
+
+impl<'d, T: Instance> Drop for Adc<'d, T> {
+ fn drop(&mut self) {
+ T::disable();
+ }
+}
diff --git a/embassy-stm32/src/adc/v4.rs b/embassy-stm32/src/adc/v4.rs
index d356d7b66..eda2b2a72 100644
--- a/embassy-stm32/src/adc/v4.rs
+++ b/embassy-stm32/src/adc/v4.rs
@@ -5,7 +5,7 @@ use embedded_hal_02::blocking::delay::DelayUs;
use pac::adc::vals::{Adcaldif, Boost, Difsel, Exten, Pcsel};
use pac::adccommon::vals::Presc;
-use super::{AdcPin, Instance};
+use super::{AdcPin, Instance, InternalChannel};
use crate::time::Hertz;
use crate::{pac, Peripheral};
@@ -50,18 +50,10 @@ impl Resolution {
}
}
-pub trait InternalChannel: sealed::InternalChannel {}
-
-mod sealed {
- pub trait InternalChannel {
- fn channel(&self) -> u8;
- }
-}
-
// NOTE: Vrefint/Temperature/Vbat are only available on ADC3 on H7, this currently cannot be modeled with stm32-data, so these are available from the software on all ADCs
pub struct VrefInt;
impl InternalChannel for VrefInt {}
-impl sealed::InternalChannel for VrefInt {
+impl super::sealed::InternalChannel for VrefInt {
fn channel(&self) -> u8 {
19
}
@@ -69,7 +61,7 @@ impl sealed::InternalChannel for VrefInt {
pub struct Temperature;
impl InternalChannel for Temperature {}
-impl sealed::InternalChannel for Temperature {
+impl super::sealed::InternalChannel for Temperature {
fn channel(&self) -> u8 {
18
}
@@ -77,7 +69,7 @@ impl sealed::InternalChannel for Temperature {
pub struct Vbat;
impl InternalChannel for Vbat {}
-impl sealed::InternalChannel for Vbat {
+impl super::sealed::InternalChannel for Vbat {
fn channel(&self) -> u8 {
// TODO this should be 14 for H7a/b/35
17
diff --git a/embassy-stm32/src/flash/h7.rs b/embassy-stm32/src/flash/h7.rs
index 7ce0ac776..3f2129de8 100644
--- a/embassy-stm32/src/flash/h7.rs
+++ b/embassy-stm32/src/flash/h7.rs
@@ -39,6 +39,10 @@ pub(crate) unsafe fn blocking_write(offset: u32, buf: &[u8]) -> Result<(), Error
w.set_psize(2); // 32 bits at once
});
+ cortex_m::asm::isb();
+ cortex_m::asm::dsb();
+ atomic_polyfill::fence(atomic_polyfill::Ordering::SeqCst);
+
let ret = {
let mut ret: Result<(), Error> = Ok(());
let mut offset = offset;
@@ -64,6 +68,10 @@ pub(crate) unsafe fn blocking_write(offset: u32, buf: &[u8]) -> Result<(), Error
bank.cr().write(|w| w.set_pg(false));
+ cortex_m::asm::isb();
+ cortex_m::asm::dsb();
+ atomic_polyfill::fence(atomic_polyfill::Ordering::SeqCst);
+
ret
}
diff --git a/embassy-stm32/src/flash/mod.rs b/embassy-stm32/src/flash/mod.rs
index 5258c9b04..988cf9fae 100644
--- a/embassy-stm32/src/flash/mod.rs
+++ b/embassy-stm32/src/flash/mod.rs
@@ -23,17 +23,6 @@ impl<'d> Flash<'d> {
Self { _inner: p }
}
- pub fn unlock(p: impl Peripheral + 'd) -> Self {
- let flash = Self::new(p);
-
- unsafe { family::unlock() };
- flash
- }
-
- pub fn lock(&mut self) {
- unsafe { family::lock() };
- }
-
pub fn blocking_read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Error> {
let offset = FLASH_BASE as u32 + offset;
if offset as usize >= FLASH_END || offset as usize + bytes.len() > FLASH_END {
@@ -57,7 +46,12 @@ impl<'d> Flash<'d> {
self.clear_all_err();
- unsafe { family::blocking_write(offset, buf) }
+ unsafe {
+ family::unlock();
+ let res = family::blocking_write(offset, buf);
+ family::lock();
+ res
+ }
}
pub fn blocking_erase(&mut self, from: u32, to: u32) -> Result<(), Error> {
@@ -72,7 +66,12 @@ impl<'d> Flash<'d> {
self.clear_all_err();
- unsafe { family::blocking_erase(from, to) }
+ unsafe {
+ family::unlock();
+ let res = family::blocking_erase(from, to);
+ family::lock();
+ res
+ }
}
fn clear_all_err(&mut self) {
@@ -82,7 +81,7 @@ impl<'d> Flash<'d> {
impl Drop for Flash<'_> {
fn drop(&mut self) {
- self.lock();
+ unsafe { family::lock() };
}
}
diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs
index 22de6d180..074061218 100644
--- a/embassy-stm32/src/usart/mod.rs
+++ b/embassy-stm32/src/usart/mod.rs
@@ -160,6 +160,30 @@ impl<'d, T: BasicInstance, RxDma> UartRx<'d, T, RxDma> {
Ok(())
}
+ pub fn nb_read(&mut self) -> Result> {
+ let r = T::regs();
+ unsafe {
+ let sr = sr(r).read();
+ if sr.pe() {
+ rdr(r).read_volatile();
+ Err(nb::Error::Other(Error::Parity))
+ } else if sr.fe() {
+ rdr(r).read_volatile();
+ Err(nb::Error::Other(Error::Framing))
+ } else if sr.ne() {
+ rdr(r).read_volatile();
+ Err(nb::Error::Other(Error::Noise))
+ } else if sr.ore() {
+ rdr(r).read_volatile();
+ Err(nb::Error::Other(Error::Overrun))
+ } else if sr.rxne() {
+ Ok(rdr(r).read_volatile())
+ } else {
+ Err(nb::Error::WouldBlock)
+ }
+ }
+ }
+
pub fn blocking_read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
unsafe {
let r = T::regs();
@@ -285,6 +309,10 @@ impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
self.rx.read(buffer).await
}
+ pub fn nb_read(&mut self) -> Result> {
+ self.rx.nb_read()
+ }
+
pub fn blocking_read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
self.rx.blocking_read(buffer)
}
@@ -303,27 +331,7 @@ mod eh02 {
impl<'d, T: BasicInstance, RxDma> embedded_hal_02::serial::Read for UartRx<'d, T, RxDma> {
type Error = Error;
fn read(&mut self) -> Result> {
- let r = T::regs();
- unsafe {
- let sr = sr(r).read();
- if sr.pe() {
- rdr(r).read_volatile();
- Err(nb::Error::Other(Error::Parity))
- } else if sr.fe() {
- rdr(r).read_volatile();
- Err(nb::Error::Other(Error::Framing))
- } else if sr.ne() {
- rdr(r).read_volatile();
- Err(nb::Error::Other(Error::Noise))
- } else if sr.ore() {
- rdr(r).read_volatile();
- Err(nb::Error::Other(Error::Overrun))
- } else if sr.rxne() {
- Ok(rdr(r).read_volatile())
- } else {
- Err(nb::Error::WouldBlock)
- }
- }
+ self.nb_read()
}
}
@@ -340,7 +348,7 @@ mod eh02 {
impl<'d, T: BasicInstance, TxDma, RxDma> embedded_hal_02::serial::Read for Uart<'d, T, TxDma, RxDma> {
type Error = Error;
fn read(&mut self) -> Result> {
- embedded_hal_02::serial::Read::read(&mut self.rx)
+ self.nb_read()
}
}
@@ -381,6 +389,58 @@ mod eh1 {
impl<'d, T: BasicInstance, RxDma> embedded_hal_1::serial::ErrorType for UartRx<'d, T, RxDma> {
type Error = Error;
}
+
+ impl<'d, T: BasicInstance, RxDma> embedded_hal_nb::serial::Read for UartRx<'d, T, RxDma> {
+ fn read(&mut self) -> nb::Result {
+ self.nb_read()
+ }
+ }
+
+ impl<'d, T: BasicInstance, TxDma> embedded_hal_1::serial::Write for UartTx<'d, T, TxDma> {
+ fn write(&mut self, buffer: &[u8]) -> Result<(), Self::Error> {
+ self.blocking_write(buffer)
+ }
+
+ fn flush(&mut self) -> Result<(), Self::Error> {
+ self.blocking_flush()
+ }
+ }
+
+ impl<'d, T: BasicInstance, TxDma> embedded_hal_nb::serial::Write for UartTx<'d, T, TxDma> {
+ fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> {
+ self.blocking_write(&[char]).map_err(nb::Error::Other)
+ }
+
+ fn flush(&mut self) -> nb::Result<(), Self::Error> {
+ self.blocking_flush().map_err(nb::Error::Other)
+ }
+ }
+
+ impl<'d, T: BasicInstance, TxDma, RxDma> embedded_hal_nb::serial::Read for Uart<'d, T, TxDma, RxDma> {
+ fn read(&mut self) -> Result> {
+ self.nb_read()
+ }
+ }
+
+ impl<'d, T: BasicInstance, TxDma, RxDma> embedded_hal_1::serial::Write for Uart<'d, T, TxDma, RxDma> {
+ fn write(&mut self, buffer: &[u8]) -> Result<(), Self::Error> {
+ self.blocking_write(buffer)
+ }
+
+ fn flush(&mut self) -> Result<(), Self::Error> {
+ self.blocking_flush()
+ }
+ }
+
+ impl<'d, T: BasicInstance, TxDma, RxDma> embedded_hal_nb::serial::Write for Uart<'d, T, TxDma, RxDma> {
+ fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> {
+ self.blocking_write(&[char]).map_err(nb::Error::Other)
+ }
+
+ fn flush(&mut self) -> nb::Result<(), Self::Error> {
+ self.blocking_flush().map_err(nb::Error::Other)
+ }
+ }
}
#[cfg(all(
diff --git a/embassy-sync/Cargo.toml b/embassy-sync/Cargo.toml
index 14ab1d003..584d5ba9f 100644
--- a/embassy-sync/Cargo.toml
+++ b/embassy-sync/Cargo.toml
@@ -2,6 +2,16 @@
name = "embassy-sync"
version = "0.1.0"
edition = "2021"
+description = "no-std, no-alloc synchronization primitives with async support"
+repository = "https://github.com/embassy-rs/embassy"
+readme = "README.md"
+license = "MIT OR Apache-2.0"
+categories = [
+ "embedded",
+ "no-std",
+ "concurrency",
+ "asynchronous",
+]
[package.metadata.embassy_docs]
src_base = "https://github.com/embassy-rs/embassy/blob/embassy-sync-v$VERSION/embassy-sync/src/"
diff --git a/embassy-sync/README.md b/embassy-sync/README.md
index 106295c0d..cc65cf6ef 100644
--- a/embassy-sync/README.md
+++ b/embassy-sync/README.md
@@ -1,12 +1,32 @@
# embassy-sync
-Synchronization primitives and data structures with an async API:
+An [Embassy](https://embassy.dev) project.
+
+Synchronization primitives and data structures with async support:
- [`Channel`](channel::Channel) - A Multiple Producer Multiple Consumer (MPMC) channel. Each message is only received by a single consumer.
- [`PubSubChannel`](pubsub::PubSubChannel) - A broadcast channel (publish-subscribe) channel. Each message is received by all consumers.
- [`Signal`](signal::Signal) - Signalling latest value to a single consumer.
-- [`Mutex`](mutex::Mutex) - A Mutex for synchronizing state between asynchronous tasks.
+- [`Mutex`](mutex::Mutex) - Mutex for synchronizing state between asynchronous tasks.
- [`Pipe`](pipe::Pipe) - Byte stream implementing `embedded_io` traits.
- [`WakerRegistration`](waitqueue::WakerRegistration) - Utility to register and wake a `Waker`.
- [`AtomicWaker`](waitqueue::AtomicWaker) - A variant of `WakerRegistration` accessible using a non-mut API.
- [`MultiWakerRegistration`](waitqueue::MultiWakerRegistration) - Utility registering and waking multiple `Waker`'s.
+
+## Interoperability
+
+Futures from this crate can run on any executor.
+
+## Minimum supported Rust version (MSRV)
+
+Embassy is guaranteed to compile on the latest stable Rust version at the time of release. It might compile with older versions but that may change in any new patch release.
+
+## License
+
+This work is licensed under either of
+
+- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or
+ )
+- MIT license ([LICENSE-MIT](LICENSE-MIT) or )
+
+at your option.
diff --git a/embassy-sync/src/pubsub/mod.rs b/embassy-sync/src/pubsub/mod.rs
index 62a9e4763..faaf99dc6 100644
--- a/embassy-sync/src/pubsub/mod.rs
+++ b/embassy-sync/src/pubsub/mod.rs
@@ -192,6 +192,10 @@ impl u64 {
+ self.inner.lock(|s| s.borrow().next_message_id - next_message_id)
+ }
+
fn publish_with_context(&self, message: T, cx: Option<&mut Context<'_>>) -> Result<(), T> {
self.inner.lock(|s| {
let mut s = s.borrow_mut();
@@ -217,6 +221,13 @@ impl usize {
+ self.inner.lock(|s| {
+ let s = s.borrow();
+ s.queue.capacity() - s.queue.len()
+ })
+ }
+
fn unregister_subscriber(&self, subscriber_next_message_id: u64) {
self.inner.lock(|s| {
let mut s = s.borrow_mut();
@@ -388,6 +399,10 @@ pub trait PubSubBehavior {
/// If the message is not yet present and a context is given, then its waker is registered in the subsriber wakers.
fn get_message_with_context(&self, next_message_id: &mut u64, cx: Option<&mut Context<'_>>) -> Poll>;
+ /// Get the amount of messages that are between the given the next_message_id and the most recent message.
+ /// This is not necessarily the amount of messages a subscriber can still received as it may have lagged.
+ fn available(&self, next_message_id: u64) -> u64;
+
/// Try to publish a message to the queue.
///
/// If the queue is full and a context is given, then its waker is registered in the publisher wakers.
@@ -396,6 +411,9 @@ pub trait PubSubBehavior {
/// Publish a message immediately
fn publish_immediate(&self, message: T);
+ /// The amount of messages that can still be published without having to wait or without having to lag the subscribers
+ fn space(&self) -> usize;
+
/// Let the channel know that a subscriber has dropped
fn unregister_subscriber(&self, subscriber_next_message_id: u64);
@@ -539,4 +557,59 @@ mod tests {
drop(sub0);
}
+
+ #[futures_test::test]
+ async fn correct_available() {
+ let channel = PubSubChannel::::new();
+
+ let sub0 = channel.subscriber().unwrap();
+ let mut sub1 = channel.subscriber().unwrap();
+ let pub0 = channel.publisher().unwrap();
+
+ assert_eq!(sub0.available(), 0);
+ assert_eq!(sub1.available(), 0);
+
+ pub0.publish(42).await;
+
+ assert_eq!(sub0.available(), 1);
+ assert_eq!(sub1.available(), 1);
+
+ sub1.next_message().await;
+
+ assert_eq!(sub1.available(), 0);
+
+ pub0.publish(42).await;
+
+ assert_eq!(sub0.available(), 2);
+ assert_eq!(sub1.available(), 1);
+ }
+
+ #[futures_test::test]
+ async fn correct_space() {
+ let channel = PubSubChannel::::new();
+
+ let mut sub0 = channel.subscriber().unwrap();
+ let mut sub1 = channel.subscriber().unwrap();
+ let pub0 = channel.publisher().unwrap();
+
+ assert_eq!(pub0.space(), 4);
+
+ pub0.publish(42).await;
+
+ assert_eq!(pub0.space(), 3);
+
+ pub0.publish(42).await;
+
+ assert_eq!(pub0.space(), 2);
+
+ sub0.next_message().await;
+ sub0.next_message().await;
+
+ assert_eq!(pub0.space(), 2);
+
+ sub1.next_message().await;
+ assert_eq!(pub0.space(), 3);
+ sub1.next_message().await;
+ assert_eq!(pub0.space(), 4);
+ }
}
diff --git a/embassy-sync/src/pubsub/publisher.rs b/embassy-sync/src/pubsub/publisher.rs
index 705797f60..e1edc9eb9 100644
--- a/embassy-sync/src/pubsub/publisher.rs
+++ b/embassy-sync/src/pubsub/publisher.rs
@@ -42,6 +42,14 @@ impl<'a, PSB: PubSubBehavior + ?Sized, T: Clone> Pub<'a, PSB, T> {
pub fn try_publish(&self, message: T) -> Result<(), T> {
self.channel.publish_with_context(message, None)
}
+
+ /// The amount of messages that can still be published without having to wait or without having to lag the subscribers
+ ///
+ /// *Note: In the time between checking this and a publish action, other publishers may have had time to publish something.
+ /// So checking doesn't give any guarantees.*
+ pub fn space(&self) -> usize {
+ self.channel.space()
+ }
}
impl<'a, PSB: PubSubBehavior + ?Sized, T: Clone> Drop for Pub<'a, PSB, T> {
@@ -115,6 +123,14 @@ impl<'a, PSB: PubSubBehavior + ?Sized, T: Clone> ImmediatePub<'a, PSB, T> {
pub fn try_publish(&self, message: T) -> Result<(), T> {
self.channel.publish_with_context(message, None)
}
+
+ /// The amount of messages that can still be published without having to wait or without having to lag the subscribers
+ ///
+ /// *Note: In the time between checking this and a publish action, other publishers may have had time to publish something.
+ /// So checking doesn't give any guarantees.*
+ pub fn space(&self) -> usize {
+ self.channel.space()
+ }
}
/// An immediate publisher that holds a dynamic reference to the channel
@@ -158,6 +174,7 @@ impl<'a, M: RawMutex, T: Clone, const CAP: usize, const SUBS: usize, const PUBS:
}
/// Future for the publisher wait action
+#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct PublisherWaitFuture<'s, 'a, PSB: PubSubBehavior + ?Sized, T: Clone> {
/// The message we need to publish
message: Option,
diff --git a/embassy-sync/src/pubsub/subscriber.rs b/embassy-sync/src/pubsub/subscriber.rs
index b9a2cbe18..f420a75f0 100644
--- a/embassy-sync/src/pubsub/subscriber.rs
+++ b/embassy-sync/src/pubsub/subscriber.rs
@@ -64,6 +64,11 @@ impl<'a, PSB: PubSubBehavior + ?Sized, T: Clone> Sub<'a, PSB, T> {
}
}
}
+
+ /// The amount of messages this subscriber hasn't received yet
+ pub fn available(&self) -> u64 {
+ self.channel.available(self.next_message_id)
+ }
}
impl<'a, PSB: PubSubBehavior + ?Sized, T: Clone> Drop for Sub<'a, PSB, T> {
@@ -135,6 +140,7 @@ impl<'a, M: RawMutex, T: Clone, const CAP: usize, const SUBS: usize, const PUBS:
}
/// Future for the subscriber wait action
+#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct SubscriberWaitFuture<'s, 'a, PSB: PubSubBehavior + ?Sized, T: Clone> {
subscriber: &'s mut Sub<'a, PSB, T>,
}
diff --git a/embassy-time/Cargo.toml b/embassy-time/Cargo.toml
index c3b361b8a..c51a71d01 100644
--- a/embassy-time/Cargo.toml
+++ b/embassy-time/Cargo.toml
@@ -2,6 +2,7 @@
name = "embassy-time"
version = "0.1.0"
edition = "2021"
+license = "MIT OR Apache-2.0"
[package.metadata.embassy_docs]
diff --git a/embassy-usb-driver/Cargo.toml b/embassy-usb-driver/Cargo.toml
index b525df337..d22bf7d72 100644
--- a/embassy-usb-driver/Cargo.toml
+++ b/embassy-usb-driver/Cargo.toml
@@ -2,6 +2,7 @@
name = "embassy-usb-driver"
version = "0.1.0"
edition = "2021"
+license = "MIT OR Apache-2.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -13,4 +14,4 @@ target = "thumbv7em-none-eabi"
[dependencies]
defmt = { version = "0.3", optional = true }
-log = { version = "0.4.14", optional = true }
\ No newline at end of file
+log = { version = "0.4.14", optional = true }
diff --git a/embassy-usb-driver/src/lib.rs b/embassy-usb-driver/src/lib.rs
index fc29786fc..931e9c318 100644
--- a/embassy-usb-driver/src/lib.rs
+++ b/embassy-usb-driver/src/lib.rs
@@ -54,12 +54,16 @@ impl From for u8 {
}
impl EndpointAddress {
- const INBITS: u8 = Direction::In as u8;
+ const INBITS: u8 = 0x80;
/// Constructs a new EndpointAddress with the given index and direction.
#[inline]
pub fn from_parts(index: usize, dir: Direction) -> Self {
- EndpointAddress(index as u8 | dir as u8)
+ let dir_u8 = match dir {
+ Direction::Out => 0x00,
+ Direction::In => Self::INBITS,
+ };
+ EndpointAddress(index as u8 | dir_u8)
}
/// Gets the direction part of the address.
diff --git a/embassy-usb/Cargo.toml b/embassy-usb/Cargo.toml
index aad54dbaf..b59ba8a22 100644
--- a/embassy-usb/Cargo.toml
+++ b/embassy-usb/Cargo.toml
@@ -2,11 +2,12 @@
name = "embassy-usb"
version = "0.1.0"
edition = "2021"
+license = "MIT OR Apache-2.0"
[package.metadata.embassy_docs]
src_base = "https://github.com/embassy-rs/embassy/blob/embassy-usb-v$VERSION/embassy-usb/src/"
src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-usb/src/"
-features = ["defmt"]
+features = ["defmt", "usbd-hid"]
target = "thumbv7em-none-eabi"
[features]
diff --git a/examples/boot/application/nrf/Cargo.toml b/examples/boot/application/nrf/Cargo.toml
index b9ff92578..a5d82b601 100644
--- a/examples/boot/application/nrf/Cargo.toml
+++ b/examples/boot/application/nrf/Cargo.toml
@@ -2,6 +2,7 @@
edition = "2021"
name = "embassy-boot-nrf-examples"
version = "0.1.0"
+license = "MIT OR Apache-2.0"
[dependencies]
embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync" }
diff --git a/examples/boot/application/stm32f3/Cargo.toml b/examples/boot/application/stm32f3/Cargo.toml
index ce1e6fe4a..3a1843562 100644
--- a/examples/boot/application/stm32f3/Cargo.toml
+++ b/examples/boot/application/stm32f3/Cargo.toml
@@ -2,6 +2,7 @@
edition = "2021"
name = "embassy-boot-stm32f3-examples"
version = "0.1.0"
+license = "MIT OR Apache-2.0"
[dependencies]
embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync", features = ["defmt"] }
diff --git a/examples/boot/application/stm32f3/src/bin/a.rs b/examples/boot/application/stm32f3/src/bin/a.rs
index fdbd5ab99..d92d59b29 100644
--- a/examples/boot/application/stm32f3/src/bin/a.rs
+++ b/examples/boot/application/stm32f3/src/bin/a.rs
@@ -17,7 +17,7 @@ static APP_B: &[u8] = include_bytes!("../../b.bin");
#[embassy_executor::main]
async fn main(_spawner: Spawner) {
let p = embassy_stm32::init(Default::default());
- let flash = Flash::unlock(p.FLASH);
+ let flash = Flash::new(p.FLASH);
let mut flash = BlockingAsync::new(flash);
let button = Input::new(p.PC13, Pull::Up);
diff --git a/examples/boot/application/stm32f7/Cargo.toml b/examples/boot/application/stm32f7/Cargo.toml
index 2fc7ae834..8d9c4490e 100644
--- a/examples/boot/application/stm32f7/Cargo.toml
+++ b/examples/boot/application/stm32f7/Cargo.toml
@@ -2,6 +2,7 @@
edition = "2021"
name = "embassy-boot-stm32f7-examples"
version = "0.1.0"
+license = "MIT OR Apache-2.0"
[dependencies]
embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync", features = ["defmt"] }
diff --git a/examples/boot/application/stm32f7/src/bin/a.rs b/examples/boot/application/stm32f7/src/bin/a.rs
index 77b897b0f..79ab80e09 100644
--- a/examples/boot/application/stm32f7/src/bin/a.rs
+++ b/examples/boot/application/stm32f7/src/bin/a.rs
@@ -16,7 +16,7 @@ static APP_B: &[u8] = include_bytes!("../../b.bin");
#[embassy_executor::main]
async fn main(_spawner: Spawner) {
let p = embassy_stm32::init(Default::default());
- let mut flash = Flash::unlock(p.FLASH);
+ let mut flash = Flash::new(p.FLASH);
let button = Input::new(p.PC13, Pull::Down);
let mut button = ExtiInput::new(button, p.EXTI13);
diff --git a/examples/boot/application/stm32h7/Cargo.toml b/examples/boot/application/stm32h7/Cargo.toml
index fd809714a..b4314aa72 100644
--- a/examples/boot/application/stm32h7/Cargo.toml
+++ b/examples/boot/application/stm32h7/Cargo.toml
@@ -2,6 +2,7 @@
edition = "2021"
name = "embassy-boot-stm32h7-examples"
version = "0.1.0"
+license = "MIT OR Apache-2.0"
[dependencies]
embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync" }
diff --git a/examples/boot/application/stm32h7/src/bin/a.rs b/examples/boot/application/stm32h7/src/bin/a.rs
index 0fe598a5d..8b452be34 100644
--- a/examples/boot/application/stm32h7/src/bin/a.rs
+++ b/examples/boot/application/stm32h7/src/bin/a.rs
@@ -16,7 +16,7 @@ static APP_B: &[u8] = include_bytes!("../../b.bin");
#[embassy_executor::main]
async fn main(_spawner: Spawner) {
let p = embassy_stm32::init(Default::default());
- let mut flash = Flash::unlock(p.FLASH);
+ let mut flash = Flash::new(p.FLASH);
let button = Input::new(p.PC13, Pull::Down);
let mut button = ExtiInput::new(button, p.EXTI13);
diff --git a/examples/boot/application/stm32l0/Cargo.toml b/examples/boot/application/stm32l0/Cargo.toml
index 470eca52a..a17d336a6 100644
--- a/examples/boot/application/stm32l0/Cargo.toml
+++ b/examples/boot/application/stm32l0/Cargo.toml
@@ -2,6 +2,7 @@
edition = "2021"
name = "embassy-boot-stm32l0-examples"
version = "0.1.0"
+license = "MIT OR Apache-2.0"
[dependencies]
embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync", features = ["defmt"] }
diff --git a/examples/boot/application/stm32l0/src/bin/a.rs b/examples/boot/application/stm32l0/src/bin/a.rs
index f0b0b80e3..59ca34386 100644
--- a/examples/boot/application/stm32l0/src/bin/a.rs
+++ b/examples/boot/application/stm32l0/src/bin/a.rs
@@ -18,7 +18,7 @@ static APP_B: &[u8] = include_bytes!("../../b.bin");
#[embassy_executor::main]
async fn main(_spawner: Spawner) {
let p = embassy_stm32::init(Default::default());
- let flash = Flash::unlock(p.FLASH);
+ let flash = Flash::new(p.FLASH);
let mut flash = BlockingAsync::new(flash);
let button = Input::new(p.PB2, Pull::Up);
diff --git a/examples/boot/application/stm32l1/Cargo.toml b/examples/boot/application/stm32l1/Cargo.toml
index 2b4b29357..683f2c860 100644
--- a/examples/boot/application/stm32l1/Cargo.toml
+++ b/examples/boot/application/stm32l1/Cargo.toml
@@ -2,6 +2,7 @@
edition = "2021"
name = "embassy-boot-stm32l1-examples"
version = "0.1.0"
+license = "MIT OR Apache-2.0"
[dependencies]
embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync", features = ["defmt"] }
diff --git a/examples/boot/application/stm32l1/src/bin/a.rs b/examples/boot/application/stm32l1/src/bin/a.rs
index f0b0b80e3..59ca34386 100644
--- a/examples/boot/application/stm32l1/src/bin/a.rs
+++ b/examples/boot/application/stm32l1/src/bin/a.rs
@@ -18,7 +18,7 @@ static APP_B: &[u8] = include_bytes!("../../b.bin");
#[embassy_executor::main]
async fn main(_spawner: Spawner) {
let p = embassy_stm32::init(Default::default());
- let flash = Flash::unlock(p.FLASH);
+ let flash = Flash::new(p.FLASH);
let mut flash = BlockingAsync::new(flash);
let button = Input::new(p.PB2, Pull::Up);
diff --git a/examples/boot/application/stm32l4/Cargo.toml b/examples/boot/application/stm32l4/Cargo.toml
index 40bddd194..b879c0d76 100644
--- a/examples/boot/application/stm32l4/Cargo.toml
+++ b/examples/boot/application/stm32l4/Cargo.toml
@@ -2,6 +2,7 @@
edition = "2021"
name = "embassy-boot-stm32l4-examples"
version = "0.1.0"
+license = "MIT OR Apache-2.0"
[dependencies]
embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync", features = ["defmt"] }
diff --git a/examples/boot/application/stm32l4/src/bin/a.rs b/examples/boot/application/stm32l4/src/bin/a.rs
index 5119bad2e..6cddc6cc8 100644
--- a/examples/boot/application/stm32l4/src/bin/a.rs
+++ b/examples/boot/application/stm32l4/src/bin/a.rs
@@ -17,7 +17,7 @@ static APP_B: &[u8] = include_bytes!("../../b.bin");
#[embassy_executor::main]
async fn main(_spawner: Spawner) {
let p = embassy_stm32::init(Default::default());
- let flash = Flash::unlock(p.FLASH);
+ let flash = Flash::new(p.FLASH);
let mut flash = BlockingAsync::new(flash);
let button = Input::new(p.PC13, Pull::Up);
diff --git a/examples/boot/application/stm32wl/Cargo.toml b/examples/boot/application/stm32wl/Cargo.toml
index 5b4a61e8f..e3bc0e49c 100644
--- a/examples/boot/application/stm32wl/Cargo.toml
+++ b/examples/boot/application/stm32wl/Cargo.toml
@@ -2,6 +2,7 @@
edition = "2021"
name = "embassy-boot-stm32wl-examples"
version = "0.1.0"
+license = "MIT OR Apache-2.0"
[dependencies]
embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync", features = ["defmt"] }
diff --git a/examples/boot/application/stm32wl/src/bin/a.rs b/examples/boot/application/stm32wl/src/bin/a.rs
index faa650778..1ff47eddd 100644
--- a/examples/boot/application/stm32wl/src/bin/a.rs
+++ b/examples/boot/application/stm32wl/src/bin/a.rs
@@ -17,7 +17,7 @@ static APP_B: &[u8] = include_bytes!("../../b.bin");
#[embassy_executor::main]
async fn main(_spawner: Spawner) {
let p = embassy_stm32::init(Default::default());
- let flash = Flash::unlock(p.FLASH);
+ let flash = Flash::new(p.FLASH);
let mut flash = BlockingAsync::new(flash);
let button = Input::new(p.PA0, Pull::Up);
diff --git a/examples/boot/bootloader/nrf/Cargo.toml b/examples/boot/bootloader/nrf/Cargo.toml
index aa2a13ecb..b417a40d1 100644
--- a/examples/boot/bootloader/nrf/Cargo.toml
+++ b/examples/boot/bootloader/nrf/Cargo.toml
@@ -3,6 +3,7 @@ edition = "2021"
name = "nrf-bootloader-example"
version = "0.1.0"
description = "Bootloader for nRF chips"
+license = "MIT OR Apache-2.0"
[dependencies]
defmt = { version = "0.3", optional = true }
diff --git a/examples/boot/bootloader/stm32/Cargo.toml b/examples/boot/bootloader/stm32/Cargo.toml
index 491777103..4ddd1c99c 100644
--- a/examples/boot/bootloader/stm32/Cargo.toml
+++ b/examples/boot/bootloader/stm32/Cargo.toml
@@ -3,6 +3,7 @@ edition = "2021"
name = "stm32-bootloader-example"
version = "0.1.0"
description = "Example bootloader for STM32 chips"
+license = "MIT OR Apache-2.0"
[dependencies]
defmt = { version = "0.3", optional = true }
diff --git a/examples/boot/bootloader/stm32/src/main.rs b/examples/boot/bootloader/stm32/src/main.rs
index 294464d1c..4b17cd799 100644
--- a/examples/boot/bootloader/stm32/src/main.rs
+++ b/examples/boot/bootloader/stm32/src/main.rs
@@ -20,7 +20,7 @@ fn main() -> ! {
*/
let mut bl: BootLoader = BootLoader::default();
- let flash = Flash::unlock(p.FLASH);
+ let flash = Flash::new(p.FLASH);
let mut flash = BootFlash::<_, ERASE_SIZE, ERASE_VALUE>::new(flash);
let start = bl.prepare(&mut SingleFlashConfig::new(&mut flash));
core::mem::drop(flash);
diff --git a/examples/nrf-rtos-trace/Cargo.toml b/examples/nrf-rtos-trace/Cargo.toml
index 87c9f33f5..d8c24dfad 100644
--- a/examples/nrf-rtos-trace/Cargo.toml
+++ b/examples/nrf-rtos-trace/Cargo.toml
@@ -2,6 +2,7 @@
edition = "2021"
name = "embassy-nrf-rtos-trace-examples"
version = "0.1.0"
+license = "MIT OR Apache-2.0"
[features]
default = ["log", "nightly"]
diff --git a/examples/nrf/Cargo.toml b/examples/nrf/Cargo.toml
index a5d340c69..6949042e2 100644
--- a/examples/nrf/Cargo.toml
+++ b/examples/nrf/Cargo.toml
@@ -2,10 +2,12 @@
edition = "2021"
name = "embassy-nrf-examples"
version = "0.1.0"
+license = "MIT OR Apache-2.0"
[features]
default = ["nightly"]
-nightly = ["embassy-executor/nightly", "embassy-nrf/nightly", "embassy-net/nightly", "embassy-nrf/unstable-traits", "embassy-usb", "embedded-io/async", "embassy-net"]
+nightly = ["embassy-executor/nightly", "embassy-nrf/nightly", "embassy-net/nightly", "embassy-nrf/unstable-traits", "embassy-usb", "embedded-io/async", "embassy-net",
+ "embassy-lora", "lorawan-device", "lorawan"]
[dependencies]
embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
@@ -16,6 +18,10 @@ embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defm
embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "pool-16"], optional = true }
embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"], optional = true }
embedded-io = "0.3.0"
+embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["sx126x", "time", "defmt"], optional = true }
+
+lorawan-device = { version = "0.8.0", default-features = false, features = ["async"], optional = true }
+lorawan = { version = "0.7.1", default-features = false, features = ["default-crypto"], optional = true }
defmt = "0.3"
defmt-rtt = "0.3"
diff --git a/examples/nrf/src/bin/lora_p2p_report.rs b/examples/nrf/src/bin/lora_p2p_report.rs
new file mode 100644
index 000000000..d512b83f6
--- /dev/null
+++ b/examples/nrf/src/bin/lora_p2p_report.rs
@@ -0,0 +1,78 @@
+//! This example runs on the RAK4631 WisBlock, which has an nRF52840 MCU and Semtech Sx126x radio.
+//! Other nrf/sx126x combinations may work with appropriate pin modifications.
+//! It demonstates LORA P2P functionality in conjunction with example lora_p2p_sense.rs.
+#![no_std]
+#![no_main]
+#![macro_use]
+#![allow(dead_code)]
+#![feature(type_alias_impl_trait)]
+
+use defmt::*;
+use embassy_executor::Spawner;
+use embassy_lora::sx126x::*;
+use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pin as _, Pull};
+use embassy_nrf::{interrupt, spim};
+use embassy_time::{Duration, Timer};
+use lorawan_device::async_device::radio::{Bandwidth, CodingRate, PhyRxTx, RfConfig, SpreadingFactor};
+use {defmt_rtt as _, panic_probe as _};
+
+#[embassy_executor::main]
+async fn main(_spawner: Spawner) {
+ let p = embassy_nrf::init(Default::default());
+ let mut spi_config = spim::Config::default();
+ spi_config.frequency = spim::Frequency::M16;
+
+ let mut radio = {
+ let irq = interrupt::take!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1);
+ let spim = spim::Spim::new(p.TWISPI1, irq, p.P1_11, p.P1_13, p.P1_12, spi_config);
+
+ let cs = Output::new(p.P1_10.degrade(), Level::High, OutputDrive::Standard);
+ let reset = Output::new(p.P1_06.degrade(), Level::High, OutputDrive::Standard);
+ let dio1 = Input::new(p.P1_15.degrade(), Pull::Down);
+ let busy = Input::new(p.P1_14.degrade(), Pull::Down);
+ let antenna_rx = Output::new(p.P1_05.degrade(), Level::Low, OutputDrive::Standard);
+ let antenna_tx = Output::new(p.P1_07.degrade(), Level::Low, OutputDrive::Standard);
+
+ match Sx126xRadio::new(spim, cs, reset, antenna_rx, antenna_tx, dio1, busy, false).await {
+ Ok(r) => r,
+ Err(err) => {
+ info!("Sx126xRadio error = {}", err);
+ return;
+ }
+ }
+ };
+
+ let mut debug_indicator = Output::new(p.P1_03, Level::Low, OutputDrive::Standard);
+ let mut start_indicator = Output::new(p.P1_04, Level::Low, OutputDrive::Standard);
+
+ start_indicator.set_high();
+ Timer::after(Duration::from_secs(5)).await;
+ start_indicator.set_low();
+
+ loop {
+ let rf_config = RfConfig {
+ frequency: 903900000, // channel in Hz
+ bandwidth: Bandwidth::_250KHz,
+ spreading_factor: SpreadingFactor::_10,
+ coding_rate: CodingRate::_4_8,
+ };
+
+ let mut buffer = [00u8; 100];
+
+ // P2P receive
+ match radio.rx(rf_config, &mut buffer).await {
+ Ok((buffer_len, rx_quality)) => info!(
+ "RX received = {:?} with length = {} rssi = {} snr = {}",
+ &buffer[0..buffer_len],
+ buffer_len,
+ rx_quality.rssi(),
+ rx_quality.snr()
+ ),
+ Err(err) => info!("RX error = {}", err),
+ }
+
+ debug_indicator.set_high();
+ Timer::after(Duration::from_secs(2)).await;
+ debug_indicator.set_low();
+ }
+}
diff --git a/examples/nrf/src/bin/lora_p2p_sense.rs b/examples/nrf/src/bin/lora_p2p_sense.rs
new file mode 100644
index 000000000..b9768874b
--- /dev/null
+++ b/examples/nrf/src/bin/lora_p2p_sense.rs
@@ -0,0 +1,125 @@
+//! This example runs on the RAK4631 WisBlock, which has an nRF52840 MCU and Semtech Sx126x radio.
+//! Other nrf/sx126x combinations may work with appropriate pin modifications.
+//! It demonstates LORA P2P functionality in conjunction with example lora_p2p_report.rs.
+#![no_std]
+#![no_main]
+#![macro_use]
+#![feature(type_alias_impl_trait)]
+#![feature(alloc_error_handler)]
+#![allow(incomplete_features)]
+
+use defmt::*;
+use embassy_executor::Spawner;
+use embassy_lora::sx126x::*;
+use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pin as _, Pull};
+use embassy_nrf::{interrupt, spim};
+use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
+use embassy_sync::pubsub::{PubSubChannel, Publisher};
+use embassy_time::{Duration, Timer};
+use lorawan_device::async_device::radio::{Bandwidth, CodingRate, PhyRxTx, RfConfig, SpreadingFactor, TxConfig};
+use {defmt_rtt as _, panic_probe as _, panic_probe as _};
+
+// Message bus: queue of 2, 1 subscriber (Lora P2P), 2 publishers (temperature, motion detection)
+static MESSAGE_BUS: PubSubChannel = PubSubChannel::new();
+
+#[derive(Clone, defmt::Format)]
+enum Message {
+ Temperature(i32),
+ MotionDetected,
+}
+
+#[embassy_executor::task]
+async fn temperature_task(publisher: Publisher<'static, CriticalSectionRawMutex, Message, 2, 1, 2>) {
+ // Publish a fake temperature every 43 seconds, minimizing LORA traffic.
+ loop {
+ Timer::after(Duration::from_secs(43)).await;
+ publisher.publish(Message::Temperature(9)).await;
+ }
+}
+
+#[embassy_executor::task]
+async fn motion_detection_task(publisher: Publisher<'static, CriticalSectionRawMutex, Message, 2, 1, 2>) {
+ // Publish a fake motion detection every 79 seconds, minimizing LORA traffic.
+ loop {
+ Timer::after(Duration::from_secs(79)).await;
+ publisher.publish(Message::MotionDetected).await;
+ }
+}
+
+#[embassy_executor::main]
+async fn main(spawner: Spawner) {
+ let p = embassy_nrf::init(Default::default());
+ // set up to funnel temperature and motion detection events to the Lora Tx task
+ let mut lora_tx_subscriber = unwrap!(MESSAGE_BUS.subscriber());
+ let temperature_publisher = unwrap!(MESSAGE_BUS.publisher());
+ let motion_detection_publisher = unwrap!(MESSAGE_BUS.publisher());
+
+ let mut spi_config = spim::Config::default();
+ spi_config.frequency = spim::Frequency::M16;
+
+ let mut radio = {
+ let irq = interrupt::take!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1);
+ let spim = spim::Spim::new(p.TWISPI1, irq, p.P1_11, p.P1_13, p.P1_12, spi_config);
+
+ let cs = Output::new(p.P1_10.degrade(), Level::High, OutputDrive::Standard);
+ let reset = Output::new(p.P1_06.degrade(), Level::High, OutputDrive::Standard);
+ let dio1 = Input::new(p.P1_15.degrade(), Pull::Down);
+ let busy = Input::new(p.P1_14.degrade(), Pull::Down);
+ let antenna_rx = Output::new(p.P1_05.degrade(), Level::Low, OutputDrive::Standard);
+ let antenna_tx = Output::new(p.P1_07.degrade(), Level::Low, OutputDrive::Standard);
+
+ match Sx126xRadio::new(spim, cs, reset, antenna_rx, antenna_tx, dio1, busy, false).await {
+ Ok(r) => r,
+ Err(err) => {
+ info!("Sx126xRadio error = {}", err);
+ return;
+ }
+ }
+ };
+
+ let mut start_indicator = Output::new(p.P1_04, Level::Low, OutputDrive::Standard);
+
+ start_indicator.set_high();
+ Timer::after(Duration::from_secs(5)).await;
+ start_indicator.set_low();
+
+ match radio.lora.sleep().await {
+ Ok(()) => info!("Sleep successful"),
+ Err(err) => info!("Sleep unsuccessful = {}", err),
+ }
+
+ unwrap!(spawner.spawn(temperature_task(temperature_publisher)));
+ unwrap!(spawner.spawn(motion_detection_task(motion_detection_publisher)));
+
+ loop {
+ let message = lora_tx_subscriber.next_message_pure().await;
+
+ let tx_config = TxConfig {
+ // 11 byte maximum payload for Bandwidth 125 and SF 10
+ pw: 10, // up to 20
+ rf: RfConfig {
+ frequency: 903900000, // channel in Hz, not MHz
+ bandwidth: Bandwidth::_250KHz,
+ spreading_factor: SpreadingFactor::_10,
+ coding_rate: CodingRate::_4_8,
+ },
+ };
+
+ let mut buffer = [0x00u8];
+ match message {
+ Message::Temperature(temperature) => buffer[0] = temperature as u8,
+ Message::MotionDetected => buffer[0] = 0x01u8,
+ };
+
+ // unencrypted
+ match radio.tx(tx_config, &buffer).await {
+ Ok(ret_val) => info!("TX ret_val = {}", ret_val),
+ Err(err) => info!("TX error = {}", err),
+ }
+
+ match radio.lora.sleep().await {
+ Ok(()) => info!("Sleep successful"),
+ Err(err) => info!("Sleep unsuccessful = {}", err),
+ }
+ }
+}
diff --git a/examples/nrf/src/bin/pdm.rs b/examples/nrf/src/bin/pdm.rs
new file mode 100644
index 000000000..7388580fb
--- /dev/null
+++ b/examples/nrf/src/bin/pdm.rs
@@ -0,0 +1,33 @@
+#![no_std]
+#![no_main]
+#![feature(type_alias_impl_trait)]
+
+use defmt::info;
+use embassy_executor::Spawner;
+use embassy_nrf::interrupt;
+use embassy_nrf::pdm::{Config, Pdm};
+use embassy_time::{Duration, Timer};
+use {defmt_rtt as _, panic_probe as _};
+
+#[embassy_executor::main]
+async fn main(_p: Spawner) {
+ let p = embassy_nrf::init(Default::default());
+ let config = Config::default();
+ let mut pdm = Pdm::new(p.PDM, interrupt::take!(PDM), p.P0_01, p.P0_00, config);
+
+ loop {
+ pdm.start().await;
+
+ // wait some time till the microphon settled
+ Timer::after(Duration::from_millis(1000)).await;
+
+ const SAMPLES: usize = 2048;
+ let mut buf = [0i16; SAMPLES];
+ pdm.sample(&mut buf).await.unwrap();
+
+ info!("samples: {:?}", &buf);
+
+ pdm.stop().await;
+ Timer::after(Duration::from_millis(100)).await;
+ }
+}
diff --git a/examples/nrf/src/bin/uart_idle.rs b/examples/nrf/src/bin/uart_idle.rs
index 09ec624c0..6af4f7097 100644
--- a/examples/nrf/src/bin/uart_idle.rs
+++ b/examples/nrf/src/bin/uart_idle.rs
@@ -15,7 +15,8 @@ async fn main(_spawner: Spawner) {
config.baudrate = uarte::Baudrate::BAUD115200;
let irq = interrupt::take!(UARTE0_UART0);
- let mut uart = uarte::UarteWithIdle::new(p.UARTE0, p.TIMER0, p.PPI_CH0, p.PPI_CH1, irq, p.P0_08, p.P0_06, config);
+ let uart = uarte::Uarte::new(p.UARTE0, irq, p.P0_08, p.P0_06, config);
+ let (mut tx, mut rx) = uart.split_with_idle(p.TIMER0, p.PPI_CH0, p.PPI_CH1);
info!("uarte initialized!");
@@ -23,12 +24,12 @@ async fn main(_spawner: Spawner) {
let mut buf = [0; 8];
buf.copy_from_slice(b"Hello!\r\n");
- unwrap!(uart.write(&buf).await);
+ unwrap!(tx.write(&buf).await);
info!("wrote hello in uart!");
loop {
info!("reading...");
- let n = unwrap!(uart.read_until_idle(&mut buf).await);
+ let n = unwrap!(rx.read_until_idle(&mut buf).await);
info!("got {} bytes", n);
}
}
diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml
index 3c8f923e7..747dde515 100644
--- a/examples/rp/Cargo.toml
+++ b/examples/rp/Cargo.toml
@@ -2,6 +2,7 @@
edition = "2021"
name = "embassy-rp-examples"
version = "0.1.0"
+license = "MIT OR Apache-2.0"
[dependencies]
@@ -26,7 +27,10 @@ st7789 = "0.6.1"
display-interface = "0.4.1"
byte-slice-cast = { version = "1.2.0", default-features = false }
-embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.8" }
+embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.9" }
embedded-hal-async = { version = "0.1.0-alpha.1" }
embedded-io = { version = "0.3.0", features = ["async", "defmt"] }
static_cell = "1.0.0"
+
+[profile.release]
+debug = true
diff --git a/examples/rp/src/bin/i2c_async.rs b/examples/rp/src/bin/i2c_async.rs
new file mode 100644
index 000000000..d1a2e3cd7
--- /dev/null
+++ b/examples/rp/src/bin/i2c_async.rs
@@ -0,0 +1,102 @@
+#![no_std]
+#![no_main]
+#![feature(type_alias_impl_trait)]
+
+use defmt::*;
+use embassy_executor::Spawner;
+use embassy_rp::i2c::{self, Config};
+use embassy_rp::interrupt;
+use embassy_time::{Duration, Timer};
+use embedded_hal_async::i2c::I2c;
+use {defmt_rtt as _, panic_probe as _};
+
+#[allow(dead_code)]
+mod mcp23017 {
+ pub const ADDR: u8 = 0x20; // default addr
+
+ macro_rules! mcpregs {
+ ($($name:ident : $val:expr),* $(,)?) => {
+ $(
+ pub const $name: u8 = $val;
+ )*
+
+ pub fn regname(reg: u8) -> &'static str {
+ match reg {
+ $(
+ $val => stringify!($name),
+ )*
+ _ => panic!("bad reg"),
+ }
+ }
+ }
+ }
+
+ // These are correct for IOCON.BANK=0
+ mcpregs! {
+ IODIRA: 0x00,
+ IPOLA: 0x02,
+ GPINTENA: 0x04,
+ DEFVALA: 0x06,
+ INTCONA: 0x08,
+ IOCONA: 0x0A,
+ GPPUA: 0x0C,
+ INTFA: 0x0E,
+ INTCAPA: 0x10,
+ GPIOA: 0x12,
+ OLATA: 0x14,
+ IODIRB: 0x01,
+ IPOLB: 0x03,
+ GPINTENB: 0x05,
+ DEFVALB: 0x07,
+ INTCONB: 0x09,
+ IOCONB: 0x0B,
+ GPPUB: 0x0D,
+ INTFB: 0x0F,
+ INTCAPB: 0x11,
+ GPIOB: 0x13,
+ OLATB: 0x15,
+ }
+}
+
+#[embassy_executor::main]
+async fn main(_spawner: Spawner) {
+ let p = embassy_rp::init(Default::default());
+
+ let sda = p.PIN_14;
+ let scl = p.PIN_15;
+ let irq = interrupt::take!(I2C1_IRQ);
+
+ info!("set up i2c ");
+ let mut i2c = i2c::I2c::new_async(p.I2C1, scl, sda, irq, Config::default());
+
+ use mcp23017::*;
+
+ info!("init mcp23017 config for IxpandO");
+ // init - a outputs, b inputs
+ i2c.write(ADDR, &[IODIRA, 0x00]).await.unwrap();
+ i2c.write(ADDR, &[IODIRB, 0xff]).await.unwrap();
+ i2c.write(ADDR, &[GPPUB, 0xff]).await.unwrap(); // pullups
+
+ let mut val = 1;
+ loop {
+ let mut portb = [0];
+
+ i2c.write_read(mcp23017::ADDR, &[GPIOB], &mut portb).await.unwrap();
+ info!("portb = {:02x}", portb[0]);
+ i2c.write(mcp23017::ADDR, &[GPIOA, val | portb[0]]).await.unwrap();
+ val = val.rotate_left(1);
+
+ // get a register dump
+ info!("getting register dump");
+ let mut regs = [0; 22];
+ i2c.write_read(ADDR, &[0], &mut regs).await.unwrap();
+ // always get the regdump but only display it if portb'0 is set
+ if portb[0] & 1 != 0 {
+ for (idx, reg) in regs.into_iter().enumerate() {
+ info!("{} => {:02x}", regname(idx as u8), reg);
+ }
+ }
+
+ Timer::after(Duration::from_millis(100)).await;
+ }
+}
diff --git a/examples/rp/src/bin/i2c_blocking.rs b/examples/rp/src/bin/i2c_blocking.rs
new file mode 100644
index 000000000..7623e33c8
--- /dev/null
+++ b/examples/rp/src/bin/i2c_blocking.rs
@@ -0,0 +1,70 @@
+#![no_std]
+#![no_main]
+#![feature(type_alias_impl_trait)]
+
+use defmt::*;
+use embassy_executor::Spawner;
+use embassy_rp::i2c::{self, Config};
+use embassy_time::{Duration, Timer};
+use embedded_hal_1::i2c::I2c;
+use {defmt_rtt as _, panic_probe as _};
+
+#[allow(dead_code)]
+mod mcp23017 {
+ pub const ADDR: u8 = 0x20; // default addr
+
+ pub const IODIRA: u8 = 0x00;
+ pub const IPOLA: u8 = 0x02;
+ pub const GPINTENA: u8 = 0x04;
+ pub const DEFVALA: u8 = 0x06;
+ pub const INTCONA: u8 = 0x08;
+ pub const IOCONA: u8 = 0x0A;
+ pub const GPPUA: u8 = 0x0C;
+ pub const INTFA: u8 = 0x0E;
+ pub const INTCAPA: u8 = 0x10;
+ pub const GPIOA: u8 = 0x12;
+ pub const OLATA: u8 = 0x14;
+ pub const IODIRB: u8 = 0x01;
+ pub const IPOLB: u8 = 0x03;
+ pub const GPINTENB: u8 = 0x05;
+ pub const DEFVALB: u8 = 0x07;
+ pub const INTCONB: u8 = 0x09;
+ pub const IOCONB: u8 = 0x0B;
+ pub const GPPUB: u8 = 0x0D;
+ pub const INTFB: u8 = 0x0F;
+ pub const INTCAPB: u8 = 0x11;
+ pub const GPIOB: u8 = 0x13;
+ pub const OLATB: u8 = 0x15;
+}
+
+#[embassy_executor::main]
+async fn main(_spawner: Spawner) {
+ let p = embassy_rp::init(Default::default());
+
+ let sda = p.PIN_14;
+ let scl = p.PIN_15;
+
+ info!("set up i2c ");
+ let mut i2c = i2c::I2c::new_blocking(p.I2C1, scl, sda, Config::default());
+
+ use mcp23017::*;
+
+ info!("init mcp23017 config for IxpandO");
+ // init - a outputs, b inputs
+ i2c.write(ADDR, &[IODIRA, 0x00]).unwrap();
+ i2c.write(ADDR, &[IODIRB, 0xff]).unwrap();
+ i2c.write(ADDR, &[GPPUB, 0xff]).unwrap(); // pullups
+
+ let mut val = 0xaa;
+ loop {
+ let mut portb = [0];
+
+ i2c.write(mcp23017::ADDR, &[GPIOA, val]).unwrap();
+ i2c.write_read(mcp23017::ADDR, &[GPIOB], &mut portb).unwrap();
+
+ info!("portb = {:02x}", portb[0]);
+ val = !val;
+
+ Timer::after(Duration::from_secs(1)).await;
+ }
+}
diff --git a/examples/std/Cargo.toml b/examples/std/Cargo.toml
index dbfd9d625..b9bd1e718 100644
--- a/examples/std/Cargo.toml
+++ b/examples/std/Cargo.toml
@@ -2,6 +2,7 @@
edition = "2021"
name = "embassy-std-examples"
version = "0.1.0"
+license = "MIT OR Apache-2.0"
[dependencies]
embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["log"] }
diff --git a/examples/stm32f0/Cargo.toml b/examples/stm32f0/Cargo.toml
index c82b79c86..a56c546ee 100644
--- a/examples/stm32f0/Cargo.toml
+++ b/examples/stm32f0/Cargo.toml
@@ -2,6 +2,7 @@
name = "embassy-stm32f0-examples"
version = "0.1.0"
edition = "2021"
+license = "MIT OR Apache-2.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
diff --git a/examples/stm32f1/Cargo.toml b/examples/stm32f1/Cargo.toml
index e6553789a..6be131f30 100644
--- a/examples/stm32f1/Cargo.toml
+++ b/examples/stm32f1/Cargo.toml
@@ -2,6 +2,7 @@
edition = "2021"
name = "embassy-stm32f1-examples"
version = "0.1.0"
+license = "MIT OR Apache-2.0"
[dependencies]
embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] }
diff --git a/examples/stm32f2/Cargo.toml b/examples/stm32f2/Cargo.toml
index 60cd54bd9..f6adda2a3 100644
--- a/examples/stm32f2/Cargo.toml
+++ b/examples/stm32f2/Cargo.toml
@@ -2,6 +2,7 @@
edition = "2021"
name = "embassy-stm32f2-examples"
version = "0.1.0"
+license = "MIT OR Apache-2.0"
[dependencies]
embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] }
diff --git a/examples/stm32f3/Cargo.toml b/examples/stm32f3/Cargo.toml
index f5b0b880c..27188dd19 100644
--- a/examples/stm32f3/Cargo.toml
+++ b/examples/stm32f3/Cargo.toml
@@ -2,6 +2,7 @@
edition = "2021"
name = "embassy-stm32f3-examples"
version = "0.1.0"
+license = "MIT OR Apache-2.0"
[dependencies]
embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] }
diff --git a/examples/stm32f3/src/bin/flash.rs b/examples/stm32f3/src/bin/flash.rs
index 2cf24dbd3..baa7484d0 100644
--- a/examples/stm32f3/src/bin/flash.rs
+++ b/examples/stm32f3/src/bin/flash.rs
@@ -15,7 +15,7 @@ async fn main(_spawner: Spawner) {
const ADDR: u32 = 0x26000;
- let mut f = Flash::unlock(p.FLASH);
+ let mut f = Flash::new(p.FLASH);
info!("Reading...");
let mut buf = [0u8; 8];
diff --git a/examples/stm32f4/Cargo.toml b/examples/stm32f4/Cargo.toml
index ea5c47a43..6d4f09fba 100644
--- a/examples/stm32f4/Cargo.toml
+++ b/examples/stm32f4/Cargo.toml
@@ -2,6 +2,7 @@
edition = "2021"
name = "embassy-stm32f4-examples"
version = "0.1.0"
+license = "MIT OR Apache-2.0"
[dependencies]
diff --git a/examples/stm32f4/src/bin/adc.rs b/examples/stm32f4/src/bin/adc.rs
index 871185074..1d030f7dc 100644
--- a/examples/stm32f4/src/bin/adc.rs
+++ b/examples/stm32f4/src/bin/adc.rs
@@ -2,9 +2,10 @@
#![no_main]
#![feature(type_alias_impl_trait)]
+use cortex_m::prelude::_embedded_hal_blocking_delay_DelayUs;
use defmt::*;
use embassy_executor::Spawner;
-use embassy_stm32::adc::Adc;
+use embassy_stm32::adc::{Adc, Temperature, VrefInt};
use embassy_time::{Delay, Duration, Timer};
use {defmt_rtt as _, panic_probe as _};
@@ -13,12 +14,30 @@ async fn main(_spawner: Spawner) {
let p = embassy_stm32::init(Default::default());
info!("Hello World!");
- let mut adc = Adc::new(p.ADC1, &mut Delay);
+ let mut delay = Delay;
+ let mut adc = Adc::new(p.ADC1, &mut delay);
let mut pin = p.PC1;
+ let mut vrefint = adc.enable_vrefint();
+ let mut temp = adc.enable_temperature();
+
+ // Startup delay can be combined to the maximum of either
+ delay.delay_us(Temperature::start_time_us().max(VrefInt::start_time_us()));
+
loop {
+ // Read pin
let v = adc.read(&mut pin);
- info!("--> {} - {} mV", v, adc.to_millivolts(v));
+ info!("PC1: {} ({} mV)", v, adc.to_millivolts(v));
+
+ // Read internal temperature
+ let v = adc.read_internal(&mut temp);
+ let celcius = Temperature::to_celcius(adc.to_millivolts(v));
+ info!("Internal temp: {} ({} C)", v, celcius);
+
+ // Read internal voltage reference
+ let v = adc.read_internal(&mut vrefint);
+ info!("VrefInt: {} ({} mV)", v, adc.to_millivolts(v));
+
Timer::after(Duration::from_millis(100)).await;
}
}
diff --git a/examples/stm32f4/src/bin/flash.rs b/examples/stm32f4/src/bin/flash.rs
index 393d61e86..7ea068a42 100644
--- a/examples/stm32f4/src/bin/flash.rs
+++ b/examples/stm32f4/src/bin/flash.rs
@@ -13,7 +13,7 @@ async fn main(_spawner: Spawner) {
let p = embassy_stm32::init(Default::default());
info!("Hello Flash!");
- let mut f = Flash::unlock(p.FLASH);
+ let mut f = Flash::new(p.FLASH);
// Sector 5
test_flash(&mut f, 128 * 1024, 128 * 1024);
diff --git a/examples/stm32f7/Cargo.toml b/examples/stm32f7/Cargo.toml
index 6c2f846fe..dad92c0fc 100644
--- a/examples/stm32f7/Cargo.toml
+++ b/examples/stm32f7/Cargo.toml
@@ -2,6 +2,7 @@
edition = "2021"
name = "embassy-stm32f7-examples"
version = "0.1.0"
+license = "MIT OR Apache-2.0"
[dependencies]
embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] }
diff --git a/examples/stm32f7/src/bin/flash.rs b/examples/stm32f7/src/bin/flash.rs
index c10781d0c..4a7bca1fa 100644
--- a/examples/stm32f7/src/bin/flash.rs
+++ b/examples/stm32f7/src/bin/flash.rs
@@ -19,7 +19,7 @@ async fn main(_spawner: Spawner) {
// wait a bit before accessing the flash
Timer::after(Duration::from_millis(300)).await;
- let mut f = Flash::unlock(p.FLASH);
+ let mut f = Flash::new(p.FLASH);
info!("Reading...");
let mut buf = [0u8; 32];
diff --git a/examples/stm32g0/Cargo.toml b/examples/stm32g0/Cargo.toml
index 6baf17f36..f5673718d 100644
--- a/examples/stm32g0/Cargo.toml
+++ b/examples/stm32g0/Cargo.toml
@@ -2,6 +2,7 @@
edition = "2021"
name = "embassy-stm32g0-examples"
version = "0.1.0"
+license = "MIT OR Apache-2.0"
[dependencies]
embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] }
diff --git a/examples/stm32g4/Cargo.toml b/examples/stm32g4/Cargo.toml
index d8c05a979..ecda28805 100644
--- a/examples/stm32g4/Cargo.toml
+++ b/examples/stm32g4/Cargo.toml
@@ -2,6 +2,7 @@
edition = "2021"
name = "embassy-stm32g4-examples"
version = "0.1.0"
+license = "MIT OR Apache-2.0"
[dependencies]
embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] }
diff --git a/examples/stm32h7/Cargo.toml b/examples/stm32h7/Cargo.toml
index e725e03cb..1a05b9ecb 100644
--- a/examples/stm32h7/Cargo.toml
+++ b/examples/stm32h7/Cargo.toml
@@ -2,6 +2,7 @@
edition = "2021"
name = "embassy-stm32h7-examples"
version = "0.1.0"
+license = "MIT OR Apache-2.0"
[dependencies]
embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] }
diff --git a/examples/stm32h7/src/bin/flash.rs b/examples/stm32h7/src/bin/flash.rs
index 6682c64d5..ee86bdbf6 100644
--- a/examples/stm32h7/src/bin/flash.rs
+++ b/examples/stm32h7/src/bin/flash.rs
@@ -19,7 +19,7 @@ async fn main(_spawner: Spawner) {
// wait a bit before accessing the flash
Timer::after(Duration::from_millis(300)).await;
- let mut f = Flash::unlock(p.FLASH);
+ let mut f = Flash::new(p.FLASH);
info!("Reading...");
let mut buf = [0u8; 32];
diff --git a/examples/stm32l0/Cargo.toml b/examples/stm32l0/Cargo.toml
index 7e61f0c19..7e1120f48 100644
--- a/examples/stm32l0/Cargo.toml
+++ b/examples/stm32l0/Cargo.toml
@@ -2,6 +2,7 @@
edition = "2021"
name = "embassy-stm32l0-examples"
version = "0.1.0"
+license = "MIT OR Apache-2.0"
[features]
default = ["nightly"]
diff --git a/examples/stm32l0/src/bin/flash.rs b/examples/stm32l0/src/bin/flash.rs
index 867cb4d3e..ffe4fb10b 100644
--- a/examples/stm32l0/src/bin/flash.rs
+++ b/examples/stm32l0/src/bin/flash.rs
@@ -15,7 +15,7 @@ async fn main(_spawner: Spawner) {
const ADDR: u32 = 0x26000;
- let mut f = Flash::unlock(p.FLASH);
+ let mut f = Flash::new(p.FLASH);
info!("Reading...");
let mut buf = [0u8; 8];
diff --git a/examples/stm32l1/Cargo.toml b/examples/stm32l1/Cargo.toml
index a943c73d2..9460febf5 100644
--- a/examples/stm32l1/Cargo.toml
+++ b/examples/stm32l1/Cargo.toml
@@ -2,6 +2,7 @@
edition = "2021"
name = "embassy-stm32l1-examples"
version = "0.1.0"
+license = "MIT OR Apache-2.0"
[dependencies]
embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] }
diff --git a/examples/stm32l1/src/bin/flash.rs b/examples/stm32l1/src/bin/flash.rs
index a76b9879f..476ed51a4 100644
--- a/examples/stm32l1/src/bin/flash.rs
+++ b/examples/stm32l1/src/bin/flash.rs
@@ -15,7 +15,7 @@ async fn main(_spawner: Spawner) {
const ADDR: u32 = 0x26000;
- let mut f = Flash::unlock(p.FLASH);
+ let mut f = Flash::new(p.FLASH);
info!("Reading...");
let mut buf = [0u8; 8];
diff --git a/examples/stm32l4/Cargo.toml b/examples/stm32l4/Cargo.toml
index 2e2d07dc3..657605ebe 100644
--- a/examples/stm32l4/Cargo.toml
+++ b/examples/stm32l4/Cargo.toml
@@ -2,6 +2,7 @@
edition = "2021"
name = "embassy-stm32l4-examples"
version = "0.1.0"
+license = "MIT OR Apache-2.0"
[features]
diff --git a/examples/stm32l5/Cargo.toml b/examples/stm32l5/Cargo.toml
index 9ebab6476..63eac3ed2 100644
--- a/examples/stm32l5/Cargo.toml
+++ b/examples/stm32l5/Cargo.toml
@@ -2,6 +2,7 @@
edition = "2021"
name = "embassy-stm32l5-examples"
version = "0.1.0"
+license = "MIT OR Apache-2.0"
[features]
diff --git a/examples/stm32u5/Cargo.toml b/examples/stm32u5/Cargo.toml
index 164940586..3d704011b 100644
--- a/examples/stm32u5/Cargo.toml
+++ b/examples/stm32u5/Cargo.toml
@@ -2,6 +2,7 @@
edition = "2021"
name = "embassy-stm32u5-examples"
version = "0.1.0"
+license = "MIT OR Apache-2.0"
[dependencies]
embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] }
diff --git a/examples/stm32wb/Cargo.toml b/examples/stm32wb/Cargo.toml
index 923833e46..5b96fa191 100644
--- a/examples/stm32wb/Cargo.toml
+++ b/examples/stm32wb/Cargo.toml
@@ -2,6 +2,7 @@
edition = "2021"
name = "embassy-stm32wb-examples"
version = "0.1.0"
+license = "MIT OR Apache-2.0"
[dependencies]
embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] }
diff --git a/examples/stm32wl/Cargo.toml b/examples/stm32wl/Cargo.toml
index 94e0fb830..c827d2b71 100644
--- a/examples/stm32wl/Cargo.toml
+++ b/examples/stm32wl/Cargo.toml
@@ -2,6 +2,7 @@
edition = "2021"
name = "embassy-stm32wl-examples"
version = "0.1.0"
+license = "MIT OR Apache-2.0"
[dependencies]
embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] }
diff --git a/examples/stm32wl/src/bin/flash.rs b/examples/stm32wl/src/bin/flash.rs
index eb7489760..2a8880624 100644
--- a/examples/stm32wl/src/bin/flash.rs
+++ b/examples/stm32wl/src/bin/flash.rs
@@ -15,7 +15,7 @@ async fn main(_spawner: Spawner) {
const ADDR: u32 = 0x36000;
- let mut f = Flash::unlock(p.FLASH);
+ let mut f = Flash::new(p.FLASH);
info!("Reading...");
let mut buf = [0u8; 8];
diff --git a/examples/wasm/Cargo.toml b/examples/wasm/Cargo.toml
index ea61fb921..e0e799a34 100644
--- a/examples/wasm/Cargo.toml
+++ b/examples/wasm/Cargo.toml
@@ -2,6 +2,7 @@
edition = "2021"
name = "embassy-wasm-example"
version = "0.1.0"
+license = "MIT OR Apache-2.0"
[lib]
crate-type = ["cdylib"]
diff --git a/stm32-gen-features/Cargo.toml b/stm32-gen-features/Cargo.toml
index f92d127ea..f4aa08ebe 100644
--- a/stm32-gen-features/Cargo.toml
+++ b/stm32-gen-features/Cargo.toml
@@ -2,6 +2,7 @@
name = "gen_features"
version = "0.1.0"
edition = "2021"
+license = "MIT OR Apache-2.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
diff --git a/stm32-metapac-gen/Cargo.toml b/stm32-metapac-gen/Cargo.toml
index 0ec2075f3..3c1dab57a 100644
--- a/stm32-metapac-gen/Cargo.toml
+++ b/stm32-metapac-gen/Cargo.toml
@@ -2,6 +2,7 @@
name = "stm32-metapac-gen"
version = "0.1.0"
edition = "2021"
+license = "MIT OR Apache-2.0"
[dependencies]
diff --git a/tests/rp/Cargo.toml b/tests/rp/Cargo.toml
index 2745aef06..d6770d6e9 100644
--- a/tests/rp/Cargo.toml
+++ b/tests/rp/Cargo.toml
@@ -2,6 +2,7 @@
edition = "2021"
name = "embassy-rp-tests"
version = "0.1.0"
+license = "MIT OR Apache-2.0"
[dependencies]
embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] }
diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml
index daae3d464..bebbf557e 100644
--- a/tests/stm32/Cargo.toml
+++ b/tests/stm32/Cargo.toml
@@ -2,6 +2,7 @@
edition = "2021"
name = "embassy-stm32-tests"
version = "0.1.0"
+license = "MIT OR Apache-2.0"
[features]
stm32f103c8 = ["embassy-stm32/stm32f103c8"] # Blue Pill
diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml
index d9d6c9b26..696cfdafe 100644
--- a/xtask/Cargo.toml
+++ b/xtask/Cargo.toml
@@ -2,6 +2,7 @@
edition = "2021"
name = "xtask"
version = "0.1.0"
+license = "MIT OR Apache-2.0"
[dependencies]
anyhow = "1.0.43"