From e8b7aacd99bc4b71a7df09f677cecb2f5aff95d2 Mon Sep 17 00:00:00 2001 From: Vladimir Zidar Date: Wed, 31 May 2017 15:21:49 +0200 Subject: [PATCH] LP-512 update F3 pios_usb.c and pios_usb_cdc.c to include bind_available_cb(). --- flight/pios/stm32f30x/pios_usb.c | 49 ++++++++++++++++++++++++++-- flight/pios/stm32f30x/pios_usb_cdc.c | 38 +++++++++++++++++++-- 2 files changed, 83 insertions(+), 4 deletions(-) diff --git a/flight/pios/stm32f30x/pios_usb.c b/flight/pios/stm32f30x/pios_usb.c index 63b5c5db2..f7a36e825 100644 --- a/flight/pios/stm32f30x/pios_usb.c +++ b/flight/pios/stm32f30x/pios_usb.c @@ -7,8 +7,9 @@ * @{ * * @file pios_usb.c - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. - * @author Tau Labs, http://taulabs.org, Copyright (C) 2012-2013 + * @author The LibrePilot Project, http://www.librepilot.org (C) 2017. + * Tau Labs, http://taulabs.org, Copyright (C) 2012-2013 + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @brief USB device functions (STM32 dependent code) * @see The GNU Public License (GPL) Version 3 * @@ -44,6 +45,13 @@ /* Rx/Tx status */ static bool transfer_possible = false; +#ifdef PIOS_INCLUDE_FREERTOS +struct { + void (*callback)(bool connected, uint32_t context); + uint32_t context; +} connectionState_cb_list[3]; +#endif + /* USB activity detection */ static volatile bool sof_seen_since_reset = false; @@ -55,6 +63,9 @@ struct pios_usb_dev { enum pios_usb_dev_magic magic; const struct pios_usb_cfg *cfg; }; +#ifdef PIOS_INCLUDE_FREERTOS +static void raiseConnectionStateCallback(bool connected); +#endif /** * @brief Validate the usb device structure @@ -195,6 +206,10 @@ int32_t PIOS_USB_ChangeConnectionState(bool Connected) #endif } +#ifdef PIOS_INCLUDE_FREERTOS + raiseConnectionStateCallback(Connected); +#endif + return 0; } @@ -282,6 +297,36 @@ void SUSP_Callback(void) sof_seen_since_reset = false; } +#ifdef PIOS_INCLUDE_FREERTOS +void PIOS_USB_RegisterConnectionStateCallback(void (*connectionStateCallback)(bool connected, uint32_t context), uint32_t context) +{ + PIOS_Assert(connectionStateCallback); + + for (uint32_t i = 0; i < NELEMENTS(connectionState_cb_list); i++) { + if (connectionState_cb_list[i].callback == NULL) { + connectionState_cb_list[i].callback = connectionStateCallback; + connectionState_cb_list[i].context = context; + return; + } + } + + PIOS_Assert(0); +} + +static void raiseConnectionStateCallback(bool connected) +{ + uint32_t i = 0; + + while (i < NELEMENTS(connectionState_cb_list) && connectionState_cb_list[i].callback != NULL) { + connectionState_cb_list[i].callback(connected, connectionState_cb_list[i].context); + i++; + } +} +#else /* PIOS_INCLUDE_FREERTOS */ +void PIOS_USB_RegisterConnectionStateCallback(__attribute__((unused)) void (*connectionStateCallback)(bool connected, uint32_t context), __attribute__((unused)) uint32_t context) +{} +#endif /* PIOS_INCLUDE_FREERTOS */ + #endif /* if defined(PIOS_INCLUDE_USB) */ /** diff --git a/flight/pios/stm32f30x/pios_usb_cdc.c b/flight/pios/stm32f30x/pios_usb_cdc.c index d96a67dc6..186fb95b4 100644 --- a/flight/pios/stm32f30x/pios_usb_cdc.c +++ b/flight/pios/stm32f30x/pios_usb_cdc.c @@ -43,6 +43,8 @@ static void PIOS_USB_CDC_RegisterTxCallback(uint32_t usbcdc_id, pios_com_callback tx_out_cb, uint32_t context); static void PIOS_USB_CDC_RegisterRxCallback(uint32_t usbcdc_id, pios_com_callback rx_in_cb, uint32_t context); static void PIOS_USB_CDC_RegisterBaudRateCallback(uint32_t usbcdc_id, pios_com_callback_baud_rate baud_rate_cb, uint32_t context); +static void PIOS_USB_CDC_RegisterAvailableCallback(uint32_t usbcdc_id, pios_com_callback_available baud_rate_cb, uint32_t context); +static void PIOS_USB_CDC_ChangeConnectionState(bool connected, uint32_t usbcdc_id); static void PIOS_USB_CDC_TxStart(uint32_t usbcdc_id, uint16_t tx_bytes_avail); static void PIOS_USB_CDC_RxStart(uint32_t usbcdc_id, uint16_t rx_bytes_avail); static uint32_t PIOS_USB_CDC_Available(uint32_t usbcdc_id); @@ -54,6 +56,7 @@ const struct pios_com_driver pios_usb_cdc_com_driver = { .bind_rx_cb = PIOS_USB_CDC_RegisterRxCallback, .bind_baud_rate_cb = PIOS_USB_CDC_RegisterBaudRateCallback, .available = PIOS_USB_CDC_Available, + .bind_available_cb = PIOS_USB_CDC_RegisterAvailableCallback, }; enum pios_usb_cdc_dev_magic { @@ -73,6 +76,8 @@ struct pios_usb_cdc_dev { pios_com_callback_baud_rate baud_rate_cb; uint32_t baud_rate_context; + pios_com_callback_available available_cb; + uint32_t available_context; uint8_t rx_packet_buffer[PIOS_USB_BOARD_CDC_DATA_LENGTH]; /* @@ -158,6 +163,8 @@ int32_t PIOS_USB_CDC_Init(uint32_t *usbcdc_id, const struct pios_usb_cdc_cfg *cf pEpInt_IN[cfg->data_tx_ep - 1] = PIOS_USB_CDC_DATA_EP_IN_Callback; pEpInt_OUT[cfg->data_rx_ep - 1] = PIOS_USB_CDC_DATA_EP_OUT_Callback; + PIOS_USB_RegisterConnectionStateCallback(PIOS_USB_CDC_ChangeConnectionState, (uint32_t)usb_cdc_dev); + *usbcdc_id = (uint32_t)usb_cdc_dev; return 0; @@ -367,8 +374,7 @@ static uint32_t PIOS_USB_CDC_Available(uint32_t usbcdc_id) PIOS_Assert(valid); - return (PIOS_USB_CheckAvailable(usb_cdc_dev->lower_id) && - (control_line_state & USB_CDC_CONTROL_LINE_STATE_DTE_PRESENT)) ? COM_AVAILABLE_RXTX : COM_AVAILABLE_NONE; + return PIOS_USB_CheckAvailable(usb_cdc_dev->lower_id) ? COM_AVAILABLE_RXTX : COM_AVAILABLE_NONE; } static struct usb_cdc_line_coding line_coding = { @@ -488,5 +494,33 @@ void PIOS_USB_CDC_SetLineCoding_Completed() } } +static void PIOS_USB_CDC_ChangeConnectionState(__attribute__((unused)) bool connected, uint32_t usbcdc_id) +{ + struct pios_usb_cdc_dev *usb_cdc_dev = (struct pios_usb_cdc_dev *)usbcdc_id; + + bool valid = PIOS_USB_CDC_validate(usb_cdc_dev); + + PIOS_Assert(valid); + + if (usb_cdc_dev->available_cb) { + (usb_cdc_dev->available_cb)(usb_cdc_dev->available_context, PIOS_USB_CDC_Available(usbcdc_id)); + } +} + +static void PIOS_USB_CDC_RegisterAvailableCallback(uint32_t usbcdc_id, pios_com_callback_available available_cb, uint32_t context) +{ + struct pios_usb_cdc_dev *usb_cdc_dev = (struct pios_usb_cdc_dev *)usbcdc_id; + + bool valid = PIOS_USB_CDC_validate(usb_cdc_dev); + + PIOS_Assert(valid); + + /* + * Order is important in these assignments since ISR uses _cb + * field to determine if it's ok to dereference _cb and _context + */ + usb_cdc_dev->available_context = context; + usb_cdc_dev->available_cb = available_cb; +} #endif /* PIOS_INCLUDE_USB_CDC */