1
0
Fork 0
kirdy-firmware/src/main.rs

237 lines
8.2 KiB
Rust
Raw Normal View History

#![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;
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;
mod thermostat;
mod net;
2022-10-22 21:00:17 +08:00
use device::{boot::bootup, log_setup, sys_timer};
use crate::net::net::IpSettings;
use serde::{Deserialize, Serialize};
use stm32f4xx_hal::pac::SCB;
2022-10-22 21:00:17 +08:00
// If RTT is used, print panic info through RTT
#[cfg(all(feature = "RTT", not(test)))]
use {core::panic::PanicInfo, rtt_target::rprintln};
#[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
#[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
static mut ETH_DATA_BUFFER: [u8; 1024] = [0; 1024];
#[derive(Deserialize, Serialize, Clone, Copy, Debug)]
2024-02-19 15:08:00 +08:00
pub struct DeviceSettings{
report_readings: bool,
ip_settings: IpSettings,
2024-02-19 15:08:00 +08:00
}
const CONFIG_KEY: [&str; 3] = ["Device", "Laser_0", "Thermostat_0"];
#[derive(Default)]
pub enum State {
#[default]
LoadFlashSettings,
MainLoop,
SaveFlashSettings,
HardReset,
}
#[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();
let (mut wd, mut flash_store, mut laser, mut thermostat,) = bootup(core_perif, perif);
2024-02-19 15:08:00 +08:00
let mut device_settings = DeviceSettings {
report_readings: false,
ip_settings: IpSettings::default()
2024-02-19 15:08:00 +08:00
};
let mut state = State::default();
2022-10-20 20:57:24 +08:00
loop {
wd.feed();
net::net::eth_poll_and_update_link_speed();
match state {
State::LoadFlashSettings => {
// State Transition
state = State::MainLoop;
wd.feed();
let device_settings_flash: DeviceSettings;
match flash_store.read_value(CONFIG_KEY[0]) {
Ok(Some(config)) => {
device_settings_flash = config;
debug!("Found Device Settings");
}
Ok(None) => {
debug!("Flash does not have Device Settings");
continue;
}
Err(e) => {
debug!("Cannot Store Flash: {:?}", e);
continue;
}
}
wd.feed();
let laser_settings: laser_diode::laser_diode::LdSettingsSummary;
match flash_store.read_value(CONFIG_KEY[1]) {
Ok(Some(config)) => {
laser_settings = config;
debug!("Found Laser Diode Settings");
}
Ok(None) => {
debug!("Does not have laser diode Settings");
continue;
}
Err(e) => {
debug!("Cannot Store Flash: {:?}", e);
continue;
}
}
wd.feed();
let thermostat_settings: thermostat::thermostat::ThermostatSettingsSummary;
match flash_store.read_value(CONFIG_KEY[2]) {
Ok(Some(config)) => {
thermostat_settings = config;
debug!("Found Thermostat Settings");
}
Ok(None) => {
debug!("Does not have thermostat Settings");
continue;
}
Err(e) => {
debug!("Cannot Store Flash: {:?}", e);
continue;
}
}
wd.feed();
device_settings = device_settings_flash;
thermostat.load_settings_from_summary(thermostat_settings);
laser.load_settings_from_summary(laser_settings);
}
State::MainLoop => {
let mut eth_is_pending = false;
let mut has_temp_reading = false;
laser.poll_and_update_output_current();
if thermostat.poll_adc() {
has_temp_reading = true;
thermostat.update_pid();
if thermostat.get_temp_mon_status().over_temp_alarm {
laser.power_down();
thermostat.set_pid_engaged(false);
thermostat.power_down();
}
if net::net::eth_is_socket_active() {
if device_settings.report_readings {
unsafe {
net::cmd_handler::send_status_report(&mut ETH_DATA_BUFFER, &mut laser, &mut thermostat);
}
2024-02-19 15:08:00 +08:00
}
}
}
if net::net::eth_is_socket_active() {
cortex_m::interrupt::free(|cs|
{
eth_is_pending = net::net::is_pending(cs);
2024-03-01 11:27:02 +08:00
}
);
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);
if bytes != 0 {
info!("Ts: {:?}", sys_timer::now());
debug!("Number of bytes recv: {:?}", bytes);
// State Transition
(laser, thermostat, state, device_settings) = net::cmd_handler::execute_cmd(&mut ETH_DATA_BUFFER, bytes, laser, thermostat, state, device_settings);
}
}
}
if has_temp_reading {
thermostat.start_tec_readings_conversion();
}
}
}
State::SaveFlashSettings => {
// State Transition
state = State::MainLoop;
wd.feed();
let mut store_value_buf = [0u8; 1024];
match flash_store.write_value(CONFIG_KEY[0], &device_settings, &mut store_value_buf) {
Ok(()) => {
debug!("Device Settings is stored in flash");
}
Err(e) => {
debug!("Cannot Store Flash: {:?}", e);
}
}
wd.feed();
match flash_store.write_value(CONFIG_KEY[1], &laser.get_settings_summary(), &mut store_value_buf) {
Ok(()) => {
debug!("Laser Diode Settings is stored in flash");
}
Err(e) => {
debug!("Cannot Store Flash: {:?}", e);
}
}
wd.feed();
match flash_store.write_value(CONFIG_KEY[2], &thermostat.get_settings_summary(), &mut store_value_buf) {
Ok(()) => {
debug!("Thermostat Settings is stored in flash");
}
Err(e) => {
debug!("Cannot Store Flash: {:?}", e);
}
}
2024-02-19 15:08:00 +08:00
}
State::HardReset => {
wd.feed();
laser.power_down();
thermostat.power_down();
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();
}
}
}
2022-10-20 20:57:24 +08:00
}
2022-10-22 15:49:01 +08:00
}