platform: inhibit motor pins and remove output routes
This commit is contained in:
1 parent
5cb4b7df68
commit
b0d22b61d8
19 files changed
+426
-1126
No files matched your search
@@ -14,7 +14,6 @@ use core::marker::PhantomData;
|
||||
pub use kaptan_board::BoardConfig;
|
||||
use kaptan_board::BoardConfigError;
|
||||
|
||||
mod actuator;
|
||||
mod f722;
|
||||
|
||||
/// Dependencies used only while the platform expands its private RTIC macro.
|
||||
@@ -23,11 +22,12 @@ pub(crate) mod __platform_internal {
|
||||
pub(crate) use cortex_m as cm;
|
||||
pub(crate) use cortex_m_rt as cmrt;
|
||||
pub(crate) use kaptan_dma as dma;
|
||||
pub(crate) use kaptan_mavlink as mavlink;
|
||||
pub(crate) use kaptan_spi as spi;
|
||||
#[cfg(not(test))]
|
||||
pub(crate) use panic_halt as panic;
|
||||
pub(crate) use rtic as rtic_app;
|
||||
pub(crate) use stm32f7 as pac;
|
||||
#[cfg(test)]
|
||||
pub(crate) mod panic {}
|
||||
}
|
||||
|
||||
/// Construction or validation failure for a declarative F722 board.
|
||||
@@ -103,48 +103,6 @@ pub struct Pa4;
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub struct Pc3;
|
||||
|
||||
/// Motor-output component selector.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub struct MotorOutputs;
|
||||
/// Kakute TIM3/TIM5 motor route before selecting a waveform protocol.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub struct KakuteTim3Tim5Motors;
|
||||
/// GEPRC TIM3/TIM5 motor route before selecting a waveform protocol.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub struct GeprcTim3Tim5Motors;
|
||||
/// Validated Kakute TIM3/TIM5 DShot600 motor route.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub struct KakuteTim3Tim5Dshot600;
|
||||
/// Validated GEPRC TIM3/TIM5 DShot600 motor route.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub struct GeprcTim3Tim5Dshot600;
|
||||
|
||||
impl MotorOutputs {
|
||||
/// Selects Kakute's M1–M4 mapping: PB0, PB1, PB4, PB5.
|
||||
pub const fn kakute_tim3_tim5() -> KakuteTim3Tim5Motors {
|
||||
KakuteTim3Tim5Motors
|
||||
}
|
||||
|
||||
/// Selects GEPRC's M1–M4 mapping: PB4, PB5, PB0, PB1.
|
||||
pub const fn geprc_tim3_tim5() -> GeprcTim3Tim5Motors {
|
||||
GeprcTim3Tim5Motors
|
||||
}
|
||||
}
|
||||
|
||||
impl KakuteTim3Tim5Motors {
|
||||
/// Selects the platform-validated DShot600 waveform configuration.
|
||||
pub const fn dshot600(self) -> KakuteTim3Tim5Dshot600 {
|
||||
KakuteTim3Tim5Dshot600
|
||||
}
|
||||
}
|
||||
|
||||
impl GeprcTim3Tim5Motors {
|
||||
/// Selects the platform-validated DShot600 waveform configuration.
|
||||
pub const fn dshot600(self) -> GeprcTim3Tim5Dshot600 {
|
||||
GeprcTim3Tim5Dshot600
|
||||
}
|
||||
}
|
||||
|
||||
/// MAVLink component selector.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub struct Mavlink;
|
||||
@@ -208,13 +166,8 @@ pub struct Missing;
|
||||
/// typestate. A final `build()` exists only for complete supported route
|
||||
/// combinations, so omitted or cross-wired essential routes fail to compile at
|
||||
/// the board declaration.
|
||||
pub struct F7BoardBuilder<
|
||||
Imu = Missing,
|
||||
Motors = Missing,
|
||||
MavlinkRoute = Missing,
|
||||
Vertical = Missing,
|
||||
> {
|
||||
_state: PhantomData<(Imu, Motors, MavlinkRoute, Vertical)>,
|
||||
pub struct F7BoardBuilder<Imu = Missing, MavlinkRoute = Missing, Vertical = Missing> {
|
||||
_state: PhantomData<(Imu, MavlinkRoute, Vertical)>,
|
||||
}
|
||||
|
||||
impl F7BoardBuilder {
|
||||
@@ -232,21 +185,14 @@ impl Default for F7BoardBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, M, T, V> F7BoardBuilder<I, M, T, V> {
|
||||
impl<I, T, V> F7BoardBuilder<I, T, V> {
|
||||
/// Selects an IMU route descriptor.
|
||||
///
|
||||
/// Only a complete, profile-compatible descriptor has a final
|
||||
/// [`F7BoardBuilder::build`] implementation. Keeping this one selection
|
||||
/// operation uniform avoids teaching a board author platform profile
|
||||
/// mechanics merely because the selected IMU model differs.
|
||||
pub fn imu<Selected>(self, _: Selected) -> F7BoardBuilder<Selected, M, T, V> {
|
||||
F7BoardBuilder {
|
||||
_state: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
/// Selects the TIM3/TIM5 DShot600 output route.
|
||||
pub fn motors<Selected>(self, _: Selected) -> F7BoardBuilder<I, Selected, T, V> {
|
||||
pub fn imu<Selected>(self, _: Selected) -> F7BoardBuilder<Selected, T, V> {
|
||||
F7BoardBuilder {
|
||||
_state: PhantomData,
|
||||
}
|
||||
@@ -254,7 +200,7 @@ impl<I, M, T, V> F7BoardBuilder<I, M, T, V> {
|
||||
|
||||
/// Selects a validated MAVLink route. Only profile-compatible route types
|
||||
/// have a final [`F7BoardBuilder::build`] implementation.
|
||||
pub fn mavlink<Selected>(self, _: Selected) -> F7BoardBuilder<I, M, Selected, V> {
|
||||
pub fn mavlink<Selected>(self, _: Selected) -> F7BoardBuilder<I, Selected, V> {
|
||||
F7BoardBuilder {
|
||||
_state: PhantomData,
|
||||
}
|
||||
@@ -262,7 +208,7 @@ impl<I, M, T, V> F7BoardBuilder<I, M, T, V> {
|
||||
|
||||
/// Selects a validated vertical-sensor route. Its capability is checked
|
||||
/// against [`F7Board::CONFIG`] before any peripheral is initialized.
|
||||
pub fn vertical_sensor<Selected>(self, _: Selected) -> F7BoardBuilder<I, M, T, Selected> {
|
||||
pub fn vertical_sensor<Selected>(self, _: Selected) -> F7BoardBuilder<I, T, Selected> {
|
||||
F7BoardBuilder {
|
||||
_state: PhantomData,
|
||||
}
|
||||
@@ -285,7 +231,6 @@ pub(crate) enum F722Profile {
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub struct F722BoardRoutes {
|
||||
profile: F722Profile,
|
||||
motors: f722::MotorRoute,
|
||||
vertical: f722::VerticalRoute,
|
||||
}
|
||||
|
||||
@@ -297,12 +242,11 @@ impl F722BoardRoutes {
|
||||
|
||||
macro_rules! impl_mpu6000_routes {
|
||||
($vertical:ty, $route:expr) => {
|
||||
impl F7BoardBuilder<Mpu6000Spi1Exti4, KakuteTim3Tim5Dshot600, MavlinkUsart1, $vertical> {
|
||||
impl F7BoardBuilder<Mpu6000Spi1Exti4, MavlinkUsart1, $vertical> {
|
||||
/// Finishes a complete supported MPU6000 F722 declaration.
|
||||
pub const fn build(self) -> Result<F722BoardRoutes, BoardError> {
|
||||
Ok(F722BoardRoutes {
|
||||
profile: F722Profile::Mpu6000Spi1Usart1,
|
||||
motors: f722::MotorRoute::KakuteTim3Tim5,
|
||||
vertical: $route,
|
||||
})
|
||||
}
|
||||
@@ -316,12 +260,11 @@ impl_mpu6000_routes!(NoVerticalSensor, f722::VerticalRoute::None);
|
||||
|
||||
macro_rules! impl_icm42688_routes {
|
||||
($vertical:ty, $route:expr) => {
|
||||
impl F7BoardBuilder<Icm42688Spi3Exti3, GeprcTim3Tim5Dshot600, MavlinkUsart2, $vertical> {
|
||||
impl F7BoardBuilder<Icm42688Spi3Exti3, MavlinkUsart2, $vertical> {
|
||||
/// Finishes a complete supported ICM-42688-P F722 declaration.
|
||||
pub const fn build(self) -> Result<F722BoardRoutes, BoardError> {
|
||||
Ok(F722BoardRoutes {
|
||||
profile: F722Profile::Icm42688Spi3Usart2,
|
||||
motors: f722::MotorRoute::GeprcTim3Tim5,
|
||||
vertical: $route,
|
||||
})
|
||||
}
|
||||
@@ -333,30 +276,28 @@ impl_icm42688_routes!(NoVerticalSensor, f722::VerticalRoute::None);
|
||||
impl_icm42688_routes!(Mtf01Uart4, f722::VerticalRoute::Mtf01);
|
||||
impl_icm42688_routes!(LidarLiteV3I2c1, f722::VerticalRoute::LidarLiteV3);
|
||||
|
||||
/// Missing and cross-profile route selections are rejected before firmware is
|
||||
/// Missing and cross-profile route selections are rejected before board I/O is
|
||||
/// linked, because no matching `build` implementation exists.
|
||||
///
|
||||
/// ```compile_fail
|
||||
/// use platform_stm32f7::{
|
||||
/// F7BoardBuilder, Mavlink, MotorOutputs, Mpu6000, Pa4,
|
||||
/// F7BoardBuilder, Mavlink, Mpu6000, Pa4,
|
||||
/// };
|
||||
///
|
||||
/// let _ = F7BoardBuilder::new()
|
||||
/// .imu(Mpu6000::on_spi1().with_drdy(Pa4))
|
||||
/// .motors(MotorOutputs::kakute_tim3_tim5().dshot600())
|
||||
/// .mavlink(Mavlink::on_usart1())
|
||||
/// .build(); // vertical route is missing
|
||||
/// ```
|
||||
///
|
||||
/// ```compile_fail
|
||||
/// use platform_stm32f7::{
|
||||
/// F7BoardBuilder, Icm42688, Mavlink, MotorOutputs, Pc3,
|
||||
/// F7BoardBuilder, Icm42688, Mavlink, Pc3,
|
||||
/// VerticalSensor,
|
||||
/// };
|
||||
///
|
||||
/// let _ = F7BoardBuilder::new()
|
||||
/// .imu(Icm42688::on_spi3().with_drdy(Pc3))
|
||||
/// .motors(MotorOutputs::geprc_tim3_tim5().dshot600())
|
||||
/// .mavlink(Mavlink::on_usart1()) // ICM route requires USART2
|
||||
/// .vertical_sensor(VerticalSensor::none())
|
||||
/// .build();
|
||||
@@ -364,15 +305,14 @@ impl_icm42688_routes!(LidarLiteV3I2c1, f722::VerticalRoute::LidarLiteV3);
|
||||
///
|
||||
/// ```compile_fail
|
||||
/// use platform_stm32f7::{
|
||||
/// F7BoardBuilder, Icm42688, Mavlink, MotorOutputs, Pc3, VerticalSensor,
|
||||
/// F7BoardBuilder, Icm42688, Mavlink, Pc3, VerticalSensor,
|
||||
/// };
|
||||
///
|
||||
/// let _ = F7BoardBuilder::new()
|
||||
/// .imu(Icm42688::on_spi3().with_drdy(Pc3))
|
||||
/// .motors(MotorOutputs::kakute_tim3_tim5().dshot600())
|
||||
/// .mavlink(Mavlink::on_usart2())
|
||||
/// .vertical_sensor(VerticalSensor::none())
|
||||
/// .build(); // ICM/USART2 uses the GEPRC logical motor order.
|
||||
/// .build(); // MPU6000/USART1 is the only other supported profile.
|
||||
/// ```
|
||||
/// Contract implemented by a declarative STM32F722 board crate.
|
||||
pub trait F7Board {
|
||||
@@ -394,7 +334,10 @@ macro_rules! enforce_f7_board_contract {
|
||||
};
|
||||
}
|
||||
|
||||
/// Installs the platform-owned RTIC flight firmware for a declarative board.
|
||||
/// Installs the one platform-owned RTIC application for a declarative board.
|
||||
///
|
||||
/// Board crates can only select one of the reviewed physical-sensor telemetry
|
||||
/// route descriptors; RTIC ownership stays platform-private.
|
||||
///
|
||||
/// The application binds the finite superset of interrupt roles needed by the
|
||||
/// currently supported F722 profiles. The route declaration selects which
|
||||
@@ -416,11 +359,11 @@ macro_rules! flight_firmware {
|
||||
<$board as $crate::F7Board>::build($crate::F7BoardBuilder::new())
|
||||
}
|
||||
#[used]
|
||||
static KAPTAN_F722_PLATFORM_FIRMWARE: fn() = $crate::firmware_anchor;
|
||||
static KAPTAN_F722_PLATFORM_FLIGHT: fn() = $crate::firmware_anchor;
|
||||
};
|
||||
}
|
||||
|
||||
/// Link anchor for the platform-owned F722 RTIC application.
|
||||
/// Link anchor for the platform-owned F722 board-I/O application.
|
||||
#[doc(hidden)]
|
||||
pub fn firmware_anchor() {}
|
||||
|
||||
@@ -432,7 +375,6 @@ mod tests {
|
||||
fn route_descriptors_select_the_mpu6000_profile() {
|
||||
let routes = F7BoardBuilder::new()
|
||||
.imu(Mpu6000::on_spi1().with_drdy(Pa4))
|
||||
.motors(MotorOutputs::kakute_tim3_tim5().dshot600())
|
||||
.mavlink(Mavlink::on_usart1())
|
||||
.vertical_sensor(VerticalSensor::mtf01_on_uart4())
|
||||
.build()
|
||||
@@ -444,7 +386,6 @@ mod tests {
|
||||
fn route_descriptors_select_the_icm42688_profile() {
|
||||
let routes = F7BoardBuilder::new()
|
||||
.imu(Icm42688::on_spi3().with_drdy(Pc3))
|
||||
.motors(MotorOutputs::geprc_tim3_tim5().dshot600())
|
||||
.mavlink(Mavlink::on_usart2())
|
||||
.vertical_sensor(VerticalSensor::none())
|
||||
.build()
|
||||
|
||||
Reference in new issue
Block a user