feat(f722): add usb mavlink transport
This commit is contained in:
1 parent
7dc3ccb619
commit
604a7aba86
18 files changed
+1087
-208
No files matched your search
@@ -1,12 +1,12 @@
|
||||
//! F722 transport and vertical-route adapters for the portable data channel.
|
||||
|
||||
use super::peripherals;
|
||||
use kaptan_data_channel::FrameSink;
|
||||
use kaptan_dma::TxCompletion;
|
||||
use kaptan_mavlink::{
|
||||
MavlinkFrame,
|
||||
transmitter::{EnqueueResult, FrameClass, MavlinkTransmitter},
|
||||
MavlinkFrame, receiver::IntegrityCheckedFrame, transmitter::MavlinkTransmitter,
|
||||
};
|
||||
use kaptan_tx::PendingFrame;
|
||||
use peripherals::F722UsbMavlink;
|
||||
|
||||
// Baud, sensor topology, and mounting remain immutable build-time policy. The
|
||||
// output-inhibited board image may recover endpoint identity and selected
|
||||
@@ -28,16 +28,25 @@ enum F722MavlinkTransport {
|
||||
Usart2(MavlinkTransmitter<peripherals::DcacheDisabledDmaMemory, peripherals::Usart2TxDma, 4>),
|
||||
}
|
||||
|
||||
/// Sole F722 MAVLink DMA owner.
|
||||
pub(crate) struct F722MavlinkTransmitter {
|
||||
inner: F722MavlinkTransport,
|
||||
/// Physical link on which an inbound frame arrived.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub(crate) enum MavlinkIngress {
|
||||
Uart,
|
||||
Usb,
|
||||
}
|
||||
|
||||
impl F722MavlinkTransmitter {
|
||||
/// Concrete F722 MAVLink link ownership.
|
||||
pub(crate) struct F722MavlinkLink {
|
||||
uart: F722MavlinkTransport,
|
||||
usb: F722UsbMavlink,
|
||||
}
|
||||
|
||||
impl F722MavlinkLink {
|
||||
pub(crate) fn usart1(
|
||||
rcc: &stm32f7::stm32f722::RCC,
|
||||
uart: stm32f7::stm32f722::USART1,
|
||||
baud: u32,
|
||||
usb: F722UsbMavlink,
|
||||
) -> Result<Self, ()> {
|
||||
let uart = peripherals::Usart1Tx::new(rcc, uart, UART1_CLOCK_HZ, baud).map_err(|_| ())?;
|
||||
// SAFETY: platform initialization disables D-cache before this object
|
||||
@@ -45,10 +54,11 @@ impl F722MavlinkTransmitter {
|
||||
// this platform receives a terminal DMA completion notification.
|
||||
let memory = unsafe { peripherals::DcacheDisabledDmaMemory::new() };
|
||||
Ok(Self {
|
||||
inner: F722MavlinkTransport::Usart1(MavlinkTransmitter::new(
|
||||
uart: F722MavlinkTransport::Usart1(MavlinkTransmitter::new(
|
||||
memory,
|
||||
peripherals::Usart1TxDma::new(rcc, uart),
|
||||
)),
|
||||
usb,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -56,45 +66,73 @@ impl F722MavlinkTransmitter {
|
||||
rcc: &stm32f7::stm32f722::RCC,
|
||||
uart: stm32f7::stm32f722::USART2,
|
||||
baud: u32,
|
||||
usb: F722UsbMavlink,
|
||||
) -> Result<Self, ()> {
|
||||
let uart = peripherals::Usart2Tx::new(rcc, uart, UART2_CLOCK_HZ, baud).map_err(|_| ())?;
|
||||
// SAFETY: identical DMA-memory invariant to the USART1 route above;
|
||||
// only the fixed platform DMA endpoint differs.
|
||||
let memory = unsafe { peripherals::DcacheDisabledDmaMemory::new() };
|
||||
Ok(Self {
|
||||
inner: F722MavlinkTransport::Usart2(MavlinkTransmitter::new(
|
||||
uart: F722MavlinkTransport::Usart2(MavlinkTransmitter::new(
|
||||
memory,
|
||||
peripherals::Usart2TxDma::new(rcc, uart),
|
||||
)),
|
||||
usb,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl FrameSink for F722MavlinkTransmitter {
|
||||
fn send(&mut self, class: FrameClass, frame: MavlinkFrame) -> EnqueueResult {
|
||||
match &mut self.inner {
|
||||
/// Sends publications on the open USB link, or on UART when USB is closed.
|
||||
pub(crate) fn send_active(&mut self, pending: PendingFrame<MavlinkFrame>) -> bool {
|
||||
if self.usb.is_open() {
|
||||
self.usb.send(pending)
|
||||
} else {
|
||||
self.send_uart(pending)
|
||||
}
|
||||
}
|
||||
|
||||
/// Sends a protocol reply only on the link that supplied its request.
|
||||
pub(crate) fn send_to(
|
||||
&mut self,
|
||||
ingress: MavlinkIngress,
|
||||
pending: PendingFrame<MavlinkFrame>,
|
||||
) -> bool {
|
||||
match ingress {
|
||||
MavlinkIngress::Uart => self.send_uart(pending),
|
||||
MavlinkIngress::Usb => self.usb.send(pending),
|
||||
}
|
||||
}
|
||||
|
||||
fn send_uart(&mut self, pending: PendingFrame<MavlinkFrame>) -> bool {
|
||||
match &mut self.uart {
|
||||
F722MavlinkTransport::Usart1(transmitter) => transmitter
|
||||
.admit_and_start(pending.class, pending.frame)
|
||||
.admission
|
||||
.is_retained(),
|
||||
F722MavlinkTransport::Usart2(transmitter) => transmitter
|
||||
.admit_and_start(pending.class, pending.frame)
|
||||
.admission
|
||||
.is_retained(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn on_dma_complete(&mut self, completion: TxCompletion) {
|
||||
match &mut self.uart {
|
||||
F722MavlinkTransport::Usart1(transmitter) => {
|
||||
let outcome = transmitter.admit_and_start(class, frame);
|
||||
let _ = outcome.start;
|
||||
outcome.admission
|
||||
let _ = transmitter.on_dma_complete(completion);
|
||||
}
|
||||
F722MavlinkTransport::Usart2(transmitter) => {
|
||||
let outcome = transmitter.admit_and_start(class, frame);
|
||||
let _ = outcome.start;
|
||||
outcome.admission
|
||||
let _ = transmitter.on_dma_complete(completion);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn on_dma_complete(&mut self, completion: TxCompletion) {
|
||||
match &mut self.inner {
|
||||
F722MavlinkTransport::Usart1(transmitter) => {
|
||||
let _ = transmitter.on_dma_complete(completion);
|
||||
}
|
||||
F722MavlinkTransport::Usart2(transmitter) => {
|
||||
let _ = transmitter.on_dma_complete(completion);
|
||||
}
|
||||
}
|
||||
/// Services USB and reports whether the protocol worker has bytes to parse.
|
||||
pub(crate) fn poll_usb(&mut self) -> bool {
|
||||
self.usb.poll()
|
||||
}
|
||||
|
||||
pub(crate) fn take_usb_received(&mut self) -> Option<IntegrityCheckedFrame> {
|
||||
self.usb.take_received()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user