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
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
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-
5241ring_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)" )
6452static 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)
161149void 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)
185173int 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
205201int 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
224225void Serial_::flush (void )
225226{
226- USBD_Flush (CDC_ENDPOINT_IN);
227+ usb. flush (CDC_ENDPOINT_IN);
227228}
228229
229230size_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
0 commit comments