Compare commits

..

17 Commits

Author SHA1 Message Date
d6fda686bc net-esp-hosted: use released noproto version. 2023-12-20 14:13:52 +01:00
76c600365d Merge pull request #2334 from embassy-rs/embassy-net-adin1110-docs
docs: embassy-net-adin1110
2023-12-20 12:44:19 +00:00
18dac099cb Merge pull request #2333 from embassy-rs/embassy-net-wiznet-docs
docs: document public apis of wiznet driver
2023-12-20 12:44:16 +00:00
49005e955d Merge pull request #2330 from embassy-rs/embassy-net-esp-hosted-docs
Embassy net esp hosted docs
2023-12-20 12:44:11 +00:00
70ea805af3 Merge pull request #2332 from embassy-rs/embassy-net-tuntap-docs
docs: document embassy-net-tuntap
2023-12-20 12:44:06 +00:00
51a67cb69a fix: expose less 2023-12-20 13:34:34 +01:00
c8eb128a56 Merge pull request #2328 from rmja/signal-try-take
feat(embassy-sync): Add try_take() to signal
2023-12-20 12:34:01 +00:00
22ee868f04 Merge pull request #2335 from embassy-rs/remove-embedded-sdmmc
remove embedded-sdmmc
2023-12-20 12:32:04 +00:00
1c3cf347cb remove embedded-sdmmc
Remove support for embedded-sdmmc due to lack of maintainership. Bring
it back once the upstream includes the async functionality.
2023-12-20 13:25:36 +01:00
b8777eaea2 better keep missing docs for into 2023-12-20 13:12:32 +01:00
13c107e815 Put waiting state back if any 2023-12-20 13:09:16 +01:00
b0583b17cb fix: make non-public instead 2023-12-20 13:08:06 +01:00
246c49621c docs: embassy-net-adin1110 2023-12-20 12:52:35 +01:00
73f8cd7ade fix: add repository to manifest 2023-12-20 12:16:01 +01:00
4a2dd7b944 docs: document public apis of wiznet driver 2023-12-20 12:14:25 +01:00
afb01e3fc5 docs: document embassy-net-tuntap 2023-12-20 12:08:26 +01:00
f9d0daad80 feat(embassy-sync): Add try_take() to signal 2023-12-20 08:37:15 +01:00
18 changed files with 55 additions and 62 deletions

4
ci.sh
View File

@ -91,12 +91,12 @@ cargo batch \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f417zg,defmt,exti,time-driver-any,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f417zg,defmt,exti,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f423zh,defmt,exti,time-driver-any,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f423zh,defmt,exti,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f427zi,defmt,exti,time-driver-any,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f427zi,defmt,exti,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,exti,time-driver-any,embedded-sdmmc,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,exti,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f437zi,log,exti,time-driver-any,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f437zi,log,exti,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f439zi,defmt,exti,time-driver-any,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f439zi,defmt,exti,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f446ze,defmt,exti,time-driver-any,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f446ze,defmt,exti,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f469zi,defmt,exti,time-driver-any,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f469zi,defmt,exti,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f479zi,defmt,exti,time-driver-any,embedded-sdmmc,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f479zi,defmt,exti,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f730i8,defmt,exti,time-driver-any,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f730i8,defmt,exti,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h753zi,defmt,exti,time-driver-any,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h753zi,defmt,exti,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h735zg,defmt,exti,time-driver-any,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h735zg,defmt,exti,time-driver-any,time \

View File

