diff --git a/Upstream/Inc/upstream_hid.h b/Upstream/Inc/upstream_hid.h index 7d7f3f3..51cdc4e 100644 --- a/Upstream/Inc/upstream_hid.h +++ b/Upstream/Inc/upstream_hid.h @@ -41,10 +41,8 @@ typedef uint8_t (*UpstreamHidGetReportCallback)(uint8_t *report, uint16_t len); void Upstream_HID_DeInit(void); -void Upstream_HID_GetNextInterruptReport(UpstreamHidGetReportCallback callback); -void Upstream_HID_SendControlReport(UpstreamPacketTypeDef* packetToSend, uint8_t dataLength); -void Upstream_HID_ReallySendControlReport(void); - +void Upstream_HID_GetInterruptReport(UpstreamHidGetReportCallback callback); +void Upstream_HID_RequestSendControlReport(UpstreamPacketTypeDef* packetToSend, uint8_t dataLength); diff --git a/Upstream/Inc/upstream_statemachine.h b/Upstream/Inc/upstream_statemachine.h index 99b4802..3950e94 100644 --- a/Upstream/Inc/upstream_statemachine.h +++ b/Upstream/Inc/upstream_statemachine.h @@ -15,6 +15,7 @@ #include "led.h" #include "upstream_interface_def.h" +#include "usbd_def.h" typedef enum @@ -22,6 +23,7 @@ typedef enum STATE_TEST_INTERFACE, STATE_WAIT_DEVICE, STATE_DEVICE_ACTIVE, + STATE_SUSPENDED, STATE_ERROR } UpstreamStateTypeDef; @@ -39,7 +41,11 @@ typedef enum void Upstream_InitStateMachine(void); void Upstream_StateMachine_SetErrorState(void); InterfaceCommandClassTypeDef Upstream_StateMachine_CheckActiveClass(void); +uint32_t Upstream_StateMachine_GetSuspendState(void); void Upstream_StateMachine_DeviceDisconnected(void); +void Upstream_StateMachine_Suspend(void); +void Upstream_StateMachine_CheckResume(void); +void Upstream_StateMachine_Wakeup(void); diff --git a/Upstream/Middlewares/ST/STM32_USB_Device_Library/Class/HID/Src/usbd_hid.c b/Upstream/Middlewares/ST/STM32_USB_Device_Library/Class/HID/Src/usbd_hid.c index 22be3ec..f2f0219 100644 --- a/Upstream/Middlewares/ST/STM32_USB_Device_Library/Class/HID/Src/usbd_hid.c +++ b/Upstream/Middlewares/ST/STM32_USB_Device_Library/Class/HID/Src/usbd_hid.c @@ -77,7 +77,8 @@ static uint8_t USBD_HID_EP0RxReady(USBD_HandleTypeDef *pdev); -#define USBD_PID_HID 0x0002 +#define USBD_PID_MOUSE 0x0002 +#define USBD_PID_KEYBOARD 0x0003 USBD_ClassTypeDef USBD_HID = @@ -97,7 +98,7 @@ USBD_ClassTypeDef USBD_HID = USBD_HID_GetCfgDesc, USBD_HID_GetCfgDesc, USBD_HID_GetDeviceQualifierDesc, - USBD_PID_HID + 0 //USBD_PID_HID }; @@ -299,6 +300,7 @@ void USBD_HID_PreinitMouse(void) InReportSize = HID_MOUSE_INPUT_DATA_LEN; OutReportSize = HID_MOUSE_OUTPUT_DATA_LEN; + USBD_HID.USBDevPid = USBD_PID_MOUSE; 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; @@ -313,6 +315,7 @@ void USBD_HID_PreinitKeyboard(void) InReportSize = HID_KEYBOARD_INPUT_DATA_LEN; OutReportSize = HID_KEYBOARD_OUTPUT_DATA_LEN; + USBD_HID.USBDevPid = USBD_PID_KEYBOARD; 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; @@ -343,7 +346,7 @@ static uint8_t USBD_HID_Init (USBD_HandleTypeDef *pdev, ((USBD_HID_HandleTypeDef *)pdev->pClassData)->state = HID_IDLE; USBD_HID_pdev = pdev; - Upstream_HID_GetNextInterruptReport(USBD_HID_SendReport); + Upstream_HID_GetInterruptReport(USBD_HID_SendReport); } return ret; @@ -360,6 +363,11 @@ static uint8_t USBD_HID_DeInit (USBD_HandleTypeDef *pdev, uint8_t cfgidx) { Upstream_HID_DeInit(); + if (OutReportPacket != NULL) + { + Upstream_ReleasePacket(OutReportPacket); + OutReportPacket = NULL; + } /* Close HID EPs */ USBD_LL_CloseEP(pdev, @@ -566,7 +574,7 @@ static uint8_t USBD_HID_DataIn (USBD_HandleTypeDef *pdev, ((USBD_HID_HandleTypeDef *)pdev->pClassData)->state = HID_IDLE; USBD_HID_pdev = pdev; - Upstream_HID_GetNextInterruptReport(USBD_HID_SendReport); + Upstream_HID_GetInterruptReport(USBD_HID_SendReport); return USBD_OK; } @@ -586,7 +594,7 @@ static uint8_t *USBD_HID_GetDeviceQualifierDesc (uint16_t *length) //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 +//Upstream_HID will send it after the next IN interrupt transfer static uint8_t USBD_HID_EP0RxReady(USBD_HandleTypeDef *pdev) { if ((OutReportPacket == NULL) || @@ -595,7 +603,7 @@ static uint8_t USBD_HID_EP0RxReady(USBD_HandleTypeDef *pdev) while(1); } - Upstream_HID_SendControlReport(OutReportPacket, OutReportSize); + Upstream_HID_RequestSendControlReport(OutReportPacket, OutReportSize); Upstream_ReleasePacket(OutReportPacket); OutReportPacket = NULL; return USBD_OK; diff --git a/Upstream/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_core.h b/Upstream/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_core.h index 230b513..7748824 100755 --- a/Upstream/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_core.h +++ b/Upstream/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_core.h @@ -89,7 +89,7 @@ * @{ */ USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, USBD_DescriptorsTypeDef *pdesc, uint8_t id); -USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev); +USBD_ClassTypeDef* USBD_DeInit(USBD_HandleTypeDef *pdev); USBD_StatusTypeDef USBD_Start (USBD_HandleTypeDef *pdev); USBD_StatusTypeDef USBD_Stop (USBD_HandleTypeDef *pdev); USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass); @@ -146,6 +146,8 @@ USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, uint32_t USBD_LL_GetRxDataSize (USBD_HandleTypeDef *pdev, uint8_t ep_addr); void USBD_LL_Delay (uint32_t Delay); +void USBD_LL_WakeupHost(USBD_HandleTypeDef *pdev); + /** * @} */ diff --git a/Upstream/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c b/Upstream/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c index fa946cb..c524509 100755 --- a/Upstream/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c +++ b/Upstream/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c @@ -28,6 +28,7 @@ /* Includes ------------------------------------------------------------------*/ #include "usbd_core.h" #include "usbd_descriptors.h" +#include "upstream_statemachine.h" /** @addtogroup STM32_USBD_DEVICE_LIBRARY @@ -129,7 +130,7 @@ USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, USBD_DescriptorsTypeDef * * @param pdev: device instance * @retval status: status */ -USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev) +USBD_ClassTypeDef* USBD_DeInit(USBD_HandleTypeDef *pdev) { /* Set Default State */ pdev->dev_state = USBD_STATE_DEFAULT; @@ -143,7 +144,8 @@ USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev) /* Initialize low level driver */ USBD_LL_DeInit(pdev); - return USBD_OK; + return pdev->pClass; +// return USBD_OK; } @@ -456,6 +458,11 @@ USBD_StatusTypeDef USBD_Suspend(USBD_HandleTypeDef *pdev) { pdev->dev_old_state = pdev->dev_state; pdev->dev_state = USBD_STATE_SUSPENDED; + + if (pdev->dev_old_state > USBD_STATE_DEFAULT) + { + Upstream_StateMachine_Suspend(); + } return USBD_OK; } @@ -468,7 +475,12 @@ USBD_StatusTypeDef USBD_Suspend(USBD_HandleTypeDef *pdev) USBD_StatusTypeDef USBD_Resume(USBD_HandleTypeDef *pdev) { - pdev->dev_state = pdev->dev_old_state; + pdev->dev_state = pdev->dev_old_state; + + if (pdev->dev_old_state > USBD_STATE_DEFAULT) + { + Upstream_StateMachine_CheckResume(); + } return USBD_OK; } diff --git a/Upstream/Src/upstream_hid.c b/Upstream/Src/upstream_hid.c index 0355335..942c695 100644 --- a/Upstream/Src/upstream_hid.c +++ b/Upstream/Src/upstream_hid.c @@ -19,13 +19,16 @@ UpstreamPacketTypeDef* UpstreamHidPacket = NULL; UpstreamHidGetReportCallback GetReportCallback = NULL; -KeyboardOutStateTypeDef KeyboardOutDataState = KEYBOARD_OUT_STATE_IDLE; -uint8_t KeyboardOutData[HID_KEYBOARD_OUTPUT_DATA_LEN]; +KeyboardOutStateTypeDef KeyboardOutDataState = KEYBOARD_OUT_STATE_IDLE; +uint8_t KeyboardOutData[HID_KEYBOARD_OUTPUT_DATA_LEN]; +uint8_t GetReportLoopIsRunning = 0; -void Upstream_HID_GetNextInterruptReportReceiveCallback(UpstreamPacketTypeDef* receivedPacket); -void Upstream_HID_ReallySendControlReportReceiveCallback(UpstreamPacketTypeDef* receivedPacket); +static void Upstream_HID_ReceiveInterruptReport(void); +static void Upstream_HID_ReceiveInterruptReportCallback(UpstreamPacketTypeDef* receivedPacket); +static void Upstream_HID_SendControlReport(void); +static void Upstream_HID_SendControlReportCallback(UpstreamPacketTypeDef* receivedPacket); @@ -42,50 +45,42 @@ void Upstream_HID_DeInit(void) -void Upstream_HID_GetNextInterruptReport(UpstreamHidGetReportCallback callback) +//Called by usbd_hid to request our next interrupt report +void Upstream_HID_GetInterruptReport(UpstreamHidGetReportCallback callback) { - UpstreamPacketTypeDef* freePacket; - InterfaceCommandClassTypeDef activeClass; + GetReportCallback = callback; - activeClass = Upstream_StateMachine_CheckActiveClass(); - if ((activeClass != COMMAND_CLASS_HID_MOUSE) && - (activeClass != COMMAND_CLASS_HID_KEYBOARD)) //add classes here + if (UpstreamHidPacket != NULL) { - UPSTREAM_STATEMACHINE_FREAKOUT; - return; + Upstream_ReleasePacket(UpstreamHidPacket); + UpstreamHidPacket = NULL; } - if (callback != NULL) - { - //This means we were called by the host - //Release packet used for last transaction (if any) - if (UpstreamHidPacket != NULL) - { - Upstream_ReleasePacket(UpstreamHidPacket); - UpstreamHidPacket = NULL; - } + //Wakeup interrupts are apparently broken. + //So we check for resume when the host sends us something here. + Upstream_StateMachine_CheckResume(); - 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; - } - GetReportCallback = callback; + //Start our internal loop? + if (!GetReportLoopIsRunning) + { + GetReportLoopIsRunning = 1; + Upstream_HID_ReceiveInterruptReport(); } - else +} + + +//Our internal report request loop +static void Upstream_HID_ReceiveInterruptReport(void) +{ + UpstreamPacketTypeDef* freePacket; + InterfaceCommandClassTypeDef activeClass; + + activeClass = Upstream_StateMachine_CheckActiveClass(); + if ((activeClass != COMMAND_CLASS_HID_MOUSE) && + (activeClass != COMMAND_CLASS_HID_KEYBOARD)) //add classes here { - //This means were called on OUT report completion, or retrying after a downstream NAK - if (GetReportCallback == NULL) - { - //The host has not given us the callback yet, so we give up - return; - } + UPSTREAM_STATEMACHINE_FREAKOUT; + return; } freePacket = Upstream_GetFreePacketImmediately(); @@ -94,23 +89,24 @@ void Upstream_HID_GetNextInterruptReport(UpstreamHidGetReportCallback callback) return; } - freePacket->Length16 = UPSTREAM_PACKET_HEADER_LEN_16; - freePacket->CommandClass = activeClass; - freePacket->Command = COMMAND_HID_GET_REPORT; - - if (Upstream_TransmitPacket(freePacket) == HAL_OK) - { - Upstream_ReceivePacket(Upstream_HID_GetNextInterruptReportReceiveCallback); - } - else - { - Upstream_ReleasePacket(freePacket); - } + freePacket->Length16 = UPSTREAM_PACKET_HEADER_LEN_16; + freePacket->CommandClass = activeClass; + freePacket->Command = COMMAND_HID_GET_REPORT; + + if (Upstream_TransmitPacket(freePacket) == HAL_OK) + { + Upstream_ReceivePacket(Upstream_HID_ReceiveInterruptReportCallback); + } + else + { + Upstream_ReleasePacket(freePacket); + } + } -void Upstream_HID_GetNextInterruptReportReceiveCallback(UpstreamPacketTypeDef* receivedPacket) +static void Upstream_HID_ReceiveInterruptReportCallback(UpstreamPacketTypeDef* receivedPacket) { UpstreamHidGetReportCallback tempReportCallback; InterfaceCommandClassTypeDef activeClass; @@ -126,105 +122,115 @@ void Upstream_HID_GetNextInterruptReportReceiveCallback(UpstreamPacketTypeDef* r return; } - if (UpstreamHidPacket != NULL) - { - while(1); - } - if (receivedPacket == NULL) //Error receiving packet { return; //Just give up... } - if (GetReportCallback == NULL) //HID class may have been DeInitted while we were waiting for our reply - { - Upstream_ReleasePacket(receivedPacket); - return; - } - if (receivedPacket->Length16 == UPSTREAM_PACKET_HEADER_LEN_16) { //Zero-length reply indicates no data from downstream device Upstream_ReleasePacket(receivedPacket); - - //Check if we need to send OUT data to the keyboard before requesting next Interrupt IN data - if (KeyboardOutDataState == KEYBOARD_OUT_STATE_DATA_READY) - { - Upstream_HID_ReallySendControlReport(); - } - else - { - //Otherwise poll downstream again - Upstream_HID_GetNextInterruptReport(NULL); - } - return; } - - - if (activeClass == COMMAND_CLASS_HID_MOUSE) + else { - if (receivedPacket->Length16 != (UPSTREAM_PACKET_HEADER_LEN_16 + ((HID_MOUSE_INPUT_DATA_LEN + 1) / 2))) + if (activeClass == COMMAND_CLASS_HID_MOUSE) { - UPSTREAM_STATEMACHINE_FREAKOUT; - return; + if (receivedPacket->Length16 != (UPSTREAM_PACKET_HEADER_LEN_16 + ((HID_MOUSE_INPUT_DATA_LEN + 1) / 2))) + { + UPSTREAM_STATEMACHINE_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_STATEMACHINE_FREAKOUT; + return; + } + + //Mouse wakeup is triggered by button clicks only + if (receivedPacket->Data[0] != 0) + { + if (Upstream_StateMachine_GetSuspendState()) + { + //Send wakeup signal to host instead of returning data packet + GetReportCallback = NULL; + Upstream_StateMachine_Wakeup(); + } + } + + //Other mouse sanity checks & stuff go here... } - dataLength = HID_MOUSE_INPUT_DATA_LEN; - if ((receivedPacket->Data[0] & ~((1 << HID_MOUSE_MAX_BUTTONS) - 1)) != 0) //Check number of buttons received + + else if (activeClass == COMMAND_CLASS_HID_KEYBOARD) { - UPSTREAM_STATEMACHINE_FREAKOUT; - return; + if (receivedPacket->Length16 != (UPSTREAM_PACKET_HEADER_LEN_16 + ((HID_KEYBOARD_INPUT_DATA_LEN + 1) / 2))) + { + UPSTREAM_STATEMACHINE_FREAKOUT; + return; + } + dataLength = HID_KEYBOARD_INPUT_DATA_LEN; + + if (receivedPacket->Data[1] != 0) + { + UPSTREAM_STATEMACHINE_FREAKOUT; + return; + } + for (i = 2; i < HID_KEYBOARD_INPUT_DATA_LEN; i++) + { + if (receivedPacket->Data[i] > HID_KEYBOARD_MAX_KEY) + { + UPSTREAM_STATEMACHINE_FREAKOUT; + return; + } + } + + if (Upstream_StateMachine_GetSuspendState()) + { + //Send wakeup signal to host instead of returning data packet + GetReportCallback = NULL; + Upstream_StateMachine_Wakeup(); + } + + //Other keyboard sanity checks here... } - //Other 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))) + //Other HID classes go here... + else { UPSTREAM_STATEMACHINE_FREAKOUT; return; } - dataLength = HID_KEYBOARD_INPUT_DATA_LEN; - if (receivedPacket->Data[1] != 0) + if ((GetReportCallback == NULL) || + (UpstreamHidPacket != NULL)) { - UPSTREAM_STATEMACHINE_FREAKOUT; - return; + Upstream_ReleasePacket(receivedPacket); } - for (i = 2; i < HID_KEYBOARD_INPUT_DATA_LEN; i++) + else { - if (receivedPacket->Data[i] > HID_KEYBOARD_MAX_KEY) - { - UPSTREAM_STATEMACHINE_FREAKOUT; - return; - } + //Send resulting data to host + UpstreamHidPacket = receivedPacket; //Save packet so we can free it when upstream USB transaction is done + tempReportCallback = GetReportCallback; + GetReportCallback = NULL; + tempReportCallback(receivedPacket->Data, dataLength); } - //Other keyboard sanity checks here... } - //Other HID classes go here... - - else - { - UPSTREAM_STATEMACHINE_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); - //Check if we need to send OUT data to the keyboard before requesting next Interrupt IN data if (KeyboardOutDataState == KEYBOARD_OUT_STATE_DATA_READY) { - Upstream_HID_ReallySendControlReport(); + Upstream_HID_SendControlReport(); + } + else + { + Upstream_HID_ReceiveInterruptReport(); //Otherwise poll downstream again } } -void Upstream_HID_SendControlReport(UpstreamPacketTypeDef* packetToSend, uint8_t dataLength) +void Upstream_HID_RequestSendControlReport(UpstreamPacketTypeDef* packetToSend, uint8_t dataLength) { InterfaceCommandClassTypeDef activeClass; uint32_t i; @@ -248,7 +254,7 @@ void Upstream_HID_SendControlReport(UpstreamPacketTypeDef* packetToSend, uint8_t -void Upstream_HID_ReallySendControlReport(void) +static void Upstream_HID_SendControlReport(void) { UpstreamPacketTypeDef* freePacket; uint32_t i; @@ -270,7 +276,7 @@ void Upstream_HID_ReallySendControlReport(void) if (Upstream_TransmitPacket(freePacket) == HAL_OK) { - Upstream_ReceivePacket(Upstream_HID_ReallySendControlReportReceiveCallback); + Upstream_ReceivePacket(Upstream_HID_SendControlReportCallback); } else { @@ -280,7 +286,7 @@ void Upstream_HID_ReallySendControlReport(void) -void Upstream_HID_ReallySendControlReportReceiveCallback(UpstreamPacketTypeDef* receivedPacket) +static void Upstream_HID_SendControlReportCallback(UpstreamPacketTypeDef* receivedPacket) { InterfaceCommandClassTypeDef activeClass; @@ -291,6 +297,12 @@ void Upstream_HID_ReallySendControlReportReceiveCallback(UpstreamPacketTypeDef* return; } + if (KeyboardOutDataState != KEYBOARD_OUT_STATE_BUSY) + { + UPSTREAM_STATEMACHINE_FREAKOUT; + return; + } + if (receivedPacket == NULL) { return; //Just give up... @@ -298,9 +310,8 @@ void Upstream_HID_ReallySendControlReportReceiveCallback(UpstreamPacketTypeDef* 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); + Upstream_HID_ReceiveInterruptReport(); } + + diff --git a/Upstream/Src/upstream_statemachine.c b/Upstream/Src/upstream_statemachine.c index 2ae9cc1..5f0f180 100644 --- a/Upstream/Src/upstream_statemachine.c +++ b/Upstream/Src/upstream_statemachine.c @@ -12,6 +12,7 @@ #include "upstream_statemachine.h" #include "upstream_spi.h" +#include "upstream_hid.h" #include "usb_device.h" #include "usbd_core.h" #include "usbd_msc.h" @@ -82,7 +83,8 @@ InterfaceCommandClassTypeDef Upstream_StateMachine_CheckActiveClass(void) return COMMAND_CLASS_ERROR; } - if (UpstreamState != STATE_DEVICE_ACTIVE) + if ((UpstreamState != STATE_DEVICE_ACTIVE) && + (UpstreamState != STATE_SUSPENDED)) { UPSTREAM_STATEMACHINE_FREAKOUT; return COMMAND_CLASS_INTERFACE; @@ -92,6 +94,16 @@ InterfaceCommandClassTypeDef Upstream_StateMachine_CheckActiveClass(void) } +uint32_t Upstream_StateMachine_GetSuspendState(void) +{ + if (UpstreamState == STATE_SUSPENDED) + { + return 1; + } + return 0; +} + + void Upstream_StateMachine_TestInterfaceReplyCallback(UpstreamPacketTypeDef* replyPacket) { uint16_t i; @@ -228,3 +240,52 @@ void Upstream_StateMachine_DeviceDisconnected(void) Upstream_GetFreePacket(Upstream_StateMachine_NotifyDevice); } + +//Suspend event activated by our host +void Upstream_StateMachine_Suspend(void) +{ + if (UpstreamState >= STATE_ERROR) + { + return; + } + if (UpstreamState != STATE_DEVICE_ACTIVE) + { + UPSTREAM_STATEMACHINE_FREAKOUT; + return; + } + + UpstreamState = STATE_SUSPENDED; +} + + +//Resume event activated by our host +void Upstream_StateMachine_CheckResume(void) +{ + if (UpstreamState == STATE_SUSPENDED) + { + UpstreamState = STATE_DEVICE_ACTIVE; + } +} + + +//Activated by downstream report, causing us to wake up the host +void Upstream_StateMachine_Wakeup(void) +{ + USBD_ClassTypeDef* activeClass; + + if (UpstreamState != STATE_SUSPENDED) + { + UPSTREAM_STATEMACHINE_FREAKOUT; + return; + } + + //This is really ugly! But wakeup seems to be broken on the STM32, so we do it the hard way. + activeClass = USBD_DeInit(&hUsbDeviceFS); + USB_Device_Init(); + USBD_RegisterClass(&hUsbDeviceFS, activeClass); + USBD_Start(&hUsbDeviceFS); + +// This is how I'd wakeup the host, IF IT ACTUALLY WORKED! +// USBD_LL_WakeupHost(&hUsbDeviceFS); +} + diff --git a/Upstream/Src/usbd_config.c b/Upstream/Src/usbd_config.c index 9f17249..0c14415 100755 --- a/Upstream/Src/usbd_config.c +++ b/Upstream/Src/usbd_config.c @@ -501,4 +501,17 @@ void USBD_LL_Delay (uint32_t Delay) { HAL_Delay(Delay); } + + +void USBD_LL_WakeupHost(USBD_HandleTypeDef *pdev) +{ + if (pdev->dev_remote_wakeup == 1) + { + HAL_PCD_ActivateRemoteWakeup(pdev->pData); + HAL_Delay(10); + HAL_PCD_DeActivateRemoteWakeup(pdev->pData); + } +} + + /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/