diff --git a/flight/pios/inc/pios_usb.h b/flight/pios/inc/pios_usb.h index 554f6b817..a068a1705 100644 --- a/flight/pios/inc/pios_usb.h +++ b/flight/pios/inc/pios_usb.h @@ -37,7 +37,7 @@ extern int32_t PIOS_USB_Reenumerate(); extern int32_t PIOS_USB_ChangeConnectionState(bool connected); extern bool PIOS_USB_CableConnected(uint8_t id); extern bool PIOS_USB_CheckAvailable(uint32_t id); - +extern void PIOS_USB_RegisterDisconnectionCallback(void (*disconnectionCB)(void)); #endif /* PIOS_USB_H */ /** diff --git a/flight/pios/stm32f4xx/pios_usb.c b/flight/pios/stm32f4xx/pios_usb.c index 2184c303e..2c9ebea88 100644 --- a/flight/pios/stm32f4xx/pios_usb.c +++ b/flight/pios/stm32f4xx/pios_usb.c @@ -34,12 +34,14 @@ #include "usb_core.h" #include "pios_usb_board_data.h" -#include "pios_usb_priv.h" - +#include +#include /* Rx/Tx status */ static uint8_t transfer_possible = 0; +static void (*disconnection_cb_list[3])(void); + enum pios_usb_dev_magic { PIOS_USB_DEV_MAGIC = 0x17365904, }; @@ -49,6 +51,8 @@ struct pios_usb_dev { const struct pios_usb_cfg *cfg; }; +static void raiseDisconnectionCallbacks(void); + /** * @brief Validate the usb device structure * @returns true if valid device or false otherwise @@ -162,15 +166,43 @@ uint32_t usb_found; bool PIOS_USB_CheckAvailable(__attribute__((unused)) uint32_t id) { struct pios_usb_dev *usb_dev = (struct pios_usb_dev *)pios_usb_id; - + static bool lastStatus = false; if (!PIOS_USB_validate(usb_dev)) { return false; } usb_found = ((usb_dev->cfg->vsense.gpio->IDR & usb_dev->cfg->vsense.init.GPIO_Pin) != 0) ^ usb_dev->cfg->vsense_active_low; - return usb_found; - return usb_found != 0 && transfer_possible ? 1 : 0; + bool status = usb_found != 0 && transfer_possible ? 1 : 0; + + if(lastStatus && !status){ + raiseDisconnectionCallbacks(); + } + lastStatus = status; + return status; +} + +/* + * + * Register a physical disconnection callback + * + */ +void PIOS_USB_RegisterDisconnectionCallback(void (*disconnectionCB)(void)){ + PIOS_Assert(disconnectionCB); + for(uint32_t i = 0; i < NELEMENTS(disconnection_cb_list); i++){ + if(disconnection_cb_list[i] == NULL){ + disconnection_cb_list[i] = disconnectionCB; + return; + } + } + PIOS_Assert(0); +} + +static void raiseDisconnectionCallbacks(void){ + uint32_t i = 0; + while(i < NELEMENTS(disconnection_cb_list) && disconnection_cb_list[i] != NULL){ + (disconnection_cb_list[i++])(); + } } /* diff --git a/flight/pios/stm32f4xx/pios_usbhook.c b/flight/pios/stm32f4xx/pios_usbhook.c index 18c3e1a55..80bd5ad82 100644 --- a/flight/pios/stm32f4xx/pios_usbhook.c +++ b/flight/pios/stm32f4xx/pios_usbhook.c @@ -46,6 +46,8 @@ #include "usbd_req.h" /* USBD_CtlError */ #include "usb_dcd_int.h" /* USBD_OTG_ISR_Handler */ +static void reconnect(void); + /* * External API */ @@ -82,6 +84,9 @@ static USBD_Usr_cb_TypeDef user_callbacks; void PIOS_USBHOOK_Activate(void) { + + PIOS_USB_RegisterDisconnectionCallback(&reconnect); + USBD_Init(&pios_usb_otg_core_handle, USB_OTG_FS_CORE_ID, &device_callbacks, @@ -271,12 +276,7 @@ static USBD_DEVICE device_callbacks = { static void PIOS_USBHOOK_USR_Init(void) { PIOS_USB_ChangeConnectionState(false); - -#if 1 - /* Force a physical disconnect/reconnect */ - DCD_DevDisconnect(&pios_usb_otg_core_handle); - DCD_DevConnect(&pios_usb_otg_core_handle); -#endif + reconnect(); } static void PIOS_USBHOOK_USR_DeviceReset(__attribute__((unused)) uint8_t speed) @@ -483,4 +483,10 @@ static USBD_Class_cb_TypeDef class_callbacks = { #endif /* USB_SUPPORT_USER_STRING_DESC */ }; +static void reconnect(void){ + /* Force a physical disconnect/reconnect */ + DCD_DevDisconnect(&pios_usb_otg_core_handle); + DCD_DevConnect(&pios_usb_otg_core_handle); +} + #endif /* PIOS_INCLUDE_USB */