diff options
| author | alexmoon <[email protected]> | 2022-03-27 17:12:57 -0400 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2022-04-06 05:38:11 +0200 |
| commit | 52c622b1cd02ba13accc84cd57e90b04797f0405 (patch) | |
| tree | 67057b66716715a75a2ca60ecf6115720d577961 /examples/nrf/src | |
| parent | bdc6e0481c42d20d5cca19dfc8ec56306e47296e (diff) | |
Use trait objects instead of generics for UsbDevice::classes
Diffstat (limited to 'examples/nrf/src')
| -rw-r--r-- | examples/nrf/src/bin/usb/cdc_acm.rs | 117 | ||||
| -rw-r--r-- | examples/nrf/src/bin/usb/main.rs | 4 |
2 files changed, 52 insertions, 69 deletions
diff --git a/examples/nrf/src/bin/usb/cdc_acm.rs b/examples/nrf/src/bin/usb/cdc_acm.rs index eebf89221..5e4abfea2 100644 --- a/examples/nrf/src/bin/usb/cdc_acm.rs +++ b/examples/nrf/src/bin/usb/cdc_acm.rs | |||
| @@ -1,4 +1,3 @@ | |||
| 1 | use core::future::Future; | ||
| 2 | use core::mem; | 1 | use core::mem; |
| 3 | use defmt::info; | 2 | use defmt::info; |
| 4 | use embassy_usb::class::{ControlInRequestStatus, RequestStatus, UsbClass}; | 3 | use embassy_usb::class::{ControlInRequestStatus, RequestStatus, UsbClass}; |
| @@ -56,89 +55,71 @@ pub struct CdcAcmControl { | |||
| 56 | pub rts: bool, | 55 | pub rts: bool, |
| 57 | } | 56 | } |
| 58 | 57 | ||
| 59 | impl<'d, D: Driver<'d>> UsbClass<'d, D> for CdcAcmControl { | 58 | impl UsbClass for CdcAcmControl { |
| 60 | type ControlOutFuture<'a> = impl Future<Output = RequestStatus> + 'a where Self: 'a, 'd: 'a, D: 'a; | ||
| 61 | type ControlInFuture<'a> = impl Future<Output = ControlInRequestStatus> + 'a where Self: 'a, 'd: 'a, D: 'a; | ||
| 62 | |||
| 63 | fn reset(&mut self) { | 59 | fn reset(&mut self) { |
| 64 | self.line_coding = LineCoding::default(); | 60 | self.line_coding = LineCoding::default(); |
| 65 | self.dtr = false; | 61 | self.dtr = false; |
| 66 | self.rts = false; | 62 | self.rts = false; |
| 67 | } | 63 | } |
| 68 | 64 | ||
| 69 | fn control_out<'a>( | 65 | fn control_out(&mut self, req: control::Request, data: &[u8]) -> RequestStatus { |
| 70 | &'a mut self, | 66 | if !(req.request_type == control::RequestType::Class |
| 71 | req: control::Request, | 67 | && req.recipient == control::Recipient::Interface |
| 72 | data: &'a [u8], | 68 | && req.index == u8::from(self.comm_if) as u16) |
| 73 | ) -> Self::ControlOutFuture<'a> | 69 | { |
| 74 | where | 70 | return RequestStatus::Unhandled; |
| 75 | 'd: 'a, | 71 | } |
| 76 | D: 'a, | 72 | |
| 77 | { | 73 | match req.request { |
| 78 | async move { | 74 | REQ_SEND_ENCAPSULATED_COMMAND => { |
| 79 | if !(req.request_type == control::RequestType::Class | 75 | // We don't actually support encapsulated commands but pretend we do for standards |
| 80 | && req.recipient == control::Recipient::Interface | 76 | // compatibility. |
| 81 | && req.index == u8::from(self.comm_if) as u16) | 77 | RequestStatus::Accepted |
| 82 | { | ||
| 83 | return RequestStatus::Unhandled; | ||
| 84 | } | 78 | } |
| 79 | REQ_SET_LINE_CODING if data.len() >= 7 => { | ||
| 80 | self.line_coding.data_rate = u32::from_le_bytes(data[0..4].try_into().unwrap()); | ||
| 81 | self.line_coding.stop_bits = data[4].into(); | ||
| 82 | self.line_coding.parity_type = data[5].into(); | ||
| 83 | self.line_coding.data_bits = data[6]; | ||
| 84 | info!("Set line coding to: {:?}", self.line_coding); | ||
| 85 | |||
| 86 | RequestStatus::Accepted | ||
| 87 | } | ||
| 88 | REQ_SET_CONTROL_LINE_STATE => { | ||
| 89 | self.dtr = (req.value & 0x0001) != 0; | ||
| 90 | self.rts = (req.value & 0x0002) != 0; | ||
| 91 | info!("Set dtr {}, rts {}", self.dtr, self.rts); | ||
| 85 | 92 | ||
| 86 | match req.request { | 93 | RequestStatus::Accepted |
| 87 | REQ_SEND_ENCAPSULATED_COMMAND => { | ||
| 88 | // We don't actually support encapsulated commands but pretend we do for standards | ||
| 89 | // compatibility. | ||
| 90 | RequestStatus::Accepted | ||
| 91 | } | ||
| 92 | REQ_SET_LINE_CODING if data.len() >= 7 => { | ||
| 93 | self.line_coding.data_rate = u32::from_le_bytes(data[0..4].try_into().unwrap()); | ||
| 94 | self.line_coding.stop_bits = data[4].into(); | ||
| 95 | self.line_coding.parity_type = data[5].into(); | ||
| 96 | self.line_coding.data_bits = data[6]; | ||
| 97 | info!("Set line coding to: {:?}", self.line_coding); | ||
| 98 | |||
| 99 | RequestStatus::Accepted | ||
| 100 | } | ||
| 101 | REQ_SET_CONTROL_LINE_STATE => { | ||
| 102 | self.dtr = (req.value & 0x0001) != 0; | ||
| 103 | self.rts = (req.value & 0x0002) != 0; | ||
| 104 | info!("Set dtr {}, rts {}", self.dtr, self.rts); | ||
| 105 | |||
| 106 | RequestStatus::Accepted | ||
| 107 | } | ||
| 108 | _ => RequestStatus::Rejected, | ||
| 109 | } | 94 | } |
| 95 | _ => RequestStatus::Rejected, | ||
| 110 | } | 96 | } |
| 111 | } | 97 | } |
| 112 | 98 | ||
| 113 | fn control_in<'a>( | 99 | fn control_in<'a>( |
| 114 | &'a mut self, | 100 | &mut self, |
| 115 | req: Request, | 101 | req: Request, |
| 116 | control: embassy_usb::class::ControlIn<'a, 'd, D>, | 102 | control: embassy_usb::class::ControlIn<'a>, |
| 117 | ) -> Self::ControlInFuture<'a> | 103 | ) -> ControlInRequestStatus<'a> { |
| 118 | where | 104 | if !(req.request_type == control::RequestType::Class |
| 119 | 'd: 'a, | 105 | && req.recipient == control::Recipient::Interface |
| 120 | { | 106 | && req.index == u8::from(self.comm_if) as u16) |
| 121 | async move { | 107 | { |
| 122 | if !(req.request_type == control::RequestType::Class | 108 | return control.ignore(); |
| 123 | && req.recipient == control::Recipient::Interface | 109 | } |
| 124 | && req.index == u8::from(self.comm_if) as u16) | ||
| 125 | { | ||
| 126 | return control.ignore(); | ||
| 127 | } | ||
| 128 | 110 | ||
| 129 | match req.request { | 111 | match req.request { |
| 130 | // REQ_GET_ENCAPSULATED_COMMAND is not really supported - it will be rejected below. | 112 | // REQ_GET_ENCAPSULATED_COMMAND is not really supported - it will be rejected below. |
| 131 | REQ_GET_LINE_CODING if req.length == 7 => { | 113 | REQ_GET_LINE_CODING if req.length == 7 => { |
| 132 | info!("Sending line coding"); | 114 | info!("Sending line coding"); |
| 133 | let mut data = [0; 7]; | 115 | let mut data = [0; 7]; |
| 134 | data[0..4].copy_from_slice(&self.line_coding.data_rate.to_le_bytes()); | 116 | data[0..4].copy_from_slice(&self.line_coding.data_rate.to_le_bytes()); |
| 135 | data[4] = self.line_coding.stop_bits as u8; | 117 | data[4] = self.line_coding.stop_bits as u8; |
| 136 | data[5] = self.line_coding.parity_type as u8; | 118 | data[5] = self.line_coding.parity_type as u8; |
| 137 | data[6] = self.line_coding.data_bits; | 119 | data[6] = self.line_coding.data_bits; |
| 138 | control.accept(&data).await | 120 | control.accept(&data) |
| 139 | } | ||
| 140 | _ => control.reject(), | ||
| 141 | } | 121 | } |
| 122 | _ => control.reject(), | ||
| 142 | } | 123 | } |
| 143 | } | 124 | } |
| 144 | } | 125 | } |
diff --git a/examples/nrf/src/bin/usb/main.rs b/examples/nrf/src/bin/usb/main.rs index 71285579c..73ac3a21f 100644 --- a/examples/nrf/src/bin/usb/main.rs +++ b/examples/nrf/src/bin/usb/main.rs | |||
| @@ -16,6 +16,7 @@ use embassy_nrf::interrupt; | |||
| 16 | use embassy_nrf::pac; | 16 | use embassy_nrf::pac; |
| 17 | use embassy_nrf::usb::Driver; | 17 | use embassy_nrf::usb::Driver; |
| 18 | use embassy_nrf::Peripherals; | 18 | use embassy_nrf::Peripherals; |
| 19 | use embassy_usb::class::UsbClass; | ||
| 19 | use embassy_usb::driver::{EndpointIn, EndpointOut}; | 20 | use embassy_usb::driver::{EndpointIn, EndpointOut}; |
| 20 | use embassy_usb::{Config, UsbDeviceBuilder}; | 21 | use embassy_usb::{Config, UsbDeviceBuilder}; |
| 21 | use futures::future::join3; | 22 | use futures::future::join3; |
| @@ -59,7 +60,8 @@ async fn main(_spawner: Spawner, p: Peripherals) { | |||
| 59 | let mut class = CdcAcmClass::new(&mut builder, 64); | 60 | let mut class = CdcAcmClass::new(&mut builder, 64); |
| 60 | 61 | ||
| 61 | // Build the builder. | 62 | // Build the builder. |
| 62 | let mut usb = builder.build(class.control); | 63 | let mut classes: [&mut dyn UsbClass; 1] = [&mut class.control]; |
| 64 | let mut usb = builder.build(&mut classes); | ||
| 63 | 65 | ||
| 64 | // Run the USB device. | 66 | // Run the USB device. |
| 65 | let fut1 = usb.run(); | 67 | let fut1 = usb.run(); |
