change(config): improve how config is loaded from flash
Some checks failed
Publish nightly release / build (push) Has been cancelled
Some checks failed
Publish nightly release / build (push) Has been cancelled
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 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(¤t_config, &mut flash, &mut gcc_subscriber).await;
|
configuration_main_loop(¤t_config, &mut flash, &mut gcc_subscriber).await;
|
||||||
|
|
||||||
info!("Exiting config mode.");
|
info!("Exiting config mode.");
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
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.
|
// 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();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue