A personal rust firmware for the Badger 2040 W

Good enough

Changed files
+66 -35
src
pcf85063a
+59 -27
src/main.rs
··· 10 10 use core::cell::RefCell; 11 11 use core::fmt::Write; 12 12 use core::str::from_utf8; 13 - use cortex_m::asm::delay; 14 13 use cyw43::JoinOptions; 15 14 use cyw43_pio::{DEFAULT_CLOCK_DIVIDER, PioSpi}; 16 15 use defmt::info; 17 16 use defmt::*; 18 - use embassy_embedded_hal::shared_bus::I2cDeviceError; 19 17 use embassy_embedded_hal::shared_bus::blocking::i2c::I2cDevice; 20 18 use embassy_executor::Spawner; 21 19 use embassy_net::StackResources; ··· 24 22 use embassy_rp::clocks::RoscRng; 25 23 use embassy_rp::flash::Async; 26 24 use embassy_rp::gpio::Input; 27 - use embassy_rp::i2c::{Error, I2c}; 25 + use embassy_rp::i2c::I2c; 28 26 use embassy_rp::peripherals::{DMA_CH0, I2C0, PIO0, SPI0}; 29 27 use embassy_rp::pio::{InterruptHandler, Pio}; 30 28 use embassy_rp::rtc::{DateTime, DayOfWeek}; ··· 126 124 let btn_c = Input::new(p.PIN_14, Pull::Down); 127 125 let rtc_alarm = Input::new(p.PIN_8, Pull::Down); 128 126 127 + //Setup i2c bus 128 + let config = embassy_rp::i2c::Config::default(); 129 + let i2c = i2c::I2c::new_blocking(p.I2C0, p.PIN_5, p.PIN_4, config); 130 + static I2C_BUS: StaticCell<I2c0Bus> = StaticCell::new(); 131 + let i2c_bus = NoopMutex::new(RefCell::new(i2c)); 132 + let i2c_bus = I2C_BUS.init(i2c_bus); 133 + 134 + let i2c_dev = I2cDevice::new(i2c_bus); 135 + let mut rtc_device = PCF85063::new(i2c_dev); 136 + 137 + if btn_a.is_high() { 138 + //Clears the alarm on start if A button is pressed (manual start) 139 + _ = rtc_device.disable_all_alarms(); 140 + _ = rtc_device.clear_alarm_flag(); 141 + } 142 + 129 143 let spi = Spi::new( 130 144 p.SPI0, 131 145 clk, ··· 158 172 seed, 159 173 ); 160 174 161 - //rtc setup 162 - // let mut rtc = embassy_rp::rtc::Rtc::new(p.RTC); 163 - 164 175 spawner.must_spawn(net_task(runner)); 165 176 //Attempt to connect to wifi to get RTC time loop for 2 minutes 166 177 let mut wifi_connection_attempts = 0; ··· 185 196 Timer::after(Duration::from_secs(1)).await; 186 197 wifi_connection_attempts += 1; 187 198 } 188 - 189 - //Setup i2c bus 190 - let config = embassy_rp::i2c::Config::default(); 191 - let i2c = i2c::I2c::new_blocking(p.I2C0, p.PIN_5, p.PIN_4, config); 192 - static I2C_BUS: StaticCell<I2c0Bus> = StaticCell::new(); 193 - let i2c_bus = NoopMutex::new(RefCell::new(i2c)); 194 - let i2c_bus = I2C_BUS.init(i2c_bus); 195 - 196 - let i2c_dev = I2cDevice::new(i2c_bus); 197 - let mut rtc_device = PCF85063::new(i2c_dev); 198 199 199 200 if connected_to_wifi { 200 201 info!("waiting for DHCP..."); ··· 329 330 let cycle = Duration::from_millis(100); 330 331 let mut current_cycle = 0; 331 332 let mut time_to_scan = true; 332 - //15 minutes(ish) idk it's late and my math is so bad rn 333 - let reset_cycle = 9_000; 333 + //5 minutes(ish) idk it's late and my math is so bad rn 334 + let reset_cycle = 3_000; 334 335 335 336 //Turn off led to signify that the badge is ready 336 337 user_led.set_low(); 337 338 338 339 //RTC alarm stuff 339 - // info!("going to sleep"); 340 - // Timer::after(Duration::from_millis(5_000)).await; 341 - // //Set the rtc and sleep for 15 minutes 342 - // //goes to sleep for 15 mins 343 - // _ = rtc_device.clear_alarm_flag(); 344 - // _ = rtc_device.set_alarm_minutes(5); 345 - // _ = rtc_device.control_alarm_minutes(Control::On); 346 - // _ = rtc_device.control_alarm_interrupt(Control::On); 347 - // power.set_low(); 340 + let mut go_to_sleep = false; 341 + let mut reset_cycles_till_sleep = 0; 342 + //Like 15ish mins?? 343 + let sleep_after_cycles = 4; 344 + 345 + if rtc_alarm.is_high() { 346 + //sleep happened 347 + go_to_sleep = true; 348 + info!("Alarm went off"); 349 + _ = rtc_device.disable_all_alarms(); 350 + _ = rtc_device.clear_alarm_flag(); 351 + } else { 352 + info!("Alarm was clear") 353 + } 348 354 349 355 loop { 350 356 //Change Image Button 351 357 if btn_c.is_high() { 352 358 info!("Button C pressed"); 359 + reset_cycles_till_sleep = 0; 353 360 let current_image = CURRENT_IMAGE.load(core::sync::atomic::Ordering::Relaxed); 354 361 let new_image = DisplayImage::from_u8(current_image).unwrap().next(); 355 362 CURRENT_IMAGE.store(new_image.as_u8(), core::sync::atomic::Ordering::Relaxed); ··· 361 368 if btn_a.is_high() { 362 369 println!("{:?}", current_cycle); 363 370 info!("Button A pressed"); 371 + reset_cycles_till_sleep = 0; 364 372 user_led.toggle(); 365 373 Timer::after(Duration::from_millis(500)).await; 366 374 continue; ··· 368 376 369 377 if btn_down.is_high() { 370 378 info!("Button Down pressed"); 379 + reset_cycles_till_sleep = 0; 371 380 SCREEN_TO_SHOW.lock(|screen| { 372 381 screen.replace(Screen::WifiList); 373 382 }); ··· 378 387 379 388 if btn_up.is_high() { 380 389 info!("Button Up pressed"); 390 + reset_cycles_till_sleep = 0; 381 391 SCREEN_TO_SHOW.lock(|screen| { 382 392 screen.replace(Screen::Badge); 383 393 }); ··· 388 398 389 399 if btn_b.is_high() { 390 400 info!("Button B pressed"); 401 + reset_cycles_till_sleep = 0; 391 402 SCREEN_TO_SHOW.lock(|screen| { 392 403 if *screen.borrow() == Screen::Badge { 393 404 //IF on badge screen and b pressed reset wifi count ··· 447 458 448 459 if time_to_scan { 449 460 info!("Scanning for wifi networks"); 461 + reset_cycles_till_sleep += 1; 450 462 time_to_scan = false; 451 463 let mut scanner = control.scan(Default::default()).await; 452 464 while let Some(bss) = scanner.next().await { ··· 460 472 current_cycle = 0; 461 473 time_to_scan = true; 462 474 } 475 + 476 + if reset_cycles_till_sleep >= sleep_after_cycles { 477 + info!("Going to sleep"); 478 + reset_cycles_till_sleep = 0; 479 + go_to_sleep = true; 480 + } 481 + 482 + if go_to_sleep { 483 + info!("going to sleep"); 484 + Timer::after(Duration::from_secs(25)).await; 485 + //Set the rtc and sleep for 15 minutes 486 + //goes to sleep for 15 mins 487 + _ = rtc_device.disable_all_alarms(); 488 + _ = rtc_device.clear_alarm_flag(); 489 + _ = rtc_device.set_alarm_seconds(5); 490 + _ = rtc_device.control_alarm_seconds(Control::On); 491 + _ = rtc_device.control_alarm_interrupt(Control::On); 492 + power.set_low(); 493 + } 494 + 463 495 current_cycle += 1; 464 496 Timer::after(cycle).await; 465 497 }
+7 -8
src/pcf85063a/mod.rs
··· 1 1 #![allow(dead_code)] 2 + 3 + ///None of this code is mine. It's https://crates.io/crates/pcf85063a 4 + /// I just needed a synchronous version so did a local clone and pulled the async and awaits 2 5 pub mod alarm; 3 6 pub mod datetime; 4 7 5 8 use embedded_hal_1::i2c::I2c; 6 9 7 10 /// All possible errors in this crate 8 - #[derive(Debug)] 9 - #[cfg_attr(feature = "defmt", derive(defmt::Format))] 11 + #[derive(Debug, defmt::Format)] 10 12 pub enum Error<E> { 11 13 /// I2C bus error 12 14 I2C(E), ··· 80 82 81 83 /// Two possible choices, used for various enable/disable bit flags 82 84 #[allow(non_camel_case_types)] 83 - #[derive(Copy, Clone, Debug)] 84 - #[cfg_attr(feature = "defmt", derive(defmt::Format))] 85 + #[derive(Copy, Clone, Debug, defmt::Format)] 85 86 pub enum Control { 86 87 /// Enable some feature, eg. timer 87 88 On, ··· 90 91 } 91 92 92 93 /// PCF8563 driver 93 - #[derive(Debug, Default)] 94 - #[cfg_attr(feature = "defmt", derive(defmt::Format))] 94 + #[derive(Debug, Default, defmt::Format)] 95 95 pub struct PCF85063<I2C> { 96 96 /// The concrete I2C device implementation. 97 97 i2c: I2C, ··· 193 193 } 194 194 } 195 195 196 - #[derive(Debug, Clone, Copy, PartialEq, Eq)] 197 - #[cfg_attr(feature = "defmt", derive(defmt::Format))] 196 + #[derive(Debug, Clone, Copy, PartialEq, Eq, defmt::Format)] 198 197 #[repr(u8)] 199 198 pub enum OutputFrequency { 200 199 Hz32768 = 0b000,