USB device stack, fixes for USBSerial & KL25Z

Fork of USBDevice by mbed official

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers USBCDC.cpp Source File

USBCDC.cpp

00001 /* Copyright (c) 2010-2011 mbed.org, MIT License
00002 *
00003 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
00004 * and associated documentation files (the "Software"), to deal in the Software without
00005 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
00006 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
00007 * Software is furnished to do so, subject to the following conditions:
00008 *
00009 * The above copyright notice and this permission notice shall be included in all copies or
00010 * substantial portions of the Software.
00011 *
00012 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
00013 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00014 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
00015 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00016 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00017 */
00018 
00019 #include "stdint.h"
00020 #include "USBCDC.h"
00021 
00022 static uint8_t cdc_line_coding[7]= {0x80, 0x25, 0x00, 0x00, 0x00, 0x00, 0x08};
00023 
00024 #define DEFAULT_CONFIGURATION (1)
00025 
00026 #define CDC_SET_LINE_CODING        0x20
00027 #define CDC_GET_LINE_CODING        0x21
00028 #define CDC_SET_CONTROL_LINE_STATE 0x22
00029 
00030 #define MAX_CDC_REPORT_SIZE MAX_PACKET_SIZE_EPBULK
00031 
00032 USBCDC::USBCDC(uint16_t vendor_id, uint16_t product_id, uint16_t product_release, bool connect_blocking): USBDevice(vendor_id, product_id, product_release) {
00033     terminal_connected = false;
00034     USBDevice::connect(connect_blocking);
00035 }
00036 
00037 void USBCDC::USBCallback_busReset(void) {
00038     terminal_connected = false;
00039 };
00040 
00041 bool USBCDC::USBCallback_request(void) {
00042     /* Called in ISR context */
00043 
00044     bool success = false;
00045     CONTROL_TRANSFER * transfer = getTransferPtr();
00046 
00047     /* Process class-specific requests */
00048 
00049     if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
00050         switch (transfer->setup.bRequest) {
00051             case CDC_GET_LINE_CODING:
00052                 transfer->remaining = 7;
00053                 transfer->ptr = cdc_line_coding;
00054                 transfer->direction = DEVICE_TO_HOST;
00055                 success = true;
00056                 break;
00057             case CDC_SET_LINE_CODING:
00058                 transfer->remaining = 7;
00059                 transfer->notify = true;
00060                 success = true;
00061                 terminal_connected = true;
00062                 break;
00063             case CDC_SET_CONTROL_LINE_STATE:
00064                 terminal_connected = false;
00065                 success = true;
00066                 break;
00067             default:
00068                 break;
00069         }
00070     }
00071 
00072     return success;
00073 }
00074 
00075 void USBCDC::USBCallback_requestCompleted(uint8_t *buf, uint32_t length) {
00076     // Request of setting line coding has 7 bytes
00077     if (length != 7) {
00078         return;
00079     }
00080     
00081     CONTROL_TRANSFER * transfer = getTransferPtr();
00082  
00083     /* Process class-specific requests */
00084     if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
00085         if (transfer->setup.bRequest == CDC_SET_LINE_CODING) {
00086             if (memcmp(cdc_line_coding, buf, 7)) {
00087                 memcpy(cdc_line_coding, buf, 7); 
00088  
00089                 int baud = buf[0] + (buf[1] << 8)
00090                          + (buf[2] << 16) + (buf[3] << 24);
00091                 int stop = buf[4];
00092                 int bits = buf[6];
00093                 int parity = buf[5];
00094 
00095                 lineCodingChanged(baud, bits, parity, stop);
00096             }
00097         }
00098     }
00099 }
00100 
00101 // Called in ISR context
00102 // Set configuration. Return false if the
00103 // configuration is not supported.
00104 bool USBCDC::USBCallback_setConfiguration(uint8_t configuration) {
00105     if (configuration != DEFAULT_CONFIGURATION) {
00106         return false;
00107     }
00108 
00109     // Configure endpoints > 0
00110     addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT);
00111     addEndpoint(EPBULK_IN, MAX_PACKET_SIZE_EPBULK);
00112     addEndpoint(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
00113 
00114     // We activate the endpoint to be able to recceive data
00115     readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
00116     return true;
00117 }
00118 
00119 bool USBCDC::send(uint8_t * buffer, uint32_t size) {
00120     return USBDevice::write(EPBULK_IN, buffer, size, MAX_CDC_REPORT_SIZE);
00121 }
00122 
00123 bool USBCDC::readEP(uint8_t * buffer, uint32_t * size) {
00124     if (!USBDevice::readEP(EPBULK_OUT, buffer, size, MAX_CDC_REPORT_SIZE))
00125         return false;
00126     if (!readStart(EPBULK_OUT, MAX_CDC_REPORT_SIZE))
00127         return false;
00128     return true;
00129 }
00130 
00131 bool USBCDC::readEP_NB(uint8_t * buffer, uint32_t * size) {
00132     if (!USBDevice::readEP_NB(EPBULK_OUT, buffer, size, MAX_CDC_REPORT_SIZE))
00133         return false;
00134     if (!readStart(EPBULK_OUT, MAX_CDC_REPORT_SIZE))
00135         return false;
00136     return true;
00137 }
00138 
00139 
00140 uint8_t * USBCDC::deviceDesc() {
00141     static uint8_t deviceDescriptor[] = {
00142         18,                   // bLength
00143         1,                    // bDescriptorType
00144         0x10, 0x01,           // bcdUSB
00145         2,                    // bDeviceClass
00146         0,                    // bDeviceSubClass
00147         0,                    // bDeviceProtocol
00148         MAX_PACKET_SIZE_EP0,  // bMaxPacketSize0
00149         (uint8_t)(LSB(VENDOR_ID)), (uint8_t)(MSB(VENDOR_ID)),  // idVendor
00150         (uint8_t)(LSB(PRODUCT_ID)), (uint8_t)(MSB(PRODUCT_ID)),// idProduct
00151         0x00, 0x01,           // bcdDevice
00152         1,                    // iManufacturer
00153         2,                    // iProduct
00154         3,                    // iSerialNumber
00155         1                     // bNumConfigurations
00156     };
00157     return deviceDescriptor;
00158 }
00159 
00160 uint8_t * USBCDC::stringIinterfaceDesc() {
00161     static uint8_t stringIinterfaceDescriptor[] = {
00162         0x08,
00163         STRING_DESCRIPTOR,
00164         'C',0,'D',0,'C',0,
00165     };
00166     return stringIinterfaceDescriptor;
00167 }
00168 
00169 uint8_t * USBCDC::stringIproductDesc() {
00170     static uint8_t stringIproductDescriptor[] = {
00171         0x16,
00172         STRING_DESCRIPTOR,
00173         'C',0,'D',0,'C',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0
00174     };
00175     return stringIproductDescriptor;
00176 }
00177 
00178 
00179 #define CONFIG1_DESC_SIZE (9+8+9+5+5+4+5+7+9+7+7)
00180 
00181 uint8_t * USBCDC::configurationDesc() {
00182     static uint8_t configDescriptor[] = {
00183         // configuration descriptor
00184         9,                      // bLength
00185         2,                      // bDescriptorType
00186         LSB(CONFIG1_DESC_SIZE), // wTotalLength
00187         MSB(CONFIG1_DESC_SIZE),
00188         2,                      // bNumInterfaces
00189         1,                      // bConfigurationValue
00190         0,                      // iConfiguration
00191         0x80,                   // bmAttributes
00192         50,                     // bMaxPower
00193         
00194         // IAD to associate the two CDC interfaces
00195         0x08,                   // bLength
00196         0x0b,                   // bDescriptorType
00197         0x00,                   // bFirstInterface
00198         0x02,                   // bInterfaceCount
00199         0x02,                   // bFunctionClass
00200         0x02,                   // bFunctionSubClass
00201         0,                      // bFunctionProtocol
00202         0,                      // iFunction
00203 
00204         // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
00205         9,                      // bLength
00206         4,                      // bDescriptorType
00207         0,                      // bInterfaceNumber
00208         0,                      // bAlternateSetting
00209         1,                      // bNumEndpoints
00210         0x02,                   // bInterfaceClass
00211         0x02,                   // bInterfaceSubClass
00212         0x01,                   // bInterfaceProtocol
00213         0,                      // iInterface
00214 
00215         // CDC Header Functional Descriptor, CDC Spec 5.2.3.1, Table 26
00216         5,                      // bFunctionLength
00217         0x24,                   // bDescriptorType
00218         0x00,                   // bDescriptorSubtype
00219         0x10, 0x01,             // bcdCDC
00220 
00221         // Call Management Functional Descriptor, CDC Spec 5.2.3.2, Table 27
00222         5,                      // bFunctionLength
00223         0x24,                   // bDescriptorType
00224         0x01,                   // bDescriptorSubtype
00225         0x03,                   // bmCapabilities
00226         1,                      // bDataInterface
00227 
00228         // Abstract Control Management Functional Descriptor, CDC Spec 5.2.3.3, Table 28
00229         4,                      // bFunctionLength
00230         0x24,                   // bDescriptorType
00231         0x02,                   // bDescriptorSubtype
00232         0x06,                   // bmCapabilities
00233 
00234         // Union Functional Descriptor, CDC Spec 5.2.3.8, Table 33
00235         5,                      // bFunctionLength
00236         0x24,                   // bDescriptorType
00237         0x06,                   // bDescriptorSubtype
00238         0,                      // bMasterInterface
00239         1,                      // bSlaveInterface0
00240 
00241         // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
00242         ENDPOINT_DESCRIPTOR_LENGTH,     // bLength
00243         ENDPOINT_DESCRIPTOR,            // bDescriptorType
00244         PHY_TO_DESC(EPINT_IN),          // bEndpointAddress
00245         E_INTERRUPT,                    // bmAttributes (0x03=intr)
00246         LSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (LSB)
00247         MSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (MSB)
00248         16,                             // bInterval
00249 
00250 
00251 
00252 
00253         // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
00254         9,                          // bLength
00255         4,                          // bDescriptorType
00256         1,                          // bInterfaceNumber
00257         0,                          // bAlternateSetting
00258         2,                          // bNumEndpoints
00259         0x0A,                       // bInterfaceClass
00260         0x00,                       // bInterfaceSubClass
00261         0x00,                       // bInterfaceProtocol
00262         0,                          // iInterface
00263 
00264         // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
00265         ENDPOINT_DESCRIPTOR_LENGTH, // bLength
00266         ENDPOINT_DESCRIPTOR,        // bDescriptorType
00267         PHY_TO_DESC(EPBULK_IN),     // bEndpointAddress
00268         E_BULK,                     // bmAttributes (0x02=bulk)
00269         LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB)
00270         MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB)
00271         0,                          // bInterval
00272 
00273         // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
00274         ENDPOINT_DESCRIPTOR_LENGTH, // bLength
00275         ENDPOINT_DESCRIPTOR,        // bDescriptorType
00276         PHY_TO_DESC(EPBULK_OUT),    // bEndpointAddress
00277         E_BULK,                     // bmAttributes (0x02=bulk)
00278         LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB)
00279         MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB)
00280         0                           // bInterval
00281     };
00282     return configDescriptor;
00283 }