HID class driver fixes

This commit is contained in:
Diego Ismirlian 2017-06-06 09:24:10 -03:00
parent 108ae2534c
commit 1bb8f56c3b
2 changed files with 44 additions and 19 deletions

View File

@ -62,14 +62,21 @@ typedef enum {
USBHHID_REPORTTYPE_FEATURE = 3,
} usbhhid_reporttype_t;
typedef enum {
USBHHID_PROTOCOL_BOOT = 0,
USBHHID_PROTOCOL_REPORT = 1,
} usbhhid_protocol_t;
typedef struct USBHHIDDriver USBHHIDDriver;
typedef struct USBHHIDConfig USBHHIDConfig;
typedef void (*usbhhid_report_callback)(USBHHIDDriver *hidp);
typedef void (*usbhhid_report_callback)(USBHHIDDriver *hidp, uint16_t len);
struct USBHHIDConfig {
usbhhid_report_callback cb_report;
void *report_buffer;
uint16_t report_len;
usbhhid_protocol_t protocol;
};
struct USBHHIDDriver {
@ -94,14 +101,13 @@ struct USBHHIDDriver {
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
#define usbhhidGetState(hidp) ((hidp)->state)
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
extern USBHHIDDriver USBHHID[HAL_USBHHID_MAX_INSTANCES];
extern USBHHIDDriver USBHHIDD[HAL_USBHHID_MAX_INSTANCES];
#ifdef __cplusplus
extern "C" {
@ -125,6 +131,12 @@ extern "C" {
return hidp->type;
}
static inline usbhhid_state_t usbhhidGetState(USBHHIDDriver *hidp) {
return hidp->state;
}
void usbhhidStart(USBHHIDDriver *hidp, const USBHHIDConfig *cfg);
/* global initializer */
void usbhhidInit(void);
#ifdef __cplusplus

View File

@ -72,7 +72,7 @@
/* USB Class driver loader for MSD */
/*===========================================================================*/
USBHHIDDriver USBHHID[HAL_USBHHID_MAX_INSTANCES];
USBHHIDDriver USBHHIDD[HAL_USBHHID_MAX_INSTANCES];
static usbh_baseclassdriver_t *_hid_load(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem);
static void _hid_unload(usbh_baseclassdriver_t *drv);
@ -103,8 +103,8 @@ static usbh_baseclassdriver_t *_hid_load(usbh_device_t *dev, const uint8_t *desc
/* alloc driver */
for (i = 0; i < HAL_USBHHID_MAX_INSTANCES; i++) {
if (USBHHID[i].dev == NULL) {
hidp = &USBHHID[i];
if (USBHHIDD[i].dev == NULL) {
hidp = &USBHHIDD[i];
goto alloc_ok;
}
}
@ -153,9 +153,10 @@ alloc_ok:
if (ifdesc->bInterfaceSubClass != 0x01) {
hidp->type = USBHHID_DEVTYPE_GENERIC;
uinfof("HID: bInterfaceSubClass=%02x, generic HID");
uinfof("HID: bInterfaceSubClass=%02x, generic HID", ifdesc->bInterfaceSubClass);
if (ifdesc->bInterfaceSubClass != 0x00) {
uinfof("HID: bInterfaceSubClass=%02x is an invalid bInterfaceSubClass value");
uinfof("HID: bInterfaceSubClass=%02x is an invalid bInterfaceSubClass value",
ifdesc->bInterfaceSubClass);
}
} else if (ifdesc->bInterfaceProtocol == 0x01) {
hidp->type = USBHHID_DEVTYPE_BOOT_KEYBOARD;
@ -164,7 +165,8 @@ alloc_ok:
hidp->type = USBHHID_DEVTYPE_BOOT_MOUSE;
uinfo("HID: BOOT protocol mouse found");
} else {
uerrf("HID: bInterfaceProtocol=%02x is an invalid boot protocol, abort");
uerrf("HID: bInterfaceProtocol=%02x is an invalid boot protocol, abort",
ifdesc->bInterfaceProtocol);
goto deinit;
}
@ -185,12 +187,17 @@ static void _in_cb(usbh_urb_t *urb) {
USBHHIDDriver *const hidp = (USBHHIDDriver *)urb->userData;
switch (urb->status) {
case USBH_URBSTATUS_OK:
if (hidp->config->cb_report) {
hidp->config->cb_report(hidp, urb->actualLength);
}
break;
case USBH_URBSTATUS_DISCONNECTED:
uwarn("HID: URB IN disconnected");
return;
case USBH_URBSTATUS_TIMEOUT:
//no data
break;
default:
uerrf("HID: URB IN status unexpected = %d", urb->status);
break;
@ -200,7 +207,8 @@ static void _in_cb(usbh_urb_t *urb) {
}
void usbhhidStart(USBHHIDDriver *hidp, const USBHHIDConfig *cfg) {
osalDbgCheck(hidp && cfg && cfg->report_buffer);
osalDbgCheck(hidp && cfg);
osalDbgCheck(cfg->report_buffer && (cfg->protocol <= USBHHID_PROTOCOL_REPORT));
osalDbgCheck((hidp->state == USBHHID_STATE_ACTIVE)
|| (hidp->state == USBHHID_STATE_READY));
@ -210,7 +218,8 @@ void usbhhidStart(USBHHIDDriver *hidp, const USBHHIDConfig *cfg) {
hidp->config = cfg;
/* init the URBs */
usbhURBObjectInit(&hidp->in_urb, &hidp->epin, _in_cb, hidp, hidp->config->report_buffer, 64);
usbhURBObjectInit(&hidp->in_urb, &hidp->epin, _in_cb, hidp,
cfg->report_buffer, cfg->report_len);
/* open the int IN/OUT endpoints */
usbhEPOpen(&hidp->epin);
@ -220,6 +229,8 @@ void usbhhidStart(USBHHIDDriver *hidp, const USBHHIDConfig *cfg) {
}
#endif
usbhhidSetProtocol(hidp, cfg->protocol);
osalSysLock();
usbhURBSubmitI(&hidp->in_urb);
osalSysUnlock();
@ -251,7 +262,8 @@ usbh_urbstatus_t usbhhidGetReport(USBHHIDDriver *hidp,
osalDbgCheck(hidp);
osalDbgAssert((uint8_t)report_type <= USBHHID_REPORTTYPE_FEATURE, "wrong report type");
return usbhControlRequest(hidp->dev,
USBH_CLASSIN(USBH_REQTYPE_INTERFACE, USBH_HID_REQ_GET_REPORT, ((uint8_t)report_type << 8) | report_id, hidp->ifnum),
USBH_CLASSIN(USBH_REQTYPE_INTERFACE, USBH_HID_REQ_GET_REPORT,
((uint8_t)report_type << 8) | report_id, hidp->ifnum),
len, data);
}
@ -261,7 +273,8 @@ usbh_urbstatus_t usbhhidSetReport(USBHHIDDriver *hidp,
osalDbgCheck(hidp);
osalDbgAssert((uint8_t)report_type <= USBHHID_REPORTTYPE_FEATURE, "wrong report type");
return usbhControlRequest(hidp->dev,
USBH_CLASSOUT(USBH_REQTYPE_INTERFACE, USBH_HID_REQ_SET_REPORT, ((uint8_t)report_type << 8) | report_id, hidp->ifnum),
USBH_CLASSOUT(USBH_REQTYPE_INTERFACE, USBH_HID_REQ_SET_REPORT,
((uint8_t)report_type << 8) | report_id, hidp->ifnum),
len, (void *)data);
}
@ -275,8 +288,8 @@ usbh_urbstatus_t usbhhidGetIdle(USBHHIDDriver *hidp, uint8_t report_id, uint8_t
usbh_urbstatus_t usbhhidSetIdle(USBHHIDDriver *hidp, uint8_t report_id, uint8_t duration) {
osalDbgCheck(hidp);
return usbhControlRequest(hidp->dev,
USBH_CLASSOUT(USBH_REQTYPE_INTERFACE, USBH_HID_REQ_SET_IDLE, (duration << 8) | report_id, hidp->ifnum),
0, NULL);
USBH_CLASSOUT(USBH_REQTYPE_INTERFACE, USBH_HID_REQ_SET_IDLE,
(duration << 8) | report_id, hidp->ifnum), 0, NULL);
}
usbh_urbstatus_t usbhhidGetProtocol(USBHHIDDriver *hidp, uint8_t *protocol) {
@ -290,8 +303,8 @@ usbh_urbstatus_t usbhhidSetProtocol(USBHHIDDriver *hidp, uint8_t protocol) {
osalDbgCheck(hidp);
osalDbgAssert(protocol <= 1, "invalid protocol");
return usbhControlRequest(hidp->dev,
USBH_CLASSOUT(USBH_REQTYPE_INTERFACE, USBH_HID_REQ_SET_PROTOCOL, protocol, hidp->ifnum),
0, NULL);
USBH_CLASSOUT(USBH_REQTYPE_INTERFACE, USBH_HID_REQ_SET_PROTOCOL,
protocol, hidp->ifnum), 0, NULL);
}
void usbhhidObjectInit(USBHHIDDriver *hidp) {
@ -304,7 +317,7 @@ void usbhhidObjectInit(USBHHIDDriver *hidp) {
void usbhhidInit(void) {
uint8_t i;
for (i = 0; i < HAL_USBHHID_MAX_INSTANCES; i++) {
usbhhidObjectInit(&USBHHID[i]);
usbhhidObjectInit(&USBHHIDD[i]);
}
}