WiP: refactor serial ports

This commit is contained in:
Raphael Coeffic
2022-03-20 16:22:12 +01:00
parent 87a3d2f9e7
commit f733810c79
27 changed files with 601 additions and 199 deletions
+17 -8
View File
@@ -917,19 +917,28 @@ int cliSet(const char **argv)
static void spInternalModuleTx(uint8_t* buf, uint32_t len)
{
while (len > 0) {
intmoduleSendByte(*(buf++));
IntmoduleSerialDriver.sendByte(*(buf++));
len--;
}
}
static const etx_serial_init spIntmoduleSerialInitParams = {
.baudrate = 0,
.parity = ETX_Parity_None,
.stop_bits = ETX_StopBits_One,
.word_length = ETX_WordLength_8,
.rx_enable = true,
.on_receive = intmoduleFifoReceive,
.on_error = intmoduleFifoError,
};
static void spInternalModuleSetBaudRate(uint32_t baud)
{
etx_serial_init params;
etx_serial_init params(spIntmoduleSerialInitParams);
params.baudrate = baud;
params.rx_enable = true;
// re-configure serial port
intmoduleSerialStart(&params);
IntmoduleSerialDriver.init(&params);
}
// TODO: use proper method instead
@@ -988,10 +997,10 @@ int cliSerialPassthrough(const char **argv)
// setup serial com
// TODO: '8n1' param
etx_serial_init params;
etx_serial_init params(spIntmoduleSerialInitParams);
params.baudrate = baudrate;
params.rx_enable = true;
intmoduleSerialStart(&params);
IntmoduleSerialDriver.init(&params);
// backup and swap CLI input
auto backupCB = cliReceiveCallBack;
@@ -1024,7 +1033,7 @@ int cliSerialPassthrough(const char **argv)
cliReceiveCallBack = backupCB;
// and stop module
intmoduleStop();
IntmoduleSerialDriver.deinit();
// power off the module and wait for a bit
INTERNAL_MODULE_OFF();
+65
View File
@@ -0,0 +1,65 @@
/*
* 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>
enum ChannelsProtocols {
PROTOCOL_CHANNELS_UNINITIALIZED,
PROTOCOL_CHANNELS_NONE,
PROTOCOL_CHANNELS_PPM,
PROTOCOL_CHANNELS_PXX1_PULSES,
PROTOCOL_CHANNELS_PXX1_SERIAL,
PROTOCOL_CHANNELS_DSM2_LP45,
PROTOCOL_CHANNELS_DSM2_DSM2,
PROTOCOL_CHANNELS_DSM2_DSMX,
PROTOCOL_CHANNELS_CROSSFIRE,
PROTOCOL_CHANNELS_MULTIMODULE,
PROTOCOL_CHANNELS_SBUS,
PROTOCOL_CHANNELS_PXX2_LOWSPEED,
PROTOCOL_CHANNELS_PXX2_HIGHSPEED,
PROTOCOL_CHANNELS_AFHDS2A,
PROTOCOL_CHANNELS_AFHDS3,
PROTOCOL_CHANNELS_GHOST
};
struct etx_hal_module_driver_t {
// Protocol implemented by this module driver
ChannelsProtocols protocol;
// Init module communication
void* (*init)(uint8_t module);
// // Default pulse period in microseconds
// uint16_t (*get_default_period)(uint8_t module);
// De-Init module communication
void (*deinit)(void* context);
// Prepare the pulses to be sent
void (*setupPulses)(void* context, int16_t* channels, uint8_t nChannels);
// Send the pulses
void (*sendPulses)(void* context);
};
+73
View File
@@ -0,0 +1,73 @@
/*
* 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>
enum SerialParity {
ETX_Parity_None,
ETX_Parity_Even,
ETX_Parity_Odd,
};
enum SerialStopBits {
ETX_StopBits_One,
ETX_StopBits_OneAndHalf,
ETX_StopBits_Two,
};
enum SerialWordLength {
ETX_WordLength_8,
ETX_WordLength_9,
};
struct etx_serial_init {
uint32_t baudrate; // = 0;
uint8_t parity; // = ETX_Parity_None;
uint8_t stop_bits; // = ETX_StopBits_One;
uint8_t word_length; // = ETX_WordLength_8;
bool rx_enable; // = false;
void (*on_receive)(uint8_t data); // = nullptr;
void (*on_error)(); // = nullptr;
};
struct etx_hal_serial_driver_t {
// Init module communication
void (*init)(const etx_serial_init* params);
// De-Init module communication
void (*deinit)();
// Send a single byte
void (*sendByte)(uint8_t byte);
// Send a buffer
void (*sendBuffer)(const uint8_t* data, uint8_t size);
// Wait for last send operation to complete
void (*waitForTxCompleted)();
// Callbacks
void (*setReceiveCb)(void (*on_receive)(uint8_t data));
void (*setOnErrorCb)(void (*on_error)());
};
+22 -14
View File
@@ -306,6 +306,16 @@ const char * FrskyDeviceFirmwareUpdate::sendReqVersion()
// X9D / X9D+ / X9E / XLite IXJT = use S.PORT @ 57600 bauds
// XLite PRO / X9Lite / X9D+ 2019 ISRM = use TX + RX @ 57600 bauds
static const etx_serial_init serialInitParams = {
.baudrate = 0,
.parity = ETX_Parity_None,
.stop_bits = ETX_StopBits_One,
.word_length = ETX_WordLength_8,
.rx_enable = true,
.on_receive = intmoduleFifoReceive,
.on_error = intmoduleFifoError,
};
const char * FrskyDeviceFirmwareUpdate::doFlashFirmware(const char * filename, ProgressHandler progressHandler)
{
FIL file;
@@ -335,10 +345,9 @@ const char * FrskyDeviceFirmwareUpdate::doFlashFirmware(const char * filename, P
INTERNAL_MODULE_ON();
RTOS_WAIT_MS(1);
etx_serial_init params;
etx_serial_init params(serialInitParams);
params.baudrate = 38400;
params.rx_enable = true;
intmoduleSerialStart(&params);
IntmoduleSerialDriver.init(&params);
GPIO_SetBits(INTMODULE_BOOTCMD_GPIO, INTMODULE_BOOTCMD_GPIO_PIN);
result = uploadFileToHorusXJT(filename, &file, progressHandler);
@@ -352,10 +361,9 @@ const char * FrskyDeviceFirmwareUpdate::doFlashFirmware(const char * filename, P
switch (module) {
#if defined(INTERNAL_MODULE_PXX2)
case INTERNAL_MODULE: {
etx_serial_init params;
etx_serial_init params(serialInitParams);
params.baudrate = 57600;
params.rx_enable = true;
intmoduleSerialStart(&params);
IntmoduleSerialDriver.init(&params);
} break;
#endif
@@ -387,14 +395,14 @@ const char * FrskyDeviceFirmwareUpdate::uploadFileToHorusXJT(const char * filena
return STR_DEVICE_NO_RESPONSE;
}
intmoduleSendByte(0x81);
IntmoduleSerialDriver.sendByte(0x81);
readBuffer(frame, 1, 100);
if (!readBuffer(frame, 8, 100) || frame[0] != 0x02) {
return STR_DEVICE_NO_RESPONSE;
}
intmoduleSendByte(0x82);
IntmoduleSerialDriver.sendByte(0x82);
readBuffer(frame, 1, 100);
uint8_t index = 0;
@@ -412,7 +420,7 @@ const char * FrskyDeviceFirmwareUpdate::uploadFileToHorusXJT(const char * filena
return STR_DEVICE_WRONG_REQUEST;
if (count == 0) {
intmoduleSendByte(0xA1);
IntmoduleSerialDriver.sendByte(0xA1);
RTOS_WAIT_MS(50);
return nullptr;
}
@@ -420,15 +428,15 @@ const char * FrskyDeviceFirmwareUpdate::uploadFileToHorusXJT(const char * filena
if (count < 1024)
memset(((uint8_t *)buffer) + count, 0, 1024 - count);
intmoduleSendByte(frame[0] + 0x80);
intmoduleSendByte(frame[1]);
IntmoduleSerialDriver.sendByte(frame[0] + 0x80);
IntmoduleSerialDriver.sendByte(frame[1]);
uint16_t crc_16 = crc16(CRC_1189, (uint8_t *)buffer, 1024, crc16(CRC_1189, &frame[1], 1));
for (size_t i = 0; i < sizeof(buffer); i++) {
intmoduleSendByte(((uint8_t *)buffer)[i]);
IntmoduleSerialDriver.sendByte(((uint8_t *)buffer)[i]);
}
intmoduleSendByte(crc_16 >> 8);
intmoduleSendByte(crc_16);
IntmoduleSerialDriver.sendByte(crc_16 >> 8);
IntmoduleSerialDriver.sendByte(crc_16);
index++;
}
+14 -4
View File
@@ -68,6 +68,17 @@ class MultiFirmwareUpdateDriver
};
#if defined(INTERNAL_MODULE_MULTI)
static const etx_serial_init serialInitParams = {
.baudrate = 0,
.parity = ETX_Parity_None,
.stop_bits = ETX_StopBits_One,
.word_length = ETX_WordLength_8,
.rx_enable = true,
.on_receive = intmoduleFifoReceive,
.on_error = intmoduleFifoError,
};
class MultiInternalUpdateDriver: public MultiFirmwareUpdateDriver
{
public:
@@ -81,10 +92,9 @@ class MultiInternalUpdateDriver: public MultiFirmwareUpdateDriver
void init(bool inverted) const override
{
etx_serial_init params;
etx_serial_init params(serialInitParams);
params.baudrate = 57600;
params.rx_enable = true;
intmoduleSerialStart(&params);
IntmoduleSerialDriver.init(&params);
}
bool getByte(uint8_t & byte) const override
@@ -94,7 +104,7 @@ class MultiInternalUpdateDriver: public MultiFirmwareUpdateDriver
void sendByte(uint8_t byte) const override
{
intmoduleSendByte(byte);
IntmoduleSerialDriver.sendByte(byte);
}
void clear() const override
+10
View File
@@ -21,6 +21,16 @@
#include "afhds2.h"
etx_serial_init afhds2SerialInitParams = {
.baudrate = INTMODULE_USART_AFHDS2_BAUDRATE,
.parity = ETX_Parity_None,
.stop_bits = ETX_StopBits_One,
.word_length = ETX_WordLength_8,
.rx_enable = true,
.on_receive = intmoduleFifoReceive,
.on_error = intmoduleFifoError,
};
afhds2::afhds2() {
// TODO Auto-generated constructor stub
+2
View File
@@ -56,4 +56,6 @@ public:
virtual ~afhds2();
};
extern etx_serial_init afhds2SerialInitParams;
#endif /* PULSES_AFHDS2_H_ */
+116 -5
View File
@@ -20,6 +20,11 @@
*/
#include "opentx.h"
#include "mixer_scheduler.h"
#if defined(INTMODULE_USART)
#include "intmodule_serial_driver.h"
#endif
#define CROSSFIRE_CH_BITS 11
#define CROSSFIRE_CENTER 0x3E0
@@ -71,7 +76,8 @@ uint8_t createCrossfireChannelsFrame(uint8_t * frame, int16_t * pulses)
}
static void setupPulsesCrossfire(uint8_t idx, CrossfirePulsesData* p_data,
uint8_t endpoint)
uint8_t endpoint, int16_t* channels,
uint8_t nChannels)
{
#if defined(LUA)
if (outputTelemetryBuffer.destination == endpoint) {
@@ -88,18 +94,123 @@ static void setupPulsesCrossfire(uint8_t idx, CrossfirePulsesData* p_data,
} else {
p_data->length = createCrossfireChannelsFrame(
p_data->pulses,
&channelOutputs[g_model.moduleData[idx].channelsStart]);
channels /*TODO: nChannels*/);
}
}
}
void setupPulsesCrossfire(uint8_t idx)
static void setupPulsesCrossfire(uint8_t idx, int16_t* channels, uint8_t nChannels)
{
if (idx == INTERNAL_MODULE) {
auto* p_data = &intmodulePulsesData.crossfire;
setupPulsesCrossfire(idx, p_data, 0);
setupPulsesCrossfire(idx, p_data, 0, channels, nChannels);
} else if (telemetryProtocol == PROTOCOL_TELEMETRY_CROSSFIRE) {
auto* p_data = &extmodulePulsesData.crossfire;
setupPulsesCrossfire(idx, p_data, TELEMETRY_ENDPOINT_SPORT);
setupPulsesCrossfire(idx, p_data, TELEMETRY_ENDPOINT_SPORT, channels, nChannels);
}
}
#if defined(INTERNAL_MODULE_CRSF)
static void intmoduleCRSF_rx(uint8_t data)
{
intmoduleFifo.push(data);
#if !defined(SIMU)
// 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
}
#endif
static const etx_serial_init intmoduleCrossfireInitParams = {
.baudrate = 0,
.parity = ETX_Parity_None,
.stop_bits = ETX_StopBits_One,
.word_length = ETX_WordLength_8,
.rx_enable = true,
.on_receive = intmoduleCRSF_rx,
.on_error = nullptr,
};
static void* crossfireInit(uint8_t module)
{
if (module == INTERNAL_MODULE) {
#if defined(INTERNAL_MODULE_CRSF)
// serial port setup
etx_serial_init params(intmoduleCrossfireInitParams);
params.baudrate = CROSSFIRE_BAUDRATE;
// wakeup mixer when rx buffer is quarter full (16 bytes)
params.on_receive = intmoduleCRSF_rx;
intmoduleFifo.clear();
IntmoduleSerialDriver.init(&params);
#endif
} else {
// TODO: setup S.PORT
// - for now, the init is still done via telemetryWakeup()....
}
// mixer setup
mixerSchedulerSetPeriod(INTERNAL_MODULE, CROSSFIRE_PERIOD);
return (void*)(uint32_t)module;
}
static void crossfireDeInit(void* context)
{
uint32_t module = (uint32_t)context;
if (module == INTERNAL_MODULE) {
#if defined(INTERNAL_MODULE_CRSF)
mixerSchedulerSetPeriod(INTERNAL_MODULE, 0);
intmoduleStop();
intmoduleFifo.clear();
#endif
} else {
mixerSchedulerSetPeriod(EXTERNAL_MODULE, 0);
}
}
static void crossfireSetupPulses(void* context, int16_t* channels, uint8_t nChannels)
{
uint32_t module = (uint32_t)context;
ModuleSyncStatus& status = getModuleSyncStatus(module);
if (status.isValid()) {
mixerSchedulerSetPeriod(module, status.getAdjustedRefreshRate());
} else {
mixerSchedulerSetPeriod(module, CROSSFIRE_PERIOD);
}
setupPulsesCrossfire(module, channels, nChannels);
}
static void crossfireSendPulses(void* context)
{
uint32_t module = (uint32_t)context;
if (module == INTERNAL_MODULE) {
IntmoduleSerialDriver.sendBuffer(intmodulePulsesData.crossfire.pulses,
intmodulePulsesData.crossfire.length);
} else {
sportSendBuffer(extmodulePulsesData.crossfire.pulses,
extmodulePulsesData.crossfire.length);
}
}
#include "hal/module_driver.h"
etx_hal_module_driver_t CrossfireModuleDriver = {
.protocol = PROTOCOL_CHANNELS_CROSSFIRE,
.init = crossfireInit,
.deinit = crossfireDeInit,
.setupPulses = crossfireSetupPulses,
.sendPulses = crossfireSendPulses
};
+26
View File
@@ -0,0 +1,26 @@
/*
* 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 "hal/module_driver.h"
extern etx_hal_module_driver_t CrossfireModuleDriver;
+14
View File
@@ -50,6 +50,20 @@ static void sendConfig(uint8_t moduleIdx);
static void sendDSM(uint8_t moduleIdx);
#endif
#if defined(INTMODULE_USART)
#include "intmodule_serial_driver.h"
etx_serial_init multiSerialInitParams = {
.baudrate = MULTIMODULE_BAUDRATE,
.parity = ETX_Parity_Even,
.stop_bits = ETX_StopBits_Two,
.word_length = ETX_WordLength_9,
.rx_enable = true,
.on_receive = intmoduleFifoReceive,
.on_error = intmoduleFifoError,
};
#endif
void multiPatchCustom(uint8_t moduleIdx)
{
if (g_model.moduleData[moduleIdx].multi.customProto) {
+3
View File
@@ -23,6 +23,7 @@
#define _MULTI_PULSES_H_
#include "pulses_common.h"
#include "hal/serial_driver.h"
void multiPatchCustom(uint8_t moduleIdx);
void convertEtxProtocolToMulti(int *protocol, int *subprotocol);
@@ -43,4 +44,6 @@ class UartMultiPulses: public DataBuffer<uint8_t, 64>
}
};
extern etx_serial_init multiSerialInitParams;
#endif
+40 -82
View File
@@ -33,6 +33,10 @@
#include "intmodule_pulses_driver.h"
#endif
#if defined(CROSSFIRE)
#include "pulses/crossfire.h"
#endif
uint8_t s_pulses_paused = 0;
ModuleState moduleState[NUM_MODULES];
InternalModulePulsesData intmodulePulsesData __DMA;
@@ -304,7 +308,8 @@ void enablePulsesExternalModule(uint8_t protocol)
#if defined(CROSSFIRE)
case PROTOCOL_CHANNELS_CROSSFIRE:
EXTERNAL_MODULE_ON();
mixerSchedulerSetPeriod(EXTERNAL_MODULE, CROSSFIRE_PERIOD);
if (CrossfireModuleDriver.init)
CrossfireModuleDriver.init(EXTERNAL_MODULE);
break;
#endif
@@ -409,15 +414,14 @@ bool setupPulsesExternalModule(uint8_t protocol)
#if defined(CROSSFIRE)
case PROTOCOL_CHANNELS_CROSSFIRE:
{
ModuleSyncStatus& status = getModuleSyncStatus(EXTERNAL_MODULE);
if (status.isValid())
mixerSchedulerSetPeriod(EXTERNAL_MODULE, status.getAdjustedRefreshRate());
else
mixerSchedulerSetPeriod(EXTERNAL_MODULE, CROSSFIRE_PERIOD);
setupPulsesCrossfire(EXTERNAL_MODULE);
if (CrossfireModuleDriver.setupPulses) {
int16_t* channels =
&channelOutputs[g_model.moduleData[EXTERNAL_MODULE].channelsStart];
uint8_t nChannels = 16; // TODO: MAX_CHANNELS - channelsStart
CrossfireModuleDriver.setupPulses((void*)EXTERNAL_MODULE, channels,
nChannels);
}
return true;
}
#endif
#if defined(GHOST)
@@ -466,25 +470,6 @@ bool setupPulsesExternalModule(uint8_t protocol)
#if defined(HARDWARE_INTERNAL_MODULE)
#if defined(INTERNAL_MODULE_CRSF)
static void intmoduleCRSF_rx(uint8_t data)
{
intmoduleFifo.push(data);
#if !defined(SIMU)
// 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
}
#endif
static void enablePulsesInternalModule(uint8_t protocol)
{
// start new protocol hardware here
@@ -512,12 +497,8 @@ static void enablePulsesInternalModule(uint8_t protocol)
#if defined(PXX2)
case PROTOCOL_CHANNELS_PXX2_HIGHSPEED: {
etx_serial_init params;
params.baudrate = PXX2_HIGHSPEED_BAUDRATE;
params.rx_enable = true;
intmoduleFifo.clear();
intmoduleSerialStart(&params);
IntmoduleSerialDriver.init(&pxx2SerialInitParams)
resetAccessAuthenticationCount();
#if defined(INTMODULE_HEARTBEAT)
@@ -529,19 +510,11 @@ static void enablePulsesInternalModule(uint8_t protocol)
#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();
intmoduleFifo.clear();
intmoduleSerialStart(&params);
IntmoduleSerialDriver.init(&multiSerialInitParams);
// mixer setup
mixerSchedulerSetPeriod(INTERNAL_MODULE, MULTIMODULE_PERIOD);
@@ -555,26 +528,16 @@ static void enablePulsesInternalModule(uint8_t protocol)
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: {
// 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(&params);
// mixer setup
mixerSchedulerSetPeriod(INTERNAL_MODULE, CROSSFIRE_PERIOD);
} break;
case PROTOCOL_CHANNELS_CROSSFIRE:
if (CrossfireModuleDriver.init) {
// TODO: save context
CrossfireModuleDriver.init(INTERNAL_MODULE);
}
break;
#endif
#if defined(INTERNAL_MODULE_PPM)
@@ -585,20 +548,15 @@ 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();
intmoduleFifo.clear();
intmoduleSerialStart(&params);
IntmoduleSerialDriver.init(&afhds2SerialInitParams)
// mixer setup
mixerSchedulerSetPeriod(INTERNAL_MODULE, AFHDS2_PERIOD);
} break;
break;
#endif
default:
@@ -645,15 +603,14 @@ bool setupPulsesInternalModule(uint8_t protocol)
#if defined(INTERNAL_MODULE_CRSF)
case PROTOCOL_CHANNELS_CROSSFIRE:
{
ModuleSyncStatus& status = getModuleSyncStatus(INTERNAL_MODULE);
if (status.isValid())
mixerSchedulerSetPeriod(INTERNAL_MODULE, status.getAdjustedRefreshRate());
else
mixerSchedulerSetPeriod(INTERNAL_MODULE, CROSSFIRE_PERIOD);
setupPulsesCrossfire(INTERNAL_MODULE);
if (CrossfireModuleDriver.setupPulses) {
int16_t* channels =
&channelOutputs[g_model.moduleData[INTERNAL_MODULE].channelsStart];
uint8_t nChannels = 16; // TODO: MAX_CHANNELS - channelsStart
CrossfireModuleDriver.setupPulses((void*)INTERNAL_MODULE, channels,
nChannels);
}
return true;
}
#endif
#if defined(INTERNAL_MODULE_MULTI)
@@ -711,8 +668,8 @@ void intmoduleSendNextFrame()
#if defined(PXX1)
#if defined(INTMODULE_USART)
case PROTOCOL_CHANNELS_PXX1_SERIAL:
intmoduleSendBuffer(intmodulePulsesData.pxx_uart.getData(),
intmodulePulsesData.pxx_uart.getSize());
IntmoduleSerialDriver.sendBuffer(intmodulePulsesData.pxx_uart.getData(),
intmodulePulsesData.pxx_uart.getSize());
break;
#else
case PROTOCOL_CHANNELS_PXX1_PULSES:
@@ -724,15 +681,16 @@ void intmoduleSendNextFrame()
#if defined(INTERNAL_MODULE_MULTI)
case PROTOCOL_CHANNELS_MULTIMODULE:
intmoduleSendBuffer(intmodulePulsesData.multi.getData(),
intmodulePulsesData.multi.getSize());
IntmoduleSerialDriver.sendBuffer(intmodulePulsesData.multi.getData(),
intmodulePulsesData.multi.getSize());
break;
#endif
#if defined(INTERNAL_MODULE_CRSF)
case PROTOCOL_CHANNELS_CROSSFIRE:
intmoduleSendBuffer(intmodulePulsesData.crossfire.pulses,
intmodulePulsesData.crossfire.length);
if (CrossfireModuleDriver.sendPulses) {
CrossfireModuleDriver.sendPulses((void*)INTERNAL_MODULE);
}
break;
#endif
+1 -19
View File
@@ -32,6 +32,7 @@
#include "afhds2.h"
#include "modules_helpers.h"
#include "ff.h"
#include "hal/module_driver.h"
#if defined(DSM2)
@@ -276,25 +277,6 @@ inline void startPulses()
#endif
}
enum ChannelsProtocols {
PROTOCOL_CHANNELS_UNINITIALIZED,
PROTOCOL_CHANNELS_NONE,
PROTOCOL_CHANNELS_PPM,
PROTOCOL_CHANNELS_PXX1_PULSES,
PROTOCOL_CHANNELS_PXX1_SERIAL,
PROTOCOL_CHANNELS_DSM2_LP45,
PROTOCOL_CHANNELS_DSM2_DSM2,
PROTOCOL_CHANNELS_DSM2_DSMX,
PROTOCOL_CHANNELS_CROSSFIRE,
PROTOCOL_CHANNELS_MULTIMODULE,
PROTOCOL_CHANNELS_SBUS,
PROTOCOL_CHANNELS_PXX2_LOWSPEED,
PROTOCOL_CHANNELS_PXX2_HIGHSPEED,
PROTOCOL_CHANNELS_AFHDS2A,
PROTOCOL_CHANNELS_AFHDS3,
PROTOCOL_CHANNELS_GHOST
};
inline void stopPulses()
{
s_pulses_paused = true;
+14
View File
@@ -25,6 +25,20 @@
#include "io/frsky_firmware_update.h"
#include "libopenui/src/libopenui_file.h"
#if defined(INTMODULE_USART)
#include "intmodule_serial_driver.h"
const etx_serial_init pxx2SerialInitParams = {
.baudrate = PXX2_HIGHSPEED_BAUDRATE,
.parity = ETX_Parity_None,
.stop_bits = ETX_StopBits_One,
.word_length = ETX_WordLength_8,
.rx_enable = true,
.on_receive = intmoduleFifoReceive,
.on_error = intmoduleFifoError,
};
#endif
bool isPXX2PowerAvailable(const PXX2HardwareInformation& info, int value)
{
uint8_t modelId = info.modelID;
+3
View File
@@ -26,6 +26,7 @@
#include "io/frsky_pxx2.h"
#include "popups.h"
#include "./pxx.h"
#include "hal/serial_driver.h"
#define PXX2_TYPE_C_MODULE 0x01
#define PXX2_TYPE_ID_REGISTER 0x01
@@ -575,4 +576,6 @@ class Pxx2OtaUpdate {
const char * nextStep(uint8_t step, const char * rxName, uint32_t address, const uint8_t * buffer);
};
extern const etx_serial_init pxx2SerialInitParams;
#endif
@@ -21,6 +21,7 @@
#include "opentx.h"
#include "intmodule_serial_driver.h"
#include "stm32_usart_driver.h"
ModuleFifo intmoduleFifo;
#if !defined(INTMODULE_DMA_STREAM)
@@ -36,32 +37,30 @@ struct etx_serial_driver {
static etx_serial_driver intmodule_driver = { nullptr, nullptr };
// TODO: move this somewhere else
static void intmoduleFifoReceive(uint8_t data)
void intmoduleFifoReceive(uint8_t data)
{
intmoduleFifo.push(data);
}
static void intmoduleFifoError()
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)
{
}
// 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);
#if defined(INTMODULE_DMA_STREAM)
INTMODULE_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA
#endif
@@ -83,17 +82,29 @@ void intmoduleStop()
intmodule_driver.on_error = nullptr;
}
static const etx_serial_init pxx1SerialInit = {
.baudrate = INTMODULE_PXX1_SERIAL_BAUDRATE,
.parity = ETX_Parity_None,
.stop_bits = ETX_StopBits_One,
.word_length = ETX_WordLength_8,
.rx_enable = false,
.on_receive = intmoduleFifoReceive,
.on_error = intmoduleFifoError,
};
void intmodulePxx1SerialStart()
{
etx_serial_init params;
params.baudrate = INTMODULE_PXX1_SERIAL_BAUDRATE;
intmoduleSerialStart(&params);
IntmoduleSerialDriver.init(&pxx1SerialInit);
}
void intmoduleSerialStart(const etx_serial_init* params)
{
if (!params) return;
// TODO: sanity check parameters
// - the UART seems to block when initialised with baudrate = 0
// TODO: remove this!!!
INTERNAL_MODULE_ON();
// init callbacks
@@ -130,16 +141,7 @@ void intmoduleSerialStart(const etx_serial_init* params)
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(INTMODULE_GPIO, &GPIO_InitStructure);
USART_DeInit(INTMODULE_USART);
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 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);
stm32_usart_init(INTMODULE_USART, params);
if (params->rx_enable) {
USART_ITConfig(INTMODULE_USART, USART_IT_RXNE, ENABLE);
@@ -224,6 +226,8 @@ void intmoduleWaitForTxCompleted()
{
#if !defined(SIMU)
#if defined(INTMODULE_DMA_STREAM)
// TODO: check if everything is properly initialised, this seems to block when
// the port has been initialised with a zero baudrate
if (DMA_GetCmdStatus(INTMODULE_DMA_STREAM) == ENABLE) {
while(DMA_GetFlagStatus(INTMODULE_DMA_STREAM, INTMODULE_DMA_FLAG_TC) == RESET);
DMA_ClearFlag(INTMODULE_DMA_STREAM, INTMODULE_DMA_FLAG_TC);
@@ -233,3 +237,11 @@ void intmoduleWaitForTxCompleted()
#endif
#endif
}
etx_hal_serial_driver_t IntmoduleSerialDriver = {
.init = intmoduleSerialStart,
.deinit = intmoduleStop,
.sendByte = intmoduleSendByte,
.sendBuffer = intmoduleSendBuffer,
.waitForTxCompleted = intmoduleWaitForTxCompleted,
};
@@ -22,22 +22,10 @@
#pragma once
#include <stdint.h>
#include "hal/serial_driver.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)();
// Callbacks using intmoduleFifo
void intmoduleFifoReceive(uint8_t data);
void intmoduleFifoError();
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();
extern etx_hal_serial_driver_t IntmoduleSerialDriver;
@@ -0,0 +1,70 @@
/*
* 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.
*/
#include "stm32_usart_driver.h"
void stm32_usart_init(USART_TypeDef *USARTx, const etx_serial_init* params)
{
USART_DeInit(USARTx);
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = params->baudrate;
uint16_t parity = USART_Parity_No;
switch(params->parity){
case ETX_Parity_None:
parity = USART_Parity_No;
break;
case ETX_Parity_Even:
parity = USART_Parity_Even;
break;
case ETX_Parity_Odd:
parity = USART_Parity_Odd;
break;
}
USART_InitStructure.USART_Parity = parity;
uint16_t stop_bits = USART_StopBits_1;
switch(params->stop_bits) {
case ETX_StopBits_One:
stop_bits = USART_StopBits_1;
break;
case ETX_StopBits_OneAndHalf:
stop_bits = USART_StopBits_1_5;
break;
case ETX_StopBits_Two:
stop_bits = USART_StopBits_2;
break;
}
USART_InitStructure.USART_StopBits = stop_bits;
if (params->word_length == ETX_WordLength_9) {
USART_InitStructure.USART_WordLength = USART_WordLength_9b;
} else {
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
}
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_Init(USARTx, &USART_InitStructure);
USART_Cmd(USARTx, ENABLE);
}
@@ -0,0 +1,35 @@
/*
* 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>
#include "hal/serial_driver.h"
#if defined(STM32F4)
// #include "stm32f4xx.h"
#include "stm32f4xx_usart.h"
#else
// #include "stm32f2xx.h"
#include "stm32f2xx_usart.h"
#endif
void stm32_usart_init(USART_TypeDef *USARTx, const etx_serial_init* params);
@@ -37,6 +37,10 @@ enum usbMode {
#endif
};
// Control line state bits
#define CTRL_LINE_STATE_DTR (1 << 0)
#define CTRL_LINE_STATE_RTS (1 << 1)
int usbPlugged();
void usbInit();
void usbStart();
+1
View File
@@ -242,6 +242,7 @@ set(TARGET_SRC
../common/arm/stm32/mixer_scheduler_driver.cpp
../common/arm/stm32/timers_driver.cpp
../common/arm/stm32/intmodule_serial_driver.cpp
../common/arm/stm32/stm32_usart_driver.cpp
../common/arm/stm32/rotary_encoder_driver.cpp
)
+11 -13
View File
@@ -145,6 +145,10 @@ uint32_t isBootloaderStart(const uint8_t * buffer);
// SDRAM driver
void SDRAM_Init();
#if defined(INTERNAL_MODULE_PXX1) || defined(INTERNAL_MODULE_PXX2)
#define HARDWARE_INTERNAL_RAS
#endif
// Pulses driver
#if defined(RADIO_T18) || defined(RADIO_T16)
@@ -168,20 +172,14 @@ void SDRAM_Init();
#endif
#if defined(INTERNAL_MODULE_PXX1) || defined(INTERNAL_MODULE_PXX2)
#define HARDWARE_INTERNAL_RAS
#endif
#define INTERNAL_MODULE_OFF() GPIO_ResetBits(INTMODULE_PWR_GPIO, INTMODULE_PWR_GPIO_PIN)
#define EXTERNAL_MODULE_ON() GPIO_SetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN)
#define EXTERNAL_MODULE_OFF() GPIO_ResetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN)
#if defined(INTMODULE_USART)
#define INTERNAL_MODULE_OFF() intmoduleStop()
#else
#define INTERNAL_MODULE_OFF() GPIO_ResetBits(INTMODULE_PWR_GPIO, INTMODULE_PWR_GPIO_PIN)
#endif
#define EXTERNAL_MODULE_ON() GPIO_SetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN)
#define EXTERNAL_MODULE_OFF() GPIO_ResetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN)
#define IS_INTERNAL_MODULE_ON() (GPIO_ReadInputDataBit(INTMODULE_PWR_GPIO, INTMODULE_PWR_GPIO_PIN) == Bit_SET)
#define IS_EXTERNAL_MODULE_ON() (GPIO_ReadInputDataBit(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN) == Bit_SET)
#define IS_INTERNAL_MODULE_ON() \
(GPIO_ReadInputDataBit(INTMODULE_PWR_GPIO, INTMODULE_PWR_GPIO_PIN) == Bit_SET)
#define IS_EXTERNAL_MODULE_ON() \
(GPIO_ReadInputDataBit(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN) == Bit_SET)
#if !defined(PXX2)
#define IS_PXX2_INTERNAL_ENABLED() (false)
+7 -1
View File
@@ -21,6 +21,10 @@
#include "opentx.h"
#if defined(CROSSFIRE)
#include "pulses/crossfire.h"
#endif
void extmoduleStop()
{
EXTERNAL_MODULE_OFF();
@@ -413,7 +417,9 @@ void extmoduleSendNextFrame()
#if defined(CROSSFIRE)
case PROTOCOL_CHANNELS_CROSSFIRE:
sportSendBuffer(extmodulePulsesData.crossfire.pulses, extmodulePulsesData.crossfire.length);
if (CrossfireModuleDriver.sendPulses) {
CrossfireModuleDriver.sendPulses((void*)EXTERNAL_MODULE);
}
break;
#endif
+1
View File
@@ -133,6 +133,7 @@ set(TARGET_SRC
../horus/extmodule_driver.cpp
trainer_driver.cpp
../common/arm/stm32/intmodule_serial_driver.cpp
../common/arm/stm32/stm32_usart_driver.cpp
)
set(FIRMWARE_TARGET_SRC
+1
View File
@@ -411,6 +411,7 @@ if(INTERNAL_MODULE_SERIAL)
set(TARGET_SRC
${TARGET_SRC}
../common/arm/stm32/intmodule_serial_driver.cpp
../common/arm/stm32/stm32_usart_driver.cpp
)
else()
+2 -6
View File
@@ -115,12 +115,8 @@ uint32_t isFirmwareStart(const uint8_t * buffer);
uint32_t isBootloaderStart(const uint8_t * buffer);
// Pulses driver
#define INTERNAL_MODULE_ON() GPIO_SetBits(INTMODULE_PWR_GPIO, INTMODULE_PWR_GPIO_PIN)
#if defined(INTMODULE_USART)
#define INTERNAL_MODULE_OFF() intmoduleStop()
#else
#define INTERNAL_MODULE_OFF() GPIO_ResetBits(INTMODULE_PWR_GPIO, INTMODULE_PWR_GPIO_PIN)
#endif
#define INTERNAL_MODULE_ON() GPIO_SetBits(INTMODULE_PWR_GPIO, INTMODULE_PWR_GPIO_PIN)
#define INTERNAL_MODULE_OFF() GPIO_ResetBits(INTMODULE_PWR_GPIO, INTMODULE_PWR_GPIO_PIN)
#if (defined(INTERNAL_MODULE_PXX1) || defined(INTERNAL_MODULE_PXX2)) && (!defined(PCBX9LITE) || defined(PCBX9LITES))
#define HARDWARE_INTERNAL_RAS
@@ -350,7 +350,9 @@ void extmoduleSendNextFrame()
#if defined(CROSSFIRE)
case PROTOCOL_CHANNELS_CROSSFIRE:
sportSendBuffer(extmodulePulsesData.crossfire.pulses, extmodulePulsesData.crossfire.length);
if (CrossfireModuleDriver.sendPulses) {
CrossfireModuleDriver.sendPulses((void*)EXTERNAL_MODULE);
}
break;
#endif