From cda254c8bbae53f56fde9ea7b293d9794ee44ccc Mon Sep 17 00:00:00 2001 From: Robert Fisk Date: Mon, 11 Apr 2016 01:09:41 +1200 Subject: [PATCH] Downstream HID SPI interface done, untested. --- Downstream/Inc/downstream_hid.h | 31 +++++++ Downstream/Inc/downstream_interface_def.h | 1 + Downstream/Inc/downstream_msc.h | 3 +- .../Class/HID/Inc/usbh_hid.h | 30 ++++--- .../Class/HID/Src/usbh_hid.c | 89 +++++++++---------- Downstream/Src/downstream_hid.c | 77 ++++++++++++++++ Downstream/Src/downstream_msc.c | 10 +-- Downstream/Src/downstream_statemachine.c | 34 ++++--- Upstream/Inc/upstream_interface_def.h | 1 + 9 files changed, 202 insertions(+), 74 deletions(-) create mode 100644 Downstream/Inc/downstream_hid.h create mode 100644 Downstream/Src/downstream_hid.c diff --git a/Downstream/Inc/downstream_hid.h b/Downstream/Inc/downstream_hid.h new file mode 100644 index 0000000..1f80859 --- /dev/null +++ b/Downstream/Inc/downstream_hid.h @@ -0,0 +1,31 @@ +/* + * 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" + + +#define HID_MOUSE_TRANSFER_BYTES 5 +#define HID_KEYBOARD_TRANSFER_BYTES 0 + + + +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 b3dfaf2..a5cdf56 100644 --- a/Downstream/Inc/downstream_interface_def.h +++ b/Downstream/Inc/downstream_interface_def.h @@ -30,6 +30,7 @@ typedef enum COMMAND_CLASS_INTERFACE, COMMAND_CLASS_MASS_STORAGE, COMMAND_CLASS_HID_MOUSE, + COMMAND_CLASS_HID_KEYBOARD, //... COMMAND_CLASS_ERROR } 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/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 index 40f7790..a611ace 100644 --- 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 @@ -35,8 +35,8 @@ /* Includes ------------------------------------------------------------------*/ #include "usbh_core.h" -//#include "usbh_hid_mouse.h" -//#include "usbh_hid_keybd.h" +#include "downstream_spi.h" + /** @addtogroup USBH_LIB * @{ @@ -112,8 +112,6 @@ typedef enum { HID_INIT= 0, HID_IDLE, -// HID_SEND_DATA, -// HID_BUSY, HID_GET_DATA, HID_SYNC, HID_POLL, @@ -212,27 +210,32 @@ typedef struct } FIFO_TypeDef; + +typedef void (*HID_InterruptReportCallback)(DownstreamPacketTypeDef* packetToSend); + + /* Structure for HID process */ typedef struct _HID_Process { uint8_t OutPipe; uint8_t InPipe; - HID_StateTypeDef state; uint8_t OutEp; uint8_t InEp; + HID_StateTypeDef state; HID_CtlStateTypeDef ctl_state; - FIFO_TypeDef fifo; - uint8_t *pData; uint16_t length; - uint8_t ep_addr; uint16_t poll; uint32_t timer; -// uint8_t DataReady; - HID_DescTypeDef HID_Desc; - //USBH_StatusTypeDef ( * Init)(USBH_HandleTypeDef *phost); + uint8_t ep_addr; + uint8_t Protocol; + HID_DescTypeDef HID_Desc; + HID_InterruptReportCallback ReportCallback; + DownstreamPacketTypeDef* hid_packet; + uint8_t* hid_packet_pbuf; } HID_HandleTypeDef; + /** * @} */ @@ -321,6 +324,11 @@ 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); + + /** * @} */ 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 index 972bf23..be36dfa 100644 --- 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 @@ -181,7 +181,8 @@ static USBH_StatusTypeDef USBH_HID_InterfaceInit (USBH_HandleTypeDef *phost) 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->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) { @@ -298,7 +299,7 @@ static USBH_StatusTypeDef USBH_HID_ClassRequest(USBH_HandleTypeDef *phost) { USBH_HID_ParseHIDDesc(&HID_Handle->HID_Desc, phost->device.Data); - HID_Handle->ctl_state = HID_REQ_SET_IDLE; //HID_REQ_GET_REPORT_DESC; + HID_Handle->ctl_state = HID_REQ_SET_IDLE; } break; @@ -364,50 +365,29 @@ static USBH_StatusTypeDef USBH_HID_Process(USBH_HandleTypeDef *phost) switch (HID_Handle->state) { case HID_INIT: -// HID_Handle->Init(phost); - HID_Handle->pData = phost->device.Data; - -// case HID_IDLE: -// if(USBH_HID_GetReport (phost, -// 0x01, -// 0, -// HID_Handle->pData, -// HID_Handle->length) == USBH_OK) -// { -// -// fifo_write(&HID_Handle->fifo, HID_Handle->pData, HID_Handle->length); -// HID_Handle->state = HID_SYNC; -// } -// -// break; - - case HID_SYNC: - /* Sync with start of Even Frame */ - //Uhhh, doesn't this sync with an odd frame? - //Also, do we need to sync at all? - - if(phost->Timer & 1) - { - HID_Handle->state = HID_GET_DATA; - } - break; + HID_Handle->timer = phost->Timer; + HID_Handle->state = HID_IDLE; + break; case HID_GET_DATA: - USBH_InterruptReceiveData(phost, - HID_Handle->pData, - HID_Handle->length, - HID_Handle->InPipe); - - HID_Handle->state = HID_POLL; - HID_Handle->timer = phost->Timer; + 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); + urbStatus = USBH_LL_GetURBState(phost, HID_Handle->InPipe); if (urbStatus == USBH_URB_DONE) { - USBH_HID_EventCallback(phost); + HID_Handle->ReportCallback(HID_Handle->hid_packet); HID_Handle->state = HID_IDLE; break; } @@ -447,18 +427,35 @@ static USBH_StatusTypeDef USBH_HID_Process(USBH_HandleTypeDef *phost) */ static USBH_StatusTypeDef USBH_HID_SOFProcess(USBH_HandleTypeDef *phost) { - HID_HandleTypeDef *HID_Handle = (HID_HandleTypeDef *) phost->pActiveClass->pData; - - if (HID_Handle->state == HID_IDLE) - { - if ((int32_t)(phost->Timer - HID_Handle->timer) >= HID_Handle->poll) + + 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->state = HID_GET_DATA; + 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 USBH_OK; + + return HAL_ERROR; } + + + /** * @brief USBH_Get_HID_ReportDescriptor * Issue report Descriptor command to the device. Once the response diff --git a/Downstream/Src/downstream_hid.c b/Downstream/Src/downstream_hid.c new file mode 100644 index 0000000..27d1843 --- /dev/null +++ b/Downstream/Src/downstream_hid.c @@ -0,0 +1,77 @@ +/* + * 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" + + + +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 == 8) + { + 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_TRANSFER_BYTES / 2) + DOWNSTREAM_PACKET_HEADER_LEN_16; + } + //else if... + else + { + Downstream_PacketProcessor_FreakOut(); + return; + } + + + Downstream_TransmitPacket(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 a693a76..347c415 100644 --- a/Downstream/Src/downstream_statemachine.c +++ b/Downstream/Src/downstream_statemachine.c @@ -10,10 +10,12 @@ */ +#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" @@ -32,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! @@ -69,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: @@ -196,17 +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: - - //FIXME! - - newActiveClass = COMMAND_CLASS_HID_MOUSE; + newActiveClass = Downstream_HID_ApproveConnectedDevice(); break; //Add other classes here... diff --git a/Upstream/Inc/upstream_interface_def.h b/Upstream/Inc/upstream_interface_def.h index f76a6df..9f00626 100644 --- a/Upstream/Inc/upstream_interface_def.h +++ b/Upstream/Inc/upstream_interface_def.h @@ -32,6 +32,7 @@ typedef enum COMMAND_CLASS_INTERFACE, COMMAND_CLASS_MASS_STORAGE, COMMAND_CLASS_HID_MOUSE, + COMMAND_CLASS_HID_KEYBOARD, //... COMMAND_CLASS_ERROR }