Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trigger vsys voltage reading on usb edge, some tidying #47

Merged
merged 1 commit into from
Aug 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/task/alarm_settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use sequential_storage::map::{fetch_item, store_item};
const FLASH_SIZE: usize = 2 * 1024 * 1024;

/// # PersistedAlarmTime
/// This struct is used to persist the alarm time in the flash memory.
/// This struct is used to persist the alarm settings in the flash memory.
pub struct PersistedAlarmSettings<'a> {
flash: Flash<'a, FLASH, Async, { FLASH_SIZE }>,
flash_range: Range<u32>,
Expand Down
6 changes: 3 additions & 3 deletions src/task/buttons.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ use embassy_sync::channel::Sender;
use embassy_time::{with_deadline, Duration, Instant, Timer};
use {defmt_rtt as _, panic_probe as _};

// Button Manager
// Handles button press, hold, and long hold
// Debounces button press
/// Button Manager
/// Handles button press, hold, and long hold
/// Debounces button press
pub struct ButtonManager<'a> {
input: Input<'a>,
debounce_duration: Duration,
Expand Down
3 changes: 3 additions & 0 deletions src/task/light_effects.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,17 @@ use smart_leds::{brightness, RGB8};
use ws2812_async::Ws2812;
use {defmt_rtt as _, panic_probe as _};

// Number of LEDs in the ring
const NUM_LEDS: usize = 16;

/// Manages the neopixel LED ring, including brightness settings for alarm and clock modes.
pub struct NeopixelManager {
alarm_brightness: u8,
clock_brightness: u8,
}

