Skip to content

Commit 5873b03

Browse files
committed
USB device stack HID CDC validated
1 parent 6693685 commit 5873b03

17 files changed

+2075
-2582
lines changed

Diff for: cores/arduino/Arduino.h

-5
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,6 @@ void loop( void ) ;
8181
#include "WInterrupts.h"
8282

8383
// USB Device
84-
#define USB_VID 0x2341 // arduino LLC vid
85-
#define USB_PID_LEONARDO 0x0034
86-
#define USB_PID_MICRO 0x0035
87-
#define USB_PID_DUE 0x003E
88-
#define USB_PID_ZERO 0x004D
8984
#include "USB/USBDesc.h"
9085
#include "USB/USBCore.h"
9186
#include "USB/USBAPI.h"

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

+30-62
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,20 @@
1919
#include <stdint.h>
2020

2121
// Include Atmel headers
22+
#include "arduino.h"
2223
#include "sam.h"
2324
#include "wiring_constants.h"
2425
#include "USBCore.h"
2526
#include "USB_device.h"
2627
#include "USBDesc.h"
2728
#include "USBAPI.h"
28-
//#include "samd21_device.h"
2929

3030
#include "Reset.h"
3131

3232

3333
#ifdef CDC_ENABLED
3434

35-
#define CDC_SERIAL_BUFFER_SIZE 512
35+
#define CDC_SERIAL_BUFFER_SIZE 64
3636

3737
/* For information purpose only since RTS is not always handled by the terminal application */
3838
#define CDC_LINESTATE_DTR 0x01 // Data Terminal Ready
@@ -58,61 +58,44 @@ typedef struct
5858
uint8_t lineState;
5959
} LineInfo;
6060

61+
_Pragma("pack(1)")
6162
static volatile LineInfo _usbLineInfo = {
62-
57600, // dWDTERate
63+
115200, // dWDTERate
6364
0x00, // bCharFormat
6465
0x00, // bParityType
6566
0x08, // bDataBits
6667
0x00 // lineState
6768
};
6869

69-
_Pragma("pack(1)")
7070
static const CDCDescriptor _cdcInterface =
7171
{
72-
D_IAD(0,2,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,1),
73-
72+
#if (defined CDC_ENABLED) && defined(HID_ENABLED)
73+
D_IAD(0, 2, CDC_COMMUNICATION_INTERFACE_CLASS, CDC_ABSTRACT_CONTROL_MODEL, 0),
74+
#endif
7475
// CDC communication interface
7576
D_INTERFACE(CDC_ACM_INTERFACE,1,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,0),
76-
D_CDCCS(CDC_HEADER,0x10,0x01), // Header (1.10 bcd)
77-
D_CDCCS(CDC_CALL_MANAGEMENT,1,1), // Device handles call management (not)
77+
D_CDCCS( CDC_HEADER, CDC_V1_10 & 0xFF, (CDC_V1_10>>8) & 0x0FF ), // Header (1.10 bcd)
78+
7879
D_CDCCS4(CDC_ABSTRACT_CONTROL_MANAGEMENT,6), // SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported
7980
D_CDCCS(CDC_UNION,CDC_ACM_INTERFACE,CDC_DATA_INTERFACE), // Communication interface is master, data interface is slave 0
80-
D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_ACM),USB_ENDPOINT_TYPE_INTERRUPT,0x10, 0x10),
81-
82-
// CDC data interface
83-
D_INTERFACE(CDC_DATA_INTERFACE,2,CDC_DATA_INTERFACE_CLASS,0,0),
84-
D_ENDPOINT(USB_ENDPOINT_OUT(CDC_ENDPOINT_OUT),USB_ENDPOINT_TYPE_BULK,512,0),
85-
D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ),USB_ENDPOINT_TYPE_BULK,512,0)
86-
};
87-
static const CDCDescriptor _cdcOtherInterface =
88-
{
89-
D_IAD(0,2,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,1),
90-
91-
// CDC communication interface
92-
D_INTERFACE(CDC_ACM_INTERFACE,1,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,0),
93-
D_CDCCS(CDC_HEADER,0x10,0x01), // Header (1.10 bcd)
9481
D_CDCCS(CDC_CALL_MANAGEMENT,1,1), // Device handles call management (not)
95-
D_CDCCS4(CDC_ABSTRACT_CONTROL_MANAGEMENT,6), // SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported
96-
D_CDCCS(CDC_UNION,CDC_ACM_INTERFACE,CDC_DATA_INTERFACE), // Communication interface is master, data interface is slave 0
9782
D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_ACM),USB_ENDPOINT_TYPE_INTERRUPT,0x10, 0x10),
9883