@ -6,8 +6,7 @@ keywords = ["embedded", "ADIN1110", "embassy-net", "embedded-hal-async", "ethern
categories = ["embedded", "hardware-support", "no-std", "network-programming", "async"] categories = ["embedded", "hardware-support", "no-std", "network-programming", "async"]
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
edition = "2021" edition = "2021"
repository = "https://github.com/embassy-rs/embassy"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
heapless = "0.8" heapless = "0.8"

View File

@ -1,3 +1,4 @@
/// CRC32 lookup table.
pub const CRC32R_LOOKUP_TABLE: [u32; 256] = [ pub const CRC32R_LOOKUP_TABLE: [u32; 256] = [
0x0000_0000, 0x0000_0000,
0x7707_3096, 0x7707_3096,
@ -263,8 +264,9 @@ pub const CRC32R_LOOKUP_TABLE: [u32; 256] = [
pub struct ETH_FCS(pub u32); pub struct ETH_FCS(pub u32);
impl ETH_FCS { impl ETH_FCS {
pub const CRC32_OK: u32 = 0x2144_df1c; const CRC32_OK: u32 = 0x2144_df1c;
/// Create a new frame check sequence from `data`.
#[must_use] #[must_use]
pub fn new(data: &[u8]) -> Self { pub fn new(data: &[u8]) -> Self {
let fcs = data.iter().fold(u32::MAX, |crc, byte| { let fcs = data.iter().fold(u32::MAX, |crc, byte| {
@ -274,6 +276,7 @@ impl ETH_FCS {
Self(fcs) Self(fcs)
} }
/// Update the frame check sequence with `data`.
#[must_use] #[must_use]
pub fn update(self, data: &[u8]) -> Self { pub fn update(self, data: &[u8]) -> Self {
let fcs = data.iter().fold(self.0 ^ u32::MAX, |crc, byte| { let fcs = data.iter().fold(self.0 ^ u32::MAX, |crc, byte| {
@ -283,16 +286,19 @@ impl ETH_FCS {
Self(fcs) Self(fcs)
} }
/// Check if the frame check sequence is correct.
#[must_use] #[must_use]
pub fn crc_ok(&self) -> bool { pub fn crc_ok(&self) -> bool {
self.0 == Self::CRC32_OK self.0 == Self::CRC32_OK
} }
/// Switch byte order.
#[must_use] #[must_use]
pub fn hton_bytes(&self) -> [u8; 4] { pub fn hton_bytes(&self) -> [u8; 4] {
self.0.to_le_bytes() self.0.to_le_bytes()
} }
/// Switch byte order as a u32.
#[must_use] #[must_use]
pub fn hton(&self) -> u32 { pub fn hton(&self) -> u32 {
self.0.to_le() self.0.to_le()

View File

@ -5,6 +5,7 @@
#![allow(clippy::missing_errors_doc)] #![allow(clippy::missing_errors_doc)]
#![allow(clippy::missing_panics_doc)] #![allow(clippy::missing_panics_doc)]
#![doc = include_str!("../README.md")] #![doc = include_str!("../README.md")]
#![warn(missing_docs)]
// must go first! // must go first!
mod fmt; mod fmt;
@ -26,8 +27,9 @@ use embedded_hal_async::digital::Wait;
use embedded_hal_async::spi::{Error, Operation, SpiDevice}; use embedded_hal_async::spi::{Error, Operation, SpiDevice};
use heapless::Vec; use heapless::Vec;
pub use mdio::MdioBus; pub use mdio::MdioBus;
pub use phy::{Phy10BaseT1x, RegsC22, RegsC45}; pub use phy::Phy10BaseT1x;
pub use regs::{Config0, Config2, SpiRegisters as sr, Status0, Status1}; use phy::{RegsC22, RegsC45};
use regs::{Config0, Config2, SpiRegisters as sr, Status0, Status1};
use crate::fmt::Bytes; use crate::fmt::Bytes;
use crate::regs::{LedCntrl, LedFunc, LedPol, LedPolarity, SpiHeader}; use crate::regs::{LedCntrl, LedFunc, LedPol, LedPolarity, SpiHeader};
@ -446,6 +448,7 @@ pub struct Runner<'d, SPI, INT, RST> {
} }
impl<'d, SPI: SpiDevice, INT: Wait, RST: OutputPin> Runner<'d, SPI, INT, RST> { impl<'d, SPI: SpiDevice, INT: Wait, RST: OutputPin> Runner<'d, SPI, INT, RST> {
/// Run the driver.
#[allow(clippy::too_many_lines)] #[allow(clippy::too_many_lines)]
pub async fn run(mut self) -> ! { pub async fn run(mut self) -> ! {
loop { loop {

View File

@ -39,6 +39,7 @@ enum Reg13Op {
/// ///
/// Clause 45 methodes are bases on <https://www.ieee802.org/3/efm/public/nov02/oam/pannell_oam_1_1102.pdf> /// Clause 45 methodes are bases on <https://www.ieee802.org/3/efm/public/nov02/oam/pannell_oam_1_1102.pdf>
pub trait MdioBus { pub trait MdioBus {
/// Error type.
type Error; type Error;
/// Read, Clause 22 /// Read, Clause 22

View File

@ -2,6 +2,7 @@ use core::fmt::{Debug, Display};
use bitfield::{bitfield, bitfield_bitrange, bitfield_fields}; use bitfield::{bitfield, bitfield_bitrange, bitfield_fields};
#[allow(missing_docs)]
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))] #[cfg_attr(feature = "defmt", derive(defmt::Format))]

View File

@ -19,8 +19,7 @@ embassy-net-driver-channel = { version = "0.2.0", path = "../embassy-net-driver-
embedded-hal = { version = "1.0.0-rc.3" } embedded-hal = { version = "1.0.0-rc.3" }
embedded-hal-async = { version = "=1.0.0-rc.3" } embedded-hal-async = { version = "=1.0.0-rc.3" }
noproto = { git="https://github.com/embassy-rs/noproto", rev = "f5e6d1f325b6ad4e344f60452b09576e24671f62", default-features = false, features = ["derive"] } noproto = "0.1.0"
#noproto = { version = "0.1", path = "/home/dirbaio/noproto", default-features = false, features = ["derive"] }
heapless = "0.8" heapless = "0.8"
[package.metadata.embassy_docs] [package.metadata.embassy_docs]

View File

@ -6,6 +6,7 @@ keywords = ["embedded", "tuntap", "embassy-net", "embedded-hal-async", "ethernet
categories = ["embedded", "hardware-support", "no-std", "network-programming", "async"] categories = ["embedded", "hardware-support", "no-std", "network-programming", "async"]
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
edition = "2021" edition = "2021"
repository = "https://github.com/embassy-rs/embassy"
[dependencies] [dependencies]
embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver" } embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver" }
@ -16,4 +17,4 @@ libc = "0.2.101"
[package.metadata.embassy_docs] [package.metadata.embassy_docs]
src_base = "https://github.com/embassy-rs/embassy/blob/embassy-net-tuntap-v$VERSION/embassy-net-tuntap/src/" src_base = "https://github.com/embassy-rs/embassy/blob/embassy-net-tuntap-v$VERSION/embassy-net-tuntap/src/"
src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-net-tuntap/src/" src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-net-tuntap/src/"
target = "thumbv7em-none-eabi" target = "thumbv7em-none-eabi"

View File

@ -1,3 +1,5 @@
#![warn(missing_docs)]
#![doc = include_str!("../README.md")]
use std::io; use std::io;
use std::io::{Read, Write}; use std::io::{Read, Write};
use std::os::unix::io::{AsRawFd, RawFd}; use std::os::unix::io::{AsRawFd, RawFd};
@ -7,12 +9,19 @@ use async_io::Async;
use embassy_net_driver::{self, Capabilities, Driver, HardwareAddress, LinkState}; use embassy_net_driver::{self, Capabilities, Driver, HardwareAddress, LinkState};
use log::*; use log::*;
/// Get the MTU of the given interface.
pub const SIOCGIFMTU: libc::c_ulong = 0x8921; pub const SIOCGIFMTU: libc::c_ulong = 0x8921;
/// Get the index of the given interface.
pub const _SIOCGIFINDEX: libc::c_ulong = 0x8933; pub const _SIOCGIFINDEX: libc::c_ulong = 0x8933;
/// Capture all packages.
pub const _ETH_P_ALL: libc::c_short = 0x0003; pub const _ETH_P_ALL: libc::c_short = 0x0003;
/// Set the interface flags.
pub const TUNSETIFF: libc::c_ulong = 0x400454CA; pub const TUNSETIFF: libc::c_ulong = 0x400454CA;
/// TUN device.
pub const _IFF_TUN: libc::c_int = 0x0001; pub const _IFF_TUN: libc::c_int = 0x0001;
/// TAP device.
pub const IFF_TAP: libc::c_int = 0x0002; pub const IFF_TAP: libc::c_int = 0x0002;
/// No packet information.
pub const IFF_NO_PI: libc::c_int = 0x1000; pub const IFF_NO_PI: libc::c_int = 0x1000;
const ETHERNET_HEADER_LEN: usize = 14; const ETHERNET_HEADER_LEN: usize = 14;
@ -47,6 +56,7 @@ fn ifreq_ioctl(lower: libc::c_int, ifreq: &mut ifreq, cmd: libc::c_ulong) -> io:
Ok(ifreq.ifr_data) Ok(ifreq.ifr_data)
} }
/// A TUN/TAP device.
#[derive(Debug)] #[derive(Debug)]
pub struct TunTap { pub struct TunTap {
fd: libc::c_int, fd: libc::c_int,
@ -60,6 +70,7 @@ impl AsRawFd for TunTap {
} }
impl TunTap { impl TunTap {
/// Create a new TUN/TAP device.
pub fn new(name: &str) -> io::Result<TunTap> { pub fn new(name: &str) -> io::Result<TunTap> {
unsafe { unsafe {
let fd = libc::open( let fd = libc::open(
@ -126,11 +137,13 @@ impl io::Write for TunTap {
} }
} }
/// A TUN/TAP device, wrapped in an async interface.
pub struct TunTapDevice { pub struct TunTapDevice {
device: Async<TunTap>, device: Async<TunTap>,
} }
impl TunTapDevice { impl TunTapDevice {
/// Create a new TUN/TAP device.
pub fn new(name: &str) -> io::Result<TunTapDevice> { pub fn new(name: &str) -> io::Result<TunTapDevice> {
Ok(Self { Ok(Self {
device: Async::new(TunTap::new(name)?)?, device: Async::new(TunTap::new(name)?)?,

View File

@ -6,6 +6,7 @@ keywords = ["embedded", "wiznet", "embassy-net", "embedded-hal-async", "ethernet
categories = ["embedded", "hardware-support", "no-std", "network-programming", "async"] categories = ["embedded", "hardware-support", "no-std", "network-programming", "async"]
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
edition = "2021" edition = "2021"
repository = "https://github.com/embassy-rs/embassy"
[dependencies] [dependencies]
embedded-hal = { version = "1.0.0-rc.3" } embedded-hal = { version = "1.0.0-rc.3" }

View File

@ -1,3 +1,4 @@
//! Wiznet W5100s and W5500 family driver.
mod w5500; mod w5500;
pub use w5500::W5500; pub use w5500::W5500;
mod w5100s; mod w5100s;
@ -45,4 +46,5 @@ pub(crate) mod sealed {
} }
} }
/// Trait for Wiznet chips.
pub trait Chip: sealed::Chip {} pub trait Chip: sealed::Chip {}

View File

@ -4,6 +4,7 @@ const SOCKET_BASE: u16 = 0x400;
const TX_BASE: u16 = 0x4000; const TX_BASE: u16 = 0x4000;
const RX_BASE: u16 = 0x6000; const RX_BASE: u16 = 0x6000;
/// Wizard W5100S chip.
pub enum W5100S {} pub enum W5100S {}
impl super::Chip for W5100S {} impl super::Chip for W5100S {}

View File

@ -8,6 +8,7 @@ pub enum RegisterBlock {
RxBuf = 0x03, RxBuf = 0x03,
} }
/// Wiznet W5500 chip.
pub enum W5500 {} pub enum W5500 {}
impl super::Chip for W5500 {} impl super::Chip for W5500 {}

View File

@ -1,6 +1,7 @@
#![no_std] #![no_std]
#![allow(async_fn_in_trait)] #![allow(async_fn_in_trait)]
#![doc = include_str!("../README.md")] #![doc = include_str!("../README.md")]
#![warn(missing_docs)]
pub mod chip; pub mod chip;
mod device; mod device;
@ -47,6 +48,7 @@ pub struct Runner<'d, C: Chip, SPI: SpiDevice, INT: Wait, RST: OutputPin> {
/// You must call this in a background task for the driver to operate. /// You must call this in a background task for the driver to operate.
impl<'d, C: Chip, SPI: SpiDevice, INT: Wait, RST: OutputPin> Runner<'d, C, SPI, INT, RST> { impl<'d, C: Chip, SPI: SpiDevice, INT: Wait, RST: OutputPin> Runner<'d, C, SPI, INT, RST> {
/// Run the driver.
pub async fn run(mut self) -> ! { pub async fn run(mut self) -> ! {
let (state_chan, mut rx_chan, mut tx_chan) = self.ch.split(); let (state_chan, mut rx_chan, mut tx_chan) = self.ch.split();
let mut tick = Ticker::every(Duration::from_millis(500)); let mut tick = Ticker::every(Duration::from_millis(500));

View File

@ -56,7 +56,6 @@ cortex-m = "0.7.6"
futures = { version = "0.3.17", default-features = false, features = ["async-await"] } futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
rand_core = "0.6.3" rand_core = "0.6.3"
sdio-host = "0.5.0" sdio-host = "0.5.0"
embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true }
critical-section = "1.1" critical-section = "1.1"
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-2234f380f51d16d0398b8e547088b33ea623cc7c" } stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-2234f380f51d16d0398b8e547088b33ea623cc7c" }
vcell = "0.1.3" vcell = "0.1.3"

View File

@ -1538,53 +1538,3 @@ foreach_peripheral!(
impl Instance for peripherals::$inst {} impl Instance for peripherals::$inst {}
}; };
); );
#[cfg(feature = "embedded-sdmmc")]
mod sdmmc_rs {
use embedded_sdmmc::{Block, BlockCount, BlockDevice, BlockIdx};
use super::*;
impl<'d, T: Instance, Dma: SdmmcDma<T>> BlockDevice for Sdmmc<'d, T, Dma> {
type Error = Error;
async fn read(
&mut self,
blocks: &mut [Block],
start_block_idx: BlockIdx,
_reason: &str,
) -> Result<(), Self::Error> {
let mut address = start_block_idx.0;
for block in blocks.iter_mut() {
let block: &mut [u8; 512] = &mut block.contents;
// NOTE(unsafe) Block uses align(4)
let block = unsafe { &mut *(block as *mut _ as *mut DataBlock) };
self.read_block(address, block).await?;
address += 1;
}
Ok(())
}
async fn write(&mut self, blocks: &[Block], start_block_idx: BlockIdx) -> Result<(), Self::Error> {
let mut address = start_block_idx.0;
for block in blocks.iter() {
let block: &[u8; 512] = &block.contents;
// NOTE(unsafe) DataBlock uses align 4
let block = unsafe { &*(block as *const _ as *const DataBlock) };
self.write_block(address, block).await?;
address += 1;
}
Ok(())
}
fn num_blocks(&self) -> Result<BlockCount, Self::Error> {
let card = self.card()?;
let count = card.csd.block_count();
Ok(BlockCount(count))
}
}
}

View File

@ -111,6 +111,20 @@ where
poll_fn(move |cx| self.poll_wait(cx)) poll_fn(move |cx| self.poll_wait(cx))
} }
/// non-blocking method to try and take the signal value.
pub fn try_take(&self) -> Option<T> {
self.state.lock(|cell| {
let state = cell.replace(State::None);
match state {
State::Signaled(res) => Some(res),
state => {
cell.set(state);
None
}
}
})
}
/// non-blocking method to check whether this signal has been signaled. /// non-blocking method to check whether this signal has been signaled.
pub fn signaled(&self) -> bool { pub fn signaled(&self) -> bool {
self.state.lock(|cell| { self.state.lock(|cell| {

View File

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