Skip to content

Commit a3eeb41

Browse files
hasenbanckfpistm
authored andcommitted
[USB CDC] Add proposed speed improvements
1 parent f890572 commit a3eeb41

File tree

3 files changed

+100
-94
lines changed

3 files changed

+100
-94
lines changed

cores/arduino/USBSerial.cpp

+2-17
Original file line numberDiff line numberDiff line change
@@ -99,41 +99,26 @@ size_t USBSerial::write(const uint8_t *buffer, size_t size){
9999
}
100100

101101
int USBSerial::available(void) {
102-
int ret;
103-
104-
CDC_disable_TIM_Interrupt();
105-
ret = ((APP_RX_DATA_SIZE + (UserRxBufPtrIn - UserRxBufPtrOut)) % APP_RX_DATA_SIZE);
106-
CDC_enable_TIM_Interrupt();
107-
108-
return ret;
102+
return ((APP_RX_DATA_SIZE + (UserRxBufPtrIn - UserRxBufPtrOut)) % APP_RX_DATA_SIZE);
109103
}
110104

111105
int USBSerial::read(void) {
112-
/* UserTxBufPtrOut can be modified by TIM ISR, so in order to be sure that the */
113-
/* value that we read is correct, we need to disable TIM Interrupt. */
114-
CDC_disable_TIM_Interrupt();
115106
if (UserRxBufPtrOut == UserRxBufPtrIn) {
116-
CDC_enable_TIM_Interrupt();
117107
return -1;
118108
} else {
119109
unsigned char c = UserRxBuffer[UserRxBufPtrOut];
120110
UserRxBufPtrOut = ((UserRxBufPtrOut + 1) % APP_RX_DATA_SIZE);
121-
CDC_enable_TIM_Interrupt();
111+
CDC_resume_receive();
122112
return c;
123113
}
124114
}
125115

126116
int USBSerial::peek(void)
127117
{
128-
/* UserTxBufPtrOut can be modified by TIM ISR, so in order to be sure that the */
129-
/* value that we read is correct, we need to disable TIM Interrupt. */
130-
CDC_disable_TIM_Interrupt();
131118
if (UserRxBufPtrOut == UserRxBufPtrIn) {
132-
CDC_enable_TIM_Interrupt();
133119
return -1;
134120
} else {
135121
unsigned char c = UserRxBuffer[UserRxBufPtrOut];
136-
CDC_enable_TIM_Interrupt();
137122
return c;
138123
}
139124
}

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

+97-77
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,22 @@
2323
/* Includes ------------------------------------------------------------------*/
2424
#include "usbd_cdc_if.h"
2525

26+
#ifdef USE_USB_HS
27+
#define CDC_MAX_PACKET_SIZE USB_OTG_HS_MAX_PACKET_SIZE
28+
#elif defined(USB_OTG_FS) || defined(USB_OTG_FS_MAX_PACKET_SIZE)
29+
#define CDC_MAX_PACKET_SIZE USB_OTG_FS_MAX_PACKET_SIZE
30+
#else /* USB */
31+
#define CDC_MAX_PACKET_SIZE USB_MAX_EP0_SIZE
32+
#endif
33+
2634
/* USBD_CDC Private Variables */
2735

2836
/* Create buffer for reception and transmission */
2937
/* It's up to user to redefine and/or remove those define */
3038
extern USBD_HandleTypeDef hUSBD_Device_CDC;
3139
/* Received Data over USB are stored in this buffer */
3240
__IO uint8_t UserRxBuffer[APP_RX_DATA_SIZE];
33-
__IO uint8_t StackRxBuffer[APP_RX_DATA_SIZE];
41+
__IO uint8_t StackRxBuffer[CDC_MAX_PACKET_SIZE];
3442

3543
/* Send Data over USB CDC are stored in this buffer */
3644
__IO uint8_t UserTxBuffer[APP_TX_DATA_SIZE];
@@ -46,14 +54,9 @@ __IO uint32_t UserRxBufPtrIn = 0; /* Increment this pointer or roll it back to
4654
__IO uint32_t UserRxBufPtrOut = 0; /* Increment this pointer or roll it back to
4755
start address when data are sent over read call */
4856

