#![cfg(feature = "madflight_fc3")]
#![allow(clippy::similar_names)]
use crate::{
barometer_sensors::Barometer,
boards::board::{Board, BoardInit, BoardInitError, GpsHardware},
boards::platform::SharedI2cBus,
gps::GpsParser,
magnetometer_sensors::Magnetometer,
optical_flow_sensors::OpticalFlow,
rangefinder_sensors::Rangefinder,
};
use imu_sensors::{Imu426xx, ImuAxisOrder, ImuSpiBus};
use motor_mixers::{MotorDriver, MotorDriverQuadDshot, MotorDriverQuadPwm};
use radio_controllers::Radio;
use cyw43_pio::PioSpi;
use embassy_rp::{
Peri, bind_interrupts, dma, gpio,
gpio::{Input, Level, Output, Pull},
i2c,
i2c::{Async as I2cAsync, Config as I2cConfig, I2c},
peripherals, pio,
pio::InterruptHandler as PioInterruptHandler,
spi::{Async as SpiAsync, Config as SpiConfig, Spi},
uart,
uart::{Async as UartAsync, Config as UartConfig, Uart},
};
use embassy_time::Delay;
use embedded_hal_bus::spi::ExclusiveDevice;
use static_cell::StaticCell;
type BoardSpi =
ExclusiveDevice<embassy_rp::spi::Spi<'static, peripherals::SPI0, embassy_rp::spi::Async>, Output<'static>, Delay>;
pub type BoardImu = Imu426xx<ImuSpiBus<BoardSpi>>;
pub fn board_hardware(init: BoardInit) -> Result<Board<BoardImu>, BoardInitError> {
static I2C_BUS: StaticCell<SharedI2cBus> = StaticCell::new();
#[allow(clippy::default_trait_access)]
let peripherals = embassy_rp::init(Default::default());
let spi0_cs = peripherals.PIN_29;
let spi0_clk = peripherals.PIN_30;
let spi0_mosi = peripherals.PIN_31;
let spi0_miso = peripherals.PIN_28;
let spi0_tx_dma = peripherals.DMA_CH0;
let spi0_rx_dma = peripherals.DMA_CH1;
let spi0_interrupt_pin = peripherals.PIN_27;
let spi1_clk = peripherals.PIN_34;
let spi1_mosi = peripherals.PIN_11;
let spi1_miso = peripherals.PIN_12;
let spi1_tx_dma = peripherals.DMA_CH2;
let spi1_rx_dma = peripherals.DMA_CH3;
let spi1_cs = peripherals.PIN_13;
let uart0_tx = peripherals.PIN_0;
let uart0_rx = peripherals.PIN_1;
let uart0_tx_dma = peripherals.DMA_CH4;
let uart0_rx_dma = peripherals.DMA_CH5;
let uart1_tx = peripherals.PIN_4;
let uart1_rx = peripherals.PIN_5;
let uart1_tx_dma = peripherals.DMA_CH6;
let uart1_rx_dma = peripherals.DMA_CH7;
let i2c0_scl = peripherals.PIN_33;
let i2c0_sda = peripherals.PIN_32;
let i2c1_scl = peripherals.PIN_3;
let i2c1_sda = peripherals.PIN_2;
let m1 = peripherals.PIN_6;
let m2 = peripherals.PIN_7;
let m3 = peripherals.PIN_8;
let m4 = peripherals.PIN_9;
let m5 = peripherals.PIN_16;
let m6 = peripherals.PIN_17;
let m7 = peripherals.PIN_18;
let m8 = peripherals.PIN_19;
let spi0 = {
let mut spi_config = SpiConfig::default();
spi_config.frequency = 10_000_000;
let spi_bus =
Spi::new(peripherals.SPI0, spi0_clk, spi0_mosi, spi0_miso, spi0_tx_dma, spi0_rx_dma, Irqs, spi_config);
let spi_cs_output = Output::new(spi0_cs, Level::High);
ExclusiveDevice::new(spi_bus, spi_cs_output, embassy_time::Delay).unwrap()
};
let spi0_interrupt = Input::new(spi0_interrupt_pin, embassy_rp::gpio::Pull::Up);
let mut imu: BoardImu = Imu426xx::new(ImuSpiBus::new(spi0), init.axis_order);
let spi1 = {
let mut spi_config = SpiConfig::default();
spi_config.frequency = 400_000;
let spi_bus =
Spi::new(peripherals.SPI1, spi1_clk, spi1_mosi, spi1_miso, spi1_tx_dma, spi1_rx_dma, Irqs, spi_config);
let spi_cs_output = Output::new(spi1_cs, Level::High);
ExclusiveDevice::new(spi_bus, spi_cs_output, embassy_time::Delay)
};
let uart1 = {
let mut config = UsartConfig::default();
config.baudrate = 115_200;
Uart::new_blocking(peripherals.USART1, uart1_rx, uart1_tx, config)
};
let uart0 = {
let mut uart_config = UartConfig::default();
uart_config.baudrate = 115_200; Uart::new(peripherals.UART0, uart0_tx, uart0_rx, Irqs, uart0_tx_dma, uart0_rx_dma, uart_config)
.map_err(|_| BoardInitError::UartError)?
};
let uart1 = {
let mut uart_config = UartConfig::default();
uart_config.baudrate = 115_200;
Uart::new(peripherals.UART1, uart1_tx, uart1_rx, Irqs, uart1_tx_dma, uart1_rx_dma, uart_config)
.map_err(|_| BoardInitError::UartError)?
};
let i2c0 = {
let mut i2c_config = I2cConfig::default();
i2c_config.frequency = 400_000; I2c::new_async(peripherals.I2C0, i2c0_scl, i2c0_sda, Irqs, i2c_config)
};
let motor_driver_quad_dshot = MotorDriverQuadDshot::new();
let motor_driver = MotorDriver::QuadDshot(motor_driver_quad_dshot);
let radio = Radio::new(radio_controllers::RadioType::Mock);
static I2C_BUS: StaticCell<SharedI2cBus> = StaticCell::new();
let i2c = I2c::new_async(peripherals.I2C0, i2c0_sda, i2c0_scl, Irqs, config);
let shared_i2c = I2C_BUS.init(Mutex::new(i2c));
let barometer = Barometer::new(init.barometer_type, shared_i2c);
let magnetometer = Magnetometer::new(init.magnetometer_type, shared_i2c);
gps = None;
let rangefinder = Rangefinder::new(init.rangefinder_type);
let optical_flow = OpticalFlow::new(init.optical_flow_type);
Ok(Board { imu, motor_driver, radio, barometer, magnetometer, gps, rangefinder, optical_flow })
}