Skip to content

Commit 44174a0

Browse files
committed
USB device refactoring (WIP)
1 parent b0e8ff0 commit 44174a0

File tree

14 files changed

+1030
-1253
lines changed

14 files changed

+1030
-1253
lines changed

cores/arduino/USB/CDC.cpp

Lines changed: 70 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright (c) 2014 Arduino. All right reserved.
2+
Copyright (c) 2015 Arduino LLC. All right reserved.
33
44
This library is free software; you can redistribute it and/or
55
modify it under the terms of the GNU Lesser General Public
@@ -16,22 +16,13 @@
1616
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1717
*/
1818

19+
#include <Arduino.h>
20+
#include <Reset.h> // Needed for auto-reset with 1200bps port touch
21+
1922
#include <stdlib.h>
2023
#include <stdio.h>
2124
#include <stdint.h>
2225

23-
// Include Atmel headers
24-
#include "Arduino.h"
25-
#include "sam.h"
26-
#include "wiring_constants.h"
27-
#include "USBCore.h"
28-
#include "USB/USB_device.h"
29-
#include "USBDesc.h"
30-
#include "USBAPI.h"
31-
32-
#include "Reset.h"
33-
34-
3526
#ifdef CDC_ENABLED
3627

3728
#define CDC_SERIAL_BUFFER_SIZE 64
@@ -42,96 +33,93 @@
4233

4334
#define CDC_LINESTATE_READY (CDC_LINESTATE_RTS | CDC_LINESTATE_DTR)
4435

45-
struct ring_buffer
46-
{
36+
struct ring_buffer {
4737
uint8_t buffer[CDC_SERIAL_BUFFER_SIZE];
4838
volatile uint32_t head;
4939
volatile uint32_t tail;
5040
};
51-
5241
ring_buffer cdc_rx_buffer = { { 0 }, 0, 0};
5342

54-
typedef struct
55-
{
56-
uint32_t dwDTERate;
57-
uint8_t bCharFormat;
58-
uint8_t bParityType;
59-
uint8_t bDataBits;
60-
uint8_t lineState;
43+
typedef struct {
44+
uint32_t dwDTERate;
45+
uint8_t bCharFormat;
46+
uint8_t bParityType;
47+
uint8_t bDataBits;
48+
uint8_t lineState;
6149
} LineInfo;
6250

6351
_Pragma("pack(1)")
6452
static volatile LineInfo _usbLineInfo = {
65-
115200, // dWDTERate
66-
0x00, // bCharFormat
67-
0x00, // bParityType
68-
0x08, // bDataBits
69-
0x00 // lineState
53+
115200, // dWDTERate
54+
0x00, // bCharFormat
55+
0x00, // bParityType
56+
0x08, // bDataBits
57+
0x00 // lineState
7058
};
7159

72-
static const CDCDescriptor _cdcInterface =
73-
{
74-
#if (defined CDC_ENABLED) && defined(HID_ENABLED)
60+
static const CDCDescriptor _cdcInterface = {
61+
#if (defined CDC_ENABLED) && defined(HID_ENABLED)
7562
D_IAD(0, 2, CDC_COMMUNICATION_INTERFACE_CLASS, CDC_ABSTRACT_CONTROL_MODEL, 0),
76-
#endif
77-
// CDC communication interface
78-
D_INTERFACE(CDC_ACM_INTERFACE,1,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,0),
79-
D_CDCCS( CDC_HEADER, CDC_V1_10 & 0xFF, (CDC_V1_10>>8) & 0x0FF ), // Header (1.10 bcd)
80-
81-
D_CDCCS4(CDC_ABSTRACT_CONTROL_MANAGEMENT,6), // SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported
82-
D_CDCCS(CDC_UNION,CDC_ACM_INTERFACE,CDC_DATA_INTERFACE), // Communication interface is master, data interface is slave 0
83-
D_CDCCS(CDC_CALL_MANAGEMENT,1,1), // Device handles call management (not)
84-
D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_ACM),USB_ENDPOINT_TYPE_INTERRUPT,0x10, 0x10),
85-
86-
// CDC data interface
87-
D_INTERFACE(CDC_DATA_INTERFACE,2,CDC_DATA_INTERFACE_CLASS,0,0),
88-
D_ENDPOINT(USB_ENDPOINT_OUT(CDC_ENDPOINT_OUT),USB_ENDPOINT_TYPE_BULK,EPX_SIZE,0),
89-
D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ),USB_ENDPOINT_TYPE_BULK,EPX_SIZE,0)
63+
#endif
64+
65+
// CDC communication interface
66+
D_INTERFACE(CDC_ACM_INTERFACE, 1, CDC_COMMUNICATION_INTERFACE_CLASS, CDC_ABSTRACT_CONTROL_MODEL, 0),
67+
D_CDCCS(CDC_HEADER, CDC_V1_10 & 0xFF, (CDC_V1_10>>8) & 0x0FF), // Header (1.10 bcd)
68+
69+
D_CDCCS4(CDC_ABSTRACT_CONTROL_MANAGEMENT, 6), // SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported
70+
D_CDCCS(CDC_UNION, CDC_ACM_INTERFACE, CDC_DATA_INTERFACE), // Communication interface is master, data interface is slave 0
71+
D_CDCCS(CDC_CALL_MANAGEMENT, 1, 1), // Device handles call management (not)
72+
D_ENDPOINT(USB_ENDPOINT_IN(CDC_ENDPOINT_ACM), USB_ENDPOINT_TYPE_INTERRUPT, 0x10, 0x10),
73+
74+
// CDC data interface
75+
D_INTERFACE(CDC_DATA_INTERFACE, 2, CDC_DATA_INTERFACE_CLASS, 0, 0),
76+
D_ENDPOINT(USB_ENDPOINT_OUT(CDC_ENDPOINT_OUT), USB_ENDPOINT_TYPE_BULK, EPX_SIZE, 0),
77+
D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ), USB_ENDPOINT_TYPE_BULK, EPX_SIZE, 0)
9078
};
9179
_Pragma("pack()")
9280

