Rework library structure

Changed:

- Move most library components to new [`vorago-shared-periphs`](https://egit.irs.uni-stuttgart.de/rust/vorago-shared-periphs)
  which is mostly re-exported in this crate.
- Overhaul and simplification of several HAL APIs. The system configuration and IRQ router
  peripheral instance generally does not need to be passed to HAL API anymore.
- All HAL drivers are now type erased. The constructors will still expect and consume the PAC
  singleton component for resource management purposes, but are not cached anymore.
- Refactoring of GPIO library to be more inline with embassy GPIO API.

Added:

- I2C clock timeout feature support.
This commit is contained in:
2025-04-24 14:05:02 +02:00
parent d641f3943f
commit 935ee9dbb1
52 changed files with 602 additions and 9305 deletions

View File

@ -5,16 +5,10 @@ edition = "2021"
[dependencies]
cortex-m = "0.7"
cortex-m-rt = "0.7"
embedded-hal = "1"
embedded-hal-nb = "1"
embedded-io = "0.6"
defmt-rtt = "0.4"
defmt = "1"
panic-probe = { version = "1", features = ["defmt"] }
log = "0.4"
crc = "3"
rtic-sync = "1"
static_cell = "2"
satrs = { version = "0.3.0-alpha.0", default-features = false }
ringbuf = { version = "0.4", default-features = false }
@ -22,7 +16,7 @@ once_cell = { version = "1", default-features = false, features = ["critical-sec
spacepackets = { version = "0.13", default-features = false, features = ["defmt"] }
cobs = { version = "0.3", default-features = false }
va416xx-hal = { version = "0.5", features = ["va41630", "defmt"] }
va416xx-hal = { version = "0.5", features = ["va41630", "defmt"], path = "../va416xx-hal" }
rtic = { version = "2", features = ["thumbv7-backend"] }
rtic-monotonics = { version = "2", features = ["cortex-m-systick"] }

View File

@ -99,7 +99,7 @@ class ImageLoader:
)
self.verificator.add_tc(action_tc)
self.com_if.send(bytes(action_tc.pack()))
self.await_for_command_copletion("boot image selection command")
self.await_for_command_completion("boot image selection command")
def handle_ping_cmd(self):
_LOGGER.info("Sending ping command")
@ -112,7 +112,7 @@ class ImageLoader:
)
self.verificator.add_tc(ping_tc)
self.com_if.send(bytes(ping_tc.pack()))
self.await_for_command_copletion("ping command")
self.await_for_command_completion("ping command")
def handle_corruption_cmd(self, target: Target):
if target == Target.BOOTLOADER:
@ -134,11 +134,11 @@ class ImageLoader:
),
)
def await_for_command_copletion(self, context: str):
def await_for_command_completion(self, context: str):
done = False
now = time.time()
while time.time() - now < 2.0:
if not self.com_if.data_available():
if self.com_if.data_available() == 0:
time.sleep(0.2)
continue
for reply in self.com_if.receive():

View File

