Skip to content

Commit

Permalink
fix: Internal PXX exclusive S.PORT (#3822)
Browse files Browse the repository at this point in the history
  • Loading branch information
raphaelcoeffic authored Oct 12, 2023
1 parent c270ec1 commit ff2b3ac
Show file tree
Hide file tree
Showing 24 changed files with 435 additions and 186 deletions.
8 changes: 5 additions & 3 deletions radio/src/gui/128x64/model_setup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "mixer_scheduler.h"
#include "hal/adc_driver.h"
#include "hal/switch_driver.h"
#include "hal/module_port.h"
#include "switches.h"

#if defined(USBJ_EX)
Expand Down Expand Up @@ -1972,10 +1973,11 @@ void menuModelSetup(event_t event)
#endif
if (isModuleR9MNonAccess(moduleIdx)) {
lcdDrawTextAlignedLeft(y, STR_MODULE_TELEMETRY);
if (isSportLineUsedByInternalModule())
lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_DISABLE_INTERNAL);
else
if (modulePortIsPortUsedByModule(moduleIdx, ETX_MOD_PORT_SPORT)) {
lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_MODULE_TELEM_ON);
} else {
lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_DISABLE_INTERNAL);
}
}
else if (isModuleSBUS(moduleIdx)) {
lcdDrawTextAlignedLeft(y, STR_WARN_BATTVOLTAGE);
Expand Down
7 changes: 4 additions & 3 deletions radio/src/gui/212x64/model_setup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "hal/adc_driver.h"
#include "hal/adc_driver.h"
#include "hal/switch_driver.h"
#include "hal/module_port.h"

#include "opentx.h"
#include "mixer_scheduler.h"
Expand Down Expand Up @@ -1739,11 +1740,11 @@ void menuModelSetup(event_t event)
#endif
if (isModuleR9MNonAccess(moduleIdx)) {
lcdDrawTextAlignedLeft(y, STR_MODULE_TELEMETRY);
if (isSportLineUsedByInternalModule()) {
lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_DISABLE_INTERNAL);
if (modulePortIsPortUsedByModule(moduleIdx, ETX_MOD_PORT_SPORT)) {
lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_MODULE_TELEM_ON);
}
else {
lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_MODULE_TELEM_ON);
lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_DISABLE_INTERNAL);
}
}
else if (isModuleSBUS(moduleIdx)) {
Expand Down
67 changes: 57 additions & 10 deletions radio/src/hal/module_port.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,14 @@ static void modulePortClear(etx_module_state_t* st)
memset(st, 0, sizeof(etx_module_state_t));
}

