diff --git a/Downstream/Middlewares/ST/STM32_USB_Host_Library/Core/Inc/usbh_def.h b/Downstream/Middlewares/ST/STM32_USB_Host_Library/Core/Inc/usbh_def.h index 48dd3f4..0b74acd 100644 --- a/Downstream/Middlewares/ST/STM32_USB_Host_Library/Core/Inc/usbh_def.h +++ b/Downstream/Middlewares/ST/STM32_USB_Host_Library/Core/Inc/usbh_def.h @@ -190,6 +190,8 @@ #define USBH_MAX_ERROR_COUNT 2 #define USBH_DEVICE_ADDRESS 1 +#define USBH_CTRL_TRANSACTION_TIMEOUT_MS 100 + /** * @} @@ -413,8 +415,8 @@ typedef struct uint8_t pipe_out; uint8_t pipe_size; uint8_t *buff; + uint32_t timer; uint16_t length; - uint16_t timer; USB_Setup_TypeDef setup; CTRL_StateTypeDef state; uint8_t errorcount; diff --git a/Downstream/Middlewares/ST/STM32_USB_Host_Library/Core/Src/usbh_core.c b/Downstream/Middlewares/ST/STM32_USB_Host_Library/Core/Src/usbh_core.c index 4eb2709..2f0e71a 100644 --- a/Downstream/Middlewares/ST/STM32_USB_Host_Library/Core/Src/usbh_core.c +++ b/Downstream/Middlewares/ST/STM32_USB_Host_Library/Core/Src/usbh_core.c @@ -152,6 +152,8 @@ USBH_StatusTypeDef USBH_DeInit(USBH_HandleTypeDef *phost) USBH_LL_Stop(phost); } + USBH_LL_DeInit(phost); + return USBH_OK; } @@ -187,6 +189,7 @@ static USBH_StatusTypeDef DeInitStateMachine(USBH_HandleTypeDef *phost) phost->device.address = USBH_ADDRESS_DEFAULT; phost->device.speed = USBH_SPEED_FULL; + phost->device.is_connected = 0; return USBH_OK; } @@ -840,7 +843,7 @@ USBH_StatusTypeDef USBH_LL_Connect (USBH_HandleTypeDef *phost) } else if (phost->gState == HOST_DEV_WAIT_FOR_ATTACHMENT) { - //On the first boot after a power cycle with a low-speed device pre-attached, + //On a cold boot with a low-speed device pre-attached, //we get a second port-connected interrupt!??? //So go back and do the port reset again... phost->gState = HOST_IDLE; diff --git a/Downstream/Middlewares/ST/STM32_USB_Host_Library/Core/Src/usbh_ctlreq.c b/Downstream/Middlewares/ST/STM32_USB_Host_Library/Core/Src/usbh_ctlreq.c index df7f7d5..b853762 100644 --- a/Downstream/Middlewares/ST/STM32_USB_Host_Library/Core/Src/usbh_ctlreq.c +++ b/Downstream/Middlewares/ST/STM32_USB_Host_Library/Core/Src/usbh_ctlreq.c @@ -603,15 +603,14 @@ static USBH_StatusTypeDef USBH_HandleControl (USBH_HandleTypeDef *phost) { case CTRL_SETUP: /* send a SETUP packet */ - USBH_CtlSendSetup (phost, + phost->Control.timer = phost->Timer; + USBH_CtlSendSetup(phost, (uint8_t *)phost->Control.setup.d8 , phost->Control.pipe_out); - phost->Control.state = CTRL_SETUP_WAIT; break; case CTRL_SETUP_WAIT: - URB_Status = USBH_LL_GetURBState(phost, phost->Control.pipe_out); /* case SETUP packet sent successfully */ if(URB_Status == USBH_URB_DONE) @@ -647,22 +646,24 @@ static USBH_StatusTypeDef USBH_HandleControl (USBH_HandleTypeDef *phost) phost->Control.state = CTRL_STATUS_IN; } } -#if (USBH_USE_OS == 1) - osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0); -#endif } else if(URB_Status == USBH_URB_ERROR) { phost->Control.state = CTRL_ERROR; -#if (USBH_USE_OS == 1) - osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0); -#endif } else if (URB_Status == USBH_URB_NOTREADY) { - //Some mice cause a transaction error interrupt (HCINT_TXERR) at this point, - //so we retry and hope for the best! - phost->Control.state = CTRL_SETUP; + //Some mice cause a transaction error interrupt (HCINT_TXERR) at this point. + //Other mice just NAK our transaction. + //Either way we need to retry, but keep our original timeout so we don't wait forever. + USBH_CtlSendSetup(phost, + (uint8_t *)phost->Control.setup.d8 , + phost->Control.pipe_out); + } + + if ((int32_t)(phost->Timer - phost->Control.timer) >= USBH_CTRL_TRANSACTION_TIMEOUT_MS) + { + phost->Control.state = CTRL_ERROR; } break; @@ -678,171 +679,139 @@ static USBH_StatusTypeDef USBH_HandleControl (USBH_HandleTypeDef *phost) break; case CTRL_DATA_IN_WAIT: - URB_Status = USBH_LL_GetURBState(phost , phost->Control.pipe_in); /* check is DATA packet transferred successfully */ if (URB_Status == USBH_URB_DONE) { phost->Control.state = CTRL_STATUS_OUT; -#if (USBH_USE_OS == 1) - osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0); -#endif } /* manage error cases*/ if (URB_Status == USBH_URB_STALL) { - /* In stall case, return to previous machine state*/ - status = USBH_NOT_SUPPORTED; -#if (USBH_USE_OS == 1) - osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0); -#endif + //Retry transaction + phost->Control.state = CTRL_ERROR; } else if (URB_Status == USBH_URB_ERROR) { /* Device error */ - phost->Control.state = CTRL_ERROR; -#if (USBH_USE_OS == 1) - osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0); -#endif + phost->Control.state = CTRL_ERROR; + } + + if ((int32_t)(phost->Timer - phost->Control.timer) >= USBH_CTRL_TRANSACTION_TIMEOUT_MS) + { + phost->Control.state = CTRL_ERROR; } break; case CTRL_DATA_OUT: - + phost->Control.timer = phost->Timer; USBH_CtlSendData (phost, phost->Control.buff, phost->Control.length , phost->Control.pipe_out, 1); - phost->Control.timer = phost->Timer; phost->Control.state = CTRL_DATA_OUT_WAIT; break; case CTRL_DATA_OUT_WAIT: - - URB_Status = USBH_LL_GetURBState(phost , phost->Control.pipe_out); + URB_Status = USBH_LL_GetURBState(phost, phost->Control.pipe_out); if (URB_Status == USBH_URB_DONE) { /* If the Setup Pkt is sent successful, then change the state */ phost->Control.state = CTRL_STATUS_IN; -#if (USBH_USE_OS == 1) - osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0); -#endif } /* handle error cases */ else if (URB_Status == USBH_URB_STALL) { - /* In stall case, return to previous machine state*/ - phost->Control.state = CTRL_STALLED; - status = USBH_NOT_SUPPORTED; -#if (USBH_USE_OS == 1) - osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0); -#endif + //Retry transaction + phost->Control.state = CTRL_ERROR; } else if (URB_Status == USBH_URB_NOTREADY) { /* Nack received from device */ phost->Control.state = CTRL_DATA_OUT; - -#if (USBH_USE_OS == 1) - osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0); -#endif } else if (URB_Status == USBH_URB_ERROR) { /* device error */ phost->Control.state = CTRL_ERROR; status = USBH_FAIL; - -#if (USBH_USE_OS == 1) - osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0); -#endif - } + } + + if ((int32_t)(phost->Timer - phost->Control.timer) >= USBH_CTRL_TRANSACTION_TIMEOUT_MS) + { + phost->Control.state = CTRL_ERROR; + } break; case CTRL_STATUS_IN: /* Send 0 bytes out packet */ + phost->Control.timer = phost->Timer; USBH_CtlReceiveData (phost, 0, 0, phost->Control.pipe_in); - phost->Control.timer = phost->Timer; phost->Control.state = CTRL_STATUS_IN_WAIT; - break; case CTRL_STATUS_IN_WAIT: - URB_Status = USBH_LL_GetURBState(phost , phost->Control.pipe_in); if ( URB_Status == USBH_URB_DONE) { /* Control transfers completed, Exit the State Machine */ phost->Control.state = CTRL_COMPLETE; status = USBH_OK; -#if (USBH_USE_OS == 1) - osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0); -#endif } else if (URB_Status == USBH_URB_ERROR) { phost->Control.state = CTRL_ERROR; -#if (USBH_USE_OS == 1) - osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0); -#endif } else if(URB_Status == USBH_URB_STALL) { - /* Control transfers completed, Exit the State Machine */ - status = USBH_NOT_SUPPORTED; - -#if (USBH_USE_OS == 1) - osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0); -#endif + //Retry transaction + phost->Control.state = CTRL_ERROR; + } + + if ((int32_t)(phost->Timer - phost->Control.timer) >= USBH_CTRL_TRANSACTION_TIMEOUT_MS) + { + phost->Control.state = CTRL_ERROR; } break; case CTRL_STATUS_OUT: + phost->Control.timer = phost->Timer; USBH_CtlSendData (phost, 0, 0, phost->Control.pipe_out, 1); - phost->Control.timer = phost->Timer; phost->Control.state = CTRL_STATUS_OUT_WAIT; break; case CTRL_STATUS_OUT_WAIT: - URB_Status = USBH_LL_GetURBState(phost , phost->Control.pipe_out); if (URB_Status == USBH_URB_DONE) { status = USBH_OK; - phost->Control.state = CTRL_COMPLETE; - -#if (USBH_USE_OS == 1) - osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0); -#endif + phost->Control.state = CTRL_COMPLETE; } else if (URB_Status == USBH_URB_NOTREADY) { phost->Control.state = CTRL_STATUS_OUT; - -#if (USBH_USE_OS == 1) - osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0); -#endif } else if (URB_Status == USBH_URB_ERROR) { - phost->Control.state = CTRL_ERROR; - -#if (USBH_USE_OS == 1) - osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0); -#endif + phost->Control.state = CTRL_ERROR; + } + + if ((int32_t)(phost->Timer - phost->Control.timer) >= USBH_CTRL_TRANSACTION_TIMEOUT_MS) + { + phost->Control.state = CTRL_ERROR; } break; diff --git a/Downstream/Src/downstream_statemachine.c b/Downstream/Src/downstream_statemachine.c index 347c415..0a65f83 100644 --- a/Downstream/Src/downstream_statemachine.c +++ b/Downstream/Src/downstream_statemachine.c @@ -201,12 +201,6 @@ void Downstream_HostUserCallback(USBH_HandleTypeDef *phost, uint8_t id) return; } - //Called from main() - if (id == HOST_USER_UNRECOVERED_ERROR) - { - DOWNSTREAM_STATEMACHINE_FREAKOUT; - return; - } //Called from main() if (id == HOST_USER_CLASS_ACTIVE) @@ -263,8 +257,10 @@ void Downstream_HostUserCallback(USBH_HandleTypeDef *phost, uint8_t id) return; } + //Called from main(): - if (id == HOST_USER_CLASS_FAILED) + if ((id == HOST_USER_CLASS_FAILED) || + (id == HOST_USER_UNRECOVERED_ERROR)) //Probably due to a crappy device that won't enumerate! { //Unsupported device classes will cause a slow fault flash. //This is distinct from the fast freakout flash caused by internal errors or attacks. @@ -273,5 +269,6 @@ void Downstream_HostUserCallback(USBH_HandleTypeDef *phost, uint8_t id) DownstreamState = STATE_ERROR; return; } + } diff --git a/Downstream/Src/usbh_config.c b/Downstream/Src/usbh_config.c index af812dc..439da85 100644 --- a/Downstream/Src/usbh_config.c +++ b/Downstream/Src/usbh_config.c @@ -85,7 +85,7 @@ void HAL_HCD_MspDeInit(HCD_HandleTypeDef* hhcd) PA11 ------> USB_OTG_FS_DM PA12 ------> USB_OTG_FS_DP */ - HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12); + //HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12); /* Peripheral interrupt Deinit*/ HAL_NVIC_DisableIRQ(OTG_FS_IRQn);