diff options
| author | Dario Nieuwenhuis <[email protected]> | 2022-04-16 01:59:40 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2022-04-16 01:59:40 +0200 |
| commit | c0de54a341dc40b600574a5009a3d4c54e52d5c8 (patch) | |
| tree | a26059f90bfd8a2a1d204414415951593c6822a2 | |
| parent | 94090e068ec8c56e4fd6676330d87305c5dfee3e (diff) | |
usb-hid: Simplify API.
- Renamed structs to HidReaderWriter, HidReader, HidWriter.
- Removed unused const generics on `State`.
- Simplified generics on `HidReaderWriter`.
The class type previously was `HidClass<D, Driver<'d, USBD>, ReportReader<'d, Driver<'d, USBD>, OUT_N>, IN_N>`
It's now `HidClass<D, Driver<'d, USBD>, IN_N, OUT_N>`. Note that the driver type `Driver<'d, USBD>` is no longer repeated.
- Constructors are now: `HidWriter::new()` for IN-only, `HidReaderWriter::new()` for IN+OUT. No complicated bounds.
- HidReaderWriter has all the methods from HidReader, HidWriter.
| -rw-r--r-- | embassy-usb-hid/src/lib.rs | 272 | ||||
| -rw-r--r-- | examples/nrf/src/bin/usb_hid_keyboard.rs | 14 | ||||
| -rw-r--r-- | examples/nrf/src/bin/usb_hid_mouse.rs | 8 |
3 files changed, 160 insertions, 134 deletions
diff --git a/embassy-usb-hid/src/lib.rs b/embassy-usb-hid/src/lib.rs index e870becf5..1035c2792 100644 --- a/embassy-usb-hid/src/lib.rs +++ b/embassy-usb-hid/src/lib.rs | |||
| @@ -60,12 +60,12 @@ impl ReportId { | |||
| 60 | } | 60 | } |
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | pub struct State<'a, const IN_N: usize, const OUT_N: usize> { | 63 | pub struct State<'d> { |
| 64 | control: MaybeUninit<Control<'a>>, | 64 | control: MaybeUninit<Control<'d>>, |
| 65 | out_report_offset: AtomicUsize, | 65 | out_report_offset: AtomicUsize, |
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | impl<'a, const IN_N: usize, const OUT_N: usize> State<'a, IN_N, OUT_N> { | 68 | impl<'d> State<'d> { |
| 69 | pub fn new() -> Self { | 69 | pub fn new() -> Self { |
| 70 | State { | 70 | State { |
| 71 | control: MaybeUninit::uninit(), | 71 | control: MaybeUninit::uninit(), |
| @@ -74,107 +74,146 @@ impl<'a, const IN_N: usize, const OUT_N: usize> State<'a, IN_N, OUT_N> { | |||
| 74 | } | 74 | } |
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | pub struct HidClass<'d, D: Driver<'d>, T, const IN_N: usize> { | 77 | pub struct HidReaderWriter<'d, D: Driver<'d>, const READ_N: usize, const WRITE_N: usize> { |
| 78 | input: ReportWriter<'d, D, IN_N>, | 78 | reader: HidReader<'d, D, READ_N>, |
| 79 | output: T, | 79 | writer: HidWriter<'d, D, WRITE_N>, |
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | impl<'d, D: Driver<'d>, const IN_N: usize> HidClass<'d, D, (), IN_N> { | 82 | fn build<'d, D: Driver<'d>>( |
| 83 | /// Creates a new HidClass. | 83 | builder: &mut UsbDeviceBuilder<'d, D>, |
| 84 | /// | 84 | state: &'d mut State<'d>, |
| 85 | /// poll_ms configures how frequently the host should poll for reading/writing | 85 | report_descriptor: &'static [u8], |
| 86 | /// HID reports. A lower value means better throughput & latency, at the expense | 86 | request_handler: Option<&'d dyn RequestHandler>, |
| 87 | /// of CPU on the device & bandwidth on the bus. A value of 10 is reasonable for | 87 | poll_ms: u8, |
| 88 | /// high performance uses, and a value of 255 is good for best-effort usecases. | 88 | max_packet_size: u16, |
| 89 | /// | 89 | with_out_endpoint: bool, |
| 90 | /// This allocates an IN endpoint only. | 90 | ) -> (Option<D::EndpointOut>, D::EndpointIn, &'d AtomicUsize) { |
| 91 | pub fn new<const OUT_N: usize>( | 91 | let control = state.control.write(Control::new( |
| 92 | builder: &mut UsbDeviceBuilder<'d, D>, | 92 | report_descriptor, |
| 93 | state: &'d mut State<'d, IN_N, OUT_N>, | 93 | request_handler, |
| 94 | report_descriptor: &'static [u8], | 94 | &state.out_report_offset, |
| 95 | request_handler: Option<&'d dyn RequestHandler>, | 95 | )); |
| 96 | poll_ms: u8, | 96 | |
| 97 | max_packet_size: u16, | 97 | let len = report_descriptor.len(); |
| 98 | ) -> Self { | 98 | let if_num = builder.alloc_interface_with_handler(control); |
| 99 | let ep_in = builder.alloc_interrupt_endpoint_in(max_packet_size, poll_ms); | 99 | let ep_in = builder.alloc_interrupt_endpoint_in(max_packet_size, poll_ms); |
| 100 | let control = state.control.write(Control::new( | 100 | let ep_out = if with_out_endpoint { |
| 101 | report_descriptor, | 101 | Some(builder.alloc_interrupt_endpoint_out(max_packet_size, poll_ms)) |
| 102 | request_handler, | 102 | } else { |
| 103 | &state.out_report_offset, | 103 | None |
| 104 | )); | 104 | }; |
| 105 | control.build(builder, None, &ep_in); | 105 | |
| 106 | 106 | builder.config_descriptor.interface( | |
| 107 | Self { | 107 | if_num, |
| 108 | input: ReportWriter { ep_in }, | 108 | USB_CLASS_HID, |
| 109 | output: (), | 109 | USB_SUBCLASS_NONE, |
| 110 | } | 110 | USB_PROTOCOL_NONE, |
| 111 | ); | ||
| 112 | |||
| 113 | // HID descriptor | ||
| 114 | builder.config_descriptor.write( | ||
| 115 | HID_DESC_DESCTYPE_HID, | ||
| 116 | &[ | ||
| 117 | // HID Class spec version | ||
| 118 | HID_DESC_SPEC_1_10[0], | ||
| 119 | HID_DESC_SPEC_1_10[1], | ||
| 120 | // Country code not supported | ||
| 121 | HID_DESC_COUNTRY_UNSPEC, | ||
| 122 | // Number of following descriptors | ||
| 123 | 1, | ||
| 124 | // We have a HID report descriptor the host should read | ||
| 125 | HID_DESC_DESCTYPE_HID_REPORT, | ||
| 126 | // HID report descriptor size, | ||
| 127 | (len & 0xFF) as u8, | ||
| 128 | (len >> 8 & 0xFF) as u8, | ||
| 129 | ], | ||
| 130 | ); | ||
| 131 | |||
| 132 | builder.config_descriptor.endpoint(ep_in.info()); | ||
| 133 | if let Some(ep_out) = &ep_out { | ||
| 134 | builder.config_descriptor.endpoint(ep_out.info()); | ||
| 111 | } | 135 | } |
| 112 | } | ||
| 113 | 136 | ||
| 114 | impl<'d, D: Driver<'d>, T, const IN_N: usize> HidClass<'d, D, T, IN_N> { | 137 | (ep_out, ep_in, &state.out_report_offset) |
| 115 | /// Gets the [`ReportWriter`] for input reports. | ||
| 116 | /// | ||
| 117 | /// **Note:** If the `HidClass` was created with [`new_ep_out()`](Self::new_ep_out) | ||
| 118 | /// this writer will be useless as no endpoint is availabe to send reports. | ||
| 119 | pub fn input(&mut self) -> &mut ReportWriter<'d, D, IN_N> { | ||
| 120 | &mut self.input | ||
| 121 | } | ||
| 122 | } | 138 | } |
| 123 | 139 | ||
| 124 | impl<'d, D: Driver<'d>, const IN_N: usize, const OUT_N: usize> | 140 | impl<'d, D: Driver<'d>, const READ_N: usize, const WRITE_N: usize> |
| 125 | HidClass<'d, D, ReportReader<'d, D, OUT_N>, IN_N> | 141 | HidReaderWriter<'d, D, READ_N, WRITE_N> |
| 126 | { | 142 | { |
| 127 | /// Creates a new HidClass. | 143 | /// Creates a new HidReaderWriter. |
| 144 | /// | ||
| 145 | /// This will allocate one IN and one OUT endpoints. If you only need writing (sending) | ||
| 146 | /// HID reports, consider using [`HidWriter::new`] instead, which allocates an IN endpoint only. | ||
| 128 | /// | 147 | /// |
| 129 | /// poll_ms configures how frequently the host should poll for reading/writing | 148 | /// poll_ms configures how frequently the host should poll for reading/writing |
| 130 | /// HID reports. A lower value means better throughput & latency, at the expense | 149 | /// HID reports. A lower value means better throughput & latency, at the expense |
| 131 | /// of CPU on the device & bandwidth on the bus. A value of 10 is reasonable for | 150 | /// of CPU on the device & bandwidth on the bus. A value of 10 is reasonable for |
| 132 | /// high performance uses, and a value of 255 is good for best-effort usecases. | 151 | /// high performance uses, and a value of 255 is good for best-effort usecases. |
| 133 | /// | 152 | pub fn new( |
| 134 | /// This allocates two endpoints (IN and OUT). | ||
| 135 | pub fn with_output_ep( | ||
| 136 | builder: &mut UsbDeviceBuilder<'d, D>, | 153 | builder: &mut UsbDeviceBuilder<'d, D>, |
| 137 | state: &'d mut State<'d, IN_N, OUT_N>, | 154 | state: &'d mut State<'d>, |
| 138 | report_descriptor: &'static [u8], | 155 | report_descriptor: &'static [u8], |
| 139 | request_handler: Option<&'d dyn RequestHandler>, | 156 | request_handler: Option<&'d dyn RequestHandler>, |
| 140 | poll_ms: u8, | 157 | poll_ms: u8, |
| 141 | max_packet_size: u16, | 158 | max_packet_size: u16, |
| 142 | ) -> Self { | 159 | ) -> Self { |
| 143 | let ep_out = builder.alloc_interrupt_endpoint_out(max_packet_size, poll_ms); | 160 | let (ep_out, ep_in, offset) = build( |
| 144 | let ep_in = builder.alloc_interrupt_endpoint_in(max_packet_size, poll_ms); | 161 | builder, |
| 145 | 162 | state, | |
| 146 | let control = state.control.write(Control::new( | ||
| 147 | report_descriptor, | 163 | report_descriptor, |
| 148 | request_handler, | 164 | request_handler, |
| 149 | &state.out_report_offset, | 165 | poll_ms, |
| 150 | )); | 166 | max_packet_size, |
| 151 | control.build(builder, Some(&ep_out), &ep_in); | 167 | true, |
| 168 | ); | ||
| 152 | 169 | ||
| 153 | Self { | 170 | Self { |
| 154 | input: ReportWriter { ep_in }, | 171 | reader: HidReader { |
| 155 | output: ReportReader { | 172 | ep_out: ep_out.unwrap(), |
| 156 | ep_out, | 173 | offset, |
| 157 | offset: &state.out_report_offset, | ||
| 158 | }, | 174 | }, |
| 175 | writer: HidWriter { ep_in }, | ||
| 159 | } | 176 | } |
| 160 | } | 177 | } |
| 161 | 178 | ||
| 162 | /// Gets the [`ReportReader`] for output reports. | 179 | /// Splits into seperate readers/writers for input and output reports. |
| 163 | pub fn output(&mut self) -> &mut ReportReader<'d, D, OUT_N> { | 180 | pub fn split(self) -> (HidReader<'d, D, READ_N>, HidWriter<'d, D, WRITE_N>) { |
| 164 | &mut self.output | 181 | (self.reader, self.writer) |
| 182 | } | ||
| 183 | |||
| 184 | /// Waits for both IN and OUT endpoints to be enabled. | ||
| 185 | pub async fn ready(&mut self) -> () { | ||
| 186 | self.reader.ready().await; | ||
| 187 | self.writer.ready().await; | ||
| 188 | } | ||
| 189 | |||
| 190 | /// Writes an input report by serializing the given report structure. | ||
| 191 | #[cfg(feature = "usbd-hid")] | ||
| 192 | pub async fn write_serialize<IR: AsInputReport>( | ||
| 193 | &mut self, | ||
| 194 | r: &IR, | ||
| 195 | ) -> Result<(), EndpointError> { | ||
| 196 | self.writer.write_serialize(r).await | ||
| 197 | } | ||
| 198 | |||
| 199 | /// Writes `report` to its interrupt endpoint. | ||
| 200 | pub async fn write(&mut self, report: &[u8]) -> Result<(), EndpointError> { | ||
| 201 | self.writer.write(report).await | ||
| 165 | } | 202 | } |
| 166 | 203 | ||
| 167 | /// Splits this `HidClass` into seperate readers/writers for input and output reports. | 204 | /// Reads an output report from the Interrupt Out pipe. |
| 168 | pub fn split(self) -> (ReportWriter<'d, D, IN_N>, ReportReader<'d, D, OUT_N>) { | 205 | /// |
| 169 | (self.input, self.output) | 206 | /// See [`HidReader::read`]. |
| 207 | pub async fn read(&mut self, buf: &mut [u8]) -> Result<usize, ReadError> { | ||
| 208 | self.reader.read(buf).await | ||
| 170 | } | 209 | } |
| 171 | } | 210 | } |
| 172 | 211 | ||
| 173 | pub struct ReportWriter<'d, D: Driver<'d>, const N: usize> { | 212 | pub struct HidWriter<'d, D: Driver<'d>, const N: usize> { |
| 174 | ep_in: D::EndpointIn, | 213 | ep_in: D::EndpointIn, |
| 175 | } | 214 | } |
| 176 | 215 | ||
| 177 | pub struct ReportReader<'d, D: Driver<'d>, const N: usize> { | 216 | pub struct HidReader<'d, D: Driver<'d>, const N: usize> { |
| 178 | ep_out: D::EndpointOut, | 217 | ep_out: D::EndpointOut, |
| 179 | offset: &'d AtomicUsize, | 218 | offset: &'d AtomicUsize, |
| 180 | } | 219 | } |
| @@ -197,17 +236,50 @@ impl From<embassy_usb::driver::EndpointError> for ReadError { | |||
| 197 | } | 236 | } |
| 198 | } | 237 | } |
| 199 | 238 | ||
| 200 | impl<'d, D: Driver<'d>, const N: usize> ReportWriter<'d, D, N> { | 239 | impl<'d, D: Driver<'d>, const N: usize> HidWriter<'d, D, N> { |
| 240 | /// Creates a new HidWriter. | ||
| 241 | /// | ||
| 242 | /// This will allocate one IN endpoint only, so the host won't be able to send | ||
| 243 | /// reports to us. If you need that, consider using [`HidReaderWriter::new`] instead. | ||
| 244 | /// | ||
| 245 | /// poll_ms configures how frequently the host should poll for reading/writing | ||
| 246 | /// HID reports. A lower value means better throughput & latency, at the expense | ||
| 247 | /// of CPU on the device & bandwidth on the bus. A value of 10 is reasonable for | ||
| 248 | /// high performance uses, and a value of 255 is good for best-effort usecases. | ||
| 249 | pub fn new( | ||
| 250 | builder: &mut UsbDeviceBuilder<'d, D>, | ||
| 251 | state: &'d mut State<'d>, | ||
| 252 | report_descriptor: &'static [u8], | ||
| 253 | request_handler: Option<&'d dyn RequestHandler>, | ||
| 254 | poll_ms: u8, | ||
| 255 | max_packet_size: u16, | ||
| 256 | ) -> Self { | ||
| 257 | let (ep_out, ep_in, _offset) = build( | ||
| 258 | builder, | ||
| 259 | state, | ||
| 260 | report_descriptor, | ||
| 261 | request_handler, | ||
| 262 | poll_ms, | ||
| 263 | max_packet_size, | ||
| 264 | false, | ||
| 265 | ); | ||
| 266 | |||
| 267 | assert!(ep_out.is_none()); | ||
| 268 | |||
| 269 | Self { ep_in } | ||
| 270 | } | ||
| 271 | |||
| 201 | /// Waits for the interrupt in endpoint to be enabled. | 272 | /// Waits for the interrupt in endpoint to be enabled. |
| 202 | pub async fn ready(&mut self) -> () { | 273 | pub async fn ready(&mut self) -> () { |
| 203 | self.ep_in.wait_enabled().await | 274 | self.ep_in.wait_enabled().await |
| 204 | } | 275 | } |
| 205 | 276 | ||
| 206 | /// Tries to write an input report by serializing the given report structure. | 277 | /// Writes an input report by serializing the given report structure. |
| 207 | /// | ||
| 208 | /// Panics if no endpoint is available. | ||
| 209 | #[cfg(feature = "usbd-hid")] | 278 | #[cfg(feature = "usbd-hid")] |
| 210 | pub async fn serialize<IR: AsInputReport>(&mut self, r: &IR) -> Result<(), EndpointError> { | 279 | pub async fn write_serialize<IR: AsInputReport>( |
| 280 | &mut self, | ||
| 281 | r: &IR, | ||
| 282 | ) -> Result<(), EndpointError> { | ||
| 211 | let mut buf: [u8; N] = [0; N]; | 283 | let mut buf: [u8; N] = [0; N]; |
| 212 | let size = match serialize(&mut buf, r) { | 284 | let size = match serialize(&mut buf, r) { |
| 213 | Ok(size) => size, | 285 | Ok(size) => size, |
| @@ -217,8 +289,6 @@ impl<'d, D: Driver<'d>, const N: usize> ReportWriter<'d, D, N> { | |||
| 217 | } | 289 | } |
| 218 | 290 | ||
| 219 | /// Writes `report` to its interrupt endpoint. | 291 | /// Writes `report` to its interrupt endpoint. |
| 220 | /// | ||
| 221 | /// Panics if no endpoint is available. | ||
| 222 | pub async fn write(&mut self, report: &[u8]) -> Result<(), EndpointError> { | 292 | pub async fn write(&mut self, report: &[u8]) -> Result<(), EndpointError> { |
| 223 | assert!(report.len() <= N); | 293 | assert!(report.len() <= N); |
| 224 | 294 | ||
| @@ -236,16 +306,13 @@ impl<'d, D: Driver<'d>, const N: usize> ReportWriter<'d, D, N> { | |||
| 236 | } | 306 | } |
| 237 | } | 307 | } |
| 238 | 308 | ||
| 239 | impl<'d, D: Driver<'d>, const N: usize> ReportReader<'d, D, N> { | 309 | impl<'d, D: Driver<'d>, const N: usize> HidReader<'d, D, N> { |
| 240 | /// Waits for the interrupt out endpoint to be enabled. | 310 | /// Waits for the interrupt out endpoint to be enabled. |
| 241 | pub async fn ready(&mut self) -> () { | 311 | pub async fn ready(&mut self) -> () { |
| 242 | self.ep_out.wait_enabled().await | 312 | self.ep_out.wait_enabled().await |
| 243 | } | 313 | } |
| 244 | 314 | ||
| 245 | /// Starts a task to deliver output reports from the Interrupt Out pipe to | 315 | /// Delivers output reports from the Interrupt Out pipe to `handler`. |
| 246 | /// `handler`. | ||
| 247 | /// | ||
| 248 | /// Terminates when the interface becomes disabled. | ||
| 249 | /// | 316 | /// |
| 250 | /// If `use_report_ids` is true, the first byte of the report will be used as | 317 | /// If `use_report_ids` is true, the first byte of the report will be used as |
| 251 | /// the `ReportId` value. Otherwise the `ReportId` value will be 0. | 318 | /// the `ReportId` value. Otherwise the `ReportId` value will be 0. |
| @@ -391,47 +458,6 @@ impl<'a> Control<'a> { | |||
| 391 | ], | 458 | ], |
| 392 | } | 459 | } |
| 393 | } | 460 | } |
| 394 | |||
| 395 | fn build<'d, D: Driver<'d>>( | ||
| 396 | &'d mut self, | ||
| 397 | builder: &mut UsbDeviceBuilder<'d, D>, | ||
| 398 | ep_out: Option<&D::EndpointOut>, | ||
| 399 | ep_in: &D::EndpointIn, | ||
| 400 | ) { | ||
| 401 | let len = self.report_descriptor.len(); | ||
| 402 | let if_num = builder.alloc_interface_with_handler(self); | ||
| 403 | |||
| 404 | builder.config_descriptor.interface( | ||
| 405 | if_num, | ||
| 406 | USB_CLASS_HID, | ||
| 407 | USB_SUBCLASS_NONE, | ||
| 408 | USB_PROTOCOL_NONE, | ||
| 409 | ); | ||
| 410 | |||
| 411 | // HID descriptor | ||
| 412 | builder.config_descriptor.write( | ||
| 413 | HID_DESC_DESCTYPE_HID, | ||
| 414 | &[ | ||
| 415 | // HID Class spec version | ||
| 416 | HID_DESC_SPEC_1_10[0], | ||
| 417 | HID_DESC_SPEC_1_10[1], | ||
| 418 | // Country code not supported | ||
| 419 | HID_DESC_COUNTRY_UNSPEC, | ||
| 420 | // Number of following descriptors | ||
| 421 | 1, | ||
| 422 | // We have a HID report descriptor the host should read | ||
| 423 | HID_DESC_DESCTYPE_HID_REPORT, | ||
| 424 | // HID report descriptor size, | ||
| 425 | (len & 0xFF) as u8, | ||
| 426 | (len >> 8 & 0xFF) as u8, | ||
| 427 | ], | ||
| 428 | ); | ||
| 429 | |||
| 430 | builder.config_descriptor.endpoint(ep_in.info()); | ||
| 431 | if let Some(ep) = ep_out { | ||
| 432 | builder.config_descriptor.endpoint(ep.info()); | ||
| 433 | } | ||
| 434 | } | ||
| 435 | } | 461 | } |
| 436 | 462 | ||
| 437 | impl<'d> ControlHandler for Control<'d> { | 463 | impl<'d> ControlHandler for Control<'d> { |
diff --git a/examples/nrf/src/bin/usb_hid_keyboard.rs b/examples/nrf/src/bin/usb_hid_keyboard.rs index 5f03f5126..4ed49d375 100644 --- a/examples/nrf/src/bin/usb_hid_keyboard.rs +++ b/examples/nrf/src/bin/usb_hid_keyboard.rs | |||
| @@ -18,7 +18,7 @@ use embassy_nrf::usb::Driver; | |||
| 18 | use embassy_nrf::Peripherals; | 18 | use embassy_nrf::Peripherals; |
| 19 | use embassy_usb::control::OutResponse; | 19 | use embassy_usb::control::OutResponse; |
| 20 | use embassy_usb::{Config, DeviceStateHandler, UsbDeviceBuilder}; | 20 | use embassy_usb::{Config, DeviceStateHandler, UsbDeviceBuilder}; |
| 21 | use embassy_usb_hid::{HidClass, ReportId, RequestHandler, State}; | 21 | use embassy_usb_hid::{HidReaderWriter, ReportId, RequestHandler, State}; |
| 22 | use futures::future::join; | 22 | use futures::future::join; |
| 23 | use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor}; | 23 | use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor}; |
| 24 | 24 | ||
| @@ -75,7 +75,7 @@ async fn main(_spawner: Spawner, p: Peripherals) { | |||
| 75 | let request_handler = MyRequestHandler {}; | 75 | let request_handler = MyRequestHandler {}; |
| 76 | let device_state_handler = MyDeviceStateHandler::new(); | 76 | let device_state_handler = MyDeviceStateHandler::new(); |
| 77 | 77 | ||
| 78 | let mut state = State::<8, 1>::new(); | 78 | let mut state = State::new(); |
| 79 | 79 | ||
| 80 | let mut builder = UsbDeviceBuilder::new( | 80 | let mut builder = UsbDeviceBuilder::new( |
| 81 | driver, | 81 | driver, |
| @@ -88,7 +88,7 @@ async fn main(_spawner: Spawner, p: Peripherals) { | |||
| 88 | ); | 88 | ); |
| 89 | 89 | ||
| 90 | // Create classes on the builder. | 90 | // Create classes on the builder. |
| 91 | let hid = HidClass::with_output_ep( | 91 | let hid = HidReaderWriter::<_, 1, 8>::new( |
| 92 | &mut builder, | 92 | &mut builder, |
| 93 | &mut state, | 93 | &mut state, |
| 94 | KeyboardReport::desc(), | 94 | KeyboardReport::desc(), |
| @@ -135,7 +135,7 @@ async fn main(_spawner: Spawner, p: Peripherals) { | |||
| 135 | 135 | ||
| 136 | let mut button = Input::new(p.P0_11.degrade(), Pull::Up); | 136 | let mut button = Input::new(p.P0_11.degrade(), Pull::Up); |
| 137 | 137 | ||
| 138 | let (mut hid_in, hid_out) = hid.split(); | 138 | let (reader, mut writer) = hid.split(); |
| 139 | 139 | ||
| 140 | // Do stuff with the class! | 140 | // Do stuff with the class! |
| 141 | let in_fut = async { | 141 | let in_fut = async { |
| @@ -153,7 +153,7 @@ async fn main(_spawner: Spawner, p: Peripherals) { | |||
| 153 | modifier: 0, | 153 | modifier: 0, |
| 154 | reserved: 0, | 154 | reserved: 0, |
| 155 | }; | 155 | }; |
| 156 | match hid_in.serialize(&report).await { | 156 | match writer.write_serialize(&report).await { |
| 157 | Ok(()) => {} | 157 | Ok(()) => {} |
| 158 | Err(e) => warn!("Failed to send report: {:?}", e), | 158 | Err(e) => warn!("Failed to send report: {:?}", e), |
| 159 | }; | 159 | }; |
| @@ -167,7 +167,7 @@ async fn main(_spawner: Spawner, p: Peripherals) { | |||
| 167 | modifier: 0, | 167 | modifier: 0, |
| 168 | reserved: 0, | 168 | reserved: 0, |
| 169 | }; | 169 | }; |
| 170 | match hid_in.serialize(&report).await { | 170 | match writer.write_serialize(&report).await { |
| 171 | Ok(()) => {} | 171 | Ok(()) => {} |
| 172 | Err(e) => warn!("Failed to send report: {:?}", e), | 172 | Err(e) => warn!("Failed to send report: {:?}", e), |
| 173 | }; | 173 | }; |
| @@ -175,7 +175,7 @@ async fn main(_spawner: Spawner, p: Peripherals) { | |||
| 175 | }; | 175 | }; |
| 176 | 176 | ||
| 177 | let out_fut = async { | 177 | let out_fut = async { |
| 178 | hid_out.run(false, &request_handler).await; | 178 | reader.run(false, &request_handler).await; |
| 179 | }; | 179 | }; |
| 180 | 180 | ||
| 181 | let power_irq = interrupt::take!(POWER_CLOCK); | 181 | let power_irq = interrupt::take!(POWER_CLOCK); |
diff --git a/examples/nrf/src/bin/usb_hid_mouse.rs b/examples/nrf/src/bin/usb_hid_mouse.rs index fe27e76fb..bbdced745 100644 --- a/examples/nrf/src/bin/usb_hid_mouse.rs +++ b/examples/nrf/src/bin/usb_hid_mouse.rs | |||
| @@ -13,7 +13,7 @@ use embassy_nrf::usb::Driver; | |||
| 13 | use embassy_nrf::Peripherals; | 13 | use embassy_nrf::Peripherals; |
| 14 | use embassy_usb::control::OutResponse; | 14 | use embassy_usb::control::OutResponse; |
| 15 | use embassy_usb::{Config, UsbDeviceBuilder}; | 15 | use embassy_usb::{Config, UsbDeviceBuilder}; |
| 16 | use embassy_usb_hid::{HidClass, ReportId, RequestHandler, State}; | 16 | use embassy_usb_hid::{HidWriter, ReportId, RequestHandler, State}; |
| 17 | use futures::future::join; | 17 | use futures::future::join; |
| 18 | use usbd_hid::descriptor::{MouseReport, SerializedDescriptor}; | 18 | use usbd_hid::descriptor::{MouseReport, SerializedDescriptor}; |
| 19 | 19 | ||
| @@ -52,7 +52,7 @@ async fn main(_spawner: Spawner, p: Peripherals) { | |||
| 52 | let mut control_buf = [0; 16]; | 52 | let mut control_buf = [0; 16]; |
| 53 | let request_handler = MyRequestHandler {}; | 53 | let request_handler = MyRequestHandler {}; |
| 54 | 54 | ||
| 55 | let mut control = State::<5, 0>::new(); | 55 | let mut control = State::new(); |
| 56 | 56 | ||
| 57 | let mut builder = UsbDeviceBuilder::new( | 57 | let mut builder = UsbDeviceBuilder::new( |
| 58 | driver, | 58 | driver, |
| @@ -65,7 +65,7 @@ async fn main(_spawner: Spawner, p: Peripherals) { | |||
| 65 | ); | 65 | ); |
| 66 | 66 | ||
| 67 | // Create classes on the builder. | 67 | // Create classes on the builder. |
| 68 | let mut hid = HidClass::new( | 68 | let mut writer = HidWriter::<_, 5>::new( |
| 69 | &mut builder, | 69 | &mut builder, |
| 70 | &mut control, | 70 | &mut control, |
| 71 | MouseReport::desc(), | 71 | MouseReport::desc(), |
| @@ -94,7 +94,7 @@ async fn main(_spawner: Spawner, p: Peripherals) { | |||
| 94 | wheel: 0, | 94 | wheel: 0, |
| 95 | pan: 0, | 95 | pan: 0, |
| 96 | }; | 96 | }; |
| 97 | match hid.input().serialize(&report).await { | 97 | match writer.write_serialize(&report).await { |
| 98 | Ok(()) => {} | 98 | Ok(()) => {} |
| 99 | Err(e) => warn!("Failed to send report: {:?}", e), | 99 | Err(e) => warn!("Failed to send report: {:?}", e), |
| 100 | } | 100 | } |