49-
__IO uint32_t SLP;
50-
__IO uint32_t GetRxCount;
5157
__IO uint32_t lineState = 0;
52-
uint8_t cptlineState = 0;
53-
volatile uint32_t USB_received = 0;
54-
uint8_t USBBuffer[USB_MAX_EP0_SIZE];
55-
uint8_t USBPackSize;
56-
bool sendZLP = false;
58+
__IO bool receiveSuspended = false;
59+
__IO bool sendZLP = false;
5760

5861
stimer_t CDC_TimHandle;
5962

@@ -183,9 +186,8 @@ static int8_t USBD_CDC_Control (uint8_t cmd, uint8_t* pbuf, uint16_t length)
183186
break;
184187

185188
case CDC_SET_CONTROL_LINE_STATE:
186-
cptlineState++;
187-
if(cptlineState == 2)
188-
lineState = 1;
189+
lineState =
190+
(((USBD_SetupReqTypedef *)pbuf)->wValue & 0x01) != 0; // Check DTR state
189191
break;
190192

191193
case CDC_SEND_BREAK:
@@ -217,11 +219,31 @@ static int8_t USBD_CDC_Control (uint8_t cmd, uint8_t* pbuf, uint16_t length)
217219
*/
218220
static int8_t USBD_CDC_Receive (uint8_t* Buf, uint32_t *Len)
219221
{
220-
/* Initiate next USB packet transfer once a packet is received */
221-
USBPackSize = *Len;
222-
memcpy(USBBuffer, Buf, USBPackSize);
222+
uint32_t packetSize = *Len;
223+
224+
if (packetSize > 0) {
225+
if (UserRxBufPtrIn + packetSize > APP_RX_DATA_SIZE) {
226+
memcpy(((uint8_t *)UserRxBuffer + UserRxBufPtrIn), &Buf[0],
227+
(APP_RX_DATA_SIZE - UserRxBufPtrIn));
228+
memcpy((uint8_t *)UserRxBuffer,
229+
&Buf[(APP_RX_DATA_SIZE - UserRxBufPtrIn)],
230+
(packetSize - (APP_RX_DATA_SIZE - UserRxBufPtrIn)));
231+
UserRxBufPtrIn = ((UserRxBufPtrIn + packetSize) % APP_RX_DATA_SIZE);
232+
} else {
233+
memcpy(((uint8_t *)UserRxBuffer + UserRxBufPtrIn), Buf, packetSize);
234+
UserRxBufPtrIn = ((UserRxBufPtrIn + packetSize) % APP_RX_DATA_SIZE);
235+
}
236+
}
223237

224-
USB_received = 1;
238+
if ((UserRxBufPtrOut + APP_RX_DATA_SIZE - UserRxBufPtrIn - 1) %
239+
APP_RX_DATA_SIZE + 1 >= CDC_MAX_PACKET_SIZE) {
240+
USBD_CDC_ReceivePacket(
241+
&hUSBD_Device_CDC); // Initiate next USB packet transfer once a packet
242+
// is received and there is enouch space in the
243+
// buffer
244+
} else {
245+
receiveSuspended = true;
246+
}
225247
return (USBD_OK);
226248
}
227249

