2023-12-15 13:11:05 +08:00
|
|
|
#![cfg_attr(not(test), no_main)]
|
|
|
|
#![cfg_attr(not(test), no_std)]
|
2022-10-20 15:17:43 +08:00
|
|
|
|
|
|
|
use cortex_m_rt::entry;
|
2024-02-02 14:07:25 +08:00
|
|
|
use log::{info, debug};
|
2022-10-22 15:49:01 +08:00
|
|
|
use stm32f4xx_hal::pac::{CorePeripherals, Peripherals};
|
2022-10-20 20:57:24 +08:00
|
|
|
mod device;
|
2022-10-21 12:05:55 +08:00
|
|
|
mod laser_diode;
|
2023-12-20 12:08:48 +08:00
|
|
|
mod thermostat;
|
2024-01-31 17:16:10 +08:00
|
|
|
mod net;
|
2022-10-22 21:00:17 +08:00
|
|
|
|
2024-01-11 13:15:19 +08:00
|
|
|
use device::{boot::bootup, log_setup, sys_timer};
|
|
|
|
use uom::fmt::DisplayStyle::Abbreviation;
|
|
|
|
use uom::si::electric_potential::volt;
|
|
|
|
use uom::si::electric_current::{ampere, milliampere};
|
2024-02-23 11:38:26 +08:00
|
|
|
use uom::si::f64::{ElectricPotential, ElectricCurrent};
|
2023-12-20 12:08:48 +08:00
|
|
|
|
2024-02-16 16:47:17 +08:00
|
|
|
use stm32f4xx_hal::pac::SCB;
|
2022-10-22 21:00:17 +08:00
|
|
|
// If RTT is used, print panic info through RTT
|
2023-12-15 13:11:05 +08:00
|
|
|
#[cfg(all(feature = "RTT", not(test)))]
|
2023-12-20 12:08:48 +08:00
|
|
|
use {core::panic::PanicInfo, rtt_target::rprintln};
|
2023-12-15 13:11:05 +08:00
|
|
|
#[cfg(all(feature = "RTT", not(test)))]
|
2022-10-22 21:00:17 +08:00
|
|
|
#[panic_handler]
|
|
|
|
fn panic(info: &PanicInfo) -> ! {
|
|
|
|
rprintln!("{}", info);
|
|
|
|
loop {}
|
|
|
|
}
|
|
|
|
// Otherwise use panic halt
|
2023-12-15 13:11:05 +08:00
|
|
|
#[cfg(all(not(feature = "RTT"), not(test)))]
|
2022-10-22 21:00:17 +08:00
|
|
|
use panic_halt as _;
|
2022-10-20 15:17:43 +08:00
|
|
|
|
2024-02-02 14:07:25 +08:00
|
|
|
static mut ETH_DATA_BUFFER: [u8; 1024] = [0; 1024];
|
|
|
|
|
2024-02-19 15:08:00 +08:00
|
|
|
pub struct DeviceSettings{
|
|
|
|
report_readings: bool,
|
|
|
|
}
|
|
|
|
|
2023-12-15 13:11:05 +08:00
|
|
|
#[cfg(not(test))]
|
2022-10-20 15:17:43 +08:00
|
|
|
#[entry]
|
|
|
|
fn main() -> ! {
|
2022-10-22 21:00:17 +08:00
|
|
|
log_setup::init_log();
|
|
|
|
info!("Kirdy init");
|
|
|
|
|
2022-10-22 15:49:01 +08:00
|
|
|
let core_perif = CorePeripherals::take().unwrap();
|
2022-10-20 20:57:24 +08:00
|
|
|
let perif = Peripherals::take().unwrap();
|
|
|
|
|
2024-02-02 14:07:25 +08:00
|
|
|
let (mut wd, mut _flash_store, mut laser, mut thermostat,) = bootup(core_perif, perif);
|
2024-01-15 17:13:05 +08:00
|
|
|
|
2024-02-02 14:07:25 +08:00
|
|
|
// Demo Fns for reading and writing stm32 Internal Flash
|
|
|
|
/*
|
2024-01-15 17:13:05 +08:00
|
|
|
let key = "test";
|
|
|
|
info!("Read the Flash Content Stored");
|
|
|
|
match flash_store.read(key).unwrap() {
|
|
|
|
Some(val) => {info!("Flash Valued Read: {:?}", val)}
|
|
|
|
_ => {info!("Key does not match")}
|
|
|
|
}
|
|
|
|
|
|
|
|
info!("Erasing Flash");
|
|
|
|
flash_store.erase().unwrap();
|
|
|
|
match flash_store.read(key).unwrap() {
|
|
|
|
Some(val) => {info!("Flash Valued Read: {:?}", val)}
|
|
|
|
_ => {info!("Key does not match")}
|
|
|
|
}
|
|
|
|
|
|
|
|
info!("Writing Flash");
|
|
|
|
let buf = [1, 2, 3, 4];
|
|
|
|
flash_store.write(key, &buf).unwrap();
|
|
|
|
|
|
|
|
info!("Reading Flash");
|
|
|
|
match flash_store.read(key).unwrap() {
|
|
|
|
Some(val) => {info!("Val: {:?}", val)}
|
|
|
|
_ => {info!("Key does not match")}
|
|
|
|
};
|
2024-02-02 14:07:25 +08:00
|
|
|
*/
|
2024-01-11 13:15:19 +08:00
|
|
|
|
|
|
|
// https://github.com/iliekturtles/uom/blob/master/examples/si.rs
|
|
|
|
let volt_fmt = ElectricPotential::format_args(volt, Abbreviation);
|
|
|
|
let amp_fmt = ElectricCurrent::format_args(ampere, Abbreviation);
|
2024-02-07 17:37:51 +08:00
|
|
|
let milli_amp_fmt = ElectricCurrent::format_args(milliampere, Abbreviation);
|
2022-10-20 20:57:24 +08:00
|
|
|
|
2024-02-16 16:47:17 +08:00
|
|
|
let mut should_reset = false;
|
|
|
|
|
2024-02-19 15:08:00 +08:00
|
|
|
let mut device_settings = DeviceSettings {
|
|
|
|
report_readings: false,
|
|
|
|
};
|
|
|
|
|
2022-10-20 20:57:24 +08:00
|
|
|
loop {
|
|
|
|
wd.feed();
|
2024-01-24 17:03:06 +08:00
|
|
|
|
2024-02-16 16:47:17 +08:00
|
|
|
if !should_reset {
|
|
|
|
let mut eth_is_pending = false;
|
2024-02-02 14:07:25 +08:00
|
|
|
|
2024-02-20 12:39:49 +08:00
|
|
|
laser.poll_and_update_output_current();
|
|
|
|
|
2024-02-23 12:58:35 +08:00
|
|
|
if thermostat.poll_adc() {
|
|
|
|
thermostat.update_pid();
|
2024-02-21 15:49:08 +08:00
|
|
|
if thermostat.get_temp_mon_status().over_temp_alarm {
|
|
|
|
laser.power_down();
|
|
|
|
thermostat.set_pid_engaged(false);
|
|
|
|
thermostat.power_down();
|
|
|
|
}
|
|
|
|
|
2024-02-16 16:47:17 +08:00
|
|
|
info!("curr_dac_vfb: {:?}", volt_fmt.with(thermostat.get_dac_vfb()));
|
|
|
|
info!("curr_vref: {:?}", volt_fmt.with(thermostat.get_vref()));
|
|
|
|
info!("curr_tec_i: {:?}", amp_fmt.with(thermostat.get_tec_i()));
|
|
|
|
info!("curr_tec_v: {:?}", volt_fmt.with(thermostat.get_tec_v()));
|
2024-02-06 15:20:23 +08:00
|
|
|
|
2024-02-16 16:47:17 +08:00
|
|
|
info!("curr_ld_drive_cuurent: {:?}", milli_amp_fmt.with(laser.get_ld_drive_current()));
|
|
|
|
|
|
|
|
info!("pd_mon_v: {:?}", volt_fmt.with(laser.pd_mon_status().v));
|
|
|
|
info!("power_excursion: {:?}", laser.pd_mon_status().pwr_excursion);
|
|
|
|
|
|
|
|
info!("Termination Status: {:?}", laser.get_term_status());
|
2024-02-19 15:08:00 +08:00
|
|
|
|
|
|
|
if net::net::eth_is_socket_active() {
|
|
|
|
if device_settings.report_readings {
|
|
|
|
unsafe {
|
2024-02-23 11:38:26 +08:00
|
|
|
net::cmd_handler::send_status_report(&mut ETH_DATA_BUFFER, &mut laser, &mut thermostat);
|
2024-02-19 15:08:00 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-02-16 16:47:17 +08:00
|
|
|
}
|
2024-02-06 15:20:23 +08:00
|
|
|
|
2024-02-16 16:47:17 +08:00
|
|
|
if net::net::eth_is_socket_active() {
|
|
|
|
cortex_m::interrupt::free(|cs|
|
|
|
|
{
|
|
|
|
eth_is_pending = net::net::is_pending(cs);
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
if eth_is_pending {
|
|
|
|
unsafe{
|
|
|
|
cortex_m::interrupt::free(|cs| {
|
|
|
|
net::net::clear_pending(cs);
|
|
|
|
});
|
|
|
|
let bytes = net::net::eth_recv(&mut ETH_DATA_BUFFER);
|
|
|
|
debug!("Number of bytes recv: {:?}", bytes);
|
2024-02-19 15:08:00 +08:00
|
|
|
(laser, thermostat, should_reset, device_settings) = net::cmd_handler::execute_cmd(&mut ETH_DATA_BUFFER, bytes, laser, thermostat, device_settings);
|
2024-02-16 16:47:17 +08:00
|
|
|
}
|
2024-02-02 14:07:25 +08:00
|
|
|
}
|
|
|
|
}
|
2024-02-19 15:08:00 +08:00
|
|
|
else {
|
|
|
|
device_settings.report_readings = false;
|
|
|
|
}
|
2024-02-16 16:47:17 +08:00
|
|
|
} else {
|
|
|
|
// Should reset, close all TCP sockets.
|
|
|
|
let mut any_socket_alive = false;
|
|
|
|
if net::net::eth_is_socket_active() {
|
|
|
|
net::net::eth_close_socket();
|
|
|
|
any_socket_alive = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Must let loop run for one more cycle to poll server for RST to be sent,
|
|
|
|
// this makes sure system does not reset right after socket.abort() is called.
|
|
|
|
if !any_socket_alive {
|
|
|
|
SCB::sys_reset();
|
|
|
|
}
|
2024-02-02 14:07:25 +08:00
|
|
|
}
|
2022-10-20 20:57:24 +08:00
|
|
|
}
|
2022-10-22 15:49:01 +08:00
|
|
|
}
|