Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
USBDevice/USBHID/.svn/text-base/USBHID.cpp.svn-base
- Committer:
- znuh
- Date:
- 2011-11-29
- Revision:
- 0:505207de8566
File content as of revision 0:505207de8566:
/* USBHID.c */
/* Human Interface Device (HID) class */
/* Copyright (c) 2011 ARM Limited. All rights reserved. */
#include "stdint.h"
#include "USBBusInterface.h"
#include "USBHID.h"
/* Output report from SET_REPORT request */
static HID_REPORT outputReport;
bool USBHID::USBClass_HID_request(void)
{
/* Called in ISR context */
bool success = false;
CONTROL_TRANSFER *transfer = USBDevice_getTransferPtr();
uint8_t *hidDescriptor;
/* Process additional standard requests */
if ((transfer->setup.bmRequestType.Type == STANDARD_TYPE))
{
switch (transfer->setup.bRequest)
{
case GET_DESCRIPTOR:
switch (DESCRIPTOR_TYPE(transfer->setup.wValue))
{
case REPORT_DESCRIPTOR:
if ((ReportDesc() != NULL) \
&& (ReportDescLength() != 0))
{
transfer->remaining = ReportDescLength();
transfer->ptr = ReportDesc();
transfer->direction = DEVICE_TO_HOST;
success = true;
}
break;
case HID_DESCRIPTOR:
/* Find the HID descriptor, after the configuration descriptor */
hidDescriptor = USBDevice_findDescriptor(HID_DESCRIPTOR);
if (hidDescriptor != NULL) /* NULL = Not found */
{
transfer->remaining = HID_DESCRIPTOR_LENGTH;
transfer->ptr = hidDescriptor;
transfer->direction = DEVICE_TO_HOST;
success = true;
}
break;
default:
break;
}
break;
default:
break;
}
}
/* Process class-specific requests */
if (transfer->setup.bmRequestType.Type == CLASS_TYPE)
{
switch (transfer->setup.bRequest)
{
case SET_REPORT:
/* First byte will be used for report ID */
outputReport.data[0] = transfer->setup.wValue & 0xff;
outputReport.length = transfer->setup.wLength + 1;
transfer->remaining = sizeof(outputReport.data) - 1;
transfer->ptr = &outputReport.data[1];
transfer->direction = HOST_TO_DEVICE;
transfer->notify = true; /* Callback on completion */
success = true;
default:
break;
}
}
return success;
}
void USBHID::USBClass_HID_requestCompleted(void)
{
/* SET_REPORT request - data is now valid */
HID_callbackSetReport(&outputReport);
}
bool USBHID::USBHID_send(uint8_t endpoint, HID_REPORT *report)
{
return USBDevice_write(endpoint, report->data, report->length, MAX_HID_REPORT_SIZE);
}
bool USBHID::USBHID_read(uint8_t endpoint, HID_REPORT *report)
{
uint16_t bytesRead = 0;
bool result;
if(!USBDevice_readStart(endpoint, MAX_HID_REPORT_SIZE))
return false;
result = USBDevice_read(endpoint, report->data, &bytesRead, MAX_HID_REPORT_SIZE);
report->length = bytesRead;
return result;
}
bool USBHID::USBHID_readNB(uint8_t endpoint, HID_REPORT *report)
{
uint16_t bytesRead = 0;
bool result;
if(!USBDevice_readStart(endpoint, MAX_HID_REPORT_SIZE))
return false;
result = USBDevice_readNB(endpoint, report->data, &bytesRead, MAX_HID_REPORT_SIZE);
report->length = bytesRead;
return result;
}
#define DEFAULT_CONFIGURATION (1)
USBHID::USBHID(uint16_t vendor_id, uint16_t product_id, uint16_t product_release): USBDevice(vendor_id, product_id, product_release)
{
USBDevice_init();
USBDevice_connect();
}
uint16_t USBHID::ReportDescLength() {
ReportDesc();
return reportLength;
}
/*
* Route callbacks from lower layers to class(es)
*/
void USBHID::USBCallback_busReset(void) {
/* Called in ISR context */
/* Called by USBDevice layer on bus reset */
/* May be used to reset state */
}
bool USBHID::USBCallback_request() {
/* Called in ISR context */
/* Called by USBDevice on Endpoint0 request */
/* This is used to handle extensions to standard requests */
/* and class specific requests. */
/* Return true if class handles this request */
return USBClass_HID_request();
}
void USBHID::USBCallback_requestCompleted() {
/* Called in ISR context */
/* Called by USBDevice on Endpoint0 request completion */
/* if the 'notify' flag has been set to true */
/* In this case it is used to indicate that a HID report has */
/* been received from the host on endpoint 0 */
USBClass_HID_requestCompleted();
}
void USBHID::HID_callbackSetReport(HID_REPORT *report) {
/* Called in ISR context */
/* HID Report received by SET_REPORT request */
/* First byte of data will be the report ID */
}
bool USBHID::USBCallback_setConfiguration(uint8_t configuration) {
/* Called in ISR context */
/* Set configuration. Return false if the */
/* configuration is not supported. */
if (configuration != DEFAULT_CONFIGURATION) {
return false;
}
/* Configure endpoints > 0 */
USBDevice_addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT);
return true;
}
uint8_t * USBHID::StringIinterfaceDesc() {
static uint8_t stringIinterfaceDescriptor[] = {
0x08, /*bLength*/
STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
'H',0,'I',0,'D',0, /*bString iInterface - HID*/
};
return stringIinterfaceDescriptor;
}
uint8_t * USBHID::StringIproductDesc() {
static uint8_t stringIproductDescriptor[] = {
0x16, /*bLength*/
STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
'H',0,'I',0,'D',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0 /*bString iProduct - HID device*/
};
return stringIproductDescriptor;
}
#define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
+ (1 * INTERFACE_DESCRIPTOR_LENGTH) \
+ (1 * HID_DESCRIPTOR_LENGTH) \
+ (1 * ENDPOINT_DESCRIPTOR_LENGTH))
uint8_t * USBHID::ConfigurationDesc() {
static uint8_t configurationDescriptor[] = {
CONFIGURATION_DESCRIPTOR_LENGTH,/* bLength */
CONFIGURATION_DESCRIPTOR, /* bDescriptorType */
LSB(TOTAL_DESCRIPTOR_LENGTH), /* wTotalLength (LSB) */
MSB(TOTAL_DESCRIPTOR_LENGTH), /* wTotalLength (MSB) */
0x01, /* bNumInterfaces */
DEFAULT_CONFIGURATION, /* bConfigurationValue */
0x00, /* iConfiguration */
C_RESERVED | C_SELF_POWERED, /* bmAttributes */
C_POWER(0), /* bMaxPower */
INTERFACE_DESCRIPTOR_LENGTH, /* bLength */
INTERFACE_DESCRIPTOR, /* bDescriptorType */
0x00, /* bInterfaceNumber */
0x00, /* bAlternateSetting */
0x01, /* bNumEndpoints */
HID_CLASS, /* bInterfaceClass */
HID_SUBCLASS_NONE, /* bInterfaceSubClass */
HID_PROTOCOL_NONE, /* bInterfaceProtocol */
0x00, /* iInterface */
HID_DESCRIPTOR_LENGTH, /* bLength */
HID_DESCRIPTOR, /* bDescriptorType */
LSB(HID_VERSION_1_11), /* bcdHID (LSB) */
MSB(HID_VERSION_1_11), /* bcdHID (MSB) */
0x00, /* bCountryCode */
0x01, /* bNumDescriptors */
REPORT_DESCRIPTOR, /* bDescriptorType */
LSB(this->ReportDescLength()), /* wDescriptorLength (LSB) */
MSB(this->ReportDescLength()), /* wDescriptorLength (MSB) */
ENDPOINT_DESCRIPTOR_LENGTH, /* bLength */
ENDPOINT_DESCRIPTOR, /* bDescriptorType */
PHY_TO_DESC(EPINT_IN), /* bEndpointAddress */
E_INTERRUPT, /* bmAttributes */
LSB(MAX_PACKET_SIZE_EPINT), /* wMaxPacketSize (LSB) */
MSB(MAX_PACKET_SIZE_EPINT), /* wMaxPacketSize (MSB) */
10, /* bInterval (milliseconds) */
};
return configurationDescriptor;
}