adding additional features

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