Skip to content

Commit 695fc40

Browse files
committed
2 parents e45f07d + 4f87112 commit 695fc40

File tree

6 files changed

+140
-2
lines changed

6 files changed

+140
-2
lines changed

Diff for: hardware/arduino/avr/cores/arduino/CDC.cpp

+50
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#include "USBAPI.h"
2020
#include <avr/wdt.h>
21+
#include <util/atomic.h>
2122

2223
#if defined(USBCON)
2324

@@ -31,6 +32,7 @@ typedef struct
3132
} LineInfo;
3233

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

3537
#define WEAK __attribute__ ((weak))
3638

@@ -75,6 +77,11 @@ bool CDC_Setup(USBSetup& setup)
7577

7678
if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType)
7779
{
80+
if (CDC_SEND_BREAK == r)
81+
{
82+
breakValue = ((uint16_t)setup.wValueH << 8) | setup.wValueL;
83+
}
84+
7885
if (CDC_SET_LINE_CODING == r)
7986
{
8087
USB_RecvControl((void*)&_usbLineInfo,7);
@@ -173,6 +180,11 @@ int Serial_::read(void)
173180
return USB_Recv(CDC_RX);
174181
}
175182

183+
int Serial_::availableForWrite(void)
184+
{
185+
return USB_SendSpace(CDC_TX);
186+
}
187+
176188
void Serial_::flush(void)
177189
{
178190
USB_Flush(CDC_TX);
@@ -222,6 +234,44 @@ Serial_::operator bool() {
222234
return result;
223235
}
224236

237+
unsigned long Serial_::baud() {
238+
// Disable interrupts while reading a multi-byte value
239+
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
240+
return _usbLineInfo.dwDTERate;
241+
}
242+
}
243+
244+
uint8_t Serial_::stopbits() {
245+
return _usbLineInfo.bCharFormat;
246+
}
247+
248+
uint8_t Serial_::paritytype() {
249+
return _usbLineInfo.bParityType;
250+
}
251+
252+
uint8_t Serial_::numbits() {
253+
return _usbLineInfo.bDataBits;
254+
}
255+
256+
bool Serial_::dtr() {
257+
return _usbLineInfo.lineState & 0x1;
258+
}
259+
260+
bool Serial_::rts() {
261+
return _usbLineInfo.lineState & 0x2;
262+
}
263+
264+
int32_t Serial_::readBreak() {
265+
int32_t ret;
266+
// Disable IRQs while reading and clearing breakValue to make
267+
// sure we don't overwrite a value just set by the ISR.
268+
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
269+
ret = breakValue;
270+
breakValue = -1;
271+
}
272+
return ret;
273+
}
274+
225275
Serial_ Serial;
226276

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

