diff options
Diffstat (limited to 'cores')
-rw-r--r-- | cores/arduino/CDC.cpp | 50 | ||||
-rw-r--r-- | cores/arduino/HardwareSerial.cpp | 3 | ||||
-rw-r--r-- | cores/arduino/USBAPI.h | 42 | ||||
-rw-r--r-- | cores/arduino/USBCore.h | 1 |
4 files changed, 94 insertions, 2 deletions
diff --git a/cores/arduino/CDC.cpp b/cores/arduino/CDC.cpp index 7c7eacf..7168408 100644 --- a/cores/arduino/CDC.cpp +++ b/cores/arduino/CDC.cpp @@ -18,6 +18,7 @@ #include "USBAPI.h" #include <avr/wdt.h> +#include <util/atomic.h> #if defined(USBCON) @@ -31,6 +32,7 @@ typedef struct } LineInfo; static volatile LineInfo _usbLineInfo = { 57600, 0x00, 0x00, 0x00, 0x00 }; +static volatile int32_t breakValue = -1; #define WEAK __attribute__ ((weak)) @@ -75,6 +77,11 @@ bool CDC_Setup(USBSetup& setup) 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); @@ -173,6 +180,11 @@ int Serial_::read(void) return USB_Recv(CDC_RX); } +int Serial_::availableForWrite(void) +{ + return USB_SendSpace(CDC_TX); +} + void Serial_::flush(void) { USB_Flush(CDC_TX); @@ -222,6 +234,44 @@ Serial_::operator bool() { return result; } +unsigned long Serial_::baud() { + // Disable interrupts while reading a multi-byte value + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { + return _usbLineInfo.dwDTERate; + } +} + +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) */ diff --git a/cores/arduino/HardwareSerial.cpp b/cores/arduino/HardwareSerial.cpp index a2029a8..5cd89e5 100644 --- a/cores/arduino/HardwareSerial.cpp +++ b/cores/arduino/HardwareSerial.cpp @@ -138,8 +138,7 @@ void HardwareSerial::begin(unsigned long baud, byte config) void HardwareSerial::end() { // wait for transmission of outgoing data - while (_tx_buffer_head != _tx_buffer_tail) - ; + flush(); cbi(*_ucsrb, RXEN0); cbi(*_ucsrb, TXEN0); diff --git a/cores/arduino/USBAPI.h b/cores/arduino/USBAPI.h index 7f468a6..4072772 100644 --- a/cores/arduino/USBAPI.h +++ b/cores/arduino/USBAPI.h @@ -98,6 +98,7 @@ public: virtual int available(void); virtual int peek(void); virtual int read(void); + int availableForWrite(void); virtual void flush(void); virtual size_t write(uint8_t); virtual size_t write(const uint8_t*, size_t); @@ -107,6 +108,46 @@ public: volatile uint8_t _rx_buffer_head; volatile uint8_t _rx_buffer_tail; unsigned char _rx_buffer[SERIAL_BUFFER_SIZE]; + + // This method allows processing "SEND_BREAK" requests sent by + // the USB host. Those requests indicate that the host wants to + // send a BREAK signal and are accompanied by a single uint16_t + // value, specifying the duration of the break. The value 0 + // means to end any current break, while the value 0xffff means + // to start an indefinite break. + // readBreak() will return the value of the most recent break + // request, but will return it at most once, returning -1 when + // readBreak() is called again (until another break request is + // received, which is again returned once). + // This also mean that if two break requests are received + // without readBreak() being called in between, the value of the + // first request is lost. + // Note that the value returned is a long, so it can return + // 0-0xffff as well as -1. + int32_t readBreak(); + + // These return the settings specified by the USB host for the + // serial port. These aren't really used, but are offered here + // in case a sketch wants to act on these settings. + uint32_t baud(); + uint8_t stopbits(); + uint8_t paritytype(); + uint8_t numbits(); + bool dtr(); + bool rts(); + enum { + ONE_STOP_BIT = 0, + ONE_AND_HALF_STOP_BIT = 1, + TWO_STOP_BITS = 2, + }; + enum { + NO_PARITY = 0, + ODD_PARITY = 1, + EVEN_PARITY = 2, + MARK_PARITY = 3, + SPACE_PARITY = 4, + }; + }; extern Serial_ Serial; @@ -154,6 +195,7 @@ int USB_SendControl(uint8_t flags, const void* d, int len); int USB_RecvControl(void* d, int len); uint8_t USB_Available(uint8_t ep); +uint8_t USB_SendSpace(uint8_t ep); int USB_Send(uint8_t ep, const void* data, int len); // blocking int USB_Recv(uint8_t ep, void* data, int len); // non-blocking int USB_Recv(uint8_t ep); // non-blocking diff --git a/cores/arduino/USBCore.h b/cores/arduino/USBCore.h index 66f8c05..eaeecef 100644 --- a/cores/arduino/USBCore.h +++ b/cores/arduino/USBCore.h @@ -57,6 +57,7 @@ #define CDC_SET_LINE_CODING 0x20 #define CDC_GET_LINE_CODING 0x21 #define CDC_SET_CONTROL_LINE_STATE 0x22 +#define CDC_SEND_BREAK 0x23 #define MSC_RESET 0xFF #define MSC_GET_MAX_LUN 0xFE |