Skip to content

Commit b58f239

Browse files
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.
1 parent 96f7b96 commit b58f239

File tree

3 files changed

+36
-0
lines changed

3 files changed

+36
-0
lines changed

hardware/arduino/avr/cores/arduino/CDC.cpp

+18
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ typedef struct
3232
} LineInfo;
3333

3434
static volatile LineInfo _usbLineInfo = { 57600, 0x00, 0x00, 0x00, 0x00 };
35+
static volatile int32_t breakValue = -1;
3536

3637
#define WEAK __attribute__ ((weak))
3738

@@ -76,6 +77,11 @@ bool CDC_Setup(USBSetup& setup)
7677

7778
if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType)
7879
{
80+
if (CDC_SEND_BREAK == r)
81+
{
82+
breakValue = ((uint16_t)setup.wValueH << 8) | setup.wValueL;
83+
}
84+
7985
if (CDC_SET_LINE_CODING == r)
8086
{
8187
USB_RecvControl((void*)&_usbLineInfo,7);
@@ -207,6 +213,7 @@ Serial_::operator bool() {
207213
}
208214

209215
unsigned long Serial_::baud() {
216+
// Disable interrupts while reading a multi-byte value
210217
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
211218
return _usbLineInfo.dwDTERate;
212219
}
@@ -232,6 +239,17 @@ bool Serial_::rts() {
232239
return _usbLineInfo.lineState & 0x2;
233240
}
234241

242+
int32_t Serial_::readBreak() {
243+
int32_t ret;
244+
// Disable IRQs while reading and clearing breakValue to make
245+
// sure we don't overwrite a value just set by the ISR.
246+
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
247+
ret = breakValue;
248+
breakValue = -1;
249+
}
250+
return ret;
251+
}
252+
235253
Serial_ Serial;
236254

237255
#endif /* if defined(USBCON) */

hardware/arduino/avr/cores/arduino/USBAPI.h

+17
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,23 @@ class Serial_ : public Stream
102102
volatile uint8_t _rx_buffer_tail;
103103
unsigned char _rx_buffer[SERIAL_BUFFER_SIZE];
104104

105+
// This method allows processing "SEND_BREAK" requests sent by
106+
// the USB host. Those requests indicate that the host wants to
107+
// send a BREAK signal and are accompanied by a single uint16_t
108+
// value, specifying the duration of the break. The value 0
109+
// means to end any current break, while the value 0xffff means
110+
// to start an indefinite break.
111+
// readBreak() will return the value of the most recent break
112+
// request, but will return it at most once, returning -1 when
113+
// readBreak() is called again (until another break request is
114+
// received, which is again returned once).
115+
// This also mean that if two break requests are received
116+
// without readBreak() being called in between, the value of the
117+
// first request is lost.
118+
// Note that the value returned is a long, so it can return
119+
// 0-0xffff as well as -1.
120+
int32_t readBreak();
121+
105122
// These return the settings specified by the USB host for the
106123
// serial port. These aren't really used, but are offered here
107124
// in case a sketch wants to act on these settings.

hardware/arduino/avr/cores/arduino/USBCore.h

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
#define CDC_SET_LINE_CODING 0x20
5858
#define CDC_GET_LINE_CODING 0x21
5959
#define CDC_SET_CONTROL_LINE_STATE 0x22
60+
#define CDC_SEND_BREAK 0x23
6061

6162
#define MSC_RESET 0xFF
6263
#define MSC_GET_MAX_LUN 0xFE

0 commit comments

Comments
 (0)