Diff for: hardware/arduino/avr/cores/arduino/HardwareSerial.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,7 @@ void HardwareSerial::begin(unsigned long baud, byte config)
138138
void HardwareSerial::end()
139139
{
140140
// wait for transmission of outgoing data
141-
while (_tx_buffer_head != _tx_buffer_tail)
142-
;
141+
flush();
143142

144143
cbi(*_ucsrb, RXEN0);
145144
cbi(*_ucsrb, TXEN0);

Diff for: hardware/arduino/avr/cores/arduino/USBAPI.h

+42
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ class Serial_ : public Stream
9898
virtual int available(void);
9999
virtual int peek(void);
100100
virtual int read(void);
101+
int availableForWrite(void);
101102
virtual void flush(void);
102103
virtual size_t write(uint8_t);
103104
virtual size_t write(const uint8_t*, size_t);
@@ -107,6 +108,46 @@ class Serial_ : public Stream
107108
volatile uint8_t _rx_buffer_head;
108109
volatile uint8_t _rx_buffer_tail;
109110
unsigned char _rx_buffer[SERIAL_BUFFER_SIZE];
111+
112+
// This method allows processing "SEND_BREAK" requests sent by
113+
// the USB host. Those requests indicate that the host wants to
114+
// send a BREAK signal and are accompanied by a single uint16_t
115+
// value, specifying the duration of the break. The value 0
116+
// means to end any current break, while the value 0xffff means
117+
// to start an indefinite break.
118+
// readBreak() will return the value of the most recent break
119+
// request, but will return it at most once, returning -1 when
120+
// readBreak() is called again (until another break request is
121+
// received, which is again returned once).
122+
// This also mean that if two break requests are received
123+
// without readBreak() being called in between, the value of the
124+
// first request is lost.
125+
// Note that the value returned is a long, so it can return
126+
// 0-0xffff as well as -1.
127+
int32_t readBreak();
128+
129+
// These return the settings specified by the USB host for the
130+
// serial port. These aren't really used, but are offered here
131+
// in case a sketch wants to act on these settings.
132+
uint32_t baud();
133+
uint8_t stopbits();
134+
uint8_t paritytype();
135+
uint8_t numbits();
136+
bool dtr();
137+
bool rts();
138+
enum {
139+
ONE_STOP_BIT = 0,
140+
ONE_AND_HALF_STOP_BIT = 1,
141+
TWO_STOP_BITS = 2,
142+
};
143+
enum {
144+
NO_PARITY = 0,
145+
ODD_PARITY = 1,
146+
EVEN_PARITY = 2,
147+
MARK_PARITY = 3,
148+
SPACE_PARITY = 4,
149+
};
150+
110151
};
111152
extern Serial_ Serial;
112153

@@ -154,6 +195,7 @@ int USB_SendControl(uint8_t flags, const void* d, int len);
154195
int USB_RecvControl(void* d, int len);
155196

156197
uint8_t USB_Available(uint8_t ep);
198+
uint8_t USB_SendSpace(uint8_t ep);
157199
int USB_Send(uint8_t ep, const void* data, int len); // blocking
158200
int USB_Recv(uint8_t ep, void* data, int len); // non-blocking
159201
int USB_Recv(uint8_t ep); // non-blocking

Diff for: 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

Diff for: hardware/arduino/sam/cores/arduino/USB/CDC.cpp

+24
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,30 @@ Serial_::operator bool()
299299
return result;
300300
}
301301

302+
unsigned long Serial_::baud() {
303+
return _usbLineInfo.dwDTERate;
304+
}
305+
306+
uint8_t Serial_::stopbits() {
307+
return _usbLineInfo.bCharFormat;
308+
}
309+
310+
uint8_t Serial_::paritytype() {
311+
return _usbLineInfo.bParityType;
312+
}
313+
314+
uint8_t Serial_::numbits() {
315+
return _usbLineInfo.bDataBits;
316+
}
317+
318+
bool Serial_::dtr() {
319+
return _usbLineInfo.lineState & 0x1;
320+
}
321+
322+
bool Serial_::rts() {
323+
return _usbLineInfo.lineState & 0x2;
324+
}
325+
302326
Serial_ SerialUSB;
303327

304328
#endif

Diff for: hardware/arduino/sam/cores/arduino/USB/USBAPI.h

+22
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,28 @@ class Serial_ : public Stream
6161
virtual size_t write(const uint8_t *buffer, size_t size);
6262
using Print::write; // pull in write(str) from Print
6363
operator bool();
64+
65+
// These return the settings specified by the USB host for the
66+
// serial port. These aren't really used, but are offered here
67+
// in case a sketch wants to act on these settings.
68+
uint32_t baud();
69+
uint8_t stopbits();
70+
uint8_t paritytype();
71+
uint8_t numbits();
72+
bool dtr();
73+
bool rts();
74+
enum {
75+
ONE_STOP_BIT = 0,
76+
ONE_AND_HALF_STOP_BIT = 1,
77+
TWO_STOP_BITS = 2,
78+
};
79+
enum {
80+
NO_PARITY = 0,
81+
ODD_PARITY = 1,
82+
EVEN_PARITY = 2,
83+
MARK_PARITY = 3,
84+
SPACE_PARITY = 4,
85+
};
6486
};
6587
extern Serial_ SerialUSB;
6688

0 commit comments

Comments
 (0)