Added control line and bitrate callbacks

And some additional clean-up
This commit is contained in:
Raphael Coeffic
2021-11-21 11:18:35 +01:00
committed by Raphael Coeffic
parent 01059da849
commit f3301e6210
5 changed files with 108 additions and 77 deletions
+5
View File
@@ -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);
}
-12
View File
@@ -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);
+11 -13
View File
@@ -19,10 +19,10 @@
* GNU General Public License for more details.
*/
#ifndef OPENTX_USB_DRIVER_H
#define OPENTX_USB_DRIVER_H
#pragma once
#include <stdbool.h>
#include <stdint.h>
// 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));
+91 -51
View File
@@ -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****/
@@ -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;