A copy of the mbed USBDevice with USBSerial library

Dependents:   STM32L0_LoRa Smartage STM32L0_LoRa Turtle_RadioShuttle

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers USBCDC.cpp Source File

USBCDC.cpp

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