Skip to content

Commit 1c91d5a

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

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,123 +27,97 @@
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
void serialEventUSB() __attribute__((weak));
4134

35+
void USBSerial::begin(void) {
36+
CDC_init();
37+
}
38+
4239
void USBSerial::begin(uint32_t /* baud_count */) {
4340
// uart config is ignored in USB-CDC
41+
begin();
4442
}
4543

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

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

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

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

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

10288
int USBSerial::available(void) {
103-
return ((APP_RX_DATA_SIZE + (UserRxBufPtrIn - UserRxBufPtrOut)) % APP_RX_DATA_SIZE);
89+
// Just ReceiveQueue size, available for reading
90+
return static_cast<int>(CDC_ReceiveQueue_ReadSize(&ReceiveQueue));
10491
}
10592

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

117106
int USBSerial::peek(void)
118107
{
119-
if (UserRxBufPtrOut == UserRxBufPtrIn) {
108+
// Empty ReceiveQueue - nothing to return
109+
if (CDC_ReceiveQueue_ReadSize(&ReceiveQueue) <= 0) {
120110
return -1;
121-
} else {
122-
unsigned char c = UserRxBuffer[UserRxBufPtrOut];
123-
return c;
124111
}
112+
// Peek one symbol, it can't change receive avaiablity
113+
return CDC_ReceiveQueue_Peek(&ReceiveQueue);
125114
}
126115

127116
void USBSerial::flush(void)
128117
{
129-
/* UserTxBufPtrOut can be modified by TIM ISR, so in order to be sure that the */
130-
/* value that we read is correct, we need to disable TIM Interrupt. */
131-
CDC_disable_TIM_Interrupt();
132-
CDC_flush();
133-
CDC_enable_TIM_Interrupt();
134-
}
135-
136-
uint8_t USBSerial::pending(void) {
137-
return 0;
138-
}
139-
140-
uint8_t USBSerial::isConnected(void) {
141-
142-
if (device_connection_status == 1) {
143-
return 1;
144-
} else {
145-
return 0;
146-
}
118+
// Wait for TransmitQueue read size becomes zero
119+
// TS: safe, because it not be stopped while receive 0
120+
while(CDC_TransmitQueue_ReadSize(&TransmitQueue) > 0) {}
147121
}
148122

149123
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)