diff --git a/embedded-examples/embedded-client/src/main.rs b/embedded-examples/embedded-client/src/main.rs index d72bfeb..c05ae34 100644 --- a/embedded-examples/embedded-client/src/main.rs +++ b/embedded-examples/embedded-client/src/main.rs @@ -7,7 +7,7 @@ use std::{ use clap::Parser; use cobs::CobsDecoderOwned; -use embedded_models::Request; +use embedded_models::stm32f3; use spacepackets::{CcsdsPacketCreatorOwned, CcsdsPacketReader, SpHeader}; use tmtc_utils::transport::serial::PacketTransportSerialCobs; @@ -69,8 +69,7 @@ fn main() { let mut transport = PacketTransportSerialCobs::new(serial, CobsDecoderOwned::new(1024)); if cli.ping { - let request = Request::Ping; - let tc = create_stm32f3_tc(&request); + let tc = create_stm32f3_tc(&embedded_models::stm32f3::Request::Ping); log::info!( "Sending ping request with TC ID: {:#010x}", tc.ccsds_packet_id_and_psc().raw() @@ -79,7 +78,7 @@ fn main() { } if let Some(freq_ms) = cli.set_led_frequency { - let request = Request::ChangeBlinkFrequency(Duration::from_millis(freq_ms as u64)); + let request = stm32f3::Request::ChangeBlinkFrequency(Duration::from_millis(freq_ms as u64)); let tc = create_stm32f3_tc(&request); log::info!( "Sending change blink frequency request {:?} with TC ID: {:#010x}", @@ -100,7 +99,7 @@ fn main() { } } -fn create_stm32f3_tc(request: &Request) -> CcsdsPacketCreatorOwned { +fn create_stm32f3_tc(request: &stm32f3::Request) -> CcsdsPacketCreatorOwned { let req_raw = postcard::to_allocvec(&request).unwrap(); let sp_header = SpHeader::new_from_apid(satrs_stm32f3_disco_rtic::APID); CcsdsPacketCreatorOwned::new_tc_with_checksum(sp_header, &req_raw).unwrap() diff --git a/embedded-examples/models/Cargo.toml b/embedded-examples/models/Cargo.toml index b291e30..2ec7843 100644 --- a/embedded-examples/models/Cargo.toml +++ b/embedded-examples/models/Cargo.toml @@ -8,3 +8,4 @@ serde = { version = "1", default-features = false } defmt = { version = "1", optional = true } spacepackets = { version = "0.17", default-features = false, features = ["defmt", "serde"] } postcard = { version = "1", features = ["defmt"] } +arbitrary-int = "2" diff --git a/embedded-examples/models/src/lib.rs b/embedded-examples/models/src/lib.rs index 0703ce8..e3d74b6 100644 --- a/embedded-examples/models/src/lib.rs +++ b/embedded-examples/models/src/lib.rs @@ -1,33 +1,60 @@ #![no_std] -use core::time::Duration; - use spacepackets::{ CcsdsPacketCreationError, CcsdsPacketCreatorWithReservedData, CcsdsPacketIdAndPsc, SpacePacketHeader, ccsds_packet_len_for_user_data_len_with_checksum, }; -#[derive(Copy, Clone, Debug, serde::Serialize, serde::Deserialize)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub enum Request { - Ping, - ChangeBlinkFrequency(Duration), +pub mod stm32f3 { + use arbitrary_int::u11; + use core::time::Duration; + + pub const PUS_APID: u11 = u11::new(0x02); + + #[derive(Copy, Clone, Debug, serde::Serialize, serde::Deserialize)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] + pub enum Request { + Ping, + ChangeBlinkFrequency(Duration), + } + + #[derive(Debug, serde::Serialize, serde::Deserialize)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] + pub enum Response { + Ok, + } } -#[derive(Debug, serde::Serialize, serde::Deserialize)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub enum Response { - CommandDone, +/// This might look like a duplication, but we intentionally keep those separate so they can +/// change independently. +pub mod stm32h7 { + use arbitrary_int::u11; + use core::time::Duration; + + pub const PUS_APID: u11 = u11::new(0x03); + + #[derive(Copy, Clone, Debug, serde::Serialize, serde::Deserialize)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] + pub enum Request { + Ping, + ChangeBlinkFrequency(Duration), + } + + #[derive(Debug, serde::Serialize, serde::Deserialize)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] + pub enum Response { + Ok, + } } #[derive(Debug, serde::Serialize, serde::Deserialize)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct TmHeader { pub tc_packet_id: Option, - pub uptime_millis: u32, + pub uptime_millis: u64, } -pub fn tm_size(tm_header: &TmHeader, response: &Response) -> usize { +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(), @@ -35,7 +62,7 @@ pub fn tm_size(tm_header: &TmHeader, response: &Response) -> usize { .unwrap() } -pub fn create_tm_packet( +pub fn create_tm_packet( buf: &mut [u8], sp_header: SpacePacketHeader, tm_header: TmHeader, @@ -52,5 +79,6 @@ pub fn create_tm_packet( postcard::to_slice(&response, &mut creator.packet_data_mut()[current_index..]).unwrap(); Ok(creator.finish()) } + #[cfg(test)] mod tests {} diff --git a/embedded-examples/stm32f3-disco-rtic/Cargo.lock b/embedded-examples/stm32f3-disco-rtic/Cargo.lock index 5bce602..0a27024 100644 --- a/embedded-examples/stm32f3-disco-rtic/Cargo.lock +++ b/embedded-examples/stm32f3-disco-rtic/Cargo.lock @@ -596,6 +596,7 @@ dependencies = [ name = "embedded-models" version = "0.1.0" dependencies = [ + "arbitrary-int 2.0.0", "defmt 1.0.1", "postcard", "serde", diff --git a/embedded-examples/stm32f3-disco-rtic/src/main.rs b/embedded-examples/stm32f3-disco-rtic/src/main.rs index 186b72c..6022a0b 100644 --- a/embedded-examples/stm32f3-disco-rtic/src/main.rs +++ b/embedded-examples/stm32f3-disco-rtic/src/main.rs @@ -1,8 +1,8 @@ #![no_std] #![no_main] -use arbitrary_int::{u11, u14}; +use arbitrary_int::u14; use cortex_m_semihosting::debug::{self, EXIT_FAILURE, EXIT_SUCCESS}; -use embedded_models::{create_tm_packet, tm_size, Response, TmHeader}; +use embedded_models::{create_tm_packet, stm32f3, tm_size, TmHeader}; use spacepackets::{CcsdsPacketCreationError, CcsdsPacketIdAndPsc, SpHeader}; use defmt_rtt as _; // global logger @@ -23,8 +23,6 @@ const TX_HANDLER_FREQ_MS: u32 = 20; const MAX_TC_LEN: usize = 128; const MAX_TM_LEN: usize = 128; -pub const PUS_APID: u11 = u11::new(0x02); - // This is the predictable maximum overhead of the COBS encoding scheme. // It is simply the maximum packet lenght dividied by 254 rounded up. const COBS_TM_OVERHEAD: usize = cobs::max_encoding_overhead(MAX_TM_LEN); @@ -47,7 +45,7 @@ pub enum TmSendError { #[derive(Debug, defmt::Format)] pub struct RequestWithTcId { - pub request: embedded_models::Request, + pub request: stm32f3::Request, pub tc_id: CcsdsPacketIdAndPsc, } @@ -57,7 +55,7 @@ mod app { use super::*; use arbitrary_int::u14; - use embedded_models::{Request, Response}; + use embedded_models::stm32f3::{Request, Response}; use rtic::Mutex; use rtic_sync::{ channel::{Receiver, Sender}, @@ -264,7 +262,7 @@ mod app { tc_packet_id: CcsdsPacketIdAndPsc, ) -> Result<(), TmSendError> { defmt::info!("Received PUS ping telecommand, sending ping reply"); - send_tm(tc_packet_id, Response::CommandDone, *cx.local.seq_count)?; + send_tm(tc_packet_id, Response::Ok, *cx.local.seq_count)?; *cx.local.seq_count = cx.local.seq_count.wrapping_add(u14::new(1)); Ok(()) } @@ -281,7 +279,7 @@ mod app { cx.shared .blink_freq .lock(|blink_freq| *blink_freq = duration); - send_tm(tc_packet_id, Response::CommandDone, *cx.local.seq_count)?; + send_tm(tc_packet_id, Response::Ok, *cx.local.seq_count)?; *cx.local.seq_count = cx.local.seq_count.wrapping_add(u14::new(1)); Ok(()) } @@ -289,13 +287,13 @@ mod app { fn send_tm( tc_packet_id: CcsdsPacketIdAndPsc, - response: Response, + response: stm32f3::Response, current_seq_count: u14, ) -> Result<(), TmSendError> { - let sp_header = SpHeader::new_for_unseg_tc(PUS_APID, current_seq_count, 0); + let sp_header = SpHeader::new_for_unseg_tc(stm32f3::PUS_APID, current_seq_count, 0); let tm_header = TmHeader { tc_packet_id: Some(tc_packet_id), - uptime_millis: Mono::now().duration_since_epoch().to_millis(), + uptime_millis: Mono::now().duration_since_epoch().to_millis() as u64, }; let mut tm_packet = TmPacket::new(); let tm_size = tm_size(&tm_header, &response); diff --git a/embedded-examples/stm32h7-nucleo-rtic/Cargo.lock b/embedded-examples/stm32h7-nucleo-rtic/Cargo.lock index be43123..65f18f6 100644 --- a/embedded-examples/stm32h7-nucleo-rtic/Cargo.lock +++ b/embedded-examples/stm32h7-nucleo-rtic/Cargo.lock @@ -20,6 +20,22 @@ dependencies = [ "as-slice", ] +[[package]] +name = "arbitrary-int" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "825297538d77367557b912770ca3083f778a196054b3ee63b22673c4a3cae0a5" + +[[package]] +name = "arbitrary-int" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "993a810118f8f37e9c4411c86f1c4c940a09a7ab34b7bf2d88d06f50c553fab7" +dependencies = [ + "defmt 1.1.0", + "serde", +] + [[package]] name = "as-slice" version = "0.2.1" @@ -29,6 +45,15 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "atomic-polyfill" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" +dependencies = [ + "critical-section", +] + [[package]] name = "autocfg" version = "1.5.0" @@ -41,7 +66,7 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" dependencies = [ - "rustc_version", + "rustc_version 0.2.3", ] [[package]] @@ -62,6 +87,18 @@ version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e4b40c7323adcfc0a41c4b88143ed58346ff65a288fc144329c5c45e05d70c6" +[[package]] +name = "bitbybit" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec187a89ab07e209270175faf9e07ceb2755d984954e58a2296e325ddece2762" +dependencies = [ + "arbitrary-int 1.3.0", + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "bitfield" version = "0.13.2" @@ -101,6 +138,25 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +[[package]] +name = "chrono" +version = "0.4.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" +dependencies = [ + "num-traits", + "serde", +] + +[[package]] +name = "cobs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1" +dependencies = [ + "thiserror", +] + [[package]] name = "const-default" version = "1.0.0" @@ -140,6 +196,21 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "crc" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eb8a2a1cd12ab0d987a5d5e825195d372001a4094a0376319d5a0ad71c1ba0d" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "217698eaf96b4a3f0bc4f3662aaa55bdf913cd54d7204591faa790070c6d0853" + [[package]] name = "critical-section" version = "1.2.0" @@ -219,6 +290,17 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "delegate" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "780eb241654bf097afb00fc5f054a09b687dad862e485fdcf8399bb056565370" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "document-features" version = "0.2.12" @@ -288,7 +370,7 @@ dependencies = [ "embassy-time", "embedded-io-async", "embedded-nal-async", - "heapless", + "heapless 0.9.3", "managed", "smoltcp", ] @@ -337,7 +419,7 @@ dependencies = [ "embedded-storage", "embedded-storage-async", "futures-util", - "heapless", + "heapless 0.9.3", "nb 1.1.0", "proc-macro2", "quote", @@ -366,7 +448,7 @@ dependencies = [ "embedded-io-async", "futures-core", "futures-sink", - "heapless", + "heapless 0.9.3", ] [[package]] @@ -400,7 +482,7 @@ version = "0.3.2" source = "git+https://github.com/embassy-rs/embassy.git?rev=dd8e4c14e53f088bae27c5d841ab7a4fa338a52c#dd8e4c14e53f088bae27c5d841ab7a4fa338a52c" dependencies = [ "embassy-executor-timer-queue", - "heapless", + "heapless 0.9.3", ] [[package]] @@ -500,6 +582,17 @@ dependencies = [ "embedded-io", ] +[[package]] +name = "embedded-models" +version = "0.1.0" +dependencies = [ + "arbitrary-int 2.1.1", + "defmt 1.1.0", + "postcard", + "serde", + "spacepackets", +] + [[package]] name = "embedded-nal" version = "0.9.0" @@ -584,6 +677,15 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d758ba1b47b00caf47f24925c0074ecb20d6dfcffe7f6d53395c0465674841a" +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + [[package]] name = "hash32" version = "0.3.1" @@ -599,6 +701,20 @@ version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" +[[package]] +name = "heapless" +version = "0.7.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" +dependencies = [ + "atomic-polyfill", + "hash32 0.2.1", + "rustc_version 0.4.1", + "serde", + "spin", + "stable_deref_trait", +] + [[package]] name = "heapless" version = "0.9.3" @@ -606,7 +722,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25ba4bd83f9415b58b4ed8dc5714c76e626a105be4646c02630ad730ad3b5aa4" dependencies = [ "defmt 1.1.0", - "hash32", + "hash32 0.3.1", "stable_deref_trait", ] @@ -644,6 +760,15 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + [[package]] name = "managed" version = "0.8.0" @@ -681,6 +806,27 @@ dependencies = [ "libm", ] +[[package]] +name = "num_enum" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0bca838442ec211fa11de3a8b0e0e8f3a4522575b5c4c06ed722e005036f26" +dependencies = [ + "num_enum_derive", + "rustversion", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "panic-probe" version = "1.0.0" @@ -691,6 +837,12 @@ dependencies = [ "defmt 1.1.0", ] +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + [[package]] name = "pin-project-lite" version = "0.2.17" @@ -703,6 +855,18 @@ version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" +[[package]] +name = "postcard" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24" +dependencies = [ + "cobs", + "defmt 1.1.0", + "heapless 0.7.17", + "serde", +] + [[package]] name = "proc-macro-error-attr2" version = "2.0.0" @@ -842,7 +1006,16 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" dependencies = [ - "semver", + "semver 0.9.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver 1.0.28", ] [[package]] @@ -855,6 +1028,7 @@ checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" name = "satrs-stm32h7-nucleo-rtic" version = "0.1.0" dependencies = [ + "arbitrary-int 2.1.1", "cortex-m", "cortex-m-rt", "defmt 1.1.0", @@ -865,11 +1039,20 @@ dependencies = [ "embassy-sync", "embassy-time", "embedded-alloc", + "embedded-models", "panic-probe", + "postcard", "rtic", + "spacepackets", "static_cell", ] +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + [[package]] name = "sdio-host" version = "0.9.0" @@ -891,12 +1074,48 @@ dependencies = [ "semver-parser", ] +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + [[package]] name = "semver-parser" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "smoltcp" version = "0.13.1" @@ -907,10 +1126,39 @@ dependencies = [ "byteorder", "cfg-if", "defmt 0.3.100", - "heapless", + "heapless 0.9.3", "managed", ] +[[package]] +name = "spacepackets" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94979a990b4333f43667cba9fe9e72b9c4e9ada82e09fbe8fb250844358590cc" +dependencies = [ + "arbitrary-int 2.1.1", + "bitbybit", + "chrono", + "crc", + "defmt 1.1.0", + "delegate", + "num-traits", + "num_enum", + "paste", + "serde", + "thiserror", + "zerocopy", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + [[package]] name = "stable_deref_trait" version = "1.2.1" @@ -1069,3 +1317,23 @@ checksum = "de437e2a6208b014ab52972a27e59b33fa2920d3e00fe05026167a1c509d19cc" dependencies = [ "vcell", ] + +[[package]] +name = "zerocopy" +version = "0.8.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] diff --git a/embedded-examples/stm32h7-nucleo-rtic/Cargo.toml b/embedded-examples/stm32h7-nucleo-rtic/Cargo.toml index 7235c67..7e0788b 100644 --- a/embedded-examples/stm32h7-nucleo-rtic/Cargo.toml +++ b/embedded-examples/stm32h7-nucleo-rtic/Cargo.toml @@ -14,41 +14,25 @@ name = "integration" harness = false [dependencies] +embedded-models = { path = "../models", features = ["defmt"] } + cortex-m = { version = "0.7", features = ["critical-section-single-core"] } +arbitrary-int = "2" cortex-m-rt = "0.7" defmt = "1" defmt-rtt = "1" -# defmt-brtt = { version = "0.1", default-features = false, features = ["rtt"] } panic-probe = { version = "1", features = ["print-defmt"] } -# cortex-m-semihosting = "0.5.0" -# TODO: Replace with embassy-hal. -# stm32h7xx-hal = { version="0.16", features= ["stm32h743v", "ethernet"] } +embedded-alloc = "0.7" +static_cell = "2" +rtic = { version = "2", features = ["thumbv7-backend"] } +spacepackets = { version = "0.17", default-features = false, features = ["defmt"] } +postcard = "1" + embassy-stm32 = { git = "https://github.com/embassy-rs/embassy.git", rev = "dd8e4c14e53f088bae27c5d841ab7a4fa338a52c", version = "0.6", features = ["stm32h743zi", "memory-x", "defmt", "time-driver-any"]} + embassy-time = { git = "https://github.com/embassy-rs/embassy.git", rev = "dd8e4c14e53f088bae27c5d841ab7a4fa338a52c", version = "0.5", features = ["defmt-timestamp-uptime-ms", "generic-queue-16"] } embassy-net = { git = "https://github.com/embassy-rs/embassy.git", rev = "dd8e4c14e53f088bae27c5d841ab7a4fa338a52c", version = "0.9", features = ["medium-ethernet", "proto-ipv4", "tcp", "udp", "auto-icmp-echo-reply", "dhcpv4", "defmt"] } embassy-sync = { git = "https://github.com/embassy-rs/embassy.git", rev = "dd8e4c14e53f088bae27c5d841ab7a4fa338a52c" } -embedded-alloc = "0.7" -static_cell = "2" -# rtic-sync = { version = "1", features = ["defmt-03"] } -rtic = { version = "2", features = ["thumbv7-backend"] } - -# [dependencies.smoltcp] -# version = "0.13" -# default-features = false -# features = ["medium-ethernet", "proto-ipv4", "socket-raw", "socket-dhcpv4", "socket-udp", "defmt"] - -# [dependencies.rtic] -# version = "2" -# features = ["thumbv7-backend"] - -# [dependencies.rtic-monotonics] -# version = "2" -# features = ["cortex-m-systick"] - -# [dependencies.satrs] -# path = "../../satrs" -# default-features = false -# features = ["defmt", "heapless"] [dev-dependencies] defmt-test = "0.5" diff --git a/embedded-examples/stm32h7-nucleo-rtic/src/main.rs b/embedded-examples/stm32h7-nucleo-rtic/src/main.rs index fb99c22..3c2fa73 100644 --- a/embedded-examples/stm32h7-nucleo-rtic/src/main.rs +++ b/embedded-examples/stm32h7-nucleo-rtic/src/main.rs @@ -28,6 +28,7 @@ const TM_QUEUE_DEPTH: usize = 32; mod app { use super::*; + use arbitrary_int::u14; use embassy_net::udp::UdpSocket; use embassy_net::StackResources; use embassy_stm32::eth; @@ -38,6 +39,14 @@ mod app { use embassy_time::Duration; use embassy_time::Timer; use embassy_time::WithTimeout as _; + use embedded_models::create_tm_packet; + use embedded_models::stm32h7; + use embedded_models::tm_size; + use embedded_models::TmHeader; + use spacepackets::CcsdsPacketCreationError; + use spacepackets::CcsdsPacketIdAndPsc; + use spacepackets::CcsdsPacketReader; + use spacepackets::SpHeader; use static_cell::StaticCell; bind_interrupts!(struct Irqs { @@ -90,6 +99,7 @@ mod app { #[shared] struct Shared { + sequence_count: u14, blink_freq: embassy_time::Duration, } @@ -191,6 +201,7 @@ mod app { ( Shared { blink_freq: Duration::from_millis(DEFAULT_BLINK_FREQ_MS as u64), + sequence_count: u14::new(0), }, Local { link_led, @@ -290,7 +301,9 @@ mod app { if let Some(endpoint) = remote_endpoint { while let Ok(packet) = cx.local.tm_rx.try_receive() { match udp.send_to(&packet, endpoint).await { - Ok(_) => defmt::debug!("UDP TX: {} bytes to: {}", packet.len(), endpoint), + Ok(_) => { + defmt::debug!("UDP TX: {} bytes to: {}", packet.len(), endpoint) + } Err(e) => defmt::warn!("udp send error: {}", e), } } @@ -299,11 +312,70 @@ mod app { } } - #[task(local = [tc_rx])] - async fn tc_handler(cx: tc_handler::Context) { + #[task(local = [tc_rx, tm_tx], shared=[sequence_count, blink_freq])] + async fn tc_handler(mut cx: tc_handler::Context) { loop { let tc = cx.local.tc_rx.receive().await; + + match CcsdsPacketReader::new_with_checksum(&tc) { + Ok(packet) => { + let packet_id = packet.packet_id(); + let psc = packet.psc(); + let tc_packet_id = CcsdsPacketIdAndPsc { packet_id, psc }; + if let Ok(request) = + postcard::from_bytes::(packet.packet_data()) + { + let response = match request { + stm32h7::Request::Ping => { + stm32h7::Response::Ok + } + stm32h7::Request::ChangeBlinkFrequency(duration) => { + cx.shared.blink_freq.lock(|current| { + *current = Duration::from_millis(duration.as_millis() as u64) + }); + stm32h7::Response::Ok + } + }; + let sequence_count = cx.shared.sequence_count.lock(|v| { + let current = *v; + *v = v.wrapping_add(u14::new(1)); + current + }); + + // Send Pong/OK response immediately. + if let Err(e) = + send_tm(tc_packet_id, response, sequence_count, cx.local.tm_tx).await + { + defmt::warn!("Failed to send TM response: {}", e); + } + } + } + Err(e) => defmt::warn!("Failed to parse received TC packet: {}", e,), + } defmt::info!("Received from UDP client: {}", tc.as_slice()); } } + + async fn send_tm( + tc_packet_id: CcsdsPacketIdAndPsc, + response: stm32h7::Response, + current_seq_count: u14, + sender: &embassy_sync::channel::Sender< + 'static, + NoopRawMutex, + alloc::vec::Vec, + TM_QUEUE_DEPTH, + >, + ) -> Result<(), CcsdsPacketCreationError> { + let sp_header = SpHeader::new_for_unseg_tc(stm32h7::PUS_APID, current_seq_count, 0); + let tm_header = TmHeader { + tc_packet_id: Some(tc_packet_id), + uptime_millis: embassy_time::Instant::now().as_millis(), + }; + let tm_size = tm_size(&tm_header, &response); + let mut packet = alloc::vec![0; tm_size]; + create_tm_packet(&mut packet, sp_header, tm_header, response)?; + sender.send(packet).await; + Ok(()) + } }