@@ -61,6 +61,10 @@ class USBDevice_SAMD21G18x {
61
61
inline void noRunInStandby () { usb.CTRLA .bit .RUNSTDBY = 0 ; }
62
62
inline void wakeupHost () { usb.CTRLB .bit .UPRSM = 1 ; }
63
63
64
+ // USB QoS
65
+ inline void setDataSensitiveQoS () { usb.QOSCTRL .bit .DQOS = 2 ; }
66
+ inline void setConfigSensitiveQoS () { usb.QOSCTRL .bit .CQOS = 2 ; }
67
+
64
68
// USB speed
65
69
inline void setFullSpeed () { usb.CTRLB .bit .SPDCONF = USB_DEVICE_CTRLB_SPDCONF_FS_Val; }
66
70
inline void setLowSpeed () { usb.CTRLB .bit .SPDCONF = USB_DEVICE_CTRLB_SPDCONF_LS_Val; }
@@ -102,27 +106,37 @@ class USBDevice_SAMD21G18x {
102
106
// Interrupts
103
107
inline uint16_t epInterruptSummary () { return usb.EPINTSMRY .reg ; }
104
108
109
+ inline bool epHasPendingInterrupts (ep_t ep) { return usb.DeviceEndpoint [ep].EPINTFLAG .reg != 0 ; }
105
110
inline bool epBank0IsSetupReceived (ep_t ep) { return usb.DeviceEndpoint [ep].EPINTFLAG .bit .RXSTP ; }
106
111
inline bool epBank0IsStalled (ep_t ep) { return usb.DeviceEndpoint [ep].EPINTFLAG .bit .STALL0 ; }
107
112
inline bool epBank1IsStalled (ep_t ep) { return usb.DeviceEndpoint [ep].EPINTFLAG .bit .STALL1 ; }
113
+ inline bool epBank0IsTransferFailed (ep_t ep) { return usb.DeviceEndpoint [ep].EPINTFLAG .bit .TRFAIL0 ; }
114
+ inline bool epBank1IsTransferFailed (ep_t ep) { return usb.DeviceEndpoint [ep].EPINTFLAG .bit .TRFAIL1 ; }
108
115
inline bool epBank0IsTransferComplete (ep_t ep) { return usb.DeviceEndpoint [ep].EPINTFLAG .bit .TRCPT0 ; }
109
116
inline bool epBank1IsTransferComplete (ep_t ep) { return usb.DeviceEndpoint [ep].EPINTFLAG .bit .TRCPT1 ; }
110
117
118
+ inline void epAckPendingInterrupts (ep_t ep) { usb.DeviceEndpoint [ep].EPINTFLAG .reg = 0x7F ; }
111
119
inline void epBank0AckSetupReceived (ep_t ep) { usb.DeviceEndpoint [ep].EPINTFLAG .reg = USB_DEVICE_EPINTFLAG_RXSTP; }
112
120
inline void epBank0AckStalled (ep_t ep) { usb.DeviceEndpoint [ep].EPINTFLAG .reg = USB_DEVICE_EPINTFLAG_STALL (1 ); }
113
121
inline void epBank1AckStalled (ep_t ep) { usb.DeviceEndpoint [ep].EPINTFLAG .reg = USB_DEVICE_EPINTFLAG_STALL (2 ); }
122
+ inline void epBank0AckTransferFailed (ep_t ep) { usb.DeviceEndpoint [ep].EPINTFLAG .reg = USB_DEVICE_EPINTFLAG_TRFAIL (1 ); }
123
+ inline void epBank1AckTransferFailed (ep_t ep) { usb.DeviceEndpoint [ep].EPINTFLAG .reg = USB_DEVICE_EPINTFLAG_TRFAIL (2 ); }
114
124
inline void epBank0AckTransferComplete (ep_t ep) { usb.DeviceEndpoint [ep].EPINTFLAG .reg = USB_DEVICE_EPINTFLAG_TRCPT (1 ); }
115
125
inline void epBank1AckTransferComplete (ep_t ep) { usb.DeviceEndpoint [ep].EPINTFLAG .reg = USB_DEVICE_EPINTFLAG_TRCPT (2 ); }
116
126
117
127
inline void epBank0EnableSetupReceived (ep_t ep) { usb.DeviceEndpoint [ep].EPINTENSET .bit .RXSTP = 1 ; }
118
128
inline void epBank0EnableStalled (ep_t ep) { usb.DeviceEndpoint [ep].EPINTENSET .bit .STALL0 = 1 ; }
119
129
inline void epBank1EnableStalled (ep_t ep) { usb.DeviceEndpoint [ep].EPINTENSET .bit .STALL1 = 1 ; }
130
+ inline void epBank0EnableTransferFailed (ep_t ep) { usb.DeviceEndpoint [ep].EPINTENSET .bit .TRFAIL0 = 1 ; }
131
+ inline void epBank1EnableTransferFailed (ep_t ep) { usb.DeviceEndpoint [ep].EPINTENSET .bit .TRFAIL1 = 1 ; }
120
132
inline void epBank0EnableTransferComplete (ep_t ep) { usb.DeviceEndpoint [ep].EPINTENSET .bit .TRCPT0 = 1 ; }
121
133
inline void epBank1EnableTransferComplete (ep_t ep) { usb.DeviceEndpoint [ep].EPINTENSET .bit .TRCPT1 = 1 ; }
122
134
123
135
inline void epBank0DisableSetupReceived (ep_t ep) { usb.DeviceEndpoint [ep].EPINTENCLR .bit .RXSTP = 1 ; }
124
136
inline void epBank0DisableStalled (ep_t ep) { usb.DeviceEndpoint [ep].EPINTENCLR .bit .STALL0 = 1 ; }
125
137
inline void epBank1DisableStalled (ep_t ep) { usb.DeviceEndpoint [ep].EPINTENCLR .bit .STALL1 = 1 ; }
138
+ inline void epBank0DisableTransferFailed (ep_t ep) { usb.DeviceEndpoint [ep].EPINTENCLR .bit .TRFAIL0 = 1 ; }
139
+ inline void epBank1DisableTransferFailed (ep_t ep) { usb.DeviceEndpoint [ep].EPINTENCLR .bit .TRFAIL1 = 1 ; }
126
140
inline void epBank0DisableTransferComplete (ep_t ep) { usb.DeviceEndpoint [ep].EPINTENCLR .bit .TRCPT0 = 1 ; }
127
141
inline void epBank1DisableTransferComplete (ep_t ep) { usb.DeviceEndpoint [ep].EPINTENCLR .bit .TRCPT1 = 1 ; }
128
142
@@ -170,6 +184,15 @@ class USBDevice_SAMD21G18x {
170
184
inline void epBank0EnableAutoZLP (ep_t ep) { EP[ep].DeviceDescBank [0 ].PCKSIZE .bit .AUTO_ZLP = 1 ; }
171
185
inline void epBank1EnableAutoZLP (ep_t ep) { EP[ep].DeviceDescBank [1 ].PCKSIZE .bit .AUTO_ZLP = 1 ; }
172
186
187
+ // USB Device Endpoint transactions helpers
188
+ // ----------------------------------------
189
+
190
+ inline void epReleaseOutBank0 (ep_t ep, uint16_t s) {
191
+ epBank0SetMultiPacketSize (ep, s);
192
+ epBank0SetByteCount (ep, 0 );
193
+ epBank0ResetReady (ep);
194
+ }
195
+
173
196
private:
174
197
// USB Device registers
175
198
UsbDevice &usb;
@@ -211,9 +234,9 @@ class EPHandler {
211
234
public:
212
235
virtual void handleEndpoint () = 0;
213
236
virtual uint32_t recv (void *_data, uint32_t len) = 0;
214
- virtual uint32_t available () const = 0;
215
-
216
237
virtual void init () = 0;
238
+ virtual uint32_t available () = 0;
239
+ virtual int peek () = 0;
217
240
};
218
241
219
242
class DoubleBufferedEPOutHandler : public EPHandler {
@@ -233,19 +256,23 @@ class DoubleBufferedEPOutHandler : public EPHandler {
233
256
usbd.epBank0SetType (ep, 3 ); // BULK OUT
234
257
235
258
usbd.epBank0SetAddress (ep, const_cast <uint8_t *>(data0));
259
+ usbd.epBank0EnableTransferComplete (ep);
236
260
237
261
release ();
238
262
}
239
263
240
264
virtual ~DoubleBufferedEPOutHandler () {
241
- free ((void *)data0);
242
- free ((void *)data1);
243
265
}
244
266
void init () {};
245
267
246
- virtual uint32_t recv ( void *_data, uint32_t len )
268
+ uint32_t _recv ( )
247
269
{
248
- uint8_t *data = reinterpret_cast <uint8_t *>(_data);
270
+ uint32_t i = 0 ;
271
+ uint32_t len = 0 ;
272
+
273
+ synchronized {
274
+ len = _rx_buffer.availableForStore ();
275
+ }
249
276
250
277
// R/W: current, first0/1, ready0/1, notify
251
278
// R : last0/1, data0/1
@@ -256,9 +283,8 @@ class DoubleBufferedEPOutHandler : public EPHandler {
256
283
}
257
284
}
258
285
// when ready0==true the buffer is not being filled and last0 is constant
259
- uint32_t i;
260
- for (i=0 ; i<len && first0 < last0; i++) {
261
- data[i] = data0[first0++];
286
+ for (; i<len && first0 < last0; i++) {
287
+ _rx_buffer.store_char (data0[first0++]);
262
288
}
263
289
if (first0 == last0) {
264
290
first0 = 0 ;
@@ -279,9 +305,8 @@ class DoubleBufferedEPOutHandler : public EPHandler {
279
305
}
280
306
}
281
307
// when ready1==true the buffer is not being filled and last1 is constant
282
- uint32_t i;
283
- for (i=0 ; i<len && first1 < last1; i++) {
284
- data[i] = data1[first1++];
308
+ for (; i<len && first1 < last1; i++) {
309
+ _rx_buffer.store_char (data1[first1++]);
285
310
}
286
311
if (first1 == last1) {
287
312
first1 = 0 ;
@@ -298,6 +323,34 @@ class DoubleBufferedEPOutHandler : public EPHandler {
298
323
}
299
324
}
300
325
326
+ virtual uint32_t recv (void *_data, uint32_t len) {
327
+ _recv ();
328
+ uint32_t i = 0 ;
329
+ uint8_t *data = reinterpret_cast <uint8_t *>(_data);
330
+ synchronized {
331
+ for (; i < len && _rx_buffer.available (); i++) {
332
+ data[i] = _rx_buffer.read_char ();
333
+ }
334
+ }
335
+ return i;
336
+ }
337
+
338
+ virtual uint32_t _available () const {
339
+ if (current == 0 ) {
340
+ bool ready = ready0;
341
+ synchronized {
342
+ ready = ready0;
343
+ }
344
+ return ready ? (last0 - first0) : 0 ;
345
+ } else {
346
+ bool ready = false ;
347
+ synchronized {
348
+ ready = ready1;
349
+ }
350
+ return ready ? (last1 - first1) : 0 ;
351
+ }
352
+ }
353
+
301
354
virtual void handleEndpoint ()
302
355
{
303
356
// R/W : incoming, ready0/1
@@ -340,39 +393,34 @@ class DoubleBufferedEPOutHandler : public EPHandler {
340
393
}
341
394
release ();
342
395
}
396
+ if (usbd.epBank0IsTransferComplete (ep) || usbd.epBank1IsTransferComplete (ep)) {
397
+ usbd.epAckPendingInterrupts (ep);
398
+ }
343
399
}
344
400
345
401
// Returns how many bytes are stored in the buffers
346
- virtual uint32_t available () const {
347
- if (current == 0 ) {
348
- bool ready = false ;
349
- synchronized {
350
- ready = ready0;
351
- }
352
- return ready ? (last0 - first0) : 0 ;
353
- } else {
354
- bool ready = false ;
355
- synchronized {
356
- ready = ready1;
357
- }
358
- return ready ? (last1 - first1) : 0 ;
359
- }
402
+ virtual uint32_t available () {
403
+ _recv ();
404
+ return _rx_buffer.available ();
405
+ }
406
+
407
+ virtual int peek () {
408
+ _recv ();
409
+ return _rx_buffer.peek ();
360
410
}
361
411
362
412
void release () {
363
- // Release OUT EP
364
- usbd.epBank0EnableTransferComplete (ep);
365
- usbd.epBank0SetMultiPacketSize (ep, size);
366
- usbd.epBank0SetByteCount (ep, 0 );
367
- usbd.epBank0ResetReady (ep);
413
+ usbd.epReleaseOutBank0 (ep, size);
368
414
}
369
415
370
416
private:
371
417
USBDevice_SAMD21G18x &usbd;
372
418
419
+ RingBuffer _rx_buffer;
420
+
373
421
const uint32_t ep;
374
422
const uint32_t size;
375
- uint32_t current, incoming;
423
+ volatile uint32_t current, incoming;
376
424
377
425
volatile uint8_t *data0;
378
426
uint32_t first0;
0 commit comments