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