23
23
#include < stdio.h>
24
24
#include < stdint.h>
25
25
26
+ uint8_t USB_TXLEDticks = 0 , USB_RXLEDticks = 0 ;
27
+
26
28
#ifdef CDC_ENABLED
27
29
28
30
#define CDC_SERIAL_BUFFER_SIZE 256
@@ -92,6 +94,12 @@ bool CDC_Setup(USBSetup& setup)
92
94
uint8_t requestType = setup.bmRequestType ;
93
95
uint8_t r = setup.bRequest ;
94
96
97
+ digitalWrite (PIN_LED_RXL, HIGH);
98
+ digitalWrite (PIN_LED_TXL, HIGH);
99
+ pinMode (PIN_LED_RXL, OUTPUT);
100
+ pinMode (PIN_LED_TXL, OUTPUT);
101
+ USB_TXLEDticks = USB_RXLEDticks = 0 ;
102
+
95
103
if (requestType == REQUEST_DEVICETOHOST_CLASS_INTERFACE)
96
104
{
97
105
if (r == CDC_GET_LINE_CODING)
@@ -176,10 +184,16 @@ int Serial_::peek(void)
176
184
177
185
int Serial_::read (void )
178
186
{
179
- if (_serialPeek != -1 ) {
180
- int res = _serialPeek;
181
- _serialPeek = -1 ;
182
- return res;
187
+ ring_buffer *buffer = &cdc_rx_buffer;
188
+
189
+ digitalWrite (PIN_LED_RXL, LOW);
190
+ USB_RXLEDticks = 10 ; // how many ms to keep LED on
191
+
192
+ // if the head isn't ahead of the tail, we don't have any characters
193
+ if (buffer->head == buffer->tail && !buffer->full )
194
+ {
195
+ if (usb.available (CDC_ENDPOINT_OUT))
196
+ accept ();
183
197
}
184
198
return usb.recv (CDC_ENDPOINT_OUT);
185
199
}
@@ -205,7 +219,23 @@ void Serial_::flush(void)
205
219
206
220
size_t Serial_::write (const uint8_t *buffer, size_t size)
207
221
{
208
- uint32_t r = usb.send (CDC_ENDPOINT_IN, buffer, size);
222
+ /* only try to send bytes if the high-level CDC connection itself
223
+ is open (not just the pipe) - the OS should set lineState when the port
224
+ is opened and clear lineState when the port is closed.
225
+ bytes sent before the user opens the connection or after
226
+ the connection is closed are lost - just like with a UART. */
227
+
228
+ digitalWrite (PIN_LED_TXL, LOW);
229
+ USB_TXLEDticks = 10 ; // how many ms to keep LED on
230
+
231
+ // TODO - ZE - check behavior on different OSes and test what happens if an
232
+ // open connection isn't broken cleanly (cable is yanked out, host dies
233
+ // or locks up, or host virtual serial port hangs)
234
+ uint32_t r = 0 ;
235
+ if (_usbLineInfo.lineState > 0 ) // Problem with Windows(R)
236
+ {
237
+ r = usb.send (CDC_ENDPOINT_IN, buffer, size);
238
+ }
209
239
210
240
if (r > 0 ) {
211
241
return r;
@@ -243,54 +273,6 @@ Serial_::operator bool()
243
273
return result;
244
274
}
245
275
246
- <<<<<<< HEAD
247
- int32_t Serial_::readBreak () {
248
- uint8_t enableInterrupts = ((__get_PRIMASK () & 0x1 ) == 0 );
249
-
250
- // disable interrupts,
251
- // to avoid clearing a breakValue that might occur
252
- // while processing the current break value
253
- __disable_irq ();
254
-
255
- int32_t ret = breakValue;
256
-
257
- breakValue = -1 ;
258
-
259
- if (enableInterrupts) {
260
- // re-enable the interrupts
261
- __enable_irq ();
262
- }
263
-
264
- return ret;
265
- }
266
-
267
- unsigned long Serial_::baud () {
268
- return _usbLineInfo.dwDTERate ;
269
- }
270
-
271
- uint8_t Serial_::stopbits () {
272
- return _usbLineInfo.bCharFormat ;
273
- }
274
-
275
- uint8_t Serial_::paritytype () {
276
- return _usbLineInfo.bParityType ;
277
- }
278
-
279
- uint8_t Serial_::numbits () {
280
- return _usbLineInfo.bDataBits ;
281
- }
282
-
283
- bool Serial_::dtr () {
284
- return _usbLineInfo.lineState & 0x1 ;
285
- }
286
-
287
- bool Serial_::rts () {
288
- return _usbLineInfo.lineState & 0x2 ;
289
- }
290
-
291
- Serial_ SerialUSB (USBDevice);
292
- =======
293
276
Serial_ Serial (USBDevice);
294
- >>>>>>> make it so native USB is Serial
295
277
296
278
#endif
0 commit comments