Skip to content

Commit 06c576d

Browse files
bugfix(otgfs): disable endpoints on bus reset
Endpoints should be disabled on bus reset. According to datasheet it looks like the UEPx_y_MOD.{RX_EN,TX_EN} should have reset value of 0 but clearly they are reset to 1 which case our endpoints to be "enabled" by default
1 parent 289e785 commit 06c576d

File tree

2 files changed

+32
-30
lines changed

2 files changed

+32
-30
lines changed

src/otg_fs/endpoint.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use core::marker::PhantomData;
22
use core::task::Poll;
33

44
use ch32_metapac::otg::vals::{EpRxResponse, EpTxResponse, UsbToken};
5-
use embassy_usb_driver::{Direction, EndpointAllocError, EndpointError, EndpointInfo};
5+
use embassy_usb_driver::{Direction, EndpointError, EndpointInfo};
66
use futures::future::poll_fn;
77

88
use crate::usb::{Dir, EndpointData, In, Out};
@@ -135,8 +135,9 @@ impl<'d, T: Instance> embassy_usb_driver::EndpointIn for Endpoint<'d, T, In> {
135135

136136
impl<'d, T: Instance> embassy_usb_driver::EndpointOut for Endpoint<'d, T, Out> {
137137
async fn read(&mut self, buf: &mut [u8]) -> Result<usize, EndpointError> {
138-
trace!("endpoint {} OUT", self.info.addr);
138+
trace!("endpoint {} OUT", self.info.addr.index());
139139
if !self.is_enabled() {
140+
error!("OUT disabled EP");
140141
return Err(EndpointError::Disabled);
141142
}
142143

src/otg_fs/mod.rs

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
//! USB_FS and OTG_FS device mode peripheral driver
22
//! Note that this currently only implements device mode
3-
//!
3+
//!
44
//! <div class="warning">
55
//! There's a lot of TODOs and panics where things are not implemented
66
//! </div>
7-
//!
7+
//!
88
//! List of things that is tested
99
//! Untested but expected to work items are noted as well
1010
//!
1111
//! Control Pipe:
12-
//! - [x] Recieve `SETUP` packet (Host -> Dev)
12+
//! - [x] Recieve `SETUP` packet (Host -> Dev)
1313
//! - [x] Send `IN` packet (Dev -> Host).
1414
//! - [x] Recieve `OUT` packet (Host -> Dev).
15-
//!
16-
//! Other Endpoints:
15+
//!
16+
//! Other Endpoints:
1717
//! - [x] Interrupt Out
1818
//! - [x] Interrupt In
1919
//! - [ ] Bulk Out (Expected to work but not tested)
@@ -31,9 +31,9 @@ use core::task::Poll;
3131

3232
use ch32_metapac::otg::vals::{EpRxResponse, EpTxResponse, UsbToken};
3333
use embassy_sync::waitqueue::AtomicWaker;
34-
use embassy_usb_driver::{self as driver, Direction, EndpointAddress, EndpointInfo, EndpointType, Event};
35-
use endpoint::{ControlPipe, Endpoint, EndpointBufferAllocator, EndpointDataBuffer};
36-
use marker::{Dir, In, Out};
34+
use embassy_usb_driver::{Direction, EndpointAddress, EndpointInfo, EndpointType, Event};
35+
use endpoint::{ControlPipe, Endpoint};
36+
use crate::usb::{Dir, EndpointBufferAllocator, EndpointDataBuffer, In, Out};
3737

3838
use crate::gpio::{AFType, Speed};
3939
use crate::interrupt::typelevel::Interrupt;
@@ -151,7 +151,7 @@ where
151151
ep_type: EndpointType,
152152
max_packet_size: u16,
153153
interval_ms: u8,
154-
) -> Result<Endpoint<'d, T, D>, driver::EndpointAllocError> {
154+
) -> Result<Endpoint<'d, T, D>, embassy_usb_driver::EndpointAllocError> {
155155
let ep_addr = self.alloc_ep_address();
156156
let data = self.allocator.alloc_endpoint(max_packet_size)?;
157157

@@ -168,7 +168,7 @@ where
168168
}
169169
}
170170

