Keyboard support implemented, but not tested

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

@ -42,10 +42,12 @@
#define HID_ITEM_INPUT_REL 0x06
typedef void (*TransactionCompleteCallbackTypeDef)(void);
InterfaceCommandClassTypeDef Downstream_HID_ApproveConnectedDevice(void);
void Downstream_HID_PacketProcessor(DownstreamPacketTypeDef* receivedPacket);
void Downstream_HID_InterruptReportCallback(DownstreamPacketTypeDef* packetToSend);
void Downstream_HID_InterruptReportCallback(void);
void Downstream_HID_SendReportCallback(void);

@ -58,7 +58,7 @@ InterfaceCommandMscTypeDef;
typedef enum
{
COMMAND_HID_GET_REPORT, //Returns HID report from device
COMMAND_HID_SET_REPORT //Sends HID report to device. No reply or ack expected.
COMMAND_HID_SET_REPORT //Sends HID report to device. Simple ack packet contains no data.
}
InterfaceCommandHidTypeDef;

@ -71,6 +71,7 @@ typedef void (*SpiPacketReceivedCallbackTypeDef)(DownstreamPacketTypeDef* receiv
void Downstream_InitSPI(void);
HAL_StatusTypeDef Downstream_GetFreePacket(FreePacketCallbackTypeDef callback);
DownstreamPacketTypeDef* Downstream_GetFreePacketImmediately(void);
void Downstream_ReleasePacket(DownstreamPacketTypeDef* packetToRelease);
HAL_StatusTypeDef Downstream_ReceivePacket(SpiPacketReceivedCallbackTypeDef callback);
HAL_StatusTypeDef Downstream_TransmitPacket(DownstreamPacketTypeDef* packetToWrite);

@ -23,6 +23,9 @@
* limitations under the License.
*
******************************************************************************
*
* Modifications by Robert Fisk
*
*/
/* Define to prevent recursive ----------------------------------------------*/
@ -35,7 +38,7 @@
/* Includes ------------------------------------------------------------------*/
#include "usbh_core.h"
#include "downstream_spi.h"
#include "downstream_hid.h"
/** @addtogroup USBH_LIB
@ -105,6 +108,10 @@
#define HID_LOCAL_ITEM_TAG_STRING_MIN 0x08
#define HID_LOCAL_ITEM_TAG_STRING_MAX 0x09
#define HID_LOCAL_ITEM_TAG_DELIMITER 0x0A
#define HID_REPORT_DIRECTION_IN 0x01
#define HID_REPORT_DIRECTION_OUT 0x02
/* States for HID State Machine */
@ -114,8 +121,7 @@ typedef enum
HID_IDLE,
HID_GET_DATA,
HID_GET_POLL,
HID_SET_DATA,
HID_SET_POLL,
HID_SET_DATA_POLL,
HID_ERROR,
}
HID_StateTypeDef;
@ -227,7 +233,7 @@ typedef struct _HID_Process
uint8_t ep_addr;
uint8_t Protocol;
HID_DescTypeDef HID_Desc;
FreePacketCallbackTypeDef ReportCallback;
TransactionCompleteCallbackTypeDef ReportCallback;
uint8_t Data[HID_MAX_REPORT_SIZE];
}
HID_HandleTypeDef;
@ -288,7 +294,8 @@ USBH_StatusTypeDef USBH_HID_SetReport (USBH_HandleTypeDef *phost,
uint8_t reportType,
uint8_t reportId,
uint8_t* reportBuff,
uint8_t reportLen);
uint8_t reportLen,
TransactionCompleteCallbackTypeDef callback);
USBH_StatusTypeDef USBH_HID_GetReport (USBH_HandleTypeDef *phost,
uint8_t reportType,
@ -322,7 +329,7 @@ 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,
FreePacketCallbackTypeDef callback);
TransactionCompleteCallbackTypeDef callback);
/**

@ -373,17 +373,17 @@ static USBH_StatusTypeDef USBH_HID_Process(USBH_HandleTypeDef *phost)
HID_Handle->Data,
HID_Handle->length,
HID_Handle->InPipe);
HID_Handle->state = HID_GET_POLL;
HID_Handle->timer = phost->Timer;
}
break;
case HID_GET_POLL:
urbStatus = USBH_LL_GetURBState(phost, HID_Handle->InPipe);
if (urbStatus == USBH_URB_DONE)
{
Downstream_GetFreePacket(HID_Handle->ReportCallback);
HID_Handle->ReportCallback();
HID_Handle->state = HID_IDLE;
break;
}
@ -405,15 +405,14 @@ static USBH_StatusTypeDef USBH_HID_Process(USBH_HandleTypeDef *phost)
}
break;
case HID_SET_DATA:
break;
case HID_SET_POLL:
case HID_SET_DATA_POLL:
if (USBH_CtlReq(phost, HID_Handle->Data, phost->Control.setup.b.wLength.w) == USBH_OK)
{
HID_Handle->ReportCallback();
HID_Handle->state = HID_IDLE;
}
break;
case HID_IDLE:
break;
@ -441,7 +440,7 @@ static USBH_StatusTypeDef USBH_HID_SOFProcess(USBH_HandleTypeDef *phost)
//Downstream_HID calls into here at main() priority,
//to request a new report for Upstream.
HAL_StatusTypeDef USBH_HID_GetInterruptReport(USBH_HandleTypeDef *phost,
FreePacketCallbackTypeDef callback)
TransactionCompleteCallbackTypeDef callback)
{
HID_HandleTypeDef *HID_Handle = (HID_HandleTypeDef *) phost->pActiveClass->pData;
@ -452,7 +451,8 @@ HAL_StatusTypeDef USBH_HID_GetInterruptReport(USBH_HandleTypeDef *phost,
return HAL_OK;
}
return HAL_ERROR;
//return HAL_ERROR;
while (1);
}
@ -533,16 +533,18 @@ 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;
if (phost->RequestState == CMD_SEND)
{
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 );
}
@ -562,20 +564,41 @@ USBH_StatusTypeDef USBH_HID_SetReport (USBH_HandleTypeDef *phost,
uint8_t reportType,
uint8_t reportId,
uint8_t* reportBuff,
uint8_t reportLen)
uint8_t reportLen,
TransactionCompleteCallbackTypeDef callback)
{
HID_HandleTypeDef *HID_Handle = (HID_HandleTypeDef *) phost->pActiveClass->pData;
uint32_t i;
if (phost->RequestState == CMD_SEND)
{
if ((HID_Handle->state != HID_IDLE) ||
(reportLen > HID_MAX_REPORT_SIZE))
{
while (1);
}
HID_Handle->ReportCallback = callback;
HID_Handle->state = HID_SET_DATA_POLL;
for (i = 0; i < reportLen; i++)
{
HID_Handle->Data[i] = *reportBuff;
reportBuff++;
}
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;
}
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 );
//return USBH_CtlReq(phost, reportBuff, reportLen);
return USBH_OK;
}
@ -595,17 +618,19 @@ USBH_StatusTypeDef USBH_HID_GetReport (USBH_HandleTypeDef *phost,
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;
if (phost->RequestState == CMD_SEND)
{
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 );
}
@ -619,16 +644,17 @@ USBH_StatusTypeDef USBH_HID_GetReport (USBH_HandleTypeDef *phost,
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;
if (phost->RequestState == CMD_SEND)
{
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 );

@ -58,14 +58,17 @@ USBH_HandleTypeDef *Callback_MSC_phost;
*/
USBH_StatusTypeDef USBH_MSC_BOT_REQ_Reset(USBH_HandleTypeDef *phost)
{
phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_TYPE_CLASS | \
USB_REQ_RECIPIENT_INTERFACE;
phost->Control.setup.b.bRequest = USB_REQ_BOT_RESET;
phost->Control.setup.b.wValue.w = 0;
phost->Control.setup.b.wIndex.w = 0;
phost->Control.setup.b.wLength.w = 0;
if (phost->RequestState == CMD_SEND)
{
phost->Control.setup.b.bmRequestType = USB_H2D |
USB_REQ_TYPE_CLASS |
USB_REQ_RECIPIENT_INTERFACE;
phost->Control.setup.b.bRequest = USB_REQ_BOT_RESET;
phost->Control.setup.b.wValue.w = 0;
phost->Control.setup.b.wIndex.w = 0;
phost->Control.setup.b.wLength.w = 0;
}
return USBH_CtlReq(phost, 0 , 0 );
}
@ -79,13 +82,17 @@ USBH_StatusTypeDef USBH_MSC_BOT_REQ_Reset(USBH_HandleTypeDef *phost)
*/
USBH_StatusTypeDef USBH_MSC_BOT_REQ_GetMaxLUN(USBH_HandleTypeDef *phost, uint8_t *Maxlun)
{
phost->Control.setup.b.bmRequestType = USB_D2H | USB_REQ_TYPE_CLASS | \
USB_REQ_RECIPIENT_INTERFACE;
phost->Control.setup.b.bRequest = USB_REQ_GET_MAX_LUN;
phost->Control.setup.b.wValue.w = 0;
phost->Control.setup.b.wIndex.w = 0;
phost->Control.setup.b.wLength.w = 1;
if (phost->RequestState == CMD_SEND)
{
phost->Control.setup.b.bmRequestType = USB_D2H |
USB_REQ_TYPE_CLASS |
USB_REQ_RECIPIENT_INTERFACE;
phost->Control.setup.b.bRequest = USB_REQ_GET_MAX_LUN;
phost->Control.setup.b.wValue.w = 0;
phost->Control.setup.b.wIndex.w = 0;
phost->Control.setup.b.wLength.w = 1;
}
return USBH_CtlReq(phost, Maxlun , 1 );
}

