@@ -249,7 +249,8 @@ class EPHandler {
249249public:
250250 virtual void handleEndpoint () = 0;
251251 virtual uint32_t recv (void *_data, uint32_t len) = 0;
252- virtual uint32_t available () const = 0;
252+ virtual uint32_t available () = 0;
253+ virtual int peek () = 0;
253254};
254255
255256class DoubleBufferedEPOutHandler : public EPHandler {
@@ -273,13 +274,10 @@ class DoubleBufferedEPOutHandler : public EPHandler {
273274 }
274275
275276 virtual ~DoubleBufferedEPOutHandler () {
276- free ((void *)data0);
277- free ((void *)data1);
278277 }
279278
280- virtual uint32_t recv ( void *_data, uint32_t len)
279+ uint32_t _recv ( uint32_t len)
281280 {
282- uint8_t *data = reinterpret_cast <uint8_t *>(_data);
283281 uint32_t i = 0 ;
284282
285283 // R/W: current, first0/1, ready0/1, notify
@@ -292,7 +290,7 @@ class DoubleBufferedEPOutHandler : public EPHandler {
292290 }
293291 // when ready0==true the buffer is not being filled and last0 is constant
294292 for (; i<len && first0 < last0; i++) {
295- data[i] = data0[first0++];
293+ _rx_buffer. store_char ( data0[first0++]) ;
296294 }
297295 if (first0 == last0) {
298296 first0 = 0 ;
@@ -313,7 +311,7 @@ class DoubleBufferedEPOutHandler : public EPHandler {
313311 }
314312 // when ready1==true the buffer is not being filled and last1 is constant
315313 for (; i<len && first1 < last1; i++) {
316- data[i] = data1[first1++];
314+ _rx_buffer. store_char ( data1[first1++]) ;
317315 }
318316 if (first1 == last1) {
319317 first1 = 0 ;
@@ -330,6 +328,35 @@ class DoubleBufferedEPOutHandler : public EPHandler {
330328 return i;
331329 }
332330
331+ virtual uint32_t recv (void *_data, uint32_t len) {
332+ _recv (_rx_buffer.availableForStore ());
333+ uint32_t i = 0 ;
334+ uint8_t *data = reinterpret_cast <uint8_t *>(_data);
335+ for (; i < len; i++) {
336+ if (!_rx_buffer.available ()) {
337+ break ;
338+ }
339+ data[i] = _rx_buffer.read_char ();
340+ }
341+ return i;
342+ }
343+
344+ virtual uint32_t _available () const {
345+ if (current == 0 ) {
346+ bool ready = false ;
347+ synchronized {
348+ ready = ready0;
349+ }
350+ return ready ? (last0 - first0) : 0 ;
351+ } else {
352+ bool ready = false ;
353+ synchronized {
354+ ready = ready1;
355+ }
356+ return ready ? (last1 - first1) : 0 ;
357+ }
358+ }
359+
333360 virtual void handleEndpoint ()
334361 {
335362 // R/W : incoming, ready0/1
@@ -364,25 +391,18 @@ class DoubleBufferedEPOutHandler : public EPHandler {
364391 }
365392 }
366393 }
367-
368394 usbd.epAckPendingInterrupts (ep);
369395 }
370396
371397 // Returns how many bytes are stored in the buffers
372- virtual uint32_t available () const {
373- if (current == 0 ) {
374- bool ready = false ;
375- synchronized {
376- ready = ready0;
377- }
378- return ready ? (last0 - first0) : 0 ;
379- } else {
380- bool ready = false ;
381- synchronized {
382- ready = ready1;
383- }
384- return ready ? (last1 - first1) : 0 ;
385- }
398+ virtual uint32_t available () {
399+ _recv (_rx_buffer.availableForStore ());
400+ return _rx_buffer.available ();
401+ }
402+
403+ virtual int peek () {
404+ _recv (_rx_buffer.availableForStore ());
405+ return _rx_buffer.peek ();
386406 }
387407
388408 void release () {
@@ -392,6 +412,8 @@ class DoubleBufferedEPOutHandler : public EPHandler {
392412private:
393413 USBDevice_SAMD21G18x &usbd;
394414
415+ RingBuffer _rx_buffer;
416+
395417 const uint32_t ep;
396418 uint32_t current, incoming;
397419
0 commit comments