feat(firmware): validate configuration and migrate sensor-driven flight APIs

Validate configuration through its owning schemas and keep board
declarations separate from shared F722 resource ownership. Bound USB
transitions, isolate transport failures and retain restart-only activation.

Migrate navigation and flight consumers with the sensor and schema
contracts. Require explicit installation data and synchronous output
authority; board motor outputs remain inhibited.

Validation: assembled-prefix host tests, strict Clippy, platform/USB tests
and both ARM release builds. Final-source coverage and scoped Miri/Kani
evidence are retained separately from hardware qualification.
This commit is contained in:
Onur Özkan committed 2026-11-07 18:12:11 +03:00
1 parent fb1b8af2d1
commit f9a61a086f
211 files changed
+45657 -12740

No files matched your search

+92
View File
@@ -0,0 +1,92 @@
//! Target-specific definitions
use vcell::VolatileCell;
use crate::ral::register::RWRegister;
use crate::ral::{
endpoint0_out, endpoint_in, endpoint_out, otg_device, otg_global, otg_global_dieptxfx,
otg_pwrclk,
};
use crate::UsbPeripheral;
pub fn fifo_write(usb: UsbRegisters, channel: impl Into<usize>, mut buf: &[u8]) {
let fifo = usb.fifo(channel.into());
while buf.len() >= 4 {
let mut u32_bytes = [0u8; 4];
u32_bytes.copy_from_slice(&buf[..4]);
buf = &buf[4..];
fifo.write(u32::from_ne_bytes(u32_bytes));
}
if !buf.is_empty() {
let mut u32_bytes = [0u8; 4];
u32_bytes[..buf.len()].copy_from_slice(buf);
fifo.write(u32::from_ne_bytes(u32_bytes));
}
}
pub fn fifo_read_into(usb: UsbRegisters, buf: &[VolatileCell<u32>]) {
let fifo = usb.fifo(0);
for p in buf {
let word = fifo.read();
p.set(word);
}
}
/// Wrapper around device-specific peripheral that provides unified register interface
#[derive(Copy, Clone)]
pub struct UsbRegisters(usize);
impl UsbRegisters {
#[inline(always)]
pub fn new<USB: UsbPeripheral>() -> Self {
Self(USB::REGISTERS as usize)
}
#[inline(always)]
pub fn global(&self) -> &'static otg_global::RegisterBlock {
unsafe { &*(self.0 as *const _) }
}
#[inline(always)]
pub fn device(&self) -> &'static otg_device::RegisterBlock {
unsafe { &*((self.0 + 0x800) as *const _) }
}
#[inline(always)]
pub fn pwrclk(&self) -> &'static otg_pwrclk::RegisterBlock {
unsafe { &*((self.0 + 0xe00) as *const _) }
}
#[inline(always)]
pub fn fifo(&self, channel: usize) -> &'static RWRegister<u32> {
assert!(channel <= 15);
let address = self.0 + 0x1000 + channel * 0x1000;
unsafe { &*(address as *const RWRegister<u32>) }
}
#[inline(always)]
pub fn dieptxfx(&self, index: usize) -> &'static otg_global_dieptxfx::RegisterBlock {
let address = self.0 + 0x100 + 4 * index;
unsafe { &*(address as *const _) }
}
#[inline(always)]
pub fn endpoint_in(&self, index: usize) -> &'static endpoint_in::RegisterBlock {
let address = self.0 + 0x900 + 0x20 * index;
unsafe { &*(address as *const _) }
}
#[inline(always)]
pub fn endpoint0_out(&self) -> &'static endpoint0_out::RegisterBlock {
let address = self.0 + 0xb00;
unsafe { &*(address as *const _) }
}
#[inline(always)]
pub fn endpoint_out(&self, index: usize) -> &'static endpoint_out::RegisterBlock {
let address = self.0 + 0xb00 + 0x20 * index;
unsafe { &*(address as *const _) }
}
}