use super::{gpio, sys_timer, usb}; use crate::device::flash_store::{self, FlashStore}; use crate::laser_diode::ld_ctrl::{*}; use crate::laser_diode::laser_diode::LdDrive; use crate::thermostat::max1968::MAX1968; use crate::thermostat::thermostat::Thermostat; use crate::net::net::{IpSettings, ServerHandle}; use stm32_eth; use fugit::ExtU32; use log::{info, debug}; use stm32f4xx_hal::timer::TimerExt; use stm32f4xx_hal::{ pac::{CorePeripherals, Peripherals}, rcc::RccExt, time::MegaHertz, watchdog::IndependentWatchdog, }; use crate::DeviceSettings; use uom::si::electric_current::milliampere; use uom::si::{electric_current::ampere, f32::ElectricCurrent}; #[cfg(not(feature = "semihosting"))] const WATCHDOG_PERIOD: u32 = 4000; #[cfg(feature = "semihosting")] const WATCHDOG_PERIOD: u32 = 30000; pub fn bootup( mut core_perif: CorePeripherals, perif: Peripherals, ) -> (IndependentWatchdog, FlashStore, LdDrive, Thermostat) { core_perif.SCB.enable_icache(); core_perif.SCB.enable_dcache(&mut core_perif.CPUID); let clocks = perif .RCC .constrain() .cfgr .use_hse(MegaHertz::from_raw(8).convert()) .sysclk(MegaHertz::from_raw(168).convert()) .hclk(MegaHertz::from_raw(168).convert()) .pclk1(MegaHertz::from_raw(42).convert()) .pclk2(MegaHertz::from_raw(84).convert()) .freeze(); sys_timer::setup(core_perif.SYST, clocks); let (mut hw_rev, eth_pins, eth_mgmt_pins, usb, current_source_phy, ad7172_phy, max1968_phy, pd_mon_phy) = gpio::setup( clocks, perif.TIM4, perif.GPIOA, perif.GPIOB, perif.GPIOC, perif.GPIOD, perif.GPIOE, perif.SPI1, perif.SPI2, perif.SPI3, perif.OTG_FS_GLOBAL, perif.OTG_FS_DEVICE, perif.OTG_FS_PWRCLK, ); usb::State::setup(usb); debug!("Setting up TEC"); let tec_driver = MAX1968::new(max1968_phy, perif.ADC1, perif.ADC2, perif.DMA2); let mut thermostat = Thermostat::new(tec_driver, ad7172_phy); thermostat.setup(); thermostat.power_up(); thermostat.calibrate_dac_value(); thermostat.set_i(ElectricCurrent::new::(0.0)); debug!("Setting up Laser Driver"); let current_source = LdCtrl::new(current_source_phy); let mut laser = LdDrive::new(current_source, perif.ADC3, perif.TIM2.counter(&clocks), pd_mon_phy); laser.setup(); laser.ld_open(); laser.ld_set_i(ElectricCurrent::new::(0.0)); laser.set_pd_i_limit(ElectricCurrent::new::(2.5)); laser.set_pd_mon_calibrated_vdda(thermostat.get_calibrated_vdda()); laser.power_up(); debug!("Setting up Internal Flash Driver"); let flash_store = flash_store::store(perif.FLASH); let mut ip_settings: IpSettings = IpSettings::default(); let device_settings : DeviceSettings; match flash_store.read_value("Device") { Ok(Some(config)) => { device_settings = config; ip_settings = device_settings.ip_settings; debug!("Found Device Settings"); } Ok(None) => { debug!("Flash does not have IP Settings"); } Err(e) => { debug!("Cannot Store Flash: {:?}", e); } } debug!("Setting up ETH"); let mac_addr = hw_rev.get_mac_address(); let ethernet_parts_in = stm32_eth::PartsIn { dma: perif.ETHERNET_DMA, mac: perif.ETHERNET_MAC, mmc: perif.ETHERNET_MMC, ptp: perif.ETHERNET_PTP, }; ServerHandle::new(eth_pins, eth_mgmt_pins, ethernet_parts_in, clocks, mac_addr, ip_settings); debug!("Setting Watchdog"); let mut wd = IndependentWatchdog::new(perif.IWDG); wd.start(WATCHDOG_PERIOD.millis()); wd.feed(); info!("Kirdy setup complete"); (wd, flash_store, laser, thermostat) }