traits: migrate Delay to embedded-hal 1.0+async, remove Rng and Flash.
This commit is contained in:
		
							parent
							
								
									d76cd5ceaf
								
							
						
					
					
						commit
						0719b05d63
					
				| @ -2,15 +2,6 @@ | ||||
| 
 | ||||
| Embassy is a project to make async/await a first-class option for embedded development. For more information and instructions to get started, go to [https://embassy.dev](https://embassy.dev). | ||||
| 
 | ||||
| ## Traits and types | ||||
| 
 | ||||
| `embassy` provides a set of traits and types specifically designed for `async` usage. | ||||
| 
 | ||||
| - `embassy::io`: `AsyncBufRead`, `AsyncWrite`. Traits for byte-stream IO, essentially `no_std` compatible versions of `futures::io`. | ||||
| - `embassy::traits::flash`: Flash device trait. | ||||
| - `embassy::time`: `Clock` and `Alarm` traits. Std-like `Duration` and `Instant`. | ||||
| - More traits for SPI, I2C, UART async HAL coming soon. | ||||
| 
 | ||||
| ## Executor | ||||
| 
 | ||||
| The `embassy::executor` module provides an async/await executor designed for embedded usage. | ||||
|  | ||||
| @ -3,7 +3,6 @@ | ||||
| Embassy provides a set of traits and types specifically designed for `async` usage. Many of these futures will be upstreamed to the `embedded-hal` crate at some point in the future, probably when the required GAT (Generic Associated Types) feature is stabilized in Rust. | ||||
| 
 | ||||
| * `embassy::io`: `AsyncBufRead`, `AsyncWrite`. Traits for byte-stream IO, essentially `no_std` compatible versions of `futures::io`. The primary reason for re-defining these traits is that the `futures::io` variant requires `std::io::Error`, which does not work in the `no_std` environment. | ||||
| * `embassy::traits`: Async traits for Flash, SPI, I2C, UART, RNG, GPIO and more. | ||||
| * `embassy::time`: Time `Driver` trait that is implemented for different platforms. Time in Embassy is represented using the `Duration` and `Instant` types. | ||||
| 
 | ||||
| These traits are implemented by the platform-specific crates, such as `embassy-nrf` or `embassy-stm32`. | ||||
|  | ||||
| @ -50,7 +50,7 @@ embassy = { version = "0.1.0", path = "../embassy" } | ||||
| embassy-macros = { version = "0.1.0", path = "../embassy-macros", features = ["nrf"]} | ||||
| embassy-hal-common = {version = "0.1.0", path = "../embassy-hal-common" } | ||||
| 
 | ||||
| embedded-hal-02 = { package = "embedded-hal", version = "0.2.6" } | ||||
| embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] } | ||||
| embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.6", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy", optional = true} | ||||
| embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy", optional = true} | ||||
| 
 | ||||
|  | ||||
| @ -11,7 +11,7 @@ embassy-macros = { version = "0.1.0", path = "../embassy-macros", features = ["s | ||||
| embassy-hal-common = {version = "0.1.0", path = "../embassy-hal-common" } | ||||
| embassy-net = { version = "0.1.0", path = "../embassy-net", default-features = false, optional = true } | ||||
| 
 | ||||
| embedded-hal-02 = { package = "embedded-hal", version = "0.2.6" } | ||||
| embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] } | ||||
| embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.6", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy", optional = true} | ||||
| embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy", optional = true} | ||||
| 
 | ||||
|  | ||||
| @ -1,8 +1,6 @@ | ||||
| #![macro_use] | ||||
| 
 | ||||
| use core::future::Future; | ||||
| use core::task::Poll; | ||||
| use embassy::traits; | ||||
| use embassy::util::Unborrow; | ||||
| use embassy::waitqueue::AtomicWaker; | ||||
| use embassy_hal_common::unborrow; | ||||
| @ -48,6 +46,46 @@ impl<T: Instance> Rng<T> { | ||||
|         // Reference manual says to discard the first.
 | ||||
|         let _ = self.next_u32(); | ||||
|     } | ||||
| 
 | ||||
