Downstream HID SPI interface done, untested.

USG_1.0
Robert Fisk 9 years ago
parent 56e8b99ae5
commit cda254c8bb

@ -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_ */

@ -30,6 +30,7 @@ typedef enum
COMMAND_CLASS_INTERFACE, COMMAND_CLASS_INTERFACE,
COMMAND_CLASS_MASS_STORAGE, COMMAND_CLASS_MASS_STORAGE,
COMMAND_CLASS_HID_MOUSE, COMMAND_CLASS_HID_MOUSE,
COMMAND_CLASS_HID_KEYBOARD,
//... //...
COMMAND_CLASS_ERROR COMMAND_CLASS_ERROR
} }

@ -13,6 +13,7 @@
#define INC_DOWNSTREAM_MSC_H_ #define INC_DOWNSTREAM_MSC_H_
#include "downstream_interface_def.h"
#include "downstream_spi.h" #include "downstream_spi.h"
@ -24,7 +25,7 @@ typedef void (*DownstreamMSCCallbackPacketTypeDef)(DownstreamPacketTypeDef* rece
uint16_t dataLength8); uint16_t dataLength8);
HAL_StatusTypeDef Downstream_MSC_ApproveConnectedDevice(void); InterfaceCommandClassTypeDef Downstream_MSC_ApproveConnectedDevice(void);
void Downstream_MSC_PacketProcessor(DownstreamPacketTypeDef* receivedPacket); void Downstream_MSC_PacketProcessor(DownstreamPacketTypeDef* receivedPacket);
HAL_StatusTypeDef Downstream_MSC_PutStreamDataPacket(DownstreamPacketTypeDef* packetToSend, HAL_StatusTypeDef Downstream_MSC_PutStreamDataPacket(DownstreamPacketTypeDef* packetToSend,
uint32_t dataLength8); uint32_t dataLength8);

@ -35,8 +35,8 @@
/* Includes ------------------------------------------------------------------*/ /* Includes ------------------------------------------------------------------*/
#include "usbh_core.h" #include "usbh_core.h"
//#include "usbh_hid_mouse.h" #include "downstream_spi.h"
//#include "usbh_hid_keybd.h"
/** @addtogroup USBH_LIB /** @addtogroup USBH_LIB
* @{ * @{
@ -112,8 +112,6 @@ typedef enum
{ {
HID_INIT= 0, HID_INIT= 0,
HID_IDLE, HID_IDLE,
// HID_SEND_DATA,
// HID_BUSY,
HID_GET_DATA, HID_GET_DATA,
HID_SYNC, HID_SYNC,
HID_POLL, HID_POLL,
@ -212,27 +210,32 @@ typedef struct
} FIFO_TypeDef; } FIFO_TypeDef;
typedef void (*HID_InterruptReportCallback)(DownstreamPacketTypeDef* packetToSend);
/* Structure for HID process */ /* Structure for HID process */
typedef struct _HID_Process typedef struct _HID_Process
{ {
uint8_t OutPipe; uint8_t OutPipe;
uint8_t InPipe; uint8_t InPipe;
HID_StateTypeDef state;
uint8_t OutEp; uint8_t OutEp;
uint8_t InEp; uint8_t InEp;
HID_StateTypeDef state;
HID_CtlStateTypeDef ctl_state; HID_CtlStateTypeDef ctl_state;
FIFO_TypeDef fifo;
uint8_t *pData;
uint16_t length; uint16_t length;
uint8_t ep_addr;
uint16_t poll; uint16_t poll;
uint32_t timer; uint32_t timer;
// uint8_t DataReady; uint8_t ep_addr;
uint8_t Protocol;
HID_DescTypeDef HID_Desc; HID_DescTypeDef HID_Desc;
//USBH_StatusTypeDef ( * Init)(USBH_HandleTypeDef *phost); HID_InterruptReportCallback ReportCallback;
DownstreamPacketTypeDef* hid_packet;
uint8_t* hid_packet_pbuf;
} }
HID_HandleTypeDef; 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); 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);
/** /**
* @} * @}
*/ */

