#![no_std]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![cfg_attr(docsrs, doc(cfg_hide(feature = "esp32p4")))]
#![deny(missing_docs)]
#![allow(unsafe_code)]
#![deny(unsafe_op_in_unsafe_fn)]
#![deny(clippy::correctness)]
#![warn(
clippy::suspicious,
clippy::style,
clippy::complexity,
clippy::perf,
clippy::cloned_instead_of_copied,
clippy::explicit_iter_loop,
clippy::implicit_clone,
clippy::inconsistent_struct_constructor,
clippy::manual_assert,
clippy::manual_let_else,
clippy::match_same_arms,
clippy::needless_pass_by_value,
clippy::semicolon_if_nothing_returned,
clippy::uninlined_format_args,
clippy::unnested_or_patterns,
clippy::std_instead_of_core,
clippy::std_instead_of_alloc,
clippy::alloc_instead_of_core
)]
#![allow(
clippy::mod_module_files,
clippy::self_named_module_files,
clippy::similar_names,
clippy::too_many_arguments,
clippy::struct_excessive_bools,
clippy::fn_params_excessive_bools,
clippy::type_complexity,
clippy::must_use_candidate,
clippy::assertions_on_constants,
clippy::cast_possible_truncation,
clippy::cast_possible_wrap,
clippy::cast_sign_loss,
clippy::cast_precision_loss,
clippy::cast_lossless,
clippy::panic_in_result_fn,
clippy::unwrap_used,
clippy::expect_used,
clippy::module_name_repetitions,
clippy::wildcard_imports,
clippy::items_after_statements,
clippy::let_underscore_future
)]
#[cfg(all(feature = "esp32", feature = "esp32p4"))]
compile_error!("Features 'esp32' and 'esp32p4' are mutually exclusive.");
#[cfg(not(any(feature = "esp32", feature = "esp32p4")))]
compile_error!("Either feature 'esp32' or 'esp32p4' must be enabled. The default is 'esp32'.");
#[cfg(feature = "esp32")]
#[cfg_attr(docsrs, doc(cfg(feature = "esp32")))]
pub mod boards;
pub mod driver;
pub mod hal;
pub mod phy;
mod internal;
#[cfg(any(feature = "smoltcp", feature = "esp-hal", feature = "embassy-net"))]
#[cfg_attr(
docsrs,
doc(cfg(any(feature = "smoltcp", feature = "esp-hal", feature = "embassy-net")))
)]
pub mod integration;
#[cfg(feature = "critical-section")]
#[cfg_attr(docsrs, doc(cfg(feature = "critical-section")))]
pub mod sync;
#[cfg(test)]
pub mod testing;
pub use driver::config::{
ChecksumConfig, DmaBurstLen, Duplex, EmacConfig, FlowControlConfig, MAC_FILTER_SLOTS,
MacAddressFilter, MacFilterType, PauseLowThreshold, PhyInterface, RmiiClockMode, Speed, State,
TxChecksumMode,
};
pub use driver::emac::{Emac, EmacDefault, EmacLarge, EmacSmall};
pub use driver::error::{
ConfigError, ConfigResult, DmaError, DmaResult, Error, IoError, IoResult, Result,
};
pub use driver::interrupt::InterruptStatus;
pub mod unsafe_registers {
pub use crate::internal::register::dma::DmaRegs;
pub use crate::internal::register::ext::ExtRegs;
pub use crate::internal::register::mac::MacRegs;
}
pub use phy::{Lan8720a, Lan8720aWithReset, LinkStatus, PhyCapabilities, PhyDriver};
#[cfg(feature = "critical-section")]
pub use sync::{SharedEmac, SharedEmacDefault, SharedEmacLarge, SharedEmacSmall};
#[cfg(feature = "esp-hal")]
pub mod esp_hal {
#![cfg_attr(docsrs, doc(cfg(feature = "esp-hal")))]
#[cfg(feature = "esp32")]
pub use crate::integration::esp_hal::Wt32Eth01;
pub use crate::integration::esp_hal::{
Delay, EMAC_INTERRUPT, EmacBuilder, EmacExt, EmacPhyBundle, Interrupt, InterruptHandler,
Priority,
};
pub use crate::{emac_async_isr, emac_isr};
}
#[cfg(feature = "async")]
#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
pub use sync::asynch::{AsyncEmacExt, AsyncEmacState, async_interrupt_handler};
#[cfg(feature = "embassy-net")]
#[cfg_attr(docsrs, doc(cfg(feature = "embassy-net")))]
pub use integration::embassy_net::{EmbassyEmac, EmbassyEmacState, EmbassyRxToken, EmbassyTxToken};
pub mod constants {
pub use crate::internal::constants::{
CRC_SIZE,
DEFAULT_BUFFER_SIZE,
DEFAULT_FLOW_HIGH_WATER,
DEFAULT_FLOW_LOW_WATER,
DEFAULT_MAC_ADDR,
DEFAULT_RX_BUFFERS,
DEFAULT_TX_BUFFERS,
ETH_HEADER_SIZE,
FLUSH_TIMEOUT,
MAC_ADDR_LEN,
MAX_FRAME_SIZE,
MDC_MAX_FREQ_HZ,
MII_10M_CLK_HZ,
MII_100M_CLK_HZ,
MII_BUSY_TIMEOUT,
MIN_FRAME_SIZE,
MTU,
PAUSE_TIME_MAX,
RESET_POLL_INTERVAL_US,
RMII_CLK_HZ,
SOFT_RESET_TIMEOUT_MS,
VLAN_TAG_SIZE,
};
}
#[cfg(feature = "critical-section")]
#[macro_export]
macro_rules! emac_static_sync {
($name:ident) => {
$crate::emac_static_sync!($name, 10, 10, 1600);
};
($name:ident, $rx:expr, $tx:expr, $buf:expr) => {
#[cfg_attr(target_arch = "xtensa", unsafe(link_section = ".dram1"))]
static $name: $crate::sync::SharedEmac<$rx, $tx, $buf> = $crate::sync::SharedEmac::new();
};
}
#[cfg(feature = "async")]
#[macro_export]
macro_rules! emac_static_async {
($emac:ident, $state:ident) => {
$crate::emac_static_async!($emac, $state, 10, 10, 1600);
};
($emac:ident, $state:ident, $rx:expr, $tx:expr, $buf:expr) => {
#[cfg_attr(target_arch = "xtensa", unsafe(link_section = ".dram1"))]
static $emac: static_cell::StaticCell<$crate::Emac<$rx, $tx, $buf>> =
static_cell::StaticCell::new();
static $state: $crate::AsyncEmacState = $crate::AsyncEmacState::new();
};
}
#[cfg(feature = "embassy-net")]
#[macro_export]
macro_rules! embassy_net_statics {
($emac:ident, $state:ident, $resources:ident, $rx:expr, $tx:expr, $buf:expr, $res:expr) => {
#[cfg_attr(target_arch = "xtensa", unsafe(link_section = ".dram1"))]
static $emac: static_cell::StaticCell<$crate::Emac<$rx, $tx, $buf>> =
static_cell::StaticCell::new();
static $state: $crate::EmbassyEmacState =
$crate::EmbassyEmacState::new(embassy_net_driver::LinkState::Down);
static $resources: static_cell::StaticCell<embassy_net::StackResources<$res>> =
static_cell::StaticCell::new();
};
}
#[cfg(feature = "embassy-net")]
#[macro_export]
macro_rules! embassy_net_driver {
($emac_ptr:expr, $state:expr) => {{
unsafe { $crate::EmbassyEmac::new(&mut *($emac_ptr), $state) }
}};
}
#[cfg(feature = "embassy-net")]
#[macro_export]
macro_rules! embassy_net_stack {
($driver:expr, $resources:ident, $config:expr, $seed:expr) => {{
let resources = $resources.init(embassy_net::StackResources::new());
embassy_net::new($driver, $config, resources, $seed)
}};
}