Skip to content

Commit d205983

Browse files
makarenyafpistm
authored andcommitted
[USB CDC] Remove timer and buffer usage
Signed-off-by: Alexey Makarenya <[email protected]>
1 parent 34b082d commit d205983

File tree

7 files changed

+138
-292
lines changed

7 files changed

+138
-292
lines changed

cores/arduino/USBSerial.cpp

+50-76
Original file line numberDiff line numberDiff line change
@@ -27,122 +27,96 @@
2727
#define USB_TIMEOUT 50
2828
/* USB Device Core handle declaration */
2929
extern USBD_HandleTypeDef hUSBD_Device_CDC;
30-
extern __IO uint32_t device_connection_status;
3130
extern __IO uint32_t lineState;
32-
extern __IO uint8_t UserTxBuffer[APP_TX_DATA_SIZE];
33-
extern __IO uint8_t UserRxBuffer[APP_RX_DATA_SIZE];
34-
extern __IO uint32_t UserTxBufPtrIn;
35-
extern __IO uint32_t UserTxBufPtrOut;
36-
extern __IO uint32_t UserRxBufPtrIn;
37-
extern __IO uint32_t UserRxBufPtrOut;
3831

3932
USBSerial SerialUSB;
4033

34+
void USBSerial::begin(void) {
35+
CDC_init();
36+
}
37+
4138
void USBSerial::begin(uint32_t /* baud_count */) {
4239
// uart config is ignored in USB-CDC
40+
begin();
4341
}
4442

4543
void USBSerial::begin(uint32_t /* baud_count */, uint8_t /* config */) {
4644
// uart config is ignored in USB-CDC
45+
begin();
4746
}
4847

