1
1
/*
2
- Copyright (c) 2014 Arduino. All right reserved.
2
+ Copyright (c) 2015 Arduino LLC . All right reserved.
3
3
4
4
This library is free software; you can redistribute it and/or
5
5
modify it under the terms of the GNU Lesser General Public
16
16
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
17
*/
18
18
19
+ #include < Arduino.h>
20
+ #include < Reset.h> // Needed for auto-reset with 1200bps port touch
21
+
19
22
#include < stdlib.h>
20
23
#include < stdio.h>
21
24
#include < stdint.h>
22
25
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
-
35
26
#ifdef CDC_ENABLED
36
27
37
28
#define CDC_SERIAL_BUFFER_SIZE 64
42
33
43
34
#define CDC_LINESTATE_READY (CDC_LINESTATE_RTS | CDC_LINESTATE_DTR)
44
35
45
- struct ring_buffer
46
- {
36
+ struct ring_buffer {
47
37
uint8_t buffer[CDC_SERIAL_BUFFER_SIZE];
48
38
volatile uint32_t head;
49
39
volatile uint32_t tail;
50
40
};
51
-
52
41
ring_buffer cdc_rx_buffer = { { 0 }, 0 , 0 };
53
42
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;
61
49
} LineInfo;
62
50
63
51
_Pragma (" pack(1)" )
64
52
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
70
58
};
71
59
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)
75
62
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 )
90
78
};
91
79
_Pragma (" pack()" )
92
80
93
- const void * WEAK CDC_GetInterface (void )
81
+ const void * CDC_GetInterface (void )
94
82
{
95
- return &_cdcInterface;
83
+ return &_cdcInterface;
96
84
}
97
85
98
- uint32_t WEAK CDC_GetInterfaceLength (void )
86
+ uint32_t CDC_GetInterfaceLength (void )
99
87
{
100
- return sizeof ( _cdcInterface );
88
+ return sizeof (_cdcInterface);
101
89
}
102
90
103
- bool WEAK CDC_Setup (Setup& setup)
91
+ bool CDC_Setup (Setup& setup)
104
92
{
105
- uint8_t r = setup.bRequest ;
106
93
uint8_t requestType = setup.bmRequestType ;
94
+ uint8_t r = setup.bRequest ;
107
95
108
- if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType )
96
+ if (requestType == REQUEST_DEVICETOHOST_CLASS_INTERFACE )
109
97
{
110
- if (CDC_GET_LINE_CODING == r )
98
+ if (r == CDC_GET_LINE_CODING )
111
99
{
112
- USBD_SendControl ( 0 , (void *)&_usbLineInfo,7 );
100
+ USBDevice. sendControl ( (void *)&_usbLineInfo, 7 );
113
101
return true ;
114
102
}
115
103
}
116
104
117
- if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType )
105
+ if (requestType == REQUEST_HOSTTODEVICE_CLASS_INTERFACE )
118
106
{
119
- if (CDC_SET_LINE_CODING == r )
107
+ if (r == CDC_SET_LINE_CODING )
120
108
{
121
- USBD_RecvControl ((void *)&_usbLineInfo,7 );
109
+ USBDevice. recvControl ((void *)&_usbLineInfo, 7 );
122
110
}
123
111
124
- if (CDC_SET_CONTROL_LINE_STATE == r )
112
+ if (r == CDC_SET_CONTROL_LINE_STATE )
125
113
{
126
114
_usbLineInfo.lineState = setup.wValueL ;
127
115
}
128
116
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 )
130
118
{
131
119
// auto-reset into the bootloader is triggered when the port, already
132
120
// open at 1200 bps, is closed. We check DTR state to determine if host
133
121
// 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 )
135
123
{
136
124
initiateReset (250 );
137
125
}
@@ -161,7 +149,7 @@ void Serial_::end(void)
161
149
void Serial_::accept (void )
162
150
{
163
151
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);
165
153
166
154
noInterrupts ();
167
155
ring_buffer *ringBuffer = &cdc_rx_buffer;
@@ -173,7 +161,7 @@ void Serial_::accept(void)
173
161
// and so we don't write the character or advance the head.
174
162
uint32_t k = 0 ;
175
163
i = (i + 1 ) % CDC_SERIAL_BUFFER_SIZE;
176
- while (i != ringBuffer->tail && len> 0 ) {
164
+ while (( i != ringBuffer->tail ) && ( len > 0 ) ) {
177
165
len--;
178
166
ringBuffer->buffer [ringBuffer->head ] = buffer[k++];
179
167
ringBuffer->head = i;
@@ -185,6 +173,9 @@ void Serial_::accept(void)
185
173
int Serial_::available (void )
186
174
{
187
175
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
+ }
188
179
return (uint32_t )(CDC_SERIAL_BUFFER_SIZE + buffer->head - buffer->tail ) % CDC_SERIAL_BUFFER_SIZE;
189
180
}
190
181
@@ -202,28 +193,38 @@ int Serial_::peek(void)
202
193
}
203
194
}
204
195
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
205
201
int Serial_::read (void )
206
202
{
207
203
ring_buffer *buffer = &cdc_rx_buffer;
208
204
209
205
// if the head isn't ahead of the tail, we don't have any characters
210
206
if (buffer->head == buffer->tail )
207
+ {
208
+ if (usb.available (CDC_ENDPOINT_OUT))
209
+ accept ();
210
+ }
211
+ if (buffer->head == buffer->tail )
211
212
{
212
213
return -1 ;
213
214
}
214
215
else
215
216
{
216
217
unsigned char c = buffer->buffer [buffer->tail ];
217
218
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();
220
221
return c;
221
222
}
222
223
}
223
224
224
225
void Serial_::flush (void )
225
226
{
226
- USBD_Flush (CDC_ENDPOINT_IN);
227
+ usb. flush (CDC_ENDPOINT_IN);
227
228
}
228
229
229
230
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)
239
240
// or locks up, or host virtual serial port hangs)
240
241
// if (_usbLineInfo.lineState > 0) // Problem with Windows(R)
241
242
{
242
- uint32_t r = USBD_Send (CDC_ENDPOINT_IN, buffer, size);
243
+ uint32_t r = usb. send (CDC_ENDPOINT_IN, buffer, size);
243
244
244
- if (r > 0 )
245
- {
245
+ if (r > 0 ) {
246
246
return r;
247
- } else
248
- {
247
+ } else {
249
248
setWriteError ();
250
249
return 0 ;
251
250
}
@@ -282,6 +281,6 @@ Serial_::operator bool()
282
281
return result;
283
282
}
284
283
285
- Serial_ SerialUSB;
284
+ Serial_ SerialUSB (USBDevice) ;
286
285
287
286
#endif
0 commit comments