diff --git a/gem-remotes-esp32/src/ble_server.rs b/gem-remotes-esp32/src/ble_server.rs index 5e33301..fdd4cad 100644 --- a/gem-remotes-esp32/src/ble_server.rs +++ b/gem-remotes-esp32/src/ble_server.rs @@ -9,7 +9,7 @@ use std::str::FromStr; use std::sync::Arc; use crate::dispatch::{Dispatch, RecvQ, SendQ}; -use crate::commands::Commands; +use crate::commands::{Button, Commands}; // TODO HARDWARE: test these values to see if they are suitable const BLE_MIN_INTERVAL: u16 = 24; // x 1.25ms @@ -37,6 +37,9 @@ const UUID_BUTTON_DOWN: BleUuid = uuid128!("c1401122-8dda-45a3-959b-d23a0f8f53d7 const UUID_BUTTON_STOP: BleUuid = uuid128!("c1401123-8dda-45a3-959b-d23a0f8f53d7"); const UUID_BLUETOOTH_NAME: BleUuid = uuid128!("c1401224-8dda-45a3-959b-d23a0f8f53d7"); +const BLE_BUTTON_RELEASE: u8 = 0; +const BLE_BUTTON_PRESS: u8 = 1; + pub struct BleServer { send_q: SendQ, recv_q: RecvQ, @@ -48,9 +51,9 @@ pub struct BleServer { impl BleServer { pub fn new(dp: &mut Dispatch) -> Self { let cmds = vec![ - Commands::NotifyMotorDown { data: 0 }, - Commands::NotifyMotorStop { data: 0 }, - Commands::NotifyMotorUp { data: 0 }, + Commands::NotifyMotorDown { data: Button::Released }, + Commands::NotifyMotorStop { data: Button::Released }, + Commands::NotifyMotorUp { data: Button::Released }, Commands::PairTimerExpired, Commands::AllowPairing, Commands::EraseBleBonds, @@ -110,7 +113,7 @@ impl BleServer { ); button_stop.lock().set_value(&[1]) .on_write(closure!(clone sender, |args: &mut OnWriteArgs| { - on_bluetooth_cmd(&sender, args, Commands::BluetoothStop {_data: 0}) + on_bluetooth_cmd(&sender, args, Commands::BluetoothStop {data: 0}) })); // --- Device Name Bluetooth GATT -------------------------------------------------------- let device_name = lift_service.lock().create_characteristic( @@ -131,13 +134,13 @@ impl BleServer { match cmd { // TODO DISCUSS: This logic (if one button is pressed others are released) could be done in app instead. Commands::NotifyMotorUp{data} => { - button_up.lock().set_value(&[data]).notify(); + button_up.lock().set_value(&button_to_ble_button(data)).notify(); } Commands::NotifyMotorDown{data} => { - button_down.lock().set_value(&[data]).notify(); + button_down.lock().set_value(&button_to_ble_button(data)).notify(); } Commands::NotifyMotorStop{data} => { - button_up.lock().set_value(&[data]).notify(); + button_up.lock().set_value(&button_to_ble_button(data)).notify(); } Commands::PairTimerExpired => { self.advertise_unpairable()?; @@ -216,9 +219,9 @@ fn on_bluetooth_cmd(sender: &SendQ, args: &mut OnWriteArgs, cmd: Commands) { sender.send_blocking(Commands::BluetoothDown {data: v[0]} ) } else {error!("Received zero-byte bluetooth characteristic update {:?}", cmd); Ok(())} } - Commands::BluetoothStop { _data: _ } => { + Commands::BluetoothStop { data: _ } => { if v.len() > 0 { - sender.send_blocking(Commands::BluetoothStop {_data: v[0]} ) + sender.send_blocking(Commands::BluetoothStop {data: v[0]} ) } else {error!("Received zero-byte bluetooth characteristic update {:?}", cmd); Ok(())} } Commands::BluetoothName { data: _ } => { @@ -272,5 +275,12 @@ fn set_server_callbacks(server: &mut BLEServer, sender: SendQ) { }); } +fn button_to_ble_button(but: Button) -> [u8; 1] { + match but { + Button::Released => {[BLE_BUTTON_RELEASE]} + Button::Pressed => {[BLE_BUTTON_PRESS]} + } +} + //TODO set maximum pairs to remember? //TODO after disconnect, it returns to scanning - will it return to directed scanning? Find out when directed is working. \ No newline at end of file diff --git a/gem-remotes-esp32/src/commands.rs b/gem-remotes-esp32/src/commands.rs index 91a9ea6..8862708 100644 --- a/gem-remotes-esp32/src/commands.rs +++ b/gem-remotes-esp32/src/commands.rs @@ -6,42 +6,58 @@ use std::sync::Arc; #[derive(Clone, EnumCountMacro, Debug)] pub enum Commands { + // Use Arc for any data larger than 4 bytes, to keep message passing queue size down. // Inputs sent from the PIC microcontroller - PicRecvUp, - PicRecvDown, - PicRecvStop, + // TODO: move these to buttons driver, for eventual move to ESP only? + + // PIC button commands are considered "remote" due to the delay in sending notification + PicRecvUp {data: u8}, + PicRecvDown {data: u8}, + PicRecvStop {data: u8}, + PicRecvLimitUp {data: u8}, // 0 for not hit, 1 for hit + PicRecvLimitDown {data: u8}, // 0 for not hit, 1 for hit + PicRecvAutoMode {data: u8}, // 0 for disallowed, 1 for allowed + + // TODO: real hardware buttons - consider re-sending occasionally when pressed, so that transitions like holding up -> stopping -> holding down -> stopped -> (should go down but gets no new notice) work. // Inputs from bluetooth - BluetoothUp {data: u8}, + BluetoothUp {data: u8}, //TODO change these to real button states and change them on input. BluetoothDown {data: u8}, - BluetoothStop {_data: u8}, // There is no state where releasing the stop button induces a change. - BluetoothName { data: Arc}, + BluetoothStop {data: u8}, // There is no state where releasing the stop button induces a change. + BluetoothName {data: Arc}, + //TODO: Allow auto mode to be set via bluetooth as well // Internal messages StopTimerExpired, // Sent when the 2 second stop sequence is complete StopTimerRestart, StopTimerClear, - ButtonTimerExpired, + ButtonTimerExpired, // TODO: these won't be necessary for hardware buttons; rename to PIC timer? ButtonTimerRestart, ButtonTimerClear, PairTimerExpired, AllowPairing, // Also serves as the timer restart command PairTimerClear, - NotifyMotorUp {data: u8}, - NotifyMotorDown {data: u8}, - NotifyMotorStop {data: u8}, + NotifyMotorUp {data: Button}, + NotifyMotorDown {data: Button}, + NotifyMotorStop {data: Button}, EraseBleBonds, } #[non_exhaustive] -pub struct Button; +/*pub struct Button; impl Button { pub const PRESSED: u8 = 0x1; pub const RELEASED: u8 = 0x0; +}*/ + +#[derive(Copy, Clone, Debug)] +pub enum Button { + Released = 0, + Pressed =1 } pub type CmdType = std::mem::Discriminant; diff --git a/gem-remotes-esp32/src/motor_controller.rs b/gem-remotes-esp32/src/motor_controller.rs index 7f32731..d1dbe9e 100644 --- a/gem-remotes-esp32/src/motor_controller.rs +++ b/gem-remotes-esp32/src/motor_controller.rs @@ -10,41 +10,65 @@ use crate::motor_driver::Commands as MotorCommands; use crate::motor_driver::SendQ as MotorSendQ; use crate::dispatch::{Dispatch, RecvQ, SendQ}; -#[derive(Debug, PartialEq, Clone)] +#[derive(Clone, Copy, Debug, PartialEq)] enum ControllerStates { Stopped, Stopping, GoingUp, + AutoUp, GoingDown, + AutoDown, //TODO: AutoUp and AutoDown } +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum AutoMode { + Disallowed = 0, + Allowed = 1, +} + +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum LimitState { + NoLimitsHit, + UpperHit, + LowerHit, + BothHit, +} + pub struct Controller { state: ControllerStates, recv: RecvQ, send: SendQ, - motor_q: MotorSendQ + motor_q: MotorSendQ, + auto_mode: AutoMode, + limit_state: LimitState, } impl Controller { - pub fn new(recv: RecvQ, send: SendQ, motor_q: MotorSendQ) -> Controller { + pub fn new(recv: RecvQ, send: SendQ, motor_q: MotorSendQ) -> Self { Controller { state: ControllerStates::Stopping, recv: recv, send: send, - motor_q: motor_q} + motor_q: motor_q, + auto_mode: AutoMode::Disallowed, // Use safe default + limit_state: LimitState::BothHit, // Use safe default + } } /// Tell the message dispatch which messages we are interested in receiving, and get /// a callback channel that receives those messages. pub fn prepare_controller(dp: &mut Dispatch) -> RecvQ { let cmds = vec![ - Commands::PicRecvUp, - Commands::PicRecvDown, - Commands::PicRecvStop, + Commands::PicRecvUp{data: 0}, + Commands::PicRecvDown{data: 0}, + Commands::PicRecvStop{data: 0}, Commands::BluetoothUp{data: 0}, Commands::BluetoothDown{data: 0}, - Commands::BluetoothStop{_data: 0}, + Commands::BluetoothStop{data: 0}, + Commands::PicRecvLimitUp{data: 0}, + Commands::PicRecvLimitDown{data: 0}, + Commands::PicRecvAutoMode{data: 0}, Commands::StopTimerExpired, Commands::ButtonTimerExpired, ]; @@ -55,34 +79,31 @@ impl Controller { match new_s { ControllerStates::Stopped => { // Other notify commands are sent directly from the motor controller - self.send.send(Commands::NotifyMotorStop{data: Button::RELEASED}).await?; + self.send.send(Commands::NotifyMotorStop{data: Button::Released}).await?; } ControllerStates::Stopping => { self.send.send(Commands::StopTimerRestart).await?; self.motor_q.send(MotorCommands::Stop).await?; - self.send.send(Commands::NotifyMotorStop{data: Button::PRESSED}).await?; + self.send.send(Commands::NotifyMotorStop{data: Button::Pressed}).await?; } ControllerStates::GoingUp => { self.send.send(Commands::ButtonTimerRestart).await?; self.motor_q.send(MotorCommands::StartUp).await?; - self.send.send(Commands::NotifyMotorUp{data: Button::PRESSED}).await?; + self.send.send(Commands::NotifyMotorUp{data: Button::Pressed}).await?; + } + ControllerStates::AutoUp => { + self.motor_q.send(MotorCommands::StartUp).await?; + self.send.send(Commands::NotifyMotorUp{data: Button::Pressed}).await?; } ControllerStates::GoingDown => { self.send.send(Commands::ButtonTimerRestart).await?; self.motor_q.send(MotorCommands::StartDown).await?; - self.send.send(Commands::NotifyMotorUp{data: Button::PRESSED}).await?; + self.send.send(Commands::NotifyMotorUp{data: Button::Pressed}).await?; + } + ControllerStates::AutoDown => { + self.motor_q.send(MotorCommands::StartDown).await?; + self.send.send(Commands::NotifyMotorUp{data: Button::Pressed}).await?; } - } - Ok(()) - } - - /// Maintain the current state - e.g. reset button timers, etc. - async fn maintain_state(&mut self) -> Result<()> { - match self.state { - ControllerStates::Stopped => {} - ControllerStates::Stopping => {} // Do not reset this timer; let it expire. - ControllerStates::GoingUp => {self.send.send(Commands::ButtonTimerRestart).await?;} - ControllerStates::GoingDown => {self.send.send(Commands::ButtonTimerRestart).await?;} } Ok(()) } @@ -95,80 +116,169 @@ impl Controller { } ControllerStates::GoingUp => { self.send.send(Commands::ButtonTimerClear).await?; - self.send.send(Commands::NotifyMotorUp{data: Button::RELEASED}).await?; + self.send.send(Commands::NotifyMotorUp{data: Button::Released}).await?; + } + ControllerStates::AutoUp => { + self.send.send(Commands::NotifyMotorUp{data: Button::Released}).await?; } ControllerStates::GoingDown => { self.send.send(Commands::ButtonTimerClear).await?; - self.send.send(Commands::NotifyMotorDown{data: Button::RELEASED}).await?; + self.send.send(Commands::NotifyMotorDown{data: Button::Released}).await?; + } + ControllerStates::AutoDown => { + self.send.send(Commands::NotifyMotorDown{data: Button::Released}).await?; } } Ok(()) } - /// Determines the state the controller should be in based on the command received. - fn handle_cmd(&mut self, cmd: &Commands) -> ControllerStates { - match self.state { - - ControllerStates::Stopped => { - match cmd { - Commands::PicRecvUp => {return ControllerStates::GoingUp} - Commands::PicRecvDown => {return ControllerStates::GoingDown} - Commands::BluetoothUp { data } => { - match data { - 0 => {} - 1 => {return ControllerStates::GoingUp} - _ => {error!("Invalid data sent via BluetoothUp: {}", data); return ControllerStates::Stopping} - } - } - Commands::BluetoothDown { data } => { - match data { - 0 => {} - 1 => {return ControllerStates::GoingDown} - _ => {error!("Invalid data sent via BluetoothDown: {}", data); return ControllerStates::Stopping} - } - } - _ => {} // Ignore other commands when stopped. - } - } - - ControllerStates::Stopping => { - match cmd { - Commands::StopTimerExpired => {return ControllerStates::Stopped} - _ => {} // Ignore other commands when stopping - } - } - - ControllerStates::GoingUp => { - match cmd { - Commands::PicRecvUp => {return self.state.clone()} - Commands::BluetoothUp { data } => { - match data { - 0 => {} // Not an error, but transition to stop - 1 => {return self.state.clone()} - _ => {error!("Invalid data sent via BluetoothUp: {}", data)} - } - } - _ => {} // fall through to GoingUp default of stopping - } - return ControllerStates::Stopping; // Almost every command will be interpreted as stop - } - - ControllerStates::GoingDown => { - match cmd { - Commands::PicRecvDown => {return self.state.clone()} - Commands::BluetoothDown { data } => { - match data { - 0 => {} // Not an error, but transition to stop - 1 => {return self.state.clone()} - _ => {error!("Invalid data sent via BluetoothDown: {}", data)} - } - } - _ => {} // fall through to GoingDown default of stopping - } - return ControllerStates::Stopping + fn change_state_if_released(&self, data: &u8, new_state: ControllerStates) -> ControllerStates { + match data { + 0 => {new_state} + 1 => {self.state.clone()} + _ => { + warn!("Data that was not a 0 or 1 received {}", data); //TODO: internal error + self.state.clone() } } - self.state.clone() //Don't transition states by default. + } + + fn change_state_if_pressed(&self, data: &u8, new_state: ControllerStates) -> ControllerStates { + match data { + 0 => {self.state.clone()} + 1 => {new_state} + _ => { + warn!("Data that was not a 0 or 1 received {}", data); + self.state.clone() + } + } + } + + /// Determines the state the controller should be in based on the command received. + async fn handle_cmd(&mut self, cmd: &Commands) -> ControllerStates { + match cmd { + Commands::PicRecvUp { data } | Commands::BluetoothUp { data }=> { + match self.state { + ControllerStates::Stopped => {return self.change_state_if_pressed(data, self.remote_up_or_auto_up())} + ControllerStates::Stopping => {} + ControllerStates::GoingUp => { + self.send.send(Commands::ButtonTimerRestart).await.expect("Failed to necessary timer"); + return self.change_state_if_released(data, ControllerStates::Stopping) + } + ControllerStates::AutoUp => {} // Don't stop auto on button release + ControllerStates::GoingDown | + ControllerStates::AutoDown => { + return self.change_state_if_pressed(data, ControllerStates::Stopping) + } + } + } + Commands::PicRecvDown { data } | Commands::BluetoothDown { data } => { + match self.state { + ControllerStates::Stopped => {return self.change_state_if_pressed(data, self.remote_down_or_auto_down())} + ControllerStates::Stopping => {} + ControllerStates::GoingUp | + ControllerStates::AutoUp => { + return self.change_state_if_pressed(data, ControllerStates::Stopping) + } + ControllerStates::GoingDown => { + self.send.send(Commands::ButtonTimerRestart).await.expect("Failed to necessary timer"); + return self.change_state_if_released(data, ControllerStates::Stopping) + } + ControllerStates::AutoDown => {} + } + } + Commands::PicRecvStop { data } | Commands::BluetoothStop { data } => { + match self.state { + ControllerStates::Stopped => {} + ControllerStates::Stopping => {} + ControllerStates::GoingUp | + ControllerStates::AutoUp | + ControllerStates::GoingDown | + ControllerStates::AutoDown => { + return self.change_state_if_pressed(data, ControllerStates::Stopping) + } + } + } + Commands::PicRecvLimitUp { data } => { + self.adjust_limit(LimitState::UpperHit, data); + match self.state { + ControllerStates::Stopped => {} // Ignore; this could just be our initial notification on startup. + ControllerStates::Stopping => {} + ControllerStates::GoingUp | + ControllerStates::AutoUp=> { + released_warning(data, "Limit switches may be installed incorrectly!"); + return self.change_state_if_pressed(data, ControllerStates::Stopping) + } + ControllerStates::GoingDown | + ControllerStates::AutoDown=> { + pressed_warning(data, "Limit switches may be installed incorrectly!"); + // Stop out of an abundance of caution. We should not get a limit press, even if it's the wrong one. + return self.change_state_if_pressed(data, ControllerStates::Stopping) + } + } + } + Commands::PicRecvLimitDown { data } => { + self.adjust_limit(LimitState::LowerHit, data); + match self.state { + ControllerStates::Stopped => {} // Ignore; this could just be our initial notification on startup. + ControllerStates::Stopping => {} + ControllerStates::GoingUp | + ControllerStates::AutoUp => { + pressed_warning(data, "Limit switches may be installed incorrectly!"); + // Stop out of an abundance of caution. We should not get a limit press, even if it's the wrong one. + return self.change_state_if_pressed(data, ControllerStates::Stopping) + } + ControllerStates::GoingDown | + ControllerStates::AutoDown => { + released_warning(data, "Limit switches may be installed incorrectly!"); + return self.change_state_if_pressed(data, ControllerStates::Stopping) + } + } + } + Commands::PicRecvAutoMode { data } => {self.set_auto(data);} + Commands::StopTimerExpired => { + match self.state { + ControllerStates::Stopped => {} + ControllerStates::Stopping => {return ControllerStates::Stopped} + ControllerStates::GoingUp | + ControllerStates::AutoUp | + ControllerStates::GoingDown | + ControllerStates::AutoDown => { + warn!("Stop timer returned in an inappropriate state! {:?}", self.state) + } + } + } + Commands::ButtonTimerExpired => { + match self.state { + ControllerStates::Stopped => {} + ControllerStates::Stopping => {} + ControllerStates::GoingUp => {return ControllerStates::Stopping} + ControllerStates::AutoUp => {} + ControllerStates::GoingDown => {return ControllerStates::Stopping} + ControllerStates::AutoDown => {} + } + } + // Commands we should ignore (not using _ because we want to ensure all commands are accounted for!) + Commands::StopTimerRestart | + Commands::StopTimerClear | + Commands::ButtonTimerRestart | + Commands::ButtonTimerClear | + Commands::PairTimerClear | + Commands::PairTimerExpired | + Commands::AllowPairing | + Commands::EraseBleBonds => { + warn!("Unexpected command received by motor controller") // TODO: internal "us" error. + } + Commands::NotifyMotorDown { data } | + Commands::NotifyMotorStop { data } | + Commands::NotifyMotorUp { data } => { + warn!("Unexpected command received by motor controller {:?}", data) // TODO: internal "us" error. + } + Commands::BluetoothName { data } => { + warn!("Unexpected command received by motor controller {:?}", data) // TODO: internal "us" error. + } + } + self.state.clone() // Don't transition by default } async fn transition_state(&mut self, old_s: &ControllerStates, new_s: &ControllerStates) -> Result<()> { @@ -176,9 +286,6 @@ impl Controller { self.exit_state(&old_s).await?; self.enter_state(&new_s).await?; } - else { - self.maintain_state().await?; - } self.state = new_s.clone(); Ok(()) } @@ -191,10 +298,150 @@ impl Controller { loop { let cmd = self.recv.recv().await.expect("Motor controller command queue unexpectedly failed"); trace!("Got command {:?}",cmd); - let new_s = self.handle_cmd(&cmd); + let new_s = self.handle_cmd(&cmd).await; trace!("State current {:?} new {:?}", self.state, new_s); self.transition_state(&self.state.clone(), &new_s).await.expect("Unexpected state change failure in motor controller"); } } + fn remote_up_or_auto_up(&self) -> ControllerStates { + self.up_or_auto_up(ControllerStates::GoingUp) + } + + fn up_or_auto_up(&self, up: ControllerStates) -> ControllerStates { + // Assume that checking the limit against the direction has already been performed. + match self.auto_mode { + AutoMode::Disallowed => { + up // TODO: this allows manual buttons to override limits as long as "auto" mode is off. + } + AutoMode::Allowed => { + match self.limit_state { + LimitState::NoLimitsHit | LimitState::LowerHit=> { + ControllerStates::AutoUp + } + LimitState::UpperHit => { + ControllerStates::Stopping // Failsafe as we are already at our upper limit. TODO: maybe should be manual up? + } + LimitState::BothHit => { + up + } + } + } + } + } + + fn remote_down_or_auto_down(&self) -> ControllerStates { + self.down_or_auto_down(ControllerStates::GoingDown) + } + + fn down_or_auto_down(&self, down: ControllerStates) -> ControllerStates { + // Assume that checking the limit against the direction has already been performed. + match self.auto_mode { + AutoMode::Disallowed => { + down // TODO: this allows manual buttons to override limits as long as "auto" mode is off. + } + AutoMode::Allowed => { + match self.limit_state { + LimitState::NoLimitsHit | LimitState::LowerHit=> { + ControllerStates::AutoDown + } + LimitState::UpperHit => { + ControllerStates::Stopping // Failsafe as we are already at our upper limit. TODO: Maybe should be manual down? + } + LimitState::BothHit => { + down + } + } + } + } + } + + fn set_auto(&mut self, data: &u8) { + match data { + 0 => { + self.auto_mode = AutoMode::Disallowed; + } + 1 => { + if self.limit_state == LimitState::BothHit { + warn!("Limit switches not detected. Aborting auto mode."); + } else { + self.auto_mode = AutoMode::Allowed; + } + } + _ => {} // TODO: we should warn, but we're going to fix these types next. + } + } + + fn adjust_limit(&mut self, limit: LimitState, pressed: &u8) { + match pressed { + 0 => { + match limit { + LimitState::NoLimitsHit => { + unreachable!("There is no way to press NoLimits") + } + LimitState::LowerHit => { + match self.limit_state { + LimitState::NoLimitsHit | + LimitState::UpperHit => {warn!("removed limit we never hit {:?}", LimitState::LowerHit);} //TODO intenral error + LimitState::LowerHit => {self.limit_state = LimitState::NoLimitsHit;} + LimitState::BothHit => {self.limit_state = LimitState::UpperHit;} + } + } + LimitState::UpperHit => { + match self.limit_state { + LimitState::NoLimitsHit | + LimitState::LowerHit => {warn!("removed limit we never hit {:?}", LimitState::UpperHit);} //TODO intenral error + LimitState::UpperHit => {self.limit_state = LimitState::NoLimitsHit;} + LimitState::BothHit => {self.limit_state = LimitState::LowerHit;} + } + } + LimitState::BothHit => { + unreachable!("There is no way to press BothHit") + } + } + } + 1 => { + match limit { + LimitState::NoLimitsHit => { + unreachable!("There is no way to press BothHit") + } + LimitState::LowerHit => { + match self.limit_state { + LimitState::NoLimitsHit => {self.limit_state = LimitState::LowerHit;} + LimitState::LowerHit => {} + LimitState::UpperHit => {self.limit_state = LimitState::BothHit;} + LimitState::BothHit => {} + } + } + LimitState::UpperHit => { + match self.limit_state { + LimitState::NoLimitsHit => {self.limit_state = LimitState::UpperHit;} + LimitState::LowerHit => {self.limit_state = LimitState::BothHit;} + LimitState::UpperHit => {} + LimitState::BothHit => {} + } + } + LimitState::BothHit => { + unreachable!("There is no way to press BothHit") + } + } + } + _ => {} //TODO should warn but this will go away with real pressed types + } + } + +} + +fn pressed_warning(data: &u8, warn: &str) { + match data { + 1 => {warn!("{}", warn);} // TODO: user warning, not intenral + _ => {} + } +} + +fn released_warning(data: &u8, warn: &str) { + match data { + 0 => {warn!("{}", warn);} // TODO: user warning, not intenral + _ => {} + } } \ No newline at end of file diff --git a/gem-remotes-esp32/src/motor_driver.rs b/gem-remotes-esp32/src/motor_driver.rs index 4676d34..121c9e3 100644 --- a/gem-remotes-esp32/src/motor_driver.rs +++ b/gem-remotes-esp32/src/motor_driver.rs @@ -15,7 +15,7 @@ pub type SendQ = Sender; pub type RecvQ = Receiver; pub struct MotorDriverDebug{ - endpoint: SendQ, + endpoint: SendQ, // Endpoint to hand to dispatch or anyone else sending commands here. recv_q: RecvQ, } diff --git a/gem-remotes-esp32/src/test_console.rs b/gem-remotes-esp32/src/test_console.rs index 34eaae5..a18c04c 100644 --- a/gem-remotes-esp32/src/test_console.rs +++ b/gem-remotes-esp32/src/test_console.rs @@ -29,15 +29,24 @@ use async_channel::Sender; use log::*; //{trace, debug, info, warn, error} #[derive(Command)] -pub enum Menu<'a> { +pub enum Menu{//<'a> { /// Simulate the PIC controller sending aus n Up character - PicRecvUp, + PicRecvUp { + /// 0 for not pressed, 1 for pressed + data: u8, + }, /// Simulate the PIC controller sending us a Down character - PicRecvDown, + PicRecvDown { + /// 0 for not pressed, 1 for pressed + data: u8, + }, /// Simulate the PIC controller sending us a Stop character - PicRecvStop, + PicRecvStop { + /// 0 for not pressed, 1 for pressed + data: u8, + }, /// Simulate the PIC controller sending a "pair" button press PicRecvPair, @@ -73,9 +82,9 @@ pub enum Menu<'a> { BluetoothBottomLimit { data: u8 }, /// Send a bluetooth characteristic: Wifi SSID - BluetoothWifiSsid { ssid: &'a str }, + //BluetoothWifiSsid { ssid: &'a str }, /// Send a bluetooth characteristic: Wifi Password - BluetoothWifiPassword { wifipass: &'a str }, + //BluetoothWifiPassword { wifipass: &'a str }, /// Change log level (None: 0, .. Tracing: 5) Log { level: u8 }, @@ -85,28 +94,31 @@ pub enum Menu<'a> { /// Erase BLE Bonding information ClearBleBonds, + + /// Whatever misc. output I need + Misc, } pub fn process_menu( cli: &mut CliHandle<'_, SimpleWriter, Infallible>, - command: Menu<'_>, + command: Menu,//<'_>, dispatch: &Sender, ) -> Result<(), Infallible> { match command { // We ignore sending errors throughout because the Cli interface is only for // testing and debugging. - Menu::PicRecvUp => { + Menu::PicRecvUp {data} => { cli.writer().write_str("Sending PicButtonUp Received command")?; - let _ = dispatch.send_blocking(Commands::PicRecvUp); + let _ = dispatch.send_blocking(Commands::PicRecvUp{data}); } - Menu::PicRecvDown => { + Menu::PicRecvDown{data} => { cli.writer().write_str("Sending PicButtonDown command")?; - let _ = dispatch.send_blocking(Commands::PicRecvDown); + let _ = dispatch.send_blocking(Commands::PicRecvDown{data}); } - Menu::PicRecvStop => { + Menu::PicRecvStop{data} => { cli.writer().write_str("Sending PicButtonStop command")?; - let _ = dispatch.send_blocking(Commands::PicRecvStop); + let _ = dispatch.send_blocking(Commands::PicRecvStop{data}); } Menu::PicRecvPair => { cli.writer().write_str("Sending PIC command and timer reset (the job of the pair button driver, once PIC interface exists)")?; //TODO: PIC get this. @@ -125,7 +137,7 @@ pub fn process_menu( Menu::BluetoothStop { data } => { cli.writer() .write_str("SendingBluetoothStop")?; - let _ = dispatch.send_blocking(Commands::BluetoothStop { _data: data }); + let _ = dispatch.send_blocking(Commands::BluetoothStop { data: data }); } Menu::BluetoothLearn { data } => { cli.writer() @@ -147,7 +159,7 @@ pub fn process_menu( .write_str("TODO: simulate bluetooth characteristic change")?; let _ = data; } - Menu::BluetoothWifiSsid { ssid } => { + /*Menu::BluetoothWifiSsid { ssid } => { cli.writer() .write_str("TODO: simulate bluetooth characteristic change")?; let _ = ssid; @@ -156,7 +168,7 @@ pub fn process_menu( cli.writer() .write_str("TODO: simulate bluetooth characteristic change {}")?; let _ = wifipass; - } + }*/ Menu::Log { level } => { match level { 0 => { @@ -194,6 +206,9 @@ pub fn process_menu( Menu::ClearBleBonds => { let _ = dispatch.send_blocking(Commands::EraseBleBonds); } + Menu::Misc => { + println!("string {}, arc string {}, enum value {}, discriminant {}", std::mem::size_of::(), std::mem::size_of::>(), std::mem::size_of::(), std::mem::size_of::>()); + } } Ok(()) }