add code to init w5500

This commit is contained in:
lukas-heiligenbrunner 2024-12-25 19:20:34 +01:00
parent 1e771a162b
commit b326a5013c
3 changed files with 520 additions and 30 deletions

282
Cargo.lock generated
View File

@ -38,6 +38,12 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603" checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603"
[[package]]
name = "base16ct"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf"
[[package]] [[package]]
name = "bitfield" name = "bitfield"
version = "0.13.2" version = "0.13.2"
@ -56,6 +62,15 @@ version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "block-buffer"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
dependencies = [
"generic-array",
]
[[package]] [[package]]
name = "bytemuck" name = "bytemuck"
version = "1.21.0" version = "1.21.0"
@ -68,6 +83,18 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "const-oid"
version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
[[package]] [[package]]
name = "cortex-m" name = "cortex-m"
version = "0.7.7" version = "0.7.7"
@ -128,6 +155,15 @@ dependencies = [
"syn 1.0.109", "syn 1.0.109",
] ]
[[package]]
name = "cpufeatures"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "crc-any" name = "crc-any"
version = "2.5.0" version = "2.5.0"
@ -143,6 +179,28 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b"
[[package]]
name = "crypto-bigint"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76"
dependencies = [
"generic-array",
"rand_core",
"subtle",
"zeroize",
]
[[package]]
name = "crypto-common"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
dependencies = [
"generic-array",
"typenum",
]
[[package]] [[package]]
name = "debug-helper" name = "debug-helper"
version = "0.3.13" version = "0.3.13"
@ -192,12 +250,52 @@ dependencies = [
"embedded-io", "embedded-io",
] ]
[[package]]
name = "der"
version = "0.7.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0"
dependencies = [
"const-oid",
"zeroize",
]
[[package]]
name = "digest"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"crypto-common",
"subtle",
]
[[package]] [[package]]
name = "either" name = "either"
version = "1.13.0" version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
[[package]]
name = "elliptic-curve"
version = "0.13.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47"
dependencies = [
"base16ct",
"crypto-bigint",
"digest",
"ff",
"generic-array",
"group",
"hkdf",
"rand_core",
"sec1",
"subtle",
"zeroize",
]
[[package]] [[package]]
name = "embedded-dma" name = "embedded-dma"
version = "0.2.0" version = "0.2.0"
@ -248,6 +346,16 @@ version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d"
[[package]]
name = "ff"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449"
dependencies = [
"rand_core",
"subtle",
]
[[package]] [[package]]
name = "frunk" name = "frunk"
version = "0.4.3" version = "0.4.3"
@ -302,6 +410,28 @@ version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d758ba1b47b00caf47f24925c0074ecb20d6dfcffe7f6d53395c0465674841a" checksum = "1d758ba1b47b00caf47f24925c0074ecb20d6dfcffe7f6d53395c0465674841a"
[[package]]
name = "generic-array"
version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
dependencies = [
"typenum",
"version_check",
"zeroize",
]
[[package]]
name = "group"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63"
dependencies = [
"ff",
"rand_core",
"subtle",
]
[[package]] [[package]]
name = "hash32" name = "hash32"
version = "0.2.1" version = "0.2.1"
@ -349,6 +479,24 @@ dependencies = [
"stable_deref_trait", "stable_deref_trait",
] ]
[[package]]
name = "hkdf"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7"
dependencies = [
"hmac",
]
[[package]]
name = "hmac"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
dependencies = [
"digest",
]
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "1.9.3" version = "1.9.3"
@ -368,6 +516,12 @@ dependencies = [
"either", "either",
] ]
[[package]]
name = "libc"
version = "0.2.169"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
[[package]] [[package]]
name = "lock_api" name = "lock_api"
version = "0.4.12" version = "0.4.12"
@ -378,6 +532,12 @@ dependencies = [
"scopeguard", "scopeguard",
] ]
[[package]]
name = "log"
version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
[[package]] [[package]]
name = "nb" name = "nb"
version = "0.1.3" version = "0.1.3"
@ -413,6 +573,16 @@ dependencies = [
"syn 1.0.109", "syn 1.0.109",
] ]
[[package]]
name = "p256"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b"
dependencies = [
"elliptic-curve",
"primeorder",
]
[[package]] [[package]]
name = "panic-halt" name = "panic-halt"
version = "1.0.0" version = "1.0.0"
@ -442,6 +612,15 @@ version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6" checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6"
[[package]]
name = "primeorder"
version = "0.13.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6"
dependencies = [
"elliptic-curve",
]
[[package]] [[package]]
name = "proc-macro-error" name = "proc-macro-error"
version = "1.0.4" version = "1.0.4"
@ -532,12 +711,15 @@ dependencies = [
"defmt-serial", "defmt-serial",
"embedded-hal 1.0.0", "embedded-hal 1.0.0",
"fugit", "fugit",
"heapless 0.8.0",
"panic-halt", "panic-halt",
"rp2040-boot2", "rp2040-boot2",
"rp2040-hal", "rp2040-hal",
"smart-leds", "smart-leds",
"usb-device", "usb-device",
"usbd-serial", "usbd-serial",
"w5500-dhcp",
"w5500-mqtt",
"waveshare-rp2040-zero", "waveshare-rp2040-zero",
"ws2812-pio", "ws2812-pio",
] ]
@ -575,6 +757,7 @@ dependencies = [
"rand_core", "rand_core",
"rp2040-hal-macros", "rp2040-hal-macros",
"rp2040-pac", "rp2040-pac",
"rtic-monotonic",
"usb-device", "usb-device",
"vcell", "vcell",
"void", "void",
@ -652,6 +835,19 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "sec1"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc"
dependencies = [
"base16ct",
"der",
"generic-array",
"subtle",
"zeroize",
]
[[package]] [[package]]
name = "semver" name = "semver"
version = "0.9.0" version = "0.9.0"
@ -673,6 +869,17 @@ version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
name = "sha2"
version = "0.10.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]] [[package]]
name = "smart-leds" name = "smart-leds"
version = "0.3.0" version = "0.3.0"
@ -706,6 +913,12 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]]
name = "subtle"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.109" version = "1.0.109"
@ -748,6 +961,12 @@ dependencies = [
"syn 2.0.90", "syn 2.0.90",
] ]
[[package]]
name = "typenum"
version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"
version = "1.0.14" version = "1.0.14"
@ -803,6 +1022,63 @@ dependencies = [
"vcell", "vcell",
] ]
[[package]]
name = "w5500-dhcp"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a45835364e6e32f610a4aced5eef3d7cdffff94e9dc60bd8a92989e4442b2ea6"
dependencies = [
"log",
"w5500-hl",
]
[[package]]
name = "w5500-hl"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acf85c58c338dedab9c75a67f40564a0987356b6b6338335325b7bd51b5c535e"
dependencies = [
"w5500-ll",
]
[[package]]
name = "w5500-ll"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef4332c876837525e11b6949300fb7471ec8a2718a7df4fc66084f64feb28ca6"
dependencies = [
"embedded-hal 0.2.7",
]
[[package]]
name = "w5500-mqtt"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee1e988d3c3e0f50cc618999424ad177e403113fbe1f1dc13600c466f123a46b"
dependencies = [
"log",
"w5500-hl",
"w5500-tls",
]
[[package]]
name = "w5500-tls"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3aac13decfc63c93230a2d2c54928ad78affb887ff3e43e48293f01d85179693"
dependencies = [
"cfg-if",
"heapless 0.8.0",
"hkdf",
"hmac",
"log",
"p256",
"rand_core",
"sha2",
"subtle",
"w5500-hl",
]
[[package]] [[package]]
name = "waveshare-rp2040-zero" name = "waveshare-rp2040-zero"
version = "0.8.0" version = "0.8.0"
@ -828,3 +1104,9 @@ dependencies = [
"rp2040-hal", "rp2040-hal",
"smart-leds-trait", "smart-leds-trait",
] ]
[[package]]
name = "zeroize"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"

