USBH: Added mechanism for out-of-tree class driver enumeration

This commit is contained in:
Diego Ismirlian 2017-07-09 18:30:46 -03:00
parent c938866844
commit 025ca5345a
19 changed files with 349 additions and 104 deletions

View File

@ -48,6 +48,10 @@
#define HAL_USBH_USE_HID FALSE
#endif
#ifndef HAL_USBH_USE_ADDITIONAL_CLASS_DRIVERS
#define HAL_USBH_USE_ADDITIONAL_CLASS_DRIVERS FALSE
#endif
#define HAL_USBH_USE_IAD HAL_USBH_USE_UVC
#if (HAL_USE_USBH == TRUE) || defined(__DOXYGEN__)
@ -402,8 +406,10 @@ extern "C" {
typedef struct usbh_classdriver_vmt usbh_classdriver_vmt_t;
struct usbh_classdriver_vmt {
void (*init)(void);
usbh_baseclassdriver_t *(*load)(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem);
void (*unload)(usbh_baseclassdriver_t *drv);
/* TODO: add power control, suspend, etc */
};
struct usbh_classdriverinfo {

View File

@ -140,12 +140,8 @@ extern USBHAOADriver USBHAOAD[HAL_USBHAOA_MAX_INSTANCES];
extern "C" {
#endif
/* AOA device driver */
void usbhaoaObjectInit(USBHAOADriver *aoap);
void usbhaoaChannelStart(USBHAOADriver *aoap);
void usbhaoaChannelStop(USBHAOADriver *aoap);
/* global initializer */
void usbhaoaInit(void);
#ifdef __cplusplus
}
#endif

View File

@ -138,16 +138,9 @@ extern USBHFTDIPortDriver FTDIPD[HAL_USBHFTDI_MAX_PORTS];
#ifdef __cplusplus
extern "C" {
#endif
/* FTDI device driver */
void usbhftdiObjectInit(USBHFTDIDriver *ftdip);
/* FTDI port driver */
void usbhftdipObjectInit(USBHFTDIPortDriver *ftdipp);
void usbhftdipStart(USBHFTDIPortDriver *ftdipp, const USBHFTDIPortConfig *config);
void usbhftdipStop(USBHFTDIPortDriver *ftdipp);
/* global initializer */
void usbhftdiInit(void);
#ifdef __cplusplus
}
#endif

View File

@ -112,9 +112,6 @@ extern USBHHIDDriver USBHHIDD[HAL_USBHHID_MAX_INSTANCES];
#ifdef __cplusplus
extern "C" {
#endif
/* HID Driver */
void usbhHIDObjectInit(USBHHIDDriver *hidp);
/* HID Common API */
usbh_urbstatus_t usbhhidGetReport(USBHHIDDriver *hidp,
uint8_t report_id, usbhhid_reporttype_t report_type,
@ -136,9 +133,6 @@ extern "C" {
}
void usbhhidStart(USBHHIDDriver *hidp, const USBHHIDConfig *cfg);
/* global initializer */
void usbhhidInit(void);
#ifdef __cplusplus
}
#endif

View File

@ -88,10 +88,6 @@ static inline usbh_urbstatus_t usbhhubSetFeaturePort(usbh_port_t *port, uint8_t
0);
}
void usbhhubObjectInit(USBHHubDriver *hubdp);
void usbhhubInit(void);
#else
static inline usbh_urbstatus_t usbhhubControlRequest(USBHDriver *host,

View File

@ -109,9 +109,6 @@ extern "C" {
bool usbhmsdLUNGetInfo(USBHMassStorageLUNDriver *lunp, BlockDeviceInfo *bdip);
bool usbhmsdLUNIsInserted(USBHMassStorageLUNDriver *lunp);
bool usbhmsdLUNIsProtected(USBHMassStorageLUNDriver *lunp);
/* global initializer */
void usbhmsdInit(void);
#ifdef __cplusplus
}
#endif

View File

@ -394,9 +394,6 @@ extern USBHUVCDriver USBHUVCD[HAL_USBHUVC_MAX_INSTANCES];
#ifdef __cplusplus
extern "C" {
#endif
void usbhuvcObjectInit(USBHUVCDriver *uvcd);
static inline usbhuvc_state_t usbhuvcGetState(USBHUVCDriver *uvcd) {
return uvcd->state;
}
@ -457,11 +454,6 @@ extern "C" {
static inline void usbhuvcFreeStatusMessage(USBHUVCDriver *uvcdp, usbhuvc_message_status_t *msg) {
chPoolFree(&uvcdp->mp_status, msg);
}
/* global initializer */
void usbhuvcInit(void);
#ifdef __cplusplus
}
#endif

View File

@ -66,6 +66,12 @@ static void _classdriver_process_device(usbh_device_t *dev);
static bool _classdriver_load(usbh_device_t *dev, uint8_t class,
uint8_t subclass, uint8_t protocol, uint8_t *descbuff, uint16_t rem);
#if HAL_USBH_USE_ADDITIONAL_CLASS_DRIVERS
#include "usbh_additional_class_drivers.h"
#ifndef HAL_USBH_ADDITIONAL_CLASS_DRIVERS
#error "Must define HAL_USBH_ADDITIONAL_CLASS_DRIVERS"
#endif
#endif
/*===========================================================================*/
/* Checks. */
@ -105,28 +111,6 @@ void usbhObjectInit(USBHDriver *usbh) {
#endif
}
void usbhInit(void) {
#if HAL_USBH_USE_FTDI
usbhftdiInit();
#endif
#if HAL_USBH_USE_AOA
usbhaoaInit();
#endif
#if HAL_USBH_USE_MSD
usbhmsdInit();
#endif
#if HAL_USBH_USE_HID
usbhhidInit();
#endif
#if HAL_USBH_USE_UVC
usbhuvcInit();
#endif
#if HAL_USBH_USE_HUB
usbhhubInit();
#endif
usbh_lld_init();
}
void usbhStart(USBHDriver *usbh) {
usbDbgInit(usbh);
@ -1236,6 +1220,7 @@ void usbhMainLoop(USBHDriver *usbh) {
static usbh_baseclassdriver_t *iad_load(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem);
static void iad_unload(usbh_baseclassdriver_t *drv);
static const usbh_classdriver_vmt_t usbhiadClassDriverVMT = {
NULL,
iad_load,
iad_unload
};
@ -1290,8 +1275,11 @@ static void iad_unload(usbh_baseclassdriver_t *drv) {
/*===========================================================================*/
/* Class driver loader. */
/*===========================================================================*/
static const usbh_classdriverinfo_t *usbh_classdrivers_lookup[] = {
#if HAL_USBH_USE_ADDITIONAL_CLASS_DRIVERS
/* user-defined out of tree class drivers */
HAL_USBH_ADDITIONAL_CLASS_DRIVERS
#endif
#if HAL_USBH_USE_FTDI
&usbhftdiClassDriverInfo,
#endif
@ -1431,6 +1419,14 @@ exit:
}
}
void usbhInit(void) {
uint8_t i;
for (i = 0; i < sizeof_array(usbh_classdrivers_lookup); i++) {
if (usbh_classdrivers_lookup[i]->vmt->init) {
usbh_classdrivers_lookup[i]->vmt->init();
}
}
}
#endif

View File

@ -124,8 +124,10 @@ USBHAOADriver USBHAOAD[HAL_USBHAOA_MAX_INSTANCES];
static usbh_baseclassdriver_t *_aoa_load(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem);
static void _aoa_unload(usbh_baseclassdriver_t *drv);
static void _aoa_init(void);
static const usbh_classdriver_vmt_t class_driver_vmt = {
_aoa_init,
_aoa_load,
_aoa_unload
};
@ -658,7 +660,7 @@ static bool _send_string(usbh_device_t *dev, uint8_t index, const char *string)
return HAL_SUCCESS;
}
void usbhaoaObjectInit(USBHAOADriver *aoap) {
static void _object_init(USBHAOADriver *aoap) {
osalDbgCheck(aoap != NULL);
memset(aoap, 0, sizeof(*aoap));
aoap->info = &usbhaoaClassDriverInfo;
@ -668,10 +670,10 @@ void usbhaoaObjectInit(USBHAOADriver *aoap) {
aoap->channel.state = USBHAOA_CHANNEL_STATE_STOP;
}
void usbhaoaInit(void) {
static void _aoa_init(void) {
uint8_t i;
for (i = 0; i < HAL_USBHAOA_MAX_INSTANCES; i++) {
usbhaoaObjectInit(&USBHAOAD[i]);
_object_init(&USBHAOAD[i]);
}
}

View File

@ -62,16 +62,19 @@
#define uerr(f, ...) do {} while(0)
#endif
static void _ftdip_object_init(USBHFTDIPortDriver *ftdipp);
/*===========================================================================*/
/* USB Class driver loader for FTDI */
/*===========================================================================*/
USBHFTDIDriver USBHFTDID[HAL_USBHFTDI_MAX_INSTANCES];
static void _ftdi_init(void);
static usbh_baseclassdriver_t *_ftdi_load(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem);
static void _ftdi_unload(usbh_baseclassdriver_t *drv);
static const usbh_classdriver_vmt_t class_driver_vmt = {
_ftdi_init,
_ftdi_load,
_ftdi_unload
};
@ -229,7 +232,7 @@ static void _ftdi_unload(usbh_baseclassdriver_t *drv) {
osalSysLock();
while (ftdipp) {
USBHFTDIPortDriver *next = ftdipp->next;
usbhftdipObjectInit(ftdipp);
_ftdip_object_init(ftdipp);
ftdipp = next;
}
osalSysUnlock();
@ -700,27 +703,27 @@ void usbhftdipStart(USBHFTDIPortDriver *ftdipp, const USBHFTDIPortConfig *config
osalMutexUnlock(&ftdipp->ftdip->mtx);
}
void usbhftdiObjectInit(USBHFTDIDriver *ftdip) {
static void _ftdi_object_init(USBHFTDIDriver *ftdip) {
osalDbgCheck(ftdip != NULL);
memset(ftdip, 0, sizeof(*ftdip));
ftdip->info = &usbhftdiClassDriverInfo;
osalMutexObjectInit(&ftdip->mtx);
}
void usbhftdipObjectInit(USBHFTDIPortDriver *ftdipp) {
static void _ftdip_object_init(USBHFTDIPortDriver *ftdipp) {
osalDbgCheck(ftdipp != NULL);
memset(ftdipp, 0, sizeof(*ftdipp));
ftdipp->vmt = &async_channel_vmt;
ftdipp->state = USBHFTDIP_STATE_STOP;
}
void usbhftdiInit(void) {
static void _ftdi_init(void) {
uint8_t i;
for (i = 0; i < HAL_USBHFTDI_MAX_INSTANCES; i++) {
usbhftdiObjectInit(&USBHFTDID[i]);
_ftdi_object_init(&USBHFTDID[i]);
}
for (i = 0; i < HAL_USBHFTDI_MAX_PORTS; i++) {
usbhftdipObjectInit(&FTDIPD[i]);
_ftdip_object_init(&FTDIPD[i]);
}
}

View File

@ -74,10 +74,12 @@
USBHHIDDriver USBHHIDD[HAL_USBHHID_MAX_INSTANCES];
static void _hid_init(void);
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);
static const usbh_classdriver_vmt_t class_driver_vmt = {
_hid_init,
_hid_load,
_hid_unload
};
@ -305,17 +307,17 @@ usbh_urbstatus_t usbhhidSetProtocol(USBHHIDDriver *hidp, uint8_t protocol) {
protocol, hidp->ifnum, 0, NULL);
}
void usbhhidObjectInit(USBHHIDDriver *hidp) {
static void _hid_object_init(USBHHIDDriver *hidp) {
osalDbgCheck(hidp != NULL);
memset(hidp, 0, sizeof(*hidp));
hidp->info = &usbhhidClassDriverInfo;
hidp->state = USBHHID_STATE_STOP;
}
void usbhhidInit(void) {
static void _hid_init(void) {
uint8_t i;
for (i = 0; i < HAL_USBHHID_MAX_INSTANCES; i++) {
usbhhidObjectInit(&USBHHIDD[i]);
_hid_object_init(&USBHHIDD[i]);
}
}

View File

@ -63,12 +63,15 @@
USBHHubDriver USBHHUBD[HAL_USBHHUB_MAX_INSTANCES];
static usbh_port_t USBHPorts[HAL_USBHHUB_MAX_PORTS];
static usbh_baseclassdriver_t *hub_load(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem);
static void hub_unload(usbh_baseclassdriver_t *drv);
static void _hub_init(void);
static usbh_baseclassdriver_t *_hub_load(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem);
static void _hub_unload(usbh_baseclassdriver_t *drv);
static const usbh_classdriver_vmt_t usbhhubClassDriverVMT = {
hub_load,
hub_unload
_hub_init,
_hub_load,
_hub_unload
};
const usbh_classdriverinfo_t usbhhubClassDriverInfo = {
0x09, 0x00, -1, "HUB", &usbhhubClassDriverVMT
};
@ -137,7 +140,7 @@ static void _urb_complete(usbh_urb_t *urb) {
usbhURBSubmitI(urb);
}
static usbh_baseclassdriver_t *hub_load(usbh_device_t *dev,
static usbh_baseclassdriver_t *_hub_load(usbh_device_t *dev,
const uint8_t *descriptor, uint16_t rem) {
int i;
@ -261,7 +264,7 @@ alloc_ok:
return (usbh_baseclassdriver_t *)hubdp;
}
static void hub_unload(usbh_baseclassdriver_t *drv) {
static void _hub_unload(usbh_baseclassdriver_t *drv) {
osalDbgCheck(drv != NULL);
USBHHubDriver *const hubdp = (USBHHubDriver *)drv;
@ -283,16 +286,16 @@ static void hub_unload(usbh_baseclassdriver_t *drv) {
}
void usbhhubObjectInit(USBHHubDriver *hubdp) {
static void _object_init(USBHHubDriver *hubdp) {
osalDbgCheck(hubdp != NULL);
memset(hubdp, 0, sizeof(*hubdp));
hubdp->info = &usbhhubClassDriverInfo;
}
void usbhhubInit(void) {
static void _hub_init(void) {
uint8_t i;
for (i = 0; i < HAL_USBHHUB_MAX_INSTANCES; i++) {
usbhhubObjectInit(&USBHHUBD[i]);
_object_init(&USBHHUBD[i]);
}
}

View File

@ -62,7 +62,7 @@
#define uerr(f, ...) do {} while(0)
#endif
static void usbhmsdLUNObjectDeinit(USBHMassStorageLUNDriver *lunp);
static void _lun_object_deinit(USBHMassStorageLUNDriver *lunp);
/*===========================================================================*/
/* USB Class driver loader for MSD */
@ -70,10 +70,12 @@ static void usbhmsdLUNObjectDeinit(USBHMassStorageLUNDriver *lunp);
USBHMassStorageDriver USBHMSD[HAL_USBHMSD_MAX_INSTANCES];
static void _msd_init(void);
static usbh_baseclassdriver_t *_msd_load(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem);
static void _msd_unload(usbh_baseclassdriver_t *drv);
static const usbh_classdriver_vmt_t class_driver_vmt = {
_msd_init,
_msd_load,
_msd_unload
};
@ -205,7 +207,7 @@ static void _msd_unload(usbh_baseclassdriver_t *drv) {
/* disconnect all LUNs */
while (lunp) {
usbhmsdLUNDisconnect(lunp);
usbhmsdLUNObjectDeinit(lunp);
_lun_object_deinit(lunp);
lunp = lunp->next;
}
@ -682,7 +684,7 @@ static const struct USBHMassStorageDriverVMT blk_vmt = {
(bool (*)(void *, BlockDeviceInfo *))usbhmsdLUNGetInfo
};
static void usbhmsdLUNObjectDeinit(USBHMassStorageLUNDriver *lunp) {
static void _lun_object_deinit(USBHMassStorageLUNDriver *lunp) {
osalDbgCheck(lunp != NULL);
osalMutexLock(&lunp->mtx);
lunp->msdp = NULL;
@ -692,7 +694,7 @@ static void usbhmsdLUNObjectDeinit(USBHMassStorageLUNDriver *lunp) {
osalMutexUnlock(&lunp->mtx);
}
static void usbhmsdLUNObjectInit(USBHMassStorageLUNDriver *lunp) {
static void _lun_object_init(USBHMassStorageLUNDriver *lunp) {
osalDbgCheck(lunp != NULL);
memset(lunp, 0, sizeof(*lunp));
lunp->vmt = &blk_vmt;
@ -954,19 +956,19 @@ bool usbhmsdLUNIsProtected(USBHMassStorageLUNDriver *lunp) {
return FALSE;
}
static void usbhmsdObjectInit(USBHMassStorageDriver *msdp) {
static void _msd_object_init(USBHMassStorageDriver *msdp) {
osalDbgCheck(msdp != NULL);
memset(msdp, 0, sizeof(*msdp));
msdp->info = &usbhmsdClassDriverInfo;
}
void usbhmsdInit(void) {
static void _msd_init(void) {
uint8_t i;
for (i = 0; i < HAL_USBHMSD_MAX_INSTANCES; i++) {
usbhmsdObjectInit(&USBHMSD[i]);
_msd_object_init(&USBHMSD[i]);
}
for (i = 0; i < HAL_USBHMSD_MAX_LUNS; i++) {
usbhmsdLUNObjectInit(&MSBLKD[i]);
_lun_object_init(&MSBLKD[i]);
}
}
#endif

View File

@ -66,14 +66,15 @@
USBHUVCDriver USBHUVCD[HAL_USBHUVC_MAX_INSTANCES];
static usbh_baseclassdriver_t *uvc_load(usbh_device_t *dev,
static void _uvc_init(void);
static usbh_baseclassdriver_t *_uvc_load(usbh_device_t *dev,
const uint8_t *descriptor, uint16_t rem);
static void uvc_unload(usbh_baseclassdriver_t *drv);
static void _uvc_unload(usbh_baseclassdriver_t *drv);
static const usbh_classdriver_vmt_t class_driver_vmt = {
uvc_load,
uvc_unload
_uvc_init,
_uvc_load,
_uvc_unload
};
const usbh_classdriverinfo_t usbhuvcClassDriverInfo = {
0x0e, 0x03, 0x00, "UVC", &class_driver_vmt
@ -512,17 +513,7 @@ uint32_t usbhuvcEstimateRequiredEPSize(USBHUVCDriver *uvcdp, const uint8_t *form
return (sz * mul) / div + 12;
}
void usbhuvcObjectInit(USBHUVCDriver *uvcdp) {
osalDbgCheck(uvcdp != NULL);
memset(uvcdp, 0, sizeof(*uvcdp));
uvcdp->info = &usbhuvcClassDriverInfo;
chMBObjectInit(&uvcdp->mb, uvcdp->mb_buff, HAL_USBHUVC_MAX_MAILBOX_SZ);
chMtxObjectInit(&uvcdp->mtx);
uvcdp->state = USBHUVC_STATE_STOP;
}
static usbh_baseclassdriver_t *uvc_load(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem) {
static usbh_baseclassdriver_t *_uvc_load(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem) {
USBHUVCDriver *uvcdp;
uint8_t i;
@ -710,7 +701,7 @@ alloc_ok:
return (usbh_baseclassdriver_t *)uvcdp;
}
static void uvc_unload(usbh_baseclassdriver_t *drv) {
static void _uvc_unload(usbh_baseclassdriver_t *drv) {
USBHUVCDriver *const uvcdp = (USBHUVCDriver *)drv;
usbhuvcStreamStop(uvcdp);
@ -727,10 +718,19 @@ static void uvc_unload(usbh_baseclassdriver_t *drv) {
osalSysUnlock();
}
void usbhuvcInit(void) {
static void _object_init(USBHUVCDriver *uvcdp) {
osalDbgCheck(uvcdp != NULL);
memset(uvcdp, 0, sizeof(*uvcdp));
uvcdp->info = &usbhuvcClassDriverInfo;
chMBObjectInit(&uvcdp->mb, uvcdp->mb_buff, HAL_USBHUVC_MAX_MAILBOX_SZ);
chMtxObjectInit(&uvcdp->mtx);
uvcdp->state = USBHUVC_STATE_STOP;
}
static void _uvc_init(void) {
uint8_t i;
for (i = 0; i < HAL_USBHUVC_MAX_INSTANCES; i++) {
usbhuvcObjectInit(&USBHUVCD[i]);
_object_init(&USBHUVCD[i]);
}
}

View File

@ -123,7 +123,7 @@ CSRC = $(STARTUPSRC) \
$(FATFSSRC) \
$(STREAMSSRC) \
$(SHELLSRC) \
main.c
main.c usbh_custom_class_example.c
# C++ sources that can be compiled in ARM or THUMB mode depending on the global
# setting.

View File

@ -141,6 +141,8 @@
#define HAL_USBHHUB_MAX_INSTANCES 1
#define HAL_USBHHUB_MAX_PORTS 6
#define HAL_USBH_USE_ADDITIONAL_CLASS_DRIVERS 1
/* debug */
#define USBH_DEBUG_ENABLE TRUE
#define USBH_DEBUG_USBHD USBHD1

View File

@ -0,0 +1,38 @@
/*
ChibiOS - Copyright (C) 2006..2017 Giovanni Di Sirio
Copyright (C) 2015..2017 Diego Ismirlian, (dismirlian (at) google's mail)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef USBH_ADDITIONAL_H_
#define USBH_ADDITIONAL_H_
#include "hal_usbh.h"
#if HAL_USE_USBH && HAL_USBH_USE_ADDITIONAL_CLASS_DRIVERS
/* Declarations */
extern const usbh_classdriverinfo_t usbhCustomClassDriverInfo;
/* Comma separated list of additional class drivers */
#define HAL_USBH_ADDITIONAL_CLASS_DRIVERS \
&usbhCustomClassDriverInfo,
#endif
#endif /* USBH_ADDITIONAL_H_ */

View File

@ -0,0 +1,140 @@
/*
ChibiOS - Copyright (C) 2006..2017 Giovanni Di Sirio
Copyright (C) 2015..2017 Diego Ismirlian, (dismirlian (at) google's mail)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "hal.h"
#include "usbh/internal.h"
#include "usbh_custom_class_example.h"
#include <string.h>
#if USBH_DEBUG_ENABLE_TRACE
#define udbgf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__)
#define udbg(f, ...) usbDbgPuts(f, ##__VA_ARGS__)
#else
#define udbgf(f, ...) do {} while(0)
#define udbg(f, ...) do {} while(0)
#endif
#if USBH_DEBUG_ENABLE_INFO
#define uinfof(f, ...) usbDbgPrintf(f, ##__VA_ARGS__)
#define uinfo(f, ...) usbDbgPuts(f, ##__VA_ARGS__)
#else
#define uinfof(f, ...) do {} while(0)
#define uinfo(f, ...) do {} while(0)
#endif
#if USBH_DEBUG_ENABLE_WARNINGS
#define uwarnf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__)
#define uwarn(f, ...) usbDbgPuts(f, ##__VA_ARGS__)
#else
#define uwarnf(f, ...) do {} while(0)
#define uwarn(f, ...) do {} while(0)
#endif
#if USBH_DEBUG_ENABLE_ERRORS
#define uerrf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__)
#define uerr(f, ...) usbDbgPuts(f, ##__VA_ARGS__)
#else
#define uerrf(f, ...) do {} while(0)
#define uerr(f, ...) do {} while(0)
#endif
/*===========================================================================*/
/* USB Class driver loader for Custom Class Example */
/*===========================================================================*/
USBHCustomDriver USBHCUSTOMD[USBH_CUSTOM_CLASS_MAX_INSTANCES];
static void _init(void);
static usbh_baseclassdriver_t *_load(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem);
static void _unload(usbh_baseclassdriver_t *drv);
static const usbh_classdriver_vmt_t class_driver_vmt = {
_init,
_load,
_unload
};
const usbh_classdriverinfo_t usbhCustomClassDriverInfo = {
0x54, -1, -1, "CUSTOM", &class_driver_vmt
};
static usbh_baseclassdriver_t *_load(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem) {
int i;
USBHCustomDriver *custp;
(void)dev;
if ((rem < descriptor[0]) || (descriptor[1] != USBH_DT_INTERFACE))
return NULL;
const usbh_interface_descriptor_t * const ifdesc = (const usbh_interface_descriptor_t *)descriptor;
/* alloc driver */
for (i = 0; i < USBH_CUSTOM_CLASS_MAX_INSTANCES; i++) {
if (USBHCUSTOMD[i].dev == NULL) {
custp = &USBHCUSTOMD[i];
goto alloc_ok;
}
}
uwarn("Can't alloc CUSTOM driver");
/* can't alloc */
return NULL;
alloc_ok:
/* initialize the driver's variables */
custp->ifnum = ifdesc->bInterfaceNumber;
/* parse the configuration descriptor */
if_iterator_t iif;
generic_iterator_t iep;
iif.iad = 0;
iif.curr = descriptor;
iif.rem = rem;
for (ep_iter_init(&iep, &iif); iep.valid; ep_iter_next(&iep)) {
const usbh_endpoint_descriptor_t *const epdesc = ep_get(&iep);
if ((epdesc->bEndpointAddress & 0x80) && (epdesc->bmAttributes == USBH_EPTYPE_INT)) {
/* ... */
} else {
uinfof("unsupported endpoint found: bEndpointAddress=%02x, bmAttributes=%02x",
epdesc->bEndpointAddress, epdesc->bmAttributes);
}
}
custp->state = USBHCUSTOM_STATE_ACTIVE;
return (usbh_baseclassdriver_t *)custp;
}
static void _unload(usbh_baseclassdriver_t *drv) {
(void)drv;
}
static void _object_init(USBHCustomDriver *custp) {
osalDbgCheck(custp != NULL);
memset(custp, 0, sizeof(*custp));
custp->state = USBHCUSTOM_STATE_STOP;
}
static void _init(void) {
uint8_t i;
for (i = 0; i < USBH_CUSTOM_CLASS_MAX_INSTANCES; i++) {
_object_init(&USBHCUSTOMD[i]);
}
}

View File

@ -0,0 +1,83 @@
/*
ChibiOS - Copyright (C) 2006..2017 Giovanni Di Sirio
Copyright (C) 2015..2017 Diego Ismirlian, (dismirlian (at) google's mail)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef USBH_CUSTOM_H_
#define USBH_CUSTOM_H_
#include "hal_usbh.h"
#if HAL_USE_USBH
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
#define USBH_CUSTOM_CLASS_MAX_INSTANCES 1
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
typedef enum {
USBHCUSTOM_STATE_UNINIT = 0,
USBHCUSTOM_STATE_STOP = 1,
USBHCUSTOM_STATE_ACTIVE = 2,
USBHCUSTOM_STATE_READY = 3
} usbhcustom_state_t;
typedef struct USBHCustomDriver USBHCustomDriver;
struct USBHCustomDriver {
/* inherited from abstract class driver */
_usbh_base_classdriver_data
uint8_t ifnum;
usbhcustom_state_t state;
};
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
extern USBHCustomDriver USBHCUSTOMD[USBH_CUSTOM_CLASS_MAX_INSTANCES];
#ifdef __cplusplus
extern "C" {
#endif
/* API goes here */
/* global initializer */
void usbhCustomInit(void);
#ifdef __cplusplus
}
#endif
#endif
#endif /* USBH_CUSTOM_H_ */