diff --git a/services/usb-device-xous/src/api.rs b/services/usb-device-xous/src/api.rs index e132188ae..4782384ac 100644 --- a/services/usb-device-xous/src/api.rs +++ b/services/usb-device-xous/src/api.rs @@ -12,6 +12,8 @@ pub(crate) enum Opcode { GetLedState, /// Switch to a specified device core SwitchCores, + /// Makes sure a given core is selected + EnsureCore, /// Check which core is connected WhichCore, /// Restrict the debug core diff --git a/services/usb-device-xous/src/lib.rs b/services/usb-device-xous/src/lib.rs index eb3071e7f..ca9983174 100644 --- a/services/usb-device-xous/src/lib.rs +++ b/services/usb-device-xous/src/lib.rs @@ -29,6 +29,7 @@ impl UsbHid { conn } } + /// this will always trigger a reset, even if it's the same core we're switching to pub fn switch_to_core(&self, core: UsbDeviceType) -> Result<(), xous::Error> { match send_message( self.conn, @@ -50,6 +51,28 @@ impl UsbHid { _ => panic!("Internal error: illegal return type"), } } + /// this will not trigger a reset if we're already on the requested core + pub fn ensure_core(&self, core: UsbDeviceType) -> Result<(), xous::Error> { + match send_message( + self.conn, + Message::new_blocking_scalar( + Opcode::EnsureCore.to_usize().unwrap(), + match core { + UsbDeviceType::Debug => 0, + UsbDeviceType::Hid => 1, + }, + 0, 0, 0 + ) + ) { + Ok(xous::Result::Scalar1(code)) => { + match code { + 0 => Ok(()), + _ => Err(xous::Error::InternalError) + } + } + _ => panic!("Internal error: illegal return type"), + } + } pub fn get_current_core(&self) -> Result { match send_message( self.conn, diff --git a/services/usb-device-xous/src/main.rs b/services/usb-device-xous/src/main.rs index e6af6f805..29c66f9f7 100644 --- a/services/usb-device-xous/src/main.rs +++ b/services/usb-device-xous/src/main.rs @@ -318,6 +318,20 @@ fn main() -> ! { } xous::return_scalar(msg.sender, 0).unwrap(); }), + Some(Opcode::EnsureCore) => msg_blocking_scalar_unpack!(msg, core, _, _, _, { + if core == 1 { + if !usbmgmt.is_device_connected() { + log::info!("Connecting USB device core; disconnecting debug USB core"); + usbmgmt.connect_device_core(true); + } + } else { + if usbmgmt.is_device_connected() { + log::info!("Connecting debug core; disconnecting USB device core"); + usbmgmt.connect_device_core(false); + } + } + xous::return_scalar(msg.sender, 0).unwrap(); + }), Some(Opcode::WhichCore) => msg_blocking_scalar_unpack!(msg, _, _, _, _, { if usbmgmt.is_device_connected() { xous::return_scalar(msg.sender, 1).unwrap();