change(config): improve how config is loaded from flash
Some checks failed
Publish nightly release / build (push) Has been cancelled

This commit is contained in:
Naxdy 2024-04-03 14:33:23 +02:00
parent ef02ca6950
commit 5e102fd14f
Signed by: Naxdy
GPG key ID: CC15075846BCE91B
4 changed files with 57 additions and 53 deletions

View file

@ -16,7 +16,7 @@ use embassy_rp::{
use packed_struct::{derive::PackedStruct, PackedStruct}; use packed_struct::{derive::PackedStruct, PackedStruct};
use crate::{ use crate::{
gcc_hid::SIGNAL_CHANGE_RUMBLE_STRENGTH, gcc_hid::{SIGNAL_CHANGE_RUMBLE_STRENGTH, SIGNAL_INPUT_CONSISTENCY_MODE_STATUS},
helpers::{PackedFloat, ToPackedFloatArray, ToRegularArray, XyValuePair}, helpers::{PackedFloat, ToPackedFloatArray, ToRegularArray, XyValuePair},
input::{ input::{
read_ext_adc, Stick, StickAxis, StickState, FLOAT_ORIGIN, SPI_ACS_SHARED, SPI_CCS_SHARED, read_ext_adc, Stick, StickAxis, StickState, FLOAT_ORIGIN, SPI_ACS_SHARED, SPI_CCS_SHARED,
@ -568,7 +568,8 @@ impl ControllerConfig {
r.unwrap(); r.unwrap();
} }
match ControllerConfig::unpack(&controller_config_packed).unwrap() { match ControllerConfig::unpack(&controller_config_packed) {
Ok(cfg) => match cfg {
a if a.config_revision == CONTROLLER_CONFIG_REVISION => { a if a.config_revision == CONTROLLER_CONFIG_REVISION => {
info!("Controller config loaded from flash: {}", a); info!("Controller config loaded from flash: {}", a);
Ok(a) Ok(a)
@ -580,6 +581,13 @@ impl ControllerConfig {
cfg.write_to_flash(&mut flash)?; cfg.write_to_flash(&mut flash)?;
Ok(cfg) Ok(cfg)
} }
},
Err(_) => {
let cfg = ControllerConfig::default();
info!("Going to save default controller config.");
cfg.write_to_flash(&mut flash)?;
Ok(cfg)
}
} }
} }
@ -1063,7 +1071,7 @@ async fn configuration_main_loop<
current_config: &ControllerConfig, current_config: &ControllerConfig,
mut flash: &mut Flash<'static, FLASH, Async, FLASH_SIZE>, mut flash: &mut Flash<'static, FLASH, Async, FLASH_SIZE>,
gcc_subscriber: &mut Subscriber<'a, M, GcReport, C, S, P>, gcc_subscriber: &mut Subscriber<'a, M, GcReport, C, S, P>,
) { ) -> ControllerConfig {
let mut final_config = current_config.clone(); let mut final_config = current_config.clone();
let config_options = [ let config_options = [
EXIT_CONFIG_MODE_COMBO, EXIT_CONFIG_MODE_COMBO,
@ -1618,23 +1626,28 @@ async fn configuration_main_loop<
} }
info!("Exiting config main loop."); info!("Exiting config main loop.");
final_config
} }
#[embassy_executor::task] #[embassy_executor::task]
pub async fn config_task( pub async fn config_task(mut flash: Flash<'static, FLASH, Async, FLASH_SIZE>) {
current_config: ControllerConfig,
mut flash: Flash<'static, FLASH, Async, FLASH_SIZE>,
) {
let mut gcc_subscriber = CHANNEL_GCC_STATE.subscriber().unwrap(); let mut gcc_subscriber = CHANNEL_GCC_STATE.subscriber().unwrap();
info!("Config task is running."); 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); let mut current_config = ControllerConfig::from_flash_memory(&mut flash).unwrap();
SIGNAL_CONFIG_CHANGE.signal(new_config);
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 { loop {
let desired_config_state = SIGNAL_CONFIG_MODE_STATUS_CHANGE.wait().await; let desired_config_state = SIGNAL_CONFIG_MODE_STATUS_CHANGE.wait().await;
@ -1667,6 +1680,7 @@ pub async fn config_task(
}) })
.await; .await;
current_config =
configuration_main_loop(&current_config, &mut flash, &mut gcc_subscriber).await; configuration_main_loop(&current_config, &mut flash, &mut gcc_subscriber).await;
info!("Exiting config mode."); info!("Exiting config mode.");

View file

@ -30,6 +30,10 @@ static SIGNAL_RUMBLE: Signal<CriticalSectionRawMutex, bool> = Signal::new();
/// would just transmit unnecessary amounts of data. /// would just transmit unnecessary amounts of data.
pub static SIGNAL_CHANGE_RUMBLE_STRENGTH: Signal<CriticalSectionRawMutex, u8> = Signal::new(); pub static SIGNAL_CHANGE_RUMBLE_STRENGTH: Signal<CriticalSectionRawMutex, u8> = Signal::new();
/// Only dispatched ONCE after powerup, to determine how to advertise itself via USB.
pub static SIGNAL_INPUT_CONSISTENCY_MODE_STATUS: Signal<CriticalSectionRawMutex, bool> =
Signal::new();
#[rustfmt::skip] #[rustfmt::skip]
pub const GCC_REPORT_DESCRIPTOR: &[u8] = &[ pub const GCC_REPORT_DESCRIPTOR: &[u8] = &[
0x05, 0x01, // Usage Page (Generic Desktop Ctrls) 0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
@ -261,8 +265,8 @@ impl Handler for MyDeviceHandler {
} }
#[embassy_executor::task] #[embassy_executor::task]
pub async fn usb_transfer_task(driver: Driver<'static, USB>, input_consistency_mode: bool) { pub async fn usb_transfer_task(raw_serial: [u8; 8], driver: Driver<'static, USB>) {
let raw_serial = [0u8; 8]; let input_consistency_mode = SIGNAL_INPUT_CONSISTENCY_MODE_STATUS.wait().await;
let mut serial_buffer = [0u8; 64]; 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"); trace!("Start of config");
let mut usb_config = embassy_usb::Config::new(0x057e, 0x0337); let mut usb_config = embassy_usb::Config::new(0x057e, 0x0337);
usb_config.manufacturer = Some("Naxdy"); 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.serial_number = Some(serial);
usb_config.max_power = 200; usb_config.max_power = 200;
usb_config.max_packet_size_0 = 64; usb_config.max_packet_size_0 = 64;
@ -422,12 +430,11 @@ fn calc_rumble_power(strength: u8) -> u16 {
} }
#[embassy_executor::task] #[embassy_executor::task]
pub async fn rumble_task( pub async fn rumble_task(pwm_rumble: Pwm<'static, PWM_CH4>, pwm_brake: Pwm<'static, PWM_CH6>) {
strength: u8, let mut rumble_power = {
pwm_rumble: Pwm<'static, PWM_CH4>, let strength = SIGNAL_CHANGE_RUMBLE_STRENGTH.wait().await;
pwm_brake: Pwm<'static, PWM_CH6>, calc_rumble_power(strength)
) { };
let mut rumble_power = calc_rumble_power(strength);
loop { loop {
let new_rumble_status = SIGNAL_RUMBLE.wait().await; let new_rumble_status = SIGNAL_RUMBLE.wait().await;

View file

@ -511,13 +511,14 @@ pub async fn update_stick_states_task(
spi: Spi<'static, SPI0, embassy_rp::spi::Blocking>, spi: Spi<'static, SPI0, embassy_rp::spi::Blocking>,
spi_acs: Output<'static, AnyPin>, spi_acs: Output<'static, AnyPin>,
spi_ccs: Output<'static, AnyPin>, spi_ccs: Output<'static, AnyPin>,
mut controller_config: ControllerConfig,
) { ) {
Timer::after_secs(1).await; Timer::after_secs(1).await;
*SPI_SHARED.lock().await = Some(spi); *SPI_SHARED.lock().await = Some(spi);
*SPI_ACS_SHARED.lock().await = Some(spi_acs); *SPI_ACS_SHARED.lock().await = Some(spi_acs);
*SPI_CCS_SHARED.lock().await = Some(spi_ccs); *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 controlstick_params = StickParams::from_stick_config(&controller_config.astick_config);
let mut cstick_params = StickParams::from_stick_config(&controller_config.cstick_config); let mut cstick_params = StickParams::from_stick_config(&controller_config.cstick_config);
let mut filter_gains = FILTER_GAINS.get_normalized_gains(&controller_config); let mut filter_gains = FILTER_GAINS.get_normalized_gains(&controller_config);

View file

@ -64,9 +64,9 @@ fn main() -> ! {
// reading and writing from flash has to be done on the main thread, else funny things happen. // 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 mut flash = Flash::<_, Async, FLASH_SIZE>::new(p.FLASH, p.DMA_CH0);
let mut uid = [0u8; 8];
let controller_config = ControllerConfig::default(); flash.blocking_unique_id(&mut uid).unwrap();
let mosi = p.PIN_7; let mosi = p.PIN_7;
let miso = p.PIN_4; let miso = p.PIN_4;
@ -98,20 +98,9 @@ fn main() -> ! {
let executor1 = EXECUTOR1.init(Executor::new()); let executor1 = EXECUTOR1.init(Executor::new());
debug!("Mana"); debug!("Mana");
executor1.run(|spawner| { executor1.run(|spawner| {
spawner spawner.spawn(usb_transfer_task(uid, driver)).unwrap();
.spawn(usb_transfer_task(
driver,
controller_config.input_consistency_mode,
))
.unwrap();
spawner.spawn(enter_config_mode_task()).unwrap(); spawner.spawn(enter_config_mode_task()).unwrap();
spawner spawner.spawn(rumble_task(pwm_rumble, pwm_brake)).unwrap();
.spawn(rumble_task(
controller_config.rumble_strength,
pwm_rumble,
pwm_brake,
))
.unwrap();
// spawner.spawn(input_integrity_benchmark()).unwrap(); // spawner.spawn(input_integrity_benchmark()).unwrap();
spawner spawner
.spawn(update_button_state_task( .spawn(update_button_state_task(
@ -152,17 +141,10 @@ fn main() -> ! {
executor0.run(|spawner| { executor0.run(|spawner| {
// Config task has to run on core0 because it reads and writes to flash. // Config task has to run on core0 because it reads and writes to flash.
spawner spawner.spawn(config_task(flash)).unwrap();
.spawn(config_task(controller_config.clone(), flash))
.unwrap();
spawner spawner
.spawn(update_stick_states_task( .spawn(update_stick_states_task(spi, spi_acs, spi_ccs))
spi,
spi_acs,
spi_ccs,
controller_config,
))
.unwrap(); .unwrap();
}); });
} }