From 2007b623c9457ecb1b15397f41d632f911b4461e Mon Sep 17 00:00:00 2001 From: Sandeep Mistry Date: Tue, 17 Nov 2015 09:53:52 -0500 Subject: [PATCH 1/3] Add CDC_SEND_BREAK define --- hardware/arduino/sam/cores/arduino/USB/USBCore.h | 1 + 1 file changed, 1 insertion(+) diff --git a/hardware/arduino/sam/cores/arduino/USB/USBCore.h b/hardware/arduino/sam/cores/arduino/USB/USBCore.h index 893d84fcbbe..465c71de1d5 100644 --- a/hardware/arduino/sam/cores/arduino/USB/USBCore.h +++ b/hardware/arduino/sam/cores/arduino/USB/USBCore.h @@ -55,6 +55,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 From 86e34b99401679e1790bf8fedc7df13f5f3dd4e3 Mon Sep 17 00:00:00 2001 From: Sandeep Mistry Date: Tue, 17 Nov 2015 09:57:04 -0500 Subject: [PATCH 2/3] Support receiving a USB CDC SEND_BREAK --- hardware/arduino/sam/cores/arduino/USB/CDC.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/hardware/arduino/sam/cores/arduino/USB/CDC.cpp b/hardware/arduino/sam/cores/arduino/USB/CDC.cpp index 306c124ff24..9ab8356d92f 100644 --- a/hardware/arduino/sam/cores/arduino/USB/CDC.cpp +++ b/hardware/arduino/sam/cores/arduino/USB/CDC.cpp @@ -141,6 +141,11 @@ bool WEAK CDC_Setup(USBSetup& setup) } return true; } + + if (CDC_SEND_BREAK == r) + { + return true; + } } return false; } From 9759f2cc607a1d65eccb49e5271cb686b99442e3 Mon Sep 17 00:00:00 2001 From: Sandeep Mistry Date: Tue, 17 Nov 2015 10:09:56 -0500 Subject: [PATCH 3/3] Port AVR Serial_::readBreak() API to SAM core --- .../arduino/sam/cores/arduino/USB/CDC.cpp | 25 +++++++++++++++++++ .../arduino/sam/cores/arduino/USB/USBAPI.h | 17 +++++++++++++ 2 files changed, 42 insertions(+) diff --git a/hardware/arduino/sam/cores/arduino/USB/CDC.cpp b/hardware/arduino/sam/cores/arduino/USB/CDC.cpp index 9ab8356d92f..1df3061e3ed 100644 --- a/hardware/arduino/sam/cores/arduino/USB/CDC.cpp +++ b/hardware/arduino/sam/cores/arduino/USB/CDC.cpp @@ -55,6 +55,8 @@ static volatile LineInfo _usbLineInfo = { 0x00 // lineState }; +static volatile int32_t breakValue = -1; + _Pragma("pack(1)") static const CDCDescriptor _cdcInterface = { @@ -144,6 +146,7 @@ bool WEAK CDC_Setup(USBSetup& setup) if (CDC_SEND_BREAK == r) { + breakValue = ((uint16_t)setup.wValueH << 8) | setup.wValueL; return true; } } @@ -305,6 +308,28 @@ Serial_::operator bool() return result; } +int32_t Serial_::readBreak() { + uint8_t enableInterrupts = ((__get_PRIMASK() & 0x1) == 0 && + (__get_FAULTMASK() & 0x1) == 0); + + // disable interrupts, + // to avoid clearing a breakValue that might occur + // while processing the current break value + __disable_irq(); + + int ret = breakValue; + + breakValue = -1; + + if (enableInterrupts) + { + // re-enable the interrupts + __enable_irq(); + } + + return ret; +} + unsigned long Serial_::baud() { return _usbLineInfo.dwDTERate; } diff --git a/hardware/arduino/sam/cores/arduino/USB/USBAPI.h b/hardware/arduino/sam/cores/arduino/USB/USBAPI.h index dbc2ec5dc61..2eeaca08e88 100644 --- a/hardware/arduino/sam/cores/arduino/USB/USBAPI.h +++ b/hardware/arduino/sam/cores/arduino/USB/USBAPI.h @@ -63,6 +63,23 @@ class Serial_ : public Stream using Print::write; // pull in write(str) from Print operator bool(); + // 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.