Merge pull request 'Store pwm settings in flash' (#2) from nonvolatile-state into main
/ audit (push) Successful in 19s Details
/ build-firmware (push) Successful in 24s Details
/ build-linux (push) Successful in 1m19s Details
/ build-windows (push) Successful in 1m42s Details
/ build-appimage (push) Successful in 3m31s Details

Reviewed-on: #2
This commit is contained in:
Sebastian 2024-01-17 18:39:26 +01:00
commit c2b7bf9e1e
4 changed files with 71 additions and 3 deletions

View File

@ -26,3 +26,4 @@ cheapsdo-protocol = { path = "../protocol" }
postcard = {version = "1.0.8", features = ["use-defmt"]}
heapless = {version = "0.8.0", features = ["defmt-03"]}
num = {version = "0.4.1", default-features = false, features = ["libm"]}
serde = { version = "1.0.195", default-features = false }

View File

@ -6,6 +6,7 @@ use defmt_rtt as _; // global logger
use panic_probe as _;
use stm32f1xx_hal as _;
mod nvstate;
mod si5153;
// same panicking *behavior* as `panic-probe` but doesn't print a panic message
@ -24,6 +25,7 @@ mod app {
use rtic_monotonics::systick::*;
use stm32f1xx_hal::{
flash::{self, FlashWriter},
gpio::{self, gpioa, gpioc, Alternate, Output, PushPull},
i2c, pac,
pac::{RCC, TIM2, TIM3, TIM4},
@ -41,6 +43,7 @@ mod app {
use cheapsdo_protocol::{DeviceMessage, HostMessage, StatusMessage};
use crate::nvstate::{self, NVState};
use crate::si5153;
const USB_BUFFER_SIZE: usize = 64;
@ -51,6 +54,8 @@ mod app {
tim2: TIM2,
tim3: TIM3,
pwm: PwmHz<TIM4, Tim4NoRemap, timer::Ch<0>, gpio::Pin<'B', 6, Alternate>>,
nvstate: NVState,
flash: flash::Parts,
}
#[shared]
@ -229,6 +234,10 @@ mod app {
si_pll.set_ms_freq(&mut i2c1, si5153::Multisynth::MS0, 100_000_000);
si_pll.enable_ms_output(&mut i2c1, si5153::Multisynth::MS0);
let nvstate = nvstate::load(&mut flash);
defmt::info!("read nvstate from flash");
update_pwm::spawn().unwrap();
(
@ -243,13 +252,15 @@ mod app {
tim2,
tim3,
pwm,
nvstate,
flash,
},
)
}
const WINDOW_LEN: usize = 100;
#[task(local=[tim2, tim3, pwm, board_led], shared=[device_status])]
#[task(local=[tim2, tim3, pwm, board_led, nvstate, flash], shared=[device_status])]
async fn update_pwm(mut cx: update_pwm::Context) {
defmt::info!("Update Task started");
@ -257,9 +268,16 @@ mod app {
let tim3 = cx.local.tim3;
let pwm = cx.local.pwm;
let board_led = cx.local.board_led;
let mut nvstate = cx.local.nvstate;
let mut flash = cx.local.flash;
let max_pwm = pwm.get_max_duty() as i32;
let mut cur_pwm = max_pwm / 2;
let mut cur_pwm = nvstate.pwm as i32;
cur_pwm = if cur_pwm < 0 { 0 } else { cur_pwm };
cur_pwm = if cur_pwm > max_pwm { max_pwm } else { cur_pwm };
pwm.set_duty(Channel::C1, cur_pwm as u16);
defmt::info!("pwm:\t{}", cur_pwm);
// Inialize last_ic
while !tim2.sr.read().cc1if().bit_is_set() || !tim3.sr.read().cc1if().bit_is_set() {
@ -343,6 +361,9 @@ mod app {
pwm.set_duty(Channel::C1, cur_pwm as u16);
defmt::info!("pwm:\t{}", cur_pwm);
nvstate.pwm = cur_pwm as u16;
nvstate.save(&mut flash);
Systick::delay(500.millis()).await;
}
}

45
firmware/src/nvstate.rs Normal file
View File

@ -0,0 +1,45 @@
use postcard::{from_bytes_cobs, to_slice_cobs};
use serde::{Deserialize, Serialize};
use stm32f1xx_hal::flash::{self, FlashSize, FlashWriter, SectorSize};
#[derive(Serialize, Deserialize, Debug, PartialEq)]
pub struct NVState {
pub pwm: u16,
}
impl Default for NVState {
fn default() -> Self {
Self { pwm: 1500u16 }
}
}
const PAGE_SIZE: usize = 1024;
const NVSTATE_OFFSET: u32 = 63 * PAGE_SIZE as u32;
const FLASH_SIZE: FlashSize = FlashSize::Sz64K;
const SECTOR_SIZE: SectorSize = SectorSize::Sz1K;
pub fn load(flash: &mut flash::Parts) -> NVState {
let mut flash_writer = flash.writer(SECTOR_SIZE, FLASH_SIZE);
let tmp = flash_writer.read(NVSTATE_OFFSET, PAGE_SIZE).unwrap();
let mut nvstate_page = [0u8; PAGE_SIZE];
nvstate_page.copy_from_slice(tmp);
match from_bytes_cobs::<NVState>(&mut nvstate_page) {
Ok(nvstate) => nvstate,
Err(_) => NVState::default(),
}
}
impl NVState {
pub fn save(&self, flash: &mut flash::Parts) {
let mut flash_writer = flash.writer(SECTOR_SIZE, FLASH_SIZE);
let mut page = [0u8; PAGE_SIZE];
let used = to_slice_cobs(self, &mut page).unwrap();
flash_writer.page_erase(NVSTATE_OFFSET).unwrap();
flash_writer.write(NVSTATE_OFFSET, &used).unwrap();
}
}

View File

@ -1,6 +1,7 @@
/* Linker script for the STM32F103C8T6 */
MEMORY
{
FLASH : ORIGIN = 0x08000000, LENGTH = 64K
FLASH : ORIGIN = 0x08000000, LENGTH = 63K
NVSTATE : ORIGIN = FLASH + 63K, LENGTH = 1K
RAM : ORIGIN = 0x20000000, LENGTH = 20K
}