Jerry Roletter / USBDevice

Dependents:   FinalProject

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): USBDevice(vendor_id, product_id, product_release) {
00033     terminal_connected = false;
00034     USBDevice::connect();
00035 }
00036 
00037 bool USBCDC::USBCallback_request(void) {
00038     /* Called in ISR context */
00039 
00040     bool success = false;
00041     CONTROL_TRANSFER * transfer = getTransferPtr();
00042 
00043     /* Process class-specific requests */
00044 
00045     if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
00046         switch (transfer->setup.bRequest) {
00047             case CDC_GET_LINE_CODING:
00048                 transfer->remaining = 7;
00049                 transfer->ptr = cdc_line_coding;
00050                 transfer->direction = DEVICE_TO_HOST;
00051                 success = true;
00052                 break;
00053             case CDC_SET_LINE_CODING:
00054                 transfer->remaining = 7;
00055                 success = true;
00056                 terminal_connected = true;
00057                 break;
00058             case CDC_SET_CONTROL_LINE_STATE:
00059                 terminal_connected = false;
00060                 success = true;
00061                 break;
00062             default:
00063                 break;
00064         }
00065     }
00066 
00067     return success;
00068 }
00069 
00070 
00071 // Called in ISR context
00072 // Set configuration. Return false if the
00073 // configuration is not supported.
00074 bool USBCDC::USBCallback_setConfiguration(uint8_t configuration) {
00075     if (configuration != DEFAULT_CONFIGURATION) {
00076         return false;
00077     }
00078 
00079     // Configure endpoints > 0
00080     addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT);
00081     addEndpoint(EPBULK_IN, MAX_PACKET_SIZE_EPBULK);
00082     addEndpoint(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
00083 
00084     // We activate the endpoint to be able to recceive data
00085     readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
00086     return true;
00087 }
00088 
00089 bool USBCDC::send(uint8_t * buffer, uint32_t size) {
00090     return USBDevice::write(EPBULK_IN, buffer, size, MAX_CDC_REPORT_SIZE);
00091 }
00092 
00093 bool USBCDC::sendNB(uint8_t * buffer, uint32_t size) {
00094     return USBDevice::writeNB(EPBULK_IN, buffer, size, MAX_CDC_REPORT_SIZE);
00095 }
00096 
00097 bool USBCDC::readEP(uint8_t * buffer, uint32_t * size) {
00098     if (!USBDevice::readEP(EPBULK_OUT, buffer, size, MAX_CDC_REPORT_SIZE))
00099         return false;
00100     if (!readStart(EPBULK_OUT, MAX_CDC_REPORT_SIZE))
00101         return false;
00102     return true;
00103 }
00104 
00105 bool USBCDC::readEP_NB(uint8_t * buffer, uint32_t * size) {
00106     if (!USBDevice::readEP_NB(EPBULK_OUT, buffer, size, MAX_CDC_REPORT_SIZE))
00107         return false;
00108     if (!readStart(EPBULK_OUT, MAX_CDC_REPORT_SIZE))
00109         return false;
00110     return true;
00111 }
00112 
00113 
00114 uint8_t * USBCDC::deviceDesc() {
00115     static uint8_t deviceDescriptor[] = {
00116         18,                   // bLength
00117         1,                    // bDescriptorType
00118         0x10, 0x01,           // bcdUSB
00119         2,                    // bDeviceClass
00120         0,                    // bDeviceSubClass
00121         0,                    // bDeviceProtocol
00122         MAX_PACKET_SIZE_EP0,  // bMaxPacketSize0
00123         LSB(VENDOR_ID), MSB(VENDOR_ID),  // idVendor
00124         LSB(PRODUCT_ID), MSB(PRODUCT_ID),// idProduct
00125         0x00, 0x01,           // bcdDevice
00126         1,                    // iManufacturer
00127         2,                    // iProduct
00128         3,                    // iSerialNumber
00129         1                     // bNumConfigurations
00130     };
00131     return deviceDescriptor;
00132 }
00133 
00134 uint8_t * USBCDC::stringIinterfaceDesc() {
00135     static uint8_t stringIinterfaceDescriptor[] = {
00136         0x08,
00137         STRING_DESCRIPTOR,
00138         'C',0,'D',0,'C',0,
00139     };
00140     return stringIinterfaceDescriptor;
00141 }
00142 
00143 uint8_t * USBCDC::stringIproductDesc() {
00144     static uint8_t stringIproductDescriptor[] = {
00145         0x16,
00146         STRING_DESCRIPTOR,
00147         'C',0,'D',0,'C',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0
00148     };
00149     return stringIproductDescriptor;
00150 }
00151 
00152 
00153 #define CONFIG1_DESC_SIZE (9+8+9+5+5+4+5+7+9+7+7)
00154 
00155 uint8_t * USBCDC::configurationDesc() {
00156     static uint8_t configDescriptor[] = {
00157         // configuration descriptor
00158         9,                      // bLength
00159         2,                      // bDescriptorType
00160         LSB(CONFIG1_DESC_SIZE), // wTotalLength
00161         MSB(CONFIG1_DESC_SIZE),
00162         2,                      // bNumInterfaces
00163         1,                      // bConfigurationValue
00164         0,                      // iConfiguration
00165         0x80,                   // bmAttributes
00166         50,                     // bMaxPower
00167         
00168         // IAD to associate the two CDC interfaces
00169         0x08,                   // bLength
00170         0x0b,                   // bDescriptorType
00171         0x00,                   // bFirstInterface
00172         0x02,                   // bInterfaceCount
00173         0x02,                   // bFunctionClass
00174         0x02,                   // bFunctionSubClass
00175         0,                      // bFunctionProtocol
00176         0,                      // iFunction
00177 
00178         // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
00179         9,                      // bLength
00180         4,                      // bDescriptorType
00181         0,                      // bInterfaceNumber
00182         0,                      // bAlternateSetting
00183         1,                      // bNumEndpoints
00184         0x02,                   // bInterfaceClass
00185         0x02,                   // bInterfaceSubClass
00186         0x01,                   // bInterfaceProtocol
00187         0,                      // iInterface
00188 
00189         // CDC Header Functional Descriptor, CDC Spec 5.2.3.1, Table 26
00190         5,                      // bFunctionLength
00191         0x24,                   // bDescriptorType
00192         0x00,                   // bDescriptorSubtype
00193         0x10, 0x01,             // bcdCDC
00194 
00195         // Call Management Functional Descriptor, CDC Spec 5.2.3.2, Table 27
00196         5,                      // bFunctionLength
00197         0x24,                   // bDescriptorType
00198         0x01,                   // bDescriptorSubtype
00199         0x03,                   // bmCapabilities
00200         1,                      // bDataInterface
00201 
00202         // Abstract Control Management Functional Descriptor, CDC Spec 5.2.3.3, Table 28
00203         4,                      // bFunctionLength
00204         0x24,                   // bDescriptorType
00205         0x02,                   // bDescriptorSubtype
00206         0x06,                   // bmCapabilities
00207 
00208         // Union Functional Descriptor, CDC Spec 5.2.3.8, Table 33
00209         5,                      // bFunctionLength
00210         0x24,                   // bDescriptorType
00211         0x06,                   // bDescriptorSubtype
00212         0,                      // bMasterInterface
00213         1,                      // bSlaveInterface0
00214 
00215         // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
00216         ENDPOINT_DESCRIPTOR_LENGTH,     // bLength
00217         ENDPOINT_DESCRIPTOR,            // bDescriptorType
00218         PHY_TO_DESC(EPINT_IN),          // bEndpointAddress
00219         E_INTERRUPT,                    // bmAttributes (0x03=intr)
00220         LSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (LSB)
00221         MSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (MSB)
00222         16,                             // bInterval
00223 
00224 
00225 
00226 
00227         // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
00228         9,                          // bLength
00229         4,                          // bDescriptorType
00230         1,                          // bInterfaceNumber
00231         0,                          // bAlternateSetting
00232         2,                          // bNumEndpoints
00233         0x0A,                       // bInterfaceClass
00234         0x00,                       // bInterfaceSubClass
00235         0x00,                       // bInterfaceProtocol
00236         0,                          // iInterface
00237 
00238         // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
00239         ENDPOINT_DESCRIPTOR_LENGTH, // bLength
00240         ENDPOINT_DESCRIPTOR,        // bDescriptorType
00241         PHY_TO_DESC(EPBULK_IN),     // bEndpointAddress
00242         E_BULK,                     // bmAttributes (0x02=bulk)
00243         LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB)
00244         MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB)
00245         0,                          // bInterval
00246 
00247         // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
00248         ENDPOINT_DESCRIPTOR_LENGTH, // bLength
00249         ENDPOINT_DESCRIPTOR,        // bDescriptorType
00250         PHY_TO_DESC(EPBULK_OUT),    // bEndpointAddress
00251         E_BULK,                     // bmAttributes (0x02=bulk)
00252         LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB)
00253         MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB)
00254         0                           // bInterval
00255     };
00256     return configDescriptor;
00257 }