1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-02-26 15:54:15 +01:00

Merged in corvusvcorax/librepilot/LP-602_workaround (pull request #518)

LP-602 fix crashes, reboots and other problems with USB reconnects/replugs

Approved-by: Eric Price <corvuscorax@cybertrench.com>
Approved-by: Alessio Morale <alessiomorale@gmail.com>
Approved-by: Lalanne Laurent <f5soh@free.fr>
This commit is contained in:
Eric Price 2019-02-21 20:35:27 +00:00 committed by Lalanne Laurent
commit ae1a0e93b8
10 changed files with 55 additions and 33 deletions

View File

@ -681,7 +681,7 @@ static uint32_t DCD_WriteEmptyTxFifo(USB_OTG_CORE_HANDLE *pdev, uint32_t epnum)
} }
// --- start fix // --- start fix
uint32_t fifoemptymsk; uint32_t fifoemptymsk;
if (len < ep->maxpacket) if (len < ep->maxpacket || ep->xfer_count==0)
{ {
// FIFO empty // FIFO empty
fifoemptymsk = 0x1 << epnum; fifoemptymsk = 0x1 << epnum;

View File

@ -38,7 +38,7 @@
#include <pios_helpers.h> #include <pios_helpers.h>
/* Rx/Tx status */ /* Rx/Tx status */
static uint8_t transfer_possible = 0; static volatile uint8_t transfer_possible = 0;
#ifdef PIOS_INCLUDE_FREERTOS #ifdef PIOS_INCLUDE_FREERTOS
static void(*disconnection_cb_list[3]) (void); static void(*disconnection_cb_list[3]) (void);
@ -148,6 +148,9 @@ out_fail:
*/ */
int32_t PIOS_USB_ChangeConnectionState(bool connected) int32_t PIOS_USB_ChangeConnectionState(bool connected)
{ {
#ifdef PIOS_INCLUDE_FREERTOS
static volatile uint8_t lastStatus = 2; // 2 is "no last status"
#endif
// In all cases: re-initialise USB HID driver // In all cases: re-initialise USB HID driver
if (connected) { if (connected) {
transfer_possible = 1; transfer_possible = 1;
@ -168,6 +171,12 @@ int32_t PIOS_USB_ChangeConnectionState(bool connected)
#ifdef PIOS_INCLUDE_FREERTOS #ifdef PIOS_INCLUDE_FREERTOS
raiseConnectionStateCallback(connected); raiseConnectionStateCallback(connected);
if (lastStatus != transfer_possible) {
if (lastStatus == 1) {
raiseDisconnectionCallbacks();
}
lastStatus = transfer_possible;
}
#endif #endif
return 0; return 0;
@ -187,28 +196,19 @@ bool PIOS_USB_CheckAvailable(__attribute__((unused)) uint32_t id)
return false; 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 transfer_possible;
// Please note that checks of transfer_possible and the reconnection handling is
// suppressed for non freertos mode (aka bootloader) as this is causing problems detecting connection and
// broken communications.
#ifdef PIOS_INCLUDE_FREERTOS
static bool lastStatus = false;
bool status = usb_found != 0 && transfer_possible ? 1 : 0;
bool reconnect = false;
if (xSemaphoreTakeFromISR(usb_dev->statusCheckSemaphore, NULL) == pdTRUE) {
reconnect = (lastStatus && !status);
lastStatus = status;
xSemaphoreGiveFromISR(usb_dev->statusCheckSemaphore, NULL);
} }
if (reconnect) {
raiseDisconnectionCallbacks();
}
return status;
#else /**
return usb_found; * This function returns wether a USB cable (5V pin) has been detected
* \return true: cable connected
* \return false: cable not detected (no cable or cable with no power)
*/
bool PIOS_USB_CableConnected(__attribute__((unused)) uint8_t id)
{
struct pios_usb_dev *usb_dev = (struct pios_usb_dev *)pios_usb_id;
#endif return ((usb_dev->cfg->vsense.gpio->IDR & usb_dev->cfg->vsense.init.GPIO_Pin) != 0) ^ usb_dev->cfg->vsense_active_low;
} }
/* /*

View File

@ -191,7 +191,7 @@ int32_t PIOS_USB_CDC_Init(uint32_t *usbcdc_id, const struct pios_usb_cdc_cfg *cf
pios_usb_cdc_id = (uint32_t)usb_cdc_dev; pios_usb_cdc_id = (uint32_t)usb_cdc_dev;
/* Tx is not active yet */ /* Tx and Rx are not active yet */
usb_cdc_dev->tx_active = false; usb_cdc_dev->tx_active = false;
/* Clear stats */ /* Clear stats */
@ -607,6 +607,11 @@ static void PIOS_USB_CDC_DATA_IF_Init(uint32_t usb_cdc_id)
PIOS_USB_CDC_DATA_EP_OUT_Callback, PIOS_USB_CDC_DATA_EP_OUT_Callback,
(uint32_t)usb_cdc_dev); (uint32_t)usb_cdc_dev);
usb_cdc_dev->usb_data_if_enabled = true; usb_cdc_dev->usb_data_if_enabled = true;
usb_cdc_dev->tx_active = false;
/* Activate rx prophylactically */
PIOS_USBHOOK_EndpointRx(usb_cdc_dev->cfg->data_rx_ep,
usb_cdc_dev->rx_packet_buffer,
sizeof(usb_cdc_dev->rx_packet_buffer));
} }
static void PIOS_USB_CDC_DATA_IF_DeInit(uint32_t usb_cdc_id) static void PIOS_USB_CDC_DATA_IF_DeInit(uint32_t usb_cdc_id)

