Skip to content

Commit 4dfa7e4

Browse files
committed
Merge pull request #1 from arduino/master
pull master
2 parents fc98842 + bda5848 commit 4dfa7e4

23 files changed

+632
-819
lines changed

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

Lines changed: 76 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@
1818

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

2223
#if defined(USBCON)
23-
#ifdef CDC_ENABLED
2424

2525
typedef struct
2626
{
@@ -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

@@ -50,17 +51,17 @@ const CDCDescriptor _cdcInterface =
5051

5152
// CDC data interface
5253
D_INTERFACE(CDC_DATA_INTERFACE,2,CDC_DATA_INTERFACE_CLASS,0,0),
53-
D_ENDPOINT(USB_ENDPOINT_OUT(CDC_ENDPOINT_OUT),USB_ENDPOINT_TYPE_BULK,0x40,0),
54-
D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ),USB_ENDPOINT_TYPE_BULK,0x40,0)
54+
D_ENDPOINT(USB_ENDPOINT_OUT(CDC_ENDPOINT_OUT),USB_ENDPOINT_TYPE_BULK,USB_EP_SIZE,0),
55+
D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ),USB_ENDPOINT_TYPE_BULK,USB_EP_SIZE,0)
5556
};
5657

57-
int WEAK CDC_GetInterface(u8* interfaceNum)
58+
int CDC_GetInterface(u8* interfaceNum)
5859
{
5960
interfaceNum[0] += 2; // uses 2
6061
return USB_SendControl(TRANSFER_PGM,&_cdcInterface,sizeof(_cdcInterface));
6162
}
6263

63-
bool WEAK CDC_Setup(Setup& setup)
64+
bool CDC_Setup(USBSetup& setup)
6465
{
6566
u8 r = setup.bRequest;
6667
u8 requestType = setup.bmRequestType;
@@ -76,6 +77,11 @@ bool WEAK CDC_Setup(Setup& 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);
@@ -93,10 +99,24 @@ bool WEAK CDC_Setup(Setup& setup)
9399
// with a relatively long period so it can finish housekeeping tasks
94100
// like servicing endpoints before the sketch ends
95101

102+
#ifndef MAGIC_KEY
103+
#define MAGIC_KEY 0x7777
104+
#endif
105+
#ifndef MAGIC_KEY_POS
106+
#define MAGIC_KEY_POS 0x0800
107+
#endif
108+
96109
// We check DTR state to determine if host port is open (bit 0 of lineState).
97110
if (1200 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0)
98111
{
99-
*(uint16_t *)0x0800 = 0x7777;
112+
#if MAGIC_KEY_POS != (RAMEND-1)
113+
*(uint16_t *)(RAMEND-1) = *(uint16_t *)MAGIC_KEY_POS;
114+
*(uint16_t *)MAGIC_KEY_POS = MAGIC_KEY;
115+
#else
116+
// for future boards save the key in the inproblematic RAMEND
117+
// which is reserved for the main() return value (which will never return)
118+
*(uint16_t *)MAGIC_KEY_POS = MAGIC_KEY;
119+
#endif
100120
wdt_enable(WDTO_120MS);
101121
}
102122
else
@@ -108,7 +128,11 @@ bool WEAK CDC_Setup(Setup& setup)
108128

109129
wdt_disable();
110130
wdt_reset();
111-
*(uint16_t *)0x0800 = 0x0;
131+
#if MAGIC_KEY_POS != (RAMEND-1)
132+
*(uint16_t *)MAGIC_KEY_POS = *(uint16_t *)(RAMEND-1);
133+
#else
134+
*(uint16_t *)MAGIC_KEY_POS = 0x0000;
135+
#endif
112136
}
113137
}
114138
return true;
@@ -156,6 +180,11 @@ int Serial_::read(void)
156180
return USB_Recv(CDC_RX);
157181
}
158182

183+
int Serial_::availableForWrite(void)
184+
{
185+
return USB_SendSpace(CDC_TX);
186+
}
187+
159188
void Serial_::flush(void)
160189
{
161190
USB_Flush(CDC_TX);
@@ -205,7 +234,46 @@ Serial_::operator bool() {
205234
return result;
206235
}
207236

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

210-
#endif
211279
#endif /* if defined(USBCON) */

0 commit comments

Comments
 (0)