diff --git a/firmware/src/main.rs b/firmware/src/main.rs index 1c997d7..6a08b96 100644 --- a/firmware/src/main.rs +++ b/firmware/src/main.rs @@ -40,7 +40,9 @@ mod app { use heapless::{String, Vec}; use postcard::{from_bytes_cobs, to_vec_cobs}; - use cheapsdo_protocol::{DeviceMessage, HostMessage, PLLSettings, StatusMessage, PLL}; + use cheapsdo_protocol::{ + DeviceMessage, HostMessage, PLLResponseMessage, PLLSettings, StatusMessage, PLL, + }; use crate::nvstate::{self, NVState}; use crate::si5153; @@ -77,6 +79,7 @@ mod app { nvstate: NVState, flash: flash::Parts, i2c1: AppI2C1, + si_pll: si5153::Si5153, } const TARGET_FREQ: u64 = 10_000_000_000; // in millihertz @@ -242,6 +245,7 @@ mod app { defmt::info!("I2C Setup done"); let mut si_pll = si5153::Si5153::new(&i2c1); + si_pll.init(&mut i2c1, 10_000_000, 600_000_000, 600_000_000); match apply_pll_settings(nvstate.pll_settings.clone(), &mut si_pll, &mut i2c1) { Ok(pll_settings) => { if pll_settings != nvstate.pll_settings { @@ -268,6 +272,7 @@ mod app { nvstate, flash, i2c1, + si_pll, }, Local { board_led, @@ -396,7 +401,7 @@ mod app { } } - #[task(binds = USB_HP_CAN_TX, shared = [usb_dev, serial, buffer, device_status, nvstate, flash])] + #[task(binds = USB_HP_CAN_TX, shared = [usb_dev, serial, buffer, device_status, nvstate, flash, si_pll, i2c1])] fn usb_tx(cx: usb_tx::Context) { let mut usb_dev = cx.shared.usb_dev; let mut serial = cx.shared.serial; @@ -404,6 +409,8 @@ mod app { let mut device_status = cx.shared.device_status; let mut nvstate = cx.shared.nvstate; let mut flash = cx.shared.flash; + let mut si_pll = cx.shared.si_pll; + let mut i2c1 = cx.shared.i2c1; ( &mut usb_dev, @@ -412,13 +419,26 @@ mod app { &mut device_status, &mut nvstate, &mut flash, + &mut si_pll, + &mut i2c1, ) - .lock(|usb_dev, serial, buffer, device_status, nvstate, flash| { - usb_poll(usb_dev, serial, buffer, device_status, nvstate, flash); - }); + .lock( + |usb_dev, serial, buffer, device_status, nvstate, flash, si_pll, i2c1| { + usb_poll( + usb_dev, + serial, + buffer, + device_status, + nvstate, + flash, + si_pll, + i2c1, + ); + }, + ); } - #[task(binds = USB_LP_CAN_RX0, shared = [usb_dev, serial, buffer, device_status, nvstate, flash])] + #[task(binds = USB_LP_CAN_RX0, shared = [usb_dev, serial, buffer, device_status, nvstate, flash, si_pll, i2c1])] fn usb_rx0(cx: usb_rx0::Context) { let mut usb_dev = cx.shared.usb_dev; let mut serial = cx.shared.serial; @@ -426,6 +446,8 @@ mod app { let mut device_status = cx.shared.device_status; let mut nvstate = cx.shared.nvstate; let mut flash = cx.shared.flash; + let mut si_pll = cx.shared.si_pll; + let mut i2c1 = cx.shared.i2c1; ( &mut usb_dev, @@ -434,10 +456,23 @@ mod app { &mut device_status, &mut nvstate, &mut flash, + &mut si_pll, + &mut i2c1, ) - .lock(|usb_dev, serial, buffer, device_status, nvstate, flash| { - usb_poll(usb_dev, serial, buffer, device_status, nvstate, flash); - }); + .lock( + |usb_dev, serial, buffer, device_status, nvstate, flash, si_pll, i2c1| { + usb_poll( + usb_dev, + serial, + buffer, + device_status, + nvstate, + flash, + si_pll, + i2c1, + ); + }, + ); } fn usb_poll( @@ -447,6 +482,8 @@ mod app { device_status: &StatusMessage, nvstate: &mut NVState, flash: &mut flash::Parts, + si_pll: &mut si5153::Si5153, + i2c: &mut AppI2C1, ) { if !usb_dev.poll(&mut [serial]) { return; @@ -480,11 +517,30 @@ mod app { serial.write(bytes.as_slice()).unwrap(); } HostMessage::SetPLLSettings(settings) => { - nvstate.pll_settings = settings; - nvstate.save(flash); + let result = apply_pll_settings(settings, si_pll, i2c); + + let response = match result { + Ok(settings) => { + if settings != nvstate.pll_settings { + nvstate.pll_settings = settings; + nvstate.save(flash); + } + DeviceMessage::PLLResponse(PLLResponseMessage::Ok) + } + Err(err_msg) => { + DeviceMessage::PLLResponse(PLLResponseMessage::Error(err_msg)) + } + }; + + let bytes = + to_vec_cobs::(&response).unwrap(); + serial.write(bytes.as_slice()).unwrap(); } HostMessage::GetPllSettings => { - defmt::error!("PLL output is not implemented yet") + let response = DeviceMessage::PLLSettings(nvstate.pll_settings); + let bytes = + to_vec_cobs::(&response).unwrap(); + serial.write(bytes.as_slice()).unwrap(); } }, Err(err) => defmt::error!("Unable to parse host message: {}", err), @@ -532,10 +588,6 @@ mod app { } for i in 0..settings.outputs.len() { - if !settings.outputs[i].enable { - continue; - } - if settings.outputs[i].frequency < MIN_OUTPUT_FREQ || settings.outputs[i].frequency > MAX_OUTPUT_FREQ { @@ -553,7 +605,7 @@ mod app { settings.pll_a_frequency = si_pll.set_pll_freq(i2c, si5153::PLL::A, settings.pll_a_frequency); settings.pll_b_frequency = - si_pll.set_pll_freq(i2c, si5153::PLL::B, settings.pll_a_frequency); + si_pll.set_pll_freq(i2c, si5153::PLL::B, settings.pll_b_frequency); let multisynths = [ si5153::Multisynth::MS0, @@ -566,6 +618,7 @@ mod app { } si_pll.set_ms_source(i2c, ms, output_settings.source.into()); + defmt::debug!("Setting {} to {}Hz", ms as usize, output_settings.frequency); output_settings.frequency = si_pll.set_ms_freq(i2c, ms, output_settings.frequency); if output_settings.enable { diff --git a/protocol/src/lib.rs b/protocol/src/lib.rs index 993b989..d118298 100644 --- a/protocol/src/lib.rs +++ b/protocol/src/lib.rs @@ -34,7 +34,7 @@ impl Default for StatusMessage { } } -#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Copy)] pub struct PLLSettings { pub pll_a_frequency: u32, pub pll_b_frequency: u32, @@ -55,7 +55,7 @@ impl Default for PLLSettings { } } -#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Copy)] pub struct OutputSettings { pub frequency: u32, pub enable: bool,