diff --git a/capsules/src/usb/usbc_client.rs b/capsules/src/usb/usbc_client.rs index b0678c23..9fb43781 100644 --- a/capsules/src/usb/usbc_client.rs +++ b/capsules/src/usb/usbc_client.rs @@ -115,11 +115,11 @@ impl<'a, C: hil::usb::UsbController<'a>> hil::usb::Client<'a> for Client<'a, C> self.client_ctrl.enable(); // Set up a bulk-in endpoint for debugging - self.controller().endpoint_set_buffer(1, self.buffer(1)); + self.controller().endpoint_set_in_buffer(1, self.buffer(1)); self.controller().endpoint_in_enable(TransferType::Bulk, 1); // Set up a bulk-out endpoint for debugging - self.controller().endpoint_set_buffer(2, self.buffer(2)); + self.controller().endpoint_set_out_buffer(2, self.buffer(2)); self.controller().endpoint_out_enable(TransferType::Bulk, 2); } diff --git a/capsules/src/usb/usbc_client_ctrl.rs b/capsules/src/usb/usbc_client_ctrl.rs index 2aaca0cc..5f9b253c 100644 --- a/capsules/src/usb/usbc_client_ctrl.rs +++ b/capsules/src/usb/usbc_client_ctrl.rs @@ -201,7 +201,7 @@ impl<'a, 'b, C: hil::usb::UsbController<'a>> ClientCtrl<'a, 'b, C> { pub fn enable(&'a self) { // Set up the default control endpoint self.controller - .endpoint_set_buffer(0, &self.ctrl_buffer.buf); + .endpoint_set_ctrl_buffer(&self.ctrl_buffer.buf); self.controller .enable_as_device(hil::usb::DeviceSpeed::Full); // must be Full for Bulk transfers self.controller diff --git a/capsules/src/usb/usbc_ctap_hid.rs b/capsules/src/usb/usbc_ctap_hid.rs index fdf7263a..4b1916cf 100644 --- a/capsules/src/usb/usbc_ctap_hid.rs +++ b/capsules/src/usb/usbc_ctap_hid.rs @@ -88,8 +88,9 @@ static HID: HIDDescriptor<'static> = HIDDescriptor { pub struct ClientCtapHID<'a, 'b, C: 'a> { client_ctrl: ClientCtrl<'a, 'static, C>, - // A 64-byte buffer for the endpoint - buffer: Buffer64, + // 64-byte buffers for the endpoint + in_buffer: Buffer64, + out_buffer: Buffer64, // Interaction with the client client: OptionalCell<&'b dyn CtapUsbClient>, @@ -133,7 +134,8 @@ impl<'a, 'b, C: hil::usb::UsbController<'a>> ClientCtapHID<'a, 'b, C> { LANGUAGES, STRINGS, ), - buffer: Default::default(), + in_buffer: Default::default(), + out_buffer: Default::default(), client: OptionalCell::empty(), tx_packet: OptionalCell::empty(), pending_in: Cell::new(false), @@ -187,7 +189,7 @@ impl<'a, 'b, C: hil::usb::UsbController<'a>> ClientCtapHID<'a, 'b, C> { fn send_packet_to_client(&'a self) -> bool { // Copy the packet into a buffer to send to the client. let mut buf: [u8; 64] = [0; 64]; - for (i, x) in self.buffer.buf.iter().enumerate() { + for (i, x) in self.out_buffer.buf.iter().enumerate() { buf[i] = x.get(); } @@ -220,11 +222,7 @@ impl<'a, 'b, C: hil::usb::UsbController<'a>> ClientCtapHID<'a, 'b, C> { fn cancel_in_transaction(&'a self) -> bool { self.tx_packet.take(); - let result = self.pending_in.take(); - if result { - self.controller().endpoint_cancel_in(1); - } - result + self.pending_in.take() } fn cancel_out_transaction(&'a self) -> bool { @@ -243,7 +241,10 @@ impl<'a, 'b, C: hil::usb::UsbController<'a>> hil::usb::Client<'a> for ClientCtap self.client_ctrl.enable(); // Set up the interrupt in-out endpoint - self.controller().endpoint_set_buffer(1, &self.buffer.buf); + self.controller() + .endpoint_set_in_buffer(1, &self.in_buffer.buf); + self.controller() + .endpoint_set_out_buffer(1, &self.out_buffer.buf); self.controller() .endpoint_in_out_enable(TransferType::Interrupt, 1); } @@ -293,7 +294,7 @@ impl<'a, 'b, C: hil::usb::UsbController<'a>> hil::usb::Client<'a> for ClientCtap } if let Some(packet) = self.tx_packet.take() { - let buf = &self.buffer.buf; + let buf = &self.in_buffer.buf; for i in 0..64 { buf[i].set(packet[i]); } @@ -346,6 +347,12 @@ impl<'a, 'b, C: hil::usb::UsbController<'a>> hil::usb::Client<'a> for ClientCtap panic!("Unexpected tx_packet while a packet was being transmitted."); } self.pending_in.set(false); + + // Clear any pending packet on the receiving side. + // It's up to the client to handle the transmitted packet and decide if they want to + // receive another packet. + self.cancel_out_transaction(); + // Notify the client self.client.map(|client| client.packet_transmitted()); } diff --git a/chips/nrf52/src/usbd.rs b/chips/nrf52/src/usbd.rs index 8c1992cc..972871d0 100644 --- a/chips/nrf52/src/usbd.rs +++ b/chips/nrf52/src/usbd.rs @@ -623,7 +623,7 @@ pub enum UsbState { pub enum EndpointState { Disabled, Ctrl(CtrlState), - Bulk(TransferType, EndpointDirection, BulkState), + Bulk(TransferType, Option, Option), } impl EndpointState { @@ -634,10 +634,10 @@ impl EndpointState { } } - fn bulk_state(self) -> (TransferType, EndpointDirection, BulkState) { + fn bulk_state(self) -> (TransferType, Option, Option) { match self { - EndpointState::Bulk(transfer_type, direction, state) => { - (transfer_type, direction, state) + EndpointState::Bulk(transfer_type, in_state, out_state) => { + (transfer_type, in_state, out_state) } _ => panic!("Expected EndpointState::Bulk"), } @@ -651,31 +651,18 @@ pub enum CtrlState { ReadStatus, } -#[derive(Copy, Clone, Debug)] -pub enum EndpointDirection { - In, - Out, - InOut, -} - -impl EndpointDirection { - fn has_in(&self) -> bool { - match self { - EndpointDirection::In | EndpointDirection::InOut => true, - EndpointDirection::Out => false, - } - } - - fn has_out(&self) -> bool { - match self { - EndpointDirection::Out | EndpointDirection::InOut => true, - EndpointDirection::In => false, - } - } +#[derive(Copy, Clone, PartialEq, Debug)] +pub enum BulkInState { + // The endpoint is ready to perform transactions. + Init, + // There is a pending DMA transfer on this IN endpoint. + InDma, + // There is a pending IN packet transfer on this endpoint. + InData, } #[derive(Copy, Clone, PartialEq, Debug)] -pub enum BulkState { +pub enum BulkOutState { // The endpoint is ready to perform transactions. Init, // There is a pending OUT packet in this endpoint's buffer, to be read by @@ -685,14 +672,11 @@ pub enum BulkState { OutData, // There is a pending DMA transfer on this OUT endpoint. OutDma, - // There is a pending DMA transfer on this IN endpoint. - InDma, - // There is a pending IN packet transfer on this endpoint. - InData, } pub struct Endpoint<'a> { - slice: OptionalCell<&'a [VolatileCell]>, + slice_in: OptionalCell<&'a [VolatileCell]>, + slice_out: OptionalCell<&'a [VolatileCell]>, state: Cell, // The USB controller can only process one DMA transfer at a time (over all endpoints). The // request_transmit_* bits allow to queue transfers until the DMA becomes available again. @@ -705,7 +689,8 @@ pub struct Endpoint<'a> { impl Endpoint<'_> { const fn new() -> Self { Endpoint { - slice: OptionalCell::empty(), + slice_in: OptionalCell::empty(), + slice_out: OptionalCell::empty(), state: Cell::new(EndpointState::Disabled), request_transmit_in: Cell::new(false), request_transmit_out: Cell::new(false), @@ -914,18 +899,12 @@ impl<'a> Usbd<'a> { chip_revision.get() ); } - Some(ChipRevision::REV::Value::REVC) => { + Some(ChipRevision::REV::Value::REVC) | Some(ChipRevision::REV::Value::REVD) => { debug_info!( "Your chip is NRF52840 revision {}. The USB stack was tested on your chip :)", chip_revision.get() ); } - Some(ChipRevision::REV::Value::REVD) => { - internal_warn!( - "Your chip is NRF52840 revision {}. Although this USB implementation should be compatible, your chip hasn't been tested.", - chip_revision.get() - ); - } None => { internal_warn!( "Your chip is NRF52840 revision {} (unknown revision). Although this USB implementation should be compatible, your chip hasn't been tested.", @@ -1026,7 +1005,7 @@ impl<'a> Usbd<'a> { }); self.descriptors[endpoint].state.set(match endpoint { 0 => EndpointState::Ctrl(CtrlState::Init), - 1..=7 => EndpointState::Bulk(transfer_type, EndpointDirection::In, BulkState::Init), + 1..=7 => EndpointState::Bulk(transfer_type, Some(BulkInState::Init), None), 8 => unimplemented!("isochronous endpoint"), _ => unreachable!("unexisting endpoint"), }); @@ -1064,7 +1043,7 @@ impl<'a> Usbd<'a> { }); self.descriptors[endpoint].state.set(match endpoint { 0 => EndpointState::Ctrl(CtrlState::Init), - 1..=7 => EndpointState::Bulk(transfer_type, EndpointDirection::Out, BulkState::Init), + 1..=7 => EndpointState::Bulk(transfer_type, None, Some(BulkOutState::Init)), 8 => unimplemented!("isochronous endpoint"), _ => unreachable!("unexisting endpoint"), }); @@ -1114,7 +1093,11 @@ impl<'a> Usbd<'a> { }); self.descriptors[endpoint].state.set(match endpoint { 0 => EndpointState::Ctrl(CtrlState::Init), - 1..=7 => EndpointState::Bulk(transfer_type, EndpointDirection::InOut, BulkState::Init), + 1..=7 => EndpointState::Bulk( + transfer_type, + Some(BulkInState::Init), + Some(BulkOutState::Init), + ), 8 => unimplemented!("isochronous endpoint"), _ => unreachable!("unexisting endpoint"), }); @@ -1304,13 +1287,13 @@ impl<'a> Usbd<'a> { match desc.state.get() { EndpointState::Disabled => {} EndpointState::Ctrl(_) => desc.state.set(EndpointState::Ctrl(CtrlState::Init)), - EndpointState::Bulk(transfer_type, direction, _) => { + EndpointState::Bulk(transfer_type, in_state, out_state) => { desc.state.set(EndpointState::Bulk( transfer_type, - direction, - BulkState::Init, + in_state.map(|_| BulkInState::Init), + out_state.map(|_| BulkOutState::Init), )); - if direction.has_out() { + if out_state.is_some() { // Accept incoming OUT packets. regs.size_epout[ep].set(0); } @@ -1347,13 +1330,13 @@ impl<'a> Usbd<'a> { match endpoint { 0 => {} 1..=7 => { - let (transfer_type, direction, state) = + let (transfer_type, in_state, out_state) = self.descriptors[endpoint].state.get().bulk_state(); - assert_eq!(state, BulkState::InDma); + assert_eq!(in_state, Some(BulkInState::InDma)); self.descriptors[endpoint].state.set(EndpointState::Bulk( transfer_type, - direction, - BulkState::InData, + Some(BulkInState::InData), + out_state, )); } 8 => unimplemented!("isochronous endpoint"), @@ -1405,25 +1388,25 @@ impl<'a> Usbd<'a> { 1..=7 => { // Notify the client about the new packet. let packet_bytes = regs.size_epout[endpoint].get(); - let (transfer_type, direction, state) = + let (transfer_type, in_state, out_state) = self.descriptors[endpoint].state.get().bulk_state(); - assert_eq!(state, BulkState::OutDma); + assert_eq!(out_state, Some(BulkOutState::OutDma)); - self.debug_packet("out", packet_bytes as usize, endpoint); + self.debug_out_packet(packet_bytes as usize, endpoint); self.client.map(|client| { let result = client.packet_out(transfer_type, endpoint, packet_bytes); debug_packets!("packet_out => {:?}", result); - let newstate = match result { + let new_out_state = match result { hil::usb::OutResult::Ok => { // Indicate that the endpoint is ready to receive data again. regs.size_epout[endpoint].set(0); - BulkState::Init + BulkOutState::Init } hil::usb::OutResult::Delay => { // We can't send the packet now. Wait for a resume_out call from the client. - BulkState::OutDelay + BulkOutState::OutDelay } hil::usb::OutResult::Error => { @@ -1432,13 +1415,13 @@ impl<'a> Usbd<'a> { + EndpointStall::IO::Out + EndpointStall::STALL::Stall, ); - BulkState::Init + BulkOutState::Init } }; self.descriptors[endpoint].state.set(EndpointState::Bulk( transfer_type, - direction, - newstate, + in_state, + Some(new_out_state), )); }); } @@ -1497,29 +1480,27 @@ impl<'a> Usbd<'a> { // Endpoint 8 (isochronous) doesn't receive any EPDATA event. for endpoint in 1..NUM_ENDPOINTS { if epdatastatus.is_set(status_epin(endpoint)) { - let (transfer_type, direction, state) = + let (transfer_type, in_state, out_state) = self.descriptors[endpoint].state.get().bulk_state(); - match state { - BulkState::InData => { + assert!(in_state.is_some()); + match in_state.unwrap() { + BulkInState::InData => { // Totally expected state. Nothing to do. } - BulkState::Init => { + BulkInState::Init => { internal_warn!( "Received a stale epdata IN in an unexpected state: {:?}", - state + in_state ); } - BulkState::OutDelay - | BulkState::OutData - | BulkState::OutDma - | BulkState::InDma => { - internal_err!("Unexpected state: {:?}", state); + BulkInState::InDma => { + internal_err!("Unexpected state: {:?}", in_state); } } self.descriptors[endpoint].state.set(EndpointState::Bulk( transfer_type, - direction, - BulkState::Init, + Some(BulkInState::Init), + out_state, )); self.client .map(|client| client.packet_transmitted(endpoint)); @@ -1530,28 +1511,26 @@ impl<'a> Usbd<'a> { // Endpoint 8 (isochronous) doesn't receive any EPDATA event. for ep in 1..NUM_ENDPOINTS { if epdatastatus.is_set(status_epout(ep)) { - let (transfer_type, direction, state) = + let (transfer_type, in_state, out_state) = self.descriptors[ep].state.get().bulk_state(); - match state { - BulkState::Init => { + assert!(out_state.is_some()); + match out_state.unwrap() { + BulkOutState::Init => { // The endpoint is ready to receive data. Request a transmit_out. self.descriptors[ep].request_transmit_out.set(true); } - BulkState::OutDelay => { + BulkOutState::OutDelay => { // The endpoint will be resumed later by the client application with transmit_out(). } - BulkState::OutData - | BulkState::OutDma - | BulkState::InDma - | BulkState::InData => { - internal_err!("Unexpected state: {:?}", state); + BulkOutState::OutData | BulkOutState::OutDma => { + internal_err!("Unexpected state: {:?}", out_state); } } // Indicate that the endpoint now has data available. self.descriptors[ep].state.set(EndpointState::Bulk( transfer_type, - direction, - BulkState::OutData, + in_state, + Some(BulkOutState::OutData), )); } } @@ -1564,8 +1543,8 @@ impl<'a> Usbd<'a> { let state = self.descriptors[endpoint].state.get().ctrl_state(); match state { CtrlState::Init => { - let ep_buf = &self.descriptors[endpoint].slice; - let ep_buf = ep_buf.expect("No slice set for this descriptor"); + let ep_buf = &self.descriptors[endpoint].slice_out; + let ep_buf = ep_buf.expect("No OUT slice set for this descriptor"); if ep_buf.len() < 8 { panic!("EP0 DMA buffer length < 8"); } @@ -1697,21 +1676,21 @@ impl<'a> Usbd<'a> { let regs = &*self.registers; self.client.map(|client| { - let (transfer_type, direction, state) = + let (transfer_type, in_state, out_state) = self.descriptors[endpoint].state.get().bulk_state(); - assert_eq!(state, BulkState::Init); + assert_eq!(in_state, Some(BulkInState::Init)); let result = client.packet_in(transfer_type, endpoint); debug_packets!("packet_in => {:?}", result); - let newstate = match result { + let new_in_state = match result { hil::usb::InResult::Packet(size) => { self.start_dma_in(endpoint, size); - BulkState::InDma + BulkInState::InDma } hil::usb::InResult::Delay => { // No packet to send now. Wait for a resume call from the client. - BulkState::Init + BulkInState::Init } hil::usb::InResult::Error => { @@ -1720,14 +1699,14 @@ impl<'a> Usbd<'a> { + EndpointStall::IO::In + EndpointStall::STALL::Stall, ); - BulkState::Init + BulkInState::Init } }; self.descriptors[endpoint].state.set(EndpointState::Bulk( transfer_type, - direction, - newstate, + Some(new_in_state), + out_state, )); }); } @@ -1735,15 +1714,16 @@ impl<'a> Usbd<'a> { fn transmit_out(&self, endpoint: usize) { debug_events!("transmit_out({})", endpoint); - let (transfer_type, direction, state) = self.descriptors[endpoint].state.get().bulk_state(); + let (transfer_type, in_state, out_state) = + self.descriptors[endpoint].state.get().bulk_state(); // Starting the DMA can only happen in the OutData state, i.e. after an EPDATA event. - assert_eq!(state, BulkState::OutData); + assert_eq!(out_state, Some(BulkOutState::OutData)); self.start_dma_out(endpoint); self.descriptors[endpoint].state.set(EndpointState::Bulk( transfer_type, - direction, - BulkState::OutDma, + in_state, + Some(BulkOutState::OutDma), )); } @@ -1751,9 +1731,9 @@ impl<'a> Usbd<'a> { let regs = &*self.registers; let slice = self.descriptors[endpoint] - .slice - .expect("No slice set for this descriptor"); - self.debug_packet("in", size, endpoint); + .slice_in + .expect("No IN slice set for this descriptor"); + self.debug_in_packet(size, endpoint); // Start DMA transfer self.set_pending_dma(); @@ -1766,8 +1746,8 @@ impl<'a> Usbd<'a> { let regs = &*self.registers; let slice = self.descriptors[endpoint] - .slice - .expect("No slice set for this descriptor"); + .slice_out + .expect("No OUT slice set for this descriptor"); // Start DMA transfer self.set_pending_dma(); @@ -1777,10 +1757,27 @@ impl<'a> Usbd<'a> { } // Debug-only function - fn debug_packet(&self, _title: &str, size: usize, endpoint: usize) { + fn debug_in_packet(&self, size: usize, endpoint: usize) { + let slice = self.descriptors[endpoint] + .slice_in + .expect("No IN slice set for this descriptor"); + if size > slice.len() { + panic!("Packet is too large: {}", size); + } + + let mut packet_hex = [0; 128]; + packet_to_hex(slice, &mut packet_hex); + debug_packets!( + "in={}", + core::str::from_utf8(&packet_hex[..(2 * size)]).unwrap() + ); + } + + // Debug-only function + fn debug_out_packet(&self, size: usize, endpoint: usize) { let slice = self.descriptors[endpoint] - .slice - .expect("No slice set for this descriptor"); + .slice_out + .expect("No OUT slice set for this descriptor"); if size > slice.len() { panic!("Packet is too large: {}", size); } @@ -1788,8 +1785,7 @@ impl<'a> Usbd<'a> { let mut packet_hex = [0; 128]; packet_to_hex(slice, &mut packet_hex); debug_packets!( - "{}={}", - _title, + "out={}", core::str::from_utf8(&packet_hex[..(2 * size)]).unwrap() ); } @@ -1807,17 +1803,41 @@ impl<'a> power::PowerClient for Usbd<'a> { } impl<'a> hil::usb::UsbController<'a> for Usbd<'a> { - fn endpoint_set_buffer(&self, endpoint: usize, buf: &'a [VolatileCell]) { + fn endpoint_set_ctrl_buffer(&self, buf: &'a [VolatileCell]) { + if buf.len() < 8 { + panic!("Endpoint buffer must be at least 8 bytes"); + } + if !buf.len().is_power_of_two() { + panic!("Buffer size must be a power of 2"); + } + self.descriptors[0].slice_in.set(buf); + self.descriptors[0].slice_out.set(buf); + } + + fn endpoint_set_in_buffer(&self, endpoint: usize, buf: &'a [VolatileCell]) { + if buf.len() < 8 { + panic!("Endpoint buffer must be at least 8 bytes"); + } + if !buf.len().is_power_of_two() { + panic!("Buffer size must be a power of 2"); + } + if endpoint == 0 || endpoint >= NUM_ENDPOINTS { + panic!("Endpoint number is invalid"); + } + self.descriptors[endpoint].slice_in.set(buf); + } + + fn endpoint_set_out_buffer(&self, endpoint: usize, buf: &'a [VolatileCell]) { if buf.len() < 8 { panic!("Endpoint buffer must be at least 8 bytes"); } if !buf.len().is_power_of_two() { panic!("Buffer size must be a power of 2"); } - if endpoint >= NUM_ENDPOINTS { - panic!("Endpoint number is too high"); + if endpoint == 0 || endpoint >= NUM_ENDPOINTS { + panic!("Endpoint number is invalid"); } - self.descriptors[endpoint].slice.set(buf); + self.descriptors[endpoint].slice_out.set(buf); } fn enable_as_device(&self, speed: hil::usb::DeviceSpeed) { @@ -1900,8 +1920,8 @@ impl<'a> hil::usb::UsbController<'a> for Usbd<'a> { fn endpoint_resume_in(&self, endpoint: usize) { debug_events!("endpoint_resume_in({})", endpoint); - let (_, direction, _) = self.descriptors[endpoint].state.get().bulk_state(); - assert!(direction.has_in()); + let (_, in_state, _) = self.descriptors[endpoint].state.get().bulk_state(); + assert!(in_state.is_some()); if self.dma_pending.get() { debug_events!("requesting resume_in[{}]", endpoint); @@ -1916,20 +1936,21 @@ impl<'a> hil::usb::UsbController<'a> for Usbd<'a> { fn endpoint_resume_out(&self, endpoint: usize) { debug_events!("endpoint_resume_out({})", endpoint); - let (transfer_type, direction, state) = self.descriptors[endpoint].state.get().bulk_state(); - assert!(direction.has_out()); + let (transfer_type, in_state, out_state) = + self.descriptors[endpoint].state.get().bulk_state(); + assert!(out_state.is_some()); - match state { - BulkState::OutDelay => { + match out_state.unwrap() { + BulkOutState::OutDelay => { // The endpoint has now finished processing the last ENDEPOUT. No EPDATA event // happened in the meantime, so the state is now back to Init. self.descriptors[endpoint].state.set(EndpointState::Bulk( transfer_type, - direction, - BulkState::Init, + in_state, + Some(BulkOutState::Init), )); } - BulkState::OutData => { + BulkOutState::OutData => { // Although the client reported a delay before, an EPDATA event has // happened in the meantime. This pending transaction will now // continue in transmit_out(). @@ -1942,25 +1963,11 @@ impl<'a> hil::usb::UsbController<'a> for Usbd<'a> { self.transmit_out(endpoint); } } - BulkState::Init | BulkState::OutDma | BulkState::InDma | BulkState::InData => { - internal_err!("Unexpected state: {:?}", state); + BulkOutState::Init | BulkOutState::OutDma => { + internal_err!("Unexpected state: {:?}", out_state); } } } - - fn endpoint_cancel_in(&self, endpoint: usize) { - debug_events!("endpoint_cancel_in({})", endpoint); - - let (transfer_type, direction, state) = self.descriptors[endpoint].state.get().bulk_state(); - assert!(direction.has_in()); - assert_eq!(state, BulkState::InData); - - self.descriptors[endpoint].state.set(EndpointState::Bulk( - transfer_type, - direction, - BulkState::Init, - )); - } } fn status_epin(ep: usize) -> Field { diff --git a/chips/sam4l/src/usbc/mod.rs b/chips/sam4l/src/usbc/mod.rs index 28a0b9f9..ab5b636f 100644 --- a/chips/sam4l/src/usbc/mod.rs +++ b/chips/sam4l/src/usbc/mod.rs @@ -1438,11 +1438,28 @@ fn endpoint_enable_interrupts(endpoint: usize, mask: FieldValue for Usbc<'a> { - fn endpoint_set_buffer(&self, endpoint: usize, buf: &'a [VolatileCell]) { + fn endpoint_set_ctrl_buffer(&self, buf: &'a [VolatileCell]) { if buf.len() != 8 { client_err!("Bad endpoint buffer size"); } + self._endpoint_bank_set_buffer(EndpointIndex::new(0), BankIndex::Bank0, buf); + } + + fn endpoint_set_in_buffer(&self, endpoint: usize, buf: &'a [VolatileCell]) { + if buf.len() != 8 { + client_err!("Bad endpoint buffer size"); + } + + self._endpoint_bank_set_buffer(EndpointIndex::new(endpoint), BankIndex::Bank0, buf); + } + + fn endpoint_set_out_buffer(&self, endpoint: usize, buf: &'a [VolatileCell]) { + if buf.len() != 8 { + client_err!("Bad endpoint buffer size"); + } + + // XXX: when implementing in_out endpoints, this should probably set a different slice than endpoint_set_in_buffer. self._endpoint_bank_set_buffer(EndpointIndex::new(endpoint), BankIndex::Bank0, buf); } @@ -1547,10 +1564,6 @@ impl hil::usb::UsbController<'a> for Usbc<'a> { requests.resume_out = true; self.requests[endpoint].set(requests); } - - fn endpoint_cancel_in(&self, _endpoint: usize) { - unimplemented!() - } } /// Static state to manage the USBC diff --git a/kernel/src/hil/usb.rs b/kernel/src/hil/usb.rs index 64610fa5..a114b30d 100644 --- a/kernel/src/hil/usb.rs +++ b/kernel/src/hil/usb.rs @@ -5,7 +5,9 @@ use crate::common::cells::VolatileCell; /// USB controller interface pub trait UsbController<'a> { // Should be called before `enable_as_device()` - fn endpoint_set_buffer(&self, endpoint: usize, buf: &'a [VolatileCell]); + fn endpoint_set_ctrl_buffer(&self, buf: &'a [VolatileCell]); + fn endpoint_set_in_buffer(&self, endpoint: usize, buf: &'a [VolatileCell]); + fn endpoint_set_out_buffer(&self, endpoint: usize, buf: &'a [VolatileCell]); // Must be called before `attach()` fn enable_as_device(&self, speed: DeviceSpeed); @@ -27,8 +29,6 @@ pub trait UsbController<'a> { fn endpoint_resume_in(&self, endpoint: usize); fn endpoint_resume_out(&self, endpoint: usize); - - fn endpoint_cancel_in(&self, endpoint: usize); } #[derive(Clone, Copy, Debug)]