//! Static electrical routes selected by the Kakute F7 Mini V3. //! //! The board describes which controller and pins are connected. Protocol //! framing and controller state remain in their respective reusable crates. use kaptan_spi::{SpiCompletion, SpiDevice}; use kaptan_stm32f7::stm32f722::{Spi1, Spi1Error}; use stm32f7::stm32f722; /// Chip-select-scoped SPI1/PB2 route wired to the MPU6000. pub struct KakuteMpu6000SpiRoute { spi: Spi1, chip_select: stm32f722::GPIOB, } impl KakuteMpu6000SpiRoute { /// Configures board-selected PB2 chip select and combines it with SPI1. pub(crate) fn new(rcc: &stm32f722::RCC, spi: Spi1, chip_select: stm32f722::GPIOB) -> Self { rcc.ahb1enr().modify(|_, write| write.gpioben().set_bit()); chip_select .moder() .modify(|_, write| write.moder2().output()); chip_select .otyper() .modify(|_, write| write.ot2().push_pull()); chip_select .ospeedr() .modify(|_, write| write.ospeedr2().low_speed()); chip_select .pupdr() .modify(|_, write| write.pupdr2().floating()); chip_select.bsrr().write(|write| write.bs2().set_bit()); Self { spi, chip_select } } fn select(&self) { self.chip_select.bsrr().write(|write| write.br2().set_bit()); } fn deselect(&self) { self.chip_select.bsrr().write(|write| write.bs2().set_bit()); } } impl SpiDevice for KakuteMpu6000SpiRoute { type StartError = Spi1Error; fn start_transfer( &mut self, transmit: &[u8], receive: &mut [u8], ) -> Result<(), Self::StartError> { self.select(); if let Err(error) = self.spi.start_transfer(transmit, receive) { self.deselect(); return Err(error); } Ok(()) } fn complete_transfer(&mut self, completion: SpiCompletion) { self.spi.complete_transfer(completion); if matches!( completion, SpiCompletion::Complete | SpiCompletion::TransferFault ) { self.deselect(); } } }