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:
1 parent
fb1b8af2d1
commit
f9a61a086f
211 files changed
+45657
-12740
No files matched your search
+92
@@ -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 _) }
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user