@ -182,6 +182,7 @@ static USBH_StatusTypeDef USBH_HID_InterfaceInit (USBH_HandleTypeDef *phost)
HID_Handle->ep_addr = phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[0].bEndpointAddress; 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->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) 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); 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; break;
@ -364,42 +365,21 @@ static USBH_StatusTypeDef USBH_HID_Process(USBH_HandleTypeDef *phost)
switch (HID_Handle->state) switch (HID_Handle->state)
{ {
case HID_INIT: case HID_INIT:
// HID_Handle->Init(phost); HID_Handle->timer = phost->Timer;
HID_Handle->pData = phost->device.Data; HID_Handle->state = HID_IDLE;
// 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; break;
case HID_GET_DATA: case HID_GET_DATA:
if ((int32_t)(phost->Timer - HID_Handle->timer) >= HID_Handle->poll)
{
USBH_InterruptReceiveData(phost, USBH_InterruptReceiveData(phost,
HID_Handle->pData, HID_Handle->hid_packet_pbuf,
HID_Handle->length, HID_Handle->length,
HID_Handle->InPipe); HID_Handle->InPipe);
HID_Handle->state = HID_POLL; HID_Handle->state = HID_POLL;
HID_Handle->timer = phost->Timer; HID_Handle->timer = phost->Timer;
}
break; break;
case HID_POLL: case HID_POLL:
@ -407,7 +387,7 @@ static USBH_StatusTypeDef USBH_HID_Process(USBH_HandleTypeDef *phost)
if (urbStatus == USBH_URB_DONE) if (urbStatus == USBH_URB_DONE)
{ {
USBH_HID_EventCallback(phost); HID_Handle->ReportCallback(HID_Handle->hid_packet);
HID_Handle->state = HID_IDLE; HID_Handle->state = HID_IDLE;
break; break;
} }
@ -446,18 +426,35 @@ static USBH_StatusTypeDef USBH_HID_Process(USBH_HandleTypeDef *phost)
* @retval USBH Status * @retval USBH Status
*/ */
static USBH_StatusTypeDef USBH_HID_SOFProcess(USBH_HandleTypeDef *phost) 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; HID_HandleTypeDef *HID_Handle = (HID_HandleTypeDef *) phost->pActiveClass->pData;
if (HID_Handle->state == HID_IDLE) if (HID_Handle->state == HID_IDLE)
{ {
if ((int32_t)(phost->Timer - HID_Handle->timer) >= HID_Handle->poll) HID_Handle->ReportCallback = callback;
{ HID_Handle->hid_packet = packetToUse;
HID_Handle->hid_packet_pbuf = packetToUse->Data;
HID_Handle->state = HID_GET_DATA; HID_Handle->state = HID_GET_DATA;
return HAL_OK;
} }
return HAL_ERROR;
} }
return USBH_OK;
}
/** /**
* @brief USBH_Get_HID_ReportDescriptor * @brief USBH_Get_HID_ReportDescriptor

@ -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);
}

@ -37,27 +37,27 @@ void Downstream_MSC_GetStreamDataPacketCallback(DownstreamPacketTypeDef* receive
//High-level checks on the connected device. We don't want some weirdly //High-level checks on the connected device. We don't want some weirdly
//configured device to bomb our USB stack, accidentally or otherwise. //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; MSC_HandleTypeDef* MSC_Handle = (MSC_HandleTypeDef*)hUsbHostFS.pActiveClass->pData;
if (MSC_Handle->unit[MSC_FIXED_LUN].error != MSC_OK) 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) || if ((MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr == 0) ||
(MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr == UINT32_MAX)) (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) 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;
} }

@ -10,10 +10,12 @@
*/ */
#include <downstream_hid.h>
#include "downstream_statemachine.h" #include "downstream_statemachine.h"
#include "downstream_interface_def.h" #include "downstream_interface_def.h"
#include "downstream_spi.h" #include "downstream_spi.h"
#include "downstream_msc.h" #include "downstream_msc.h"
#include "downstream_hid.h"
#include "usbh_core.h" #include "usbh_core.h"
#include "usbh_msc.h" #include "usbh_msc.h"
#include "usbh_hid.h" #include "usbh_hid.h"
@ -32,6 +34,13 @@ void Downstream_PacketProcessor_Interface_ReplyNotifyDevice(DownstreamPacketType
void Downstream_InitStateMachine(void) void Downstream_InitStateMachine(void)
{ {
if ((DownstreamState != STATE_DEVICE_NOT_READY) ||
(ConfiguredDeviceClass != COMMAND_CLASS_INTERFACE))
{
DOWNSTREAM_STATEMACHINE_FREAKOUT;
return;
}
Downstream_InitSPI(); Downstream_InitSPI();
//Prepare to receive our first packet from Upstream! //Prepare to receive our first packet from Upstream!
@ -69,19 +78,28 @@ void Downstream_PacketProcessor(DownstreamPacketTypeDef* receivedPacket)
return; return;
} }
//We should only receive class-specific messages when we are in the Active state. //We should only receive class-specific messages when we are in the Active state,
if (DownstreamState != STATE_ACTIVE) //and only to our currently active device class.
if ((DownstreamState != STATE_ACTIVE) ||
(receivedPacket->CommandClass != ConfiguredDeviceClass))
{ {
DOWNSTREAM_STATEMACHINE_FREAKOUT; DOWNSTREAM_STATEMACHINE_FREAKOUT;
return; return;
} }
switch (receivedPacket->CommandClass)
switch (ConfiguredDeviceClass)
{ {
case COMMAND_CLASS_MASS_STORAGE: case COMMAND_CLASS_MASS_STORAGE:
Downstream_MSC_PacketProcessor(receivedPacket); Downstream_MSC_PacketProcessor(receivedPacket);
break; break;
case COMMAND_CLASS_HID_MOUSE:
case COMMAND_CLASS_HID_KEYBOARD:
Downstream_HID_PacketProcessor(receivedPacket);
break;
//Add other classes here... //Add other classes here...
default: default:
@ -196,17 +214,11 @@ void Downstream_HostUserCallback(USBH_HandleTypeDef *phost, uint8_t id)
switch (phost->pActiveClass->ClassCode) switch (phost->pActiveClass->ClassCode)
{ {
case USB_MSC_CLASS: case USB_MSC_CLASS:
if (Downstream_MSC_ApproveConnectedDevice() == HAL_OK) newActiveClass = Downstream_MSC_ApproveConnectedDevice();
{
newActiveClass = COMMAND_CLASS_MASS_STORAGE;
}
break; break;
case USB_HID_CLASS: case USB_HID_CLASS:
newActiveClass = Downstream_HID_ApproveConnectedDevice();
//FIXME!
newActiveClass = COMMAND_CLASS_HID_MOUSE;
break; break;
//Add other classes here... //Add other classes here...

@ -32,6 +32,7 @@ typedef enum
COMMAND_CLASS_INTERFACE, COMMAND_CLASS_INTERFACE,
COMMAND_CLASS_MASS_STORAGE, COMMAND_CLASS_MASS_STORAGE,
COMMAND_CLASS_HID_MOUSE, COMMAND_CLASS_HID_MOUSE,
COMMAND_CLASS_HID_KEYBOARD,
//... //...
COMMAND_CLASS_ERROR COMMAND_CLASS_ERROR
} }

Loading…
Cancel
Save