ADC Niose test Connect four analog signals to your MBED. and then run the Windows app. The four traces are displayed on an oscilloscope like display. I have used a USB HID DEVICE link, so connections to D+, D- are required. The MBED code is otherwise quite basic, So you can modify it to your own test needs. Additionaly, there is a 16 bit count value, in my MBED code Mainly to test if MSB & LSB are correct.

Dependencies:   mbed

Committer:
ceri
Date:
Sat Nov 19 22:54:22 2011 +0000
Revision:
0:cbe01b678bd4
just enough to work

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ceri 0:cbe01b678bd4 1 // USBHID.c
ceri 0:cbe01b678bd4 2 // Human Interface Device (HID) class
ceri 0:cbe01b678bd4 3 // Copyright (c) 2011 ARM Limited. All rights reserved.
ceri 0:cbe01b678bd4 4
ceri 0:cbe01b678bd4 5 #include "stdint.h"
ceri 0:cbe01b678bd4 6 #include "USBBusInterface.h"
ceri 0:cbe01b678bd4 7 #include "USBHID.h"
ceri 0:cbe01b678bd4 8
ceri 0:cbe01b678bd4 9
ceri 0:cbe01b678bd4 10 USBHID::USBHID(uint8_t output_report_length, uint8_t input_report_length, uint16_t vendor_id, uint16_t product_id, uint16_t product_release): USBDevice(vendor_id, product_id, product_release)
ceri 0:cbe01b678bd4 11 {
ceri 0:cbe01b678bd4 12 output_length = output_report_length;
ceri 0:cbe01b678bd4 13 input_length = input_report_length;
ceri 0:cbe01b678bd4 14 }
ceri 0:cbe01b678bd4 15
ceri 0:cbe01b678bd4 16
ceri 0:cbe01b678bd4 17 bool USBHID::send(HID_REPORT *report)
ceri 0:cbe01b678bd4 18 {
ceri 0:cbe01b678bd4 19 return write(EPINT_IN, report->data, report->length, MAX_HID_REPORT_SIZE);
ceri 0:cbe01b678bd4 20 }
ceri 0:cbe01b678bd4 21
ceri 0:cbe01b678bd4 22
ceri 0:cbe01b678bd4 23 bool USBHID::read(HID_REPORT *report)
ceri 0:cbe01b678bd4 24 {
ceri 0:cbe01b678bd4 25 uint16_t bytesRead = 0;
ceri 0:cbe01b678bd4 26 bool result;
ceri 0:cbe01b678bd4 27 result = USBDevice::read(EPINT_OUT, report->data, &bytesRead, MAX_HID_REPORT_SIZE);
ceri 0:cbe01b678bd4 28 if(!readStart(EPINT_OUT, MAX_HID_REPORT_SIZE))
ceri 0:cbe01b678bd4 29 return false;
ceri 0:cbe01b678bd4 30 report->length = bytesRead;
ceri 0:cbe01b678bd4 31 return result;
ceri 0:cbe01b678bd4 32 }
ceri 0:cbe01b678bd4 33
ceri 0:cbe01b678bd4 34
ceri 0:cbe01b678bd4 35 bool USBHID::readNB(HID_REPORT *report)
ceri 0:cbe01b678bd4 36 {
ceri 0:cbe01b678bd4 37 uint16_t bytesRead = 0;
ceri 0:cbe01b678bd4 38 bool result;
ceri 0:cbe01b678bd4 39 result = USBDevice::readNB(EPINT_OUT, report->data, &bytesRead, MAX_HID_REPORT_SIZE);
ceri 0:cbe01b678bd4 40 report->length = bytesRead;
ceri 0:cbe01b678bd4 41 if(!readStart(EPINT_OUT, MAX_HID_REPORT_SIZE))
ceri 0:cbe01b678bd4 42 return false;
ceri 0:cbe01b678bd4 43 return result;
ceri 0:cbe01b678bd4 44 }
ceri 0:cbe01b678bd4 45
ceri 0:cbe01b678bd4 46
ceri 0:cbe01b678bd4 47 uint16_t USBHID::reportDescLength() {
ceri 0:cbe01b678bd4 48 reportDesc();
ceri 0:cbe01b678bd4 49 return reportLength;
ceri 0:cbe01b678bd4 50 }
ceri 0:cbe01b678bd4 51
ceri 0:cbe01b678bd4 52
ceri 0:cbe01b678bd4 53
ceri 0:cbe01b678bd4 54 //
ceri 0:cbe01b678bd4 55 // Route callbacks from lower layers to class(es)
ceri 0:cbe01b678bd4 56 //
ceri 0:cbe01b678bd4 57
ceri 0:cbe01b678bd4 58
ceri 0:cbe01b678bd4 59 // Called in ISR context
ceri 0:cbe01b678bd4 60 // Called by USBDevice on Endpoint0 request
ceri 0:cbe01b678bd4 61 // This is used to handle extensions to standard requests
ceri 0:cbe01b678bd4 62 // and class specific requests
ceri 0:cbe01b678bd4 63 // Return true if class handles this request
ceri 0:cbe01b678bd4 64 bool USBHID::USBCallback_request() {
ceri 0:cbe01b678bd4 65 bool success = false;
ceri 0:cbe01b678bd4 66 CONTROL_TRANSFER * transfer = getTransferPtr();
ceri 0:cbe01b678bd4 67 uint8_t *hidDescriptor;
ceri 0:cbe01b678bd4 68
ceri 0:cbe01b678bd4 69 // Process additional standard requests
ceri 0:cbe01b678bd4 70
ceri 0:cbe01b678bd4 71 if ((transfer->setup.bmRequestType.Type == STANDARD_TYPE))
ceri 0:cbe01b678bd4 72 {
ceri 0:cbe01b678bd4 73 switch (transfer->setup.bRequest)
ceri 0:cbe01b678bd4 74 {
ceri 0:cbe01b678bd4 75 case GET_DESCRIPTOR:
ceri 0:cbe01b678bd4 76 switch (DESCRIPTOR_TYPE(transfer->setup.wValue))
ceri 0:cbe01b678bd4 77 {
ceri 0:cbe01b678bd4 78 case REPORT_DESCRIPTOR:
ceri 0:cbe01b678bd4 79 if ((reportDesc() != NULL) \
ceri 0:cbe01b678bd4 80 && (reportDescLength() != 0))
ceri 0:cbe01b678bd4 81 {
ceri 0:cbe01b678bd4 82 transfer->remaining = reportDescLength();
ceri 0:cbe01b678bd4 83 transfer->ptr = reportDesc();
ceri 0:cbe01b678bd4 84 transfer->direction = DEVICE_TO_HOST;
ceri 0:cbe01b678bd4 85 success = true;
ceri 0:cbe01b678bd4 86 }
ceri 0:cbe01b678bd4 87 break;
ceri 0:cbe01b678bd4 88 case HID_DESCRIPTOR:
ceri 0:cbe01b678bd4 89 // Find the HID descriptor, after the configuration descriptor
ceri 0:cbe01b678bd4 90 hidDescriptor = findDescriptor(HID_DESCRIPTOR);
ceri 0:cbe01b678bd4 91 if (hidDescriptor != NULL)
ceri 0:cbe01b678bd4 92 {
ceri 0:cbe01b678bd4 93 transfer->remaining = HID_DESCRIPTOR_LENGTH;
ceri 0:cbe01b678bd4 94 transfer->ptr = hidDescriptor;
ceri 0:cbe01b678bd4 95 transfer->direction = DEVICE_TO_HOST;
ceri 0:cbe01b678bd4 96 success = true;
ceri 0:cbe01b678bd4 97 }
ceri 0:cbe01b678bd4 98 break;
ceri 0:cbe01b678bd4 99
ceri 0:cbe01b678bd4 100 default:
ceri 0:cbe01b678bd4 101 break;
ceri 0:cbe01b678bd4 102 }
ceri 0:cbe01b678bd4 103 break;
ceri 0:cbe01b678bd4 104 default:
ceri 0:cbe01b678bd4 105 break;
ceri 0:cbe01b678bd4 106 }
ceri 0:cbe01b678bd4 107 }
ceri 0:cbe01b678bd4 108
ceri 0:cbe01b678bd4 109 // Process class-specific requests
ceri 0:cbe01b678bd4 110
ceri 0:cbe01b678bd4 111 if (transfer->setup.bmRequestType.Type == CLASS_TYPE)
ceri 0:cbe01b678bd4 112 {
ceri 0:cbe01b678bd4 113 switch (transfer->setup.bRequest)
ceri 0:cbe01b678bd4 114 {
ceri 0:cbe01b678bd4 115 case SET_REPORT:
ceri 0:cbe01b678bd4 116 // First byte will be used for report ID
ceri 0:cbe01b678bd4 117 outputReport.data[0] = transfer->setup.wValue & 0xff;
ceri 0:cbe01b678bd4 118 outputReport.length = transfer->setup.wLength + 1;
ceri 0:cbe01b678bd4 119
ceri 0:cbe01b678bd4 120 transfer->remaining = sizeof(outputReport.data) - 1;
ceri 0:cbe01b678bd4 121 transfer->ptr = &outputReport.data[1];
ceri 0:cbe01b678bd4 122 transfer->direction = HOST_TO_DEVICE;
ceri 0:cbe01b678bd4 123 transfer->notify = true;
ceri 0:cbe01b678bd4 124 success = true;
ceri 0:cbe01b678bd4 125 default:
ceri 0:cbe01b678bd4 126 break;
ceri 0:cbe01b678bd4 127 }
ceri 0:cbe01b678bd4 128 }
ceri 0:cbe01b678bd4 129
ceri 0:cbe01b678bd4 130 return success;
ceri 0:cbe01b678bd4 131 }
ceri 0:cbe01b678bd4 132
ceri 0:cbe01b678bd4 133
ceri 0:cbe01b678bd4 134 // Called in ISR context
ceri 0:cbe01b678bd4 135 // Called by USBDevice on Endpoint0 request completion
ceri 0:cbe01b678bd4 136 // if the 'notify' flag has been set to true
ceri 0:cbe01b678bd4 137 // In this case it is used to indicate that a HID report has
ceri 0:cbe01b678bd4 138 // been received from the host on endpoint 0
ceri 0:cbe01b678bd4 139 void USBHID::USBCallback_requestCompleted() {
ceri 0:cbe01b678bd4 140 HID_callbackSetReport(&outputReport);
ceri 0:cbe01b678bd4 141 }
ceri 0:cbe01b678bd4 142
ceri 0:cbe01b678bd4 143 #define DEFAULT_CONFIGURATION (1)
ceri 0:cbe01b678bd4 144
ceri 0:cbe01b678bd4 145
ceri 0:cbe01b678bd4 146 // Called in ISR context
ceri 0:cbe01b678bd4 147 // Set configuration. Return false if the
ceri 0:cbe01b678bd4 148 // configuration is not supported
ceri 0:cbe01b678bd4 149 bool USBHID::USBCallback_setConfiguration(uint8_t configuration) {
ceri 0:cbe01b678bd4 150 if (configuration != DEFAULT_CONFIGURATION) {
ceri 0:cbe01b678bd4 151 return false;
ceri 0:cbe01b678bd4 152 }
ceri 0:cbe01b678bd4 153
ceri 0:cbe01b678bd4 154 // Configure endpoints > 0
ceri 0:cbe01b678bd4 155 addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT);
ceri 0:cbe01b678bd4 156 addEndpoint(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
ceri 0:cbe01b678bd4 157
ceri 0:cbe01b678bd4 158 // We activate the endpoint to be able to recceive data
ceri 0:cbe01b678bd4 159 readStart(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
ceri 0:cbe01b678bd4 160 return true;
ceri 0:cbe01b678bd4 161 }
ceri 0:cbe01b678bd4 162
ceri 0:cbe01b678bd4 163 uint8_t * USBHID::stringIinterfaceDesc() {
ceri 0:cbe01b678bd4 164 static uint8_t stringIinterfaceDescriptor[] = {
ceri 0:cbe01b678bd4 165 0x08, //bLength
ceri 0:cbe01b678bd4 166 STRING_DESCRIPTOR, //bDescriptorType 0x03
ceri 0:cbe01b678bd4 167 'H',0,'I',0,'D',0, //bString iInterface - HID
ceri 0:cbe01b678bd4 168 };
ceri 0:cbe01b678bd4 169 return stringIinterfaceDescriptor;
ceri 0:cbe01b678bd4 170 }
ceri 0:cbe01b678bd4 171
ceri 0:cbe01b678bd4 172 uint8_t * USBHID::stringIproductDesc() {
ceri 0:cbe01b678bd4 173 static uint8_t stringIproductDescriptor[] = {
ceri 0:cbe01b678bd4 174 0x16, //bLength
ceri 0:cbe01b678bd4 175 STRING_DESCRIPTOR, //bDescriptorType 0x03
ceri 0:cbe01b678bd4 176 'H',0,'I',0,'D',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0 //bString iProduct - HID device
ceri 0:cbe01b678bd4 177 };
ceri 0:cbe01b678bd4 178 return stringIproductDescriptor;
ceri 0:cbe01b678bd4 179 }
ceri 0:cbe01b678bd4 180
ceri 0:cbe01b678bd4 181
ceri 0:cbe01b678bd4 182
ceri 0:cbe01b678bd4 183 uint8_t * USBHID::reportDesc() {
ceri 0:cbe01b678bd4 184 static uint8_t reportDescriptor[] = {
ceri 0:cbe01b678bd4 185 0x06, LSB(0xFFAB), MSB(0xFFAB),
ceri 0:cbe01b678bd4 186 0x0A, LSB(0x0200), MSB(0x0200),
ceri 0:cbe01b678bd4 187 0xA1, 0x01, // Collection 0x01
ceri 0:cbe01b678bd4 188 0x75, 0x08, // report size = 8 bits
ceri 0:cbe01b678bd4 189 0x15, 0x00, // logical minimum = 0
ceri 0:cbe01b678bd4 190 0x26, 0xFF, 0x00, // logical maximum = 255
ceri 0:cbe01b678bd4 191 0x95, input_length, // report count
ceri 0:cbe01b678bd4 192 0x09, 0x01, // usage
ceri 0:cbe01b678bd4 193 0x81, 0x02, // Input (array)
ceri 0:cbe01b678bd4 194 0x95, output_length, // report count
ceri 0:cbe01b678bd4 195 0x09, 0x02, // usage
ceri 0:cbe01b678bd4 196 0x91, 0x02, // Output (array)
ceri 0:cbe01b678bd4 197 0xC0 // end collection
ceri 0:cbe01b678bd4 198
ceri 0:cbe01b678bd4 199 };
ceri 0:cbe01b678bd4 200 reportLength = sizeof(reportDescriptor);
ceri 0:cbe01b678bd4 201 return reportDescriptor;
ceri 0:cbe01b678bd4 202 }
ceri 0:cbe01b678bd4 203
ceri 0:cbe01b678bd4 204 #define DEFAULT_CONFIGURATION (1)
ceri 0:cbe01b678bd4 205 #define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
ceri 0:cbe01b678bd4 206 + (1 * INTERFACE_DESCRIPTOR_LENGTH) \
ceri 0:cbe01b678bd4 207 + (1 * HID_DESCRIPTOR_LENGTH) \
ceri 0:cbe01b678bd4 208 + (2 * ENDPOINT_DESCRIPTOR_LENGTH))
ceri 0:cbe01b678bd4 209
ceri 0:cbe01b678bd4 210 uint8_t * USBHID::configurationDesc() {
ceri 0:cbe01b678bd4 211 static uint8_t configurationDescriptor[] = {
ceri 0:cbe01b678bd4 212 CONFIGURATION_DESCRIPTOR_LENGTH,// bLength
ceri 0:cbe01b678bd4 213 CONFIGURATION_DESCRIPTOR, // bDescriptorType
ceri 0:cbe01b678bd4 214 LSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (LSB)
ceri 0:cbe01b678bd4 215 MSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (MSB)
ceri 0:cbe01b678bd4 216 0x01, // bNumInterfaces
ceri 0:cbe01b678bd4 217 DEFAULT_CONFIGURATION, // bConfigurationValue
ceri 0:cbe01b678bd4 218 0x00, // iConfiguration
ceri 0:cbe01b678bd4 219 C_RESERVED | C_SELF_POWERED, // bmAttributes
ceri 0:cbe01b678bd4 220 C_POWER(0), // bMaxPower
ceri 0:cbe01b678bd4 221
ceri 0:cbe01b678bd4 222 INTERFACE_DESCRIPTOR_LENGTH, // bLength
ceri 0:cbe01b678bd4 223 INTERFACE_DESCRIPTOR, // bDescriptorType
ceri 0:cbe01b678bd4 224 0x00, // bInterfaceNumber
ceri 0:cbe01b678bd4 225 0x00, // bAlternateSetting
ceri 0:cbe01b678bd4 226 0x02, // bNumEndpoints
ceri 0:cbe01b678bd4 227 HID_CLASS, // bInterfaceClass
ceri 0:cbe01b678bd4 228 HID_SUBCLASS_NONE, // bInterfaceSubClass
ceri 0:cbe01b678bd4 229 HID_PROTOCOL_NONE, // bInterfaceProtocol
ceri 0:cbe01b678bd4 230 0x00, // iInterface
ceri 0:cbe01b678bd4 231
ceri 0:cbe01b678bd4 232 HID_DESCRIPTOR_LENGTH, // bLength
ceri 0:cbe01b678bd4 233 HID_DESCRIPTOR, // bDescriptorType
ceri 0:cbe01b678bd4 234 LSB(HID_VERSION_1_11), // bcdHID (LSB)
ceri 0:cbe01b678bd4 235 MSB(HID_VERSION_1_11), // bcdHID (MSB)
ceri 0:cbe01b678bd4 236 0x00, // bCountryCode
ceri 0:cbe01b678bd4 237 0x01, // bNumDescriptors
ceri 0:cbe01b678bd4 238 REPORT_DESCRIPTOR, // bDescriptorType
ceri 0:cbe01b678bd4 239 LSB(this->reportDescLength()), // wDescriptorLength (LSB)
ceri 0:cbe01b678bd4 240 MSB(this->reportDescLength()), // wDescriptorLength (MSB)
ceri 0:cbe01b678bd4 241
ceri 0:cbe01b678bd4 242 ENDPOINT_DESCRIPTOR_LENGTH, // bLength
ceri 0:cbe01b678bd4 243 ENDPOINT_DESCRIPTOR, // bDescriptorType
ceri 0:cbe01b678bd4 244 PHY_TO_DESC(EPINT_IN), // bEndpointAddress
ceri 0:cbe01b678bd4 245 E_INTERRUPT, // bmAttributes
ceri 0:cbe01b678bd4 246 LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB)
ceri 0:cbe01b678bd4 247 MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB)
ceri 0:cbe01b678bd4 248 10, // bInterval (milliseconds)
ceri 0:cbe01b678bd4 249
ceri 0:cbe01b678bd4 250 ENDPOINT_DESCRIPTOR_LENGTH, // bLength
ceri 0:cbe01b678bd4 251 ENDPOINT_DESCRIPTOR, // bDescriptorType
ceri 0:cbe01b678bd4 252 PHY_TO_DESC(EPINT_OUT), // bEndpointAddress
ceri 0:cbe01b678bd4 253 E_INTERRUPT, // bmAttributes
ceri 0:cbe01b678bd4 254 LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB)
ceri 0:cbe01b678bd4 255 MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB)
ceri 0:cbe01b678bd4 256 10, // bInterval (milliseconds)
ceri 0:cbe01b678bd4 257 };
ceri 0:cbe01b678bd4 258 return configurationDescriptor;
ceri 0:cbe01b678bd4 259 }