forked from NaxdyOrg/NaxGCC-FW
change(config): improve how config is loaded from flash
This commit is contained in:
parent
ef02ca6950
commit
5e102fd14f
4 changed files with 57 additions and 53 deletions
|
@ -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.");
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
32
src/main.rs
32
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();
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue