From 3ea315a0e384fcc88bcab8248aed34db045eb4fc Mon Sep 17 00:00:00 2001 From: Sandeep Mistry Date: Tue, 17 Nov 2015 15:35:30 -0500 Subject: [PATCH] Port some AVR Serial_ (SerialUSB) API's over --- cores/arduino/USB/CDC.cpp | 52 +++++++++++++++++++++++++++++++++++++ cores/arduino/USB/USBAPI.h | 40 ++++++++++++++++++++++++++++ cores/arduino/USB/USBCore.h | 1 + 3 files changed, 93 insertions(+) diff --git a/cores/arduino/USB/CDC.cpp b/cores/arduino/USB/CDC.cpp index 0f1016848..f1910da22 100644 --- a/cores/arduino/USB/CDC.cpp +++ b/cores/arduino/USB/CDC.cpp @@ -58,6 +58,8 @@ static volatile LineInfo _usbLineInfo = { 0x00 // lineState }; +static volatile int32_t breakValue = -1; + static CDCDescriptor _cdcInterface = { D_IAD(0, 2, CDC_COMMUNICATION_INTERFACE_CLASS, CDC_ABSTRACT_CONTROL_MODEL, 0), @@ -134,6 +136,12 @@ bool CDC_Setup(USBSetup& setup) } return false; } + + if (CDC_SEND_BREAK == r) + { + breakValue = ((uint16_t)setup.wValueH << 8) | setup.wValueL; + return false; + } } return false; } @@ -289,6 +297,50 @@ Serial_::operator bool() return result; } +int32_t Serial_::readBreak() { + uint8_t enableInterrupts = ((__get_PRIMASK() & 0x1) == 0); + + // disable interrupts, + // to avoid clearing a breakValue that might occur + // while processing the current break value + __disable_irq(); + + int32_t ret = breakValue; + + breakValue = -1; + + if (enableInterrupts) { + // re-enable the interrupts + __enable_irq(); + } + + return ret; +} + +unsigned long Serial_::baud() { + return _usbLineInfo.dwDTERate; +} + +uint8_t Serial_::stopbits() { + return _usbLineInfo.bCharFormat; +} + +uint8_t Serial_::paritytype() { + return _usbLineInfo.bParityType; +} + +uint8_t Serial_::numbits() { + return _usbLineInfo.bDataBits; +} + +bool Serial_::dtr() { + return _usbLineInfo.lineState & 0x1; +} + +bool Serial_::rts() { + return _usbLineInfo.lineState & 0x2; +} + Serial_ SerialUSB(USBDevice); #endif diff --git a/cores/arduino/USB/USBAPI.h b/cores/arduino/USB/USBAPI.h index f4a0babf8..1de826608 100644 --- a/cores/arduino/USB/USBAPI.h +++ b/cores/arduino/USB/USBAPI.h @@ -126,6 +126,46 @@ class Serial_ : public Stream virtual size_t write(const uint8_t *buffer, size_t size); 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. + uint32_t baud(); + uint8_t stopbits(); + uint8_t paritytype(); + uint8_t numbits(); + bool dtr(); + bool rts(); + enum { + ONE_STOP_BIT = 0, + ONE_AND_HALF_STOP_BIT = 1, + TWO_STOP_BITS = 2, + }; + enum { + NO_PARITY = 0, + ODD_PARITY = 1, + EVEN_PARITY = 2, + MARK_PARITY = 3, + SPACE_PARITY = 4, + }; + private: USBDeviceClass &usb; RingBuffer *_cdc_rx_buffer; diff --git a/cores/arduino/USB/USBCore.h b/cores/arduino/USB/USBCore.h index 853f305ae..096754ebc 100644 --- a/cores/arduino/USB/USBCore.h +++ b/cores/arduino/USB/USBCore.h @@ -68,6 +68,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