9984
// CDC data interface
10085
D_INTERFACE(CDC_DATA_INTERFACE,2,CDC_DATA_INTERFACE_CLASS,0,0),
101-
D_ENDPOINT(USB_ENDPOINT_OUT(CDC_ENDPOINT_OUT),USB_ENDPOINT_TYPE_BULK,64,0),
102-
D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ),USB_ENDPOINT_TYPE_BULK,64,0)
86+
D_ENDPOINT(USB_ENDPOINT_OUT(CDC_ENDPOINT_OUT),USB_ENDPOINT_TYPE_BULK,EPX_SIZE,0),
87+
D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ),USB_ENDPOINT_TYPE_BULK,EPX_SIZE,0)
10388
};
10489
_Pragma("pack()")
10590

106-
int WEAK CDC_GetInterface(uint8_t* interfaceNum)
91+
const void* WEAK CDC_GetInterface(void)
10792
{
108-
interfaceNum[0] += 2; // uses 2
109-
return USBD_SendControl(0,&_cdcInterface,sizeof(_cdcInterface));
93+
return &_cdcInterface;
11094
}
11195

112-
int WEAK CDC_GetOtherInterface(uint8_t* interfaceNum)
96+
uint32_t WEAK CDC_GetInterfaceLength(void)
11397
{
114-
interfaceNum[0] += 2; // uses 2
115-
return USBD_SendControl(0,&_cdcOtherInterface,sizeof(_cdcOtherInterface));
98+
return sizeof( _cdcInterface );
11699
}
117100

118101
bool WEAK CDC_Setup(Setup& setup)
@@ -134,7 +117,7 @@ bool WEAK CDC_Setup(Setup& setup)
134117
if (CDC_SET_LINE_CODING == r)
135118
{
136119
USBD_RecvControl((void*)&_usbLineInfo,7);
137-
return true;
120+
return false;
138121
}
139122

140123
if (CDC_SET_CONTROL_LINE_STATE == r)
@@ -150,13 +133,13 @@ bool WEAK CDC_Setup(Setup& setup)
150133
else
151134
cancelReset();
152135
}
153-
return true;
136+
return false;
154137
}
155138
}
156139
return false;
157140
}
158141

159-
int _serialPeek = -1;
142+
uint32_t _serialPeek = -1;
160143
void Serial_::begin(uint32_t baud_count)
161144
{
162145
}
@@ -171,16 +154,6 @@ void Serial_::end(void)
171154

