Skip to content

Commit e8fd582

Browse files
makarenyafpistm
authored andcommitted
[USB CDC] Some speed improvements
Added bulk read method readBytes and improved read and peek methods.
1 parent 9e553cb commit e8fd582

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;
@@ -90,24 +89,26 @@ int USBSerial::available(void) {
9089
}
9190

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

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

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)