Slingshot Controller

Dependencies:   ADXL345 DebounceIn USBDevice mbed

Committer:
Brandon
Date:
Sun Oct 14 18:58:38 2012 +0000
Revision:
0:cf17ea89fd09
lab3

Who changed what in which revision?

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