Norimasa Okamoto / USBLocalFileSystem

Dependencies:   USBDevice

Dependents:   KL46Z-lpc81isp lpcterm2

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers USB_HID.cpp Source File

USB_HID.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 "USB_HID.h"
00020 
00021 #if (DEBUG2 > 3)
00022 #define HID_DBG(...) do{fprintf(stderr,"[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\r\n");} while(0);
00023 #else
00024 #define HID_DBG(...) while(0)
00025 #endif
00026 
00027 USB_HID::USB_HID(USBDevice* device, uint8_t output_report_length, uint8_t input_report_length) : _device(device)
00028 {
00029     HID_DBG("device=%p", device);
00030 
00031     output_length = output_report_length;
00032     input_length = input_report_length;
00033 }
00034 
00035 bool USB_HID::send(HID_REPORT *report)
00036 {
00037     return _device->write(HID_EPINT_IN, report->data, report->length, MAX_HID_REPORT_SIZE);
00038 }
00039 
00040 bool USB_HID::sendNB(HID_REPORT *report)
00041 {
00042     return _device->writeNB(HID_EPINT_IN, report->data, report->length, MAX_HID_REPORT_SIZE);
00043 }
00044 
00045 bool USB_HID::read(HID_REPORT *report)
00046 {
00047     uint32_t bytesRead = 0;
00048     bool result;
00049     result = _device->readEP(HID_EPINT_OUT, report->data, &bytesRead, MAX_HID_REPORT_SIZE);
00050     if(!_device->readStart(HID_EPINT_OUT, MAX_HID_REPORT_SIZE))
00051         return false;
00052     report->length = bytesRead;
00053     return result;
00054 }
00055 
00056 bool USB_HID::readNB(HID_REPORT *report)
00057 {
00058     uint32_t bytesRead = 0;
00059     bool result;
00060     result = _device->readEP_NB(HID_EPINT_OUT, report->data, &bytesRead, MAX_HID_REPORT_SIZE);
00061     report->length = bytesRead;
00062     if(!_device->readStart(HID_EPINT_OUT, MAX_HID_REPORT_SIZE))
00063         return false;
00064     return result;
00065 }
00066 
00067 /* virtual */ uint8_t * USB_HID::reportDesc() {
00068     static uint8_t reportDescriptor[] = {
00069         0x06, 0x00, 0xff,
00070         0x09, 0x01,         // usage
00071         0xA1, 0x01,         // Collection 0x01
00072         0x15, 0x00,         // logical minimum = 0
00073         0x26, 0xFF, 0x00,   // logical maximum = 255
00074         0x75, 0x08,         // report size = 8 bits
00075         0x95, 0x40,         // report count
00076         0x09, 0x01,         // usage
00077         0x81, 0x02,         // Input (array)
00078         0x95, 0x40,         // report count
00079         0x09, 0x01,         // usage
00080         0x91, 0x02,         // Output (array)
00081         0x95, 0x01,         // report count
00082         0x09, 0x01,         // usage
00083         0xb1, 0x02,
00084         0xC0                // end collection
00085     };
00086     reportLength = sizeof(reportDescriptor);
00087     return reportDescriptor;
00088 }
00089 
00090 /* virtual */ uint16_t USB_HID::reportDescLength() {
00091     reportDesc();
00092     return reportLength;
00093 }
00094 
00095 bool USB_HID::Request_callback(CONTROL_TRANSFER* transfer, uint8_t* hidDescriptor)
00096 {
00097     // Process additional standard requests
00098     if (transfer->setup.bmRequestType.Type == STANDARD_TYPE) {
00099         switch (transfer->setup.bRequest) {
00100             case GET_DESCRIPTOR:
00101                 switch (DESCRIPTOR_TYPE(transfer->setup.wValue)) {
00102                     case REPORT_DESCRIPTOR:
00103                         if ((reportDesc() != NULL) && (reportDescLength() != 0)) {
00104                             transfer->remaining = reportDescLength();
00105                             transfer->ptr = reportDesc();
00106                             transfer->direction = DEVICE_TO_HOST;
00107                             return true;
00108                         }
00109                         break;
00110                     case HID_DESCRIPTOR:
00111                         if (hidDescriptor != NULL) {
00112                             transfer->remaining = HID_DESCRIPTOR_LENGTH;
00113                             transfer->ptr = hidDescriptor;
00114                             transfer->direction = DEVICE_TO_HOST;
00115                             return true;
00116                         }
00117                         break;
00118                     default:
00119                         break;
00120                 }
00121                 break;
00122             default:
00123                 break;
00124         }
00125     }
00126 
00127     if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
00128         switch (transfer->setup.bRequest) {
00129              case SET_REPORT:
00130                 // First byte will be used for report ID
00131                 outputReport.data[0] = transfer->setup.wValue & 0xff;
00132                 outputReport.length = transfer->setup.wLength + 1;
00133 
00134                 transfer->remaining = sizeof(outputReport.data) - 1;
00135                 transfer->ptr = &outputReport.data[1];
00136                 transfer->direction = HOST_TO_DEVICE;
00137                 transfer->notify = true;
00138                 return true;
00139         }
00140     }
00141     return false;
00142 }