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 d356d7b6..eda2b2a7 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 7ce0ac77..3f2129de 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 5258c9b0..988cf9fa 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 22de6d18..07406121 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 14ab1d00..584d5ba9 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 106295c0..cc65cf6e 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 62a9e476..faaf99dc 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 705797f6..e1edc9eb 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 b9a2cbe1..f420a75f 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 c3b361b8..c51a71d0 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 b525df33..d22bf7d7 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 fc29786f..931e9c31 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 aad54dba..b59ba8a2 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 b9ff9257..a5d82b60 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 ce1e6fe4..3a184356 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 fdbd5ab9..d92d59b2 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 2fc7ae83..8d9c4490 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 77b897b0..79ab80e0 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 fd809714..b4314aa7 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 0fe598a5..8b452be3 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 470eca52..a17d336a 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 f0b0b80e..59ca3438 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 2b4b2935..683f2c86 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 f0b0b80e..59ca3438 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 40bddd19..b879c0d7 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 5119bad2..6cddc6cc 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 5b4a61e8..e3bc0e49 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 faa65077..1ff47edd 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 aa2a13ec..b417a40d 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 49177710..4ddd1c99 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 294464d1..4b17cd79 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 87c9f33f..d8c24dfa 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 a5d340c6..6949042e 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 00000000..d512b83f
--- /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 00000000..b9768874
--- /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 00000000..7388580f
--- /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 09ec624c..6af4f709 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 3c8f923e..747dde51 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 00000000..d1a2e3cd
--- /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 00000000..7623e33c
--- /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 dbfd9d62..b9bd1e71 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 c82b79c8..a56c546e 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 e6553789..6be131f3 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 60cd54bd..f6adda2a 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 f5b0b880..27188dd1 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 2cf24dbd..baa7484d 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 ea5c47a4..6d4f09fb 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 87118507..1d030f7d 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 393d61e8..7ea068a4 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 6c2f846f..dad92c0f 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 c10781d0..4a7bca1f 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 6baf17f3..f5673718 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 d8c05a97..ecda2880 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 e725e03c..1a05b9ec 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 6682c64d..ee86bdbf 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 7e61f0c1..7e1120f4 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 867cb4d3..ffe4fb10 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 a943c73d..9460febf 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 a76b9879..476ed51a 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 2e2d07dc..657605eb 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 9ebab647..63eac3ed 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 16494058..3d704011 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 923833e4..5b96fa19 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 94e0fb83..c827d2b7 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 eb748976..2a888062 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 ea61fb92..e0e799a3 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 f92d127e..f4aa08eb 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 0ec2075f..3c1dab57 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 2745aef0..d6770d6e 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 daae3d46..bebbf557 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 d9d6c9b2..696cfdaf 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"