it's alive

This commit is contained in:
2025-09-13 01:39:47 +02:00
parent 79087c9353
commit 9de85b6e37
19 changed files with 1567 additions and 1488 deletions

View File

@@ -1,133 +1,138 @@
use crate::hal::Box;
use alloc::vec::Vec;
use anyhow::{anyhow, bail};
use async_trait::async_trait;
use bincode::config::Configuration;
use bincode::{config, Decode, Encode};
use chrono::{DateTime, Utc};
use ds323x::{DateTimeAccess, Ds323x};
use eeprom24x::addr_size::TwoBytes;
use eeprom24x::page_size::B32;
use eeprom24x::unique_serial::No;
use eeprom24x::Storage;
use embedded_storage::ReadStorage as embedded_storage_ReadStorage;
use embedded_storage::Storage as embedded_storage_Storage;
use serde::{Deserialize, Serialize};
const X25: crc::Crc<u16> = crc::Crc::<u16>::new(&crc::CRC_16_IBM_SDLC);
const CONFIG: Configuration = config::standard();
// use crate::hal::Box;
// use alloc::vec::Vec;
// use anyhow::{anyhow, bail};
// use async_trait::async_trait;
// use bincode::config::Configuration;
// use bincode::{config, Decode, Encode};
// use chrono::{DateTime, Utc};
// use ds323x::{DateTimeAccess, Ds323x};
// use eeprom24x::addr_size::TwoBytes;
// use eeprom24x::page_size::B32;
// use eeprom24x::unique_serial::No;
// use eeprom24x::Storage;
// use embedded_storage::ReadStorage as embedded_storage_ReadStorage;
// use embedded_storage::Storage as embedded_storage_Storage;
// use serde::{Deserialize, Serialize};
//
// const X25: crc::Crc<u16> = crc::Crc::<u16>::new(&crc::CRC_16_IBM_SDLC);
// const CONFIG: Configuration = config::standard();
//
#[async_trait]
pub trait RTCModuleInteraction {
async fn get_backup_info(&mut self) -> anyhow::Result<BackupHeader>;
async fn get_backup_config(&mut self) -> anyhow::Result<Vec<u8>>;
async fn backup_config(&mut self, bytes: &[u8]) -> anyhow::Result<()>;
async fn get_rtc_time(&mut self) -> anyhow::Result<DateTime<Utc>>;
async fn set_rtc_time(&mut self, time: &DateTime<Utc>) -> anyhow::Result<()>;
async fn get_backup_info(&mut self) -> anyhow::Result<BackupHeader>;
async fn get_backup_config(&mut self) -> anyhow::Result<Vec<u8>>;
async fn backup_config(&mut self, bytes: &[u8]) -> anyhow::Result<()>;
async fn get_rtc_time(&mut self) -> anyhow::Result<DateTime<Utc>>;
async fn set_rtc_time(&mut self, time: &DateTime<Utc>) -> anyhow::Result<()>;
}
const BACKUP_HEADER_MAX_SIZE: usize = 64;
#[derive(Serialize, Deserialize, PartialEq, Debug, Default, Encode, Decode)]
//
// const BACKUP_HEADER_MAX_SIZE: usize = 64;
// #[derive(Serialize, Deserialize, PartialEq, Debug, Default, Encode, Decode)]
pub struct BackupHeader {
pub timestamp: i64,
crc16: u16,
pub size: u16,
}
pub struct DS3231Module<'a> {
pub(crate) rtc:
Ds323x<ds323x::interface::I2cInterface<MutexDevice<'a, I2cDriver<'a>>>, ds323x::ic::DS3231>,
pub(crate) storage: Storage<MutexDevice<'a, I2cDriver<'a>>, B32, TwoBytes, No, Delay>,
}
impl RTCModuleInteraction for DS3231Module<'_> {
fn get_backup_info(&mut self) -> anyhow::Result<BackupHeader> {
let mut header_page_buffer = [0_u8; BACKUP_HEADER_MAX_SIZE];
self.storage
.read(0, &mut header_page_buffer)
.map_err(|err| anyhow!("Error reading eeprom header {:?}", err))?;
let (header, len): (BackupHeader, usize) =
bincode::decode_from_slice(&header_page_buffer[..], CONFIG)?;
log::info!("Raw header is {:?} with size {}", header_page_buffer, len);
anyhow::Ok(header)
}
fn get_backup_config(&mut self) -> anyhow::Result<Vec<u8>> {
let mut header_page_buffer = [0_u8; BACKUP_HEADER_MAX_SIZE];
self.storage
.read(0, &mut header_page_buffer)
.map_err(|err| anyhow!("Error reading eeprom header {:?}", err))?;
let (header, _header_size): (BackupHeader, usize) =
bincode::decode_from_slice(&header_page_buffer[..], CONFIG)?;
let mut data_buffer = vec![0_u8; header.size as usize];
//read the specified number of bytes after the header
self.storage
.read(BACKUP_HEADER_MAX_SIZE as u32, &mut data_buffer)
.map_err(|err| anyhow!("Error reading eeprom data {:?}", err))?;
let checksum = X25.checksum(&data_buffer);
if checksum != header.crc16 {
bail!(
"Invalid checksum, got {} but expected {}",
checksum,
header.crc16
);
}
anyhow::Ok(data_buffer)
}
fn backup_config(&mut self, bytes: &[u8]) -> anyhow::Result<()> {
let mut header_page_buffer = [0_u8; BACKUP_HEADER_MAX_SIZE];
let time = self.get_rtc_time()?.timestamp_millis();
let checksum = X25.checksum(bytes);
let header = BackupHeader {
crc16: checksum,
timestamp: time,
size: bytes.len() as u16,
};
let config = config::standard();
let encoded = bincode::encode_into_slice(&header, &mut header_page_buffer, config)?;
log::info!(
"Raw header is {:?} with size {}",
header_page_buffer,
encoded
);
self.storage
.write(0, &header_page_buffer)
.map_err(|err| anyhow!("Error writing header {:?}", err))?;
//write rest after the header
self.storage
.write(BACKUP_HEADER_MAX_SIZE as u32, &bytes)
.map_err(|err| anyhow!("Error writing body {:?}", err))?;
anyhow::Ok(())
}
fn get_rtc_time(&mut self) -> anyhow::Result<DateTime<Utc>> {
match self.rtc.datetime() {
OkStd(rtc_time) => anyhow::Ok(rtc_time.and_utc()),
Err(err) => {
bail!("Error getting rtc time {:?}", err)
}
}
}
fn set_rtc_time(&mut self, time: &DateTime<Utc>) -> anyhow::Result<()> {
let naive_time = time.naive_utc();
match self.rtc.set_datetime(&naive_time) {
OkStd(_) => anyhow::Ok(()),
Err(err) => {
bail!("Error getting rtc time {:?}", err)
}
}
}
}
//
// pub struct DS3231Module<'a> {
// pub(crate) rtc:
// Ds323x<ds323x::interface::I2cInterface<MutexDevice<'a, I2cDriver<'a>>>, ds323x::ic::DS3231>,
//
// pub(crate) storage: Storage<MutexDevice<'a, I2cDriver<'a>>, B32, TwoBytes, No, Delay>,
// }
//
// impl RTCModuleInteraction for DS3231Module<'_> {
// fn get_backup_info(&mut self) -> anyhow::Result<BackupHeader> {
// let mut header_page_buffer = [0_u8; BACKUP_HEADER_MAX_SIZE];
//
// self.storage
// .read(0, &mut header_page_buffer)
// .map_err(|err| anyhow!("Error reading eeprom header {:?}", err))?;
//
// let (header, len): (BackupHeader, usize) =
// bincode::decode_from_slice(&header_page_buffer[..], CONFIG)?;
//
// log::info!("Raw header is {:?} with size {}", header_page_buffer, len);
// anyhow::Ok(header)
// }
//
// fn get_backup_config(&mut self) -> anyhow::Result<Vec<u8>> {
// let mut header_page_buffer = [0_u8; BACKUP_HEADER_MAX_SIZE];
//
// self.storage
// .read(0, &mut header_page_buffer)
// .map_err(|err| anyhow!("Error reading eeprom header {:?}", err))?;
// let (header, _header_size): (BackupHeader, usize) =
// bincode::decode_from_slice(&header_page_buffer[..], CONFIG)?;
//
// let mut data_buffer = vec![0_u8; header.size as usize];
// //read the specified number of bytes after the header
// self.storage
// .read(BACKUP_HEADER_MAX_SIZE as u32, &mut data_buffer)
// .map_err(|err| anyhow!("Error reading eeprom data {:?}", err))?;
//
// let checksum = X25.checksum(&data_buffer);
// if checksum != header.crc16 {
// bail!(
// "Invalid checksum, got {} but expected {}",
// checksum,
// header.crc16
// );
// }
//
// anyhow::Ok(data_buffer)
// }
// fn backup_config(&mut self, bytes: &[u8]) -> anyhow::Result<()> {
// let mut header_page_buffer = [0_u8; BACKUP_HEADER_MAX_SIZE];
//
// let time = self.get_rtc_time()?.timestamp_millis();
// let checksum = X25.checksum(bytes);
//
// let header = BackupHeader {
// crc16: checksum,
// timestamp: time,
// size: bytes.len() as u16,
// };
// let config = config::standard();
// let encoded = bincode::encode_into_slice(&header, &mut header_page_buffer, config)?;
// log::info!(
// "Raw header is {:?} with size {}",
// header_page_buffer,
// encoded
// );
// self.storage
// .write(0, &header_page_buffer)
// .map_err(|err| anyhow!("Error writing header {:?}", err))?;
//
// //write rest after the header
// self.storage
// .write(BACKUP_HEADER_MAX_SIZE as u32, &bytes)
// .map_err(|err| anyhow!("Error writing body {:?}", err))?;
//
// anyhow::Ok(())
// }
//
// fn get_rtc_time(&mut self) -> anyhow::Result<DateTime<Utc>> {
// match self.rtc.datetime() {
// OkStd(rtc_time) => anyhow::Ok(rtc_time.and_utc()),
// Err(err) => {
// bail!("Error getting rtc time {:?}", err)
// }
// }
// }
//
// fn set_rtc_time(&mut self, time: &DateTime<Utc>) -> anyhow::Result<()> {
// let naive_time = time.naive_utc();
// match self.rtc.set_datetime(&naive_time) {
// OkStd(_) => anyhow::Ok(()),
// Err(err) => {
// bail!("Error getting rtc time {:?}", err)
// }
// }
// }
// }