static void _init_serial_driver(etx_module_driver_t* d, const etx_module_port_t* port,
static bool _init_serial_driver(etx_module_driver_t* d, const etx_module_port_t* port,
const etx_serial_init* params)
{
auto drv = port->drv.serial;
d->ctx = drv->init(port->hw_def, params);
auto ctx = drv->init(port->hw_def, params);
if (!ctx) return false;

d->ctx = ctx;
d->port = port;

// S.PORT specific HW settings
Expand All @@ -80,19 +83,26 @@ static void _init_serial_driver(etx_module_driver_t* d, const etx_module_port_t*
if (port->set_inverted) {
port->set_inverted(params->polarity == ETX_Pol_Inverted);
}

return true;
}

static void _init_timer_driver(etx_module_driver_t* d, const etx_module_port_t* port,
static bool _init_timer_driver(etx_module_driver_t* d, const etx_module_port_t* port,
const etx_timer_config_t* cfg)
{
auto drv = port->drv.timer;
d->ctx = drv->init(port->hw_def, cfg);
auto ctx = drv->init(port->hw_def, cfg);
if (!ctx) return false;

d->ctx = ctx;
d->port = port;

// setup polarity
if (port->set_inverted) {
port->set_inverted(false);
}

return true;
}

static bool _match_port(const etx_module_port_t* p, uint8_t type, uint8_t port,
Expand Down Expand Up @@ -202,10 +212,11 @@ etx_module_state_t* modulePortInitSerial(uint8_t module, uint8_t port,
const uint8_t duplex = ETX_Dir_TX_RX;
uint8_t dir = params->direction & duplex;

bool init_ok = false;
if (dir == duplex) {

// init RX first, in case TX was already done previously
_init_serial_driver(&state->rx, found_port, params);
init_ok = _init_serial_driver(&state->rx, found_port, params);

// do not overwrite TX state if it has already been set:
// -> support using S.PORT in bidir mode
Expand All @@ -214,12 +225,12 @@ etx_module_state_t* modulePortInitSerial(uint8_t module, uint8_t port,
state->tx.ctx = state->rx.ctx;
}
} else if (dir == ETX_Dir_TX) {
_init_serial_driver(&state->tx, found_port, params);
init_ok = _init_serial_driver(&state->tx, found_port, params);
} else if (dir == ETX_Dir_RX) {
_init_serial_driver(&state->rx, found_port, params);
init_ok = _init_serial_driver(&state->rx, found_port, params);
}

return state;
return init_ok ? state : nullptr;
}

etx_module_state_t* modulePortInitTimer(uint8_t module, uint8_t port,
Expand All @@ -230,9 +241,9 @@ etx_module_state_t* modulePortInitTimer(uint8_t module, uint8_t port,
if (!found_port) return nullptr;

auto state = &(_module_states[module]);
_init_timer_driver(&state->tx, found_port, cfg);
bool init_ok = _init_timer_driver(&state->tx, found_port, cfg);

return state;
return init_ok ? state : nullptr;
}

static void _deinit_driver(etx_module_driver_t* d)
Expand Down Expand Up @@ -262,6 +273,14 @@ void modulePortDeInit(etx_module_state_t* st)
modulePortClear(st);
}

void modulePortDeInitRxPort(etx_module_state_t* st)
{
if (st->rx.port) {
_deinit_driver(&st->rx);
memset(&st->rx, 0, sizeof(etx_module_driver_t));
}
}

etx_module_state_t* modulePortGetState(uint8_t module)
{
if (module >= MAX_MODULES) return nullptr;
Expand All @@ -272,3 +291,31 @@ uint8_t modulePortGetModule(etx_module_state_t* st)
{
return st - _module_states;
}

bool modulePortIsPortUsedByModule(uint8_t module, uint8_t port)
{
auto mod_st = modulePortGetState(module);
if (!mod_st) return false;

auto tx_port = mod_st->tx.port;
auto rx_port = mod_st->rx.port;

return (tx_port && tx_port->port == port) ||
(rx_port && rx_port->port == port);
}

bool modulePortIsPortUsed(uint8_t port)
{
return modulePortGetModuleForPort(port) >= 0;
}

int8_t modulePortGetModuleForPort(uint8_t port)
{
for (uint8_t module = 0; module < MAX_MODULES; module++) {
if (modulePortIsPortUsedByModule(module, port)) {
return module;
}
}

return -1;
}
7 changes: 7 additions & 0 deletions radio/src/hal/module_port.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,9 @@ etx_module_state_t* modulePortInitTimer(uint8_t module, uint8_t port,
// De-init port and clear data
void modulePortDeInit(etx_module_state_t* st);

// De-init RX part
void modulePortDeInitRxPort(etx_module_state_t* st);

// Once initialized, retrieve module serial driver and context
etx_module_state_t* modulePortGetState(uint8_t module);

Expand All @@ -159,3 +162,7 @@ inline void* modulePortGetCtx(const etx_module_driver_t& d) {
return d.ctx;
}

bool modulePortIsPortUsedByModule(uint8_t module, uint8_t port);
bool modulePortIsPortUsed(uint8_t port);

int8_t modulePortGetModuleForPort(uint8_t port);
15 changes: 2 additions & 13 deletions radio/src/pulses/modules_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "storage/storage.h"
#include "globals.h"
#include "MultiProtoDefs.h"
#include "hal/module_port.h"

#if defined(MULTIMODULE)
#include "telemetry/multi.h"
Expand Down Expand Up @@ -728,25 +729,13 @@ inline bool isBindCh9To16Allowed(uint8_t moduleIndex)
}
}

#if defined(PCBTARANIS) || defined(PCBHORUS)
inline bool isSportLineUsedByInternalModule()
{
return g_model.moduleData[INTERNAL_MODULE].type == MODULE_TYPE_XJT_PXX1;
}
#else
inline bool isSportLineUsedByInternalModule()
{
return false;
}
#endif

inline bool isTelemAllowedOnBind(uint8_t moduleIndex)
{
#if defined(HARDWARE_INTERNAL_MODULE)
if (moduleIndex == INTERNAL_MODULE)
return true;

if (isSportLineUsedByInternalModule())
if (!modulePortIsPortUsedByModule(moduleIndex, ETX_MOD_PORT_SPORT))
return false;
#endif

Expand Down
6 changes: 3 additions & 3 deletions radio/src/pulses/multi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,8 @@ static void setupPulsesMulti(uint8_t*& p_buf, uint8_t module)
}

// Invert telemetry if needed
if (invert[module] & 0x80 &&
!g_model.moduleData[module].multi.disableTelemetry) {
uint8_t disableTelemetry = modulePortIsPortUsedByModule(module, ETX_MOD_PORT_SPORT) ? 0 : 1;
if (invert[module] & 0x80 && !disableTelemetry) {
if (getMultiModuleStatus(module).isValid()) {
invert[module] &= 0x08; // Telemetry received, stop searching
} else if (counter[module] % 100 == 0) {
Expand Down Expand Up @@ -170,7 +170,7 @@ static void setupPulsesMulti(uint8_t*& p_buf, uint8_t module)
| (g_model.header.modelId[module] & 0x30)
| (invert[module] & 0x08)
//| 0x04 // Future use
| (g_model.moduleData[module].multi.disableTelemetry << 1)
| (disableTelemetry << 1)
| g_model.moduleData[module].multi.disableMapping));
}

Expand Down
17 changes: 0 additions & 17 deletions radio/src/pulses/multi.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,6 @@

#pragma once

#include "pulses_common.h"
#include "hal/serial_driver.h"
#include "hal/module_driver.h"

class UartMultiPulses: public DataBuffer<uint8_t, 64>
{
public:
void initFrame()
{
initBuffer();
}

void sendByte(uint8_t b)
{
if (getSize() < 64)
*ptr++ = b;
}
};

extern const etx_proto_driver_t MultiDriver;
13 changes: 13 additions & 0 deletions radio/src/pulses/pulses.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,19 @@ void restartModule(uint8_t module)
mixerTaskStart();
}

void pulsesRestartModuleUnsafe(uint8_t module)
{
if (module >= MAX_MODULES)
return;

auto mod_drv = pulsesGetModuleDriver(module);
if (!mod_drv->drv) return;

auto drv = mod_drv->drv;
drv->deinit(mod_drv->ctx);
mod_drv->ctx = drv->init(module);
}

#if !defined(SIMU)
#include <FreeRTOS/include/FreeRTOS.h>
#include <FreeRTOS/include/timers.h>
Expand Down
6 changes: 6 additions & 0 deletions radio/src/pulses/pulses.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,12 @@ void pulsesSetModuleDeInitCb(module_deinit_cb_t cb);
void restartModule(uint8_t module);
bool restartModuleAsync(uint8_t module, uint8_t cnt_delay);

// Re-Init module
//
// Note: this can only be used from within
// module init.
void pulsesRestartModuleUnsafe(uint8_t module);

void pulsesModuleSettingsUpdate(uint8_t module);

void setupPulsesPPMTrainer();
Expand Down
46 changes: 46 additions & 0 deletions radio/src/pulses/pxx.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* 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 "pxx.h"
#include "hal/module_port.h"

bool pxxClearSPort()
{
auto sport_module = modulePortGetModuleForPort(ETX_MOD_PORT_SPORT);
if (sport_module >= 0) {
// verify S.PORT is not used for TX (otherwise fail early)
auto mod_st = modulePortGetState(sport_module);
if (mod_st && mod_st->tx.port &&
mod_st->tx.port->port == ETX_MOD_PORT_SPORT) {
return false;
}
} else {
// S.PORT soft-serial cannot be used for sending
sport_module = modulePortGetModuleForPort(ETX_MOD_PORT_SPORT_INV);
}

if (sport_module >= 0) {
auto mod_st = modulePortGetState(sport_module);
if (mod_st) modulePortDeInitRxPort(mod_st);
}

return true;
}
4 changes: 4 additions & 0 deletions radio/src/pulses/pxx.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,7 @@

#define EXTMODULE_PXX1_SERIAL_PERIOD 4000/*us*/
#define EXTMODULE_PXX1_SERIAL_BAUDRATE 420000

// Releases S.PORT usage from
// the module driver using it.
bool pxxClearSPort();
Loading

0 comments on commit ff2b3ac

Please sign in to comment.