@@ -233,33 +255,44 @@ void CDC_flush(void)
233255
{
234256
if(UserTxBufPtrOut > UserTxBufPtrIn) /* Roll-back */
235257
{
236-
memcpy((uint8_t*)&StackTxBuffer[0], (uint8_t*)&UserTxBuffer[UserTxBufPtrOut], (APP_TX_DATA_SIZE - UserTxBufPtrOut));
237-
238-
memcpy((uint8_t*)&StackTxBuffer[APP_TX_DATA_SIZE - UserTxBufPtrOut], (uint8_t*)&UserTxBuffer[0], UserTxBufPtrIn);
239-
240-
USBD_CDC_SetTxBuffer(&hUSBD_Device_CDC, (uint8_t*)&StackTxBuffer[0], (APP_TX_DATA_SIZE - UserTxBufPtrOut + UserTxBufPtrIn));
258+
memcpy((uint8_t *)&StackTxBuffer[0],
259+
(uint8_t *)&UserTxBuffer[UserTxBufPtrOut],
260+
(APP_TX_DATA_SIZE - UserTxBufPtrOut));
261+
memcpy((uint8_t *)&StackTxBuffer[APP_TX_DATA_SIZE - UserTxBufPtrOut],
262+
(uint8_t *)&UserTxBuffer[0], UserTxBufPtrIn);
263+
264+
USBD_CDC_SetTxBuffer(
265+
&hUSBD_Device_CDC, (uint8_t *)&StackTxBuffer[0],
266+
(APP_TX_DATA_SIZE - UserTxBufPtrOut + UserTxBufPtrIn));
267+
} else {
268+
USBD_CDC_SetTxBuffer(&hUSBD_Device_CDC,
269+
(uint8_t *)&UserTxBuffer[UserTxBufPtrOut],
270+
(UserTxBufPtrIn - UserTxBufPtrOut));
271+
}
241272

242-
do {
273+
do {
274+
if (lineState == 0) { // Device disconnected
275+
status = USBD_OK;
276+
} else {
243277
status = USBD_CDC_TransmitPacket(&hUSBD_Device_CDC);
244-
} while(status == USBD_BUSY);
245-
246-
if(status == USBD_OK)
247-
{
248-
UserTxBufPtrOut = UserTxBufPtrIn;
249278
}
250-
}
251-
else
252-
{
253-
USBD_CDC_SetTxBuffer(&hUSBD_Device_CDC, (uint8_t*)&UserTxBuffer[UserTxBufPtrOut], (UserTxBufPtrIn - UserTxBufPtrOut));
279+
} while (status == USBD_BUSY);
254280

255-
do {
256-
status = USBD_CDC_TransmitPacket(&hUSBD_Device_CDC);
257-
} while(status == USBD_BUSY);
281+
if (status == USBD_OK) {
282+
UserTxBufPtrOut = UserTxBufPtrIn;
283+
}
284+
}
285+
}
258286

