commit
cde20e2fce
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* downstream_hid.h
|
||||
*
|
||||
* Created on: Apr 10, 2016
|
||||
* Author: Robert Fisk
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef INC_DOWNSTREAM_HID_H_
|
||||
#define INC_DOWNSTREAM_HID_H_
|
||||
|
||||
|
||||
#include "downstream_interface_def.h"
|
||||
#include "downstream_spi.h"
|
||||
|
||||
|
||||
|
||||
|
||||
InterfaceCommandClassTypeDef Downstream_HID_ApproveConnectedDevice(void);
|
||||
void Downstream_HID_PacketProcessor(DownstreamPacketTypeDef* receivedPacket);
|
||||
void Downstream_HID_InterruptReportCallback(DownstreamPacketTypeDef* packetToSend);
|
||||
|
||||
|
||||
|
||||
#endif /* INC_DOWNSTREAM_HID_H_ */
|
@ -0,0 +1,358 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbh_hid.h
|
||||
* @author MCD Application Team
|
||||
* @version V3.2.2
|
||||
* @date 07-July-2015
|
||||
* @brief This file contains all the prototypes for the usbh_hid.c
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive ----------------------------------------------*/
|
||||
#ifndef __USBH_HID_H
|
||||
#define __USBH_HID_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbh_core.h"
|
||||
#include "downstream_spi.h"
|
||||
|
||||
|
||||
/** @addtogroup USBH_LIB
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_CLASS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_HID_CLASS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_HID_CORE
|
||||
* @brief This file is the Header file for usbh_hid.c
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_HID_CORE_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define HID_MIN_POLL 10
|
||||
#define HID_REPORT_SIZE 16
|
||||
#define HID_MAX_USAGE 10
|
||||
#define HID_MAX_NBR_REPORT_FMT 10
|
||||
#define HID_QUEUE_SIZE 10
|
||||
|
||||
#define HID_ITEM_LONG 0xFE
|
||||
|
||||
#define HID_ITEM_TYPE_MAIN 0x00
|
||||
#define HID_ITEM_TYPE_GLOBAL 0x01
|
||||
#define HID_ITEM_TYPE_LOCAL 0x02
|
||||
#define HID_ITEM_TYPE_RESERVED 0x03
|
||||
|
||||
|
||||
#define HID_MAIN_ITEM_TAG_INPUT 0x08
|
||||
#define HID_MAIN_ITEM_TAG_OUTPUT 0x09
|
||||
#define HID_MAIN_ITEM_TAG_COLLECTION 0x0A
|
||||
#define HID_MAIN_ITEM_TAG_FEATURE 0x0B
|
||||
#define HID_MAIN_ITEM_TAG_ENDCOLLECTION 0x0C
|
||||
|
||||
|
||||
#define HID_GLOBAL_ITEM_TAG_USAGE_PAGE 0x00
|
||||
#define HID_GLOBAL_ITEM_TAG_LOG_MIN 0x01
|
||||
#define HID_GLOBAL_ITEM_TAG_LOG_MAX 0x02
|
||||
#define HID_GLOBAL_ITEM_TAG_PHY_MIN 0x03
|
||||
#define HID_GLOBAL_ITEM_TAG_PHY_MAX 0x04
|
||||
#define HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT 0x05
|
||||
#define HID_GLOBAL_ITEM_TAG_UNIT 0x06
|
||||
#define HID_GLOBAL_ITEM_TAG_REPORT_SIZE 0x07
|
||||
#define HID_GLOBAL_ITEM_TAG_REPORT_ID 0x08
|
||||
#define HID_GLOBAL_ITEM_TAG_REPORT_COUNT 0x09
|
||||
#define HID_GLOBAL_ITEM_TAG_PUSH 0x0A
|
||||
#define HID_GLOBAL_ITEM_TAG_POP 0x0B
|
||||
|
||||
|
||||
#define HID_LOCAL_ITEM_TAG_USAGE 0x00
|
||||
#define HID_LOCAL_ITEM_TAG_USAGE_MIN 0x01
|
||||
#define HID_LOCAL_ITEM_TAG_USAGE_MAX 0x02
|
||||
#define HID_LOCAL_ITEM_TAG_DESIGNATOR_INDEX 0x03
|
||||
#define HID_LOCAL_ITEM_TAG_DESIGNATOR_MIN 0x04
|
||||
#define HID_LOCAL_ITEM_TAG_DESIGNATOR_MAX 0x05
|
||||
#define HID_LOCAL_ITEM_TAG_STRING_INDEX 0x07
|
||||
#define HID_LOCAL_ITEM_TAG_STRING_MIN 0x08
|
||||
#define HID_LOCAL_ITEM_TAG_STRING_MAX 0x09
|
||||
#define HID_LOCAL_ITEM_TAG_DELIMITER 0x0A
|
||||
|
||||
|
||||
/* States for HID State Machine */
|
||||
typedef enum
|
||||
{
|
||||
HID_INIT= 0,
|
||||
HID_IDLE,
|
||||
HID_GET_DATA,
|
||||
HID_SYNC,
|
||||
HID_POLL,
|
||||
HID_ERROR,
|
||||
}
|
||||
HID_StateTypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
HID_REQ_INIT = 0,
|
||||
HID_REQ_IDLE,
|
||||
HID_REQ_GET_REPORT_DESC,
|
||||
HID_REQ_GET_HID_DESC,
|
||||
HID_REQ_SET_IDLE,
|
||||
HID_REQ_SET_PROTOCOL,
|
||||
HID_REQ_SET_REPORT,
|
||||
|
||||
}
|
||||
HID_CtlStateTypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
HID_MOUSE = 0x01,
|
||||
HID_KEYBOARD = 0x02,
|
||||
HID_UNKNOWN = 0xFF,
|
||||
}
|
||||
HID_TypeTypeDef;
|
||||
|
||||
|
||||
typedef struct _HID_ReportData
|
||||
{
|
||||
uint8_t ReportID;
|
||||
uint8_t ReportType;
|
||||
uint16_t UsagePage;
|
||||
uint32_t Usage[HID_MAX_USAGE];
|
||||
uint32_t NbrUsage;
|
||||
uint32_t UsageMin;
|
||||
uint32_t UsageMax;
|
||||
int32_t LogMin;
|
||||
int32_t LogMax;
|
||||
int32_t PhyMin;
|
||||
int32_t PhyMax;
|
||||
int32_t UnitExp;
|
||||
uint32_t Unit;
|
||||
uint32_t ReportSize;
|
||||
uint32_t ReportCnt;
|
||||
uint32_t Flag;
|
||||
uint32_t PhyUsage;
|
||||
uint32_t AppUsage;
|
||||
uint32_t LogUsage;
|
||||
}
|
||||
HID_ReportDataTypeDef;
|
||||
|
||||
typedef struct _HID_ReportIDTypeDef {
|
||||
uint8_t Size; /* Report size return by the device id */
|
||||
uint8_t ReportID; /* Report Id */
|
||||
uint8_t Type; /* Report Type (INPUT/OUTPUT/FEATURE) */
|
||||
} HID_ReportIDTypeDef;
|
||||
|
||||
typedef struct _HID_CollectionTypeDef
|
||||
{
|
||||
uint32_t Usage;
|
||||
uint8_t Type;
|
||||
struct _HID_CollectionTypeDef *NextPtr;
|
||||
} HID_CollectionTypeDef;
|
||||
|
||||
|
||||
typedef struct _HID_AppCollectionTypeDef {
|
||||
uint32_t Usage;
|
||||
uint8_t Type;
|
||||
uint8_t NbrReportFmt;
|
||||
HID_ReportDataTypeDef ReportData[HID_MAX_NBR_REPORT_FMT];
|
||||
} HID_AppCollectionTypeDef;
|
||||
|
||||
|
||||
typedef struct _HIDDescriptor
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t bcdHID; /* indicates what endpoint this descriptor is describing */
|
||||
uint8_t bCountryCode; /* specifies the transfer type. */
|
||||
uint8_t bNumDescriptors; /* specifies the transfer type. */
|
||||
uint8_t bReportDescriptorType; /* Maximum Packet Size this endpoint is capable of sending or receiving */
|
||||
uint16_t wItemLength; /* is used to specify the polling interval of certain transfers. */
|
||||
}
|
||||
HID_DescTypeDef;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t *buf;
|
||||
uint16_t head;
|
||||
uint16_t tail;
|
||||
uint16_t size;
|
||||
uint8_t lock;
|
||||
} FIFO_TypeDef;
|
||||
|
||||
|
||||
|
||||
typedef void (*HID_InterruptReportCallback)(DownstreamPacketTypeDef* packetToSend);
|
||||
|
||||
|
||||
/* Structure for HID process */
|
||||
typedef struct _HID_Process
|
||||
{
|
||||
uint8_t OutPipe;
|
||||
uint8_t InPipe;
|
||||
uint8_t OutEp;
|
||||
uint8_t InEp;
|
||||
HID_StateTypeDef state;
|
||||
HID_CtlStateTypeDef ctl_state;
|
||||
uint16_t length;
|
||||
uint16_t poll;
|
||||
uint32_t timer;
|
||||
uint8_t ep_addr;
|
||||
uint8_t Protocol;
|
||||
HID_DescTypeDef HID_Desc;
|
||||
HID_InterruptReportCallback ReportCallback;
|
||||
DownstreamPacketTypeDef* hid_packet;
|
||||
uint8_t* hid_packet_pbuf;
|
||||
}
|
||||
HID_HandleTypeDef;
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_HID_CORE_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define USB_HID_GET_REPORT 0x01
|
||||
#define USB_HID_GET_IDLE 0x02
|
||||
#define USB_HID_GET_PROTOCOL 0x03
|
||||
#define USB_HID_SET_REPORT 0x09
|
||||
#define USB_HID_SET_IDLE 0x0A
|
||||
#define USB_HID_SET_PROTOCOL 0x0B
|
||||
|
||||
|
||||
|
||||
|
||||
/* HID Class Codes */
|
||||
#define USB_HID_CLASS 0x03
|
||||
|
||||
/* Interface Descriptor field values for HID Boot Protocol */
|
||||
#define HID_BOOT_CODE 0x01
|
||||
#define HID_KEYBRD_BOOT_CODE 0x01
|
||||
#define HID_MOUSE_BOOT_CODE 0x02
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_HID_CORE_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_HID_CORE_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
extern USBH_ClassTypeDef HID_Class;
|
||||
#define USBH_HID_CLASS &HID_Class
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_HID_CORE_Exported_FunctionsPrototype
|
||||
* @{
|
||||
*/
|
||||
|
||||
USBH_StatusTypeDef USBH_HID_SetReport (USBH_HandleTypeDef *phost,
|
||||
uint8_t reportType,
|
||||
uint8_t reportId,
|
||||
uint8_t* reportBuff,
|
||||
uint8_t reportLen);
|
||||
|
||||
USBH_StatusTypeDef USBH_HID_GetReport (USBH_HandleTypeDef *phost,
|
||||
uint8_t reportType,
|
||||
uint8_t reportId,
|
||||
uint8_t* reportBuff,
|
||||
uint8_t reportLen);
|
||||
|
||||
USBH_StatusTypeDef USBH_HID_GetHIDReportDescriptor (USBH_HandleTypeDef *phost,
|
||||
uint16_t length);
|
||||
|
||||
USBH_StatusTypeDef USBH_HID_GetHIDDescriptor (USBH_HandleTypeDef *phost,
|
||||
uint16_t length);
|
||||
|
||||
USBH_StatusTypeDef USBH_HID_SetIdle (USBH_HandleTypeDef *phost,
|
||||
uint8_t duration,
|
||||
uint8_t reportId);
|
||||
|
||||
USBH_StatusTypeDef USBH_HID_SetProtocol (USBH_HandleTypeDef *phost,
|
||||
uint8_t protocol);
|
||||
|
||||
void USBH_HID_EventCallback(USBH_HandleTypeDef *phost);
|
||||
|
||||
HID_TypeTypeDef USBH_HID_GetDeviceType(USBH_HandleTypeDef *phost);
|
||||
|
||||
uint8_t USBH_HID_GetPollInterval(USBH_HandleTypeDef *phost);
|
||||
|
||||
void fifo_init(FIFO_TypeDef * f, uint8_t * buf, uint16_t size);
|
||||
|
||||
uint16_t fifo_read(FIFO_TypeDef * f, void * buf, uint16_t nbytes);
|
||||
|
||||
uint16_t fifo_write(FIFO_TypeDef * f, const void * buf, uint16_t nbytes);
|
||||
|
||||
HAL_StatusTypeDef USBH_HID_GetInterruptReport(USBH_HandleTypeDef *phost,
|
||||
HID_InterruptReportCallback callback,
|
||||
DownstreamPacketTypeDef* packetToUse);
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBH_HID_H */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
@ -0,0 +1,821 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbh_hid.c
|
||||
* @author MCD Application Team
|
||||
* @version V3.2.2
|
||||
* @date 07-July-2015
|
||||
* @brief This file is the HID Layer Handlers for USB Host HID class.
|
||||
*
|
||||
* @verbatim
|
||||
*
|
||||
* ===================================================================
|
||||
* HID Class Description
|
||||
* ===================================================================
|
||||
* This module manages the HID class V1.11 following the "Device Class Definition
|
||||
* for Human Interface Devices (HID) Version 1.11 Jun 27, 2001".
|
||||
* This driver implements the following aspects of the specification:
|
||||
* - The Boot Interface Subclass
|
||||
* - The Mouse and Keyboard protocols
|
||||
*
|
||||
* @endverbatim
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*
|
||||
* Modifications by Robert Fisk
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbh_hid.h"
|
||||
#include "usbh_hid_parser.h"
|
||||
|
||||
|
||||
/** @addtogroup USBH_LIB
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_CLASS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_HID_CLASS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_HID_CORE
|
||||
* @brief This file includes HID Layer Handlers for USB Host HID class.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_HID_CORE_Private_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_HID_CORE_Private_Defines
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_HID_CORE_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_HID_CORE_Private_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_HID_CORE_Private_FunctionPrototypes
|
||||
* @{
|
||||
*/
|
||||
|
||||
static USBH_StatusTypeDef USBH_HID_InterfaceInit (USBH_HandleTypeDef *phost);
|
||||
static USBH_StatusTypeDef USBH_HID_InterfaceDeInit (USBH_HandleTypeDef *phost);
|
||||
static USBH_StatusTypeDef USBH_HID_ClassRequest(USBH_HandleTypeDef *phost);
|
||||
static USBH_StatusTypeDef USBH_HID_Process(USBH_HandleTypeDef *phost);
|
||||
static USBH_StatusTypeDef USBH_HID_SOFProcess(USBH_HandleTypeDef *phost);
|
||||
static void USBH_HID_ParseHIDDesc (HID_DescTypeDef *desc, uint8_t *buf);
|
||||
|
||||
//extern USBH_StatusTypeDef USBH_HID_MouseInit(USBH_HandleTypeDef *phost);
|
||||
//extern USBH_StatusTypeDef USBH_HID_KeybdInit(USBH_HandleTypeDef *phost);
|
||||
|
||||
USBH_ClassTypeDef HID_Class =
|
||||
{
|
||||
"HID",
|
||||
USB_HID_CLASS,
|
||||
USBH_HID_InterfaceInit,
|
||||
USBH_HID_InterfaceDeInit,
|
||||
USBH_HID_ClassRequest,
|
||||
USBH_HID_Process,
|
||||
USBH_HID_SOFProcess,
|
||||
NULL,
|
||||
};
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_HID_CORE_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_HID_InterfaceInit
|
||||
* The function init the HID class.
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
static USBH_StatusTypeDef USBH_HID_InterfaceInit (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
uint8_t max_ep;
|
||||
uint8_t num = 0;
|
||||
uint8_t interface;
|
||||
|
||||
USBH_StatusTypeDef status = USBH_FAIL ;
|
||||
HID_HandleTypeDef *HID_Handle;
|
||||
|
||||
interface = USBH_FindInterface(phost, phost->pActiveClass->ClassCode, HID_BOOT_CODE, 0xFF);
|
||||
|
||||
if(interface == 0xFF) /* No Valid Interface */
|
||||
{
|
||||
status = USBH_FAIL;
|
||||
USBH_DbgLog ("Cannot Find the interface for %s class.", phost->pActiveClass->Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
USBH_SelectInterface (phost, interface);
|
||||
phost->pActiveClass->pData = (HID_HandleTypeDef *)USBH_malloc (sizeof(HID_HandleTypeDef));
|
||||
HID_Handle = (HID_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
HID_Handle->state = HID_ERROR;
|
||||
|
||||
/*Decode Bootclass Protocol: Mouse or Keyboard*/
|
||||
if(phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].bInterfaceProtocol == HID_KEYBRD_BOOT_CODE)
|
||||
{
|
||||
USBH_UsrLog ("KeyBoard device found!");
|
||||
//HID_Handle->Init = USBH_HID_KeybdInit;
|
||||
}
|
||||
else if(phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].bInterfaceProtocol == HID_MOUSE_BOOT_CODE)
|
||||
{
|
||||
USBH_UsrLog ("Mouse device found!");
|
||||
//HID_Handle->Init = USBH_HID_MouseInit;
|
||||
}
|
||||
else
|
||||
{
|
||||
USBH_UsrLog ("Protocol not supported.");
|
||||
return USBH_FAIL;
|
||||
}
|
||||
|
||||
HID_Handle->state = HID_INIT;
|
||||
HID_Handle->ctl_state = HID_REQ_INIT;
|
||||
HID_Handle->ep_addr = phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[0].bEndpointAddress;
|
||||
HID_Handle->length = phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[0].wMaxPacketSize;
|
||||
HID_Handle->poll = phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[0].bInterval;
|
||||
HID_Handle->Protocol = phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].bInterfaceProtocol;
|
||||
|
||||
if (HID_Handle->poll < HID_MIN_POLL)
|
||||
{
|
||||
HID_Handle->poll = HID_MIN_POLL;
|
||||
}
|
||||
|
||||
/* Check fo available number of endpoints */
|
||||
/* Find the number of EPs in the Interface Descriptor */
|
||||
/* Choose the lower number in order not to overrun the buffer allocated */
|
||||
max_ep = ( (phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].bNumEndpoints <= USBH_MAX_NUM_ENDPOINTS) ?
|
||||
phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].bNumEndpoints :
|
||||
USBH_MAX_NUM_ENDPOINTS);
|
||||
|
||||
|
||||
/* Decode endpoint IN and OUT address from interface descriptor */
|
||||
for ( ;num < max_ep; num++)
|
||||
{
|
||||
if(phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[num].bEndpointAddress & 0x80)
|
||||
{
|
||||
HID_Handle->InEp = (phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[num].bEndpointAddress);
|
||||
HID_Handle->InPipe =\
|
||||
USBH_AllocPipe(phost, HID_Handle->InEp);
|
||||
|
||||
/* Open pipe for IN endpoint */
|
||||
USBH_OpenPipe (phost,
|
||||
HID_Handle->InPipe,
|
||||
HID_Handle->InEp,
|
||||
phost->device.address,
|
||||
phost->device.speed,
|
||||
USB_EP_TYPE_INTR,
|
||||
HID_Handle->length);
|
||||
|
||||
USBH_LL_SetToggle (phost, HID_Handle->InPipe, 0);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
HID_Handle->OutEp = (phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[num].bEndpointAddress);
|
||||
HID_Handle->OutPipe =\
|
||||
USBH_AllocPipe(phost, HID_Handle->OutEp);
|
||||
|
||||
/* Open pipe for OUT endpoint */
|
||||
USBH_OpenPipe (phost,
|
||||
HID_Handle->OutPipe,
|
||||
HID_Handle->OutEp,
|
||||
phost->device.address,
|
||||
phost->device.speed,
|
||||
USB_EP_TYPE_INTR,
|
||||
HID_Handle->length);
|
||||
|
||||
USBH_LL_SetToggle (phost, HID_Handle->OutPipe, 0);
|
||||
}
|
||||
|
||||
}
|
||||
status = USBH_OK;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_HID_InterfaceDeInit
|
||||
* The function DeInit the Pipes used for the HID class.
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_HID_InterfaceDeInit (USBH_HandleTypeDef *phost )
|
||||
{
|
||||
HID_HandleTypeDef *HID_Handle = (HID_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
if(HID_Handle->InPipe != 0x00)
|
||||
{
|
||||
USBH_ClosePipe (phost, HID_Handle->InPipe);
|
||||
USBH_FreePipe (phost, HID_Handle->InPipe);
|
||||
HID_Handle->InPipe = 0; /* Reset the pipe as Free */
|
||||
}
|
||||
|
||||
if(HID_Handle->OutPipe != 0x00)
|
||||
{
|
||||
USBH_ClosePipe(phost, HID_Handle->OutPipe);
|
||||
USBH_FreePipe (phost, HID_Handle->OutPipe);
|
||||
HID_Handle->OutPipe = 0; /* Reset the pipe as Free */
|
||||
}
|
||||
|
||||
if(phost->pActiveClass->pData)
|
||||
{
|
||||
USBH_free (phost->pActiveClass->pData);
|
||||
}
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_HID_ClassRequest
|
||||
* The function is responsible for handling Standard requests
|
||||
* for HID class.
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
static USBH_StatusTypeDef USBH_HID_ClassRequest(USBH_HandleTypeDef *phost)
|
||||
{
|
||||
|
||||
USBH_StatusTypeDef status = USBH_BUSY;
|
||||
USBH_StatusTypeDef classReqStatus = USBH_BUSY;
|
||||
HID_HandleTypeDef *HID_Handle = (HID_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
/* Switch HID state machine */
|
||||
switch (HID_Handle->ctl_state)
|
||||
{
|
||||
case HID_REQ_INIT:
|
||||
case HID_REQ_GET_HID_DESC:
|
||||
|
||||
/* Get HID Desc */
|
||||
if (USBH_HID_GetHIDDescriptor (phost, USB_HID_DESC_SIZE)== USBH_OK)
|
||||
{
|
||||
|
||||
USBH_HID_ParseHIDDesc(&HID_Handle->HID_Desc, phost->device.Data);
|
||||
HID_Handle->ctl_state = HID_REQ_SET_IDLE;
|
||||
}
|
||||
|
||||
break;
|
||||
// case HID_REQ_GET_REPORT_DESC:
|
||||
//
|
||||
//
|
||||
// /* Get Report Desc */
|
||||
// if (USBH_HID_GetHIDReportDescriptor(phost, HID_Handle->HID_Desc.wItemLength) == USBH_OK)
|
||||
// {
|
||||
// /* The descriptor is available in phost->device.Data */
|
||||
//
|
||||
// HID_Handle->ctl_state = HID_REQ_SET_IDLE;
|
||||
// }
|
||||
//
|
||||
// break;
|
||||
|
||||
case HID_REQ_SET_IDLE:
|
||||
|
||||
classReqStatus = USBH_HID_SetIdle (phost, 0, 0);
|
||||
|
||||
/* set Idle */
|
||||
if (classReqStatus == USBH_OK)
|
||||
{
|
||||
HID_Handle->ctl_state = HID_REQ_SET_PROTOCOL;
|
||||
}
|
||||
else if(classReqStatus == USBH_NOT_SUPPORTED)
|
||||
{
|
||||
HID_Handle->ctl_state = HID_REQ_SET_PROTOCOL;
|
||||
}
|
||||
break;
|
||||
|
||||
case HID_REQ_SET_PROTOCOL:
|
||||
/* set protocol */
|
||||
if (USBH_HID_SetProtocol (phost, 0) == USBH_OK)
|
||||
{
|
||||
HID_Handle->ctl_state = HID_REQ_IDLE;
|
||||
|
||||
/* all requests performed*/
|
||||
phost->pUser(phost, HOST_USER_CLASS_ACTIVE);
|
||||
status = USBH_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
case HID_REQ_IDLE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_HID_Process
|
||||
* The function is for managing state machine for HID data transfers
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
static USBH_StatusTypeDef USBH_HID_Process(USBH_HandleTypeDef *phost)
|
||||
{
|
||||
USBH_URBStateTypeDef urbStatus;
|
||||
HID_HandleTypeDef *HID_Handle = (HID_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
switch (HID_Handle->state)
|
||||
{
|
||||
case HID_INIT:
|
||||
HID_Handle->timer = phost->Timer;
|
||||
HID_Handle->state = HID_IDLE;
|
||||
break;
|
||||
|
||||
case HID_GET_DATA:
|
||||
if ((int32_t)(phost->Timer - HID_Handle->timer) >= HID_Handle->poll)
|
||||
{
|
||||
USBH_InterruptReceiveData(phost,
|
||||
HID_Handle->hid_packet_pbuf,
|
||||
HID_Handle->length,
|
||||
HID_Handle->InPipe);
|
||||
|
||||
HID_Handle->state = HID_POLL;
|
||||
HID_Handle->timer = phost->Timer;
|
||||
}
|
||||
break;
|
||||
|
||||
case HID_POLL:
|
||||
urbStatus = USBH_LL_GetURBState(phost, HID_Handle->InPipe);
|
||||
|
||||
if (urbStatus == USBH_URB_DONE)
|
||||
{
|
||||
HID_Handle->ReportCallback(HID_Handle->hid_packet);
|
||||
HID_Handle->state = HID_IDLE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (urbStatus == USBH_URB_NOTREADY)
|
||||
{
|
||||
HID_Handle->state = HID_GET_DATA;
|
||||
break;
|
||||
}
|
||||
|
||||
if (urbStatus == USBH_URB_STALL)
|
||||
{
|
||||
/* Issue Clear Feature on interrupt IN endpoint */
|
||||
if(USBH_ClrFeature(phost,
|
||||
HID_Handle->ep_addr) == USBH_OK)
|
||||
{
|
||||
HID_Handle->state = HID_GET_DATA;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case HID_IDLE:
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_HID_SOFProcess
|
||||
* The function is for managing the SOF Process
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
static USBH_StatusTypeDef USBH_HID_SOFProcess(USBH_HandleTypeDef *phost)
|
||||
{
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Downstream_HID calls into here at main() priority,
|
||||
//to request a new report for Upstream.
|
||||
HAL_StatusTypeDef USBH_HID_GetInterruptReport(USBH_HandleTypeDef *phost,
|
||||
HID_InterruptReportCallback callback,
|
||||
DownstreamPacketTypeDef* packetToUse)
|
||||
{
|
||||
HID_HandleTypeDef *HID_Handle = (HID_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
if (HID_Handle->state == HID_IDLE)
|
||||
{
|
||||
HID_Handle->ReportCallback = callback;
|
||||
HID_Handle->hid_packet = packetToUse;
|
||||
HID_Handle->hid_packet_pbuf = packetToUse->Data;
|
||||
HID_Handle->state = HID_GET_DATA;
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_Get_HID_ReportDescriptor
|
||||
* Issue report Descriptor command to the device. Once the response
|
||||
* received, parse the report descriptor and update the status.
|
||||
* @param phost: Host handle
|
||||
* @param Length : HID Report Descriptor Length
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_HID_GetHIDReportDescriptor (USBH_HandleTypeDef *phost,
|
||||
uint16_t length)
|
||||
{
|
||||
|
||||
USBH_StatusTypeDef status;
|
||||
|
||||
status = USBH_GetDescriptor(phost,
|
||||
USB_REQ_RECIPIENT_INTERFACE | USB_REQ_TYPE_STANDARD,
|
||||
USB_DESC_HID_REPORT,
|
||||
phost->device.Data,
|
||||
length);
|
||||
|
||||
/* HID report descriptor is available in phost->device.Data.
|
||||
In case of USB Boot Mode devices for In report handling ,
|
||||
HID report descriptor parsing is not required.
|
||||
In case, for supporting Non-Boot Protocol devices and output reports,
|
||||
user may parse the report descriptor*/
|
||||
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_Get_HID_Descriptor
|
||||
* Issue HID Descriptor command to the device. Once the response
|
||||
* received, parse the report descriptor and update the status.
|
||||
* @param phost: Host handle
|
||||
* @param Length : HID Descriptor Length
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_HID_GetHIDDescriptor (USBH_HandleTypeDef *phost,
|
||||
uint16_t length)
|
||||
{
|
||||
|
||||
USBH_StatusTypeDef status;
|
||||
|
||||
status = USBH_GetDescriptor( phost,
|
||||
USB_REQ_RECIPIENT_INTERFACE | USB_REQ_TYPE_STANDARD,
|
||||
USB_DESC_HID,
|
||||
phost->device.Data,
|
||||
length);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_Set_Idle
|
||||
* Set Idle State.
|
||||
* @param phost: Host handle
|
||||
* @param duration: Duration for HID Idle request
|
||||
* @param reportId : Targeted report ID for Set Idle request
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_HID_SetIdle (USBH_HandleTypeDef *phost,
|
||||
uint8_t duration,
|
||||
uint8_t reportId)
|
||||
{
|
||||
|
||||
phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_INTERFACE |\
|
||||
USB_REQ_TYPE_CLASS;
|
||||
|
||||
|
||||
phost->Control.setup.b.bRequest = USB_HID_SET_IDLE;
|
||||
phost->Control.setup.b.wValue.w = (duration << 8 ) | reportId;
|
||||
|
||||
phost->Control.setup.b.wIndex.w = 0;
|
||||
phost->Control.setup.b.wLength.w = 0;
|
||||
|
||||
return USBH_CtlReq(phost, 0 , 0 );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_HID_Set_Report
|
||||
* Issues Set Report
|
||||
* @param phost: Host handle
|
||||
* @param reportType : Report type to be sent
|
||||
* @param reportId : Targeted report ID for Set Report request
|
||||
* @param reportBuff : Report Buffer
|
||||
* @param reportLen : Length of data report to be send
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_HID_SetReport (USBH_HandleTypeDef *phost,
|
||||
uint8_t reportType,
|
||||
uint8_t reportId,
|
||||
uint8_t* reportBuff,
|
||||
uint8_t reportLen)
|
||||
{
|
||||
|
||||
phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_INTERFACE |\
|
||||
USB_REQ_TYPE_CLASS;
|
||||
|
||||
|
||||
phost->Control.setup.b.bRequest = USB_HID_SET_REPORT;
|
||||
phost->Control.setup.b.wValue.w = (reportType << 8 ) | reportId;
|
||||
|
||||
phost->Control.setup.b.wIndex.w = 0;
|
||||
phost->Control.setup.b.wLength.w = reportLen;
|
||||
|
||||
return USBH_CtlReq(phost, reportBuff , reportLen );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_HID_GetReport
|
||||
* retreive Set Report
|
||||
* @param phost: Host handle
|
||||
* @param reportType : Report type to be sent
|
||||
* @param reportId : Targeted report ID for Set Report request
|
||||
* @param reportBuff : Report Buffer
|
||||
* @param reportLen : Length of data report to be send
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_HID_GetReport (USBH_HandleTypeDef *phost,
|
||||
uint8_t reportType,
|
||||
uint8_t reportId,
|
||||
uint8_t* reportBuff,
|
||||
uint8_t reportLen)
|
||||
{
|
||||
|
||||
phost->Control.setup.b.bmRequestType = USB_D2H | USB_REQ_RECIPIENT_INTERFACE |\
|
||||
USB_REQ_TYPE_CLASS;
|
||||
|
||||
|
||||
phost->Control.setup.b.bRequest = USB_HID_GET_REPORT;
|
||||
phost->Control.setup.b.wValue.w = (reportType << 8 ) | reportId;
|
||||
|
||||
phost->Control.setup.b.wIndex.w = 0;
|
||||
phost->Control.setup.b.wLength.w = reportLen;
|
||||
|
||||
return USBH_CtlReq(phost, reportBuff , reportLen );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_Set_Protocol
|
||||
* Set protocol State.
|
||||
* @param phost: Host handle
|
||||
* @param protocol : Set Protocol for HID : boot/report protocol
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_HID_SetProtocol(USBH_HandleTypeDef *phost,
|
||||
uint8_t protocol)
|
||||
{
|
||||
|
||||
|
||||
phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_INTERFACE |\
|
||||
USB_REQ_TYPE_CLASS;
|
||||
|
||||
|
||||
phost->Control.setup.b.bRequest = USB_HID_SET_PROTOCOL;
|
||||
phost->Control.setup.b.wValue.w = protocol == 0 ? 0 : 1;
|
||||
phost->Control.setup.b.wIndex.w = 0;
|
||||
phost->Control.setup.b.wLength.w = 0;
|
||||
|
||||
return USBH_CtlReq(phost, 0 , 0 );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_ParseHIDDesc
|
||||
* This function Parse the HID descriptor
|
||||
* @param desc: HID Descriptor
|
||||
* @param buf: Buffer where the source descriptor is available
|
||||
* @retval None
|
||||
*/
|
||||
static void USBH_HID_ParseHIDDesc (HID_DescTypeDef *desc, uint8_t *buf)
|
||||
{
|
||||
|
||||
desc->bLength = *(uint8_t *) (buf + 0);
|
||||
desc->bDescriptorType = *(uint8_t *) (buf + 1);
|
||||
desc->bcdHID = LE16 (buf + 2);
|
||||
desc->bCountryCode = *(uint8_t *) (buf + 4);
|
||||
desc->bNumDescriptors = *(uint8_t *) (buf + 5);
|
||||
desc->bReportDescriptorType = *(uint8_t *) (buf + 6);
|
||||
desc->wItemLength = LE16 (buf + 7);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_HID_GetDeviceType
|
||||
* Return Device function.
|
||||
* @param phost: Host handle
|
||||
* @retval HID function: HID_MOUSE / HID_KEYBOARD
|
||||
*/
|
||||
HID_TypeTypeDef USBH_HID_GetDeviceType(USBH_HandleTypeDef *phost)
|
||||
{
|
||||
HID_TypeTypeDef type = HID_UNKNOWN;
|
||||
|
||||
if(phost->gState == HOST_CLASS)
|
||||
{
|
||||
|
||||
if(phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].bInterfaceProtocol \
|
||||
== HID_KEYBRD_BOOT_CODE)
|
||||
{
|
||||
type = HID_KEYBOARD;
|
||||
}
|
||||
else if(phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].bInterfaceProtocol \
|
||||
== HID_MOUSE_BOOT_CODE)
|
||||
{
|
||||
type= HID_MOUSE;
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_HID_GetPollInterval
|
||||
* Return HID device poll time
|
||||
* @param phost: Host handle
|
||||
* @retval poll time (ms)
|
||||
*/
|
||||
uint8_t USBH_HID_GetPollInterval(USBH_HandleTypeDef *phost)
|
||||
{
|
||||
HID_HandleTypeDef *HID_Handle = (HID_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
if((phost->gState == HOST_CLASS_REQUEST) ||
|
||||
(phost->gState == HOST_INPUT) ||
|
||||
(phost->gState == HOST_SET_CONFIGURATION) ||
|
||||
(phost->gState == HOST_CHECK_CLASS) ||
|
||||
((phost->gState == HOST_CLASS)))
|
||||
{
|
||||
return (HID_Handle->poll);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief fifo_init
|
||||
* Initialize FIFO.
|
||||
* @param f: Fifo address
|
||||
* @param buf: Fifo buffer
|
||||
* @param size: Fifo Size
|
||||
* @retval none
|
||||
*/
|
||||
void fifo_init(FIFO_TypeDef * f, uint8_t * buf, uint16_t size)
|
||||
{
|
||||
f->head = 0;
|
||||
f->tail = 0;
|
||||
f->lock = 0;
|
||||
f->size = size;
|
||||
f->buf = buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief fifo_read
|
||||
* Read from FIFO.
|
||||
* @param f: Fifo address
|
||||
* @param buf: read buffer
|
||||
* @param nbytes: number of item to read
|
||||
* @retval number of read items
|
||||
*/
|
||||
uint16_t fifo_read(FIFO_TypeDef * f, void * buf, uint16_t nbytes)
|
||||
{
|
||||
uint16_t i;
|
||||
uint8_t * p;
|
||||
p = (uint8_t*) buf;
|
||||
|
||||
if(f->lock == 0)
|
||||
{
|
||||
f->lock = 1;
|
||||
for(i=0; i < nbytes; i++)
|
||||
{
|
||||
if( f->tail != f->head )
|
||||
{
|
||||
*p++ = f->buf[f->tail];
|
||||
f->tail++;
|
||||
if( f->tail == f->size )
|
||||
{
|
||||
f->tail = 0;
|
||||
}
|
||||
} else
|
||||
{
|
||||
f->lock = 0;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
f->lock = 0;
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief fifo_write
|
||||
* Read from FIFO.
|
||||
* @param f: Fifo address
|
||||
* @param buf: read buffer
|
||||
* @param nbytes: number of item to write
|
||||
* @retval number of written items
|
||||
*/
|
||||
uint16_t fifo_write(FIFO_TypeDef * f, const void * buf, uint16_t nbytes)
|
||||
{
|
||||
uint16_t i;
|
||||
const uint8_t * p;
|
||||
p = (const uint8_t*) buf;
|
||||
if(f->lock == 0)
|
||||
{
|
||||
f->lock = 1;
|
||||
for(i=0; i < nbytes; i++)
|
||||
{
|
||||
if( (f->head + 1 == f->tail) ||
|
||||
( (f->head + 1 == f->size) && (f->tail == 0)) )
|
||||
{
|
||||
f->lock = 0;
|
||||
return i;
|
||||
}
|
||||
else
|
||||
{
|
||||
f->buf[f->head] = *p++;
|
||||
f->head++;
|
||||
if( f->head == f->size )
|
||||
{
|
||||
f->head = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
f->lock = 0;
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief The function is a callback about HID Data events
|
||||
* @param phost: Selected device
|
||||
* @retval None
|
||||
*/
|
||||
__weak void USBH_HID_EventCallback(USBH_HandleTypeDef *phost)
|
||||
{
|
||||
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* downstream_hid.c
|
||||
*
|
||||
* Created on: Apr 10, 2016
|
||||
* Author: Robert Fisk
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "downstream_hid.h"
|
||||
#include "downstream_statemachine.h"
|
||||
#include "usbh_hid.h"
|
||||
|
||||
|
||||
|
||||
#define HID_REPORT_DATA_LEN 8
|
||||
#define HID_MOUSE_DATA_LEN 3
|
||||
#define HID_KEYBOARD_DATA_LEN 0
|
||||
|
||||
|
||||
extern USBH_HandleTypeDef hUsbHostFS; //Hard-link ourselves to usb_host.c
|
||||
extern InterfaceCommandClassTypeDef ConfiguredDeviceClass; //Do a cheap hard-link to downstream_statemachine.c, rather than keep a duplicate here
|
||||
|
||||
|
||||
|
||||
InterfaceCommandClassTypeDef Downstream_HID_ApproveConnectedDevice(void)
|
||||
{
|
||||
HID_HandleTypeDef* HID_Handle = (HID_HandleTypeDef*)hUsbHostFS.pActiveClass->pData;
|
||||
|
||||
if (HID_Handle->Protocol == HID_MOUSE_BOOT_CODE)
|
||||
{
|
||||
if ((HID_Handle->length >= HID_MOUSE_DATA_LEN) && (HID_Handle->length <= HID_REPORT_DATA_LEN))
|
||||
{
|
||||
return COMMAND_CLASS_HID_MOUSE;
|
||||
}
|
||||
}
|
||||
|
||||
return COMMAND_CLASS_INTERFACE; //fail
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Downstream_HID_PacketProcessor(DownstreamPacketTypeDef* receivedPacket)
|
||||
{
|
||||
if (receivedPacket->Command != COMMAND_HID_REPORT)
|
||||
{
|
||||
Downstream_PacketProcessor_FreakOut();
|
||||
return;
|
||||
}
|
||||
|
||||
if (USBH_HID_GetInterruptReport(&hUsbHostFS,
|
||||
Downstream_HID_InterruptReportCallback,
|
||||
receivedPacket) != HAL_OK) //Don't free the packet, USBH_HID will use it then return it to InterruptReportCallback below
|
||||
{
|
||||
Downstream_PacketProcessor_FreakOut();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Downstream_HID_InterruptReportCallback(DownstreamPacketTypeDef* packetToSend)
|
||||
{
|
||||
if (ConfiguredDeviceClass == COMMAND_CLASS_HID_MOUSE)
|
||||
{
|
||||
packetToSend->Length16 = ((HID_MOUSE_DATA_LEN + 1) / 2) + DOWNSTREAM_PACKET_HEADER_LEN_16;
|
||||
}
|
||||
//else if...
|
||||
else
|
||||
{
|
||||
Downstream_PacketProcessor_FreakOut();
|
||||
return;
|
||||
}
|
||||
|
||||
Downstream_PacketProcessor_ClassReply(packetToSend);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* upstream_hid.h
|
||||
*
|
||||
* Created on: Jan 16, 2016
|
||||
* Author: Robert Fisk
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef UPSTREAM_HID_H_
|
||||
#define UPSTREAM_HID_H_
|
||||
|
||||
|
||||
|
||||
#include "stm32f4xx_hal.h"
|
||||
|
||||
|
||||
typedef uint8_t (*UpstreamHidSendReportCallback)(uint8_t *report,
|
||||
uint16_t len);
|
||||
|
||||
|
||||
|
||||
void Upstream_HID_DeInit(void);
|
||||
HAL_StatusTypeDef Upstream_HID_GetNextReport(UpstreamHidSendReportCallback callback);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* UPSTREAM_HID_H_ */
|
@ -0,0 +1,151 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_hid.h
|
||||
* @author MCD Application Team
|
||||
* @version V2.4.1
|
||||
* @date 19-June-2015
|
||||
* @brief Header file for the usbd_hid_core.c file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USB_HID_H
|
||||
#define __USB_HID_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_ioreq.h"
|
||||
|
||||
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_HID
|
||||
* @brief This file is the Header file for usbd_hid.c
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_HID_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
#define HID_EPIN_ADDR 0x81
|
||||
#define HID_EPIN_SIZE 0x04
|
||||
|
||||
#define USB_HID_CONFIG_DESC_SIZ 34
|
||||
#define USB_HID_DESC_SIZ 9
|
||||
#define HID_MOUSE_REPORT_DESC_SIZE 74
|
||||
|
||||
#define HID_DESCRIPTOR_TYPE 0x21
|
||||
#define HID_REPORT_DESC 0x22
|
||||
|
||||
#define HID_HS_BINTERVAL 0x07
|
||||
#define HID_FS_BINTERVAL 0x0A
|
||||
#define HID_POLLING_INTERVAL 0x0A
|
||||
|
||||
#define HID_REQ_SET_PROTOCOL 0x0B
|
||||
#define HID_REQ_GET_PROTOCOL 0x03
|
||||
|
||||
#define HID_REQ_SET_IDLE 0x0A
|
||||
#define HID_REQ_GET_IDLE 0x02
|
||||
|
||||
#define HID_REQ_SET_REPORT 0x09
|
||||
#define HID_REQ_GET_REPORT 0x01
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_CORE_Exported_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
HID_IDLE = 0,
|
||||
HID_BUSY,
|
||||
}
|
||||
HID_StateTypeDef;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t Protocol;
|
||||
uint32_t IdleState;
|
||||
uint32_t AltSetting;
|
||||
HID_StateTypeDef state;
|
||||
}
|
||||
USBD_HID_HandleTypeDef;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/** @defgroup USBD_CORE_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_CORE_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
extern USBD_ClassTypeDef USBD_HID;
|
||||
|
||||
|
||||
//#define USBD_HID_CLASS &USBD_HID
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USB_CORE_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
uint32_t USBD_HID_GetPollingInterval (USBD_HandleTypeDef *pdev);
|
||||
|
||||
void USBD_HID_PreinitMouse(void);
|
||||
void USBD_HID_PreinitKeyboard(void);
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USB_HID_H */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
@ -0,0 +1,521 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_hid.c
|
||||
* @author MCD Application Team
|
||||
* @version V2.4.1
|
||||
* @date 19-June-2015
|
||||
* @brief This file provides the HID core functions.
|
||||
*
|
||||
* @verbatim
|
||||
*
|
||||
* ===================================================================
|
||||
* HID Class Description
|
||||
* ===================================================================
|
||||
* This module manages the HID class V1.11 following the "Device Class Definition
|
||||
* for Human Interface Devices (HID) Version 1.11 Jun 27, 2001".
|
||||
* This driver implements the following aspects of the specification:
|
||||
* - The Boot Interface Subclass
|
||||
* - The Mouse protocol
|
||||
* - Usage Page : Generic Desktop
|
||||
* - Usage : Joystick
|
||||
* - Collection : Application
|
||||
*
|
||||
* @note In HS mode and when the DMA is used, all variables and data structures
|
||||
* dealing with the DMA during the transaction process should be 32-bit aligned.
|
||||
*
|
||||
*
|
||||
* @endverbatim
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*
|
||||
* Modifications by Robert Fisk
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_hid.h"
|
||||
#include "usbd_ctlreq.h"
|
||||
#include "upstream_hid.h"
|
||||
|
||||
|
||||
|
||||
static uint8_t USBD_HID_Init (USBD_HandleTypeDef *pdev,
|
||||
uint8_t cfgidx);
|
||||
|
||||
static uint8_t USBD_HID_DeInit (USBD_HandleTypeDef *pdev,
|
||||
uint8_t cfgidx);
|
||||
|
||||
static uint8_t USBD_HID_Setup (USBD_HandleTypeDef *pdev,
|
||||
USBD_SetupReqTypedef *req);
|
||||
|
||||
static uint8_t *USBD_HID_GetCfgDesc (uint16_t *length);
|
||||
|
||||
static uint8_t *USBD_HID_GetDeviceQualifierDesc (uint16_t *length);
|
||||
|
||||
static uint8_t USBD_HID_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum);
|
||||
|
||||
static uint8_t USBD_HID_SendReport (uint8_t *report,
|
||||
uint16_t len);
|
||||
|
||||
|
||||
|
||||
USBD_ClassTypeDef USBD_HID =
|
||||
{
|
||||
USBD_HID_Init,
|
||||
USBD_HID_DeInit,
|
||||
USBD_HID_Setup,
|
||||
NULL, /*EP0_TxSent*/
|
||||
NULL, /*EP0_RxReady*/
|
||||
USBD_HID_DataIn, /*DataIn*/
|
||||
NULL, /*DataOut*/
|
||||
NULL, /*SOF */
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
USBD_HID_GetCfgDesc,
|
||||
USBD_HID_GetCfgDesc,
|
||||
USBD_HID_GetCfgDesc,
|
||||
USBD_HID_GetDeviceQualifierDesc,
|
||||
};
|
||||
|
||||
|
||||
|
||||
#define USB_HID_CFGDESC__HID_REPORT_DESC_SIZE_OFFSET 25
|
||||
#define USB_HID_DESC__HID_REPORT_DESC_SIZE_OFFSET 7
|
||||
|
||||
|
||||
/* USB HID device Configuration Descriptor */
|
||||
__ALIGN_BEGIN static uint8_t USBD_HID_CfgDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_END =
|
||||
{
|
||||
0x09, /* bLength: Configuration Descriptor size */
|
||||
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
|
||||
USB_HID_CONFIG_DESC_SIZ,
|
||||
/* wTotalLength: Bytes returned */
|
||||
0x00,
|
||||
0x01, /*bNumInterfaces: 1 interface*/
|
||||
0x01, /*bConfigurationValue: Configuration value*/
|
||||
0x00, /*iConfiguration: Index of string descriptor describing
|
||||
the configuration*/
|
||||
0xE0, /*bmAttributes: bus powered and Support Remote Wake-up */
|
||||
0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/
|
||||
|
||||
/************** Descriptor of Joystick Mouse interface ****************/
|
||||
/* 09 */
|
||||
0x09, /*bLength: Interface Descriptor size*/
|
||||
USB_DESC_TYPE_INTERFACE,/*bDescriptorType: Interface descriptor type*/
|
||||
0x00, /*bInterfaceNumber: Number of Interface*/
|
||||
0x00, /*bAlternateSetting: Alternate setting*/
|
||||
0x01, /*bNumEndpoints*/
|
||||
0x03, /*bInterfaceClass: HID*/
|
||||
0x01, /*bInterfaceSubClass : 1=BOOT, 0=no boot*/
|
||||
0x02, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/
|
||||
0, /*iInterface: Index of string descriptor*/
|
||||
/******************** Descriptor of Joystick Mouse HID ********************/
|
||||
/* 18 */
|
||||
0x09, /*bLength: HID Descriptor size*/
|
||||
HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/
|
||||
0x11, /*bcdHID: HID Class Spec release number*/
|
||||
0x01,
|
||||
0x00, /*bCountryCode: Hardware target country*/
|
||||
0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/
|
||||
0x22, /*bDescriptorType*/
|
||||
0x00, //HID_MOUSE_REPORT_DESC_SIZE, /*wItemLength: Total length of Report descriptor*/
|
||||
0x00,
|
||||
/******************** Descriptor of Mouse endpoint ********************/
|
||||
/* 27 */
|
||||
0x07, /*bLength: Endpoint Descriptor size*/
|
||||
USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/
|
||||
|
||||
HID_EPIN_ADDR, /*bEndpointAddress: Endpoint Address (IN)*/
|
||||
0x03, /*bmAttributes: Interrupt endpoint*/
|
||||
HID_EPIN_SIZE, /*wMaxPacketSize: 4 Byte max */
|
||||
0x00,
|
||||
HID_FS_BINTERVAL, /*bInterval: Polling Interval (10 ms)*/
|
||||
/* 34 */
|
||||
} ;
|
||||
|
||||
/* USB HID device Configuration Descriptor */
|
||||
__ALIGN_BEGIN static uint8_t USBD_HID_Desc[USB_HID_DESC_SIZ] __ALIGN_END =
|
||||
{
|
||||
0x09, /*bLength: HID Descriptor size*/
|
||||
HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/
|
||||
0x11, /*bcdHID: HID Class Spec release number*/
|
||||
0x01,
|
||||
0x00, /*bCountryCode: Hardware target country*/
|
||||
0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/
|
||||
0x22, /*bDescriptorType*/
|
||||
0x00, //HID_MOUSE_REPORT_DESC_SIZE, /*wItemLength: Total length of Report descriptor*/
|
||||
0x00,
|
||||
};
|
||||
|
||||
/* USB Standard Device Descriptor */
|
||||
__ALIGN_BEGIN static uint8_t USBD_HID_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
|
||||
{
|
||||
USB_LEN_DEV_QUALIFIER_DESC,
|
||||
USB_DESC_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x01,
|
||||
0x00,
|
||||
};
|
||||
|
||||
__ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END =
|
||||
{
|
||||
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
|
||||
0x09, 0x02, // Usage (Mouse)
|
||||
0xA1, 0x01, // Collection (Application)
|
||||
0x09, 0x01, // Usage (Pointer)
|
||||
0xA1, 0x00, // Collection (Physical)
|
||||
0x05, 0x09, // Usage Page (Button)
|
||||
0x19, 0x01, // Usage Minimum (0x01)
|
||||
0x29, 0x03, // Usage Maximum (0x03)
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x25, 0x01, // Logical Maximum (1)
|
||||
0x95, 0x03, // Report Count (3)
|
||||
0x75, 0x01, // Report Size (1)
|
||||
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0x95, 0x01, // Report Count (1)
|
||||
0x75, 0x05, // Report Size (5)
|
||||
0x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
|
||||
0x09, 0x30, // Usage (X)
|
||||
0x09, 0x31, // Usage (Y)
|
||||
0x09, 0x38, // Usage (Wheel)
|
||||
0x15, 0x81, // Logical Minimum (129)
|
||||
0x25, 0x7F, // Logical Maximum (127)
|
||||
0x75, 0x08, // Report Size (8)
|
||||
0x95, 0x03, // Report Count (3)
|
||||
0x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0xC0, // End Collection
|
||||
0x09, 0x3C, // Usage (Motion Wakeup)
|
||||
0x05, 0xFF, // Usage Page (Reserved 0xFF)
|
||||
0x09, 0x01, // Usage (0x01)
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x25, 0x01, // Logical Maximum (1)
|
||||
0x75, 0x01, // Report Size (1)
|
||||
0x95, 0x01, // Report Count (1)
|
||||
0xB1, 0x22, // Feature (Data,Var,Abs,No Wrap,Linear,No Preferred State,No Null Position,Non-volatile)
|
||||
0x75, 0x07, // Report Size (7)
|
||||
0x95, 0x01, // Report Count (1)
|
||||
0xB1, 0x01, // Feature (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
|
||||
0xC0, // End Collection
|
||||
|
||||
// 74 bytes
|
||||
};
|
||||
|
||||
|
||||
USBD_HandleTypeDef *USBD_HID_pdev;
|
||||
uint8_t* ActiveReportDescriptor = NULL;
|
||||
uint8_t ActiveReportDescriptorLength;
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_HID_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief USBD_HID_Init
|
||||
* Initialize the HID interface
|
||||
* @param pdev: device instance
|
||||
* @param cfgidx: Configuration index
|
||||
* @retval status
|
||||
*/
|
||||
void USBD_HID_PreinitMouse(void)
|
||||
{
|
||||
ActiveReportDescriptor = HID_MOUSE_ReportDesc;
|
||||
ActiveReportDescriptorLength = HID_MOUSE_REPORT_DESC_SIZE;
|
||||
|
||||
USBD_HID_CfgDesc[USB_HID_CFGDESC__HID_REPORT_DESC_SIZE_OFFSET] = HID_MOUSE_REPORT_DESC_SIZE;
|
||||
USBD_HID_Desc[USB_HID_DESC__HID_REPORT_DESC_SIZE_OFFSET] = HID_MOUSE_REPORT_DESC_SIZE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static uint8_t USBD_HID_Init (USBD_HandleTypeDef *pdev,
|
||||
uint8_t cfgidx)
|
||||
{
|
||||
uint8_t ret = 0;
|
||||
|
||||
/* Open EP IN */
|
||||
USBD_LL_OpenEP(pdev,
|
||||
HID_EPIN_ADDR,
|
||||
USBD_EP_TYPE_INTR,
|
||||
HID_EPIN_SIZE);
|
||||
|
||||
pdev->pClassData = USBD_malloc(sizeof (USBD_HID_HandleTypeDef));
|
||||
|
||||
if(pdev->pClassData == NULL)
|
||||
{
|
||||
ret = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
((USBD_HID_HandleTypeDef *)pdev->pClassData)->state = HID_IDLE;
|
||||
|
||||
USBD_HID_pdev = pdev;
|
||||
Upstream_HID_GetNextReport(USBD_HID_SendReport);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_HID_Init
|
||||
* DeInitialize the HID layer
|
||||
* @param pdev: device instance
|
||||
* @param cfgidx: Configuration index
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_HID_DeInit (USBD_HandleTypeDef *pdev,
|
||||
uint8_t cfgidx)
|
||||
{
|
||||
ActiveReportDescriptor = NULL;
|
||||
Upstream_HID_DeInit();
|
||||
|
||||
/* Close HID EPs */
|
||||
USBD_LL_CloseEP(pdev,
|
||||
HID_EPIN_ADDR);
|
||||
|
||||
/* FRee allocated memory */
|
||||
if(pdev->pClassData != NULL)
|
||||
{
|
||||
USBD_free(pdev->pClassData);
|
||||
pdev->pClassData = NULL;
|
||||
}
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_HID_Setup
|
||||
* Handle the HID specific requests
|
||||
* @param pdev: instance
|
||||
* @param req: usb requests
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_HID_Setup (USBD_HandleTypeDef *pdev,
|
||||
USBD_SetupReqTypedef *req)
|
||||
{
|
||||
uint16_t len = 0;
|
||||
uint8_t *pbuf = NULL;
|
||||
USBD_HID_HandleTypeDef *hhid = (USBD_HID_HandleTypeDef*) pdev->pClassData;
|
||||
|
||||
if (ActiveReportDescriptor == NULL)
|
||||
{
|
||||
while (1);
|
||||
}
|
||||
|
||||
|
||||
switch (req->bmRequest & USB_REQ_TYPE_MASK)
|
||||
{
|
||||
case USB_REQ_TYPE_CLASS :
|
||||
switch (req->bRequest)
|
||||
{
|
||||
|
||||
|
||||
case HID_REQ_SET_PROTOCOL:
|
||||
hhid->Protocol = (uint8_t)(req->wValue);
|
||||
break;
|
||||
|
||||
case HID_REQ_GET_PROTOCOL:
|
||||
USBD_CtlSendData (pdev,
|
||||
(uint8_t *)&hhid->Protocol,
|
||||
1);
|
||||
break;
|
||||
|
||||
case HID_REQ_SET_IDLE:
|
||||
hhid->IdleState = (uint8_t)(req->wValue >> 8);
|
||||
break;
|
||||
|
||||
case HID_REQ_GET_IDLE:
|
||||
USBD_CtlSendData (pdev,
|
||||
(uint8_t *)&hhid->IdleState,
|
||||
1);
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_CtlError (pdev, req);
|
||||
return USBD_FAIL;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_REQ_TYPE_STANDARD:
|
||||
switch (req->bRequest)
|
||||
{
|
||||
case USB_REQ_GET_DESCRIPTOR:
|
||||
if( req->wValue >> 8 == HID_REPORT_DESC)
|
||||
{
|
||||
len = MIN(ActiveReportDescriptorLength , req->wLength);
|
||||
pbuf = ActiveReportDescriptor;
|
||||
}
|
||||
else if( req->wValue >> 8 == HID_DESCRIPTOR_TYPE)
|
||||
{
|
||||
pbuf = USBD_HID_Desc;
|
||||
len = MIN(USB_HID_DESC_SIZ , req->wLength);
|
||||
}
|
||||
|
||||
USBD_CtlSendData (pdev,
|
||||
pbuf,
|
||||
len);
|
||||
break;
|
||||
|
||||
case USB_REQ_GET_INTERFACE :
|
||||
USBD_CtlSendData (pdev,
|
||||
(uint8_t *)&hhid->AltSetting,
|
||||
1);
|
||||
break;
|
||||
|
||||
case USB_REQ_SET_INTERFACE :
|
||||
hhid->AltSetting = (uint8_t)(req->wValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_HID_SendReport
|
||||
* Send HID Report
|
||||
* @param pdev: device instance
|
||||
* @param buff: pointer to report
|
||||
* @retval status
|
||||
*/
|
||||
uint8_t USBD_HID_SendReport(uint8_t *report,
|
||||
uint16_t len)
|
||||
{
|
||||
USBD_HID_HandleTypeDef *hhid = (USBD_HID_HandleTypeDef*)USBD_HID_pdev->pClassData;
|
||||
|
||||
if (USBD_HID_pdev->dev_state == USBD_STATE_CONFIGURED )
|
||||
{
|
||||
if(hhid->state == HID_IDLE)
|
||||
{
|
||||
hhid->state = HID_BUSY;
|
||||
USBD_LL_Transmit (USBD_HID_pdev,
|
||||
HID_EPIN_ADDR,
|
||||
report,
|
||||
len);
|
||||
}
|
||||
}
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_HID_GetPollingInterval
|
||||
* return polling interval from endpoint descriptor
|
||||
* @param pdev: device instance
|
||||
* @retval polling interval
|
||||
*/
|
||||
uint32_t USBD_HID_GetPollingInterval (USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
uint32_t polling_interval = 0;
|
||||
|
||||
/* HIGH-speed endpoints */
|
||||
if(pdev->dev_speed == USBD_SPEED_HIGH)
|
||||
{
|
||||
/* Sets the data transfer polling interval for high speed transfers.
|
||||
Values between 1..16 are allowed. Values correspond to interval
|
||||
of 2 ^ (bInterval-1). This option (8 ms, corresponds to HID_HS_BINTERVAL */
|
||||
polling_interval = (((1 <<(HID_HS_BINTERVAL - 1)))/8);
|
||||
}
|
||||
else /* LOW and FULL-speed endpoints */
|
||||
{
|
||||
/* Sets the data transfer polling interval for low and full
|
||||
speed transfers */
|
||||
polling_interval = HID_FS_BINTERVAL;
|
||||
}
|
||||
|
||||
return ((uint32_t)(polling_interval));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_HID_GetCfgDesc
|
||||
* return configuration descriptor
|
||||
* @param speed : current device speed
|
||||
* @param length : pointer data length
|
||||
* @retval pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *USBD_HID_GetCfgDesc (uint16_t *length)
|
||||
{
|
||||
if (ActiveReportDescriptor == NULL)
|
||||
{
|
||||
while (1);
|
||||
}
|
||||
|
||||
*length = sizeof (USBD_HID_CfgDesc);
|
||||
return USBD_HID_CfgDesc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBD_HID_DataIn
|
||||
* handle data IN Stage
|
||||
* @param pdev: device instance
|
||||
* @param epnum: endpoint index
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_HID_DataIn (USBD_HandleTypeDef *pdev,
|
||||
uint8_t epnum)
|
||||
{
|
||||
/* Ensure that the FIFO is empty before a new transfer, this condition could
|
||||
be caused by a new transfer before the end of the previous transfer */
|
||||
((USBD_HID_HandleTypeDef *)pdev->pClassData)->state = HID_IDLE;
|
||||
|
||||
USBD_HID_pdev = pdev;
|
||||
Upstream_HID_GetNextReport(USBD_HID_SendReport);
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief DeviceQualifierDescriptor
|
||||
* return Device Qualifier descriptor
|
||||
* @param length : pointer data length
|
||||
* @retval pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *USBD_HID_GetDeviceQualifierDesc (uint16_t *length)
|
||||
{
|
||||
*length = sizeof (USBD_HID_DeviceQualifierDesc);
|
||||
return USBD_HID_DeviceQualifierDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
@ -0,0 +1,152 @@
|
||||
/*
|
||||
* upstream_hid.c
|
||||
*
|
||||
* Created on: Jan 16, 2016
|
||||
* Author: Robert Fisk
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "upstream_hid.h"
|
||||
#include "upstream_spi.h"
|
||||
#include "upstream_interface_def.h"
|
||||
|
||||
|
||||
#define HID_REPORT_DATA_LEN 8
|
||||
#define HID_MOUSE_DATA_LEN 3
|
||||
#define HID_KEYBOARD_DATA_LEN 0
|
||||
|
||||
|
||||
UpstreamPacketTypeDef* UpstreamHidPacket = NULL;
|
||||
UpstreamHidSendReportCallback ReportCallback = NULL;
|
||||
|
||||
|
||||
|
||||
void Upstream_HID_GetNextReportReceiveCallback(UpstreamPacketTypeDef* receivedPacket);
|
||||
|
||||
|
||||
|
||||
void Upstream_HID_DeInit(void)
|
||||
{
|
||||
if (UpstreamHidPacket != NULL)
|
||||
{
|
||||
Upstream_ReleasePacket(UpstreamHidPacket);
|
||||
UpstreamHidPacket = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
HAL_StatusTypeDef Upstream_HID_GetNextReport(UpstreamHidSendReportCallback callback)
|
||||
{
|
||||
UpstreamPacketTypeDef* freePacket;
|
||||
InterfaceCommandClassTypeDef activeClass;
|
||||
|
||||
activeClass = Upstream_StateMachine_CheckActiveClass();
|
||||
if ((activeClass != COMMAND_CLASS_HID_MOUSE)) //add classes here
|
||||
{
|
||||
UPSTREAM_STATEMACHINE_FREAKOUT;
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
//Release packet used for last transaction (if any)
|
||||
if (UpstreamHidPacket != NULL)
|
||||
{
|
||||
Upstream_ReleasePacket(UpstreamHidPacket);
|
||||
UpstreamHidPacket = NULL;
|
||||
}
|
||||
|
||||
if (ReportCallback != NULL)
|
||||
{
|
||||
UPSTREAM_STATEMACHINE_FREAKOUT;
|
||||
return HAL_ERROR;
|
||||
}
|
||||
ReportCallback = callback;
|
||||
|
||||
freePacket = Upstream_GetFreePacketImmediately();
|
||||
if (freePacket == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
freePacket->Length16 = UPSTREAM_PACKET_HEADER_LEN_16;
|
||||
freePacket->CommandClass = activeClass;
|
||||
freePacket->Command = COMMAND_HID_REPORT;
|
||||
|
||||
if (Upstream_TransmitPacket(freePacket) == HAL_OK)
|
||||
{
|
||||
return Upstream_ReceivePacket(Upstream_HID_GetNextReportReceiveCallback);
|
||||
}
|
||||
|
||||
//else:
|
||||
Upstream_ReleasePacket(freePacket);
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Upstream_HID_GetNextReportReceiveCallback(UpstreamPacketTypeDef* receivedPacket)
|
||||
{
|
||||
UpstreamHidSendReportCallback tempReportCallback;
|
||||
InterfaceCommandClassTypeDef activeClass;
|
||||
uint8_t dataLength = 0;
|
||||
uint8_t i;
|
||||
|
||||
activeClass = Upstream_StateMachine_CheckActiveClass();
|
||||
if ((activeClass != COMMAND_CLASS_HID_MOUSE)) //add classes here
|
||||
{
|
||||
UPSTREAM_STATEMACHINE_FREAKOUT;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((UpstreamHidPacket != NULL) ||
|
||||
(ReportCallback == NULL))
|
||||
{
|
||||
UPSTREAM_SPI_FREAKOUT;
|
||||
return;
|
||||
}
|
||||
|
||||
if (receivedPacket == NULL)
|
||||
{
|
||||
return; //Just give up...
|
||||
}
|
||||
|
||||
|
||||
if (activeClass == COMMAND_CLASS_HID_MOUSE)
|
||||
{
|
||||
if (receivedPacket->Length16 != (UPSTREAM_PACKET_HEADER_LEN_16 + ((HID_MOUSE_DATA_LEN + 1) / 2)))
|
||||
{
|
||||
UPSTREAM_SPI_FREAKOUT;
|
||||
return;
|
||||
}
|
||||
|
||||
//Mouse sanity checks & stuff go here...
|
||||
|
||||
dataLength = HID_MOUSE_DATA_LEN;
|
||||
}
|
||||
|
||||
//Other HID classes go here...
|
||||
|
||||
|
||||
if (dataLength == 0)
|
||||
{
|
||||
UPSTREAM_SPI_FREAKOUT;
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = dataLength; i < HID_REPORT_DATA_LEN; i++)
|
||||
{
|
||||
receivedPacket->Data[i] = 0; //Zero out unused bytes before we send report upstream
|
||||
}
|
||||
|
||||
UpstreamHidPacket = receivedPacket; //Save packet so we can free it when upstream USB transaction is done
|
||||
tempReportCallback = ReportCallback;
|
||||
ReportCallback = NULL;
|
||||
tempReportCallback(receivedPacket->Data, HID_REPORT_DATA_LEN);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in new issue