|     pub async fn async_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { | ||||
|         unsafe { | ||||
|             T::regs().cr().modify(|reg| { | ||||
|                 reg.set_rngen(true); | ||||
|             }) | ||||
|         } | ||||
| 
 | ||||
|         for chunk in dest.chunks_mut(4) { | ||||
|             poll_fn(|cx| { | ||||
|                 RNG_WAKER.register(cx.waker()); | ||||
|                 unsafe { | ||||
|                     T::regs().cr().modify(|reg| { | ||||
|                         reg.set_ie(true); | ||||
|                     }); | ||||
|                 } | ||||
| 
 | ||||
|                 let bits = unsafe { T::regs().sr().read() }; | ||||
| 
 | ||||
|                 if bits.drdy() { | ||||
|                     Poll::Ready(Ok(())) | ||||
|                 } else if bits.seis() { | ||||
|                     self.reset(); | ||||
|                     Poll::Ready(Err(Error::SeedError)) | ||||
|                 } else if bits.ceis() { | ||||
|                     self.reset(); | ||||
|                     Poll::Ready(Err(Error::ClockError)) | ||||
|                 } else { | ||||
|                     Poll::Pending | ||||
|                 } | ||||
|             }) | ||||
|             .await?; | ||||
|             let random_bytes = unsafe { T::regs().dr().read() }.to_be_bytes(); | ||||
|             for (dest, src) in chunk.iter_mut().zip(random_bytes.iter()) { | ||||
|                 *dest = *src | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         Ok(()) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<T: Instance> RngCore for Rng<T> { | ||||
| @ -83,54 +121,6 @@ impl<T: Instance> RngCore for Rng<T> { | ||||
| 
 | ||||
| impl<T: Instance> CryptoRng for Rng<T> {} | ||||
| 
 | ||||
| impl<T: Instance> traits::rng::Rng for Rng<T> { | ||||
|     type Error = Error; | ||||
|     type RngFuture<'a> | ||||
|     where | ||||
|         Self: 'a, | ||||
|     = impl Future<Output = Result<(), Self::Error>> + 'a; | ||||
| 
 | ||||
|     fn fill_bytes<'a>(&'a mut self, dest: &'a mut [u8]) -> Self::RngFuture<'a> { | ||||
|         unsafe { | ||||
|             T::regs().cr().modify(|reg| { | ||||
|                 reg.set_rngen(true); | ||||
|             }); | ||||
|         } | ||||
|         async move { | ||||
|             for chunk in dest.chunks_mut(4) { | ||||
|                 poll_fn(|cx| { | ||||
|                     RNG_WAKER.register(cx.waker()); | ||||
|                     unsafe { | ||||
|                         T::regs().cr().modify(|reg| { | ||||
|                             reg.set_ie(true); | ||||
|                         }); | ||||
|                     } | ||||
| 
 | ||||
|                     let bits = unsafe { T::regs().sr().read() }; | ||||
| 
 | ||||
|                     if bits.drdy() { | ||||
|                         Poll::Ready(Ok(())) | ||||
|                     } else if bits.seis() { | ||||
|                         self.reset(); | ||||
|                         Poll::Ready(Err(Error::SeedError)) | ||||
|                     } else if bits.ceis() { | ||||
|                         self.reset(); | ||||
|                         Poll::Ready(Err(Error::ClockError)) | ||||
|                     } else { | ||||
|                         Poll::Pending | ||||
|                     } | ||||
|                 }) | ||||
|                 .await?; | ||||
|                 let random_bytes = unsafe { T::regs().dr().read() }.to_be_bytes(); | ||||
|                 for (dest, src) in chunk.iter_mut().zip(random_bytes.iter()) { | ||||
|                     *dest = *src | ||||
|                 } | ||||
|             } | ||||
|             Ok(()) | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub(crate) mod sealed { | ||||
|     use super::*; | ||||
| 
 | ||||
|  | ||||
| @ -8,7 +8,6 @@ edition = "2018" | ||||
| std = [] | ||||
| 
 | ||||
| [dependencies] | ||||
| defmt = { version = "0.3", optional = true } | ||||
| embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] } | ||||
| embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.6", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy" } | ||||
| embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy"} | ||||
|  | ||||
| @ -1,13 +0,0 @@ | ||||
| use core::future::Future; | ||||
| 
 | ||||
| pub trait Delay { | ||||
|     type DelayFuture<'a>: Future<Output = ()> + 'a | ||||
|     where | ||||
|         Self: 'a; | ||||
| 
 | ||||
|     /// Future that completes after now + millis
 | ||||
|     fn delay_ms(&mut self, millis: u64) -> Self::DelayFuture<'_>; | ||||
| 
 | ||||
|     /// Future that completes after now + micros
 | ||||
|     fn delay_us(&mut self, micros: u64) -> Self::DelayFuture<'_>; | ||||
| } | ||||
| @ -1,57 +0,0 @@ | ||||
| use core::future::Future; | ||||
| 
 | ||||
| #[derive(Copy, Clone, Debug, Eq, PartialEq)] | ||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||
| #[non_exhaustive] | ||||
| pub enum Error { | ||||
|     Failed, | ||||
|     AddressMisaligned, | ||||
|     BufferMisaligned, | ||||
| } | ||||
| 
 | ||||
| pub trait Flash { | ||||
|     type ReadFuture<'a>: Future<Output = Result<(), Error>> | ||||
|     where | ||||
|         Self: 'a; | ||||
| 
 | ||||
|     type WriteFuture<'a>: Future<Output = Result<(), Error>> | ||||
|     where | ||||
|         Self: 'a; | ||||
| 
 | ||||
|     type ErasePageFuture<'a>: Future<Output = Result<(), Error>> | ||||
|     where | ||||
|         Self: 'a; | ||||
| 
 | ||||
|     /// Reads data from the flash device.
 | ||||
|     ///
 | ||||
|     /// address must be a multiple of self.read_size().
 | ||||
|     /// buf.len() must be a multiple of self.read_size().
 | ||||
|     fn read<'a>(&'a mut self, address: usize, buf: &'a mut [u8]) -> Self::ReadFuture<'a>; | ||||
| 
 | ||||
|     /// Writes data to the flash device.
 | ||||
|     ///
 | ||||
|     /// address must be a multiple of self.write_size().
 | ||||
|     /// buf.len() must be a multiple of self.write_size().
 | ||||
|     fn write<'a>(&'a mut self, address: usize, buf: &'a [u8]) -> Self::WriteFuture<'a>; | ||||
| 
 | ||||
|     /// Erases a single page from the flash device.
 | ||||
|     ///
 | ||||
|     /// address must be a multiple of self.erase_size().
 | ||||
|     fn erase(&mut self, address: usize) -> Self::ErasePageFuture<'_>; | ||||
| 
 | ||||
|     /// Returns the total size, in bytes.
 | ||||
|     /// This is not guaranteed to be a power of 2.
 | ||||
|     fn size(&self) -> usize; | ||||
| 
 | ||||
|     /// Returns the read size in bytes.
 | ||||
|     /// This is guaranteed to be a power of 2.
 | ||||
|     fn read_size(&self) -> usize; | ||||
| 
 | ||||
|     /// Returns the write size in bytes.
 | ||||
|     /// This is guaranteed to be a power of 2.
 | ||||
|     fn write_size(&self) -> usize; | ||||
| 
 | ||||
|     /// Returns the erase size in bytes.
 | ||||
|     /// This is guaranteed to be a power of 2.
 | ||||
|     fn erase_size(&self) -> usize; | ||||
| } | ||||
| @ -3,6 +3,3 @@ | ||||
| #![feature(type_alias_impl_trait)] | ||||
| 
 | ||||
| pub mod adapter; | ||||
| pub mod delay; | ||||
| pub mod flash; | ||||
| pub mod rng; | ||||
|  | ||||
| @ -1,75 +0,0 @@ | ||||
| use core::future::Future; | ||||
| 
 | ||||
| /// Random-number Generator
 | ||||
| pub trait Rng { | ||||
|     type Error; | ||||
| 
 | ||||
|     type RngFuture<'a>: Future<Output = Result<(), Self::Error>> + 'a | ||||
|     where | ||||
|         Self: 'a; | ||||
| 
 | ||||
|     /// Completely fill the provided buffer with random bytes.
 | ||||
|     ///
 | ||||
|     /// May result in delays if entropy is exhausted prior to completely
 | ||||
|     /// filling the buffer. Upon completion, the buffer will be completely
 | ||||
|     /// filled or an error will have been reported.
 | ||||
|     fn fill_bytes<'a>(&'a mut self, dest: &'a mut [u8]) -> Self::RngFuture<'a>; | ||||
| } | ||||
| 
 | ||||
| pub struct Random<T: Rng> { | ||||
|     rng: T, | ||||
| } | ||||
| 
 | ||||
| impl<T: Rng> Random<T> { | ||||
|     pub fn new(rng: T) -> Self { | ||||
|         Self { rng } | ||||
|     } | ||||
| 
 | ||||
|     pub async fn next_u8(&mut self, range: u8) -> Result<u8, T::Error> { | ||||
|         // Lemire's method
 | ||||
|         let t = (-(range as i8) % (range as i8)) as u8; | ||||
|         loop { | ||||
|             let mut buf = [0; 1]; | ||||
|             self.rng.fill_bytes(&mut buf).await?; | ||||
|             let x = u8::from_le_bytes(buf); | ||||
|             let m = x as u16 * range as u16; | ||||
|             let l = m as u8; | ||||
|             if l < t { | ||||
|                 continue; | ||||
|             } | ||||
|             return Ok((m >> 8) as u8); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub async fn next_u16(&mut self, range: u16) -> Result<u16, T::Error> { | ||||
|         // Lemire's method
 | ||||
|         let t = (-(range as i16) % (range as i16)) as u16; | ||||
|         loop { | ||||
|             let mut buf = [0; 2]; | ||||
|             self.rng.fill_bytes(&mut buf).await?; | ||||
|             let x = u16::from_le_bytes(buf); | ||||
|             let m = x as u32 * range as u32; | ||||
|             let l = m as u16; | ||||
|             if l < t { | ||||
|                 continue; | ||||
|             } | ||||
|             return Ok((m >> 16) as u16); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub async fn next_u32(&mut self, range: u32) -> Result<u32, T::Error> { | ||||
|         // Lemire's method
 | ||||
|         let t = (-(range as i32) % (range as i32)) as u32; | ||||
|         loop { | ||||
|             let mut buf = [0; 4]; | ||||
|             self.rng.fill_bytes(&mut buf).await?; | ||||
|             let x = u32::from_le_bytes(buf); | ||||
|             let m = x as u64 * range as u64; | ||||
|             let l = m as u32; | ||||
|             if l < t { | ||||
|                 continue; | ||||
|             } | ||||
|             return Ok((m >> 32) as u32); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -7,9 +7,12 @@ resolver = "2" | ||||
| 
 | ||||
| [features] | ||||
| default = [] | ||||
| std = ["futures/std", "embassy-traits/std", "time", "time-tick-1mhz", "embassy-macros/std"] | ||||
| std = ["futures/std", "time", "time-tick-1mhz", "embassy-macros/std"] | ||||
| wasm = ["wasm-bindgen", "js-sys", "embassy-macros/wasm", "wasm-timer", "time", "time-tick-1mhz"] | ||||
| 
 | ||||
| # Implement embedded-hal 1.0 alpha and embedded-hal-async traits. | ||||
| unstable-traits = ["embedded-hal-1", "embedded-hal-async"] | ||||
| 
 | ||||
| # Enable `embassy::time` module.  | ||||
| # NOTE: This feature is only intended to be enabled by crates providing the time driver implementation. | ||||
| # Enabling it directly without supplying a time driver will fail to link. | ||||
| @ -29,13 +32,15 @@ executor-agnostic = [] | ||||
| defmt = { version = "0.3", optional = true } | ||||
| log = { version = "0.4.14", optional = true } | ||||
| 
 | ||||
| embedded-hal-02 = { package = "embedded-hal", version = "0.2.6" } | ||||
| embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.6", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy", optional = true} | ||||
| embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy", optional = true} | ||||
| 
 | ||||
| futures     = { version = "0.3.17", default-features = false, features = [ "cfg-target-has-atomic", "unstable" ] } | ||||
| pin-project = { version = "1.0.8", default-features = false } | ||||
| embassy-macros  = { version = "0.1.0", path = "../embassy-macros"} | ||||
| embassy-traits  = { version = "0.1.0", path = "../embassy-traits"} | ||||
| atomic-polyfill = "0.1.5" | ||||
| critical-section = "0.2.5" | ||||
| embedded-hal = "0.2.6" | ||||
| heapless = "0.7.5" | ||||
| cfg-if = "1.0.0" | ||||
| 
 | ||||
|  | ||||
| @ -21,7 +21,6 @@ pub mod time; | ||||
| pub mod util; | ||||
| 
 | ||||
| pub use embassy_macros::*; | ||||
| pub use embassy_traits as traits; | ||||
| 
 | ||||
| #[doc(hidden)] | ||||
| /// Implementation details for embassy macros. DO NOT USE.
 | ||||
|  | ||||
| @ -1,6 +1,10 @@ | ||||
| use core::future::Future; | ||||
| use super::{Duration, Instant}; | ||||
| 
 | ||||
| use super::{Duration, Instant, Timer}; | ||||
| /// Blocks for at least `duration`.
 | ||||
| pub fn block_for(duration: Duration) { | ||||
|     let expires_at = Instant::now() + duration; | ||||
|     while Instant::now() < expires_at {} | ||||
| } | ||||
| 
 | ||||
| /// Type implementing async delays and blocking `embedded-hal` delays.
 | ||||
| ///
 | ||||
| @ -10,55 +14,86 @@ use super::{Duration, Instant, Timer}; | ||||
| /// active driver.
 | ||||
| pub struct Delay; | ||||
| 
 | ||||
| impl crate::traits::delay::Delay for Delay { | ||||
|     type DelayFuture<'a> = impl Future<Output = ()> + 'a; | ||||
| #[cfg(feature = "unstable-traits")] | ||||
| mod eh1 { | ||||
|     use core::future::Future; | ||||
|     use futures::FutureExt; | ||||
| 
 | ||||
|     fn delay_ms(&mut self, millis: u64) -> Self::DelayFuture<'_> { | ||||
|         Timer::after(Duration::from_millis(millis)) | ||||
|     use super::*; | ||||
|     use crate::time::Timer; | ||||
| 
 | ||||
|     impl embedded_hal_1::delay::blocking::DelayUs for Delay { | ||||
|         type Error = core::convert::Infallible; | ||||
| 
 | ||||
|         fn delay_us(&mut self, us: u32) -> Result<(), Self::Error> { | ||||
|             Ok(block_for(Duration::from_micros(us as u64))) | ||||
|         } | ||||
| 
 | ||||
|         fn delay_ms(&mut self, ms: u32) -> Result<(), Self::Error> { | ||||
|             Ok(block_for(Duration::from_millis(ms as u64))) | ||||
|         } | ||||
|     } | ||||
|     fn delay_us(&mut self, micros: u64) -> Self::DelayFuture<'_> { | ||||
|         Timer::after(Duration::from_micros(micros)) | ||||
| 
 | ||||
|     impl embedded_hal_async::delay::DelayUs for Delay { | ||||
|         type Error = core::convert::Infallible; | ||||
| 
 | ||||
|         type DelayUsFuture<'a> | ||||
|         where | ||||
|             Self: 'a, | ||||
|         = impl Future<Output = Result<(), Self::Error>> + 'a; | ||||
| 
 | ||||
|         fn delay_us(&mut self, micros: u32) -> Self::DelayUsFuture<'_> { | ||||
|             Timer::after(Duration::from_micros(micros as _)).map(Ok) | ||||
|         } | ||||
| 
 | ||||
|         type DelayMsFuture<'a> | ||||
|         where | ||||
|             Self: 'a, | ||||
|         = impl Future<Output = Result<(), Self::Error>> + 'a; | ||||
| 
 | ||||
|         fn delay_ms(&mut self, millis: u32) -> Self::DelayMsFuture<'_> { | ||||
|             Timer::after(Duration::from_millis(millis as _)).map(Ok) | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl embedded_hal::blocking::delay::DelayMs<u8> for Delay { | ||||
|     fn delay_ms(&mut self, ms: u8) { | ||||
|         block_for(Duration::from_millis(ms as u64)) | ||||
| mod eh02 { | ||||
|     use super::*; | ||||
|     use embedded_hal_02::blocking::delay::{DelayMs, DelayUs}; | ||||
| 
 | ||||
|     impl DelayMs<u8> for Delay { | ||||
|         fn delay_ms(&mut self, ms: u8) { | ||||
|             block_for(Duration::from_millis(ms as u64)) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     impl DelayMs<u16> for Delay { | ||||
|         fn delay_ms(&mut self, ms: u16) { | ||||
|             block_for(Duration::from_millis(ms as u64)) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     impl DelayMs<u32> for Delay { | ||||
|         fn delay_ms(&mut self, ms: u32) { | ||||
|             block_for(Duration::from_millis(ms as u64)) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     impl DelayUs<u8> for Delay { | ||||
|         fn delay_us(&mut self, us: u8) { | ||||
|             block_for(Duration::from_micros(us as u64)) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     impl DelayUs<u16> for Delay { | ||||
|         fn delay_us(&mut self, us: u16) { | ||||
|             block_for(Duration::from_micros(us as u64)) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     impl DelayUs<u32> for Delay { | ||||
|         fn delay_us(&mut self, us: u32) { | ||||
|             block_for(Duration::from_micros(us as u64)) | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl embedded_hal::blocking::delay::DelayMs<u16> for Delay { | ||||
|     fn delay_ms(&mut self, ms: u16) { | ||||
|         block_for(Duration::from_millis(ms as u64)) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl embedded_hal::blocking::delay::DelayMs<u32> for Delay { | ||||
|     fn delay_ms(&mut self, ms: u32) { | ||||
|         block_for(Duration::from_millis(ms as u64)) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl embedded_hal::blocking::delay::DelayUs<u8> for Delay { | ||||
|     fn delay_us(&mut self, us: u8) { | ||||
|         block_for(Duration::from_micros(us as u64)) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl embedded_hal::blocking::delay::DelayUs<u16> for Delay { | ||||
|     fn delay_us(&mut self, us: u16) { | ||||
|         block_for(Duration::from_micros(us as u64)) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl embedded_hal::blocking::delay::DelayUs<u32> for Delay { | ||||
|     fn delay_us(&mut self, us: u32) { | ||||
|         block_for(Duration::from_micros(us as u64)) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /// Blocks for at least `duration`.
 | ||||
| pub fn block_for(duration: Duration) { | ||||
|     let expires_at = Instant::now() + duration; | ||||
|     while Instant::now() < expires_at {} | ||||
| } | ||||
|  | ||||
| @ -7,7 +7,6 @@ version = "0.1.0" | ||||
| 
 | ||||
| [dependencies] | ||||
| embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] } | ||||
| embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] } | ||||
| embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote"] } | ||||
| 
 | ||||
| defmt = "0.3" | ||||
|  | ||||
| @ -7,7 +7,6 @@ resolver = "2" | ||||
| 
 | ||||
| [dependencies] | ||||
| embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] } | ||||
| embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] } | ||||
| embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32f103c8", "unstable-pac", "memory-x", "time-driver-any"]  } | ||||
| 
 | ||||
| defmt = "0.3" | ||||
|  | ||||
| @ -6,10 +6,9 @@ | ||||
| mod example_common; | ||||
| 
 | ||||
| use embassy::executor::Spawner; | ||||
| use embassy::time::Delay; | ||||
| use embassy::time::{Delay, Duration, Timer}; | ||||
| use embassy_stm32::adc::Adc; | ||||
| use embassy_stm32::Peripherals; | ||||
| use embassy_traits::delay::Delay as _; | ||||
| use example_common::*; | ||||
| 
 | ||||
| #[embassy::main] | ||||
| @ -24,6 +23,6 @@ async fn main(_spawner: Spawner, p: Peripherals) { | ||||
|     loop { | ||||
|         let v = adc.read(&mut pin); | ||||
|         info!("--> {} - {} mV", v, adc.to_millivolts(v)); | ||||
|         Delay.delay_ms(100).await; | ||||
|         Timer::after(Duration::from_millis(100)).await; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -7,7 +7,6 @@ resolver = "2" | ||||
| 
 | ||||
| [dependencies] | ||||
| embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] } | ||||
| embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] } | ||||
| embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32f303vc", "unstable-pac", "memory-x", "time-driver-any", "exti"]  } | ||||
| 
 | ||||
| defmt = "0.3" | ||||
|  | ||||
| @ -7,8 +7,7 @@ resolver = "2" | ||||
| 
 | ||||
| 
 | ||||
| [dependencies] | ||||
| embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] } | ||||
| embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] } | ||||
| embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt", "unstable-traits"] } | ||||
| embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32f429zi", "unstable-pac", "memory-x", "time-driver-any", "exti"]  } | ||||
| 
 | ||||
| defmt = "0.3" | ||||
|  | ||||
| @ -7,7 +7,6 @@ resolver = "2" | ||||
| 
 | ||||
| [dependencies] | ||||
| embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] } | ||||
| embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] } | ||||
| embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "net", "stm32f767zi", "unstable-pac", "time-driver-any", "exti"]  } | ||||
| embassy-net = { path = "../../embassy-net", default-features = false, features = ["defmt", "tcp", "medium-ethernet", "pool-16"] } | ||||
| 
 | ||||
|  | ||||
| @ -7,7 +7,6 @@ resolver = "2" | ||||
| 
 | ||||
| [dependencies] | ||||
| embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] } | ||||
| embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] } | ||||
| embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "time-driver-any", "stm32g071rb", "memory-x", "unstable-pac", "exti"]  } | ||||
| 
 | ||||
| defmt = "0.3" | ||||
|  | ||||
| @ -7,7 +7,6 @@ resolver = "2" | ||||
| 
 | ||||
| [dependencies] | ||||
| embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] } | ||||
| embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] } | ||||
| embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "time-driver-any", "stm32g491re", "memory-x", "unstable-pac", "exti"]  } | ||||
| embassy-hal-common = {version = "0.1.0", path = "../../embassy-hal-common" } | ||||
| 
 | ||||
|  | ||||
| @ -9,7 +9,6 @@ resolver = "2" | ||||
| 
 | ||||
| [dependencies] | ||||
| embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] } | ||||
| embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] } | ||||
| embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32h743zi", "net", "time-driver-any", "exti", "unstable-pac", "unstable-traits"] } | ||||
| embassy-net = { path = "../../embassy-net", default-features = false, features = ["defmt", "tcp", "medium-ethernet", "pool-16"] } | ||||
| embassy-hal-common = { path = "../../embassy-hal-common", default-features = false, features = ["defmt"] } | ||||
|  | ||||
| @ -5,9 +5,6 @@ | ||||
| #[path = "../example_common.rs"] | ||||
| mod example_common; | ||||
| use embassy::executor::Spawner; | ||||
| use embassy::time::{Duration, Timer}; | ||||
| use embassy::traits::rng::Random; | ||||
| use embassy_stm32::gpio::{Level, Output, Speed}; | ||||
| use embassy_stm32::rng::Rng; | ||||
| use embassy_stm32::Peripherals; | ||||
| use example_common::*; | ||||
| @ -16,17 +13,9 @@ use example_common::*; | ||||
| async fn main(_spawner: Spawner, p: Peripherals) { | ||||
|     info!("Hello World!"); | ||||
| 
 | ||||
|     let mut led = Output::new(p.PB14, Level::High, Speed::Low); | ||||
|     let mut rng = Rng::new(p.RNG); | ||||
| 
 | ||||
|     let mut rng = Random::new(Rng::new(p.RNG)); | ||||
| 
 | ||||
|     loop { | ||||
|         info!("high {}", unwrap!(rng.next_u8(16).await)); | ||||
|         led.set_high(); | ||||
|         Timer::after(Duration::from_millis(500)).await; | ||||
| 
 | ||||
|         info!("low {}", unwrap!(rng.next_u8(16).await)); | ||||
|         led.set_low(); | ||||
|         Timer::after(Duration::from_millis(500)).await; | ||||
|     } | ||||
|     let mut buf = [0u8; 16]; | ||||
|     unwrap!(rng.async_fill_bytes(&mut buf).await); | ||||
|     info!("random bytes: {:02x}", buf); | ||||
| } | ||||
|  | ||||
| @ -7,7 +7,6 @@ resolver = "2" | ||||
| 
 | ||||
| [dependencies] | ||||
| embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] } | ||||
| embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] } | ||||
| embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32l072cz", "time-driver-any", "exti", "unstable-traits", "memory-x"]  } | ||||
| 
 | ||||
| embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["sx127x", "time", "defmt"] } | ||||
|  | ||||
| @ -7,7 +7,6 @@ resolver = "2" | ||||
| 
 | ||||
| [dependencies] | ||||
| embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] } | ||||
| embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] } | ||||
| embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32l151cb-a", "time-driver-any", "memory-x"]  } | ||||
| 
 | ||||
| defmt = "0.3" | ||||
|  | ||||
| @ -9,7 +9,7 @@ resolver = "2" | ||||
| 
 | ||||
| [dependencies] | ||||
| embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt" ] } | ||||
| embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] } | ||||
| embassy-traits = { version = "0.1.0", path = "../../embassy-traits" } | ||||
| embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "unstable-pac", "stm32l4s5vi", "time-driver-any", "exti", "unstable-traits"]  } | ||||
| 
 | ||||
| defmt = "0.3" | ||||
|  | ||||
| @ -5,8 +5,6 @@ | ||||
| #[path = "../example_common.rs"] | ||||
| mod example_common; | ||||
| use embassy::executor::Spawner; | ||||
| use embassy::time::{Duration, Timer}; | ||||
| use embassy::traits::rng::Random; | ||||
| use embassy_stm32::rcc::{ClockSrc, PLLClkDiv, PLLMul, PLLSource, PLLSrcDiv}; | ||||
| use embassy_stm32::rng::Rng; | ||||
| use embassy_stm32::{Config, Peripherals}; | ||||
| @ -28,10 +26,9 @@ fn config() -> Config { | ||||
| async fn main(_spawner: Spawner, p: Peripherals) { | ||||
|     info!("Hello World!"); | ||||
| 
 | ||||
|     let mut rng = Random::new(Rng::new(p.RNG)); | ||||
|     let mut rng = Rng::new(p.RNG); | ||||
| 
 | ||||
|     loop { | ||||
|         info!("random {}", unwrap!(rng.next_u8(16).await)); | ||||
|         Timer::after(Duration::from_secs(1)).await; | ||||
|     } | ||||
|     let mut buf = [0u8; 16]; | ||||
|     unwrap!(rng.async_fill_bytes(&mut buf).await); | ||||
|     info!("random bytes: {:02x}", buf); | ||||
| } | ||||
|  | ||||
| @ -6,10 +6,10 @@ | ||||
| mod example_common; | ||||
| 
 | ||||
| use embassy::executor::Spawner; | ||||
| use embassy::traits::adapter::BlockingAsync; | ||||
| use embassy_stm32::dma::NoDma; | ||||
| use embassy_stm32::usart::{Config, Uart}; | ||||
| use embassy_stm32::Peripherals; | ||||
| use embassy_traits::adapter::BlockingAsync; | ||||
| use embedded_hal_async::serial::{Read, Write}; | ||||
| use example_common::*; | ||||
| 
 | ||||
|  | ||||
| @ -7,7 +7,6 @@ resolver = "2" | ||||
| 
 | ||||
| [dependencies] | ||||
| embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] } | ||||
| embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] } | ||||
| embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "unstable-pac", "stm32u585ai", "memory-x" ]  } | ||||
| 
 | ||||
| defmt = "0.3" | ||||
|  | ||||
| @ -7,7 +7,6 @@ resolver = "2" | ||||
| 
 | ||||
| [dependencies] | ||||
| embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] } | ||||
| embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] } | ||||
| embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32wb55cc", "time-driver-any", "exti"]  } | ||||
| 
 | ||||
| defmt = "0.3" | ||||
|  | ||||
| @ -7,7 +7,6 @@ resolver = "2" | ||||
| 
 | ||||
| [dependencies] | ||||
| embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] } | ||||
| embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] } | ||||
| embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32wl55jc-cm4", "time-driver-any", "memory-x", "subghz", "unstable-pac", "exti"]  } | ||||
| embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["stm32wl", "time"] } | ||||
| 
 | ||||
|  | ||||
| @ -14,7 +14,6 @@ stm32wb55rg = ["embassy-stm32/stm32wb55rg"] | ||||
| 
 | ||||
| [dependencies] | ||||
| embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] } | ||||
| embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] } | ||||
| embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "unstable-pac", "memory-x", "time-driver-tim2"]  } | ||||
| 
 | ||||
| defmt = "0.3.0" | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user