View File

@ -15,8 +15,9 @@ cortex-m = "0.7"
fugit = "0.3.7" fugit = "0.3.7"
cortex-m-rt = "0.7" cortex-m-rt = "0.7"
rp2040-boot2 = { version = "0.3.0", optional = true } rp2040-boot2 = { version = "0.3.0", optional = true }
rp2040-hal = "0.10.2" rp2040-hal = {version = "0.10.2", features = ["rtic-monotonic"]}
waveshare-rp2040-zero = "0.8.0" waveshare-rp2040-zero = { version = "0.8.0", features = ["rt"] }
cortex-m-rtic = "1" cortex-m-rtic = "1"
embedded-hal = "1.0.0" embedded-hal = "1.0.0"
@ -30,3 +31,6 @@ usbd-serial = "0.2.2"
smart-leds = "0.3.0" smart-leds = "0.3.0"
ws2812-pio = "0.8.0" ws2812-pio = "0.8.0"
w5500-dhcp = { version = "0.7", features = ["eh0", "log"] }
w5500-mqtt = { version = "0.4", features = ["eh0", "log"] }
heapless = "0.8.0"

View File

@ -3,35 +3,100 @@
use panic_halt as _; use panic_halt as _;
#[rtic::app(device = waveshare_rp2040_zero::hal::pac, peripherals = true)] #[rtic::app(device = waveshare_rp2040_zero::hal::pac, peripherals = true, dispatchers = [I2C0_IRQ])]
mod app { mod app {
use core::iter::once;use fugit::MicrosDurationU32; use core::iter::once;
use rp2040_hal::Clock; use cortex_m::delay::Delay;
use rp2040_hal::gpio::{FunctionPio0, PullDown}; use fugit::MicrosDurationU32;
use rp2040_hal::gpio::bank0::Gpio16; use fugit::RateExtU32;
use rp2040_hal::pac::PIO0; use rp2040_hal::gpio::bank0::{Gpio16, Gpio2, Gpio3, Gpio4, Gpio5, Gpio7};
use rp2040_hal::gpio::{
FunctionPio0, FunctionSio, FunctionSpi, Pin, PullDown, PullNone, PullUp, SioOutput,
};
use rp2040_hal::pio::SM0; use rp2040_hal::pio::SM0;
use rp2040_hal::timer::CountDown; use rp2040_hal::timer::CountDown;
use rp2040_hal::{Clock, Spi};
use smart_leds::{brightness, SmartLedsWrite}; use smart_leds::{brightness, SmartLedsWrite};
use usbd_serial::SerialPort; use usbd_serial::SerialPort;
use waveshare_rp2040_zero::hal::spi::Enabled;
use waveshare_rp2040_zero::{ use waveshare_rp2040_zero::{
hal::{self, clocks::init_clocks_and_plls, timer::Alarm, watchdog::Watchdog, Sio}, hal::{
self, clocks::init_clocks_and_plls, timer::monotonic::Monotonic, timer::Alarm,
watchdog::Watchdog, Sio,
},
pac::{PIO0, SPI0},
XOSC_CRYSTAL_FREQ, XOSC_CRYSTAL_FREQ,
}; };
use usb_device::{class_prelude::*, prelude::*}; use usb_device::{class_prelude::*, prelude::*};
use ws2812_pio::Ws2812;
use waveshare_rp2040_zero::hal::pio::PIOExt; use waveshare_rp2040_zero::hal::pio::PIOExt;
use ws2812_pio::Ws2812;
use core::fmt::Write;
use embedded_hal::digital::OutputPin;
use fugit::ExtU32;
use rp2040_hal::timer::Alarm0;
use w5500_dhcp::{
hl::Hostname,
ll::{
eh0::vdm_infallible_gpio::W5500,
eh0::MODE as W5500_MODE,
net::{Eui48Addr, Ipv4Addr, SocketAddrV4},
LinkStatus, OperationMode, PhyCfg, Registers, Sn,
},
Client as DhcpClient,
};
use w5500_mqtt::{
Client as MqttClient, ClientId, Event as MqttEvent, SRC_PORT as MQTT_SRC_PORT,
};
const SYSCLK_HZ: u32 = 8_000_000;
const SCAN_TIME_US: MicrosDurationU32 = MicrosDurationU32::millis(400); const SCAN_TIME_US: MicrosDurationU32 = MicrosDurationU32::millis(400);
const DHCP_SN: Sn = Sn::Sn0;
const MQTT_SN: Sn = Sn::Sn1;
const MQTT_SERVER: SocketAddrV4 = SocketAddrV4::new(Ipv4Addr::new(192, 168, 0, 14), 1883);
const NAME: &str = "ambient1";
const HOSTNAME: Hostname<'static> = Hostname::new_unwrapped(NAME);
const CLIENT_ID: ClientId<'static> = ClientId::new_unwrapped(NAME);
#[monotonic(binds = TIMER_IRQ_0, default = true)]
type MyMono = Monotonic<Alarm0>;
#[inline(always)]
pub fn delay_ms(ms: u32) {
const CYCLES_PER_MILLIS: u32 = SYSCLK_HZ / 1000;
cortex_m::asm::delay(CYCLES_PER_MILLIS.saturating_mul(ms));
}
pub enum BlinkState {
GOOD,
Init,
EthernetError,
OtherError,
}
#[shared] #[shared]
struct Shared { struct Shared {
timer: hal::Timer, timer: hal::Timer,
alarm: hal::timer::Alarm0,
usb_dev: UsbDevice<'static, hal::usb::UsbBus>, usb_dev: UsbDevice<'static, hal::usb::UsbBus>,
serial: SerialPort<'static, hal::usb::UsbBus>, serial: SerialPort<'static, hal::usb::UsbBus>,
ws: Ws2812<PIO0, SM0, CountDown<'static>, hal::gpio::Pin<Gpio16, FunctionPio0, PullDown>> ws: Ws2812<PIO0, SM0, CountDown<'static>, hal::gpio::Pin<Gpio16, FunctionPio0, PullDown>>,
w5500: W5500<
Spi<
Enabled,
SPI0,
(
Pin<Gpio3, FunctionSpi, PullNone>,
Pin<Gpio4, FunctionSpi, PullUp>,
Pin<Gpio2, FunctionSpi, PullNone>,
),
>,
Pin<Gpio5, FunctionSio<SioOutput>, PullDown>,
>,
spi_reset: Pin<Gpio7, FunctionSio<SioOutput>, PullDown>,
blink_state: BlinkState,
} }
#[local] #[local]
@ -123,32 +188,171 @@ mod app {
let _ = alarm.schedule(SCAN_TIME_US); let _ = alarm.schedule(SCAN_TIME_US);
alarm.enable_interrupt(); alarm.enable_interrupt();
(Shared { timer: *timer, alarm, usb_dev, serial, ws}, Local {}, init::Monotonics()) timer_irq::spawn_after(500_u32.millis().into()).unwrap();
// init ethernet stuff
// Set up our SPI pins into the correct mode
let spi_sclk: hal::gpio::Pin<_, hal::gpio::FunctionSpi, hal::gpio::PullNone> =
pins.gp2.reconfigure();
let spi_mosi: hal::gpio::Pin<_, hal::gpio::FunctionSpi, hal::gpio::PullNone> =
pins.gp3.reconfigure();
let spi_miso: hal::gpio::Pin<_, hal::gpio::FunctionSpi, hal::gpio::PullUp> =
pins.gp4.reconfigure();
let spi_cs = pins.gp5.into_push_pull_output();
let mut spi_reset = pins.gp7.into_push_pull_output();
// Create the SPI driver instance for the SPI0 device
let spi = hal::spi::Spi::<_, _, _, 8>::new(c.device.SPI0, (spi_mosi, spi_miso, spi_sclk));
// Exchange the uninitialised SPI driver for an initialised one
let spi = spi.init(
&mut resets,
clocks.peripheral_clock.freq(),
400.kHz(),
W5500_MODE,
);
let w5500 = W5500::new(spi, spi_cs);
w5500_dhcp::ll::eh0::reset(&mut spi_reset, &mut Delay::new(c.core.SYST, SYSCLK_HZ))
.unwrap();
init_ethernet::spawn_after(5000_u32.millis().into()).unwrap();
(Shared { timer: *timer, usb_dev, serial, ws, w5500,spi_reset, blink_state: BlinkState::Init}, Local {}, init::Monotonics(Monotonic::new(*timer, alarm)))
} }
#[task( #[task(
binds = TIMER_IRQ_0,
priority = 1, priority = 1,
shared = [alarm, serial, ws], shared = [serial, ws, blink_state],
local = [tog: bool = true], local = [tog: bool = true],
)] )]
fn timer_irq(mut c: timer_irq::Context) { fn timer_irq(c: timer_irq::Context) {
if *c.local.tog { let blink_state = c.shared.blink_state;
c.shared.ws.lock(|ws| ws.write(brightness(once((255, 0, 0).into()), 32)).unwrap()); let ws = c.shared.ws;
c.shared.serial.lock(|serial| _ = serial.write(b"High\r\n")); let serial = c.shared.serial;
let tog = c.local.tog;
} else { (blink_state, ws, serial).lock(|blink_state, ws, serial| {
c.shared.ws.lock(|ws| ws.write(brightness(once((0, 0, 0).into()), 32)).unwrap()); if *tog {
c.shared.serial.lock(|serial| _ = serial.write(b"LOW\r\n")); match blink_state {
} BlinkState::GOOD => {
*c.local.tog = !*c.local.tog; ws.write(brightness(once((0, 255, 0).into()), 25)).unwrap();
_ = serial.write(b"High\r\n");
}
let mut alarm = c.shared.alarm; BlinkState::Init => {
(alarm).lock(|a| { ws.write(brightness(once((0, 0, 255).into()), 25)).unwrap();
a.clear_interrupt(); _ = serial.write(b"Init\r\n");
let _ = a.schedule(SCAN_TIME_US); }
BlinkState::EthernetError => {
ws.write(brightness(once((255, 255, 0).into()), 25)).unwrap();
_ = serial.write(b"Ethernet error error\r\n");
}
BlinkState::OtherError => {
ws.write(brightness(once((255, 0, 0).into()), 25)).unwrap();
_ = serial.write(b"Other error\r\n");
}
}
} else {
ws.write(brightness(once((0, 0, 0).into()), 32)).unwrap();
}
*tog = !*tog;
}); });
timer_irq::spawn_after(250.millis().into()).unwrap();
}
#[task(
shared = [w5500, serial,spi_reset, blink_state],)
]
fn init_ethernet(c: init_ethernet::Context) {
let mac: Eui48Addr = Eui48Addr::new(0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED );
let w5500 = c.shared.w5500;
let serial = c.shared.serial;
let spi_reset = c.shared.spi_reset;
let blink_state = c.shared.blink_state;
(w5500, serial,spi_reset, blink_state).lock(|w5500, serial, spi_reset, blink_state| {
// continually initialize the W5500 until we link up
// since we are using power over Ethernet we know that if the device
// has power it also has an Ethernet cable connected.
let _phy_cfg: PhyCfg = 'outer: loop {
// sanity check W5500 communications
_ = serial.write(b"Sanity checks\r\n");
let version = w5500.version();
match version {
Ok(v) => {
let mut data: heapless::String<16> = heapless::String::new();
write!(
&mut data,
"Read version of w5500 {}\r\n",
v
)
.unwrap();
_ = serial.write(data.as_bytes());
}
Err(_) => {
_ = serial.write(b"Failed to read W5500 version\r\n");
*blink_state = BlinkState::EthernetError;
return;
}
}
_ = serial.write(b"Sanity checks passed\r\n");
// load the MAC address we got from EEPROM
w5500.set_shar(&mac).unwrap();
debug_assert_eq!(w5500.shar().unwrap(), mac);
// wait for the PHY to indicate the Ethernet link is up
let mut attempts: u32 = 0;
_ = serial.write(b"Polling for link up\r\n");
const PHY_CFG: PhyCfg = PhyCfg::DEFAULT.set_opmdc(OperationMode::FullDuplex10bt);
w5500.set_phycfgr(PHY_CFG).unwrap();
const LINK_UP_POLL_PERIOD_MILLIS: u32 = 100;
const LINK_UP_POLL_ATTEMPTS: u32 = 50;
loop {
let phy_cfg: PhyCfg = w5500.phycfgr().unwrap();
if phy_cfg.lnk() == LinkStatus::Up {
break 'outer phy_cfg;
}
if attempts >= LINK_UP_POLL_ATTEMPTS {
let mut data: heapless::String<16> = heapless::String::new();
write!(
&mut data,
"Failed to link up in {} ms\r\n",
attempts * LINK_UP_POLL_PERIOD_MILLIS
)
.unwrap();
_ = serial.write(data.as_bytes());
break;
}
delay_ms(LINK_UP_POLL_PERIOD_MILLIS);
attempts += 1;
}
spi_reset.set_low().unwrap();
delay_ms(1);
spi_reset.set_high().unwrap();
delay_ms(3);
};
let mut data: heapless::String<16> = heapless::String::new();
write!(&mut data, "Done link up\n{}", _phy_cfg).unwrap();
_ = serial.write(data.as_bytes());
let mut mqtt: MqttClient = MqttClient::new(MQTT_SN, MQTT_SRC_PORT, MQTT_SERVER);
mqtt.set_client_id(CLIENT_ID);
let seed: u64 = u64::from(cortex_m::peripheral::SYST::get_current()) << 32
| u64::from(cortex_m::peripheral::SYST::get_current());
let dhcp = DhcpClient::new(DHCP_SN, seed, mac, HOSTNAME);
dhcp.setup_socket(w5500).unwrap();
});
} }
#[task( #[task(