93-
const void* WEAK CDC_GetInterface(void)
81+
const void* CDC_GetInterface(void)
9482
{
95-
return &_cdcInterface;
83+
return &_cdcInterface;
9684
}
9785

98-
uint32_t WEAK CDC_GetInterfaceLength(void)
86+
uint32_t CDC_GetInterfaceLength(void)
9987
{
100-
return sizeof( _cdcInterface );
88+
return sizeof(_cdcInterface);
10189
}
10290

103-
bool WEAK CDC_Setup(Setup& setup)
91+
bool CDC_Setup(Setup& setup)
10492
{
105-
uint8_t r = setup.bRequest;
10693
uint8_t requestType = setup.bmRequestType;
94+
uint8_t r = setup.bRequest;
10795

108-
if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType)
96+
if (requestType == REQUEST_DEVICETOHOST_CLASS_INTERFACE)
10997
{
110-
if (CDC_GET_LINE_CODING == r)
98+
if (r == CDC_GET_LINE_CODING)
11199
{
112-
USBD_SendControl(0,(void*)&_usbLineInfo,7);
100+
USBDevice.sendControl((void*)&_usbLineInfo, 7);
113101
return true;
114102
}
115103
}
116104

117-
if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType)
105+
if (requestType == REQUEST_HOSTTODEVICE_CLASS_INTERFACE)
118106
{
119-
if (CDC_SET_LINE_CODING == r)
107+
if (r == CDC_SET_LINE_CODING)
120108
{
121-
USBD_RecvControl((void*)&_usbLineInfo,7);
109+
USBDevice.recvControl((void*)&_usbLineInfo, 7);
122110
}
123111

124-
if (CDC_SET_CONTROL_LINE_STATE == r)
112+
if (r == CDC_SET_CONTROL_LINE_STATE)
125113
{
126114
_usbLineInfo.lineState = setup.wValueL;
127115
}
128116

129-
if (CDC_SET_LINE_CODING == r || CDC_SET_CONTROL_LINE_STATE == r)
117+
if (r == CDC_SET_LINE_CODING || r == CDC_SET_CONTROL_LINE_STATE)
130118
{
131119
// auto-reset into the bootloader is triggered when the port, already
132120
// open at 1200 bps, is closed. We check DTR state to determine if host
133121
// port is open (bit 0 of lineState).
134-
if (1200 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0)
122+
if (_usbLineInfo.dwDTERate == 1200 && (_usbLineInfo.lineState & 0x01) == 0)
135123
{
136124
initiateReset(250);
137125
}
@@ -161,7 +149,7 @@ void Serial_::end(void)
161149
void Serial_::accept(void)
162150
{
163151
uint8_t buffer[CDC_SERIAL_BUFFER_SIZE];
164-
uint32_t len = USBD_Recv(CDC_ENDPOINT_OUT, (void*)&buffer, CDC_SERIAL_BUFFER_SIZE);
152+
uint32_t len = usb.recv(CDC_ENDPOINT_OUT, &buffer, CDC_SERIAL_BUFFER_SIZE);
165153

166154
noInterrupts();
167155
ring_buffer *ringBuffer = &cdc_rx_buffer;
@@ -173,7 +161,7 @@ void Serial_::accept(void)
173161
// and so we don't write the character or advance the head.
174162
uint32_t k = 0;
175163
i = (i + 1) % CDC_SERIAL_BUFFER_SIZE;
176-
while (i != ringBuffer->tail && len>0) {
164+
while ((i != ringBuffer->tail) && (len > 0)) {
177165
len--;
178166
ringBuffer->buffer[ringBuffer->head] = buffer[k++];
179167
ringBuffer->head = i;
@@ -185,6 +173,9 @@ void Serial_::accept(void)
185173
int Serial_::available(void)
186174
{
187175
ring_buffer *buffer = &cdc_rx_buffer;
176+
if (buffer->head == buffer->tail) {
177+
USB->DEVICE.DeviceEndpoint[2].EPINTENSET.reg = USB_DEVICE_EPINTENCLR_TRCPT(1);
178+
}
188179
return (uint32_t)(CDC_SERIAL_BUFFER_SIZE + buffer->head - buffer->tail) % CDC_SERIAL_BUFFER_SIZE;
189180
}
190181

@@ -202,28 +193,38 @@ int Serial_::peek(void)
202193
}
203194
}
204195

196+
197+
// if the ringBuffer is empty: try to fill it
198+
// if it's still empty: return -1
199+
// else return the last char
200+
// so the buffer is filled only when needed
205201
int Serial_::read(void)
206202
{
207203
ring_buffer *buffer = &cdc_rx_buffer;
208204

209205
// if the head isn't ahead of the tail, we don't have any characters
210206
if (buffer->head == buffer->tail)
207+
{
208+
if (usb.available(CDC_ENDPOINT_OUT))
209+
accept();
210+
}
211+
if (buffer->head == buffer->tail)
211212
{
212213
return -1;
213214
}
214215
else
215216
{
216217
unsigned char c = buffer->buffer[buffer->tail];
217218
buffer->tail = (uint32_t)(buffer->tail + 1) % CDC_SERIAL_BUFFER_SIZE;
218-
if (USBD_Available(CDC_ENDPOINT_OUT))
219-
accept();
219+
// if (usb.available(CDC_ENDPOINT_OUT))
220+
// accept();
220221
return c;
221222
}
222223
}
223224

224225
void Serial_::flush(void)
225226
{
226-
USBD_Flush(CDC_ENDPOINT_IN);
227+
usb.flush(CDC_ENDPOINT_IN);
227228
}
228229

229230
size_t Serial_::write(const uint8_t *buffer, size_t size)
@@ -239,13 +240,11 @@ size_t Serial_::write(const uint8_t *buffer, size_t size)
239240
// or locks up, or host virtual serial port hangs)
240241
// if (_usbLineInfo.lineState > 0) // Problem with Windows(R)
241242
{
242-
uint32_t r = USBD_Send(CDC_ENDPOINT_IN, buffer, size);
243+
uint32_t r = usb.send(CDC_ENDPOINT_IN, buffer, size);
243244

244-
if (r > 0)
245-
{
245+
if (r > 0) {
246246
return r;
247-
} else
248-
{
247+
} else {
249248
setWriteError();
250249
return 0;
251250
}
@@ -282,6 +281,6 @@ Serial_::operator bool()
282281
return result;
283282
}
284283

285-
Serial_ SerialUSB;
284+
Serial_ SerialUSB(USBDevice);
286285

287286
#endif

cores/arduino/USB/HID.cpp

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright (c) 2014 Arduino. All right reserved.
2+
Copyright (c) 2014 Arduino LLC. All right reserved.
33
44
This library is free software; you can redistribute it and/or
55
modify it under the terms of the GNU Lesser General Public
@@ -16,13 +16,7 @@
1616
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1717
*/
1818

19-
#include "USBAPI.h"
20-
#include "Reset.h"
21-
#include "USBCore.h"
22-
#include "USBDesc.h"
23-
#include "sam.h"
24-
#include "USB/USB_device.h"
25-
19+
#include <Arduino.h>
2620

2721
#ifdef HID_ENABLED
2822

@@ -143,14 +137,12 @@ _Pragma("pack()")
143137
uint8_t _hid_protocol = 1;
144138
uint8_t _hid_idle = 1;
145139

146-
#define WEAK __attribute__ ((weak))
147-
148-
const void* WEAK HID_GetInterface(void)
140+
const void* HID_GetInterface(void)
149141
{
150142
return &_hidInterface;
151143
}
152144

153-
uint32_t WEAK HID_GetInterfaceLength(void)
145+
uint32_t HID_GetInterfaceLength(void)
154146
{
155147
return sizeof( _hidInterface );
156148
}
@@ -160,12 +152,12 @@ uint32_t HID_SizeReportDescriptor(void)
160152
return sizeof(_hidReportDescriptor);
161153
}
162154

163-
uint32_t WEAK HID_GetDescriptor(void)
155+
uint32_t HID_GetDescriptor(void)
164156
{
165-
return USBD_SendControl(0,_hidReportDescriptor,sizeof(_hidReportDescriptor));
157+
return USBDevice.sendControl(_hidReportDescriptor, sizeof(_hidReportDescriptor));
166158
}
167159

168-
void WEAK HID_SendReport(uint8_t id, const void* data, uint32_t len)
160+
void HID_SendReport(uint8_t id, const void* data, uint32_t len)
169161
{
170162
uint8_t p[8];
171163
const uint8_t *d = reinterpret_cast<const uint8_t *>(data);
@@ -175,10 +167,10 @@ void WEAK HID_SendReport(uint8_t id, const void* data, uint32_t len)
175167
{
176168
p[i+1] = d[i];
177169
}
178-
USBD_Send(HID_ENDPOINT_INT, p, len+1);
170+
USBDevice.send(HID_ENDPOINT_INT, p, len+1);
179171
}
180172

181-
bool WEAK HID_Setup(Setup& setup)
173+
bool HID_Setup(Setup& setup)
182174
{
183175
uint8_t r = setup.bRequest;
184176
uint8_t requestType = setup.bmRequestType;
@@ -197,8 +189,9 @@ bool WEAK HID_Setup(Setup& setup)
197189
}
198190
if (HID_GET_IDLE == r)
199191
{
200-
UDD_Send(0, &_hid_idle, 1);
201-
UDD_ClearIN();
192+
USBDevice.armSend(0, &_hid_idle, 1);
193+
// RAM buffer is full, we can send data (IN)
194+
USB->DEVICE.DeviceEndpoint[0].EPSTATUSSET.bit.BK1RDY = 1;
202195
return true;
203196
}
204197
}

0 commit comments

Comments
 (0)