support bi-directional mavlink

Signed-off-by: Onur Özkan <work@onurozkan.dev>
This commit is contained in:
Onur Özkan committed 2026-07-21 13:43:07 +03:00
1 parent 2d35d935b4
commit d32d9f4d36
16 files changed
+651 -344

No files matched your search

+10
View File
@@ -70,6 +70,16 @@ pub fn configure_usart1_tx_pin_pa9(port: &stm32f722::GPIOA) {
port.pupdr().modify(|_, write| write.pupdr9().floating());
}
/// Configures PA10 for USART1 receive alternate function 7.
pub fn configure_usart1_rx_pin_pa10(port: &stm32f722::GPIOA) {
port.moder().modify(|_, write| write.moder10().alternate());
port.afrh().modify(|_, write| {
// SAFETY: AF7 selects USART1 RX on PA10 on STM32F722.
unsafe { write.afrh10().bits(0b0111) }
});
port.pupdr().modify(|_, write| write.pupdr10().floating());
}
/// Active-low status LED connected to PD2.
pub struct ActiveLowLedPd2 {
port: stm32f722::GPIOD,
+2 -2
View File
@@ -16,10 +16,10 @@ pub use clock::{ClockProfileError, select_hsi16_profile};
pub use dma_buffer::DcacheDisabledDmaMemory;
pub use gpio::{
ActiveLowLedPd2, configure_exti4_pin_pa4, configure_spi1_pins_pa5_pa6_pa7,
configure_usart1_tx_pin_pa9,
configure_usart1_rx_pin_pa10, configure_usart1_tx_pin_pa9,
};
pub use spi1::{Spi1, Spi1Error};
pub use tim2::{Tim2Periodic, Tim2PeriodicConfig};
pub use time::{DwtClockStartError, DwtMicrosecondClock};
pub use usart::{BaudRateError, Usart1Tx};
pub use usart::{BaudRateError, ReceiveInterrupt, Usart1Tx};
pub use usart1_tx_dma2_stream7::{StartError, Usart1TxDma};
+69 -5
View File
@@ -11,7 +11,18 @@ pub enum BaudRateError {
OutOfRange,
}
/// Owns configured transmit-only USART1 hardware.
/// Terminal result from acknowledging the USART1 receive interrupt.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum ReceiveInterrupt {
/// One received byte was removed from the UART data register.
Byte(u8),
/// A serial transport fault invalidated the current receive stream.
Fault,
/// This USART1 interrupt did not have a receive event pending.
NotPending,
}
/// Owns configured full-duplex USART1 hardware.
///
/// Pin alternate-function setup remains board-owned because it depends on the
/// schematic. Configure pins before constructing this type.
@@ -20,7 +31,7 @@ pub struct Usart1Tx {
}
impl Usart1Tx {
/// Enables USART1 and configures 8N1 transmit-only operation.
/// Enables USART1 and configures 8N1 transmit and receive operation.
pub fn new(
rcc: &stm32f722::RCC,
peripheral: stm32f722::USART1,
@@ -38,9 +49,17 @@ impl Usart1Tx {
// SAFETY: `brr` is validated to fit the complete BRR register.
unsafe { write.bits(u32::from(brr)) }
});
peripheral
.cr1()
.write(|write| write.te().set_bit().ue().set_bit());
peripheral.cr1().write(|write| {
write
.te()
.set_bit()
.re()
.set_bit()
.rxneie()
.set_bit()
.ue()
.set_bit()
});
peripheral.cr2().write(|write| write.stop().stop1());
Ok(Self { peripheral })
@@ -53,6 +72,51 @@ impl Usart1Tx {
pub(crate) fn transmit_data_register_address(&self) -> u32 {
self.peripheral.tdr().as_ptr() as u32
}
/// Acknowledges one USART1 receive interrupt without accessing TX state.
///
/// The board invokes this only from the `USART1` interrupt. USART1 TX DMA
/// owns its disjoint data register and DMA stream, so this static route may
/// safely acknowledge RX while that transfer is active.
pub fn acknowledge_receive_interrupt() -> ReceiveInterrupt {
// SAFETY: the board binds USART1 exactly once and this function touches
// only its receive/error registers, never the TX DMA configuration.
let peripheral = unsafe { &*stm32f722::USART1::ptr() };
let status = peripheral.isr().read();
let fault = status.pe().is_error()
|| status.fe().is_error()
|| status.nf().is_noise()
|| status.ore().is_overrun();
if status.rxne().is_data_ready() {
let byte = peripheral.rdr().read().rdr().bits() as u8;
if fault {
clear_receive_errors(peripheral);
ReceiveInterrupt::Fault
} else {
ReceiveInterrupt::Byte(byte)
}
} else if fault {
clear_receive_errors(peripheral);
ReceiveInterrupt::Fault
} else {
ReceiveInterrupt::NotPending
}
}
}
fn clear_receive_errors(peripheral: &stm32f722::usart1::RegisterBlock) {
peripheral.icr().write(|write| {
write
.pecf()
.clear()
.fecf()
.clear()
.ncf()
.clear()
.orecf()
.clear()
});
}
const fn calculate_brr(peripheral_clock_hz: u32, baud: u32) -> Result<u16, BaudRateError> {