191 lines
6.1 KiB
Rust
191 lines
6.1 KiB
Rust
#![no_main]
|
|
#![no_std]
|
|
|
|
use arbitrary_int::u11;
|
|
use core::time::Duration;
|
|
use embassy_stm32::gpio::Output;
|
|
use spacepackets::{
|
|
ccsds_packet_len_for_user_data_len_with_checksum, CcsdsPacketCreationError,
|
|
CcsdsPacketCreatorWithReservedData, CcsdsPacketIdAndPsc, SpacePacketHeader,
|
|
};
|
|
|
|
pub const APID: u11 = u11::new(0x02);
|
|
|
|
#[derive(defmt::Format, serde::Serialize, serde::Deserialize, PartialEq, Eq, Clone, Copy)]
|
|
pub enum Direction {
|
|
North,
|
|
NorthEast,
|
|
East,
|
|
SouthEast,
|
|
South,
|
|
SouthWest,
|
|
West,
|
|
NorthWest,
|
|
}
|
|
|
|
impl Direction {
|
|
pub fn switch_to_next(&mut self) -> (Self, Self) {
|
|
let curr = *self;
|
|
*self = match self {
|
|
Direction::North => Direction::NorthEast,
|
|
Direction::NorthEast => Direction::East,
|
|
Direction::East => Direction::SouthEast,
|
|
Direction::SouthEast => Direction::South,
|
|
Direction::South => Direction::SouthWest,
|
|
Direction::SouthWest => Direction::West,
|
|
Direction::West => Direction::NorthWest,
|
|
Direction::NorthWest => Direction::North,
|
|
};
|
|
(curr, *self)
|
|
}
|
|
}
|
|
|
|
#[derive(Copy, Clone, Debug, defmt::Format, serde::Serialize, serde::Deserialize)]
|
|
pub enum Request {
|
|
Ping,
|
|
ChangeBlinkFrequency(Duration),
|
|
}
|
|
|
|
#[derive(Debug, defmt::Format, serde::Serialize, serde::Deserialize)]
|
|
pub struct TmHeader {
|
|
pub tc_packet_id: Option<CcsdsPacketIdAndPsc>,
|
|
pub uptime_millis: u32,
|
|
}
|
|
|
|
#[derive(Debug, defmt::Format, serde::Serialize, serde::Deserialize)]
|
|
pub enum Response {
|
|
CommandDone,
|
|
}
|
|
|
|
pub fn tm_size(tm_header: &TmHeader, response: &Response) -> usize {
|
|
ccsds_packet_len_for_user_data_len_with_checksum(
|
|
postcard::experimental::serialized_size(tm_header).unwrap()
|
|
+ postcard::experimental::serialized_size(response).unwrap(),
|
|
)
|
|
.unwrap()
|
|
}
|
|
|
|
pub fn create_tm_packet(
|
|
buf: &mut [u8],
|
|
sp_header: SpacePacketHeader,
|
|
tm_header: TmHeader,
|
|
response: Response,
|
|
) -> Result<usize, CcsdsPacketCreationError> {
|
|
let packet_data_size = postcard::experimental::serialized_size(&tm_header).unwrap()
|
|
+ postcard::experimental::serialized_size(&response).unwrap();
|
|
let mut creator =
|
|
CcsdsPacketCreatorWithReservedData::new_tm_with_checksum(sp_header, packet_data_size, buf)?;
|
|
|
|
let current_index = postcard::to_slice(&tm_header, creator.packet_data_mut())
|
|
.unwrap()
|
|
.len();
|
|
postcard::to_slice(&response, &mut creator.packet_data_mut()[current_index..]).unwrap();
|
|
Ok(creator.finish())
|
|
}
|
|
|
|
pub struct Leds {
|
|
pub north: Output<'static>,
|
|
pub north_east: Output<'static>,
|
|
pub east: Output<'static>,
|
|
pub south_east: Output<'static>,
|
|
pub south: Output<'static>,
|
|
pub south_west: Output<'static>,
|
|
pub west: Output<'static>,
|
|
pub north_west: Output<'static>,
|
|
}
|
|
|
|
impl Leds {
|
|
pub fn blink_next(&mut self, current_dir: &mut Direction) {
|
|
let (prev, curr) = current_dir.switch_to_next();
|
|
self.set_dir_low(prev);
|
|
self.set_dir_high(curr);
|
|
}
|
|
|
|
pub fn set_dir(&mut self, dir: Direction, level: embassy_stm32::gpio::Level) {
|
|
match dir {
|
|
Direction::North => self.north.set_level(level),
|
|
Direction::NorthEast => self.north_east.set_level(level),
|
|
Direction::East => self.east.set_level(level),
|
|
Direction::SouthEast => self.south_east.set_level(level),
|
|
Direction::South => self.south.set_level(level),
|
|
Direction::SouthWest => self.south_west.set_level(level),
|
|
Direction::West => self.west.set_level(level),
|
|
Direction::NorthWest => self.north_west.set_level(level),
|
|
}
|
|
}
|
|
|
|
pub fn set_dir_low(&mut self, dir: Direction) {
|
|
self.set_dir(dir, embassy_stm32::gpio::Level::Low);
|
|
}
|
|
|
|
pub fn set_dir_high(&mut self, dir: Direction) {
|
|
self.set_dir(dir, embassy_stm32::gpio::Level::High);
|
|
}
|
|
}
|
|
|
|
pub struct LedPinSet {
|
|
pub pin_n: embassy_stm32::Peri<'static, embassy_stm32::peripherals::PE8>,
|
|
pub pin_ne: embassy_stm32::Peri<'static, embassy_stm32::peripherals::PE9>,
|
|
pub pin_e: embassy_stm32::Peri<'static, embassy_stm32::peripherals::PE10>,
|
|
pub pin_se: embassy_stm32::Peri<'static, embassy_stm32::peripherals::PE11>,
|
|
pub pin_s: embassy_stm32::Peri<'static, embassy_stm32::peripherals::PE12>,
|
|
pub pin_sw: embassy_stm32::Peri<'static, embassy_stm32::peripherals::PE13>,
|
|
pub pin_w: embassy_stm32::Peri<'static, embassy_stm32::peripherals::PE14>,
|
|
pub pin_nw: embassy_stm32::Peri<'static, embassy_stm32::peripherals::PE15>,
|
|
}
|
|
|
|
impl Leds {
|
|
pub fn new(pin_set: LedPinSet) -> Self {
|
|
let led_n = Output::new(
|
|
pin_set.pin_n,
|
|
embassy_stm32::gpio::Level::Low,
|
|
embassy_stm32::gpio::Speed::Medium,
|
|
);
|
|
let led_ne = Output::new(
|
|
pin_set.pin_ne,
|
|
embassy_stm32::gpio::Level::Low,
|
|
embassy_stm32::gpio::Speed::Medium,
|
|
);
|
|
let led_e = Output::new(
|
|
pin_set.pin_e,
|
|
embassy_stm32::gpio::Level::Low,
|
|
embassy_stm32::gpio::Speed::Medium,
|
|
);
|
|
let led_se = Output::new(
|
|
pin_set.pin_se,
|
|
embassy_stm32::gpio::Level::Low,
|
|
embassy_stm32::gpio::Speed::Medium,
|
|
);
|
|
let led_s = Output::new(
|
|
pin_set.pin_s,
|
|
embassy_stm32::gpio::Level::Low,
|
|
embassy_stm32::gpio::Speed::Medium,
|
|
);
|
|
let led_sw = Output::new(
|
|
pin_set.pin_sw,
|
|
embassy_stm32::gpio::Level::Low,
|
|
embassy_stm32::gpio::Speed::Medium,
|
|
);
|
|
let led_w = Output::new(
|
|
pin_set.pin_w,
|
|
embassy_stm32::gpio::Level::Low,
|
|
embassy_stm32::gpio::Speed::Medium,
|
|
);
|
|
let led_nw = Output::new(
|
|
pin_set.pin_nw,
|
|
embassy_stm32::gpio::Level::Low,
|
|
embassy_stm32::gpio::Speed::Medium,
|
|
);
|
|
Self {
|
|
north: led_n,
|
|
north_east: led_ne,
|
|
east: led_e,
|
|
south_east: led_se,
|
|
south: led_s,
|
|
south_west: led_sw,
|
|
west: led_w,
|
|
north_west: led_nw,
|
|
}
|
|
}
|
|
}
|