feat(ACCESS): Configure AUX serial port as "External module" (#2562)

* Enable RX DMA on external module USART

* feat(ACCESS): configure AUX serial port as "External module" (#2562)

This allows configuring the external access mod on runtime rather than by compilation option.

* fix: fetch external module driver
This commit is contained in:
Raphael Coeffic
2022-12-14 18:41:32 +10:00
committed by GitHub
parent efe2ddd2b1
commit 06c359f096
22 changed files with 323 additions and 128 deletions
+1
View File
@@ -238,6 +238,7 @@ enum UartModes {
UART_MODE_GPS,
UART_MODE_DEBUG,
UART_MODE_SPACEMOUSE,
UART_MODE_EXT_MODULE,
UART_MODE_COUNT SKIP,
UART_MODE_MAX SKIP = UART_MODE_COUNT-1
};
+31 -3
View File
@@ -21,6 +21,10 @@
#include "opentx.h"
#if defined(PXX2)
#include "extmodule_serial_driver.h"
#endif
#if defined(PCBFRSKY) || defined(PCBFLYSKY)
uint8_t switchToMix(uint8_t source)
{
@@ -431,6 +435,15 @@ bool isSerialModeAvailable(uint8_t port_nr, int mode)
return false;
#endif
#if !defined(AUX_SERIAL_DMA_TX) || defined(EXTMODULE_USART)
if (mode == UART_MODE_EXT_MODULE)
return false;
#else // defined(AUX_SERIAL_DMA_TX) && !defined(EXTMODULE_USART)
// UART_MODE_EXT_MODULE is only supported on AUX1, as AUX2 has no TX DMA
if (mode == UART_MODE_EXT_MODULE && port_nr != SP_AUX1)
return false;
#endif
#if !defined(LUA)
if (mode == UART_MODE_LUA)
return false;
@@ -802,6 +815,7 @@ bool isInternalModuleAvailable(int moduleType)
}
#endif
#if defined(HARDWARE_EXTERNAL_MODULE)
bool isExternalModuleAvailable(int moduleType)
{
@@ -834,11 +848,17 @@ bool isExternalModuleAvailable(int moduleType)
return false; // doesn't exist for now
#if !defined(PXX2) || !defined(EXTMODULE_USART)
if (moduleType == MODULE_TYPE_XJT_LITE_PXX2 || moduleType == MODULE_TYPE_R9M_PXX2 || moduleType == MODULE_TYPE_R9M_LITE_PXX2 || moduleType == MODULE_TYPE_R9M_LITE_PRO_PXX2) {
if (moduleType == MODULE_TYPE_XJT_LITE_PXX2 ||
moduleType == MODULE_TYPE_R9M_PXX2 ||
moduleType == MODULE_TYPE_R9M_LITE_PXX2 ||
moduleType == MODULE_TYPE_R9M_LITE_PRO_PXX2) {
#if defined(PXX2)
return extmoduleGetSerialPort() != nullptr;
#else
return false;
}
#endif
}
#if !defined(CROSSFIRE)
if (moduleType == MODULE_TYPE_CROSSFIRE)
@@ -886,6 +906,14 @@ bool isExternalModuleAvailable(int moduleType)
return true;
}
#else // !defined(HARDWARE_EXTERNAL_MODULE)
bool isExternalModuleAvailable(int moduleType)
{
return false;
}
#endif
bool isRfProtocolAvailable(int protocol)
{
#if defined(CROSSFIRE)
+3 -1
View File
@@ -864,7 +864,9 @@ void applyModelConfig(uint8_t module)
static void* initExternal(uint8_t module)
{
#if defined(AFHDS3_EXT_UART)
const etx_serial_driver_t* drv = &ExtmoduleSerialDriver;
auto drv = extmoduleGetSerialPort();
if (!drv) return nullptr;
uint16_t period = AFHDS3_UART_COMMAND_TIMEOUT * 1000 /* us */;
#else
const etx_serial_driver_t* drv = nullptr;
+3 -1
View File
@@ -207,9 +207,11 @@ uint8_t getModuleType(uint8_t module)
}
#endif
#if defined(HARDWARE_EXTERNAL_MODULE)
if (module == EXTERNAL_MODULE && isExternalModuleAvailable(type)) {
return type;
}
#endif
return MODULE_TYPE_NONE;
}
@@ -579,7 +581,7 @@ void enablePulsesExternalModule(uint8_t protocol)
break;
#endif
#if defined(PXX2) && defined(EXTMODULE_USART)
#if defined(PXX2)
case PROTOCOL_CHANNELS_PXX2_HIGHSPEED:
externalModuleContext = Pxx2ExternalDriver.init(EXTERNAL_MODULE);
externalModuleDriver = &Pxx2ExternalDriver;
+12 -4
View File
@@ -295,7 +295,10 @@ static const etx_serial_init pxx1ExtSerialInit = {
static void* pxx1InitExternal(uint8_t module)
{
void* uart_ctx = ExtmoduleSerialDriver.init(&pxx1ExtSerialInit);
auto drv = extmoduleGetSerialPort();
if (!drv) return nullptr;
void* uart_ctx = drv->init(&pxx1ExtSerialInit);
mixerSchedulerSetPeriod(EXTERNAL_MODULE, EXTMODULE_PXX1_SERIAL_PERIOD);
EXTERNAL_MODULE_ON();
@@ -307,7 +310,9 @@ static void pxx1DeInitExternal(void* context)
{
EXTERNAL_MODULE_OFF();
mixerSchedulerSetPeriod(EXTERNAL_MODULE, 0);
ExtmoduleSerialDriver.deinit(context);
auto drv = extmoduleGetSerialPort();
if (drv) drv->deinit(context);
}
static void pxx1SetupPulsesExternal(void* context, int16_t* channels, uint8_t nChannels)
@@ -323,8 +328,11 @@ static void pxx1SetupPulsesExternal(void* context, int16_t* channels, uint8_t nC
static void pxx1SendPulsesExternal(void* context)
{
ExtmoduleSerialDriver.sendBuffer(context, extmodulePulsesData.pxx_uart.getData(),
extmodulePulsesData.pxx_uart.getSize());
auto drv = extmoduleGetSerialPort();
if (!drv) return;
drv->sendBuffer(context, extmodulePulsesData.pxx_uart.getData(),
extmodulePulsesData.pxx_uart.getSize());
}
const etx_module_driver_t Pxx1ExternalSerialDriver = {
+8 -8
View File
@@ -812,6 +812,7 @@ static void pxx2ProcessData(void* context, uint8_t data, uint8_t* buffer, uint8_
#include "hal/module_driver.h"
#include "extmodule_serial_driver.h"
const etx_module_driver_t Pxx2InternalDriver = {
.protocol = PROTOCOL_CHANNELS_PXX2_HIGHSPEED,
@@ -823,9 +824,6 @@ const etx_module_driver_t Pxx2InternalDriver = {
.processData = pxx2ProcessData,
};
#if defined(EXTMODULE_USART)
#include "extmodule_serial_driver.h"
static void* pxx2InitExternal(uint8_t module, uint32_t baudrate)
{
etx_serial_init params(pxx2SerialInitParams);
@@ -837,9 +835,10 @@ static void* pxx2InitExternal(uint8_t module, uint32_t baudrate)
telemetryProtocol = PROTOCOL_TELEMETRY_FRSKY_SPORT;
auto state = &pxx2State[module];
state->init(module, &extmodulePulsesData.pxx2, &ExtmoduleSerialDriver,
ExtmoduleSerialDriver.init(&params));
auto drv = extmoduleGetSerialPort();
if (!drv) return nullptr;
state->init(module, &extmodulePulsesData.pxx2, drv, drv->init(&params));
return state;
}
@@ -855,9 +854,11 @@ static void* pxx2InitExtHighSpeed(uint8_t module)
static void pxx2DeInitExternal(void* context)
{
auto state = (PXX2State*)context;
if (state) state->deinit();
EXTERNAL_MODULE_OFF();
mixerSchedulerSetPeriod(EXTERNAL_MODULE, 0);
ExtmoduleSerialDriver.deinit(context);
telemetryProtocol = 0xFF;
}
@@ -897,4 +898,3 @@ const etx_module_driver_t Pxx2LowSpeedExternalDriver = {
.getByte = pxx2GetByte,
.processData = pxx2ProcessData,
};
#endif
+24 -5
View File
@@ -41,6 +41,10 @@
#include "telemetry/crossfire.h"
#endif
#if defined(AUX_SERIAL_DMA_TX) && !defined(EXTMODULE_USART)
#include "extmodule_serial_driver.h"
#endif
#define PRINTF_BUFFER_SIZE 128
static void (*dbg_serial_putc)(void*, uint8_t) = nullptr;
@@ -212,11 +216,19 @@ static void serialSetCallBacks(int mode, void* ctx, const etx_serial_port_t* por
gpsSetSerialDriver(ctx, drv);
break;
#endif
#if defined(SPACEMOUSE)
case UART_MODE_SPACEMOUSE:
spacemouseSetSerialDriver(ctx, drv);
break;
#endif
#if defined(AUX_SERIAL_DMA_TX) && !defined(EXTMODULE_USART)
case UART_MODE_EXT_MODULE:
extmoduleSetSerialPort(drv);
break;
#endif
#endif
}
}
@@ -279,6 +291,12 @@ static void serialSetupPort(int mode, etx_serial_init& params)
params.rx_enable = true;
break;
#endif
#if defined(AUX_SERIAL_DMA_TX) && !defined(EXTMODULE_USART)
case UART_MODE_EXT_MODULE:
params.rx_enable = true;
break;
#endif
#endif
}
}
@@ -330,10 +348,10 @@ void serialInit(uint8_t port_nr, int mode)
if (state->port) {
auto drv = state->port->uart;
if (drv && drv->deinit) {
if (drv && drv->deinit && state->usart_ctx) {
drv->deinit(state->usart_ctx);
}
if (state->mode != 0) {
if (state->mode != UART_MODE_NONE) {
// Clear callbacks
serialSetCallBacks(state->mode, nullptr, nullptr);
}
@@ -356,11 +374,12 @@ void serialInit(uint8_t port_nr, int mode)
serialSetPowerState(port_nr);
#endif
if (params.baudrate != 0) {
state->mode = mode;
state->mode = mode;
if (mode != UART_MODE_NONE) {
state->port = port;
if (port) {
if (port && params.baudrate != 0) {
if (port->uart && port->uart->init)
state->usart_ctx = port->uart->init(&params);
}
-9
View File
@@ -114,15 +114,6 @@ void postModelLoad(bool alarms)
}
#endif
#if defined(HARDWARE_INTERNAL_MODULE)
if (!isInternalModuleAvailable(g_model.moduleData[INTERNAL_MODULE].type)) {
memclear(&g_model.moduleData[INTERNAL_MODULE], sizeof(ModuleData));
}
#endif
if (!isExternalModuleAvailable(g_model.moduleData[EXTERNAL_MODULE].type)) {
memclear(&g_model.moduleData[EXTERNAL_MODULE], sizeof(ModuleData));
}
#if defined(MULTIMODULE) && defined(MULTI_PROTOLIST)
MultiRfProtocols::removeInstance(EXTERNAL_MODULE);
#endif
@@ -1881,6 +1881,7 @@ static const struct YamlIdStr enum_UartModes[] = {
{ UART_MODE_GPS, "GPS" },
{ UART_MODE_DEBUG, "DEBUG" },
{ UART_MODE_SPACEMOUSE, "SPACEMOUSE" },
{ UART_MODE_EXT_MODULE, "EXT_MODULE" },
{ 0, NULL }
};
@@ -32,7 +32,7 @@
#define AUX_SERIAL_TX_BUFFER 512
#if defined(SDRAM)
#define AUX_SERIAL_RX_BUFFER 128
#define AUX_SERIAL_RX_BUFFER 512
#else
#define AUX_SERIAL_RX_BUFFER 32
#endif
@@ -53,8 +53,8 @@ static void* aux_serial_init(const SerialState* st, const etx_serial_init* param
stm32_usart_init(st->usart, params);
if (params->rx_enable && st->usart->rxDMA) {
st->rxFifo->clear();
stm32_usart_init_rx_dma(st->usart, st->rxFifo->buffer(), st->rxFifo->size());
st->rxFifo->clear();
}
return (void*)st;
@@ -62,17 +62,25 @@ static void* aux_serial_init(const SerialState* st, const etx_serial_init* param
static void aux_serial_putc(void* ctx, uint8_t c)
{
// When sending single bytes,
// send is based on IRQ, so that this
// only enables the corresponding IRQ
auto st = (const SerialState*)ctx;
if (st->txFifo->isFull()) return;
st->txFifo->push(c);
// Send is based on IRQ, so that this
// only enables the corresponding IRQ
stm32_usart_send_buffer(st->usart, &c, 1);
stm32_usart_enable_tx_irq(st->usart);
}
static void aux_serial_send_buffer(void* ctx, const uint8_t* data, uint8_t size)
{
auto st = (const SerialState*)ctx;
if (st->usart->txDMA) {
stm32_usart_send_buffer(st->usart, data, size);
return;
}
while(size > 0) {
aux_serial_putc(ctx, *data++);
size--;
@@ -112,15 +120,22 @@ static const LL_GPIO_InitTypeDef auxUSARTPinInit = {
.Alternate = AUX_SERIAL_GPIO_AF_LL,
};
#if !defined(AUX_SERIAL_DMA_TX)
#define AUX_SERIAL_DMA_TX nullptr
#define AUX_SERIAL_DMA_Stream_TX nullptr
#define AUX_SERIAL_DMA_Stream_TX_LL 0
#define AUX_SERIAL_DMA_Channel_TX 0
#endif
static const stm32_usart_t auxUSART = {
.USARTx = AUX_SERIAL_USART,
.GPIOx = AUX_SERIAL_GPIO,
.pinInit = &auxUSARTPinInit,
.IRQn = AUX_SERIAL_USART_IRQn,
.IRQ_Prio = 7, // TODO: define constant
.txDMA = nullptr,
.txDMA_Stream = 0,
.txDMA_Channel = 0,
.txDMA = AUX_SERIAL_DMA_TX,
.txDMA_Stream = AUX_SERIAL_DMA_Stream_TX_LL,
.txDMA_Channel = AUX_SERIAL_DMA_Channel_TX,
.rxDMA = AUX_SERIAL_DMA_RX,
.rxDMA_Stream = AUX_SERIAL_DMA_Stream_RX_LL,
.rxDMA_Channel = AUX_SERIAL_DMA_Channel_RX,
@@ -20,38 +20,60 @@
*/
#include "stm32_hal_ll.h"
#include "stm32_usart_driver.h"
#include "extmodule_serial_driver.h"
#include "board.h"
#if defined(EXTMODULE_USART)
#include "stm32_usart_driver.h"
#include "fifo.h"
typedef Fifo<uint8_t, INTMODULE_FIFO_SIZE> RxFifo;
static RxFifo extmoduleFifo;
struct RxFifo {
uint8_t* buf;
uint16_t size;
uint16_t widx;
uint16_t ridx;
};
struct ExtmoduleCtx
{
RxFifo* rxFifo;
struct ExtmoduleCtx {
RxFifo rxFifo;
const stm32_usart_t* usart;
};
static etx_serial_callbacks_t extmodule_driver = {
static etx_serial_callbacks_t extmodule_callbacks = {
nullptr, nullptr, nullptr
};
void extmoduleFifoReceive(uint8_t data)
static void _fifo_clear(const stm32_usart_t* usart, RxFifo& fifo)
{
extmoduleFifo.push(data);
if (usart->rxDMA) {
auto dma_len = LL_DMA_GetDataLength(usart->rxDMA, usart->rxDMA_Stream);
fifo.ridx = fifo.size - dma_len;
} else {
fifo.widx = fifo.ridx = 0;
}
}
static const etx_serial_init extmoduleSerialParams = {
.baudrate = 0,
.parity = ETX_Parity_None,
.stop_bits = ETX_StopBits_One,
.word_length = ETX_WordLength_8,
.rx_enable = true,
};
static int _fifo_get_byte(const stm32_usart_t* usart, RxFifo& fifo, uint8_t* data)
{
if (usart->rxDMA) {
auto DMAx = usart->rxDMA;
auto stream = usart->rxDMA_Stream;
// DMA stream enabled?
if (!LL_DMA_IsEnabledStream(DMAx, stream)) return 0;
// Anything to read?
auto dma_len = LL_DMA_GetDataLength(DMAx, stream);
if (fifo.size - dma_len == fifo.ridx) return 0;
} else {
if (fifo.ridx == fifo.widx) return 0;
}
*data = fifo.buf[fifo.ridx];
fifo.ridx = (fifo.ridx + 1) & (fifo.size - 1);
return 1;
}
static const LL_GPIO_InitTypeDef extmoduleUSART_PinDef = {
.Pin = EXTMODULE_TX_GPIO_PIN | EXTMODULE_RX_GPIO_PIN,
@@ -71,96 +93,118 @@ static const stm32_usart_t extmoduleUSART = {
.txDMA = EXTMODULE_USART_TX_DMA,
.txDMA_Stream = EXTMODULE_USART_TX_DMA_STREAM_LL,
.txDMA_Channel = EXTMODULE_USART_TX_DMA_CHANNEL,
.rxDMA = nullptr,
.rxDMA_Stream = 0,
.rxDMA_Channel = 0,
.rxDMA = EXTMODULE_USART_TX_DMA,
.rxDMA_Stream = EXTMODULE_USART_RX_DMA_STREAM_LL,
.rxDMA_Channel = EXTMODULE_USART_RX_DMA_CHANNEL,
};
static const ExtmoduleCtx extmoduleCtx = {
.rxFifo = &extmoduleFifo,
static uint8_t _rx_buffer[INTMODULE_FIFO_SIZE] __DMA;
static ExtmoduleCtx extmoduleCtx = {
.rxFifo = { _rx_buffer, sizeof(_rx_buffer), 0, 0 },
.usart = &extmoduleUSART,
};
static void* extmoduleSerialStart(const etx_serial_init* params)
static void* extmoduleSerialInit(const etx_serial_init* params)
{
if (!params) return nullptr;
extmodule_driver.on_receive = extmoduleFifoReceive;
extmodule_driver.on_error = nullptr;
extmodule_callbacks.on_receive = nullptr;
extmodule_callbacks.on_error = nullptr;
// UART config
stm32_usart_init(&extmoduleUSART, params);
extmoduleCtx.rxFifo->clear();
auto usart = extmoduleCtx.usart;
stm32_usart_init(usart, params);
auto& fifo = extmoduleCtx.rxFifo;
if (params->rx_enable && usart->rxDMA) {
stm32_usart_init_rx_dma(usart, fifo.buf, fifo.size);
}
_fifo_clear(usart, fifo);
return (void*)&extmoduleCtx;
}
void extmoduleInvertedSerialStart(uint32_t baudrate)
void extmoduleSerialStop(void* ctx)
{
EXTERNAL_MODULE_ON();
etx_serial_init params(extmoduleSerialParams);
params.baudrate = baudrate;
extmoduleSerialStart(&params);
}
void extmoduleSerialStop(void*)
{
stm32_usart_deinit(&extmoduleUSART);
auto modCtx = (ExtmoduleCtx*)ctx;
stm32_usart_deinit(modCtx->usart);
// reset callbacks
extmodule_driver.on_receive = nullptr;
extmodule_driver.on_error = nullptr;
extmodule_callbacks.on_receive = nullptr;
extmodule_callbacks.on_error = nullptr;
}
static void extmoduleSendByte(void* ctx, uint8_t byte)
static void extmoduleSerialSendByte(void* ctx, uint8_t byte)
{
auto modCtx = (ExtmoduleCtx*)ctx;
stm32_usart_send_byte(modCtx->usart, byte);
}
static void extmoduleSendBuffer(void* ctx, const uint8_t * data, uint8_t size)
static void extmoduleSerialSendBuffer(void* ctx, const uint8_t * data, uint8_t size)
{
auto modCtx = (ExtmoduleCtx*)ctx;
if (size == 0) return;
stm32_usart_send_buffer(modCtx->usart, data, size);
}
static void extmoduleWaitForTxCompleted(void* ctx)
static void extmoduleSerialWaitForTxCompleted(void* ctx)
{
auto modCtx = (ExtmoduleCtx*)ctx;
stm32_usart_wait_for_tx_dma(modCtx->usart);
}
static int extmoduleGetByte(void* ctx, uint8_t* data)
static int extmoduleSerialGetByte(void* ctx, uint8_t* data)
{
auto modCtx = (ExtmoduleCtx*)ctx;
if (!modCtx->rxFifo) return -1;
return modCtx->rxFifo->pop(*data);
return _fifo_get_byte(modCtx->usart, modCtx->rxFifo, data);
}
static void extmoduleClearRxBuffer(void* ctx)
static void extmoduleSerialClearRxBuffer(void* ctx)
{
auto modCtx = (ExtmoduleCtx*)ctx;
if (!modCtx->rxFifo) return;
modCtx->rxFifo->clear();
_fifo_clear(modCtx->usart, modCtx->rxFifo);
}
const etx_serial_driver_t ExtmoduleSerialDriver = {
.init = extmoduleSerialStart,
static const etx_serial_driver_t extmoduleSerialDriver = {
.init = extmoduleSerialInit,
.deinit = extmoduleSerialStop,
.sendByte = extmoduleSendByte,
.sendBuffer = extmoduleSendBuffer,
.waitForTxCompleted = extmoduleWaitForTxCompleted,
.getByte = extmoduleGetByte,
.clearRxBuffer = extmoduleClearRxBuffer,
.sendByte = extmoduleSerialSendByte,
.sendBuffer = extmoduleSerialSendBuffer,
.waitForTxCompleted = extmoduleSerialWaitForTxCompleted,
.getByte = extmoduleSerialGetByte,
.clearRxBuffer = extmoduleSerialClearRxBuffer,
.getBaudrate = nullptr,
.setReceiveCb = nullptr,
.setBaudrateCb = nullptr,
};
constexpr const etx_serial_driver_t* _default_driver = &extmoduleSerialDriver;
// IRQ based RX/TX: probably obsolete now
extern "C" void EXTMODULE_USART_IRQHandler(void)
{
stm32_usart_isr(&extmoduleUSART, &extmodule_driver);
stm32_usart_isr(extmoduleCtx.usart, &extmodule_callbacks);
}
#else
constexpr const etx_serial_driver_t* _default_driver = nullptr;
#endif // defined(EXTMODULE_USART)
const etx_serial_driver_t* _extmodule_driver = _default_driver;
void extmoduleSetSerialPort(const etx_serial_driver_t* drv)
{
if (drv) {
_extmodule_driver = drv;
} else {
_extmodule_driver = _default_driver;
}
}
const etx_serial_driver_t* extmoduleGetSerialPort()
{
return _extmodule_driver;
}
@@ -26,8 +26,8 @@
#define EXTMODULE_USART_IRQ_PRIORITY 6
// Callbacks using intmoduleFifo
void extmoduleFifoReceive(uint8_t data);
void extmoduleFifoError();
// Use an alternative USART as external module
void extmoduleSetSerialPort(const etx_serial_driver_t* port);
extern const etx_serial_driver_t ExtmoduleSerialDriver;
// Return the serial driver to be used as external module
const etx_serial_driver_t* extmoduleGetSerialPort();
@@ -19,9 +19,52 @@
* GNU General Public License for more details.
*/
#include "stm32_hal_ll.h"
#include "stm32_usart_driver.h"
#include <string.h>
// WARNING:
//
// NVIC_GetEnableIRQ is stolen from "${THIRDPARTY_DIR}/CMSIS/Include/core_cm4.h".
//
// Until we can include the new CMSIS everywhere, this
// needs to be defined here, as the old CMSIS does not define it.
//
// The new CMSIS can be used when StdPeriph is gone, as it mandates
// the old version located in "${STM32LIB_DIR}/CMSIS/Include"
//
static inline uint32_t NVIC_GetEnableIRQ(IRQn_Type IRQn)
{
if ((int32_t)(IRQn) >= 0) {
return ((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] &
(1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL)
? 1UL
: 0UL));
} else {
return (0U);
}
}
static void _enable_usart_irq(const stm32_usart_t* usart)
{
NVIC_SetPriority(usart->IRQn, usart->IRQ_Prio);
NVIC_EnableIRQ(usart->IRQn);
}
void stm32_usart_enable_tx_irq(const stm32_usart_t* usart)
{
if (LL_USART_IsEnabledDMAReq_TX(usart->USARTx)) {
stm32_usart_wait_for_tx_dma(usart);
LL_USART_DisableDMAReq_TX(usart->USARTx);
}
if (!NVIC_GetEnableIRQ(usart->IRQn)) {
_enable_usart_irq(usart);
}
LL_USART_EnableIT_TXE(usart->USARTx);
}
static void enable_usart_clock(USART_TypeDef* USARTx)
{
if (USARTx == USART1) {
@@ -60,6 +103,7 @@ static void disable_usart_clock(USART_TypeDef* USARTx)
LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_UART7);
}
#endif
}
void stm32_usart_init_rx_dma(const stm32_usart_t* usart, void* buffer, uint32_t length)
@@ -103,9 +147,7 @@ void stm32_usart_deinit_rx_dma(const stm32_usart_t* usart)
// Enable IRQ based RX
LL_USART_EnableIT_RXNE(usart->USARTx);
NVIC_SetPriority(usart->IRQn, usart->IRQ_Prio);
NVIC_EnableIRQ(usart->IRQn);
_enable_usart_irq(usart);
}
}
@@ -172,8 +214,7 @@ void stm32_usart_init(const stm32_usart_t* usart, const etx_serial_init* params)
}
if (!usart->txDMA || (params->rx_enable && !usart->rxDMA)) {
NVIC_SetPriority(usart->IRQn, usart->IRQ_Prio);
NVIC_EnableIRQ(usart->IRQn);
_enable_usart_irq(usart);
}
}
@@ -49,6 +49,7 @@ struct stm32_usart_t {
void stm32_usart_init(const stm32_usart_t* usart, const etx_serial_init* params);
void stm32_usart_init_rx_dma(const stm32_usart_t* usart, void* buffer, uint32_t length);
void stm32_usart_enable_tx_irq(const stm32_usart_t* usart);
void stm32_usart_deinit(const stm32_usart_t* usart);
void stm32_usart_deinit_rx_dma(const stm32_usart_t* usart);
void stm32_usart_send_byte(const stm32_usart_t* usart, uint8_t byte);
@@ -358,23 +358,26 @@ static void* sbus_trainer_ctx = nullptr;
void init_trainer_module_sbus()
{
sbus_trainer_ctx = ExtmoduleSerialDriver.init(&sbusTrainerParams);
auto serial_driver = extmoduleGetSerialPort();
sbus_trainer_ctx = serial_driver->init(&sbusTrainerParams);
}
void stop_trainer_module_sbus()
{
auto serial_driver = extmoduleGetSerialPort();
auto ctx = sbus_trainer_ctx;
if (ctx) {
sbus_trainer_ctx = nullptr;
ExtmoduleSerialDriver.deinit(ctx);
serial_driver->deinit(ctx);
}
}
int trainerModuleSbusGetByte(uint8_t* data)
{
auto serial_driver = extmoduleGetSerialPort();
auto ctx = sbus_trainer_ctx;
if (ctx) {
return ExtmoduleSerialDriver.getByte(ctx, data);
return serial_driver->getByte(ctx, data);
}
return 0;
+6 -2
View File
@@ -434,10 +434,14 @@
#define AUX_SERIAL_USART USART3
#define AUX_SERIAL_USART_IRQHandler USART3_IRQHandler
#define AUX_SERIAL_USART_IRQn USART3_IRQn
#define AUX_SERIAL_DMA_TX DMA1
#define AUX_SERIAL_DMA_Stream_TX DMA1_Stream3
#define AUX_SERIAL_DMA_Stream_TX_LL LL_DMA_STREAM_3
#define AUX_SERIAL_DMA_Channel_TX LL_DMA_CHANNEL_4
#define AUX_SERIAL_DMA_RX DMA1
#define AUX_SERIAL_DMA_Stream_RX DMA1_Stream1
#define AUX_SERIAL_DMA_Stream_RX_LL LL_DMA_STREAM_1
#define AUX_SERIAL_DMA_Channel_RX DMA_Channel_4
#define AUX_SERIAL_DMA_Channel_RX LL_DMA_CHANNEL_4
#if defined(RADIO_TX16S)
#define AUX_SERIAL_PWR_GPIO GPIOA
#define AUX_SERIAL_PWR_GPIO_PIN GPIO_Pin_15 // PA.15
@@ -876,9 +880,9 @@
#define EXTMODULE_USART_TX_DMA_CHANNEL LL_DMA_CHANNEL_4
#define EXTMODULE_USART_TX_DMA_STREAM DMA1_Stream3
#define EXTMODULE_USART_TX_DMA_STREAM_LL LL_DMA_STREAM_3
#define EXTMODULE_USART_TX_DMA_FLAG_TC DMA_FLAG_TCIF3
#define EXTMODULE_USART_RX_DMA_CHANNEL LL_DMA_CHANNEL_4
#define EXTMODULE_USART_RX_DMA_STREAM DMA1_Stream1
#define EXTMODULE_USART_RX_DMA_STREAM_LL LL_DMA_STREAM_1
#elif defined(PCBX10) || PCBREV >= 13
#define EXTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_DMA2)
#define EXTMODULE_TX_GPIO GPIOA
+1 -8
View File
@@ -462,20 +462,14 @@
#define EXTMODULE_USART_TX_DMA_CHANNEL LL_DMA_CHANNEL_5
#define EXTMODULE_USART_TX_DMA_STREAM DMA2_Stream7
#define EXTMODULE_USART_TX_DMA_STREAM_LL LL_DMA_STREAM_7
#define EXTMODULE_USART_TX_DMA_IRQn DMA2_Stream7_IRQn
#define EXTMODULE_USART_TX_DMA_IRQHandler DMA2_Stream7_IRQHandler
#define EXTMODULE_USART_TX_DMA_FLAG_TC DMA_IT_TCIF7
#define EXTMODULE_USART_RX_DMA_CHANNEL LL_DMA_CHANNEL_5
#define EXTMODULE_USART_RX_DMA_STREAM DMA2_Stream2
#define EXTMODULE_USART_RX_DMA_IRQn DMA2_Stream2_IRQn
#define EXTMODULE_USART_RX_DMA_IRQHandler DMA2_Stream2_IRQHandler
#define EXTMODULE_USART_RX_DMA_FLAG_TC DMA_IT_TCIF2
#define EXTMODULE_USART_RX_DMA_STREAM_LL LL_DMA_STREAM_2
#define EXTMODULE_USART_IRQHandler USART6_IRQHandler
#define EXTMODULE_USART_IRQn USART6_IRQn
#define EXTMODULE_TIMER_DMA_SIZE (DMA_SxCR_PSIZE_0 | DMA_SxCR_MSIZE_0)
//TIMER
#define EXTMODULE_TIMER_DMA_CHANNEL LL_DMA_CHANNEL_7
#define EXTMODULE_TIMER_DMA_STREAM DMA2_Stream1
@@ -483,7 +477,6 @@
#define EXTMODULE_TIMER_DMA_STREAM_LL LL_DMA_STREAM_1
#define EXTMODULE_TIMER_DMA_STREAM_IRQn DMA2_Stream1_IRQn
#define EXTMODULE_TIMER_DMA_IRQHandler DMA2_Stream1_IRQHandler
#define EXTMODULE_TIMER_DMA_FLAG_TC DMA_IT_TCIF1
#define EXTMODULE_TX_INVERT_GPIO GPIOE
#define EXTMODULE_TX_INVERT_GPIO_PIN GPIO_Pin_3 // PE.03
+20 -1
View File
@@ -80,7 +80,8 @@ const etx_serial_driver_t IntmoduleSerialDriver = {
.setBaudrateCb = nullptr,
};
const etx_serial_driver_t ExtmoduleSerialDriver = {
#if defined(EXTMODULE_USART)
static const etx_serial_driver_t _extmoduleSerialDriver = {
.init = init,
.deinit = deinit,
.sendByte = sendByte,
@@ -92,3 +93,21 @@ const etx_serial_driver_t ExtmoduleSerialDriver = {
.setReceiveCb = nullptr,
.setBaudrateCb = nullptr,
};
constexpr const etx_serial_driver_t* _ext_default_drv = &_extmoduleSerialDriver;
#else
constexpr const etx_serial_driver_t* _ext_default_drv = nullptr;
#endif
const etx_serial_driver_t* _ext_drv = _ext_default_drv;
void extmoduleSetSerialPort(const etx_serial_driver_t* drv)
{
if (drv) _ext_drv = drv;
else _ext_drv = _ext_default_drv;
}
const etx_serial_driver_t* extmoduleGetSerialPort()
{
return _ext_drv;
}
+22 -2
View File
@@ -743,6 +743,26 @@ void rtcSetTime(const struct gtm * t)
const etx_serial_port_t UsbSerialPort = { "USB-VCP", nullptr, nullptr };
#endif
#if defined(AUX_SERIAL) || defined(AUX2_SERIAL)
static void* _fake_drv_init(const etx_serial_init*) { return nullptr; }
static void _fake_drv_fct1(void*) {}
static void _fake_drv_send_byte(void*, uint8_t) {}
static void _fake_drv_send_buffer(void*, const uint8_t*, uint8_t) {}
static int _fake_drv_get_byte(void*, uint8_t*) { return 0; }
static const etx_serial_driver_t _fake_drv = {
.init = _fake_drv_init,
.deinit = _fake_drv_fct1,
.sendByte = _fake_drv_send_byte,
.sendBuffer = _fake_drv_send_buffer,
.waitForTxCompleted = _fake_drv_fct1,
.getByte = _fake_drv_get_byte,
.clearRxBuffer = nullptr,
.getBaudrate = nullptr,
.setReceiveCb = nullptr,
.setBaudrateCb = nullptr,
};
#endif
#if defined(AUX_SERIAL)
#if defined(AUX_SERIAL_PWR_GPIO)
static void _fake_pwr_aux(uint8_t) {}
@@ -750,7 +770,7 @@ const etx_serial_port_t UsbSerialPort = { "USB-VCP", nullptr, nullptr };
#else
#define AUX_SERIAL_PWR nullptr
#endif
const etx_serial_port_t auxSerialPort = { "AUX1", nullptr, AUX_SERIAL_PWR };
static const etx_serial_port_t auxSerialPort = {"AUX1", &_fake_drv, AUX_SERIAL_PWR};
#define AUX_SERIAL_PORT &auxSerialPort
#else
#define AUX_SERIAL_PORT nullptr
@@ -763,7 +783,7 @@ const etx_serial_port_t auxSerialPort = { "AUX1", nullptr, AUX_SERIAL_PWR };
#else
#define AUX2_SERIAL_PWR nullptr
#endif
const etx_serial_port_t aux2SerialPort = { "AUX2", nullptr, AUX2_SERIAL_PWR };
static const etx_serial_port_t aux2SerialPort = {"AUX2", &_fake_drv, AUX2_SERIAL_PWR};
#define AUX2_SERIAL_PORT &aux2SerialPort
#else
#define AUX2_SERIAL_PORT nullptr
+3 -3
View File
@@ -1783,12 +1783,12 @@
#define EXTMODULE_USART_IRQn USART6_IRQn
#define EXTMODULE_USART_IRQHandler USART6_IRQHandler
#define EXTMODULE_USART_TX_DMA DMA2
#define EXTMODULE_USART_TX_DMA_CHANNEL DMA_Channel_5
#define EXTMODULE_USART_TX_DMA_CHANNEL LL_DMA_CHANNEL_5
#define EXTMODULE_USART_TX_DMA_STREAM DMA2_Stream6
#define EXTMODULE_USART_TX_DMA_STREAM_LL LL_DMA_STREAM_6
#define EXTMODULE_USART_TX_DMA_FLAG_TC DMA_FLAG_TCIF6
#define EXTMODULE_USART_RX_DMA_CHANNEL DMA_Channel_5
#define EXTMODULE_USART_RX_DMA_CHANNEL LL_DMA_CHANNEL_5
#define EXTMODULE_USART_RX_DMA_STREAM DMA2_Stream1
#define EXTMODULE_USART_RX_DMA_STREAM_LL LL_DMA_STREAM_1
#else
#define EXTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_DMA2)
#if defined(RADIO_COMMANDO8)
+7 -4
View File
@@ -95,12 +95,15 @@ TEST(Conversions, ConversionX9DPFrom23)
EXPECT_STRNEQ("Tes", g_model.gvars[0].name); // ZSTREQ
EXPECT_STRNEQ("Test", g_model.flightModeData[0].name); // ZSTREQ
#if defined(INTERNAL_MODULE_PXX2)
// Please note: we don't wipe the model's module settings
// in case the module is not supported anymore.
//
// #if defined(INTERNAL_MODULE_PXX2)
EXPECT_EQ(MODULE_TYPE_ISRM_PXX2, g_model.moduleData[INTERNAL_MODULE].type);
EXPECT_EQ(MODULE_SUBTYPE_ISRM_PXX2_ACCST_D16, g_model.moduleData[INTERNAL_MODULE].subType);
#else
EXPECT_EQ(MODULE_TYPE_NONE, g_model.moduleData[INTERNAL_MODULE].type);
#endif
// #else
// EXPECT_EQ(MODULE_TYPE_NONE, g_model.moduleData[INTERNAL_MODULE].type);
// #endif
EXPECT_EQ(MODULE_TYPE_R9M_PXX1, g_model.moduleData[EXTERNAL_MODULE].type);
EXPECT_EQ(MODULE_SUBTYPE_R9M_FCC, g_model.moduleData[EXTERNAL_MODULE].subType);
+1 -1
View File
@@ -37,7 +37,7 @@
#define TR_TRNMODE "OFF","+=",":="
#define TR_TRNCHN "CH1","CH2","CH3","CH4"
#define TR_AUX_SERIAL_MODES "OFF","Telem Mirror","Telemetry In","SBUS Trainer","LUA","CLI","GPS","Debug","SpaceMouse"
#define TR_AUX_SERIAL_MODES "OFF","Telem Mirror","Telemetry In","SBUS Trainer","LUA","CLI","GPS","Debug","SpaceMouse","External module"
#define TR_SWTYPES "None","Toggle","2POS","3POS"
#define TR_POTTYPES "None",TR("Pot w. det","Pot with detent"),TR("Multipos","Multipos Switch"),"Pot"
#define TR_SLIDERTYPES "None","Slider"