aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-nrf/src/usb.rs26
-rw-r--r--embassy-usb-hid/src/lib.rs14
-rw-r--r--embassy-usb-serial/src/lib.rs6
-rw-r--r--embassy-usb/src/control.rs4
-rw-r--r--embassy-usb/src/driver.rs30
-rw-r--r--examples/nrf/src/bin/usb_serial.rs19
-rw-r--r--examples/nrf/src/bin/usb_serial_multitask.rs19
7 files changed, 44 insertions, 74 deletions
diff --git a/embassy-nrf/src/usb.rs b/embassy-nrf/src/usb.rs
index 9f483d96e..5e2f585f2 100644
--- a/embassy-nrf/src/usb.rs
+++ b/embassy-nrf/src/usb.rs
@@ -10,7 +10,7 @@ use embassy::util::Unborrow;
10use embassy::waitqueue::AtomicWaker; 10use embassy::waitqueue::AtomicWaker;
11use embassy_hal_common::unborrow; 11use embassy_hal_common::unborrow;
12use embassy_usb::control::Request; 12use embassy_usb::control::Request;
13use embassy_usb::driver::{self, Event, ReadError, WriteError}; 13use embassy_usb::driver::{self, EndpointError, Event};
14use embassy_usb::types::{EndpointAddress, EndpointInfo, EndpointType, UsbDirection}; 14use embassy_usb::types::{EndpointAddress, EndpointInfo, EndpointType, UsbDirection};
15use futures::future::poll_fn; 15use futures::future::poll_fn;
16use futures::Future; 16use futures::Future;
@@ -472,13 +472,13 @@ impl<'d, T: Instance, Dir> Endpoint<'d, T, Dir> {
472 } 472 }
473} 473}
474 474
475unsafe fn read_dma<T: Instance>(i: usize, buf: &mut [u8]) -> Result<usize, ReadError> { 475unsafe fn read_dma<T: Instance>(i: usize, buf: &mut [u8]) -> Result<usize, EndpointError> {
476 let regs = T::regs(); 476 let regs = T::regs();
477 477
478 // Check that the packet fits into the buffer 478 // Check that the packet fits into the buffer
479 let size = regs.size.epout[i].read().bits() as usize; 479 let size = regs.size.epout[i].read().bits() as usize;
480 if size > buf.len() { 480 if size > buf.len() {
481 return Err(ReadError::BufferOverflow); 481 return Err(EndpointError::BufferOverflow);
482 } 482 }
483 483
484 if i == 0 { 484 if i == 0 {
@@ -554,7 +554,7 @@ unsafe fn write_dma<T: Instance>(i: usize, buf: &[u8]) {
554} 554}
555 555
556impl<'d, T: Instance> driver::EndpointOut for Endpoint<'d, T, Out> { 556impl<'d, T: Instance> driver::EndpointOut for Endpoint<'d, T, Out> {
557 type ReadFuture<'a> = impl Future<Output = Result<usize, ReadError>> + 'a where Self: 'a; 557 type ReadFuture<'a> = impl Future<Output = Result<usize, EndpointError>> + 'a where Self: 'a;
558 558
559 fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> { 559 fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
560 async move { 560 async move {
@@ -563,7 +563,7 @@ impl<'d, T: Instance> driver::EndpointOut for Endpoint<'d, T, Out> {
563 563
564 self.wait_data_ready() 564 self.wait_data_ready()
565 .await 565 .await
566 .map_err(|_| ReadError::Disabled)?; 566 .map_err(|_| EndpointError::Disabled)?;
567 567
568 unsafe { read_dma::<T>(i, buf) } 568 unsafe { read_dma::<T>(i, buf) }
569 } 569 }
@@ -571,7 +571,7 @@ impl<'d, T: Instance> driver::EndpointOut for Endpoint<'d, T, Out> {
571} 571}
572 572
573impl<'d, T: Instance> driver::EndpointIn for Endpoint<'d, T, In> { 573impl<'d, T: Instance> driver::EndpointIn for Endpoint<'d, T, In> {
574 type WriteFuture<'a> = impl Future<Output = Result<(), WriteError>> + 'a where Self: 'a; 574 type WriteFuture<'a> = impl Future<Output = Result<(), EndpointError>> + 'a where Self: 'a;
575 575
576 fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> { 576 fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
577 async move { 577 async move {
@@ -580,7 +580,7 @@ impl<'d, T: Instance> driver::EndpointIn for Endpoint<'d, T, In> {
580 580
581 self.wait_data_ready() 581 self.wait_data_ready()
582 .await 582 .await
583 .map_err(|_| WriteError::Disabled)?; 583 .map_err(|_| EndpointError::Disabled)?;
584 584
585 unsafe { write_dma::<T>(i, buf) } 585 unsafe { write_dma::<T>(i, buf) }
586 586
@@ -596,8 +596,8 @@ pub struct ControlPipe<'d, T: Instance> {
596 596
597impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { 597impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> {
598 type SetupFuture<'a> = impl Future<Output = Request> + 'a where Self: 'a; 598 type SetupFuture<'a> = impl Future<Output = Request> + 'a where Self: 'a;
599 type DataOutFuture<'a> = impl Future<Output = Result<usize, ReadError>> + 'a where Self: 'a; 599 type DataOutFuture<'a> = impl Future<Output = Result<usize, EndpointError>> + 'a where Self: 'a;
600 type DataInFuture<'a> = impl Future<Output = Result<(), WriteError>> + 'a where Self: 'a; 600 type DataInFuture<'a> = impl Future<Output = Result<(), EndpointError>> + 'a where Self: 'a;
601 601
602 fn max_packet_size(&self) -> usize { 602 fn max_packet_size(&self) -> usize {
603 usize::from(self.max_packet_size) 603 usize::from(self.max_packet_size)
@@ -666,10 +666,10 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> {
666 Poll::Ready(Ok(())) 666 Poll::Ready(Ok(()))
667 } else if regs.events_usbreset.read().bits() != 0 { 667 } else if regs.events_usbreset.read().bits() != 0 {
668 trace!("aborted control data_out: usb reset"); 668 trace!("aborted control data_out: usb reset");
669 Poll::Ready(Err(ReadError::Disabled)) 669 Poll::Ready(Err(EndpointError::Disabled))
670 } else if regs.events_ep0setup.read().bits() != 0 { 670 } else if regs.events_ep0setup.read().bits() != 0 {
671 trace!("aborted control data_out: received another SETUP"); 671 trace!("aborted control data_out: received another SETUP");
672 Poll::Ready(Err(ReadError::Disabled)) 672 Poll::Ready(Err(EndpointError::Disabled))
673 } else { 673 } else {
674 Poll::Pending 674 Poll::Pending
675 } 675 }
@@ -705,10 +705,10 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> {
705 Poll::Ready(Ok(())) 705 Poll::Ready(Ok(()))
706 } else if regs.events_usbreset.read().bits() != 0 { 706 } else if regs.events_usbreset.read().bits() != 0 {
707 trace!("aborted control data_in: usb reset"); 707 trace!("aborted control data_in: usb reset");
708 Poll::Ready(Err(WriteError::Disabled)) 708 Poll::Ready(Err(EndpointError::Disabled))
709 } else if regs.events_ep0setup.read().bits() != 0 { 709 } else if regs.events_ep0setup.read().bits() != 0 {
710 trace!("aborted control data_in: received another SETUP"); 710 trace!("aborted control data_in: received another SETUP");
711 Poll::Ready(Err(WriteError::Disabled)) 711 Poll::Ready(Err(EndpointError::Disabled))
712 } else { 712 } else {
713 Poll::Pending 713 Poll::Pending
714 } 714 }
diff --git a/embassy-usb-hid/src/lib.rs b/embassy-usb-hid/src/lib.rs
index f50c5f8cb..e870becf5 100644
--- a/embassy-usb-hid/src/lib.rs
+++ b/embassy-usb-hid/src/lib.rs
@@ -15,7 +15,7 @@ use embassy::time::Duration;
15use embassy_usb::driver::EndpointOut; 15use embassy_usb::driver::EndpointOut;
16use embassy_usb::{ 16use embassy_usb::{
17 control::{ControlHandler, InResponse, OutResponse, Request, RequestType}, 17 control::{ControlHandler, InResponse, OutResponse, Request, RequestType},
18 driver::{Driver, Endpoint, EndpointIn, WriteError}, 18 driver::{Driver, Endpoint, EndpointError, EndpointIn},
19 UsbDeviceBuilder, 19 UsbDeviceBuilder,
20}; 20};
21 21
@@ -187,9 +187,9 @@ pub enum ReadError {
187 Sync(Range<usize>), 187 Sync(Range<usize>),
188} 188}
189 189
190impl From<embassy_usb::driver::ReadError> for ReadError { 190impl From<embassy_usb::driver::EndpointError> for ReadError {
191 fn from(val: embassy_usb::driver::ReadError) -> Self { 191 fn from(val: embassy_usb::driver::EndpointError) -> Self {
192 use embassy_usb::driver::ReadError::*; 192 use embassy_usb::driver::EndpointError::*;
193 match val { 193 match val {
194 BufferOverflow => ReadError::BufferOverflow, 194 BufferOverflow => ReadError::BufferOverflow,
195 Disabled => ReadError::Disabled, 195 Disabled => ReadError::Disabled,
@@ -207,11 +207,11 @@ impl<'d, D: Driver<'d>, const N: usize> ReportWriter<'d, D, N> {
207 /// 207 ///
208 /// Panics if no endpoint is available. 208 /// Panics if no endpoint is available.
209 #[cfg(feature = "usbd-hid")] 209 #[cfg(feature = "usbd-hid")]
210 pub async fn serialize<IR: AsInputReport>(&mut self, r: &IR) -> Result<(), WriteError> { 210 pub async fn serialize<IR: AsInputReport>(&mut self, r: &IR) -> Result<(), EndpointError> {
211 let mut buf: [u8; N] = [0; N]; 211 let mut buf: [u8; N] = [0; N];
212 let size = match serialize(&mut buf, r) { 212 let size = match serialize(&mut buf, r) {
213 Ok(size) => size, 213 Ok(size) => size,
214 Err(_) => return Err(WriteError::BufferOverflow), 214 Err(_) => return Err(EndpointError::BufferOverflow),
215 }; 215 };
216 self.write(&buf[0..size]).await 216 self.write(&buf[0..size]).await
217 } 217 }
@@ -219,7 +219,7 @@ impl<'d, D: Driver<'d>, const N: usize> ReportWriter<'d, D, N> {
219 /// Writes `report` to its interrupt endpoint. 219 /// Writes `report` to its interrupt endpoint.
220 /// 220 ///
221 /// Panics if no endpoint is available. 221 /// Panics if no endpoint is available.
222 pub async fn write(&mut self, report: &[u8]) -> Result<(), WriteError> { 222 pub async fn write(&mut self, report: &[u8]) -> Result<(), EndpointError> {
223 assert!(report.len() <= N); 223 assert!(report.len() <= N);
224 224
225 let max_packet_size = usize::from(self.ep_in.info().max_packet_size); 225 let max_packet_size = usize::from(self.ep_in.info().max_packet_size);
diff --git a/embassy-usb-serial/src/lib.rs b/embassy-usb-serial/src/lib.rs
index 07352fac5..7b25398d0 100644
--- a/embassy-usb-serial/src/lib.rs
+++ b/embassy-usb-serial/src/lib.rs
@@ -10,7 +10,7 @@ use core::mem::{self, MaybeUninit};
10use core::sync::atomic::{AtomicBool, Ordering}; 10use core::sync::atomic::{AtomicBool, Ordering};
11use embassy::blocking_mutex::CriticalSectionMutex; 11use embassy::blocking_mutex::CriticalSectionMutex;
12use embassy_usb::control::{self, ControlHandler, InResponse, OutResponse, Request}; 12use embassy_usb::control::{self, ControlHandler, InResponse, OutResponse, Request};
13use embassy_usb::driver::{Endpoint, EndpointIn, EndpointOut, ReadError, WriteError}; 13use embassy_usb::driver::{Endpoint, EndpointError, EndpointIn, EndpointOut};
14use embassy_usb::{driver::Driver, types::*, UsbDeviceBuilder}; 14use embassy_usb::{driver::Driver, types::*, UsbDeviceBuilder};
15 15
16/// This should be used as `device_class` when building the `UsbDevice`. 16/// This should be used as `device_class` when building the `UsbDevice`.
@@ -265,12 +265,12 @@ impl<'d, D: Driver<'d>> CdcAcmClass<'d, D> {
265 } 265 }
266 266
267 /// Writes a single packet into the IN endpoint. 267 /// Writes a single packet into the IN endpoint.
268 pub async fn write_packet(&mut self, data: &[u8]) -> Result<(), WriteError> { 268 pub async fn write_packet(&mut self, data: &[u8]) -> Result<(), EndpointError> {
269 self.write_ep.write(data).await 269 self.write_ep.write(data).await
270 } 270 }
271 271
272 /// Reads a single packet from the OUT endpoint. 272 /// Reads a single packet from the OUT endpoint.
273 pub async fn read_packet(&mut self, data: &mut [u8]) -> Result<usize, ReadError> { 273 pub async fn read_packet(&mut self, data: &mut [u8]) -> Result<usize, EndpointError> {
274 self.read_ep.read(data).await 274 self.read_ep.read(data).await
275 } 275 }
276 276
diff --git a/embassy-usb/src/control.rs b/embassy-usb/src/control.rs
index 7c46812bd..a613f1145 100644
--- a/embassy-usb/src/control.rs
+++ b/embassy-usb/src/control.rs
@@ -1,7 +1,7 @@
1use core::mem; 1use core::mem;
2 2
3use crate::descriptor::DescriptorWriter; 3use crate::descriptor::DescriptorWriter;
4use crate::driver::{self, ReadError}; 4use crate::driver::{self, EndpointError};
5use crate::DEFAULT_ALTERNATE_SETTING; 5use crate::DEFAULT_ALTERNATE_SETTING;
6 6
7use super::types::*; 7use super::types::*;
@@ -253,7 +253,7 @@ impl<C: driver::ControlPipe> ControlPipe<C> {
253 &mut self, 253 &mut self,
254 buf: &'a mut [u8], 254 buf: &'a mut [u8],
255 stage: DataOutStage, 255 stage: DataOutStage,
256 ) -> Result<(&'a [u8], StatusStage), ReadError> { 256 ) -> Result<(&'a [u8], StatusStage), EndpointError> {
257 if stage.length == 0 { 257 if stage.length == 0 {
258 Ok((&[], StatusStage {})) 258 Ok((&[], StatusStage {}))
259 } else { 259 } else {
diff --git a/embassy-usb/src/driver.rs b/embassy-usb/src/driver.rs
index 01eb3d577..875ceafcb 100644
--- a/embassy-usb/src/driver.rs
+++ b/embassy-usb/src/driver.rs
@@ -130,7 +130,7 @@ pub trait Endpoint {
130} 130}
131 131
132pub trait EndpointOut: Endpoint { 132pub trait EndpointOut: Endpoint {
133 type ReadFuture<'a>: Future<Output = Result<usize, ReadError>> + 'a 133 type ReadFuture<'a>: Future<Output = Result<usize, EndpointError>> + 'a
134 where 134 where
135 Self: 'a; 135 Self: 'a;
136 136
@@ -145,10 +145,10 @@ pub trait ControlPipe {
145 type SetupFuture<'a>: Future<Output = Request> + 'a 145 type SetupFuture<'a>: Future<Output = Request> + 'a
146 where 146 where
147 Self: 'a; 147 Self: 'a;
148 type DataOutFuture<'a>: Future<Output = Result<usize, ReadError>> + 'a 148 type DataOutFuture<'a>: Future<Output = Result<usize, EndpointError>> + 'a
149 where 149 where
150 Self: 'a; 150 Self: 'a;
151 type DataInFuture<'a>: Future<Output = Result<(), WriteError>> + 'a 151 type DataInFuture<'a>: Future<Output = Result<(), EndpointError>> + 'a
152 where 152 where
153 Self: 'a; 153 Self: 'a;
154 154
@@ -181,7 +181,7 @@ pub trait ControlPipe {
181} 181}
182 182
183pub trait EndpointIn: Endpoint { 183pub trait EndpointIn: Endpoint {
184 type WriteFuture<'a>: Future<Output = Result<(), WriteError>> + 'a 184 type WriteFuture<'a>: Future<Output = Result<(), EndpointError>> + 'a
185 where 185 where
186 Self: 'a; 186 Self: 'a;
187 187
@@ -216,24 +216,12 @@ pub struct Unsupported;
216 216
217#[derive(Copy, Clone, Eq, PartialEq, Debug)] 217#[derive(Copy, Clone, Eq, PartialEq, Debug)]
218#[cfg_attr(feature = "defmt", derive(defmt::Format))] 218#[cfg_attr(feature = "defmt", derive(defmt::Format))]
219/// Errors returned by [`EndpointIn::write`] 219/// Errors returned by [`EndpointIn::write`] and [`EndpointOut::read`]
220pub enum WriteError { 220pub enum EndpointError {
221 /// The packet is too long to fit in the 221 /// Either the packet to be written is too long to fit in the transmission
222 /// transmission buffer. This is generally an error in the class implementation, because the 222 /// buffer or the received packet is too long to fit in `buf`.
223 /// class shouldn't provide more data than the `max_packet_size` it specified when allocating
224 /// the endpoint.
225 BufferOverflow, 223 BufferOverflow,
226 Disabled,
227}
228 224
229#[derive(Copy, Clone, Eq, PartialEq, Debug)] 225 /// The endpoint is disabled.
230#[cfg_attr(feature = "defmt", derive(defmt::Format))]
231/// Errors returned by [`EndpointOut::read`]
232pub enum ReadError {
233 /// The received packet is too long to
234 /// fit in `buf`. This is generally an error in the class implementation, because the class
235 /// should use a buffer that is large enough for the `max_packet_size` it specified when
236 /// allocating the endpoint.
237 BufferOverflow,
238 Disabled, 226 Disabled,
239} 227}
diff --git a/examples/nrf/src/bin/usb_serial.rs b/examples/nrf/src/bin/usb_serial.rs
index 500be2ce8..684322837 100644
--- a/examples/nrf/src/bin/usb_serial.rs
+++ b/examples/nrf/src/bin/usb_serial.rs
@@ -10,7 +10,7 @@ use embassy_nrf::interrupt;
10use embassy_nrf::pac; 10use embassy_nrf::pac;
11use embassy_nrf::usb::{Driver, Instance}; 11use embassy_nrf::usb::{Driver, Instance};
12use embassy_nrf::Peripherals; 12use embassy_nrf::Peripherals;
13use embassy_usb::driver::{ReadError, WriteError}; 13use embassy_usb::driver::EndpointError;
14use embassy_usb::{Config, UsbDeviceBuilder}; 14use embassy_usb::{Config, UsbDeviceBuilder};
15use embassy_usb_serial::{CdcAcmClass, State}; 15use embassy_usb_serial::{CdcAcmClass, State};
16use futures::future::join; 16use futures::future::join;
@@ -82,20 +82,11 @@ async fn main(_spawner: Spawner, p: Peripherals) {
82 82
83struct Disconnected {} 83struct Disconnected {}
84 84
85impl From<ReadError> for Disconnected { 85impl From<EndpointError> for Disconnected {
86 fn from(val: ReadError) -> Self { 86 fn from(val: EndpointError) -> Self {
87 match val { 87 match val {
88 ReadError::BufferOverflow => panic!("Buffer overflow"), 88 EndpointError::BufferOverflow => panic!("Buffer overflow"),
89 ReadError::Disabled => Disconnected {}, 89 EndpointError::Disabled => Disconnected {},
90 }
91 }
92}
93
94impl From<WriteError> for Disconnected {
95 fn from(val: WriteError) -> Self {
96 match val {
97 WriteError::BufferOverflow => panic!("Buffer overflow"),
98 WriteError::Disabled => Disconnected {},
99 } 90 }
100 } 91 }
101} 92}
diff --git a/examples/nrf/src/bin/usb_serial_multitask.rs b/examples/nrf/src/bin/usb_serial_multitask.rs
index 1258bc53d..bfb09014c 100644
--- a/examples/nrf/src/bin/usb_serial_multitask.rs
+++ b/examples/nrf/src/bin/usb_serial_multitask.rs
@@ -11,7 +11,7 @@ use embassy_nrf::pac;
11use embassy_nrf::usb::Driver; 11use embassy_nrf::usb::Driver;
12use embassy_nrf::Peripherals; 12use embassy_nrf::Peripherals;
13use embassy_nrf::{interrupt, peripherals}; 13use embassy_nrf::{interrupt, peripherals};
14use embassy_usb::driver::{ReadError, WriteError}; 14use embassy_usb::driver::EndpointError;
15use embassy_usb::{Config, UsbDevice, UsbDeviceBuilder}; 15use embassy_usb::{Config, UsbDevice, UsbDeviceBuilder};
16use embassy_usb_serial::{CdcAcmClass, State}; 16use embassy_usb_serial::{CdcAcmClass, State};
17 17
@@ -93,20 +93,11 @@ async fn main(spawner: Spawner, p: Peripherals) {
93 93
94struct Disconnected {} 94struct Disconnected {}
95 95
96impl From<ReadError> for Disconnected { 96impl From<EndpointError> for Disconnected {
97 fn from(val: ReadError) -> Self { 97 fn from(val: EndpointError) -> Self {
98 match val { 98 match val {
99 ReadError::BufferOverflow => panic!("Buffer overflow"), 99 EndpointError::BufferOverflow => panic!("Buffer overflow"),
100 ReadError::Disabled => Disconnected {}, 100 EndpointError::Disabled => Disconnected {},
101 }
102 }
103}
104
105impl From<WriteError> for Disconnected {
106 fn from(val: WriteError) -> Self {
107 match val {
108 WriteError::BufferOverflow => panic!("Buffer overflow"),
109 WriteError::Disabled => Disconnected {},
110 } 101 }
111 } 102 }
112} 103}