Skip to content

Commit ae1a0e9

Browse files
CorvusCoraxf5soh
authored andcommitted
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>
2 parents aba11f0 + f162bbf commit ae1a0e9

10 files changed

Lines changed: 55 additions & 33 deletions

File tree

flight/pios/stm32f4xx/libraries/STM32_USB_OTG_Driver/src/usb_dcd_int.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -681,7 +681,7 @@ static uint32_t DCD_WriteEmptyTxFifo(USB_OTG_CORE_HANDLE *pdev, uint32_t epnum)
681681
}
682682
// --- start fix
683683
uint32_t fifoemptymsk;
684-
if (len < ep->maxpacket)
684+
if (len < ep->maxpacket || ep->xfer_count==0)
685685
{
686686
// FIFO empty
687687
fifoemptymsk = 0x1 << epnum;

flight/pios/stm32f4xx/pios_usb.c

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
#include <pios_helpers.h>
3939

4040
/* Rx/Tx status */
41-
static uint8_t transfer_possible = 0;
41+
static volatile uint8_t transfer_possible = 0;
4242

4343
#ifdef PIOS_INCLUDE_FREERTOS
4444
static void(*disconnection_cb_list[3]) (void);
@@ -148,6 +148,9 @@ int32_t PIOS_USB_Init(uint32_t *usb_id, const struct pios_usb_cfg *cfg)
148148
*/
149149
int32_t PIOS_USB_ChangeConnectionState(bool connected)
150150
{
151+
#ifdef PIOS_INCLUDE_FREERTOS
152+
static volatile uint8_t lastStatus = 2; // 2 is "no last status"
153+
#endif
151154
// In all cases: re-initialise USB HID driver
152155
if (connected) {
153156
transfer_possible = 1;
@@ -168,6 +171,12 @@ int32_t PIOS_USB_ChangeConnectionState(bool connected)
168171

169172
#ifdef PIOS_INCLUDE_FREERTOS
170173
raiseConnectionStateCallback(connected);
174+
if (lastStatus != transfer_possible) {
175+
if (lastStatus == 1) {
176+
raiseDisconnectionCallbacks();
177+
}
178+
lastStatus = transfer_possible;
179+
}
171180
#endif
172181

173182
return 0;
@@ -187,28 +196,19 @@ bool PIOS_USB_CheckAvailable(__attribute__((unused)) uint32_t id)
187196
return false;
188197
}
189198

190-
usb_found = ((usb_dev->cfg->vsense.gpio->IDR & usb_dev->cfg->vsense.init.GPIO_Pin) != 0) ^ usb_dev->cfg->vsense_active_low;
191-
// Please note that checks of transfer_possible and the reconnection handling is
192-
// suppressed for non freertos mode (aka bootloader) as this is causing problems detecting connection and
193-
// broken communications.
194-
#ifdef PIOS_INCLUDE_FREERTOS
195-
static bool lastStatus = false;
196-
bool status = usb_found != 0 && transfer_possible ? 1 : 0;
197-
bool reconnect = false;
198-
if (xSemaphoreTakeFromISR(usb_dev->statusCheckSemaphore, NULL) == pdTRUE) {
199-
reconnect = (lastStatus && !status);
200-
lastStatus = status;
201-
xSemaphoreGiveFromISR(usb_dev->statusCheckSemaphore, NULL);
202-
}
203-
if (reconnect) {
204-
raiseDisconnectionCallbacks();
205-
}
206-
return status;
199+
return transfer_possible;
200+
}
207201

208-
#else
209-
return usb_found;
202+
/**
203+
* This function returns wether a USB cable (5V pin) has been detected
204+
* \return true: cable connected
205+
* \return false: cable not detected (no cable or cable with no power)
206+
*/
207+
bool PIOS_USB_CableConnected(__attribute__((unused)) uint8_t id)
208+
{
209+
struct pios_usb_dev *usb_dev = (struct pios_usb_dev *)pios_usb_id;
210210

211-
#endif
211+
return ((usb_dev->cfg->vsense.gpio->IDR & usb_dev->cfg->vsense.init.GPIO_Pin) != 0) ^ usb_dev->cfg->vsense_active_low;
212212
}
213213

214214
/*

flight/pios/stm32f4xx/pios_usb_cdc.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ int32_t PIOS_USB_CDC_Init(uint32_t *usbcdc_id, const struct pios_usb_cdc_cfg *cf
191191

192192
pios_usb_cdc_id = (uint32_t)usb_cdc_dev;
193193

194-
/* Tx is not active yet */
194+
/* Tx and Rx are not active yet */
195195
usb_cdc_dev->tx_active = false;
196196

197197
/* Clear stats */
@@ -607,6 +607,11 @@ static void PIOS_USB_CDC_DATA_IF_Init(uint32_t usb_cdc_id)
607607
PIOS_USB_CDC_DATA_EP_OUT_Callback,
608608
(uint32_t)usb_cdc_dev);
609609
usb_cdc_dev->usb_data_if_enabled = true;
610+
usb_cdc_dev->tx_active = false;
611+
/* Activate rx prophylactically */
612+
PIOS_USBHOOK_EndpointRx(usb_cdc_dev->cfg->data_rx_ep,
613+
usb_cdc_dev->rx_packet_buffer,
614+
sizeof(usb_cdc_dev->rx_packet_buffer));
610615
}
611616

