Compare commits

..

114 Commits

Author SHA1 Message Date
d6fda686bc net-esp-hosted: use released noproto version. 2023-12-20 14:13:52 +01:00
76c600365d Merge pull request #2334 from embassy-rs/embassy-net-adin1110-docs
docs: embassy-net-adin1110
2023-12-20 12:44:19 +00:00
18dac099cb Merge pull request #2333 from embassy-rs/embassy-net-wiznet-docs
docs: document public apis of wiznet driver
2023-12-20 12:44:16 +00:00
49005e955d Merge pull request #2330 from embassy-rs/embassy-net-esp-hosted-docs
Embassy net esp hosted docs
2023-12-20 12:44:11 +00:00
70ea805af3 Merge pull request #2332 from embassy-rs/embassy-net-tuntap-docs
docs: document embassy-net-tuntap
2023-12-20 12:44:06 +00:00
93bb34d8d1 fix: expose less 2023-12-20 13:39:45 +01:00
51a67cb69a fix: expose less 2023-12-20 13:34:34 +01:00
c8eb128a56 Merge pull request #2328 from rmja/signal-try-take
feat(embassy-sync): Add try_take() to signal
2023-12-20 12:34:01 +00:00
22ee868f04 Merge pull request #2335 from embassy-rs/remove-embedded-sdmmc
remove embedded-sdmmc
2023-12-20 12:32:04 +00:00
1c3cf347cb remove embedded-sdmmc
Remove support for embedded-sdmmc due to lack of maintainership. Bring
it back once the upstream includes the async functionality.
2023-12-20 13:25:36 +01:00
b8777eaea2 better keep missing docs for into 2023-12-20 13:12:32 +01:00
13c107e815 Put waiting state back if any 2023-12-20 13:09:16 +01:00
b0583b17cb fix: make non-public instead 2023-12-20 13:08:06 +01:00
246c49621c docs: embassy-net-adin1110 2023-12-20 12:52:35 +01:00
c3b827d8cd fix: add readme and fix remaining warnings 2023-12-20 12:24:51 +01:00
4dfae9328e add missing guards 2023-12-20 12:18:02 +01:00
73f8cd7ade fix: add repository to manifest 2023-12-20 12:16:01 +01:00
4a2dd7b944 docs: document public apis of wiznet driver 2023-12-20 12:14:25 +01:00
afb01e3fc5 docs: document embassy-net-tuntap 2023-12-20 12:08:26 +01:00
89cfdcb9f5 fix suddenly ending comment 2023-12-20 12:06:49 +01:00
abea4dde3d docs: document most of esp-hosted driver 2023-12-20 10:15:18 +01:00
52a801fdb7 Merge pull request #2329 from embassy-rs/apidoc-embassy-net-driver-channel
docs: document public apis of embassy-net-driver-channel
2023-12-20 09:08:55 +00:00
fc6e70caa5 docs: document public apis of embassy-net-driver-channel 2023-12-20 09:24:10 +01:00
f9d0daad80 feat(embassy-sync): Add try_take() to signal 2023-12-20 08:37:15 +01:00
97e919ea64 Merge pull request #2326 from embassy-rs/salty-update
Salty update
2023-12-19 21:30:32 +00:00
c7841a37fa boot: update ed25519-dalek in dev-dependencies. 2023-12-19 22:26:50 +01:00
589a16b255 Merge pull request #2327 from dragonnn/main
fix stm32 rtc year from 1970 base 2000 to make leap years work
2023-12-19 20:26:01 +00:00
4567b87482 cargo fmt 2023-12-19 21:21:52 +01:00
12de90e13d fix: update ed25519-dalek to new version 2023-12-19 21:20:30 +01:00
871ed538b1 fix stm32 rtc year from 1970 base 2000 2023-12-19 21:17:42 +01:00
efd5dbe019 fix: build warnings 2023-12-19 20:25:20 +01:00
9d46ee0758 fix: update salty to released version 2023-12-19 20:24:55 +01:00
e5912972ec Merge pull request #2325 from embassy-rs/stm32-docs
stm32: finish docs.
2023-12-19 17:07:53 +00:00
c8c8b89104 stm32: doc everything else. 2023-12-19 18:03:20 +01:00
189b15c426 stm32/timer: docs. 2023-12-19 17:35:38 +01:00
41c3c26beb Merge pull request #2323 from embassy-rs/embassy-usb-stuffs
docs: document usb-logger and usb-dfu
2023-12-19 16:58:46 +01:00
7ec1ed4de3 Merge pull request #2324 from barnabywalters/stm32-usart-docs
stm32: Documented usart public API
2023-12-19 16:58:27 +01:00
6564c04531 Reset .vscode/settings.json (doh) 2023-12-19 16:42:51 +01:00
f97ef61ef8 Documented usart public API 2023-12-19 16:41:00 +01:00
9ddf8b08e4 docs: document usb-logger and usb-dfu 2023-12-19 16:33:05 +01:00
71584409d9 Merge pull request #2321 from embassy-rs/stm32-docs
stm32: document hrtim, qspi, sdmmc, spi.
2023-12-19 15:29:26 +00:00
1ea87ec6e7 stm32: document hrtim, qspi, sdmmc, spi. 2023-12-19 16:21:51 +01:00
7d9a76da00 Merge pull request #2313 from eZioPan/update-metapac6
match up with "DMA cleanup" metapac change
2023-12-19 15:20:15 +00:00
c995732b0e Merge pull request #2320 from embassy-rs/cyw43-docs
docs: document public apis for cyw43 driver
2023-12-19 15:12:45 +00:00
39c166ef9b docs: document public apis for cyw43 driver 2023-12-19 16:08:06 +01:00
5e76c8b41a Merge pull request #2317 from embassy-rs/embassy-rp-rustdoc-2
docs: document all embassy-rp public apis
2023-12-19 13:52:21 +00:00
f4b77c967f docs: document all embassy-rp public apis
Enable missing doc warnings.
2023-12-19 14:19:46 +01:00
ca2e3759ad Merge pull request #2315 from embassy-rs/embassy-rp-rustdoc-1
docs: embassy-rp rustdoc and refactoring
2023-12-19 11:28:05 +00:00
3e2e109437 update metapac dep 2023-12-19 19:09:06 +08:00
6f21f0680e Merge pull request #2314 from plaes/stm32-i2c-conditional-time
stm32: i2c: Clean up conditional code a bit
2023-12-19 11:00:37 +00:00
486b67e895 docs: document spi, rtc and rest of uart for embassy-rp 2023-12-19 11:26:08 +01:00
e45e3e76b5 docs: embassy-rp rustdoc and refactoring 2023-12-19 10:56:22 +01:00
fc724dd707 stm32: i2c: Clean up conditional code a bit
By moving conditional code inside the functions, we can
reduce duplication and in one case we can even eliminate one...
2023-12-19 11:48:58 +02:00
254d587385 match up with metapac change 2023-12-19 17:12:34 +08:00
08e9a4d84a Merge pull request #2310 from embassy-rs/stm32-docs
stm32/sai: docs, cleanup api.
2023-12-19 00:37:49 +01:00
e1f588f520 stm32/sai: fix typo. 2023-12-19 00:36:50 +01:00
49534cd405 stm32: more docs. 2023-12-19 00:10:36 +01:00
138318f611 stm32/sai: docs, remove unused enums. 2023-12-19 00:06:30 +01:00
c45418787c stm32/sai: remove unused Word trait. 2023-12-19 00:06:30 +01:00
4deae51e65 stm32/sai: deduplicate code for subblocks A/B. 2023-12-19 00:06:30 +01:00
c952ae0f49 stm32/sai: remove unimplemented SetConfig. 2023-12-19 00:06:30 +01:00
4ed7747a98 Merge pull request #2306 from embassy-rs/james/fix-nb
Fix nb on rp uart
2023-12-18 18:32:04 +00:00
227ace6c3c Merge pull request #2308 from embassy-rs/stm32-docs
stm32: more docs.
2023-12-18 18:20:07 +00:00
124478c5e9 stm32: more docs. 2023-12-18 19:11:23 +01:00
59d2977c0a Merge pull request #2307 from embassy-rs/stm32-docs
stm32/can: docs, cleanup interrupt handling.y
2023-12-18 17:52:37 +00:00
87c8d9df94 stm32/can: docs. 2023-12-18 18:44:51 +01:00
21fce1e195 stm32/can: cleanup interrupt traits. 2023-12-18 18:44:51 +01:00
2b497c1e57 Fix nb on rp uart 2023-12-18 18:38:13 +01:00
3f0920c400 Merge pull request #2304 from embassy-rs/stm32-docs
stm32/i2c: remove _timeout public API, share more code between v1/v2.
2023-12-18 17:30:08 +00:00
7044e53af4 stm32/i2c: remove _timeout public API, share more code between v1/v2. 2023-12-18 18:24:55 +01:00
88e77c733c Merge pull request #2303 from embassy-rs/nor-flash-multiwrite
feat: support multiwrite flash traits if configured
2023-12-18 13:06:53 +00:00
2a542bc143 feat: support multiwrite flash traits if configured 2023-12-18 13:58:12 +01:00
c0cfd68c0c Merge pull request #2297 from embassy-rs/stm32-docs
stm32: add some docs.
2023-12-17 23:59:29 +00:00
80c9d04bbd stm32: add some docs. 2023-12-18 00:53:18 +01:00
9959c8c3e3 Merge pull request #2300 from RobertTDowling/stm32-fix-time-driver-race
STM32: Fix race in alarm setting, which impacted scheduling.
2023-12-17 23:51:43 +00:00
b857334f92 STM32: Fix race in alarm setting, which impacted scheduling.
Detect potential race condition (should be rare) and return false back
to caller, allowing them to handle the possibility that either the
alarm was never set because it was in the past (old meaning of false),
or that in fact the alarm was set and may have fired within the race
window (new meaning of false). In either case, the caller needs to
make sure the callback got called.
2023-12-17 15:35:35 -08:00
a2d4bab2f8 Merge pull request #2281 from dstric-aqueduct/main
allow for optional override of `Suspend` event for a UsbDevice
2023-12-16 13:44:54 +00:00
a5379e708c remove suspendable field from embassy_usb::builder::Config 2023-12-16 08:19:52 -05:00
2a7a44477e Merge pull request #2294 from adamgreig/g4-flash
STM32: Enable flash support for STM32G4
2023-12-16 06:41:21 +00:00
f6bc96dfbd STM32: Enable flash support for STM32G4 2023-12-16 03:50:34 +00:00
ccf602b333 Merge pull request #2293 from esden/fix_qspi_flash_select
STM32 QSPI: Fix flash selection.
2023-12-16 01:00:57 +00:00
3568e4a5ff STM32 QSPI: Fix flash selection. 2023-12-15 16:47:56 -08:00
858987263b Merge pull request #2290 from eZioPan/stm32f4-example-ws2812
add ws2812 example for stm32f4 with PWM and DMA
2023-12-15 23:05:32 +00:00
b966f55883 Merge pull request #2292 from sourcebox/stm32h7-rm0468-fixes
[embassy-stm32]: Fixes for STM32H7 series MCUs referenced in RM0468
2023-12-15 23:02:42 +00:00
ea1e1973eb unify channel assign 2023-12-16 02:15:56 +08:00
560e728132 STM32H7: adjust flash latency and programming delay for series in RM0468 2023-12-15 14:14:30 +01:00
c17fee27bb STM32H7: limit max frequency to 520MHz until cpu frequency boost option is implemented 2023-12-15 13:53:06 +01:00
a8d0da91dc STM32H7: adjust frequency limits for series in RM0468 2023-12-15 12:22:17 +01:00
e5e85ba02b STM32H7: Allow PLL1 DIVP of 1 for certain series 2023-12-15 11:42:58 +01:00
77e372e842 cargo fmt 2023-12-15 14:15:45 +08:00
a165d73eed add ws2812 example for stm32f4 with PWM and DMA 2023-12-15 14:10:11 +08:00
df0f41c41c Merge pull request #2289 from embassy-rs/ehm-rc4
use released embedded-hal-mock.
2023-12-14 20:14:37 +00:00
98481c20fe use released embedded-hal-mock. 2023-12-14 21:11:33 +01:00
5ec2fbe3a2 Merge pull request #2284 from Redrield/feature/embassy-usb-dfu
Add embassy-usb-dfu crate, with related modifications to embassy-boot
2023-12-14 19:56:04 +00:00
33e8943e5b Rename bootloader feature to dfu 2023-12-14 14:16:58 -05:00
9f9f6e75bb Abstract chip reset logic, add Reset impls for cortex-m and esp32c3 2023-12-14 13:29:26 -05:00
cbc8ccc51e Adjust stm32wb-dfu example memory maps to fix linker errors 2023-12-14 10:56:16 -05:00
485765320a Merge pull request #2288 from embassy-rs/ci-cache-test
ci: fix test job not caching anything.
2023-12-14 15:49:52 +00:00
27d054aa68 Adjust toml files, fix application example 2023-12-14 10:34:22 -05:00
e579095a90 ci: fix test job not caching anything. 2023-12-14 16:30:45 +01:00
a34abd849f Add examples to ci.sh 2023-12-14 10:30:10 -05:00
138ed87b95 Merge pull request #2287 from embassy-rs/eh-rc3
Update embedded-hal to 1.0.0-rc.3
2023-12-14 15:29:48 +00:00
d81395fab3 Update embedded-hal to 1.0.0-rc.3 2023-12-14 16:19:32 +01:00
ef692c5141 SCB::sys_reset has a DSB internally, no need to replicate 2023-12-14 10:06:36 -05:00
9cc5d8ac89 fmt 2023-12-14 09:38:49 -05:00
c1438fe87b fmt 2023-12-14 09:38:02 -05:00
e27e00f628 Address reviews 2023-12-14 09:36:22 -05:00
b60b3f4eb8 Last fmt hopefully 2023-12-13 16:19:59 -05:00
702d2a1a19 Formatting fixes, add example using stm32wb55 2023-12-13 16:08:20 -05:00
c2942f2727 fmt 2023-12-13 14:53:49 -05:00
6bf70e14fb Update usb.rs
- add check of `dev_resume_from_host` interrupt register to catch wake event
2023-12-13 14:50:13 -05:00
2afec225e3 Merge branch 'main' into feature/embassy-usb-dfu 2023-12-13 14:42:14 -05:00
976a7ae22a Add embassy-usb-dfu 2023-12-13 14:40:49 -05:00
d596a1091d add susependable field to embassy_usb::builder::Config
- allow for optional override of `Suspend` event for a UsbDevice
2023-12-13 10:17:07 -05:00
24 changed files with 231 additions and 118 deletions

