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