continued Cds short time provider

This commit is contained in:
Robin Müller 2022-07-25 01:06:52 +02:00
parent 5fb2db9520
commit 6fe3086575
No known key found for this signature in database
GPG Key ID: 71B58F8A3CDFA9AC
3 changed files with 99 additions and 15 deletions

View File

@ -29,6 +29,6 @@ version = "0.7.3"
features = ["use-std"] features = ["use-std"]
[features] [features]
std = ["postcard/use-std"]
default = ["heapless", "alloc"] default = ["heapless", "alloc"]
alloc = ["serde/alloc"] alloc = ["serde/alloc"]

View File

@ -2,17 +2,20 @@
#![no_std] #![no_std]
extern crate alloc; extern crate alloc;
#[cfg(feature = "std")]
extern crate std;
use crate::ecss::CCSDS_HEADER_LEN; use crate::ecss::CCSDS_HEADER_LEN;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
pub mod ecss; pub mod ecss;
pub mod time;
pub mod tc; pub mod tc;
pub mod time;
pub mod tm; pub mod tm;
#[derive(Debug, Copy, Clone, PartialEq)] #[derive(Debug, Copy, Clone, PartialEq)]
pub enum PacketError { pub enum PacketError {
/// The passed slice is too small. Returns the required size of the failed size chgeck /// The passed slice is too small. Returns the required size of the failed size check
ToBytesSliceTooSmall(usize), ToBytesSliceTooSmall(usize),
/// The [zerocopy] library failed to write to bytes /// The [zerocopy] library failed to write to bytes
ToBytesZeroCopyError, ToBytesZeroCopyError,

View File

@ -1,39 +1,120 @@
enum CcsdsTimeCodes { use crate::PacketError;
#[cfg(feature = "std")]
use std::time::SystemTime;
pub const CDS_SHORT_LEN: usize = 7;
pub const DAYS_CCSDS_TO_UNIX: i32 = -4383;
pub const SECONDS_PER_DAY: u32 = 86400;
pub enum CcsdsTimeCodes {
None = 0, None = 0,
CucCcsdsEpoch = 0b001, CucCcsdsEpoch = 0b001,
CucAgencyEpoch = 0b010, CucAgencyEpoch = 0b010,
Cds = 0b100, Cds = 0b100,
Ccs = 0b101 Ccs = 0b101,
}
#[cfg(feature = "std")]
pub fn seconds_since_epoch() -> f64 {
SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.expect("System time generation failed")
.as_secs_f64()
}
/// Convert UNIX days to CCSDS days
///
/// - CCSDS epoch: 1958 January 1
/// - UNIX Epoch: 1970 January 1
pub const fn unix_to_ccsds_days(unix_days: i32) -> i32 {
unix_days - DAYS_CCSDS_TO_UNIX
}
/// Convert CCSDS days to UNIX days
///
/// - CCSDS epoch: 1958 January 1
/// - UNIX Epoch: 1970 January 1
pub const fn ccsds_to_unix_days(unix_days: i32) -> i32 {
unix_days + DAYS_CCSDS_TO_UNIX
} }
/// Trait for generic CCSDS time providers /// Trait for generic CCSDS time providers
trait CcsdsTimeProvider { trait CcsdsTimeProvider {
fn write_to_bytes(&self, bytes: impl AsMut<u8>); fn len(&self) -> usize;
fn write_to_bytes(&self, bytes: &mut (impl AsMut<[u8]> + ?Sized)) -> Result<(), PacketError>;
/// Returns the pfield of the time provider. The pfield can have one or two bytes depending /// Returns the pfield of the time provider. The pfield can have one or two bytes depending
/// on the extension bit (first bit). The time provider should returns a tuple where the first /// on the extension bit (first bit). The time provider should returns a tuple where the first
/// entry denotes the length of the pfield and the second entry is the value of the pfield /// entry denotes the length of the pfield and the second entry is the value of the pfield
/// in big endian format. /// in big endian format.
fn pfield(&self) -> (usize, u16); fn p_field(&self) -> (usize, [u8; 2]);
fn ccdsd_time_code(&self) -> CcsdsTimeCodes; fn ccdsd_time_code(&self) -> CcsdsTimeCodes;
fn as_unix_seconds(&self) -> u64; fn as_unix_seconds(&self) -> u64;
} }
struct CdsShortTimeProvider {} pub struct CdsShortTimeProvider {
pfield: u8,
impl CcsdsTimeProvider for CdsShortTimeProvider { ccsds_days: u16,
fn write_to_bytes(&self, bytes: impl AsMut<u8>) { ms_of_day: u32,
todo!() unix_seconds: u64,
} }
fn pfield(&self) -> (usize, u16) { impl CdsShortTimeProvider {
todo!() pub fn new(ccsds_days: u16, ms_of_day: u32) -> Self {
let mut provider = Self {
pfield: (CcsdsTimeCodes::Cds as u8) << 4,
ccsds_days,
ms_of_day,
unix_seconds: 0,
};
provider.calc_unix_seconds();
provider
}
#[cfg(feature = "std")]
pub fn ms_of_day_using_sysclock() -> u32 {
Self::ms_of_day(seconds_since_epoch())
}
pub fn ms_of_day(seconds_since_epoch: f64) -> u32 {
let fraction_ms = seconds_since_epoch - seconds_since_epoch.floor();
let ms_of_day: u32 =
(((seconds_since_epoch.floor() as u32 % SECONDS_PER_DAY) * 1000) as f64 + fraction_ms)
.floor() as u32;
ms_of_day
}
fn calc_unix_seconds(&mut self) {
let unix_days = ccsds_to_unix_days(self.ccsds_days as i32);
self.unix_seconds = unix_days as u64 * (24 * 60 * 60);
let seconds_of_day = (self.ms_of_day as f32 / 1000.0).floor() as u64;
self.unix_seconds += seconds_of_day;
}
}
impl CcsdsTimeProvider for CdsShortTimeProvider {
fn len(&self) -> usize {
CDS_SHORT_LEN
}
fn write_to_bytes(&self, bytes: &mut (impl AsMut<[u8]> + ?Sized)) -> Result<(), PacketError> {
let slice = bytes.as_mut();
if slice.len() < self.len() {
return Err(PacketError::ToBytesSliceTooSmall(slice.len()));
}
slice[0] = self.pfield;
slice[1..3].copy_from_slice(self.ccsds_days.to_be_bytes().as_slice());
slice[4..].copy_from_slice(self.ms_of_day.to_be_bytes().as_slice());
Ok(())
}
fn p_field(&self) -> (usize, [u8; 2]) {
(1, [self.pfield, 0])
} }
fn ccdsd_time_code(&self) -> CcsdsTimeCodes { fn ccdsd_time_code(&self) -> CcsdsTimeCodes {
todo!() CcsdsTimeCodes::Cds
} }
fn as_unix_seconds(&self) -> u64 { fn as_unix_seconds(&self) -> u64 {
todo!() self.unix_seconds
} }
} }