171-
impl<'d, T: Instance, const NR_EP: usize> driver::Driver<'d> for Driver<'d, T, NR_EP> {
171+
impl<'d, T: Instance, const NR_EP: usize> embassy_usb_driver::Driver<'d> for Driver<'d, T, NR_EP> {
172172
type EndpointOut = Endpoint<'d, T, Out>;
173173

174174
type EndpointIn = Endpoint<'d, T, In>;
@@ -179,19 +179,19 @@ impl<'d, T: Instance, const NR_EP: usize> driver::Driver<'d> for Driver<'d, T, N
179179

180180
fn alloc_endpoint_out(
181181
&mut self,
182-
ep_type: driver::EndpointType,
182+
ep_type: embassy_usb_driver::EndpointType,
183183
max_packet_size: u16,
184184
interval_ms: u8,
185-
) -> Result<Self::EndpointOut, driver::EndpointAllocError> {
185+
) -> Result<Self::EndpointOut, embassy_usb_driver::EndpointAllocError> {
186186
self.alloc_endpoint::<Out>(ep_type, max_packet_size, interval_ms)
187187
}
188188

189189
fn alloc_endpoint_in(
190190
&mut self,
191-
ep_type: driver::EndpointType,
191+
ep_type: embassy_usb_driver::EndpointType,
192192
max_packet_size: u16,
193193
interval_ms: u8,
194-
) -> Result<Self::EndpointIn, driver::EndpointAllocError> {
194+
) -> Result<Self::EndpointIn, embassy_usb_driver::EndpointAllocError> {
195195
self.alloc_endpoint::<In>(ep_type, max_packet_size, interval_ms)
196196
}
197197

@@ -229,23 +229,11 @@ impl<'d, T: Instance, const NR_EP: usize> driver::Driver<'d> for Driver<'d, T, N
229229
});
230230

231231
let ep0_buf = self.allocator.alloc_endpoint(control_max_packet_size).unwrap();
232-
233232
regs.uep_dma(0).write_value(ep0_buf.addr() as u32);
234233

235234
regs.uep_rx_ctrl(0).write(|w| w.set_mask_r_res(EpRxResponse::ACK));
236235
regs.uep_tx_ctrl(0).write(|w| w.set_mask_t_res(EpTxResponse::NAK));
237236

238-
// Hookup the bus on start?
239-
regs.udev_ctrl().write(|w| {
240-
// pd is for HOST
241-
w.set_pd_dis(true);
242-
w.set_port_en(true);
243-
});
244-
245-
// Initialize the bus so that it signals that power is available
246-
// usbd.rs does BUS_WAKER.wake(), but it doesn't seem necessary
247-
BUS_WAKER.wake();
248-
249237
critical_section::with(|_cs| {
250238
T::Interrupt::unpend();
251239
unsafe {
@@ -284,18 +272,31 @@ impl<'d, T: Instance> Bus<'d, T> {
284272

285273
// Mark all other EPs as NAK
286274
for i in 1..=7 {
275+
use embassy_usb_driver::Bus;
287276
regs.uep_rx_ctrl(i).write(|v| v.set_mask_r_res(EpRxResponse::NAK));
288277
regs.uep_tx_ctrl(i).write(|v| v.set_mask_t_res(EpTxResponse::NAK));
278+
self.endpoint_set_enabled(EndpointAddress::from_parts(i, Direction::In), false);
279+
self.endpoint_set_enabled(EndpointAddress::from_parts(i, Direction::Out), false);
289280
}
290281
}
291282
}
292283

293-
impl<'d, T> driver::Bus for Bus<'d, T>
284+
impl<'d, T> embassy_usb_driver::Bus for Bus<'d, T>
294285
where
295286
T: Instance,
296287
{
297288
async fn enable(&mut self) {
298-
trace!("enable")
289+
// Do a bus reset on "enable"
290+
let regs = T::regs();
291+
292+
// Enable the port
293+
regs.udev_ctrl().write(|w| {
294+
// Pull Down needs to be disabled because that is for HOST
295+
w.set_pd_dis(true);
296+
w.set_port_en(true);
297+
});
298+
299+
self.bus_reset();
299300
}
300301

301302
async fn disable(&mut self) {

0 commit comments

Comments
 (0)