From dab400c80d82967a5bbdfc8e630a61fac89ccded Mon Sep 17 00:00:00 2001 From: Stacey Sheldon Date: Tue, 22 May 2012 00:21:24 -0400 Subject: [PATCH] usb: decouple "available" from "cable connected" The bootloader needs to understand whether the USB cable is connected. The HID and CDC drivers need to know if the cable is connected _and_ the device has been enumerated already. Separate these two concepts in the API. Combining these was resulting in the BL not properly detecting that the cable was plugged in, and trying to boot the firmware image immediately. This effectively bricked the board if you ever had an invalid firmware image. It also happens to be the case that the BU images automatically invalidate themselves after updating the BL so they don't run again. The cable detect bug + this intended behaviour of the BU image resulted in a bricked board after upgrading the BL. --- flight/PiOS/STM32F10x/pios_usb.c | 24 ++++++++++++++++-------- flight/PiOS/inc/pios_usb.h | 1 + 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/flight/PiOS/STM32F10x/pios_usb.c b/flight/PiOS/STM32F10x/pios_usb.c index ea279233c..edac4611a 100644 --- a/flight/PiOS/STM32F10x/pios_usb.c +++ b/flight/PiOS/STM32F10x/pios_usb.c @@ -40,7 +40,7 @@ #if defined(PIOS_INCLUDE_USB_HID) /* Rx/Tx status */ -static uint8_t transfer_possible = 0; +static bool transfer_possible = false; enum pios_usb_dev_magic { PIOS_USB_DEV_MAGIC = 0x17365904, @@ -152,7 +152,7 @@ int32_t PIOS_USB_ChangeConnectionState(bool Connected) { // In all cases: re-initialise USB HID driver if (Connected) { - transfer_possible = 1; + transfer_possible = true; //TODO: Check SetEPRxValid(ENDP1); @@ -161,7 +161,7 @@ int32_t PIOS_USB_ChangeConnectionState(bool Connected) #endif } else { // Cable disconnected: disable transfers - transfer_possible = 0; + transfer_possible = false; #if defined(USB_LED_OFF) USB_LED_OFF; // turn the USB led off @@ -207,22 +207,30 @@ int32_t PIOS_USB_Reenumerate() return 0; } +bool PIOS_USB_CableConnected(uint8_t id) +{ + struct pios_usb_dev * usb_dev = (struct pios_usb_dev *) pios_usb_com_id; + + if (PIOS_USB_validate(usb_dev) != 0) + return false; + + return usb_dev->cfg->vsense.gpio->IDR & usb_dev->cfg->vsense.init.GPIO_Pin; +} + /** * This function returns the connection status of the USB HID interface * \return 1: interface available * \return 0: interface not available * \note Applications shouldn't call this function directly, instead please use \ref PIOS_COM layer functions */ -uint32_t usb_found; bool PIOS_USB_CheckAvailable(uint8_t id) { struct pios_usb_dev * usb_dev = (struct pios_usb_dev *) pios_usb_com_id; - if(PIOS_USB_validate(usb_dev) != 0) - return 0; + if (PIOS_USB_validate(usb_dev) != 0) + return false; - usb_found = (usb_dev->cfg->vsense.gpio->IDR & usb_dev->cfg->vsense.init.GPIO_Pin); - return usb_found != 0 && transfer_possible ? 1 : 0; + return PIOS_USB_CableConnected(id) && transfer_possible; } #endif diff --git a/flight/PiOS/inc/pios_usb.h b/flight/PiOS/inc/pios_usb.h index 76b8f01b4..ad63ae3a8 100644 --- a/flight/PiOS/inc/pios_usb.h +++ b/flight/PiOS/inc/pios_usb.h @@ -35,6 +35,7 @@ /* Global functions */ 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(uint8_t id); #endif /* PIOS_USB_H */