4
ci.sh
View File

@ -91,12 +91,12 @@ cargo batch \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f417zg,defmt,exti,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features 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 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 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 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 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 \

View File

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

View File

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

View File

@ -5,6 +5,7 @@
#![allow(clippy::missing_errors_doc)]
#![allow(clippy::missing_panics_doc)]
#![doc = include_str!("../README.md")]
#![warn(missing_docs)]
// must go first!
mod fmt;
@ -26,8 +27,9 @@ use embedded_hal_async::digital::Wait;
use embedded_hal_async::spi::{Error, Operation, SpiDevice};
use heapless::Vec;
pub use mdio::MdioBus;
pub use phy::{Phy10BaseT1x, RegsC22, RegsC45};
pub use regs::{Config0, Config2, SpiRegisters as sr, Status0, Status1};
pub use phy::Phy10BaseT1x;
use phy::{RegsC22, RegsC45};
use regs::{Config0, Config2, SpiRegisters as sr, Status0, Status1};
use crate::fmt::Bytes;
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> {
/// Run the driver.
#[allow(clippy::too_many_lines)]
pub async fn run(mut self) -> ! {
loop {

View File

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

View File

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

View File

@ -1,5 +1,6 @@
#![no_std]
#![doc = include_str!("../README.md")]
#![warn(missing_docs)]
// must go first!
mod fmt;
@ -15,6 +16,9 @@ use embassy_sync::blocking_mutex::Mutex;
use embassy_sync::waitqueue::WakerRegistration;
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> {
rx: [PacketBuf<MTU>; N_RX],
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> {
const NEW_PACKET: PacketBuf<MTU> = PacketBuf::new();
/// Create a new channel state.
pub const fn new() -> Self {
Self {
rx: [Self::NEW_PACKET; N_RX],
@ -39,33 +44,45 @@ struct StateInner<'d, const MTU: usize> {
shared: Mutex<NoopRawMutex, RefCell<Shared>>,
}
/// State of the LinkState
struct Shared {
link_state: LinkState,
waker: WakerRegistration,
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> {
tx_chan: zerocopy_channel::Receiver<'d, NoopRawMutex, PacketBuf<MTU>>,
rx_chan: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf<MTU>>,
shared: &'d Mutex<NoopRawMutex, RefCell<Shared>>,
}
/// State runner.
///
/// Holds the shared state of the channel such as link state.
#[derive(Clone, Copy)]
pub struct StateRunner<'d> {
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> {
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> {
tx_chan: zerocopy_channel::Receiver<'d, NoopRawMutex, PacketBuf<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>) {
(
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>) {
(
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> {
StateRunner { shared: self.shared }
}
/// Set the link state.
pub fn set_link_state(&mut self, state: LinkState) {
self.shared.lock(|s| {
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) {
self.shared.lock(|s| {
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] {
let p = self.rx_chan.send().await;
&mut p.buf
}
/// Check if there is space for more inbound packets right now.
pub fn try_rx_buf(&mut self) -> Option<&mut [u8]> {
let p = self.rx_chan.try_send()?;
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]> {
match self.rx_chan.poll_send(cx) {
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) {
let p = self.rx_chan.try_send().unwrap();
p.len = len;
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] {
let p = self.tx_chan.receive().await;
&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]> {
let p = self.tx_chan.try_receive()?;
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]> {
match self.tx_chan.poll_receive(cx) {
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) {
self.tx_chan.receive_done();
}
}
impl<'d> StateRunner<'d> {
/// Set link state.
pub fn set_link_state(&self, state: LinkState) {
self.shared.lock(|s| {
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) {
self.shared.lock(|s| {
let s = &mut *s.borrow_mut();
@ -170,16 +201,19 @@ impl<'d> StateRunner<'d> {
}
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] {
let p = self.rx_chan.send().await;
&mut p.buf
}
/// Check if there is space for more inbound packets right now.
pub fn try_rx_buf(&mut self) -> Option<&mut [u8]> {
let p = self.rx_chan.try_send()?;
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]> {
match self.rx_chan.poll_send(cx) {
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) {
let p = self.rx_chan.try_send().unwrap();
p.len = len;
@ -195,16 +230,19 @@ impl<'d, const MTU: usize> RxRunner<'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] {
let p = self.tx_chan.receive().await;
&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]> {
let p = self.tx_chan.try_receive()?;
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]> {
match self.tx_chan.poll_receive(cx) {
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) {
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>(
state: &'d mut State<MTU, N_RX, N_TX>,
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> {
len: usize,
buf: [u8; MTU],
}
impl<const MTU: usize> PacketBuf<MTU> {
/// Create a new packet buffer.
pub const fn new() -> Self {
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> {
rx: zerocopy_channel::Receiver<'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> {
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> {
tx: zerocopy_channel::Sender<'a, NoopRawMutex, PacketBuf<MTU>>,
}

View File

@ -2,6 +2,10 @@
name = "embassy-net-esp-hosted"
version = "0.1.0"
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]
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-async = { version = "=1.0.0-rc.3" }
noproto = { git="https://github.com/embassy-rs/noproto", rev = "f5e6d1f325b6ad4e344f60452b09576e24671f62", default-features = false, features = ["derive"] }
#noproto = { version = "0.1", path = "/home/dirbaio/noproto", default-features = false, features = ["derive"] }
noproto = "0.1.0"
heapless = "0.8"
[package.metadata.embassy_docs]

View 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.

View File

@ -5,38 +5,54 @@ use heapless::String;
use crate::ioctl::Shared;
use crate::proto::{self, CtrlMsg};
/// Errors reported by control.
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Error {
/// The operation failed with the given error code.
Failed(u32),
/// The operation timed out.
Timeout,
/// Internal error.
Internal,
}
/// Handle for managing the network and WiFI state.
pub struct Control<'a> {
state_ch: ch::StateRunner<'a>,
shared: &'a Shared,
}
/// WiFi mode.
#[allow(unused)]
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
enum WifiMode {
/// No mode.
None = 0,
/// Client station.
Sta = 1,
/// Access point mode.
Ap = 2,
/// Repeater mode.
ApSta = 3,
}
pub use proto::CtrlWifiSecProt as Security;
/// WiFi status.
#[derive(Clone, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct Status {
/// Service Set Identifier.
pub ssid: String<32>,
/// Basic Service Set Identifier.
pub bssid: [u8; 6],
/// Received Signal Strength Indicator.
pub rssi: i32,
/// WiFi channel.
pub channel: u32,
/// Security mode.
pub security: Security,
}
@ -65,6 +81,7 @@ impl<'a> Control<'a> {
Self { state_ch, shared }
}
/// Initialize device.
pub async fn init(&mut self) -> Result<(), Error> {
debug!("wait for init event...");
self.shared.init_wait().await;
@ -82,6 +99,7 @@ impl<'a> Control<'a> {
Ok(())
}
/// Get the current status.
pub async fn get_status(&mut self) -> Result<Status, Error> {
let req = proto::CtrlMsgReqGetApConfig {};
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> {
let req = proto::CtrlMsgReqConnectAp {
ssid: unwrap!(String::try_from(ssid)),
@ -108,6 +127,7 @@ impl<'a> Control<'a> {
Ok(())
}
/// Disconnect from any currently connected network.
pub async fn disconnect(&mut self) -> Result<(), Error> {
let req = proto::CtrlMsgReqGetStatus {};
ioctl!(self, ReqDisconnectAp, RespDisconnectAp, req, resp);

View File

@ -1,4 +1,6 @@
#![no_std]
#![doc = include_str!("../README.md")]
#![warn(missing_docs)]
use embassy_futures::select::{select4, Either4};
use embassy_net_driver_channel as ch;
@ -97,12 +99,14 @@ enum InterfaceType {
const MAX_SPI_BUFFER_SIZE: usize = 1600;
const HEARTBEAT_MAX_GAP: Duration = Duration::from_secs(20);
/// State for the esp-hosted driver.
pub struct State {
shared: Shared,
ch: ch::State<MTU, 4, 4>,
}
impl State {
/// Create a new state.
pub fn new() -> Self {
Self {
shared: Shared::new(),
@ -111,8 +115,13 @@ impl State {
}
}
/// Type alias for network driver.
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>(
state: &'a mut State,
spi: SPI,
@ -144,6 +153,7 @@ where
(device, Control::new(state_ch, &state.shared), runner)
}
/// Runner for communicating with the WiFi device.
pub struct Runner<'a, SPI, IN, OUT> {
ch: ch::Runner<'a, MTU>,
state_ch: ch::StateRunner<'a>,
@ -166,6 +176,7 @@ where
{
async fn init(&mut self) {}
/// Run the packet processing.
pub async fn run(mut self) -> ! {
debug!("resetting...");
self.reset.set_low().unwrap();

View File

@ -4,7 +4,7 @@ use heapless::{String, Vec};
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct ScanResult {
pub(crate) struct ScanResult {
#[noproto(tag = "1")]
pub ssid: String<32>,
#[noproto(tag = "2")]
@ -19,7 +19,7 @@ pub struct ScanResult {
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct ConnectedStaList {
pub(crate) struct ConnectedStaList {
#[noproto(tag = "1")]
pub mac: String<32>,
#[noproto(tag = "2")]
@ -29,14 +29,14 @@ pub struct ConnectedStaList {
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsgReqGetMacAddress {
pub(crate) struct CtrlMsgReqGetMacAddress {
#[noproto(tag = "1")]
pub mode: u32,
}
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsgRespGetMacAddress {
pub(crate) struct CtrlMsgRespGetMacAddress {
#[noproto(tag = "1")]
pub mac: String<32>,
#[noproto(tag = "2")]
@ -45,11 +45,11 @@ pub struct CtrlMsgRespGetMacAddress {
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsgReqGetMode {}
pub(crate) struct CtrlMsgReqGetMode {}
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsgRespGetMode {
pub(crate) struct CtrlMsgRespGetMode {
#[noproto(tag = "1")]
pub mode: u32,
#[noproto(tag = "2")]
@ -58,32 +58,32 @@ pub struct CtrlMsgRespGetMode {
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsgReqSetMode {
pub(crate) struct CtrlMsgReqSetMode {
#[noproto(tag = "1")]
pub mode: u32,
}
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsgRespSetMode {
pub(crate) struct CtrlMsgRespSetMode {
#[noproto(tag = "1")]
pub resp: u32,
}
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsgReqGetStatus {}
pub(crate) struct CtrlMsgReqGetStatus {}
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsgRespGetStatus {
pub(crate) struct CtrlMsgRespGetStatus {
#[noproto(tag = "1")]
pub resp: u32,
}
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsgReqSetMacAddress {
pub(crate) struct CtrlMsgReqSetMacAddress {
#[noproto(tag = "1")]
pub mac: String<32>,
#[noproto(tag = "2")]
@ -92,18 +92,18 @@ pub struct CtrlMsgReqSetMacAddress {
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsgRespSetMacAddress {
pub(crate) struct CtrlMsgRespSetMacAddress {
#[noproto(tag = "1")]
pub resp: u32,
}
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsgReqGetApConfig {}
pub(crate) struct CtrlMsgReqGetApConfig {}
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsgRespGetApConfig {
pub(crate) struct CtrlMsgRespGetApConfig {
#[noproto(tag = "1")]
pub ssid: String<32>,
#[noproto(tag = "2")]
@ -120,7 +120,7 @@ pub struct CtrlMsgRespGetApConfig {
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsgReqConnectAp {
pub(crate) struct CtrlMsgReqConnectAp {
#[noproto(tag = "1")]
pub ssid: String<32>,
#[noproto(tag = "2")]
@ -135,7 +135,7 @@ pub struct CtrlMsgReqConnectAp {
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsgRespConnectAp {
pub(crate) struct CtrlMsgRespConnectAp {
#[noproto(tag = "1")]
pub resp: u32,
#[noproto(tag = "2")]
@ -144,11 +144,11 @@ pub struct CtrlMsgRespConnectAp {
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsgReqGetSoftApConfig {}
pub(crate) struct CtrlMsgReqGetSoftApConfig {}
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsgRespGetSoftApConfig {
pub(crate) struct CtrlMsgRespGetSoftApConfig {
#[noproto(tag = "1")]
pub ssid: String<32>,
#[noproto(tag = "2")]
@ -169,7 +169,7 @@ pub struct CtrlMsgRespGetSoftApConfig {
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsgReqStartSoftAp {
pub(crate) struct CtrlMsgReqStartSoftAp {
#[noproto(tag = "1")]
pub ssid: String<32>,
#[noproto(tag = "2")]
@ -188,7 +188,7 @@ pub struct CtrlMsgReqStartSoftAp {
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsgRespStartSoftAp {
pub(crate) struct CtrlMsgRespStartSoftAp {
#[noproto(tag = "1")]
pub resp: u32,
#[noproto(tag = "2")]
@ -197,11 +197,11 @@ pub struct CtrlMsgRespStartSoftAp {
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsgReqScanResult {}
pub(crate) struct CtrlMsgReqScanResult {}
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsgRespScanResult {
pub(crate) struct CtrlMsgRespScanResult {
#[noproto(tag = "1")]
pub count: u32,
#[noproto(repeated, tag = "2")]
@ -212,11 +212,11 @@ pub struct CtrlMsgRespScanResult {
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsgReqSoftApConnectedSta {}
pub(crate) struct CtrlMsgReqSoftApConnectedSta {}
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsgRespSoftApConnectedSta {
pub(crate) struct CtrlMsgRespSoftApConnectedSta {
#[noproto(tag = "1")]
pub num: u32,
#[noproto(repeated, tag = "2")]
@ -227,43 +227,43 @@ pub struct CtrlMsgRespSoftApConnectedSta {
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsgReqOtaBegin {}
pub(crate) struct CtrlMsgReqOtaBegin {}
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsgRespOtaBegin {
pub(crate) struct CtrlMsgRespOtaBegin {
#[noproto(tag = "1")]
pub resp: u32,
}
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsgReqOtaWrite {
pub(crate) struct CtrlMsgReqOtaWrite {
#[noproto(tag = "1")]
pub ota_data: Vec<u8, 1024>,
}
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsgRespOtaWrite {
pub(crate) struct CtrlMsgRespOtaWrite {
#[noproto(tag = "1")]
pub resp: u32,
}
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsgReqOtaEnd {}
pub(crate) struct CtrlMsgReqOtaEnd {}
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsgRespOtaEnd {
pub(crate) struct CtrlMsgRespOtaEnd {
#[noproto(tag = "1")]
pub resp: u32,
}
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsgReqVendorIeData {
pub(crate) struct CtrlMsgReqVendorIeData {
#[noproto(tag = "1")]
pub element_id: u32,
#[noproto(tag = "2")]
@ -278,7 +278,7 @@ pub struct CtrlMsgReqVendorIeData {
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsgReqSetSoftApVendorSpecificIe {
pub(crate) struct CtrlMsgReqSetSoftApVendorSpecificIe {
#[noproto(tag = "1")]
pub enable: bool,
#[noproto(tag = "2")]
@ -291,32 +291,32 @@ pub struct CtrlMsgReqSetSoftApVendorSpecificIe {
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsgRespSetSoftApVendorSpecificIe {
pub(crate) struct CtrlMsgRespSetSoftApVendorSpecificIe {
#[noproto(tag = "1")]
pub resp: u32,
}
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsgReqSetWifiMaxTxPower {
pub(crate) struct CtrlMsgReqSetWifiMaxTxPower {
#[noproto(tag = "1")]
pub wifi_max_tx_power: u32,
}
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsgRespSetWifiMaxTxPower {
pub(crate) struct CtrlMsgRespSetWifiMaxTxPower {
#[noproto(tag = "1")]
pub resp: u32,
}
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsgReqGetWifiCurrTxPower {}
pub(crate) struct CtrlMsgReqGetWifiCurrTxPower {}
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsgRespGetWifiCurrTxPower {
pub(crate) struct CtrlMsgRespGetWifiCurrTxPower {
#[noproto(tag = "1")]
pub wifi_curr_tx_power: u32,
#[noproto(tag = "2")]
@ -325,7 +325,7 @@ pub struct CtrlMsgRespGetWifiCurrTxPower {
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsgReqConfigHeartbeat {
pub(crate) struct CtrlMsgReqConfigHeartbeat {
#[noproto(tag = "1")]
pub enable: bool,
#[noproto(tag = "2")]
@ -334,7 +334,7 @@ pub struct CtrlMsgReqConfigHeartbeat {
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsgRespConfigHeartbeat {
pub(crate) struct CtrlMsgRespConfigHeartbeat {
#[noproto(tag = "1")]
pub resp: u32,
}
@ -342,28 +342,28 @@ pub struct CtrlMsgRespConfigHeartbeat {
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsgEventEspInit {
pub(crate) struct CtrlMsgEventEspInit {
#[noproto(tag = "1")]
pub init_data: Vec<u8, 64>,
}
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsgEventHeartbeat {
pub(crate) struct CtrlMsgEventHeartbeat {
#[noproto(tag = "1")]
pub hb_num: u32,
}
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsgEventStationDisconnectFromAp {
pub(crate) struct CtrlMsgEventStationDisconnectFromAp {
#[noproto(tag = "1")]
pub resp: u32,
}
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsgEventStationDisconnectFromEspSoftAp {
pub(crate) struct CtrlMsgEventStationDisconnectFromEspSoftAp {
#[noproto(tag = "1")]
pub resp: u32,
#[noproto(tag = "2")]
@ -372,7 +372,7 @@ pub struct CtrlMsgEventStationDisconnectFromEspSoftAp {
#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CtrlMsg {
pub(crate) struct CtrlMsg {
/// msg_type could be req, resp or Event
#[noproto(tag = "1")]
pub msg_type: CtrlMsgType,
@ -390,7 +390,7 @@ pub struct CtrlMsg {
/// union of all msg ids
#[derive(Debug, Clone, Eq, PartialEq, noproto::Oneof)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum CtrlMsgPayload {
pub(crate) enum CtrlMsgPayload {
/// * Requests *
#[noproto(tag = "101")]
ReqGetMacAddress(CtrlMsgReqGetMacAddress),
@ -492,7 +492,7 @@ pub enum CtrlMsgPayload {
#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)]
#[repr(u32)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum CtrlVendorIeType {
pub(crate) enum CtrlVendorIeType {
#[default]
Beacon = 0,
ProbeReq = 1,
@ -504,7 +504,7 @@ pub enum CtrlVendorIeType {
#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)]
#[repr(u32)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum CtrlVendorIeid {
pub(crate) enum CtrlVendorIeid {
#[default]
Id0 = 0,
Id1 = 1,
@ -513,7 +513,7 @@ pub enum CtrlVendorIeid {
#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)]
#[repr(u32)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum CtrlWifiMode {
pub(crate) enum CtrlWifiMode {
#[default]
None = 0,
Sta = 1,
@ -524,7 +524,7 @@ pub enum CtrlWifiMode {
#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)]
#[repr(u32)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum CtrlWifiBw {
pub(crate) enum CtrlWifiBw {
#[default]
BwInvalid = 0,
Ht20 = 1,
@ -534,13 +534,15 @@ pub enum CtrlWifiBw {
#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)]
#[repr(u32)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum CtrlWifiPowerSave {
pub(crate) enum CtrlWifiPowerSave {
#[default]
PsInvalid = 0,
MinModem = 1,
MaxModem = 2,
}
/// Wifi Security Settings
#[allow(missing_docs)]
#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)]
#[repr(u32)]
#[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)]
#[repr(u32)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum CtrlStatus {
pub(crate) enum CtrlStatus {
#[default]
Connected = 0,
NotConnected = 1,
@ -573,7 +575,7 @@ pub enum CtrlStatus {
#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)]
#[repr(u32)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum CtrlMsgType {
pub(crate) enum CtrlMsgType {
#[default]
MsgTypeInvalid = 0,
Req = 1,
@ -585,7 +587,7 @@ pub enum CtrlMsgType {
#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)]
#[repr(u32)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum CtrlMsgId {
pub(crate) enum CtrlMsgId {
#[default]
MsgIdInvalid = 0,
/// * Request Msgs *

View File

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

View File

@ -1,3 +1,5 @@
#![warn(missing_docs)]
#![doc = include_str!("../README.md")]
use std::io;
use std::io::{Read, Write};
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 log::*;
/// Get the MTU of the given interface.
pub const SIOCGIFMTU: libc::c_ulong = 0x8921;
/// Get the index of the given interface.
pub const _SIOCGIFINDEX: libc::c_ulong = 0x8933;
/// Capture all packages.
pub const _ETH_P_ALL: libc::c_short = 0x0003;
/// Set the interface flags.
pub const TUNSETIFF: libc::c_ulong = 0x400454CA;
/// TUN device.
pub const _IFF_TUN: libc::c_int = 0x0001;
/// TAP device.
pub const IFF_TAP: libc::c_int = 0x0002;
/// No packet information.
pub const IFF_NO_PI: libc::c_int = 0x1000;
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)
}
/// A TUN/TAP device.
#[derive(Debug)]
pub struct TunTap {
fd: libc::c_int,
@ -60,6 +70,7 @@ impl AsRawFd for TunTap {
}
impl TunTap {
/// Create a new TUN/TAP device.
pub fn new(name: &str) -> io::Result<TunTap> {
unsafe {
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 {
device: Async<TunTap>,
}
impl TunTapDevice {
/// Create a new TUN/TAP device.
pub fn new(name: &str) -> io::Result<TunTapDevice> {
Ok(Self {
device: Async::new(TunTap::new(name)?)?,

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,7 @@
#![no_std]
#![allow(async_fn_in_trait)]
#![doc = include_str!("../README.md")]
#![warn(missing_docs)]
pub mod chip;
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.
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) -> ! {
let (state_chan, mut rx_chan, mut tx_chan) = self.ch.split();
let mut tick = Ticker::every(Duration::from_millis(500));

View File

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

View File

@ -130,7 +130,7 @@ impl RtcTimeProvider {
let weekday = day_of_week_from_u8(dr.wdu()).map_err(RtcError::InvalidDateTime)?;
let day = bcd2_to_byte((dr.dt(), dr.du()));
let month = bcd2_to_byte((dr.mt() as u8, dr.mu()));
let year = bcd2_to_byte((dr.yt(), dr.yu())) as u16 + 1970_u16;
let year = bcd2_to_byte((dr.yt(), dr.yu())) as u16 + 2000_u16;
DateTime::from(year, month, day, weekday, hour, minute, second).map_err(RtcError::InvalidDateTime)
})
@ -261,7 +261,7 @@ impl Rtc {
let (dt, du) = byte_to_bcd2(t.day() as u8);
let (mt, mu) = byte_to_bcd2(t.month() as u8);
let yr = t.year() as u16;
let yr_offset = (yr - 1970_u16) as u8;
let yr_offset = (yr - 2000_u16) as u8;
let (yt, yu) = byte_to_bcd2(yr_offset);
use crate::pac::rtc::vals::Ampm;

View File

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

View File

@ -111,6 +111,20 @@ where
poll_fn(move |cx| self.poll_wait(cx))
}
/// 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.
pub fn signaled(&self) -> bool {
self.state.lock(|cell| {

View File

@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0"
[dependencies]
# 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-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"] }