impl NeopixelManager {
/// Creates a new `NeopixelManager` with default brightness settings.
pub fn new() -> Self {
Self {
alarm_brightness: 90,
Expand Down
16 changes: 9 additions & 7 deletions src/task/orchestrate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::task::task_messages::*;
use core::cell::RefCell;
use defmt::*;
use embassy_executor::Spawner;
use embassy_futures::select::{select, Either};
use embassy_futures::select::select;
use embassy_rp::peripherals::RTC;
use embassy_rp::rtc::DayOfWeek;
use embassy_rp::rtc::{DateTime, Rtc};
Expand All @@ -22,7 +22,10 @@ pub async fn orchestrator(_spawner: Spawner) {
*(STATE_MANAGER_MUTEX.lock().await) = Some(state_manager);
}

// init the receiver for the event channel, this is the line we are listening on
let event_receiver = EVENT_CHANNEL.receiver();

// init the sender for the flash channel
let flash_sender = FLASH_CHANNEL.sender();

loop {
Expand Down Expand Up @@ -52,7 +55,9 @@ pub async fn orchestrator(_spawner: Spawner) {
Events::Vbus(usb) => {
info!("Vbus event, usb: {}", usb);
state_manager.power_state.set_usb_power(usb);
state_manager.power_state.set_battery_level();
if !state_manager.power_state.get_usb_power() {
VSYS_WAKE_SIGNAL.signal(Commands::VsysWakeUp);
};
DISPLAY_SIGNAL.signal(Commands::DisplayUpdate);
}
Events::Vsys(voltage) => {
Expand Down Expand Up @@ -184,7 +189,7 @@ pub async fn scheduler(_spawner: Spawner, rtc_ref: &'static RefCell<Rtc<'static,
};
drop(state_manager_guard);

// calculate the downtime
// calculate the downtime we need to wait until the next iteration
let mut downtime: Duration;
if state_manager.alarm_settings.get_enabled() {
// wait for 1 minute, unless we are in proximity of the alarm time, in which case we wait for 10 seconds
Expand Down Expand Up @@ -215,9 +220,6 @@ pub async fn scheduler(_spawner: Spawner, rtc_ref: &'static RefCell<Rtc<'static,

// we either wait for the downtime or until we are woken up early. Whatever comes first, starts the next iteration.
let downtime_timer = Timer::after(downtime);
match select(downtime_timer, SCHEDULER_WAKE_SIGNAL.wait()).await {
Either::First(_) => {}
Either::Second(_) => {}
}
select(downtime_timer, SCHEDULER_WAKE_SIGNAL.wait()).await;
}
}
18 changes: 12 additions & 6 deletions src/task/power.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
//! Detremine the supply voltage of the system.

use crate::task::resources::{Irqs, UsbPowerResources};
use crate::task::task_messages::{Events, EVENT_CHANNEL};
use crate::task::task_messages::{Events, EVENT_CHANNEL, VSYS_WAKE_SIGNAL};
use crate::VsysResources;
use defmt::*;
use embassy_executor::Spawner;
use embassy_futures::select::select;
use embassy_rp::adc::{Adc, Channel, Config};
use embassy_rp::gpio::{Input, Pull};
use embassy_time::{Duration, Timer};
Expand Down Expand Up @@ -39,21 +40,26 @@ pub async fn usb_power_detector(_spawner: Spawner, r: UsbPowerResources) {
#[embassy_executor::task]
pub async fn vsys_voltage_reader(_spawner: Spawner, r: VsysResources) {
info!("vsys_voltage task started");

// Initialize the ADC and the Vsys input pin.
let mut adc = Adc::new(r.adc, Irqs, Config::default());
let vsys_in = r.pin_27;
let mut channel = Channel::new_pin(vsys_in, Pull::None);
let sender = EVENT_CHANNEL.sender();
let refresh_after_secs = 600; // 10 minutes

// wait for the system to settle, before starting the loop -> the adc is not stable immediately
Timer::after(Duration::from_secs(2)).await;
let sender = EVENT_CHANNEL.sender();
let downtime = Duration::from_secs(600); // 10 minutes

loop {
// wait for the system to settle, before reading -> the adc is not stable immediately if we got here after either the usb power was cut the system just started
Timer::after(Duration::from_secs(1)).await;
// read the adc value
let adc_value = adc.read(&mut channel).await.unwrap();
// reference voltage is 3.3V, and the voltage divider ratio is 2.65. The ADC is 12-bit, so 2^12 = 4096
let voltage = (adc_value as f32) * 3.3 * 2.65 / 4096.0;
sender.send(Events::Vsys(voltage)).await;
Timer::after(Duration::from_secs(refresh_after_secs)).await;

// we either wait for the downtime or until we are woken up early. Whatever comes first, starts the next iteration.
let downtime_timer = Timer::after(downtime);
select(downtime_timer, VSYS_WAKE_SIGNAL.wait()).await;
}
}
1 change: 1 addition & 0 deletions src/task/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -432,5 +432,6 @@ impl PowerState {

pub fn set_usb_power(&mut self, usb_power: bool) {
self.usb_power = usb_power;
self.set_battery_level();
}
}
6 changes: 5 additions & 1 deletion src/task/task_messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,10 @@ pub enum Commands {
SchedulerStop,
/// Start the scheduler
SchedulerStart,
/// Wake the scheduler early when awaiting the next tick
/// Wake the scheduler early when awaiting the next iteration
SchedulerWakeUp,
/// Wake the vsys_voltage_reader task early when awaiting the next iteration
VsysWakeUp,
}

/// For the events that we want the orchestrator to react to, all state events are of the type Enum Events.
Expand All @@ -94,3 +96,5 @@ pub static LIGHTFX_STOP_SIGNAL: Signal<CriticalSectionRawMutex, Commands> = Sign

/// Signal for the update commands that we want the orchestrator to send to the sound task.
pub static SOUND_SIGNAL: Signal<CriticalSectionRawMutex, Commands> = Signal::new();

pub static VSYS_WAKE_SIGNAL: Signal<CriticalSectionRawMutex, Commands> = Signal::new();
2 changes: 0 additions & 2 deletions src/task/time_updater.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
//! # populate constant TIME_SERVER_URL
//! make sure to have a time_api_config.json file in the config folder formatted as follows:
//! ```json
//! // populate constant TIME_SERVER_URL
//! make sure to have a time_api_config.json file in the config folder formatted as follows:
//! {
//! "time api by zone": {
//! "baseurl": "http://worldtimeapi.org/api",
Expand Down
Loading