diff --git a/Cargo.lock b/Cargo.lock index 5a8e571..d07d248 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -38,6 +38,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603" +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + [[package]] name = "bitfield" version = "0.13.2" @@ -56,6 +62,15 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" 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]] name = "bytemuck" version = "1.21.0" @@ -68,6 +83,18 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" 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]] name = "cortex-m" version = "0.7.7" @@ -128,6 +155,15 @@ dependencies = [ "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]] name = "crc-any" version = "2.5.0" @@ -143,6 +179,28 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" 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]] name = "debug-helper" version = "0.3.13" @@ -192,12 +250,52 @@ dependencies = [ "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]] name = "either" version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" 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]] name = "embedded-dma" version = "0.2.0" @@ -248,6 +346,16 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" 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]] name = "frunk" version = "0.4.3" @@ -302,6 +410,28 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" 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]] name = "hash32" version = "0.2.1" @@ -349,6 +479,24 @@ dependencies = [ "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]] name = "indexmap" version = "1.9.3" @@ -368,6 +516,12 @@ dependencies = [ "either", ] +[[package]] +name = "libc" +version = "0.2.169" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" + [[package]] name = "lock_api" version = "0.4.12" @@ -378,6 +532,12 @@ dependencies = [ "scopeguard", ] +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + [[package]] name = "nb" version = "0.1.3" @@ -413,6 +573,16 @@ dependencies = [ "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]] name = "panic-halt" version = "1.0.0" @@ -442,6 +612,15 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" 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]] name = "proc-macro-error" version = "1.0.4" @@ -532,12 +711,15 @@ dependencies = [ "defmt-serial", "embedded-hal 1.0.0", "fugit", + "heapless 0.8.0", "panic-halt", "rp2040-boot2", "rp2040-hal", "smart-leds", "usb-device", "usbd-serial", + "w5500-dhcp", + "w5500-mqtt", "waveshare-rp2040-zero", "ws2812-pio", ] @@ -575,6 +757,7 @@ dependencies = [ "rand_core", "rp2040-hal-macros", "rp2040-pac", + "rtic-monotonic", "usb-device", "vcell", "void", @@ -652,6 +835,19 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" 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]] name = "semver" version = "0.9.0" @@ -673,6 +869,17 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" 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]] name = "smart-leds" version = "0.3.0" @@ -706,6 +913,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] name = "syn" version = "1.0.109" @@ -748,6 +961,12 @@ dependencies = [ "syn 2.0.90", ] +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + [[package]] name = "unicode-ident" version = "1.0.14" @@ -803,6 +1022,63 @@ dependencies = [ "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]] name = "waveshare-rp2040-zero" version = "0.8.0" @@ -828,3 +1104,9 @@ dependencies = [ "rp2040-hal", "smart-leds-trait", ] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" diff --git a/Cargo.toml b/Cargo.toml index d23881e..fd95c59 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,8 +15,9 @@ cortex-m = "0.7" fugit = "0.3.7" cortex-m-rt = "0.7" rp2040-boot2 = { version = "0.3.0", optional = true } -rp2040-hal = "0.10.2" -waveshare-rp2040-zero = "0.8.0" +rp2040-hal = {version = "0.10.2", features = ["rtic-monotonic"]} +waveshare-rp2040-zero = { version = "0.8.0", features = ["rt"] } + cortex-m-rtic = "1" embedded-hal = "1.0.0" @@ -30,3 +31,6 @@ usbd-serial = "0.2.2" smart-leds = "0.3.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" \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index c899de3..9fd042f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,35 +3,100 @@ 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 { - use core::iter::once;use fugit::MicrosDurationU32; - use rp2040_hal::Clock; - use rp2040_hal::gpio::{FunctionPio0, PullDown}; - use rp2040_hal::gpio::bank0::Gpio16; - use rp2040_hal::pac::PIO0; + use core::iter::once; + use cortex_m::delay::Delay; + use fugit::MicrosDurationU32; + use fugit::RateExtU32; + 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::timer::CountDown; + use rp2040_hal::{Clock, Spi}; use smart_leds::{brightness, SmartLedsWrite}; use usbd_serial::SerialPort; + use waveshare_rp2040_zero::hal::spi::Enabled; 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, }; use usb_device::{class_prelude::*, prelude::*}; - use ws2812_pio::Ws2812; 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 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; + + #[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] struct Shared { timer: hal::Timer, - alarm: hal::timer::Alarm0, usb_dev: UsbDevice<'static, hal::usb::UsbBus>, serial: SerialPort<'static, hal::usb::UsbBus>, - ws: Ws2812, hal::gpio::Pin> + ws: Ws2812, hal::gpio::Pin>, + w5500: W5500< + Spi< + Enabled, + SPI0, + ( + Pin, + Pin, + Pin, + ), + >, + Pin, PullDown>, + >, + spi_reset: Pin, PullDown>, + blink_state: BlinkState, } #[local] @@ -123,32 +188,171 @@ mod app { let _ = alarm.schedule(SCAN_TIME_US); 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( - binds = TIMER_IRQ_0, priority = 1, - shared = [alarm, serial, ws], + shared = [serial, ws, blink_state], local = [tog: bool = true], )] - fn timer_irq(mut c: timer_irq::Context) { - if *c.local.tog { - c.shared.ws.lock(|ws| ws.write(brightness(once((255, 0, 0).into()), 32)).unwrap()); - c.shared.serial.lock(|serial| _ = serial.write(b"High\r\n")); + fn timer_irq(c: timer_irq::Context) { + let blink_state = c.shared.blink_state; + let ws = c.shared.ws; + let serial = c.shared.serial; + let tog = c.local.tog; - } else { - c.shared.ws.lock(|ws| ws.write(brightness(once((0, 0, 0).into()), 32)).unwrap()); - c.shared.serial.lock(|serial| _ = serial.write(b"LOW\r\n")); - } - *c.local.tog = !*c.local.tog; - - - let mut alarm = c.shared.alarm; - (alarm).lock(|a| { - a.clear_interrupt(); - let _ = a.schedule(SCAN_TIME_US); + (blink_state, ws, serial).lock(|blink_state, ws, serial| { + if *tog { + match blink_state { + BlinkState::GOOD => { + ws.write(brightness(once((0, 255, 0).into()), 25)).unwrap(); + _ = serial.write(b"High\r\n"); + } + BlinkState::Init => { + ws.write(brightness(once((0, 0, 255).into()), 25)).unwrap(); + _ = serial.write(b"Init\r\n"); + } + 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(