@ -56,6 +56,7 @@ uint8_t ItemData;
static HAL_StatusTypeDef Downstream_HID_Mouse_ParseReportDescriptor(void);
static HAL_StatusTypeDef Downstream_HID_GetNextReportItem(void);
static void Downstream_HID_Mouse_ExtractDataFromReport(DownstreamPacketTypeDef* packetToSend);
static void Downstream_HID_Keyboard_ExtractDataFromReport(DownstreamPacketTypeDef* packetToSend);
static uint8_t Downstream_HID_Mouse_Extract8BitValue(HID_HandleTypeDef* hidHandle,
uint8_t valueBitOffset,
uint8_t valueBitLength);
@ -84,7 +85,7 @@ InterfaceCommandClassTypeDef Downstream_HID_ApproveConnectedDevice(void)
HAL_StatusTypeDef Downstream_HID_Mouse_ParseReportDescriptor(void)
static HAL_StatusTypeDef Downstream_HID_Mouse_ParseReportDescriptor(void)
{
uint32_t currentReportBitIndex = 0;
uint8_t currentUsagePage = 0;
@ -242,7 +243,7 @@ HAL_StatusTypeDef Downstream_HID_Mouse_ParseReportDescriptor(void)
//Retrieves the next item in the HID report, and at most one of its associated data bytes.
//Then it updates ReportDataPointer based on the actual length of the retrieved item.
HAL_StatusTypeDef Downstream_HID_GetNextReportItem(void)
static HAL_StatusTypeDef Downstream_HID_GetNextReportItem(void)
{
HID_HandleTypeDef* HID_Handle = (HID_HandleTypeDef*)hUsbHostFS.pActiveClass->pData;
uint32_t itemLength;
@ -287,9 +288,22 @@ void Downstream_HID_PacketProcessor(DownstreamPacketTypeDef* receivedPacket)
Downstream_PacketProcessor_NotifyDisconnectReplyRequired();
}
if (receivedPacket->Command == COMMAND_HID_SET_REPORT)
else if (receivedPacket->Command == COMMAND_HID_SET_REPORT)
{
if ((ConfiguredDeviceClass != COMMAND_CLASS_HID_KEYBOARD) ||
(receivedPacket->Length16 != ((HID_KEYBOARD_OUTPUT_DATA_LEN + 1) / 2) + DOWNSTREAM_PACKET_HEADER_LEN_16) ||
((receivedPacket->Data[0] & ~((1 << HID_KEYBOARD_MAX_LED) - 1)) != 0))
{
Downstream_PacketProcessor_FreakOut();
}
USBH_HID_SetReport(&hUsbHostFS,
HID_REPORT_DIRECTION_OUT,
0,
receivedPacket->Data,
HID_KEYBOARD_OUTPUT_DATA_LEN,
Downstream_HID_SendReportCallback);
Downstream_ReleasePacket(receivedPacket);
Downstream_PacketProcessor_NotifyDisconnectReplyRequired();
}
//else:
@ -297,17 +311,20 @@ void Downstream_HID_PacketProcessor(DownstreamPacketTypeDef* receivedPacket)
}
void Downstream_HID_InterruptReportCallback(DownstreamPacketTypeDef* packetToSend)
void Downstream_HID_InterruptReportCallback(void)
{
DownstreamPacketTypeDef* freePacket;
freePacket = Downstream_GetFreePacketImmediately();
if (ConfiguredDeviceClass == COMMAND_CLASS_HID_MOUSE)
{
Downstream_HID_Mouse_ExtractDataFromReport(packetToSend);
packetToSend->Length16 = ((HID_MOUSE_INPUT_DATA_LEN + 1) / 2) + DOWNSTREAM_PACKET_HEADER_LEN_16;
Downstream_HID_Mouse_ExtractDataFromReport(freePacket);
freePacket->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;
Downstream_HID_Keyboard_ExtractDataFromReport(freePacket);
freePacket->Length16 = ((HID_KEYBOARD_INPUT_DATA_LEN + 1) / 2) + DOWNSTREAM_PACKET_HEADER_LEN_16;
}
//else if...
@ -317,13 +334,13 @@ void Downstream_HID_InterruptReportCallback(DownstreamPacketTypeDef* packetToSen
return;
}
packetToSend->CommandClass = ConfiguredDeviceClass;
packetToSend->Command = COMMAND_HID_GET_REPORT;
Downstream_PacketProcessor_ClassReply(packetToSend);
freePacket->CommandClass = ConfiguredDeviceClass;
freePacket->Command = COMMAND_HID_GET_REPORT;
Downstream_PacketProcessor_ClassReply(freePacket);
}
void Downstream_HID_Mouse_ExtractDataFromReport(DownstreamPacketTypeDef* packetToSend)
static void Downstream_HID_Mouse_ExtractDataFromReport(DownstreamPacketTypeDef* packetToSend)
{
HID_HandleTypeDef* HID_Handle = (HID_HandleTypeDef*)hUsbHostFS.pActiveClass->pData;
uint32_t readData;
@ -348,9 +365,9 @@ void Downstream_HID_Mouse_ExtractDataFromReport(DownstreamPacketTypeDef* packetT
uint8_t Downstream_HID_Mouse_Extract8BitValue(HID_HandleTypeDef* hidHandle,
uint8_t valueBitOffset,
uint8_t valueBitLength)
static uint8_t Downstream_HID_Mouse_Extract8BitValue(HID_HandleTypeDef* hidHandle,
uint8_t valueBitOffset,
uint8_t valueBitLength)
{
int32_t readData;
@ -371,7 +388,7 @@ uint8_t Downstream_HID_Mouse_Extract8BitValue(HID_HandleTypeDef* hidHandle,
void Downstream_HID_Keyboard_ExtractDataFromReport(DownstreamPacketTypeDef* packetToSend)
static void Downstream_HID_Keyboard_ExtractDataFromReport(DownstreamPacketTypeDef* packetToSend)
{
HID_HandleTypeDef* HID_Handle = (HID_HandleTypeDef*)hUsbHostFS.pActiveClass->pData;
uint32_t i;
@ -392,3 +409,14 @@ void Downstream_HID_Keyboard_ExtractDataFromReport(DownstreamPacketTypeDef* pack
}
void Downstream_HID_SendReportCallback(void)
{
DownstreamPacketTypeDef* freePacket;
freePacket = Downstream_GetFreePacketImmediately();
freePacket->CommandClass = ConfiguredDeviceClass;
freePacket->Command = COMMAND_HID_SET_REPORT;
Downstream_PacketProcessor_ClassReply(freePacket);
}

@ -92,6 +92,33 @@ HAL_StatusTypeDef Downstream_GetFreePacket(FreePacketCallbackTypeDef callback)
}
DownstreamPacketTypeDef* Downstream_GetFreePacketImmediately(void)
{
if (DownstreamInterfaceState >= DOWNSTREAM_INTERFACE_ERROR)
{
return NULL;
}
//We are expecting a free buffer now
if (DownstreamPacket0.Busy == NOT_BUSY)
{
DownstreamPacket0.Busy = BUSY;
return &DownstreamPacket0;
}
if (DownstreamPacket1.Busy == NOT_BUSY)
{
DownstreamPacket1.Busy = BUSY;
return &DownstreamPacket1;
}
//Should not happen:
DOWNSTREAM_SPI_FREAKOUT;
return NULL;
}
//Used by Downstream state machine and USB host classes.
void Downstream_ReleasePacket(DownstreamPacketTypeDef* packetToRelease)
{

@ -10,7 +10,6 @@
*/
#include <downstream_hid.h>
#include "downstream_statemachine.h"
#include "downstream_interface_def.h"
#include "downstream_spi.h"

@ -29,10 +29,16 @@
#define HID_KEYBOARD_MAX_LED 3
typedef uint8_t (*UpstreamHidGetReportCallback)(uint8_t *report,
uint16_t len);
typedef enum
{
KEYBOARD_OUT_STATE_IDLE,
KEYBOARD_OUT_STATE_DATA_READY,
KEYBOARD_OUT_STATE_BUSY
} KeyboardOutStateTypeDef;
typedef uint8_t (*UpstreamHidGetReportCallback)(uint8_t *report,
uint16_t len);
void Upstream_HID_DeInit(void);
void Upstream_HID_GetNextInterruptReport(UpstreamHidGetReportCallback callback);

@ -60,7 +60,7 @@ InterfaceCommandMscTypeDef;
typedef enum
{
COMMAND_HID_GET_REPORT, //Returns HID report from device
COMMAND_HID_SET_REPORT //Sends HID report to device. No reply or ack expected.
COMMAND_HID_SET_REPORT //Sends HID report to device. Simple ack packet contains no data.
}
InterfaceCommandHidTypeDef;

@ -19,8 +19,8 @@
UpstreamPacketTypeDef* UpstreamHidPacket = NULL;
UpstreamHidGetReportCallback GetReportCallback = NULL;
uint8_t KeyboardOutDataAvailable = 0;
uint8_t KeyboardOutData[HID_KEYBOARD_OUTPUT_DATA_LEN];
KeyboardOutStateTypeDef KeyboardOutDataState = KEYBOARD_OUT_STATE_IDLE;
uint8_t KeyboardOutData[HID_KEYBOARD_OUTPUT_DATA_LEN];
@ -36,7 +36,7 @@ void Upstream_HID_DeInit(void)
UpstreamHidPacket = NULL;
}
GetReportCallback = NULL;
KeyboardOutDataAvailable = 0;
KeyboardOutDataState = KEYBOARD_OUT_STATE_IDLE;
}
@ -54,11 +54,31 @@ void Upstream_HID_GetNextInterruptReport(UpstreamHidGetReportCallback callback)
return;
}
//Just return if we already have an outstanding request
if (GetReportCallback != NULL)
if (callback != NULL)
{
return;
//This means we were called by the host (normal operation)
if (KeyboardOutDataState == KEYBOARD_OUT_STATE_BUSY)
{
//Just save the callback, because we are still waiting for the OUT report to complete
GetReportCallback = callback;
return;
}
if (GetReportCallback != NULL)
{
//Just return if we already have an outstanding request
return;
}
}
else
{
//This means were called on OUT report completion
if (GetReportCallback == NULL)
{
//The host has not given us the callback yet, so we give up
return;
}
}
GetReportCallback = callback;
//Release packet used for last transaction (if any)
@ -175,7 +195,7 @@ void Upstream_HID_GetNextInterruptReportReceiveCallback(UpstreamPacketTypeDef* r
//Check if we need to send OUT data to the keyboard before requesting next Interrupt IN data
if (KeyboardOutDataAvailable)
if (KeyboardOutDataState == KEYBOARD_OUT_STATE_DATA_READY)
{
Upstream_HID_ReallySendControlReport();
}
@ -203,7 +223,7 @@ void Upstream_HID_SendControlReport(UpstreamPacketTypeDef* packetToSend, uint8_t
}
//Save data until after the next interrupt data is received from Downstream
KeyboardOutDataAvailable = 1;
KeyboardOutDataState = KEYBOARD_OUT_STATE_DATA_READY;
for (i = 0; i < HID_KEYBOARD_OUTPUT_DATA_LEN; i++)
{
KeyboardOutData[i] = packetToSend->Data[i];
@ -217,7 +237,7 @@ void Upstream_HID_ReallySendControlReport(void)
UpstreamPacketTypeDef* freePacket;
uint32_t i;
KeyboardOutDataAvailable = 0;
KeyboardOutDataState = KEYBOARD_OUT_STATE_BUSY;
freePacket = Upstream_GetFreePacketImmediately();
if (freePacket == NULL) return;
@ -232,10 +252,39 @@ void Upstream_HID_ReallySendControlReport(void)
}
freePacket->Data[0] &= ((1 << HID_KEYBOARD_MAX_LED) - 1);
if (Upstream_TransmitPacket(freePacket) != HAL_OK)
if (Upstream_TransmitPacket(freePacket) == HAL_OK)
{
Upstream_ReceivePacket(Upstream_HID_GetNextInterruptReportReceiveCallback);
}
else
{
Upstream_ReleasePacket(freePacket);
}
}
void Upstream_HID_ReallySendControlReportReceiveCallback(UpstreamPacketTypeDef* receivedPacket)
{
InterfaceCommandClassTypeDef activeClass;
activeClass = Upstream_StateMachine_CheckActiveClass();
if (activeClass != COMMAND_CLASS_HID_KEYBOARD) //add classes here
{
UPSTREAM_STATEMACHINE_FREAKOUT;
return;
}
if (receivedPacket == NULL)
{
return; //Just give up...
}
Upstream_ReleasePacket(receivedPacket);
KeyboardOutDataState = KEYBOARD_OUT_STATE_IDLE;
//If upstream host has already requested the next IN report data,
//this will send the request downstream.
Upstream_HID_GetNextInterruptReport(NULL);
}

Loading…
Cancel
Save