]> git.donarmstrong.com Git - qmk_firmware.git/blob - tool/mbed/mbed-sdk/libraries/USBDevice/USBSerial/USBCDC.cpp
Squashed 'tmk_core/' changes from 7967731..b9e0ea0
[qmk_firmware.git] / tool / mbed / mbed-sdk / libraries / USBDevice / USBSerial / USBCDC.cpp
1 /* Copyright (c) 2010-2011 mbed.org, MIT License
2 *
3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
4 * and associated documentation files (the "Software"), to deal in the Software without
5 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
6 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
7 * Software is furnished to do so, subject to the following conditions:
8 *
9 * The above copyright notice and this permission notice shall be included in all copies or
10 * substantial portions of the Software.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
17 */
18
19 #include "stdint.h"
20 #include "USBCDC.h"
21
22 static uint8_t cdc_line_coding[7]= {0x80, 0x25, 0x00, 0x00, 0x00, 0x00, 0x08};
23
24 #define DEFAULT_CONFIGURATION (1)
25
26 #define CDC_SET_LINE_CODING        0x20
27 #define CDC_GET_LINE_CODING        0x21
28 #define CDC_SET_CONTROL_LINE_STATE 0x22
29
30 // Control Line State bits
31 #define CLS_DTR   (1 << 0)
32 #define CLS_RTS   (1 << 1)
33
34 #define MAX_CDC_REPORT_SIZE MAX_PACKET_SIZE_EPBULK
35
36 USBCDC::USBCDC(uint16_t vendor_id, uint16_t product_id, uint16_t product_release, bool connect_blocking): USBDevice(vendor_id, product_id, product_release) {
37     terminal_connected = false;
38     USBDevice::connect(connect_blocking);
39 }
40
41 bool USBCDC::USBCallback_request(void) {
42     /* Called in ISR context */
43
44     bool success = false;
45     CONTROL_TRANSFER * transfer = getTransferPtr();
46
47     /* Process class-specific requests */
48
49     if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
50         switch (transfer->setup.bRequest) {
51             case CDC_GET_LINE_CODING:
52                 transfer->remaining = 7;
53                 transfer->ptr = cdc_line_coding;
54                 transfer->direction = DEVICE_TO_HOST;
55                 success = true;
56                 break;
57             case CDC_SET_LINE_CODING:
58                 transfer->remaining = 7;
59                 transfer->notify = true;
60                 success = true;
61                 break;
62             case CDC_SET_CONTROL_LINE_STATE:
63                 if (transfer->setup.wValue & CLS_DTR) {
64                     terminal_connected = true;
65                 } else {
66                     terminal_connected = false;
67                 }
68                 success = true;
69                 break;
70             default:
71                 break;
72         }
73     }
74
75     return success;
76 }
77
78 void USBCDC::USBCallback_requestCompleted(uint8_t *buf, uint32_t length) {
79     // Request of setting line coding has 7 bytes
80     if (length != 7) {
81         return;
82     }
83
84     CONTROL_TRANSFER * transfer = getTransferPtr();
85
86     /* Process class-specific requests */
87     if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
88         if (transfer->setup.bRequest == CDC_SET_LINE_CODING) {
89             if (memcmp(cdc_line_coding, buf, 7)) {
90                 memcpy(cdc_line_coding, buf, 7);
91
92                 int baud = buf[0] + (buf[1] << 8)
93                          + (buf[2] << 16) + (buf[3] << 24);
94                 int stop = buf[4];
95                 int bits = buf[6];
96                 int parity = buf[5];
97
98                 lineCodingChanged(baud, bits, parity, stop);
99             }
100         }
101     }
102 }
103
104 // Called in ISR context
105 // Set configuration. Return false if the
106 // configuration is not supported.
107 bool USBCDC::USBCallback_setConfiguration(uint8_t configuration) {
108     if (configuration != DEFAULT_CONFIGURATION) {
109         return false;
110     }
111
112     // Configure endpoints > 0
113     addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT);
114     addEndpoint(EPBULK_IN, MAX_PACKET_SIZE_EPBULK);
115     addEndpoint(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
116
117     // We activate the endpoint to be able to recceive data
118     readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
119     return true;
120 }
121
122 bool USBCDC::send(uint8_t * buffer, uint32_t size) {
123     return USBDevice::write(EPBULK_IN, buffer, size, MAX_CDC_REPORT_SIZE);
124 }
125
126 bool USBCDC::readEP(uint8_t * buffer, uint32_t * size) {
127     if (!USBDevice::readEP(EPBULK_OUT, buffer, size, MAX_CDC_REPORT_SIZE))
128         return false;
129     if (!readStart(EPBULK_OUT, MAX_CDC_REPORT_SIZE))
130         return false;
131     return true;
132 }
133
134 bool USBCDC::readEP_NB(uint8_t * buffer, uint32_t * size) {
135     if (!USBDevice::readEP_NB(EPBULK_OUT, buffer, size, MAX_CDC_REPORT_SIZE))
136         return false;
137     if (!readStart(EPBULK_OUT, MAX_CDC_REPORT_SIZE))
138         return false;
139     return true;
140 }
141
142
143 uint8_t * USBCDC::deviceDesc() {
144     static uint8_t deviceDescriptor[] = {
145         18,                   // bLength
146         1,                    // bDescriptorType
147         0x10, 0x01,           // bcdUSB
148         2,                    // bDeviceClass
149         0,                    // bDeviceSubClass
150         0,                    // bDeviceProtocol
151         MAX_PACKET_SIZE_EP0,  // bMaxPacketSize0
152         (uint8_t)(LSB(VENDOR_ID)), (uint8_t)(MSB(VENDOR_ID)),  // idVendor
153         (uint8_t)(LSB(PRODUCT_ID)), (uint8_t)(MSB(PRODUCT_ID)),// idProduct
154         0x00, 0x01,           // bcdDevice
155         1,                    // iManufacturer
156         2,                    // iProduct
157         3,                    // iSerialNumber
158         1                     // bNumConfigurations
159     };
160     return deviceDescriptor;
161 }
162
163 uint8_t * USBCDC::stringIinterfaceDesc() {
164     static uint8_t stringIinterfaceDescriptor[] = {
165         0x08,
166         STRING_DESCRIPTOR,
167         'C',0,'D',0,'C',0,
168     };
169     return stringIinterfaceDescriptor;
170 }
171
172 uint8_t * USBCDC::stringIproductDesc() {
173     static uint8_t stringIproductDescriptor[] = {
174         0x16,
175         STRING_DESCRIPTOR,
176         'C',0,'D',0,'C',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0
177     };
178     return stringIproductDescriptor;
179 }
180
181
182 #define CONFIG1_DESC_SIZE (9+8+9+5+5+4+5+7+9+7+7)
183
184 uint8_t * USBCDC::configurationDesc() {
185     static uint8_t configDescriptor[] = {
186         // configuration descriptor
187         9,                      // bLength
188         2,                      // bDescriptorType
189         LSB(CONFIG1_DESC_SIZE), // wTotalLength
190         MSB(CONFIG1_DESC_SIZE),
191         2,                      // bNumInterfaces
192         1,                      // bConfigurationValue
193         0,                      // iConfiguration
194         0x80,                   // bmAttributes
195         50,                     // bMaxPower
196
197         // IAD to associate the two CDC interfaces
198         0x08,                   // bLength
199         0x0b,                   // bDescriptorType
200         0x00,                   // bFirstInterface
201         0x02,                   // bInterfaceCount
202         0x02,                   // bFunctionClass
203         0x02,                   // bFunctionSubClass
204         0,                      // bFunctionProtocol
205         0,                      // iFunction
206
207         // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
208         9,                      // bLength
209         4,                      // bDescriptorType
210         0,                      // bInterfaceNumber
211         0,                      // bAlternateSetting
212         1,                      // bNumEndpoints
213         0x02,                   // bInterfaceClass
214         0x02,                   // bInterfaceSubClass
215         0x01,                   // bInterfaceProtocol
216         0,                      // iInterface
217
218         // CDC Header Functional Descriptor, CDC Spec 5.2.3.1, Table 26
219         5,                      // bFunctionLength
220         0x24,                   // bDescriptorType
221         0x00,                   // bDescriptorSubtype
222         0x10, 0x01,             // bcdCDC
223
224         // Call Management Functional Descriptor, CDC Spec 5.2.3.2, Table 27
225         5,                      // bFunctionLength
226         0x24,                   // bDescriptorType
227         0x01,                   // bDescriptorSubtype
228         0x03,                   // bmCapabilities
229         1,                      // bDataInterface
230
231         // Abstract Control Management Functional Descriptor, CDC Spec 5.2.3.3, Table 28
232         4,                      // bFunctionLength
233         0x24,                   // bDescriptorType
234         0x02,                   // bDescriptorSubtype
235         0x06,                   // bmCapabilities
236
237         // Union Functional Descriptor, CDC Spec 5.2.3.8, Table 33
238         5,                      // bFunctionLength
239         0x24,                   // bDescriptorType
240         0x06,                   // bDescriptorSubtype
241         0,                      // bMasterInterface
242         1,                      // bSlaveInterface0
243
244         // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
245         ENDPOINT_DESCRIPTOR_LENGTH,     // bLength
246         ENDPOINT_DESCRIPTOR,            // bDescriptorType
247         PHY_TO_DESC(EPINT_IN),          // bEndpointAddress
248         E_INTERRUPT,                    // bmAttributes (0x03=intr)
249         LSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (LSB)
250         MSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (MSB)
251         16,                             // bInterval
252
253
254
255
256         // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
257         9,                          // bLength
258         4,                          // bDescriptorType
259         1,                          // bInterfaceNumber
260         0,                          // bAlternateSetting
261         2,                          // bNumEndpoints
262         0x0A,                       // bInterfaceClass
263         0x00,                       // bInterfaceSubClass
264         0x00,                       // bInterfaceProtocol
265         0,                          // iInterface
266
267         // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
268         ENDPOINT_DESCRIPTOR_LENGTH, // bLength
269         ENDPOINT_DESCRIPTOR,        // bDescriptorType
270         PHY_TO_DESC(EPBULK_IN),     // bEndpointAddress
271         E_BULK,                     // bmAttributes (0x02=bulk)
272         LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB)
273         MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB)
274         0,                          // bInterval
275
276         // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
277         ENDPOINT_DESCRIPTOR_LENGTH, // bLength
278         ENDPOINT_DESCRIPTOR,        // bDescriptorType
279         PHY_TO_DESC(EPBULK_OUT),    // bEndpointAddress
280         E_BULK,                     // bmAttributes (0x02=bulk)
281         LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB)
282         MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB)
283         0                           // bInterval
284     };
285     return configDescriptor;
286 }