]> git.gir.st - tmk_keyboard.git/blob - tmk_core/tool/mbed/mbed-sdk/libraries/USBDevice/USBSerial/USBCDC.cpp
Merge commit '1fe4406f374291ab2e86e95a97341fd9c475fcb8'
[tmk_keyboard.git] / tmk_core / 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 }
Imprint / Impressum