Skip to content

Commit 250eedf

Browse files
makarenyafpistm
authored andcommitted
[USB CDC] Bulk read fixed, added bulk read until
1 parent 862c877 commit 250eedf

File tree

6 files changed

+87
-5
lines changed

6 files changed

+87
-5
lines changed

cores/arduino/Stream.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ class Stream : public Print
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)
101101

102-
size_t readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character
102+
virtual size_t readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character
103103
size_t readBytesUntil( char terminator, uint8_t *buffer, size_t length) { return readBytesUntil(terminator, (char *)buffer, length); }
104104
// terminates if length characters have been read, timeout, or if the terminator character detected
105105
// returns the number of characters placed in the buffer (0 means no valid data found)

cores/arduino/USBSerial.cpp

+25-1
Original file line numberDiff line numberDiff line change
@@ -99,15 +99,39 @@ int USBSerial::read(void) {
9999
}
100100

101101
size_t USBSerial::readBytes(char *buffer, size_t length) {
102+
uint16_t read;
102103
auto rest = static_cast<uint16_t>(length);
103104
_startMillis = millis();
104105
do {
105-
rest -= CDC_ReceiveQueue_Read(&ReceiveQueue, reinterpret_cast<uint8_t*>(buffer), rest);
106+
read = CDC_ReceiveQueue_Read(&ReceiveQueue, reinterpret_cast<uint8_t*>(buffer), rest);
107+
CDC_resume_receive();
108+
rest -= read;
109+
buffer += read;
106110
if (rest == 0) return length;
107111
} while(millis() - _startMillis < _timeout);
108112
return length - rest;
109113
}
110114

115+
size_t USBSerial::readBytesUntil(char terminator, char *buffer, size_t length) {
116+
uint16_t read;
117+
auto rest = static_cast<uint16_t>(length);
118+
_startMillis = millis();
119+
do {
120+
bool found = CDC_ReceiveQueue_ReadUntil(&ReceiveQueue, static_cast<uint8_t>(terminator),
121+
reinterpret_cast<uint8_t*>(buffer), rest, &read);
122+
CDC_resume_receive();
123+
rest -= read;
124+
buffer += read;
125+
if (found) {
126+
return length - rest;
127+
}
128+
if (rest == 0) {
129+
return length;
130+
}
131+
} while(millis() - _startMillis < _timeout);
132+
return length - rest;
133+
}
134+
111135
int USBSerial::peek(void)
112136
{
113137
// Peek one symbol, it can't change receive avaiablity

cores/arduino/USBSerial.h

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class USBSerial : public Stream {
3737
virtual int peek(void);
3838
virtual int read(void);
3939
virtual size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer
40+
virtual size_t readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character
4041
virtual void flush(void);
4142
virtual size_t write(uint8_t);
4243
virtual size_t write(const uint8_t *buffer, size_t size);

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

+57-2
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,9 @@ void CDC_ReceiveQueue_CommitBlock(CDC_ReceiveQueue_TypeDef *queue, uint16_t size
116116
if (queue->write >= queue->length) {
117117
queue->length = CDC_RECEIVE_QUEUE_BUFFER_SIZE;
118118
}
119+
if (queue->write >= CDC_RECEIVE_QUEUE_BUFFER_SIZE) {
120+
queue->write = 0;
121+
}
119122
}
120123

121124
// Determine size, available for read
@@ -145,18 +148,70 @@ int CDC_ReceiveQueue_Peek(CDC_ReceiveQueue_TypeDef *queue) {
145148

146149
uint16_t CDC_ReceiveQueue_Read(CDC_ReceiveQueue_TypeDef *queue, uint8_t *buffer, uint16_t size) {
147150
volatile uint16_t write = queue->write;
151+
volatile uint16_t length = queue->length;
148152
uint16_t available;
153+
while(write != queue->write || length != queue->length) {
154+
write = queue->write;
155+
length = queue->length;
156+
}
157+
149158
if (write >= queue->read) {
150159
available = write - queue->read;
151160
} else {
152-
available = CDC_RECEIVE_QUEUE_BUFFER_SIZE - queue->read;
161+
available = length - queue->read;
153162
}
154163
if (available < size) {
155164
size = available;
156165
}
166+
157167
memcpy(buffer, &queue->buffer[queue->read], size);
158-
queue->read = (queue->read + size) % CDC_RECEIVE_QUEUE_BUFFER_SIZE;
168+
queue->read = queue->read + size;
169+
if (queue->read >= length) {
170+
queue->read = 0;
171+
}
159172
return size;
160173
}
174+
175+
bool CDC_ReceiveQueue_ReadUntil(CDC_ReceiveQueue_TypeDef *queue, uint8_t terminator, uint8_t *buffer,
176+
uint16_t size, uint16_t* fetched) {
177+
volatile uint16_t write = queue->write;
178+
volatile uint16_t length = queue->length;
179+
uint16_t available;
180+
while(write != queue->write || length != queue->length) {
181+
write = queue->write;
182+
length = queue->length;
183+
}
184+
185+
if (write >= queue->read) {
186+
available = write - queue->read;
187+
} else {
188+
available = length - queue->read;
189+
}
190+
if (available < size) {
191+
size = available;
192+
}
193+
194+
uint8_t* start = &queue->buffer[queue->read];
195+
for(uint16_t i = 0; i < size; i++) {
196+
uint8_t ch = start[i];
197+
if (ch == terminator) {
198+
queue->read += (uint16_t)(i + 1);
199+
if (queue->read >= length) {
200+
queue->read = 0;
201+
}
202+
*fetched = i;
203+
return true;
204+
} else {
205+
buffer[i] = ch;
206+
}
207+
}
208+
209+
*fetched = size;
210+
queue->read += size;
211+
if (queue->read >= length) {
212+
queue->read = 0;
213+
}
214+
return false;
215+
}
161216
#endif /* USBD_USE_CDC */
162217
#endif /* USBCON */

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

+2
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ int CDC_ReceiveQueue_ReadSize(CDC_ReceiveQueue_TypeDef* queue);
8181
int CDC_ReceiveQueue_Dequeue(CDC_ReceiveQueue_TypeDef* queue);
8282
int CDC_ReceiveQueue_Peek(CDC_ReceiveQueue_TypeDef* queue);
8383
uint16_t CDC_ReceiveQueue_Read(CDC_ReceiveQueue_TypeDef* queue, uint8_t* buffer, uint16_t size);
84+
bool CDC_ReceiveQueue_ReadUntil(CDC_ReceiveQueue_TypeDef* queue, uint8_t terminator, uint8_t* buffer,
85+
uint16_t size, uint16_t* fetched);
8486
uint8_t* CDC_ReceiveQueue_ReserveBlock(CDC_ReceiveQueue_TypeDef* queue);
8587
void CDC_ReceiveQueue_CommitBlock(CDC_ReceiveQueue_TypeDef* queue, uint16_t size);
8688

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ USBD_HandleTypeDef hUSBD_Device_CDC;
4040
CDC_TransmitQueue_TypeDef TransmitQueue;
4141
CDC_ReceiveQueue_TypeDef ReceiveQueue;
4242
__IO uint32_t lineState = 0;
43-
__IO bool receivePended = false;
43+
__IO bool receivePended = true;
4444

4545

4646
/** USBD_CDC Private Function Prototypes */

0 commit comments

Comments
 (0)