612617
static void PIOS_USB_CDC_DATA_IF_DeInit(uint32_t usb_cdc_id)

flight/pios/stm32f4xx/pios_usbhook.c

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,9 @@ static USBD_DEVICE device_callbacks = {
280280
static void PIOS_USBHOOK_USR_Init(void)
281281
{
282282
PIOS_USB_ChangeConnectionState(false);
283-
reconnect();
283+
// reconnect dev logically on init (previously a call to reconnect())
284+
DCD_DevDisconnect(&pios_usb_otg_core_handle);
285+
DCD_DevConnect(&pios_usb_otg_core_handle);
284286
}
285287

286288
static void PIOS_USBHOOK_USR_DeviceReset(__attribute__((unused)) uint8_t speed)
@@ -491,9 +493,24 @@ static USBD_Class_cb_TypeDef class_callbacks = {
491493

492494
static void reconnect(void)
493495
{
494-
/* Force a physical disconnect/reconnect */
495-
DCD_DevDisconnect(&pios_usb_otg_core_handle);
496-
DCD_DevConnect(&pios_usb_otg_core_handle);
496+
static volatile bool in_reconnect = false;
497+
498+
/* Force a complete device reset. This can trigger a call to reconnect() so prevent recursion */
499+
if (!in_reconnect) {
500+
in_reconnect = true; // save since volatile and STM32F4 is single core
501+
// disable USB device
502+
DCD_DevDisconnect(&pios_usb_otg_core_handle);
503+
USBD_DeInit(&pios_usb_otg_core_handle);
504+
USB_OTG_StopDevice(&pios_usb_otg_core_handle);
505+
// enable USB device
506+
USBD_Init(&pios_usb_otg_core_handle,
507+
USB_OTG_FS_CORE_ID,
508+
&device_callbacks,
509+
&class_callbacks,
510+
&user_callbacks);
511+
512+
in_reconnect = false;
513+
}
497514
}
498515

499516
#endif /* PIOS_INCLUDE_USB */

flight/targets/boards/discoveryf4bare/bootloader/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ int main()
8282
// is 2.7 volts
8383
check_bor();
8484

85-
USB_connected = PIOS_USB_CheckAvailable(0);
85+
USB_connected = PIOS_USB_CableConnected(0);
8686

8787
if (PIOS_IAP_CheckRequest() == true) {
8888
PIOS_DELAY_WaitmS(1000);

flight/targets/boards/osd/bootloader/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ int main()
7676
PIOS_Board_Init();
7777
PIOS_IAP_Init();
7878

79-
USB_connected = PIOS_USB_CheckAvailable(0);
79+
USB_connected = PIOS_USB_CableConnected(0);
8080

8181
if (PIOS_IAP_CheckRequest() == true) {
8282
PIOS_DELAY_WaitmS(1000);

flight/targets/boards/revolution/bootloader/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ int main()
8282
// is 2.7 volts
8383
check_bor();
8484

85-
USB_connected = PIOS_USB_CheckAvailable(0);
85+
USB_connected = PIOS_USB_CableConnected(0);
8686

8787
if (PIOS_IAP_CheckRequest() == true) {
8888
PIOS_DELAY_WaitmS(1000);

flight/targets/boards/revonano/bootloader/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ int main()
8282
// is 2.7 volts
8383
check_bor();
8484

85-
USB_connected = PIOS_USB_CheckAvailable(0);
85+
USB_connected = PIOS_USB_CableConnected(0);
8686

8787
if (PIOS_IAP_CheckRequest() == true) {
8888
PIOS_DELAY_WaitmS(1000);

flight/targets/boards/revoproto/bootloader/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ int main()
8282
// is 2.7 volts
8383
check_bor();
8484

85-
USB_connected = PIOS_USB_CheckAvailable(0);
85+
USB_connected = PIOS_USB_CableConnected(0);
8686

8787
if (PIOS_IAP_CheckRequest() == true) {
8888
PIOS_DELAY_WaitmS(1000);

flight/targets/boards/sparky2/bootloader/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ int main()
8383
// is 2.7 volts
8484
check_bor();
8585

86-
USB_connected = PIOS_USB_CheckAvailable(0);
86+
USB_connected = PIOS_USB_CableConnected(0);
8787

8888
if (PIOS_IAP_CheckRequest() == true) {
8989
PIOS_DELAY_WaitmS(1000);

0 commit comments

Comments
 (0)