aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthijs Kooijman <matthijs@stdin.nl>2015-07-30 15:33:37 +0200
committerMatthijs Kooijman <matthijs@stdin.nl>2015-07-31 14:06:19 +0200
commit31e0c941240f2b1d0e4f97d6e65d3a1ad66fbae5 (patch)
tree0d080cc0e9601e1dc453f4452d29a5fddf4b2232
parentacb1a47a78ef96a5fcfbae9013dcc7d39e30292e (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.cpp18
-rw-r--r--cores/arduino/USBAPI.h17
-rw-r--r--cores/arduino/USBCore.h1
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