From f3301e621067ca90a1692dd2ebf830967962d2a6 Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Wed, 17 Nov 2021 13:18:06 +0100 Subject: [PATCH] Added control line and bitrate callbacks And some additional clean-up --- radio/src/cli.cpp | 5 + radio/src/gui/128x64/view_statistics.cpp | 12 -- .../src/targets/common/arm/stm32/usb_driver.h | 24 ++- .../src/targets/common/arm/stm32/usbd_cdc.cpp | 142 +++++++++++------- .../Class/cdc/src/usbd_cdc_core.c | 2 +- 5 files changed, 108 insertions(+), 77 deletions(-) diff --git a/radio/src/cli.cpp b/radio/src/cli.cpp index 8c1b13865..7741ac56e 100644 --- a/radio/src/cli.cpp +++ b/radio/src/cli.cpp @@ -1586,6 +1586,11 @@ void cliStart() // Setup consumer callback cliReceiveCallBack = cliDefaultRx; + // Setup USB callbacks + usbSerialSetReceiveDataCb(cliReceiveData); + // usbSerialSetBaudRateCb(...); + // usbSerialSetCtrlLineStateCb(...); + RTOS_CREATE_TASK(cliTaskId, cliTask, "CLI", cliStack, CLI_STACK_SIZE, CLI_TASK_PRIO); } diff --git a/radio/src/gui/128x64/view_statistics.cpp b/radio/src/gui/128x64/view_statistics.cpp index d1099c29f..4384166b8 100644 --- a/radio/src/gui/128x64/view_statistics.cpp +++ b/radio/src/gui/128x64/view_statistics.cpp @@ -214,18 +214,6 @@ void menuStatisticsDebug(event_t event) y += FH; #endif -#if defined(STM32) && !defined(SIMU) && defined(DEBUG) - lcdDrawTextAlignedLeft(y, "Usb"); - lcdDrawNumber(MENU_DEBUG_COL1_OFS, y, charsWritten, LEFT); - lcdDrawText(lcdLastRightPos, y, " "); - lcdDrawNumber(lcdLastRightPos, y, APP_Rx_ptr_in, LEFT); - lcdDrawText(lcdLastRightPos, y, " "); - lcdDrawNumber(lcdLastRightPos, y, APP_Rx_ptr_out, LEFT); - lcdDrawText(lcdLastRightPos, y, " "); - lcdDrawNumber(lcdLastRightPos, y, usbWraps, LEFT); - y += FH; -#endif - #if defined(STM32) lcdDrawTextAlignedLeft(y, "Free Mem"); lcdDrawNumber(MENU_DEBUG_COL1_OFS, y, availableMemory(), LEFT); diff --git a/radio/src/targets/common/arm/stm32/usb_driver.h b/radio/src/targets/common/arm/stm32/usb_driver.h index 825f3757c..c6eb92206 100644 --- a/radio/src/targets/common/arm/stm32/usb_driver.h +++ b/radio/src/targets/common/arm/stm32/usb_driver.h @@ -19,10 +19,10 @@ * GNU General Public License for more details. */ -#ifndef OPENTX_USB_DRIVER_H -#define OPENTX_USB_DRIVER_H +#pragma once #include +#include // USB driver enum usbMode { @@ -37,22 +37,20 @@ enum usbMode { #endif }; -int usbPlugged(); +int usbPlugged(); void usbInit(); void usbStart(); void usbStop(); bool usbStarted(); -int getSelectedUsbMode(); + +int getSelectedUsbMode(); void setSelectedUsbMode(int mode); -void usbSerialPutc(uint8_t c); +uint32_t usbSerialFreeSpace(); +void usbSerialPutc(uint8_t c); -// Used in view_statistics.cpp -#if defined(DEBUG) && !defined(BOOT) - extern uint16_t usbWraps; - extern uint16_t charsWritten; - extern volatile uint32_t APP_Rx_ptr_in; - extern volatile uint32_t APP_Rx_ptr_out; -#endif +uint32_t usbSerialBaudRate(void); -#endif +void usbSerialSetReceiveDataCb(void (*cb)(uint8_t* buf, uint32_t len)); +void usbSerialSetCtrlLineStateCb(void (*cb)(uint16_t ctrlLineState)); +void usbSerialSetBaudRateCb(void (*cb)(uint32_t baud)); diff --git a/radio/src/targets/common/arm/stm32/usbd_cdc.cpp b/radio/src/targets/common/arm/stm32/usbd_cdc.cpp index 332600e5d..3879d74e7 100644 --- a/radio/src/targets/common/arm/stm32/usbd_cdc.cpp +++ b/radio/src/targets/common/arm/stm32/usbd_cdc.cpp @@ -23,7 +23,8 @@ #pragma data_alignment = 4 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -#include "opentx.h" +// include STM32 headers and generic board defs +#include "board_common.h" extern "C" { @@ -35,6 +36,18 @@ extern "C" { /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ +/* The following structures groups all needed parameters to be configured for the + ComPort. These parameters can modified on the fly by the host through CDC class + command class requests. */ +typedef struct __attribute__ ((packed)) +{ + uint32_t bitrate; + uint8_t format; + uint8_t paritytype; + uint8_t datatype; +} LINE_CODING; + +static LINE_CODING g_lc; /* These are external variables imported from CDC core to be used for IN transfer management. */ @@ -63,6 +76,10 @@ extern "C" const CDC_IF_Prop_TypeDef VCP_fops = } // extern "C" +static void (*receiveDataCb)(uint8_t* buf, uint32_t len); +static void (*ctrlLineStateCb)(uint16_t ctrlLineState); +static void (*baudRateCb)(uint32_t baud); + bool cdcConnected = false; /* Private functions ---------------------------------------------------------*/ @@ -75,6 +92,8 @@ bool cdcConnected = false; static uint16_t VCP_Init(void) { cdcConnected = true; + ctrlLineStateCb = NULL; + baudRateCb = NULL; return USBD_OK; } @@ -90,6 +109,13 @@ static uint16_t VCP_DeInit(void) return USBD_OK; } +void ust_cpy(LINE_CODING* plc2, const LINE_CODING* plc1) +{ + plc2->bitrate = plc1->bitrate; + plc2->format = plc1->format; + plc2->paritytype = plc1->paritytype; + plc2->datatype = plc1->datatype; +} /** * @brief VCP_Ctrl @@ -101,6 +127,10 @@ static uint16_t VCP_DeInit(void) */ static uint16_t VCP_Ctrl (uint32_t Cmd, uint8_t* Buf, uint32_t Len) { + LINE_CODING* plc = (LINE_CODING*)Buf; + + assert_param(Len>=sizeof(LINE_CODING)); + switch (Cmd) { case SEND_ENCAPSULATED_COMMAND: @@ -124,15 +154,29 @@ static uint16_t VCP_Ctrl (uint32_t Cmd, uint8_t* Buf, uint32_t Len) break; case SET_LINE_CODING: - /* Not needed for this driver */ + if (plc && (Len == sizeof (*plc))) { + // If a callback is provided, tell the upper driver of changes in baud rate + if (baudRateCb) { + baudRateCb(plc->bitrate); + } + // Copy into structure to save for later + ust_cpy(&g_lc, plc); + } break; case GET_LINE_CODING: - /* Not needed for this driver */ + if (plc && (Len == sizeof (*plc))) { + ust_cpy(plc, &g_lc); + } break; case SET_CONTROL_LINE_STATE: - /* Not needed for this driver */ + // If a callback is provided, tell the upper driver of changes in DTR/RTS state + if (plc && (Len == sizeof (uint16_t))) { + if (ctrlLineStateCb) { + ctrlLineStateCb(*((uint16_t *)Buf)); + } + } break; case SEND_BREAK: @@ -146,11 +190,6 @@ static uint16_t VCP_Ctrl (uint32_t Cmd, uint8_t* Buf, uint32_t Len) return USBD_OK; } -// some debug vars -uint16_t usbWraps = 0; -uint16_t charsWritten = 0; -uint16_t usbTxErrors = 0; - // return the bytes free in the circular buffer uint32_t usbSerialFreeSpace() { @@ -169,24 +208,15 @@ uint32_t usbSerialFreeSpace() void usbSerialPutc(uint8_t c) { /* - Apparently there is no reliable way to tell if the - virtual serial port is opened or not. + Apparently there is no reliable way to tell if the + virtual serial port is opened or not. - The cdcConnected variable only reports the state - of the physical USB connection. + The cdcConnected variable only reports the state + of the physical USB connection. */ if (!cdcConnected) return; - uint32_t prim = __get_PRIMASK(); - __disable_irq(); - uint32_t txDataLen = APP_RX_DATA_SIZE + APP_Rx_ptr_in - APP_Rx_ptr_out; - if (!prim) __enable_irq(); - - if (txDataLen >= APP_RX_DATA_SIZE) { - txDataLen -= APP_RX_DATA_SIZE; - } - /* APP_Rx_Buffer and associated variables must be modified atomically, because they are used from the interrupt @@ -194,14 +224,13 @@ void usbSerialPutc(uint8_t c) /* Read PRIMASK register, check interrupt status before you disable them */ /* Returns 0 if they are enabled, or non-zero if disabled */ - prim = __get_PRIMASK(); + + uint32_t prim = __get_PRIMASK(); __disable_irq(); - APP_Rx_Buffer[APP_Rx_ptr_in++] = c; - if(APP_Rx_ptr_in >= APP_RX_DATA_SIZE) - { - APP_Rx_ptr_in = 0; - ++usbWraps; - } + + APP_Rx_Buffer[APP_Rx_ptr_in] = c; + APP_Rx_ptr_in = (APP_Rx_ptr_in + 1) % APP_RX_DATA_SIZE; + if (!prim) __enable_irq(); } @@ -224,31 +253,42 @@ void usbSerialPutc(uint8_t c) */ static uint16_t VCP_DataRx (uint8_t* Buf, uint32_t Len) { - // TODO: try implementing inbound flow control: - // if the cliRxFifo does not have enough free space to receive all - // available characters, return VCP_FAIL. Maybe that will throttle down - // the sender and we will receive the same packet at a later time. - -#if defined(CLI) - - // pass data to CLI - cliReceiveData(Buf, Len); - -#elif defined(LUA) - // TODO: find a better implementation to allow - // run-time selection of the USB CDC receiver - // (here either CLI or LUA) + if (receiveDataCb) + receiveDataCb(Buf, Len); - // copy data to the LUA FIFO - if (luaRxFifo) { - for (uint32_t i = 0; i < Len; i++) { - luaRxFifo->push(Buf[i]); - } - } - -#endif +// #if defined(CLI) +// // pass data to CLI +// cliReceiveData(Buf, Len); +// #elif defined(LUA) +// // copy data to the LUA FIFO +// if (luaRxFifo) { +// for (uint32_t i = 0; i < Len; i++) { +// luaRxFifo->push(Buf[i]); +// } +// } +// #endif return USBD_OK; } +uint32_t usbSerialBaudRate(void) +{ + return g_lc.bitrate; +} + +void usbSerialSetReceiveDataCb(void (*cb)(uint8_t* buf, uint32_t len)) +{ + receiveDataCb = cb; +} + +void usbSerialSetBaudRateCb(void (*cb)(uint32_t baud)) +{ + baudRateCb = cb; +} + +void usbSerialSetCtrlLineStateCb(void (*cb)(uint16_t ctrlLineState)) +{ + ctrlLineStateCb = cb; +} + // /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/radio/src/thirdparty/STM32_USB-Host-Device_Lib_V2.2.0/Libraries/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c b/radio/src/thirdparty/STM32_USB-Host-Device_Lib_V2.2.0/Libraries/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c index 5df0ac77f..62ea64942 100644 --- a/radio/src/thirdparty/STM32_USB-Host-Device_Lib_V2.2.0/Libraries/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c +++ b/radio/src/thirdparty/STM32_USB-Host-Device_Lib_V2.2.0/Libraries/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c @@ -553,7 +553,7 @@ uint8_t usbd_cdc_Setup (void *pdev, else /* No Data request */ { /* Transfer the command to the interface layer */ - APP_FOPS.pIf_Ctrl(req->bRequest, NULL, 0); + APP_FOPS.pIf_Ctrl(req->bRequest, (uint8_t *)&req->wValue, sizeof(req->wValue)); } return USBD_OK;