2323#include < stdio.h>
2424#include < stdint.h>
2525
26+ uint8_t USB_TXLEDticks = 0 , USB_RXLEDticks = 0 ;
27+
2628#ifdef CDC_ENABLED
2729
2830#define CDC_SERIAL_BUFFER_SIZE 256
@@ -92,6 +94,12 @@ bool CDC_Setup(USBSetup& setup)
9294 uint8_t requestType = setup.bmRequestType ;
9395 uint8_t r = setup.bRequest ;
9496
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+
95103 if (requestType == REQUEST_DEVICETOHOST_CLASS_INTERFACE)
96104 {
97105 if (r == CDC_GET_LINE_CODING)
@@ -176,10 +184,16 @@ int Serial_::peek(void)
176184
177185int Serial_::read (void )
178186{
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 ();
183197 }
184198 return usb.recv (CDC_ENDPOINT_OUT);
185199}
@@ -205,7 +219,23 @@ void Serial_::flush(void)
205219
206220size_t Serial_::write (const uint8_t *buffer, size_t size)
207221{
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+ }
209239
210240 if (r > 0 ) {
211241 return r;
@@ -243,54 +273,6 @@ Serial_::operator bool()
243273 return result;
244274}
245275
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- =======
293276Serial_ Serial (USBDevice);
294- >>>>>>> make it so native USB is Serial
295277
296278#endif
0 commit comments