Merge pull request #1831 from vDorst/adin1110-part2
embassy-net-adin1110 more improvements
This commit is contained in:
commit
9d8c527308
8 changed files with 811 additions and 232 deletions
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "embassy-net-adin1110"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
description = "embassy-net driver for the ADIN1110 ethernet chip"
|
||||
keywords = ["embedded", "ADIN1110", "embassy-net", "embedded-hal-async", "ethernet", "async"]
|
||||
categories = ["embedded", "hardware-support", "no-std", "network-programming", "async"]
|
||||
|
@ -12,30 +12,31 @@ edition = "2021"
|
|||
[dependencies]
|
||||
heapless = "0.7.16"
|
||||
defmt = { version = "0.3", optional = true }
|
||||
log = { version = "0.4.4", default-features = false, optional = true }
|
||||
log = { version = "0.4", default-features = false, optional = true }
|
||||
embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-rc.1" }
|
||||
embedded-hal-async = { version = "=1.0.0-rc.1" }
|
||||
embedded-hal-bus = { version = "=0.1.0-rc.1", features = ["async"] }
|
||||
embassy-net-driver-channel = { version = "0.1.0", path = "../embassy-net-driver-channel" }
|
||||
embassy-time = { version = "0.1.0" }
|
||||
embassy-time = { version = "0.1.3" }
|
||||
embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
|
||||
bitfield = "0.14.0"
|
||||
|
||||
|
||||
[dev-dependencies]
|
||||
# reenable when https://github.com/dbrgn/embedded-hal-mock/pull/86 is merged.
|
||||
#embedded-hal-mock = { git = "https://github.com/dbrgn/embedded-hal-mock", branch = "1-alpha", features = ["embedded-hal-async", "eh1"] }] }
|
||||
embedded-hal-mock = { git = "https://github.com/newAM/embedded-hal-mock", branch = "eh1-rc.1", features = ["embedded-hal-async", "eh1"] }
|
||||
crc = "3.0.1"
|
||||
env_logger = "0.10"
|
||||
critical-section = { version = "1.1.1", features = ["std"] }
|
||||
futures-test = "0.3.17"
|
||||
critical-section = { version = "1.1.2", features = ["std"] }
|
||||
futures-test = "0.3.28"
|
||||
|
||||
[features]
|
||||
default = [ ]
|
||||
defmt = [ "dep:defmt" ]
|
||||
defmt = [ "dep:defmt", "embedded-hal-1/defmt-03" ]
|
||||
log = ["dep:log"]
|
||||
|
||||
[package.metadata.embassy_docs]
|
||||
src_base = "https://github.com/embassy-rs/embassy/blob/embassy-net-adin1110-v$VERSION/embassy-net-adin1110/src/"
|
||||
src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-net-adin1110/src/"
|
||||
target = "thumbv7em-none-eabi"
|
||||
features = ["defmt"]
|
||||
|
|
|
@ -30,8 +30,8 @@ Currently only `Generic` SPI with or without CRC is supported.
|
|||
|
||||
## Hardware
|
||||
|
||||
- Tested on [`Analog Devices EVAL-ADIN1110EBZ`](https://www.analog.com/en/design-center/evaluation-hardware-and-software/evaluation-boards-kits/eval-adin1110.html) with an `STM32L4S5QII3P`, see [`spe_adin1110_http_server`](../examples/stm32l4/src/bin/spe_adin1110_http_server.rs) dor an example.
|
||||
- [`SparkFun MicroMod Single Pair Ethernet Function Board`](https://www.sparkfun.com/products/19038) or [`SparkFun MicroMod Single Pair Ethernet Kit`](https://www.sparkfun.com/products/19628), supporting multiple microcontrollers. **Make sure to check if it's a microcontroller that is supported by Embassy!**
|
||||
- Tested on [`Analog Devices EVAL-ADIN1110EBZ`](https://www.analog.com/en/design-center/evaluation-hardware-and-software/evaluation-boards-kits/eval-adin1110.html) with an `STM32L4S5QII3P`, see [`spe_adin1110_http_server`](../examples/stm32l4/src/bin/spe_adin1110_http_server.rs) for an example.
|
||||
- [`SparkFun MicroMod Single Pair Ethernet Function Board`](https://www.sparkfun.com/products/19038) or [`SparkFun MicroMod Single Pair Ethernet Kit (End Of Life)`](https://www.sparkfun.com/products/19628), supporting multiple microcontrollers. **Make sure to check if it's a microcontroller that is supported by Embassy!**
|
||||
|
||||
## Other SPE chips
|
||||
|
||||
|
@ -44,6 +44,39 @@ ADIN1110 library can tested on the host with a mock SPI driver.
|
|||
|
||||
$ `cargo test --target x86_64-unknown-linux-gnu`
|
||||
|
||||
## Benchmark
|
||||
|
||||
- Benchmarked on [`Analog Devices EVAL-ADIN1110EBZ`](https://www.analog.com/en/design-center/evaluation-hardware-and-software/evaluation-boards-kits/eval-adin1110.html), with [`spe_adin1110_http_server`](../examples/stm32l4/src/bin/spe_adin1110_http_server.rs) example.
|
||||
|
||||
Basic `ping` benchmark
|
||||
```rust,ignore
|
||||
# ping <IP> -c 60
|
||||
|
||||
60 packets transmitted, 60 received, 0% packet loss, time 59066ms
|
||||
rtt min/avg/max/mdev = 1.089/1.161/1.237/0.018 ms
|
||||
|
||||
# ping <IP> -s 1472 -M do -c 60
|
||||
|
||||
60 packets transmitted, 60 received, 0% packet loss, time 59066ms
|
||||
rtt min/avg/max/mdev = 5.122/5.162/6.177/0.133 ms
|
||||
```
|
||||
|
||||
HTTP load generator benchmark with [`oha`](https://github.com/hatoo/oha)
|
||||
```rust,ignore
|
||||
# oha -c 1 http://<IP> -z 60s
|
||||
Summary:
|
||||
Success rate: 50.00%
|
||||
Total: 60.0005 secs
|
||||
Slowest: 0.0055 secs
|
||||
Fastest: 0.0033 secs
|
||||
Average: 0.0034 secs
|
||||
Requests/sec: 362.1971
|
||||
|
||||
Total data: 2.99 MiB
|
||||
Size/request: 289 B
|
||||
Size/sec: 51.11 KiB
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
This work is licensed under either of
|
||||
|
|
|
@ -257,29 +257,30 @@ pub const CRC32R_LOOKUP_TABLE: [u32; 256] = [
|
|||
0x2D02_EF8D,
|
||||
];
|
||||
|
||||
/// Generate Ethernet Frame Check Sequence
|
||||
#[allow(non_camel_case_types)]
|
||||
#[derive(Debug)]
|
||||
pub struct ETH_FSC(pub u32);
|
||||
pub struct ETH_FCS(pub u32);
|
||||
|
||||
impl ETH_FSC {
|
||||
impl ETH_FCS {
|
||||
pub const CRC32_OK: u32 = 0x2144_df1c;
|
||||
|
||||
#[must_use]
|
||||
pub fn new(data: &[u8]) -> Self {
|
||||
let fsc = data.iter().fold(u32::MAX, |crc, byte| {
|
||||
let fcs = data.iter().fold(u32::MAX, |crc, byte| {
|
||||
let idx = u8::try_from(crc & 0xFF).unwrap() ^ byte;
|
||||
CRC32R_LOOKUP_TABLE[usize::from(idx)] ^ (crc >> 8)
|
||||
}) ^ u32::MAX;
|
||||
Self(fsc)
|
||||
Self(fcs)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn update(self, data: &[u8]) -> Self {
|
||||
let fsc = data.iter().fold(self.0 ^ u32::MAX, |crc, byte| {
|
||||
let fcs = data.iter().fold(self.0 ^ u32::MAX, |crc, byte| {
|
||||
let idx = u8::try_from(crc & 0xFF).unwrap() ^ byte;
|
||||
CRC32R_LOOKUP_TABLE[usize::from(idx)] ^ (crc >> 8)
|
||||
}) ^ u32::MAX;
|
||||
Self(fsc)
|
||||
Self(fcs)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
|
@ -319,24 +320,24 @@ mod tests {
|
|||
];
|
||||
|
||||
// Packet A
|
||||
let own_crc = ETH_FSC::new(&packet_a[0..60]);
|
||||
let own_crc = ETH_FCS::new(&packet_a[0..60]);
|
||||
let crc_bytes = own_crc.hton_bytes();
|
||||
println!("{:08x} {:02x?}", own_crc.0, crc_bytes);
|
||||
assert_eq!(&crc_bytes, &packet_a[60..64]);
|
||||
|
||||
let own_crc = ETH_FSC::new(packet_a);
|
||||
let own_crc = ETH_FCS::new(packet_a);
|
||||
println!("{:08x}", own_crc.0);
|
||||
assert_eq!(own_crc.0, ETH_FSC::CRC32_OK);
|
||||
assert_eq!(own_crc.0, ETH_FCS::CRC32_OK);
|
||||
|
||||
// Packet B
|
||||
let own_crc = ETH_FSC::new(&packet_b[0..60]);
|
||||
let own_crc = ETH_FCS::new(&packet_b[0..60]);
|
||||
let crc_bytes = own_crc.hton_bytes();
|
||||
println!("{:08x} {:02x?}", own_crc.0, crc_bytes);
|
||||
assert_eq!(&crc_bytes, &packet_b[60..64]);
|
||||
|
||||
let own_crc = ETH_FSC::new(packet_b);
|
||||
let own_crc = ETH_FCS::new(packet_b);
|
||||
println!("{:08x}", own_crc.0);
|
||||
assert_eq!(own_crc.0, ETH_FSC::CRC32_OK);
|
||||
assert_eq!(own_crc.0, ETH_FCS::CRC32_OK);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -349,9 +350,9 @@ mod tests {
|
|||
];
|
||||
|
||||
let (part_a, part_b) = full_data.split_at(16);
|
||||
let crc_partially = ETH_FSC::new(part_a).update(part_b);
|
||||
let crc_partially = ETH_FCS::new(part_a).update(part_b);
|
||||
|
||||
let crc_full = ETH_FSC::new(full_data);
|
||||
let crc_full = ETH_FCS::new(full_data);
|
||||
|
||||
assert_eq!(crc_full.0, crc_partially.0);
|
||||
}
|
||||
|
|
254
embassy-net-adin1110/src/fmt.rs
Normal file
254
embassy-net-adin1110/src/fmt.rs
Normal file
|
@ -0,0 +1,254 @@
|
|||
#![macro_use]
|
||||
#![allow(unused_macros)]
|
||||
|
||||
use core::fmt::{Debug, Display, LowerHex};
|
||||
|
||||
#[cfg(all(feature = "defmt", feature = "log"))]
|
||||
compile_error!("You may not enable both `defmt` and `log` features.");
|
||||
|
||||
macro_rules! assert {
|
||||
($($x:tt)*) => {
|
||||
{
|
||||
#[cfg(not(feature = "defmt"))]
|
||||
::core::assert!($($x)*);
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::assert!($($x)*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! assert_eq {
|
||||
($($x:tt)*) => {
|
||||
{
|
||||
#[cfg(not(feature = "defmt"))]
|
||||
::core::assert_eq!($($x)*);
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::assert_eq!($($x)*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! assert_ne {
|
||||
($($x:tt)*) => {
|
||||
{
|
||||
#[cfg(not(feature = "defmt"))]
|
||||
::core::assert_ne!($($x)*);
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::assert_ne!($($x)*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! debug_assert {
|
||||
($($x:tt)*) => {
|
||||
{
|
||||
#[cfg(not(feature = "defmt"))]
|
||||
::core::debug_assert!($($x)*);
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::debug_assert!($($x)*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! debug_assert_eq {
|
||||
($($x:tt)*) => {
|
||||
{
|
||||
#[cfg(not(feature = "defmt"))]
|
||||
::core::debug_assert_eq!($($x)*);
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::debug_assert_eq!($($x)*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! debug_assert_ne {
|
||||
($($x:tt)*) => {
|
||||
{
|
||||
#[cfg(not(feature = "defmt"))]
|
||||
::core::debug_assert_ne!($($x)*);
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::debug_assert_ne!($($x)*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! todo {
|
||||
($($x:tt)*) => {
|
||||
{
|
||||
#[cfg(not(feature = "defmt"))]
|
||||
::core::todo!($($x)*);
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::todo!($($x)*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! unreachable {
|
||||
($($x:tt)*) => {
|
||||
{
|
||||
#[cfg(not(feature = "defmt"))]
|
||||
::core::unreachable!($($x)*);
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::unreachable!($($x)*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! panic {
|
||||
($($x:tt)*) => {
|
||||
{
|
||||
#[cfg(not(feature = "defmt"))]
|
||||
::core::panic!($($x)*);
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::panic!($($x)*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! trace {
|
||||
($s:literal $(, $x:expr)* $(,)?) => {
|
||||
{
|
||||
#[cfg(feature = "log")]
|
||||
::log::trace!($s $(, $x)*);
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::trace!($s $(, $x)*);
|
||||
#[cfg(not(any(feature = "log", feature="defmt")))]
|
||||
let _ignored = ($( & $x ),*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! debug {
|
||||
($s:literal $(, $x:expr)* $(,)?) => {
|
||||
{
|
||||
#[cfg(feature = "log")]
|
||||
::log::debug!($s $(, $x)*);
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::debug!($s $(, $x)*);
|
||||
#[cfg(not(any(feature = "log", feature="defmt")))]
|
||||
let _ignored = ($( & $x ),*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! info {
|
||||
($s:literal $(, $x:expr)* $(,)?) => {
|
||||
{
|
||||
#[cfg(feature = "log")]
|
||||
::log::info!($s $(, $x)*);
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::info!($s $(, $x)*);
|
||||
#[cfg(not(any(feature = "log", feature="defmt")))]
|
||||
let _ignored = ($( & $x ),*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! warn {
|
||||
($s:literal $(, $x:expr)* $(,)?) => {
|
||||
{
|
||||
#[cfg(feature = "log")]
|
||||
::log::warn!($s $(, $x)*);
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::warn!($s $(, $x)*);
|
||||
#[cfg(not(any(feature = "log", feature="defmt")))]
|
||||
let _ignored = ($( & $x ),*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! error {
|
||||
($s:literal $(, $x:expr)* $(,)?) => {
|
||||
{
|
||||
#[cfg(feature = "log")]
|
||||
::log::error!($s $(, $x)*);
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::error!($s $(, $x)*);
|
||||
#[cfg(not(any(feature = "log", feature="defmt")))]
|
||||
let _ignored = ($( & $x ),*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(feature = "defmt")]
|
||||
macro_rules! unwrap {
|
||||
($($x:tt)*) => {
|
||||
::defmt::unwrap!($($x)*)
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "defmt"))]
|
||||
macro_rules! unwrap {
|
||||
($arg:expr) => {
|
||||
match $crate::fmt::Try::into_result($arg) {
|
||||
::core::result::Result::Ok(t) => t,
|
||||
::core::result::Result::Err(e) => {
|
||||
::core::panic!("unwrap of `{}` failed: {:?}", ::core::stringify!($arg), e);
|
||||
}
|
||||
}
|
||||
};
|
||||
($arg:expr, $($msg:expr),+ $(,)? ) => {
|
||||
match $crate::fmt::Try::into_result($arg) {
|
||||
::core::result::Result::Ok(t) => t,
|
||||
::core::result::Result::Err(e) => {
|
||||
::core::panic!("unwrap of `{}` failed: {}: {:?}", ::core::stringify!($arg), ::core::format_args!($($msg,)*), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
pub struct NoneError;
|
||||
|
||||
pub trait Try {
|
||||
type Ok;
|
||||
type Error;
|
||||
fn into_result(self) -> Result<Self::Ok, Self::Error>;
|
||||
}
|
||||
|
||||
impl<T> Try for Option<T> {
|
||||
type Ok = T;
|
||||
type Error = NoneError;
|
||||
|
||||
#[inline]
|
||||
fn into_result(self) -> Result<T, NoneError> {
|
||||
self.ok_or(NoneError)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, E> Try for Result<T, E> {
|
||||
type Ok = T;
|
||||
type Error = E;
|
||||
|
||||
#[inline]
|
||||
fn into_result(self) -> Self {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Bytes<'a>(pub &'a [u8]);
|
||||
|
||||
impl<'a> Debug for Bytes<'a> {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
write!(f, "{:#02x?}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Display for Bytes<'a> {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
write!(f, "{:#02x?}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> LowerHex for Bytes<'a> {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
write!(f, "{:#02x?}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "defmt")]
|
||||
impl<'a> defmt::Format for Bytes<'a> {
|
||||
fn format(&self, fmt: defmt::Formatter) {
|
||||
defmt::write!(fmt, "{:02x}", self.0)
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,3 +1,5 @@
|
|||
use core::fmt::{Debug, Display};
|
||||
|
||||
use bitfield::{bitfield, bitfield_bitrange, bitfield_fields};
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
|
@ -34,6 +36,12 @@ pub enum SpiRegisters {
|
|||
RX = 0x91,
|
||||
}
|
||||
|
||||
impl Display for SpiRegisters {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
write!(f, "{self:?}")
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SpiRegisters> for u16 {
|
||||
fn from(val: SpiRegisters) -> Self {
|
||||
val as u16
|
||||
|
@ -68,7 +76,7 @@ impl From<u16> for SpiRegisters {
|
|||
0x73 => Self::ADDR_MSK_UPR1,
|
||||
0x90 => Self::RX_FSIZE,
|
||||
0x91 => Self::RX,
|
||||
e => panic!("Unknown value {e}"),
|
||||
e => panic!("Unknown value {}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -174,7 +182,7 @@ bitfield! {
|
|||
pub sdf_detect_src, set_sdf_detect_src : 7;
|
||||
/// Statistics Clear on Reading
|
||||
pub stats_clr_on_rd, set_stats_clr_on_rd : 6;
|
||||
/// Enable CRC Append
|
||||
/// Enable SPI CRC
|
||||
pub crc_append, set_crc_append : 5;
|
||||
/// Admit Frames with IFG Errors on Port 1 (P1)
|
||||
pub p1_rcv_ifg_err_frm, set_p1_rcv_ifg_err_frm : 4;
|
||||
|
@ -313,7 +321,7 @@ impl From<u8> for LedFunc {
|
|||
26 => LedFunc::Clk25Ref,
|
||||
27 => LedFunc::TxTCLK,
|
||||
28 => LedFunc::Clk120MHz,
|
||||
e => panic!("Invalid value {e}"),
|
||||
e => panic!("Invalid value {}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -369,7 +377,7 @@ impl From<u8> for LedPol {
|
|||
0 => LedPol::AutoSense,
|
||||
1 => LedPol::ActiveHigh,
|
||||
2 => LedPol::ActiveLow,
|
||||
e => panic!("Invalid value {e}"),
|
||||
e => panic!("Invalid value {}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[package]
|
||||
edition = "2021"
|
||||
name = "embassy-stm32l4-examples"
|
||||
version = "0.1.0"
|
||||
version = "0.1.1"
|
||||
license = "MIT OR Apache-2.0"
|
||||
|
||||
[dependencies]
|
||||
|
@ -12,7 +12,7 @@ embassy-executor = { version = "0.3.0", path = "../../embassy-executor", feature
|
|||
embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768", "unstable-traits", "nightly"] }
|
||||
embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal" }
|
||||
embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
|
||||
embassy-net-adin1110 = { version = "0.1.0", path = "../../embassy-net-adin1110", default-features = false }
|
||||
embassy-net-adin1110 = { version = "0.2.0", path = "../../embassy-net-adin1110" }
|
||||
embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "nightly", "udp", "tcp", "dhcpv4", "medium-ethernet"] }
|
||||
embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
|
||||
embedded-io-async = { version = "0.5.0", features = ["defmt-03"] }
|
||||
|
|
|
@ -11,7 +11,9 @@
|
|||
// Settings switch S201 "HW CFG":
|
||||
// - Without SPI CRC: OFF-ON-OFF-OFF-OFF
|
||||
// - With SPI CRC: ON -ON-OFF-OFF-OFF
|
||||
// Settings switch S303 "uC CFG": CFG0: On = static ip, Off = Dhcp
|
||||
// Settings switch S303 "uC CFG":
|
||||
// - CFG0: On = static ip, Off = Dhcp
|
||||
// - CFG1: Ethernet `FCS` on TX path: On, Off
|
||||
// The webserver shows the actual temperature of the onboard i2c temp sensor.
|
||||
|
||||
use core::marker::PhantomData;
|
||||
|
@ -107,7 +109,7 @@ async fn main(spawner: Spawner) {
|
|||
|
||||
// Read the uc_cfg switches
|
||||
let uc_cfg0 = Input::new(dp.PB2, Pull::None);
|
||||
let _uc_cfg1 = Input::new(dp.PF11, Pull::None);
|
||||
let uc_cfg1 = Input::new(dp.PF11, Pull::None);
|
||||
let _uc_cfg2 = Input::new(dp.PG6, Pull::None);
|
||||
let _uc_cfg3 = Input::new(dp.PG11, Pull::None);
|
||||
|
||||
|
@ -154,11 +156,13 @@ async fn main(spawner: Spawner) {
|
|||
|
||||
let cfg0_without_crc = spe_cfg0.is_high();
|
||||
let cfg1_spi_mode = spe_cfg1.is_high();
|
||||
let uc_cfg1_fcs_en = uc_cfg1.is_low();
|
||||
|
||||
defmt::println!(
|
||||
"ADIN1110: CFG SPI-MODE 1-{}, CRC-bit 0-{}",
|
||||
"ADIN1110: CFG SPI-MODE 1-{}, CRC-bit 0-{} FCS-{}",
|
||||
cfg1_spi_mode,
|
||||
cfg0_without_crc
|
||||
cfg0_without_crc,
|
||||
uc_cfg1_fcs_en
|
||||
);
|
||||
|
||||
// Check the SPI mode selected with the "HW CFG" dip-switch
|
||||
|
@ -172,8 +176,16 @@ async fn main(spawner: Spawner) {
|
|||
|
||||
let state = make_static!(embassy_net_adin1110::State::<8, 8>::new());
|
||||
|
||||
let (device, runner) =
|
||||
embassy_net_adin1110::new(MAC, state, spe_spi, spe_int, spe_reset_n, !cfg0_without_crc).await;
|
||||
let (device, runner) = embassy_net_adin1110::new(
|
||||
MAC,
|
||||
state,
|
||||
spe_spi,
|
||||
spe_int,
|
||||
spe_reset_n,
|
||||
!cfg0_without_crc,
|
||||
uc_cfg1_fcs_en,
|
||||
)
|
||||
.await;
|
||||
|
||||
// Start task blink_led
|
||||
unwrap!(spawner.spawn(heartbeat_led(led_uc3_yellow)));
|
||||
|
|
Loading…
Reference in a new issue