View File

@ -280,7 +280,9 @@ static USBD_DEVICE device_callbacks = {
static void PIOS_USBHOOK_USR_Init(void) static void PIOS_USBHOOK_USR_Init(void)
{ {
PIOS_USB_ChangeConnectionState(false); PIOS_USB_ChangeConnectionState(false);
reconnect(); // reconnect dev logically on init (previously a call to reconnect())
DCD_DevDisconnect(&pios_usb_otg_core_handle);
DCD_DevConnect(&pios_usb_otg_core_handle);
} }
static void PIOS_USBHOOK_USR_DeviceReset(__attribute__((unused)) uint8_t speed) static void PIOS_USBHOOK_USR_DeviceReset(__attribute__((unused)) uint8_t speed)
@ -491,9 +493,24 @@ static USBD_Class_cb_TypeDef class_callbacks = {
static void reconnect(void) static void reconnect(void)
{ {
/* Force a physical disconnect/reconnect */ static volatile bool in_reconnect = false;
/* Force a complete device reset. This can trigger a call to reconnect() so prevent recursion */
if (!in_reconnect) {
in_reconnect = true; // save since volatile and STM32F4 is single core
// disable USB device
DCD_DevDisconnect(&pios_usb_otg_core_handle); DCD_DevDisconnect(&pios_usb_otg_core_handle);
DCD_DevConnect(&pios_usb_otg_core_handle); USBD_DeInit(&pios_usb_otg_core_handle);
USB_OTG_StopDevice(&pios_usb_otg_core_handle);
// enable USB device
USBD_Init(&pios_usb_otg_core_handle,
USB_OTG_FS_CORE_ID,
&device_callbacks,
&class_callbacks,
&user_callbacks);
in_reconnect = false;
}
} }
#endif /* PIOS_INCLUDE_USB */ #endif /* PIOS_INCLUDE_USB */

View File

@ -82,7 +82,7 @@ int main()
// is 2.7 volts // is 2.7 volts
check_bor(); check_bor();
USB_connected = PIOS_USB_CheckAvailable(0); USB_connected = PIOS_USB_CableConnected(0);
if (PIOS_IAP_CheckRequest() == true) { if (PIOS_IAP_CheckRequest() == true) {
PIOS_DELAY_WaitmS(1000); PIOS_DELAY_WaitmS(1000);

View File

@ -76,7 +76,7 @@ int main()
PIOS_Board_Init(); PIOS_Board_Init();
PIOS_IAP_Init(); PIOS_IAP_Init();
USB_connected = PIOS_USB_CheckAvailable(0); USB_connected = PIOS_USB_CableConnected(0);
if (PIOS_IAP_CheckRequest() == true) { if (PIOS_IAP_CheckRequest() == true) {
PIOS_DELAY_WaitmS(1000); PIOS_DELAY_WaitmS(1000);

View File

@ -82,7 +82,7 @@ int main()
// is 2.7 volts // is 2.7 volts
check_bor(); check_bor();
USB_connected = PIOS_USB_CheckAvailable(0); USB_connected = PIOS_USB_CableConnected(0);
if (PIOS_IAP_CheckRequest() == true) { if (PIOS_IAP_CheckRequest() == true) {
PIOS_DELAY_WaitmS(1000); PIOS_DELAY_WaitmS(1000);

View File

@ -82,7 +82,7 @@ int main()
// is 2.7 volts // is 2.7 volts
check_bor(); check_bor();
USB_connected = PIOS_USB_CheckAvailable(0); USB_connected = PIOS_USB_CableConnected(0);
if (PIOS_IAP_CheckRequest() == true) { if (PIOS_IAP_CheckRequest() == true) {
PIOS_DELAY_WaitmS(1000); PIOS_DELAY_WaitmS(1000);

View File

@ -82,7 +82,7 @@ int main()
// is 2.7 volts // is 2.7 volts
check_bor(); check_bor();
USB_connected = PIOS_USB_CheckAvailable(0); USB_connected = PIOS_USB_CableConnected(0);
if (PIOS_IAP_CheckRequest() == true) { if (PIOS_IAP_CheckRequest() == true) {
PIOS_DELAY_WaitmS(1000); PIOS_DELAY_WaitmS(1000);

View File

@ -83,7 +83,7 @@ int main()
// is 2.7 volts // is 2.7 volts
check_bor(); check_bor();
USB_connected = PIOS_USB_CheckAvailable(0); USB_connected = PIOS_USB_CableConnected(0);
if (PIOS_IAP_CheckRequest() == true) { if (PIOS_IAP_CheckRequest() == true) {
PIOS_DELAY_WaitmS(1000); PIOS_DELAY_WaitmS(1000);