Support disconnect/reconnect of attached HID device

pull/7/head
Robert Fisk 8 years ago
parent 056932d6bc
commit 655b0e56a8

@ -45,7 +45,7 @@
InterfaceCommandClassTypeDef Downstream_HID_ApproveConnectedDevice(void);
void Downstream_HID_PacketProcessor(DownstreamPacketTypeDef* receivedPacket);
void Downstream_HID_InterruptReportCallback(uint8_t* reportBuffer);
void Downstream_HID_InterruptReportCallback(DownstreamPacketTypeDef* packetToSend);

@ -45,6 +45,8 @@ void Downstream_HostUserCallback(USBH_HandleTypeDef *phost, uint8_t id);
void Downstream_PacketProcessor(DownstreamPacketTypeDef* receivedPacket);
void Downstream_PacketProcessor_GenericErrorReply(DownstreamPacketTypeDef* replyPacket);
void Downstream_PacketProcessor_ClassReply(DownstreamPacketTypeDef* replyPacket);
void Downstream_PacketProcessor_NotifyDisconnectReplyRequired(void);
void Downstream_PacketProcessor_CheckNotifyDisconnectReply(void);
void Downstream_PacketProcessor_SetErrorState(void);
void Downstream_PacketProcessor_FreakOut(void);

@ -211,9 +211,6 @@ typedef struct
typedef void (*HID_InterruptReportCallback)(uint8_t* reportBuffer);
/* Structure for HID process */
typedef struct _HID_Process
{
@ -229,7 +226,7 @@ typedef struct _HID_Process
uint8_t ep_addr;
uint8_t Protocol;
HID_DescTypeDef HID_Desc;
HID_InterruptReportCallback ReportCallback;
FreePacketCallbackTypeDef ReportCallback;
uint8_t Data[HID_MAX_REPORT_SIZE];
}
HID_HandleTypeDef;
@ -324,7 +321,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,
HID_InterruptReportCallback callback);
FreePacketCallbackTypeDef callback);
/**

@ -382,7 +382,7 @@ static USBH_StatusTypeDef USBH_HID_Process(USBH_HandleTypeDef *phost)
if (urbStatus == USBH_URB_DONE)
{
HID_Handle->ReportCallback(HID_Handle->Data);
Downstream_GetFreePacket(HID_Handle->ReportCallback);
HID_Handle->state = HID_IDLE;
break;
}
@ -431,7 +431,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,
HID_InterruptReportCallback callback)
FreePacketCallbackTypeDef callback)
{
HID_HandleTypeDef *HID_Handle = (HID_HandleTypeDef *) phost->pActiveClass->pData;

@ -25,7 +25,6 @@
#define HID_MOUSE_MAX_BUTTONS 4
DownstreamPacketTypeDef* SavedPacket;
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
@ -50,7 +49,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(uint8_t* reportBuffer);
static void Downstream_HID_Mouse_ExtractDataFromReport(DownstreamPacketTypeDef* packetToSend);
@ -259,23 +258,22 @@ void Downstream_HID_PacketProcessor(DownstreamPacketTypeDef* receivedPacket)
return;
}
SavedPacket = receivedPacket;
Downstream_ReleasePacket(receivedPacket);
if (USBH_HID_GetInterruptReport(&hUsbHostFS,
Downstream_HID_InterruptReportCallback) != HAL_OK)
{
Downstream_PacketProcessor_FreakOut();
}
Downstream_PacketProcessor_NotifyDisconnectReplyRequired();
}
void Downstream_HID_InterruptReportCallback(uint8_t* reportBuffer)
void Downstream_HID_InterruptReportCallback(DownstreamPacketTypeDef* packetToSend)
{
if (ConfiguredDeviceClass == COMMAND_CLASS_HID_MOUSE)
{
Downstream_HID_Mouse_ExtractDataFromReport(reportBuffer);
SavedPacket->Length16 = ((HID_MOUSE_DATA_LEN + 1) / 2) + DOWNSTREAM_PACKET_HEADER_LEN_16;
Downstream_HID_Mouse_ExtractDataFromReport(packetToSend);
packetToSend->Length16 = ((HID_MOUSE_DATA_LEN + 1) / 2) + DOWNSTREAM_PACKET_HEADER_LEN_16;
}
//else if...
else
@ -284,35 +282,37 @@ void Downstream_HID_InterruptReportCallback(uint8_t* reportBuffer)
return;
}
Downstream_PacketProcessor_ClassReply(SavedPacket);
packetToSend->CommandClass = ConfiguredDeviceClass;
packetToSend->Command = COMMAND_HID_REPORT;
Downstream_PacketProcessor_ClassReply(packetToSend);
}
void Downstream_HID_Mouse_ExtractDataFromReport(uint8_t* reportBuffer)
void Downstream_HID_Mouse_ExtractDataFromReport(DownstreamPacketTypeDef* packetToSend)
{
HID_HandleTypeDef* HID_Handle = (HID_HandleTypeDef*)hUsbHostFS.pActiveClass->pData;
uint16_t readData;
//Grab the buttons
readData = *(uint16_t*)&(reportBuffer[(ReportButtonBitOffset / 8)]);
readData = *(uint16_t*)&(HID_Handle->Data[(ReportButtonBitOffset / 8)]);
readData >>= (ReportButtonBitOffset % 8);
readData &= ((1 << ReportButtonBitLength) - 1);
SavedPacket->Data[0] = readData;
packetToSend->Data[0] = readData;
//Grab X
readData = *(uint16_t*)&(reportBuffer[(ReportXBitOffset / 8)]);
readData = *(uint16_t*)&(HID_Handle->Data[(ReportXBitOffset / 8)]);
readData >>= (ReportXBitOffset % 8);
SavedPacket->Data[1] = (uint8_t)readData;
packetToSend->Data[1] = (uint8_t)readData;
//Grab Y
readData = *(uint16_t*)&(reportBuffer[(ReportYBitOffset / 8)]);
readData = *(uint16_t*)&(HID_Handle->Data[(ReportYBitOffset / 8)]);
readData >>= (ReportYBitOffset % 8);
SavedPacket->Data[2] = (uint8_t)readData;
packetToSend->Data[2] = (uint8_t)readData;
//Grab wheel
readData = *(uint16_t*)&(reportBuffer[(ReportWheelBitOffset / 8)]);
readData = *(uint16_t*)&(HID_Handle->Data[(ReportWheelBitOffset / 8)]);
readData >>= (ReportWheelBitOffset % 8);
SavedPacket->Data[3] = (uint8_t)readData;
packetToSend->Data[3] = (uint8_t)readData;
}

@ -25,10 +25,12 @@
DownstreamStateTypeDef DownstreamState = STATE_DEVICE_NOT_READY;
InterfaceCommandClassTypeDef ConfiguredDeviceClass = COMMAND_CLASS_INTERFACE;
uint8_t NotifyDisconnectReply = 0;
void Downstream_PacketProcessor_Interface(DownstreamPacketTypeDef* receivedPacket);
void Downstream_PacketProcessor_Interface_ReplyNotifyDevice(DownstreamPacketTypeDef* replyPacket);
static void Downstream_PacketProcessor_Interface(DownstreamPacketTypeDef* receivedPacket);
static void Downstream_PacketProcessor_Interface_ReplyNotifyDevice(DownstreamPacketTypeDef* replyPacket);
static void Downstream_PacketProcessor_NotifyDisconnectReply(DownstreamPacketTypeDef* packetToSend);
@ -71,10 +73,7 @@ void Downstream_PacketProcessor(DownstreamPacketTypeDef* receivedPacket)
//we need to tell Upstream of the fact (and not freak out).
if (DownstreamState == STATE_DEVICE_NOT_READY)
{
receivedPacket->Length16 = DOWNSTREAM_PACKET_HEADER_LEN_16;
receivedPacket->CommandClass = COMMAND_CLASS_ERROR;
receivedPacket->Command = COMMAND_ERROR_DEVICE_DISCONNECTED;
Downstream_PacketProcessor_ClassReply(receivedPacket);
Downstream_PacketProcessor_NotifyDisconnectReply(receivedPacket);
return;
}
@ -172,6 +171,7 @@ void Downstream_PacketProcessor_GenericErrorReply(DownstreamPacketTypeDef* reply
Downstream_TransmitPacket(replyPacket);
Downstream_ReceivePacket(Downstream_PacketProcessor);
NotifyDisconnectReply = 0;
}
@ -179,6 +179,31 @@ void Downstream_PacketProcessor_ClassReply(DownstreamPacketTypeDef* replyPacket)
{
Downstream_TransmitPacket(replyPacket);
Downstream_ReceivePacket(Downstream_PacketProcessor);
NotifyDisconnectReply = 0;
}
void Downstream_PacketProcessor_NotifyDisconnectReplyRequired(void)
{
NotifyDisconnectReply = 1;
}
void Downstream_PacketProcessor_CheckNotifyDisconnectReply(void)
{
if (NotifyDisconnectReply == 2)
{
Downstream_GetFreePacket(Downstream_PacketProcessor_NotifyDisconnectReply);
}
}
void Downstream_PacketProcessor_NotifyDisconnectReply(DownstreamPacketTypeDef* packetToSend)
{
packetToSend->Length16 = DOWNSTREAM_PACKET_HEADER_LEN_16;
packetToSend->CommandClass = COMMAND_CLASS_ERROR;
packetToSend->Command = COMMAND_ERROR_DEVICE_DISCONNECTED;
Downstream_PacketProcessor_ClassReply(packetToSend);
}
@ -198,6 +223,10 @@ void Downstream_HostUserCallback(USBH_HandleTypeDef *phost, uint8_t id)
if (id == HOST_USER_DISCONNECTION)
{
DownstreamState = STATE_DEVICE_NOT_READY;
if (NotifyDisconnectReply == 1)
{
NotifyDisconnectReply = 2; //Request a 'device disconnected' reply when we get back to main()
}
return;
}

@ -73,23 +73,19 @@ void SysTick_Handler(void)
void DMA2_Stream2_IRQHandler(void)
{
//SPI_INT_ACTIVE_ON;
HAL_DMA_IRQHandler(&hdma_spi1_rx);
//SPI_INT_ACTIVE_OFF;
}
void DMA2_Stream3_IRQHandler(void)
{
//SPI_INT_ACTIVE_ON;
HAL_DMA_IRQHandler(&hdma_spi1_tx);
//SPI_INT_ACTIVE_OFF;
}
void OTG_FS_IRQHandler(void)
{
INT_ACTIVE_ON;
//INT_ACTIVE_ON;
HAL_HCD_IRQHandler(&hhcd_USB_OTG_FS);
INT_ACTIVE_OFF;
//INT_ACTIVE_OFF;
}

@ -73,6 +73,7 @@ int main(void)
{
USB_Host_Process();
Downstream_SPIProcess();
Downstream_PacketProcessor_CheckNotifyDisconnectReply();
}
}

@ -20,6 +20,8 @@
#define HID_MOUSE_DATA_LEN 4
#define HID_KEYBOARD_DATA_LEN 0
#define HID_MOUSE_MAX_BUTTONS 4
UpstreamPacketTypeDef* UpstreamHidPacket = NULL;
UpstreamHidSendReportCallback ReportCallback = NULL;
@ -60,11 +62,6 @@ HAL_StatusTypeDef Upstream_HID_GetNextReport(UpstreamHidSendReportCallback callb
UpstreamHidPacket = NULL;
}
if (ReportCallback != NULL)
{
UPSTREAM_STATEMACHINE_FREAKOUT;
return HAL_ERROR;
}
ReportCallback = callback;
freePacket = Upstream_GetFreePacketImmediately();
@ -124,6 +121,8 @@ void Upstream_HID_GetNextReportReceiveCallback(UpstreamPacketTypeDef* receivedPa
return;
}
receivedPacket->Data[0] &= ((1 << HID_MOUSE_MAX_BUTTONS) - 1); //Limit number of buttons received
//Mouse sanity checks & stuff go here...
dataLength = HID_MOUSE_DATA_LEN;

@ -150,6 +150,7 @@ void Upstream_MSC_GetCapacityReplyCallback(UpstreamPacketTypeDef* replyPacket)
if (replyPacket->Length16 != (UPSTREAM_PACKET_HEADER_LEN_16 + (8 / 2)))
{
Upstream_ReleasePacket(replyPacket);
GetCapacityCallback(NULL, 0, 0);
return;
}

Loading…
Cancel
Save