aboutsummaryrefslogtreecommitdiff
path: root/cores/arduino/CDC.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cores/arduino/CDC.cpp')
-rw-r--r--cores/arduino/CDC.cpp277
1 files changed, 0 insertions, 277 deletions
diff --git a/cores/arduino/CDC.cpp b/cores/arduino/CDC.cpp
index 142f8f6..a6bce17 100644
--- a/cores/arduino/CDC.cpp
+++ b/cores/arduino/CDC.cpp
@@ -17,286 +17,9 @@
*/
#include "USBAPI.h"
-#include <avr/wdt.h>
-#include <util/atomic.h>
#if defined(USBCON)
-typedef struct
-{
- u32 dwDTERate;
- u8 bCharFormat;
- u8 bParityType;
- u8 bDataBits;
- u8 lineState;
-} LineInfo;
-
-static volatile LineInfo _usbLineInfo = { 57600, 0x00, 0x00, 0x00, 0x00 };
-static volatile int32_t breakValue = -1;
-
-static u8 wdtcsr_save;
-
-#define WEAK __attribute__ ((weak))
-
-extern const CDCDescriptor _cdcInterface PROGMEM;
-const CDCDescriptor _cdcInterface =
-{
- D_IAD(0,2,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,1),
-
- // CDC communication interface
- D_INTERFACE(CDC_ACM_INTERFACE,1,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,0),
- D_CDCCS(CDC_HEADER,0x10,0x01), // Header (1.10 bcd)
- D_CDCCS(CDC_CALL_MANAGEMENT,1,1), // Device handles call management (not)
- D_CDCCS4(CDC_ABSTRACT_CONTROL_MANAGEMENT,6), // SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported
- D_CDCCS(CDC_UNION,CDC_ACM_INTERFACE,CDC_DATA_INTERFACE), // Communication interface is master, data interface is slave 0
- D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_ACM),USB_ENDPOINT_TYPE_INTERRUPT,0x10,0x40),
-
- // CDC data interface
- D_INTERFACE(CDC_DATA_INTERFACE,2,CDC_DATA_INTERFACE_CLASS,0,0),
- D_ENDPOINT(USB_ENDPOINT_OUT(CDC_ENDPOINT_OUT),USB_ENDPOINT_TYPE_BULK,USB_EP_SIZE,0),
- D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ),USB_ENDPOINT_TYPE_BULK,USB_EP_SIZE,0)
-};
-
-bool isLUFAbootloader()
-{
- return pgm_read_word(FLASHEND - 1) == NEW_LUFA_SIGNATURE;
-}
-
-int CDC_GetInterface(u8* interfaceNum)
-{
- interfaceNum[0] += 2; // uses 2
- return USB_SendControl(TRANSFER_PGM,&_cdcInterface,sizeof(_cdcInterface));
-}
-
-bool CDC_Setup(USBSetup& setup)
-{
- u8 r = setup.bRequest;
- u8 requestType = setup.bmRequestType;
-
- if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType)
- {
- if (CDC_GET_LINE_CODING == r)
- {
- USB_SendControl(0,(void*)&_usbLineInfo,7);
- return true;
- }
- }
-
- if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType)
- {
- if (CDC_SEND_BREAK == r)
- {
- breakValue = ((uint16_t)setup.wValueH << 8) | setup.wValueL;
- }
-
- if (CDC_SET_LINE_CODING == r)
- {
- USB_RecvControl((void*)&_usbLineInfo,7);
- }
-
- if (CDC_SET_CONTROL_LINE_STATE == r)
- {
- _usbLineInfo.lineState = setup.wValueL;
-
- // auto-reset into the bootloader is triggered when the port, already
- // open at 1200 bps, is closed. this is the signal to start the watchdog
- // with a relatively long period so it can finish housekeeping tasks
- // like servicing endpoints before the sketch ends
-
- uint16_t magic_key_pos = MAGIC_KEY_POS;
-
-// If we don't use the new RAMEND directly, check manually if we have a newer bootloader.
-// This is used to keep compatible with the old leonardo bootloaders.
-// You are still able to set the magic key position manually to RAMEND-1 to save a few bytes for this check.
-#if MAGIC_KEY_POS != (RAMEND-1)
- // For future boards save the key in the inproblematic RAMEND
- // Which is reserved for the main() return value (which will never return)
- if (isLUFAbootloader()) {
- // horray, we got a new bootloader!
- magic_key_pos = (RAMEND-1);
- }
-#endif
-
- // We check DTR state to determine if host port is open (bit 0 of lineState).
- if (1200 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0)
- {
-#if MAGIC_KEY_POS != (RAMEND-1)
- // Backup ram value if its not a newer bootloader and it hasn't already been saved.
- // This should avoid memory corruption at least a bit, not fully
- if (magic_key_pos != (RAMEND-1) && *(uint16_t *)magic_key_pos != MAGIC_KEY) {
- *(uint16_t *)(RAMEND-1) = *(uint16_t *)magic_key_pos;
- }
-#endif
- // Store boot key
- *(uint16_t *)magic_key_pos = MAGIC_KEY;
- // Save the watchdog state in case the reset is aborted.
- wdtcsr_save = WDTCSR;
- wdt_enable(WDTO_120MS);
- }
- else if (*(uint16_t *)magic_key_pos == MAGIC_KEY)
- {
- // Most OSs do some intermediate steps when configuring ports and DTR can
- // twiggle more than once before stabilizing.
- // To avoid spurious resets we set the watchdog to 120ms and eventually
- // cancel if DTR goes back high.
- // Cancellation is only done if an auto-reset was started, which is
- // indicated by the magic key having been set.
-
- wdt_reset();
- // Restore the watchdog state in case the sketch was using it.
- WDTCSR |= (1<<WDCE) | (1<<WDE);
- WDTCSR = wdtcsr_save;
-#if MAGIC_KEY_POS != (RAMEND-1)
- // Restore backed up (old bootloader) magic key data
- if (magic_key_pos != (RAMEND-1)) {
- *(uint16_t *)magic_key_pos = *(uint16_t *)(RAMEND-1);
- } else
-#endif
- {
- // Clean up RAMEND key
- *(uint16_t *)magic_key_pos = 0x0000;
- }
- }
- }
- return true;
- }
- return false;
-}
-
-
-void Serial_::begin(unsigned long /* baud_count */)
-{
- peek_buffer = -1;
-}
-
-void Serial_::begin(unsigned long /* baud_count */, byte /* config */)
-{
- peek_buffer = -1;
-}
-
-void Serial_::end(void)
-{
-}
-
-int Serial_::available(void)
-{
- if (peek_buffer >= 0) {
- return 1 + USB_Available(CDC_RX);
- }
- return USB_Available(CDC_RX);
-}
-
-int Serial_::peek(void)
-{
- if (peek_buffer < 0)
- peek_buffer = USB_Recv(CDC_RX);
- return peek_buffer;
-}
-
-int Serial_::read(void)
-{
- if (peek_buffer >= 0) {
- int c = peek_buffer;
- peek_buffer = -1;
- return c;
- }
- return USB_Recv(CDC_RX);
-}
-
-int Serial_::availableForWrite(void)
-{
- return USB_SendSpace(CDC_TX);
-}
-
-void Serial_::flush(void)
-{
- USB_Flush(CDC_TX);
-}
-
-size_t Serial_::write(uint8_t c)
-{
- return write(&c, 1);
-}
-
-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 lineState when the port
- is opened and clear lineState 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. */
-
- // 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 (_usbLineInfo.lineState > 0) {
- int r = USB_Send(CDC_TX,buffer,size);
- if (r > 0) {
- return r;
- } else {
- setWriteError();
- return 0;
- }
- }
- setWriteError();
- return 0;
-}
-
-// This operator is a convenient way for a sketch to check whether the
-// port has actually been configured and opened by the host (as opposed
-// to just being connected to the host). It can be used, for example, in
-// setup() before printing to ensure that an application on the host is
-// actually ready to receive and display the data.
-// We add a short delay before returning to fix a bug observed by Federico
-// where the port is configured (lineState != 0) but not quite opened.
-Serial_::operator bool() {
- bool result = false;
- if (_usbLineInfo.lineState > 0)
- result = true;
- delay(10);
- return result;
-}
-
-unsigned long Serial_::baud() {
- // Disable interrupts while reading a multi-byte value
- uint32_t baudrate;
- ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
- baudrate = _usbLineInfo.dwDTERate;
- }
- return baudrate;
-}
-
-uint8_t Serial_::stopbits() {
- return _usbLineInfo.bCharFormat;
-}
-
-uint8_t Serial_::paritytype() {
- return _usbLineInfo.bParityType;
-}
-
-uint8_t Serial_::numbits() {
- return _usbLineInfo.bDataBits;
-}
-
-bool Serial_::dtr() {
- return _usbLineInfo.lineState & 0x1;
-}
-
-bool Serial_::rts() {
- return _usbLineInfo.lineState & 0x2;
-}
-
-int32_t Serial_::readBreak() {
- int32_t ret;
- // Disable IRQs while reading and clearing breakValue to make
- // sure we don't overwrite a value just set by the ISR.
- ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
- ret = breakValue;
- breakValue = -1;
- }
- return ret;
-}
-
Serial_ Serial;
#endif /* if defined(USBCON) */