A personal rust firmware for the Badger 2040 W

real time clock wip

Changed files
+83 -15
src
+6 -6
src/cyw43_driver.rs
··· 30 30 dma_ch0: DMA_CH0, 31 31 spawner: Spawner, 32 32 ) -> (Device<'a>, Control<'a>) { 33 - // let fw = include_bytes!("../cyw43-firmware/43439A0.bin"); 34 - // let clm = include_bytes!("../cyw43-firmware/43439A0_clm.bin"); 35 - // let btfw = include_bytes!("../cyw43-firmware/43439A0_btfw.bin"); 33 + let fw = include_bytes!("../cyw43-firmware/43439A0.bin"); 34 + let clm = include_bytes!("../cyw43-firmware/43439A0_clm.bin"); 35 + let btfw = include_bytes!("../cyw43-firmware/43439A0_btfw.bin"); 36 36 37 37 // To make flashing faster for development, you may want to flash the firmwares independently 38 38 // at hardcoded addresses, instead of baking them into the program with `include_bytes!`: 39 39 // probe-rs download 43439A0.bin --binary-format bin --chip RP2040 --base-address 0x10100000 40 40 // probe-rs download 43439A0_clm.bin --binary-format bin --chip RP2040 --base-address 0x10140000 41 41 // probe-rs download 43439A0_btfw.bin --binary-format bin --chip RP2040 --base-address 0x10141400 42 - let fw = unsafe { core::slice::from_raw_parts(0x10100000 as *const u8, 224190) }; 43 - let clm = unsafe { core::slice::from_raw_parts(0x10140000 as *const u8, 4752) }; 44 - let btfw = unsafe { core::slice::from_raw_parts(0x10141400 as *const u8, 6164) }; 42 + // let fw = unsafe { core::slice::from_raw_parts(0x10100000 as *const u8, 224190) }; 43 + // let clm = unsafe { core::slice::from_raw_parts(0x10140000 as *const u8, 4752) }; 44 + // let btfw = unsafe { core::slice::from_raw_parts(0x10141400 as *const u8, 6164) }; 45 45 46 46 let pwr = Output::new(p_23, Level::Low); 47 47 let cs = Output::new(p_25, Level::High);
+77 -9
src/main.rs
··· 6 6 #![no_main] 7 7 use badge_display::display_image::DisplayImage; 8 8 use badge_display::{run_the_display, CHANGE_IMAGE, CURRENT_IMAGE, RTC_TIME_STRING}; 9 + use bt_hci::cmd::info; 10 + use cyw43_driver::setup_cyw43; 11 + use cyw43_pio::PioSpi; 9 12 use defmt::info; 10 13 use embassy_executor::Spawner; 14 + use embassy_net::{Stack, StackResources}; 15 + use embassy_rp::clocks::RoscRng; 11 16 use embassy_rp::gpio; 12 17 use embassy_rp::gpio::Input; 13 - use embassy_rp::peripherals::SPI0; 18 + use embassy_rp::peripherals::{DMA_CH0, PIO0, SPI0}; 14 19 use embassy_rp::rtc::{DateTime, DayOfWeek}; 15 20 use embassy_rp::spi::Spi; 16 21 use embassy_rp::spi::{self}; 17 22 use embassy_sync::blocking_mutex::raw::NoopRawMutex; 18 23 use embassy_sync::mutex::Mutex; 19 24 use embassy_time::{Duration, Timer}; 25 + use env::env_value; 20 26 use gpio::{Level, Output, Pull}; 21 27 use helpers::easy_format; 28 + use rand::RngCore; 22 29 use static_cell::StaticCell; 23 30 use temp_sensor::run_the_temp_sensor; 24 31 use {defmt_rtt as _, panic_probe as _}; ··· 34 41 #[embassy_executor::main] 35 42 async fn main(spawner: Spawner) { 36 43 let p = embassy_rp::init(Default::default()); 37 - // let (_net_device, mut control) = setup_cyw43( 38 - // p.PIO0, p.PIN_23, p.PIN_24, p.PIN_25, p.PIN_29, p.DMA_CH0, spawner, 39 - // ) 40 - // .await; 41 - 42 - // let input = gpio::Input::new(p.PIN_29, gpio::Pull::Up); 44 + let (net_device, mut control) = setup_cyw43( 45 + p.PIO0, p.PIN_23, p.PIN_24, p.PIN_25, p.PIN_29, p.DMA_CH0, spawner, 46 + ) 47 + .await; 43 48 44 49 let miso = p.PIN_16; 45 50 let mosi = p.PIN_19; ··· 79 84 80 85 info!("led on!"); 81 86 // control.gpio_set(0, true).await; 82 - spawner.must_spawn(run_the_temp_sensor(p.I2C0, p.PIN_5, p.PIN_4)); 83 - spawner.must_spawn(run_the_display(spi_bus, cs, dc, busy, reset)); 87 + 88 + //wifi setup 89 + let mut rng = RoscRng; 90 + 91 + let config = embassy_net::Config::dhcpv4(Default::default()); 92 + let seed = rng.next_u64(); 93 + 94 + // Init network stack 95 + static STACK: StaticCell<Stack<cyw43::NetDriver<'static>>> = StaticCell::new(); 96 + static RESOURCES: StaticCell<StackResources<5>> = StaticCell::new(); 97 + let stack = &*STACK.init(Stack::new( 98 + net_device, 99 + config, 100 + RESOURCES.init(StackResources::<5>::new()), 101 + seed, 102 + )); 103 + 104 + spawner.must_spawn(net_task(stack)); 105 + //Attempt to connect to wifi to get RTC time loop for 2 minutes 106 + let mut wifi_connection_attempts = 0; 107 + let mut connected_to_wifi = false; 108 + 109 + let wifi_ssid = env_value("WIFI_SSID"); 110 + let wifi_password = env_value("WIFI_PASSWORD"); 111 + while wifi_connection_attempts < 30 { 112 + match control.join_wpa2(wifi_ssid, &wifi_password).await { 113 + Ok(_) => { 114 + connected_to_wifi = true; 115 + info!("join successful"); 116 + break; 117 + } 118 + Err(err) => { 119 + info!("join failed with status={}", err.status); 120 + } 121 + } 122 + Timer::after(Duration::from_secs(1)).await; 123 + wifi_connection_attempts += 1; 124 + } 125 + 126 + if connected_to_wifi { 127 + info!("waiting for DHCP..."); 128 + while !stack.is_config_up() { 129 + Timer::after_millis(100).await; 130 + } 131 + info!("DHCP is now up!"); 132 + 133 + info!("waiting for link up..."); 134 + while !stack.is_link_up() { 135 + Timer::after_millis(500).await; 136 + } 137 + info!("Link is up!"); 138 + 139 + info!("waiting for stack to be up..."); 140 + stack.wait_config_up().await; 141 + info!("Stack is up!"); 142 + } 84 143 85 144 //rtc setup 86 145 let mut rtc = embassy_rp::rtc::Rtc::new(p.RTC); ··· 97 156 }; 98 157 rtc.set_datetime(now).unwrap(); 99 158 } 159 + 160 + //Task spawning 161 + spawner.must_spawn(run_the_temp_sensor(p.I2C0, p.PIN_5, p.PIN_4)); 162 + spawner.must_spawn(run_the_display(spi_bus, cs, dc, busy, reset)); 100 163 101 164 //Input loop 102 165 loop { ··· 149 212 .unwrap(); 150 213 }); 151 214 } 215 + 216 + #[embassy_executor::task] 217 + async fn net_task(stack: &'static Stack<cyw43::NetDriver<'static>>) -> ! { 218 + stack.run().await 219 + }