diff --git a/radio/src/cli.cpp b/radio/src/cli.cpp index af8141ce2..54985b4df 100644 --- a/radio/src/cli.cpp +++ b/radio/src/cli.cpp @@ -25,7 +25,7 @@ #include #include -#include "cli_traces.h" +#include "cli.h" #if defined(INTMODULE_USART) #include "intmodule_serial_driver.h" @@ -34,13 +34,30 @@ #define CLI_COMMAND_MAX_ARGS 8 #define CLI_COMMAND_MAX_LEN 256 +// CLI receive buffer size +#define CLI_RX_BUFFER_SIZE 256 + RTOS_TASK_HANDLE cliTaskId; RTOS_DEFINE_STACK(cliStack, CLI_STACK_SIZE); static uint8_t cliRxBufferStorage[CLI_RX_BUFFER_SIZE]; static StaticStreamBuffer_t cliRxBufferStatic; -StreamBufferHandle_t cliRxBuffer; +// CLI receive stream buffer +static StreamBufferHandle_t cliRxBuffer; + +static void cliDefaultRx(uint8_t* buf, uint32_t len) +{ + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + + xStreamBufferSendFromISR(cliRxBuffer, buf, len, &xHigherPriorityTaskWoken); + xTaskNotifyFromISR(cliTaskId.rtos_handle, 0, eNoAction, + &xHigherPriorityTaskWoken); + + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); +} + +void (*cliReceiveCallBack)(uint8_t* buf, uint32_t len) = cliDefaultRx; uint8_t cliTracesEnabled = true; char cliLastLine[CLI_COMMAND_MAX_LEN+1]; @@ -857,18 +874,29 @@ int cliSet(const char **argv) } #if defined(ENABLE_SERIAL_PASSTHROUGH) -static StreamBufferHandle_t spIntRxBuffer; +// static StreamBufferHandle_t spIntRxBuffer; -static void spRx(uint8_t data) +// static void spRx(uint8_t data) +// { +// BaseType_t xHigherPriorityTaskWoken = pdFALSE; +// xStreamBufferSendFromISR(spIntRxBuffer, &data, 1, +// &xHigherPriorityTaskWoken); +// xTaskNotifyFromISR(cliTaskId.rtos_handle, 0, eNoAction, +// &xHigherPriorityTaskWoken); + +// // might effect a context switch on ISR exit +// portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); +// } + +static void spInternalModuleTx(uint8_t* buf, uint32_t len) { - BaseType_t xHigherPriorityTaskWoken = pdFALSE; - xStreamBufferSendFromISR(spIntRxBuffer, &data, 1, - &xHigherPriorityTaskWoken); - xTaskNotifyFromISR(cliTaskId.rtos_handle, 0, eNoAction, - &xHigherPriorityTaskWoken); + intmoduleSendBuffer(buf, len); + intmoduleWaitForTxCompleted(); +} - // might effect a context switch on ISR exit - portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); +static void spSerialTx(uint8_t data) +{ + serialPutc(data); } int cliSerialPassthrough(const char **argv) @@ -920,67 +948,27 @@ int cliSerialPassthrough(const char **argv) #if defined(HARDWARE_INTERNAL_MODULE) if (port_n == INTERNAL_MODULE) { - size_t rx_bytes = 0; - - // allocate quick & dirty a buffer on the heap - // to be able to send via DMA - constexpr size_t tmpBufSize = 128; - uint8_t* tmpBuf = (uint8_t*)malloc(tmpBufSize*2); - uint8_t* tmpBuf2 = tmpBuf + tmpBufSize; - - StaticStreamBuffer_t spIntRxBufferStatic; - // uses first half of 'tmpBuf' - spIntRxBuffer = xStreamBufferCreateStatic(tmpBufSize, 1, tmpBuf, &spIntRxBufferStatic); - // setup serial com // TODO: // - '8n1' param etx_serial_init params; params.baudrate = baudrate; params.rx_enable = true; - params.on_receive = spRx; + params.on_receive = spSerialTx; intmoduleSerialStart(¶ms); + cliReceiveCallBack = spInternalModuleTx; + // loop forever for (;;) { - /* Block for max 100ms. */ - const TickType_t xTimeout = 10 / RTOS_MS_PER_TICK; - BaseType_t notified = xTaskNotifyWait(0, 0, NULL, xTimeout); - // keep us up & running WDG_RESET(); - - // Timeout ? - if (notified == pdFALSE) - continue; - - // use 2nd half of 'tmpBuf' - rx_bytes = xStreamBufferBytesAvailable(cliRxBuffer); - if (rx_bytes) { - - // wait for end of last transmission - intmoduleWaitForTxCompleted(); - - rx_bytes = xStreamBufferReceive(cliRxBuffer, tmpBuf2, tmpBufSize, 0); - intmoduleSendBuffer(tmpBuf2, rx_bytes); // sends asynchronously - - } - - // Let's hope this does not starve the other side - uint8_t inData[tmpBufSize]; - rx_bytes = xStreamBufferReceive(spIntRxBuffer, inData, tmpBufSize, 0); - if (rx_bytes) { - for (uint8_t *tx_data = inData; rx_bytes > 0; tx_data++, rx_bytes--) { - serialPutc(*tx_data); // sends synchronously - } - } + RTOS_WAIT_MS(200); } intmoduleSerialStop(); - vStreamBufferDelete(spIntRxBuffer); - free(tmpBuf); - tmpBuf = nullptr; + // TODO: reset cli rx callback } #endif @@ -1585,6 +1573,13 @@ void cliTask(void * pdata) } } +// Called from receive ISR (either USB or UART) +void cliReceiveData(uint8_t* buf, uint32_t len) +{ + if (cliReceiveCallBack) + cliReceiveCallBack(buf, len); +} + void cliStart() { // Init stream buffer diff --git a/radio/src/cli.h b/radio/src/cli.h index 337be3f2b..73f71b1e4 100644 --- a/radio/src/cli.h +++ b/radio/src/cli.h @@ -27,16 +27,12 @@ #include #include -// CLI receive buffer size -#define CLI_RX_BUFFER_SIZE 256 - -// CLI receive stream buffer -extern StreamBufferHandle_t cliRxBuffer; - -// Allows for switchable debug prints via CLI -extern uint8_t cliTracesEnabled; +#include "cli_traces.h" // CLI task function void cliStart(); +// Called from receive ISR (either USB or UART) +void cliReceiveData(uint8_t* buf, uint32_t len); + #endif // _CLI_H_ diff --git a/radio/src/targets/common/arm/stm32/aux_serial_driver.cpp b/radio/src/targets/common/arm/stm32/aux_serial_driver.cpp index 5d3cd0060..d0c1673f7 100644 --- a/radio/src/targets/common/arm/stm32/aux_serial_driver.cpp +++ b/radio/src/targets/common/arm/stm32/aux_serial_driver.cpp @@ -22,10 +22,6 @@ #include "opentx.h" #include "targets/horus/board.h" -#if defined(AUX_SERIAL) || defined(AUX2_SERIAL) -#include -#endif - #if defined(AUX_SERIAL) uint8_t auxSerialMode = UART_MODE_COUNT; // Prevent debug output before port is setup Fifo auxSerialTxFifo; @@ -196,7 +192,6 @@ uint8_t auxSerialTracesEnabled() extern "C" void AUX_SERIAL_USART_IRQHandler(void) { DEBUG_INTERRUPT(INT_SER2); - BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Send if (USART_GetITStatus(AUX_SERIAL_USART, USART_IT_TXE) != RESET) { @@ -219,8 +214,7 @@ extern "C" void AUX_SERIAL_USART_IRQHandler(void) if (!(status & USART_FLAG_ERRORS)) { switch (auxSerialMode) { case UART_MODE_DEBUG: - xStreamBufferSendFromISR(cliRxBuffer, &data, 1, - &xHigherPriorityTaskWoken); + cliReceiveData(&data, 1); break; } } @@ -242,9 +236,6 @@ extern "C" void AUX_SERIAL_USART_IRQHandler(void) } status = AUX_SERIAL_USART->SR; } - - // might effect a context switch on ISR exit - portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); } #endif // AUX_SERIAL @@ -393,7 +384,6 @@ uint8_t aux2SerialTracesEnabled() extern "C" void AUX2_SERIAL_USART_IRQHandler(void) { DEBUG_INTERRUPT(INT_SER2); - BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Send if (USART_GetITStatus(AUX2_SERIAL_USART, USART_IT_TXE) != RESET) { @@ -416,8 +406,7 @@ extern "C" void AUX2_SERIAL_USART_IRQHandler(void) if (!(status & USART_FLAG_ERRORS)) { switch (aux2SerialMode) { case UART_MODE_DEBUG: - xStreamBufferSendFromISR(cliRxBuffer, &data, 1, - &xHigherPriorityTaskWoken); + cliReceiveData(&data, 1); break; } } @@ -440,8 +429,5 @@ extern "C" void AUX2_SERIAL_USART_IRQHandler(void) } status = AUX2_SERIAL_USART->SR; } - - // might effect a context switch on ISR exit - portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); } #endif // AUX2_SERIAL diff --git a/radio/src/targets/common/arm/stm32/usbd_cdc.cpp b/radio/src/targets/common/arm/stm32/usbd_cdc.cpp index 613f504e6..b8f48581a 100644 --- a/radio/src/targets/common/arm/stm32/usbd_cdc.cpp +++ b/radio/src/targets/common/arm/stm32/usbd_cdc.cpp @@ -149,6 +149,7 @@ static uint16_t VCP_Ctrl (uint32_t Cmd, uint8_t* Buf, uint32_t Len) // some debug vars uint16_t usbWraps = 0; uint16_t charsWritten = 0; +uint16_t usbTxErrors = 0; void usbSerialPutc(uint8_t c) { @@ -172,7 +173,10 @@ void usbSerialPutc(uint8_t c) } // buffer is too full, skip this write - if (txDataLen > (APP_RX_DATA_SIZE - CDC_DATA_MAX_PACKET_SIZE)) return; + if (txDataLen > (APP_RX_DATA_SIZE - CDC_DATA_MAX_PACKET_SIZE)) { + usbTxErrors++; + return; + } ++charsWritten; @@ -217,17 +221,11 @@ static uint16_t VCP_DataRx (uint8_t* Buf, uint32_t Len) // 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. - BaseType_t xHigherPriorityTaskWoken = pdFALSE; #if defined(CLI) - //copy data to the application FIFO - xStreamBufferSendFromISR(cliRxBuffer, Buf, Len, &xHigherPriorityTaskWoken); - xTaskNotifyFromISR(cliTaskId.rtos_handle, 0, eNoAction, - &xHigherPriorityTaskWoken); - // Please note that we don't try to yield to the task that has - // potentially been woken up, as this might effect a context switch - // in place, whereby the ISR is not done yet handling the USB request + // pass data to CLI + cliReceiveData(Buf, Len); #elif defined(LUA) // TODO: find a better implementation to allow @@ -243,8 +241,6 @@ static uint16_t VCP_DataRx (uint8_t* Buf, uint32_t Len) #endif - // might effect a context switch on ISR exit - portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); return USBD_OK; }