172155
void Serial_::accept(void)
173156
{
174-
// static uint32_t guard = 0;
175-
176-
// synchronized access to guard
177-
//JCB do {
178-
// if (__LDREXW(&guard) != 0) {
179-
// __CLREX();
180-
// return; // busy
181-
// }
182-
// } while (__STREXW(1, &guard) != 0); // retry until write succeed
183-
184157
ring_buffer *buffer = &cdc_rx_buffer;
185158
uint32_t i = (uint32_t)(buffer->head+1) % CDC_SERIAL_BUFFER_SIZE;
186159

@@ -190,27 +163,22 @@ void Serial_::accept(void)
190163
// and so we don't write the character or advance the head.
191164
while (i != buffer->tail) {
192165
uint32_t c;
193-
if (!USBD_Available(CDC_RX)) {
194-
UDD_ReleaseRX(CDC_RX);
195-
//JCB udd_ack_fifocon(CDC_RX);
166+
if (!USBD_Available(CDC_ENDPOINT_OUT)) {
167+
UDD_ReleaseRX(CDC_ENDPOINT_OUT);
196168
break;
197169
}
198-
c = USBD_Recv(CDC_RX);
199-
// c = UDD_Recv8(CDC_RX & 0xF);
170+
c = USBD_Recv(CDC_ENDPOINT_OUT);
200171
buffer->buffer[buffer->head] = c;
201172
buffer->head = i;
202173

203174
i = (i + 1) % CDC_SERIAL_BUFFER_SIZE;
204175
}
205-
206-
// release the guard
207-
// guard = 0;
208176
}
209177

210178
int Serial_::available(void)
211179
{
212180
ring_buffer *buffer = &cdc_rx_buffer;
213-
return (unsigned int)(CDC_SERIAL_BUFFER_SIZE + buffer->head - buffer->tail) % CDC_SERIAL_BUFFER_SIZE;
181+
return (uint32_t)(CDC_SERIAL_BUFFER_SIZE + buffer->head - buffer->tail) % CDC_SERIAL_BUFFER_SIZE;
214182
}
215183

216184
int Serial_::peek(void)
@@ -239,16 +207,16 @@ int Serial_::read(void)
239207
else
240208
{
241209
unsigned char c = buffer->buffer[buffer->tail];
242-
buffer->tail = (unsigned int)(buffer->tail + 1) % CDC_SERIAL_BUFFER_SIZE;
243-
if (USBD_Available(CDC_RX))
210+
buffer->tail = (uint32_t)(buffer->tail + 1) % CDC_SERIAL_BUFFER_SIZE;
211+
if (USBD_Available(CDC_ENDPOINT_OUT))
244212
accept();
245213
return c;
246214
}
247215
}
248216

249217
void Serial_::flush(void)
250218
{
251-
USBD_Flush(CDC_TX);
219+
USBD_Flush(CDC_ENDPOINT_IN);
252220
}
253221