49-
void USBSerial::end(void) {
50-
51-
USBD_LL_DeInit(&hUSBD_Device_CDC);
48+
void USBSerial::end() {
49+
CDC_deInit();
5250
}
5351

54-
int USBSerial::availableForWrite(void)
52+
int USBSerial::availableForWrite()
5553
{
56-
int ret_val;
57-
58-
/* UserTxBufPtrOut can be modified by TIM ISR, so in order to be sure that the */
59-
/* value that we read is correct, we need to disable TIM Interrupt. */
60-
CDC_disable_TIM_Interrupt();
61-
62-
if (UserTxBufPtrIn >= UserTxBufPtrOut) {
63-
ret_val = (APP_TX_DATA_SIZE - 1 - UserTxBufPtrIn + UserTxBufPtrOut);
64-
} else {
65-
ret_val = (UserTxBufPtrOut - UserTxBufPtrIn - 1);
66-
}
67-
68-
CDC_enable_TIM_Interrupt();
69-
70-
return ret_val;
54+
// Just transmit queue size, available for write
55+
return static_cast<int>(CDC_TransmitQueue_WriteSize(&TransmitQueue));
7156
}
7257

7358
size_t USBSerial::write(uint8_t ch) {
74-
75-
/* UserTxBufPtrOut can be modified by TIM ISR, so in order to be sure that the */
76-
/* value that we read is correct, we need to disable TIM Interrupt. */
77-
CDC_disable_TIM_Interrupt();
78-
79-
if (((UserTxBufPtrIn + 1) % APP_TX_DATA_SIZE) == UserTxBufPtrOut) {
80-
// Buffer full!!! Force a flush to not loose data and go on
81-
CDC_flush();
82-
}
83-
UserTxBuffer[UserTxBufPtrIn] = ch;
84-
UserTxBufPtrIn = ((UserTxBufPtrIn + 1) % APP_TX_DATA_SIZE);
85-
86-
CDC_enable_TIM_Interrupt();
87-
88-
return 1;
59+
// Just write single-byte buffer.
60+
return write(&ch, 1);
8961
}
9062

9163
size_t USBSerial::write(const uint8_t *buffer, size_t size){
92-
size_t i = 0;
93-
for (i=0; i < size; i++) {
94-
if (write(buffer[i]) != 1) {
95-
break;
96-
}
64+
size_t rest = size;
65+
while(rest > 0) {
66+
// Determine buffer size available for write
67+
auto portion = (size_t)CDC_TransmitQueue_WriteSize(&TransmitQueue);
68+
// Truncate it to content size (if rest is greater)
69+
if (rest < portion) {
70+
portion = rest;
71+
}
72+
if (portion > 0) {
73+
// Only if some space in the buffer exists.
74+
// TS: Only main thread calls write and writeSize methods,
75+
// it's thread-safe since IRQ does not affects
76+
// TransmitQueue write position
77+
CDC_TransmitQueue_Enqueue(&TransmitQueue, buffer, portion);
78+
rest -= portion;
79+
buffer += portion;
80+
// After storing data, start transmitting process
81+
CDC_continue_transmit();
82+
}
9783
}
98-
return i;
84+
return size;
9985
}
10086

10187
int USBSerial::available(void) {
102-
return ((APP_RX_DATA_SIZE + (UserRxBufPtrIn - UserRxBufPtrOut)) % APP_RX_DATA_SIZE);
88+
// Just ReceiveQueue size, available for reading
89+
return static_cast<int>(CDC_ReceiveQueue_ReadSize(&ReceiveQueue));
10390
}
10491

10592
int USBSerial::read(void) {
106-
if (UserRxBufPtrOut == UserRxBufPtrIn) {
93+
// Empty ReceiveQueue - nothing to return
94+
if (CDC_ReceiveQueue_ReadSize(&ReceiveQueue) <= 0) {
10795
return -1;
108-
} else {
109-
unsigned char c = UserRxBuffer[UserRxBufPtrOut];
110-
UserRxBufPtrOut = ((UserRxBufPtrOut + 1) % APP_RX_DATA_SIZE);
111-
CDC_resume_receive();
112-
return c;
11396
}
97+
// Dequeue only one char from queue
98+
// TS: it safe, because only main thread affects ReceiveQueue->read pos
99+
char ch = CDC_ReceiveQueue_Dequeue(&ReceiveQueue);
100+
// Resume receive process, if possible
101+
CDC_resume_receive();
102+
return ch;
114103
}
115104

116105
int USBSerial::peek(void)
117106
{
118-
if (UserRxBufPtrOut == UserRxBufPtrIn) {
107+
// Empty ReceiveQueue - nothing to return
108+
if (CDC_ReceiveQueue_ReadSize(&ReceiveQueue) <= 0) {
119109
return -1;
120-
} else {
121-
unsigned char c = UserRxBuffer[UserRxBufPtrOut];
122-
return c;
123110
}
111+
// Peek one symbol, it can't change receive avaiablity
112+
return CDC_ReceiveQueue_Peek(&ReceiveQueue);
124113
}
125114

126115
void USBSerial::flush(void)
127116
{
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();
131-
CDC_flush();
132-
CDC_enable_TIM_Interrupt();
133-
}
134-
135-
uint8_t USBSerial::pending(void) {
136-
return 0;
137-
}
138-
139-
uint8_t USBSerial::isConnected(void) {
140-
141-
if (device_connection_status == 1) {
142-
return 1;
143-
} else {
144-
return 0;
145-
}
117+
// Wait for TransmitQueue read size becomes zero
118+
// TS: safe, because it not be stopped while receive 0
119+
while(CDC_TransmitQueue_ReadSize(&TransmitQueue) > 0) {}
146120
}
147121

148122
uint32_t USBSerial::baud() {

cores/arduino/USBSerial.h

+1-5
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@
2727
// Serial over CDC
2828
class USBSerial : public Stream {
2929
public:
30-
USBSerial(void) {};
31-
30+
void begin(void);
3231
void begin(uint32_t);
3332
void begin(uint32_t, uint8_t);
3433
void end(void);
@@ -64,9 +63,6 @@ class USBSerial : public Stream {
6463
MARK_PARITY = 3,
6564
SPACE_PARITY = 4,
6665
};
67-
68-
uint8_t isConnected();
69-
uint8_t pending();
7066
};
7167

7268
extern USBSerial SerialUSB;

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

+5
Original file line numberDiff line numberDiff line change
@@ -678,6 +678,7 @@ static uint8_t USBD_CDC_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum)
678678
{
679679
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)pdev->pClassData;
680680
PCD_HandleTypeDef *hpcd = pdev->pData;
681+
USBD_CDC_ItfTypeDef* ctrl = (USBD_CDC_ItfTypeDef *)pdev->pUserData;
681682

682683
if(pdev->pClassData != NULL)
683684
{
@@ -692,6 +693,10 @@ static uint8_t USBD_CDC_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum)
692693
else
693694
{
694695
hcdc->TxState = 0U;
696+
if (ctrl->Transferred)
697+
{
698+
ctrl->Transferred();
699+
}
695700
}
696701
return USBD_OK;
697702
}

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

+1
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ typedef struct _USBD_CDC_Itf
104104
int8_t (* DeInit) (void);
105105
int8_t (* Control) (uint8_t cmd, uint8_t* pbuf, uint16_t length);
106106
int8_t (* Receive) (uint8_t* Buf, uint32_t *Len);
107+
int8_t (* Transferred) (void);
107108

108109
}USBD_CDC_ItfTypeDef;
109110

0 commit comments

Comments
 (0)