power_manager/
messages.rs

1// SPDX-FileCopyrightText: 2024 Foundation Devices, Inc. <hello@foundation.xyz>
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#[cfg(keyos)]
5use atsama5d27::pmc::PeripheralId;
6use num_traits::{FromPrimitive, ToPrimitive};
7use server::{AsScalar, FromScalar};
8
9use crate::{AttachedState, ChargeStatus, OtgPriority, Status};
10
11#[cfg(not(keyos))]
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
13#[repr(u8)]
14pub enum PeripheralId {
15    Reserved1 = 1,
16}
17
18#[cfg(not(keyos))]
19impl TryFrom<u8> for PeripheralId {
20    type Error = ();
21
22    fn try_from(_value: u8) -> Result<Self, Self::Error> { Err(()) }
23}
24
25#[derive(Debug, server::Message)]
26#[response(())]
27pub struct Shutdown;
28
29#[derive(Debug, server::Message)]
30#[response(())]
31pub struct Reboot;
32
33#[derive(Debug, server::Message)]
34#[response(Status)]
35pub struct GetStatus;
36
37impl FromScalar<3> for Status {
38    fn from_scalar([status, percent, state]: [u32; 3]) -> Self {
39        Status {
40            charge_status: ChargeStatus::from_u32(status).unwrap_or(ChargeStatus::Fault),
41            battery_percent: percent as u8,
42            attached_state: AttachedState::from_u32(state).unwrap_or(AttachedState::None),
43        }
44    }
45}
46
47impl AsScalar<3> for Status {
48    fn as_scalar(&self) -> [u32; 3] {
49        [
50            self.charge_status.to_u32().unwrap(),
51            self.battery_percent as u32,
52            self.attached_state.to_u32().unwrap(),
53        ]
54    }
55}
56
57#[derive(Debug, server::Message)]
58#[response(SetUsbBoostResponse)]
59pub struct SetUsbBoost {
60    pub enabled: bool,
61}
62
63pub struct SetUsbBoostResponse {
64    pub success: bool,
65    pub previous_state: bool,
66}
67
68impl FromScalar<1> for SetUsbBoost {
69    fn from_scalar([value]: [u32; 1]) -> Self { Self { enabled: value != 0 } }
70}
71
72impl AsScalar<1> for SetUsbBoost {
73    fn as_scalar(&self) -> [u32; 1] { [self.enabled.into()] }
74}
75
76impl FromScalar<2> for SetUsbBoostResponse {
77    fn from_scalar(value: [u32; 2]) -> Self { Self { success: value[0] != 0, previous_state: value[1] != 0 } }
78}
79
80impl AsScalar<2> for SetUsbBoostResponse {
81    fn as_scalar(&self) -> [u32; 2] { [self.success.into(), self.previous_state.into()] }
82}
83
84#[derive(Debug, server::Message)]
85#[response(())]
86pub struct SetPeripheralEnabled {
87    pub peripheral: PeripheralId,
88    pub enabled: bool,
89}
90
91impl FromScalar<2> for SetPeripheralEnabled {
92    fn from_scalar(value: [u32; 2]) -> Self {
93        Self {
94            peripheral: PeripheralId::try_from(value[0] as u8).unwrap_or(PeripheralId::Reserved1),
95            enabled: value[1] != 0,
96        }
97    }
98}
99
100impl AsScalar<2> for SetPeripheralEnabled {
101    fn as_scalar(&self) -> [u32; 2] { [self.peripheral as u32, self.enabled as u32] }
102}
103
104#[derive(Debug, server::Message)]
105pub struct SetOtgPriority(pub OtgPriority);
106
107impl FromScalar<1> for OtgPriority {
108    fn from_scalar([value]: [u32; 1]) -> Self { OtgPriority::from_u32(value).unwrap_or_default() }
109}
110
111impl AsScalar<1> for OtgPriority {
112    fn as_scalar(&self) -> [u32; 1] { [self.to_u32().unwrap_or_default()] }
113}
114
115#[derive(Debug, server::Message, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
116#[response(Option<ExtendedStatus>)]
117pub struct GetExtendedStatus;
118
119#[derive(Debug, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
120pub struct ExtendedStatus {
121    pub current: i16,
122    pub voltage_mv: i16,
123    pub capacity_mah: u16,
124    pub remaining_capacity_mah: u16,
125    pub last_reported_fault: Option<ChargeFault>,
126    pub num_reported_faults: u32,
127}
128
129#[derive(Debug, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
130pub enum ChargeFault {
131    Normal,
132    VbusOvp,
133    SleepMode,
134    BadAdaptor,
135    OutputOvp,
136    ThermalShutdown,
137    TimerFault,
138    NoBattery,
139}
140
141#[cfg(keyos)]
142impl From<bq24157::ChargeFault> for ChargeFault {
143    fn from(fault: bq24157::ChargeFault) -> Self {
144        match fault {
145            bq24157::ChargeFault::Normal => ChargeFault::Normal,
146            bq24157::ChargeFault::VbusOvp => ChargeFault::VbusOvp,
147            bq24157::ChargeFault::SleepMode => ChargeFault::SleepMode,
148            bq24157::ChargeFault::BadAdaptor => ChargeFault::BadAdaptor,
149            bq24157::ChargeFault::OutputOvp => ChargeFault::OutputOvp,
150            bq24157::ChargeFault::ThermalShutdown => ChargeFault::ThermalShutdown,
151            bq24157::ChargeFault::TimerFault => ChargeFault::TimerFault,
152            bq24157::ChargeFault::NoBattery => ChargeFault::NoBattery,
153        }
154    }
155}
156
157#[derive(Debug, server::Message)]
158pub struct ClearChargeFault;
159
160#[derive(Debug, server::Message, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
161#[event(Status)]
162pub struct StatusSubscribe;
163
164#[derive(Debug, server::Message)]
165pub struct SetBatteryPercent(pub(crate) u8);