Modified for PS3 Joystick

Dependents:   NiseKabuto

Fork of USBDevice by Samuel Mokrani

Committer:
samux
Date:
Wed May 30 18:28:11 2012 +0000
Revision:
0:140cdf8e2d60
Child:
1:ac5cca60029a

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
samux 0:140cdf8e2d60 1 /* Copyright (c) 2010-2011 mbed.org, MIT License
samux 0:140cdf8e2d60 2 *
samux 0:140cdf8e2d60 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
samux 0:140cdf8e2d60 4 * and associated documentation files (the "Software"), to deal in the Software without
samux 0:140cdf8e2d60 5 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
samux 0:140cdf8e2d60 6 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
samux 0:140cdf8e2d60 7 * Software is furnished to do so, subject to the following conditions:
samux 0:140cdf8e2d60 8 *
samux 0:140cdf8e2d60 9 * The above copyright notice and this permission notice shall be included in all copies or
samux 0:140cdf8e2d60 10 * substantial portions of the Software.
samux 0:140cdf8e2d60 11 *
samux 0:140cdf8e2d60 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
samux 0:140cdf8e2d60 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
samux 0:140cdf8e2d60 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
samux 0:140cdf8e2d60 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
samux 0:140cdf8e2d60 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
samux 0:140cdf8e2d60 17 */
samux 0:140cdf8e2d60 18
samux 0:140cdf8e2d60 19 #include "stdint.h"
samux 0:140cdf8e2d60 20 #include "USBHAL.h"
samux 0:140cdf8e2d60 21 #include "USBHID.h"
samux 0:140cdf8e2d60 22
samux 0:140cdf8e2d60 23
samux 0:140cdf8e2d60 24 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)
samux 0:140cdf8e2d60 25 {
samux 0:140cdf8e2d60 26 output_length = output_report_length;
samux 0:140cdf8e2d60 27 input_length = input_report_length;
samux 0:140cdf8e2d60 28 if(connect) {
samux 0:140cdf8e2d60 29 USBDevice::connect();
samux 0:140cdf8e2d60 30 }
samux 0:140cdf8e2d60 31 }
samux 0:140cdf8e2d60 32
samux 0:140cdf8e2d60 33
samux 0:140cdf8e2d60 34 bool USBHID::send(HID_REPORT *report)
samux 0:140cdf8e2d60 35 {
samux 0:140cdf8e2d60 36 return write(EPINT_IN, report->data, report->length, MAX_HID_REPORT_SIZE);
samux 0:140cdf8e2d60 37 }
samux 0:140cdf8e2d60 38
samux 0:140cdf8e2d60 39 bool USBHID::sendNB(HID_REPORT *report)
samux 0:140cdf8e2d60 40 {
samux 0:140cdf8e2d60 41 return writeNB(EPINT_IN, report->data, report->length, MAX_HID_REPORT_SIZE);
samux 0:140cdf8e2d60 42 }
samux 0:140cdf8e2d60 43
samux 0:140cdf8e2d60 44
samux 0:140cdf8e2d60 45 bool USBHID::read(HID_REPORT *report)
samux 0:140cdf8e2d60 46 {
samux 0:140cdf8e2d60 47 uint32_t bytesRead = 0;
samux 0:140cdf8e2d60 48 bool result;
samux 0:140cdf8e2d60 49 result = USBDevice::readEP(EPINT_OUT, report->data, &bytesRead, MAX_HID_REPORT_SIZE);
samux 0:140cdf8e2d60 50 if(!readStart(EPINT_OUT, MAX_HID_REPORT_SIZE))
samux 0:140cdf8e2d60 51 return false;
samux 0:140cdf8e2d60 52 report->length = bytesRead;
samux 0:140cdf8e2d60 53 return result;
samux 0:140cdf8e2d60 54 }
samux 0:140cdf8e2d60 55
samux 0:140cdf8e2d60 56
samux 0:140cdf8e2d60 57 bool USBHID::readNB(HID_REPORT *report)
samux 0:140cdf8e2d60 58 {
samux 0:140cdf8e2d60 59 uint32_t bytesRead = 0;
samux 0:140cdf8e2d60 60 bool result;
samux 0:140cdf8e2d60 61 result = USBDevice::readEP_NB(EPINT_OUT, report->data, &bytesRead, MAX_HID_REPORT_SIZE);
samux 0:140cdf8e2d60 62 report->length = bytesRead;
samux 0:140cdf8e2d60 63 if(!readStart(EPINT_OUT, MAX_HID_REPORT_SIZE))
samux 0:140cdf8e2d60 64 return false;
samux 0:140cdf8e2d60 65 return result;
samux 0:140cdf8e2d60 66 }
samux 0:140cdf8e2d60 67
samux 0:140cdf8e2d60 68
samux 0:140cdf8e2d60 69 uint16_t USBHID::reportDescLength() {
samux 0:140cdf8e2d60 70 reportDesc();
samux 0:140cdf8e2d60 71 return reportLength;
samux 0:140cdf8e2d60 72 }
samux 0:140cdf8e2d60 73
samux 0:140cdf8e2d60 74
samux 0:140cdf8e2d60 75
samux 0:140cdf8e2d60 76 //
samux 0:140cdf8e2d60 77 // Route callbacks from lower layers to class(es)
samux 0:140cdf8e2d60 78 //
samux 0:140cdf8e2d60 79
samux 0:140cdf8e2d60 80
samux 0:140cdf8e2d60 81 // Called in ISR context
samux 0:140cdf8e2d60 82 // Called by USBDevice on Endpoint0 request
samux 0:140cdf8e2d60 83 // This is used to handle extensions to standard requests
samux 0:140cdf8e2d60 84 // and class specific requests
samux 0:140cdf8e2d60 85 // Return true if class handles this request
samux 0:140cdf8e2d60 86 bool USBHID::USBCallback_request() {
samux 0:140cdf8e2d60 87 bool success = false;
samux 0:140cdf8e2d60 88 CONTROL_TRANSFER * transfer = getTransferPtr();
samux 0:140cdf8e2d60 89 uint8_t *hidDescriptor;
samux 0:140cdf8e2d60 90
samux 0:140cdf8e2d60 91 // Process additional standard requests
samux 0:140cdf8e2d60 92
samux 0:140cdf8e2d60 93 if ((transfer->setup.bmRequestType.Type == STANDARD_TYPE))
samux 0:140cdf8e2d60 94 {
samux 0:140cdf8e2d60 95 switch (transfer->setup.bRequest)
samux 0:140cdf8e2d60 96 {
samux 0:140cdf8e2d60 97 case GET_DESCRIPTOR:
samux 0:140cdf8e2d60 98 switch (DESCRIPTOR_TYPE(transfer->setup.wValue))
samux 0:140cdf8e2d60 99 {
samux 0:140cdf8e2d60 100 case REPORT_DESCRIPTOR:
samux 0:140cdf8e2d60 101 if ((reportDesc() != NULL) \
samux 0:140cdf8e2d60 102 && (reportDescLength() != 0))
samux 0:140cdf8e2d60 103 {
samux 0:140cdf8e2d60 104 transfer->remaining = reportDescLength();
samux 0:140cdf8e2d60 105 transfer->ptr = reportDesc();
samux 0:140cdf8e2d60 106 transfer->direction = DEVICE_TO_HOST;
samux 0:140cdf8e2d60 107 success = true;
samux 0:140cdf8e2d60 108 }
samux 0:140cdf8e2d60 109 break;
samux 0:140cdf8e2d60 110 case HID_DESCRIPTOR:
samux 0:140cdf8e2d60 111 // Find the HID descriptor, after the configuration descriptor
samux 0:140cdf8e2d60 112 hidDescriptor = findDescriptor(HID_DESCRIPTOR);
samux 0:140cdf8e2d60 113 if (hidDescriptor != NULL)
samux 0:140cdf8e2d60 114 {
samux 0:140cdf8e2d60 115 transfer->remaining = HID_DESCRIPTOR_LENGTH;
samux 0:140cdf8e2d60 116 transfer->ptr = hidDescriptor;
samux 0:140cdf8e2d60 117 transfer->direction = DEVICE_TO_HOST;
samux 0:140cdf8e2d60 118 success = true;
samux 0:140cdf8e2d60 119 }
samux 0:140cdf8e2d60 120 break;
samux 0:140cdf8e2d60 121
samux 0:140cdf8e2d60 122 default:
samux 0:140cdf8e2d60 123 break;
samux 0:140cdf8e2d60 124 }
samux 0:140cdf8e2d60 125 break;
samux 0:140cdf8e2d60 126 default:
samux 0:140cdf8e2d60 127 break;
samux 0:140cdf8e2d60 128 }
samux 0:140cdf8e2d60 129 }
samux 0:140cdf8e2d60 130
samux 0:140cdf8e2d60 131 // Process class-specific requests
samux 0:140cdf8e2d60 132
samux 0:140cdf8e2d60 133 if (transfer->setup.bmRequestType.Type == CLASS_TYPE)
samux 0:140cdf8e2d60 134 {
samux 0:140cdf8e2d60 135 switch (transfer->setup.bRequest)
samux 0:140cdf8e2d60 136 {
samux 0:140cdf8e2d60 137 case SET_REPORT:
samux 0:140cdf8e2d60 138 // First byte will be used for report ID
samux 0:140cdf8e2d60 139 outputReport.data[0] = transfer->setup.wValue & 0xff;
samux 0:140cdf8e2d60 140 outputReport.length = transfer->setup.wLength + 1;
samux 0:140cdf8e2d60 141
samux 0:140cdf8e2d60 142 transfer->remaining = sizeof(outputReport.data) - 1;
samux 0:140cdf8e2d60 143 transfer->ptr = &outputReport.data[1];
samux 0:140cdf8e2d60 144 transfer->direction = HOST_TO_DEVICE;
samux 0:140cdf8e2d60 145 transfer->notify = true;
samux 0:140cdf8e2d60 146 success = true;
samux 0:140cdf8e2d60 147 default:
samux 0:140cdf8e2d60 148 break;
samux 0:140cdf8e2d60 149 }
samux 0:140cdf8e2d60 150 }
samux 0:140cdf8e2d60 151
samux 0:140cdf8e2d60 152 return success;
samux 0:140cdf8e2d60 153 }
samux 0:140cdf8e2d60 154
samux 0:140cdf8e2d60 155
samux 0:140cdf8e2d60 156 #define DEFAULT_CONFIGURATION (1)
samux 0:140cdf8e2d60 157
samux 0:140cdf8e2d60 158
samux 0:140cdf8e2d60 159 // Called in ISR context
samux 0:140cdf8e2d60 160 // Set configuration. Return false if the
samux 0:140cdf8e2d60 161 // configuration is not supported
samux 0:140cdf8e2d60 162 bool USBHID::USBCallback_setConfiguration(uint8_t configuration) {
samux 0:140cdf8e2d60 163 if (configuration != DEFAULT_CONFIGURATION) {
samux 0:140cdf8e2d60 164 return false;
samux 0:140cdf8e2d60 165 }
samux 0:140cdf8e2d60 166
samux 0:140cdf8e2d60 167 // Configure endpoints > 0
samux 0:140cdf8e2d60 168 addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT);
samux 0:140cdf8e2d60 169 addEndpoint(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
samux 0:140cdf8e2d60 170
samux 0:140cdf8e2d60 171 // We activate the endpoint to be able to recceive data
samux 0:140cdf8e2d60 172 readStart(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
samux 0:140cdf8e2d60 173 return true;
samux 0:140cdf8e2d60 174 }
samux 0:140cdf8e2d60 175
samux 0:140cdf8e2d60 176
samux 0:140cdf8e2d60 177 uint8_t * USBHID::stringIinterfaceDesc() {
samux 0:140cdf8e2d60 178 static uint8_t stringIinterfaceDescriptor[] = {
samux 0:140cdf8e2d60 179 0x08, //bLength
samux 0:140cdf8e2d60 180 STRING_DESCRIPTOR, //bDescriptorType 0x03
samux 0:140cdf8e2d60 181 'H',0,'I',0,'D',0, //bString iInterface - HID
samux 0:140cdf8e2d60 182 };
samux 0:140cdf8e2d60 183 return stringIinterfaceDescriptor;
samux 0:140cdf8e2d60 184 }
samux 0:140cdf8e2d60 185
samux 0:140cdf8e2d60 186 uint8_t * USBHID::stringIproductDesc() {
samux 0:140cdf8e2d60 187 static uint8_t stringIproductDescriptor[] = {
samux 0:140cdf8e2d60 188 0x16, //bLength
samux 0:140cdf8e2d60 189 STRING_DESCRIPTOR, //bDescriptorType 0x03
samux 0:140cdf8e2d60 190 'H',0,'I',0,'D',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0 //bString iProduct - HID device
samux 0:140cdf8e2d60 191 };
samux 0:140cdf8e2d60 192 return stringIproductDescriptor;
samux 0:140cdf8e2d60 193 }
samux 0:140cdf8e2d60 194
samux 0:140cdf8e2d60 195
samux 0:140cdf8e2d60 196
samux 0:140cdf8e2d60 197 uint8_t * USBHID::reportDesc() {
samux 0:140cdf8e2d60 198 static uint8_t reportDescriptor[] = {
samux 0:140cdf8e2d60 199 0x06, LSB(0xFFAB), MSB(0xFFAB),
samux 0:140cdf8e2d60 200 0x0A, LSB(0x0200), MSB(0x0200),
samux 0:140cdf8e2d60 201 0xA1, 0x01, // Collection 0x01
samux 0:140cdf8e2d60 202 0x75, 0x08, // report size = 8 bits
samux 0:140cdf8e2d60 203 0x15, 0x00, // logical minimum = 0
samux 0:140cdf8e2d60 204 0x26, 0xFF, 0x00, // logical maximum = 255
samux 0:140cdf8e2d60 205 0x95, input_length, // report count
samux 0:140cdf8e2d60 206 0x09, 0x01, // usage
samux 0:140cdf8e2d60 207 0x81, 0x02, // Input (array)
samux 0:140cdf8e2d60 208 0x95, output_length, // report count
samux 0:140cdf8e2d60 209 0x09, 0x02, // usage
samux 0:140cdf8e2d60 210 0x91, 0x02, // Output (array)
samux 0:140cdf8e2d60 211 0xC0 // end collection
samux 0:140cdf8e2d60 212
samux 0:140cdf8e2d60 213 };
samux 0:140cdf8e2d60 214 reportLength = sizeof(reportDescriptor);
samux 0:140cdf8e2d60 215 return reportDescriptor;
samux 0:140cdf8e2d60 216 }
samux 0:140cdf8e2d60 217
samux 0:140cdf8e2d60 218 #define DEFAULT_CONFIGURATION (1)
samux 0:140cdf8e2d60 219 #define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
samux 0:140cdf8e2d60 220 + (1 * INTERFACE_DESCRIPTOR_LENGTH) \
samux 0:140cdf8e2d60 221 + (1 * HID_DESCRIPTOR_LENGTH) \
samux 0:140cdf8e2d60 222 + (2 * ENDPOINT_DESCRIPTOR_LENGTH))
samux 0:140cdf8e2d60 223
samux 0:140cdf8e2d60 224 uint8_t * USBHID::configurationDesc() {
samux 0:140cdf8e2d60 225 static uint8_t configurationDescriptor[] = {
samux 0:140cdf8e2d60 226 CONFIGURATION_DESCRIPTOR_LENGTH,// bLength
samux 0:140cdf8e2d60 227 CONFIGURATION_DESCRIPTOR, // bDescriptorType
samux 0:140cdf8e2d60 228 LSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (LSB)
samux 0:140cdf8e2d60 229 MSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (MSB)
samux 0:140cdf8e2d60 230 0x01, // bNumInterfaces
samux 0:140cdf8e2d60 231 DEFAULT_CONFIGURATION, // bConfigurationValue
samux 0:140cdf8e2d60 232 0x00, // iConfiguration
samux 0:140cdf8e2d60 233 C_RESERVED | C_SELF_POWERED, // bmAttributes
samux 0:140cdf8e2d60 234 C_POWER(0), // bMaxPower
samux 0:140cdf8e2d60 235
samux 0:140cdf8e2d60 236 INTERFACE_DESCRIPTOR_LENGTH, // bLength
samux 0:140cdf8e2d60 237 INTERFACE_DESCRIPTOR, // bDescriptorType
samux 0:140cdf8e2d60 238 0x00, // bInterfaceNumber
samux 0:140cdf8e2d60 239 0x00, // bAlternateSetting
samux 0:140cdf8e2d60 240 0x02, // bNumEndpoints
samux 0:140cdf8e2d60 241 HID_CLASS, // bInterfaceClass
samux 0:140cdf8e2d60 242 HID_SUBCLASS_NONE, // bInterfaceSubClass
samux 0:140cdf8e2d60 243 HID_PROTOCOL_NONE, // bInterfaceProtocol
samux 0:140cdf8e2d60 244 0x00, // iInterface
samux 0:140cdf8e2d60 245
samux 0:140cdf8e2d60 246 HID_DESCRIPTOR_LENGTH, // bLength
samux 0:140cdf8e2d60 247 HID_DESCRIPTOR, // bDescriptorType
samux 0:140cdf8e2d60 248 LSB(HID_VERSION_1_11), // bcdHID (LSB)
samux 0:140cdf8e2d60 249 MSB(HID_VERSION_1_11), // bcdHID (MSB)
samux 0:140cdf8e2d60 250 0x00, // bCountryCode
samux 0:140cdf8e2d60 251 0x01, // bNumDescriptors
samux 0:140cdf8e2d60 252 REPORT_DESCRIPTOR, // bDescriptorType
samux 0:140cdf8e2d60 253 LSB(this->reportDescLength()), // wDescriptorLength (LSB)
samux 0:140cdf8e2d60 254 MSB(this->reportDescLength()), // wDescriptorLength (MSB)
samux 0:140cdf8e2d60 255
samux 0:140cdf8e2d60 256 ENDPOINT_DESCRIPTOR_LENGTH, // bLength
samux 0:140cdf8e2d60 257 ENDPOINT_DESCRIPTOR, // bDescriptorType
samux 0:140cdf8e2d60 258 PHY_TO_DESC(EPINT_IN), // bEndpointAddress
samux 0:140cdf8e2d60 259 E_INTERRUPT, // bmAttributes
samux 0:140cdf8e2d60 260 LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB)
samux 0:140cdf8e2d60 261 MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB)
samux 0:140cdf8e2d60 262 1, // bInterval (milliseconds)
samux 0:140cdf8e2d60 263
samux 0:140cdf8e2d60 264 ENDPOINT_DESCRIPTOR_LENGTH, // bLength
samux 0:140cdf8e2d60 265 ENDPOINT_DESCRIPTOR, // bDescriptorType
samux 0:140cdf8e2d60 266 PHY_TO_DESC(EPINT_OUT), // bEndpointAddress
samux 0:140cdf8e2d60 267 E_INTERRUPT, // bmAttributes
samux 0:140cdf8e2d60 268 LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB)
samux 0:140cdf8e2d60 269 MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB)
samux 0:140cdf8e2d60 270 1, // bInterval (milliseconds)
samux 0:140cdf8e2d60 271 };
samux 0:140cdf8e2d60 272 return configurationDescriptor;
samux 0:140cdf8e2d60 273 }