Incomplete and untested implementation of keyboard support

USG_1.0
Robert Fisk 8 years ago
parent 5c18898611
commit 9b2b8972a4

@ -57,7 +57,8 @@ InterfaceCommandMscTypeDef;
typedef enum
{
COMMAND_HID_REPORT, //Returns HID report
COMMAND_HID_GET_REPORT, //Returns HID report from device
COMMAND_HID_SET_REPORT //Sends HID report to device. No reply or ack expected.
}
InterfaceCommandHidTypeDef;

@ -112,9 +112,10 @@ typedef enum
{
HID_INIT= 0,
HID_IDLE,
HID_GET_DATA,
HID_SYNC,
HID_POLL,
HID_GET_DATA,
HID_GET_POLL,
HID_SET_DATA,
HID_SET_POLL,
HID_ERROR,
}
HID_StateTypeDef;

@ -327,8 +327,10 @@ static USBH_StatusTypeDef USBH_HID_ClassRequest(USBH_HandleTypeDef *phost)
break;
case HID_REQ_SET_PROTOCOL:
/* set protocol */
if (USBH_HID_SetProtocol (phost, 1) == USBH_OK)
//Mouse in 'report' mode,
//Keyboard in 'boot' mode
if (USBH_HID_SetProtocol(phost,
(HID_Handle->Protocol == HID_MOUSE_BOOT_CODE ? 1 : 0)) == USBH_OK)
{
HID_Handle->ctl_state = HID_REQ_IDLE;
@ -372,12 +374,11 @@ static USBH_StatusTypeDef USBH_HID_Process(USBH_HandleTypeDef *phost)
HID_Handle->length,
HID_Handle->InPipe);
HID_Handle->state = HID_POLL;
HID_Handle->state = HID_GET_POLL;
HID_Handle->timer = phost->Timer;
}
break;
case HID_POLL:
case HID_GET_POLL:
urbStatus = USBH_LL_GetURBState(phost, HID_Handle->InPipe);
if (urbStatus == USBH_URB_DONE)
@ -404,6 +405,15 @@ static USBH_StatusTypeDef USBH_HID_Process(USBH_HandleTypeDef *phost)
}
break;
case HID_SET_DATA:
break;
case HID_SET_POLL:
break;
case HID_IDLE:
break;

