use embassy_usb::{ class::hid::{HidReader, HidReaderWriter, HidWriter, ReadError, RequestHandler}, driver::{Driver, EndpointError}, }; pub mod gcc; pub mod procon; pub mod xinput; /// Custom trait to unify the API between embassy's HID writer, and our XInput reader/writer (and any /// custom writers we may create in the future) pub trait HidReaderWriterSplit<'d, D: Driver<'d>, const READ_N: usize, const WRITE_N: usize> { fn split( self, ) -> ( impl UsbReader<'d, D, READ_N>, impl UsbWriter<'d, D, WRITE_N>, ); } /// Custom trait to unify the API between embassy's HID writer, and our XInput reader (and any /// custom writers we may create in the future) pub trait UsbReader<'d, D: Driver<'d>, const READ_N: usize> { async fn run<T: RequestHandler>(self, use_report_ids: bool, handler: &mut T) -> !; async fn read(&mut self, buf: &mut [u8]) -> Result<usize, ReadError>; } /// Custom trait to unify the API between embassy's HID writer, and our XInput writer (and any /// custom writers we may create in the future) pub trait UsbWriter<'d, D: Driver<'d>, const WRITE_N: usize> { async fn ready(&mut self); async fn write(&mut self, report: &[u8]) -> Result<(), EndpointError>; } impl<'d, D: Driver<'d>, const READ_N: usize, const WRITE_N: usize> HidReaderWriterSplit<'d, D, READ_N, WRITE_N> for HidReaderWriter<'d, D, READ_N, WRITE_N> { fn split( self, ) -> ( impl UsbReader<'d, D, READ_N>, impl UsbWriter<'d, D, WRITE_N>, ) { self.split() } } impl<'d, D: Driver<'d>, const READ_N: usize> UsbReader<'d, D, READ_N> for HidReader<'d, D, READ_N> { async fn run<T: RequestHandler>(self, use_report_ids: bool, handler: &mut T) -> ! { self.run(use_report_ids, handler).await } async fn read(&mut self, buf: &mut [u8]) -> Result<usize, ReadError> { self.read(buf).await } } impl<'d, D: Driver<'d>, const WRITE_N: usize> UsbWriter<'d, D, WRITE_N> for HidWriter<'d, D, WRITE_N> { async fn ready(&mut self) { self.ready().await } async fn write(&mut self, report: &[u8]) -> Result<(), EndpointError> { self.write(report).await } }