Compare commits
	
		
			28 Commits
		
	
	
		
			apidoc-emb
			...
			make-stati
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 0acf7b09c3 | ||
|  | d832d45c0b | ||
|  | 03dc624fb1 | ||
|  | d6fda686bc | ||
|  | 896690c415 | ||
|  | 76c600365d | ||
|  | 18dac099cb | ||
|  | 49005e955d | ||
|  | 70ea805af3 | ||
|  | 93bb34d8d1 | ||
|  | 51a67cb69a | ||
|  | c8eb128a56 | ||
|  | 22ee868f04 | ||
|  | 1c3cf347cb | ||
|  | b8777eaea2 | ||
|  | 13c107e815 | ||
|  | b0583b17cb | ||
|  | 246c49621c | ||
|  | c3b827d8cd | ||
|  | 4dfae9328e | ||
|  | 73f8cd7ade | ||
|  | 4a2dd7b944 | ||
|  | afb01e3fc5 | ||
|  | 89cfdcb9f5 | ||
|  | abea4dde3d | ||
|  | 52a801fdb7 | ||
|  | fc6e70caa5 | ||
|  | f9d0daad80 | 
							
								
								
									
										4
									
								
								ci.sh
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								ci.sh
									
									
									
									
									
								
							| @@ -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 \ | ||||||
