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 /cores/arduino | |
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.
Diffstat (limited to 'cores/arduino')
-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 |