@ -18,11 +18,17 @@
#define HID_MAX_REPORT_LEN 8
#define HID_MOUSE_DATA_LEN 4
#define HID_KEYBOARD_DATA_LEN 0
#define HID_MAX_REPORT_LEN 8
#define HID_MOUSE_MAX_BUTTONS 4
//These defines are duplicated in downstream_hid.c. Keep them in sync!
#define HID_MOUSE_INPUT_DATA_LEN 4
#define HID_MOUSE_OUTPUT_DATA_LEN 0
#define HID_MOUSE_MAX_BUTTONS 3
#define HID_KEYBOARD_INPUT_DATA_LEN 8
#define HID_KEYBOARD_OUTPUT_DATA_LEN 1
#define HID_KEYBOARD_MAX_KEY 101 //Also set in Upstream's HID report descriptor
#define HID_KEYBOARD_MAX_LED 3
@ -59,17 +65,21 @@ 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->Protocol == HID_MOUSE_BOOT_CODE)
{
return COMMAND_CLASS_INTERFACE; //fail
if (Downstream_HID_Mouse_ParseReportDescriptor() == HAL_OK)
{
return COMMAND_CLASS_HID_MOUSE; //success!
}
}
if (Downstream_HID_Mouse_ParseReportDescriptor() != HAL_OK)
if (HID_Handle->Protocol == HID_KEYBRD_BOOT_CODE)
{
return COMMAND_CLASS_INTERFACE; //fail
return COMMAND_CLASS_HID_KEYBOARD; //success!
}
return COMMAND_CLASS_HID_MOUSE; //success!
//else:
return COMMAND_CLASS_INTERFACE; //fail
}
@ -266,19 +276,24 @@ HAL_StatusTypeDef Downstream_HID_GetNextReportItem(void)
void Downstream_HID_PacketProcessor(DownstreamPacketTypeDef* receivedPacket)
{
if (receivedPacket->Command != COMMAND_HID_REPORT)
if (receivedPacket->Command == COMMAND_HID_GET_REPORT)
{
Downstream_PacketProcessor_FreakOut();
return;
Downstream_ReleasePacket(receivedPacket);
if (USBH_HID_GetInterruptReport(&hUsbHostFS,
Downstream_HID_InterruptReportCallback) != HAL_OK)
{
Downstream_PacketProcessor_FreakOut();
}
Downstream_PacketProcessor_NotifyDisconnectReplyRequired();
}
Downstream_ReleasePacket(receivedPacket);
if (USBH_HID_GetInterruptReport(&hUsbHostFS,
Downstream_HID_InterruptReportCallback) != HAL_OK)
if (receivedPacket->Command == COMMAND_HID_SET_REPORT)
{
Downstream_PacketProcessor_FreakOut();
}
Downstream_PacketProcessor_NotifyDisconnectReplyRequired();
//else:
Downstream_PacketProcessor_FreakOut();
}
@ -287,9 +302,15 @@ void Downstream_HID_InterruptReportCallback(DownstreamPacketTypeDef* packetToSen
if (ConfiguredDeviceClass == COMMAND_CLASS_HID_MOUSE)
{
Downstream_HID_Mouse_ExtractDataFromReport(packetToSend);
packetToSend->Length16 = ((HID_MOUSE_DATA_LEN + 1) / 2) + DOWNSTREAM_PACKET_HEADER_LEN_16;
packetToSend->Length16 = ((HID_MOUSE_INPUT_DATA_LEN + 1) / 2) + DOWNSTREAM_PACKET_HEADER_LEN_16;
}
else if (ConfiguredDeviceClass == COMMAND_CLASS_HID_KEYBOARD)
{
Downstream_HID_Keyboard_ExtractDataFromReport(packetToSend);
packetToSend->Length16 = ((HID_KEYBOARD_INPUT_DATA_LEN + 1) / 2) + DOWNSTREAM_PACKET_HEADER_LEN_16;
}
//else if...
else
{
Downstream_PacketProcessor_FreakOut();
@ -297,7 +318,7 @@ void Downstream_HID_InterruptReportCallback(DownstreamPacketTypeDef* packetToSen
}
packetToSend->CommandClass = ConfiguredDeviceClass;
packetToSend->Command = COMMAND_HID_REPORT;
packetToSend->Command = COMMAND_HID_GET_REPORT;
Downstream_PacketProcessor_ClassReply(packetToSend);
}
@ -348,3 +369,26 @@ uint8_t Downstream_HID_Mouse_Extract8BitValue(HID_HandleTypeDef* hidHandle,
return (int8_t)readData;
}
void Downstream_HID_Keyboard_ExtractDataFromReport(DownstreamPacketTypeDef* packetToSend)
{
HID_HandleTypeDef* HID_Handle = (HID_HandleTypeDef*)hUsbHostFS.pActiveClass->pData;
uint32_t i;
uint8_t readData;
packetToSend->Data[0] = HID_Handle->Data[0]; //Modifier keys - pass straight through
packetToSend->Data[1] = 0; //Constant byte
for (i = 2; i < HID_KEYBOARD_INPUT_DATA_LEN; i++) //Key array
{
readData = HID_Handle->Data[i];
if (readData > HID_KEYBOARD_MAX_KEY)
{
readData = HID_KEYBOARD_MAX_KEY;
}
packetToSend->Data[i] = readData;
}
}

@ -14,18 +14,30 @@
#define UPSTREAM_HID_H_
#include "stm32f4xx_hal.h"
#include "upstream_spi.h"
//These defines are duplicated in downstream_hid.h. Keep them in sync!
#define HID_MOUSE_INPUT_DATA_LEN 4
#define HID_MOUSE_OUTPUT_DATA_LEN 0
#define HID_MOUSE_MAX_BUTTONS 3
#define HID_KEYBOARD_INPUT_DATA_LEN 8
#define HID_KEYBOARD_OUTPUT_DATA_LEN 1
#define HID_KEYBOARD_MAX_KEY 101
#define HID_KEYBOARD_MAX_LED 3
typedef uint8_t (*UpstreamHidSendReportCallback)(uint8_t *report,
typedef uint8_t (*UpstreamHidGetReportCallback)(uint8_t *report,
uint16_t len);
void Upstream_HID_DeInit(void);
HAL_StatusTypeDef Upstream_HID_GetNextReport(UpstreamHidSendReportCallback callback);
void Upstream_HID_GetNextInterruptReport(UpstreamHidGetReportCallback callback);
void Upstream_HID_SendControlReport(UpstreamPacketTypeDef* packetToSend, uint8_t dataLength);
void Upstream_HID_ReallySendControlReport(void);

@ -59,7 +59,8 @@ InterfaceCommandMscTypeDef;
typedef enum
{
COMMAND_HID_REPORT, //Returns HID report
COMMAND_HID_GET_REPORT, //Returns HID report from device
COMMAND_HID_SET_REPORT //Sends HID report to device. No reply or ack expected.
}
InterfaceCommandHidTypeDef;

@ -23,6 +23,9 @@
* limitations under the License.
*
******************************************************************************
*
* Modifications by Robert Fisk
*
*/
/* Define to prevent recursive inclusion -------------------------------------*/
@ -50,11 +53,11 @@
* @{
*/
#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_KEYBOARD_REPORT_DESC_SIZE 63
#define HID_DESCRIPTOR_TYPE 0x21
#define HID_REPORT_DESC 0x22
@ -71,6 +74,10 @@
#define HID_REQ_SET_REPORT 0x09
#define HID_REQ_GET_REPORT 0x01
#define HID_KEYBRD_BOOT_CODE 0x01
#define HID_MOUSE_BOOT_CODE 0x02
/**
* @}
*/

@ -73,6 +73,8 @@ static uint8_t USBD_HID_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum);
static uint8_t USBD_HID_SendReport (uint8_t *report,
uint16_t len);
static uint8_t USBD_HID_EP0RxReady(USBD_HandleTypeDef *pdev);
#define USBD_PID_HID 0x0002
@ -84,7 +86,7 @@ USBD_ClassTypeDef USBD_HID =
USBD_HID_DeInit,
USBD_HID_Setup,
NULL, /*EP0_TxSent*/
NULL, /*EP0_RxReady*/
USBD_HID_EP0RxReady, /*EP0_RxReady*/
USBD_HID_DataIn, /*DataIn*/
NULL, /*DataOut*/
NULL, /*SOF */
@ -99,9 +101,11 @@ USBD_ClassTypeDef USBD_HID =
};
#define USB_HID_CFGDESC__INTERFACE_PROTOCOL_OFFSET 16
#define USB_HID_CFGDESC__HID_REPORT_DESC_SIZE_OFFSET 25
#define USB_HID_CFGDESC__EPIN_SIZE_OFFSET 31
#define USB_HID_DESC__HID_REPORT_DESC_SIZE_OFFSET 7
#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 */
@ -128,7 +132,7 @@ __ALIGN_BEGIN static uint8_t USBD_HID_CfgDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_
0x01, /*bNumEndpoints*/
0x03, /*bInterfaceClass: HID*/
0x01, /*bInterfaceSubClass : 1=BOOT, 0=no boot*/
0x02, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/
0x00, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/
0, /*iInterface: Index of string descriptor*/
/******************** Descriptor of Joystick Mouse HID ********************/
/* 18 */
@ -148,7 +152,7 @@ __ALIGN_BEGIN static uint8_t USBD_HID_CfgDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_
HID_EPIN_ADDR, /*bEndpointAddress: Endpoint Address (IN)*/
0x03, /*bmAttributes: Interrupt endpoint*/
HID_EPIN_SIZE, /*wMaxPacketSize: 4 Byte max */
0x00, //HID_EPIN_SIZE, /*wMaxPacketSize: 4 Byte max */
0x00,
HID_FS_BINTERVAL, /*bInterval: Polling Interval (10 ms)*/
/* 34 */
@ -192,14 +196,14 @@ __ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] _
0xA1, 0x00, // Collection (Physical)
0x05, 0x09, // Usage Page (Button)
0x19, 0x01, // Usage Minimum (0x01)
0x29, 0x03, // Usage Maximum (0x03)
0x29, HID_MOUSE_MAX_BUTTONS, // Usage Maximum (0x03)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x95, 0x03, // Report Count (3)
0x95, HID_MOUSE_MAX_BUTTONS, // 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)
0x75, (8 - HID_MOUSE_MAX_BUTTONS), // 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)
@ -223,14 +227,54 @@ __ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] _
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;
__ALIGN_BEGIN static uint8_t HID_KEYBOARD_ReportDesc[HID_KEYBOARD_REPORT_DESC_SIZE] __ALIGN_END = {
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x06, // USAGE (Keyboard)
0xa1, 0x01, // COLLECTION (Application)
0x05, 0x07, // USAGE_PAGE (Keyboard)
0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x08, // REPORT_COUNT (8)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x08, // REPORT_SIZE (8)
0x81, 0x03, // INPUT (Cnst,Var,Abs)
0x95, HID_KEYBOARD_MAX_LED, // REPORT_COUNT (5)
0x75, 0x01, // REPORT_SIZE (1)
0x05, 0x08, // USAGE_PAGE (LEDs)
0x19, 0x01, // USAGE_MINIMUM (Num Lock)
0x29, 0x03, // USAGE_MAXIMUM (Scroll Lock)
0x91, 0x02, // OUTPUT (Data,Var,Abs)
0x95, 0x01, // REPORT_COUNT (1)
0x75, (8 - HID_KEYBOARD_MAX_LED), // REPORT_SIZE (3)
0x91, 0x03, // OUTPUT (Cnst,Var,Abs)
0x95, 0x06, // REPORT_COUNT (6)
0x75, 0x08, // REPORT_SIZE (8)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, HID_KEYBOARD_MAX_KEY, // LOGICAL_MAXIMUM (101)
0x05, 0x07, // USAGE_PAGE (Keyboard)
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
0x81, 0x00, // INPUT (Data,Ary,Abs)
0xc0 // END_COLLECTION
};
USBD_HandleTypeDef *USBD_HID_pdev;
UpstreamPacketTypeDef* OutReportPacket = NULL;
uint8_t* ActiveReportDescriptor = NULL;
uint8_t ActiveReportDescriptorLength;
uint8_t InReportSize;
uint8_t OutReportSize;
/**
@ -252,12 +296,29 @@ void USBD_HID_PreinitMouse(void)
{
ActiveReportDescriptor = HID_MOUSE_ReportDesc;
ActiveReportDescriptorLength = HID_MOUSE_REPORT_DESC_SIZE;
InReportSize = HID_MOUSE_INPUT_DATA_LEN;
OutReportSize = HID_MOUSE_OUTPUT_DATA_LEN;
USBD_HID_CfgDesc[USB_HID_CFGDESC__INTERFACE_PROTOCOL_OFFSET] = HID_MOUSE_BOOT_CODE;
USBD_HID_CfgDesc[USB_HID_CFGDESC__HID_REPORT_DESC_SIZE_OFFSET] = HID_MOUSE_REPORT_DESC_SIZE;
USBD_HID_CfgDesc[USB_HID_CFGDESC__EPIN_SIZE_OFFSET] = HID_MOUSE_INPUT_DATA_LEN;
USBD_HID_Desc[USB_HID_DESC__HID_REPORT_DESC_SIZE_OFFSET] = HID_MOUSE_REPORT_DESC_SIZE;
}
void USBD_HID_PreinitKeyboard(void)
{
ActiveReportDescriptor = HID_KEYBOARD_ReportDesc;
ActiveReportDescriptorLength = HID_KEYBOARD_REPORT_DESC_SIZE;
InReportSize = HID_KEYBOARD_INPUT_DATA_LEN;
OutReportSize = HID_KEYBOARD_OUTPUT_DATA_LEN;
USBD_HID_CfgDesc[USB_HID_CFGDESC__INTERFACE_PROTOCOL_OFFSET] = HID_KEYBRD_BOOT_CODE;
USBD_HID_CfgDesc[USB_HID_CFGDESC__HID_REPORT_DESC_SIZE_OFFSET] = HID_KEYBOARD_REPORT_DESC_SIZE;
USBD_HID_CfgDesc[USB_HID_CFGDESC__EPIN_SIZE_OFFSET] = HID_KEYBOARD_INPUT_DATA_LEN;
USBD_HID_Desc[USB_HID_DESC__HID_REPORT_DESC_SIZE_OFFSET] = HID_KEYBOARD_REPORT_DESC_SIZE;
}
static uint8_t USBD_HID_Init (USBD_HandleTypeDef *pdev,
@ -269,7 +330,7 @@ static uint8_t USBD_HID_Init (USBD_HandleTypeDef *pdev,
USBD_LL_OpenEP(pdev,
HID_EPIN_ADDR,
USBD_EP_TYPE_INTR,
HID_EPIN_SIZE);
InReportSize);
pdev->pClassData = USBD_malloc(sizeof (USBD_HID_HandleTypeDef));
@ -282,7 +343,7 @@ static uint8_t USBD_HID_Init (USBD_HandleTypeDef *pdev,
((USBD_HID_HandleTypeDef *)pdev->pClassData)->state = HID_IDLE;
USBD_HID_pdev = pdev;
Upstream_HID_GetNextReport(USBD_HID_SendReport);
Upstream_HID_GetNextInterruptReport(USBD_HID_SendReport);
}
return ret;
@ -326,7 +387,7 @@ static uint8_t USBD_HID_Setup (USBD_HandleTypeDef *pdev,
{
uint16_t len = 0;
uint8_t *pbuf = NULL;
USBD_HID_HandleTypeDef *hhid = (USBD_HID_HandleTypeDef*) pdev->pClassData;
USBD_HID_HandleTypeDef *hhid = (USBD_HID_HandleTypeDef*) pdev->pClassData;
if (ActiveReportDescriptor == NULL)
{
@ -339,8 +400,7 @@ static uint8_t USBD_HID_Setup (USBD_HandleTypeDef *pdev,
case USB_REQ_TYPE_CLASS :
switch (req->bRequest)
{
case HID_REQ_SET_PROTOCOL:
hhid->Protocol = (uint8_t)(req->wValue);
break;
@ -358,7 +418,24 @@ static uint8_t USBD_HID_Setup (USBD_HandleTypeDef *pdev,
case HID_REQ_GET_IDLE:
USBD_CtlSendData (pdev,
(uint8_t *)&hhid->IdleState,
1);
1);
break;
case HID_REQ_SET_REPORT:
if ((OutReportSize > 0) &&
(req->wLength == OutReportSize))
{
if (OutReportPacket != NULL) while(1);
OutReportPacket = Upstream_GetFreePacketImmediately();
if (OutReportPacket == NULL) while(1);
USBD_CtlPrepareRx(pdev, OutReportPacket->Data, OutReportSize);
}
else
{
USBD_CtlError (pdev, req);
return USBD_FAIL;
}
break;
default:
@ -489,7 +566,7 @@ static uint8_t USBD_HID_DataIn (USBD_HandleTypeDef *pdev,
((USBD_HID_HandleTypeDef *)pdev->pClassData)->state = HID_IDLE;
USBD_HID_pdev = pdev;
Upstream_HID_GetNextReport(USBD_HID_SendReport);
Upstream_HID_GetNextInterruptReport(USBD_HID_SendReport);
return USBD_OK;
}
@ -507,6 +584,23 @@ static uint8_t *USBD_HID_GetDeviceQualifierDesc (uint16_t *length)
return USBD_HID_DeviceQualifierDesc;
}
//Called when data is received from host on control endpoint.
//Upstream_HID may send this immediately, but will probably have to save it and send after the next interrupt transfer
static uint8_t USBD_HID_EP0RxReady(USBD_HandleTypeDef *pdev)
{
if ((OutReportPacket == NULL) ||
(OutReportSize == 0))
{
while(1);
}
Upstream_HID_SendControlReport(OutReportPacket, OutReportSize);
Upstream_ReleasePacket(OutReportPacket);
OutReportPacket = NULL;
return USBD_OK;
}
/**
* @}
*/

