diff --git a/Downstream/.cproject b/Downstream/.cproject index 2730d12..1f23b55 100644 --- a/Downstream/.cproject +++ b/Downstream/.cproject @@ -45,10 +45,10 @@ - + - + @@ -61,6 +61,7 @@ + @@ -103,7 +104,7 @@ - + @@ -166,10 +167,10 @@ - + - + @@ -182,6 +183,7 @@ + @@ -223,7 +225,7 @@ - + diff --git a/Downstream/.settings/org.eclipse.cdt.codan.core.prefs b/Downstream/.settings/org.eclipse.cdt.codan.core.prefs index 77386c2..ff135cf 100644 --- a/Downstream/.settings/org.eclipse.cdt.codan.core.prefs +++ b/Downstream/.settings/org.eclipse.cdt.codan.core.prefs @@ -3,6 +3,10 @@ org.eclipse.cdt.codan.checkers.errnoreturn=Warning org.eclipse.cdt.codan.checkers.errnoreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},implicit\=>false} org.eclipse.cdt.codan.checkers.errreturnvalue=Error org.eclipse.cdt.codan.checkers.errreturnvalue.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} +org.eclipse.cdt.codan.checkers.nocommentinside=-Error +org.eclipse.cdt.codan.checkers.nocommentinside.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} +org.eclipse.cdt.codan.checkers.nolinecomment=-Error +org.eclipse.cdt.codan.checkers.nolinecomment.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} org.eclipse.cdt.codan.checkers.noreturn=Error org.eclipse.cdt.codan.checkers.noreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},implicit\=>false} org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation=Error diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hcd.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hcd.c index 1c26e4d..cb659bf 100644 --- a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hcd.c +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hcd.c @@ -879,11 +879,14 @@ static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum) hhcd->hc[chnum].urb_state = URB_NOTREADY; } - /* re-activate the channel */ - tmpreg = USBx_HC(chnum)->HCCHAR; - tmpreg &= ~USB_OTG_HCCHAR_CHDIS; - tmpreg |= USB_OTG_HCCHAR_CHENA; - USBx_HC(chnum)->HCCHAR = tmpreg; + if (hhcd->hc[chnum].ep_type != EP_TYPE_INTR) //DON'T re-enable an interrupt-in transaction + { + /* re-activate the channel */ + tmpreg = USBx_HC(chnum)->HCCHAR; + tmpreg &= ~USB_OTG_HCCHAR_CHDIS; + tmpreg |= USB_OTG_HCCHAR_CHENA; + USBx_HC(chnum)->HCCHAR = tmpreg; + } } __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH); HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state); diff --git a/Downstream/Inc/downstream_hid.h b/Downstream/Inc/downstream_hid.h new file mode 100644 index 0000000..e3c3bbd --- /dev/null +++ b/Downstream/Inc/downstream_hid.h @@ -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_ */ diff --git a/Downstream/Inc/downstream_interface_def.h b/Downstream/Inc/downstream_interface_def.h index 435d6e8..57ebfcf 100644 --- a/Downstream/Inc/downstream_interface_def.h +++ b/Downstream/Inc/downstream_interface_def.h @@ -15,7 +15,7 @@ //*************** // Attention! -// Keep this file synchronised with downstream_interface_def.h +// Keep this file synchronised with upstream_interface_def.h // in the Upstream project. //*************** @@ -29,6 +29,8 @@ typedef enum { COMMAND_CLASS_INTERFACE, COMMAND_CLASS_MASS_STORAGE, + COMMAND_CLASS_HID_MOUSE, + COMMAND_CLASS_HID_KEYBOARD, //... COMMAND_CLASS_ERROR } @@ -53,6 +55,13 @@ typedef enum InterfaceCommandMscTypeDef; +typedef enum +{ + COMMAND_HID_REPORT, //Returns HID report +} +InterfaceCommandHidTypeDef; + + typedef enum { COMMAND_ERROR_GENERIC, diff --git a/Downstream/Inc/downstream_msc.h b/Downstream/Inc/downstream_msc.h index 9b5bbd8..d78c226 100644 --- a/Downstream/Inc/downstream_msc.h +++ b/Downstream/Inc/downstream_msc.h @@ -13,6 +13,7 @@ #define INC_DOWNSTREAM_MSC_H_ +#include "downstream_interface_def.h" #include "downstream_spi.h" @@ -24,7 +25,7 @@ typedef void (*DownstreamMSCCallbackPacketTypeDef)(DownstreamPacketTypeDef* rece uint16_t dataLength8); -HAL_StatusTypeDef Downstream_MSC_ApproveConnectedDevice(void); +InterfaceCommandClassTypeDef Downstream_MSC_ApproveConnectedDevice(void); void Downstream_MSC_PacketProcessor(DownstreamPacketTypeDef* receivedPacket); HAL_StatusTypeDef Downstream_MSC_PutStreamDataPacket(DownstreamPacketTypeDef* packetToSend, uint32_t dataLength8); diff --git a/Downstream/Inc/downstream_spi.h b/Downstream/Inc/downstream_spi.h index 5e6f0fb..6f59a6f 100644 --- a/Downstream/Inc/downstream_spi.h +++ b/Downstream/Inc/downstream_spi.h @@ -17,7 +17,7 @@ #define DOWNSTREAM_PACKET_HEADER_LEN (2) //Min length = CommandClass & Command bytes -#define DOWNSTREAM_PACKET_LEN (DOWNSTREAM_PACKET_HEADER_LEN + USBH_MAX_DATA_BUFFER) +#define DOWNSTREAM_PACKET_LEN (DOWNSTREAM_PACKET_HEADER_LEN + BOT_PAGE_LENGTH) #define DOWNSTREAM_PACKET_LEN_MIN (DOWNSTREAM_PACKET_HEADER_LEN) #define DOWNSTREAM_PACKET_HEADER_LEN_16 (DOWNSTREAM_PACKET_HEADER_LEN / 2) @@ -59,7 +59,7 @@ typedef struct uint16_t Length16 __ALIGN_END; //Packet length includes CommandClass, Command, and Data uint8_t CommandClass; uint8_t Command; - uint8_t Data[USBH_MAX_DATA_BUFFER]; //Should (must?) be word-aligned, for USB copy routine + uint8_t Data[BOT_PAGE_LENGTH]; //Should (must?) be word-aligned, for USB copy routine } DownstreamPacketTypeDef; diff --git a/Downstream/Inc/downstream_statemachine.h b/Downstream/Inc/downstream_statemachine.h index fbd5874..6e86311 100644 --- a/Downstream/Inc/downstream_statemachine.h +++ b/Downstream/Inc/downstream_statemachine.h @@ -33,7 +33,7 @@ typedef enum do { \ USB_Host_Disconnect(); \ LED_Fault_SetBlinkRate(LED_FAST_BLINK_RATE); \ - DownstreamState = STATE_ERROR; \ + /*DownstreamState = STATE_ERROR; */ \ while (1); \ } while (0); diff --git a/Downstream/Inc/usbh_config.h b/Downstream/Inc/usbh_config.h index a576fa4..9552859 100644 --- a/Downstream/Inc/usbh_config.h +++ b/Downstream/Inc/usbh_config.h @@ -62,22 +62,23 @@ #define USBH_KEEP_CFG_DESCRIPTOR 1 /*---------- -----------*/ -#define USBH_MAX_NUM_SUPPORTED_CLASS 1 +#define USBH_MAX_NUM_SUPPORTED_CLASS 2 /*---------- -----------*/ #define USBH_MAX_SIZE_CONFIGURATION 256 /*---------- -----------*/ -#define USBH_MAX_DATA_BUFFER 512 +#define USBH_MAX_DATA_BUFFER 256 //was 512, string descriptors are max 255 bytes /*---------- -----------*/ #define USBH_DEBUG_LEVEL 0 /*---------- -----------*/ #define USBH_USE_OS 0 + - - +#define BOT_PAGE_LENGTH 512 //Moved here from usbh_msc_bot.h to avoid a circular include loop :( + /****************************************/ /* #define for FS and HS identification */ diff --git a/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/HID/Inc/usbh_hid.h b/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/HID/Inc/usbh_hid.h new file mode 100644 index 0000000..a611ace --- /dev/null +++ b/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/HID/Inc/usbh_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 + * + * © COPYRIGHT 2015 STMicroelectronics + * + * 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****/ + diff --git a/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/HID/Src/usbh_hid.c b/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/HID/Src/usbh_hid.c new file mode 100644 index 0000000..557cc9f --- /dev/null +++ b/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/HID/Src/usbh_hid.c @@ -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 + * + * © COPYRIGHT 2015 STMicroelectronics + * + * 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****/ diff --git a/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Inc/usbh_msc.h b/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Inc/usbh_msc.h index 83d2a3f..d184b7a 100644 --- a/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Inc/usbh_msc.h +++ b/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Inc/usbh_msc.h @@ -144,7 +144,7 @@ MSC_HandleTypeDef; /* Interface Descriptor field values for MSC Protocol */ #define MSC_BOT 0x50 -#define MSC_TRANSPARENT 0x06 +#define MSC_TRANSPARENT 0x06 /** * @} */ diff --git a/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Inc/usbh_msc_bot.h b/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Inc/usbh_msc_bot.h index 2c8e805..3067d30 100644 --- a/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Inc/usbh_msc_bot.h +++ b/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Inc/usbh_msc_bot.h @@ -38,7 +38,6 @@ /* Includes ------------------------------------------------------------------*/ #include "usbh_core.h" -#include "usbh_msc_bot.h" #include "downstream_spi.h" @@ -177,8 +176,6 @@ BOT_HandleTypeDef; #define BOT_DIR_OUT 1 #define BOT_DIR_BOTH 2 -#define BOT_PAGE_LENGTH 512 - #define BOT_CBW_CB_LENGTH 16 diff --git a/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Src/usbh_msc_bot.c b/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Src/usbh_msc_bot.c index e49aafc..65f7f13 100644 --- a/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Src/usbh_msc_bot.c +++ b/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Src/usbh_msc_bot.c @@ -243,7 +243,7 @@ USBH_StatusTypeDef USBH_MSC_BOT_Process (USBH_HandleTypeDef *phost, uint8_t lun) { //Dispatch current bot_packet, then get a new one if (Downstream_MSC_PutStreamDataPacket(MSC_Handle->hbot.bot_packet, - (BOT_PAGE_LENGTH - MSC_Handle->hbot.bot_packet_bytes_remaining)) != HAL_OK) + BOT_PAGE_LENGTH) != HAL_OK) { MSC_Handle->hbot.state = BOT_ERROR_IN; break; diff --git a/Downstream/Middlewares/ST/STM32_USB_Host_Library/Core/Inc/usbh_ctlreq.h b/Downstream/Middlewares/ST/STM32_USB_Host_Library/Core/Inc/usbh_ctlreq.h index 8b2f7c2..59042d9 100644 --- a/Downstream/Middlewares/ST/STM32_USB_Host_Library/Core/Inc/usbh_ctlreq.h +++ b/Downstream/Middlewares/ST/STM32_USB_Host_Library/Core/Inc/usbh_ctlreq.h @@ -88,7 +88,7 @@ /** @defgroup USBH_CTLREQ_Exported_Variables * @{ */ -extern uint8_t USBH_CfgDesc[512]; +//extern uint8_t USBH_CfgDesc[512]; /** * @} */ diff --git a/Downstream/Src/downstream_hid.c b/Downstream/Src/downstream_hid.c new file mode 100644 index 0000000..67dee40 --- /dev/null +++ b/Downstream/Src/downstream_hid.c @@ -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); +} + + diff --git a/Downstream/Src/downstream_msc.c b/Downstream/Src/downstream_msc.c index b6b83a9..23ef28f 100644 --- a/Downstream/Src/downstream_msc.c +++ b/Downstream/Src/downstream_msc.c @@ -37,27 +37,27 @@ void Downstream_MSC_GetStreamDataPacketCallback(DownstreamPacketTypeDef* receive //High-level checks on the connected device. We don't want some weirdly //configured device to bomb our USB stack, accidentally or otherwise. -HAL_StatusTypeDef Downstream_MSC_ApproveConnectedDevice(void) +InterfaceCommandClassTypeDef Downstream_MSC_ApproveConnectedDevice(void) { MSC_HandleTypeDef* MSC_Handle = (MSC_HandleTypeDef*)hUsbHostFS.pActiveClass->pData; if (MSC_Handle->unit[MSC_FIXED_LUN].error != MSC_OK) { - return HAL_ERROR; + return COMMAND_CLASS_INTERFACE; //fail } if ((MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr == 0) || (MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr == UINT32_MAX)) { - return HAL_ERROR; + return COMMAND_CLASS_INTERFACE; //fail } if (MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_size != MSC_SUPPORTED_BLOCK_SIZE) { - return HAL_ERROR; + return COMMAND_CLASS_INTERFACE; //fail } - return HAL_OK; + return COMMAND_CLASS_MASS_STORAGE; } diff --git a/Downstream/Src/downstream_statemachine.c b/Downstream/Src/downstream_statemachine.c index d4482cd..347c415 100644 --- a/Downstream/Src/downstream_statemachine.c +++ b/Downstream/Src/downstream_statemachine.c @@ -10,12 +10,15 @@ */ +#include #include "downstream_statemachine.h" #include "downstream_interface_def.h" #include "downstream_spi.h" #include "downstream_msc.h" +#include "downstream_hid.h" #include "usbh_core.h" #include "usbh_msc.h" +#include "usbh_hid.h" #include "led.h" @@ -31,6 +34,13 @@ void Downstream_PacketProcessor_Interface_ReplyNotifyDevice(DownstreamPacketType void Downstream_InitStateMachine(void) { + if ((DownstreamState != STATE_DEVICE_NOT_READY) || + (ConfiguredDeviceClass != COMMAND_CLASS_INTERFACE)) + { + DOWNSTREAM_STATEMACHINE_FREAKOUT; + return; + } + Downstream_InitSPI(); //Prepare to receive our first packet from Upstream! @@ -68,19 +78,28 @@ void Downstream_PacketProcessor(DownstreamPacketTypeDef* receivedPacket) return; } - //We should only receive class-specific messages when we are in the Active state. - if (DownstreamState != STATE_ACTIVE) + //We should only receive class-specific messages when we are in the Active state, + //and only to our currently active device class. + if ((DownstreamState != STATE_ACTIVE) || + (receivedPacket->CommandClass != ConfiguredDeviceClass)) { DOWNSTREAM_STATEMACHINE_FREAKOUT; return; } - switch (receivedPacket->CommandClass) + + switch (ConfiguredDeviceClass) { case COMMAND_CLASS_MASS_STORAGE: Downstream_MSC_PacketProcessor(receivedPacket); break; + case COMMAND_CLASS_HID_MOUSE: + case COMMAND_CLASS_HID_KEYBOARD: + Downstream_HID_PacketProcessor(receivedPacket); + break; + + //Add other classes here... default: @@ -195,10 +214,11 @@ void Downstream_HostUserCallback(USBH_HandleTypeDef *phost, uint8_t id) switch (phost->pActiveClass->ClassCode) { case USB_MSC_CLASS: - if (Downstream_MSC_ApproveConnectedDevice() == HAL_OK) - { - newActiveClass = COMMAND_CLASS_MASS_STORAGE; - } + newActiveClass = Downstream_MSC_ApproveConnectedDevice(); + break; + + case USB_HID_CLASS: + newActiveClass = Downstream_HID_ApproveConnectedDevice(); break; //Add other classes here... diff --git a/Downstream/Src/usb_host.c b/Downstream/Src/usb_host.c index 442eea1..5db673e 100644 --- a/Downstream/Src/usb_host.c +++ b/Downstream/Src/usb_host.c @@ -38,6 +38,7 @@ #include "usb_host.h" #include "usbh_core.h" #include "usbh_msc.h" +#include "usbh_hid.h" #include "downstream_statemachine.h" /* USB Host Core handle declaration */ @@ -51,6 +52,7 @@ void USB_Host_Init(void) USBH_Init(&hUsbHostFS, Downstream_HostUserCallback, HOST_FS); USBH_RegisterClass(&hUsbHostFS, USBH_MSC_CLASS); + USBH_RegisterClass(&hUsbHostFS, USBH_HID_CLASS); USBH_Start(&hUsbHostFS); } diff --git a/OpenOCD_scripts/README b/OpenOCD_scripts/README index e5834ef..8913e8a 100644 --- a/OpenOCD_scripts/README +++ b/OpenOCD_scripts/README @@ -1,4 +1,5 @@ -The OpenOCD scripts in ./board/ are used in-place by the Eclipse debug configurations. +The OpenOCD scripts in ./board/ are used in-place by the Eclipse debug configurations. You +don't need to copy them anywhere. If your OpenOCD version is <= 0.8, you will need to copy ./target/stm32f4x.cfg to your OpenOCD installation's /scripts/target/ folder, replacing the version currently there. diff --git a/Upstream/.cproject b/Upstream/.cproject index 5f285a8..e0a67c4 100755 --- a/Upstream/.cproject +++ b/Upstream/.cproject @@ -8,6 +8,8 @@ + + @@ -46,7 +48,7 @@ - + @@ -56,6 +58,7 @@ + @@ -70,6 +73,7 @@ + @@ -136,6 +140,8 @@ + + @@ -171,7 +177,7 @@ - + @@ -181,6 +187,7 @@ + @@ -195,6 +202,7 @@ + diff --git a/Upstream/Inc/upstream_hid.h b/Upstream/Inc/upstream_hid.h new file mode 100644 index 0000000..9bc5de7 --- /dev/null +++ b/Upstream/Inc/upstream_hid.h @@ -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_ */ diff --git a/Upstream/Inc/upstream_interface_def.h b/Upstream/Inc/upstream_interface_def.h index dc2a12c..f122887 100644 --- a/Upstream/Inc/upstream_interface_def.h +++ b/Upstream/Inc/upstream_interface_def.h @@ -31,6 +31,8 @@ typedef enum { COMMAND_CLASS_INTERFACE, COMMAND_CLASS_MASS_STORAGE, + COMMAND_CLASS_HID_MOUSE, + COMMAND_CLASS_HID_KEYBOARD, //... COMMAND_CLASS_ERROR } @@ -55,6 +57,13 @@ typedef enum InterfaceCommandMscTypeDef; +typedef enum +{ + COMMAND_HID_REPORT, //Returns HID report +} +InterfaceCommandHidTypeDef; + + typedef enum { COMMAND_ERROR_GENERIC, diff --git a/Upstream/Inc/upstream_spi.h b/Upstream/Inc/upstream_spi.h index f41c8c6..7e180c2 100644 --- a/Upstream/Inc/upstream_spi.h +++ b/Upstream/Inc/upstream_spi.h @@ -13,7 +13,10 @@ #define INC_UPSTREAM_SPI_H_ +#include "upstream_statemachine.h" #include "usbd_config.h" +#include "led.h" + #define UPSTREAM_PACKET_HEADER_LEN (2) //Min length = CommandClass & Command bytes @@ -86,4 +89,5 @@ void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi); void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi); + #endif /* INC_UPSTREAM_SPI_H_ */ diff --git a/Upstream/Inc/upstream_statemachine.h b/Upstream/Inc/upstream_statemachine.h index c199e66..99b4802 100644 --- a/Upstream/Inc/upstream_statemachine.h +++ b/Upstream/Inc/upstream_statemachine.h @@ -14,6 +14,7 @@ #include "led.h" +#include "upstream_interface_def.h" typedef enum @@ -37,7 +38,7 @@ typedef enum void Upstream_InitStateMachine(void); void Upstream_StateMachine_SetErrorState(void); -HAL_StatusTypeDef Upstream_StateMachine_CheckClassOperationOk(void); +InterfaceCommandClassTypeDef Upstream_StateMachine_CheckActiveClass(void); void Upstream_StateMachine_DeviceDisconnected(void); diff --git a/Upstream/Middlewares/ST/STM32_USB_Device_Library/Class/HID/Inc/usbd_hid.h b/Upstream/Middlewares/ST/STM32_USB_Device_Library/Class/HID/Inc/usbd_hid.h new file mode 100644 index 0000000..2aef166 --- /dev/null +++ b/Upstream/Middlewares/ST/STM32_USB_Device_Library/Class/HID/Inc/usbd_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 + * + * © COPYRIGHT 2015 STMicroelectronics + * + * 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****/ diff --git a/Upstream/Middlewares/ST/STM32_USB_Device_Library/Class/HID/Src/usbd_hid.c b/Upstream/Middlewares/ST/STM32_USB_Device_Library/Class/HID/Src/usbd_hid.c new file mode 100644 index 0000000..c60c011 --- /dev/null +++ b/Upstream/Middlewares/ST/STM32_USB_Device_Library/Class/HID/Src/usbd_hid.c @@ -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 + * + * © COPYRIGHT 2015 STMicroelectronics + * + * 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****/ diff --git a/Upstream/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c b/Upstream/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c index 6e00101..8353a12 100755 --- a/Upstream/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c +++ b/Upstream/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c @@ -548,7 +548,10 @@ USBD_StatusTypeDef USBD_DevDisconnected(USBD_HandleTypeDef *pdev) USBD_StatusTypeDef USBD_BufferFreed(USBD_HandleTypeDef *pdev) { - pdev->pClass->FreeDataBuffer(pdev); + if(pdev->pClass->FreeDataBuffer != NULL) + { + pdev->pClass->FreeDataBuffer(pdev); + } return USBD_OK; } /** diff --git a/Upstream/Src/upstream_hid.c b/Upstream/Src/upstream_hid.c new file mode 100644 index 0000000..3835fcd --- /dev/null +++ b/Upstream/Src/upstream_hid.c @@ -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); +} + + diff --git a/Upstream/Src/upstream_msc.c b/Upstream/Src/upstream_msc.c index dd35959..bf71253 100644 --- a/Upstream/Src/upstream_msc.c +++ b/Upstream/Src/upstream_msc.c @@ -41,8 +41,9 @@ static void Upstream_MSC_BeginWriteReplyCallback(UpstreamPacketTypeDef* replyPac HAL_StatusTypeDef Upstream_MSC_TestReady(UpstreamMSCCallbackTypeDef callback) { - if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK) + if (Upstream_StateMachine_CheckActiveClass() != COMMAND_CLASS_MASS_STORAGE) { + //UPSTREAM_STATEMACHINE_FREAKOUT; return HAL_ERROR; } @@ -60,7 +61,7 @@ void Upstream_MSC_TestReadyFreePacketCallback(UpstreamPacketTypeDef* freePacket) if (Upstream_TransmitPacket(freePacket) == HAL_OK) { - Upstream_ReleasePacket(freePacket); + //Upstream_ReleasePacket(freePacket); /////////!!!!!!!!!!!!!??????????? if (Upstream_ReceivePacket(Upstream_MSC_TestReadyReplyCallback) != HAL_OK) { TestReadyCallback(HAL_ERROR); @@ -77,7 +78,7 @@ void Upstream_MSC_TestReadyFreePacketCallback(UpstreamPacketTypeDef* freePacket) void Upstream_MSC_TestReadyReplyCallback(UpstreamPacketTypeDef* replyPacket) { - if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK) + if (Upstream_StateMachine_CheckActiveClass() != COMMAND_CLASS_MASS_STORAGE) { return; } @@ -89,7 +90,7 @@ void Upstream_MSC_TestReadyReplyCallback(UpstreamPacketTypeDef* replyPacket) } if ((replyPacket->Length16 != (UPSTREAM_PACKET_HEADER_LEN_16 + 1)) || - (replyPacket->Data[0] != HAL_OK)) + (replyPacket->Data[0] != HAL_OK)) { Upstream_ReleasePacket(replyPacket); TestReadyCallback(HAL_ERROR); @@ -106,7 +107,7 @@ HAL_StatusTypeDef Upstream_MSC_GetCapacity(UpstreamMSCCallbackUintPacketTypeDef { UpstreamPacketTypeDef* freePacket; - if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK) + if (Upstream_StateMachine_CheckActiveClass() != COMMAND_CLASS_MASS_STORAGE) { return HAL_ERROR; } @@ -126,6 +127,7 @@ HAL_StatusTypeDef Upstream_MSC_GetCapacity(UpstreamMSCCallbackUintPacketTypeDef return Upstream_ReceivePacket(Upstream_MSC_GetCapacityReplyCallback); } //else: + Upstream_ReleasePacket(freePacket); ////////????????? return HAL_ERROR; } @@ -135,7 +137,7 @@ void Upstream_MSC_GetCapacityReplyCallback(UpstreamPacketTypeDef* replyPacket) uint32_t uint1; uint32_t uint2; - if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK) + if (Upstream_StateMachine_CheckActiveClass() != COMMAND_CLASS_MASS_STORAGE) { return; } @@ -164,7 +166,7 @@ HAL_StatusTypeDef Upstream_MSC_BeginRead(UpstreamMSCCallbackTypeDef callback, uint32_t readBlockCount, uint32_t readByteCount) { - if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK) + if (Upstream_StateMachine_CheckActiveClass() != COMMAND_CLASS_MASS_STORAGE) { return HAL_ERROR; } @@ -207,7 +209,7 @@ void Upstream_MSC_BeginReadFreePacketCallback(UpstreamPacketTypeDef* freePacket) HAL_StatusTypeDef Upstream_MSC_GetStreamDataPacket(UpstreamMSCCallbackPacketTypeDef callback) { - if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK) + if (Upstream_StateMachine_CheckActiveClass() != COMMAND_CLASS_MASS_STORAGE) { return HAL_ERROR; } @@ -236,7 +238,7 @@ void Upstream_MSC_GetStreamDataPacketCallback(UpstreamPacketTypeDef* replyPacket ReadStreamBusy = 0; - if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK) + if (Upstream_StateMachine_CheckActiveClass() != COMMAND_CLASS_MASS_STORAGE) { return; } @@ -256,7 +258,7 @@ void Upstream_MSC_GetStreamDataPacketCallback(UpstreamPacketTypeDef* replyPacket dataLength8 = (replyPacket->Length16 - UPSTREAM_PACKET_HEADER_LEN_16) * 2; if (((replyPacket->CommandClass & COMMAND_CLASS_DATA_FLAG) == 0) || //Any 'command' reply (as opposed to 'data' reply) is an automatic fail here - (replyPacket->Length16 <= UPSTREAM_PACKET_HEADER_LEN_16) || //Should be at least one data byte in the reply. + (replyPacket->Length16 <= UPSTREAM_PACKET_HEADER_LEN_16) || //Should be at least one data byte in the reply. (dataLength8 > ByteCount)) //No more data than expected transfer length { GetStreamDataCallback(NULL, 0); @@ -277,7 +279,7 @@ HAL_StatusTypeDef Upstream_MSC_BeginWrite(UpstreamMSCCallbackTypeDef callback, uint64_t writeBlockStart, uint32_t writeBlockCount) { - if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK) + if (Upstream_StateMachine_CheckActiveClass() != COMMAND_CLASS_MASS_STORAGE) { return HAL_ERROR; } @@ -318,7 +320,7 @@ void Upstream_MSC_BeginWriteReplyCallback(UpstreamPacketTypeDef* replyPacket) { uint8_t tempResult; - if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK) + if (Upstream_StateMachine_CheckActiveClass() != COMMAND_CLASS_MASS_STORAGE) { return; } @@ -347,7 +349,7 @@ void Upstream_MSC_BeginWriteReplyCallback(UpstreamPacketTypeDef* replyPacket) HAL_StatusTypeDef Upstream_MSC_PutStreamDataPacket(UpstreamPacketTypeDef* packetToSend, uint32_t dataLength8) { - if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK) + if (Upstream_StateMachine_CheckActiveClass() != COMMAND_CLASS_MASS_STORAGE) { return HAL_ERROR; } diff --git a/Upstream/Src/upstream_spi.c b/Upstream/Src/upstream_spi.c index e4787d1..d3c1b42 100644 --- a/Upstream/Src/upstream_spi.c +++ b/Upstream/Src/upstream_spi.c @@ -11,9 +11,7 @@ #include "upstream_interface_def.h" #include "upstream_spi.h" -#include "upstream_statemachine.h" #include "stm32f4xx_hal.h" -#include "usbd_def.h" #include "board_config.h" #include "interrupts.h" @@ -148,6 +146,12 @@ void Upstream_ReleasePacket(UpstreamPacketTypeDef* packetToRelease) return; } + if (packetToRelease->Busy != BUSY) + { + UPSTREAM_SPI_FREAKOUT; + return; + } + if (PendingFreePacketCallback != NULL) { tempCallback = PendingFreePacketCallback; //In extreme situations, running this callback can trigger another request for a free packet, @@ -445,8 +449,8 @@ void Upstream_BeginTransmitPacketSize(void) if (HAL_SPI_TransmitReceive(&Hspi1, (uint8_t*)&CurrentWorkingPacket->Length16, (uint8_t*)&TemporaryIncomingPacketLength, - 2, - SPI_TIMEOUT_VALUE) != HAL_OK) //We only need to write one word, but the peripheral library freaks out... + 2, //We only need to write one word, but the peripheral library freaks out... + SPI_TIMEOUT_VALUE) != HAL_OK) { UPSTREAM_SPI_FREAKOUT; } @@ -491,8 +495,8 @@ void Upstream_BeginReceivePacketSize(UpstreamPacketTypeDef* freePacket) if (HAL_SPI_TransmitReceive(&Hspi1, (uint8_t*)&CurrentWorkingPacket->Length16, (uint8_t*)&CurrentWorkingPacket->Length16, - 2, - SPI_TIMEOUT_VALUE) != HAL_OK) //We only need to write one word, but the peripheral library freaks out... + 2, //We only need to write one word, but the peripheral library freaks out... + SPI_TIMEOUT_VALUE) != HAL_OK) { UPSTREAM_SPI_FREAKOUT; } @@ -515,7 +519,6 @@ void Upstream_BeginReceivePacketBody(void) } - //Something bad happened! Possibly CRC error... void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi) { @@ -537,3 +540,4 @@ void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi) } + diff --git a/Upstream/Src/upstream_statemachine.c b/Upstream/Src/upstream_statemachine.c index cf2dbc8..1002b53 100644 --- a/Upstream/Src/upstream_statemachine.c +++ b/Upstream/Src/upstream_statemachine.c @@ -12,10 +12,10 @@ #include "upstream_statemachine.h" #include "upstream_spi.h" -#include "upstream_interface_def.h" #include "usb_device.h" #include "usbd_core.h" #include "usbd_msc.h" +#include "usbd_hid.h" UpstreamStateTypeDef UpstreamState = STATE_TEST_INTERFACE; @@ -75,20 +75,20 @@ void Upstream_StateMachine_SetErrorState(void) } -HAL_StatusTypeDef Upstream_StateMachine_CheckClassOperationOk(void) +InterfaceCommandClassTypeDef Upstream_StateMachine_CheckActiveClass(void) { if (UpstreamState == STATE_ERROR) { - return HAL_ERROR; + return COMMAND_CLASS_ERROR; } if (UpstreamState != STATE_DEVICE_ACTIVE) { UPSTREAM_STATEMACHINE_FREAKOUT; - return HAL_ERROR; + return COMMAND_CLASS_INTERFACE; } - return HAL_OK; + return ConfiguredDeviceClass; } @@ -174,7 +174,13 @@ void Upstream_StateMachine_NotifyDeviceReplyCallback(UpstreamPacketTypeDef* repl newClassPointer = &USBD_MSC; break; - //Add other supported classes here... + case COMMAND_CLASS_HID_MOUSE: + newActiveClass = COMMAND_CLASS_HID_MOUSE; + newClassPointer = &USBD_HID; + USBD_HID_PreinitMouse(); + break; + + //Add other supported classes here... } Upstream_ReleasePacket(replyPacket); diff --git a/Upstream/Src/usbd_descriptors.c b/Upstream/Src/usbd_descriptors.c index 8eb2cce..5a06500 100755 --- a/Upstream/Src/usbd_descriptors.c +++ b/Upstream/Src/usbd_descriptors.c @@ -59,14 +59,14 @@ /** @defgroup USBD_DESC_Private_Defines * @{ */ -#define USBD_VID 1155 -#define USBD_LANGID_STRING 1033 -#define USBD_MANUFACTURER_STRING "STMicroelectronics" -#define USBD_PID_FS 22314 -#define USBD_PRODUCT_STRING_FS "STM32 Mass Storage" +#define USBD_VID 1155 +#define USBD_LANGID_STRING 1033 +#define USBD_MANUFACTURER_STRING "The USG is Good, not Bad" +#define USBD_PID_FS 22314 +#define USBD_PRODUCT_STRING_FS "USG v1.0" #define USBD_SERIALNUMBER_STRING_FS "00000000001A" -#define USBD_CONFIGURATION_STRING_FS "MSC Config" -#define USBD_INTERFACE_STRING_FS "MSC Interface" +#define USBD_CONFIGURATION_STRING_FS "USG multipurpose configuration" +#define USBD_INTERFACE_STRING_FS "USG multipurpose interface" /** * @} @@ -162,10 +162,10 @@ const int8_t STORAGE_Inquirydata_FS[] = { //36 0x00, 0x00, 0x00, - 'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', /* Manufacturer : 8 bytes */ - 'P', 'r', 'o', 'd', 'u', 'c', 't', ' ', /* Product : 16 Bytes */ - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - '0', '.', '0' ,'1', /* Version : 4 Bytes */ + 'T', 'h', 'e', ' ', 'U', 'S', 'G', ' ', /* Manufacturer : 8 bytes */ + 'i', 's', ' ', 'G', 'o', 'o', 'd', ',', /* Product : 16 Bytes */ + 'n', 'o', 't', ' ', 'b', 'a', 'd', '.', + 'v', '1', '.' ,'0', /* Version : 4 Bytes */ }; /**