50fdaab25b
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Alexander <akotenev2003@gmail.com>
84 lines
2.4 KiB
Rust
84 lines
2.4 KiB
Rust
//! Типы сообщений SoC↔MCU (B08, спека v0.4 §6.1). seq — поле кадра (codec), не сообщения.
|
|
|
|
pub mod wire {
|
|
pub const HEARTBEAT: u8 = 0x01;
|
|
pub const SHUTDOWN_IMMINENT: u8 = 0x02;
|
|
pub const SAFE_TO_CUT: u8 = 0x03;
|
|
pub const ACK: u8 = 0x81;
|
|
pub const ACC: u8 = 0x82;
|
|
pub const VOLTAGE: u8 = 0x83;
|
|
pub const CUT_WARNING: u8 = 0x84;
|
|
}
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
pub enum SocToMcu {
|
|
Heartbeat,
|
|
ShutdownImminent { budget: u8 },
|
|
SafeToCut,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
pub enum McuToSoc {
|
|
Ack,
|
|
Acc { on: bool },
|
|
Voltage { mv: u16 },
|
|
CutWarning,
|
|
}
|
|
|
|
impl SocToMcu {
|
|
pub fn wire_type(&self) -> u8 {
|
|
match self {
|
|
SocToMcu::Heartbeat => wire::HEARTBEAT,
|
|
SocToMcu::ShutdownImminent { .. } => wire::SHUTDOWN_IMMINENT,
|
|
SocToMcu::SafeToCut => wire::SAFE_TO_CUT,
|
|
}
|
|
}
|
|
pub fn payload(&self) -> Vec<u8> {
|
|
match self {
|
|
SocToMcu::ShutdownImminent { budget } => vec![*budget],
|
|
_ => vec![],
|
|
}
|
|
}
|
|
pub fn from_wire(t: u8, p: &[u8]) -> Option<Self> {
|
|
match t {
|
|
wire::HEARTBEAT => Some(SocToMcu::Heartbeat),
|
|
wire::SHUTDOWN_IMMINENT => Some(SocToMcu::ShutdownImminent {
|
|
budget: *p.first()?,
|
|
}),
|
|
wire::SAFE_TO_CUT => Some(SocToMcu::SafeToCut),
|
|
_ => None,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl McuToSoc {
|
|
pub fn wire_type(&self) -> u8 {
|
|
match self {
|
|
McuToSoc::Ack => wire::ACK,
|
|
McuToSoc::Acc { .. } => wire::ACC,
|
|
McuToSoc::Voltage { .. } => wire::VOLTAGE,
|
|
McuToSoc::CutWarning => wire::CUT_WARNING,
|
|
}
|
|
}
|
|
pub fn payload(&self) -> Vec<u8> {
|
|
match self {
|
|
McuToSoc::Acc { on } => vec![*on as u8],
|
|
McuToSoc::Voltage { mv } => mv.to_be_bytes().to_vec(),
|
|
_ => vec![],
|
|
}
|
|
}
|
|
pub fn from_wire(t: u8, p: &[u8]) -> Option<Self> {
|
|
match t {
|
|
wire::ACK => Some(McuToSoc::Ack),
|
|
wire::ACC => Some(McuToSoc::Acc {
|
|
on: *p.first()? != 0,
|
|
}),
|
|
wire::VOLTAGE => Some(McuToSoc::Voltage {
|
|
mv: u16::from_be_bytes([*p.first()?, *p.get(1)?]),
|
|
}),
|
|
wire::CUT_WARNING => Some(McuToSoc::CutWarning),
|
|
_ => None,
|
|
}
|
|
}
|
|
}
|