use p_hal::stm32 as pac;
use stm32f4xx_hal as p_hal;
use pac::{DCMI, RCC};
use embedded_hal::blocking::delay::{DelayMs, DelayUs};
use embedded_hal::digital::v2::{OutputPin, ToggleableOutputPin};
use embedded_hal::timer::CountDown;
use embedded_hal::PwmPin;
use p_hal::timer::{self, Timer};
use p_hal::gpio::{GpioExt, Output, PushPull, Speed};
use p_hal::pwm;
use p_hal::rcc::RccExt;
use p_hal::time::U32Ext;
#[cfg(feature = "rttdebug")]
use panic_rtt_core::rprintln;
use shared_bus::{BusManager, BusProxy, CortexMBusManager};
use stm32f4xx_hal::timer::{PinC3, PinC4};
use stm32f4xx_hal::dwt::{Dwt,DwtExt};
pub fn setup_peripherals() -> (
(LedOutputActivity, LedOutputComm, LedOutputError),
DelaySource,
Dwt,
I2c1Port,
I2c2Port,
Spi2Port,
SpiGyroCsn,
Usart2Port,
Usart3Port,
Uart4Port,
DcmiCtrlPins,
DcmiDataPins,
pac::DMA2,
pac::DCMI,
) {
let mut dp = pac::Peripherals::take().unwrap();
let mut cp = cortex_m::Peripherals::take().unwrap();
let mut rcc = dp.RCC.constrain();
let mut clocks = rcc
.cfgr
.use_hse(24.mhz())
.sysclk(168.mhz())
.pclk1(42.mhz())
.pclk2(84.mhz())
.freeze();
let mut delay_source = p_hal::delay::Delay::new(cp.SYST, clocks);
let dwt = cp.DWT.constrain(cp.DCB, clocks);
let rcc2 = unsafe { &(*RCC::ptr()) };
rcc2.ahb2enr.modify(|_, w| w.dcmien().set_bit());
rcc2.ahb1enr.modify(|_, w| w.dma2en().set_bit());
let gpioa = dp.GPIOA.split();
let gpiob = dp.GPIOB.split();
let gpioc = dp.GPIOC.split();
let gpiod = dp.GPIOD.split();
let gpioe = dp.GPIOE.split();
#[cfg(feature = "breakout")]
let user_led0 = gpioa
.pa1
.into_push_pull_output()
.set_speed(Speed::Low)
.downgrade();
#[cfg(not(feature = "breakout"))]
let user_led0 = gpioe.pe2.into_push_pull_output().downgrade();
let user_led1 = gpioe.pe3.into_push_pull_output().downgrade();
let user_led2 = gpioe.pe7.into_push_pull_output().downgrade();
let i2c1_port = {
let scl = gpiob.pb8.into_alternate_af4().set_open_drain();
let sda = gpiob.pb9.into_alternate_af4().set_open_drain();
p_hal::i2c::I2c::i2c1(dp.I2C1, (scl, sda), 400.khz(), clocks)
};
let i2c2_port = {
let scl = gpiob
.pb10
.into_alternate_af4()
.internal_pull_up(true)
.set_speed(Speed::Low)
.set_open_drain();
let sda = gpiob
.pb11
.into_alternate_af4()
.internal_pull_up(true)
.set_speed(Speed::Low)
.set_open_drain();
p_hal::i2c::I2c::i2c2(dp.I2C2, (scl, sda), 100.khz(), clocks)
};
let usart2_port = {
let config =
p_hal::serial::config::Config::default().baudrate(115200.bps());
let tx = gpiod.pd5.into_alternate_af7();
let rx = gpiod.pd6.into_alternate_af7();
p_hal::serial::Serial::usart2(dp.USART2, (tx, rx), config, clocks)
.unwrap()
};
let usart3_port = {
let config =
p_hal::serial::config::Config::default().baudrate(115200.bps());
let tx = gpiod.pd8.into_alternate_af7();
let rx = gpiod.pd9.into_alternate_af7();
p_hal::serial::Serial::usart3(dp.USART3, (tx, rx), config, clocks)
.unwrap()
};
let uart4_port = {
let config =
p_hal::serial::config::Config::default().baudrate(9600.bps());
let tx = gpioa.pa0.into_alternate_af8();
let rx = gpioc.pc11.into_alternate_af8();
p_hal::serial::Serial::uart4(dp.UART4, (tx, rx), config, clocks)
.unwrap()
};
let spi2_port = {
let sck = gpiob.pb13.into_alternate_af5();
let cipo = gpiob.pb14.into_alternate_af5();
let copi = gpiob.pb15.into_alternate_af5();
p_hal::spi::Spi::spi2(
dp.SPI2,
(sck, cipo, copi),
embedded_hal::spi::MODE_3,
1_000_000.hz(),
clocks,
)
};
let mut spi_cs_gyro = gpiob.pb12.into_push_pull_output();
let _ = spi_cs_gyro.set_high();
let dcmi_ctrl_pins = {
let pixck = gpioa
.pa6
.into_pull_up_input()
.into_alternate_af13()
.internal_pull_up(true)
.set_speed(Speed::VeryHigh);
let hsync = gpioa
.pa4
.into_pull_up_input()
.into_alternate_af13()
.internal_pull_up(true)
.set_speed(Speed::VeryHigh);
let vsync = gpiob
.pb7
.into_pull_up_input()
.into_alternate_af13()
.internal_pull_up(true)
.set_speed(Speed::VeryHigh);
(pixck, hsync, vsync)
};
let dcmi_data_pins = (
gpioc
.pc6
.into_pull_up_input()
.into_alternate_af13()
.internal_pull_up(true)
.set_speed(Speed::VeryHigh),
gpioc
.pc7
.into_pull_up_input()
.into_alternate_af13()
.internal_pull_up(true)
.set_speed(Speed::VeryHigh),
gpioe
.pe0
.into_pull_up_input()
.into_alternate_af13()
.internal_pull_up(true)
.set_speed(Speed::VeryHigh),
gpioe
.pe1
.into_pull_up_input()
.into_alternate_af13()
.internal_pull_up(true)
.set_speed(Speed::VeryHigh),
gpioe
.pe4
.into_pull_up_input()
.into_alternate_af13()
.internal_pull_up(true)
.set_speed(Speed::VeryHigh),
gpiob
.pb6
.into_pull_up_input()
.into_alternate_af13()
.internal_pull_up(true)
.set_speed(Speed::VeryHigh),
gpioe
.pe5
.into_pull_up_input()
.into_alternate_af13()
.internal_pull_up(true)
.set_speed(Speed::VeryHigh),
gpioe
.pe6
.into_pull_up_input()
.into_alternate_af13()
.internal_pull_up(true)
.set_speed(Speed::VeryHigh),
gpioc
.pc10
.into_pull_up_input()
.into_alternate_af13()
.internal_pull_up(true)
.set_speed(Speed::VeryHigh),
gpioc
.pc12
.into_pull_up_input()
.into_alternate_af13()
.internal_pull_up(true)
.set_speed(Speed::VeryHigh),
);
let dcmi = dp.DCMI;
let dma2 = dp.DMA2;
let mut exposure_line =
gpioa.pa2.into_push_pull_output().set_speed(Speed::Low);
let mut standby_line =
gpioa.pa3.into_push_pull_output().set_speed(Speed::Low);
let _ = exposure_line.set_low();
let _ = standby_line.set_low();
let channels = (
gpioc.pc8.into_alternate_af2(),
gpioc.pc9.into_alternate_af2(),
);
let (mut ch1, _ch2) = pwm::tim3(dp.TIM3, channels, clocks, 24u32.mhz());
let max_duty = ch1.get_max_duty();
let duty_avg = (max_duty / 2) + 1;
#[cfg(feature = "rttdebug")]
rprintln!("duty cycle: {} max: {}", duty_avg, max_duty);
ch1.set_duty(duty_avg);
ch1.enable();
#[cfg(feature = "rttdebug")]
rprintln!("TIM3 XCLK config done");
(
(user_led0, user_led1, user_led2),
delay_source,
dwt,
i2c1_port,
i2c2_port,
spi2_port,
spi_cs_gyro,
usart2_port,
usart3_port,
uart4_port,
dcmi_ctrl_pins,
dcmi_data_pins,
dma2,
dcmi,
)
}
pub type I2c1Port = p_hal::i2c::I2c<
pac::I2C1,
(
p_hal::gpio::gpiob::PB8<p_hal::gpio::AlternateOD<p_hal::gpio::AF4>>,
p_hal::gpio::gpiob::PB9<p_hal::gpio::AlternateOD<p_hal::gpio::AF4>>,
),
>;
pub type I2c2Port = p_hal::i2c::I2c<
pac::I2C2,
(
p_hal::gpio::gpiob::PB10<p_hal::gpio::AlternateOD<p_hal::gpio::AF4>>,
p_hal::gpio::gpiob::PB11<p_hal::gpio::AlternateOD<p_hal::gpio::AF4>>,
),
>;
pub type Spi2Port = p_hal::spi::Spi<
pac::SPI2,
(
p_hal::gpio::gpiob::PB13<p_hal::gpio::Alternate<p_hal::gpio::AF5>>,
p_hal::gpio::gpiob::PB14<p_hal::gpio::Alternate<p_hal::gpio::AF5>>,
p_hal::gpio::gpiob::PB15<p_hal::gpio::Alternate<p_hal::gpio::AF5>>,
),
>;
pub type SpiGyroCsn =
p_hal::gpio::gpiob::PB12<p_hal::gpio::Output<p_hal::gpio::PushPull>>;
pub type DcmiCtrlPins = (
p_hal::gpio::gpioa::PA6<DcmiControlPin>,
p_hal::gpio::gpioa::PA4<DcmiControlPin>,
p_hal::gpio::gpiob::PB7<DcmiControlPin>,
);
pub type DcmiControlPin = p_hal::gpio::Alternate<p_hal::gpio::AF13>;
pub type DcmiParallelDataPin = DcmiControlPin;
pub type DcmiDataPins = (
p_hal::gpio::gpioc::PC6<DcmiParallelDataPin>,
p_hal::gpio::gpioc::PC7<DcmiParallelDataPin>,
p_hal::gpio::gpioe::PE0<DcmiParallelDataPin>,
p_hal::gpio::gpioe::PE1<DcmiParallelDataPin>,
p_hal::gpio::gpioe::PE4<DcmiParallelDataPin>,
p_hal::gpio::gpiob::PB6<DcmiParallelDataPin>,
p_hal::gpio::gpioe::PE5<DcmiParallelDataPin>,
p_hal::gpio::gpioe::PE6<DcmiParallelDataPin>,
p_hal::gpio::gpioc::PC10<DcmiParallelDataPin>,
p_hal::gpio::gpioc::PC12<DcmiParallelDataPin>,
);
pub type LedOutputPinA = p_hal::gpio::gpioa::PA<Output<PushPull>>;
pub type LedOutputPinE = p_hal::gpio::gpioe::PE<Output<PushPull>>;
#[cfg(feature = "breakout")]
pub type LedOutputActivity = LedOutputPinA;
#[cfg(not(feature = "breakout"))]
pub type LedOutputActivity = LedOutputPinE;
pub type LedOutputComm = LedOutputPinE;
pub type LedOutputError = LedOutputPinE;
pub type DelaySource = p_hal::delay::Delay;
pub type UsartIoPin = p_hal::gpio::Alternate<p_hal::gpio::AF7>;
pub type Usart2Port = p_hal::serial::Serial<
pac::USART2,
(
p_hal::gpio::gpiod::PD5<UsartIoPin>,
p_hal::gpio::gpiod::PD6<UsartIoPin>,
),
>;
pub type Usart3Port = p_hal::serial::Serial<
pac::USART3,
(
p_hal::gpio::gpiod::PD8<UsartIoPin>,
p_hal::gpio::gpiod::PD9<UsartIoPin>,
),
>;
pub type UartIoPin = p_hal::gpio::Alternate<p_hal::gpio::AF8>;
pub type Uart4Port = p_hal::serial::Serial<
pac::UART4,
(
p_hal::gpio::gpioa::PA0<UartIoPin>,
p_hal::gpio::gpioc::PC11<UartIoPin>,
),
>;