diff options
author | Matthijs Kooijman <matthijs@stdin.nl> | 2015-07-30 15:33:37 +0200 |
---|---|---|
committer | Matthijs Kooijman <matthijs@stdin.nl> | 2015-07-31 14:06:19 +0200 |
commit | 31e0c941240f2b1d0e4f97d6e65d3a1ad66fbae5 (patch) | |
tree | 0d080cc0e9601e1dc453f4452d29a5fddf4b2232 | |
parent | acb1a47a78ef96a5fcfbae9013dcc7d39e30292e (diff) |
Add Serial_::readBreak() to process SEND_BREAK requests
This allows detecting when the USB host sends a break request and what
the value of the request was. See the comments in USBAPI.h for details.
This just modifies the avr core, not the sam core.
-rw-r--r-- | cores/arduino/CDC.cpp | 18 | ||||
-rw-r--r-- | cores/arduino/USBAPI.h | 17 | ||||
-rw-r--r-- | cores/arduino/USBCore.h | 1 |
3 files changed, 36 insertions, 0 deletions
diff --git a/cores/arduino/CDC.cpp b/cores/arduino/CDC.cpp index 90a1698..5e872c5 100644 --- a/cores/arduino/CDC.cpp +++ b/cores/arduino/CDC.cpp @@ -32,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)) @@ -76,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); @@ -207,6 +213,7 @@ Serial_::operator bool() { } unsigned long Serial_::baud() { + // Disable interrupts while reading a multi-byte value ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { return _usbLineInfo.dwDTERate; } @@ -232,6 +239,17 @@ 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/USBAPI.h b/cores/arduino/USBAPI.h index ada73b0..3d355d2 100644 --- a/cores/arduino/USBAPI.h +++ b/cores/arduino/USBAPI.h @@ -102,6 +102,23 @@ public: 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. 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 |