diff --git a/pico/Cargo.lock b/pico/Cargo.lock index 3bff83c..dcfd4a2 100644 --- a/pico/Cargo.lock +++ b/pico/Cargo.lock @@ -10,6 +10,7 @@ checksum = "2d33be4690212133536fac4ad4eea4b313bf4df60b5d2a27f78e8303e36b93a7" dependencies = [ "embedded-hal 1.0.0", "shared-bus", + "ufmt 0.1.2", ] [[package]] @@ -57,6 +58,17 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "as5600" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fdbe60b23e3ae22f4618c03b63aa884c4ca641830880f9d64b770d6467b4b7f" +dependencies = [ + "embedded-hal 1.0.0", + "num-derive", + "num-traits", +] + [[package]] name = "ascii-canvas" version = "4.0.0" @@ -518,11 +530,32 @@ dependencies = [ "num-traits", ] +[[package]] +name = "embassy-net" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "347bc855bdbdf50ed9c5a1d80e8204badb0ba149b8732dde38e1e9708ed9d313" +dependencies = [ + "defmt 1.0.1", + "document-features", + "embassy-net-driver", + "embassy-sync 0.8.0", + "embassy-time", + "embedded-io-async 0.7.0", + "embedded-nal-async", + "heapless 0.9.2", + "managed", + "smoltcp", +] + [[package]] name = "embassy-net-driver" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "524eb3c489760508f71360112bca70f6e53173e6fe48fc5f0efd0f5ab217751d" +dependencies = [ + "defmt 0.3.100", +] [[package]] name = "embassy-net-driver-channel" @@ -768,6 +801,25 @@ dependencies = [ "embedded-io 0.7.1", ] +[[package]] +name = "embedded-nal" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c56a28be191a992f28f178ec338a0bf02f63d7803244add736d026a471e6ed77" +dependencies = [ + "nb 1.1.0", +] + +[[package]] +name = "embedded-nal-async" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb5a1bd585135d302f8f6d7de329310938093da6271b37a6c94b8798795c0c6d" +dependencies = [ + "embedded-io-async 0.7.0", + "embedded-nal", +] + [[package]] name = "embedded-storage" version = "0.3.1" @@ -976,14 +1028,6 @@ version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" -[[package]] -name = "hd44780-driver" -version = "0.4.0" -source = "git+https://github.com/JohnDoneth/hd44780-driver.git?rev=9009f2c24771ba0a20f8f7534471c9869188f76c#9009f2c24771ba0a20f8f7534471c9869188f76c" -dependencies = [ - "embedded-hal 1.0.0", -] - [[package]] name = "heapless" version = "0.8.0" @@ -1083,15 +1127,6 @@ version = "0.2.186" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" -[[package]] -name = "liquid_crystal" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b66e0794bc41fc20f70a92e9a9a69ff0e4f411db40dcd1002913e585a031e9" -dependencies = [ - "embedded-hal 1.0.0", -] - [[package]] name = "litrs" version = "1.0.0" @@ -1126,6 +1161,12 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "managed" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ca88d725a0a943b096803bd34e73a4437208b6077654cc4ecb2947a5f91618d" + [[package]] name = "matchers" version = "0.2.0" @@ -1171,6 +1212,17 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -1270,6 +1322,8 @@ name = "pico" version = "0.1.0" dependencies = [ "ag-lcd", + "arrayvec", + "as5600", "cortex-m", "cortex-m-rt", "critical-section", @@ -1278,16 +1332,19 @@ dependencies = [ "defmt 1.0.1", "defmt-rtt", "embassy-executor", + "embassy-futures", + "embassy-net", "embassy-rp", "embassy-time", "embassy-usb-logger", "embedded-hal-compat", - "hd44780-driver", - "liquid_crystal", + "embedded-io 0.7.1", + "embedded-io-async 0.7.0", "log", "panic-probe", "portable-atomic", "static_cell", + "ufmt 0.2.0", ] [[package]] @@ -1387,6 +1444,12 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "proc-macro-hack" +version = "0.5.20+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" + [[package]] name = "proc-macro2" version = "1.0.106" @@ -1640,6 +1703,20 @@ dependencies = [ "rgb", ] +[[package]] +name = "smoltcp" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f73d40463bba65efc9adc6370b56df76d563cc46e2482bba58351b4afb7535e" +dependencies = [ + "bitflags 1.3.2", + "byteorder", + "cfg-if", + "defmt 0.3.100", + "heapless 0.9.2", + "managed", +] + [[package]] name = "ssmarshal" version = "1.0.0" @@ -1819,6 +1896,56 @@ version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" +[[package]] +name = "ufmt" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31d3c0c63312dfc9d8e5c71114d617018a19f6058674003c0da29ee8d8036cdd" +dependencies = [ + "proc-macro-hack", + "ufmt-macros 0.2.0", + "ufmt-write", +] + +[[package]] +name = "ufmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a64846ec02b57e9108d6469d98d1648782ad6bb150a95a9baac26900bbeab9d" +dependencies = [ + "ufmt-macros 0.3.0", + "ufmt-write", +] + +[[package]] +name = "ufmt-macros" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4ab6c92f30c996394a8bd525aef9f03ce01d0d7ac82d81902968057e37dd7d9" +dependencies = [ + "proc-macro-hack", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ufmt-macros" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d337d3be617449165cb4633c8dece429afd83f84051024079f97ad32a9663716" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ufmt-write" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e87a2ed6b42ec5e28cc3b94c09982969e9227600b2e3dcbc1db927a84c06bd69" + [[package]] name = "unicode-ident" version = "1.0.24" diff --git a/pico/Cargo.toml b/pico/Cargo.toml index 2621b22..7037621 100644 --- a/pico/Cargo.toml +++ b/pico/Cargo.toml @@ -5,12 +5,17 @@ edition = "2024" [dependencies] -hd44780-driver = { git = "https://github.com/JohnDoneth/hd44780-driver.git", rev = "9009f2c24771ba0a20f8f7534471c9869188f76c"} embedded-hal-compat = "0.13.0" embassy-usb-logger = "0.5.1" +ufmt = "0.2.0" log = "0.4" -liquid_crystal = "0.2" -ag-lcd="0.3" +ag-lcd={ version = "0.3", features = ["ufmt"]} +as5600 = "0.8.0" +embassy-futures = "0.1.2" +embedded-io-async = "0.7.0" +embedded-io = "0.7.1" +arrayvec = { version = "0.7.6", default-features = false } +embassy-net = { version = "0.9.1",features = ["defmt", "icmp", "tcp", "udp", "raw", "dhcpv4", "medium-ethernet", "dns", "proto-ipv4", "proto-ipv6", "multicast"]} embassy-executor = { version = "0.10.0", features = [ "platform-cortex-m", "executor-thread", diff --git a/pico/src/main.rs b/pico/src/main.rs index e06c7cb..db142ae 100644 --- a/pico/src/main.rs +++ b/pico/src/main.rs @@ -1,32 +1,35 @@ #![no_std] #![no_main] +use arrayvec::ArrayVec; +use core::str::FromStr; + use ag_lcd::{Blink, Cursor, Display, LcdDisplay}; -use cyw43::aligned_bytes; +use as5600::As5600; +use cyw43::{JoinOptions, aligned_bytes}; use cyw43_pio::{DEFAULT_CLOCK_DIVIDER, PioSpi}; use defmt::*; use embassy_executor::Spawner; -use embassy_rp::gpio::{Level, Output}; -use embassy_rp::peripherals::{DMA_CH0, PIO0}; +use embassy_futures::yield_now; +use embassy_net::tcp::client::{TcpClient, TcpClientState}; +use embassy_net::{Stack, StackResources}; +use embassy_rp::clocks::RoscRng; +use embassy_rp::gpio::{Input, Level, Output}; +use embassy_rp::i2c::{self, Config, I2c}; +use embassy_rp::peripherals::{DMA_CH0, I2C0, PIO0}; use embassy_rp::pio::{InterruptHandler, Pio}; use embassy_rp::{bind_interrupts, dma}; use embassy_rp::{peripherals::USB, usb}; use embassy_time::{Delay, Duration, Timer}; -use hd44780_driver::HD44780; -use hd44780_driver::bus::FourBitBusPins; -use hd44780_driver::memory_map::MemoryMap1602; -use hd44780_driver::setup::DisplayOptions4Bit; - -use liquid_crystal::BusBits::Bus4Bits; -use liquid_crystal::SendType::Text; -use liquid_crystal::{LCD16X2, LiquidCrystal, Parallel, lcd_dummy}; use static_cell::StaticCell; +use ufmt::uwrite; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs { PIO0_IRQ_0 => InterruptHandler; DMA_IRQ_0 => dma::InterruptHandler; USBCTRL_IRQ => usb::InterruptHandler; + I2C0_IRQ => i2c::InterruptHandler; }); #[embassy_executor::task] @@ -41,6 +44,13 @@ async fn logger_task(usb: embassy_rp::Peri<'static, embassy_rp::peripherals::USB embassy_usb_logger::run!(1024, log::LevelFilter::Info, driver); } +#[embassy_executor::task] +async fn net_task(mut runner: embassy_net::Runner<'static, cyw43::NetDriver<'static>>) -> ! { + runner.run().await +} + +const WIFI_NETWORK: &str = "flamme"; +const WIFI_PASSWORD: &str = "12345678"; #[embassy_executor::main] async fn main(spawner: Spawner) { @@ -49,6 +59,7 @@ async fn main(spawner: Spawner) { let fw = aligned_bytes!("../firmware/43439A0.bin"); let clm = aligned_bytes!("../firmware/43439A0_clm.bin"); let nvram = aligned_bytes!("../firmware/nvram_rp2040.bin"); + let mut rng = RoscRng; // To make flashing faster for development, you may want to flash the firmwares independently // at hardcoded addresses, instead of baking them into the program with `include_bytes!`: @@ -73,16 +84,11 @@ async fn main(spawner: Spawner) { static STATE: StaticCell = StaticCell::new(); let state = STATE.init(cyw43::State::new()); - let (_net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw, nvram).await; + let (net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw, nvram).await; spawner.spawn(unwrap!(cyw43_task(runner))); spawner.spawn(unwrap!(logger_task(p.USB))); - control.init(clm).await; - control - .set_power_management(cyw43::PowerManagementMode::PowerSave) - .await; - let edelay = &mut Delay; let mut lcd: LcdDisplay<_, _> = LcdDisplay::new( @@ -100,67 +106,101 @@ async fn main(spawner: Spawner) { .with_blink(Blink::On) .with_cursor(Cursor::On) .build(); - // let mut lcd_interface = Parallel::new( - // Output::new(p.PIN_14, Level::Low), - // Output::new(p.PIN_15, Level::Low), - // Output::new(p.PIN_16, Level::Low), - // Output::new(p.PIN_17, Level::Low), - // Output::new(p.PIN_19, Level::Low), - // Output::new(p.PIN_20, Level::Low), - // lcd_dummy, - // ); - // let mut lcd = LiquidCrystal::new(&mut lcd_interface, Bus4Bits, LCD16X2); - // let mut lcd = HD44780::new( - // DisplayOptions4Bit::new(MemoryMap1602::new()).with_pins(FourBitBusPins { - // rs: Output::new(p.PIN_19, Level::Low), - // en: Output::new(p.PIN_20, Level::Low), - - // d4: Output::new(p.PIN_14, Level::Low), - // d5: Output::new(p.PIN_15, Level::Low), - // d6: Output::new(p.PIN_16, Level::Low), - // d7: Output::new(p.PIN_17, Level::Low), - // }), - // edelay, - // ) - // .unwrap(); - - // lcd.begin(edelay); lcd.set_cursor(Cursor::Off); lcd.set_blink(Blink::Off); - // // Unshift display and set cursor to 0 - // lcd.reset(edelay).unwrap(); + control.init(clm).await; + control + .set_power_management(cyw43::PowerManagementMode::PowerSave) + .await; - // // Clear existing characters - // lcd.clear(edelay).unwrap(); + static RESOURCES: StaticCell> = StaticCell::new(); + let (stack, runner) = embassy_net::new( + net_device, + embassy_net::Config::dhcpv4(Default::default()), + RESOURCES.init(StackResources::new()), + rng.next_u64(), + ); + spawner.spawn(unwrap!(net_task(runner))); + while let Err(err) = control + .join(WIFI_NETWORK, JoinOptions::new(WIFI_PASSWORD.as_bytes())) + .await + { + lcd.clear(); + let num = match err { + cyw43::JoinError::AuthenticationFailure => 200, + cyw43::JoinError::JoinFailure(e) => e, + cyw43::JoinError::NetworkNotFound => 201, + }; + uwrite!(lcd, "join {}", num); + } - // // Display the following string - // lcd.write_str("Hello, world!", edelay).unwrap(); + uwrite!(lcd, "link."); + stack.wait_link_up().await; - // // Move the cursor to the second line - // lcd.set_cursor_xy((0, 1), edelay).unwrap(); + lcd.clear(); + uwrite!(lcd, "dhcp."); + stack.wait_config_up().await; + let cfg = wait_for_config(stack).await; + let local_addr = cfg.address.address(); + uwrite!(lcd, "IP address: {:?}", local_addr.octets()); + + let i2c = I2c::new_async(p.I2C0, p.PIN_5, p.PIN_4, Irqs, Config::default()); + let mut as5600 = As5600::new(i2c); - // // Display the following string on the second line - // lcd.write_str("I'm on line 2!", edelay).unwrap(); - // let mut led = Output::new(p.PIN_1, Level::Low); - let delay = Duration::from_secs(1); + let in1 = Input::new(p.PIN_18, embassy_rp::gpio::Pull::Up); + let in2 = Input::new(p.PIN_19, embassy_rp::gpio::Pull::Up); + let in3 = Input::new(p.PIN_20, embassy_rp::gpio::Pull::Up); + let in4 = Input::new(p.PIN_21, embassy_rp::gpio::Pull::Up); + + let mut rx_buffer = [0; 4096]; + let mut tx_buffer = [0; 4096]; + let mut socket = embassy_net::tcp::TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer); + socket.set_timeout(Some(Duration::from_secs(10))); + + led.set_low(); + info!("Connecting..."); + let host_addr = embassy_net::Ipv4Address::from_str("84.238.32.253").unwrap(); + if let Err(e) = socket.connect((host_addr, 7070)).await { + warn!("connect error: {:?}", e); + } + info!("Connected to {:?}", socket.remote_endpoint()); + + let delay = Duration::from_millis(100); + let mut buffer = ArrayVec::::new(); loop { - log::info!("led on!"); - control.gpio_set(0, true).await; - led.set_high(); + let in1 = in1.is_low(); + let in2 = in2.is_low(); + let in3 = in3.is_low(); + let in4 = in4.is_low(); + let angle = as5600.angle().unwrap_or(0); + { + use embedded_io::Write; + let _ = core::write!( + &mut buffer[..], + "in1={} in2={} in3={} in4={} angle={}", + in1, + in2, + in3, + in4, + angle + ); + } + { + use embedded_io_async::Write; + let _ = socket.write_all(&*buffer).await; + } Timer::after(delay).await; - - lcd.print("Test message!"); - // lcd.write(edelay, Text("hello World!")); - - log::info!("led off!"); - control.gpio_set(0, false).await; - led.set_low(); - Timer::after(delay).await; - - lcd.print("Test message2!"); - // lcd.write(edelay, Text("hello World2!")); + } +} + +async fn wait_for_config(stack: Stack<'static>) -> embassy_net::StaticConfigV4 { + loop { + if let Some(config) = stack.config_v4() { + return config.clone(); + } + yield_now().await; } }