Skip to content

Commit 96f7b96

Browse files
Expose serial settings from CDC virtual serial port
This allows a sketch to find out the settings chosen by the USB host (computer) and act accordingly. Other than reading the DTR flag and checking if the baudrate is 1200, the regular CDC code doesn't actually use any of these settings. By exposing these settings to the sketch, it can for example copy them to the hardware UART, turning the Leonardo into a proper USB-to-serial device. This can be useful to let the computer directly talk to whatever device is connected to the hardware serial port (like an XBee module). The Teensy core already supported these methods. This code was independently developed, but the method names were chosen to match the Teensy code, for compatibility (except that `dtr()` and `rtr()` return `bool`, while the Teensy version return a `uint8_t`). This change is applied to both the avr and sam cores, which have a very similar CDC implementation.
1 parent 2659ec6 commit 96f7b96

File tree

4 files changed

+96
-0
lines changed

4 files changed

+96
-0
lines changed

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

+27
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

@@ -205,6 +206,32 @@ Serial_::operator bool() {
205206
return result;
206207
}
207208

209+
unsigned long Serial_::baud() {
210+
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
211+
return _usbLineInfo.dwDTERate;
212+
}
213+
}
214+
215+
uint8_t Serial_::stopbits() {
216+
return _usbLineInfo.bCharFormat;
217+
}
218+
219+
uint8_t Serial_::paritytype() {
220+
return _usbLineInfo.bParityType;
221+
}
222+
223+
uint8_t Serial_::numbits() {
224+
return _usbLineInfo.bDataBits;
225+
}
226+
227+
bool Serial_::dtr() {
228+
return _usbLineInfo.lineState & 0x1;
229+
}
230+
231+
bool Serial_::rts() {
232+
return _usbLineInfo.lineState & 0x2;
233+
}
234+
208235
Serial_ Serial;
209236

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

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

+23
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,29 @@ class Serial_ : public Stream
101101
volatile uint8_t _rx_buffer_head;
102102
volatile uint8_t _rx_buffer_tail;
103103
unsigned char _rx_buffer[SERIAL_BUFFER_SIZE];
104+
105+
// These return the settings specified by the USB host for the
106+
// serial port. These aren't really used, but are offered here
107+
// in case a sketch wants to act on these settings.
108+
uint32_t baud();
109+
uint8_t stopbits();
110+
uint8_t paritytype();
111+
uint8_t numbits();
112+
bool dtr();
113+
bool rts();
114+
enum {
115+
ONE_STOP_BIT = 0,
116+
ONE_AND_HALF_STOP_BIT = 1,
117+
TWO_STOP_BITS = 2,
118+
};
119+
enum {
120+
NO_PARITY = 0,
121+
ODD_PARITY = 1,
122+
EVEN_PARITY = 2,
123+
MARK_PARITY = 3,
124+
SPACE_PARITY = 4,
125+
};
126+
104127
};
105128
extern Serial_ Serial;
106129

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

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)