aboutsummaryrefslogtreecommitdiff
path: root/examples/nrf/src/bin
diff options
context:
space:
mode:
authoralexmoon <[email protected]>2022-03-27 17:12:57 -0400
committerDario Nieuwenhuis <[email protected]>2022-04-06 05:38:11 +0200
commit52c622b1cd02ba13accc84cd57e90b04797f0405 (patch)
tree67057b66716715a75a2ca60ecf6115720d577961 /examples/nrf/src/bin
parentbdc6e0481c42d20d5cca19dfc8ec56306e47296e (diff)
Use trait objects instead of generics for UsbDevice::classes
Diffstat (limited to 'examples/nrf/src/bin')
-rw-r--r--examples/nrf/src/bin/usb/cdc_acm.rs117
-rw-r--r--examples/nrf/src/bin/usb/main.rs4
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 @@
1use core::future::Future;
2use core::mem; 1use core::mem;
3use defmt::info; 2use defmt::info;
4use embassy_usb::class::{ControlInRequestStatus, RequestStatus, UsbClass}; 3use 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
59impl<'d, D: Driver<'d>> UsbClass<'d, D> for CdcAcmControl { 58impl 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;
16use embassy_nrf::pac; 16use embassy_nrf::pac;
17use embassy_nrf::usb::Driver; 17use embassy_nrf::usb::Driver;
18use embassy_nrf::Peripherals; 18use embassy_nrf::Peripherals;
19use embassy_usb::class::UsbClass;
19use embassy_usb::driver::{EndpointIn, EndpointOut}; 20use embassy_usb::driver::{EndpointIn, EndpointOut};
20use embassy_usb::{Config, UsbDeviceBuilder}; 21use embassy_usb::{Config, UsbDeviceBuilder};
21use futures::future::join3; 22use 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();