Downstream HID SPI interface done, untested.

USG_1.0
Robert Fisk 8 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_MASS_STORAGE,
COMMAND_CLASS_HID_MOUSE,
COMMAND_CLASS_HID_KEYBOARD,
//...
COMMAND_CLASS_ERROR
}

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

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

@ -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

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

@ -10,10 +10,12 @@
*/
#include <downstream_hid.h>
#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...

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

Loading…
Cancel
Save