/// Handles the actual hardware interface with motor or its controller. use log::*; //{trace, debug, info, warn, error} use anyhow::Result; use async_channel::unbounded; use gem_remotes_lib::{MotorCommands, MotorRecvQ, MotorSendQ}; pub struct MotorDriverDebug{ endpoint: MotorSendQ, // Endpoint to hand to dispatch or anyone else sending commands here. recv_q: MotorRecvQ, } /// Debug / example version of Motor Driver. impl MotorDriverDebug { pub fn new() -> Self { let (s,r) = unbounded(); // TODO: reserve a reasonable amount for all unbounded? MotorDriverDebug { endpoint: s, recv_q: r, } } pub fn get_endpoint(&self) -> MotorSendQ { self.endpoint.clone() } pub async fn run(&self) -> Result<()> { loop { let cmd = self.recv_q.recv() .await .expect("Unexpected failure in motor driver command queue"); self.handle_cmd(cmd) .await .expect("Unexpected failure of motor driver notification queue"); } } async fn handle_cmd(&self, cmd: MotorCommands) -> Result<()> { match cmd { MotorCommands::StartUp => {self.start_up().await?;} MotorCommands::StartDown => {self.start_down().await?;} MotorCommands::Stop => {self.stop().await?;} } Ok(()) } async fn start_up(&self) -> Result<()> { warn!("Starting motor, direction: Up"); Ok(()) } async fn start_down(&self) -> Result<()> { warn!("Starting motor, direction: Down"); Ok(()) } async fn stop(&self) -> Result<()> { warn!("Stopping motor"); Ok(()) } } //TODO: we should fix panic to ensure that we shut down motors before rebooting ESP! // Maybe by getting another endpoint and passing it to the panic handler? Add a different // command that doesn't just stop, but stops and stops processing any new commands. //TODO: Design - are there any implications to the PIC motor driver essentially sending button // presses instead of commanding the motor on/off? Feedback loops? No way to know without PIC // code.