WiP: refactor serial ports
This commit is contained in:
+17
-8
@@ -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(¶ms);
|
||||
IntmoduleSerialDriver.init(¶ms);
|
||||
}
|
||||
|
||||
// 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(¶ms);
|
||||
|
||||
IntmoduleSerialDriver.init(¶ms);
|
||||
|
||||
// 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();
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -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)());
|
||||
};
|
||||
@@ -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(¶ms);
|
||||
IntmoduleSerialDriver.init(¶ms);
|
||||
|
||||
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(¶ms);
|
||||
IntmoduleSerialDriver.init(¶ms);
|
||||
} 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++;
|
||||
}
|
||||
|
||||
@@ -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(¶ms);
|
||||
IntmoduleSerialDriver.init(¶ms);
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -56,4 +56,6 @@ public:
|
||||
virtual ~afhds2();
|
||||
};
|
||||
|
||||
extern etx_serial_init afhds2SerialInitParams;
|
||||
|
||||
#endif /* PULSES_AFHDS2_H_ */
|
||||
|
||||
@@ -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(¶ms);
|
||||
#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
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
@@ -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(¶ms);
|
||||
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(¶ms);
|
||||
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(¶ms);
|
||||
|
||||
// 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(¶ms);
|
||||
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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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(¶ms);
|
||||
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();
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user