|   | |||||||
| @@ -4,6 +4,12 @@ name = "embassy-boot-nrf" | |||||||
| version = "0.1.0" | version = "0.1.0" | ||||||
| description = "Bootloader lib for nRF chips" | description = "Bootloader lib for nRF chips" | ||||||
| license = "MIT OR Apache-2.0" | license = "MIT OR Apache-2.0" | ||||||
|  | repository = "https://github.com/embassy-rs/embassy" | ||||||
|  | categories = [ | ||||||
|  |     "embedded", | ||||||
|  |     "no-std", | ||||||
|  |     "asynchronous", | ||||||
|  | ] | ||||||
|  |  | ||||||
| [package.metadata.embassy_docs] | [package.metadata.embassy_docs] | ||||||
| src_base = "https://github.com/embassy-rs/embassy/blob/embassy-boot-nrf-v$VERSION/embassy-boot/nrf/src/" | src_base = "https://github.com/embassy-rs/embassy/blob/embassy-boot-nrf-v$VERSION/embassy-boot/nrf/src/" | ||||||
| @@ -25,7 +31,7 @@ embedded-storage = "0.3.1" | |||||||
| embedded-storage-async = { version = "0.4.1" } | embedded-storage-async = { version = "0.4.1" } | ||||||
| cfg-if = "1.0.0" | cfg-if = "1.0.0" | ||||||
|  |  | ||||||
| nrf-softdevice-mbr = { version = "0.1.0", git = "https://github.com/embassy-rs/nrf-softdevice.git", branch = "master", optional = true } | nrf-softdevice-mbr = { version = "0.2.0", optional = true } | ||||||
|  |  | ||||||
| [features] | [features] | ||||||
| defmt = [ | defmt = [ | ||||||
|   | |||||||
| @@ -4,6 +4,12 @@ name = "embassy-boot-rp" | |||||||
| version = "0.1.0" | version = "0.1.0" | ||||||
| description = "Bootloader lib for RP2040 chips" | description = "Bootloader lib for RP2040 chips" | ||||||
| license = "MIT OR Apache-2.0" | license = "MIT OR Apache-2.0" | ||||||
|  | repository = "https://github.com/embassy-rs/embassy" | ||||||
|  | categories = [ | ||||||
|  |     "embedded", | ||||||
|  |     "no-std", | ||||||
|  |     "asynchronous", | ||||||
|  | ] | ||||||
|  |  | ||||||
| [package.metadata.embassy_docs] | [package.metadata.embassy_docs] | ||||||
| src_base = "https://github.com/embassy-rs/embassy/blob/embassy-boot-rp-v$VERSION/src/" | src_base = "https://github.com/embassy-rs/embassy/blob/embassy-boot-rp-v$VERSION/src/" | ||||||
|   | |||||||
| @@ -4,6 +4,12 @@ name = "embassy-boot-stm32" | |||||||
| version = "0.1.0" | version = "0.1.0" | ||||||
| description = "Bootloader lib for STM32 chips" | description = "Bootloader lib for STM32 chips" | ||||||
| license = "MIT OR Apache-2.0" | license = "MIT OR Apache-2.0" | ||||||
|  | repository = "https://github.com/embassy-rs/embassy" | ||||||
|  | categories = [ | ||||||
|  |     "embedded", | ||||||
|  |     "no-std", | ||||||
|  |     "asynchronous", | ||||||
|  | ] | ||||||
|  |  | ||||||
| [package.metadata.embassy_docs] | [package.metadata.embassy_docs] | ||||||
| src_base = "https://github.com/embassy-rs/embassy/blob/embassy-boot-nrf-v$VERSION/embassy-boot/stm32/src/" | src_base = "https://github.com/embassy-rs/embassy/blob/embassy-boot-nrf-v$VERSION/embassy-boot/stm32/src/" | ||||||
|   | |||||||
| @@ -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" | ||||||
|   | |||||||
| @@ -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() | ||||||
|   | |||||||
| @@ -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 { | ||||||
|   | |||||||
| @@ -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 | ||||||
|   | |||||||
| @@ -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))] | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| #![no_std] | #![no_std] | ||||||
| #![doc = include_str!("../README.md")] | #![doc = include_str!("../README.md")] | ||||||
|  | #![warn(missing_docs)] | ||||||
|  |  | ||||||
| // must go first! | // must go first! | ||||||
| mod fmt; | mod fmt; | ||||||
| @@ -15,6 +16,9 @@ use embassy_sync::blocking_mutex::Mutex; | |||||||
| use embassy_sync::waitqueue::WakerRegistration; | use embassy_sync::waitqueue::WakerRegistration; | ||||||
| use embassy_sync::zerocopy_channel; | use embassy_sync::zerocopy_channel; | ||||||
|  |  | ||||||
|  | /// Channel state. | ||||||
|  | /// | ||||||
|  | /// Holds a buffer of packets with size MTU, for both TX and RX. | ||||||
| pub struct State<const MTU: usize, const N_RX: usize, const N_TX: usize> { | pub struct State<const MTU: usize, const N_RX: usize, const N_TX: usize> { | ||||||
|     rx: [PacketBuf<MTU>; N_RX], |     rx: [PacketBuf<MTU>; N_RX], | ||||||
|     tx: [PacketBuf<MTU>; N_TX], |     tx: [PacketBuf<MTU>; N_TX], | ||||||
| @@ -24,6 +28,7 @@ pub struct State<const MTU: usize, const N_RX: usize, const N_TX: usize> { | |||||||
| impl<const MTU: usize, const N_RX: usize, const N_TX: usize> State<MTU, N_RX, N_TX> { | impl<const MTU: usize, const N_RX: usize, const N_TX: usize> State<MTU, N_RX, N_TX> { | ||||||
|     const NEW_PACKET: PacketBuf<MTU> = PacketBuf::new(); |     const NEW_PACKET: PacketBuf<MTU> = PacketBuf::new(); | ||||||
|  |  | ||||||
|  |     /// Create a new channel state. | ||||||
|     pub const fn new() -> Self { |     pub const fn new() -> Self { | ||||||
|         Self { |         Self { | ||||||
|             rx: [Self::NEW_PACKET; N_RX], |             rx: [Self::NEW_PACKET; N_RX], | ||||||
| @@ -39,33 +44,45 @@ struct StateInner<'d, const MTU: usize> { | |||||||
|     shared: Mutex<NoopRawMutex, RefCell<Shared>>, |     shared: Mutex<NoopRawMutex, RefCell<Shared>>, | ||||||
| } | } | ||||||
|  |  | ||||||
| /// State of the LinkState |  | ||||||
| struct Shared { | struct Shared { | ||||||
|     link_state: LinkState, |     link_state: LinkState, | ||||||
|     waker: WakerRegistration, |     waker: WakerRegistration, | ||||||
|     hardware_address: driver::HardwareAddress, |     hardware_address: driver::HardwareAddress, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// Channel runner. | ||||||
|  | /// | ||||||
|  | /// Holds the shared state and the lower end of channels for inbound and outbound packets. | ||||||
| pub struct Runner<'d, const MTU: usize> { | pub struct Runner<'d, const MTU: usize> { | ||||||
|     tx_chan: zerocopy_channel::Receiver<'d, NoopRawMutex, PacketBuf<MTU>>, |     tx_chan: zerocopy_channel::Receiver<'d, NoopRawMutex, PacketBuf<MTU>>, | ||||||
|     rx_chan: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf<MTU>>, |     rx_chan: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf<MTU>>, | ||||||
|     shared: &'d Mutex<NoopRawMutex, RefCell<Shared>>, |     shared: &'d Mutex<NoopRawMutex, RefCell<Shared>>, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// State runner. | ||||||
|  | /// | ||||||
|  | /// Holds the shared state of the channel such as link state. | ||||||
| #[derive(Clone, Copy)] | #[derive(Clone, Copy)] | ||||||
| pub struct StateRunner<'d> { | pub struct StateRunner<'d> { | ||||||
|     shared: &'d Mutex<NoopRawMutex, RefCell<Shared>>, |     shared: &'d Mutex<NoopRawMutex, RefCell<Shared>>, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// RX runner. | ||||||
|  | /// | ||||||
|  | /// Holds the lower end of the channel for passing inbound packets up the stack. | ||||||
| pub struct RxRunner<'d, const MTU: usize> { | pub struct RxRunner<'d, const MTU: usize> { | ||||||
|     rx_chan: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf<MTU>>, |     rx_chan: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf<MTU>>, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// TX runner. | ||||||
|  | /// | ||||||
|  | /// Holds the lower end of the channel for passing outbound packets down the stack. | ||||||
| pub struct TxRunner<'d, const MTU: usize> { | pub struct TxRunner<'d, const MTU: usize> { | ||||||
|     tx_chan: zerocopy_channel::Receiver<'d, NoopRawMutex, PacketBuf<MTU>>, |     tx_chan: zerocopy_channel::Receiver<'d, NoopRawMutex, PacketBuf<MTU>>, | ||||||
| } | } | ||||||
|  |  | ||||||
| impl<'d, const MTU: usize> Runner<'d, MTU> { | impl<'d, const MTU: usize> Runner<'d, MTU> { | ||||||
|  |     /// Split the runner into separate runners for controlling state, rx and tx. | ||||||
|     pub fn split(self) -> (StateRunner<'d>, RxRunner<'d, MTU>, TxRunner<'d, MTU>) { |     pub fn split(self) -> (StateRunner<'d>, RxRunner<'d, MTU>, TxRunner<'d, MTU>) { | ||||||
|         ( |         ( | ||||||
|             StateRunner { shared: self.shared }, |             StateRunner { shared: self.shared }, | ||||||
| @@ -74,6 +91,7 @@ impl<'d, const MTU: usize> Runner<'d, MTU> { | |||||||
|         ) |         ) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Split the runner into separate runners for controlling state, rx and tx borrowing the underlying state. | ||||||
|     pub fn borrow_split(&mut self) -> (StateRunner<'_>, RxRunner<'_, MTU>, TxRunner<'_, MTU>) { |     pub fn borrow_split(&mut self) -> (StateRunner<'_>, RxRunner<'_, MTU>, TxRunner<'_, MTU>) { | ||||||
|         ( |         ( | ||||||
|             StateRunner { shared: self.shared }, |             StateRunner { shared: self.shared }, | ||||||
| @@ -86,10 +104,12 @@ impl<'d, const MTU: usize> Runner<'d, MTU> { | |||||||
|         ) |         ) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Create a state runner sharing the state channel. | ||||||
|     pub fn state_runner(&self) -> StateRunner<'d> { |     pub fn state_runner(&self) -> StateRunner<'d> { | ||||||
|         StateRunner { shared: self.shared } |         StateRunner { shared: self.shared } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Set the link state. | ||||||
|     pub fn set_link_state(&mut self, state: LinkState) { |     pub fn set_link_state(&mut self, state: LinkState) { | ||||||
|         self.shared.lock(|s| { |         self.shared.lock(|s| { | ||||||
|             let s = &mut *s.borrow_mut(); |             let s = &mut *s.borrow_mut(); | ||||||
| @@ -98,6 +118,7 @@ impl<'d, const MTU: usize> Runner<'d, MTU> { | |||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Set the hardware address. | ||||||
|     pub fn set_hardware_address(&mut self, address: driver::HardwareAddress) { |     pub fn set_hardware_address(&mut self, address: driver::HardwareAddress) { | ||||||
|         self.shared.lock(|s| { |         self.shared.lock(|s| { | ||||||
|             let s = &mut *s.borrow_mut(); |             let s = &mut *s.borrow_mut(); | ||||||
| @@ -106,16 +127,19 @@ impl<'d, const MTU: usize> Runner<'d, MTU> { | |||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Wait until there is space for more inbound packets and return a slice they can be copied into. | ||||||
|     pub async fn rx_buf(&mut self) -> &mut [u8] { |     pub async fn rx_buf(&mut self) -> &mut [u8] { | ||||||
|         let p = self.rx_chan.send().await; |         let p = self.rx_chan.send().await; | ||||||
|         &mut p.buf |         &mut p.buf | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Check if there is space for more inbound packets right now. | ||||||
|     pub fn try_rx_buf(&mut self) -> Option<&mut [u8]> { |     pub fn try_rx_buf(&mut self) -> Option<&mut [u8]> { | ||||||
|         let p = self.rx_chan.try_send()?; |         let p = self.rx_chan.try_send()?; | ||||||
|         Some(&mut p.buf) |         Some(&mut p.buf) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Polling the inbound channel if there is space for packets. | ||||||
|     pub fn poll_rx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> { |     pub fn poll_rx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> { | ||||||
|         match self.rx_chan.poll_send(cx) { |         match self.rx_chan.poll_send(cx) { | ||||||
|             Poll::Ready(p) => Poll::Ready(&mut p.buf), |             Poll::Ready(p) => Poll::Ready(&mut p.buf), | ||||||
| @@ -123,22 +147,26 @@ impl<'d, const MTU: usize> Runner<'d, MTU> { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Mark packet of len bytes as pushed to the inbound channel. | ||||||
|     pub fn rx_done(&mut self, len: usize) { |     pub fn rx_done(&mut self, len: usize) { | ||||||
|         let p = self.rx_chan.try_send().unwrap(); |         let p = self.rx_chan.try_send().unwrap(); | ||||||
|         p.len = len; |         p.len = len; | ||||||
|         self.rx_chan.send_done(); |         self.rx_chan.send_done(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Wait until there is space for more outbound packets and return a slice they can be copied into. | ||||||
|     pub async fn tx_buf(&mut self) -> &mut [u8] { |     pub async fn tx_buf(&mut self) -> &mut [u8] { | ||||||
|         let p = self.tx_chan.receive().await; |         let p = self.tx_chan.receive().await; | ||||||
|         &mut p.buf[..p.len] |         &mut p.buf[..p.len] | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Check if there is space for more outbound packets right now. | ||||||
|     pub fn try_tx_buf(&mut self) -> Option<&mut [u8]> { |     pub fn try_tx_buf(&mut self) -> Option<&mut [u8]> { | ||||||
|         let p = self.tx_chan.try_receive()?; |         let p = self.tx_chan.try_receive()?; | ||||||
|         Some(&mut p.buf[..p.len]) |         Some(&mut p.buf[..p.len]) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Polling the outbound channel if there is space for packets. | ||||||
|     pub fn poll_tx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> { |     pub fn poll_tx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> { | ||||||
|         match self.tx_chan.poll_receive(cx) { |         match self.tx_chan.poll_receive(cx) { | ||||||
|             Poll::Ready(p) => Poll::Ready(&mut p.buf[..p.len]), |             Poll::Ready(p) => Poll::Ready(&mut p.buf[..p.len]), | ||||||
| @@ -146,12 +174,14 @@ impl<'d, const MTU: usize> Runner<'d, MTU> { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Mark outbound packet as copied. | ||||||
|     pub fn tx_done(&mut self) { |     pub fn tx_done(&mut self) { | ||||||
|         self.tx_chan.receive_done(); |         self.tx_chan.receive_done(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| impl<'d> StateRunner<'d> { | impl<'d> StateRunner<'d> { | ||||||
|  |     /// Set link state. | ||||||
|     pub fn set_link_state(&self, state: LinkState) { |     pub fn set_link_state(&self, state: LinkState) { | ||||||
|         self.shared.lock(|s| { |         self.shared.lock(|s| { | ||||||
|             let s = &mut *s.borrow_mut(); |             let s = &mut *s.borrow_mut(); | ||||||
| @@ -160,6 +190,7 @@ impl<'d> StateRunner<'d> { | |||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Set the hardware address. | ||||||
|     pub fn set_hardware_address(&self, address: driver::HardwareAddress) { |     pub fn set_hardware_address(&self, address: driver::HardwareAddress) { | ||||||
|         self.shared.lock(|s| { |         self.shared.lock(|s| { | ||||||
|             let s = &mut *s.borrow_mut(); |             let s = &mut *s.borrow_mut(); | ||||||
| @@ -170,16 +201,19 @@ impl<'d> StateRunner<'d> { | |||||||
| } | } | ||||||
|  |  | ||||||
| impl<'d, const MTU: usize> RxRunner<'d, MTU> { | impl<'d, const MTU: usize> RxRunner<'d, MTU> { | ||||||
|  |     /// Wait until there is space for more inbound packets and return a slice they can be copied into. | ||||||
|     pub async fn rx_buf(&mut self) -> &mut [u8] { |     pub async fn rx_buf(&mut self) -> &mut [u8] { | ||||||
|         let p = self.rx_chan.send().await; |         let p = self.rx_chan.send().await; | ||||||
|         &mut p.buf |         &mut p.buf | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Check if there is space for more inbound packets right now. | ||||||
|     pub fn try_rx_buf(&mut self) -> Option<&mut [u8]> { |     pub fn try_rx_buf(&mut self) -> Option<&mut [u8]> { | ||||||
|         let p = self.rx_chan.try_send()?; |         let p = self.rx_chan.try_send()?; | ||||||
|         Some(&mut p.buf) |         Some(&mut p.buf) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Polling the inbound channel if there is space for packets. | ||||||
|     pub fn poll_rx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> { |     pub fn poll_rx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> { | ||||||
|         match self.rx_chan.poll_send(cx) { |         match self.rx_chan.poll_send(cx) { | ||||||
|             Poll::Ready(p) => Poll::Ready(&mut p.buf), |             Poll::Ready(p) => Poll::Ready(&mut p.buf), | ||||||
| @@ -187,6 +221,7 @@ impl<'d, const MTU: usize> RxRunner<'d, MTU> { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Mark packet of len bytes as pushed to the inbound channel. | ||||||
|     pub fn rx_done(&mut self, len: usize) { |     pub fn rx_done(&mut self, len: usize) { | ||||||
|         let p = self.rx_chan.try_send().unwrap(); |         let p = self.rx_chan.try_send().unwrap(); | ||||||
|         p.len = len; |         p.len = len; | ||||||
| @@ -195,16 +230,19 @@ impl<'d, const MTU: usize> RxRunner<'d, MTU> { | |||||||
| } | } | ||||||
|  |  | ||||||
| impl<'d, const MTU: usize> TxRunner<'d, MTU> { | impl<'d, const MTU: usize> TxRunner<'d, MTU> { | ||||||
|  |     /// Wait until there is space for more outbound packets and return a slice they can be copied into. | ||||||
|     pub async fn tx_buf(&mut self) -> &mut [u8] { |     pub async fn tx_buf(&mut self) -> &mut [u8] { | ||||||
|         let p = self.tx_chan.receive().await; |         let p = self.tx_chan.receive().await; | ||||||
|         &mut p.buf[..p.len] |         &mut p.buf[..p.len] | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Check if there is space for more outbound packets right now. | ||||||
|     pub fn try_tx_buf(&mut self) -> Option<&mut [u8]> { |     pub fn try_tx_buf(&mut self) -> Option<&mut [u8]> { | ||||||
|         let p = self.tx_chan.try_receive()?; |         let p = self.tx_chan.try_receive()?; | ||||||
|         Some(&mut p.buf[..p.len]) |         Some(&mut p.buf[..p.len]) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Polling the outbound channel if there is space for packets. | ||||||
|     pub fn poll_tx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> { |     pub fn poll_tx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> { | ||||||
|         match self.tx_chan.poll_receive(cx) { |         match self.tx_chan.poll_receive(cx) { | ||||||
|             Poll::Ready(p) => Poll::Ready(&mut p.buf[..p.len]), |             Poll::Ready(p) => Poll::Ready(&mut p.buf[..p.len]), | ||||||
| @@ -212,11 +250,18 @@ impl<'d, const MTU: usize> TxRunner<'d, MTU> { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Mark outbound packet as copied. | ||||||
|     pub fn tx_done(&mut self) { |     pub fn tx_done(&mut self) { | ||||||
|         self.tx_chan.receive_done(); |         self.tx_chan.receive_done(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// Create a channel. | ||||||
|  | /// | ||||||
|  | /// Returns a pair of handles for interfacing with the peripheral and the networking stack. | ||||||
|  | /// | ||||||
|  | /// The runner is interfacing with the peripheral at the lower part of the stack. | ||||||
|  | /// The device is interfacing with the networking stack on the layer above. | ||||||
| pub fn new<'d, const MTU: usize, const N_RX: usize, const N_TX: usize>( | pub fn new<'d, const MTU: usize, const N_RX: usize, const N_TX: usize>( | ||||||
|     state: &'d mut State<MTU, N_RX, N_TX>, |     state: &'d mut State<MTU, N_RX, N_TX>, | ||||||
|     hardware_address: driver::HardwareAddress, |     hardware_address: driver::HardwareAddress, | ||||||
| @@ -257,17 +302,22 @@ pub fn new<'d, const MTU: usize, const N_RX: usize, const N_TX: usize>( | |||||||
|     ) |     ) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// Represents a packet of size MTU. | ||||||
| pub struct PacketBuf<const MTU: usize> { | pub struct PacketBuf<const MTU: usize> { | ||||||
|     len: usize, |     len: usize, | ||||||
|     buf: [u8; MTU], |     buf: [u8; MTU], | ||||||
| } | } | ||||||
|  |  | ||||||
| impl<const MTU: usize> PacketBuf<MTU> { | impl<const MTU: usize> PacketBuf<MTU> { | ||||||
|  |     /// Create a new packet buffer. | ||||||
|     pub const fn new() -> Self { |     pub const fn new() -> Self { | ||||||
|         Self { len: 0, buf: [0; MTU] } |         Self { len: 0, buf: [0; MTU] } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// Channel device. | ||||||
|  | /// | ||||||
|  | /// Holds the shared state and upper end of channels for inbound and outbound packets. | ||||||
| pub struct Device<'d, const MTU: usize> { | pub struct Device<'d, const MTU: usize> { | ||||||
|     rx: zerocopy_channel::Receiver<'d, NoopRawMutex, PacketBuf<MTU>>, |     rx: zerocopy_channel::Receiver<'d, NoopRawMutex, PacketBuf<MTU>>, | ||||||
|     tx: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf<MTU>>, |     tx: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf<MTU>>, | ||||||
| @@ -314,6 +364,9 @@ impl<'d, const MTU: usize> embassy_net_driver::Driver for Device<'d, MTU> { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// A rx token. | ||||||
|  | /// | ||||||
|  | /// Holds inbound receive channel and interfaces with embassy-net-driver. | ||||||
| pub struct RxToken<'a, const MTU: usize> { | pub struct RxToken<'a, const MTU: usize> { | ||||||
|     rx: zerocopy_channel::Receiver<'a, NoopRawMutex, PacketBuf<MTU>>, |     rx: zerocopy_channel::Receiver<'a, NoopRawMutex, PacketBuf<MTU>>, | ||||||
| } | } | ||||||
| @@ -331,6 +384,9 @@ impl<'a, const MTU: usize> embassy_net_driver::RxToken for RxToken<'a, MTU> { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// A tx token. | ||||||
|  | /// | ||||||
|  | /// Holds outbound transmit channel and interfaces with embassy-net-driver. | ||||||
| pub struct TxToken<'a, const MTU: usize> { | pub struct TxToken<'a, const MTU: usize> { | ||||||
|     tx: zerocopy_channel::Sender<'a, NoopRawMutex, PacketBuf<MTU>>, |     tx: zerocopy_channel::Sender<'a, NoopRawMutex, PacketBuf<MTU>>, | ||||||
| } | } | ||||||
|   | |||||||
| @@ -2,6 +2,10 @@ | |||||||
| name = "embassy-net-esp-hosted" | name = "embassy-net-esp-hosted" | ||||||
| version = "0.1.0" | version = "0.1.0" | ||||||
| edition = "2021" | edition = "2021" | ||||||
|  | description = "embassy-net driver for ESP-Hosted" | ||||||
|  | keywords = ["embedded", "esp-hosted", "embassy-net", "embedded-hal-async", "wifi", "async"] | ||||||
|  | categories = ["embedded", "hardware-support", "no-std", "network-programming", "async"] | ||||||
|  | license = "MIT OR Apache-2.0" | ||||||
|  |  | ||||||
| [dependencies] | [dependencies] | ||||||
| defmt = { version = "0.3", optional = true } | defmt = { version = "0.3", optional = true } | ||||||
| @@ -15,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] | ||||||
|   | |||||||
							
								
								
									
										27
									
								
								embassy-net-esp-hosted/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								embassy-net-esp-hosted/README.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | |||||||
|  | # ESP-Hosted `embassy-net` integration | ||||||
|  |  | ||||||
|  | [`embassy-net`](https://crates.io/crates/embassy-net) integration for Espressif SoCs running the the ESP-Hosted stack. | ||||||
|  |  | ||||||
|  | See [`examples`](https://github.com/embassy-rs/embassy/tree/main/examples/nrf52840) directory for usage examples with the nRF52840. | ||||||
|  |  | ||||||
|  | ## Supported chips | ||||||
|  |  | ||||||
|  | - W5500 | ||||||
|  | - W5100S | ||||||
|  |  | ||||||
|  | ## Interoperability | ||||||
|  |  | ||||||
|  | This crate can run on any executor. | ||||||
|  |  | ||||||
|  | It supports any SPI driver implementing [`embedded-hal-async`](https://crates.io/crates/embedded-hal-async). | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ## License | ||||||
|  |  | ||||||
|  | This work is licensed under either of | ||||||
|  |  | ||||||
|  | - Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or | ||||||
|  |   http://www.apache.org/licenses/LICENSE-2.0) | ||||||
|  | - MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) | ||||||
|  |  | ||||||
|  | at your option. | ||||||
| @@ -5,38 +5,54 @@ use heapless::String; | |||||||
| use crate::ioctl::Shared; | use crate::ioctl::Shared; | ||||||
| use crate::proto::{self, CtrlMsg}; | use crate::proto::{self, CtrlMsg}; | ||||||
|  |  | ||||||
|  | /// Errors reported by control. | ||||||
| #[derive(Copy, Clone, PartialEq, Eq, Debug)] | #[derive(Copy, Clone, PartialEq, Eq, Debug)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub enum Error { | pub enum Error { | ||||||
|  |     /// The operation failed with the given error code. | ||||||
|     Failed(u32), |     Failed(u32), | ||||||
|  |     /// The operation timed out. | ||||||
|     Timeout, |     Timeout, | ||||||
|  |     /// Internal error. | ||||||
|     Internal, |     Internal, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// Handle for managing the network and WiFI state. | ||||||
| pub struct Control<'a> { | pub struct Control<'a> { | ||||||
|     state_ch: ch::StateRunner<'a>, |     state_ch: ch::StateRunner<'a>, | ||||||
|     shared: &'a Shared, |     shared: &'a Shared, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// WiFi mode. | ||||||
| #[allow(unused)] | #[allow(unused)] | ||||||
| #[derive(Copy, Clone, PartialEq, Eq, Debug)] | #[derive(Copy, Clone, PartialEq, Eq, Debug)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| enum WifiMode { | enum WifiMode { | ||||||
|  |     /// No mode. | ||||||
|     None = 0, |     None = 0, | ||||||
|  |     /// Client station. | ||||||
|     Sta = 1, |     Sta = 1, | ||||||
|  |     /// Access point mode. | ||||||
|     Ap = 2, |     Ap = 2, | ||||||
|  |     /// Repeater mode. | ||||||
|     ApSta = 3, |     ApSta = 3, | ||||||
| } | } | ||||||
|  |  | ||||||
| pub use proto::CtrlWifiSecProt as Security; | pub use proto::CtrlWifiSecProt as Security; | ||||||
|  |  | ||||||
|  | /// WiFi status. | ||||||
| #[derive(Clone, Debug)] | #[derive(Clone, Debug)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct Status { | pub struct Status { | ||||||
|  |     /// Service Set Identifier. | ||||||
|     pub ssid: String<32>, |     pub ssid: String<32>, | ||||||
|  |     /// Basic Service Set Identifier. | ||||||
|     pub bssid: [u8; 6], |     pub bssid: [u8; 6], | ||||||
|  |     /// Received Signal Strength Indicator. | ||||||
|     pub rssi: i32, |     pub rssi: i32, | ||||||
|  |     /// WiFi channel. | ||||||
|     pub channel: u32, |     pub channel: u32, | ||||||
|  |     /// Security mode. | ||||||
|     pub security: Security, |     pub security: Security, | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -65,6 +81,7 @@ impl<'a> Control<'a> { | |||||||
|         Self { state_ch, shared } |         Self { state_ch, shared } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Initialize device. | ||||||
|     pub async fn init(&mut self) -> Result<(), Error> { |     pub async fn init(&mut self) -> Result<(), Error> { | ||||||
|         debug!("wait for init event..."); |         debug!("wait for init event..."); | ||||||
|         self.shared.init_wait().await; |         self.shared.init_wait().await; | ||||||
| @@ -82,6 +99,7 @@ impl<'a> Control<'a> { | |||||||
|         Ok(()) |         Ok(()) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Get the current status. | ||||||
|     pub async fn get_status(&mut self) -> Result<Status, Error> { |     pub async fn get_status(&mut self) -> Result<Status, Error> { | ||||||
|         let req = proto::CtrlMsgReqGetApConfig {}; |         let req = proto::CtrlMsgReqGetApConfig {}; | ||||||
|         ioctl!(self, ReqGetApConfig, RespGetApConfig, req, resp); |         ioctl!(self, ReqGetApConfig, RespGetApConfig, req, resp); | ||||||
| @@ -95,6 +113,7 @@ impl<'a> Control<'a> { | |||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Connect to the network identified by ssid using the provided password. | ||||||
|     pub async fn connect(&mut self, ssid: &str, password: &str) -> Result<(), Error> { |     pub async fn connect(&mut self, ssid: &str, password: &str) -> Result<(), Error> { | ||||||
|         let req = proto::CtrlMsgReqConnectAp { |         let req = proto::CtrlMsgReqConnectAp { | ||||||
|             ssid: unwrap!(String::try_from(ssid)), |             ssid: unwrap!(String::try_from(ssid)), | ||||||
| @@ -108,6 +127,7 @@ impl<'a> Control<'a> { | |||||||
|         Ok(()) |         Ok(()) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Disconnect from any currently connected network. | ||||||
|     pub async fn disconnect(&mut self) -> Result<(), Error> { |     pub async fn disconnect(&mut self) -> Result<(), Error> { | ||||||
|         let req = proto::CtrlMsgReqGetStatus {}; |         let req = proto::CtrlMsgReqGetStatus {}; | ||||||
|         ioctl!(self, ReqDisconnectAp, RespDisconnectAp, req, resp); |         ioctl!(self, ReqDisconnectAp, RespDisconnectAp, req, resp); | ||||||
|   | |||||||
| @@ -1,4 +1,6 @@ | |||||||
| #![no_std] | #![no_std] | ||||||
|  | #![doc = include_str!("../README.md")] | ||||||
|  | #![warn(missing_docs)] | ||||||
|  |  | ||||||
| use embassy_futures::select::{select4, Either4}; | use embassy_futures::select::{select4, Either4}; | ||||||
| use embassy_net_driver_channel as ch; | use embassy_net_driver_channel as ch; | ||||||
| @@ -97,12 +99,14 @@ enum InterfaceType { | |||||||
| const MAX_SPI_BUFFER_SIZE: usize = 1600; | const MAX_SPI_BUFFER_SIZE: usize = 1600; | ||||||
| const HEARTBEAT_MAX_GAP: Duration = Duration::from_secs(20); | const HEARTBEAT_MAX_GAP: Duration = Duration::from_secs(20); | ||||||
|  |  | ||||||
|  | /// State for the esp-hosted driver. | ||||||
| pub struct State { | pub struct State { | ||||||
|     shared: Shared, |     shared: Shared, | ||||||
|     ch: ch::State<MTU, 4, 4>, |     ch: ch::State<MTU, 4, 4>, | ||||||
| } | } | ||||||
|  |  | ||||||
| impl State { | impl State { | ||||||
|  |     /// Create a new state. | ||||||
|     pub fn new() -> Self { |     pub fn new() -> Self { | ||||||
|         Self { |         Self { | ||||||
|             shared: Shared::new(), |             shared: Shared::new(), | ||||||
| @@ -111,8 +115,13 @@ impl State { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// Type alias for network driver. | ||||||
| pub type NetDriver<'a> = ch::Device<'a, MTU>; | pub type NetDriver<'a> = ch::Device<'a, MTU>; | ||||||
|  |  | ||||||
|  | /// Create a new esp-hosted driver using the provided state, SPI peripheral and pins. | ||||||
|  | /// | ||||||
|  | /// Returns a device handle for interfacing with embassy-net, a control handle for | ||||||
|  | /// interacting with the driver, and a runner for communicating with the WiFi device. | ||||||
| pub async fn new<'a, SPI, IN, OUT>( | pub async fn new<'a, SPI, IN, OUT>( | ||||||
|     state: &'a mut State, |     state: &'a mut State, | ||||||
|     spi: SPI, |     spi: SPI, | ||||||
| @@ -144,6 +153,7 @@ where | |||||||
|     (device, Control::new(state_ch, &state.shared), runner) |     (device, Control::new(state_ch, &state.shared), runner) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// Runner for communicating with the WiFi device. | ||||||
| pub struct Runner<'a, SPI, IN, OUT> { | pub struct Runner<'a, SPI, IN, OUT> { | ||||||
|     ch: ch::Runner<'a, MTU>, |     ch: ch::Runner<'a, MTU>, | ||||||
|     state_ch: ch::StateRunner<'a>, |     state_ch: ch::StateRunner<'a>, | ||||||
| @@ -166,6 +176,7 @@ where | |||||||
| { | { | ||||||
|     async fn init(&mut self) {} |     async fn init(&mut self) {} | ||||||
|  |  | ||||||
|  |     /// Run the packet processing. | ||||||
|     pub async fn run(mut self) -> ! { |     pub async fn run(mut self) -> ! { | ||||||
|         debug!("resetting..."); |         debug!("resetting..."); | ||||||
|         self.reset.set_low().unwrap(); |         self.reset.set_low().unwrap(); | ||||||
|   | |||||||
| @@ -4,7 +4,7 @@ use heapless::{String, Vec}; | |||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct ScanResult { | pub(crate) struct ScanResult { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub ssid: String<32>, |     pub ssid: String<32>, | ||||||
|     #[noproto(tag = "2")] |     #[noproto(tag = "2")] | ||||||
| @@ -19,7 +19,7 @@ pub struct ScanResult { | |||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct ConnectedStaList { | pub(crate) struct ConnectedStaList { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub mac: String<32>, |     pub mac: String<32>, | ||||||
|     #[noproto(tag = "2")] |     #[noproto(tag = "2")] | ||||||
| @@ -29,14 +29,14 @@ pub struct ConnectedStaList { | |||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgReqGetMacAddress { | pub(crate) struct CtrlMsgReqGetMacAddress { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub mode: u32, |     pub mode: u32, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgRespGetMacAddress { | pub(crate) struct CtrlMsgRespGetMacAddress { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub mac: String<32>, |     pub mac: String<32>, | ||||||
|     #[noproto(tag = "2")] |     #[noproto(tag = "2")] | ||||||
| @@ -45,11 +45,11 @@ pub struct CtrlMsgRespGetMacAddress { | |||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgReqGetMode {} | pub(crate) struct CtrlMsgReqGetMode {} | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgRespGetMode { | pub(crate) struct CtrlMsgRespGetMode { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub mode: u32, |     pub mode: u32, | ||||||
|     #[noproto(tag = "2")] |     #[noproto(tag = "2")] | ||||||
| @@ -58,32 +58,32 @@ pub struct CtrlMsgRespGetMode { | |||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgReqSetMode { | pub(crate) struct CtrlMsgReqSetMode { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub mode: u32, |     pub mode: u32, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgRespSetMode { | pub(crate) struct CtrlMsgRespSetMode { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub resp: u32, |     pub resp: u32, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgReqGetStatus {} | pub(crate) struct CtrlMsgReqGetStatus {} | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgRespGetStatus { | pub(crate) struct CtrlMsgRespGetStatus { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub resp: u32, |     pub resp: u32, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgReqSetMacAddress { | pub(crate) struct CtrlMsgReqSetMacAddress { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub mac: String<32>, |     pub mac: String<32>, | ||||||
|     #[noproto(tag = "2")] |     #[noproto(tag = "2")] | ||||||
| @@ -92,18 +92,18 @@ pub struct CtrlMsgReqSetMacAddress { | |||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgRespSetMacAddress { | pub(crate) struct CtrlMsgRespSetMacAddress { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub resp: u32, |     pub resp: u32, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgReqGetApConfig {} | pub(crate) struct CtrlMsgReqGetApConfig {} | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgRespGetApConfig { | pub(crate) struct CtrlMsgRespGetApConfig { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub ssid: String<32>, |     pub ssid: String<32>, | ||||||
|     #[noproto(tag = "2")] |     #[noproto(tag = "2")] | ||||||
| @@ -120,7 +120,7 @@ pub struct CtrlMsgRespGetApConfig { | |||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgReqConnectAp { | pub(crate) struct CtrlMsgReqConnectAp { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub ssid: String<32>, |     pub ssid: String<32>, | ||||||
|     #[noproto(tag = "2")] |     #[noproto(tag = "2")] | ||||||
| @@ -135,7 +135,7 @@ pub struct CtrlMsgReqConnectAp { | |||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgRespConnectAp { | pub(crate) struct CtrlMsgRespConnectAp { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub resp: u32, |     pub resp: u32, | ||||||
|     #[noproto(tag = "2")] |     #[noproto(tag = "2")] | ||||||
| @@ -144,11 +144,11 @@ pub struct CtrlMsgRespConnectAp { | |||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgReqGetSoftApConfig {} | pub(crate) struct CtrlMsgReqGetSoftApConfig {} | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgRespGetSoftApConfig { | pub(crate) struct CtrlMsgRespGetSoftApConfig { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub ssid: String<32>, |     pub ssid: String<32>, | ||||||
|     #[noproto(tag = "2")] |     #[noproto(tag = "2")] | ||||||
| @@ -169,7 +169,7 @@ pub struct CtrlMsgRespGetSoftApConfig { | |||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgReqStartSoftAp { | pub(crate) struct CtrlMsgReqStartSoftAp { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub ssid: String<32>, |     pub ssid: String<32>, | ||||||
|     #[noproto(tag = "2")] |     #[noproto(tag = "2")] | ||||||
| @@ -188,7 +188,7 @@ pub struct CtrlMsgReqStartSoftAp { | |||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgRespStartSoftAp { | pub(crate) struct CtrlMsgRespStartSoftAp { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub resp: u32, |     pub resp: u32, | ||||||
|     #[noproto(tag = "2")] |     #[noproto(tag = "2")] | ||||||
| @@ -197,11 +197,11 @@ pub struct CtrlMsgRespStartSoftAp { | |||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgReqScanResult {} | pub(crate) struct CtrlMsgReqScanResult {} | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgRespScanResult { | pub(crate) struct CtrlMsgRespScanResult { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub count: u32, |     pub count: u32, | ||||||
|     #[noproto(repeated, tag = "2")] |     #[noproto(repeated, tag = "2")] | ||||||
| @@ -212,11 +212,11 @@ pub struct CtrlMsgRespScanResult { | |||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgReqSoftApConnectedSta {} | pub(crate) struct CtrlMsgReqSoftApConnectedSta {} | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgRespSoftApConnectedSta { | pub(crate) struct CtrlMsgRespSoftApConnectedSta { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub num: u32, |     pub num: u32, | ||||||
|     #[noproto(repeated, tag = "2")] |     #[noproto(repeated, tag = "2")] | ||||||
| @@ -227,43 +227,43 @@ pub struct CtrlMsgRespSoftApConnectedSta { | |||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgReqOtaBegin {} | pub(crate) struct CtrlMsgReqOtaBegin {} | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgRespOtaBegin { | pub(crate) struct CtrlMsgRespOtaBegin { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub resp: u32, |     pub resp: u32, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgReqOtaWrite { | pub(crate) struct CtrlMsgReqOtaWrite { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub ota_data: Vec<u8, 1024>, |     pub ota_data: Vec<u8, 1024>, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgRespOtaWrite { | pub(crate) struct CtrlMsgRespOtaWrite { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub resp: u32, |     pub resp: u32, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgReqOtaEnd {} | pub(crate) struct CtrlMsgReqOtaEnd {} | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgRespOtaEnd { | pub(crate) struct CtrlMsgRespOtaEnd { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub resp: u32, |     pub resp: u32, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgReqVendorIeData { | pub(crate) struct CtrlMsgReqVendorIeData { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub element_id: u32, |     pub element_id: u32, | ||||||
|     #[noproto(tag = "2")] |     #[noproto(tag = "2")] | ||||||
| @@ -278,7 +278,7 @@ pub struct CtrlMsgReqVendorIeData { | |||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgReqSetSoftApVendorSpecificIe { | pub(crate) struct CtrlMsgReqSetSoftApVendorSpecificIe { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub enable: bool, |     pub enable: bool, | ||||||
|     #[noproto(tag = "2")] |     #[noproto(tag = "2")] | ||||||
| @@ -291,32 +291,32 @@ pub struct CtrlMsgReqSetSoftApVendorSpecificIe { | |||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgRespSetSoftApVendorSpecificIe { | pub(crate) struct CtrlMsgRespSetSoftApVendorSpecificIe { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub resp: u32, |     pub resp: u32, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgReqSetWifiMaxTxPower { | pub(crate) struct CtrlMsgReqSetWifiMaxTxPower { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub wifi_max_tx_power: u32, |     pub wifi_max_tx_power: u32, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgRespSetWifiMaxTxPower { | pub(crate) struct CtrlMsgRespSetWifiMaxTxPower { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub resp: u32, |     pub resp: u32, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgReqGetWifiCurrTxPower {} | pub(crate) struct CtrlMsgReqGetWifiCurrTxPower {} | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgRespGetWifiCurrTxPower { | pub(crate) struct CtrlMsgRespGetWifiCurrTxPower { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub wifi_curr_tx_power: u32, |     pub wifi_curr_tx_power: u32, | ||||||
|     #[noproto(tag = "2")] |     #[noproto(tag = "2")] | ||||||
| @@ -325,7 +325,7 @@ pub struct CtrlMsgRespGetWifiCurrTxPower { | |||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgReqConfigHeartbeat { | pub(crate) struct CtrlMsgReqConfigHeartbeat { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub enable: bool, |     pub enable: bool, | ||||||
|     #[noproto(tag = "2")] |     #[noproto(tag = "2")] | ||||||
| @@ -334,7 +334,7 @@ pub struct CtrlMsgReqConfigHeartbeat { | |||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgRespConfigHeartbeat { | pub(crate) struct CtrlMsgRespConfigHeartbeat { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub resp: u32, |     pub resp: u32, | ||||||
| } | } | ||||||
| @@ -342,28 +342,28 @@ pub struct CtrlMsgRespConfigHeartbeat { | |||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgEventEspInit { | pub(crate) struct CtrlMsgEventEspInit { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub init_data: Vec<u8, 64>, |     pub init_data: Vec<u8, 64>, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgEventHeartbeat { | pub(crate) struct CtrlMsgEventHeartbeat { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub hb_num: u32, |     pub hb_num: u32, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgEventStationDisconnectFromAp { | pub(crate) struct CtrlMsgEventStationDisconnectFromAp { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub resp: u32, |     pub resp: u32, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgEventStationDisconnectFromEspSoftAp { | pub(crate) struct CtrlMsgEventStationDisconnectFromEspSoftAp { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub resp: u32, |     pub resp: u32, | ||||||
|     #[noproto(tag = "2")] |     #[noproto(tag = "2")] | ||||||
| @@ -372,7 +372,7 @@ pub struct CtrlMsgEventStationDisconnectFromEspSoftAp { | |||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsg { | pub(crate) struct CtrlMsg { | ||||||
|     /// msg_type could be req, resp or Event |     /// msg_type could be req, resp or Event | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub msg_type: CtrlMsgType, |     pub msg_type: CtrlMsgType, | ||||||
| @@ -390,7 +390,7 @@ pub struct CtrlMsg { | |||||||
| /// union of all msg ids | /// union of all msg ids | ||||||
| #[derive(Debug, Clone, Eq, PartialEq, noproto::Oneof)] | #[derive(Debug, Clone, Eq, PartialEq, noproto::Oneof)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub enum CtrlMsgPayload { | pub(crate) enum CtrlMsgPayload { | ||||||
|     /// * Requests * |     /// * Requests * | ||||||
|     #[noproto(tag = "101")] |     #[noproto(tag = "101")] | ||||||
|     ReqGetMacAddress(CtrlMsgReqGetMacAddress), |     ReqGetMacAddress(CtrlMsgReqGetMacAddress), | ||||||
| @@ -492,7 +492,7 @@ pub enum CtrlMsgPayload { | |||||||
| #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | ||||||
| #[repr(u32)] | #[repr(u32)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub enum CtrlVendorIeType { | pub(crate) enum CtrlVendorIeType { | ||||||
|     #[default] |     #[default] | ||||||
|     Beacon = 0, |     Beacon = 0, | ||||||
|     ProbeReq = 1, |     ProbeReq = 1, | ||||||
| @@ -504,7 +504,7 @@ pub enum CtrlVendorIeType { | |||||||
| #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | ||||||
| #[repr(u32)] | #[repr(u32)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub enum CtrlVendorIeid { | pub(crate) enum CtrlVendorIeid { | ||||||
|     #[default] |     #[default] | ||||||
|     Id0 = 0, |     Id0 = 0, | ||||||
|     Id1 = 1, |     Id1 = 1, | ||||||
| @@ -513,7 +513,7 @@ pub enum CtrlVendorIeid { | |||||||
| #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | ||||||
| #[repr(u32)] | #[repr(u32)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub enum CtrlWifiMode { | pub(crate) enum CtrlWifiMode { | ||||||
|     #[default] |     #[default] | ||||||
|     None = 0, |     None = 0, | ||||||
|     Sta = 1, |     Sta = 1, | ||||||
| @@ -524,7 +524,7 @@ pub enum CtrlWifiMode { | |||||||
| #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | ||||||
| #[repr(u32)] | #[repr(u32)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub enum CtrlWifiBw { | pub(crate) enum CtrlWifiBw { | ||||||
|     #[default] |     #[default] | ||||||
|     BwInvalid = 0, |     BwInvalid = 0, | ||||||
|     Ht20 = 1, |     Ht20 = 1, | ||||||
| @@ -534,13 +534,15 @@ pub enum CtrlWifiBw { | |||||||
| #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | ||||||
| #[repr(u32)] | #[repr(u32)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub enum CtrlWifiPowerSave { | pub(crate) enum CtrlWifiPowerSave { | ||||||
|     #[default] |     #[default] | ||||||
|     PsInvalid = 0, |     PsInvalid = 0, | ||||||
|     MinModem = 1, |     MinModem = 1, | ||||||
|     MaxModem = 2, |     MaxModem = 2, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// Wifi Security Settings | ||||||
|  | #[allow(missing_docs)] | ||||||
| #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | ||||||
| #[repr(u32)] | #[repr(u32)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| @@ -560,7 +562,7 @@ pub enum CtrlWifiSecProt { | |||||||
| #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | ||||||
| #[repr(u32)] | #[repr(u32)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub enum CtrlStatus { | pub(crate) enum CtrlStatus { | ||||||
|     #[default] |     #[default] | ||||||
|     Connected = 0, |     Connected = 0, | ||||||
|     NotConnected = 1, |     NotConnected = 1, | ||||||
| @@ -573,7 +575,7 @@ pub enum CtrlStatus { | |||||||
| #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | ||||||
| #[repr(u32)] | #[repr(u32)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub enum CtrlMsgType { | pub(crate) enum CtrlMsgType { | ||||||
|     #[default] |     #[default] | ||||||
|     MsgTypeInvalid = 0, |     MsgTypeInvalid = 0, | ||||||
|     Req = 1, |     Req = 1, | ||||||
| @@ -585,7 +587,7 @@ pub enum CtrlMsgType { | |||||||
| #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | ||||||
| #[repr(u32)] | #[repr(u32)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub enum CtrlMsgId { | pub(crate) enum CtrlMsgId { | ||||||
|     #[default] |     #[default] | ||||||
|     MsgIdInvalid = 0, |     MsgIdInvalid = 0, | ||||||
|     /// * Request Msgs * |     /// * Request Msgs * | ||||||
|   | |||||||
| @@ -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" } | ||||||
|   | |||||||
| @@ -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)?)?, | ||||||
|   | |||||||
| @@ -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" } | ||||||
|   | |||||||
| @@ -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 {} | ||||||
|   | |||||||
| @@ -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 {} | ||||||
|   | |||||||
| @@ -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 {} | ||||||
|   | |||||||
| @@ -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)); | ||||||
|   | |||||||
| @@ -411,10 +411,12 @@ impl<D: Driver> Stack<D> { | |||||||
|     /// ```ignore |     /// ```ignore | ||||||
|     /// let config = embassy_net::Config::dhcpv4(Default::default()); |     /// let config = embassy_net::Config::dhcpv4(Default::default()); | ||||||
|     ///// Init network stack |     ///// Init network stack | ||||||
|     /// let stack = &*make_static!(embassy_net::Stack::new( |     /// static RESOURCES: StaticCell<embassy_net::StackResources<2> = StaticCell::new(); | ||||||
|  |     /// static STACK: StaticCell<embassy_net::Stack> = StaticCell::new(); | ||||||
|  |     /// let stack = &*STACK.init(embassy_net::Stack::new( | ||||||
|     ///    device, |     ///    device, | ||||||
|     ///    config, |     ///    config, | ||||||
|     ///    make_static!(embassy_net::StackResources::<2>::new()), |     ///    RESOURCES.init(embassy_net::StackResources::new()), | ||||||
|     ///    seed |     ///    seed | ||||||
|     /// )); |     /// )); | ||||||
|     /// // Launch network task that runs `stack.run().await` |     /// // Launch network task that runs `stack.run().await` | ||||||
|   | |||||||
| @@ -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" | ||||||
|   | |||||||
| @@ -24,7 +24,7 @@ | |||||||
| //! use embassy_executor::Spawner; | //! use embassy_executor::Spawner; | ||||||
| //! use embassy_stm32::low_power::Executor; | //! use embassy_stm32::low_power::Executor; | ||||||
| //! use embassy_stm32::rtc::{Rtc, RtcConfig}; | //! use embassy_stm32::rtc::{Rtc, RtcConfig}; | ||||||
| //! use static_cell::make_static; | //! use static_cell::StaticCell; | ||||||
| //! | //! | ||||||
| //! #[cortex_m_rt::entry] | //! #[cortex_m_rt::entry] | ||||||
| //! fn main() -> ! { | //! fn main() -> ! { | ||||||
| @@ -41,7 +41,8 @@ | |||||||
| //! | //! | ||||||
| //!     // give the RTC to the executor... | //!     // give the RTC to the executor... | ||||||
| //!     let mut rtc = Rtc::new(p.RTC, RtcConfig::default()); | //!     let mut rtc = Rtc::new(p.RTC, RtcConfig::default()); | ||||||
| //!     let rtc = make_static!(rtc); | //!     static RTC: StaticCell<Rtc> = StaticCell::new(); | ||||||
|  | //!     let rtc = RTC.init(rtc); | ||||||
| //!     embassy_stm32::low_power::stop_with_rtc(rtc); | //!     embassy_stm32::low_power::stop_with_rtc(rtc); | ||||||
| //! | //! | ||||||
| //!     // your application here... | //!     // your application here... | ||||||
|   | |||||||
| @@ -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)) |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -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| { | ||||||
|   | |||||||
| @@ -14,7 +14,7 @@ use embassy_nrf::{bind_interrupts, peripherals, spim}; | |||||||
| use embassy_time::Delay; | use embassy_time::Delay; | ||||||
| use embedded_hal_bus::spi::ExclusiveDevice; | use embedded_hal_bus::spi::ExclusiveDevice; | ||||||
| use embedded_io_async::Write; | use embedded_io_async::Write; | ||||||
| use static_cell::make_static; | use static_cell::StaticCell; | ||||||
| use {defmt_rtt as _, panic_probe as _}; | use {defmt_rtt as _, panic_probe as _}; | ||||||
|  |  | ||||||
| bind_interrupts!(struct Irqs { | bind_interrupts!(struct Irqs { | ||||||
| @@ -70,11 +70,20 @@ async fn main(spawner: Spawner) { | |||||||
|     let seed = u64::from_le_bytes(seed); |     let seed = u64::from_le_bytes(seed); | ||||||
|  |  | ||||||
|     // Init network stack |     // Init network stack | ||||||
|     let stack = &*make_static!(Stack::new( |     static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | ||||||
|  |     static STACK: StaticCell< | ||||||
|  |         Stack< | ||||||
|  |             Enc28j60< | ||||||
|  |                 ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static, peripherals::P0_15>, Delay>, | ||||||
|  |                 Output<'static, peripherals::P0_13>, | ||||||
|  |             >, | ||||||
|  |         >, | ||||||
|  |     > = StaticCell::new(); | ||||||
|  |     let stack = STACK.init(Stack::new( | ||||||
|         device, |         device, | ||||||
|         config, |         config, | ||||||
|         make_static!(StackResources::<2>::new()), |         RESOURCES.init(StackResources::<2>::new()), | ||||||
|         seed |         seed, | ||||||
|     )); |     )); | ||||||
|  |  | ||||||
|     unwrap!(spawner.spawn(net_task(stack))); |     unwrap!(spawner.spawn(net_task(stack))); | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ use embassy_usb::class::cdc_ncm::embassy_net::{Device, Runner, State as NetState | |||||||
| use embassy_usb::class::cdc_ncm::{CdcNcmClass, State}; | use embassy_usb::class::cdc_ncm::{CdcNcmClass, State}; | ||||||
| use embassy_usb::{Builder, Config, UsbDevice}; | use embassy_usb::{Builder, Config, UsbDevice}; | ||||||
| use embedded_io_async::Write; | use embedded_io_async::Write; | ||||||
| use static_cell::make_static; | use static_cell::StaticCell; | ||||||
| use {defmt_rtt as _, panic_probe as _}; | use {defmt_rtt as _, panic_probe as _}; | ||||||
|  |  | ||||||
| bind_interrupts!(struct Irqs { | bind_interrupts!(struct Irqs { | ||||||
| @@ -71,14 +71,19 @@ async fn main(spawner: Spawner) { | |||||||
|     config.device_protocol = 0x01; |     config.device_protocol = 0x01; | ||||||
|  |  | ||||||
|     // Create embassy-usb DeviceBuilder using the driver and config. |     // Create embassy-usb DeviceBuilder using the driver and config. | ||||||
|  |     static DEVICE_DESC: StaticCell<[u8; 256]> = StaticCell::new(); | ||||||
|  |     static CONFIG_DESC: StaticCell<[u8; 256]> = StaticCell::new(); | ||||||
|  |     static BOS_DESC: StaticCell<[u8; 256]> = StaticCell::new(); | ||||||
|  |     static MSOS_DESC: StaticCell<[u8; 128]> = StaticCell::new(); | ||||||
|  |     static CONTROL_BUF: StaticCell<[u8; 128]> = StaticCell::new(); | ||||||
|     let mut builder = Builder::new( |     let mut builder = Builder::new( | ||||||
|         driver, |         driver, | ||||||
|         config, |         config, | ||||||
|         &mut make_static!([0; 256])[..], |         &mut DEVICE_DESC.init([0; 256])[..], | ||||||
|         &mut make_static!([0; 256])[..], |         &mut CONFIG_DESC.init([0; 256])[..], | ||||||
|         &mut make_static!([0; 256])[..], |         &mut BOS_DESC.init([0; 256])[..], | ||||||
|         &mut make_static!([0; 128])[..], |         &mut MSOS_DESC.init([0; 128])[..], | ||||||
|         &mut make_static!([0; 128])[..], |         &mut CONTROL_BUF.init([0; 128])[..], | ||||||
|     ); |     ); | ||||||
|  |  | ||||||
|     // Our MAC addr. |     // Our MAC addr. | ||||||
| @@ -87,14 +92,16 @@ async fn main(spawner: Spawner) { | |||||||
|     let host_mac_addr = [0x88, 0x88, 0x88, 0x88, 0x88, 0x88]; |     let host_mac_addr = [0x88, 0x88, 0x88, 0x88, 0x88, 0x88]; | ||||||
|  |  | ||||||
|     // Create classes on the builder. |     // Create classes on the builder. | ||||||
|     let class = CdcNcmClass::new(&mut builder, make_static!(State::new()), host_mac_addr, 64); |     static STATE: StaticCell<State> = StaticCell::new(); | ||||||
|  |     let class = CdcNcmClass::new(&mut builder, STATE.init(State::new()), host_mac_addr, 64); | ||||||
|  |  | ||||||
|     // Build the builder. |     // Build the builder. | ||||||
|     let usb = builder.build(); |     let usb = builder.build(); | ||||||
|  |  | ||||||
|     unwrap!(spawner.spawn(usb_task(usb))); |     unwrap!(spawner.spawn(usb_task(usb))); | ||||||
|  |  | ||||||
|     let (runner, device) = class.into_embassy_net_device::<MTU, 4, 4>(make_static!(NetState::new()), our_mac_addr); |     static NET_STATE: StaticCell<NetState<MTU, 4, 4>> = StaticCell::new(); | ||||||
|  |     let (runner, device) = class.into_embassy_net_device::<MTU, 4, 4>(NET_STATE.init(NetState::new()), our_mac_addr); | ||||||
|     unwrap!(spawner.spawn(usb_ncm_task(runner))); |     unwrap!(spawner.spawn(usb_ncm_task(runner))); | ||||||
|  |  | ||||||
|     let config = embassy_net::Config::dhcpv4(Default::default()); |     let config = embassy_net::Config::dhcpv4(Default::default()); | ||||||
| @@ -111,12 +118,9 @@ async fn main(spawner: Spawner) { | |||||||
|     let seed = u64::from_le_bytes(seed); |     let seed = u64::from_le_bytes(seed); | ||||||
|  |  | ||||||
|     // Init network stack |     // Init network stack | ||||||
|     let stack = &*make_static!(Stack::new( |     static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | ||||||
|         device, |     static STACK: StaticCell<Stack<Device<'static, MTU>>> = StaticCell::new(); | ||||||
|         config, |     let stack = &*STACK.init(Stack::new(device, config, RESOURCES.init(StackResources::new()), seed)); | ||||||
|         make_static!(StackResources::<2>::new()), |  | ||||||
|         seed |  | ||||||
|     )); |  | ||||||
|  |  | ||||||
|     unwrap!(spawner.spawn(net_task(stack))); |     unwrap!(spawner.spawn(net_task(stack))); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ use embassy_nrf::{bind_interrupts, pac, peripherals, usb}; | |||||||
| use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; | ||||||
| use embassy_usb::driver::EndpointError; | use embassy_usb::driver::EndpointError; | ||||||
| use embassy_usb::{Builder, Config, UsbDevice}; | use embassy_usb::{Builder, Config, UsbDevice}; | ||||||
| use static_cell::make_static; | use static_cell::StaticCell; | ||||||
| use {defmt_rtt as _, panic_probe as _}; | use {defmt_rtt as _, panic_probe as _}; | ||||||
|  |  | ||||||
| bind_interrupts!(struct Irqs { | bind_interrupts!(struct Irqs { | ||||||
| @@ -64,17 +64,23 @@ async fn main(spawner: Spawner) { | |||||||
|     config.device_protocol = 0x01; |     config.device_protocol = 0x01; | ||||||
|     config.composite_with_iads = true; |     config.composite_with_iads = true; | ||||||
|  |  | ||||||
|     let state = make_static!(State::new()); |     static STATE: StaticCell<State> = StaticCell::new(); | ||||||
|  |     let state = STATE.init(State::new()); | ||||||
|  |  | ||||||
|     // Create embassy-usb DeviceBuilder using the driver and config. |     // Create embassy-usb DeviceBuilder using the driver and config. | ||||||
|  |     static DEVICE_DESC: StaticCell<[u8; 256]> = StaticCell::new(); | ||||||
|  |     static CONFIG_DESC: StaticCell<[u8; 256]> = StaticCell::new(); | ||||||
|  |     static BOS_DESC: StaticCell<[u8; 256]> = StaticCell::new(); | ||||||
|  |     static MSOS_DESC: StaticCell<[u8; 128]> = StaticCell::new(); | ||||||
|  |     static CONTROL_BUF: StaticCell<[u8; 128]> = StaticCell::new(); | ||||||
|     let mut builder = Builder::new( |     let mut builder = Builder::new( | ||||||
|         driver, |         driver, | ||||||
|         config, |         config, | ||||||
|         &mut make_static!([0; 256])[..], |         &mut DEVICE_DESC.init([0; 256])[..], | ||||||
|         &mut make_static!([0; 256])[..], |         &mut CONFIG_DESC.init([0; 256])[..], | ||||||
|         &mut make_static!([0; 256])[..], |         &mut BOS_DESC.init([0; 256])[..], | ||||||
|         &mut make_static!([0; 128])[..], |         &mut MSOS_DESC.init([0; 128])[..], | ||||||
|         &mut make_static!([0; 128])[..], |         &mut CONTROL_BUF.init([0; 128])[..], | ||||||
|     ); |     ); | ||||||
|  |  | ||||||
|     // Create classes on the builder. |     // Create classes on the builder. | ||||||
|   | |||||||
| @@ -13,7 +13,7 @@ use embassy_nrf::{bind_interrupts, peripherals}; | |||||||
| use embassy_time::Delay; | use embassy_time::Delay; | ||||||
| use embedded_hal_bus::spi::ExclusiveDevice; | use embedded_hal_bus::spi::ExclusiveDevice; | ||||||
| use embedded_io_async::Write; | use embedded_io_async::Write; | ||||||
| use static_cell::make_static; | use static_cell::StaticCell; | ||||||
| use {defmt_rtt as _, embassy_net_esp_hosted as hosted, panic_probe as _}; | use {defmt_rtt as _, embassy_net_esp_hosted as hosted, panic_probe as _}; | ||||||
|  |  | ||||||
| const WIFI_NETWORK: &str = "EmbassyTest"; | const WIFI_NETWORK: &str = "EmbassyTest"; | ||||||
| @@ -61,8 +61,9 @@ async fn main(spawner: Spawner) { | |||||||
|     let spi = spim::Spim::new(p.SPI3, Irqs, sck, miso, mosi, config); |     let spi = spim::Spim::new(p.SPI3, Irqs, sck, miso, mosi, config); | ||||||
|     let spi = ExclusiveDevice::new(spi, cs, Delay); |     let spi = ExclusiveDevice::new(spi, cs, Delay); | ||||||
|  |  | ||||||
|  |     static ESP_STATE: StaticCell<embassy_net_esp_hosted::State> = StaticCell::new(); | ||||||
|     let (device, mut control, runner) = embassy_net_esp_hosted::new( |     let (device, mut control, runner) = embassy_net_esp_hosted::new( | ||||||
|         make_static!(embassy_net_esp_hosted::State::new()), |         ESP_STATE.init(embassy_net_esp_hosted::State::new()), | ||||||
|         spi, |         spi, | ||||||
|         handshake, |         handshake, | ||||||
|         ready, |         ready, | ||||||
| @@ -89,11 +90,13 @@ async fn main(spawner: Spawner) { | |||||||
|     let seed = u64::from_le_bytes(seed); |     let seed = u64::from_le_bytes(seed); | ||||||
|  |  | ||||||
|     // Init network stack |     // Init network stack | ||||||
|     let stack = &*make_static!(Stack::new( |     static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | ||||||
|  |     static STACK: StaticCell<Stack<hosted::NetDriver<'static>>> = StaticCell::new(); | ||||||
|  |     let stack = &*STACK.init(Stack::new( | ||||||
|         device, |         device, | ||||||
|         config, |         config, | ||||||
|         make_static!(StackResources::<2>::new()), |         RESOURCES.init(StackResources::<2>::new()), | ||||||
|         seed |         seed, | ||||||
|     )); |     )); | ||||||
|  |  | ||||||
|     unwrap!(spawner.spawn(net_task(stack))); |     unwrap!(spawner.spawn(net_task(stack))); | ||||||
|   | |||||||
| @@ -20,7 +20,7 @@ use embassy_time::{Delay, Duration}; | |||||||
| use embedded_hal_bus::spi::ExclusiveDevice; | use embedded_hal_bus::spi::ExclusiveDevice; | ||||||
| use embedded_io_async::Write; | use embedded_io_async::Write; | ||||||
| use rand::RngCore; | use rand::RngCore; | ||||||
| use static_cell::make_static; | use static_cell::StaticCell; | ||||||
| use {defmt_rtt as _, panic_probe as _}; | use {defmt_rtt as _, panic_probe as _}; | ||||||
|  |  | ||||||
| #[embassy_executor::task] | #[embassy_executor::task] | ||||||
| @@ -55,7 +55,8 @@ async fn main(spawner: Spawner) { | |||||||
|     let w5500_reset = Output::new(p.PIN_20, Level::High); |     let w5500_reset = Output::new(p.PIN_20, Level::High); | ||||||
|  |  | ||||||
|     let mac_addr = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00]; |     let mac_addr = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00]; | ||||||
|     let state = make_static!(State::<8, 8>::new()); |     static STATE: StaticCell<State<8, 8>> = StaticCell::new(); | ||||||
|  |     let state = STATE.init(State::<8, 8>::new()); | ||||||
|     let (device, runner) = embassy_net_wiznet::new( |     let (device, runner) = embassy_net_wiznet::new( | ||||||
|         mac_addr, |         mac_addr, | ||||||
|         state, |         state, | ||||||
| @@ -70,11 +71,13 @@ async fn main(spawner: Spawner) { | |||||||
|     let seed = rng.next_u64(); |     let seed = rng.next_u64(); | ||||||
|  |  | ||||||
|     // Init network stack |     // Init network stack | ||||||
|     let stack = &*make_static!(Stack::new( |     static STACK: StaticCell<Stack<Device<'static>>> = StaticCell::new(); | ||||||
|  |     static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new(); | ||||||
|  |     let stack = &*STACK.init(Stack::new( | ||||||
|         device, |         device, | ||||||
|         embassy_net::Config::dhcpv4(Default::default()), |         embassy_net::Config::dhcpv4(Default::default()), | ||||||
|         make_static!(StackResources::<3>::new()), |         RESOURCES.init(StackResources::<3>::new()), | ||||||
|         seed |         seed, | ||||||
|     )); |     )); | ||||||
|  |  | ||||||
|     // Launch network task |     // Launch network task | ||||||
|   | |||||||
| @@ -22,7 +22,7 @@ use embassy_time::{Delay, Duration, Timer}; | |||||||
| use embedded_hal_bus::spi::ExclusiveDevice; | use embedded_hal_bus::spi::ExclusiveDevice; | ||||||
| use embedded_io_async::Write; | use embedded_io_async::Write; | ||||||
| use rand::RngCore; | use rand::RngCore; | ||||||
| use static_cell::make_static; | use static_cell::StaticCell; | ||||||
| use {defmt_rtt as _, panic_probe as _}; | use {defmt_rtt as _, panic_probe as _}; | ||||||
|  |  | ||||||
| #[embassy_executor::task] | #[embassy_executor::task] | ||||||
| @@ -58,7 +58,8 @@ async fn main(spawner: Spawner) { | |||||||
|     let w5500_reset = Output::new(p.PIN_20, Level::High); |     let w5500_reset = Output::new(p.PIN_20, Level::High); | ||||||
|  |  | ||||||
|     let mac_addr = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00]; |     let mac_addr = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00]; | ||||||
|     let state = make_static!(State::<8, 8>::new()); |     static STATE: StaticCell<State<8, 8>> = StaticCell::new(); | ||||||
|  |     let state = STATE.init(State::<8, 8>::new()); | ||||||
|     let (device, runner) = embassy_net_wiznet::new( |     let (device, runner) = embassy_net_wiznet::new( | ||||||
|         mac_addr, |         mac_addr, | ||||||
|         state, |         state, | ||||||
| @@ -73,11 +74,13 @@ async fn main(spawner: Spawner) { | |||||||
|     let seed = rng.next_u64(); |     let seed = rng.next_u64(); | ||||||
|  |  | ||||||
|     // Init network stack |     // Init network stack | ||||||
|     let stack = &*make_static!(Stack::new( |     static STACK: StaticCell<Stack<Device<'static>>> = StaticCell::new(); | ||||||
|  |     static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | ||||||
|  |     let stack = &*STACK.init(Stack::new( | ||||||
|         device, |         device, | ||||||
|         embassy_net::Config::dhcpv4(Default::default()), |         embassy_net::Config::dhcpv4(Default::default()), | ||||||
|         make_static!(StackResources::<2>::new()), |         RESOURCES.init(StackResources::<2>::new()), | ||||||
|         seed |         seed, | ||||||
|     )); |     )); | ||||||
|  |  | ||||||
|     // Launch network task |     // Launch network task | ||||||
|   | |||||||
| @@ -21,7 +21,7 @@ use embassy_time::{Delay, Duration}; | |||||||
| use embedded_hal_bus::spi::ExclusiveDevice; | use embedded_hal_bus::spi::ExclusiveDevice; | ||||||
| use embedded_io_async::Write; | use embedded_io_async::Write; | ||||||
| use rand::RngCore; | use rand::RngCore; | ||||||
| use static_cell::make_static; | use static_cell::StaticCell; | ||||||
| use {defmt_rtt as _, panic_probe as _}; | use {defmt_rtt as _, panic_probe as _}; | ||||||
|  |  | ||||||
| #[embassy_executor::task] | #[embassy_executor::task] | ||||||
| @@ -57,7 +57,8 @@ async fn main(spawner: Spawner) { | |||||||
|     let w5500_reset = Output::new(p.PIN_20, Level::High); |     let w5500_reset = Output::new(p.PIN_20, Level::High); | ||||||
|  |  | ||||||
|     let mac_addr = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00]; |     let mac_addr = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00]; | ||||||
|     let state = make_static!(State::<8, 8>::new()); |     static STATE: StaticCell<State<8, 8>> = StaticCell::new(); | ||||||
|  |     let state = STATE.init(State::<8, 8>::new()); | ||||||
|     let (device, runner) = embassy_net_wiznet::new( |     let (device, runner) = embassy_net_wiznet::new( | ||||||
|         mac_addr, |         mac_addr, | ||||||
|         state, |         state, | ||||||
| @@ -72,11 +73,13 @@ async fn main(spawner: Spawner) { | |||||||
|     let seed = rng.next_u64(); |     let seed = rng.next_u64(); | ||||||
|  |  | ||||||
|     // Init network stack |     // Init network stack | ||||||
|     let stack = &*make_static!(Stack::new( |     static STACK: StaticCell<Stack<Device<'static>>> = StaticCell::new(); | ||||||
|  |     static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | ||||||
|  |     let stack = &*STACK.init(Stack::new( | ||||||
|         device, |         device, | ||||||
|         embassy_net::Config::dhcpv4(Default::default()), |         embassy_net::Config::dhcpv4(Default::default()), | ||||||
|         make_static!(StackResources::<2>::new()), |         RESOURCES.init(StackResources::<2>::new()), | ||||||
|         seed |         seed, | ||||||
|     )); |     )); | ||||||
|  |  | ||||||
|     // Launch network task |     // Launch network task | ||||||
|   | |||||||
| @@ -20,7 +20,7 @@ use embassy_rp::spi::{Async, Config as SpiConfig, Spi}; | |||||||
| use embassy_time::Delay; | use embassy_time::Delay; | ||||||
| use embedded_hal_bus::spi::ExclusiveDevice; | use embedded_hal_bus::spi::ExclusiveDevice; | ||||||
| use rand::RngCore; | use rand::RngCore; | ||||||
| use static_cell::make_static; | use static_cell::StaticCell; | ||||||
| use {defmt_rtt as _, panic_probe as _}; | use {defmt_rtt as _, panic_probe as _}; | ||||||
|  |  | ||||||
| #[embassy_executor::task] | #[embassy_executor::task] | ||||||
| @@ -55,7 +55,8 @@ async fn main(spawner: Spawner) { | |||||||
|     let w5500_reset = Output::new(p.PIN_20, Level::High); |     let w5500_reset = Output::new(p.PIN_20, Level::High); | ||||||
|  |  | ||||||
|     let mac_addr = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00]; |     let mac_addr = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00]; | ||||||
|     let state = make_static!(State::<8, 8>::new()); |     static STATE: StaticCell<State<8, 8>> = StaticCell::new(); | ||||||
|  |     let state = STATE.init(State::<8, 8>::new()); | ||||||
|     let (device, runner) = embassy_net_wiznet::new( |     let (device, runner) = embassy_net_wiznet::new( | ||||||
|         mac_addr, |         mac_addr, | ||||||
|         state, |         state, | ||||||
| @@ -70,11 +71,13 @@ async fn main(spawner: Spawner) { | |||||||
|     let seed = rng.next_u64(); |     let seed = rng.next_u64(); | ||||||
|  |  | ||||||
|     // Init network stack |     // Init network stack | ||||||
|     let stack = &*make_static!(Stack::new( |     static STACK: StaticCell<Stack<Device<'static>>> = StaticCell::new(); | ||||||
|  |     static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | ||||||
|  |     let stack = &*STACK.init(Stack::new( | ||||||
|         device, |         device, | ||||||
|         embassy_net::Config::dhcpv4(Default::default()), |         embassy_net::Config::dhcpv4(Default::default()), | ||||||
|         make_static!(StackResources::<2>::new()), |         RESOURCES.init(StackResources::<2>::new()), | ||||||
|         seed |         seed, | ||||||
|     )); |     )); | ||||||
|  |  | ||||||
|     // Launch network task |     // Launch network task | ||||||
|   | |||||||
| @@ -15,7 +15,7 @@ use embassy_rp::peripherals::UART0; | |||||||
| use embassy_rp::uart::{BufferedInterruptHandler, BufferedUart, BufferedUartRx, Config}; | use embassy_rp::uart::{BufferedInterruptHandler, BufferedUart, BufferedUartRx, Config}; | ||||||
| use embassy_time::Timer; | use embassy_time::Timer; | ||||||
| use embedded_io_async::{Read, Write}; | use embedded_io_async::{Read, Write}; | ||||||
| use static_cell::make_static; | use static_cell::StaticCell; | ||||||
| use {defmt_rtt as _, panic_probe as _}; | use {defmt_rtt as _, panic_probe as _}; | ||||||
|  |  | ||||||
| bind_interrupts!(struct Irqs { | bind_interrupts!(struct Irqs { | ||||||
| @@ -27,8 +27,10 @@ async fn main(spawner: Spawner) { | |||||||
|     let p = embassy_rp::init(Default::default()); |     let p = embassy_rp::init(Default::default()); | ||||||
|     let (tx_pin, rx_pin, uart) = (p.PIN_0, p.PIN_1, p.UART0); |     let (tx_pin, rx_pin, uart) = (p.PIN_0, p.PIN_1, p.UART0); | ||||||
|  |  | ||||||
|     let tx_buf = &mut make_static!([0u8; 16])[..]; |     static TX_BUF: StaticCell<[u8; 16]> = StaticCell::new(); | ||||||
|     let rx_buf = &mut make_static!([0u8; 16])[..]; |     let tx_buf = &mut TX_BUF.init([0; 16])[..]; | ||||||
|  |     static RX_BUF: StaticCell<[u8; 16]> = StaticCell::new(); | ||||||
|  |     let rx_buf = &mut RX_BUF.init([0; 16])[..]; | ||||||
|     let uart = BufferedUart::new(uart, Irqs, tx_pin, rx_pin, tx_buf, rx_buf, Config::default()); |     let uart = BufferedUart::new(uart, Irqs, tx_pin, rx_pin, tx_buf, rx_buf, Config::default()); | ||||||
|     let (rx, mut tx) = uart.split(); |     let (rx, mut tx) = uart.split(); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -17,7 +17,7 @@ use embassy_usb::class::cdc_ncm::embassy_net::{Device, Runner, State as NetState | |||||||
| use embassy_usb::class::cdc_ncm::{CdcNcmClass, State}; | use embassy_usb::class::cdc_ncm::{CdcNcmClass, State}; | ||||||
| use embassy_usb::{Builder, Config, UsbDevice}; | use embassy_usb::{Builder, Config, UsbDevice}; | ||||||
| use embedded_io_async::Write; | use embedded_io_async::Write; | ||||||
| use static_cell::make_static; | use static_cell::StaticCell; | ||||||
| use {defmt_rtt as _, panic_probe as _}; | use {defmt_rtt as _, panic_probe as _}; | ||||||
|  |  | ||||||
| bind_interrupts!(struct Irqs { | bind_interrupts!(struct Irqs { | ||||||
| @@ -65,14 +65,18 @@ async fn main(spawner: Spawner) { | |||||||
|     config.device_protocol = 0x01; |     config.device_protocol = 0x01; | ||||||
|  |  | ||||||
|     // Create embassy-usb DeviceBuilder using the driver and config. |     // Create embassy-usb DeviceBuilder using the driver and config. | ||||||
|  |     static DEVICE_DESC: StaticCell<[u8; 256]> = StaticCell::new(); | ||||||
|  |     static CONFIG_DESC: StaticCell<[u8; 256]> = StaticCell::new(); | ||||||
|  |     static BOS_DESC: StaticCell<[u8; 256]> = StaticCell::new(); | ||||||
|  |     static CONTROL_BUF: StaticCell<[u8; 128]> = StaticCell::new(); | ||||||
|     let mut builder = Builder::new( |     let mut builder = Builder::new( | ||||||
|         driver, |         driver, | ||||||
|         config, |         config, | ||||||
|         &mut make_static!([0; 256])[..], |         &mut DEVICE_DESC.init([0; 256])[..], | ||||||
|         &mut make_static!([0; 256])[..], |         &mut CONFIG_DESC.init([0; 256])[..], | ||||||
|         &mut make_static!([0; 256])[..], |         &mut BOS_DESC.init([0; 256])[..], | ||||||
|         &mut [], // no msos descriptors |         &mut [], // no msos descriptors | ||||||
|         &mut make_static!([0; 128])[..], |         &mut CONTROL_BUF.init([0; 128])[..], | ||||||
|     ); |     ); | ||||||
|  |  | ||||||
|     // Our MAC addr. |     // Our MAC addr. | ||||||
| @@ -81,14 +85,16 @@ async fn main(spawner: Spawner) { | |||||||
|     let host_mac_addr = [0x88, 0x88, 0x88, 0x88, 0x88, 0x88]; |     let host_mac_addr = [0x88, 0x88, 0x88, 0x88, 0x88, 0x88]; | ||||||
|  |  | ||||||
|     // Create classes on the builder. |     // Create classes on the builder. | ||||||
|     let class = CdcNcmClass::new(&mut builder, make_static!(State::new()), host_mac_addr, 64); |     static STATE: StaticCell<State> = StaticCell::new(); | ||||||
|  |     let class = CdcNcmClass::new(&mut builder, STATE.init(State::new()), host_mac_addr, 64); | ||||||
|  |  | ||||||
|     // Build the builder. |     // Build the builder. | ||||||
|     let usb = builder.build(); |     let usb = builder.build(); | ||||||
|  |  | ||||||
|     unwrap!(spawner.spawn(usb_task(usb))); |     unwrap!(spawner.spawn(usb_task(usb))); | ||||||
|  |  | ||||||
|     let (runner, device) = class.into_embassy_net_device::<MTU, 4, 4>(make_static!(NetState::new()), our_mac_addr); |     static NET_STATE: StaticCell<NetState<MTU, 4, 4>> = StaticCell::new(); | ||||||
|  |     let (runner, device) = class.into_embassy_net_device::<MTU, 4, 4>(NET_STATE.init(NetState::new()), our_mac_addr); | ||||||
|     unwrap!(spawner.spawn(usb_ncm_task(runner))); |     unwrap!(spawner.spawn(usb_ncm_task(runner))); | ||||||
|  |  | ||||||
|     let config = embassy_net::Config::dhcpv4(Default::default()); |     let config = embassy_net::Config::dhcpv4(Default::default()); | ||||||
| @@ -102,11 +108,13 @@ async fn main(spawner: Spawner) { | |||||||
|     let seed = 1234; // guaranteed random, chosen by a fair dice roll |     let seed = 1234; // guaranteed random, chosen by a fair dice roll | ||||||
|  |  | ||||||
|     // Init network stack |     // Init network stack | ||||||
|     let stack = &*make_static!(Stack::new( |     static STACK: StaticCell<Stack<Device<'static, MTU>>> = StaticCell::new(); | ||||||
|  |     static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | ||||||
|  |     let stack = &*STACK.init(Stack::new( | ||||||
|         device, |         device, | ||||||
|         config, |         config, | ||||||
|         make_static!(StackResources::<2>::new()), |         RESOURCES.init(StackResources::<2>::new()), | ||||||
|         seed |         seed, | ||||||
|     )); |     )); | ||||||
|  |  | ||||||
|     unwrap!(spawner.spawn(net_task(stack))); |     unwrap!(spawner.spawn(net_task(stack))); | ||||||
|   | |||||||
| @@ -19,7 +19,7 @@ use embassy_rp::peripherals::{DMA_CH0, PIN_23, PIN_25, PIO0}; | |||||||
| use embassy_rp::pio::{InterruptHandler, Pio}; | use embassy_rp::pio::{InterruptHandler, Pio}; | ||||||
| use embassy_time::Duration; | use embassy_time::Duration; | ||||||
| use embedded_io_async::Write; | use embedded_io_async::Write; | ||||||
| use static_cell::make_static; | use static_cell::StaticCell; | ||||||
| use {defmt_rtt as _, panic_probe as _}; | use {defmt_rtt as _, panic_probe as _}; | ||||||
|  |  | ||||||
| bind_interrupts!(struct Irqs { | bind_interrupts!(struct Irqs { | ||||||
| @@ -59,7 +59,8 @@ async fn main(spawner: Spawner) { | |||||||
|     let mut pio = Pio::new(p.PIO0, Irqs); |     let mut pio = Pio::new(p.PIO0, Irqs); | ||||||
|     let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0); |     let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0); | ||||||
|  |  | ||||||
|     let state = make_static!(cyw43::State::new()); |     static STATE: StaticCell<cyw43::State> = StaticCell::new(); | ||||||
|  |     let state = STATE.init(cyw43::State::new()); | ||||||
|     let (net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await; |     let (net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await; | ||||||
|     unwrap!(spawner.spawn(wifi_task(runner))); |     unwrap!(spawner.spawn(wifi_task(runner))); | ||||||
|  |  | ||||||
| @@ -79,11 +80,13 @@ async fn main(spawner: Spawner) { | |||||||
|     let seed = 0x0123_4567_89ab_cdef; // chosen by fair dice roll. guarenteed to be random. |     let seed = 0x0123_4567_89ab_cdef; // chosen by fair dice roll. guarenteed to be random. | ||||||
|  |  | ||||||
|     // Init network stack |     // Init network stack | ||||||
|     let stack = &*make_static!(Stack::new( |     static STACK: StaticCell<Stack<cyw43::NetDriver<'static>>> = StaticCell::new(); | ||||||
|  |     static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | ||||||
|  |     let stack = &*STACK.init(Stack::new( | ||||||
|         net_device, |         net_device, | ||||||
|         config, |         config, | ||||||
|         make_static!(StackResources::<2>::new()), |         RESOURCES.init(StackResources::<2>::new()), | ||||||
|         seed |         seed, | ||||||
|     )); |     )); | ||||||
|  |  | ||||||
|     unwrap!(spawner.spawn(net_task(stack))); |     unwrap!(spawner.spawn(net_task(stack))); | ||||||
|   | |||||||
| @@ -14,7 +14,7 @@ use embassy_rp::gpio::{Level, Output}; | |||||||
| use embassy_rp::peripherals::{DMA_CH0, PIN_23, PIN_25, PIO0}; | use embassy_rp::peripherals::{DMA_CH0, PIN_23, PIN_25, PIO0}; | ||||||
| use embassy_rp::pio::{InterruptHandler, Pio}; | use embassy_rp::pio::{InterruptHandler, Pio}; | ||||||
| use embassy_time::{Duration, Timer}; | use embassy_time::{Duration, Timer}; | ||||||
| use static_cell::make_static; | use static_cell::StaticCell; | ||||||
| use {defmt_rtt as _, panic_probe as _}; | use {defmt_rtt as _, panic_probe as _}; | ||||||
|  |  | ||||||
| bind_interrupts!(struct Irqs { | bind_interrupts!(struct Irqs { | ||||||
| @@ -46,7 +46,8 @@ async fn main(spawner: Spawner) { | |||||||
|     let mut pio = Pio::new(p.PIO0, Irqs); |     let mut pio = Pio::new(p.PIO0, Irqs); | ||||||
|     let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0); |     let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0); | ||||||
|  |  | ||||||
|     let state = make_static!(cyw43::State::new()); |     static STATE: StaticCell<cyw43::State> = StaticCell::new(); | ||||||
|  |     let state = STATE.init(cyw43::State::new()); | ||||||
|     let (_net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await; |     let (_net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await; | ||||||
|     unwrap!(spawner.spawn(wifi_task(runner))); |     unwrap!(spawner.spawn(wifi_task(runner))); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ use embassy_rp::bind_interrupts; | |||||||
| use embassy_rp::gpio::{Level, Output}; | use embassy_rp::gpio::{Level, Output}; | ||||||
| use embassy_rp::peripherals::{DMA_CH0, PIN_23, PIN_25, PIO0}; | use embassy_rp::peripherals::{DMA_CH0, PIN_23, PIN_25, PIO0}; | ||||||
| use embassy_rp::pio::{InterruptHandler, Pio}; | use embassy_rp::pio::{InterruptHandler, Pio}; | ||||||
| use static_cell::make_static; | use static_cell::StaticCell; | ||||||
| use {defmt_rtt as _, panic_probe as _}; | use {defmt_rtt as _, panic_probe as _}; | ||||||
|  |  | ||||||
| bind_interrupts!(struct Irqs { | bind_interrupts!(struct Irqs { | ||||||
| @@ -56,7 +56,8 @@ async fn main(spawner: Spawner) { | |||||||
|     let mut pio = Pio::new(p.PIO0, Irqs); |     let mut pio = Pio::new(p.PIO0, Irqs); | ||||||
|     let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0); |     let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0); | ||||||
|  |  | ||||||
|     let state = make_static!(cyw43::State::new()); |     static STATE: StaticCell<cyw43::State> = StaticCell::new(); | ||||||
|  |     let state = STATE.init(cyw43::State::new()); | ||||||
|     let (_net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await; |     let (_net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await; | ||||||
|     unwrap!(spawner.spawn(wifi_task(runner))); |     unwrap!(spawner.spawn(wifi_task(runner))); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -19,7 +19,7 @@ use embassy_rp::peripherals::{DMA_CH0, PIN_23, PIN_25, PIO0}; | |||||||
| use embassy_rp::pio::{InterruptHandler, Pio}; | use embassy_rp::pio::{InterruptHandler, Pio}; | ||||||
| use embassy_time::{Duration, Timer}; | use embassy_time::{Duration, Timer}; | ||||||
| use embedded_io_async::Write; | use embedded_io_async::Write; | ||||||
| use static_cell::make_static; | use static_cell::StaticCell; | ||||||
| use {defmt_rtt as _, panic_probe as _}; | use {defmt_rtt as _, panic_probe as _}; | ||||||
|  |  | ||||||
| bind_interrupts!(struct Irqs { | bind_interrupts!(struct Irqs { | ||||||
| @@ -62,7 +62,8 @@ async fn main(spawner: Spawner) { | |||||||
|     let mut pio = Pio::new(p.PIO0, Irqs); |     let mut pio = Pio::new(p.PIO0, Irqs); | ||||||
|     let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0); |     let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0); | ||||||
|  |  | ||||||
|     let state = make_static!(cyw43::State::new()); |     static STATE: StaticCell<cyw43::State> = StaticCell::new(); | ||||||
|  |     let state = STATE.init(cyw43::State::new()); | ||||||
|     let (net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await; |     let (net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await; | ||||||
|     unwrap!(spawner.spawn(wifi_task(runner))); |     unwrap!(spawner.spawn(wifi_task(runner))); | ||||||
|  |  | ||||||
| @@ -82,11 +83,13 @@ async fn main(spawner: Spawner) { | |||||||
|     let seed = 0x0123_4567_89ab_cdef; // chosen by fair dice roll. guarenteed to be random. |     let seed = 0x0123_4567_89ab_cdef; // chosen by fair dice roll. guarenteed to be random. | ||||||
|  |  | ||||||
|     // Init network stack |     // Init network stack | ||||||
|     let stack = &*make_static!(Stack::new( |     static STACK: StaticCell<Stack<cyw43::NetDriver<'static>>> = StaticCell::new(); | ||||||
|  |     static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | ||||||
|  |     let stack = &*STACK.init(Stack::new( | ||||||
|         net_device, |         net_device, | ||||||
|         config, |         config, | ||||||
|         make_static!(StackResources::<2>::new()), |         RESOURCES.init(StackResources::<2>::new()), | ||||||
|         seed |         seed, | ||||||
|     )); |     )); | ||||||
|  |  | ||||||
|     unwrap!(spawner.spawn(net_task(stack))); |     unwrap!(spawner.spawn(net_task(stack))); | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ use embedded_io_async::Write; | |||||||
| use heapless::Vec; | use heapless::Vec; | ||||||
| use log::*; | use log::*; | ||||||
| use rand_core::{OsRng, RngCore}; | use rand_core::{OsRng, RngCore}; | ||||||
| use static_cell::{make_static, StaticCell}; | use static_cell::StaticCell; | ||||||
|  |  | ||||||
| #[derive(Parser)] | #[derive(Parser)] | ||||||
| #[clap(version = "1.0")] | #[clap(version = "1.0")] | ||||||
| @@ -54,11 +54,13 @@ async fn main_task(spawner: Spawner) { | |||||||
|     let seed = u64::from_le_bytes(seed); |     let seed = u64::from_le_bytes(seed); | ||||||
|  |  | ||||||
|     // Init network stack |     // Init network stack | ||||||
|     let stack = &*make_static!(Stack::new( |     static STACK: StaticCell<Stack<TunTapDevice>> = StaticCell::new(); | ||||||
|  |     static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new(); | ||||||
|  |     let stack = &*STACK.init(Stack::new( | ||||||
|         device, |         device, | ||||||
|         config, |         config, | ||||||
|         make_static!(StackResources::<3>::new()), |         RESOURCES.init(StackResources::<3>::new()), | ||||||
|         seed |         seed, | ||||||
|     )); |     )); | ||||||
|  |  | ||||||
|     // Launch network task |     // Launch network task | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ use embassy_net_tuntap::TunTapDevice; | |||||||
| use heapless::Vec; | use heapless::Vec; | ||||||
| use log::*; | use log::*; | ||||||
| use rand_core::{OsRng, RngCore}; | use rand_core::{OsRng, RngCore}; | ||||||
| use static_cell::{make_static, StaticCell}; | use static_cell::StaticCell; | ||||||
|  |  | ||||||
| #[derive(Parser)] | #[derive(Parser)] | ||||||
| #[clap(version = "1.0")] | #[clap(version = "1.0")] | ||||||
| @@ -53,11 +53,13 @@ async fn main_task(spawner: Spawner) { | |||||||
|     let seed = u64::from_le_bytes(seed); |     let seed = u64::from_le_bytes(seed); | ||||||
|  |  | ||||||
|     // Init network stack |     // Init network stack | ||||||
|     let stack: &Stack<_> = &*make_static!(Stack::new( |     static STACK: StaticCell<Stack<TunTapDevice>> = StaticCell::new(); | ||||||
|  |     static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new(); | ||||||
|  |     let stack: &Stack<_> = &*STACK.init(Stack::new( | ||||||
|         device, |         device, | ||||||
|         config, |         config, | ||||||
|         make_static!(StackResources::<3>::new()), |         RESOURCES.init(StackResources::<3>::new()), | ||||||
|         seed |         seed, | ||||||
|     )); |     )); | ||||||
|  |  | ||||||
|     // Launch network task |     // Launch network task | ||||||
|   | |||||||
| @@ -25,7 +25,7 @@ use heapless::Vec; | |||||||
| use log::*; | use log::*; | ||||||
| use nix::sys::termios; | use nix::sys::termios; | ||||||
| use rand_core::{OsRng, RngCore}; | use rand_core::{OsRng, RngCore}; | ||||||
| use static_cell::{make_static, StaticCell}; | use static_cell::StaticCell; | ||||||
|  |  | ||||||
| use crate::serial_port::SerialPort; | use crate::serial_port::SerialPort; | ||||||
|  |  | ||||||
| @@ -88,7 +88,8 @@ async fn main_task(spawner: Spawner) { | |||||||
|     let port = SerialPort::new(opts.device.as_str(), baudrate).unwrap(); |     let port = SerialPort::new(opts.device.as_str(), baudrate).unwrap(); | ||||||
|  |  | ||||||
|     // Init network device |     // Init network device | ||||||
|     let state = make_static!(embassy_net_ppp::State::<4, 4>::new()); |     static STATE: StaticCell<embassy_net_ppp::State<4, 4>> = StaticCell::new(); | ||||||
|  |     let state = STATE.init(embassy_net_ppp::State::<4, 4>::new()); | ||||||
|     let (device, runner) = embassy_net_ppp::new(state); |     let (device, runner) = embassy_net_ppp::new(state); | ||||||
|  |  | ||||||
|     // Generate random seed |     // Generate random seed | ||||||
| @@ -97,11 +98,13 @@ async fn main_task(spawner: Spawner) { | |||||||
|     let seed = u64::from_le_bytes(seed); |     let seed = u64::from_le_bytes(seed); | ||||||
|  |  | ||||||
|     // Init network stack |     // Init network stack | ||||||
|     let stack = &*make_static!(Stack::new( |     static STACK: StaticCell<Stack<embassy_net_ppp::Device<'static>>> = StaticCell::new(); | ||||||
|  |     static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new(); | ||||||
|  |     let stack = &*STACK.init(Stack::new( | ||||||
|         device, |         device, | ||||||
|         Config::default(), // don't configure IP yet |         Config::default(), // don't configure IP yet | ||||||
|         make_static!(StackResources::<3>::new()), |         RESOURCES.init(StackResources::<3>::new()), | ||||||
|         seed |         seed, | ||||||
|     )); |     )); | ||||||
|  |  | ||||||
|     // Launch network task |     // Launch network task | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ use embassy_net_tuntap::TunTapDevice; | |||||||
| use heapless::Vec; | use heapless::Vec; | ||||||
| use log::*; | use log::*; | ||||||
| use rand_core::{OsRng, RngCore}; | use rand_core::{OsRng, RngCore}; | ||||||
| use static_cell::{make_static, StaticCell}; | use static_cell::StaticCell; | ||||||
|  |  | ||||||
| #[derive(Parser)] | #[derive(Parser)] | ||||||
| #[clap(version = "1.0")] | #[clap(version = "1.0")] | ||||||
| @@ -50,11 +50,13 @@ async fn main_task(spawner: Spawner) { | |||||||
|     let seed = u64::from_le_bytes(seed); |     let seed = u64::from_le_bytes(seed); | ||||||
|  |  | ||||||
|     // Init network stack |     // Init network stack | ||||||
|     let stack = &*make_static!(Stack::new( |     static STACK: StaticCell<Stack<TunTapDevice>> = StaticCell::new(); | ||||||
|  |     static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new(); | ||||||
|  |     let stack = &*STACK.init(Stack::new( | ||||||
|         device, |         device, | ||||||
|         config, |         config, | ||||||
|         make_static!(StackResources::<3>::new()), |         RESOURCES.init(StackResources::<3>::new()), | ||||||
|         seed |         seed, | ||||||
|     )); |     )); | ||||||
|  |  | ||||||
|     // Launch network task |     // Launch network task | ||||||
|   | |||||||
| @@ -13,7 +13,7 @@ use embedded_io_async::Write as _; | |||||||
| use heapless::Vec; | use heapless::Vec; | ||||||
| use log::*; | use log::*; | ||||||
| use rand_core::{OsRng, RngCore}; | use rand_core::{OsRng, RngCore}; | ||||||
| use static_cell::{make_static, StaticCell}; | use static_cell::StaticCell; | ||||||
|  |  | ||||||
| #[derive(Parser)] | #[derive(Parser)] | ||||||
| #[clap(version = "1.0")] | #[clap(version = "1.0")] | ||||||
| @@ -65,11 +65,13 @@ async fn main_task(spawner: Spawner) { | |||||||
|     let seed = u64::from_le_bytes(seed); |     let seed = u64::from_le_bytes(seed); | ||||||
|  |  | ||||||
|     // Init network stack |     // Init network stack | ||||||
|     let stack = &*make_static!(Stack::new( |     static STACK: StaticCell<Stack<TunTapDevice>> = StaticCell::new(); | ||||||
|  |     static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new(); | ||||||
|  |     let stack = &*STACK.init(Stack::new( | ||||||
|         device, |         device, | ||||||
|         config, |         config, | ||||||
|         make_static!(StackResources::<3>::new()), |         RESOURCES.init(StackResources::<3>::new()), | ||||||
|         seed |         seed, | ||||||
|     )); |     )); | ||||||
|  |  | ||||||
|     // Launch network task |     // Launch network task | ||||||
|   | |||||||
| @@ -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"] } | ||||||
|   | |||||||
| @@ -14,7 +14,7 @@ use embassy_stm32::time::Hertz; | |||||||
| use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; | use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; | ||||||
| use embassy_time::Timer; | use embassy_time::Timer; | ||||||
| use embedded_io_async::Write; | use embedded_io_async::Write; | ||||||
| use static_cell::make_static; | use static_cell::StaticCell; | ||||||
| use {defmt_rtt as _, panic_probe as _}; | use {defmt_rtt as _, panic_probe as _}; | ||||||
|  |  | ||||||
| bind_interrupts!(struct Irqs { | bind_interrupts!(struct Irqs { | ||||||
| @@ -63,8 +63,9 @@ async fn main(spawner: Spawner) -> ! { | |||||||
|  |  | ||||||
|     let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; |     let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; | ||||||
|  |  | ||||||
|  |     static PACKETS: StaticCell<PacketQueue<16, 16>> = StaticCell::new(); | ||||||
|     let device = Ethernet::new( |     let device = Ethernet::new( | ||||||
|         make_static!(PacketQueue::<16, 16>::new()), |         PACKETS.init(PacketQueue::<16, 16>::new()), | ||||||
|         p.ETH, |         p.ETH, | ||||||
|         Irqs, |         Irqs, | ||||||
|         p.PA1, |         p.PA1, | ||||||
| @@ -88,11 +89,13 @@ async fn main(spawner: Spawner) -> ! { | |||||||
|     //}); |     //}); | ||||||
|  |  | ||||||
|     // Init network stack |     // Init network stack | ||||||
|     let stack = &*make_static!(Stack::new( |     static STACK: StaticCell<Stack<Device>> = StaticCell::new(); | ||||||
|  |     static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | ||||||
|  |     let stack = &*STACK.init(Stack::new( | ||||||
|         device, |         device, | ||||||
|         config, |         config, | ||||||
|         make_static!(StackResources::<2>::new()), |         RESOURCES.init(StackResources::<2>::new()), | ||||||
|         seed |         seed, | ||||||
|     )); |     )); | ||||||
|  |  | ||||||
|     // Launch network task |     // Launch network task | ||||||
|   | |||||||
| @@ -14,7 +14,7 @@ use embassy_usb::class::cdc_ncm::embassy_net::{Device, Runner, State as NetState | |||||||
| use embassy_usb::class::cdc_ncm::{CdcNcmClass, State}; | use embassy_usb::class::cdc_ncm::{CdcNcmClass, State}; | ||||||
| use embassy_usb::{Builder, UsbDevice}; | use embassy_usb::{Builder, UsbDevice}; | ||||||
| use embedded_io_async::Write; | use embedded_io_async::Write; | ||||||
| use static_cell::make_static; | use static_cell::StaticCell; | ||||||
| use {defmt_rtt as _, panic_probe as _}; | use {defmt_rtt as _, panic_probe as _}; | ||||||
|  |  | ||||||
| type UsbDriver = Driver<'static, embassy_stm32::peripherals::USB_OTG_FS>; | type UsbDriver = Driver<'static, embassy_stm32::peripherals::USB_OTG_FS>; | ||||||
| @@ -68,7 +68,8 @@ async fn main(spawner: Spawner) { | |||||||
|     let p = embassy_stm32::init(config); |     let p = embassy_stm32::init(config); | ||||||
|  |  | ||||||
|     // Create the driver, from the HAL. |     // Create the driver, from the HAL. | ||||||
|     let ep_out_buffer = &mut make_static!([0; 256])[..]; |     static OUTPUT_BUFFER: StaticCell<[u8; 256]> = StaticCell::new(); | ||||||
|  |     let ep_out_buffer = &mut OUTPUT_BUFFER.init([0; 256])[..]; | ||||||
|     let mut config = embassy_stm32::usb_otg::Config::default(); |     let mut config = embassy_stm32::usb_otg::Config::default(); | ||||||
|     config.vbus_detection = true; |     config.vbus_detection = true; | ||||||
|     let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, ep_out_buffer, config); |     let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, ep_out_buffer, config); | ||||||
| @@ -88,14 +89,18 @@ async fn main(spawner: Spawner) { | |||||||
|     config.device_protocol = 0x01; |     config.device_protocol = 0x01; | ||||||
|  |  | ||||||
|     // Create embassy-usb DeviceBuilder using the driver and config. |     // Create embassy-usb DeviceBuilder using the driver and config. | ||||||
|  |     static DEVICE_DESC: StaticCell<[u8; 256]> = StaticCell::new(); | ||||||
|  |     static CONFIG_DESC: StaticCell<[u8; 256]> = StaticCell::new(); | ||||||
|  |     static BOS_DESC: StaticCell<[u8; 256]> = StaticCell::new(); | ||||||
|  |     static CONTROL_BUF: StaticCell<[u8; 128]> = StaticCell::new(); | ||||||
|     let mut builder = Builder::new( |     let mut builder = Builder::new( | ||||||
|         driver, |         driver, | ||||||
|         config, |         config, | ||||||
|         &mut make_static!([0; 256])[..], |         &mut DEVICE_DESC.init([0; 256])[..], | ||||||
|         &mut make_static!([0; 256])[..], |         &mut CONFIG_DESC.init([0; 256])[..], | ||||||
|         &mut make_static!([0; 256])[..], |         &mut BOS_DESC.init([0; 256])[..], | ||||||
|         &mut [], // no msos descriptors |         &mut [], // no msos descriptors | ||||||
|         &mut make_static!([0; 128])[..], |         &mut CONTROL_BUF.init([0; 128])[..], | ||||||
|     ); |     ); | ||||||
|  |  | ||||||
|     // Our MAC addr. |     // Our MAC addr. | ||||||
| @@ -104,14 +109,16 @@ async fn main(spawner: Spawner) { | |||||||
|     let host_mac_addr = [0x88, 0x88, 0x88, 0x88, 0x88, 0x88]; |     let host_mac_addr = [0x88, 0x88, 0x88, 0x88, 0x88, 0x88]; | ||||||
|  |  | ||||||
|     // Create classes on the builder. |     // Create classes on the builder. | ||||||
|     let class = CdcNcmClass::new(&mut builder, make_static!(State::new()), host_mac_addr, 64); |     static STATE: StaticCell<State> = StaticCell::new(); | ||||||
|  |     let class = CdcNcmClass::new(&mut builder, STATE.init(State::new()), host_mac_addr, 64); | ||||||
|  |  | ||||||
|     // Build the builder. |     // Build the builder. | ||||||
|     let usb = builder.build(); |     let usb = builder.build(); | ||||||
|  |  | ||||||
|     unwrap!(spawner.spawn(usb_task(usb))); |     unwrap!(spawner.spawn(usb_task(usb))); | ||||||
|  |  | ||||||
|     let (runner, device) = class.into_embassy_net_device::<MTU, 4, 4>(make_static!(NetState::new()), our_mac_addr); |     static NET_STATE: StaticCell<NetState<MTU, 4, 4>> = StaticCell::new(); | ||||||
|  |     let (runner, device) = class.into_embassy_net_device::<MTU, 4, 4>(NET_STATE.init(NetState::new()), our_mac_addr); | ||||||
|     unwrap!(spawner.spawn(usb_ncm_task(runner))); |     unwrap!(spawner.spawn(usb_ncm_task(runner))); | ||||||
|  |  | ||||||
|     let config = embassy_net::Config::dhcpv4(Default::default()); |     let config = embassy_net::Config::dhcpv4(Default::default()); | ||||||
| @@ -128,11 +135,13 @@ async fn main(spawner: Spawner) { | |||||||
|     let seed = u64::from_le_bytes(seed); |     let seed = u64::from_le_bytes(seed); | ||||||
|  |  | ||||||
|     // Init network stack |     // Init network stack | ||||||
|     let stack = &*make_static!(Stack::new( |     static STACK: StaticCell<Stack<Device<'static, MTU>>> = StaticCell::new(); | ||||||
|  |     static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | ||||||
|  |     let stack = &*STACK.init(Stack::new( | ||||||
|         device, |         device, | ||||||
|         config, |         config, | ||||||
|         make_static!(StackResources::<2>::new()), |         RESOURCES.init(StackResources::<2>::new()), | ||||||
|         seed |         seed, | ||||||
|     )); |     )); | ||||||
|  |  | ||||||
|     unwrap!(spawner.spawn(net_task(stack))); |     unwrap!(spawner.spawn(net_task(stack))); | ||||||
|   | |||||||
| @@ -12,6 +12,7 @@ use embassy_stm32::can::{ | |||||||
| }; | }; | ||||||
| use embassy_stm32::gpio::{Input, Pull}; | use embassy_stm32::gpio::{Input, Pull}; | ||||||
| use embassy_stm32::peripherals::CAN3; | use embassy_stm32::peripherals::CAN3; | ||||||
|  | use static_cell::StaticCell; | ||||||
| use {defmt_rtt as _, panic_probe as _}; | use {defmt_rtt as _, panic_probe as _}; | ||||||
|  |  | ||||||
| bind_interrupts!(struct Irqs { | bind_interrupts!(struct Irqs { | ||||||
| @@ -43,7 +44,8 @@ async fn main(spawner: Spawner) { | |||||||
|     let rx_pin = Input::new(&mut p.PA15, Pull::Up); |     let rx_pin = Input::new(&mut p.PA15, Pull::Up); | ||||||
|     core::mem::forget(rx_pin); |     core::mem::forget(rx_pin); | ||||||
|  |  | ||||||
|     let can: &'static mut Can<'static, CAN3> = static_cell::make_static!(Can::new(p.CAN3, p.PA8, p.PA15, Irqs)); |     static CAN: StaticCell<Can<'static, CAN3>> = StaticCell::new(); | ||||||
|  |     let can = CAN.init(Can::new(p.CAN3, p.PA8, p.PA15, Irqs)); | ||||||
|     can.as_mut() |     can.as_mut() | ||||||
|         .modify_filters() |         .modify_filters() | ||||||
|         .enable_bank(0, Fifo::Fifo0, Mask32::accept_all()); |         .enable_bank(0, Fifo::Fifo0, Mask32::accept_all()); | ||||||
| @@ -56,7 +58,8 @@ async fn main(spawner: Spawner) { | |||||||
|  |  | ||||||
|     let (tx, mut rx) = can.split(); |     let (tx, mut rx) = can.split(); | ||||||
|  |  | ||||||
|     let tx: &'static mut CanTx<'static, 'static, CAN3> = static_cell::make_static!(tx); |     static CAN_TX: StaticCell<CanTx<'static, 'static, CAN3>> = StaticCell::new(); | ||||||
|  |     let tx = CAN_TX.init(tx); | ||||||
|     spawner.spawn(send_can_message(tx)).unwrap(); |     spawner.spawn(send_can_message(tx)).unwrap(); | ||||||
|  |  | ||||||
|     loop { |     loop { | ||||||
|   | |||||||
| @@ -15,7 +15,7 @@ use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; | |||||||
| use embassy_time::Timer; | use embassy_time::Timer; | ||||||
| use embedded_io_async::Write; | use embedded_io_async::Write; | ||||||
| use rand_core::RngCore; | use rand_core::RngCore; | ||||||
| use static_cell::make_static; | use static_cell::StaticCell; | ||||||
| use {defmt_rtt as _, panic_probe as _}; | use {defmt_rtt as _, panic_probe as _}; | ||||||
|  |  | ||||||
| bind_interrupts!(struct Irqs { | bind_interrupts!(struct Irqs { | ||||||
| @@ -64,8 +64,9 @@ async fn main(spawner: Spawner) -> ! { | |||||||
|  |  | ||||||
|     let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; |     let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; | ||||||
|  |  | ||||||
|  |     static PACKETS: StaticCell<PacketQueue<16, 16>> = StaticCell::new(); | ||||||
|     let device = Ethernet::new( |     let device = Ethernet::new( | ||||||
|         make_static!(PacketQueue::<16, 16>::new()), |         PACKETS.init(PacketQueue::<16, 16>::new()), | ||||||
|         p.ETH, |         p.ETH, | ||||||
|         Irqs, |         Irqs, | ||||||
|         p.PA1, |         p.PA1, | ||||||
| @@ -89,11 +90,13 @@ async fn main(spawner: Spawner) -> ! { | |||||||
|     //}); |     //}); | ||||||
|  |  | ||||||
|     // Init network stack |     // Init network stack | ||||||
|     let stack = &*make_static!(Stack::new( |     static STACK: StaticCell<Stack<Device>> = StaticCell::new(); | ||||||
|  |     static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | ||||||
|  |     let stack = &*STACK.init(Stack::new( | ||||||
|         device, |         device, | ||||||
|         config, |         config, | ||||||
|         make_static!(StackResources::<2>::new()), |         RESOURCES.init(StackResources::<2>::new()), | ||||||
|         seed |         seed, | ||||||
|     )); |     )); | ||||||
|  |  | ||||||
|     // Launch network task |     // Launch network task | ||||||
|   | |||||||
| @@ -18,7 +18,7 @@ use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; | |||||||
| use embassy_time::Timer; | use embassy_time::Timer; | ||||||
| use embedded_io_async::Write; | use embedded_io_async::Write; | ||||||
| use rand_core::RngCore; | use rand_core::RngCore; | ||||||
| use static_cell::make_static; | use static_cell::StaticCell; | ||||||
| use {defmt_rtt as _, panic_probe as _}; | use {defmt_rtt as _, panic_probe as _}; | ||||||
|  |  | ||||||
| bind_interrupts!(struct Irqs { | bind_interrupts!(struct Irqs { | ||||||
| @@ -67,8 +67,9 @@ async fn main(spawner: Spawner) -> ! { | |||||||
|  |  | ||||||
|     let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; |     let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; | ||||||
|  |  | ||||||
|  |     static PACKETS: StaticCell<PacketQueue<4, 4>> = StaticCell::new(); | ||||||
|     let device = Ethernet::new( |     let device = Ethernet::new( | ||||||
|         make_static!(PacketQueue::<4, 4>::new()), |         PACKETS.init(PacketQueue::<4, 4>::new()), | ||||||
|         p.ETH, |         p.ETH, | ||||||
|         Irqs, |         Irqs, | ||||||
|         p.PA1, |         p.PA1, | ||||||
| @@ -92,11 +93,13 @@ async fn main(spawner: Spawner) -> ! { | |||||||
|     //}); |     //}); | ||||||
|  |  | ||||||
|     // Init network stack |     // Init network stack | ||||||
|     let stack = &*make_static!(Stack::new( |     static STACK: StaticCell<Stack<Device>> = StaticCell::new(); | ||||||
|  |     static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | ||||||
|  |     let stack = &*STACK.init(Stack::new( | ||||||
|         device, |         device, | ||||||
|         config, |         config, | ||||||
|         make_static!(StackResources::<2>::new()), |         RESOURCES.init(StackResources::<2>::new()), | ||||||
|         seed |         seed, | ||||||
|     )); |     )); | ||||||
|  |  | ||||||
|     // Launch network task |     // Launch network task | ||||||
|   | |||||||
| @@ -14,7 +14,7 @@ use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; | |||||||
| use embassy_time::Timer; | use embassy_time::Timer; | ||||||
| use embedded_io_async::Write; | use embedded_io_async::Write; | ||||||
| use rand_core::RngCore; | use rand_core::RngCore; | ||||||
| use static_cell::make_static; | use static_cell::StaticCell; | ||||||
| use {defmt_rtt as _, panic_probe as _}; | use {defmt_rtt as _, panic_probe as _}; | ||||||
|  |  | ||||||
| bind_interrupts!(struct Irqs { | bind_interrupts!(struct Irqs { | ||||||
| @@ -64,8 +64,9 @@ async fn main(spawner: Spawner) -> ! { | |||||||
|  |  | ||||||
|     let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; |     let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; | ||||||
|  |  | ||||||
|  |     static PACKETS: StaticCell<PacketQueue<4, 4>> = StaticCell::new(); | ||||||
|     let device = Ethernet::new( |     let device = Ethernet::new( | ||||||
|         make_static!(PacketQueue::<16, 16>::new()), |         PACKETS.init(PacketQueue::<4, 4>::new()), | ||||||
|         p.ETH, |         p.ETH, | ||||||
|         Irqs, |         Irqs, | ||||||
|         p.PA1, |         p.PA1, | ||||||
| @@ -89,11 +90,13 @@ async fn main(spawner: Spawner) -> ! { | |||||||
|     //}); |     //}); | ||||||
|  |  | ||||||
|     // Init network stack |     // Init network stack | ||||||
|     let stack = &*make_static!(Stack::new( |     static STACK: StaticCell<Stack<Device>> = StaticCell::new(); | ||||||
|  |     static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new(); | ||||||
|  |     let stack = &*STACK.init(Stack::new( | ||||||
|         device, |         device, | ||||||
|         config, |         config, | ||||||
|         make_static!(StackResources::<3>::new()), |         RESOURCES.init(StackResources::<3>::new()), | ||||||
|         seed |         seed, | ||||||
|     )); |     )); | ||||||
|  |  | ||||||
|     // Launch network task |     // Launch network task | ||||||
|   | |||||||
| @@ -15,7 +15,7 @@ use embassy_time::Timer; | |||||||
| use embedded_io_async::Write; | use embedded_io_async::Write; | ||||||
| use embedded_nal_async::{Ipv4Addr, SocketAddr, SocketAddrV4, TcpConnect}; | use embedded_nal_async::{Ipv4Addr, SocketAddr, SocketAddrV4, TcpConnect}; | ||||||
| use rand_core::RngCore; | use rand_core::RngCore; | ||||||
| use static_cell::make_static; | use static_cell::StaticCell; | ||||||
| use {defmt_rtt as _, panic_probe as _}; | use {defmt_rtt as _, panic_probe as _}; | ||||||
|  |  | ||||||
| bind_interrupts!(struct Irqs { | bind_interrupts!(struct Irqs { | ||||||
| @@ -65,8 +65,9 @@ async fn main(spawner: Spawner) -> ! { | |||||||
|  |  | ||||||
|     let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; |     let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; | ||||||
|  |  | ||||||
|  |     static PACKETS: StaticCell<PacketQueue<16, 16>> = StaticCell::new(); | ||||||
|     let device = Ethernet::new( |     let device = Ethernet::new( | ||||||
|         make_static!(PacketQueue::<16, 16>::new()), |         PACKETS.init(PacketQueue::<16, 16>::new()), | ||||||
|         p.ETH, |         p.ETH, | ||||||
|         Irqs, |         Irqs, | ||||||
|         p.PA1, |         p.PA1, | ||||||
| @@ -90,11 +91,13 @@ async fn main(spawner: Spawner) -> ! { | |||||||
|     //}); |     //}); | ||||||
|  |  | ||||||
|     // Init network stack |     // Init network stack | ||||||
|     let stack = &*make_static!(Stack::new( |     static STACK: StaticCell<Stack<Device>> = StaticCell::new(); | ||||||
|  |     static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new(); | ||||||
|  |     let stack = &*STACK.init(Stack::new( | ||||||
|         device, |         device, | ||||||
|         config, |         config, | ||||||
|         make_static!(StackResources::<3>::new()), |         RESOURCES.init(StackResources::<3>::new()), | ||||||
|         seed |         seed, | ||||||
|     )); |     )); | ||||||
|  |  | ||||||
|     // Launch network task |     // Launch network task | ||||||
|   | |||||||
| @@ -36,7 +36,7 @@ use hal::rng::{self, Rng}; | |||||||
| use hal::{bind_interrupts, exti, pac, peripherals}; | use hal::{bind_interrupts, exti, pac, peripherals}; | ||||||
| use heapless::Vec; | use heapless::Vec; | ||||||
| use rand::RngCore; | use rand::RngCore; | ||||||
| use static_cell::make_static; | use static_cell::StaticCell; | ||||||
| use {embassy_stm32 as hal, panic_probe as _}; | use {embassy_stm32 as hal, panic_probe as _}; | ||||||
|  |  | ||||||
| bind_interrupts!(struct Irqs { | bind_interrupts!(struct Irqs { | ||||||
| @@ -180,7 +180,8 @@ async fn main(spawner: Spawner) { | |||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     let state = make_static!(embassy_net_adin1110::State::<8, 8>::new()); |     static STATE: StaticCell<embassy_net_adin1110::State<8, 8>> = StaticCell::new(); | ||||||
|  |     let state = STATE.init(embassy_net_adin1110::State::<8, 8>::new()); | ||||||
|  |  | ||||||
|     let (device, runner) = embassy_net_adin1110::new( |     let (device, runner) = embassy_net_adin1110::new( | ||||||
|         MAC, |         MAC, | ||||||
| @@ -217,11 +218,13 @@ async fn main(spawner: Spawner) { | |||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     // Init network stack |     // Init network stack | ||||||
|     let stack = &*make_static!(Stack::new( |     static STACK: StaticCell<Stack<Device<'static>>> = StaticCell::new(); | ||||||
|  |     static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | ||||||
|  |     let stack = &*STACK.init(Stack::new( | ||||||
|         device, |         device, | ||||||
|         ip_cfg, |         ip_cfg, | ||||||
|         make_static!(StackResources::<2>::new()), |         RESOURCES.init(StackResources::<2>::new()), | ||||||
|         seed |         seed, | ||||||
|     )); |     )); | ||||||
|  |  | ||||||
|     // Launch network task |     // Launch network task | ||||||
|   | |||||||
| @@ -15,7 +15,7 @@ use embassy_usb::class::cdc_ncm::{CdcNcmClass, State}; | |||||||
| use embassy_usb::{Builder, UsbDevice}; | use embassy_usb::{Builder, UsbDevice}; | ||||||
| use embedded_io_async::Write; | use embedded_io_async::Write; | ||||||
| use rand_core::RngCore; | use rand_core::RngCore; | ||||||
| use static_cell::make_static; | use static_cell::StaticCell; | ||||||
| use {defmt_rtt as _, panic_probe as _}; | use {defmt_rtt as _, panic_probe as _}; | ||||||
|  |  | ||||||
| type MyDriver = Driver<'static, embassy_stm32::peripherals::USB>; | type MyDriver = Driver<'static, embassy_stm32::peripherals::USB>; | ||||||
| @@ -76,14 +76,18 @@ async fn main(spawner: Spawner) { | |||||||
|     config.device_protocol = 0x01; |     config.device_protocol = 0x01; | ||||||
|  |  | ||||||
|     // Create embassy-usb DeviceBuilder using the driver and config. |     // Create embassy-usb DeviceBuilder using the driver and config. | ||||||
|  |     static DEVICE_DESC: StaticCell<[u8; 256]> = StaticCell::new(); | ||||||
|  |     static CONFIG_DESC: StaticCell<[u8; 256]> = StaticCell::new(); | ||||||
|  |     static BOS_DESC: StaticCell<[u8; 256]> = StaticCell::new(); | ||||||
|  |     static CONTROL_BUF: StaticCell<[u8; 128]> = StaticCell::new(); | ||||||
|     let mut builder = Builder::new( |     let mut builder = Builder::new( | ||||||
|         driver, |         driver, | ||||||
|         config, |         config, | ||||||
|         &mut make_static!([0; 256])[..], |         &mut DEVICE_DESC.init([0; 256])[..], | ||||||
|         &mut make_static!([0; 256])[..], |         &mut CONFIG_DESC.init([0; 256])[..], | ||||||
|         &mut make_static!([0; 256])[..], |         &mut BOS_DESC.init([0; 256])[..], | ||||||
|         &mut [], // no msos descriptors |         &mut [], // no msos descriptors | ||||||
|         &mut make_static!([0; 128])[..], |         &mut CONTROL_BUF.init([0; 128])[..], | ||||||
|     ); |     ); | ||||||
|  |  | ||||||
|     // Our MAC addr. |     // Our MAC addr. | ||||||
| @@ -92,14 +96,16 @@ async fn main(spawner: Spawner) { | |||||||
|     let host_mac_addr = [0x88, 0x88, 0x88, 0x88, 0x88, 0x88]; |     let host_mac_addr = [0x88, 0x88, 0x88, 0x88, 0x88, 0x88]; | ||||||
|  |  | ||||||
|     // Create classes on the builder. |     // Create classes on the builder. | ||||||
|     let class = CdcNcmClass::new(&mut builder, make_static!(State::new()), host_mac_addr, 64); |     static STATE: StaticCell<State> = StaticCell::new(); | ||||||
|  |     let class = CdcNcmClass::new(&mut builder, STATE.init(State::new()), host_mac_addr, 64); | ||||||
|  |  | ||||||
|     // Build the builder. |     // Build the builder. | ||||||
|     let usb = builder.build(); |     let usb = builder.build(); | ||||||
|  |  | ||||||
|     unwrap!(spawner.spawn(usb_task(usb))); |     unwrap!(spawner.spawn(usb_task(usb))); | ||||||
|  |  | ||||||
|     let (runner, device) = class.into_embassy_net_device::<MTU, 4, 4>(make_static!(NetState::new()), our_mac_addr); |     static NET_STATE: StaticCell<NetState<MTU, 4, 4>> = StaticCell::new(); | ||||||
|  |     let (runner, device) = class.into_embassy_net_device::<MTU, 4, 4>(NET_STATE.init(NetState::new()), our_mac_addr); | ||||||
|     unwrap!(spawner.spawn(usb_ncm_task(runner))); |     unwrap!(spawner.spawn(usb_ncm_task(runner))); | ||||||
|  |  | ||||||
|     let config = embassy_net::Config::dhcpv4(Default::default()); |     let config = embassy_net::Config::dhcpv4(Default::default()); | ||||||
| @@ -114,11 +120,13 @@ async fn main(spawner: Spawner) { | |||||||
|     let seed = rng.next_u64(); |     let seed = rng.next_u64(); | ||||||
|  |  | ||||||
|     // Init network stack |     // Init network stack | ||||||
|     let stack = &*make_static!(Stack::new( |     static STACK: StaticCell<Stack<Device<'static, MTU>>> = StaticCell::new(); | ||||||
|  |     static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | ||||||
|  |     let stack = &*STACK.init(Stack::new( | ||||||
|         device, |         device, | ||||||
|         config, |         config, | ||||||
|         make_static!(StackResources::<2>::new()), |         RESOURCES.init(StackResources::<2>::new()), | ||||||
|         seed |         seed, | ||||||
|     )); |     )); | ||||||
|  |  | ||||||
|     unwrap!(spawner.spawn(net_task(stack))); |     unwrap!(spawner.spawn(net_task(stack))); | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ use embassy_stm32_wpan::mac::typedefs::{MacChannel, PanId, PibId}; | |||||||
| use embassy_stm32_wpan::mac::{self, Runner}; | use embassy_stm32_wpan::mac::{self, Runner}; | ||||||
| use embassy_stm32_wpan::sub::mm; | use embassy_stm32_wpan::sub::mm; | ||||||
| use embassy_stm32_wpan::TlMbox; | use embassy_stm32_wpan::TlMbox; | ||||||
| use static_cell::make_static; | use static_cell::StaticCell; | ||||||
| use {defmt_rtt as _, panic_probe as _}; | use {defmt_rtt as _, panic_probe as _}; | ||||||
|  |  | ||||||
| bind_interrupts!(struct Irqs{ | bind_interrupts!(struct Irqs{ | ||||||
| @@ -154,15 +154,21 @@ async fn main(spawner: Spawner) { | |||||||
|         .unwrap(); |         .unwrap(); | ||||||
|     defmt::info!("{:#x}", mbox.mac_subsystem.read().await.unwrap()); |     defmt::info!("{:#x}", mbox.mac_subsystem.read().await.unwrap()); | ||||||
|  |  | ||||||
|  |     static TX1: StaticCell<[u8; 127]> = StaticCell::new(); | ||||||
|  |     static TX2: StaticCell<[u8; 127]> = StaticCell::new(); | ||||||
|  |     static TX3: StaticCell<[u8; 127]> = StaticCell::new(); | ||||||
|  |     static TX4: StaticCell<[u8; 127]> = StaticCell::new(); | ||||||
|  |     static TX5: StaticCell<[u8; 127]> = StaticCell::new(); | ||||||
|     let tx_queue = [ |     let tx_queue = [ | ||||||
|         make_static!([0u8; 127]), |         TX1.init([0u8; 127]), | ||||||
|         make_static!([0u8; 127]), |         TX2.init([0u8; 127]), | ||||||
|         make_static!([0u8; 127]), |         TX3.init([0u8; 127]), | ||||||
|         make_static!([0u8; 127]), |         TX4.init([0u8; 127]), | ||||||
|         make_static!([0u8; 127]), |         TX5.init([0u8; 127]), | ||||||
|     ]; |     ]; | ||||||
|  |  | ||||||
|     let runner = make_static!(Runner::new(mbox.mac_subsystem, tx_queue)); |     static RUNNER: StaticCell<Runner> = StaticCell::new(); | ||||||
|  |     let runner = RUNNER.init(Runner::new(mbox.mac_subsystem, tx_queue)); | ||||||
|  |  | ||||||
|     spawner.spawn(run_mac(runner)).unwrap(); |     spawner.spawn(run_mac(runner)).unwrap(); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -14,7 +14,7 @@ use embassy_nrf::spim::{self, Spim}; | |||||||
| use embassy_nrf::{bind_interrupts, peripherals}; | use embassy_nrf::{bind_interrupts, peripherals}; | ||||||
| use embassy_time::Delay; | use embassy_time::Delay; | ||||||
| use embedded_hal_bus::spi::ExclusiveDevice; | use embedded_hal_bus::spi::ExclusiveDevice; | ||||||
| use static_cell::make_static; | use static_cell::StaticCell; | ||||||
| use {defmt_rtt as _, panic_probe as _}; | use {defmt_rtt as _, panic_probe as _}; | ||||||
|  |  | ||||||
| bind_interrupts!(struct Irqs { | bind_interrupts!(struct Irqs { | ||||||
| @@ -68,11 +68,13 @@ async fn main(spawner: Spawner) { | |||||||
|     let seed = u64::from_le_bytes(seed); |     let seed = u64::from_le_bytes(seed); | ||||||
|  |  | ||||||
|     // Init network stack |     // Init network stack | ||||||
|     let stack = &*make_static!(Stack::new( |     static STACK: StaticCell<Stack<MyDriver>> = StaticCell::new(); | ||||||
|  |     static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | ||||||
|  |     let stack = &*STACK.init(Stack::new( | ||||||
|         device, |         device, | ||||||
|         config, |         config, | ||||||
|         make_static!(StackResources::<2>::new()), |         RESOURCES.init(StackResources::<2>::new()), | ||||||
|         seed |         seed, | ||||||
|     )); |     )); | ||||||
|  |  | ||||||
|     unwrap!(spawner.spawn(net_task(stack))); |     unwrap!(spawner.spawn(net_task(stack))); | ||||||
|   | |||||||
| @@ -13,7 +13,7 @@ use embassy_nrf::spim::{self, Spim}; | |||||||
| use embassy_nrf::{bind_interrupts, peripherals}; | use embassy_nrf::{bind_interrupts, peripherals}; | ||||||
| use embassy_time::Delay; | use embassy_time::Delay; | ||||||
| use embedded_hal_bus::spi::ExclusiveDevice; | use embedded_hal_bus::spi::ExclusiveDevice; | ||||||
| use static_cell::make_static; | use static_cell::StaticCell; | ||||||
| use {defmt_rtt as _, embassy_net_esp_hosted as hosted, panic_probe as _}; | use {defmt_rtt as _, embassy_net_esp_hosted as hosted, panic_probe as _}; | ||||||
|  |  | ||||||
| bind_interrupts!(struct Irqs { | bind_interrupts!(struct Irqs { | ||||||
| @@ -64,8 +64,9 @@ async fn main(spawner: Spawner) { | |||||||
|     let spi = spim::Spim::new(p.SPI3, Irqs, sck, miso, mosi, config); |     let spi = spim::Spim::new(p.SPI3, Irqs, sck, miso, mosi, config); | ||||||
|     let spi = ExclusiveDevice::new(spi, cs, Delay); |     let spi = ExclusiveDevice::new(spi, cs, Delay); | ||||||
|  |  | ||||||
|  |     static STATE: StaticCell<embassy_net_esp_hosted::State> = StaticCell::new(); | ||||||
|     let (device, mut control, runner) = embassy_net_esp_hosted::new( |     let (device, mut control, runner) = embassy_net_esp_hosted::new( | ||||||
|         make_static!(embassy_net_esp_hosted::State::new()), |         STATE.init(embassy_net_esp_hosted::State::new()), | ||||||
|         spi, |         spi, | ||||||
|         handshake, |         handshake, | ||||||
|         ready, |         ready, | ||||||
| @@ -85,11 +86,13 @@ async fn main(spawner: Spawner) { | |||||||
|     let seed = u64::from_le_bytes(seed); |     let seed = u64::from_le_bytes(seed); | ||||||
|  |  | ||||||
|     // Init network stack |     // Init network stack | ||||||
|     let stack = &*make_static!(Stack::new( |     static STACK: StaticCell<Stack<MyDriver>> = StaticCell::new(); | ||||||
|  |     static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | ||||||
|  |     let stack = &*STACK.init(Stack::new( | ||||||
|         device, |         device, | ||||||
|         Config::dhcpv4(Default::default()), |         Config::dhcpv4(Default::default()), | ||||||
|         make_static!(StackResources::<2>::new()), |         RESOURCES.init(StackResources::<2>::new()), | ||||||
|         seed |         seed, | ||||||
|     )); |     )); | ||||||
|  |  | ||||||
|     unwrap!(spawner.spawn(net_task(stack))); |     unwrap!(spawner.spawn(net_task(stack))); | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ use embassy_rp::gpio::{Level, Output}; | |||||||
| use embassy_rp::peripherals::{DMA_CH0, PIN_23, PIN_25, PIO0}; | use embassy_rp::peripherals::{DMA_CH0, PIN_23, PIN_25, PIO0}; | ||||||
| use embassy_rp::pio::{InterruptHandler, Pio}; | use embassy_rp::pio::{InterruptHandler, Pio}; | ||||||
| use embassy_rp::{bind_interrupts, rom_data}; | use embassy_rp::{bind_interrupts, rom_data}; | ||||||
| use static_cell::make_static; | use static_cell::StaticCell; | ||||||
| use {defmt_rtt as _, panic_probe as _}; | use {defmt_rtt as _, panic_probe as _}; | ||||||
|  |  | ||||||
| bind_interrupts!(struct Irqs { | bind_interrupts!(struct Irqs { | ||||||
| @@ -58,7 +58,8 @@ async fn main(spawner: Spawner) { | |||||||
|     let mut pio = Pio::new(p.PIO0, Irqs); |     let mut pio = Pio::new(p.PIO0, Irqs); | ||||||
|     let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0); |     let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0); | ||||||
|  |  | ||||||
|     let state = make_static!(cyw43::State::new()); |     static STATE: StaticCell<cyw43::State> = StaticCell::new(); | ||||||
|  |     let state = STATE.init(cyw43::State::new()); | ||||||
|     let (net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await; |     let (net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await; | ||||||
|     unwrap!(spawner.spawn(wifi_task(runner))); |     unwrap!(spawner.spawn(wifi_task(runner))); | ||||||
|  |  | ||||||
| @@ -71,11 +72,13 @@ async fn main(spawner: Spawner) { | |||||||
|     let seed = 0x0123_4567_89ab_cdef; // chosen by fair dice roll. guarenteed to be random. |     let seed = 0x0123_4567_89ab_cdef; // chosen by fair dice roll. guarenteed to be random. | ||||||
|  |  | ||||||
|     // Init network stack |     // Init network stack | ||||||
|     let stack = &*make_static!(Stack::new( |     static STACK: StaticCell<Stack<cyw43::NetDriver<'static>>> = StaticCell::new(); | ||||||
|  |     static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | ||||||
|  |     let stack = &*STACK.init(Stack::new( | ||||||
|         net_device, |         net_device, | ||||||
|         Config::dhcpv4(Default::default()), |         Config::dhcpv4(Default::default()), | ||||||
|         make_static!(StackResources::<2>::new()), |         RESOURCES.init(StackResources::<2>::new()), | ||||||
|         seed |         seed, | ||||||
|     )); |     )); | ||||||
|  |  | ||||||
|     unwrap!(spawner.spawn(net_task(stack))); |     unwrap!(spawner.spawn(net_task(stack))); | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ use embassy_rp::spi::{Async, Config as SpiConfig, Spi}; | |||||||
| use embassy_time::Delay; | use embassy_time::Delay; | ||||||
| use embedded_hal_bus::spi::ExclusiveDevice; | use embedded_hal_bus::spi::ExclusiveDevice; | ||||||
| use rand::RngCore; | use rand::RngCore; | ||||||
| use static_cell::make_static; | use static_cell::StaticCell; | ||||||
| use {defmt_rtt as _, panic_probe as _}; | use {defmt_rtt as _, panic_probe as _}; | ||||||
|  |  | ||||||
| #[embassy_executor::task] | #[embassy_executor::task] | ||||||
| @@ -51,7 +51,8 @@ async fn main(spawner: Spawner) { | |||||||
|     let w5500_reset = Output::new(p.PIN_20, Level::High); |     let w5500_reset = Output::new(p.PIN_20, Level::High); | ||||||
|  |  | ||||||
|     let mac_addr = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00]; |     let mac_addr = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00]; | ||||||
|     let state = make_static!(State::<8, 8>::new()); |     static STATE: StaticCell<State<8, 8>> = StaticCell::new(); | ||||||
|  |     let state = STATE.init(State::<8, 8>::new()); | ||||||
|     let (device, runner) = embassy_net_wiznet::new( |     let (device, runner) = embassy_net_wiznet::new( | ||||||
|         mac_addr, |         mac_addr, | ||||||
|         state, |         state, | ||||||
| @@ -66,11 +67,13 @@ async fn main(spawner: Spawner) { | |||||||
|     let seed = rng.next_u64(); |     let seed = rng.next_u64(); | ||||||
|  |  | ||||||
|     // Init network stack |     // Init network stack | ||||||
|     let stack = &*make_static!(Stack::new( |     static STACK: StaticCell<Stack<Device<'static>>> = StaticCell::new(); | ||||||
|  |     static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | ||||||
|  |     let stack = &*STACK.init(Stack::new( | ||||||
|         device, |         device, | ||||||
|         embassy_net::Config::dhcpv4(Default::default()), |         embassy_net::Config::dhcpv4(Default::default()), | ||||||
|         make_static!(StackResources::<2>::new()), |         RESOURCES.init(StackResources::<2>::new()), | ||||||
|         seed |         seed, | ||||||
|     )); |     )); | ||||||
|  |  | ||||||
|     // Launch network task |     // Launch network task | ||||||
|   | |||||||
| @@ -14,7 +14,7 @@ use embassy_stm32::peripherals::ETH; | |||||||
| use embassy_stm32::rng::Rng; | use embassy_stm32::rng::Rng; | ||||||
| use embassy_stm32::{bind_interrupts, eth, peripherals, rng}; | use embassy_stm32::{bind_interrupts, eth, peripherals, rng}; | ||||||
| use rand_core::RngCore; | use rand_core::RngCore; | ||||||
| use static_cell::make_static; | use static_cell::StaticCell; | ||||||
| use {defmt_rtt as _, panic_probe as _}; | use {defmt_rtt as _, panic_probe as _}; | ||||||
|  |  | ||||||
| teleprobe_meta::timeout!(120); | teleprobe_meta::timeout!(120); | ||||||
| @@ -71,8 +71,9 @@ async fn main(spawner: Spawner) { | |||||||
|     #[cfg(not(feature = "stm32f207zg"))] |     #[cfg(not(feature = "stm32f207zg"))] | ||||||
|     const PACKET_QUEUE_SIZE: usize = 4; |     const PACKET_QUEUE_SIZE: usize = 4; | ||||||
|  |  | ||||||
|  |     static PACKETS: StaticCell<PacketQueue<PACKET_QUEUE_SIZE, PACKET_QUEUE_SIZE>> = StaticCell::new(); | ||||||
|     let device = Ethernet::new( |     let device = Ethernet::new( | ||||||
|         make_static!(PacketQueue::<PACKET_QUEUE_SIZE, PACKET_QUEUE_SIZE>::new()), |         PACKETS.init(PacketQueue::<PACKET_QUEUE_SIZE, PACKET_QUEUE_SIZE>::new()), | ||||||
|         p.ETH, |         p.ETH, | ||||||
|         Irqs, |         Irqs, | ||||||
|         p.PA1, |         p.PA1, | ||||||
| @@ -99,11 +100,13 @@ async fn main(spawner: Spawner) { | |||||||
|     //}); |     //}); | ||||||
|  |  | ||||||
|     // Init network stack |     // Init network stack | ||||||
|     let stack = &*make_static!(Stack::new( |     static STACK: StaticCell<Stack<Device>> = StaticCell::new(); | ||||||
|  |     static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | ||||||
|  |     let stack = &*STACK.init(Stack::new( | ||||||
|         device, |         device, | ||||||
|         config, |         config, | ||||||
|         make_static!(StackResources::<2>::new()), |         RESOURCES.init(StackResources::<2>::new()), | ||||||
|         seed |         seed, | ||||||
|     )); |     )); | ||||||
|  |  | ||||||
|     // Launch network task |     // Launch network task | ||||||
|   | |||||||
| @@ -15,7 +15,7 @@ use embassy_stm32::rcc::LsConfig; | |||||||
| use embassy_stm32::rtc::{Rtc, RtcConfig}; | use embassy_stm32::rtc::{Rtc, RtcConfig}; | ||||||
| use embassy_stm32::Config; | use embassy_stm32::Config; | ||||||
| use embassy_time::Timer; | use embassy_time::Timer; | ||||||
| use static_cell::make_static; | use static_cell::StaticCell; | ||||||
|  |  | ||||||
| #[entry] | #[entry] | ||||||
| fn main() -> ! { | fn main() -> ! { | ||||||
| @@ -64,7 +64,8 @@ async fn async_main(spawner: Spawner) { | |||||||
|  |  | ||||||
|     rtc.set_datetime(now.into()).expect("datetime not set"); |     rtc.set_datetime(now.into()).expect("datetime not set"); | ||||||
|  |  | ||||||
|     let rtc = make_static!(rtc); |     static RTC: StaticCell<Rtc> = StaticCell::new(); | ||||||
|  |     let rtc = RTC.init(rtc); | ||||||
|  |  | ||||||
|     stop_with_rtc(rtc); |     stop_with_rtc(rtc); | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user