From 5e102fd14f82bdaff36472100999f67905ffe614 Mon Sep 17 00:00:00 2001 From: Naxdy Date: Wed, 3 Apr 2024 14:33:23 +0200 Subject: [PATCH] change(config): improve how config is loaded from flash --- src/config.rs | 50 ++++++++++++++++++++++++++++++++------------------ src/gcc_hid.rs | 25 ++++++++++++++++--------- src/input.rs | 3 ++- src/main.rs | 32 +++++++------------------------- 4 files changed, 57 insertions(+), 53 deletions(-) diff --git a/src/config.rs b/src/config.rs index 07fda71..2a2bee7 100644 --- a/src/config.rs +++ b/src/config.rs @@ -16,7 +16,7 @@ use embassy_rp::{ use packed_struct::{derive::PackedStruct, PackedStruct}; use crate::{ - gcc_hid::SIGNAL_CHANGE_RUMBLE_STRENGTH, + gcc_hid::{SIGNAL_CHANGE_RUMBLE_STRENGTH, SIGNAL_INPUT_CONSISTENCY_MODE_STATUS}, helpers::{PackedFloat, ToPackedFloatArray, ToRegularArray, XyValuePair}, input::{ read_ext_adc, Stick, StickAxis, StickState, FLOAT_ORIGIN, SPI_ACS_SHARED, SPI_CCS_SHARED, @@ -568,13 +568,21 @@ impl ControllerConfig { r.unwrap(); } - match ControllerConfig::unpack(&controller_config_packed).unwrap() { - a if a.config_revision == CONTROLLER_CONFIG_REVISION => { - info!("Controller config loaded from flash: {}", a); - Ok(a) - } - a => { - warn!("Outdated controller config detected ({:02X}), or controller config was never present, using default.", a.config_revision); + match ControllerConfig::unpack(&controller_config_packed) { + Ok(cfg) => match cfg { + a if a.config_revision == CONTROLLER_CONFIG_REVISION => { + info!("Controller config loaded from flash: {}", a); + Ok(a) + } + a => { + warn!("Outdated controller config detected ({:02X}), or controller config was never present, using default.", a.config_revision); + let cfg = ControllerConfig::default(); + info!("Going to save default controller config."); + cfg.write_to_flash(&mut flash)?; + Ok(cfg) + } + }, + Err(_) => { let cfg = ControllerConfig::default(); info!("Going to save default controller config."); cfg.write_to_flash(&mut flash)?; @@ -1063,7 +1071,7 @@ async fn configuration_main_loop< current_config: &ControllerConfig, mut flash: &mut Flash<'static, FLASH, Async, FLASH_SIZE>, gcc_subscriber: &mut Subscriber<'a, M, GcReport, C, S, P>, -) { +) -> ControllerConfig { let mut final_config = current_config.clone(); let config_options = [ EXIT_CONFIG_MODE_COMBO, @@ -1618,23 +1626,28 @@ async fn configuration_main_loop< } info!("Exiting config main loop."); + + final_config } #[embassy_executor::task] -pub async fn config_task( - current_config: ControllerConfig, - mut flash: Flash<'static, FLASH, Async, FLASH_SIZE>, -) { +pub async fn config_task(mut flash: Flash<'static, FLASH, Async, FLASH_SIZE>) { let mut gcc_subscriber = CHANNEL_GCC_STATE.subscriber().unwrap(); info!("Config task is running."); - Timer::after_millis(100).await; + // We are loading the config from flash slightly deferred mainly because + // if a debug probe is connected, it could potentially interfere. + // This means we need to dispatch "updated" config status at least once to the + // other tasks. - let new_config = ControllerConfig::from_flash_memory(&mut flash).unwrap(); + Timer::after_millis(10).await; - SIGNAL_CHANGE_RUMBLE_STRENGTH.signal(new_config.rumble_strength); - SIGNAL_CONFIG_CHANGE.signal(new_config); + let mut current_config = ControllerConfig::from_flash_memory(&mut flash).unwrap(); + + SIGNAL_INPUT_CONSISTENCY_MODE_STATUS.signal(current_config.input_consistency_mode); + SIGNAL_CHANGE_RUMBLE_STRENGTH.signal(current_config.rumble_strength); + SIGNAL_CONFIG_CHANGE.signal(current_config.clone()); loop { let desired_config_state = SIGNAL_CONFIG_MODE_STATUS_CHANGE.wait().await; @@ -1667,7 +1680,8 @@ pub async fn config_task( }) .await; - configuration_main_loop(¤t_config, &mut flash, &mut gcc_subscriber).await; + current_config = + configuration_main_loop(¤t_config, &mut flash, &mut gcc_subscriber).await; info!("Exiting config mode."); diff --git a/src/gcc_hid.rs b/src/gcc_hid.rs index 71caf60..e7e1d3a 100644 --- a/src/gcc_hid.rs +++ b/src/gcc_hid.rs @@ -30,6 +30,10 @@ static SIGNAL_RUMBLE: Signal = Signal::new(); /// would just transmit unnecessary amounts of data. pub static SIGNAL_CHANGE_RUMBLE_STRENGTH: Signal = Signal::new(); +/// Only dispatched ONCE after powerup, to determine how to advertise itself via USB. +pub static SIGNAL_INPUT_CONSISTENCY_MODE_STATUS: Signal = + Signal::new(); + #[rustfmt::skip] pub const GCC_REPORT_DESCRIPTOR: &[u8] = &[ 0x05, 0x01, // Usage Page (Generic Desktop Ctrls) @@ -261,8 +265,8 @@ impl Handler for MyDeviceHandler { } #[embassy_executor::task] -pub async fn usb_transfer_task(driver: Driver<'static, USB>, input_consistency_mode: bool) { - let raw_serial = [0u8; 8]; +pub async fn usb_transfer_task(raw_serial: [u8; 8], driver: Driver<'static, USB>) { + let input_consistency_mode = SIGNAL_INPUT_CONSISTENCY_MODE_STATUS.wait().await; let mut serial_buffer = [0u8; 64]; @@ -287,7 +291,11 @@ pub async fn usb_transfer_task(driver: Driver<'static, USB>, input_consistency_m trace!("Start of config"); let mut usb_config = embassy_usb::Config::new(0x057e, 0x0337); usb_config.manufacturer = Some("Naxdy"); - usb_config.product = Some("NaxGCC"); + usb_config.product = Some(if input_consistency_mode { + "NaxGCC (Consistency Mode)" + } else { + "NaxGCC (OG Mode)" + }); usb_config.serial_number = Some(serial); usb_config.max_power = 200; usb_config.max_packet_size_0 = 64; @@ -422,12 +430,11 @@ fn calc_rumble_power(strength: u8) -> u16 { } #[embassy_executor::task] -pub async fn rumble_task( - strength: u8, - pwm_rumble: Pwm<'static, PWM_CH4>, - pwm_brake: Pwm<'static, PWM_CH6>, -) { - let mut rumble_power = calc_rumble_power(strength); +pub async fn rumble_task(pwm_rumble: Pwm<'static, PWM_CH4>, pwm_brake: Pwm<'static, PWM_CH6>) { + let mut rumble_power = { + let strength = SIGNAL_CHANGE_RUMBLE_STRENGTH.wait().await; + calc_rumble_power(strength) + }; loop { let new_rumble_status = SIGNAL_RUMBLE.wait().await; diff --git a/src/input.rs b/src/input.rs index 2d4b6b5..33b649d 100644 --- a/src/input.rs +++ b/src/input.rs @@ -511,13 +511,14 @@ pub async fn update_stick_states_task( spi: Spi<'static, SPI0, embassy_rp::spi::Blocking>, spi_acs: Output<'static, AnyPin>, spi_ccs: Output<'static, AnyPin>, - mut controller_config: ControllerConfig, ) { Timer::after_secs(1).await; *SPI_SHARED.lock().await = Some(spi); *SPI_ACS_SHARED.lock().await = Some(spi_acs); *SPI_CCS_SHARED.lock().await = Some(spi_ccs); + let mut controller_config = SIGNAL_CONFIG_CHANGE.wait().await; + let mut controlstick_params = StickParams::from_stick_config(&controller_config.astick_config); let mut cstick_params = StickParams::from_stick_config(&controller_config.cstick_config); let mut filter_gains = FILTER_GAINS.get_normalized_gains(&controller_config); diff --git a/src/main.rs b/src/main.rs index 446c1c1..202e3b0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -64,9 +64,9 @@ fn main() -> ! { // reading and writing from flash has to be done on the main thread, else funny things happen. - let flash = Flash::<_, Async, FLASH_SIZE>::new(p.FLASH, p.DMA_CH0); - - let controller_config = ControllerConfig::default(); + let mut flash = Flash::<_, Async, FLASH_SIZE>::new(p.FLASH, p.DMA_CH0); + let mut uid = [0u8; 8]; + flash.blocking_unique_id(&mut uid).unwrap(); let mosi = p.PIN_7; let miso = p.PIN_4; @@ -98,20 +98,9 @@ fn main() -> ! { let executor1 = EXECUTOR1.init(Executor::new()); debug!("Mana"); executor1.run(|spawner| { - spawner - .spawn(usb_transfer_task( - driver, - controller_config.input_consistency_mode, - )) - .unwrap(); + spawner.spawn(usb_transfer_task(uid, driver)).unwrap(); spawner.spawn(enter_config_mode_task()).unwrap(); - spawner - .spawn(rumble_task( - controller_config.rumble_strength, - pwm_rumble, - pwm_brake, - )) - .unwrap(); + spawner.spawn(rumble_task(pwm_rumble, pwm_brake)).unwrap(); // spawner.spawn(input_integrity_benchmark()).unwrap(); spawner .spawn(update_button_state_task( @@ -152,17 +141,10 @@ fn main() -> ! { executor0.run(|spawner| { // Config task has to run on core0 because it reads and writes to flash. - spawner - .spawn(config_task(controller_config.clone(), flash)) - .unwrap(); + spawner.spawn(config_task(flash)).unwrap(); spawner - .spawn(update_stick_states_task( - spi, - spi_acs, - spi_ccs, - controller_config, - )) + .spawn(update_stick_states_task(spi, spi_acs, spi_ccs)) .unwrap(); }); }