+80
-29
src/main.rs
+80
-29
src/main.rs
···
1
1
#![no_std]
2
2
#![no_main]
3
3
4
-
use crate::pcf85063a::Control;
4
+
use crate::pcf85063a::{Control, Error};
5
5
use badge_display::display_image::DisplayImage;
6
6
use badge_display::{
7
7
CHANGE_IMAGE, CURRENT_IMAGE, DISPLAY_CHANGED, FORCE_SCREEN_REFRESH, RECENT_WIFI_NETWORKS,
···
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;
···
24
23
use embassy_rp::clocks::RoscRng;
25
24
use embassy_rp::flash::Async;
26
25
use embassy_rp::gpio::Input;
27
-
use embassy_rp::i2c::{Error, I2c};
26
+
use embassy_rp::i2c::I2c;
28
27
use embassy_rp::peripherals::{DMA_CH0, I2C0, PIO0, SPI0};
29
28
use embassy_rp::pio::{InterruptHandler, Pio};
30
29
use embassy_rp::rtc::{DateTime, DayOfWeek};
31
30
use embassy_rp::spi::Spi;
32
31
use embassy_rp::spi::{self};
32
+
use embassy_rp::watchdog::Watchdog;
33
33
use embassy_rp::{bind_interrupts, gpio, i2c};
34
34
use embassy_sync::blocking_mutex::NoopMutex;
35
35
use embassy_sync::blocking_mutex::raw::NoopRawMutex;
···
125
125
let btn_b = Input::new(p.PIN_13, Pull::Down);
126
126
let btn_c = Input::new(p.PIN_14, Pull::Down);
127
127
let rtc_alarm = Input::new(p.PIN_8, Pull::Down);
128
+
let mut watchdog = Watchdog::new(p.WATCHDOG);
129
+
130
+
//Setup i2c bus
131
+
let config = embassy_rp::i2c::Config::default();
132
+
let i2c = i2c::I2c::new_blocking(p.I2C0, p.PIN_5, p.PIN_4, config);
133
+
static I2C_BUS: StaticCell<I2c0Bus> = StaticCell::new();
134
+
let i2c_bus = NoopMutex::new(RefCell::new(i2c));
135
+
let i2c_bus = I2C_BUS.init(i2c_bus);
136
+
137
+
let i2c_dev = I2cDevice::new(i2c_bus);
138
+
let mut rtc_device = PCF85063::new(i2c_dev);
139
+
140
+
if btn_a.is_high() {
141
+
//Clears the alarm on start if A button is pressed (manual start)
142
+
_ = rtc_device.disable_all_alarms();
143
+
_ = rtc_device.clear_alarm_flag();
144
+
}
145
+
146
+
// //RTC alarm stuff
147
+
// let mut go_to_sleep = false;
148
+
// let mut reset_cycles_till_sleep = 0;
149
+
// //Like 15ish mins??
150
+
// let sleep_after_cycles = 2;
151
+
//
152
+
// if rtc_alarm.is_high() {
153
+
// //sleep happened
154
+
// go_to_sleep = true;
155
+
// info!("Alarm went off");
156
+
// _ = rtc_device.disable_all_alarms();
157
+
// _ = rtc_device.clear_alarm_flag();
158
+
// } else {
159
+
// info!("Alarm was clear")
160
+
// }
128
161
129
162
let spi = Spi::new(
130
163
p.SPI0,
···
158
191
seed,
159
192
);
160
193
161
-
//rtc setup
162
-
// let mut rtc = embassy_rp::rtc::Rtc::new(p.RTC);
194
+
//If the watch dog isn't fed in 8 seconds reboot to help with hang up
195
+
watchdog.start(Duration::from_secs(8));
163
196
164
197
spawner.must_spawn(net_task(runner));
165
198
//Attempt to connect to wifi to get RTC time loop for 2 minutes
···
169
202
let wifi_ssid = env_value("WIFI_SSID");
170
203
let wifi_password = env_value("WIFI_PASSWORD");
171
204
while wifi_connection_attempts < 30 {
205
+
watchdog.feed();
172
206
match control
173
207
.join(wifi_ssid, JoinOptions::new(wifi_password.as_bytes()))
174
208
.await
···
186
220
wifi_connection_attempts += 1;
187
221
}
188
222
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
223
if connected_to_wifi {
224
+
//Feed the dog if it makes it this far
225
+
watchdog.feed();
200
226
info!("waiting for DHCP...");
201
227
while !stack.is_config_up() {
202
228
Timer::after_millis(100).await;
···
233
259
234
260
let url = env_value("TIME_API");
235
261
info!("connecting to {}", &url);
262
+
263
+
// Feeds the dog again for one last time
264
+
watchdog.feed();
236
265
237
266
//If the call goes through set the rtc
238
267
match http_client.request(Method::GET, &url).await {
···
329
358
let cycle = Duration::from_millis(100);
330
359
let mut current_cycle = 0;
331
360
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;
361
+
//5 minutes(ish) idk it's late and my math is so bad rn
362
+
let reset_cycle = 3_000;
334
363
335
364
//Turn off led to signify that the badge is ready
336
-
user_led.set_low();
365
+
// user_led.set_low();
337
366
338
-
//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();
367
+
loop {
368
+
//Keep feeding the dog
369
+
watchdog.feed();
348
370
349
-
loop {
350
371
//Change Image Button
351
372
if btn_c.is_high() {
352
373
info!("Button C pressed");
374
+
// reset_cycles_till_sleep = 0;
353
375
let current_image = CURRENT_IMAGE.load(core::sync::atomic::Ordering::Relaxed);
354
376
let new_image = DisplayImage::from_u8(current_image).unwrap().next();
355
377
CURRENT_IMAGE.store(new_image.as_u8(), core::sync::atomic::Ordering::Relaxed);
···
361
383
if btn_a.is_high() {
362
384
println!("{:?}", current_cycle);
363
385
info!("Button A pressed");
386
+
// reset_cycles_till_sleep = 0;
364
387
user_led.toggle();
365
388
Timer::after(Duration::from_millis(500)).await;
366
389
continue;
···
368
391
369
392
if btn_down.is_high() {
370
393
info!("Button Down pressed");
394
+
// reset_cycles_till_sleep = 0;
371
395
SCREEN_TO_SHOW.lock(|screen| {
372
396
screen.replace(Screen::WifiList);
373
397
});
···
378
402
379
403
if btn_up.is_high() {
380
404
info!("Button Up pressed");
405
+
// reset_cycles_till_sleep = 0;
381
406
SCREEN_TO_SHOW.lock(|screen| {
382
407
screen.replace(Screen::Badge);
383
408
});
···
388
413
389
414
if btn_b.is_high() {
390
415
info!("Button B pressed");
416
+
// reset_cycles_till_sleep = 0;
391
417
SCREEN_TO_SHOW.lock(|screen| {
392
418
if *screen.borrow() == Screen::Badge {
393
419
//IF on badge screen and b pressed reset wifi count
···
447
473
448
474
if time_to_scan {
449
475
info!("Scanning for wifi networks");
476
+
// reset_cycles_till_sleep += 1;
450
477
time_to_scan = false;
451
478
let mut scanner = control.scan(Default::default()).await;
452
479
while let Some(bss) = scanner.next().await {
···
460
487
current_cycle = 0;
461
488
time_to_scan = true;
462
489
}
490
+
491
+
// if reset_cycles_till_sleep >= sleep_after_cycles {
492
+
// info!("Going to sleep");
493
+
// reset_cycles_till_sleep = 0;
494
+
// go_to_sleep = true;
495
+
// }
496
+
//
497
+
// if go_to_sleep {
498
+
// info!("going to sleep");
499
+
// //SO i need to wait for 25 seconds to make sure the display updates fully...But i need to keep feeding the dog atleast every 8 seconds
500
+
// for _ in 0..25 {
501
+
// //watchdog.feed();
502
+
// Timer::after(Duration::from_secs(1)).await;
503
+
// }
504
+
// //Set the rtc and sleep for 15 minutes
505
+
// //goes to sleep for 15 mins
506
+
// _ = rtc_device.disable_all_alarms();
507
+
// _ = rtc_device.clear_alarm_flag();
508
+
// _ = rtc_device.set_alarm_minutes(5);
509
+
// _ = rtc_device.control_alarm_minutes(Control::On);
510
+
// _ = rtc_device.control_alarm_interrupt(Control::On);
511
+
// power.set_low();
512
+
// }
513
+
463
514
current_cycle += 1;
464
515
Timer::after(cycle).await;
465
516
}
+7
-8
src/pcf85063a/mod.rs
+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,