tough, but we made it work..
All checks were successful
Rust/sat-rs/pipeline/head This commit looks good

This commit is contained in:
Robin Müller 2024-03-23 17:45:07 +01:00
parent 52a649d687
commit 5dbdda46aa
Signed by: muellerr
GPG Key ID: A649FB78196E3849
3 changed files with 274 additions and 224 deletions

View File

@ -60,7 +60,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40ac3d0c0a542d0ab5521211f873f62706a7136df415676f676d347e5a41dd80" checksum = "40ac3d0c0a542d0ab5521211f873f62706a7136df415676f676d347e5a41dd80"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"embedded-hal", "embedded-hal 0.2.7",
"nb 1.1.0", "nb 1.1.0",
"vcell", "vcell",
] ]
@ -114,7 +114,8 @@ checksum = "8ec610d8f49840a5b376c69663b6369e71f4b34484b9b2eb29fb918d92516cb9"
dependencies = [ dependencies = [
"bare-metal 0.2.5", "bare-metal 0.2.5",
"bitfield", "bitfield",
"embedded-hal", "critical-section",
"embedded-hal 0.2.7",
"volatile-register", "volatile-register",
] ]
@ -138,34 +139,6 @@ dependencies = [
"syn 1.0.109", "syn 1.0.109",
] ]
[[package]]
name = "cortex-m-rtic"
version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d696ae7390bdb9f7978f71ca7144256a2c4616240a6df9002da3c451f9fc8f02"
dependencies = [
"bare-metal 1.0.0",
"cortex-m",
"cortex-m-rtic-macros",
"heapless 0.7.17",
"rtic-core",
"rtic-monotonic",
"version_check",
]
[[package]]
name = "cortex-m-rtic-macros"
version = "1.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eefb40b1ca901c759d29526e5c8a0a1b246c20caaa5b4cc5d0f0b94debecd4c7"
dependencies = [
"proc-macro-error",
"proc-macro2",
"quote",
"rtic-syntax",
"syn 1.0.109",
]
[[package]] [[package]]
name = "crc" name = "crc"
version = "3.0.1" version = "3.0.1"
@ -251,6 +224,12 @@ dependencies = [
"void", "void",
] ]
[[package]]
name = "embedded-hal"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89"
[[package]] [[package]]
name = "embedded-time" name = "embedded-time"
version = "0.12.1" version = "0.12.1"
@ -281,6 +260,12 @@ dependencies = [
"syn 2.0.53", "syn 2.0.53",
] ]
[[package]]
name = "equivalent"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]] [[package]]
name = "fnv" name = "fnv"
version = "1.0.7" version = "1.0.7"
@ -296,6 +281,30 @@ dependencies = [
"gcd", "gcd",
] ]
[[package]]
name = "futures-core"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
[[package]]
name = "futures-task"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
[[package]]
name = "futures-util"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
dependencies = [
"futures-core",
"futures-task",
"pin-project-lite",
"pin-utils",
]
[[package]] [[package]]
name = "gcd" name = "gcd"
version = "2.3.0" version = "2.3.0"
@ -321,15 +330,6 @@ dependencies = [
"version_check", "version_check",
] ]
[[package]]
name = "hash32"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67"
dependencies = [
"byteorder",
]
[[package]] [[package]]
name = "hash32" name = "hash32"
version = "0.3.1" version = "0.3.1"
@ -341,22 +341,9 @@ dependencies = [
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.12.3" version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
[[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.0",
"spin",
"stable_deref_trait",
]
[[package]] [[package]]
name = "heapless" name = "heapless"
@ -364,7 +351,7 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad"
dependencies = [ dependencies = [
"hash32 0.3.1", "hash32",
"stable_deref_trait", "stable_deref_trait",
] ]
@ -376,11 +363,11 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "1.9.3" version = "2.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
dependencies = [ dependencies = [
"autocfg", "equivalent",
"hashbrown", "hashbrown",
] ]
@ -393,16 +380,6 @@ dependencies = [
"log", "log",
] ]
[[package]]
name = "lock_api"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45"
dependencies = [
"autocfg",
"scopeguard",
]
[[package]] [[package]]
name = "log" name = "log"
version = "0.4.21" version = "0.4.21"
@ -416,7 +393,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e5d1a5c290951321d1b0d4a40edd828537de9889134a0e67c5146542ae57706" checksum = "9e5d1a5c290951321d1b0d4a40edd828537de9889134a0e67c5146542ae57706"
dependencies = [ dependencies = [
"cast", "cast",
"embedded-hal", "embedded-hal 0.2.7",
"generic-array 0.11.2", "generic-array 0.11.2",
] ]
@ -541,6 +518,18 @@ version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
[[package]]
name = "pin-project-lite"
version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58"
[[package]]
name = "pin-utils"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]] [[package]]
name = "proc-macro-error" name = "proc-macro-error"
version = "1.0.4" version = "1.0.4"
@ -592,6 +581,29 @@ dependencies = [
"chrono", "chrono",
] ]
[[package]]
name = "rtic"
version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c443db16326376bdd64377da268f6616d5f804aba8ce799bac7d1f7f244e9d51"
dependencies = [
"atomic-polyfill",
"bare-metal 1.0.0",
"cortex-m",
"critical-section",
"rtic-core",
"rtic-macros",
]
[[package]]
name = "rtic-common"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0786b50b81ef9d2a944a000f60405bb28bf30cd45da2d182f3fe636b2321f35c"
dependencies = [
"critical-section",
]
[[package]] [[package]]
name = "rtic-core" name = "rtic-core"
version = "1.0.0" version = "1.0.0"
@ -599,21 +611,41 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9369355b04d06a3780ec0f51ea2d225624db777acbc60abd8ca4832da5c1a42" checksum = "d9369355b04d06a3780ec0f51ea2d225624db777acbc60abd8ca4832da5c1a42"
[[package]] [[package]]
name = "rtic-monotonic" name = "rtic-macros"
version = "1.0.0" version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb8b0b822d1a366470b9cea83a1d4e788392db763539dc4ba022bcc787fece82" checksum = "54053598ea24b1b74937724e366558412a1777eb2680b91ef646db540982789a"
[[package]]
name = "rtic-syntax"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f5e215601dc467752c2bddc6284a622c6f3d2bab569d992adcd5ab7e4cb9478"
dependencies = [ dependencies = [
"indexmap", "indexmap",
"proc-macro-error",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 1.0.109", "syn 2.0.53",
]
[[package]]
name = "rtic-monotonics"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "058c2397dbd5bb4c5650a0e368c3920953e458805ff5097a0511b8147b3619d7"
dependencies = [
"atomic-polyfill",
"cfg-if",
"cortex-m",
"embedded-hal 1.0.0",
"fugit",
"rtic-time",
]
[[package]]
name = "rtic-time"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75b232e7aebc045cfea81cdd164bc2727a10aca9a4568d406d0a5661cdfd0f19"
dependencies = [
"critical-section",
"futures-util",
"rtic-common",
] ]
[[package]] [[package]]
@ -658,16 +690,16 @@ dependencies = [
"cobs 0.2.3 (git+https://github.com/robamu/cobs.rs.git?branch=all_features)", "cobs 0.2.3 (git+https://github.com/robamu/cobs.rs.git?branch=all_features)",
"cortex-m", "cortex-m",
"cortex-m-rt", "cortex-m-rt",
"cortex-m-rtic", "embedded-hal 0.2.7",
"embedded-hal",
"enumset", "enumset",
"heapless 0.8.0", "heapless",
"itm_logger", "itm_logger",
"panic-itm", "panic-itm",
"rtic",
"rtic-monotonics",
"satrs", "satrs",
"stm32f3-discovery", "stm32f3-discovery",
"stm32f3xx-hal", "stm32f3xx-hal",
"systick-monotonic",
] ]
[[package]] [[package]]
@ -679,12 +711,6 @@ dependencies = [
"spacepackets", "spacepackets",
] ]
[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]] [[package]]
name = "semver" name = "semver"
version = "0.9.0" version = "0.9.0"
@ -732,15 +758,6 @@ dependencies = [
"zerocopy", "zerocopy",
] ]
[[package]]
name = "spin"
version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
dependencies = [
"lock_api",
]
[[package]] [[package]]
name = "stable_deref_trait" name = "stable_deref_trait"
version = "1.2.0" version = "1.2.0"
@ -786,7 +803,7 @@ dependencies = [
[[package]] [[package]]
name = "stm32f3xx-hal" name = "stm32f3xx-hal"
version = "0.11.0-alpha.0" version = "0.11.0-alpha.0"
source = "git+https://github.com/robamu/stm32f3xx-hal?branch=complete-dma-update#f3c3b81b91ecd9498eb133f2cda0b061ce9c9d98" source = "git+https://github.com/robamu/stm32f3xx-hal?branch=complete-dma-update#04fc76b7912649c84b57bd0ab803ea3ccf2aadae"
dependencies = [ dependencies = [
"bxcan", "bxcan",
"cfg-if", "cfg-if",
@ -794,7 +811,7 @@ dependencies = [
"cortex-m-rt", "cortex-m-rt",
"critical-section", "critical-section",
"embedded-dma", "embedded-dma",
"embedded-hal", "embedded-hal 0.2.7",
"embedded-time", "embedded-time",
"enumset", "enumset",
"nb 1.1.0", "nb 1.1.0",
@ -813,7 +830,7 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90a4adc8cbd1726249b161898e48e0f3f1ce74d34dc784cbbc98fba4ed283fbf" checksum = "90a4adc8cbd1726249b161898e48e0f3f1ce74d34dc784cbbc98fba4ed283fbf"
dependencies = [ dependencies = [
"embedded-hal", "embedded-hal 0.2.7",
] ]
[[package]] [[package]]
@ -838,17 +855,6 @@ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]]
name = "systick-monotonic"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67fb822d5c615a0ae3a4795ee5b1d06381c7faf488d861c0a4fa8e6a88d5ff84"
dependencies = [
"cortex-m",
"fugit",
"rtic-monotonic",
]
[[package]] [[package]]
name = "typenum" name = "typenum"
version = "1.17.0" version = "1.17.0"

View File

@ -6,13 +6,19 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
cortex-m = "0.7" cortex-m = { version = "0.7", features = ["critical-section-single-core"] }
cortex-m-rt = "0.7" cortex-m-rt = "0.7"
embedded-hal = "0.2.6" embedded-hal = "0.2.7"
cortex-m-rtic = "1.0" enumset = "1"
enumset = "1.0"
heapless = "0.8" heapless = "0.8"
systick-monotonic = "1.0"
[dependencies.rtic]
version = "2"
features = ["thumbv7-backend"]
[dependencies.rtic-monotonics]
version = "1"
features = ["cortex-m-systick"]
[dependencies.cobs] [dependencies.cobs]
git = "https://github.com/robamu/cobs.rs.git" git = "https://github.com/robamu/cobs.rs.git"

View File

@ -7,6 +7,8 @@ use rtic::app;
use heapless::{mpmc::Q8, Vec}; use heapless::{mpmc::Q8, Vec};
#[allow(unused_imports)] #[allow(unused_imports)]
use itm_logger::{debug, info, logger_init, warn}; use itm_logger::{debug, info, logger_init, warn};
use rtic_monotonics::systick::fugit::TimerInstantU32;
use rtic_monotonics::systick::ExtU32;
use satrs::seq_count::SequenceCountProviderCore; use satrs::seq_count::SequenceCountProviderCore;
use satrs::{ use satrs::{
pool::StoreError, pool::StoreError,
@ -17,19 +19,18 @@ use stm32f3xx_hal::dma::dma1;
use stm32f3xx_hal::gpio::{PushPull, AF7, PA2, PA3}; use stm32f3xx_hal::gpio::{PushPull, AF7, PA2, PA3};
use stm32f3xx_hal::pac::USART2; use stm32f3xx_hal::pac::USART2;
use stm32f3xx_hal::serial::{Rx, RxEvent, Serial, SerialDmaRx, SerialDmaTx, Tx, TxEvent}; use stm32f3xx_hal::serial::{Rx, RxEvent, Serial, SerialDmaRx, SerialDmaTx, Tx, TxEvent};
use systick_monotonic::{fugit::Duration, Systick};
const UART_BAUD: u32 = 115200; const UART_BAUD: u32 = 115200;
const BLINK_FREQ_MS: u64 = 1000; const BLINK_FREQ_MS: u32 = 1000;
const TX_HANDLER_FREQ_MS: u64 = 20; const TX_HANDLER_FREQ_MS: u32 = 20;
const MIN_DELAY_BETWEEN_TX_PACKETS_MS: u16 = 5; const MIN_DELAY_BETWEEN_TX_PACKETS_MS: u32 = 5;
const MAX_TC_LEN: usize = 128; const MAX_TC_LEN: usize = 128;
const MAX_TM_LEN: usize = 128; const MAX_TM_LEN: usize = 128;
pub const PUS_APID: u16 = 0x02; pub const PUS_APID: u16 = 0x02;
type TxType = Tx<USART2, PA2<AF7<PushPull>>>; type TxType = Tx<USART2, PA2<AF7<PushPull>>>;
type RxType = Rx<USART2, PA3<AF7<PushPull>>>; type RxType = Rx<USART2, PA3<AF7<PushPull>>>;
type MsDuration = Duration<u64, 1, 1000>; type InstantFugit = TimerInstantU32<1000>;
type TxDmaTransferType = SerialDmaTx<&'static [u8], dma1::C7, TxType>; type TxDmaTransferType = SerialDmaTx<&'static [u8], dma1::C7, TxType>;
type RxDmaTransferType = SerialDmaRx<&'static mut [u8], dma1::C6, RxType>; type RxDmaTransferType = SerialDmaRx<&'static mut [u8], dma1::C6, RxType>;
@ -53,9 +54,6 @@ type TcPacket = Vec<u8, MAX_TC_LEN>;
static TM_REQUESTS: Q8<TmPacket> = Q8::new(); static TM_REQUESTS: Q8<TmPacket> = Q8::new();
const TC_POOL_SLOTS: usize = 8;
const TM_POOL_SLOTS: usize = 8;
use core::cell::RefCell; use core::cell::RefCell;
use core::sync::atomic::{AtomicU16, Ordering}; use core::sync::atomic::{AtomicU16, Ordering};
@ -151,11 +149,18 @@ pub enum UartTxState {
Transmitting(Option<TxDmaTransferType>), Transmitting(Option<TxDmaTransferType>),
} }
#[app(device = stm32f3xx_hal::pac, peripherals = true, dispatchers = [TIM20_BRK, TIM20_UP, TIM20_TRG_COM])] pub struct UartTxShared {
last_completed: Option<InstantFugit>,
state: UartTxState,
}
#[app(device = stm32f3xx_hal::pac, peripherals = true)]
mod app { mod app {
use super::*; use super::*;
use core::slice::Iter; use core::slice::Iter;
use cortex_m::iprintln; use cortex_m::iprintln;
use rtic_monotonics::systick::Systick;
use rtic_monotonics::Monotonic;
use satrs::pus::verification::FailParams; use satrs::pus::verification::FailParams;
use satrs::pus::verification::VerificationReporterCore; use satrs::pus::verification::VerificationReporterCore;
use satrs::spacepackets::{ use satrs::spacepackets::{
@ -166,15 +171,15 @@ mod app {
use stm32f3_discovery::leds::Direction; use stm32f3_discovery::leds::Direction;
use stm32f3_discovery::leds::Leds; use stm32f3_discovery::leds::Leds;
use stm32f3xx_hal::prelude::*; use stm32f3xx_hal::prelude::*;
use stm32f3xx_hal::Switch;
use stm32f3_discovery::switch_hal::OutputSwitch; use stm32f3_discovery::switch_hal::OutputSwitch;
use stm32f3xx_hal::Switch;
#[allow(dead_code)] #[allow(dead_code)]
type SerialType = Serial<USART2, (PA2<AF7<PushPull>>, PA3<AF7<PushPull>>)>; type SerialType = Serial<USART2, (PA2<AF7<PushPull>>, PA3<AF7<PushPull>>)>;
#[shared] #[shared]
struct Shared { struct Shared {
tx_transfer: UartTxState, tx_shared: UartTxShared,
rx_transfer: Option<RxDmaTransferType>, rx_transfer: Option<RxDmaTransferType>,
} }
@ -186,17 +191,14 @@ mod app {
curr_dir: Iter<'static, Direction>, curr_dir: Iter<'static, Direction>,
} }
#[monotonic(binds = SysTick, default = true)] #[init]
type MonoTimer = Systick<1000>; fn init(mut cx: init::Context) -> (Shared, Local) {
#[init(local = [
tc_pool_mem: [u8; TC_BUF_LEN * TC_POOL_SLOTS] = [0; TC_BUF_LEN * TC_POOL_SLOTS],
tm_pool_mem: [u8; MAX_TM_LEN * TM_POOL_SLOTS] = [0; MAX_TM_LEN * TM_POOL_SLOTS]
])]
fn init(mut cx: init::Context) -> (Shared, Local, init::Monotonics) {
let mut rcc = cx.device.RCC.constrain(); let mut rcc = cx.device.RCC.constrain();
let mono = Systick::new(cx.core.SYST, 8_000_000); // Initialize the systick interrupt & obtain the token to prove that we did
let systick_mono_token = rtic_monotonics::create_systick_token!();
Systick::start(cx.core.SYST, 8_000_000, systick_mono_token);
logger_init(); logger_init();
let mut flash = cx.device.FLASH.constrain(); let mut flash = cx.device.FLASH.constrain();
let clocks = rcc let clocks = rcc
@ -205,6 +207,10 @@ mod app {
.sysclk(8.MHz()) .sysclk(8.MHz())
.pclk1(8.MHz()) .pclk1(8.MHz())
.freeze(&mut flash.acr); .freeze(&mut flash.acr);
// Set up monotonic timer.
//let mono_timer = MonoTimer::new(cx.core.DWT, clocks, &mut cx.core.DCB);
// setup ITM output // setup ITM output
iprintln!( iprintln!(
&mut cx.core.ITM.stim[0], &mut cx.core.ITM.stim[0],
@ -251,63 +257,96 @@ mod app {
usart2.configure_tx_interrupt(TxEvent::TransmissionComplete, Switch::On); usart2.configure_tx_interrupt(TxEvent::TransmissionComplete, Switch::On);
let dma1 = cx.device.DMA1.split(&mut rcc.ahb); let dma1 = cx.device.DMA1.split(&mut rcc.ahb);
let (tx_serial, mut rx_serial) = usart2.split(); let (mut tx_serial, mut rx_serial) = usart2.split();
// This interrupt is immediately triggered, clear it. It will only be reset // This interrupt is immediately triggered, clear it. It will only be reset
// by the hardware when data is received on RX (RXNE event) // by the hardware when data is received on RX (RXNE event)
rx_serial.clear_event(RxEvent::Idle); rx_serial.clear_event(RxEvent::Idle);
// For some reason, this is also immediately triggered..
tx_serial.clear_event(TxEvent::TransmissionComplete);
let rx_transfer = rx_serial.read_exact(unsafe { DMA_RX_BUF.as_mut_slice() }, dma1.ch6); let rx_transfer = rx_serial.read_exact(unsafe { DMA_RX_BUF.as_mut_slice() }, dma1.ch6);
info!(target: "init", "Spawning tasks"); info!(target: "init", "Spawning tasks");
blink::spawn().unwrap(); blink::spawn().unwrap();
serial_tx_handler::spawn().unwrap(); serial_tx_handler::spawn().unwrap();
( (
Shared { Shared {
tx_transfer: UartTxState::Idle(Some(TxIdle { tx_shared: UartTxShared {
last_completed: None,
state: UartTxState::Idle(Some(TxIdle {
tx: tx_serial, tx: tx_serial,
dma_channel: dma1.ch7, dma_channel: dma1.ch7,
})), })),
},
rx_transfer: Some(rx_transfer), rx_transfer: Some(rx_transfer),
}, },
Local { Local {
//timer: mono_timer,
leds, leds,
last_dir: Direction::North, last_dir: Direction::North,
curr_dir: Direction::iter(), curr_dir: Direction::iter(),
verif_reporter, verif_reporter,
}, },
init::Monotonics(mono),
) )
} }
#[task(local = [leds, curr_dir, last_dir])] #[task(local = [leds, curr_dir, last_dir])]
fn blink(cx: blink::Context) { async fn blink(cx: blink::Context) {
let toggle_leds = |dir: &Direction| { let blink::LocalResources {
let leds = cx.local.leds; leds,
let last_led = leds.for_direction(*cx.local.last_dir); curr_dir,
last_dir,
..
} = cx.local;
let mut toggle_leds = |dir: &Direction| {
let last_led = leds.for_direction(*last_dir);
last_led.off().ok(); last_led.off().ok();
let led = leds.for_direction(*dir); let led = leds.for_direction(*dir);
led.on().ok(); led.on().ok();
*cx.local.last_dir = *dir; *last_dir = *dir;
}; };
loop {
match cx.local.curr_dir.next() { match curr_dir.next() {
Some(dir) => { Some(dir) => {
toggle_leds(dir); toggle_leds(dir);
} }
None => { None => {
*cx.local.curr_dir = Direction::iter(); *curr_dir = Direction::iter();
toggle_leds(cx.local.curr_dir.next().unwrap()); toggle_leds(curr_dir.next().unwrap());
} }
} }
blink::spawn_after(MsDuration::from_ticks(BLINK_FREQ_MS)).unwrap(); Systick::delay(BLINK_FREQ_MS.millis()).await;
}
} }
#[task( #[task(
shared = [tx_transfer], shared = [tx_shared],
local = []
)] )]
fn serial_tx_handler(mut cx: serial_tx_handler::Context) { async fn serial_tx_handler(mut cx: serial_tx_handler::Context) {
loop {
let is_idle = cx.shared.tx_shared.lock(|tx_shared| {
if let UartTxState::Idle(_) = tx_shared.state {
return true;
}
false
});
if is_idle {
let last_completed = cx.shared.tx_shared.lock(|shared| shared.last_completed);
if let Some(last_completed) = last_completed {
let elapsed_ms = (Systick::now() - last_completed).to_millis();
if elapsed_ms < MIN_DELAY_BETWEEN_TX_PACKETS_MS {
Systick::delay((MIN_DELAY_BETWEEN_TX_PACKETS_MS - elapsed_ms).millis())
.await;
}
}
} else {
// Check for completion after 1 ms
Systick::delay(1.millis()).await;
continue;
}
if let Some(vec) = TM_REQUESTS.dequeue() { if let Some(vec) = TM_REQUESTS.dequeue() {
cx.shared.tx_transfer.lock(|tx_state| match tx_state { cx.shared
.tx_shared
.lock(|tx_shared| match &mut tx_shared.state {
UartTxState::Idle(tx) => { UartTxState::Idle(tx) => {
let encoded_len; let encoded_len;
//debug!(target: "serial_tx_handler", "bytes: {:x?}", &buf[0..len]); //debug!(target: "serial_tx_handler", "bytes: {:x?}", &buf[0..len]);
@ -316,7 +355,8 @@ mod app {
unsafe { unsafe {
// 0 sentinel value as start marker // 0 sentinel value as start marker
DMA_TX_BUF[0] = 0; DMA_TX_BUF[0] = 0;
encoded_len = cobs::encode(&vec[0..vec.len()], &mut DMA_TX_BUF[1..]); encoded_len =
cobs::encode(&vec[0..vec.len()], &mut DMA_TX_BUF[1..]);
// Should never panic, we accounted for the overhead. // Should never panic, we accounted for the overhead.
// Write into transfer buffer directly, no need for intermediate // Write into transfer buffer directly, no need for intermediate
// encoding buffer. // encoding buffer.
@ -333,23 +373,17 @@ mod app {
unsafe { &DMA_TX_BUF[0..encoded_len + 2] }, unsafe { &DMA_TX_BUF[0..encoded_len + 2] },
tx_idle.dma_channel, tx_idle.dma_channel,
); );
*tx_state = UartTxState::Transmitting(Some(transfer)); tx_shared.state = UartTxState::Transmitting(Some(transfer));
// The memory block is automatically returned to the pool when it is dropped. // The memory block is automatically returned to the pool when it is dropped.
} }
UartTxState::Transmitting(_) => { UartTxState::Transmitting(_) => (),
// This is a SW configuration error. Only the ISR which
// detects transfer completion should be able to spawn a new
// task, and that ISR should set the state to IDLE.
panic!("invalid internal tx state detected")
}
})
} else {
cx.shared.tx_transfer.lock(|tx_state| {
if let UartTxState::Idle(_) = tx_state {
serial_tx_handler::spawn_after(MsDuration::from_ticks(TX_HANDLER_FREQ_MS))
.unwrap();
}
}); });
// Check for completion after 1 ms
Systick::delay(1.millis()).await;
continue;
}
// Nothing to do, and we are idle.
Systick::delay(TX_HANDLER_FREQ_MS.millis()).await;
} }
} }
@ -361,7 +395,11 @@ mod app {
verif_reporter verif_reporter
], ],
)] )]
fn serial_rx_handler(cx: serial_rx_handler::Context, received_packet: Vec<u8, MAX_TC_LEN>) { async fn serial_rx_handler(
cx: serial_rx_handler::Context,
received_packet: Vec<u8, MAX_TC_LEN>,
) {
info!("running rx handler");
let tgt: &'static str = "serial_rx_handler"; let tgt: &'static str = "serial_rx_handler";
cx.local.stamp_buf[0] = P_FIELD_BASE; cx.local.stamp_buf[0] = P_FIELD_BASE;
info!(target: tgt, "Received packet with {} bytes", received_packet.len()); info!(target: tgt, "Received packet with {} bytes", received_packet.len());
@ -438,7 +476,6 @@ mod app {
FailParams::new(stamp_buf, &EcssEnumU16::new(0), &[]), FailParams::new(stamp_buf, &EcssEnumU16::new(0), &[]),
) )
.unwrap(); .unwrap();
// let mem_block = poolmod::TM::alloc().unwrap().init([0u8; MAX_TM_LEN]);
let sender = TmSender::new(TmPacket::new(), tgt); let sender = TmSender::new(TmPacket::new(), tgt);
if let Err(e) = verif_reporter.send_acceptance_failure(sendable, &sender) { if let Err(e) = verif_reporter.send_acceptance_failure(sendable, &sender) {
warn!(target: tgt, "Sending acceptance failure failed: {:?}", e.0); warn!(target: tgt, "Sending acceptance failure failed: {:?}", e.0);
@ -449,7 +486,6 @@ mod app {
.acceptance_success(src_data_buf, token, SEQ_COUNT_PROVIDER.get(), 0, stamp_buf) .acceptance_success(src_data_buf, token, SEQ_COUNT_PROVIDER.get(), 0, stamp_buf)
.unwrap(); .unwrap();
// let mem_block = poolmod::TM::alloc().unwrap().init([0u8; MAX_TM_LEN]);
let sender = TmSender::new(TmPacket::new(), tgt); let sender = TmSender::new(TmPacket::new(), tgt);
let accepted_token = match verif_reporter.send_acceptance_success(sendable, &sender) { let accepted_token = match verif_reporter.send_acceptance_success(sendable, &sender) {
Ok(token) => token, Ok(token) => token,
@ -518,6 +554,7 @@ mod app {
#[task(binds = DMA1_CH6, shared = [rx_transfer])] #[task(binds = DMA1_CH6, shared = [rx_transfer])]
fn rx_dma_isr(mut cx: rx_dma_isr::Context) { fn rx_dma_isr(mut cx: rx_dma_isr::Context) {
let mut tc_packet = TcPacket::new();
cx.shared.rx_transfer.lock(|rx_transfer| { cx.shared.rx_transfer.lock(|rx_transfer| {
let rx_ref = rx_transfer.as_ref().unwrap(); let rx_ref = rx_transfer.as_ref().unwrap();
if rx_ref.is_complete() { if rx_ref.is_complete() {
@ -526,7 +563,6 @@ mod app {
// The received data is transferred to another task now to avoid any processing overhead // The received data is transferred to another task now to avoid any processing overhead
// during the interrupt. There are multiple ways to do this, we use a stack allocaed vector here // during the interrupt. There are multiple ways to do this, we use a stack allocaed vector here
// to do this. // to do this.
let mut tc_packet = TcPacket::new();
tc_packet.resize(buf.len(), 0).expect("vec resize failed"); tc_packet.resize(buf.len(), 0).expect("vec resize failed");
tc_packet.copy_from_slice(buf); tc_packet.copy_from_slice(buf);
@ -545,23 +581,26 @@ mod app {
}); });
} }
#[task(binds = USART2_EXTI26, shared = [rx_transfer, tx_transfer])] #[task(binds = USART2_EXTI26, shared = [rx_transfer, tx_shared])]
fn serial_isr(mut cx: serial_isr::Context) { fn serial_isr(mut cx: serial_isr::Context) {
cx.shared.tx_transfer.lock(|tx_state| match tx_state { cx.shared
.tx_shared
.lock(|tx_shared| match &mut tx_shared.state {
UartTxState::Idle(_) => (), UartTxState::Idle(_) => (),
UartTxState::Transmitting(transfer) => { UartTxState::Transmitting(transfer) => {
let transfer_ref = transfer.as_ref().unwrap(); let transfer_ref = transfer.as_ref().unwrap();
if transfer_ref.is_complete() { if transfer_ref.is_complete() {
let transfer = transfer.take().unwrap(); let transfer = transfer.take().unwrap();
let (_, dma_channel, tx) = transfer.stop(); let (_, dma_channel, mut tx) = transfer.stop();
*tx_state = UartTxState::Idle(Some(TxIdle { tx, dma_channel })); tx.clear_event(TxEvent::TransmissionComplete);
serial_tx_handler::spawn_after(MsDuration::from_ticks( tx_shared.state = UartTxState::Idle(Some(TxIdle { tx, dma_channel }));
MIN_DELAY_BETWEEN_TX_PACKETS_MS.into(), // We cache the last completed time to ensure that there is a minimum delay between consecutive
)) // transferred packets.
.unwrap(); tx_shared.last_completed = Some(Systick::now());
} }
} }
}); });
let mut tc_packet = TcPacket::new();
cx.shared.rx_transfer.lock(|rx_transfer| { cx.shared.rx_transfer.lock(|rx_transfer| {
let rx_transfer_ref = rx_transfer.as_ref().unwrap(); let rx_transfer_ref = rx_transfer.as_ref().unwrap();
// Received a partial packet. // Received a partial packet.
@ -571,14 +610,13 @@ mod app {
// The received data is transferred to another task now to avoid any processing overhead // The received data is transferred to another task now to avoid any processing overhead
// during the interrupt. There are multiple ways to do this, we use a stack // during the interrupt. There are multiple ways to do this, we use a stack
// allocated vector to do this. // allocated vector to do this.
let mut tc_packet = TcPacket::new();
tc_packet tc_packet
.resize(rx_len as usize, 0) .resize(rx_len as usize, 0)
.expect("vec resize failed"); .expect("vec resize failed");
tc_packet[0..rx_len as usize].copy_from_slice(&buf[0..rx_len as usize]); tc_packet[0..rx_len as usize].copy_from_slice(&buf[0..rx_len as usize]);
rx.clear_event(RxEvent::Idle); rx.clear_event(RxEvent::Idle);
// Only send owning pointer to pool memory and the received packet length. info!("spawning rx task");
serial_rx_handler::spawn(tc_packet).expect("spawning rx handler task failed"); serial_rx_handler::spawn(tc_packet).expect("spawning rx handler failed");
*rx_transfer = Some(rx.read_exact(buf, ch)); *rx_transfer = Some(rx.read_exact(buf, ch));
} }
}); });