1 /* Copyright (c) 2010-2011 mbed.org, MIT License
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:
9 * The above copyright notice and this permission notice shall be included in all copies or
10 * substantial portions of the Software.
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.
22 static uint8_t cdc_line_coding
[7]= {0x80, 0x25, 0x00, 0x00, 0x00, 0x00, 0x08};
24 #define DEFAULT_CONFIGURATION (1)
26 #define CDC_SET_LINE_CODING 0x20
27 #define CDC_GET_LINE_CODING 0x21
28 #define CDC_SET_CONTROL_LINE_STATE 0x22
30 // Control Line State bits
31 #define CLS_DTR (1 << 0)
32 #define CLS_RTS (1 << 1)
34 #define MAX_CDC_REPORT_SIZE MAX_PACKET_SIZE_EPBULK
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
);
41 bool USBCDC::USBCallback_request(void) {
42 /* Called in ISR context */
45 CONTROL_TRANSFER
* transfer
= getTransferPtr();
47 /* Process class-specific requests */
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
;
57 case CDC_SET_LINE_CODING
:
58 transfer
->remaining
= 7;
59 transfer
->notify
= true;
62 case CDC_SET_CONTROL_LINE_STATE
:
63 if (transfer
->setup
.wValue
& CLS_DTR
) {
64 terminal_connected
= true;
66 terminal_connected
= false;
78 void USBCDC::USBCallback_requestCompleted(uint8_t *buf
, uint32_t length
) {
79 // Request of setting line coding has 7 bytes
84 CONTROL_TRANSFER
* transfer
= getTransferPtr();
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);
92 int baud
= buf
[0] + (buf
[1] << 8)
93 + (buf
[2] << 16) + (buf
[3] << 24);
98 lineCodingChanged(baud
, bits
, parity
, stop
);
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
) {
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
);
117 // We activate the endpoint to be able to recceive data
118 readStart(EPBULK_OUT
, MAX_PACKET_SIZE_EPBULK
);
122 bool USBCDC::send(uint8_t * buffer
, uint32_t size
) {
123 return USBDevice::write(EPBULK_IN
, buffer
, size
, MAX_CDC_REPORT_SIZE
);
126 bool USBCDC::readEP(uint8_t * buffer
, uint32_t * size
) {
127 if (!USBDevice::readEP(EPBULK_OUT
, buffer
, size
, MAX_CDC_REPORT_SIZE
))
129 if (!readStart(EPBULK_OUT
, MAX_CDC_REPORT_SIZE
))
134 bool USBCDC::readEP_NB(uint8_t * buffer
, uint32_t * size
) {
135 if (!USBDevice::readEP_NB(EPBULK_OUT
, buffer
, size
, MAX_CDC_REPORT_SIZE
))
137 if (!readStart(EPBULK_OUT
, MAX_CDC_REPORT_SIZE
))
143 uint8_t * USBCDC::deviceDesc() {
144 static uint8_t deviceDescriptor
[] = {
146 1, // bDescriptorType
147 0x10, 0x01, // bcdUSB
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
158 1 // bNumConfigurations
160 return deviceDescriptor
;
163 uint8_t * USBCDC::stringIinterfaceDesc() {
164 static uint8_t stringIinterfaceDescriptor
[] = {
169 return stringIinterfaceDescriptor
;
172 uint8_t * USBCDC::stringIproductDesc() {
173 static uint8_t stringIproductDescriptor
[] = {
176 'C',0,'D',0,'C',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0
178 return stringIproductDescriptor
;
182 #define CONFIG1_DESC_SIZE (9+8+9+5+5+4+5+7+9+7+7)
184 uint8_t * USBCDC::configurationDesc() {
185 static uint8_t configDescriptor
[] = {
186 // configuration descriptor
188 2, // bDescriptorType
189 LSB(CONFIG1_DESC_SIZE
), // wTotalLength
190 MSB(CONFIG1_DESC_SIZE
),
192 1, // bConfigurationValue
194 0x80, // bmAttributes
197 // IAD to associate the two CDC interfaces
199 0x0b, // bDescriptorType
200 0x00, // bFirstInterface
201 0x02, // bInterfaceCount
202 0x02, // bFunctionClass
203 0x02, // bFunctionSubClass
204 0, // bFunctionProtocol
207 // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
209 4, // bDescriptorType
210 0, // bInterfaceNumber
211 0, // bAlternateSetting
213 0x02, // bInterfaceClass
214 0x02, // bInterfaceSubClass
215 0x01, // bInterfaceProtocol
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
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
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
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
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)
256 // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
258 4, // bDescriptorType
259 1, // bInterfaceNumber
260 0, // bAlternateSetting
262 0x0A, // bInterfaceClass
263 0x00, // bInterfaceSubClass
264 0x00, // bInterfaceProtocol
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)
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)
285 return configDescriptor
;