Use FreeRTOS stream buffers and task notifications
This commit is contained in:
committed by
Raphael Coeffic
parent
59f2b5e8b0
commit
73790c1654
+66
-15
@@ -27,6 +27,10 @@
|
||||
|
||||
#include "cli_traces.h"
|
||||
|
||||
#if defined(INTMODULE_USART)
|
||||
#include "intmodule_serial_driver.h"
|
||||
#endif
|
||||
|
||||
#define CLI_COMMAND_MAX_ARGS 8
|
||||
#define CLI_COMMAND_MAX_LEN 256
|
||||
|
||||
@@ -853,6 +857,20 @@ int cliSet(const char **argv)
|
||||
}
|
||||
|
||||
#if defined(ENABLE_SERIAL_PASSTHROUGH)
|
||||
static StreamBufferHandle_t spIntRxBuffer;
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
int cliSerialPassthrough(const char **argv)
|
||||
{
|
||||
const char* port_type = argv[1];
|
||||
@@ -902,36 +920,69 @@ int cliSerialPassthrough(const char **argv)
|
||||
#if defined(HARDWARE_INTERNAL_MODULE)
|
||||
if (port_n == INTERNAL_MODULE) {
|
||||
|
||||
// TODO: check the stack level so we don't crash it
|
||||
uint8_t* tmpBuf = (uint8_t*)malloc(256);
|
||||
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
|
||||
intmoduleSerialStart(baudrate, true, USART_Parity_No, USART_StopBits_1,
|
||||
USART_WordLength_8b);
|
||||
for (;;) {
|
||||
/* Block for max 10ms. */
|
||||
const TickType_t xTimeout = 10 / RTOS_MS_PER_TICK;
|
||||
size_t xReceivedBytes =
|
||||
xStreamBufferReceive(cliRxBuffer, tmpBuf, sizeof(tmpBuf), xTimeout);
|
||||
etx_serial_init params;
|
||||
params.baudrate = baudrate;
|
||||
params.rx_enable = true;
|
||||
params.on_receive = spRx;
|
||||
intmoduleSerialStart(¶ms);
|
||||
|
||||
// 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();
|
||||
|
||||
if (xReceivedBytes) {
|
||||
// TODO: wait for previous buffer flushed
|
||||
// Timeout ?
|
||||
if (notified == pdFALSE)
|
||||
continue;
|
||||
|
||||
// use 2nd half of 'tmpBuf'
|
||||
rx_bytes = xStreamBufferBytesAvailable(cliRxBuffer);
|
||||
if (rx_bytes) {
|
||||
// debug
|
||||
GPIO_SetBits(EXTMODULE_TX_GPIO, EXTMODULE_TX_GPIO_PIN);
|
||||
|
||||
// wait for end of last transmission
|
||||
intmoduleWaitForTxCompleted();
|
||||
intmoduleSendBuffer(tmpBuf, xReceivedBytes);
|
||||
|
||||
rx_bytes = xStreamBufferReceive(cliRxBuffer, tmpBuf2, tmpBufSize, 0);
|
||||
intmoduleSendBuffer(tmpBuf2, rx_bytes); // sends asynchronously
|
||||
|
||||
// debug
|
||||
GPIO_ResetBits(EXTMODULE_TX_GPIO, EXTMODULE_TX_GPIO_PIN);
|
||||
}
|
||||
|
||||
// Let's hope this does not starve the other side
|
||||
uint8_t inData;
|
||||
while(intmoduleFifo.pop(inData)) {
|
||||
serialPutc(inData);
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
intmoduleSerialStop();
|
||||
vStreamBufferDelete(spIntRxBuffer);
|
||||
free(tmpBuf);
|
||||
tmpBuf = nullptr;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,10 @@
|
||||
#include "libopenui/src/libopenui_file.h"
|
||||
#endif
|
||||
|
||||
#if defined(INTMODULE_USART)
|
||||
#include "intmodule_serial_driver.h"
|
||||
#endif
|
||||
|
||||
#define PRIM_REQ_POWERUP 0
|
||||
#define PRIM_REQ_VERSION 1
|
||||
#define PRIM_CMD_DOWNLOAD 3
|
||||
@@ -329,10 +333,16 @@ const char * FrskyDeviceFirmwareUpdate::doFlashFirmware(const char * filename, P
|
||||
if (module == INTERNAL_MODULE && information.productId == FIRMWARE_ID_MODULE_XJT) {
|
||||
INTERNAL_MODULE_ON();
|
||||
RTOS_WAIT_MS(1);
|
||||
intmoduleSerialStart(38400, true, USART_Parity_No, USART_StopBits_1, USART_WordLength_8b);
|
||||
|
||||
etx_serial_init params;
|
||||
params.baudrate = 38400;
|
||||
params.rx_enable = true;
|
||||
intmoduleSerialStart(¶ms);
|
||||
|
||||
GPIO_SetBits(INTMODULE_BOOTCMD_GPIO, INTMODULE_BOOTCMD_GPIO_PIN);
|
||||
result = uploadFileToHorusXJT(filename, &file, progressHandler);
|
||||
GPIO_ResetBits(INTMODULE_BOOTCMD_GPIO, INTMODULE_BOOTCMD_GPIO_PIN);
|
||||
|
||||
f_close(&file);
|
||||
return result;
|
||||
}
|
||||
@@ -340,9 +350,12 @@ const char * FrskyDeviceFirmwareUpdate::doFlashFirmware(const char * filename, P
|
||||
|
||||
switch (module) {
|
||||
#if defined(INTERNAL_MODULE_PXX2)
|
||||
case INTERNAL_MODULE:
|
||||
intmoduleSerialStart(57600, true, USART_Parity_No, USART_StopBits_1, USART_WordLength_8b);
|
||||
break;
|
||||
case INTERNAL_MODULE: {
|
||||
etx_serial_init params;
|
||||
params.baudrate = 57600;
|
||||
params.rx_enable = true;
|
||||
intmoduleSerialStart(¶ms);
|
||||
} break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
|
||||
@@ -37,6 +37,10 @@
|
||||
#include "io/multi_protolist.h"
|
||||
#endif
|
||||
|
||||
#if defined(INTMODULE_USART)
|
||||
#include "intmodule_serial_driver.h"
|
||||
#endif
|
||||
|
||||
#define UPDATE_MULTI_EXT_BIN ".bin"
|
||||
|
||||
class MultiFirmwareUpdateDriver
|
||||
@@ -77,7 +81,10 @@ class MultiInternalUpdateDriver: public MultiFirmwareUpdateDriver
|
||||
|
||||
void init(bool inverted) const override
|
||||
{
|
||||
intmoduleSerialStart(57600, true, USART_Parity_No, USART_StopBits_1, USART_WordLength_8b);
|
||||
etx_serial_init params;
|
||||
params.baudrate = 57600;
|
||||
params.rx_enable = true;
|
||||
intmoduleSerialStart(¶ms);
|
||||
}
|
||||
|
||||
bool getByte(uint8_t & byte) const override
|
||||
|
||||
+113
-15
@@ -27,6 +27,10 @@
|
||||
#include "pulses/pxx2.h"
|
||||
#include "pulses/flysky.h"
|
||||
|
||||
#if defined(INTMODULE_USART)
|
||||
#include "intmodule_serial_driver.h"
|
||||
#endif
|
||||
|
||||
uint8_t s_pulses_paused = 0;
|
||||
ModuleState moduleState[NUM_MODULES];
|
||||
InternalModulePulsesData intmodulePulsesData __DMA;
|
||||
@@ -470,6 +474,24 @@ bool setupPulsesExternalModule(uint8_t protocol)
|
||||
#endif
|
||||
|
||||
#if defined(HARDWARE_INTERNAL_MODULE)
|
||||
|
||||
#if defined(INTERNAL_MODULE_CRSF)
|
||||
static void intmoduleCRSF_rx(uint8_t data)
|
||||
{
|
||||
intmoduleFifo.push(data);
|
||||
|
||||
// wakeup mixer when rx buffer is quarter full (16 bytes)
|
||||
if (intmoduleFifo.size() >= 16) {
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
xTaskNotifyFromISR(mixerTaskId.rtos_handle, 0, eNoAction,
|
||||
&xHigherPriorityTaskWoken);
|
||||
|
||||
// might effect a context switch on ISR exit
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void enablePulsesInternalModule(uint8_t protocol)
|
||||
{
|
||||
// start new protocol hardware here
|
||||
@@ -496,8 +518,13 @@ static void enablePulsesInternalModule(uint8_t protocol)
|
||||
#endif
|
||||
|
||||
#if defined(PXX2)
|
||||
case PROTOCOL_CHANNELS_PXX2_HIGHSPEED:
|
||||
intmoduleSerialStart(PXX2_HIGHSPEED_BAUDRATE, true, USART_Parity_No, USART_StopBits_1, USART_WordLength_8b);
|
||||
case PROTOCOL_CHANNELS_PXX2_HIGHSPEED: {
|
||||
etx_serial_init params;
|
||||
params.baudrate = PXX2_HIGHSPEED_BAUDRATE;
|
||||
params.rx_enable = true;
|
||||
|
||||
intmoduleFifo.clear();
|
||||
intmoduleSerialStart(¶ms);
|
||||
resetAccessAuthenticationCount();
|
||||
|
||||
#if defined(INTMODULE_HEARTBEAT)
|
||||
@@ -505,30 +532,56 @@ static void enablePulsesInternalModule(uint8_t protocol)
|
||||
init_intmodule_heartbeat();
|
||||
#endif
|
||||
mixerSchedulerSetPeriod(INTERNAL_MODULE, PXX2_PERIOD);
|
||||
break;
|
||||
} break;
|
||||
#endif
|
||||
|
||||
#if defined(INTERNAL_MODULE_MULTI)
|
||||
case PROTOCOL_CHANNELS_MULTIMODULE:
|
||||
case PROTOCOL_CHANNELS_MULTIMODULE: {
|
||||
|
||||
// serial port setup
|
||||
etx_serial_init params;
|
||||
params.baudrate = MULTIMODULE_BAUDRATE;
|
||||
params.rx_enable = true;
|
||||
params.parity = USART_Parity_Even;
|
||||
params.stop_bits = USART_StopBits_2;
|
||||
params.word_length = USART_WordLength_9b;
|
||||
|
||||
intmodulePulsesData.multi.initFrame();
|
||||
intmoduleSerialStart(MULTIMODULE_BAUDRATE, true, USART_Parity_Even, USART_StopBits_2, USART_WordLength_9b);
|
||||
intmoduleFifo.clear();
|
||||
intmoduleSerialStart(¶ms);
|
||||
|
||||
// mixer setup
|
||||
mixerSchedulerSetPeriod(INTERNAL_MODULE, MULTIMODULE_PERIOD);
|
||||
|
||||
// reset status
|
||||
getMultiModuleStatus(INTERNAL_MODULE).failsafeChecked = false;
|
||||
getMultiModuleStatus(INTERNAL_MODULE).flags = 0;
|
||||
|
||||
#if defined(MULTI_PROTOLIST)
|
||||
TRACE("enablePulsesInternalModule(): trigger scan");
|
||||
MultiRfProtocols::instance(INTERNAL_MODULE)->triggerScan();
|
||||
TRACE("counter = %d", moduleState[INTERNAL_MODULE].counter);
|
||||
#endif
|
||||
break;
|
||||
} break;
|
||||
#endif
|
||||
|
||||
#if defined(INTERNAL_MODULE_CRSF)
|
||||
case PROTOCOL_CHANNELS_CROSSFIRE:
|
||||
intmoduleSerialStart(CROSSFIRE_BAUDRATE, true, USART_Parity_No,
|
||||
USART_StopBits_1, USART_WordLength_8b);
|
||||
case PROTOCOL_CHANNELS_CROSSFIRE: {
|
||||
|
||||
// serial port setup
|
||||
etx_serial_init params;
|
||||
params.baudrate = CROSSFIRE_BAUDRATE;
|
||||
params.rx_enable = true;
|
||||
|
||||
// wakeup mixer when rx buffer is quarter full (16 bytes)
|
||||
params.on_receive = intmoduleCRSF_rx;
|
||||
|
||||
intmoduleFifo.clear();
|
||||
intmoduleSerialStart(¶ms);
|
||||
|
||||
// mixer setup
|
||||
mixerSchedulerSetPeriod(INTERNAL_MODULE, CROSSFIRE_PERIOD);
|
||||
break;
|
||||
} break;
|
||||
#endif
|
||||
|
||||
#if defined(INTERNAL_MODULE_PPM)
|
||||
@@ -539,13 +592,20 @@ static void enablePulsesInternalModule(uint8_t protocol)
|
||||
#endif
|
||||
|
||||
#if defined(AFHDS2)
|
||||
case PROTOCOL_CHANNELS_AFHDS2A:
|
||||
case PROTOCOL_CHANNELS_AFHDS2A: {
|
||||
|
||||
// serial port setup
|
||||
etx_serial_init params;
|
||||
params.baudrate = INTMODULE_USART_AFHDS2_BAUDRATE;
|
||||
params.rx_enable = true;
|
||||
|
||||
resetPulsesAFHDS2();
|
||||
intmoduleSerialStart(INTMODULE_USART_AFHDS2_BAUDRATE, true,
|
||||
USART_Parity_No, USART_StopBits_1,
|
||||
USART_WordLength_8b);
|
||||
intmoduleFifo.clear();
|
||||
intmoduleSerialStart(¶ms);
|
||||
|
||||
// mixer setup
|
||||
mixerSchedulerSetPeriod(INTERNAL_MODULE, AFHDS2_PERIOD);
|
||||
break;
|
||||
} break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
@@ -637,6 +697,44 @@ void stopPulsesInternalModule()
|
||||
}
|
||||
}
|
||||
|
||||
void intmoduleSendNextFrame()
|
||||
{
|
||||
switch (moduleState[INTERNAL_MODULE].protocol) {
|
||||
#if defined(PXX2)
|
||||
case PROTOCOL_CHANNELS_PXX2_HIGHSPEED:
|
||||
intmoduleSendBuffer(intmodulePulsesData.pxx2.getData(), intmodulePulsesData.pxx2.getSize());
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(PXX1)
|
||||
case PROTOCOL_CHANNELS_PXX1_SERIAL:
|
||||
intmoduleSendBuffer(intmodulePulsesData.pxx_uart.getData(), intmodulePulsesData.pxx_uart.getSize());
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(INTERNAL_MODULE_MULTI)
|
||||
case PROTOCOL_CHANNELS_MULTIMODULE:
|
||||
intmoduleSendBuffer(intmodulePulsesData.multi.getData(), intmodulePulsesData.multi.getSize());
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(INTERNAL_MODULE_CRSF)
|
||||
case PROTOCOL_CHANNELS_CROSSFIRE:
|
||||
intmoduleSendBuffer(intmodulePulsesData.crossfire.pulses,
|
||||
intmodulePulsesData.crossfire.length);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(AFHDS2)
|
||||
case PROTOCOL_CHANNELS_AFHDS2A: {
|
||||
uint8_t* data = (uint8_t*)intmodulePulsesData.flysky.pulses;
|
||||
uint16_t size = intmodulePulsesData.flysky.ptr - data;
|
||||
intmoduleSendBuffer(data, size);
|
||||
} break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
bool setupPulsesInternalModule()
|
||||
{
|
||||
uint8_t protocol = getRequiredProtocol(INTERNAL_MODULE);
|
||||
|
||||
@@ -244,6 +244,7 @@ extern TrainerPulsesData trainerPulsesData;
|
||||
#if defined(HARDWARE_INTERNAL_MODULE)
|
||||
bool setupPulsesInternalModule();
|
||||
void stopPulsesInternalModule();
|
||||
void intmoduleSendNextFrame();
|
||||
#endif
|
||||
#if defined(HARDWARE_EXTERNAL_MODULE)
|
||||
bool setupPulsesExternalModule();
|
||||
|
||||
@@ -192,6 +192,8 @@ 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) {
|
||||
uint8_t txchar;
|
||||
@@ -212,11 +214,10 @@ extern "C" void AUX_SERIAL_USART_IRQHandler(void)
|
||||
uint8_t data = AUX_SERIAL_USART->DR;
|
||||
if (!(status & USART_FLAG_ERRORS)) {
|
||||
switch (auxSerialMode) {
|
||||
case UART_MODE_DEBUG: {
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
case UART_MODE_DEBUG:
|
||||
xStreamBufferSendFromISR(cliRxBuffer, &data, 1,
|
||||
&xHigherPriorityTaskWoken);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
status = AUX_SERIAL_USART->SR;
|
||||
@@ -237,6 +238,9 @@ 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
|
||||
|
||||
@@ -385,6 +389,8 @@ 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) {
|
||||
uint8_t txchar;
|
||||
@@ -405,11 +411,10 @@ extern "C" void AUX2_SERIAL_USART_IRQHandler(void)
|
||||
uint8_t data = AUX2_SERIAL_USART->DR;
|
||||
if (!(status & USART_FLAG_ERRORS)) {
|
||||
switch (aux2SerialMode) {
|
||||
case UART_MODE_DEBUG: {
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
case UART_MODE_DEBUG:
|
||||
xStreamBufferSendFromISR(cliRxBuffer, &data, 1,
|
||||
&xHigherPriorityTaskWoken);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
status = AUX2_SERIAL_USART->SR;
|
||||
@@ -431,5 +436,8 @@ extern "C" void AUX2_SERIAL_USART_IRQHandler(void)
|
||||
}
|
||||
status = AUX2_SERIAL_USART->SR;
|
||||
}
|
||||
|
||||
// might effect a context switch on ISR exit
|
||||
taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||
}
|
||||
#endif // AUX2_SERIAL
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
*/
|
||||
|
||||
#include "opentx.h"
|
||||
#include "intmodule_serial_driver.h"
|
||||
|
||||
ModuleFifo intmoduleFifo;
|
||||
#if !defined(INTMODULE_DMA_STREAM)
|
||||
@@ -27,6 +28,36 @@ uint8_t * intmoduleTxBufferData;
|
||||
volatile uint8_t intmoduleTxBufferRemaining;
|
||||
#endif
|
||||
|
||||
struct etx_serial_driver {
|
||||
void (*on_receive)(uint8_t data);
|
||||
void (*on_error)();
|
||||
};
|
||||
|
||||
static etx_serial_driver intmodule_driver = { nullptr, nullptr };
|
||||
|
||||
// TODO: move this somewhere else
|
||||
static void intmoduleFifoReceive(uint8_t data)
|
||||
{
|
||||
intmoduleFifo.push(data);
|
||||
}
|
||||
|
||||
static void intmoduleFifoError()
|
||||
{
|
||||
intmoduleFifo.errors++;
|
||||
}
|
||||
|
||||
etx_serial_init::etx_serial_init():
|
||||
baudrate(0),
|
||||
parity(USART_Parity_No),
|
||||
stop_bits(USART_StopBits_1),
|
||||
word_length(USART_WordLength_8b),
|
||||
rx_enable(false),
|
||||
// TODO: this should not be needed
|
||||
on_receive(intmoduleFifoReceive),
|
||||
on_error(intmoduleFifoError)
|
||||
{
|
||||
}
|
||||
|
||||
void intmoduleStop()
|
||||
{
|
||||
GPIO_ResetBits(INTMODULE_PWR_GPIO, INTMODULE_PWR_GPIO_PIN);
|
||||
@@ -46,27 +77,38 @@ void intmoduleStop()
|
||||
USART_DeInit(INTMODULE_USART);
|
||||
|
||||
GPIO_ResetBits(INTMODULE_GPIO, INTMODULE_TX_GPIO_PIN | INTMODULE_RX_GPIO_PIN);
|
||||
|
||||
// reset callbacks
|
||||
intmodule_driver.on_receive = nullptr;
|
||||
intmodule_driver.on_error = nullptr;
|
||||
}
|
||||
|
||||
void intmodulePxx1SerialStart()
|
||||
{
|
||||
intmoduleSerialStart(INTMODULE_PXX1_SERIAL_BAUDRATE, false, USART_Parity_No, USART_StopBits_1, USART_WordLength_8b);
|
||||
etx_serial_init params;
|
||||
params.baudrate = INTMODULE_PXX1_SERIAL_BAUDRATE;
|
||||
intmoduleSerialStart(¶ms);
|
||||
}
|
||||
|
||||
void intmoduleSerialStart(uint32_t baudrate, uint8_t rxEnable, uint16_t parity, uint16_t stopBits, uint16_t wordLength)
|
||||
void intmoduleSerialStart(const etx_serial_init* params)
|
||||
{
|
||||
if (!params) return;
|
||||
|
||||
INTERNAL_MODULE_ON();
|
||||
|
||||
// init callbacks
|
||||
intmodule_driver.on_receive = params->on_receive;
|
||||
intmodule_driver.on_error = params->on_error;
|
||||
|
||||
#if !defined(INTMODULE_DMA_STREAM)
|
||||
// IRQ based TX
|
||||
NVIC_InitTypeDef NVIC_InitStructure;
|
||||
#if defined(INTMODULE_DMA_STREAM)
|
||||
NVIC_InitStructure.NVIC_IRQChannel = INTMODULE_DMA_STREAM_IRQ;
|
||||
#else
|
||||
NVIC_InitStructure.NVIC_IRQChannel = INTMODULE_USART_IRQn;
|
||||
#endif
|
||||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
|
||||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; /* Not used as 4 bits are used for the pre-emption priority. */;
|
||||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
||||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||||
NVIC_Init(&NVIC_InitStructure);
|
||||
#endif
|
||||
|
||||
GPIO_PinAFConfig(INTMODULE_GPIO, INTMODULE_GPIO_PinSource_TX, INTMODULE_GPIO_AF);
|
||||
GPIO_PinAFConfig(INTMODULE_GPIO, INTMODULE_GPIO_PinSource_RX, INTMODULE_GPIO_AF);
|
||||
@@ -81,16 +123,17 @@ void intmoduleSerialStart(uint32_t baudrate, uint8_t rxEnable, uint16_t parity,
|
||||
|
||||
USART_DeInit(INTMODULE_USART);
|
||||
USART_InitTypeDef USART_InitStructure;
|
||||
USART_InitStructure.USART_BaudRate = baudrate;
|
||||
USART_InitStructure.USART_Parity = parity;
|
||||
USART_InitStructure.USART_StopBits = stopBits;
|
||||
USART_InitStructure.USART_WordLength = wordLength;
|
||||
USART_InitStructure.USART_BaudRate = params->baudrate;
|
||||
USART_InitStructure.USART_Parity = params->parity;
|
||||
USART_InitStructure.USART_StopBits = params->stop_bits;
|
||||
USART_InitStructure.USART_WordLength = params->word_length;
|
||||
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
|
||||
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
|
||||
USART_Init(INTMODULE_USART, &USART_InitStructure);
|
||||
USART_Cmd(INTMODULE_USART, ENABLE);
|
||||
|
||||
if (rxEnable) {
|
||||
if (params->rx_enable) {
|
||||
// TODO: move into the caller
|
||||
intmoduleFifo.clear();
|
||||
USART_ITConfig(INTMODULE_USART, USART_IT_RXNE, ENABLE);
|
||||
NVIC_SetPriority(INTMODULE_USART_IRQn, 6);
|
||||
@@ -120,10 +163,12 @@ extern "C" void INTMODULE_USART_IRQHandler(void)
|
||||
while (status & (USART_FLAG_RXNE | USART_FLAG_ERRORS)) {
|
||||
uint8_t data = INTMODULE_USART->DR;
|
||||
if (status & USART_FLAG_ERRORS) {
|
||||
intmoduleFifo.errors++;
|
||||
if (intmodule_driver.on_error)
|
||||
intmodule_driver.on_error();
|
||||
}
|
||||
else {
|
||||
intmoduleFifo.push(data);
|
||||
if (intmodule_driver.on_receive)
|
||||
intmodule_driver.on_receive(data);
|
||||
}
|
||||
status = INTMODULE_USART->SR;
|
||||
}
|
||||
@@ -168,44 +213,6 @@ void intmoduleSendBuffer(const uint8_t * data, uint8_t size)
|
||||
#endif
|
||||
}
|
||||
|
||||
void intmoduleSendNextFrame()
|
||||
{
|
||||
switch (moduleState[INTERNAL_MODULE].protocol) {
|
||||
#if defined(PXX2)
|
||||
case PROTOCOL_CHANNELS_PXX2_HIGHSPEED:
|
||||
intmoduleSendBuffer(intmodulePulsesData.pxx2.getData(), intmodulePulsesData.pxx2.getSize());
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(PXX1)
|
||||
case PROTOCOL_CHANNELS_PXX1_SERIAL:
|
||||
intmoduleSendBuffer(intmodulePulsesData.pxx_uart.getData(), intmodulePulsesData.pxx_uart.getSize());
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(INTERNAL_MODULE_MULTI)
|
||||
case PROTOCOL_CHANNELS_MULTIMODULE:
|
||||
intmoduleSendBuffer(intmodulePulsesData.multi.getData(), intmodulePulsesData.multi.getSize());
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(INTERNAL_MODULE_CRSF)
|
||||
case PROTOCOL_CHANNELS_CROSSFIRE:
|
||||
intmoduleSendBuffer(intmodulePulsesData.crossfire.pulses,
|
||||
intmodulePulsesData.crossfire.length);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(AFHDS2)
|
||||
case PROTOCOL_CHANNELS_AFHDS2A: {
|
||||
uint8_t* data = (uint8_t*)intmodulePulsesData.flysky.pulses;
|
||||
uint16_t size = intmodulePulsesData.flysky.ptr - data;
|
||||
intmoduleSendBuffer(data, size);
|
||||
} break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void intmoduleWaitForTxCompleted()
|
||||
{
|
||||
#if !defined(SIMU)
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct etx_serial_init {
|
||||
uint32_t baudrate;
|
||||
uint16_t parity;
|
||||
uint16_t stop_bits;
|
||||
uint16_t word_length;
|
||||
bool rx_enable;
|
||||
void (*on_receive)(uint8_t data);
|
||||
void (*on_error)();
|
||||
|
||||
etx_serial_init();
|
||||
};
|
||||
|
||||
void intmoduleSerialStart(const etx_serial_init* params);
|
||||
void intmoduleSerialStop();
|
||||
|
||||
void intmoduleSendByte(uint8_t byte);
|
||||
void intmoduleSendBuffer(const uint8_t* data, uint8_t size);
|
||||
void intmoduleWaitForTxCompleted();
|
||||
@@ -170,7 +170,9 @@ void usbSerialPutc(uint8_t c)
|
||||
if (txDataLen >= APP_RX_DATA_SIZE) {
|
||||
txDataLen -= APP_RX_DATA_SIZE;
|
||||
}
|
||||
if (txDataLen > (APP_RX_DATA_SIZE - CDC_DATA_MAX_PACKET_SIZE)) return; // buffer is too full, skip this write
|
||||
|
||||
// buffer is too full, skip this write
|
||||
if (txDataLen > (APP_RX_DATA_SIZE - CDC_DATA_MAX_PACKET_SIZE)) return;
|
||||
|
||||
++charsWritten;
|
||||
|
||||
@@ -215,13 +217,14 @@ 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
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
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
|
||||
@@ -240,6 +243,8 @@ 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -198,12 +198,6 @@ void SDRAM_Init();
|
||||
void init_intmodule_heartbeat();
|
||||
void check_intmodule_heartbeat();
|
||||
|
||||
void intmoduleSerialStart(uint32_t baudrate, uint8_t rxEnable, uint16_t parity, uint16_t stopBits, uint16_t wordLength);
|
||||
void intmoduleSendByte(uint8_t byte);
|
||||
void intmoduleSendBuffer(const uint8_t * data, uint8_t size);
|
||||
void intmoduleSendNextFrame();
|
||||
void intmoduleWaitForTxCompleted();
|
||||
|
||||
void extmoduleSerialStart();
|
||||
void extmoduleInvertedSerialStart(uint32_t baudrate);
|
||||
void extmoduleSendBuffer(const uint8_t * data, uint8_t size);
|
||||
|
||||
@@ -126,10 +126,6 @@ void EXTERNAL_MODULE_OFF();
|
||||
void init_intmodule_heartbeat();
|
||||
void check_intmodule_heartbeat();
|
||||
|
||||
void intmoduleSerialStart(uint32_t baudrate, uint8_t rxEnable, uint16_t parity, uint16_t stopBits, uint16_t wordLength);
|
||||
void intmoduleSendBuffer(const uint8_t * data, uint8_t size);
|
||||
void intmoduleSendNextFrame();
|
||||
|
||||
//void extmoduleSerialStart(uint32_t baudrate, uint32_t period_half_us, bool inverted);
|
||||
void extmoduleSerialStart();
|
||||
void extmoduleSendNextFrame();
|
||||
|
||||
@@ -136,14 +136,6 @@ uint32_t isBootloaderStart(const uint8_t * buffer);
|
||||
#define IS_INTERNAL_MODULE_ON() (GPIO_ReadInputDataBit(INTMODULE_PWR_GPIO, INTMODULE_PWR_GPIO_PIN) == Bit_SET)
|
||||
#endif
|
||||
|
||||
void intmoduleSerialStart(uint32_t baudrate, uint8_t rxEnable, uint16_t parity, uint16_t stopBits, uint16_t wordLength);
|
||||
#if defined(INTERNAL_MODULE_MULTI)
|
||||
void intmoduleTimerStart(uint32_t periodMs);
|
||||
#endif
|
||||
void intmoduleSendByte(uint8_t byte);
|
||||
void intmoduleSendBuffer(const uint8_t * data, uint8_t size);
|
||||
void intmoduleSendNextFrame();
|
||||
|
||||
void extmoduleSerialStart();
|
||||
void extmoduleInvertedSerialStart(uint32_t baudrate);
|
||||
void extmoduleSendBuffer(const uint8_t * data, uint8_t size);
|
||||
|
||||
Reference in New Issue
Block a user