change(config): improve how config is loaded from flash

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 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(&current_config, &mut flash, &mut gcc_subscriber).await;
current_config =
configuration_main_loop(&current_config, &mut flash, &mut gcc_subscriber).await;
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.
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]
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;

View file

@ -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);

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.
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();
});
}