Skip to content

Commit 862c877

Browse files
makarenyafpistm
authored andcommitted
[USB CDC] Some speed improvements
Added bulk read method readBytes and improved read and peek methods.
1 parent 290ec58 commit 862c877

File tree

5 files changed

+35
-15
lines changed

5 files changed

+35
-15
lines changed

cores/arduino/Stream.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ class Stream : public Print
9494
float parseFloat(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR);
9595
// float version of parseInt
9696

97-
size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer
97+
virtual size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer
9898
size_t readBytes( uint8_t *buffer, size_t length) { return readBytes((char *)buffer, length); }
9999
// terminates if length characters have been read or timeout (see setTimeout)
100100
// returns the number of characters placed in the buffer (0 means no valid data found)

cores/arduino/USBSerial.cpp

+11-10
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
#include "usbd_desc.h"
2525
#include "wiring.h"
2626

27-
#define USB_TIMEOUT 50
2827
/* USB Device Core handle declaration */
2928
extern USBD_HandleTypeDef hUSBD_Device_CDC;
3029
extern __IO uint32_t lineState;
@@ -91,24 +90,26 @@ int USBSerial::available(void) {
9190
}
9291

9392
int USBSerial::read(void) {
94-
// Empty ReceiveQueue - nothing to return
95-
if (CDC_ReceiveQueue_ReadSize(&ReceiveQueue) <= 0) {
96-
return -1;
97-
}
9893
// Dequeue only one char from queue
9994
// TS: it safe, because only main thread affects ReceiveQueue->read pos
100-
char ch = CDC_ReceiveQueue_Dequeue(&ReceiveQueue);
95+
auto ch = CDC_ReceiveQueue_Dequeue(&ReceiveQueue);
10196
// Resume receive process, if possible
10297
CDC_resume_receive();
10398
return ch;
10499
}
105100

101+
size_t USBSerial::readBytes(char *buffer, size_t length) {
102+
auto rest = static_cast<uint16_t>(length);
103+
_startMillis = millis();
104+
do {
105+
rest -= CDC_ReceiveQueue_Read(&ReceiveQueue, reinterpret_cast<uint8_t*>(buffer), rest);
106+
if (rest == 0) return length;
107+
} while(millis() - _startMillis < _timeout);
108+
return length - rest;
109+
}
110+
106111
int USBSerial::peek(void)
107112
{
108-
// Empty ReceiveQueue - nothing to return
109-
if (CDC_ReceiveQueue_ReadSize(&ReceiveQueue) <= 0) {
110-
return -1;
111-
}
112113
// Peek one symbol, it can't change receive avaiablity
113114
return CDC_ReceiveQueue_Peek(&ReceiveQueue);
114115
}

cores/arduino/USBSerial.h

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class USBSerial : public Stream {
3636
virtual int availableForWrite(void);
3737
virtual int peek(void);
3838
virtual int read(void);
39+
virtual size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer
3940
virtual void flush(void);
4041
virtual size_t write(uint8_t);
4142
virtual size_t write(const uint8_t *buffer, size_t size);

cores/arduino/stm32/usb/cdc/cdc_queue.c

+19-2
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,8 @@ int CDC_ReceiveQueue_ReadSize(CDC_ReceiveQueue_TypeDef *queue) {
128128
}
129129

130130
// Read one byte from queue.
131-
uint8_t CDC_ReceiveQueue_Dequeue(CDC_ReceiveQueue_TypeDef *queue) {
131+
int CDC_ReceiveQueue_Dequeue(CDC_ReceiveQueue_TypeDef *queue) {
132+
if (queue->write == queue->read) return -1;
132133
uint8_t ch = queue->buffer[queue->read++];
133134
if (queue->read >= queue->length) {
134135
queue->read = 0;
@@ -137,9 +138,25 @@ uint8_t CDC_ReceiveQueue_Dequeue(CDC_ReceiveQueue_TypeDef *queue) {
137138
}
138139

139140
// Peek byte from queue.
140-
uint8_t CDC_ReceiveQueue_Peek(CDC_ReceiveQueue_TypeDef *queue) {
141+
int CDC_ReceiveQueue_Peek(CDC_ReceiveQueue_TypeDef *queue) {
142+
if (queue->write == queue->read) return -1;
141143
return queue->buffer[queue->read];
142144
}
143145

146+
uint16_t CDC_ReceiveQueue_Read(CDC_ReceiveQueue_TypeDef *queue, uint8_t *buffer, uint16_t size) {
147+
volatile uint16_t write = queue->write;
148+
uint16_t available;
149+
if (write >= queue->read) {
150+
available = write - queue->read;
151+
} else {
152+
available = CDC_RECEIVE_QUEUE_BUFFER_SIZE - queue->read;
153+
}
154+
if (available < size) {
155+
size = available;
156+
}
157+
memcpy(buffer, &queue->buffer[queue->read], size);
158+
queue->read = (queue->read + size) % CDC_RECEIVE_QUEUE_BUFFER_SIZE;
159+
return size;
160+
}
144161
#endif /* USBD_USE_CDC */
145162
#endif /* USBCON */

cores/arduino/stm32/usb/cdc/cdc_queue.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,9 @@ void CDC_TransmitQueue_CommitRead(CDC_TransmitQueue_TypeDef *queue);
7878

7979
void CDC_ReceiveQueue_Init(CDC_ReceiveQueue_TypeDef* queue);
8080
int CDC_ReceiveQueue_ReadSize(CDC_ReceiveQueue_TypeDef* queue);
81-
uint8_t CDC_ReceiveQueue_Dequeue(CDC_ReceiveQueue_TypeDef* queue);
82-
uint8_t CDC_ReceiveQueue_Peek(CDC_ReceiveQueue_TypeDef* queue);
81+
int CDC_ReceiveQueue_Dequeue(CDC_ReceiveQueue_TypeDef* queue);
82+
int CDC_ReceiveQueue_Peek(CDC_ReceiveQueue_TypeDef* queue);
83+
uint16_t CDC_ReceiveQueue_Read(CDC_ReceiveQueue_TypeDef* queue, uint8_t* buffer, uint16_t size);
8384
uint8_t* CDC_ReceiveQueue_ReserveBlock(CDC_ReceiveQueue_TypeDef* queue);
8485
void CDC_ReceiveQueue_CommitBlock(CDC_ReceiveQueue_TypeDef* queue, uint16_t size);
8586

0 commit comments

Comments
 (0)