@@ -148,6 +148,32 @@ static void hw_endpoint_xfer(uint8_t ep_addr, uint8_t* buffer, uint16_t total_by
148
148
hw_endpoint_xfer_start (ep , buffer , total_bytes );
149
149
}
150
150
151
+ static void hw_endpoint_abort_xfer (struct hw_endpoint * ep ) {
152
+ // Abort any pending transfer
153
+ // Due to Errata RP2040-E2: ABORT flag is only applicable for B2 and later (unusable for B0, B1).
154
+ // Which means we are not guaranteed to safely abort pending transfer on B0 and B1.
155
+ const uint8_t dir = tu_edpt_dir (ep -> ep_addr );
156
+ const uint8_t epnum = tu_edpt_number (ep -> ep_addr );
157
+ const uint32_t abort_mask = TU_BIT ((epnum << 1 ) | (dir ? 0 : 1 ));
158
+ if (rp2040_chip_version () >= 2 ) {
159
+ usb_hw_set -> abort = abort_mask ;
160
+ while ((usb_hw -> abort_done & abort_mask ) != abort_mask ) {}
161
+ }
162
+
163
+ uint32_t buf_ctrl = USB_BUF_CTRL_SEL ; // reset to buffer 0
164
+ if (ep -> next_pid ) {
165
+ buf_ctrl |= USB_BUF_CTRL_DATA1_PID ;
166
+ }
167
+
168
+ _hw_endpoint_buffer_control_set_value32 (ep , buf_ctrl );
169
+ hw_endpoint_reset_transfer (ep );
170
+
171
+ if (rp2040_chip_version () >= 2 ) {
172
+ usb_hw_clear -> abort_done = abort_mask ;
173
+ usb_hw_clear -> abort = abort_mask ;
174
+ }
175
+ }
176
+
151
177
static void __tusb_irq_path_func (hw_handle_buff_status )(void ) {
152
178
uint32_t remaining_buffers = usb_hw -> buf_status ;
153
179
pico_trace ("buf_status = 0x%08lx\r\n" , remaining_buffers );
@@ -178,25 +204,10 @@ TU_ATTR_ALWAYS_INLINE static inline void reset_ep0(void) {
178
204
// setup transfer. Also clear a stall in case
179
205
for (uint8_t dir = 0 ; dir < 2 ; dir ++ ) {
180
206
struct hw_endpoint * ep = hw_endpoint_get_by_num (0 , dir );
207
+ ep -> next_pid = 1u ;
181
208
if (ep -> active ) {
182
- // Abort any pending transfer from a prior control transfer per USB specs
183
- // Due to Errata RP2040-E2: ABORT flag is only applicable for B2 and later (unusable for B0, B1).
184
- // Which means we are not guaranteed to safely abort pending transfer on B0 and B1.
185
- uint32_t const abort_mask = (dir ? USB_EP_ABORT_EP0_IN_BITS : USB_EP_ABORT_EP0_OUT_BITS );
186
- if (rp2040_chip_version () >= 2 ) {
187
- usb_hw_set -> abort = abort_mask ;
188
- while ((usb_hw -> abort_done & abort_mask ) != abort_mask ) {}
189
- }
190
-
191
- _hw_endpoint_buffer_control_set_value32 (ep , USB_BUF_CTRL_DATA1_PID | USB_BUF_CTRL_SEL );
192
- hw_endpoint_reset_transfer (ep );
193
-
194
- if (rp2040_chip_version () >= 2 ) {
195
- usb_hw_clear -> abort_done = abort_mask ;
196
- usb_hw_clear -> abort = abort_mask ;
197
- }
209
+ hw_endpoint_abort_xfer (ep ); // Abort any pending transfer per USB specs
198
210
}
199
- ep -> next_pid = 1u ;
200
211
}
201
212
}
202
213
@@ -495,12 +506,14 @@ bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet
495
506
// New API: Configure and enable an ISO endpoint according to descriptor
496
507
bool dcd_edpt_iso_activate (uint8_t rhport , tusb_desc_endpoint_t const * ep_desc ) {
497
508
(void ) rhport ;
498
- const uint8_t ep_addr = ep_desc -> bEndpointAddress ;
499
- // Fill in endpoint control register with buffer offset
500
- struct hw_endpoint * ep = hw_endpoint_get_by_addr (ep_addr );
501
- TU_ASSERT (ep -> hw_data_buf != NULL ); // must be inited and buffer allocated
502
- ep -> wMaxPacketSize = ep_desc -> wMaxPacketSize ;
509
+ struct hw_endpoint * ep = hw_endpoint_get_by_addr (ep_desc -> bEndpointAddress );
510
+ TU_ASSERT (ep -> hw_data_buf != NULL ); // must be inited and allocated previously
511
+
512
+ if (ep -> active ) {
513
+ hw_endpoint_abort_xfer (ep ); // abort any pending transfer
514
+ }
503
515
516
+ ep -> wMaxPacketSize = ep_desc -> wMaxPacketSize ;
504
517
hw_endpoint_enable (ep );
505
518
return true;
506
519
}
0 commit comments