@ -32,6 +32,7 @@ const MAX_TM_FRAME_SIZE: usize = cobs::max_encoding_length(MAX_TM_SIZE);
const UART_BAUDRATE: u32 = 115200;
const BOOT_NVM_MEMORY_ID: u8 = 1;
const RX_DEBUGGING: bool = false;
const TX_DEBUGGING: bool = false;
pub enum ActionId {
CorruptImageA = 128,
@ -105,14 +106,14 @@ mod app {
use spacepackets::ecss::{
tc::PusTcReader, tm::PusTmCreator, EcssEnumU8, PusPacket, WritablePusPacket,
};
use va416xx_hal::clock::ClockConfigurator;
use va416xx_hal::irq_router::enable_and_init_irq_router;
use va416xx_hal::uart::IrqContextTimeoutOrMaxSize;
use va416xx_hal::{
clock::ClkgenExt,
edac,
gpio::PinsG,
nvm::Nvm,
pac,
pins::PinsG,
uart::{self, Uart},
};
@ -128,8 +129,8 @@ mod app {
#[local]
struct Local {
uart_rx: uart::RxWithInterrupt<pac::Uart0>,
uart_tx: uart::Tx<pac::Uart0>,
uart_rx: uart::RxWithInterrupt,
uart_tx: uart::Tx,
rx_context: IrqContextTimeoutOrMaxSize,
rom_spi: Option<pac::Spi3>,
// We handle all TM in one task.
@ -154,28 +155,24 @@ mod app {
defmt::println!("-- Vorago flashloader --");
// Initialize the systick interrupt & obtain the token to prove that we did
// Use the external clock connected to XTAL_N.
let clocks = cx
.device
.clkgen
.constrain()
let clocks = ClockConfigurator::new(cx.device.clkgen)
.xtal_n_clk_with_src_freq(Hertz::from_raw(EXTCLK_FREQ))
.freeze(&mut cx.device.sysconfig)
.freeze()
.unwrap();
enable_and_init_irq_router(&mut cx.device.sysconfig, &cx.device.irq_router);
enable_and_init_irq_router();
setup_edac(&mut cx.device.sysconfig);
let gpiog = PinsG::new(&mut cx.device.sysconfig, cx.device.portg);
let tx = gpiog.pg0.into_funsel_1();
let rx = gpiog.pg1.into_funsel_1();
let gpiog = PinsG::new(cx.device.portg);
let uart0 = Uart::new(
&mut cx.device.sysconfig,
cx.device.uart0,
(tx, rx),
Hertz::from_raw(UART_BAUDRATE),
gpiog.pg0,
gpiog.pg1,
&clocks,
);
Hertz::from_raw(UART_BAUDRATE).into(),
)
.unwrap();
let (tx, rx) = uart0.split();
let verif_reporter = VerificationReportCreator::new(0).unwrap();
@ -259,8 +256,8 @@ mod app {
{
Ok(result) => {
if RX_DEBUGGING {
log::debug!("RX Info: {:?}", cx.local.rx_context);
log::debug!("RX Result: {:?}", result);
defmt::info!("RX Info: {:?}", cx.local.rx_context);
defmt::info!("RX Result: {:?}", result);
}
if result.complete() {
// Check frame validity (must have COBS format) and decode the frame.
@ -331,7 +328,7 @@ mod app {
continue;
}
let packet_len = packet_len.unwrap();
log::info!(target: "TC Handler", "received packet with length {}", packet_len);
defmt::info!("received packet with length {}", packet_len);
assert_eq!(
cx.local
.tc_cons
@ -378,9 +375,7 @@ mod app {
let mut corrupt_image = |base_addr: u32| {
// Safety: We only use this for NVM handling and we only do NVM
// handling here.
let mut sys_cfg = unsafe { pac::Sysconfig::steal() };
let nvm = Nvm::new(
&mut sys_cfg,
cx.local.rom_spi.take().unwrap(),
CLOCKS.get().as_ref().unwrap(),
);
@ -388,7 +383,7 @@ mod app {
nvm.read_data(base_addr + 32, &mut buf);
buf[0] += 1;
nvm.write_data(base_addr + 32, &buf);
*cx.local.rom_spi = Some(nvm.release(&mut sys_cfg));
*cx.local.rom_spi = Some(nvm.release());
let tm = cx
.local
.verif_reporter
@ -406,7 +401,7 @@ mod app {
}
}
if pus_tc.service() == PusServiceId::Test as u8 && pus_tc.subservice() == 1 {
log::info!(target: "TC Handler", "received ping TC");
defmt::info!("received ping TC");
let tm = cx
.local
.verif_reporter
@ -453,31 +448,22 @@ mod app {
return;
}
let data = &app_data[10..10 + data_len as usize];
log::info!(
target: "TC Handler",
"writing {} bytes at offset {} to NVM",
data_len,
offset
);
defmt::info!("writing {} bytes at offset {} to NVM", data_len, offset);
// Safety: We only use this for NVM handling and we only do NVM
// handling here.
let mut sys_cfg = unsafe { pac::Sysconfig::steal() };
let nvm = Nvm::new(
&mut sys_cfg,
cx.local.rom_spi.take().unwrap(),
CLOCKS.get().as_ref().unwrap(),
);
nvm.write_data(offset, data);
*cx.local.rom_spi = Some(nvm.release(&mut sys_cfg));
*cx.local.rom_spi = Some(nvm.release());
let tm = cx
.local
.verif_reporter
.completion_success(cx.local.src_data_buf, started_token, 0, 0, &[])
.expect("completion success failed");
write_and_send(&tm);
log::info!(
target: "TC Handler",
"NVM operation done");
defmt::info!("NVM operation done");
}
}
}
@ -506,9 +492,12 @@ mod app {
&mut cx.local.encoded_buf[1..],
);
cx.local.encoded_buf[send_size + 1] = 0;
if TX_DEBUGGING {
defmt::debug!("UART TX: Sending data with size {}", send_size + 2);
}
cx.local
.uart_tx
.write(&cx.local.encoded_buf[0..send_size + 2])
.write_all(&cx.local.encoded_buf[0..send_size + 2])
.unwrap();
Mono::delay(2.millis()).await;
}