diff --git a/platforms/common/include/px4_platform_common/board_common.h b/platforms/common/include/px4_platform_common/board_common.h index b05d832718..6b316c31d8 100644 --- a/platforms/common/include/px4_platform_common/board_common.h +++ b/platforms/common/include/px4_platform_common/board_common.h @@ -458,6 +458,15 @@ static inline bool board_rc_singlewire(const char *device) { return false; } * A board may define RC_SERIAL_SWAP_RXTX, so that RC_SERIAL_PORT is configured * as UART with RX/TX swapped. * + * It can optionaly define RC_SERIAL_SWAP_USING_SINGLEWIRE If the board is wired + * with TX to the input (Swapped) and the SoC does not support U[S]ART level + * HW swapping, then use onewire to do the swap if and only if: + * + * RC_SERIAL_SWAP_USING_SINGLEWIRE is defined + * RC_SERIAL_SWAP_RXTX is defined + * TIOCSSWAP is defined and retuns !OK + * TIOCSSINGLEWIRE is defined + * * Input Parameters: * device: serial device, e.g. "/dev/ttyS0" * diff --git a/src/drivers/rc_input/RCInput.cpp b/src/drivers/rc_input/RCInput.cpp index 5caab7e973..bea3af194c 100644 --- a/src/drivers/rc_input/RCInput.cpp +++ b/src/drivers/rc_input/RCInput.cpp @@ -302,6 +302,25 @@ void RCInput::rc_io_invert(bool invert) } } +void RCInput::swap_rx_tx() +{ +#if defined(RC_SERIAL_SWAP_USING_SINGLEWIRE) + int rv = -ENOTTY; +# if defined(TIOCSSWAP) + rv = ioctl(_rcs_fd, TIOCSSWAP, SER_SWAP_ENABLED); +# endif // TIOCSSWAP +# ifdef TIOCSSINGLEWIRE + + if (rv != OK) { + ioctl(_rcs_fd, TIOCSSINGLEWIRE, SER_SINGLEWIRE_ENABLED); + } + +# else + UNUSED(rv); +# endif // TIOCSSINGLEWIRE +#endif // RC_SERIAL_SWAP_USING_SINGLEWIRE +} + void RCInput::Run() { if (should_exit()) { @@ -494,6 +513,7 @@ void RCInput::Run() _rc_scan_begin = cycle_timestamp; // Configure serial port for DSM dsm_config(_rcs_fd); + swap_rx_tx(); // flush serial buffer and any existing buffered data tcflush(_rcs_fd, TCIOFLUSH); @@ -531,6 +551,7 @@ void RCInput::Run() _rc_scan_begin = cycle_timestamp; // Configure serial port for DSM dsm_config(_rcs_fd); + swap_rx_tx(); // flush serial buffer and any existing buffered data tcflush(_rcs_fd, TCIOFLUSH); @@ -582,6 +603,7 @@ void RCInput::Run() _rc_scan_begin = cycle_timestamp; // Configure serial port for DSM dsm_config(_rcs_fd); + swap_rx_tx(); // flush serial buffer and any existing buffered data tcflush(_rcs_fd, TCIOFLUSH); @@ -660,6 +682,7 @@ void RCInput::Run() _rc_scan_begin = cycle_timestamp; // Configure serial port for CRSF crsf_config(_rcs_fd); + swap_rx_tx(); // flush serial buffer and any existing buffered data tcflush(_rcs_fd, TCIOFLUSH); @@ -708,6 +731,7 @@ void RCInput::Run() _rc_scan_begin = cycle_timestamp; // Configure serial port for GHST ghst_config(_rcs_fd); + swap_rx_tx(); // flush serial buffer and any existing buffered data tcflush(_rcs_fd, TCIOFLUSH); diff --git a/src/drivers/rc_input/RCInput.hpp b/src/drivers/rc_input/RCInput.hpp index 718fb2647c..be781471c8 100644 --- a/src/drivers/rc_input/RCInput.hpp +++ b/src/drivers/rc_input/RCInput.hpp @@ -126,6 +126,7 @@ private: void set_rc_scan_state(RC_SCAN _rc_scan_state); void rc_io_invert(bool invert); + void swap_rx_tx(void); input_rc_s _input_rc{}; hrt_abstime _rc_scan_begin{0};