Unify ReadError and WriteError into EndpointError
This commit is contained in:
parent
b2cdaa56c1
commit
e867364d42
@ -10,7 +10,7 @@ use embassy::util::Unborrow;
|
|||||||
use embassy::waitqueue::AtomicWaker;
|
use embassy::waitqueue::AtomicWaker;
|
||||||
use embassy_hal_common::unborrow;
|
use embassy_hal_common::unborrow;
|
||||||
use embassy_usb::control::Request;
|
use embassy_usb::control::Request;
|
||||||
use embassy_usb::driver::{self, Event, ReadError, WriteError};
|
use embassy_usb::driver::{self, EndpointError, Event};
|
||||||
use embassy_usb::types::{EndpointAddress, EndpointInfo, EndpointType, UsbDirection};
|
use embassy_usb::types::{EndpointAddress, EndpointInfo, EndpointType, UsbDirection};
|
||||||
use futures::future::poll_fn;
|
use futures::future::poll_fn;
|
||||||
use futures::Future;
|
use futures::Future;
|
||||||
@ -472,13 +472,13 @@ impl<'d, T: Instance, Dir> Endpoint<'d, T, Dir> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn read_dma<T: Instance>(i: usize, buf: &mut [u8]) -> Result<usize, ReadError> {
|
unsafe fn read_dma<T: Instance>(i: usize, buf: &mut [u8]) -> Result<usize, EndpointError> {
|
||||||
let regs = T::regs();
|
let regs = T::regs();
|
||||||
|
|
||||||
// Check that the packet fits into the buffer
|
// Check that the packet fits into the buffer
|
||||||
let size = regs.size.epout[i].read().bits() as usize;
|
let size = regs.size.epout[i].read().bits() as usize;
|
||||||
if size > buf.len() {
|
if size > buf.len() {
|
||||||
return Err(ReadError::BufferOverflow);
|
return Err(EndpointError::BufferOverflow);
|
||||||
}
|
}
|
||||||
|
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
@ -554,7 +554,7 @@ unsafe fn write_dma<T: Instance>(i: usize, buf: &[u8]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance> driver::EndpointOut for Endpoint<'d, T, Out> {
|
impl<'d, T: Instance> driver::EndpointOut for Endpoint<'d, T, Out> {
|
||||||
type ReadFuture<'a> = impl Future<Output = Result<usize, ReadError>> + 'a where Self: 'a;
|
type ReadFuture<'a> = impl Future<Output = Result<usize, EndpointError>> + 'a where Self: 'a;
|
||||||
|
|
||||||
fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
|
fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
|
||||||
async move {
|
async move {
|
||||||
@ -563,7 +563,7 @@ impl<'d, T: Instance> driver::EndpointOut for Endpoint<'d, T, Out> {
|
|||||||
|
|
||||||
self.wait_data_ready()
|
self.wait_data_ready()
|
||||||
.await
|
.await
|
||||||
.map_err(|_| ReadError::Disabled)?;
|
.map_err(|_| EndpointError::Disabled)?;
|
||||||
|
|
||||||
unsafe { read_dma::<T>(i, buf) }
|
unsafe { read_dma::<T>(i, buf) }
|
||||||
}
|
}
|
||||||
@ -571,7 +571,7 @@ impl<'d, T: Instance> driver::EndpointOut for Endpoint<'d, T, Out> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance> driver::EndpointIn for Endpoint<'d, T, In> {
|
impl<'d, T: Instance> driver::EndpointIn for Endpoint<'d, T, In> {
|
||||||
type WriteFuture<'a> = impl Future<Output = Result<(), WriteError>> + 'a where Self: 'a;
|
type WriteFuture<'a> = impl Future<Output = Result<(), EndpointError>> + 'a where Self: 'a;
|
||||||
|
|
||||||
fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
|
fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
|
||||||
async move {
|
async move {
|
||||||
@ -580,7 +580,7 @@ impl<'d, T: Instance> driver::EndpointIn for Endpoint<'d, T, In> {
|
|||||||
|
|
||||||
self.wait_data_ready()
|
self.wait_data_ready()
|
||||||
.await
|
.await
|
||||||
.map_err(|_| WriteError::Disabled)?;
|
.map_err(|_| EndpointError::Disabled)?;
|
||||||
|
|
||||||
unsafe { write_dma::<T>(i, buf) }
|
unsafe { write_dma::<T>(i, buf) }
|
||||||
|
|
||||||
@ -596,8 +596,8 @@ pub struct ControlPipe<'d, T: Instance> {
|
|||||||
|
|
||||||
impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> {
|
impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> {
|
||||||
type SetupFuture<'a> = impl Future<Output = Request> + 'a where Self: 'a;
|
type SetupFuture<'a> = impl Future<Output = Request> + 'a where Self: 'a;
|
||||||
type DataOutFuture<'a> = impl Future<Output = Result<usize, ReadError>> + 'a where Self: 'a;
|
type DataOutFuture<'a> = impl Future<Output = Result<usize, EndpointError>> + 'a where Self: 'a;
|
||||||
type DataInFuture<'a> = impl Future<Output = Result<(), WriteError>> + 'a where Self: 'a;
|
type DataInFuture<'a> = impl Future<Output = Result<(), EndpointError>> + 'a where Self: 'a;
|
||||||
|
|
||||||
fn max_packet_size(&self) -> usize {
|
fn max_packet_size(&self) -> usize {
|
||||||
usize::from(self.max_packet_size)
|
usize::from(self.max_packet_size)
|
||||||
@ -666,10 +666,10 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> {
|
|||||||
Poll::Ready(Ok(()))
|
Poll::Ready(Ok(()))
|
||||||
} else if regs.events_usbreset.read().bits() != 0 {
|
} else if regs.events_usbreset.read().bits() != 0 {
|
||||||
trace!("aborted control data_out: usb reset");
|
trace!("aborted control data_out: usb reset");
|
||||||
Poll::Ready(Err(ReadError::Disabled))
|
Poll::Ready(Err(EndpointError::Disabled))
|
||||||
} else if regs.events_ep0setup.read().bits() != 0 {
|
} else if regs.events_ep0setup.read().bits() != 0 {
|
||||||
trace!("aborted control data_out: received another SETUP");
|
trace!("aborted control data_out: received another SETUP");
|
||||||
Poll::Ready(Err(ReadError::Disabled))
|
Poll::Ready(Err(EndpointError::Disabled))
|
||||||
} else {
|
} else {
|
||||||
Poll::Pending
|
Poll::Pending
|
||||||
}
|
}
|
||||||
@ -705,10 +705,10 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> {
|
|||||||
Poll::Ready(Ok(()))
|
Poll::Ready(Ok(()))
|
||||||
} else if regs.events_usbreset.read().bits() != 0 {
|
} else if regs.events_usbreset.read().bits() != 0 {
|
||||||
trace!("aborted control data_in: usb reset");
|
trace!("aborted control data_in: usb reset");
|
||||||
Poll::Ready(Err(WriteError::Disabled))
|
Poll::Ready(Err(EndpointError::Disabled))
|
||||||
} else if regs.events_ep0setup.read().bits() != 0 {
|
} else if regs.events_ep0setup.read().bits() != 0 {
|
||||||
trace!("aborted control data_in: received another SETUP");
|
trace!("aborted control data_in: received another SETUP");
|
||||||
Poll::Ready(Err(WriteError::Disabled))
|
Poll::Ready(Err(EndpointError::Disabled))
|
||||||
} else {
|
} else {
|
||||||
Poll::Pending
|
Poll::Pending
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ use embassy::time::Duration;
|
|||||||
use embassy_usb::driver::EndpointOut;
|
use embassy_usb::driver::EndpointOut;
|
||||||
use embassy_usb::{
|
use embassy_usb::{
|
||||||
control::{ControlHandler, InResponse, OutResponse, Request, RequestType},
|
control::{ControlHandler, InResponse, OutResponse, Request, RequestType},
|
||||||
driver::{Driver, Endpoint, EndpointIn, WriteError},
|
driver::{Driver, Endpoint, EndpointError, EndpointIn},
|
||||||
UsbDeviceBuilder,
|
UsbDeviceBuilder,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -187,9 +187,9 @@ pub enum ReadError {
|
|||||||
Sync(Range<usize>),
|
Sync(Range<usize>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<embassy_usb::driver::ReadError> for ReadError {
|
impl From<embassy_usb::driver::EndpointError> for ReadError {
|
||||||
fn from(val: embassy_usb::driver::ReadError) -> Self {
|
fn from(val: embassy_usb::driver::EndpointError) -> Self {
|
||||||
use embassy_usb::driver::ReadError::*;
|
use embassy_usb::driver::EndpointError::*;
|
||||||
match val {
|
match val {
|
||||||
BufferOverflow => ReadError::BufferOverflow,
|
BufferOverflow => ReadError::BufferOverflow,
|
||||||
Disabled => ReadError::Disabled,
|
Disabled => ReadError::Disabled,
|
||||||
@ -207,11 +207,11 @@ impl<'d, D: Driver<'d>, const N: usize> ReportWriter<'d, D, N> {
|
|||||||
///
|
///
|
||||||
/// Panics if no endpoint is available.
|
/// Panics if no endpoint is available.
|
||||||
#[cfg(feature = "usbd-hid")]
|
#[cfg(feature = "usbd-hid")]
|
||||||
pub async fn serialize<IR: AsInputReport>(&mut self, r: &IR) -> Result<(), WriteError> {
|
pub async fn serialize<IR: AsInputReport>(&mut self, r: &IR) -> Result<(), EndpointError> {
|
||||||
let mut buf: [u8; N] = [0; N];
|
let mut buf: [u8; N] = [0; N];
|
||||||
let size = match serialize(&mut buf, r) {
|
let size = match serialize(&mut buf, r) {
|
||||||
Ok(size) => size,
|
Ok(size) => size,
|
||||||
Err(_) => return Err(WriteError::BufferOverflow),
|
Err(_) => return Err(EndpointError::BufferOverflow),
|
||||||
};
|
};
|
||||||
self.write(&buf[0..size]).await
|
self.write(&buf[0..size]).await
|
||||||
}
|
}
|
||||||
@ -219,7 +219,7 @@ impl<'d, D: Driver<'d>, const N: usize> ReportWriter<'d, D, N> {
|
|||||||
/// Writes `report` to its interrupt endpoint.
|
/// Writes `report` to its interrupt endpoint.
|
||||||
///
|
///
|
||||||
/// Panics if no endpoint is available.
|
/// Panics if no endpoint is available.
|
||||||
pub async fn write(&mut self, report: &[u8]) -> Result<(), WriteError> {
|
pub async fn write(&mut self, report: &[u8]) -> Result<(), EndpointError> {
|
||||||
assert!(report.len() <= N);
|
assert!(report.len() <= N);
|
||||||
|
|
||||||
let max_packet_size = usize::from(self.ep_in.info().max_packet_size);
|
let max_packet_size = usize::from(self.ep_in.info().max_packet_size);
|
||||||
|
@ -10,7 +10,7 @@ use core::mem::{self, MaybeUninit};
|
|||||||
use core::sync::atomic::{AtomicBool, Ordering};
|
use core::sync::atomic::{AtomicBool, Ordering};
|
||||||
use embassy::blocking_mutex::CriticalSectionMutex;
|
use embassy::blocking_mutex::CriticalSectionMutex;
|
||||||
use embassy_usb::control::{self, ControlHandler, InResponse, OutResponse, Request};
|
use embassy_usb::control::{self, ControlHandler, InResponse, OutResponse, Request};
|
||||||
use embassy_usb::driver::{Endpoint, EndpointIn, EndpointOut, ReadError, WriteError};
|
use embassy_usb::driver::{Endpoint, EndpointError, EndpointIn, EndpointOut};
|
||||||
use embassy_usb::{driver::Driver, types::*, UsbDeviceBuilder};
|
use embassy_usb::{driver::Driver, types::*, UsbDeviceBuilder};
|
||||||
|
|
||||||
/// This should be used as `device_class` when building the `UsbDevice`.
|
/// This should be used as `device_class` when building the `UsbDevice`.
|
||||||
@ -265,12 +265,12 @@ impl<'d, D: Driver<'d>> CdcAcmClass<'d, D> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Writes a single packet into the IN endpoint.
|
/// Writes a single packet into the IN endpoint.
|
||||||
pub async fn write_packet(&mut self, data: &[u8]) -> Result<(), WriteError> {
|
pub async fn write_packet(&mut self, data: &[u8]) -> Result<(), EndpointError> {
|
||||||
self.write_ep.write(data).await
|
self.write_ep.write(data).await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reads a single packet from the OUT endpoint.
|
/// Reads a single packet from the OUT endpoint.
|
||||||
pub async fn read_packet(&mut self, data: &mut [u8]) -> Result<usize, ReadError> {
|
pub async fn read_packet(&mut self, data: &mut [u8]) -> Result<usize, EndpointError> {
|
||||||
self.read_ep.read(data).await
|
self.read_ep.read(data).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use core::mem;
|
use core::mem;
|
||||||
|
|
||||||
use crate::descriptor::DescriptorWriter;
|
use crate::descriptor::DescriptorWriter;
|
||||||
use crate::driver::{self, ReadError};
|
use crate::driver::{self, EndpointError};
|
||||||
use crate::DEFAULT_ALTERNATE_SETTING;
|
use crate::DEFAULT_ALTERNATE_SETTING;
|
||||||
|
|
||||||
use super::types::*;
|
use super::types::*;
|
||||||
@ -253,7 +253,7 @@ impl<C: driver::ControlPipe> ControlPipe<C> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
buf: &'a mut [u8],
|
buf: &'a mut [u8],
|
||||||
stage: DataOutStage,
|
stage: DataOutStage,
|
||||||
) -> Result<(&'a [u8], StatusStage), ReadError> {
|
) -> Result<(&'a [u8], StatusStage), EndpointError> {
|
||||||
if stage.length == 0 {
|
if stage.length == 0 {
|
||||||
Ok((&[], StatusStage {}))
|
Ok((&[], StatusStage {}))
|
||||||
} else {
|
} else {
|
||||||
|
@ -130,7 +130,7 @@ pub trait Endpoint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait EndpointOut: Endpoint {
|
pub trait EndpointOut: Endpoint {
|
||||||
type ReadFuture<'a>: Future<Output = Result<usize, ReadError>> + 'a
|
type ReadFuture<'a>: Future<Output = Result<usize, EndpointError>> + 'a
|
||||||
where
|
where
|
||||||
Self: 'a;
|
Self: 'a;
|
||||||
|
|
||||||
@ -145,10 +145,10 @@ pub trait ControlPipe {
|
|||||||
type SetupFuture<'a>: Future<Output = Request> + 'a
|
type SetupFuture<'a>: Future<Output = Request> + 'a
|
||||||
where
|
where
|
||||||
Self: 'a;
|
Self: 'a;
|
||||||
type DataOutFuture<'a>: Future<Output = Result<usize, ReadError>> + 'a
|
type DataOutFuture<'a>: Future<Output = Result<usize, EndpointError>> + 'a
|
||||||
where
|
where
|
||||||
Self: 'a;
|
Self: 'a;
|
||||||
type DataInFuture<'a>: Future<Output = Result<(), WriteError>> + 'a
|
type DataInFuture<'a>: Future<Output = Result<(), EndpointError>> + 'a
|
||||||
where
|
where
|
||||||
Self: 'a;
|
Self: 'a;
|
||||||
|
|
||||||
@ -181,7 +181,7 @@ pub trait ControlPipe {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait EndpointIn: Endpoint {
|
pub trait EndpointIn: Endpoint {
|
||||||
type WriteFuture<'a>: Future<Output = Result<(), WriteError>> + 'a
|
type WriteFuture<'a>: Future<Output = Result<(), EndpointError>> + 'a
|
||||||
where
|
where
|
||||||
Self: 'a;
|
Self: 'a;
|
||||||
|
|
||||||
@ -216,24 +216,12 @@ pub struct Unsupported;
|
|||||||
|
|
||||||
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
|
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
/// Errors returned by [`EndpointIn::write`]
|
/// Errors returned by [`EndpointIn::write`] and [`EndpointOut::read`]
|
||||||
pub enum WriteError {
|
pub enum EndpointError {
|
||||||
/// The packet is too long to fit in the
|
/// Either the packet to be written is too long to fit in the transmission
|
||||||
/// transmission buffer. This is generally an error in the class implementation, because the
|
/// buffer or the received packet is too long to fit in `buf`.
|
||||||
/// class shouldn't provide more data than the `max_packet_size` it specified when allocating
|
|
||||||
/// the endpoint.
|
|
||||||
BufferOverflow,
|
BufferOverflow,
|
||||||
Disabled,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
|
/// The endpoint is disabled.
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
|
||||||
/// Errors returned by [`EndpointOut::read`]
|
|
||||||
pub enum ReadError {
|
|
||||||
/// The received packet is too long to
|
|
||||||
/// fit in `buf`. This is generally an error in the class implementation, because the class
|
|
||||||
/// should use a buffer that is large enough for the `max_packet_size` it specified when
|
|
||||||
/// allocating the endpoint.
|
|
||||||
BufferOverflow,
|
|
||||||
Disabled,
|
Disabled,
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ use embassy_nrf::interrupt;
|
|||||||
use embassy_nrf::pac;
|
use embassy_nrf::pac;
|
||||||
use embassy_nrf::usb::{Driver, Instance};
|
use embassy_nrf::usb::{Driver, Instance};
|
||||||
use embassy_nrf::Peripherals;
|
use embassy_nrf::Peripherals;
|
||||||
use embassy_usb::driver::{ReadError, WriteError};
|
use embassy_usb::driver::EndpointError;
|
||||||
use embassy_usb::{Config, UsbDeviceBuilder};
|
use embassy_usb::{Config, UsbDeviceBuilder};
|
||||||
use embassy_usb_serial::{CdcAcmClass, State};
|
use embassy_usb_serial::{CdcAcmClass, State};
|
||||||
use futures::future::join;
|
use futures::future::join;
|
||||||
@ -82,20 +82,11 @@ async fn main(_spawner: Spawner, p: Peripherals) {
|
|||||||
|
|
||||||
struct Disconnected {}
|
struct Disconnected {}
|
||||||
|
|
||||||
impl From<ReadError> for Disconnected {
|
impl From<EndpointError> for Disconnected {
|
||||||
fn from(val: ReadError) -> Self {
|
fn from(val: EndpointError) -> Self {
|
||||||
match val {
|
match val {
|
||||||
ReadError::BufferOverflow => panic!("Buffer overflow"),
|
EndpointError::BufferOverflow => panic!("Buffer overflow"),
|
||||||
ReadError::Disabled => Disconnected {},
|
EndpointError::Disabled => Disconnected {},
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<WriteError> for Disconnected {
|
|
||||||
fn from(val: WriteError) -> Self {
|
|
||||||
match val {
|
|
||||||
WriteError::BufferOverflow => panic!("Buffer overflow"),
|
|
||||||
WriteError::Disabled => Disconnected {},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ use embassy_nrf::pac;
|
|||||||
use embassy_nrf::usb::Driver;
|
use embassy_nrf::usb::Driver;
|
||||||
use embassy_nrf::Peripherals;
|
use embassy_nrf::Peripherals;
|
||||||
use embassy_nrf::{interrupt, peripherals};
|
use embassy_nrf::{interrupt, peripherals};
|
||||||
use embassy_usb::driver::{ReadError, WriteError};
|
use embassy_usb::driver::EndpointError;
|
||||||
use embassy_usb::{Config, UsbDevice, UsbDeviceBuilder};
|
use embassy_usb::{Config, UsbDevice, UsbDeviceBuilder};
|
||||||
use embassy_usb_serial::{CdcAcmClass, State};
|
use embassy_usb_serial::{CdcAcmClass, State};
|
||||||
|
|
||||||
@ -93,20 +93,11 @@ async fn main(spawner: Spawner, p: Peripherals) {
|
|||||||
|
|
||||||
struct Disconnected {}
|
struct Disconnected {}
|
||||||
|
|
||||||
impl From<ReadError> for Disconnected {
|
impl From<EndpointError> for Disconnected {
|
||||||
fn from(val: ReadError) -> Self {
|
fn from(val: EndpointError) -> Self {
|
||||||
match val {
|
match val {
|
||||||
ReadError::BufferOverflow => panic!("Buffer overflow"),
|
EndpointError::BufferOverflow => panic!("Buffer overflow"),
|
||||||
ReadError::Disabled => Disconnected {},
|
EndpointError::Disabled => Disconnected {},
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<WriteError> for Disconnected {
|
|
||||||
fn from(val: WriteError) -> Self {
|
|
||||||
match val {
|
|
||||||
WriteError::BufferOverflow => panic!("Buffer overflow"),
|
|
||||||
WriteError::Disabled => Disconnected {},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user