@ -314,7 +314,7 @@ USBD_StatusTypeDef USBD_DataOutStage(USBD_HandleTypeDef *pdev , uint8_t epnum, u
USBD_CtlContinueRx (pdev,
pdata,
MIN(pep->rem_length ,pep->maxpacket));
pep->rem_length);
}
else
{
@ -354,35 +354,24 @@ USBD_StatusTypeDef USBD_DataInStage(USBD_HandleTypeDef *pdev ,uint8_t epnum, uin
{
if(pep->rem_length > pep->maxpacket)
{
pep->rem_length -= pep->maxpacket;
pep->rem_length -= pep->maxpacket;
USBD_CtlContinueSendData (pdev,
pdata,
pep->rem_length);
}
else
/* Prepare endpoint for premature end of transfer */
USBD_LL_PrepareReceive (pdev,
0,
NULL,
0);
{ /* last packet is MPS multiple, so send ZLP packet */
{
//We sent less data than host was expecting?
/* last packet is MPS multiple, so send ZLP packet */
if((pep->total_length % pep->maxpacket == 0) &&
(pep->total_length >= pep->maxpacket) &&
(pep->total_length < pdev->ep0_data_len ))
{
USBD_CtlContinueSendData(pdev , NULL, 0);
pdev->ep0_data_len = 0;
}
else
/* Prepare endpoint for premature end of transfer */
USBD_LL_PrepareReceive (pdev,
0,
NULL,
0);
{
if((pdev->pClass->EP0_TxSent != NULL)&&
(pdev->dev_state == USBD_STATE_CONFIGURED))

@ -12,23 +12,19 @@
#include "upstream_hid.h"
#include "upstream_spi.h"
#include "upstream_interface_def.h"
#include "usbd_hid.h"
#define HID_MOUSE_DATA_LEN 4
#define HID_KEYBOARD_DATA_LEN 0
#define HID_MOUSE_MAX_BUTTONS 4
UpstreamPacketTypeDef* UpstreamHidPacket = NULL;
UpstreamHidSendReportCallback ReportCallback = NULL;
UpstreamHidGetReportCallback GetReportCallback = NULL;
uint8_t KeyboardOutDataAvailable = 0;
uint8_t KeyboardOutData[HID_KEYBOARD_OUTPUT_DATA_LEN];
void Upstream_HID_GetNextReportReceiveCallback(UpstreamPacketTypeDef* receivedPacket);
void Upstream_HID_GetNextInterruptReportReceiveCallback(UpstreamPacketTypeDef* receivedPacket);
@ -39,29 +35,31 @@ void Upstream_HID_DeInit(void)
Upstream_ReleasePacket(UpstreamHidPacket);
UpstreamHidPacket = NULL;
}
ReportCallback = NULL;
GetReportCallback = NULL;
KeyboardOutDataAvailable = 0;
}
HAL_StatusTypeDef Upstream_HID_GetNextReport(UpstreamHidSendReportCallback callback)
void Upstream_HID_GetNextInterruptReport(UpstreamHidGetReportCallback callback)
{
UpstreamPacketTypeDef* freePacket;
InterfaceCommandClassTypeDef activeClass;
activeClass = Upstream_StateMachine_CheckActiveClass();
if ((activeClass != COMMAND_CLASS_HID_MOUSE)) //add classes here
if ((activeClass != COMMAND_CLASS_HID_MOUSE) &&
(activeClass != COMMAND_CLASS_HID_KEYBOARD)) //add classes here
{
UPSTREAM_STATEMACHINE_FREAKOUT;
return HAL_ERROR;
return;
}
//Just return if we already have an outstanding request
if (ReportCallback != NULL)
if (GetReportCallback != NULL)
{
return HAL_OK;
return;
}
ReportCallback = callback;
GetReportCallback = callback;
//Release packet used for last transaction (if any)
if (UpstreamHidPacket != NULL)
@ -73,41 +71,43 @@ HAL_StatusTypeDef Upstream_HID_GetNextReport(UpstreamHidSendReportCallback callb
freePacket = Upstream_GetFreePacketImmediately();
if (freePacket == NULL)
{
return HAL_ERROR;
return;
}
freePacket->Length16 = UPSTREAM_PACKET_HEADER_LEN_16;
freePacket->CommandClass = activeClass;
freePacket->Command = COMMAND_HID_REPORT;
freePacket->Command = COMMAND_HID_GET_REPORT;
if (Upstream_TransmitPacket(freePacket) == HAL_OK)
{
return Upstream_ReceivePacket(Upstream_HID_GetNextReportReceiveCallback);
Upstream_ReceivePacket(Upstream_HID_GetNextInterruptReportReceiveCallback);
}
else
{
Upstream_ReleasePacket(freePacket);
}
//else:
Upstream_ReleasePacket(freePacket);
return HAL_ERROR;
}
void Upstream_HID_GetNextReportReceiveCallback(UpstreamPacketTypeDef* receivedPacket)
void Upstream_HID_GetNextInterruptReportReceiveCallback(UpstreamPacketTypeDef* receivedPacket)
{
UpstreamHidSendReportCallback tempReportCallback;
UpstreamHidGetReportCallback tempReportCallback;
InterfaceCommandClassTypeDef activeClass;
uint8_t dataLength = 0;
uint8_t i;
uint32_t i;
uint8_t dataLength;
activeClass = Upstream_StateMachine_CheckActiveClass();
if ((activeClass != COMMAND_CLASS_HID_MOUSE)) //add classes here
if ((activeClass != COMMAND_CLASS_HID_MOUSE) &&
(activeClass != COMMAND_CLASS_HID_KEYBOARD)) //add classes here
{
UPSTREAM_STATEMACHINE_FREAKOUT;
return;
}
if ((UpstreamHidPacket != NULL) ||
(ReportCallback == NULL))
(GetReportCallback == NULL))
{
UPSTREAM_SPI_FREAKOUT;
return;
@ -121,37 +121,121 @@ void Upstream_HID_GetNextReportReceiveCallback(UpstreamPacketTypeDef* receivedPa
if (activeClass == COMMAND_CLASS_HID_MOUSE)
{
if (receivedPacket->Length16 != (UPSTREAM_PACKET_HEADER_LEN_16 + ((HID_MOUSE_DATA_LEN + 1) / 2)))
if (receivedPacket->Length16 != (UPSTREAM_PACKET_HEADER_LEN_16 + ((HID_MOUSE_INPUT_DATA_LEN + 1) / 2)))
{
UPSTREAM_SPI_FREAKOUT;
return;
}
dataLength = HID_MOUSE_INPUT_DATA_LEN;
if ((receivedPacket->Data[0] & ~((1 << HID_MOUSE_MAX_BUTTONS) - 1)) != 0) //Check number of buttons received
{
UPSTREAM_SPI_FREAKOUT;
return;
}
//Other mouse sanity checks & stuff go here...
}
receivedPacket->Data[0] &= ((1 << HID_MOUSE_MAX_BUTTONS) - 1); //Limit number of buttons received
//Mouse sanity checks & stuff go here...
else if (activeClass == COMMAND_CLASS_HID_KEYBOARD)
{
if (receivedPacket->Length16 != (UPSTREAM_PACKET_HEADER_LEN_16 + ((HID_KEYBOARD_INPUT_DATA_LEN + 1) / 2)))
{
UPSTREAM_SPI_FREAKOUT;
return;
}
dataLength = HID_KEYBOARD_INPUT_DATA_LEN;
dataLength = HID_MOUSE_DATA_LEN;
if (receivedPacket->Data[1] != 0)
{
UPSTREAM_SPI_FREAKOUT;
return;
}
for (i = 2; i < HID_KEYBOARD_INPUT_DATA_LEN; i++)
{
if (receivedPacket->Data[i] > HID_KEYBOARD_MAX_KEY)
{
UPSTREAM_SPI_FREAKOUT;
return;
}
}
//Other keyboard sanity checks here...
}
//Other HID classes go here...
else
{
UPSTREAM_SPI_FREAKOUT;
return;
}
UpstreamHidPacket = receivedPacket; //Save packet so we can free it when upstream USB transaction is done
tempReportCallback = GetReportCallback;
GetReportCallback = NULL;
tempReportCallback(receivedPacket->Data, dataLength);
if (dataLength == 0)
//Check if we need to send OUT data to the keyboard before requesting next Interrupt IN data
if (KeyboardOutDataAvailable)
{
Upstream_HID_ReallySendControlReport();
}
}
void Upstream_HID_SendControlReport(UpstreamPacketTypeDef* packetToSend, uint8_t dataLength)
{
InterfaceCommandClassTypeDef activeClass;
uint32_t i;
activeClass = Upstream_StateMachine_CheckActiveClass();
if ((packetToSend == NULL) ||
(activeClass != COMMAND_CLASS_HID_KEYBOARD) ||
(dataLength != HID_KEYBOARD_OUTPUT_DATA_LEN))
{
UPSTREAM_SPI_FREAKOUT;
return;
}
for (i = dataLength; i < HID_EPIN_SIZE; i++)
if (GetReportCallback == NULL)
{
receivedPacket->Data[i] = 0; //Zero out unused bytes before we send report upstream
while(1); //checkme!
}
UpstreamHidPacket = receivedPacket; //Save packet so we can free it when upstream USB transaction is done
tempReportCallback = ReportCallback;
ReportCallback = NULL;
tempReportCallback(receivedPacket->Data, HID_EPIN_SIZE);
//Save data until after the next interrupt data is received from Downstream
KeyboardOutDataAvailable = 1;
for (i = 0; i < HID_KEYBOARD_OUTPUT_DATA_LEN; i++)
{
KeyboardOutData[i] = packetToSend->Data[i];
}
}
void Upstream_HID_ReallySendControlReport(void)
{
UpstreamPacketTypeDef* freePacket;
uint32_t i;
KeyboardOutDataAvailable = 0;
freePacket = Upstream_GetFreePacketImmediately();
if (freePacket == NULL) return;
freePacket->Length16 = UPSTREAM_PACKET_HEADER_LEN_16 + ((HID_KEYBOARD_OUTPUT_DATA_LEN + 1) / 2);
freePacket->CommandClass = COMMAND_CLASS_HID_KEYBOARD;
freePacket->Command = COMMAND_HID_SET_REPORT;
for (i = 0; i < HID_KEYBOARD_OUTPUT_DATA_LEN; i++)
{
freePacket->Data[i] = KeyboardOutData[i];
}
freePacket->Data[0] &= ((1 << HID_KEYBOARD_MAX_LED) - 1);
if (Upstream_TransmitPacket(freePacket) != HAL_OK)
{
Upstream_ReleasePacket(freePacket);
}
}

@ -180,6 +180,12 @@ void Upstream_StateMachine_NotifyDeviceReplyCallback(UpstreamPacketTypeDef* repl
USBD_HID_PreinitMouse();
break;
case COMMAND_CLASS_HID_KEYBOARD:
newActiveClass = COMMAND_CLASS_HID_KEYBOARD;
newClassPointer = &USBD_HID;
USBD_HID_PreinitKeyboard();
break;
//Add other supported classes here...
}

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="ilg.gnuarmeclipse.debug.gdbjtag.openocd.launchConfigurationType">
<stringAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.PERIPHERALS" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;peripherals&gt;&#10;&lt;peripheral name=&quot;DMA2&quot;/&gt;&#10;&lt;/peripherals&gt;&#10;"/>
<stringAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.PERIPHERALS" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;peripherals&gt;&#10;&lt;peripheral name=&quot;DMA2&quot;/&gt;&#10;&lt;peripheral name=&quot;GPIOA&quot;/&gt;&#10;&lt;/peripherals&gt;&#10;"/>
<booleanAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.openocd.doContinue" value="true"/>
<booleanAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.openocd.doDebugInRam" value="false"/>
<booleanAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.openocd.doFirstReset" value="true"/>

Loading…
Cancel
Save