Serial_::operator bool() { bool result = false; if(USBDevice.configured() && (_cdcLineState & CONTROL_LINE_STATE_DTR) && !USB_IsSendQFull(CDC_TX) // && !USB_IsStalled(CDC_TX) ) { result = true; } // We add a short delay before returning to fix a bug observed by Federico // where the port is configured (_cdcLineState != 0) but not quite opened. // delay(10); if(!result) { if(!USBDevice.configured()) { #ifdef DEBUG_CODE error_printP(F("USB device not configured")); #endif // DEBUG_CODE } else if(!(_cdcLineState & CONTROL_LINE_STATE_DTR)) { #ifdef DEBUG_CODE error_printP(F("DTR is off")); #endif // DEBUG_CODE } else if(USB_IsSendQFull(CDC_TX)) { #ifdef DEBUG_CODE error_printP(F("Send Queue FULL")); #endif // DEBUG_CODE } // else if(USB_IsStalled(CDC_TX)) // { //#ifdef DEBUG_CODE // error_printP(F("USB is stalled")); //#endif // DEBUG_CODE // } } return result; }
size_t Serial_::write(const uint8_t *buffer, size_t size) { /* only try to send bytes if the high-level CDC connection itself is open (not just the pipe) - the OS should set _cdcLineState when the port is opened and clear _cdcLineState when the port is closed. bytes sent before the user opens the connection or after the connection is closed are lost - just like with a UART. */ // NOTE: if my outgoing buffer is too full, stop sending // TODO - ZE - check behavior on different OSes and test what happens if an // open connection isn't broken cleanly (cable is yanked out, host dies // or locks up, or host virtual serial port hangs) if(USBDevice.configured() && // make sure I'm running // !USB_IsStalled(CDC_TX) && // make sure I'm not stalled !USB_IsSendQFull(CDC_TX)) // make sure I'm not flooding the queue { if(_cdcLineState & CONTROL_LINE_STATE_DTR) // make sure DTR is set { if(size > 128) { size = 128; // adjust size DOWN to limit output buffer size } int r = USB_Send(CDC_TX, buffer, size, 1); // TODO: check for partial sends and retry?? if(r > 0) { CDC_FrameReceived(); // inform the host of my data send/receive state return r; } } } // TODO: block? setWriteError(); return 0; }