updsted the USB to persuade it to build for the Dragonfly platfom

Fork of USBDevice by mbed official

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers USBHID.cpp Source File

USBHID.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 "USBHAL.h"
00021 #include "USBHID.h"
00022 
00023 
00024 USBHID::USBHID(uint8_t output_report_length, uint8_t input_report_length, uint16_t vendor_id, uint16_t product_id, uint16_t product_release, bool connect): USBDevice(vendor_id, product_id, product_release)
00025 {
00026 
00027 
00028 extern int  USBHID_USBHIDInstCount; // debug BL
00029 ++USBHID_USBHIDInstCount; // debug BL
00030 
00031 
00032     output_length = output_report_length;
00033     input_length = input_report_length;
00034     if(connect) {
00035         USBDevice::connect();
00036     }
00037 }
00038 
00039 
00040 bool USBHID::send(HID_REPORT *report)
00041 {
00042 printf("USBHID::send %s : %d\r\n", __FILE__, __LINE__);
00043     return write(EPINT_IN, report->data, report->length, MAX_HID_REPORT_SIZE);
00044 }
00045 
00046 bool USBHID::sendNB(HID_REPORT *report)
00047 {
00048     return writeNB(EPINT_IN, report->data, report->length, MAX_HID_REPORT_SIZE);
00049 }
00050 
00051 
00052 bool USBHID::read(HID_REPORT *report)
00053 {
00054     uint32_t bytesRead = 0;
00055     bool result;
00056     result = USBDevice::readEP(EPINT_OUT, report->data, &bytesRead, MAX_HID_REPORT_SIZE);
00057     if(!readStart(EPINT_OUT, MAX_HID_REPORT_SIZE))
00058         return false;
00059     report->length = bytesRead;
00060     return result;
00061 }
00062 
00063 
00064 bool USBHID::readNB(HID_REPORT *report)
00065 {
00066     uint32_t bytesRead = 0;
00067     bool result;
00068     result = USBDevice::readEP_NB(EPINT_OUT, report->data, &bytesRead, MAX_HID_REPORT_SIZE);
00069     // if readEP_NB did not succeed, does not issue a readStart
00070     if (!result)
00071         return false;
00072     report->length = bytesRead;
00073     if(!readStart(EPINT_OUT, MAX_HID_REPORT_SIZE))
00074         return false;
00075     return result;
00076 }
00077 
00078 
00079 uint16_t USBHID::reportDescLength() {
00080     reportDesc();
00081     return reportLength;
00082 }
00083 
00084 
00085 
00086 //
00087 //  Route callbacks from lower layers to class(es)
00088 //
00089 
00090 
00091 // Called in ISR context
00092 // Called by USBDevice on Endpoint0 request
00093 // This is used to handle extensions to standard requests
00094 // and class specific requests
00095 // Return true if class handles this request
00096 bool USBHID::USBCallback_request() {
00097     bool success = false;
00098     CONTROL_TRANSFER * transfer = getTransferPtr();
00099     uint8_t *hidDescriptor;
00100 
00101     // Process additional standard requests
00102 
00103     if ((transfer->setup.bmRequestType.Type == STANDARD_TYPE))
00104     {
00105         switch (transfer->setup.bRequest)
00106         {
00107             case GET_DESCRIPTOR:
00108                 switch (DESCRIPTOR_TYPE(transfer->setup.wValue))
00109                 {
00110                     case REPORT_DESCRIPTOR:
00111                         if ((reportDesc() != NULL) \
00112                             && (reportDescLength() != 0))
00113                         {
00114                             transfer->remaining = reportDescLength();
00115                             transfer->ptr = reportDesc();
00116                             transfer->direction = DEVICE_TO_HOST;
00117                             success = true;
00118                         }
00119                         break;
00120                     case HID_DESCRIPTOR:
00121                             // Find the HID descriptor, after the configuration descriptor
00122                             hidDescriptor = findDescriptor(HID_DESCRIPTOR);
00123                             if (hidDescriptor != NULL)
00124                             {
00125                                 transfer->remaining = HID_DESCRIPTOR_LENGTH;
00126                                 transfer->ptr = hidDescriptor;
00127                                 transfer->direction = DEVICE_TO_HOST;
00128                                 success = true;
00129                             }
00130                             break;
00131 
00132                     default:
00133                         break;
00134                 }
00135                 break;
00136             default:
00137                 break;
00138         }
00139     }
00140 
00141     // Process class-specific requests
00142 
00143     if (transfer->setup.bmRequestType.Type == CLASS_TYPE)
00144     {
00145         switch (transfer->setup.bRequest)
00146         {
00147              case SET_REPORT:
00148                 // First byte will be used for report ID
00149                 outputReport.data[0] = transfer->setup.wValue & 0xff;
00150                 outputReport.length = transfer->setup.wLength + 1;
00151 
00152                 transfer->remaining = sizeof(outputReport.data) - 1;
00153                 transfer->ptr = &outputReport.data[1];
00154                 transfer->direction = HOST_TO_DEVICE;
00155                 transfer->notify = true;
00156                 success = true;
00157             default:
00158                 break;
00159         }
00160     }
00161 
00162     return success;
00163 }
00164 
00165 
00166 #define DEFAULT_CONFIGURATION (1)
00167 
00168 
00169 // Called in ISR context
00170 // Set configuration. Return false if the
00171 // configuration is not supported
00172 bool USBHID::USBCallback_setConfiguration(uint8_t configuration) {
00173     if (configuration != DEFAULT_CONFIGURATION) {
00174         return false;
00175     }
00176 
00177     // Configure endpoints > 0
00178     addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT);
00179     addEndpoint(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
00180 
00181     // We activate the endpoint to be able to recceive data
00182     readStart(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
00183     return true;
00184 }
00185 
00186 
00187 uint8_t * USBHID::stringIinterfaceDesc() {
00188     static uint8_t stringIinterfaceDescriptor[] = {
00189         0x08,               //bLength
00190         STRING_DESCRIPTOR,  //bDescriptorType 0x03
00191         'H',0,'I',0,'D',0,  //bString iInterface - HID
00192     };
00193     return stringIinterfaceDescriptor;
00194 }
00195 
00196 uint8_t * USBHID::stringIproductDesc() {
00197     static uint8_t stringIproductDescriptor[] = {
00198         0x16,                                                       //bLength
00199         STRING_DESCRIPTOR,                                          //bDescriptorType 0x03
00200         'H',0,'I',0,'D',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0 //bString iProduct - HID device
00201     };
00202     return stringIproductDescriptor;
00203 }
00204 
00205 
00206 
00207 uint8_t * USBHID::reportDesc() {
00208     static uint8_t reportDescriptor[] = {
00209         USAGE_PAGE(2), LSB(0xFFAB), MSB(0xFFAB),
00210         USAGE(2), LSB(0x0200), MSB(0x0200),
00211         COLLECTION(1), 0x01, // Collection (Application)
00212 
00213         REPORT_SIZE(1), 0x08, // 8 bits
00214         LOGICAL_MINIMUM(1), 0x00,
00215         LOGICAL_MAXIMUM(1), 0xFF,
00216 
00217         REPORT_COUNT(1), input_length,
00218         USAGE(1), 0x01,
00219         INPUT(1), 0x02, // Data, Var, Abs
00220 
00221         REPORT_COUNT(1), output_length,
00222         USAGE(1), 0x02,
00223         OUTPUT(1), 0x02, // Data, Var, Abs
00224 
00225         END_COLLECTION(0),
00226     };
00227     reportLength = sizeof(reportDescriptor);
00228     return reportDescriptor;
00229 }
00230 
00231 #define DEFAULT_CONFIGURATION (1)
00232 #define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
00233                                + (1 * INTERFACE_DESCRIPTOR_LENGTH) \
00234                                + (1 * HID_DESCRIPTOR_LENGTH) \
00235                                + (2 * ENDPOINT_DESCRIPTOR_LENGTH))
00236 
00237 uint8_t * USBHID::configurationDesc() {
00238     static uint8_t configurationDescriptor[] = {
00239         CONFIGURATION_DESCRIPTOR_LENGTH,    // bLength
00240         CONFIGURATION_DESCRIPTOR,           // bDescriptorType
00241         LSB(TOTAL_DESCRIPTOR_LENGTH),       // wTotalLength (LSB)
00242         MSB(TOTAL_DESCRIPTOR_LENGTH),       // wTotalLength (MSB)
00243         0x01,                               // bNumInterfaces
00244         DEFAULT_CONFIGURATION,              // bConfigurationValue
00245         0x00,                               // iConfiguration
00246         C_RESERVED | C_SELF_POWERED,        // bmAttributes
00247         C_POWER(0),                         // bMaxPower
00248 
00249         INTERFACE_DESCRIPTOR_LENGTH,        // bLength
00250         INTERFACE_DESCRIPTOR,               // bDescriptorType
00251         0x00,                               // bInterfaceNumber
00252         0x00,                               // bAlternateSetting
00253         0x02,                               // bNumEndpoints
00254         HID_CLASS,                          // bInterfaceClass
00255         HID_SUBCLASS_NONE,                  // bInterfaceSubClass
00256         HID_PROTOCOL_NONE,                  // bInterfaceProtocol
00257         0x00,                               // iInterface
00258 
00259         HID_DESCRIPTOR_LENGTH,              // bLength
00260         HID_DESCRIPTOR,                     // bDescriptorType
00261         LSB(HID_VERSION_1_11),              // bcdHID (LSB)
00262         MSB(HID_VERSION_1_11),              // bcdHID (MSB)
00263         0x00,                               // bCountryCode
00264         0x01,                               // bNumDescriptors
00265         REPORT_DESCRIPTOR,                  // bDescriptorType
00266         (uint8_t)(LSB(reportDescLength())), // wDescriptorLength (LSB)
00267         (uint8_t)(MSB(reportDescLength())), // wDescriptorLength (MSB)
00268 
00269         ENDPOINT_DESCRIPTOR_LENGTH,         // bLength
00270         ENDPOINT_DESCRIPTOR,                // bDescriptorType
00271         PHY_TO_DESC(EPINT_IN),              // bEndpointAddress
00272         E_INTERRUPT,                        // bmAttributes
00273         LSB(MAX_PACKET_SIZE_EPINT),         // wMaxPacketSize (LSB)
00274         MSB(MAX_PACKET_SIZE_EPINT),         // wMaxPacketSize (MSB)
00275         1,                                  // bInterval (milliseconds)
00276 
00277         ENDPOINT_DESCRIPTOR_LENGTH,         // bLength
00278         ENDPOINT_DESCRIPTOR,                // bDescriptorType
00279         PHY_TO_DESC(EPINT_OUT),             // bEndpointAddress
00280         E_INTERRUPT,                        // bmAttributes
00281         LSB(MAX_PACKET_SIZE_EPINT),         // wMaxPacketSize (LSB)
00282         MSB(MAX_PACKET_SIZE_EPINT),         // wMaxPacketSize (MSB)
00283         1,                                  // bInterval (milliseconds)
00284     };
00285     return configurationDescriptor;
00286 }