259-
if(status == USBD_OK)
260-
{
261-
UserTxBufPtrOut = UserTxBufPtrIn;
262-
}
287+
void CDC_resume_receive(void) {
288+
if (receiveSuspended) {
289+
if ((UserRxBufPtrOut + APP_RX_DATA_SIZE - UserRxBufPtrIn - 1) %
290+
APP_RX_DATA_SIZE + 1 >= CDC_MAX_PACKET_SIZE) {
291+
USBD_CDC_ReceivePacket(
292+
&hUSBD_Device_CDC); // Initiate next USB packet transfer once a packet
293+
// is received and there is enouch space in the
294+
// buffer
295+
receiveSuspended = false;
263296
}
264297
}
265298
}
@@ -293,62 +326,49 @@ static void CDC_TIM_Config(void)
293326
void CDC_TIM_PeriodElapsedCallback(stimer_t *htim)
294327
{
295328
UNUSED(htim);
329+
if (UserTxBufPtrOut == UserTxBufPtrIn &&
330+
sendZLP == false) // Nothing to do, return immediately
331+
return;
332+
296333
uint8_t status;
297-
uint16_t transferSize;
298-
299-
if(USB_received) {
300-
USB_received = 0;
301-
302-
if((USBPackSize > 0)) {
303-
if(UserRxBufPtrIn + USBPackSize > APP_RX_DATA_SIZE) {
304-
memcpy(((uint8_t *)UserRxBuffer+UserRxBufPtrIn), &USBBuffer[0], (APP_RX_DATA_SIZE - UserRxBufPtrIn));
305-
memcpy((uint8_t *)UserRxBuffer, &USBBuffer[(APP_RX_DATA_SIZE - UserRxBufPtrIn)], (USBPackSize - (APP_RX_DATA_SIZE - UserRxBufPtrIn)));
306-
UserRxBufPtrIn = ((UserRxBufPtrIn + USBPackSize) % APP_RX_DATA_SIZE);
307-
} else {
308-
memcpy(((uint8_t *)UserRxBuffer+UserRxBufPtrIn), USBBuffer, USBPackSize);
309-
UserRxBufPtrIn = ((UserRxBufPtrIn + USBPackSize) % APP_RX_DATA_SIZE);
310-
}
311-
}
334+
uint16_t packetLength;
312335

313-
USBD_CDC_ReceivePacket(&hUSBD_Device_CDC);
314-
}
336+
if (UserTxBufPtrOut > UserTxBufPtrIn) { /* Roll-back */
337+
memcpy((uint8_t *)&StackTxBuffer[0],
338+
(uint8_t *)&UserTxBuffer[UserTxBufPtrOut],
339+
(APP_TX_DATA_SIZE - UserTxBufPtrOut));
340+
memcpy((uint8_t *)&StackTxBuffer[APP_TX_DATA_SIZE - UserTxBufPtrOut],
341+
(uint8_t *)&UserTxBuffer[0], UserTxBufPtrIn);
315342

316-
if(UserTxBufPtrOut > UserTxBufPtrIn) { /* Roll-back */
317-
memcpy((uint8_t*)&StackTxBuffer[0], (uint8_t*)&UserTxBuffer[UserTxBufPtrOut], (APP_TX_DATA_SIZE - UserTxBufPtrOut));
318-
memcpy((uint8_t*)&StackTxBuffer[APP_TX_DATA_SIZE - UserTxBufPtrOut], (uint8_t*)&UserTxBuffer[0], UserTxBufPtrIn);
343+
packetLength = (APP_TX_DATA_SIZE - UserTxBufPtrOut + UserTxBufPtrIn);
319344

320-
transferSize = (APP_TX_DATA_SIZE - UserTxBufPtrOut + UserTxBufPtrIn);
345+
USBD_CDC_SetTxBuffer(&hUSBD_Device_CDC, (uint8_t *)&StackTxBuffer[0],
346+
packetLength);
347+
} else if (UserTxBufPtrOut != UserTxBufPtrIn) {
348+
packetLength = (UserTxBufPtrIn - UserTxBufPtrOut);
321349

322-
USBD_CDC_SetTxBuffer(&hUSBD_Device_CDC, (uint8_t*)&StackTxBuffer[0], transferSize);
323-
}
324-
else if (UserTxBufPtrOut != UserTxBufPtrIn) {
325-
transferSize = (UserTxBufPtrIn - UserTxBufPtrOut);
350+
USBD_CDC_SetTxBuffer(&hUSBD_Device_CDC,
351+
(uint8_t *)&UserTxBuffer[UserTxBufPtrOut],
352+
packetLength);
353+
} else {
354+
packetLength = 0;
326355

327-
USBD_CDC_SetTxBuffer(&hUSBD_Device_CDC, (uint8_t*)&UserTxBuffer[UserTxBufPtrOut], transferSize);
356+
USBD_CDC_SetTxBuffer(&hUSBD_Device_CDC, NULL, 0); // Send Zero Length Packet
328357
}
329-
else if (sendZLP) {
330-
transferSize = 0;
331358

332-
USBD_CDC_SetTxBuffer(&hUSBD_Device_CDC, NULL, 0);
359+
if (lineState == 0) { // Device disconnected
360+
status = USBD_OK;
333361
} else {
334-
return;
362+
status = USBD_CDC_TransmitPacket(&hUSBD_Device_CDC);
335363
}
336364

337-
do {
338-
if (lineState == 0) // Device disconnected
339-
status = USBD_OK;
340-
else
341-
status = USBD_CDC_TransmitPacket(&hUSBD_Device_CDC);
342-
} while(status == USBD_BUSY);
343-
344-
if(status == USBD_OK) {
365+
if (status == USBD_OK) {
345366
UserTxBufPtrOut = UserTxBufPtrIn;
346367

347-
sendZLP = transferSize%USB_MAX_EP0_SIZE == 0;
368+
sendZLP = packetLength % CDC_MAX_PACKET_SIZE == 0;
348369
}
349370
}
350371

351-
352372
#endif /* USBD_USE_CDC */
353373
#endif /* USBCON */
354374
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

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

+1
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ extern USBD_CDC_ItfTypeDef USBD_CDC_fops;
6060
void CDC_disable_TIM_Interrupt(void);
6161
void CDC_enable_TIM_Interrupt(void);
6262
void CDC_flush(void);
63+
void CDC_resume_receive(void);
6364

6465
#ifdef __cplusplus
6566
}

0 commit comments

Comments
 (0)