254222
size_t Serial_::write(const uint8_t *buffer, size_t size)
@@ -262,9 +230,9 @@ size_t Serial_::write(const uint8_t *buffer, size_t size)
262230
// TODO - ZE - check behavior on different OSes and test what happens if an
263231
// open connection isn't broken cleanly (cable is yanked out, host dies
264232
// or locks up, or host virtual serial port hangs)
265-
if (_usbLineInfo.lineState > 0)
233+
// if (_usbLineInfo.lineState > 0) // Problem with Windows(R)
266234
{
267-
int r = USBD_Send(CDC_TX, buffer, size);
235+
uint32_t r = USBD_Send(CDC_ENDPOINT_IN, buffer, size);
268236

269237
if (r > 0)
270238
{
@@ -293,8 +261,8 @@ size_t Serial_::write(uint8_t c) {
293261
Serial_::operator bool()
294262
{
295263
// this is here to avoid spurious opening after upload
296-
// if (millis() < 500)
297-
// return false;
264+
if (millis() < 500)
265+
return false;
298266

299267
bool result = false;
300268

@@ -303,7 +271,7 @@ Serial_::operator bool()
303271
result = true;
304272
}
305273

306-
// delay(10);
274+
delay(10);
307275
return result;
308276
}
309277

Diff for: cores/arduino/USB/HID.cpp

+30-21
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
** SOFTWARE.
1515
*/
1616

17-
#ifdef HID_ENABLED
1817

1918
#include "USBAPI.h"
2019
#include "Reset.h"
@@ -23,21 +22,18 @@
2322
#include "sam.h"
2423
#include "USB_device.h"
2524

26-
//#define RAWHID_ENABLED
27-
#ifdef __cplusplus
28-
extern "C"{
29-
#endif // __cplusplus
3025

31-
// Singletons for mouse and keyboard
26+
#ifdef HID_ENABLED
27+
28+
//#define RAWHID_ENABLED
3229

30+
// Singletons for mouse and keyboard
3331
Mouse_ Mouse;
3432
Keyboard_ Keyboard;
3533

3634
//================================================================================
3735
//================================================================================
3836

39-
// HID report descriptor
40-
4137
#define LSB(_x) ((_x) & 0xFF)
4238
#define MSB(_x) ((_x) >> 8)
4339

@@ -46,6 +42,8 @@ Keyboard_ Keyboard;
4642
#define RAWHID_TX_SIZE 64
4743
#define RAWHID_RX_SIZE 64
4844

45+
// HID report descriptor
46+
_Pragma("pack(1)")
4947
extern const uint8_t _hidReportDescriptor[] = {
5048
// Mouse
5149
0x05, 0x01, // USAGE_PAGE (Generic Desktop) // 54
@@ -129,7 +127,6 @@ extern const uint8_t _hidReportDescriptor[] = {
129127
#endif
130128
};
131129

132-
_Pragma("pack(1)")
133130
extern const HIDDescriptor _hidInterface =
134131
{
135132
D_INTERFACE(HID_INTERFACE,1,3,0,0),
@@ -147,26 +144,37 @@ uint8_t _hid_idle = 1;
147144

148145
#define WEAK __attribute__ ((weak))
149146

150-
int WEAK HID_GetInterface(uint8_t* interfaceNum)
147+
const void* WEAK HID_GetInterface(void)
148+
{
149+
return &_hidInterface;
150+
}
151+
152+
uint32_t WEAK HID_GetInterfaceLength(void)
153+
{
154+
return sizeof( _hidInterface );
155+
}
156+
157+
uint32_t HID_SizeReportDescriptor(void)
151158
{
152-
interfaceNum[0] += 1; // uses 1
153-
return USBD_SendControl(0,&_hidInterface,sizeof(_hidInterface));
159+
return sizeof(_hidReportDescriptor);
154160
}
155161

156-
int WEAK HID_GetDescriptor(int i)
162+
uint32_t WEAK HID_GetDescriptor(void)
157163
{
158164
return USBD_SendControl(0,_hidReportDescriptor,sizeof(_hidReportDescriptor));
159165
}
160166

161167
void WEAK HID_SendReport(uint8_t id, const void* data, uint32_t len)
162168
{
163-
uint8_t p[64];
169+
uint8_t p[8];
164170
const uint8_t *d = reinterpret_cast<const uint8_t *>(data);
165171

166172
p[0] = id;
167173
for (uint32_t i=0; i<len; i++)
174+
{
168175
p[i+1] = d[i];
169-
USBD_Send(HID_TX, p, len+1);
176+
}
177+
USBD_Send(HID_ENDPOINT_INT, p, len+1);
170178
}
171179

172180
bool WEAK HID_Setup(Setup& setup)
@@ -186,6 +194,12 @@ bool WEAK HID_Setup(Setup& setup)
186194
//Send8(_hid_protocol); // TODO
187195
return true;
188196
}
197+
if (HID_GET_IDLE == r)
198+
{
199+
UDD_Send(0, &_hid_idle, 1);
200+
UDD_ClearIN();
201+
return true;
202+
}
189203
}
190204

191205
if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType)
@@ -198,15 +212,12 @@ bool WEAK HID_Setup(Setup& setup)
198212

199213
if (HID_SET_IDLE == r)
200214
{
201-
_hid_idle = setup.wValueL;
215+
_hid_idle = setup.wValueH;
202216
return true;
203217
}
204218
}
205219
return false;
206220
}
207-
#ifdef __cplusplus
208-
}
209-
#endif
210221

211222
//================================================================================
212223
//================================================================================
@@ -423,8 +434,6 @@ extern const uint8_t _asciimap[128] =
423434
0 // DEL
424435
};
425436

426-
uint8_t USBPutChar(uint8_t c);
427-
428437
// press() adds the specified key (printing, non-printing, or modifier)
429438
// to the persistent key report and sends the report. Because of the way
430439
// USB HID works, the host acts like the key remains pressed until we

0 commit comments

Comments
 (0)