From ad7b74847eb21a944659b72b0a02e4da75d1adda Mon Sep 17 00:00:00 2001 From: Daniel Agar Date: Sat, 24 Sep 2022 15:11:55 -0400 Subject: [PATCH] split drivers/rc_input per protocol --- ROMFS/px4fmu_common/init.d/rcS | 8 +- boards/airmind/mindpx-v2/default.px4board | 4 +- boards/ark/fmu-v6x/default.px4board | 4 +- .../ark/fmu-v6x/extras/px4_io-v2_default.bin | Bin 40140 -> 40128 bytes boards/ark/fmu-v6x/src/board_config.h | 1 - boards/atl/mantis-edu/src/board_config.h | 4 - boards/av/x-v1/default.px4board | 9 +- boards/av/x-v1/src/board_config.h | 1 - boards/beaglebone/blue/default.px4board | 3 +- boards/cuav/nora/default.px4board | 4 +- boards/cuav/x7pro/default.px4board | 4 +- .../extras/cubepilot_io-v2_default.bin | Bin 39920 -> 39908 bytes .../extras/cubepilot_io-v2_default.bin | Bin 39920 -> 39908 bytes .../diatone/mamba-f405-mk2/default.px4board | 4 +- .../diatone/mamba-f405-mk2/src/board_config.h | 1 - boards/emlid/navio2/default.px4board | 3 +- boards/flywoo/gn-f405/default.px4board | 1 + boards/flywoo/gn-f405/src/board_config.h | 1 - .../durandal-v1/extras/px4_io-v2_default.bin | Bin 40140 -> 40128 bytes boards/holybro/kakutef7/default.px4board | 3 +- boards/holybro/kakutef7/src/board_config.h | 1 - boards/holybro/kakuteh7/default.px4board | 4 +- boards/holybro/pix32v5/default.px4board | 4 +- .../pix32v5/extras/px4_io-v2_default.bin | Bin 40140 -> 40128 bytes boards/holybro/pix32v5/src/board_config.h | 1 - boards/matek/h743-mini/default.px4board | 3 +- boards/matek/h743-mini/src/board_config.h | 1 - boards/matek/h743-slim/default.px4board | 3 +- boards/matek/h743-slim/src/board_config.h | 1 - boards/matek/h743/default.px4board | 3 +- boards/matek/h743/src/board_config.h | 1 - boards/modalai/fc-v1/default.px4board | 4 +- boards/modalai/fc-v1/src/board_config.h | 2 - boards/modalai/fc-v2/default.px4board | 3 +- boards/modalai/fc-v2/src/board_config.h | 1 - boards/mro/ctrl-zero-classic/default.px4board | 4 +- boards/mro/ctrl-zero-f7-oem/default.px4board | 4 +- boards/mro/ctrl-zero-f7/default.px4board | 4 +- boards/mro/ctrl-zero-h7-oem/default.px4board | 4 +- boards/mro/ctrl-zero-h7/default.px4board | 4 +- boards/mro/pixracerpro/default.px4board | 4 +- boards/mro/pixracerpro/src/board_config.h | 1 - .../mro/x21-777/extras/px4_io-v2_default.bin | Bin 40140 -> 40128 bytes boards/mro/x21/extras/px4_io-v2_default.bin | Bin 40140 -> 40128 bytes boards/nxp/fmuk66-e/default.px4board | 4 +- boards/nxp/fmuk66-e/src/board_config.h | 1 - boards/nxp/fmuk66-v3/default.px4board | 4 +- boards/nxp/fmuk66-v3/src/board_config.h | 1 - boards/nxp/fmurt1062-v1/default.px4board | 4 +- boards/omnibus/f4sd/default.px4board | 4 +- boards/omnibus/f4sd/src/board_config.h | 1 - .../px4/fmu-v2/extras/px4_io-v2_default.bin | Bin 40140 -> 40128 bytes .../px4/fmu-v3/extras/px4_io-v2_default.bin | Bin 40140 -> 40128 bytes boards/px4/fmu-v4/default.px4board | 4 +- boards/px4/fmu-v4/src/board_config.h | 1 - .../fmu-v4pro/extras/px4_io-v2_default.bin | Bin 40140 -> 40128 bytes boards/px4/fmu-v5/default.px4board | 4 +- .../px4/fmu-v5/extras/px4_io-v2_default.bin | Bin 40140 -> 40128 bytes boards/px4/fmu-v5/src/board_config.h | 2 - boards/px4/fmu-v5/uavcanv0periph.px4board | 4 +- boards/px4/fmu-v5x/default.px4board | 3 +- .../px4/fmu-v5x/extras/px4_io-v2_default.bin | Bin 40140 -> 40128 bytes boards/px4/fmu-v5x/src/board_config.h | 1 - .../px4/fmu-v6c/extras/px4_io-v2_default.bin | Bin 40140 -> 40128 bytes boards/px4/fmu-v6u/default.px4board | 4 +- boards/px4/fmu-v6u/src/board_config.h | 1 - boards/px4/fmu-v6x/default.px4board | 6 +- .../px4/fmu-v6x/extras/px4_io-v2_default.bin | Bin 40140 -> 40128 bytes boards/px4/fmu-v6x/src/board_config.h | 1 - boards/px4/raspberrypi/default.px4board | 3 +- boards/raspberrypi/pico/default.px4board | 3 +- boards/raspberrypi/pico/src/board_config.h | 1 - boards/scumaker/pilotpi/default.px4board | 8 +- .../smartap-airlink/default.px4board | 4 +- .../smartap-airlink/src/board_config.h | 1 - boards/spracing/h7extreme/default.px4board | 4 +- boards/uvify/core/default.px4board | 4 +- src/drivers/px4io/px4io.cpp | 2 +- src/drivers/rc/Kconfig | 12 +- .../rc/{crsf_rc => crsf}/CMakeLists.txt | 6 +- src/drivers/rc/{crsf_rc => crsf}/Crc8.cpp | 0 src/drivers/rc/{crsf_rc => crsf}/Crc8.hpp | 0 .../rc/{crsf_rc => crsf}/CrsfParser.cpp | 0 .../rc/{crsf_rc => crsf}/CrsfParser.hpp | 0 src/drivers/rc/{crsf_rc => crsf}/CrsfRc.cpp | 16 +- src/drivers/rc/{crsf_rc => crsf}/CrsfRc.hpp | 0 src/drivers/rc/{crsf_rc => crsf}/Kconfig | 4 +- .../rc/{crsf_rc => crsf}/QueueBuffer.cpp | 0 .../rc/{crsf_rc => crsf}/QueueBuffer.hpp | 0 src/drivers/rc/{crsf_rc => crsf}/module.yaml | 2 +- src/drivers/rc/ghst_rc/CMakeLists.txt | 51 + src/drivers/rc/ghst_rc/Kconfig | 5 + src/drivers/rc/ghst_rc/RCInput.cpp | 427 ++++++++ .../ghst_rc/RCInput.hpp} | 105 +- .../rc/ghst_rc/ghst_parser.cpp} | 74 +- .../rc/ghst_rc/ghst_parser.hpp} | 0 src/drivers/rc/ghst_rc/module.yaml | 7 + .../ghst_rc/test}/CMakeLists.txt | 13 +- src/drivers/rc/ghst_rc/test/RcGhstTest.cpp | 123 +++ .../{rc_input => rc/ppm_in}/CMakeLists.txt | 11 +- src/drivers/rc/ppm_in/Kconfig | 5 + src/drivers/rc/ppm_in/RCInput.cpp | 316 ++++++ src/drivers/rc/ppm_in/RCInput.hpp | 118 +++ src/drivers/rc/ppm_in/module.yaml | 12 + src/drivers/rc/sbus/CMakeLists.txt | 45 + src/drivers/rc/sbus/Kconfig | 5 + src/drivers/rc/sbus/RCInput.cpp | 415 ++++++++ src/drivers/{rc_input => rc/sbus}/RCInput.hpp | 76 +- src/drivers/rc/sbus/module.yaml | 7 + src/drivers/rc/spektrum_dsm/CMakeLists.txt | 45 + src/drivers/rc/spektrum_dsm/Kconfig | 5 + src/drivers/rc/spektrum_dsm/RCInput.cpp | 456 +++++++++ src/drivers/rc/spektrum_dsm/RCInput.hpp | 95 ++ src/drivers/rc/spektrum_dsm/module.yaml | 7 + src/drivers/rc/st24_rc/CMakeLists.txt | 45 + src/drivers/rc/st24_rc/Kconfig | 5 + src/drivers/rc/st24_rc/RCInput.cpp | 378 +++++++ src/drivers/rc/st24_rc/RCInput.hpp | 106 ++ src/drivers/rc/st24_rc/module.yaml | 7 + src/drivers/rc/sumd_rc/CMakeLists.txt | 45 + src/drivers/rc/sumd_rc/Kconfig | 5 + src/drivers/rc/sumd_rc/RCInput.cpp | 371 +++++++ src/drivers/rc/sumd_rc/RCInput.hpp | 107 ++ src/drivers/rc/sumd_rc/module.yaml | 7 + src/drivers/rc_input/Kconfig | 5 - src/drivers/rc_input/RCInput.cpp | 953 ------------------ src/drivers/rc_input/crsf_telemetry.cpp | 183 ---- src/drivers/rc_input/crsf_telemetry.h | 92 -- src/drivers/rc_input/ghst_telemetry.cpp | 139 --- src/drivers/rc_input/module.yaml | 35 - .../snapdragon_spektrum_rc/spektrum_rc.cpp | 298 ------ src/drivers/spektrum_rc/Kconfig | 5 - src/lib/rc/CMakeLists.txt | 23 +- src/lib/rc/common_rc.cpp | 31 - src/lib/rc/common_rc.h | 29 - src/lib/rc/crsf.cpp | 478 --------- src/lib/rc/crsf.h | 134 --- src/lib/rc/dsm/CMakeLists.txt | 44 + src/lib/rc/{ => dsm}/dsm.cpp | 48 +- src/lib/rc/{ => dsm}/dsm.h | 4 - src/lib/rc/rc_tests/CMakeLists.txt | 5 +- src/lib/rc/rc_tests/RCTest.cpp | 188 +--- src/lib/rc/sbus/CMakeLists.txt | 48 + src/lib/rc/{ => sbus}/sbus.cpp | 4 +- src/lib/rc/{ => sbus}/sbus.h | 2 +- src/lib/rc/spektrum_rssi.h | 88 -- src/lib/rc/st24/CMakeLists.txt | 44 + src/lib/rc/{ => st24}/st24.cpp | 10 +- src/lib/rc/{ => st24}/st24.h | 9 - src/lib/rc/sumd/CMakeLists.txt | 44 + src/lib/rc/{ => sumd}/sumd.cpp | 28 +- src/lib/rc/{ => sumd}/sumd.h | 26 - src/modules/px4iofirmware/CMakeLists.txt | 5 +- src/modules/px4iofirmware/controls.cpp | 8 +- src/modules/px4iofirmware/mixer.cpp | 2 +- src/modules/px4iofirmware/registers.c | 4 +- 156 files changed, 3780 insertions(+), 2967 deletions(-) rename src/drivers/rc/{crsf_rc => crsf}/CMakeLists.txt (97%) rename src/drivers/rc/{crsf_rc => crsf}/Crc8.cpp (100%) rename src/drivers/rc/{crsf_rc => crsf}/Crc8.hpp (100%) rename src/drivers/rc/{crsf_rc => crsf}/CrsfParser.cpp (100%) rename src/drivers/rc/{crsf_rc => crsf}/CrsfParser.hpp (100%) rename src/drivers/rc/{crsf_rc => crsf}/CrsfRc.cpp (95%) rename src/drivers/rc/{crsf_rc => crsf}/CrsfRc.hpp (100%) rename src/drivers/rc/{crsf_rc => crsf}/Kconfig (53%) rename src/drivers/rc/{crsf_rc => crsf}/QueueBuffer.cpp (100%) rename src/drivers/rc/{crsf_rc => crsf}/QueueBuffer.hpp (100%) rename src/drivers/rc/{crsf_rc => crsf}/module.yaml (91%) create mode 100644 src/drivers/rc/ghst_rc/CMakeLists.txt create mode 100644 src/drivers/rc/ghst_rc/Kconfig create mode 100644 src/drivers/rc/ghst_rc/RCInput.cpp rename src/drivers/{rc_input/ghst_telemetry.hpp => rc/ghst_rc/RCInput.hpp} (54%) rename src/{lib/rc/ghst.cpp => drivers/rc/ghst_rc/ghst_parser.cpp} (90%) rename src/{lib/rc/ghst.hpp => drivers/rc/ghst_rc/ghst_parser.hpp} (100%) create mode 100644 src/drivers/rc/ghst_rc/module.yaml rename src/drivers/{snapdragon_spektrum_rc => rc/ghst_rc/test}/CMakeLists.txt (89%) create mode 100644 src/drivers/rc/ghst_rc/test/RcGhstTest.cpp rename src/drivers/{rc_input => rc/ppm_in}/CMakeLists.txt (91%) create mode 100644 src/drivers/rc/ppm_in/Kconfig create mode 100644 src/drivers/rc/ppm_in/RCInput.cpp create mode 100644 src/drivers/rc/ppm_in/RCInput.hpp create mode 100644 src/drivers/rc/ppm_in/module.yaml create mode 100644 src/drivers/rc/sbus/CMakeLists.txt create mode 100644 src/drivers/rc/sbus/Kconfig create mode 100644 src/drivers/rc/sbus/RCInput.cpp rename src/drivers/{rc_input => rc/sbus}/RCInput.hpp (71%) create mode 100644 src/drivers/rc/sbus/module.yaml create mode 100644 src/drivers/rc/spektrum_dsm/CMakeLists.txt create mode 100644 src/drivers/rc/spektrum_dsm/Kconfig create mode 100644 src/drivers/rc/spektrum_dsm/RCInput.cpp create mode 100644 src/drivers/rc/spektrum_dsm/RCInput.hpp create mode 100644 src/drivers/rc/spektrum_dsm/module.yaml create mode 100644 src/drivers/rc/st24_rc/CMakeLists.txt create mode 100644 src/drivers/rc/st24_rc/Kconfig create mode 100644 src/drivers/rc/st24_rc/RCInput.cpp create mode 100644 src/drivers/rc/st24_rc/RCInput.hpp create mode 100644 src/drivers/rc/st24_rc/module.yaml create mode 100644 src/drivers/rc/sumd_rc/CMakeLists.txt create mode 100644 src/drivers/rc/sumd_rc/Kconfig create mode 100644 src/drivers/rc/sumd_rc/RCInput.cpp create mode 100644 src/drivers/rc/sumd_rc/RCInput.hpp create mode 100644 src/drivers/rc/sumd_rc/module.yaml delete mode 100644 src/drivers/rc_input/Kconfig delete mode 100644 src/drivers/rc_input/RCInput.cpp delete mode 100644 src/drivers/rc_input/crsf_telemetry.cpp delete mode 100644 src/drivers/rc_input/crsf_telemetry.h delete mode 100644 src/drivers/rc_input/ghst_telemetry.cpp delete mode 100644 src/drivers/rc_input/module.yaml delete mode 100644 src/drivers/snapdragon_spektrum_rc/spektrum_rc.cpp delete mode 100644 src/drivers/spektrum_rc/Kconfig delete mode 100644 src/lib/rc/common_rc.cpp delete mode 100644 src/lib/rc/common_rc.h delete mode 100644 src/lib/rc/crsf.cpp delete mode 100644 src/lib/rc/crsf.h create mode 100644 src/lib/rc/dsm/CMakeLists.txt rename src/lib/rc/{ => dsm}/dsm.cpp (93%) rename src/lib/rc/{ => dsm}/dsm.h (98%) create mode 100644 src/lib/rc/sbus/CMakeLists.txt rename src/lib/rc/{ => sbus}/sbus.cpp (99%) rename src/lib/rc/{ => sbus}/sbus.h (98%) delete mode 100644 src/lib/rc/spektrum_rssi.h create mode 100644 src/lib/rc/st24/CMakeLists.txt rename src/lib/rc/{ => st24}/st24.cpp (96%) rename src/lib/rc/{ => st24}/st24.h (95%) create mode 100644 src/lib/rc/sumd/CMakeLists.txt rename src/lib/rc/{ => sumd}/sumd.cpp (94%) rename src/lib/rc/{ => sumd}/sumd.h (85%) diff --git a/ROMFS/px4fmu_common/init.d/rcS b/ROMFS/px4fmu_common/init.d/rcS index f1e54e0910..de183fccc4 100644 --- a/ROMFS/px4fmu_common/init.d/rcS +++ b/ROMFS/px4fmu_common/init.d/rcS @@ -29,7 +29,6 @@ set LOGGER_ARGS "" set LOGGER_BUF 8 set PARAM_FILE "" set PARAM_BACKUP_FILE "" -set RC_INPUT_ARGS "" set SDCARD_AVAILABLE no set SDCARD_EXT_PATH /fs/microsd/ext_autostart set SDCARD_FORMAT no @@ -411,8 +410,10 @@ else # . ${R}etc/init.d/rc.serial - # Must be started after the serial config is read - rc_input start $RC_INPUT_ARGS + if param compare -s RC_PPM_EN 1 + then + ppm_in start + fi # # Play the startup tune (if not disabled or there is an error) @@ -544,7 +545,6 @@ unset LOGGER_ARGS unset LOGGER_BUF unset PARAM_FILE unset PARAM_BACKUP_FILE -unset RC_INPUT_ARGS unset SDCARD_AVAILABLE unset SDCARD_EXT_PATH unset SDCARD_FORMAT diff --git a/boards/airmind/mindpx-v2/default.px4board b/boards/airmind/mindpx-v2/default.px4board index 89f5620399..fb22de8202 100644 --- a/boards/airmind/mindpx-v2/default.px4board +++ b/boards/airmind/mindpx-v2/default.px4board @@ -4,6 +4,7 @@ CONFIG_BOARD_CONSTRAINED_MEMORY=y CONFIG_BOARD_SERIAL_GPS1="/dev/ttyS3" CONFIG_BOARD_SERIAL_TEL1="/dev/ttyS1" CONFIG_BOARD_SERIAL_TEL2="/dev/ttyS2" +CONFIG_BOARD_SERIAL_RC="/dev/ttyS0" CONFIG_DRIVERS_ADC_ADS1115=y CONFIG_DRIVERS_ADC_BOARD_ADC=y CONFIG_COMMON_BAROMETERS=y @@ -28,7 +29,8 @@ CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_INPUT=y CONFIG_DRIVERS_PWM_OUT=y -CONFIG_DRIVERS_RC_INPUT=y +CONFIG_COMMON_RC=y +CONFIG_DRIVERS_RC_PPM_IN=y CONFIG_DRIVERS_ROBOCLAW=y CONFIG_DRIVERS_RPM=y CONFIG_DRIVERS_SMART_BATTERY_BATMON=y diff --git a/boards/ark/fmu-v6x/default.px4board b/boards/ark/fmu-v6x/default.px4board index b531e66539..ddb17a42f8 100644 --- a/boards/ark/fmu-v6x/default.px4board +++ b/boards/ark/fmu-v6x/default.px4board @@ -7,6 +7,7 @@ CONFIG_BOARD_SERIAL_TEL1="/dev/ttyS6" CONFIG_BOARD_SERIAL_TEL2="/dev/ttyS4" CONFIG_BOARD_SERIAL_TEL3="/dev/ttyS1" CONFIG_BOARD_SERIAL_TEL4="/dev/ttyS3" +CONFIG_BOARD_SERIAL_RC="/dev/ttyS5" CONFIG_DRIVERS_ADC_BOARD_ADC=y CONFIG_DRIVERS_BAROMETER_BMP388=y CONFIG_DRIVERS_BATT_SMBUS=y @@ -27,7 +28,8 @@ CONFIG_DRIVERS_POWER_MONITOR_INA228=y CONFIG_DRIVERS_POWER_MONITOR_INA238=y CONFIG_DRIVERS_PWM_OUT=y CONFIG_DRIVERS_PX4IO=y -CONFIG_DRIVERS_RC_INPUT=y +CONFIG_COMMON_RC=y +CONFIG_DRIVERS_RC_PPM_IN=y CONFIG_DRIVERS_SAFETY_BUTTON=y CONFIG_DRIVERS_TONE_ALARM=y CONFIG_DRIVERS_UAVCAN=y diff --git a/boards/ark/fmu-v6x/extras/px4_io-v2_default.bin b/boards/ark/fmu-v6x/extras/px4_io-v2_default.bin index 957f0f13a12e8eb8a7979955f29ad98d82433933..cad477b0e9232e7ff73192e3b1074f3137864089 100755 GIT binary patch delta 3980 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 delta 4072 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 Ms4)Pl_yEBF0*mHmb^rhX diff --git a/boards/ark/fmu-v6x/src/board_config.h b/boards/ark/fmu-v6x/src/board_config.h index 89500da23f..4a8439c385 100644 --- a/boards/ark/fmu-v6x/src/board_config.h +++ b/boards/ark/fmu-v6x/src/board_config.h @@ -323,7 +323,6 @@ #define GPIO_PPM_IN /* PI5 T8C1 */ GPIO_TIM8_CH1IN_2 /* RC Serial port */ - #define RC_SERIAL_PORT "/dev/ttyS5" /* Input Capture Channels. */ diff --git a/boards/atl/mantis-edu/src/board_config.h b/boards/atl/mantis-edu/src/board_config.h index 8b8a99b12e..a25477a14a 100644 --- a/boards/atl/mantis-edu/src/board_config.h +++ b/boards/atl/mantis-edu/src/board_config.h @@ -145,10 +145,6 @@ #define HRT_TIMER 8 /* use timer8 for the HRT */ #define HRT_TIMER_CHANNEL 3 /* use capture/compare channel 3 */ -/* RC Serial port */ -#define RC_SERIAL_PORT "/dev/ttyS5" -#define RC_SERIAL_SINGLEWIRE - /* power on/off */ #define MS_PWR_BUTTON_DOWN 750 #define KEY_AD_GPIO (GPIO_INPUT|GPIO_PULLUP|GPIO_EXTI|GPIO_PORTC|GPIO_PIN4) diff --git a/boards/av/x-v1/default.px4board b/boards/av/x-v1/default.px4board index 3deacca91c..318748c9ec 100644 --- a/boards/av/x-v1/default.px4board +++ b/boards/av/x-v1/default.px4board @@ -6,6 +6,7 @@ CONFIG_BOARD_SERIAL_TEL1="/dev/ttyS0" CONFIG_BOARD_SERIAL_TEL2="/dev/ttyS1" CONFIG_BOARD_SERIAL_TEL3="/dev/ttyS2" CONFIG_BOARD_SERIAL_TEL4="/dev/ttyS3" +CONFIG_BOARD_SERIAL_RC="/dev/ttyS4" CONFIG_DRIVERS_ADC_ADS1115=y CONFIG_DRIVERS_ADC_BOARD_ADC=y CONFIG_COMMON_BAROMETERS=y @@ -22,14 +23,12 @@ CONFIG_DRIVERS_IRLOCK=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y CONFIG_COMMON_OPTICAL_FLOW=y -CONFIG_DRIVERS_OSD=y CONFIG_DRIVERS_PCA9685=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_OUT=y -CONFIG_DRIVERS_RC_INPUT=y +CONFIG_COMMON_RC=y CONFIG_DRIVERS_ROBOCLAW=y -CONFIG_DRIVERS_RPM=y CONFIG_DRIVERS_SMART_BATTERY_BATMON=y CONFIG_COMMON_TELEMETRY=y CONFIG_DRIVERS_UAVCAN=y @@ -38,6 +37,7 @@ CONFIG_MODULES_ATTITUDE_ESTIMATOR_Q=y CONFIG_MODULES_BATTERY_STATUS=y CONFIG_MODULES_CAMERA_FEEDBACK=y CONFIG_MODULES_COMMANDER=y +CONFIG_MODULES_CONTROL_ALLOCATOR=y CONFIG_MODULES_DATAMAN=y CONFIG_MODULES_EKF2=y CONFIG_MODULES_ESC_BATTERY=y @@ -46,6 +46,7 @@ CONFIG_MODULES_FLIGHT_MODE_MANAGER=y CONFIG_MODULES_FW_ATT_CONTROL=y CONFIG_MODULES_FW_AUTOTUNE_ATTITUDE_CONTROL=y CONFIG_MODULES_FW_POS_CONTROL_L1=y +CONFIG_MODULES_GIMBAL=y CONFIG_MODULES_GYRO_CALIBRATION=y CONFIG_MODULES_GYRO_FFT=y CONFIG_MODULES_LAND_DETECTOR=y @@ -61,7 +62,6 @@ CONFIG_MODULES_MC_AUTOTUNE_ATTITUDE_CONTROL=y CONFIG_MODULES_MC_HOVER_THRUST_ESTIMATOR=y CONFIG_MODULES_MC_POS_CONTROL=y CONFIG_MODULES_MC_RATE_CONTROL=y -CONFIG_MODULES_CONTROL_ALLOCATOR=y CONFIG_MODULES_NAVIGATOR=y CONFIG_MODULES_RC_UPDATE=y CONFIG_MODULES_ROVER_POS_CONTROL=y @@ -74,7 +74,6 @@ CONFIG_MODULES_SIMULATION_SIMULATOR_SIH=y CONFIG_MODULES_TEMPERATURE_COMPENSATION=y CONFIG_MODULES_UUV_ATT_CONTROL=y CONFIG_MODULES_UUV_POS_CONTROL=y -CONFIG_MODULES_GIMBAL=y CONFIG_MODULES_VTOL_ATT_CONTROL=y CONFIG_SYSTEMCMDS_ACTUATOR_TEST=y CONFIG_SYSTEMCMDS_BL_UPDATE=y diff --git a/boards/av/x-v1/src/board_config.h b/boards/av/x-v1/src/board_config.h index b87abf26c0..3fdf1375df 100644 --- a/boards/av/x-v1/src/board_config.h +++ b/boards/av/x-v1/src/board_config.h @@ -103,7 +103,6 @@ #define HRT_TIMER_CHANNEL 1 /* use capture/compare channel 3 */ /* RC Serial port */ - #define RC_SERIAL_PORT "/dev/ttyS4" /* Power switch controls ******************************************************/ diff --git a/boards/beaglebone/blue/default.px4board b/boards/beaglebone/blue/default.px4board index 7cef007869..51a31ca56a 100644 --- a/boards/beaglebone/blue/default.px4board +++ b/boards/beaglebone/blue/default.px4board @@ -3,6 +3,7 @@ CONFIG_BOARD_LINUX_TARGET=y CONFIG_BOARD_TOOLCHAIN="arm-linux-gnueabihf" CONFIG_BOARD_ARCHITECTURE="cortex-a8" CONFIG_BOARD_TESTING=y +CONFIG_BOARD_SERIAL_RC="/dev/ttyS4" CONFIG_DRIVERS_ADC_ADS1115=y CONFIG_DRIVERS_ADC_BOARD_ADC=y CONFIG_DRIVERS_BAROMETER_BMP280=y @@ -16,7 +17,7 @@ CONFIG_DRIVERS_IMU_INVENSENSE_ICM20948=y CONFIG_DRIVERS_IMU_INVENSENSE_MPU9250=y CONFIG_DRIVERS_LINUX_PWM_OUT=y CONFIG_DRIVERS_MAGNETOMETER_HMC5883=y -CONFIG_DRIVERS_RC_INPUT=y +CONFIG_COMMON_RC=y CONFIG_DRIVERS_SMART_BATTERY_BATMON=y CONFIG_MODULES_AIRSPEED_SELECTOR=y CONFIG_MODULES_ATTITUDE_ESTIMATOR_Q=y diff --git a/boards/cuav/nora/default.px4board b/boards/cuav/nora/default.px4board index 13ae300774..1613fe437f 100644 --- a/boards/cuav/nora/default.px4board +++ b/boards/cuav/nora/default.px4board @@ -31,7 +31,9 @@ CONFIG_DRIVERS_PCA9685=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_OUT=y -CONFIG_DRIVERS_RC_INPUT=y +CONFIG_COMMON_RC=y +CONFIG_BOARD_SERIAL_RC="/dev/ttyS5" +CONFIG_DRIVERS_RC_PPM_IN=y CONFIG_DRIVERS_ROBOCLAW=y CONFIG_DRIVERS_RPM=y CONFIG_DRIVERS_SAFETY_BUTTON=y diff --git a/boards/cuav/x7pro/default.px4board b/boards/cuav/x7pro/default.px4board index 07ed35b162..d0757c47a1 100644 --- a/boards/cuav/x7pro/default.px4board +++ b/boards/cuav/x7pro/default.px4board @@ -4,6 +4,7 @@ CONFIG_BOARD_SERIAL_GPS1="/dev/ttyS0" CONFIG_BOARD_SERIAL_GPS2="/dev/ttyS2" CONFIG_BOARD_SERIAL_TEL1="/dev/ttyS1" CONFIG_BOARD_SERIAL_TEL2="/dev/ttyS3" +CONFIG_BOARD_SERIAL_RC="/dev/ttyS5" CONFIG_DRIVERS_ADC_ADS1115=y CONFIG_DRIVERS_ADC_BOARD_ADC=y CONFIG_COMMON_BAROMETERS=y @@ -31,7 +32,8 @@ CONFIG_DRIVERS_PCA9685=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_OUT=y -CONFIG_DRIVERS_RC_INPUT=y +CONFIG_COMMON_RC=y +CONFIG_DRIVERS_RC_PPM_IN=y CONFIG_DRIVERS_ROBOCLAW=y CONFIG_DRIVERS_SAFETY_BUTTON=y CONFIG_DRIVERS_SMART_BATTERY_BATMON=y diff --git a/boards/cubepilot/cubeorange/extras/cubepilot_io-v2_default.bin b/boards/cubepilot/cubeorange/extras/cubepilot_io-v2_default.bin index 4d29f3a0415562d157333f3a3e4cf7b3dc991db0..464ef5e65ea906533d386a2ffc916138714fda94 100755 GIT binary patch delta 4048 zcmY*cZB$cNx_5QuFc=_VDB7h}+tA1;S1HV$vDe#~&Wfwk4z|5judUIkoo26?xiK zsu70y&45=l1OE4Bz}22VXrEW1G8)kDL}j$rFb?(8(}o;WMn5xj$LoIwxMxjeG424S zk#V~z7k5EP*f-yEVdOaxmC?m<$I((6hOq)-k)bvKW!dVp*i`B^C;@Nc$4!@j)8hghbDs(dPsMSJKOsa7FYe z`7?TpuC^{gGVLt3aO~IC1U>|TAThe)ZqDD zdJf_wf6dr56gh;Ub21Cm!?OdK=THrunpJ>mXl>TB$W9Mu?Hs{#$RZt+Jx|NK!aGt% zw`9M{neJuJi!^O&PFrO5ZO$!Zr`K{fKW%5;ggHD=C*ckxsY-y&l?A7{0(U|8p%%dB zH9!O>lFTk(A6pDJc)wQ#1Op)_ zG|-~~V#YvB7)Y4_BoPC-r~$$>K(0qpiN^uk3!?$kta;nfL(heIDT0XDok9Bf{8V9O z_~3%F_@84SsTc^)aTNpk3kEV@05ZB2?h)qJan{(4akBD8B!4g&i9q9ulXS|Csa_WfEQGd&B+HOM$q z3&d0ec83;-bR6)0x^D4i?IA4?4xUNBU;K)e!}UdA-{)EOVjN0CtR|#!S|xLZrUWs) zGQw%Di0OiEE{@m4KTZt-5Q!dLl3~53I2-~iA5=?364-}|jWw16k;~x%@6N z*IuuQL&nl5#UzLe^=#Q(WsL2Vy&7S90=kSQtFMn$6(E@311q_+U&aYezb-eOtE#KWI z@UPNn*UwNSYWkYvNX@Z?e!I3HvYGa(AE|q_K(5o2bxyTc3*>9Maa}3$(rfFAk=J8* z&4Z?Xr3Dg`iR>g3+4VXg6El%r)B(XdAYb!to&bDX3xtQ4N4zQ10pXo5q64qLioA49 z<%vvyp2vT*MPmun;Fg=1?aTYqa6 zSOtn$eNf{}tWf-G21Ypl_yCaNcPm7~?wGDprsM{F_oIM#qkw=dwTqF;u_`+`C93^ z+Hng4{#loYRR{bt<*xhrcEvxpd-{_%fzM_Cjc!OjUugQGnkar-7_9sx;Lnx$+7jlG ze4Q$ziQoBV_37ZQFTbmmKBzrrM(l5)lMcjQ3L-W&c*230IfU4lu&4QrS%RqeSBL07 z>JkcXM*-otgO}ny0l2o{Z~^qJDB>-x(*x1#fp|^;=4JABS4Uc2qaQBY8%3r15;J0@ z!MPG*U(1MHmKRHi(EwscgY=#H4@UC#aDLvN+fkmEcO;={ysf-tytO?hM@gmqN7fSwSVNF|iJhY>6#wr7)U`SBnI1imGkPFyJ&^nk zgEYe$_P-ydO`DU2Hv_b1^LXLo0PWwL6x%G%m4Ia^4hh)*DTv*dX=?Qb{i2}O-F2V6 z4c(XZ^quPG(-$9b9GI1Iq$ z>3w9gKT*~ZBFmpg-+v~&5o$^djJ1y0aanFk+V+pXRz#U(d0Z6$4$di+R4F(|Z3PAJ*Ad3t@ z<{N-4GypNR0nTp&yrd0qeH-9++5mgo0EgQEr=Fr)H>Rq9eM(Pnv^@)~M^-l-ks&v> z8q&9VtJ)nUz{^Zwf@ zz~@f^zI+NW*K_|AV6NqjQ-H~7z}{1UxkeTJWEcO3_Qze5^Y(?(C9C9;LjHNO#+}>6 zXHB7gUv3A#u6x`_LT7+kWR5~-LjD4}e76-v)B4>OHZiw#RlZ+10jy=ymcj-T#((9a}WN~TdOz8~xX9r1Vs>|N4a#>ue+o>*dyUMl1 zWtEN;6Dhx|j9MGx1X=VKvZ%S1v z0HE!M(rE9Ya{7?=pd5PRfXVaU2gV6)6Az2}>JOCdoDBdFH6BigB@m+;CIYYne?n8^ zVH3Ja>yH+TYCshsqNx}$`k-lh{FxTOnZna7 Xk?a6)mDV3yqE{3}u}=a}qLK3dyrzwN delta 4069 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 Xk?a6)mDV3yqE{3}u}=a}qLK3dyrzwN delta 4069 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 delta 4072 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 Ms4)Pl_yEBF0*mHmb^rhX diff --git a/boards/holybro/kakutef7/default.px4board b/boards/holybro/kakutef7/default.px4board index c4d16ff985..4c8c5f8458 100644 --- a/boards/holybro/kakutef7/default.px4board +++ b/boards/holybro/kakutef7/default.px4board @@ -12,9 +12,8 @@ CONFIG_DRIVERS_BAROMETER_BMP280=y CONFIG_DRIVERS_DSHOT=y CONFIG_DRIVERS_IMU_INVENSENSE_ICM20689=y CONFIG_DRIVERS_IMU_INVENSENSE_MPU6000=y -CONFIG_DRIVERS_OSD=y CONFIG_DRIVERS_PWM_OUT=y -CONFIG_DRIVERS_RC_INPUT=y +CONFIG_COMMON_RC=y CONFIG_DRIVERS_TELEMETRY_FRSKY_TELEMETRY=y CONFIG_MODULES_ATTITUDE_ESTIMATOR_Q=y CONFIG_MODULES_BATTERY_STATUS=y diff --git a/boards/holybro/kakutef7/src/board_config.h b/boards/holybro/kakutef7/src/board_config.h index 9254c57c52..3d3d146fcb 100644 --- a/boards/holybro/kakutef7/src/board_config.h +++ b/boards/holybro/kakutef7/src/board_config.h @@ -111,7 +111,6 @@ #define HRT_TIMER_CHANNEL 1 /* use capture/compare channel 1 */ /* RC Serial port */ - #define RC_SERIAL_PORT "/dev/ttyS4" #define GPIO_RSSI_IN /* PC5 */ (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTC|GPIO_PIN5) diff --git a/boards/holybro/kakuteh7/default.px4board b/boards/holybro/kakuteh7/default.px4board index 7ee74459bf..c96f76e111 100644 --- a/boards/holybro/kakuteh7/default.px4board +++ b/boards/holybro/kakuteh7/default.px4board @@ -18,12 +18,10 @@ CONFIG_DRIVERS_IMU_INVENSENSE_MPU6000=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y CONFIG_COMMON_OPTICAL_FLOW=y -CONFIG_DRIVERS_OSD=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_OUT=y -CONFIG_DRIVERS_RC_INPUT=y +CONFIG_COMMON_RC=y CONFIG_DRIVERS_ROBOCLAW=y -CONFIG_DRIVERS_RPM=y CONFIG_DRIVERS_SMART_BATTERY_BATMON=y CONFIG_COMMON_TELEMETRY=y CONFIG_DRIVERS_TONE_ALARM=y diff --git a/boards/holybro/pix32v5/default.px4board b/boards/holybro/pix32v5/default.px4board index 92e74327f8..49a72823b2 100644 --- a/boards/holybro/pix32v5/default.px4board +++ b/boards/holybro/pix32v5/default.px4board @@ -34,7 +34,9 @@ CONFIG_DRIVERS_PWM_INPUT=y CONFIG_DRIVERS_PWM_OUT=y CONFIG_MODULES_SIMULATION_PWM_OUT_SIM=y CONFIG_DRIVERS_PX4IO=y -CONFIG_DRIVERS_RC_INPUT=y +CONFIG_COMMON_RC=y +CONFIG_BOARD_SERIAL_RC="/dev/ttyS4" +CONFIG_DRIVERS_RC_PPM_IN=y CONFIG_DRIVERS_ROBOCLAW=y CONFIG_DRIVERS_RPM=y CONFIG_DRIVERS_SAFETY_BUTTON=y diff --git a/boards/holybro/pix32v5/extras/px4_io-v2_default.bin b/boards/holybro/pix32v5/extras/px4_io-v2_default.bin index 957f0f13a12e8eb8a7979955f29ad98d82433933..cad477b0e9232e7ff73192e3b1074f3137864089 100755 GIT binary patch delta 3980 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 delta 4072 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 Ms4)Pl_yEBF0*mHmb^rhX diff --git a/boards/holybro/pix32v5/src/board_config.h b/boards/holybro/pix32v5/src/board_config.h index 67b3909f78..b40363b0d1 100644 --- a/boards/holybro/pix32v5/src/board_config.h +++ b/boards/holybro/pix32v5/src/board_config.h @@ -283,7 +283,6 @@ #define GPIO_PPM_IN /* PI5 T8C1 */ GPIO_TIM8_CH1IN_2 /* RC Serial port */ - #define RC_SERIAL_PORT "/dev/ttyS4" #define RC_SERIAL_SINGLEWIRE diff --git a/boards/matek/h743-mini/default.px4board b/boards/matek/h743-mini/default.px4board index e654a21f97..7c319c6aa0 100644 --- a/boards/matek/h743-mini/default.px4board +++ b/boards/matek/h743-mini/default.px4board @@ -22,7 +22,8 @@ CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_OSD=y CONFIG_DRIVERS_PWM_OUT=y CONFIG_DRIVERS_PWM_OUT_SIM=n -CONFIG_DRIVERS_RC_INPUT=y +CONFIG_COMMON_RC=y +CONFIG_BOARD_SERIAL_RC="/dev/ttyS4" CONFIG_DRIVERS_RPM=n CONFIG_COMMON_TELEMETRY=y CONFIG_DRIVERS_TONE_ALARM=y diff --git a/boards/matek/h743-mini/src/board_config.h b/boards/matek/h743-mini/src/board_config.h index 151d6b59c5..9dfbf3df65 100644 --- a/boards/matek/h743-mini/src/board_config.h +++ b/boards/matek/h743-mini/src/board_config.h @@ -159,7 +159,6 @@ /* RC Serial port */ #define RC_SERIAL_PORT "/dev/ttyS4" -#define BOARD_SUPPORTS_RC_SERIAL_PORT_OUTPUT // #define GPIO_RSSI_IN /* PC5 */ (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTC|GPIO_PIN5) diff --git a/boards/matek/h743-slim/default.px4board b/boards/matek/h743-slim/default.px4board index 06c0cd20c3..4bcf41b846 100644 --- a/boards/matek/h743-slim/default.px4board +++ b/boards/matek/h743-slim/default.px4board @@ -21,7 +21,8 @@ CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_OSD=y CONFIG_DRIVERS_PWM_OUT=y CONFIG_DRIVERS_PWM_OUT_SIM=n -CONFIG_DRIVERS_RC_INPUT=y +CONFIG_COMMON_RC=y +CONFIG_BOARD_SERIAL_RC="/dev/ttyS4" CONFIG_DRIVERS_RPM=n CONFIG_COMMON_TELEMETRY=y CONFIG_DRIVERS_TONE_ALARM=y diff --git a/boards/matek/h743-slim/src/board_config.h b/boards/matek/h743-slim/src/board_config.h index f977a2e8dd..0ef600b9f3 100644 --- a/boards/matek/h743-slim/src/board_config.h +++ b/boards/matek/h743-slim/src/board_config.h @@ -150,7 +150,6 @@ /* RC Serial port */ #define RC_SERIAL_PORT "/dev/ttyS4" -#define BOARD_SUPPORTS_RC_SERIAL_PORT_OUTPUT // #define GPIO_RSSI_IN /* PC5 */ (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTC|GPIO_PIN5) diff --git a/boards/matek/h743/default.px4board b/boards/matek/h743/default.px4board index 0e3b91b463..269937dd13 100644 --- a/boards/matek/h743/default.px4board +++ b/boards/matek/h743/default.px4board @@ -22,7 +22,8 @@ CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_OSD=y CONFIG_DRIVERS_PWM_OUT=y CONFIG_DRIVERS_PWM_OUT_SIM=n -CONFIG_DRIVERS_RC_INPUT=y +CONFIG_COMMON_RC=y +CONFIG_BOARD_SERIAL_RC="/dev/ttyS4" CONFIG_DRIVERS_RPM=n CONFIG_COMMON_TELEMETRY=y CONFIG_DRIVERS_TONE_ALARM=y diff --git a/boards/matek/h743/src/board_config.h b/boards/matek/h743/src/board_config.h index 151d6b59c5..9dfbf3df65 100644 --- a/boards/matek/h743/src/board_config.h +++ b/boards/matek/h743/src/board_config.h @@ -159,7 +159,6 @@ /* RC Serial port */ #define RC_SERIAL_PORT "/dev/ttyS4" -#define BOARD_SUPPORTS_RC_SERIAL_PORT_OUTPUT // #define GPIO_RSSI_IN /* PC5 */ (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTC|GPIO_PIN5) diff --git a/boards/modalai/fc-v1/default.px4board b/boards/modalai/fc-v1/default.px4board index 5353dd0ceb..5ded2a4be2 100644 --- a/boards/modalai/fc-v1/default.px4board +++ b/boards/modalai/fc-v1/default.px4board @@ -30,7 +30,9 @@ CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_POWER_MONITOR_VOXLPM=y CONFIG_DRIVERS_PWM_OUT=y -CONFIG_DRIVERS_RC_INPUT=y +CONFIG_COMMON_RC=y +CONFIG_BOARD_SERIAL_RC="/dev/ttyS5" +CONFIG_DRIVERS_RC_PPM_IN=y CONFIG_DRIVERS_ROBOCLAW=y CONFIG_DRIVERS_SAFETY_BUTTON=y CONFIG_DRIVERS_SMART_BATTERY_BATMON=y diff --git a/boards/modalai/fc-v1/src/board_config.h b/boards/modalai/fc-v1/src/board_config.h index e67c0a5629..54212e5420 100644 --- a/boards/modalai/fc-v1/src/board_config.h +++ b/boards/modalai/fc-v1/src/board_config.h @@ -182,9 +182,7 @@ #define GPIO_PPM_IN /* PI5 T8C1 */ GPIO_TIM8_CH1IN_2 /* RC Serial port */ - #define RC_SERIAL_PORT "/dev/ttyS5" -#define BOARD_SUPPORTS_RC_SERIAL_PORT_OUTPUT /* Safety Switch: Enable the FMU to control it as there is no px4io in ModalAI FC-v1 */ #define GPIO_SAFETY_SWITCH_IN /* PF3 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_PORTF|GPIO_PIN3) diff --git a/boards/modalai/fc-v2/default.px4board b/boards/modalai/fc-v2/default.px4board index 83ac665636..e41be52b11 100644 --- a/boards/modalai/fc-v2/default.px4board +++ b/boards/modalai/fc-v2/default.px4board @@ -3,6 +3,7 @@ CONFIG_BOARD_ARCHITECTURE="cortex-m7" CONFIG_BOARD_SERIAL_GPS1="/dev/ttyS0" CONFIG_BOARD_SERIAL_TEL1="/dev/ttyS6" CONFIG_BOARD_SERIAL_TEL2="/dev/ttyS4" +CONFIG_BOARD_SERIAL_RC="/dev/ttyS5" CONFIG_DRIVERS_ACTUATORS_MODALAI_ESC=y CONFIG_DRIVERS_ADC_ADS1115=y CONFIG_DRIVERS_ADC_BOARD_ADC=y @@ -29,7 +30,7 @@ CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_POWER_MONITOR_VOXLPM=y CONFIG_DRIVERS_PWM_OUT=y -CONFIG_DRIVERS_RC_INPUT=y +CONFIG_COMMON_RC=y CONFIG_DRIVERS_ROBOCLAW=y CONFIG_COMMON_TELEMETRY=y CONFIG_DRIVERS_UAVCAN=y diff --git a/boards/modalai/fc-v2/src/board_config.h b/boards/modalai/fc-v2/src/board_config.h index 8aa70b5dc7..36abae249e 100644 --- a/boards/modalai/fc-v2/src/board_config.h +++ b/boards/modalai/fc-v2/src/board_config.h @@ -237,7 +237,6 @@ //#define GPIO_PPM_IN /* PI5 T8C1 */ GPIO_TIM8_CH1IN_2 /* RC Serial port */ - #define RC_SERIAL_PORT "/dev/ttyS5" /* Input Capture Channels. */ diff --git a/boards/mro/ctrl-zero-classic/default.px4board b/boards/mro/ctrl-zero-classic/default.px4board index 9bfb078b39..fedff17a34 100644 --- a/boards/mro/ctrl-zero-classic/default.px4board +++ b/boards/mro/ctrl-zero-classic/default.px4board @@ -26,7 +26,9 @@ CONFIG_DRIVERS_PCA9685=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_OUT=y -CONFIG_DRIVERS_RC_INPUT=y +CONFIG_COMMON_RC=y +CONFIG_BOARD_SERIAL_RC="/dev/ttyS3" +CONFIG_DRIVERS_RC_PPM_IN=y CONFIG_DRIVERS_ROBOCLAW=y CONFIG_DRIVERS_RPM=y CONFIG_DRIVERS_SMART_BATTERY_BATMON=y diff --git a/boards/mro/ctrl-zero-f7-oem/default.px4board b/boards/mro/ctrl-zero-f7-oem/default.px4board index e632bfedad..6c716ffe60 100644 --- a/boards/mro/ctrl-zero-f7-oem/default.px4board +++ b/boards/mro/ctrl-zero-f7-oem/default.px4board @@ -26,7 +26,9 @@ CONFIG_DRIVERS_PCA9685=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_OUT=y -CONFIG_DRIVERS_RC_INPUT=y +CONFIG_COMMON_RC=y +CONFIG_BOARD_SERIAL_RC="/dev/ttyS3" +CONFIG_DRIVERS_RC_PPM_IN=y CONFIG_DRIVERS_ROBOCLAW=y CONFIG_DRIVERS_RPM=y CONFIG_DRIVERS_SAFETY_BUTTON=y diff --git a/boards/mro/ctrl-zero-f7/default.px4board b/boards/mro/ctrl-zero-f7/default.px4board index 12a58fd397..31bc03a718 100644 --- a/boards/mro/ctrl-zero-f7/default.px4board +++ b/boards/mro/ctrl-zero-f7/default.px4board @@ -25,7 +25,9 @@ CONFIG_DRIVERS_PCA9685=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_OUT=y -CONFIG_DRIVERS_RC_INPUT=y +CONFIG_COMMON_RC=y +CONFIG_BOARD_SERIAL_RC="/dev/ttyS3" +CONFIG_DRIVERS_RC_PPM_IN=y CONFIG_DRIVERS_ROBOCLAW=y CONFIG_DRIVERS_RPM=y CONFIG_DRIVERS_SAFETY_BUTTON=y diff --git a/boards/mro/ctrl-zero-h7-oem/default.px4board b/boards/mro/ctrl-zero-h7-oem/default.px4board index 19b0058892..042011338f 100644 --- a/boards/mro/ctrl-zero-h7-oem/default.px4board +++ b/boards/mro/ctrl-zero-h7-oem/default.px4board @@ -26,7 +26,9 @@ CONFIG_DRIVERS_PCA9685=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_OUT=y -CONFIG_DRIVERS_RC_INPUT=y +CONFIG_COMMON_RC=y +CONFIG_BOARD_SERIAL_RC="/dev/ttyS3" +CONFIG_DRIVERS_RC_PPM_IN=y CONFIG_DRIVERS_ROBOCLAW=y CONFIG_DRIVERS_SMART_BATTERY_BATMON=y CONFIG_COMMON_TELEMETRY=y diff --git a/boards/mro/ctrl-zero-h7/default.px4board b/boards/mro/ctrl-zero-h7/default.px4board index 35e4a5110e..b04b9cc82e 100644 --- a/boards/mro/ctrl-zero-h7/default.px4board +++ b/boards/mro/ctrl-zero-h7/default.px4board @@ -25,7 +25,9 @@ CONFIG_DRIVERS_PCA9685=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_OUT=y -CONFIG_DRIVERS_RC_INPUT=y +CONFIG_COMMON_RC=y +CONFIG_BOARD_SERIAL_RC="/dev/ttyS3" +CONFIG_DRIVERS_RC_PPM_IN=y CONFIG_DRIVERS_ROBOCLAW=y CONFIG_DRIVERS_SMART_BATTERY_BATMON=y CONFIG_COMMON_TELEMETRY=y diff --git a/boards/mro/pixracerpro/default.px4board b/boards/mro/pixracerpro/default.px4board index 7474649fad..00d5eadc28 100644 --- a/boards/mro/pixracerpro/default.px4board +++ b/boards/mro/pixracerpro/default.px4board @@ -26,7 +26,9 @@ CONFIG_DRIVERS_PCA9685=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_OUT=y -CONFIG_DRIVERS_RC_INPUT=y +CONFIG_COMMON_RC=y +CONFIG_BOARD_SERIAL_RC="/dev/ttyS4" +CONFIG_DRIVERS_RC_PPM_IN=y CONFIG_DRIVERS_ROBOCLAW=y CONFIG_DRIVERS_SMART_BATTERY_BATMON=y CONFIG_COMMON_TELEMETRY=y diff --git a/boards/mro/pixracerpro/src/board_config.h b/boards/mro/pixracerpro/src/board_config.h index 0d067bb12c..0a2af629ce 100644 --- a/boards/mro/pixracerpro/src/board_config.h +++ b/boards/mro/pixracerpro/src/board_config.h @@ -118,7 +118,6 @@ /* RC Serial port */ #define RC_SERIAL_PORT "/dev/ttyS4" -#define BOARD_SUPPORTS_RC_SERIAL_PORT_OUTPUT #define GPIO_RSSI_IN /* PC1 */ (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTC|GPIO_PIN1) diff --git a/boards/mro/x21-777/extras/px4_io-v2_default.bin b/boards/mro/x21-777/extras/px4_io-v2_default.bin index 957f0f13a12e8eb8a7979955f29ad98d82433933..cad477b0e9232e7ff73192e3b1074f3137864089 100755 GIT binary patch delta 3980 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 delta 4072 zcmaJ^dvsG(y8phDq}eA;Xi5vDq~K1|LZ7tdp(sMrBBu=z3MgZFs2Kzea2FQwN`XQP ztxyz)#}>psrVonO3&^w+8L4Aw!O_JX_1>bRi-&WkTx0?R;^rYqlQie9-IiJ2e{R;w z+WXu4_x<+odz|F#?hfh84hhZexE^CqN+$YO*oe z+pf_>nI<;?$!`GiWCM^A?`ioF4VJJzV-=RL&8G4A7k1c`jV0_`Q&+;x1|Z!lOAE;f z;Q9b*kIx~UP!#qp^?oqys1{4uqPRv}&idls#2>t`$4}Dg>RW-hy`7eqag3NkBM`S1 zDDn?Gq}g#EoD}CSErhP+%sKi-N~sno*8-iB4#cAc8r28{bU=v?=uIuquombww#b@| zMQo>aCML44tl24vI-n0wrc5B@#7}o)t19hPcVlZFwqcR#|32^(vn5(}0#(BD6J1FI zGcC}2TA*5&)njkBc-n%M+##11A}uWh9Xp;_Ac2nENn9WXWlSv^y_d%vl}tiOuTUZs zv3KbgxSFl7EfJ`X3rCCLzik6U(DoWuv$aVd;bfL(w_+ljWzW-zAa1gqc9(7-BzD36 zg7BGEm69%e^~OuVCyhJzDS3j{j?~5w`bqt_EX;EXif{M0Z5|J3C7YOT6Ds{6??a+6ZKW z_k+iZHL)l4K+Q*hh%cCdn7yVMH}pbwa8|*9xO*&L87~%ADYZija^ZM1v)n@KFmodi zbXh#2|3JqU7cL%xoVHno&v%7$(achcGVnw1{GxZGFpAxnJ4Wu-0}bnee!^mlt$3DY z6=&nWv1g03F@e2RycsWgqvy5btf>U35CwqbX$k0O2|&*4fu3vx5+*?Z+z4b(j|Nf+ z&>RAkHtXT69w;S16A93H63}FZ3o`IOSk{8o37_bJ2J}FChK~QC5s0H82ClL81r-?f z=024oX(hfP%oZ<9)$9tbVX+J2*ujO5C(I^5g&J|{mjvkd1gKD?_x`wWJf?{yCjnYS zfbJqdM>YYuNq{aMf(duw5@yq%*=-Ue^W;GSBfId-B%N4!n#Go6V-CwN$wo6@%TQy%cfY|`Xc0$BT+7k+uR9VLYoLl{A^WAK*zB$OEYYDRi{(p+ao%KDiXh` zDo%-4L{LdpBtAve@M&!2(uG>&M^$!a>5<%HGSFM)6?rcY*G#)RLI-W~V9+9<8VP8g zNdr$CfMyzizDR(&S;Mm{v=W~l@gv4S`PowUUOdm_ir;@=}PA{UTAY#Jjh4?k(Df)D)k51zGdmo z2Sv+m1|n!hi=32Updz9|qKLnjfu5Fuo{@q6N*b(`sAyg@5D~W9=2h{G##`6Dff1)$QH2cFMbo-BLgiLr)Q!=G}}`4 z)k|N%GYihMuK zE|jjuUN&oOGuu-+RRUmVEBE2MY{^!u3As1?j1zf52)V?nw$53Me0zAlf_y~CsUZI{ zg#7C;{5-ETC7?C-Zb%78#zPydlIC9N3znJ4O9!xOP+Mkt!jz}xt6V~s?Z|;G{EjxE!QI79bnH@TeQfx2H3{x zBrWna0oGJKvIzOF1DAdK3_uSWfbMAlA_$u#pv(aD9Rtv}4L}bVfF5rF@^uT4pId-f z4*_u;0)M?~$c+K9GPAwV zRalfzhL7TnbFVBgBL}wW_1)4*l^M4uN$;sFXM3Xbj>_h4A6p@G2wg&x(DCCTAWAEc z1+74YzHO~Qgf>enkdIq|tZD@!G&i&Y$vL4NYf^T$C0|;p0KcjZcY2gQ|JaaJw@R6L zuW23Fs3I}oe^s;EF{$|8!L?KYejozLkV0Hz+^YX$46-LTCXPI50NP{#`o00^)DtFU zrY-EB)z7wUOqPBVWUU(~O70*#zcFceOP^??+<>U|wE*&4eayJ&730c?+}3%G?}n~6 z1AAlBBk4=_I`=*)*ZeIouLW!O7Xa67O_`9|lQ3aiPkb71UuD$!N4?rK;GeS_n=#HpeD7Ani&|hXUh1DwuM?m<04W7wnNjQ4{wCr0!2{L(H(AxU$90 zeF5xUveX_Nc6VPu(`)>P#%K%q?w zSO<4j<=6uw0U!R-r{OsBWcWTv^Nn>0F%RxTD4v zb2KVGDLr^$T$yIV=pHL;+?-aC;X}LQj%uq{qJ07ZNl88t9QNpEk90@3>s<+z<~nP; z-es<}dg9!gf#Qe)i$cFI4Yr#o_Sse-Zw|aK)4Z(feCGZ(qcTF#|9e8xK?V5t;kMf# zr~Os+pAL+e{q=R2`1$B!4s6zz>4`Ow5rVY}XwU~;zvO=3z<#@BTzdE2Pwmke<`eOX z`F!_X14NesZ&!yqfjc6=M@P&~;6F!zhg3HFm2DLkBhXAE&FRMJ5`gS;W%F}8MH+Eb+;4{8qhR|h+;(M33JSX_B0PmXH;9vO_-5ZRz!l%r&SUJyb#)ftt0FB<;C*4> z--Mf;z>oI>|1jchdUdv>jrjZe*{#<`7f>Tm@sA|}sW}W}bKd?u=>GK+BB3?L!Lq-3 z7>Ec`B)f7b;nhPyn~iMt`XUSPt6|aiuZDon4T;`Q3j@#YXGhlmewav(;1|iEM(?V! zB%C3VDiS6VD}KoYMw}rqS=V{t_O^GGZOR@cMv3@YICid1F)B1ESDB{(Zw|0OZ+JMW zWx$1<+4A=2kpIzs?bxVG=}NAG2UY)ZRXbL9G2pKWv(kzJZO9+p&;C#`R$3Tl-&M?z zE`{01%48`i%pR|tkX#;U^3aYeJ2gB;qsjR3T&kjR0$&^O`CjHD;HnS0jPJ4cwvR(I z`)d26BN9XDicRq-LI3}#`nH@-j}r2yGwTj3{ug^>hYcIqq8--Q{C9x7H3!Jl6GC~& zAI)ChF$vpP$Bq=K`xNWlkt!WM#SAr*(X*ceXdDj% Ms4)Pl_yEBF0*mHmb^rhX diff --git a/boards/mro/x21/extras/px4_io-v2_default.bin b/boards/mro/x21/extras/px4_io-v2_default.bin index 957f0f13a12e8eb8a7979955f29ad98d82433933..cad477b0e9232e7ff73192e3b1074f3137864089 100755 GIT binary patch delta 3980 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 delta 4072 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 Ms4)Pl_yEBF0*mHmb^rhX diff --git a/boards/nxp/fmuk66-e/default.px4board b/boards/nxp/fmuk66-e/default.px4board index dfab3337cd..04d0afd70d 100644 --- a/boards/nxp/fmuk66-e/default.px4board +++ b/boards/nxp/fmuk66-e/default.px4board @@ -27,7 +27,9 @@ CONFIG_DRIVERS_PCA9685=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_OUT=y -CONFIG_DRIVERS_RC_INPUT=y +CONFIG_COMMON_RC=y +CONFIG_BOARD_SERIAL_RC="/dev/ttyS2" +CONFIG_DRIVERS_RC_PPM_IN=y CONFIG_DRIVERS_ROBOCLAW=y CONFIG_DRIVERS_SAFETY_BUTTON=y CONFIG_DRIVERS_SMART_BATTERY_BATMON=y diff --git a/boards/nxp/fmuk66-e/src/board_config.h b/boards/nxp/fmuk66-e/src/board_config.h index af6c56a469..46053cef37 100644 --- a/boards/nxp/fmuk66-e/src/board_config.h +++ b/boards/nxp/fmuk66-e/src/board_config.h @@ -131,7 +131,6 @@ __END_DECLS #define SPEKTRUM_OUT(_one_true) px4_arch_gpiowrite(GPIO_PPM_IN_AS_OUT, (_one_true)) /* RC input */ - #define RC_SERIAL_PORT "/dev/ttyS2" /* UART1 */ #define GPIO_RSSI_IN PIN_ADC1_SE13 diff --git a/boards/nxp/fmuk66-v3/default.px4board b/boards/nxp/fmuk66-v3/default.px4board index 080a841a7e..65c1b35727 100644 --- a/boards/nxp/fmuk66-v3/default.px4board +++ b/boards/nxp/fmuk66-v3/default.px4board @@ -4,6 +4,7 @@ CONFIG_BOARD_CONSTRAINED_MEMORY=y CONFIG_BOARD_SERIAL_GPS1="/dev/ttyS3" CONFIG_BOARD_SERIAL_TEL1="/dev/ttyS4" CONFIG_BOARD_SERIAL_TEL2="/dev/ttyS1" +CONFIG_BOARD_SERIAL_RC="/dev/ttyS2" CONFIG_DRIVERS_ADC_ADS1115=y CONFIG_DRIVERS_ADC_BOARD_ADC=y CONFIG_COMMON_BAROMETERS=y @@ -28,7 +29,8 @@ CONFIG_DRIVERS_PCA9685=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_OUT=y -CONFIG_DRIVERS_RC_INPUT=y +CONFIG_COMMON_RC=y +CONFIG_DRIVERS_RC_PPM_IN=y CONFIG_DRIVERS_ROBOCLAW=y CONFIG_DRIVERS_SAFETY_BUTTON=y CONFIG_DRIVERS_SMART_BATTERY_BATMON=y diff --git a/boards/nxp/fmuk66-v3/src/board_config.h b/boards/nxp/fmuk66-v3/src/board_config.h index 56a5c0ceb1..9bf503dfb2 100644 --- a/boards/nxp/fmuk66-v3/src/board_config.h +++ b/boards/nxp/fmuk66-v3/src/board_config.h @@ -131,7 +131,6 @@ __END_DECLS #define SPEKTRUM_OUT(_one_true) px4_arch_gpiowrite(GPIO_PPM_IN_AS_OUT, (_one_true)) /* RC input */ - #define RC_SERIAL_PORT "/dev/ttyS2" /* UART1 */ #define GPIO_RSSI_IN PIN_ADC1_SE13 diff --git a/boards/nxp/fmurt1062-v1/default.px4board b/boards/nxp/fmurt1062-v1/default.px4board index 7d04b986f1..4c85b8cc02 100644 --- a/boards/nxp/fmurt1062-v1/default.px4board +++ b/boards/nxp/fmurt1062-v1/default.px4board @@ -19,7 +19,9 @@ CONFIG_DRIVERS_LIGHTS_RGBLED_PWM=y CONFIG_DRIVERS_MAGNETOMETER_HMC5883=y CONFIG_DRIVERS_MAGNETOMETER_ISENTEK_IST8310=y CONFIG_DRIVERS_PWM_OUT=y -CONFIG_DRIVERS_RC_INPUT=y +CONFIG_COMMON_RC=y +CONFIG_BOARD_SERIAL_RC="/dev/ttyS5" +CONFIG_DRIVERS_RC_PPM_IN=y CONFIG_DRIVERS_SAFETY_BUTTON=y CONFIG_DRIVERS_TONE_ALARM=y CONFIG_COMMON_UWB=y diff --git a/boards/omnibus/f4sd/default.px4board b/boards/omnibus/f4sd/default.px4board index 3de33fb7eb..9657c0cb90 100644 --- a/boards/omnibus/f4sd/default.px4board +++ b/boards/omnibus/f4sd/default.px4board @@ -14,7 +14,9 @@ CONFIG_DRIVERS_IMU_INVENSENSE_MPU6000=y CONFIG_DRIVERS_MAGNETOMETER_HMC5883=y CONFIG_DRIVERS_OSD=y CONFIG_DRIVERS_PWM_OUT=y -CONFIG_DRIVERS_RC_INPUT=y +CONFIG_COMMON_RC=y +CONFIG_BOARD_SERIAL_RC="/dev/ttyS0" +CONFIG_DRIVERS_RC_PPM_IN=y CONFIG_DRIVERS_TELEMETRY_FRSKY_TELEMETRY=y CONFIG_MODULES_ATTITUDE_ESTIMATOR_Q=y CONFIG_MODULES_BATTERY_STATUS=y diff --git a/boards/omnibus/f4sd/src/board_config.h b/boards/omnibus/f4sd/src/board_config.h index 627a42e9c0..1402a3a656 100644 --- a/boards/omnibus/f4sd/src/board_config.h +++ b/boards/omnibus/f4sd/src/board_config.h @@ -123,7 +123,6 @@ #define GPIO_PPM_IN (GPIO_ALT|GPIO_AF2|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN8) #define RC_SERIAL_PORT "/dev/ttyS0" -#define BOARD_SUPPORTS_RC_SERIAL_PORT_OUTPUT /* * One RC_IN diff --git a/boards/px4/fmu-v2/extras/px4_io-v2_default.bin b/boards/px4/fmu-v2/extras/px4_io-v2_default.bin index 957f0f13a12e8eb8a7979955f29ad98d82433933..cad477b0e9232e7ff73192e3b1074f3137864089 100755 GIT binary patch delta 3980 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 delta 4072 zcmaJ^dvsG(y8phDq}eA;Xi5vDq~K1|LZ7tdp(sMrBBu=z3MgZFs2Kzea2FQwN`XQP ztxyz)#}>psrVonO3&^w+8L4Aw!O_JX_1>bRi-&WkTx0?R;^rYqlQie9-IiJ2e{R;w z+WXu4_x<+odz|F#?hfh84hhZexE^CqN+$YO*oe z+pf_>nI<;?$!`GiWCM^A?`ioF4VJJzV-=RL&8G4A7k1c`jV0_`Q&+;x1|Z!lOAE;f z;Q9b*kIx~UP!#qp^?oqys1{4uqPRv}&idls#2>t`$4}Dg>RW-hy`7eqag3NkBM`S1 zDDn?Gq}g#EoD}CSErhP+%sKi-N~sno*8-iB4#cAc8r28{bU=v?=uIuquombww#b@| zMQo>aCML44tl24vI-n0wrc5B@#7}o)t19hPcVlZFwqcR#|32^(vn5(}0#(BD6J1FI zGcC}2TA*5&)njkBc-n%M+##11A}uWh9Xp;_Ac2nENn9WXWlSv^y_d%vl}tiOuTUZs zv3KbgxSFl7EfJ`X3rCCLzik6U(DoWuv$aVd;bfL(w_+ljWzW-zAa1gqc9(7-BzD36 zg7BGEm69%e^~OuVCyhJzDS3j{j?~5w`bqt_EX;EXif{M0Z5|J3C7YOT6Ds{6??a+6ZKW z_k+iZHL)l4K+Q*hh%cCdn7yVMH}pbwa8|*9xO*&L87~%ADYZija^ZM1v)n@KFmodi zbXh#2|3JqU7cL%xoVHno&v%7$(achcGVnw1{GxZGFpAxnJ4Wu-0}bnee!^mlt$3DY z6=&nWv1g03F@e2RycsWgqvy5btf>U35CwqbX$k0O2|&*4fu3vx5+*?Z+z4b(j|Nf+ z&>RAkHtXT69w;S16A93H63}FZ3o`IOSk{8o37_bJ2J}FChK~QC5s0H82ClL81r-?f z=024oX(hfP%oZ<9)$9tbVX+J2*ujO5C(I^5g&J|{mjvkd1gKD?_x`wWJf?{yCjnYS zfbJqdM>YYuNq{aMf(duw5@yq%*=-Ue^W;GSBfId-B%N4!n#Go6V-CwN$wo6@%TQy%cfY|`Xc0$BT+7k+uR9VLYoLl{A^WAK*zB$OEYYDRi{(p+ao%KDiXh` zDo%-4L{LdpBtAve@M&!2(uG>&M^$!a>5<%HGSFM)6?rcY*G#)RLI-W~V9+9<8VP8g zNdr$CfMyzizDR(&S;Mm{v=W~l@gv4S`PowUUOdm_ir;@=}PA{UTAY#Jjh4?k(Df)D)k51zGdmo z2Sv+m1|n!hi=32Updz9|qKLnjfu5Fuo{@q6N*b(`sAyg@5D~W9=2h{G##`6Dff1)$QH2cFMbo-BLgiLr)Q!=G}}`4 z)k|N%GYihMuK zE|jjuUN&oOGuu-+RRUmVEBE2MY{^!u3As1?j1zf52)V?nw$53Me0zAlf_y~CsUZI{ zg#7C;{5-ETC7?C-Zb%78#zPydlIC9N3znJ4O9!xOP+Mkt!jz}xt6V~s?Z|;G{EjxE!QI79bnH@TeQfx2H3{x zBrWna0oGJKvIzOF1DAdK3_uSWfbMAlA_$u#pv(aD9Rtv}4L}bVfF5rF@^uT4pId-f z4*_u;0)M?~$c+K9GPAwV zRalfzhL7TnbFVBgBL}wW_1)4*l^M4uN$;sFXM3Xbj>_h4A6p@G2wg&x(DCCTAWAEc z1+74YzHO~Qgf>enkdIq|tZD@!G&i&Y$vL4NYf^T$C0|;p0KcjZcY2gQ|JaaJw@R6L zuW23Fs3I}oe^s;EF{$|8!L?KYejozLkV0Hz+^YX$46-LTCXPI50NP{#`o00^)DtFU zrY-EB)z7wUOqPBVWUU(~O70*#zcFceOP^??+<>U|wE*&4eayJ&730c?+}3%G?}n~6 z1AAlBBk4=_I`=*)*ZeIouLW!O7Xa67O_`9|lQ3aiPkb71UuD$!N4?rK;GeS_n=#HpeD7Ani&|hXUh1DwuM?m<04W7wnNjQ4{wCr0!2{L(H(AxU$90 zeF5xUveX_Nc6VPu(`)>P#%K%q?w zSO<4j<=6uw0U!R-r{OsBWcWTv^Nn>0F%RxTD4v zb2KVGDLr^$T$yIV=pHL;+?-aC;X}LQj%uq{qJ07ZNl88t9QNpEk90@3>s<+z<~nP; z-es<}dg9!gf#Qe)i$cFI4Yr#o_Sse-Zw|aK)4Z(feCGZ(qcTF#|9e8xK?V5t;kMf# zr~Os+pAL+e{q=R2`1$B!4s6zz>4`Ow5rVY}XwU~;zvO=3z<#@BTzdE2Pwmke<`eOX z`F!_X14NesZ&!yqfjc6=M@P&~;6F!zhg3HFm2DLkBhXAE&FRMJ5`gS;W%F}8MH+Eb+;4{8qhR|h+;(M33JSX_B0PmXH;9vO_-5ZRz!l%r&SUJyb#)ftt0FB<;C*4> z--Mf;z>oI>|1jchdUdv>jrjZe*{#<`7f>Tm@sA|}sW}W}bKd?u=>GK+BB3?L!Lq-3 z7>Ec`B)f7b;nhPyn~iMt`XUSPt6|aiuZDon4T;`Q3j@#YXGhlmewav(;1|iEM(?V! zB%C3VDiS6VD}KoYMw}rqS=V{t_O^GGZOR@cMv3@YICid1F)B1ESDB{(Zw|0OZ+JMW zWx$1<+4A=2kpIzs?bxVG=}NAG2UY)ZRXbL9G2pKWv(kzJZO9+p&;C#`R$3Tl-&M?z zE`{01%48`i%pR|tkX#;U^3aYeJ2gB;qsjR3T&kjR0$&^O`CjHD;HnS0jPJ4cwvR(I z`)d26BN9XDicRq-LI3}#`nH@-j}r2yGwTj3{ug^>hYcIqq8--Q{C9x7H3!Jl6GC~& zAI)ChF$vpP$Bq=K`xNWlkt!WM#SAr*(X*ceXdDj% Ms4)Pl_yEBF0*mHmb^rhX diff --git a/boards/px4/fmu-v3/extras/px4_io-v2_default.bin b/boards/px4/fmu-v3/extras/px4_io-v2_default.bin index 957f0f13a12e8eb8a7979955f29ad98d82433933..cad477b0e9232e7ff73192e3b1074f3137864089 100755 GIT binary patch delta 3980 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 delta 4072 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 Ms4)Pl_yEBF0*mHmb^rhX diff --git a/boards/px4/fmu-v4/default.px4board b/boards/px4/fmu-v4/default.px4board index f016ee5820..4e6dffe765 100644 --- a/boards/px4/fmu-v4/default.px4board +++ b/boards/px4/fmu-v4/default.px4board @@ -4,6 +4,7 @@ CONFIG_BOARD_CONSTRAINED_MEMORY=y CONFIG_BOARD_SERIAL_GPS1="/dev/ttyS3" CONFIG_BOARD_SERIAL_TEL1="/dev/ttyS1" CONFIG_BOARD_SERIAL_TEL2="/dev/ttyS2" +CONFIG_BOARD_SERIAL_RC="/dev/ttyS4" CONFIG_BOARD_SERIAL_WIFI="/dev/ttyS0" CONFIG_DRIVERS_ADC_ADS1115=y CONFIG_DRIVERS_ADC_BOARD_ADC=y @@ -30,7 +31,8 @@ CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_INPUT=y CONFIG_DRIVERS_PWM_OUT=y -CONFIG_DRIVERS_RC_INPUT=y +CONFIG_COMMON_RC=y +CONFIG_DRIVERS_RC_PPM_IN=y CONFIG_DRIVERS_ROBOCLAW=y CONFIG_DRIVERS_SAFETY_BUTTON=y CONFIG_DRIVERS_SMART_BATTERY_BATMON=y diff --git a/boards/px4/fmu-v4/src/board_config.h b/boards/px4/fmu-v4/src/board_config.h index ef6571d84d..89f53a201b 100644 --- a/boards/px4/fmu-v4/src/board_config.h +++ b/boards/px4/fmu-v4/src/board_config.h @@ -114,7 +114,6 @@ #define GPIO_PPM_IN (GPIO_ALT|GPIO_AF2|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN0) /* RC Serial port */ - #define RC_SERIAL_PORT "/dev/ttyS4" /* PWM input driver. Use FMU AUX5 pins attached to timer4 channel 2. */ diff --git a/boards/px4/fmu-v4pro/extras/px4_io-v2_default.bin b/boards/px4/fmu-v4pro/extras/px4_io-v2_default.bin index 957f0f13a12e8eb8a7979955f29ad98d82433933..cad477b0e9232e7ff73192e3b1074f3137864089 100755 GIT binary patch delta 3980 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 delta 4072 zcmaJ^dvsG(y8phDq}eA;Xi5vDq~K1|LZ7tdp(sMrBBu=z3MgZFs2Kzea2FQwN`XQP ztxyz)#}>psrVonO3&^w+8L4Aw!O_JX_1>bRi-&WkTx0?R;^rYqlQie9-IiJ2e{R;w z+WXu4_x<+odz|F#?hfh84hhZexE^CqN+$YO*oe z+pf_>nI<;?$!`GiWCM^A?`ioF4VJJzV-=RL&8G4A7k1c`jV0_`Q&+;x1|Z!lOAE;f z;Q9b*kIx~UP!#qp^?oqys1{4uqPRv}&idls#2>t`$4}Dg>RW-hy`7eqag3NkBM`S1 zDDn?Gq}g#EoD}CSErhP+%sKi-N~sno*8-iB4#cAc8r28{bU=v?=uIuquombww#b@| zMQo>aCML44tl24vI-n0wrc5B@#7}o)t19hPcVlZFwqcR#|32^(vn5(}0#(BD6J1FI zGcC}2TA*5&)njkBc-n%M+##11A}uWh9Xp;_Ac2nENn9WXWlSv^y_d%vl}tiOuTUZs zv3KbgxSFl7EfJ`X3rCCLzik6U(DoWuv$aVd;bfL(w_+ljWzW-zAa1gqc9(7-BzD36 zg7BGEm69%e^~OuVCyhJzDS3j{j?~5w`bqt_EX;EXif{M0Z5|J3C7YOT6Ds{6??a+6ZKW z_k+iZHL)l4K+Q*hh%cCdn7yVMH}pbwa8|*9xO*&L87~%ADYZija^ZM1v)n@KFmodi zbXh#2|3JqU7cL%xoVHno&v%7$(achcGVnw1{GxZGFpAxnJ4Wu-0}bnee!^mlt$3DY z6=&nWv1g03F@e2RycsWgqvy5btf>U35CwqbX$k0O2|&*4fu3vx5+*?Z+z4b(j|Nf+ z&>RAkHtXT69w;S16A93H63}FZ3o`IOSk{8o37_bJ2J}FChK~QC5s0H82ClL81r-?f z=024oX(hfP%oZ<9)$9tbVX+J2*ujO5C(I^5g&J|{mjvkd1gKD?_x`wWJf?{yCjnYS zfbJqdM>YYuNq{aMf(duw5@yq%*=-Ue^W;GSBfId-B%N4!n#Go6V-CwN$wo6@%TQy%cfY|`Xc0$BT+7k+uR9VLYoLl{A^WAK*zB$OEYYDRi{(p+ao%KDiXh` zDo%-4L{LdpBtAve@M&!2(uG>&M^$!a>5<%HGSFM)6?rcY*G#)RLI-W~V9+9<8VP8g zNdr$CfMyzizDR(&S;Mm{v=W~l@gv4S`PowUUOdm_ir;@=}PA{UTAY#Jjh4?k(Df)D)k51zGdmo z2Sv+m1|n!hi=32Updz9|qKLnjfu5Fuo{@q6N*b(`sAyg@5D~W9=2h{G##`6Dff1)$QH2cFMbo-BLgiLr)Q!=G}}`4 z)k|N%GYihMuK zE|jjuUN&oOGuu-+RRUmVEBE2MY{^!u3As1?j1zf52)V?nw$53Me0zAlf_y~CsUZI{ zg#7C;{5-ETC7?C-Zb%78#zPydlIC9N3znJ4O9!xOP+Mkt!jz}xt6V~s?Z|;G{EjxE!QI79bnH@TeQfx2H3{x zBrWna0oGJKvIzOF1DAdK3_uSWfbMAlA_$u#pv(aD9Rtv}4L}bVfF5rF@^uT4pId-f z4*_u;0)M?~$c+K9GPAwV zRalfzhL7TnbFVBgBL}wW_1)4*l^M4uN$;sFXM3Xbj>_h4A6p@G2wg&x(DCCTAWAEc z1+74YzHO~Qgf>enkdIq|tZD@!G&i&Y$vL4NYf^T$C0|;p0KcjZcY2gQ|JaaJw@R6L zuW23Fs3I}oe^s;EF{$|8!L?KYejozLkV0Hz+^YX$46-LTCXPI50NP{#`o00^)DtFU zrY-EB)z7wUOqPBVWUU(~O70*#zcFceOP^??+<>U|wE*&4eayJ&730c?+}3%G?}n~6 z1AAlBBk4=_I`=*)*ZeIouLW!O7Xa67O_`9|lQ3aiPkb71UuD$!N4?rK;GeS_n=#HpeD7Ani&|hXUh1DwuM?m<04W7wnNjQ4{wCr0!2{L(H(AxU$90 zeF5xUveX_Nc6VPu(`)>P#%K%q?w zSO<4j<=6uw0U!R-r{OsBWcWTv^Nn>0F%RxTD4v zb2KVGDLr^$T$yIV=pHL;+?-aC;X}LQj%uq{qJ07ZNl88t9QNpEk90@3>s<+z<~nP; z-es<}dg9!gf#Qe)i$cFI4Yr#o_Sse-Zw|aK)4Z(feCGZ(qcTF#|9e8xK?V5t;kMf# zr~Os+pAL+e{q=R2`1$B!4s6zz>4`Ow5rVY}XwU~;zvO=3z<#@BTzdE2Pwmke<`eOX z`F!_X14NesZ&!yqfjc6=M@P&~;6F!zhg3HFm2DLkBhXAE&FRMJ5`gS;W%F}8MH+Eb+;4{8qhR|h+;(M33JSX_B0PmXH;9vO_-5ZRz!l%r&SUJyb#)ftt0FB<;C*4> z--Mf;z>oI>|1jchdUdv>jrjZe*{#<`7f>Tm@sA|}sW}W}bKd?u=>GK+BB3?L!Lq-3 z7>Ec`B)f7b;nhPyn~iMt`XUSPt6|aiuZDon4T;`Q3j@#YXGhlmewav(;1|iEM(?V! zB%C3VDiS6VD}KoYMw}rqS=V{t_O^GGZOR@cMv3@YICid1F)B1ESDB{(Zw|0OZ+JMW zWx$1<+4A=2kpIzs?bxVG=}NAG2UY)ZRXbL9G2pKWv(kzJZO9+p&;C#`R$3Tl-&M?z zE`{01%48`i%pR|tkX#;U^3aYeJ2gB;qsjR3T&kjR0$&^O`CjHD;HnS0jPJ4cwvR(I z`)d26BN9XDicRq-LI3}#`nH@-j}r2yGwTj3{ug^>hYcIqq8--Q{C9x7H3!Jl6GC~& zAI)ChF$vpP$Bq=K`xNWlkt!WM#SAr*(X*ceXdDj% Ms4)Pl_yEBF0*mHmb^rhX diff --git a/boards/px4/fmu-v5/default.px4board b/boards/px4/fmu-v5/default.px4board index 9b596385ae..5544577f8e 100644 --- a/boards/px4/fmu-v5/default.px4board +++ b/boards/px4/fmu-v5/default.px4board @@ -4,6 +4,7 @@ CONFIG_BOARD_SERIAL_GPS1="/dev/ttyS0" CONFIG_BOARD_SERIAL_TEL1="/dev/ttyS1" CONFIG_BOARD_SERIAL_TEL2="/dev/ttyS2" CONFIG_BOARD_SERIAL_TEL4="/dev/ttyS3" +CONFIG_BOARD_SERIAL_RC="/dev/ttyS4" CONFIG_DRIVERS_ADC_ADS1115=y CONFIG_DRIVERS_ADC_BOARD_ADC=y CONFIG_COMMON_BAROMETERS=y @@ -35,7 +36,8 @@ CONFIG_DRIVERS_PWM_INPUT=y CONFIG_DRIVERS_PWM_OUT=y CONFIG_DRIVERS_PX4IO=y CONFIG_COMMON_RC=y -CONFIG_DRIVERS_RC_INPUT=y +CONFIG_COMMON_RC=y +CONFIG_DRIVERS_RC_PPM_IN=y CONFIG_DRIVERS_ROBOCLAW=y CONFIG_DRIVERS_SAFETY_BUTTON=y CONFIG_DRIVERS_SMART_BATTERY_BATMON=y diff --git a/boards/px4/fmu-v5/extras/px4_io-v2_default.bin b/boards/px4/fmu-v5/extras/px4_io-v2_default.bin index 957f0f13a12e8eb8a7979955f29ad98d82433933..cad477b0e9232e7ff73192e3b1074f3137864089 100755 GIT binary patch delta 3980 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 delta 4072 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 Ms4)Pl_yEBF0*mHmb^rhX diff --git a/boards/px4/fmu-v5/src/board_config.h b/boards/px4/fmu-v5/src/board_config.h index 8246664dec..d9393d6c09 100644 --- a/boards/px4/fmu-v5/src/board_config.h +++ b/boards/px4/fmu-v5/src/board_config.h @@ -297,10 +297,8 @@ #define GPIO_PPM_IN /* PI5 T8C1 */ GPIO_TIM8_CH1IN_2 /* RC Serial port */ - #define RC_SERIAL_PORT "/dev/ttyS4" #define RC_SERIAL_SINGLEWIRE -#define BOARD_SUPPORTS_RC_SERIAL_PORT_OUTPUT /* PWM input driver. Use FMU AUX5 pins attached to timer4 channel 2 */ #define PWMIN_TIMER 4 diff --git a/boards/px4/fmu-v5/uavcanv0periph.px4board b/boards/px4/fmu-v5/uavcanv0periph.px4board index e8bcc526a1..aab5a950d7 100644 --- a/boards/px4/fmu-v5/uavcanv0periph.px4board +++ b/boards/px4/fmu-v5/uavcanv0periph.px4board @@ -18,8 +18,10 @@ CONFIG_EXAMPLES_FAKE_GPS=n CONFIG_MODULES_ATTITUDE_ESTIMATOR_Q=n CONFIG_MODULES_CAMERA_FEEDBACK=n CONFIG_MODULES_ESC_BATTERY=n -CONFIG_MODULES_GYRO_FFT=n +CONFIG_MODULES_FW_AUTOTUNE_ATTITUDE_CONTROL=n +# CONFIG_MODULES_GYRO_FFT is not set CONFIG_MODULES_LOCAL_POSITION_ESTIMATOR=n +CONFIG_MODULES_MC_AUTOTUNE_ATTITUDE_CONTROL=n CONFIG_MODULES_MICRODDS_CLIENT=n CONFIG_MODULES_ROVER_POS_CONTROL=n CONFIG_MODULES_TEMPERATURE_COMPENSATION=n diff --git a/boards/px4/fmu-v5x/default.px4board b/boards/px4/fmu-v5x/default.px4board index 6a2c121548..b44e8459c0 100644 --- a/boards/px4/fmu-v5x/default.px4board +++ b/boards/px4/fmu-v5x/default.px4board @@ -6,6 +6,7 @@ CONFIG_BOARD_SERIAL_GPS2="/dev/ttyS7" CONFIG_BOARD_SERIAL_TEL1="/dev/ttyS6" CONFIG_BOARD_SERIAL_TEL2="/dev/ttyS4" CONFIG_BOARD_SERIAL_TEL3="/dev/ttyS1" +CONFIG_BOARD_SERIAL_RC="/dev/ttyS5" CONFIG_DRIVERS_ADC_ADS1115=y CONFIG_DRIVERS_ADC_BOARD_ADC=y CONFIG_DRIVERS_BAROMETER_BMP388=y @@ -36,7 +37,6 @@ CONFIG_DRIVERS_POWER_MONITOR_INA238=y CONFIG_DRIVERS_PWM_OUT=y CONFIG_DRIVERS_PX4IO=y CONFIG_COMMON_RC=y -CONFIG_DRIVERS_RC_INPUT=y CONFIG_DRIVERS_ROBOCLAW=y CONFIG_DRIVERS_SAFETY_BUTTON=y CONFIG_DRIVERS_SMART_BATTERY_BATMON=y @@ -59,7 +59,6 @@ CONFIG_MODULES_FW_AUTOTUNE_ATTITUDE_CONTROL=y CONFIG_MODULES_FW_POS_CONTROL_L1=y CONFIG_MODULES_GIMBAL=y CONFIG_MODULES_GYRO_CALIBRATION=y -CONFIG_MODULES_GYRO_FFT=n CONFIG_MODULES_LAND_DETECTOR=y CONFIG_MODULES_LANDING_TARGET_ESTIMATOR=y CONFIG_MODULES_LOAD_MON=y diff --git a/boards/px4/fmu-v5x/extras/px4_io-v2_default.bin b/boards/px4/fmu-v5x/extras/px4_io-v2_default.bin index 957f0f13a12e8eb8a7979955f29ad98d82433933..cad477b0e9232e7ff73192e3b1074f3137864089 100755 GIT binary patch delta 3980 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 delta 4072 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 Ms4)Pl_yEBF0*mHmb^rhX diff --git a/boards/px4/fmu-v5x/src/board_config.h b/boards/px4/fmu-v5x/src/board_config.h index 281c769f26..32ea72ad18 100644 --- a/boards/px4/fmu-v5x/src/board_config.h +++ b/boards/px4/fmu-v5x/src/board_config.h @@ -301,7 +301,6 @@ #define GPIO_PPM_IN /* PI5 T8C1 */ GPIO_TIM8_CH1IN_2 /* RC Serial port */ - #define RC_SERIAL_PORT "/dev/ttyS5" #define RC_SERIAL_SINGLEWIRE diff --git a/boards/px4/fmu-v6c/extras/px4_io-v2_default.bin b/boards/px4/fmu-v6c/extras/px4_io-v2_default.bin index 957f0f13a12e8eb8a7979955f29ad98d82433933..cad477b0e9232e7ff73192e3b1074f3137864089 100755 GIT binary patch delta 3980 zcmY*c4OCRuwch8>9p=n%M*#=Jf6g$V{12$lXst4!UYLvqv@t=WhUZU%+Gj8(iV>nw zqF|F+-P$5*0hO-ApAtXyIX?PkR4se#}6Mv0vFvim}Q%o^)Ze)k%u+OKV5;&BH)DSCtpg)4)v{ zZM9|7b|@V1J?T9)>V!;+ap9N-vKafv{F3x~U$ae=jhCB&mU!Evo+t5QI`BK7B{DF= z-)WN`A5%sqjwvlKfR4rJj=7y&CIh=E1Dl%$v{VKrH2~FQU|yP99wUZ;eFLe)b&2nhY)o~;5*yBT2W-h73s?0}79PZED9wPS8WK77KZx&q<9Vy05 zS!+b58(H&5nl{~ebY%9m^9qT>v)LOTwlinqToGtd>1m=G3W3klBu`W+ZHJEX2B0TR zz$6b*qsoAPdm z)K7{G;VmX$%5k9L4`DzRuXV<4lb{`#oj*kGTg+3(i-px{{m6p3U_4PUryzEe(g2ir zqRPba(_~y!uxJD_qT=5Ro*)V)7p9Yw-g$)wLWqpFpNKb~F#+o{0ec6-i(*M9W)?X~ zGcGA|l1K23qAJqk4J~dZv$H8MK?;D-CnaEKqk(pbum+%g6xhcNK!4q307ikOP++Xd z1f3>eQ52Ys0xOn)#UYuWPW~G+=dX!=#{`Up&xUS?G>pn9um<6sn zGqAbd3neBJKGzJ)HVa(y%)k;Gf!5)jg&WO>%)kVAF0NbjoLRt?S>W2|y}D=&NhSQv zpvhxbqe@MMgip~!JW-`#?a(2(iIT)qt6BnC0_M_ zs41$%C+Y@16;~}@AWQs|h950Ho^#9$?EA_sxz9%!rrnD)!kgydqD4V960lsW0p?hM zC0T$irNBz?@RF4>;oXDYkfqCrEb+HB{Kd1c$P%yZ$M2tgJh|8cOdDyPpw(ywCb9~u zE~^0o6xdSllG1A=>a7nQH9e*qUuJmH)b^Xa!0wJJBRt_lELk>1A_KU0S(^KyXqinw zMOtx0TFfw{h)_s~c-#!E%?#{)Gq9(mVWotk)0%*aBHT?t&!BO+IK(;2J%m(X)r#jx z1%AC^rtw2Fu=AL?(nHSSrj^r-15H3HylpF;0(R@?pNF3_1FL8P3K_&D4qFL+`rIdG zvHH3Mtisz=_9z*NI=iZYgb3_F6Rut}V`TNznj*>AYX;VZWUa^8V+M8u=dCRwJ=nCi zfb@88t@V=W*UiAfGKh<15SPsYY*GesDHdR17GO8bz$%Xby=ev}!b?XKDX{<({host z%GZz{oV~6o1EBNXUmT(7VW(|sSWo9Y3xt*v9y=J}Cj5Ai@akZgoA74`2wypf-&Ags zdP8w-Rm|jmf3XG`371x>OeOr6fug>vIb~|U|Lh=BAxS#8T6Od_t_Qn>gufavdE!cS z|EfX!Q`OiI9tx}{6fagyNa_s*c0Lr?xlmwTp}=ZH1*gq(9A%JhxH!{3;QvC$>{p^l zBf4Kn{nFqbCxOD%#j=cN3K+HA&@(xHknQyyT!F0br2zKGo{2%GU z{vjwLh5f!xCf)Wue%Aumd{f#R@$4%HqX_>Zc*ITk@&Mt}15Iwiqk@Dd40tQHJT8^$ z{*}S8p1<4zlI^2y7L_oPV@v&AH?X5V=(rgQOz131dHo2`s@(m#(D|RUN)%u<3NV`j zZ1)kMqRb2h*j5EtmIAC=87{jg6ce`fdC5c6Sb?cZ4 zygC3$kW4-CrMmy!e$!Bcm>S}VFEzJhw-<4J(hol9Xxu^IoC2&x0d__KHs!Qc6}sjP zq~gX3hqS974^>Q%7WZRUMPkGuZJr7|U3aU%|4%3UriSvS7nG+1=9c!Gd^dD-D!6Ua zV`&TbxcAI4*Id!&{E^h}&j&8Qnw*u=6`eJ%%a#iK#@3LYsa`o1_*uNRDV= z$8h?~k8Iht73`}E{~q(J{0XY-?jN>(w3y_8M$+&59Ix2Yr}Yp!2^j8?J7M9`E=axB z^}Y(@-pikK0hp3V)TJIN7&2k6CUt&z2S$(T8dI@XBfXAU&r~=9qwek1486)X21N;s z8gPB10Ld|=N_S-GMmO*i`a%`>jA;)= zDkM(B=Qqb&3w%;q;KH~HLsm>z93I%58k^xG4%c1Xen?e(MVu&*=JJ|H^=@I zI)pevq&FpCyGDcxJ1SnpEI0EOpSiz9Q6p8;ThWPiD)94K%N;PM{_}yqL&wRLg>kzc zL<)Jf0}J^6J=qxr>nq1$Z}r}o0e^ueCxl!|Q*%^Or~BX5X}}+? zL5h4SO|=iXdv!xgc6-=q-T(avaJi0mUz;J_(s9C$Bq>|Rk{wy&YJ!brtnFH@fsZyA z(!c9YQ4Mb3RY9Ncc^(O0`=F!iC{VnyZVIv&_NLbBXYyVA)K*^wah7yRPT+5C1*eO@ zxwUZ<@Fjy!yMccj1bz}Py)f4XJbO@_$Bv-TY{LNX%0axmJ}L`%%#h=)AxG%|@ShLD zzlzI~HAy+=6R9kNnQq_*g1{FJ;&0aT;Qx#G;(r)`zm1=~xJ3s3U;X&RODh=gsr}WyXwPMjKSt|nGywib8_3ZpB?RC2rfh52E? zkK^YXc1z1NT(L1xD%P-OW1N(y;qNyl{6z2&yaXq~!`Te9rWxqIW}t%KUz>pnZi~b{ zsTt_WW}t%em1aD?V;oVid&ktsgrGQ8Wop2GT{pF4x0k6we+E9fGnRDYw4HX+giChD zhEM-3&^P7+opM?{DuaG2*6y50PGI}aWa*s`@cPaaso?`0RWm7VQUFr!T>Rc=QH%O^ zt<(LLA3&n(Ze+Ob-}r%ek6KismX_)MYeD=)O%fT0dukqg1nVBAw|HbVw#+^7xMC0h5Vr>7k4AB+0sxSW!+yn^ zx4Xz-007*xKN%bMhv2*WpTcwdI*Ajz_u9Ni_l}p2hW$n+hcLW;d{~%aI3B1L&iP{{J+qc3c1e delta 4072 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 Ms4)Pl_yEBF0*mHmb^rhX diff --git a/boards/px4/fmu-v6u/default.px4board b/boards/px4/fmu-v6u/default.px4board index 9a5289b998..c1511f4a9d 100644 --- a/boards/px4/fmu-v6u/default.px4board +++ b/boards/px4/fmu-v6u/default.px4board @@ -29,7 +29,9 @@ CONFIG_DRIVERS_PCA9685=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_OUT=y -CONFIG_DRIVERS_RC_INPUT=y +CONFIG_COMMON_RC=y +CONFIG_BOARD_SERIAL_RC="/dev/ttyS5" +CONFIG_DRIVERS_RC_PPM_IN=y CONFIG_DRIVERS_ROBOCLAW=y CONFIG_DRIVERS_SAFETY_BUTTON=y CONFIG_DRIVERS_SMART_BATTERY_BATMON=y diff --git a/boards/px4/fmu-v6u/src/board_config.h b/boards/px4/fmu-v6u/src/board_config.h index a61f2a5a57..a0496389d6 100644 --- a/boards/px4/fmu-v6u/src/board_config.h +++ b/boards/px4/fmu-v6u/src/board_config.h @@ -257,7 +257,6 @@ #define GPIO_PPM_IN /* PI5 T8C1 */ GPIO_TIM8_CH1IN_2 /* RC Serial port */ - #define RC_SERIAL_PORT "/dev/ttyS5" #define RC_SERIAL_SINGLEWIRE #define RC_SERIAL_SWAP_RXTX diff --git a/boards/px4/fmu-v6x/default.px4board b/boards/px4/fmu-v6x/default.px4board index ee85f7ccc2..2f5ac4b1c6 100644 --- a/boards/px4/fmu-v6x/default.px4board +++ b/boards/px4/fmu-v6x/default.px4board @@ -6,7 +6,7 @@ CONFIG_BOARD_SERIAL_GPS2="/dev/ttyS7" CONFIG_BOARD_SERIAL_TEL1="/dev/ttyS6" CONFIG_BOARD_SERIAL_TEL2="/dev/ttyS4" CONFIG_BOARD_SERIAL_TEL3="/dev/ttyS1" -CONFIG_BOARD_SERIAL_EXT2="/dev/ttyS3" +CONFIG_BOARD_SERIAL_RC="/dev/ttyS5" CONFIG_DRIVERS_ADC_BOARD_ADC=y CONFIG_DRIVERS_BAROMETER_BMP388=y CONFIG_DRIVERS_BAROMETER_INVENSENSE_ICP201XX=y @@ -28,13 +28,13 @@ CONFIG_DRIVERS_IMU_INVENSENSE_ICM42688P=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y CONFIG_COMMON_OPTICAL_FLOW=y -CONFIG_COMMON_OSD=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_POWER_MONITOR_INA228=y CONFIG_DRIVERS_POWER_MONITOR_INA238=y CONFIG_DRIVERS_PWM_OUT=y CONFIG_DRIVERS_PX4IO=y -CONFIG_DRIVERS_RC_INPUT=y +CONFIG_COMMON_RC=y +CONFIG_DRIVERS_RC_PPM_IN=y CONFIG_DRIVERS_SAFETY_BUTTON=y CONFIG_DRIVERS_TONE_ALARM=y CONFIG_DRIVERS_UAVCAN=y diff --git a/boards/px4/fmu-v6x/extras/px4_io-v2_default.bin b/boards/px4/fmu-v6x/extras/px4_io-v2_default.bin index 957f0f13a12e8eb8a7979955f29ad98d82433933..cad477b0e9232e7ff73192e3b1074f3137864089 100755 GIT binary patch delta 3980 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 delta 4072 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 Ms4)Pl_yEBF0*mHmb^rhX diff --git a/boards/px4/fmu-v6x/src/board_config.h b/boards/px4/fmu-v6x/src/board_config.h index fecd7efc9c..faa4f77d1d 100644 --- a/boards/px4/fmu-v6x/src/board_config.h +++ b/boards/px4/fmu-v6x/src/board_config.h @@ -333,7 +333,6 @@ #define GPIO_PPM_IN /* PI5 T8C1 */ GPIO_TIM8_CH1IN_2 /* RC Serial port */ - #define RC_SERIAL_PORT "/dev/ttyS5" #define RC_SERIAL_SINGLEWIRE diff --git a/boards/px4/raspberrypi/default.px4board b/boards/px4/raspberrypi/default.px4board index 74aca7c7d8..7ed9175c93 100644 --- a/boards/px4/raspberrypi/default.px4board +++ b/boards/px4/raspberrypi/default.px4board @@ -3,6 +3,7 @@ CONFIG_BOARD_LINUX_TARGET=y CONFIG_BOARD_TOOLCHAIN="arm-linux-gnueabihf" CONFIG_BOARD_ARCHITECTURE="cortex-a53" CONFIG_BOARD_TESTING=y +CONFIG_BOARD_SERIAL_RC="/dev/ttyS4" CONFIG_DRIVERS_ADC_ADS1115=y CONFIG_DRIVERS_BAROMETER_MS5611=y CONFIG_DRIVERS_BATT_SMBUS=y @@ -14,7 +15,7 @@ CONFIG_DRIVERS_IMU_INVENSENSE_ICM20948=y CONFIG_DRIVERS_IMU_INVENSENSE_MPU9250=y CONFIG_DRIVERS_MAGNETOMETER_HMC5883=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y -CONFIG_DRIVERS_RC_INPUT=y +CONFIG_COMMON_RC=y CONFIG_DRIVERS_RPI_RC_IN=y CONFIG_DRIVERS_SMART_BATTERY_BATMON=y CONFIG_MODULES_AIRSPEED_SELECTOR=y diff --git a/boards/raspberrypi/pico/default.px4board b/boards/raspberrypi/pico/default.px4board index a5727267a1..3f860509f1 100644 --- a/boards/raspberrypi/pico/default.px4board +++ b/boards/raspberrypi/pico/default.px4board @@ -4,13 +4,14 @@ CONFIG_BOARD_CONSTRAINED_FLASH=y CONFIG_BOARD_CONSTRAINED_MEMORY=y CONFIG_BOARD_SERIAL_GPS1="/dev/ttyS2" CONFIG_BOARD_SERIAL_TEL1="/dev/ttyS1" +CONFIG_BOARD_SERIAL_RC="/dev/ttyS3" CONFIG_DRIVERS_ADC_BOARD_ADC=y CONFIG_DRIVERS_BAROMETER_BMP280=y CONFIG_DRIVERS_GPS=y CONFIG_DRIVERS_IMU_INVENSENSE_MPU9250=y CONFIG_DRIVERS_MAGNETOMETER_HMC5883=y CONFIG_DRIVERS_PWM_OUT=y -CONFIG_DRIVERS_RC_INPUT=y +CONFIG_COMMON_RC=y CONFIG_MODULES_ATTITUDE_ESTIMATOR_Q=y CONFIG_MODULES_BATTERY_STATUS=y CONFIG_MODULES_COMMANDER=y diff --git a/boards/raspberrypi/pico/src/board_config.h b/boards/raspberrypi/pico/src/board_config.h index 581233e7ac..de1b0bfbf5 100644 --- a/boards/raspberrypi/pico/src/board_config.h +++ b/boards/raspberrypi/pico/src/board_config.h @@ -71,7 +71,6 @@ #define HRT_PPM_CHANNEL 1 // Number really doesn't matter for this board #define GPIO_PPM_IN (16 | GPIO_FUN(RP2040_GPIO_FUNC_SIO)) #define RC_SERIAL_PORT "/dev/ttyS3" -#define BOARD_SUPPORTS_RC_SERIAL_PORT_OUTPUT /* This board provides a DMA pool and APIs */ // Needs to be figured out #define BOARD_DMA_ALLOC_POOL_SIZE 2048 diff --git a/boards/scumaker/pilotpi/default.px4board b/boards/scumaker/pilotpi/default.px4board index 873998f093..3d22dbe1aa 100644 --- a/boards/scumaker/pilotpi/default.px4board +++ b/boards/scumaker/pilotpi/default.px4board @@ -3,6 +3,7 @@ CONFIG_BOARD_LINUX_TARGET=y CONFIG_BOARD_TOOLCHAIN="arm-linux-gnueabihf" CONFIG_BOARD_ARCHITECTURE="cortex-a53" CONFIG_BOARD_TESTING=y +CONFIG_BOARD_SERIAL_RC="/dev/ttyS4" CONFIG_DRIVERS_ADC_ADS1115=y CONFIG_DRIVERS_BAROMETER_MS5611=y CONFIG_DRIVERS_BATT_SMBUS=y @@ -16,14 +17,14 @@ CONFIG_DRIVERS_MAGNETOMETER_HMC5883=y CONFIG_DRIVERS_MAGNETOMETER_ISENTEK_IST8310=y CONFIG_DRIVERS_MAGNETOMETER_QMC5883L=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y -CONFIG_MODULES_SIMULATION_PWM_OUT_SIM=y -CONFIG_DRIVERS_RC_INPUT=y +CONFIG_COMMON_RC=y CONFIG_DRIVERS_SMART_BATTERY_BATMON=y CONFIG_MODULES_AIRSPEED_SELECTOR=y CONFIG_MODULES_ATTITUDE_ESTIMATOR_Q=y CONFIG_MODULES_BATTERY_STATUS=y CONFIG_MODULES_CAMERA_FEEDBACK=y CONFIG_MODULES_COMMANDER=y +CONFIG_MODULES_CONTROL_ALLOCATOR=y CONFIG_MODULES_DATAMAN=y CONFIG_MODULES_EKF2=y CONFIG_MODULES_EVENTS=y @@ -31,6 +32,7 @@ CONFIG_MODULES_FLIGHT_MODE_MANAGER=y CONFIG_MODULES_FW_ATT_CONTROL=y CONFIG_MODULES_FW_AUTOTUNE_ATTITUDE_CONTROL=y CONFIG_MODULES_FW_POS_CONTROL_L1=y +CONFIG_MODULES_GIMBAL=y CONFIG_MODULES_GYRO_CALIBRATION=y CONFIG_MODULES_GYRO_FFT=y CONFIG_MODULES_LAND_DETECTOR=y @@ -46,7 +48,6 @@ CONFIG_MODULES_MC_AUTOTUNE_ATTITUDE_CONTROL=y CONFIG_MODULES_MC_HOVER_THRUST_ESTIMATOR=y CONFIG_MODULES_MC_POS_CONTROL=y CONFIG_MODULES_MC_RATE_CONTROL=y -CONFIG_MODULES_CONTROL_ALLOCATOR=y CONFIG_MODULES_NAVIGATOR=y CONFIG_MODULES_RC_UPDATE=y CONFIG_MODULES_ROVER_POS_CONTROL=y @@ -57,7 +58,6 @@ CONFIG_MODULES_SIMULATION_SENSOR_GPS_SIM=y CONFIG_MODULES_SIMULATION_SENSOR_MAG_SIM=y CONFIG_MODULES_SIMULATION_SIMULATOR_SIH=y CONFIG_MODULES_TEMPERATURE_COMPENSATION=y -CONFIG_MODULES_GIMBAL=y CONFIG_MODULES_VTOL_ATT_CONTROL=y CONFIG_SYSTEMCMDS_BSONDUMP=y CONFIG_SYSTEMCMDS_DYN=y diff --git a/boards/sky-drones/smartap-airlink/default.px4board b/boards/sky-drones/smartap-airlink/default.px4board index 6951c4cbda..4f356a602f 100644 --- a/boards/sky-drones/smartap-airlink/default.px4board +++ b/boards/sky-drones/smartap-airlink/default.px4board @@ -31,7 +31,9 @@ CONFIG_DRIVERS_PWM_INPUT=y CONFIG_DRIVERS_PWM_OUT=y CONFIG_MODULES_SIMULATION_PWM_OUT_SIM=y CONFIG_DRIVERS_PX4IO=y -CONFIG_DRIVERS_RC_INPUT=y +CONFIG_COMMON_RC=y +CONFIG_BOARD_SERIAL_RC="/dev/ttyS5" +CONFIG_DRIVERS_RC_PPM_IN=y CONFIG_DRIVERS_ROBOCLAW=y CONFIG_DRIVERS_RPM=y CONFIG_DRIVERS_SAFETY_BUTTON=y diff --git a/boards/sky-drones/smartap-airlink/src/board_config.h b/boards/sky-drones/smartap-airlink/src/board_config.h index ac21a1686c..744a98f9f2 100644 --- a/boards/sky-drones/smartap-airlink/src/board_config.h +++ b/boards/sky-drones/smartap-airlink/src/board_config.h @@ -251,7 +251,6 @@ #define GPIO_PPM_IN /* PI5 T8C1 */ GPIO_TIM8_CH1IN_2 /* RC Serial port */ - #define RC_SERIAL_PORT "/dev/ttyS5" #define RC_SERIAL_SINGLEWIRE diff --git a/boards/spracing/h7extreme/default.px4board b/boards/spracing/h7extreme/default.px4board index f44aeac552..8657dc0780 100644 --- a/boards/spracing/h7extreme/default.px4board +++ b/boards/spracing/h7extreme/default.px4board @@ -1,5 +1,6 @@ CONFIG_BOARD_TOOLCHAIN="arm-none-eabi" CONFIG_BOARD_ARCHITECTURE="cortex-m7" +CONFIG_BOARD_SERIAL_RC="/dev/ttyS0" CONFIG_DRIVERS_ADC_BOARD_ADC=y CONFIG_COMMON_BAROMETERS=y CONFIG_DRIVERS_CAMERA_CAPTURE=y @@ -13,9 +14,8 @@ CONFIG_DRIVERS_IMU_INVENSENSE_MPU6000=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y CONFIG_COMMON_OPTICAL_FLOW=y -CONFIG_DRIVERS_OSD=y CONFIG_DRIVERS_PWM_OUT=y -CONFIG_DRIVERS_RC_INPUT=y +CONFIG_COMMON_RC=y CONFIG_COMMON_TELEMETRY=y CONFIG_DRIVERS_TONE_ALARM=y CONFIG_MODULES_ATTITUDE_ESTIMATOR_Q=y diff --git a/boards/uvify/core/default.px4board b/boards/uvify/core/default.px4board index fed8bf42a7..23348ab8b2 100644 --- a/boards/uvify/core/default.px4board +++ b/boards/uvify/core/default.px4board @@ -25,7 +25,9 @@ CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_PCA9685=y CONFIG_DRIVERS_PWM_INPUT=y CONFIG_DRIVERS_PWM_OUT=y -CONFIG_DRIVERS_RC_INPUT=y +CONFIG_COMMON_RC=y +CONFIG_BOARD_SERIAL_RC="/dev/ttyS4" +CONFIG_DRIVERS_RC_PPM_IN=y CONFIG_DRIVERS_TONE_ALARM=y CONFIG_DRIVERS_UAVCAN=y CONFIG_BOARD_UAVCAN_INTERFACES=1 diff --git a/src/drivers/px4io/px4io.cpp b/src/drivers/px4io/px4io.cpp index 70d8ec6004..cd53347882 100644 --- a/src/drivers/px4io/px4io.cpp +++ b/src/drivers/px4io/px4io.cpp @@ -58,7 +58,7 @@ #include #include #include -#include +#include #include #include diff --git a/src/drivers/rc/Kconfig b/src/drivers/rc/Kconfig index f4b771e2ba..1aaa21f675 100644 --- a/src/drivers/rc/Kconfig +++ b/src/drivers/rc/Kconfig @@ -1,9 +1,15 @@ menu "RC" menuconfig COMMON_RC - bool "Common RC" + bool "Common RC drivers" default n - select DRIVERS_RC_CRSF_RC + select DRIVERS_RC_CRSF + select DRIVERS_RC_SPEKTRUM_DSM + select DRIVERS_RC_GHST_RC + #select DRIVERS_RC_PPM_IN + select DRIVERS_RC_SBUS + #select DRIVERS_RC_ST24_RC + #select DRIVERS_RC_SUMD_RC ---help--- - Enable default set of magnetometer drivers + Enable default set of RC drivers rsource "*/Kconfig" endmenu diff --git a/src/drivers/rc/crsf_rc/CMakeLists.txt b/src/drivers/rc/crsf/CMakeLists.txt similarity index 97% rename from src/drivers/rc/crsf_rc/CMakeLists.txt rename to src/drivers/rc/crsf/CMakeLists.txt index ceb7531079..4eaa93252a 100644 --- a/src/drivers/rc/crsf_rc/CMakeLists.txt +++ b/src/drivers/rc/crsf/CMakeLists.txt @@ -31,8 +31,8 @@ # ############################################################################ px4_add_module( - MODULE drivers__rc__crsf_rc - MAIN crsf_rc + MODULE drivers__rc__crsf + MAIN crsf COMPILE_FLAGS SRCS CrsfRc.cpp @@ -47,5 +47,5 @@ px4_add_module( MODULE_CONFIG module.yaml DEPENDS - rc + px4_work_queue ) diff --git a/src/drivers/rc/crsf_rc/Crc8.cpp b/src/drivers/rc/crsf/Crc8.cpp similarity index 100% rename from src/drivers/rc/crsf_rc/Crc8.cpp rename to src/drivers/rc/crsf/Crc8.cpp diff --git a/src/drivers/rc/crsf_rc/Crc8.hpp b/src/drivers/rc/crsf/Crc8.hpp similarity index 100% rename from src/drivers/rc/crsf_rc/Crc8.hpp rename to src/drivers/rc/crsf/Crc8.hpp diff --git a/src/drivers/rc/crsf_rc/CrsfParser.cpp b/src/drivers/rc/crsf/CrsfParser.cpp similarity index 100% rename from src/drivers/rc/crsf_rc/CrsfParser.cpp rename to src/drivers/rc/crsf/CrsfParser.cpp diff --git a/src/drivers/rc/crsf_rc/CrsfParser.hpp b/src/drivers/rc/crsf/CrsfParser.hpp similarity index 100% rename from src/drivers/rc/crsf_rc/CrsfParser.hpp rename to src/drivers/rc/crsf/CrsfParser.hpp diff --git a/src/drivers/rc/crsf_rc/CrsfRc.cpp b/src/drivers/rc/crsf/CrsfRc.cpp similarity index 95% rename from src/drivers/rc/crsf_rc/CrsfRc.cpp rename to src/drivers/rc/crsf/CrsfRc.cpp index 1423f2398c..7b03bfb531 100644 --- a/src/drivers/rc/crsf_rc/CrsfRc.cpp +++ b/src/drivers/rc/crsf/CrsfRc.cpp @@ -500,12 +500,12 @@ int CrsfRc::print_status() perf_print_counter(_cycle_interval_perf); perf_print_counter(_publish_interval_perf); - PX4_INFO("Disposed bytes: %li", _packet_parser_statistics.disposed_bytes); - PX4_INFO("Valid known packet CRCs: %li", _packet_parser_statistics.crcs_valid_known_packets); - PX4_INFO("Valid unknown packet CRCs: %li", _packet_parser_statistics.crcs_valid_unknown_packets); - PX4_INFO("Invalid CRCs: %li", _packet_parser_statistics.crcs_invalid); - PX4_INFO("Invalid known packet sizes: %li", _packet_parser_statistics.invalid_known_packet_sizes); - PX4_INFO("Invalid unknown packet sizes: %li", _packet_parser_statistics.invalid_unknown_packet_sizes); + PX4_INFO("Disposed bytes: %" PRIu32, _packet_parser_statistics.disposed_bytes); + PX4_INFO("Valid known packet CRCs: %" PRIu32, _packet_parser_statistics.crcs_valid_known_packets); + PX4_INFO("Valid unknown packet CRCs: %" PRIu32, _packet_parser_statistics.crcs_valid_unknown_packets); + PX4_INFO("Invalid CRCs: %" PRIu32, _packet_parser_statistics.crcs_invalid); + PX4_INFO("Invalid known packet sizes: %" PRIu32, _packet_parser_statistics.invalid_known_packet_sizes); + PX4_INFO("Invalid unknown packet sizes: %" PRIu32, _packet_parser_statistics.invalid_unknown_packet_sizes); return 0; } @@ -528,7 +528,7 @@ This module parses the CRSF RC uplink protocol and generates CRSF downlink telem )DESCR_STR"); - PRINT_MODULE_USAGE_NAME("crsf_rc", "driver"); + PRINT_MODULE_USAGE_NAME("crsf", "driver"); PRINT_MODULE_USAGE_COMMAND("start"); PRINT_MODULE_USAGE_PARAM_STRING('d', "/dev/ttyS3", "", "RC device", true); @@ -537,7 +537,7 @@ This module parses the CRSF RC uplink protocol and generates CRSF downlink telem return 0; } -extern "C" __EXPORT int crsf_rc_main(int argc, char *argv[]) +extern "C" __EXPORT int crsf_main(int argc, char *argv[]) { return CrsfRc::main(argc, argv); } diff --git a/src/drivers/rc/crsf_rc/CrsfRc.hpp b/src/drivers/rc/crsf/CrsfRc.hpp similarity index 100% rename from src/drivers/rc/crsf_rc/CrsfRc.hpp rename to src/drivers/rc/crsf/CrsfRc.hpp diff --git a/src/drivers/rc/crsf_rc/Kconfig b/src/drivers/rc/crsf/Kconfig similarity index 53% rename from src/drivers/rc/crsf_rc/Kconfig rename to src/drivers/rc/crsf/Kconfig index 21096275af..279aba1cb1 100644 --- a/src/drivers/rc/crsf_rc/Kconfig +++ b/src/drivers/rc/crsf/Kconfig @@ -1,5 +1,5 @@ -menuconfig DRIVERS_RC_CRSF_RC - bool "crsf_rc" +menuconfig DRIVERS_RC_CRSF + bool "crsf" default n ---help--- Enable support for crsf rc diff --git a/src/drivers/rc/crsf_rc/QueueBuffer.cpp b/src/drivers/rc/crsf/QueueBuffer.cpp similarity index 100% rename from src/drivers/rc/crsf_rc/QueueBuffer.cpp rename to src/drivers/rc/crsf/QueueBuffer.cpp diff --git a/src/drivers/rc/crsf_rc/QueueBuffer.hpp b/src/drivers/rc/crsf/QueueBuffer.hpp similarity index 100% rename from src/drivers/rc/crsf_rc/QueueBuffer.hpp rename to src/drivers/rc/crsf/QueueBuffer.hpp diff --git a/src/drivers/rc/crsf_rc/module.yaml b/src/drivers/rc/crsf/module.yaml similarity index 91% rename from src/drivers/rc/crsf_rc/module.yaml rename to src/drivers/rc/crsf/module.yaml index fc4ce23a27..2702c30683 100644 --- a/src/drivers/rc/crsf_rc/module.yaml +++ b/src/drivers/rc/crsf/module.yaml @@ -1,6 +1,6 @@ module_name: CRSF RC Input Driver serial_config: - - command: "crsf_rc start -d ${SERIAL_DEV}" + - command: "crsf start -d ${SERIAL_DEV}" port_config_param: name: RC_CRSF_PRT_CFG group: Serial diff --git a/src/drivers/rc/ghst_rc/CMakeLists.txt b/src/drivers/rc/ghst_rc/CMakeLists.txt new file mode 100644 index 0000000000..f9b55e8900 --- /dev/null +++ b/src/drivers/rc/ghst_rc/CMakeLists.txt @@ -0,0 +1,51 @@ +############################################################################ +# +# Copyright (c) 2015-2022 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +if(PX4_TESTING AND (${PX4_PLATFORM} MATCHES "posix")) + add_subdirectory(test) +endif() + +px4_add_module( + MODULE drivers__rc__ghst + MAIN rc_ghst + COMPILE_FLAGS + SRCS + RCInput.cpp + RCInput.hpp + ghst_parser.cpp + ghst_parser.hpp + MODULE_CONFIG + module.yaml + DEPENDS + px4_work_queue + ) diff --git a/src/drivers/rc/ghst_rc/Kconfig b/src/drivers/rc/ghst_rc/Kconfig new file mode 100644 index 0000000000..59ba89316c --- /dev/null +++ b/src/drivers/rc/ghst_rc/Kconfig @@ -0,0 +1,5 @@ +menuconfig DRIVERS_RC_GHST_RC + bool "rc_ghst" + default n + ---help--- + Enable support for rc_ghst diff --git a/src/drivers/rc/ghst_rc/RCInput.cpp b/src/drivers/rc/ghst_rc/RCInput.cpp new file mode 100644 index 0000000000..1bce045afe --- /dev/null +++ b/src/drivers/rc/ghst_rc/RCInput.cpp @@ -0,0 +1,427 @@ +/**************************************************************************** + * + * Copyright (c) 2012-2022 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include "RCInput.hpp" + +#include + +using namespace time_literals; + +RcGhst::RcGhst(const char *device) : + ModuleParams(nullptr), + ScheduledWorkItem(MODULE_NAME, px4::serial_port_to_wq(device)) +{ + // initialize raw_rc values and count + for (unsigned i = 0; i < input_rc_s::RC_INPUT_MAX_CHANNELS; i++) { + _raw_rc_values[i] = UINT16_MAX; + } + + if (device) { + strncpy(_device, device, sizeof(_device) - 1); + _device[sizeof(_device) - 1] = '\0'; + } +} + +RcGhst::~RcGhst() +{ + perf_free(_cycle_perf); + perf_free(_publish_interval_perf); +} + +int RcGhst::init() +{ + _rcs_fd = ::open(_device, O_RDWR | O_NONBLOCK); + + if (_rcs_fd >= 0) { + ghst_config(_rcs_fd); + } + + if (_rcs_fd < 0) { + return -errno; + } + + if (board_rc_swap_rxtx(_device)) { +#if defined(TIOCSSWAP) + ioctl(_rcs_fd, TIOCSSWAP, SER_SWAP_ENABLED); +#endif // TIOCSSWAP + } + + rc_io_invert(false); + + return 0; +} + +int RcGhst::task_spawn(int argc, char *argv[]) +{ + bool error_flag = false; + + int myoptind = 1; + int ch; + const char *myoptarg = nullptr; + const char *device_name = nullptr; +#if defined(RC_SERIAL_PORT) + device_name = RC_SERIAL_PORT; +#endif // RC_SERIAL_PORT + + while ((ch = px4_getopt(argc, argv, "d:", &myoptind, &myoptarg)) != EOF) { + switch (ch) { + case 'd': + device_name = myoptarg; + break; + + case '?': + error_flag = true; + break; + + default: + PX4_WARN("unrecognized flag"); + error_flag = true; + break; + } + } + + if (error_flag) { + return -1; + } + + if (device_name && (access(device_name, R_OK | W_OK) == 0)) { + RcGhst *instance = new RcGhst(device_name); + + if (instance == nullptr) { + PX4_ERR("alloc failed"); + return PX4_ERROR; + } + + _object.store(instance); + _task_id = task_id_is_work_queue; + + instance->ScheduleOnInterval(_current_update_interval); + + return PX4_OK; + + } else { + if (device_name) { + PX4_ERR("invalid device (-d) %s", device_name); + + } else { + PX4_INFO("valid device required"); + } + } + + return PX4_ERROR; +} + +void RcGhst::fill_rc_in(uint16_t raw_rc_count_local, + uint16_t raw_rc_values_local[input_rc_s::RC_INPUT_MAX_CHANNELS], + hrt_abstime now, bool frame_drop, bool failsafe, + unsigned frame_drops, int rssi = -1) +{ + // fill rc_in struct for publishing + _rc_in.channel_count = raw_rc_count_local; + + if (_rc_in.channel_count > input_rc_s::RC_INPUT_MAX_CHANNELS) { + _rc_in.channel_count = input_rc_s::RC_INPUT_MAX_CHANNELS; + } + + unsigned valid_chans = 0; + + for (unsigned i = 0; i < _rc_in.channel_count; i++) { + _rc_in.values[i] = raw_rc_values_local[i]; + + if (raw_rc_values_local[i] != UINT16_MAX) { + valid_chans++; + } + + // once filled, reset values back to default + _raw_rc_values[i] = UINT16_MAX; + } + + _rc_in.timestamp = now; + _rc_in.timestamp_last_signal = _rc_in.timestamp; + _rc_in.rc_ppm_frame_length = 0; + + if (valid_chans == 0) { + _rc_in.rssi = 0; + } + + _rc_in.rc_failsafe = failsafe; + _rc_in.rc_lost = (valid_chans == 0); + _rc_in.rc_lost_frame_count = frame_drops; + _rc_in.rc_total_frame_count = 0; +} + +void RcGhst::rc_io_invert(bool invert) +{ + // First check if the board provides a board-specific inversion method (e.g. via GPIO), + // and if not use an IOCTL + if (!board_rc_invert_input(_device, invert)) { +#if defined(TIOCSINVERT) + + if (invert) { + ioctl(_rcs_fd, TIOCSINVERT, SER_INVERT_ENABLED_RX | SER_INVERT_ENABLED_TX); + + } else { + ioctl(_rcs_fd, TIOCSINVERT, 0); + } + +#endif // TIOCSINVERT + } +} + +void RcGhst::Run() +{ + if (should_exit()) { + exit_and_cleanup(); + return; + } + + if (!_initialized) { + if (init() == PX4_OK) { + _initialized = true; + + } else { + PX4_ERR("init failed"); + exit_and_cleanup(); + } + + } else { + + perf_begin(_cycle_perf); + + const hrt_abstime cycle_timestamp = hrt_absolute_time(); + + bool rc_updated = false; + + // This block scans for a supported serial RC input and locks onto the first one found + // Scan for 500 msec, then switch protocol + constexpr hrt_abstime rc_scan_max = 500_ms; + + // TODO: needs work (poll _rcs_fd) + // int ret = poll(fds, sizeof(fds) / sizeof(fds[0]), 100); + // then update priority to SCHED_PRIORITY_FAST_DRIVER + // read all available data from the serial RC input UART + + // read all available data from the serial RC input UART + int newBytes = ::read(_rcs_fd, &_rcs_buf[0], RC_MAX_BUFFER_SIZE); + + if (newBytes > 0) { + _bytes_rx += newBytes; + } + + const bool rc_scan_locked = _rc_scan_locked; + + if (_rc_scan_begin == 0) { + _rc_scan_begin = cycle_timestamp; + // Configure serial port for GHST + ghst_config(_rcs_fd); + + // flush serial buffer and any existing buffered data + tcflush(_rcs_fd, TCIOFLUSH); + memset(_rcs_buf, 0, sizeof(_rcs_buf)); + + } else if (_rc_scan_locked + || cycle_timestamp - _rc_scan_begin < rc_scan_max) { + + // parse new data + if (newBytes > 0) { + int8_t ghst_rssi = -1; + rc_updated = ghst_parse(cycle_timestamp, &_rcs_buf[0], newBytes, &_raw_rc_values[0], &ghst_rssi, + &_raw_rc_count, input_rc_s::RC_INPUT_MAX_CHANNELS); + + if (rc_updated) { + // we have a new GHST frame. Publish it. + _rc_in.input_source = input_rc_s::RC_INPUT_SOURCE_PX4FMU_GHST; + fill_rc_in(_raw_rc_count, _raw_rc_values, cycle_timestamp, false, false, 0, ghst_rssi); + + _rc_scan_locked = true; + + // telemetry + if ((cycle_timestamp - _last_update) > (1_s / (UPDATE_RATE_HZ * NUM_DATA_TYPES))) { + + switch (_next_type) { + case 0U: + send_battery_status(); + break; + + case 1U: + send_gps1_status(); + break; + + case 2U: + send_gps2_status(); + break; + + default: + break; + } + + _last_update = cycle_timestamp; + _next_type = (_next_type + 1U) % NUM_DATA_TYPES; + } + } + } + } + + perf_end(_cycle_perf); + + if (rc_updated) { + perf_count(_publish_interval_perf); + + _to_input_rc.publish(_rc_in); + + } else if (!rc_updated && (hrt_elapsed_time(&_rc_in.timestamp_last_signal) > 1_s)) { + _rc_scan_locked = false; + } + + if (!rc_scan_locked && _rc_scan_locked) { + PX4_INFO("RC input locked"); + } + } +} + +bool RcGhst::send_battery_status() +{ + battery_status_s battery_status; + + if (_battery_status_sub.update(&battery_status)) { + + float voltage_in_10mV = battery_status.voltage_filtered_v * FACTOR_VOLTS_TO_10MV; + float current_in_10mA = battery_status.current_filtered_a * FACTOR_AMPS_TO_10MA; + float fuel_in_10mAh = battery_status.discharged_mah * FACTOR_MAH_TO_10MAH; + return ghst_send_telemetry_battery_status(_rcs_fd, + static_cast(voltage_in_10mV), + static_cast(current_in_10mA), + static_cast(fuel_in_10mAh)); + } + + return false; +} + +bool RcGhst::send_gps1_status() +{ + sensor_gps_s vehicle_gps_position; + + if (_vehicle_gps_position_sub.update(&vehicle_gps_position)) { + int32_t latitude = vehicle_gps_position.lat; // 1e-7 degrees + int32_t longitude = vehicle_gps_position.lon; // 1e-7 degrees + uint16_t altitude = vehicle_gps_position.alt / 1000; // mm -> m + + return ghst_send_telemetry_gps1_status(_rcs_fd, latitude, longitude, altitude); + } + + return false; +} + +bool RcGhst::send_gps2_status() +{ + sensor_gps_s vehicle_gps_position; + + if (_vehicle_gps_position_sub.update(&vehicle_gps_position)) { + + uint16_t ground_speed = (uint16_t)(vehicle_gps_position.vel_d_m_s / 3.6f * 10.f); + uint16_t ground_course = (uint16_t)(math::degrees(vehicle_gps_position.cog_rad) * 100.f); + uint8_t num_sats = vehicle_gps_position.satellites_used; + + // TBD: Can these be computed in a RC telemetry driver? + uint16_t home_dist = 0; + uint16_t home_dir = 0; + uint8_t flags = 0; + + return ghst_send_telemetry_gps2_status(_rcs_fd, ground_speed, ground_course, num_sats, home_dist, home_dir, flags); + } + + return false; +} + +int RcGhst::custom_command(int argc, char *argv[]) +{ + if (!is_running()) { + int ret = RcGhst::task_spawn(argc, argv); + + if (ret) { + return ret; + } + } + + return print_usage("unknown command"); +} + +int RcGhst::print_status() +{ + PX4_INFO("Max update rate: %u Hz", 1000000 / _current_update_interval); + + if (_device[0] != '\0') { + PX4_INFO("UART device: %s", _device); + PX4_INFO("UART RX bytes: %" PRIu32, _bytes_rx); + } + + PX4_INFO("RC state: %s", _rc_scan_locked ? "found" : "searching for signal"); + // PX4_INFO("GHST Telemetry: %s", _ghst_telemetry ? "yes" : "no"); + + perf_print_counter(_cycle_perf); + perf_print_counter(_publish_interval_perf); + + if (hrt_elapsed_time(&_rc_in.timestamp) < 1_s) { + print_message(ORB_ID(input_rc), _rc_in); + } + + return 0; +} + +int RcGhst::print_usage(const char *reason) +{ + if (reason) { + PX4_WARN("%s\n", reason); + } + + PRINT_MODULE_DESCRIPTION( + R"DESCR_STR( +### Description +This module does the RC input parsing and auto-selecting the method. Supported methods are: +- GHST + +)DESCR_STR"); + + PRINT_MODULE_USAGE_NAME("rc_ghst", "driver"); + PRINT_MODULE_USAGE_COMMAND("start"); + PRINT_MODULE_USAGE_PARAM_STRING('d', "/dev/ttyS3", "", "RC device", false); + + PRINT_MODULE_USAGE_DEFAULT_COMMANDS(); + + return 0; +} + +extern "C" __EXPORT int rc_ghst_main(int argc, char *argv[]) +{ + return RcGhst::main(argc, argv); +} diff --git a/src/drivers/rc_input/ghst_telemetry.hpp b/src/drivers/rc/ghst_rc/RCInput.hpp similarity index 54% rename from src/drivers/rc_input/ghst_telemetry.hpp rename to src/drivers/rc/ghst_rc/RCInput.hpp index faa61f69b2..82da63b3b2 100644 --- a/src/drivers/rc_input/ghst_telemetry.hpp +++ b/src/drivers/rc/ghst_rc/RCInput.hpp @@ -1,6 +1,6 @@ /**************************************************************************** * - * Copyright (c) 2021 PX4 Development Team. All rights reserved. + * Copyright (c) 2012-2022 PX4 Development Team. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -31,44 +31,83 @@ * ****************************************************************************/ -/** - * @file ghst_telemetry.cpp - * - * IRC Ghost (Immersion RC Ghost) telemetry. - * - * @author Igor Misic - * @author Juraj Ciberlin - */ - #pragma once -#include -#include -#include -#include +#include -/** - * High-level class that handles sending of GHST telemetry data - */ -class GHSTTelemetry +#include "ghst_parser.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class RcGhst : public ModuleBase, public ModuleParams, public px4::ScheduledWorkItem { public: - /** - * @param uart_fd file descriptor for the UART to use. It is expected to be configured - * already. - */ - explicit GHSTTelemetry(int uart_fd); + RcGhst(const char *device); + virtual ~RcGhst(); - ~GHSTTelemetry() = default; + /** @see ModuleBase */ + static int task_spawn(int argc, char *argv[]); - /** - * Send telemetry data. Call this regularly (i.e. at 100Hz), it will automatically - * limit the sending rate. - * @return true if new data sent - */ - bool update(const hrt_abstime &now); + /** @see ModuleBase */ + static int custom_command(int argc, char *argv[]); + + /** @see ModuleBase */ + static int print_usage(const char *reason = nullptr); + + /** @see ModuleBase::print_status() */ + int print_status() override; + + int init(); private: + void Run() override; + + void fill_rc_in(uint16_t raw_rc_count_local, + uint16_t raw_rc_values_local[input_rc_s::RC_INPUT_MAX_CHANNELS], + hrt_abstime now, bool frame_drop, bool failsafe, + unsigned frame_drops, int rssi); + + void rc_io_invert(bool invert); + + hrt_abstime _rc_scan_begin{0}; + + bool _initialized{false}; + bool _rc_scan_locked{false}; + + static constexpr unsigned _current_update_interval{4000}; // 250 Hz + + input_rc_s _rc_in{}; + + uORB::PublicationMulti _to_input_rc{ORB_ID(input_rc)}; + + int _rcs_fd{-1}; + char _device[20] {}; ///< device / serial port path + + static constexpr size_t RC_MAX_BUFFER_SIZE{sizeof(ghst_frame_t)}; + uint8_t _rcs_buf[RC_MAX_BUFFER_SIZE] {}; + + uint16_t _raw_rc_values[input_rc_s::RC_INPUT_MAX_CHANNELS] {}; + uint16_t _raw_rc_count{}; + + perf_counter_t _cycle_perf{perf_alloc(PC_ELAPSED, MODULE_NAME": cycle time")}; + perf_counter_t _publish_interval_perf{perf_alloc(PC_INTERVAL, MODULE_NAME": publish interval")}; + uint32_t _bytes_rx{0}; + + // telemetry bool send_battery_status(); bool send_gps1_status(); bool send_gps2_status(); @@ -76,9 +115,8 @@ private: uORB::Subscription _vehicle_gps_position_sub{ORB_ID(vehicle_gps_position)}; uORB::Subscription _battery_status_sub{ORB_ID(battery_status)}; - int _uart_fd; - hrt_abstime _last_update {0U}; - uint32_t _next_type {0U}; + hrt_abstime _last_update{}; + uint32_t _next_type{}; static constexpr uint32_t NUM_DATA_TYPES {3U}; // number of different telemetry data types static constexpr uint32_t UPDATE_RATE_HZ {10U}; // update rate [Hz] @@ -87,5 +125,4 @@ private: static constexpr float FACTOR_VOLTS_TO_10MV {100.0F}; static constexpr float FACTOR_AMPS_TO_10MA {100.0F}; static constexpr float FACTOR_MAH_TO_10MAH {0.1F}; - }; diff --git a/src/lib/rc/ghst.cpp b/src/drivers/rc/ghst_rc/ghst_parser.cpp similarity index 90% rename from src/lib/rc/ghst.cpp rename to src/drivers/rc/ghst_rc/ghst_parser.cpp index d3c13d7ad2..7209e231c9 100644 --- a/src/lib/rc/ghst.cpp +++ b/src/drivers/rc/ghst_rc/ghst_parser.cpp @@ -53,15 +53,12 @@ #endif #include +#include #include #include #include -// TODO: include RSSI dBm to percentage conversion for ghost receiver -#include "spektrum_rssi.h" - -#include "ghst.hpp" -#include "common_rc.h" +#include "ghst_parser.hpp" #define MIN(a,b) (((a)<(b))?(a):(b)) @@ -79,12 +76,59 @@ enum class ghst_parser_state_t : uint8_t { // only RSSI frame contains value of RSSI, if it is not received, send last received RSSI static int8_t ghst_rssi = -1; -static ghst_frame_t &ghst_frame = rc_decode_buf.ghst_frame; +static ghst_frame_t ghst_frame; static uint32_t current_frame_position = 0U; static ghst_parser_state_t parser_state = ghst_parser_state_t::unsynced; static uint16_t prev_rc_vals[GHST_MAX_NUM_CHANNELS]; +static uint8_t crc8_dvb_s2(uint8_t crc, uint8_t a) +{ + crc ^= a; + + for (int i = 0; i < 8; ++i) { + if (crc & 0x80) { + crc = (crc << 1) ^ 0xD5; + + } else { + crc = crc << 1; + } + } + + return crc; +} + +static uint8_t crc8_dvb_s2_buf(uint8_t *buf, int len) +{ + uint8_t crc = 0; + + for (int i = 0; i < len; ++i) { + crc = crc8_dvb_s2(crc, buf[i]); + } + + return crc; +} + +static constexpr int8_t lu_dbm_percent[] { + 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 99, 98, 98, 97, 96, + 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 79, + 78, 77, 75, 74, 73, 71, 70, 68, 66, 65, 63, 61, 59, 57, 55, 52, + 50, 47, 45, 42, 39, 35, 32, 28, 24, 19, 13, 7, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +#define MASK(n) (n >> (sizeof(n) * CHAR_BIT - 1)) + +/* constexpr-compatible version of abs() */ +static constexpr unsigned c_abs(int n) { return (n + MASK(n)) ^ MASK(n); } + +/* convert signed dbm (-92 to -42) to percentage */ +static constexpr int8_t dbm_to_percent(int8_t dbm) { return lu_dbm_percent[c_abs(dbm)]; } + /** * parse the current ghst_frame buffer */ @@ -104,14 +148,6 @@ int ghst_config(int uart_fd) return ret_val; } -/** - * Convert from RC to PWM value - * @param chan_value channel value in [172, 1811] - * @return PWM channel value in [1000, 2000] - */ -static uint16_t convert_channel_value(unsigned chan_value); - - bool ghst_parse(const uint64_t now, const uint8_t *frame, unsigned len, uint16_t *values, int8_t *rssi, uint16_t *num_values, uint16_t max_channels) { @@ -164,7 +200,12 @@ uint8_t ghst_frame_CRC(const ghst_frame_t &frame) return crc; } -static uint16_t convert_channel_value(unsigned int chan_value) +/** + * Convert from RC to PWM value + * @param chan_value channel value in [172, 1811] + * @return PWM channel value in [1000, 2000] + */ +static uint16_t convert_channel_value(unsigned chan_value) { /* * RC PWM @@ -297,7 +338,7 @@ static bool ghst_parse_buffer(uint16_t *values, int8_t *rssi, uint16_t *num_valu } else if (ghst_frame.type == static_cast(ghstFrameType::frameTypeRssi)) { const ghstPayloadRssi_t *const rssiValues = (ghstPayloadRssi_t *)&ghst_frame.payload; // TODO: call function for RSSI dBm to percentage conversion for ghost receiver - ghst_rssi = spek_dbm_to_percent(static_cast(rssiValues->rssidBm)); + ghst_rssi = dbm_to_percent(static_cast(rssiValues->rssidBm)); } else { GHST_DEBUG("Frame type: %u", ghst_frame.type); @@ -428,4 +469,3 @@ bool ghst_send_telemetry_gps2_status(int uart_fd, uint16_t ground_speed, uint16_ return write(uart_fd, buf, offset) == offset; } - diff --git a/src/lib/rc/ghst.hpp b/src/drivers/rc/ghst_rc/ghst_parser.hpp similarity index 100% rename from src/lib/rc/ghst.hpp rename to src/drivers/rc/ghst_rc/ghst_parser.hpp diff --git a/src/drivers/rc/ghst_rc/module.yaml b/src/drivers/rc/ghst_rc/module.yaml new file mode 100644 index 0000000000..e5e49b7c4f --- /dev/null +++ b/src/drivers/rc/ghst_rc/module.yaml @@ -0,0 +1,7 @@ +module_name: RC GHST input driver +serial_config: + - command: "rc_ghst start -d ${SERIAL_DEV}" + port_config_param: + name: RC_GHST_PRT_CFG + group: Serial + #default: RC diff --git a/src/drivers/snapdragon_spektrum_rc/CMakeLists.txt b/src/drivers/rc/ghst_rc/test/CMakeLists.txt similarity index 89% rename from src/drivers/snapdragon_spektrum_rc/CMakeLists.txt rename to src/drivers/rc/ghst_rc/test/CMakeLists.txt index 7626afd716..ac01d85a90 100644 --- a/src/drivers/snapdragon_spektrum_rc/CMakeLists.txt +++ b/src/drivers/rc/ghst_rc/test/CMakeLists.txt @@ -1,6 +1,6 @@ ############################################################################ # -# Copyright (c) 2016 PX4 Development Team. All rights reserved. +# Copyright (c) 2016-2022 PX4 Development Team. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -32,10 +32,11 @@ ############################################################################ px4_add_module( - MODULE drivers__snapdragon_spektrum_rc - MAIN spektrum_rc + MODULE drivers__rc__ghst__test + MAIN rc_ghst_test + COMPILE_FLAGS + -Wno-unused-result SRCS - spektrum_rc.cpp - DEPENDS - rc + RcGhstTest.cpp + ../ghst_parser.cpp ) diff --git a/src/drivers/rc/ghst_rc/test/RcGhstTest.cpp b/src/drivers/rc/ghst_rc/test/RcGhstTest.cpp new file mode 100644 index 0000000000..a70253a4fd --- /dev/null +++ b/src/drivers/rc/ghst_rc/test/RcGhstTest.cpp @@ -0,0 +1,123 @@ +#include + +#include + +#include +#include +#include + +#include + +#include "../ghst_parser.hpp" + +#if defined(CONFIG_ARCH_BOARD_PX4_SITL) +#define TEST_DATA_PATH "./test_data/" +#else +#define TEST_DATA_PATH "/fs/microsd" +#endif + +class RcGhstTest : public UnitTest +{ +public: + bool run_tests() override; + +private: + bool ghstTest(); +}; + +bool RcGhstTest::run_tests() +{ + ut_run_test(ghstTest); + + return (_tests_failed == 0); +} + +bool RcGhstTest::ghstTest() +{ + const char *filepath = TEST_DATA_PATH "ghst_rc_channels.txt"; + + FILE *fp = fopen(filepath, "rt"); + + ut_test(fp); + + int uart_fd = -1; + const int line_size = 500; + char line[line_size]; + bool has_decoded_values = false; + const int max_channels = 16; + uint16_t rc_values[max_channels]; + uint16_t num_values = 0; + int line_counter = 1; + int8_t ghst_rssi = -1; + ghst_config(uart_fd); + + while (fgets(line, line_size, fp) != nullptr) { + + if (strncmp(line, "INPUT ", 6) == 0) { + + if (has_decoded_values) { + PX4_ERR("Parser decoded values that are not in the test file (line=%i)", line_counter); + return false; + } + + // read the values + const char *file_buffer = line + 6; + int frame_len = 0; + uint8_t frame[300]; + int offset; + int number; + + while (sscanf(file_buffer, "%x, %n", &number, &offset) > 0) { + frame[frame_len++] = number; + file_buffer += offset; + } + + // Pipe the data into the parser + hrt_abstime now = hrt_absolute_time(); + + bool result = ghst_parse(now, frame, frame_len, rc_values, &ghst_rssi, &num_values, max_channels); + + if (result) { + has_decoded_values = true; + } + + } else if (strncmp(line, "DECODED ", 8) == 0) { + + if (!has_decoded_values) { + PX4_ERR("Test file contains decoded values but the parser did not decode anything (line=%i)", line_counter); + return false; + } + + // read the values + const char *file_buffer = line + 8; + int offset; + int expected_rc_value; + int expected_num_channels = 0; + + while (sscanf(file_buffer, "%x, %n", &expected_rc_value, &offset) > 0) { + + // allow a small difference + if (abs(expected_rc_value - (int)rc_values[expected_num_channels]) > 10) { + PX4_ERR("File line: %i, channel: %i", line_counter, expected_num_channels); + ut_compare("Wrong decoded channel", expected_rc_value, rc_values[expected_num_channels]); + } + + file_buffer += offset; + ++expected_num_channels; + } + + if (expected_num_channels != num_values) { + PX4_ERR("File line: %d", line_counter); + ut_compare("Unexpected number of decoded channels", expected_num_channels, num_values); + } + + has_decoded_values = false; + } + + ++line_counter; + } + + return true; +} + +ut_declare_test_c(rc_ghst_test_main, RcGhstTest) diff --git a/src/drivers/rc_input/CMakeLists.txt b/src/drivers/rc/ppm_in/CMakeLists.txt similarity index 91% rename from src/drivers/rc_input/CMakeLists.txt rename to src/drivers/rc/ppm_in/CMakeLists.txt index 6c58fb2605..630f886359 100644 --- a/src/drivers/rc_input/CMakeLists.txt +++ b/src/drivers/rc/ppm_in/CMakeLists.txt @@ -1,6 +1,6 @@ ############################################################################ # -# Copyright (c) 2015 PX4 Development Team. All rights reserved. +# Copyright (c) 2015-2022 PX4 Development Team. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -31,15 +31,14 @@ # ############################################################################ px4_add_module( - MODULE drivers__rc_input - MAIN rc_input + MODULE drivers__rc__ppm_in + MAIN ppm_in COMPILE_FLAGS SRCS RCInput.cpp - crsf_telemetry.cpp - ghst_telemetry.cpp + RCInput.hpp MODULE_CONFIG module.yaml DEPENDS - rc + px4_work_queue ) diff --git a/src/drivers/rc/ppm_in/Kconfig b/src/drivers/rc/ppm_in/Kconfig new file mode 100644 index 0000000000..8869c2f63e --- /dev/null +++ b/src/drivers/rc/ppm_in/Kconfig @@ -0,0 +1,5 @@ +menuconfig DRIVERS_RC_PPM_IN + bool "ppm_in" + default n + ---help--- + Enable support for ppm_in diff --git a/src/drivers/rc/ppm_in/RCInput.cpp b/src/drivers/rc/ppm_in/RCInput.cpp new file mode 100644 index 0000000000..726cf3b27b --- /dev/null +++ b/src/drivers/rc/ppm_in/RCInput.cpp @@ -0,0 +1,316 @@ +/**************************************************************************** + * + * Copyright (c) 2012-2022 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include "RCInput.hpp" + +using namespace time_literals; + +RcPpm::RcPpm() : + ModuleParams(nullptr), + ScheduledWorkItem(MODULE_NAME, px4::wq_configurations::hp_default) +{ + // initialize raw_rc values and count + for (unsigned i = 0; i < input_rc_s::RC_INPUT_MAX_CHANNELS; i++) { + _raw_rc_values[i] = UINT16_MAX; + } +} + +RcPpm::~RcPpm() +{ + perf_free(_cycle_perf); + perf_free(_publish_interval_perf); +} + +int RcPpm::init() +{ +#ifdef GPIO_PPM_IN + // disable CPPM input by mapping it away from the timer capture input + px4_arch_unconfiggpio(GPIO_PPM_IN); +#endif // GPIO_PPM_IN + + return 0; +} + +int RcPpm::task_spawn(int argc, char *argv[]) +{ + RcPpm *instance = new RcPpm(); + + if (instance == nullptr) { + PX4_ERR("alloc failed"); + return PX4_ERROR; + } + + _object.store(instance); + _task_id = task_id_is_work_queue; + + instance->ScheduleOnInterval(_current_update_interval); + + return PX4_OK; +} + +void RcPpm::fill_rc_in(uint16_t raw_rc_count_local, + uint16_t raw_rc_values_local[input_rc_s::RC_INPUT_MAX_CHANNELS], + hrt_abstime now, bool frame_drop, bool failsafe, + unsigned frame_drops, int rssi = -1) +{ + // fill rc_in struct for publishing + _rc_in.channel_count = raw_rc_count_local; + + if (_rc_in.channel_count > input_rc_s::RC_INPUT_MAX_CHANNELS) { + _rc_in.channel_count = input_rc_s::RC_INPUT_MAX_CHANNELS; + } + + unsigned valid_chans = 0; + + for (unsigned i = 0; i < _rc_in.channel_count; i++) { + _rc_in.values[i] = raw_rc_values_local[i]; + + if (raw_rc_values_local[i] != UINT16_MAX) { + valid_chans++; + } + + // once filled, reset values back to default + _raw_rc_values[i] = UINT16_MAX; + } + + _rc_in.timestamp = now; + _rc_in.timestamp_last_signal = _rc_in.timestamp; + _rc_in.rc_ppm_frame_length = 0; + + /* fake rssi if no value was provided */ + if (rssi == -1) { + if ((_param_rc_rssi_pwm_chan.get() > 0) && (_param_rc_rssi_pwm_chan.get() < _rc_in.channel_count)) { + const int32_t rssi_pwm_chan = _param_rc_rssi_pwm_chan.get(); + const int32_t rssi_pwm_min = _param_rc_rssi_pwm_min.get(); + const int32_t rssi_pwm_max = _param_rc_rssi_pwm_max.get(); + + // get RSSI from input channel + int rc_rssi = ((_rc_in.values[rssi_pwm_chan - 1] - rssi_pwm_min) * 100) / (rssi_pwm_max - rssi_pwm_min); + _rc_in.rssi = math::constrain(rc_rssi, 0, 100); + + } else if (_analog_rc_rssi_stable) { + // set RSSI if analog RSSI input is present + float rssi_analog = ((_analog_rc_rssi_volt - 0.2f) / 3.0f) * 100.0f; + + if (rssi_analog > 100.0f) { + rssi_analog = 100.0f; + } + + if (rssi_analog < 0.0f) { + rssi_analog = 0.0f; + } + + _rc_in.rssi = rssi_analog; + + } else { + _rc_in.rssi = 255; + } + + } else { + _rc_in.rssi = rssi; + } + + if (valid_chans == 0) { + _rc_in.rssi = 0; + } + + _rc_in.rc_failsafe = failsafe; + _rc_in.rc_lost = (valid_chans == 0); + _rc_in.rc_lost_frame_count = frame_drops; + _rc_in.rc_total_frame_count = 0; +} + +void RcPpm::Run() +{ + if (should_exit()) { + exit_and_cleanup(); + return; + } + + if (!_initialized) { + if (init() == PX4_OK) { + _initialized = true; + + } else { + PX4_ERR("init failed"); + exit_and_cleanup(); + } + + } else { + + perf_begin(_cycle_perf); + + const hrt_abstime cycle_timestamp = hrt_absolute_time(); + +#if defined(ADC_RC_RSSI_CHANNEL) + + // update ADC sampling + if (_adc_report_sub.updated()) { + adc_report_s adc; + + if (_adc_report_sub.copy(&adc)) { + for (unsigned i = 0; i < PX4_MAX_ADC_CHANNELS; ++i) { + if (adc.channel_id[i] == ADC_RC_RSSI_CHANNEL) { + float adc_volt = adc.raw_data[i] * + adc.v_ref / + adc.resolution; + + if (_analog_rc_rssi_volt < 0.0f) { + _analog_rc_rssi_volt = adc_volt; + } + + _analog_rc_rssi_volt = _analog_rc_rssi_volt * 0.995f + adc_volt * 0.005f; + + /* only allow this to be used if we see a high RSSI once */ + if (_analog_rc_rssi_volt > 2.5f) { + _analog_rc_rssi_stable = true; + } + } + } + } + } + +#endif // ADC_RC_RSSI_CHANNEL + + bool rc_updated = false; + + // This block scans for a supported serial RC input and locks onto the first one found + // Scan for 500 msec, then switch protocol + constexpr hrt_abstime rc_scan_max = 500_ms; + + const bool rc_scan_locked = _rc_scan_locked; + + if (_rc_scan_begin == 0) { + _rc_scan_begin = cycle_timestamp; + // Configure timer input pin for CPPM + px4_arch_configgpio(GPIO_PPM_IN); + + } else if (_rc_scan_locked || cycle_timestamp - _rc_scan_begin < rc_scan_max) { + + // see if we have new PPM input data + if ((ppm_last_valid_decode != _rc_in.timestamp_last_signal) && ppm_decoded_channels > 3) { + // we have a new PPM frame. Publish it. + rc_updated = true; + _rc_in.input_source = input_rc_s::RC_INPUT_SOURCE_PX4FMU_PPM; + fill_rc_in(ppm_decoded_channels, ppm_buffer, cycle_timestamp, false, false, 0); + _rc_scan_locked = true; + _rc_in.rc_ppm_frame_length = ppm_frame_length; + _rc_in.timestamp_last_signal = ppm_last_valid_decode; + } + + } else { + // disable CPPM input by mapping it away from the timer capture input + px4_arch_unconfiggpio(GPIO_PPM_IN); + } + + perf_end(_cycle_perf); + + if (rc_updated) { + perf_count(_publish_interval_perf); + + _to_input_rc.publish(_rc_in); + + } else if (!rc_updated && (hrt_elapsed_time(&_rc_in.timestamp_last_signal) > 1_s)) { + _rc_scan_locked = false; + } + + if (!rc_scan_locked && _rc_scan_locked) { + PX4_INFO("RC input locked"); + } + } +} + +int RcPpm::custom_command(int argc, char *argv[]) +{ + /* start the FMU if not running */ + if (!is_running()) { + int ret = RcPpm::task_spawn(argc, argv); + + if (ret) { + return ret; + } + } + + return print_usage("unknown command"); +} + +int RcPpm::print_status() +{ + PX4_INFO("Max update rate: %u Hz", 1000000 / _current_update_interval); + + PX4_INFO("RC state: %s", _rc_scan_locked ? "found" : "searching for signal"); + +#if ADC_RC_RSSI_CHANNEL + + if (_analog_rc_rssi_stable) { + PX4_INFO("vrssi: %dmV", (int)(_analog_rc_rssi_volt * 1000.0f)); + } + +#endif + + perf_print_counter(_cycle_perf); + perf_print_counter(_publish_interval_perf); + + if (hrt_elapsed_time(&_rc_in.timestamp) < 1_s) { + print_message(ORB_ID(input_rc), _rc_in); + } + + return 0; +} + +int +RcPpm::print_usage(const char *reason) +{ + if (reason) { + PX4_WARN("%s\n", reason); + } + + PRINT_MODULE_DESCRIPTION( + R"DESCR_STR( +### Description +This module does the RC input parsing and auto-selecting the method. Supported methods are: +- PPM + +)DESCR_STR"); + + PRINT_MODULE_USAGE_NAME("ppm_in", "driver"); + PRINT_MODULE_USAGE_COMMAND("start"); + PRINT_MODULE_USAGE_DEFAULT_COMMANDS(); + + return 0; +} + +extern "C" __EXPORT int ppm_in_main(int argc, char *argv[]) +{ + return RcPpm::main(argc, argv); +} diff --git a/src/drivers/rc/ppm_in/RCInput.hpp b/src/drivers/rc/ppm_in/RCInput.hpp new file mode 100644 index 0000000000..4a35f35372 --- /dev/null +++ b/src/drivers/rc/ppm_in/RCInput.hpp @@ -0,0 +1,118 @@ +/**************************************************************************** + * + * Copyright (c) 2012-2022 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#pragma once + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +using namespace time_literals; + +class RcPpm : public ModuleBase, public ModuleParams, public px4::ScheduledWorkItem +{ +public: + RcPpm(); + virtual ~RcPpm(); + + /** @see ModuleBase */ + static int task_spawn(int argc, char *argv[]); + + /** @see ModuleBase */ + static int custom_command(int argc, char *argv[]); + + /** @see ModuleBase */ + static int print_usage(const char *reason = nullptr); + + /** @see ModuleBase::print_status() */ + int print_status() override; + + int init(); + +private: + void Run() override; + + void fill_rc_in(uint16_t raw_rc_count_local, + uint16_t raw_rc_values_local[input_rc_s::RC_INPUT_MAX_CHANNELS], + hrt_abstime now, bool frame_drop, bool failsafe, + unsigned frame_drops, int rssi); + + void rc_io_invert(bool invert); + + hrt_abstime _rc_scan_begin{0}; + + bool _initialized{false}; + bool _rc_scan_locked{false}; + + static constexpr unsigned _current_update_interval{4000}; // 250 Hz + + uORB::SubscriptionInterval _parameter_update_sub{ORB_ID(parameter_update), 1_s}; + + uORB::Subscription _adc_report_sub{ORB_ID(adc_report)}; + + input_rc_s _rc_in{}; + + float _analog_rc_rssi_volt{-1.0f}; + bool _analog_rc_rssi_stable{false}; + + uORB::PublicationMulti _to_input_rc{ORB_ID(input_rc)}; + + uint16_t _raw_rc_values[input_rc_s::RC_INPUT_MAX_CHANNELS] {}; + uint16_t _raw_rc_count{}; + + perf_counter_t _cycle_perf{perf_alloc(PC_ELAPSED, MODULE_NAME": cycle time")}; + perf_counter_t _publish_interval_perf{perf_alloc(PC_INTERVAL, MODULE_NAME": publish interval")}; + + DEFINE_PARAMETERS( + (ParamInt) _param_rc_rssi_pwm_chan, + (ParamInt) _param_rc_rssi_pwm_min, + (ParamInt) _param_rc_rssi_pwm_max + ) +}; diff --git a/src/drivers/rc/ppm_in/module.yaml b/src/drivers/rc/ppm_in/module.yaml new file mode 100644 index 0000000000..709fa599cd --- /dev/null +++ b/src/drivers/rc/ppm_in/module.yaml @@ -0,0 +1,12 @@ +module_name: RC PPM input driver + +parameters: + - group: RC + definitions: + PPM_IN_EN: + description: + short: RC PPM in enable + long: | + RC PPM in enable. + type: boolean + default: false diff --git a/src/drivers/rc/sbus/CMakeLists.txt b/src/drivers/rc/sbus/CMakeLists.txt new file mode 100644 index 0000000000..3935de5bc1 --- /dev/null +++ b/src/drivers/rc/sbus/CMakeLists.txt @@ -0,0 +1,45 @@ +############################################################################ +# +# Copyright (c) 2015-2022 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ +px4_add_module( + MODULE drivers__rc__sbus + MAIN sbus + COMPILE_FLAGS + SRCS + RCInput.cpp + RCInput.hpp + MODULE_CONFIG + module.yaml + DEPENDS + rc_sbus + px4_work_queue + ) diff --git a/src/drivers/rc/sbus/Kconfig b/src/drivers/rc/sbus/Kconfig new file mode 100644 index 0000000000..45d3986f72 --- /dev/null +++ b/src/drivers/rc/sbus/Kconfig @@ -0,0 +1,5 @@ +menuconfig DRIVERS_RC_SBUS + bool "sbus" + default n + ---help--- + Enable support for sbus diff --git a/src/drivers/rc/sbus/RCInput.cpp b/src/drivers/rc/sbus/RCInput.cpp new file mode 100644 index 0000000000..1e560aa09a --- /dev/null +++ b/src/drivers/rc/sbus/RCInput.cpp @@ -0,0 +1,415 @@ +/**************************************************************************** + * + * Copyright (c) 2012-2022 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include "RCInput.hpp" + +#include + +using namespace time_literals; + +RcSbus::RcSbus(const char *device) : + ModuleParams(nullptr), + ScheduledWorkItem(MODULE_NAME, px4::serial_port_to_wq(device)) +{ + // initialize raw_rc values and count + for (unsigned i = 0; i < input_rc_s::RC_INPUT_MAX_CHANNELS; i++) { + _raw_rc_values[i] = UINT16_MAX; + } + + if (device) { + strncpy(_device, device, sizeof(_device) - 1); + _device[sizeof(_device) - 1] = '\0'; + } +} + +RcSbus::~RcSbus() +{ + perf_free(_cycle_perf); + perf_free(_publish_interval_perf); +} + +int RcSbus::init() +{ + _rcs_fd = ::open(_device, O_RDWR | O_NONBLOCK); + + // assume SBUS input and immediately switch it to + // so that if Single wire mode on TX there will be only + // a short contention + sbus_config(_rcs_fd, board_rc_singlewire(_device)); + + if (_rcs_fd < 0) { + return -errno; + } + + if (board_rc_swap_rxtx(_device)) { +#if defined(TIOCSSWAP) + ioctl(_rcs_fd, TIOCSSWAP, SER_SWAP_ENABLED); +#endif // TIOCSSWAP + } + +#ifdef GPIO_PPM_IN + // disable CPPM input by mapping it away from the timer capture input + px4_arch_unconfiggpio(GPIO_PPM_IN); +#endif // GPIO_PPM_IN + + rc_io_invert(false); + + return 0; +} + +int RcSbus::task_spawn(int argc, char *argv[]) +{ + bool error_flag = false; + + int myoptind = 1; + int ch; + const char *myoptarg = nullptr; + const char *device_name = nullptr; +#if defined(RC_SERIAL_PORT) + device_name = RC_SERIAL_PORT; +#endif // RC_SERIAL_PORT + + while ((ch = px4_getopt(argc, argv, "d:", &myoptind, &myoptarg)) != EOF) { + switch (ch) { + case 'd': + device_name = myoptarg; + break; + + case '?': + error_flag = true; + break; + + default: + PX4_WARN("unrecognized flag"); + error_flag = true; + break; + } + } + + if (error_flag) { + return -1; + } + + if (device_name && (access(device_name, R_OK | W_OK) == 0)) { + RcSbus *instance = new RcSbus(device_name); + + if (instance == nullptr) { + PX4_ERR("alloc failed"); + return PX4_ERROR; + } + + _object.store(instance); + _task_id = task_id_is_work_queue; + + instance->ScheduleOnInterval(_current_update_interval); + + return PX4_OK; + + } else { + if (device_name) { + PX4_ERR("invalid device (-d) %s", device_name); + + } else { + PX4_INFO("valid device required"); + } + } + + return PX4_ERROR; +} + +void RcSbus::fill_rc_in(uint16_t raw_rc_count_local, + uint16_t raw_rc_values_local[input_rc_s::RC_INPUT_MAX_CHANNELS], + hrt_abstime now, bool frame_drop, bool failsafe, + unsigned frame_drops, int rssi = -1) +{ + // fill rc_in struct for publishing + _rc_in.channel_count = raw_rc_count_local; + + if (_rc_in.channel_count > input_rc_s::RC_INPUT_MAX_CHANNELS) { + _rc_in.channel_count = input_rc_s::RC_INPUT_MAX_CHANNELS; + } + + unsigned valid_chans = 0; + + for (unsigned i = 0; i < _rc_in.channel_count; i++) { + _rc_in.values[i] = raw_rc_values_local[i]; + + if (raw_rc_values_local[i] != UINT16_MAX) { + valid_chans++; + } + + // once filled, reset values back to default + _raw_rc_values[i] = UINT16_MAX; + } + + _rc_in.timestamp = now; + _rc_in.timestamp_last_signal = _rc_in.timestamp; + _rc_in.rc_ppm_frame_length = 0; + + /* fake rssi if no value was provided */ + if (rssi == -1) { + if ((_param_rc_rssi_pwm_chan.get() > 0) && (_param_rc_rssi_pwm_chan.get() < _rc_in.channel_count)) { + const int32_t rssi_pwm_chan = _param_rc_rssi_pwm_chan.get(); + const int32_t rssi_pwm_min = _param_rc_rssi_pwm_min.get(); + const int32_t rssi_pwm_max = _param_rc_rssi_pwm_max.get(); + + // get RSSI from input channel + int rc_rssi = ((_rc_in.values[rssi_pwm_chan - 1] - rssi_pwm_min) * 100) / (rssi_pwm_max - rssi_pwm_min); + _rc_in.rssi = math::constrain(rc_rssi, 0, 100); + + } else if (_analog_rc_rssi_stable) { + // set RSSI if analog RSSI input is present + float rssi_analog = ((_analog_rc_rssi_volt - 0.2f) / 3.0f) * 100.0f; + + if (rssi_analog > 100.0f) { + rssi_analog = 100.0f; + } + + if (rssi_analog < 0.0f) { + rssi_analog = 0.0f; + } + + _rc_in.rssi = rssi_analog; + + } else { + _rc_in.rssi = 255; + } + + } else { + _rc_in.rssi = rssi; + } + + if (valid_chans == 0) { + _rc_in.rssi = 0; + } + + _rc_in.rc_failsafe = failsafe; + _rc_in.rc_lost = (valid_chans == 0); + _rc_in.rc_lost_frame_count = frame_drops; + _rc_in.rc_total_frame_count = 0; +} + +void RcSbus::rc_io_invert(bool invert) +{ + // First check if the board provides a board-specific inversion method (e.g. via GPIO), + // and if not use an IOCTL + if (!board_rc_invert_input(_device, invert)) { +#if defined(TIOCSINVERT) + + if (invert) { + ioctl(_rcs_fd, TIOCSINVERT, SER_INVERT_ENABLED_RX | SER_INVERT_ENABLED_TX); + + } else { + ioctl(_rcs_fd, TIOCSINVERT, 0); + } + +#endif // TIOCSINVERT + } +} + +void RcSbus::Run() +{ + if (should_exit()) { + exit_and_cleanup(); + return; + } + + if (!_initialized) { + if (init() == PX4_OK) { + _initialized = true; + + } else { + PX4_ERR("init failed"); + exit_and_cleanup(); + } + + } else { + + perf_begin(_cycle_perf); + + // Check if parameters have changed + if (_parameter_update_sub.updated()) { + // clear update + parameter_update_s param_update; + _parameter_update_sub.copy(¶m_update); + + updateParams(); + } + + const hrt_abstime cycle_timestamp = hrt_absolute_time(); + + bool rc_updated = false; + + // This block scans for a supported serial RC input and locks onto the first one found + // Scan for 500 msec, then switch protocol + constexpr hrt_abstime rc_scan_max = 500_ms; + + unsigned frame_drops = 0; + + // TODO: needs work (poll _rcs_fd) + // int ret = poll(fds, sizeof(fds) / sizeof(fds[0]), 100); + // then update priority to SCHED_PRIORITY_FAST_DRIVER + // read all available data from the serial RC input UART + + // read all available data from the serial RC input UART + int newBytes = ::read(_rcs_fd, &_rcs_buf[0], RC_MAX_BUFFER_SIZE); + + if (newBytes > 0) { + _bytes_rx += newBytes; + } + + const bool rc_scan_locked = _rc_scan_locked; + + if (_rc_scan_begin == 0) { + _rc_scan_begin = cycle_timestamp; + // Configure serial port for SBUS + sbus_config(_rcs_fd, board_rc_singlewire(_device)); + rc_io_invert(true); + + // flush serial buffer and any existing buffered data + tcflush(_rcs_fd, TCIOFLUSH); + memset(_rcs_buf, 0, sizeof(_rcs_buf)); + + } else if (_rc_scan_locked + || cycle_timestamp - _rc_scan_begin < rc_scan_max) { + + // parse new data + if (newBytes > 0) { + bool sbus_failsafe = false; + bool sbus_frame_drop = false; + + rc_updated = sbus_parse(cycle_timestamp, &_rcs_buf[0], newBytes, &_raw_rc_values[0], &_raw_rc_count, &sbus_failsafe, + &sbus_frame_drop, &frame_drops, input_rc_s::RC_INPUT_MAX_CHANNELS); + + if (rc_updated) { + // we have a new SBUS frame. Publish it. + _rc_in.input_source = input_rc_s::RC_INPUT_SOURCE_PX4FMU_SBUS; + fill_rc_in(_raw_rc_count, _raw_rc_values, cycle_timestamp, + sbus_frame_drop, sbus_failsafe, frame_drops); + _rc_scan_locked = true; + } + } + + } else { + // Scan the next protocol + rc_io_invert(false); + } + + perf_end(_cycle_perf); + + if (rc_updated) { + perf_count(_publish_interval_perf); + + _to_input_rc.publish(_rc_in); + + } else if (!rc_updated && (hrt_elapsed_time(&_rc_in.timestamp_last_signal) > 1_s)) { + _rc_scan_locked = false; + } + + if (!rc_scan_locked && _rc_scan_locked) { + PX4_INFO("RC input locked"); + } + + } +} + +int RcSbus::custom_command(int argc, char *argv[]) +{ + if (!is_running()) { + int ret = RcSbus::task_spawn(argc, argv); + + if (ret) { + return ret; + } + } + + return print_usage("unknown command"); +} + +int RcSbus::print_status() +{ + PX4_INFO("Max update rate: %u Hz", 1000000 / _current_update_interval); + + if (_device[0] != '\0') { + PX4_INFO("UART device: %s", _device); + PX4_INFO("UART RX bytes: %" PRIu32, _bytes_rx); + } + + PX4_INFO("RC state: %s", _rc_scan_locked ? "found" : "searching for signal"); + PX4_INFO("SBUS frame drops: %u", sbus_dropped_frames()); + +#if ADC_RC_RSSI_CHANNEL + + if (_analog_rc_rssi_stable) { + PX4_INFO("vrssi: %dmV", (int)(_analog_rc_rssi_volt * 1000.0f)); + } + +#endif + + perf_print_counter(_cycle_perf); + perf_print_counter(_publish_interval_perf); + + if (hrt_elapsed_time(&_rc_in.timestamp) < 1_s) { + print_message(ORB_ID(input_rc), _rc_in); + } + + return 0; +} + +int RcSbus::print_usage(const char *reason) +{ + if (reason) { + PX4_WARN("%s\n", reason); + } + + PRINT_MODULE_DESCRIPTION( + R"DESCR_STR( +### Description +This module does the RC input parsing and auto-selecting the method. Supported methods are: +- SBUS + +)DESCR_STR"); + + PRINT_MODULE_USAGE_NAME("rc_sbus", "driver"); + PRINT_MODULE_USAGE_COMMAND("start"); + PRINT_MODULE_USAGE_PARAM_STRING('d', "/dev/ttyS3", "", "RC device", false); + + PRINT_MODULE_USAGE_DEFAULT_COMMANDS(); + + return 0; +} + +extern "C" __EXPORT int sbus_main(int argc, char *argv[]) +{ + return RcSbus::main(argc, argv); +} diff --git a/src/drivers/rc_input/RCInput.hpp b/src/drivers/rc/sbus/RCInput.hpp similarity index 71% rename from src/drivers/rc_input/RCInput.hpp rename to src/drivers/rc/sbus/RCInput.hpp index efea2ba231..5ae3c98c93 100644 --- a/src/drivers/rc_input/RCInput.hpp +++ b/src/drivers/rc/sbus/RCInput.hpp @@ -39,12 +39,7 @@ #include #include #include -#include -#include -#include -#include -#include -#include +#include #include #include #include @@ -57,22 +52,15 @@ #include #include #include -#include #include -#include "crsf_telemetry.h" -#include "ghst_telemetry.hpp" +using namespace time_literals; -#ifdef HRT_PPM_CHANNEL -# include -#endif - -class RCInput : public ModuleBase, public ModuleParams, public px4::ScheduledWorkItem +class RcSbus : public ModuleBase, public ModuleParams, public px4::ScheduledWorkItem { public: - - RCInput(const char *device); - virtual ~RCInput(); + RcSbus(const char *device); + virtual ~RcSbus(); /** @see ModuleBase */ static int task_spawn(int argc, char *argv[]); @@ -86,45 +74,16 @@ public: /** @see ModuleBase::print_status() */ int print_status() override; - int init(); + int init(); private: - - enum RC_SCAN { - RC_SCAN_NONE = 0, - RC_SCAN_PPM = 1, - RC_SCAN_SBUS = 2, - RC_SCAN_DSM = 3, - RC_SCAN_ST24 = 5, - RC_SCAN_SUMD = 4, - RC_SCAN_CRSF = 6, - RC_SCAN_GHST = 7, - } _rc_scan_state{RC_SCAN_SBUS}; - - static constexpr char const *RC_SCAN_STRING[] { - "None", - "PPM", - "SBUS", - "DSM", - "ST24", - "SUMD", - "CRSF", - "GHST" - }; - void Run() override; -#if defined(SPEKTRUM_POWER) - bool bind_spektrum(int arg = DSMX8_BIND_PULSES) const; -#endif // SPEKTRUM_POWER - void fill_rc_in(uint16_t raw_rc_count_local, uint16_t raw_rc_values_local[input_rc_s::RC_INPUT_MAX_CHANNELS], hrt_abstime now, bool frame_drop, bool failsafe, unsigned frame_drops, int rssi); - void set_rc_scan_state(RC_SCAN _rc_scan_state); - void rc_io_invert(bool invert); hrt_abstime _rc_scan_begin{0}; @@ -136,40 +95,29 @@ private: uORB::SubscriptionInterval _parameter_update_sub{ORB_ID(parameter_update), 1_s}; - uORB::Subscription _adc_report_sub{ORB_ID(adc_report)}; - uORB::Subscription _vehicle_cmd_sub{ORB_ID(vehicle_command)}; - uORB::Subscription _vehicle_status_sub{ORB_ID(vehicle_status)}; - input_rc_s _rc_in{}; - float _analog_rc_rssi_volt{-1.0f}; - bool _analog_rc_rssi_stable{false}; - - bool _armed{false}; - + float _analog_rc_rssi_volt{-1.0f}; + bool _analog_rc_rssi_stable{false}; uORB::PublicationMulti _to_input_rc{ORB_ID(input_rc)}; int _rcs_fd{-1}; char _device[20] {}; ///< device / serial port path - static constexpr size_t RC_MAX_BUFFER_SIZE{SBUS_BUFFER_SIZE}; + static constexpr size_t RC_MAX_BUFFER_SIZE{sizeof(sbus_frame_t)}; uint8_t _rcs_buf[RC_MAX_BUFFER_SIZE] {}; uint16_t _raw_rc_values[input_rc_s::RC_INPUT_MAX_CHANNELS] {}; uint16_t _raw_rc_count{}; - CRSFTelemetry *_crsf_telemetry{nullptr}; - GHSTTelemetry *_ghst_telemetry{nullptr}; - - perf_counter_t _cycle_perf; - perf_counter_t _publish_interval_perf; + perf_counter_t _cycle_perf{perf_alloc(PC_ELAPSED, MODULE_NAME": cycle time")}; + perf_counter_t _publish_interval_perf{perf_alloc(PC_INTERVAL, MODULE_NAME": publish interval")}; uint32_t _bytes_rx{0}; DEFINE_PARAMETERS( (ParamInt) _param_rc_rssi_pwm_chan, (ParamInt) _param_rc_rssi_pwm_min, - (ParamInt) _param_rc_rssi_pwm_max, - (ParamInt) _param_rc_input_proto + (ParamInt) _param_rc_rssi_pwm_max ) }; diff --git a/src/drivers/rc/sbus/module.yaml b/src/drivers/rc/sbus/module.yaml new file mode 100644 index 0000000000..79f02a316f --- /dev/null +++ b/src/drivers/rc/sbus/module.yaml @@ -0,0 +1,7 @@ +module_name: RC SBUS input driver +serial_config: + - command: "sbus start -d ${SERIAL_DEV}" + port_config_param: + name: RC_SBUS_PRT_CFG + group: Serial + #default: RC diff --git a/src/drivers/rc/spektrum_dsm/CMakeLists.txt b/src/drivers/rc/spektrum_dsm/CMakeLists.txt new file mode 100644 index 0000000000..4c8e8e3033 --- /dev/null +++ b/src/drivers/rc/spektrum_dsm/CMakeLists.txt @@ -0,0 +1,45 @@ +############################################################################ +# +# Copyright (c) 2015-2022 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ +px4_add_module( + MODULE drivers__rc__spektrum_dsm + MAIN spektrum_dsm + COMPILE_FLAGS + SRCS + RCInput.cpp + RCInput.hpp + MODULE_CONFIG + module.yaml + DEPENDS + rc_dsm + px4_work_queue + ) diff --git a/src/drivers/rc/spektrum_dsm/Kconfig b/src/drivers/rc/spektrum_dsm/Kconfig new file mode 100644 index 0000000000..97fe0f2f2a --- /dev/null +++ b/src/drivers/rc/spektrum_dsm/Kconfig @@ -0,0 +1,5 @@ +menuconfig DRIVERS_RC_SPEKTRUM_DSM + bool "spektrum_dsm" + default n + ---help--- + Enable support for spektrum_dsm diff --git a/src/drivers/rc/spektrum_dsm/RCInput.cpp b/src/drivers/rc/spektrum_dsm/RCInput.cpp new file mode 100644 index 0000000000..01b100866e --- /dev/null +++ b/src/drivers/rc/spektrum_dsm/RCInput.cpp @@ -0,0 +1,456 @@ +/**************************************************************************** + * + * Copyright (c) 2012-2022 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include "RCInput.hpp" + +#include + +#include + +using namespace time_literals; + +RcDsm::RcDsm(const char *device) : + ModuleParams(nullptr), + ScheduledWorkItem(MODULE_NAME, px4::serial_port_to_wq(device)) +{ + if (device) { + strncpy(_device, device, sizeof(_device) - 1); + _device[sizeof(_device) - 1] = '\0'; + } +} + +RcDsm::~RcDsm() +{ +#if defined(RC_SERIAL_PORT) && defined(SPEKTRUM_POWER_PASSIVE) + + if ((strcmp(RC_SERIAL_PORT, _device) == 0)) { + // Disable power controls for Spektrum receiver + SPEKTRUM_POWER_PASSIVE(); + } + +#endif // RC_SERIAL_PORT && SPEKTRUM_POWER_PASSIVE + + perf_free(_cycle_perf); + perf_free(_publish_interval_perf); +} + +int RcDsm::init() +{ + + + return 0; +} + +int RcDsm::task_spawn(int argc, char *argv[]) +{ + bool error_flag = false; + + int myoptind = 1; + int ch; + const char *myoptarg = nullptr; + const char *device_name = nullptr; + + while ((ch = px4_getopt(argc, argv, "d:", &myoptind, &myoptarg)) != EOF) { + switch (ch) { + case 'd': + device_name = myoptarg; + break; + + case '?': + error_flag = true; + break; + + default: + PX4_WARN("unrecognized flag"); + error_flag = true; + break; + } + } + + if (error_flag) { + return -1; + } + + if (device_name && (access(device_name, R_OK | W_OK) == 0)) { + RcDsm *instance = new RcDsm(device_name); + + if (instance == nullptr) { + PX4_ERR("alloc failed"); + return PX4_ERROR; + } + + _object.store(instance); + _task_id = task_id_is_work_queue; + + instance->ScheduleOnInterval(_current_update_interval); + + return PX4_OK; + + } else { + if (device_name) { + PX4_ERR("invalid device (-d) %s", device_name); + + } else { + PX4_INFO("valid device required"); + } + } + + return PX4_ERROR; +} + +void RcDsm::Run() +{ + if (should_exit()) { + + if (_rcs_fd >= 0) { + close(_rcs_fd); + _rcs_fd = -1; + } + + exit_and_cleanup(); + return; + } + + perf_begin(_cycle_perf); + + if (_vehicle_status_sub.updated()) { + vehicle_status_s vehicle_status; + + if (_vehicle_status_sub.copy(&vehicle_status)) { + _armed = (vehicle_status.arming_state == vehicle_status_s::ARMING_STATE_ARMED); + } + } + + const hrt_abstime cycle_timestamp = hrt_absolute_time(); + + + /* vehicle command */ + vehicle_command_s vcmd; + + if (_vehicle_cmd_sub.update(&vcmd)) { + // Check for a pairing command + if (vcmd.command == vehicle_command_s::VEHICLE_CMD_START_RX_PAIR) { + + uint8_t cmd_ret = vehicle_command_ack_s::VEHICLE_CMD_RESULT_UNSUPPORTED; + +#if defined(RC_SERIAL_PORT) + + if ((strcmp(RC_SERIAL_PORT, _device) == 0)) { +#if defined(SPEKTRUM_POWER) + + if (!_rc_scan_locked && !_armed) { + if ((int)vcmd.param1 == 0) { + // DSM binding command + int dsm_bind_mode = (int)vcmd.param2; + + int dsm_bind_pulses = 0; + + if (dsm_bind_mode == 0) { + dsm_bind_pulses = DSM2_BIND_PULSES; + + } else if (dsm_bind_mode == 1) { + dsm_bind_pulses = DSMX_BIND_PULSES; + + } else { + dsm_bind_pulses = DSMX8_BIND_PULSES; + } + + // specify 11ms DSMX. RX will automatically fall back to 22ms or DSM2 if necessary + if (dsm_bind_pulses == DSM2_BIND_PULSES || + dsm_bind_pulses == DSMX_BIND_PULSES || + dsm_bind_pulses == DSMX8_BIND_PULSES) { + + /* only allow DSM2, DSM-X and DSM-X with more than 7 channels */ + PX4_INFO("DSM_BIND_START: DSM%s RX", (dsm_bind_pulses == 0) ? "2" : ((dsm_bind_pulses == 1) ? "-X" : "-X8")); + + dsm_bind(DSM_CMD_BIND_POWER_DOWN, 0); + + dsm_bind(DSM_CMD_BIND_SET_RX_OUT, 0); + usleep(500000); + + dsm_bind(DSM_CMD_BIND_POWER_UP, 0); + usleep(72000); + + irqstate_t flags = px4_enter_critical_section(); + dsm_bind(DSM_CMD_BIND_SEND_PULSES, dsm_bind_pulses); + px4_leave_critical_section(flags); + + usleep(50000); + + dsm_bind(DSM_CMD_BIND_REINIT_UART, 0); + + cmd_ret = vehicle_command_ack_s::VEHICLE_CMD_RESULT_ACCEPTED; + + } else { + cmd_ret = vehicle_command_ack_s::VEHICLE_CMD_RESULT_FAILED; + PX4_ERR("DSM bind failed"); + } + } + + } else { + cmd_ret = vehicle_command_ack_s::VEHICLE_CMD_RESULT_TEMPORARILY_REJECTED; + } + +#endif // SPEKTRUM_POWER + } + +#endif // RC_SERIAL_PORT + + // publish acknowledgement + vehicle_command_ack_s command_ack{}; + command_ack.command = vcmd.command; + command_ack.result = cmd_ret; + command_ack.target_system = vcmd.source_system; + command_ack.target_component = vcmd.source_component; + command_ack.timestamp = hrt_absolute_time(); + uORB::Publication vehicle_command_ack_pub{ORB_ID(vehicle_command_ack)}; + vehicle_command_ack_pub.publish(command_ack); + } + } + + if (!_rc_scan_locked && (_rc_scan_begin == 0)) { + _rc_scan_begin = cycle_timestamp; + + // Configure serial port for DSM +#if defined(RC_SERIAL_PORT) + + if ((strcmp(RC_SERIAL_PORT, _device) == 0)) { +# if defined(SPEKTRUM_POWER_CONFIG) + // Enable power controls for Spektrum receiver + SPEKTRUM_POWER_CONFIG(); +# endif // SPEKTRUM_POWER_CONFIG +# if defined(SPEKTRUM_POWER) + // enable power on DSM connector + SPEKTRUM_POWER(true); +# endif // SPEKTRUM_POWER + } + +#endif // RC_SERIAL_PORT + + if (_rcs_fd >= 0) { + close(_rcs_fd); + _rcs_fd = -1; + } + + if (_rcs_fd < 0) { + // dsm_init sets some file static variables and returns a file descriptor + // it also powers on the radio if needed + _rcs_fd = open(_device, O_RDWR | O_NONBLOCK); + + if (board_rc_swap_rxtx(_device)) { +#if defined(TIOCSSWAP) + ioctl(_rcs_fd, TIOCSSWAP, SER_SWAP_ENABLED); +#endif // TIOCSSWAP + } + + // First check if the board provides a board-specific inversion method (e.g. via GPIO), + // and if not use an IOCTL + if (!board_rc_invert_input(_device, false)) { +#if defined(TIOCSINVERT) + ioctl(_rcs_fd, TIOCSINVERT, 0); +#endif // TIOCSINVERT + } + } + + if (_rcs_fd >= 0) { + // 115200bps, no parity, one stop bit + struct termios t; + tcgetattr(_rcs_fd, &t); + cfsetspeed(&t, 115200); + t.c_cflag &= ~(CSTOPB | PARENB); + tcsetattr(_rcs_fd, TCSANOW, &t); + + // initialise the decoder + dsm_proto_init(); + } + } + + if (_rcs_fd >= 0) { + // TODO: needs work (poll _rcs_fd) + // int ret = poll(fds, sizeof(fds) / sizeof(fds[0]), 100); + // then update priority to SCHED_PRIORITY_FAST_DRIVER + // read all available data from the serial RC input UART + const hrt_abstime timestamp_last_signal = hrt_absolute_time(); + + static constexpr size_t RC_MAX_BUFFER_SIZE{sizeof(dsm_decode_t)}; + uint8_t rcs_buf[RC_MAX_BUFFER_SIZE] {}; + int new_bytes = ::read(_rcs_fd, &rcs_buf[0], RC_MAX_BUFFER_SIZE); + + if (new_bytes > 0) { + _bytes_rx += new_bytes; + } + + if (new_bytes > 0) { + uint16_t raw_rc_values[input_rc_s::RC_INPUT_MAX_CHANNELS]; + + for (auto &rc_channel : raw_rc_values) { + rc_channel = UINT16_MAX; + } + + uint16_t raw_rc_count = 0; + bool dsm_11_bit = false; + unsigned frame_drops = 0; + int8_t dsm_rssi = -1; + + // parse new data + const bool rc_updated = dsm_parse(cycle_timestamp, &rcs_buf[0], new_bytes, &raw_rc_values[0], &raw_rc_count, + &dsm_11_bit, &frame_drops, &dsm_rssi, input_rc_s::RC_INPUT_MAX_CHANNELS); + + if (rc_updated) { + + if (!_rc_scan_locked) { + _rc_scan_locked = true; + PX4_INFO("RC input locked"); + } + + input_rc_s input_rc{}; + input_rc.timestamp_last_signal = timestamp_last_signal; + input_rc.input_source = input_rc_s::RC_INPUT_SOURCE_PX4FMU_DSM; + + unsigned valid_chans = 0; + + for (unsigned i = 0; i < math::min(raw_rc_count, (uint16_t)input_rc_s::RC_INPUT_MAX_CHANNELS); i++) { + input_rc.values[i] = raw_rc_values[i]; + + if (raw_rc_values[i] != UINT16_MAX) { + valid_chans++; + } + } + + input_rc.channel_count = valid_chans; + input_rc.rssi = -1; + input_rc.link_quality = -1; + input_rc.rssi_dbm = NAN; + + if ((valid_chans == 0) && (dsm_rssi >= 0) && (dsm_rssi <= 100)) { + input_rc.rssi = dsm_rssi; + } + + input_rc.rc_lost = (valid_chans == 0); + input_rc.rc_lost_frame_count = frame_drops; + input_rc.rc_total_frame_count = 0; // TODO: + input_rc.timestamp = hrt_absolute_time(); + _input_rc_pub.publish(input_rc); + + perf_count_interval(_publish_interval_perf, timestamp_last_signal); + _last_valid_rc = timestamp_last_signal; + } + } + } + + perf_end(_cycle_perf); + + if (!_armed && (hrt_elapsed_time(&_last_valid_rc) > 5_s)) { + _rc_scan_locked = false; + _rc_scan_begin = 0; + } +} + +int RcDsm::custom_command(int argc, char *argv[]) +{ + const char *verb = argv[0]; + + if (!strcmp(verb, "bind")) { + if (is_running()) { + uORB::Publication vehicle_command_pub{ORB_ID(vehicle_command)}; + vehicle_command_s vcmd{}; + vcmd.command = vehicle_command_s::VEHICLE_CMD_START_RX_PAIR; + vcmd.timestamp = hrt_absolute_time(); + vehicle_command_pub.publish(vcmd); + return 0; + + } else { + return -1; + } + } + + /* start the FMU if not running */ + if (!is_running()) { + int ret = RcDsm::task_spawn(argc, argv); + + if (ret) { + return ret; + } + } + + return print_usage("unknown command"); +} + +int RcDsm::print_status() +{ + PX4_INFO("Max update rate: %u Hz", 1000000 / _current_update_interval); + + if (_device[0] != '\0') { + PX4_INFO("UART device: %s", _device); + PX4_INFO("UART RX bytes: %" PRIu32, _bytes_rx); + } + + PX4_INFO("RC state: %s", _rc_scan_locked ? "found" : "searching for signal"); + + perf_print_counter(_cycle_perf); + perf_print_counter(_publish_interval_perf); + + return 0; +} + +int RcDsm::print_usage(const char *reason) +{ + if (reason) { + PX4_WARN("%s\n", reason); + } + + PRINT_MODULE_DESCRIPTION( + R"DESCR_STR( +### Description +This module does the RC input parsing and auto-selecting the method. Supported methods are: +- DSM + +)DESCR_STR"); + + PRINT_MODULE_USAGE_NAME("rc_dsm", "driver"); + PRINT_MODULE_USAGE_COMMAND("start"); + PRINT_MODULE_USAGE_PARAM_STRING('d', "/dev/ttyS3", "", "RC device", false); + +#if defined(SPEKTRUM_POWER) + PRINT_MODULE_USAGE_COMMAND_DESCR("bind", "Send a DSM bind command (module must be running)"); +#endif /* SPEKTRUM_POWER */ + + PRINT_MODULE_USAGE_DEFAULT_COMMANDS(); + + return 0; +} + +extern "C" __EXPORT int spektrum_dsm_main(int argc, char *argv[]) +{ + return RcDsm::main(argc, argv); +} diff --git a/src/drivers/rc/spektrum_dsm/RCInput.hpp b/src/drivers/rc/spektrum_dsm/RCInput.hpp new file mode 100644 index 0000000000..383aca5e45 --- /dev/null +++ b/src/drivers/rc/spektrum_dsm/RCInput.hpp @@ -0,0 +1,95 @@ +/**************************************************************************** + * + * Copyright (c) 2012-2022 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class RcDsm : public ModuleBase, public ModuleParams, public px4::ScheduledWorkItem +{ +public: + RcDsm(const char *device); + virtual ~RcDsm(); + + /** @see ModuleBase */ + static int task_spawn(int argc, char *argv[]); + + /** @see ModuleBase */ + static int custom_command(int argc, char *argv[]); + + /** @see ModuleBase */ + static int print_usage(const char *reason = nullptr); + + /** @see ModuleBase::print_status() */ + int print_status() override; + + int init(); + +private: + void Run() override; + + static constexpr unsigned _current_update_interval{4000}; // 250 Hz + + uORB::Subscription _vehicle_cmd_sub{ORB_ID(vehicle_command)}; + uORB::Subscription _vehicle_status_sub{ORB_ID(vehicle_status)}; + + uORB::PublicationMulti _input_rc_pub{ORB_ID(input_rc)}; + + int _rcs_fd{-1}; + char _device[20] {}; ///< device / serial port path + uint32_t _bytes_rx{0}; + + hrt_abstime _rc_scan_begin{0}; + hrt_abstime _last_valid_rc{0}; + bool _armed{false}; + bool _rc_scan_locked{false}; + + perf_counter_t _cycle_perf{perf_alloc(PC_ELAPSED, MODULE_NAME": cycle time")}; + perf_counter_t _publish_interval_perf{perf_alloc(PC_INTERVAL, MODULE_NAME": publish interval")}; + +}; diff --git a/src/drivers/rc/spektrum_dsm/module.yaml b/src/drivers/rc/spektrum_dsm/module.yaml new file mode 100644 index 0000000000..92630e2fd8 --- /dev/null +++ b/src/drivers/rc/spektrum_dsm/module.yaml @@ -0,0 +1,7 @@ +module_name: RC Spektrum DSM input driver +serial_config: + - command: "spektrum_dsm start -d ${SERIAL_DEV}" + port_config_param: + name: RC_DSM_PRT_CFG + group: Serial + #default: RC diff --git a/src/drivers/rc/st24_rc/CMakeLists.txt b/src/drivers/rc/st24_rc/CMakeLists.txt new file mode 100644 index 0000000000..9a8f7fa8e6 --- /dev/null +++ b/src/drivers/rc/st24_rc/CMakeLists.txt @@ -0,0 +1,45 @@ +############################################################################ +# +# Copyright (c) 2015-2022 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ +px4_add_module( + MODULE drivers__rc__rc_st24 + MAIN rc_st24 + COMPILE_FLAGS + SRCS + RCInput.cpp + RCInput.hpp + MODULE_CONFIG + module.yaml + DEPENDS + rc_st24 + px4_work_queue + ) diff --git a/src/drivers/rc/st24_rc/Kconfig b/src/drivers/rc/st24_rc/Kconfig new file mode 100644 index 0000000000..49ad11f133 --- /dev/null +++ b/src/drivers/rc/st24_rc/Kconfig @@ -0,0 +1,5 @@ +menuconfig DRIVERS_RC_ST24_RC + bool "rc_st24" + default n + ---help--- + Enable support for rc_st24 diff --git a/src/drivers/rc/st24_rc/RCInput.cpp b/src/drivers/rc/st24_rc/RCInput.cpp new file mode 100644 index 0000000000..2e4de2c12d --- /dev/null +++ b/src/drivers/rc/st24_rc/RCInput.cpp @@ -0,0 +1,378 @@ +/**************************************************************************** + * + * Copyright (c) 2012-2022 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include "RCInput.hpp" + +#include + +using namespace time_literals; + +RcSt24::RcSt24(const char *device) : + ModuleParams(nullptr), + ScheduledWorkItem(MODULE_NAME, px4::serial_port_to_wq(device)) +{ + // initialize raw_rc values and count + for (unsigned i = 0; i < input_rc_s::RC_INPUT_MAX_CHANNELS; i++) { + _raw_rc_values[i] = UINT16_MAX; + } + + if (device) { + strncpy(_device, device, sizeof(_device) - 1); + _device[sizeof(_device) - 1] = '\0'; + } +} + +RcSt24::~RcSt24() +{ + perf_free(_cycle_perf); + perf_free(_publish_interval_perf); +} + +int RcSt24::init() +{ + _rcs_fd = ::open(_device, O_RDWR | O_NONBLOCK); + + if (_rcs_fd >= 0) { + // 115200bps, no parity, one stop bit + struct termios t {}; + tcgetattr(_rcs_fd, &t); + cfsetspeed(&t, 115200); + t.c_cflag &= ~(CSTOPB | PARENB); + tcsetattr(_rcs_fd, TCSANOW, &t); + } + + if (_rcs_fd < 0) { + return -errno; + } + + if (board_rc_swap_rxtx(_device)) { +#if defined(TIOCSSWAP) + ioctl(_rcs_fd, TIOCSSWAP, SER_SWAP_ENABLED); +#endif // TIOCSSWAP + } + + rc_io_invert(false); + + return 0; +} + +int RcSt24::task_spawn(int argc, char *argv[]) +{ + bool error_flag = false; + + int myoptind = 1; + int ch; + const char *myoptarg = nullptr; + const char *device_name = nullptr; +#if defined(RC_SERIAL_PORT) + device_name = RC_SERIAL_PORT; +#endif // RC_SERIAL_PORT + + while ((ch = px4_getopt(argc, argv, "d:", &myoptind, &myoptarg)) != EOF) { + switch (ch) { + case 'd': + device_name = myoptarg; + break; + + case '?': + error_flag = true; + break; + + default: + PX4_WARN("unrecognized flag"); + error_flag = true; + break; + } + } + + if (error_flag) { + return -1; + } + + if (device_name && (access(device_name, R_OK | W_OK) == 0)) { + RcSt24 *instance = new RcSt24(device_name); + + if (instance == nullptr) { + PX4_ERR("alloc failed"); + return PX4_ERROR; + } + + _object.store(instance); + _task_id = task_id_is_work_queue; + + instance->ScheduleOnInterval(_current_update_interval); + + return PX4_OK; + + } else { + if (device_name) { + PX4_ERR("invalid device (-d) %s", device_name); + + } else { + PX4_INFO("valid device required"); + } + } + + return PX4_ERROR; +} + +void RcSt24::fill_rc_in(uint16_t raw_rc_count_local, + uint16_t raw_rc_values_local[input_rc_s::RC_INPUT_MAX_CHANNELS], + hrt_abstime now, bool frame_drop, bool failsafe, + unsigned frame_drops, int rssi = -1) +{ + // fill rc_in struct for publishing + _rc_in.channel_count = raw_rc_count_local; + + if (_rc_in.channel_count > input_rc_s::RC_INPUT_MAX_CHANNELS) { + _rc_in.channel_count = input_rc_s::RC_INPUT_MAX_CHANNELS; + } + + unsigned valid_chans = 0; + + for (unsigned i = 0; i < _rc_in.channel_count; i++) { + _rc_in.values[i] = raw_rc_values_local[i]; + + if (raw_rc_values_local[i] != UINT16_MAX) { + valid_chans++; + } + + // once filled, reset values back to default + _raw_rc_values[i] = UINT16_MAX; + } + + _rc_in.timestamp = now; + _rc_in.timestamp_last_signal = _rc_in.timestamp; + _rc_in.rc_ppm_frame_length = 0; + + if (valid_chans == 0) { + _rc_in.rssi = 0; + } + + _rc_in.rc_failsafe = failsafe; + _rc_in.rc_lost = (valid_chans == 0); + _rc_in.rc_lost_frame_count = frame_drops; + _rc_in.rc_total_frame_count = 0; +} + +void RcSt24::rc_io_invert(bool invert) +{ + // First check if the board provides a board-specific inversion method (e.g. via GPIO), + // and if not use an IOCTL + if (!board_rc_invert_input(_device, invert)) { +#if defined(TIOCSINVERT) + + if (invert) { + ioctl(_rcs_fd, TIOCSINVERT, SER_INVERT_ENABLED_RX | SER_INVERT_ENABLED_TX); + + } else { + ioctl(_rcs_fd, TIOCSINVERT, 0); + } + +#endif // TIOCSINVERT + } +} + +void RcSt24::Run() +{ + if (should_exit()) { + exit_and_cleanup(); + return; + } + + if (!_initialized) { + if (init() == PX4_OK) { + _initialized = true; + + } else { + PX4_ERR("init failed"); + exit_and_cleanup(); + } + + } else { + + perf_begin(_cycle_perf); + + const hrt_abstime cycle_timestamp = hrt_absolute_time(); + + bool rc_updated = false; + + // This block scans for a supported serial RC input and locks onto the first one found + // Scan for 500 msec, then switch protocol + constexpr hrt_abstime rc_scan_max = 500_ms; + + unsigned frame_drops = 0; + + // TODO: needs work (poll _rcs_fd) + // int ret = poll(fds, sizeof(fds) / sizeof(fds[0]), 100); + // then update priority to SCHED_PRIORITY_FAST_DRIVER + // read all available data from the serial RC input UART + + // read all available data from the serial RC input UART + int newBytes = ::read(_rcs_fd, &_rcs_buf[0], RC_MAX_BUFFER_SIZE); + + if (newBytes > 0) { + _bytes_rx += newBytes; + } + + const bool rc_scan_locked = _rc_scan_locked; + + if (_rc_scan_begin == 0) { + _rc_scan_begin = cycle_timestamp; + + // Configure serial port for DSM + if (_rcs_fd >= 0) { + // 115200bps, no parity, one stop bit + struct termios t {}; + tcgetattr(_rcs_fd, &t); + cfsetspeed(&t, 115200); + t.c_cflag &= ~(CSTOPB | PARENB); + tcsetattr(_rcs_fd, TCSANOW, &t); + } + + // flush serial buffer and any existing buffered data + tcflush(_rcs_fd, TCIOFLUSH); + memset(_rcs_buf, 0, sizeof(_rcs_buf)); + + } else if (_rc_scan_locked + || cycle_timestamp - _rc_scan_begin < rc_scan_max) { + + if (newBytes > 0) { + // parse new data + uint8_t st24_rssi, lost_count; + + rc_updated = false; + + for (unsigned i = 0; i < (unsigned)newBytes; i++) { + /* set updated flag if one complete packet was parsed */ + st24_rssi = input_rc_s::RSSI_MAX; + rc_updated = (OK == st24_decode(_rcs_buf[i], &st24_rssi, &lost_count, + &_raw_rc_count, _raw_rc_values, input_rc_s::RC_INPUT_MAX_CHANNELS)); + } + + // The st24 will keep outputting RC channels and RSSI even if RC has been lost. + // The only way to detect RC loss is therefore to look at the lost_count. + if (rc_updated) { + if (lost_count == 0) { + // we have a new ST24 frame. Publish it. + _rc_in.input_source = input_rc_s::RC_INPUT_SOURCE_PX4FMU_ST24; + fill_rc_in(_raw_rc_count, _raw_rc_values, cycle_timestamp, + false, false, frame_drops, st24_rssi); + _rc_scan_locked = true; + + } else { + // if the lost count > 0 means that there is an RC loss + _rc_in.rc_lost = true; + } + } + } + } + + perf_end(_cycle_perf); + + if (rc_updated) { + perf_count(_publish_interval_perf); + + _to_input_rc.publish(_rc_in); + + } else if (!rc_updated && (hrt_elapsed_time(&_rc_in.timestamp_last_signal) > 1_s)) { + _rc_scan_locked = false; + } + + if (!rc_scan_locked && _rc_scan_locked) { + PX4_INFO("RC input locked"); + } + } +} + +int RcSt24::custom_command(int argc, char *argv[]) +{ + if (!is_running()) { + int ret = RcSt24::task_spawn(argc, argv); + + if (ret) { + return ret; + } + } + + return print_usage("unknown command"); +} + +int RcSt24::print_status() +{ + PX4_INFO("Max update rate: %u Hz", 1000000 / _current_update_interval); + + if (_device[0] != '\0') { + PX4_INFO("UART device: %s", _device); + PX4_INFO("UART RX bytes: %" PRIu32, _bytes_rx); + } + + PX4_INFO("RC state: %s", _rc_scan_locked ? "found" : "searching for signal"); + + perf_print_counter(_cycle_perf); + perf_print_counter(_publish_interval_perf); + + if (hrt_elapsed_time(&_rc_in.timestamp) < 1_s) { + print_message(ORB_ID(input_rc), _rc_in); + } + + return 0; +} + +int RcSt24::print_usage(const char *reason) +{ + if (reason) { + PX4_WARN("%s\n", reason); + } + + PRINT_MODULE_DESCRIPTION( + R"DESCR_STR( +### Description +This module does the RC input parsing and auto-selecting the method. Supported methods are: +- ST24 + +)DESCR_STR"); + + PRINT_MODULE_USAGE_NAME("rc_st24", "driver"); + PRINT_MODULE_USAGE_COMMAND("start"); + PRINT_MODULE_USAGE_PARAM_STRING('d', "/dev/ttyS3", "", "RC device", false); + + PRINT_MODULE_USAGE_DEFAULT_COMMANDS(); + + return 0; +} + +extern "C" __EXPORT int rc_st24_main(int argc, char *argv[]) +{ + return RcSt24::main(argc, argv); +} diff --git a/src/drivers/rc/st24_rc/RCInput.hpp b/src/drivers/rc/st24_rc/RCInput.hpp new file mode 100644 index 0000000000..efe719d71a --- /dev/null +++ b/src/drivers/rc/st24_rc/RCInput.hpp @@ -0,0 +1,106 @@ +/**************************************************************************** + * + * Copyright (c) 2012-2022 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#pragma once + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class RcSt24 : public ModuleBase, public ModuleParams, public px4::ScheduledWorkItem +{ +public: + RcSt24(const char *device); + virtual ~RcSt24(); + + /** @see ModuleBase */ + static int task_spawn(int argc, char *argv[]); + + /** @see ModuleBase */ + static int custom_command(int argc, char *argv[]); + + /** @see ModuleBase */ + static int print_usage(const char *reason = nullptr); + + /** @see ModuleBase::print_status() */ + int print_status() override; + + int init(); + +private: + void Run() override; + + void fill_rc_in(uint16_t raw_rc_count_local, + uint16_t raw_rc_values_local[input_rc_s::RC_INPUT_MAX_CHANNELS], + hrt_abstime now, bool frame_drop, bool failsafe, + unsigned frame_drops, int rssi); + + void rc_io_invert(bool invert); + + hrt_abstime _rc_scan_begin{0}; + + bool _initialized{false}; + bool _rc_scan_locked{false}; + + static constexpr unsigned _current_update_interval{4000}; // 250 Hz + + input_rc_s _rc_in{}; + + uORB::PublicationMulti _to_input_rc{ORB_ID(input_rc)}; + + int _rcs_fd{-1}; + char _device[20] {}; ///< device / serial port path + + static constexpr size_t RC_MAX_BUFFER_SIZE{sizeof(ReceiverFcPacket)}; + uint8_t _rcs_buf[RC_MAX_BUFFER_SIZE] {}; + + uint16_t _raw_rc_values[input_rc_s::RC_INPUT_MAX_CHANNELS] {}; + uint16_t _raw_rc_count{}; + + perf_counter_t _cycle_perf{perf_alloc(PC_ELAPSED, MODULE_NAME": cycle time")}; + perf_counter_t _publish_interval_perf{perf_alloc(PC_INTERVAL, MODULE_NAME": publish interval")}; + uint32_t _bytes_rx{0}; +}; diff --git a/src/drivers/rc/st24_rc/module.yaml b/src/drivers/rc/st24_rc/module.yaml new file mode 100644 index 0000000000..1695043df0 --- /dev/null +++ b/src/drivers/rc/st24_rc/module.yaml @@ -0,0 +1,7 @@ +module_name: RC ST24 input driver +serial_config: + - command: "rc_st24 start -d ${SERIAL_DEV}" + port_config_param: + name: RC_ST24_PRT_CFG + group: Serial + #default: RC diff --git a/src/drivers/rc/sumd_rc/CMakeLists.txt b/src/drivers/rc/sumd_rc/CMakeLists.txt new file mode 100644 index 0000000000..1d9b8ef122 --- /dev/null +++ b/src/drivers/rc/sumd_rc/CMakeLists.txt @@ -0,0 +1,45 @@ +############################################################################ +# +# Copyright (c) 2015-2022 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ +px4_add_module( + MODULE drivers__rc__sumd + MAIN rc_sumd + COMPILE_FLAGS + SRCS + RCInput.cpp + RCInput.hpp + MODULE_CONFIG + module.yaml + DEPENDS + rc_sumd + px4_work_queue + ) diff --git a/src/drivers/rc/sumd_rc/Kconfig b/src/drivers/rc/sumd_rc/Kconfig new file mode 100644 index 0000000000..d1b9ebb88b --- /dev/null +++ b/src/drivers/rc/sumd_rc/Kconfig @@ -0,0 +1,5 @@ +menuconfig DRIVERS_RC_SUMD_RC + bool "rc_sumd" + default n + ---help--- + Enable support for rc_sumd diff --git a/src/drivers/rc/sumd_rc/RCInput.cpp b/src/drivers/rc/sumd_rc/RCInput.cpp new file mode 100644 index 0000000000..6e0ee55976 --- /dev/null +++ b/src/drivers/rc/sumd_rc/RCInput.cpp @@ -0,0 +1,371 @@ +/**************************************************************************** + * + * Copyright (c) 2012-2022 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include "RCInput.hpp" + +#include + +using namespace time_literals; + +RcSumd::RcSumd(const char *device) : + ModuleParams(nullptr), + ScheduledWorkItem(MODULE_NAME, px4::serial_port_to_wq(device)) +{ + // initialize raw_rc values and count + for (unsigned i = 0; i < input_rc_s::RC_INPUT_MAX_CHANNELS; i++) { + _raw_rc_values[i] = UINT16_MAX; + } + + if (device) { + strncpy(_device, device, sizeof(_device) - 1); + _device[sizeof(_device) - 1] = '\0'; + } +} + +RcSumd::~RcSumd() +{ + perf_free(_cycle_perf); + perf_free(_publish_interval_perf); +} + +int RcSumd::init() +{ + _rcs_fd = ::open(_device, O_RDWR | O_NONBLOCK); + + if (_rcs_fd >= 0) { + // 115200bps, no parity, one stop bit + struct termios t {}; + tcgetattr(_rcs_fd, &t); + cfsetspeed(&t, 115200); + t.c_cflag &= ~(CSTOPB | PARENB); + tcsetattr(_rcs_fd, TCSANOW, &t); + } + + if (_rcs_fd < 0) { + return -errno; + } + + if (board_rc_swap_rxtx(_device)) { +#if defined(TIOCSSWAP) + ioctl(_rcs_fd, TIOCSSWAP, SER_SWAP_ENABLED); +#endif // TIOCSSWAP + } + + rc_io_invert(false); + + return 0; +} + +int RcSumd::task_spawn(int argc, char *argv[]) +{ + bool error_flag = false; + + int myoptind = 1; + int ch; + const char *myoptarg = nullptr; + const char *device_name = nullptr; +#if defined(RC_SERIAL_PORT) + device_name = RC_SERIAL_PORT; +#endif // RC_SERIAL_PORT + + while ((ch = px4_getopt(argc, argv, "d:", &myoptind, &myoptarg)) != EOF) { + switch (ch) { + case 'd': + device_name = myoptarg; + break; + + case '?': + error_flag = true; + break; + + default: + PX4_WARN("unrecognized flag"); + error_flag = true; + break; + } + } + + if (error_flag) { + return -1; + } + + if (device_name && (access(device_name, R_OK | W_OK) == 0)) { + RcSumd *instance = new RcSumd(device_name); + + if (instance == nullptr) { + PX4_ERR("alloc failed"); + return PX4_ERROR; + } + + _object.store(instance); + _task_id = task_id_is_work_queue; + + instance->ScheduleOnInterval(_current_update_interval); + + return PX4_OK; + + } else { + if (device_name) { + PX4_ERR("invalid device (-d) %s", device_name); + + } else { + PX4_INFO("valid device required"); + } + } + + return PX4_ERROR; +} + +void RcSumd::fill_rc_in(uint16_t raw_rc_count_local, + uint16_t raw_rc_values_local[input_rc_s::RC_INPUT_MAX_CHANNELS], + hrt_abstime now, bool frame_drop, bool failsafe, + unsigned frame_drops, int rssi = -1) +{ + // fill rc_in struct for publishing + _rc_in.channel_count = raw_rc_count_local; + + if (_rc_in.channel_count > input_rc_s::RC_INPUT_MAX_CHANNELS) { + _rc_in.channel_count = input_rc_s::RC_INPUT_MAX_CHANNELS; + } + + unsigned valid_chans = 0; + + for (unsigned i = 0; i < _rc_in.channel_count; i++) { + _rc_in.values[i] = raw_rc_values_local[i]; + + if (raw_rc_values_local[i] != UINT16_MAX) { + valid_chans++; + } + + // once filled, reset values back to default + _raw_rc_values[i] = UINT16_MAX; + } + + _rc_in.timestamp = now; + _rc_in.timestamp_last_signal = _rc_in.timestamp; + _rc_in.rc_ppm_frame_length = 0; + + if (valid_chans == 0) { + _rc_in.rssi = 0; + } + + _rc_in.rc_failsafe = failsafe; + _rc_in.rc_lost = (valid_chans == 0); + _rc_in.rc_lost_frame_count = frame_drops; + _rc_in.rc_total_frame_count = 0; +} + +void RcSumd::rc_io_invert(bool invert) +{ + // First check if the board provides a board-specific inversion method (e.g. via GPIO), + // and if not use an IOCTL + if (!board_rc_invert_input(_device, invert)) { +#if defined(TIOCSINVERT) + + if (invert) { + ioctl(_rcs_fd, TIOCSINVERT, SER_INVERT_ENABLED_RX | SER_INVERT_ENABLED_TX); + + } else { + ioctl(_rcs_fd, TIOCSINVERT, 0); + } + +#endif // TIOCSINVERT + } +} + +void RcSumd::Run() +{ + if (should_exit()) { + exit_and_cleanup(); + return; + } + + if (!_initialized) { + if (init() == PX4_OK) { + _initialized = true; + + } else { + PX4_ERR("init failed"); + exit_and_cleanup(); + } + + } else { + + perf_begin(_cycle_perf); + + const hrt_abstime cycle_timestamp = hrt_absolute_time(); + + bool rc_updated = false; + + // This block scans for a supported serial RC input and locks onto the first one found + // Scan for 500 msec, then switch protocol + constexpr hrt_abstime rc_scan_max = 500_ms; + + unsigned frame_drops = 0; + + // TODO: needs work (poll _rcs_fd) + // int ret = poll(fds, sizeof(fds) / sizeof(fds[0]), 100); + // then update priority to SCHED_PRIORITY_FAST_DRIVER + // read all available data from the serial RC input UART + + // read all available data from the serial RC input UART + int newBytes = ::read(_rcs_fd, &_rcs_buf[0], RC_MAX_BUFFER_SIZE); + + if (newBytes > 0) { + _bytes_rx += newBytes; + } + + const bool rc_scan_locked = _rc_scan_locked; + + if (_rc_scan_begin == 0) { + _rc_scan_begin = cycle_timestamp; + + // Configure serial port for DSM + if (_rcs_fd >= 0) { + // 115200bps, no parity, one stop bit + struct termios t {}; + tcgetattr(_rcs_fd, &t); + cfsetspeed(&t, 115200); + t.c_cflag &= ~(CSTOPB | PARENB); + tcsetattr(_rcs_fd, TCSANOW, &t); + } + + // flush serial buffer and any existing buffered data + tcflush(_rcs_fd, TCIOFLUSH); + memset(_rcs_buf, 0, sizeof(_rcs_buf)); + + } else if (_rc_scan_locked + || cycle_timestamp - _rc_scan_begin < rc_scan_max) { + + if (newBytes > 0) { + // parse new data + uint8_t sumd_rssi, rx_count; + bool sumd_failsafe; + + rc_updated = false; + + for (unsigned i = 0; i < (unsigned)newBytes; i++) { + /* set updated flag if one complete packet was parsed */ + sumd_rssi = input_rc_s::RSSI_MAX; + rc_updated = (OK == sumd_decode(_rcs_buf[i], &sumd_rssi, &rx_count, + &_raw_rc_count, _raw_rc_values, input_rc_s::RC_INPUT_MAX_CHANNELS, &sumd_failsafe)); + } + + if (rc_updated) { + // we have a new SUMD frame. Publish it. + _rc_in.input_source = input_rc_s::RC_INPUT_SOURCE_PX4FMU_SUMD; + fill_rc_in(_raw_rc_count, _raw_rc_values, cycle_timestamp, + false, sumd_failsafe, frame_drops, sumd_rssi); + _rc_scan_locked = true; + } + } + } + + perf_end(_cycle_perf); + + if (rc_updated) { + perf_count(_publish_interval_perf); + + _to_input_rc.publish(_rc_in); + + } else if (!rc_updated && (hrt_elapsed_time(&_rc_in.timestamp_last_signal) > 1_s)) { + _rc_scan_locked = false; + } + + if (!rc_scan_locked && _rc_scan_locked) { + PX4_INFO("RC input locked"); + } + } +} + +int RcSumd::custom_command(int argc, char *argv[]) +{ + if (!is_running()) { + int ret = RcSumd::task_spawn(argc, argv); + + if (ret) { + return ret; + } + } + + return print_usage("unknown command"); +} + +int RcSumd::print_status() +{ + PX4_INFO("Max update rate: %u Hz", 1000000 / _current_update_interval); + + if (_device[0] != '\0') { + PX4_INFO("UART device: %s", _device); + PX4_INFO("UART RX bytes: %" PRIu32, _bytes_rx); + } + + PX4_INFO("RC state: %s", _rc_scan_locked ? "found" : "searching for signal"); + + perf_print_counter(_cycle_perf); + perf_print_counter(_publish_interval_perf); + + if (hrt_elapsed_time(&_rc_in.timestamp) < 1_s) { + print_message(ORB_ID(input_rc), _rc_in); + } + + return 0; +} + +int RcSumd::print_usage(const char *reason) +{ + if (reason) { + PX4_WARN("%s\n", reason); + } + + PRINT_MODULE_DESCRIPTION( + R"DESCR_STR( +### Description +This module does the RC input parsing and auto-selecting the method. Supported methods are: +- SUMD + +)DESCR_STR"); + + PRINT_MODULE_USAGE_NAME("rc_sumd", "driver"); + PRINT_MODULE_USAGE_COMMAND("start"); + PRINT_MODULE_USAGE_PARAM_STRING('d', "/dev/ttyS3", "", "RC device", false); + + PRINT_MODULE_USAGE_DEFAULT_COMMANDS(); + + return 0; +} + +extern "C" __EXPORT int rc_sumd_main(int argc, char *argv[]) +{ + return RcSumd::main(argc, argv); +} diff --git a/src/drivers/rc/sumd_rc/RCInput.hpp b/src/drivers/rc/sumd_rc/RCInput.hpp new file mode 100644 index 0000000000..76588f9b06 --- /dev/null +++ b/src/drivers/rc/sumd_rc/RCInput.hpp @@ -0,0 +1,107 @@ +/**************************************************************************** + * + * Copyright (c) 2012-2022 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#pragma once + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class RcSumd : public ModuleBase, public ModuleParams, public px4::ScheduledWorkItem +{ +public: + RcSumd(const char *device); + virtual ~RcSumd(); + + /** @see ModuleBase */ + static int task_spawn(int argc, char *argv[]); + + /** @see ModuleBase */ + static int custom_command(int argc, char *argv[]); + + /** @see ModuleBase */ + static int print_usage(const char *reason = nullptr); + + /** @see ModuleBase::print_status() */ + int print_status() override; + + int init(); + +private: + void Run() override; + + void fill_rc_in(uint16_t raw_rc_count_local, + uint16_t raw_rc_values_local[input_rc_s::RC_INPUT_MAX_CHANNELS], + hrt_abstime now, bool frame_drop, bool failsafe, + unsigned frame_drops, int rssi); + + void rc_io_invert(bool invert); + + hrt_abstime _rc_scan_begin{0}; + + bool _initialized{false}; + bool _rc_scan_locked{false}; + + static constexpr unsigned _current_update_interval{4000}; // 250 Hz + + input_rc_s _rc_in{}; + + uORB::PublicationMulti _to_input_rc{ORB_ID(input_rc)}; + + int _rcs_fd{-1}; + char _device[20] {}; ///< device / serial port path + + static constexpr size_t RC_MAX_BUFFER_SIZE{sizeof(ReceiverFcPacketHoTT)}; + uint8_t _rcs_buf[RC_MAX_BUFFER_SIZE] {}; + + uint16_t _raw_rc_values[input_rc_s::RC_INPUT_MAX_CHANNELS] {}; + uint16_t _raw_rc_count{}; + + perf_counter_t _cycle_perf{perf_alloc(PC_ELAPSED, MODULE_NAME": cycle time")}; + perf_counter_t _publish_interval_perf{perf_alloc(PC_INTERVAL, MODULE_NAME": publish interval")}; + uint32_t _bytes_rx{0}; +}; diff --git a/src/drivers/rc/sumd_rc/module.yaml b/src/drivers/rc/sumd_rc/module.yaml new file mode 100644 index 0000000000..c43dfbdbd0 --- /dev/null +++ b/src/drivers/rc/sumd_rc/module.yaml @@ -0,0 +1,7 @@ +module_name: RC SUMD input driver +serial_config: + - command: "rc_sumd start -d ${SERIAL_DEV}" + port_config_param: + name: RC_SUMD_PRT_CFG + group: Serial + #default: RC diff --git a/src/drivers/rc_input/Kconfig b/src/drivers/rc_input/Kconfig deleted file mode 100644 index 1ada2e84f4..0000000000 --- a/src/drivers/rc_input/Kconfig +++ /dev/null @@ -1,5 +0,0 @@ -menuconfig DRIVERS_RC_INPUT - bool "rc_input" - default n - ---help--- - Enable support for rc_input \ No newline at end of file diff --git a/src/drivers/rc_input/RCInput.cpp b/src/drivers/rc_input/RCInput.cpp deleted file mode 100644 index 80c7d7afd1..0000000000 --- a/src/drivers/rc_input/RCInput.cpp +++ /dev/null @@ -1,953 +0,0 @@ -/**************************************************************************** - * - * Copyright (c) 2012-2022 PX4 Development Team. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name PX4 nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -#include "RCInput.hpp" - -#include "crsf_telemetry.h" -#include - -#include - -using namespace time_literals; - -constexpr char const *RCInput::RC_SCAN_STRING[]; - -RCInput::RCInput(const char *device) : - ModuleParams(nullptr), - ScheduledWorkItem(MODULE_NAME, px4::serial_port_to_wq(device)), - _cycle_perf(perf_alloc(PC_ELAPSED, MODULE_NAME": cycle time")), - _publish_interval_perf(perf_alloc(PC_INTERVAL, MODULE_NAME": publish interval")) -{ - // initialize raw_rc values and count - for (unsigned i = 0; i < input_rc_s::RC_INPUT_MAX_CHANNELS; i++) { - _raw_rc_values[i] = UINT16_MAX; - } - - if (device) { - strncpy(_device, device, sizeof(_device) - 1); - _device[sizeof(_device) - 1] = '\0'; - } - - if ((_param_rc_input_proto.get() >= 0) && (_param_rc_input_proto.get() <= RC_SCAN::RC_SCAN_GHST)) { - _rc_scan_state = static_cast(_param_rc_input_proto.get()); - } -} - -RCInput::~RCInput() -{ -#if defined(SPEKTRUM_POWER_PASSIVE) - // Disable power controls for Spektrum receiver - SPEKTRUM_POWER_PASSIVE(); -#endif - dsm_deinit(); - - delete _crsf_telemetry; - delete _ghst_telemetry; - - perf_free(_cycle_perf); - perf_free(_publish_interval_perf); -} - -int -RCInput::init() -{ -#ifdef RF_RADIO_POWER_CONTROL - // power radio on - RF_RADIO_POWER_CONTROL(true); -#endif // RF_RADIO_POWER_CONTROL - - // dsm_init sets some file static variables and returns a file descriptor - // it also powers on the radio if needed - _rcs_fd = dsm_init(_device); - - if (_rcs_fd < 0) { - return -errno; - } - - if (board_rc_swap_rxtx(_device)) { -#if defined(TIOCSSWAP) - ioctl(_rcs_fd, TIOCSSWAP, SER_SWAP_ENABLED); -#endif // TIOCSSWAP - } - - // assume SBUS input and immediately switch it to - // so that if Single wire mode on TX there will be only - // a short contention - sbus_config(_rcs_fd, board_rc_singlewire(_device)); - -#ifdef GPIO_PPM_IN - // disable CPPM input by mapping it away from the timer capture input - px4_arch_unconfiggpio(GPIO_PPM_IN); -#endif // GPIO_PPM_IN - - rc_io_invert(false); - - return 0; -} - -int -RCInput::task_spawn(int argc, char *argv[]) -{ - bool error_flag = false; - - int myoptind = 1; - int ch; - const char *myoptarg = nullptr; - const char *device_name = nullptr; -#if defined(RC_SERIAL_PORT) - device_name = RC_SERIAL_PORT; -#endif // RC_SERIAL_PORT - -#if defined(RC_SERIAL_PORT) && defined(PX4IO_SERIAL_DEVICE) - - // if RC_SERIAL_PORT == PX4IO_SERIAL_DEVICE then don't use it by default if the px4io is running - if ((strcmp(RC_SERIAL_PORT, PX4IO_SERIAL_DEVICE) == 0) && (access("/dev/px4io", R_OK) == 0)) { - device_name = nullptr; - } - -#endif // RC_SERIAL_PORT && PX4IO_SERIAL_DEVICE - - while ((ch = px4_getopt(argc, argv, "d:", &myoptind, &myoptarg)) != EOF) { - switch (ch) { - case 'd': - device_name = myoptarg; - break; - - case '?': - error_flag = true; - break; - - default: - PX4_WARN("unrecognized flag"); - error_flag = true; - break; - } - } - - if (error_flag) { - return -1; - } - - if (device_name && (access(device_name, R_OK | W_OK) == 0)) { - RCInput *instance = new RCInput(device_name); - - if (instance == nullptr) { - PX4_ERR("alloc failed"); - return PX4_ERROR; - } - - _object.store(instance); - _task_id = task_id_is_work_queue; - - instance->ScheduleOnInterval(_current_update_interval); - - return PX4_OK; - - } else { - if (device_name) { - PX4_ERR("invalid device (-d) %s", device_name); - - } else { - PX4_INFO("valid device required"); - } - } - - return PX4_ERROR; -} - -void -RCInput::fill_rc_in(uint16_t raw_rc_count_local, - uint16_t raw_rc_values_local[input_rc_s::RC_INPUT_MAX_CHANNELS], - hrt_abstime now, bool frame_drop, bool failsafe, - unsigned frame_drops, int rssi = -1) -{ - // fill rc_in struct for publishing - _rc_in.channel_count = raw_rc_count_local; - - if (_rc_in.channel_count > input_rc_s::RC_INPUT_MAX_CHANNELS) { - _rc_in.channel_count = input_rc_s::RC_INPUT_MAX_CHANNELS; - } - - unsigned valid_chans = 0; - - for (unsigned i = 0; i < _rc_in.channel_count; i++) { - _rc_in.values[i] = raw_rc_values_local[i]; - - if (raw_rc_values_local[i] != UINT16_MAX) { - valid_chans++; - } - - // once filled, reset values back to default - _raw_rc_values[i] = UINT16_MAX; - } - - _rc_in.timestamp = now; - _rc_in.timestamp_last_signal = _rc_in.timestamp; - _rc_in.rc_ppm_frame_length = 0; - - /* fake rssi if no value was provided */ - if (rssi == -1) { - if ((_param_rc_rssi_pwm_chan.get() > 0) && (_param_rc_rssi_pwm_chan.get() < _rc_in.channel_count)) { - const int32_t rssi_pwm_chan = _param_rc_rssi_pwm_chan.get(); - const int32_t rssi_pwm_min = _param_rc_rssi_pwm_min.get(); - const int32_t rssi_pwm_max = _param_rc_rssi_pwm_max.get(); - - // get RSSI from input channel - int rc_rssi = ((_rc_in.values[rssi_pwm_chan - 1] - rssi_pwm_min) * 100) / (rssi_pwm_max - rssi_pwm_min); - _rc_in.rssi = math::constrain(rc_rssi, 0, 100); - - } else if (_analog_rc_rssi_stable) { - // set RSSI if analog RSSI input is present - float rssi_analog = ((_analog_rc_rssi_volt - 0.2f) / 3.0f) * 100.0f; - - if (rssi_analog > 100.0f) { - rssi_analog = 100.0f; - } - - if (rssi_analog < 0.0f) { - rssi_analog = 0.0f; - } - - _rc_in.rssi = rssi_analog; - - } else { - _rc_in.rssi = 255; - } - - } else { - _rc_in.rssi = rssi; - } - - if (valid_chans == 0) { - _rc_in.rssi = 0; - } - - _rc_in.rc_failsafe = failsafe; - _rc_in.rc_lost = (valid_chans == 0); - _rc_in.rc_lost_frame_count = frame_drops; - _rc_in.rc_total_frame_count = 0; -} - -void RCInput::set_rc_scan_state(RC_SCAN newState) -{ - if ((_param_rc_input_proto.get() > RC_SCAN::RC_SCAN_NONE) - && (_param_rc_input_proto.get() <= RC_SCAN::RC_SCAN_GHST)) { - - _rc_scan_state = static_cast(_param_rc_input_proto.get()); - - } else if (_param_rc_input_proto.get() < 0) { - // only auto change if RC_INPUT_PROTO set to auto (-1) - PX4_DEBUG("RCscan: %s failed, trying %s", RCInput::RC_SCAN_STRING[_rc_scan_state], RCInput::RC_SCAN_STRING[newState]); - _rc_scan_state = newState; - - } else { - _rc_scan_state = RC_SCAN::RC_SCAN_NONE; - } - - _rc_scan_begin = 0; - _rc_scan_locked = false; -} - -void RCInput::rc_io_invert(bool invert) -{ - // First check if the board provides a board-specific inversion method (e.g. via GPIO), - // and if not use an IOCTL - if (!board_rc_invert_input(_device, invert)) { -#if defined(TIOCSINVERT) - - if (invert) { - ioctl(_rcs_fd, TIOCSINVERT, SER_INVERT_ENABLED_RX | SER_INVERT_ENABLED_TX); - - } else { - ioctl(_rcs_fd, TIOCSINVERT, 0); - } - -#endif // TIOCSINVERT - } -} - -void RCInput::Run() -{ - if (should_exit()) { - exit_and_cleanup(); - return; - } - - if (!_initialized) { - if (init() == PX4_OK) { - _initialized = true; - - } else { - PX4_ERR("init failed"); - exit_and_cleanup(); - } - - } else { - - perf_begin(_cycle_perf); - - // Check if parameters have changed - if (_parameter_update_sub.updated()) { - // clear update - parameter_update_s param_update; - _parameter_update_sub.copy(¶m_update); - - updateParams(); - } - - if (_vehicle_status_sub.updated()) { - vehicle_status_s vehicle_status; - - if (_vehicle_status_sub.copy(&vehicle_status)) { - _armed = (vehicle_status.arming_state == vehicle_status_s::ARMING_STATE_ARMED); - } - } - - const hrt_abstime cycle_timestamp = hrt_absolute_time(); - - - /* vehicle command */ - vehicle_command_s vcmd; - - if (_vehicle_cmd_sub.update(&vcmd)) { - // Check for a pairing command - if (vcmd.command == vehicle_command_s::VEHICLE_CMD_START_RX_PAIR) { - - uint8_t cmd_ret = vehicle_command_ack_s::VEHICLE_CMD_RESULT_UNSUPPORTED; -#if defined(SPEKTRUM_POWER) - - if (!_rc_scan_locked && !_armed) { - if ((int)vcmd.param1 == 0) { - // DSM binding command - int dsm_bind_mode = (int)vcmd.param2; - - int dsm_bind_pulses = 0; - - if (dsm_bind_mode == 0) { - dsm_bind_pulses = DSM2_BIND_PULSES; - - } else if (dsm_bind_mode == 1) { - dsm_bind_pulses = DSMX_BIND_PULSES; - - } else { - dsm_bind_pulses = DSMX8_BIND_PULSES; - } - - bind_spektrum(dsm_bind_pulses); - - cmd_ret = vehicle_command_ack_s::VEHICLE_CMD_RESULT_ACCEPTED; - } - - } else { - cmd_ret = vehicle_command_ack_s::VEHICLE_CMD_RESULT_TEMPORARILY_REJECTED; - } - -#endif // SPEKTRUM_POWER - - // publish acknowledgement - vehicle_command_ack_s command_ack{}; - command_ack.command = vcmd.command; - command_ack.result = cmd_ret; - command_ack.target_system = vcmd.source_system; - command_ack.target_component = vcmd.source_component; - command_ack.timestamp = hrt_absolute_time(); - uORB::Publication vehicle_command_ack_pub{ORB_ID(vehicle_command_ack)}; - vehicle_command_ack_pub.publish(command_ack); - } - } - - -#if defined(ADC_RC_RSSI_CHANNEL) - - // update ADC sampling - if (_adc_report_sub.updated()) { - adc_report_s adc; - - if (_adc_report_sub.copy(&adc)) { - for (unsigned i = 0; i < PX4_MAX_ADC_CHANNELS; ++i) { - if (adc.channel_id[i] == ADC_RC_RSSI_CHANNEL) { - float adc_volt = adc.raw_data[i] * - adc.v_ref / - adc.resolution; - - if (_analog_rc_rssi_volt < 0.0f) { - _analog_rc_rssi_volt = adc_volt; - } - - _analog_rc_rssi_volt = _analog_rc_rssi_volt * 0.995f + adc_volt * 0.005f; - - /* only allow this to be used if we see a high RSSI once */ - if (_analog_rc_rssi_volt > 2.5f) { - _analog_rc_rssi_stable = true; - } - } - } - } - } - -#endif // ADC_RC_RSSI_CHANNEL - - bool rc_updated = false; - - // This block scans for a supported serial RC input and locks onto the first one found - // Scan for 500 msec, then switch protocol - constexpr hrt_abstime rc_scan_max = 500_ms; - - unsigned frame_drops = 0; - - // TODO: needs work (poll _rcs_fd) - // int ret = poll(fds, sizeof(fds) / sizeof(fds[0]), 100); - // then update priority to SCHED_PRIORITY_FAST_DRIVER - // read all available data from the serial RC input UART - - // read all available data from the serial RC input UART - int newBytes = ::read(_rcs_fd, &_rcs_buf[0], RC_MAX_BUFFER_SIZE); - - if (newBytes > 0) { - _bytes_rx += newBytes; - } - - const bool rc_scan_locked = _rc_scan_locked; - - switch (_rc_scan_state) { - case RC_SCAN_NONE: - // do nothing - break; - - case RC_SCAN_SBUS: - if (_rc_scan_begin == 0) { - _rc_scan_begin = cycle_timestamp; - // Configure serial port for SBUS - sbus_config(_rcs_fd, board_rc_singlewire(_device)); - rc_io_invert(true); - - // flush serial buffer and any existing buffered data - tcflush(_rcs_fd, TCIOFLUSH); - memset(_rcs_buf, 0, sizeof(_rcs_buf)); - - } else if (_rc_scan_locked - || cycle_timestamp - _rc_scan_begin < rc_scan_max) { - - // parse new data - if (newBytes > 0) { - bool sbus_failsafe = false; - bool sbus_frame_drop = false; - - rc_updated = sbus_parse(cycle_timestamp, &_rcs_buf[0], newBytes, &_raw_rc_values[0], &_raw_rc_count, &sbus_failsafe, - &sbus_frame_drop, &frame_drops, input_rc_s::RC_INPUT_MAX_CHANNELS); - - if (rc_updated) { - // we have a new SBUS frame. Publish it. - _rc_in.input_source = input_rc_s::RC_INPUT_SOURCE_PX4FMU_SBUS; - fill_rc_in(_raw_rc_count, _raw_rc_values, cycle_timestamp, - sbus_frame_drop, sbus_failsafe, frame_drops); - _rc_scan_locked = true; - } - } - - } else { - // Scan the next protocol - rc_io_invert(false); - set_rc_scan_state(RC_SCAN_DSM); - } - - break; - - case RC_SCAN_DSM: - if (_rc_scan_begin == 0) { - _rc_scan_begin = cycle_timestamp; - // Configure serial port for DSM - dsm_config(_rcs_fd); - - // flush serial buffer and any existing buffered data - tcflush(_rcs_fd, TCIOFLUSH); - memset(_rcs_buf, 0, sizeof(_rcs_buf)); - - } else if (_rc_scan_locked - || cycle_timestamp - _rc_scan_begin < rc_scan_max) { - - if (newBytes > 0) { - int8_t dsm_rssi = 0; - bool dsm_11_bit = false; - - // parse new data - rc_updated = dsm_parse(cycle_timestamp, &_rcs_buf[0], newBytes, &_raw_rc_values[0], &_raw_rc_count, - &dsm_11_bit, &frame_drops, &dsm_rssi, input_rc_s::RC_INPUT_MAX_CHANNELS); - - if (rc_updated) { - // we have a new DSM frame. Publish it. - _rc_in.input_source = input_rc_s::RC_INPUT_SOURCE_PX4FMU_DSM; - fill_rc_in(_raw_rc_count, _raw_rc_values, cycle_timestamp, - false, false, frame_drops, dsm_rssi); - _rc_scan_locked = true; - } - } - - } else { - // Scan the next protocol - set_rc_scan_state(RC_SCAN_ST24); - } - - break; - - case RC_SCAN_ST24: - if (_rc_scan_begin == 0) { - _rc_scan_begin = cycle_timestamp; - // Configure serial port for DSM - dsm_config(_rcs_fd); - - // flush serial buffer and any existing buffered data - tcflush(_rcs_fd, TCIOFLUSH); - memset(_rcs_buf, 0, sizeof(_rcs_buf)); - - } else if (_rc_scan_locked - || cycle_timestamp - _rc_scan_begin < rc_scan_max) { - - if (newBytes > 0) { - // parse new data - uint8_t st24_rssi, lost_count; - - rc_updated = false; - - for (unsigned i = 0; i < (unsigned)newBytes; i++) { - /* set updated flag if one complete packet was parsed */ - st24_rssi = input_rc_s::RSSI_MAX; - rc_updated = (OK == st24_decode(_rcs_buf[i], &st24_rssi, &lost_count, - &_raw_rc_count, _raw_rc_values, input_rc_s::RC_INPUT_MAX_CHANNELS)); - } - - // The st24 will keep outputting RC channels and RSSI even if RC has been lost. - // The only way to detect RC loss is therefore to look at the lost_count. - - if (rc_updated) { - if (lost_count == 0) { - // we have a new ST24 frame. Publish it. - _rc_in.input_source = input_rc_s::RC_INPUT_SOURCE_PX4FMU_ST24; - fill_rc_in(_raw_rc_count, _raw_rc_values, cycle_timestamp, - false, false, frame_drops, st24_rssi); - _rc_scan_locked = true; - - } else { - // if the lost count > 0 means that there is an RC loss - _rc_in.rc_lost = true; - } - } - } - - } else { - // Scan the next protocol - set_rc_scan_state(RC_SCAN_SUMD); - } - - break; - - case RC_SCAN_SUMD: - if (_rc_scan_begin == 0) { - _rc_scan_begin = cycle_timestamp; - // Configure serial port for DSM - dsm_config(_rcs_fd); - - // flush serial buffer and any existing buffered data - tcflush(_rcs_fd, TCIOFLUSH); - memset(_rcs_buf, 0, sizeof(_rcs_buf)); - - } else if (_rc_scan_locked - || cycle_timestamp - _rc_scan_begin < rc_scan_max) { - - if (newBytes > 0) { - // parse new data - uint8_t sumd_rssi, rx_count; - bool sumd_failsafe; - - rc_updated = false; - - for (unsigned i = 0; i < (unsigned)newBytes; i++) { - /* set updated flag if one complete packet was parsed */ - sumd_rssi = input_rc_s::RSSI_MAX; - rc_updated = (OK == sumd_decode(_rcs_buf[i], &sumd_rssi, &rx_count, - &_raw_rc_count, _raw_rc_values, input_rc_s::RC_INPUT_MAX_CHANNELS, &sumd_failsafe)); - } - - if (rc_updated) { - // we have a new SUMD frame. Publish it. - _rc_in.input_source = input_rc_s::RC_INPUT_SOURCE_PX4FMU_SUMD; - fill_rc_in(_raw_rc_count, _raw_rc_values, cycle_timestamp, - false, sumd_failsafe, frame_drops, sumd_rssi); - _rc_scan_locked = true; - } - } - - } else { - // Scan the next protocol - set_rc_scan_state(RC_SCAN_PPM); - } - - break; - - case RC_SCAN_PPM: - // skip PPM if it's not supported -#ifdef HRT_PPM_CHANNEL - if (_rc_scan_begin == 0) { - _rc_scan_begin = cycle_timestamp; - // Configure timer input pin for CPPM - px4_arch_configgpio(GPIO_PPM_IN); - - } else if (_rc_scan_locked || cycle_timestamp - _rc_scan_begin < rc_scan_max) { - - // see if we have new PPM input data - if ((ppm_last_valid_decode != _rc_in.timestamp_last_signal) && ppm_decoded_channels > 3) { - // we have a new PPM frame. Publish it. - rc_updated = true; - _rc_in.input_source = input_rc_s::RC_INPUT_SOURCE_PX4FMU_PPM; - fill_rc_in(ppm_decoded_channels, ppm_buffer, cycle_timestamp, false, false, 0); - _rc_scan_locked = true; - _rc_in.rc_ppm_frame_length = ppm_frame_length; - _rc_in.timestamp_last_signal = ppm_last_valid_decode; - } - - } else { - // disable CPPM input by mapping it away from the timer capture input - px4_arch_unconfiggpio(GPIO_PPM_IN); - // Scan the next protocol - set_rc_scan_state(RC_SCAN_CRSF); - } - -#else // skip PPM if it's not supported - set_rc_scan_state(RC_SCAN_CRSF); - -#endif // HRT_PPM_CHANNEL - - break; - - case RC_SCAN_CRSF: - if (_rc_scan_begin == 0) { - _rc_scan_begin = cycle_timestamp; - // Configure serial port for CRSF - crsf_config(_rcs_fd); - - // flush serial buffer and any existing buffered data - tcflush(_rcs_fd, TCIOFLUSH); - memset(_rcs_buf, 0, sizeof(_rcs_buf)); - - } else if (_rc_scan_locked - || cycle_timestamp - _rc_scan_begin < rc_scan_max) { - - // parse new data - if (newBytes > 0) { - rc_updated = crsf_parse(cycle_timestamp, &_rcs_buf[0], newBytes, &_raw_rc_values[0], &_raw_rc_count, - input_rc_s::RC_INPUT_MAX_CHANNELS); - - if (rc_updated) { - // we have a new CRSF frame. Publish it. - _rc_in.input_source = input_rc_s::RC_INPUT_SOURCE_PX4FMU_CRSF; - fill_rc_in(_raw_rc_count, _raw_rc_values, cycle_timestamp, false, false, 0); - - // on Pixhawk (-related) boards we cannot write to the RC UART - // another option is to use a different UART port -#ifdef BOARD_SUPPORTS_RC_SERIAL_PORT_OUTPUT - - if (!_rc_scan_locked && !_crsf_telemetry) { - _crsf_telemetry = new CRSFTelemetry(_rcs_fd); - } - -#endif /* BOARD_SUPPORTS_RC_SERIAL_PORT_OUTPUT */ - - _rc_scan_locked = true; - - if (_crsf_telemetry) { - _crsf_telemetry->update(cycle_timestamp); - } - } - } - - } else { - // Scan the next protocol - set_rc_scan_state(RC_SCAN_GHST); - } - - break; - - case RC_SCAN_GHST: - if (_rc_scan_begin == 0) { - _rc_scan_begin = cycle_timestamp; - // Configure serial port for GHST - ghst_config(_rcs_fd); - - // flush serial buffer and any existing buffered data - tcflush(_rcs_fd, TCIOFLUSH); - memset(_rcs_buf, 0, sizeof(_rcs_buf)); - - } else if (_rc_scan_locked - || cycle_timestamp - _rc_scan_begin < rc_scan_max) { - - // parse new data - if (newBytes > 0) { - int8_t ghst_rssi = -1; - rc_updated = ghst_parse(cycle_timestamp, &_rcs_buf[0], newBytes, &_raw_rc_values[0], &ghst_rssi, - &_raw_rc_count, input_rc_s::RC_INPUT_MAX_CHANNELS); - - if (rc_updated) { - // we have a new GHST frame. Publish it. - _rc_in.input_source = input_rc_s::RC_INPUT_SOURCE_PX4FMU_GHST; - fill_rc_in(_raw_rc_count, _raw_rc_values, cycle_timestamp, false, false, 0, ghst_rssi); - - // ghst telemetry works on fmu-v5 - // on other Pixhawk (-related) boards we cannot write to the RC UART - // another option is to use a different UART port -#ifdef BOARD_SUPPORTS_RC_SERIAL_PORT_OUTPUT - - if (!_rc_scan_locked && !_ghst_telemetry) { - _ghst_telemetry = new GHSTTelemetry(_rcs_fd); - } - -#endif /* BOARD_SUPPORTS_RC_SERIAL_PORT_OUTPUT */ - - _rc_scan_locked = true; - - if (_ghst_telemetry) { - _ghst_telemetry->update(cycle_timestamp); - } - } - } - - } else { - // Scan the next protocol - set_rc_scan_state(RC_SCAN_SBUS); - } - - break; - } - - perf_end(_cycle_perf); - - if (rc_updated) { - perf_count(_publish_interval_perf); - - _rc_in.link_quality = -1; - _rc_in.rssi_dbm = NAN; - - _to_input_rc.publish(_rc_in); - - } else if (!rc_updated && !_armed && (hrt_elapsed_time(&_rc_in.timestamp_last_signal) > 1_s)) { - _rc_scan_locked = false; - } - - if (!rc_scan_locked && _rc_scan_locked) { - PX4_INFO("RC scan: %s RC input locked", RC_SCAN_STRING[_rc_scan_state]); - } - - // set RC_INPUT_PROTO if RC successfully locked for > 3 seconds - if (!_armed && rc_updated && _rc_scan_locked - && ((_rc_scan_begin != 0) && hrt_elapsed_time(&_rc_scan_begin) > 3_s) - && (_param_rc_input_proto.get() < 0) - ) { - // RC_INPUT_PROTO auto => locked selection - _param_rc_input_proto.set(_rc_scan_state); - _param_rc_input_proto.commit(); - } - } -} - -#if defined(SPEKTRUM_POWER) -bool RCInput::bind_spektrum(int arg) const -{ - int ret = PX4_ERROR; - - /* specify 11ms DSMX. RX will automatically fall back to 22ms or DSM2 if necessary */ - - /* only allow DSM2, DSM-X and DSM-X with more than 7 channels */ - PX4_INFO("DSM_BIND_START: DSM%s RX", (arg == 0) ? "2" : ((arg == 1) ? "-X" : "-X8")); - - if (arg == DSM2_BIND_PULSES || - arg == DSMX_BIND_PULSES || - arg == DSMX8_BIND_PULSES) { - - dsm_bind(DSM_CMD_BIND_POWER_DOWN, 0); - - dsm_bind(DSM_CMD_BIND_SET_RX_OUT, 0); - usleep(500000); - - dsm_bind(DSM_CMD_BIND_POWER_UP, 0); - usleep(72000); - - irqstate_t flags = px4_enter_critical_section(); - dsm_bind(DSM_CMD_BIND_SEND_PULSES, arg); - px4_leave_critical_section(flags); - - usleep(50000); - - dsm_bind(DSM_CMD_BIND_REINIT_UART, 0); - - ret = OK; - - } else { - PX4_ERR("DSM bind failed"); - ret = -EINVAL; - } - - return (ret == PX4_OK); -} -#endif /* SPEKTRUM_POWER */ - -int RCInput::custom_command(int argc, char *argv[]) -{ -#if defined(SPEKTRUM_POWER) - const char *verb = argv[0]; - - if (!strcmp(verb, "bind")) { - uORB::Publication vehicle_command_pub{ORB_ID(vehicle_command)}; - vehicle_command_s vcmd{}; - vcmd.command = vehicle_command_s::VEHICLE_CMD_START_RX_PAIR; - vcmd.timestamp = hrt_absolute_time(); - vehicle_command_pub.publish(vcmd); - return 0; - } - -#endif /* SPEKTRUM_POWER */ - - /* start the FMU if not running */ - if (!is_running()) { - int ret = RCInput::task_spawn(argc, argv); - - if (ret) { - return ret; - } - } - - return print_usage("unknown command"); -} - -int RCInput::print_status() -{ - PX4_INFO("Max update rate: %u Hz", 1000000 / _current_update_interval); - - if (_device[0] != '\0') { - PX4_INFO("UART device: %s", _device); - PX4_INFO("UART RX bytes: %" PRIu32, _bytes_rx); - } - - PX4_INFO("RC state: %s: %s", _rc_scan_locked ? "found" : "searching for signal", RC_SCAN_STRING[_rc_scan_state]); - - if (_rc_scan_locked) { - switch (_rc_scan_state) { - case RC_SCAN_NONE: - break; - - case RC_SCAN_CRSF: - PX4_INFO("CRSF Telemetry: %s", _crsf_telemetry ? "yes" : "no"); - break; - - case RC_SCAN_GHST: - PX4_INFO("GHST Telemetry: %s", _ghst_telemetry ? "yes" : "no"); - break; - - case RC_SCAN_SBUS: - PX4_INFO("SBUS frame drops: %u", sbus_dropped_frames()); - break; - - - case RC_SCAN_DSM: - // DSM status output -#if defined(SPEKTRUM_POWER) -#endif - break; - - case RC_SCAN_PPM: - // PPM status output - break; - - case RC_SCAN_SUMD: - // SUMD status output - break; - - case RC_SCAN_ST24: - // SUMD status output - break; - } - } - -#if ADC_RC_RSSI_CHANNEL - - if (_analog_rc_rssi_stable) { - PX4_INFO("vrssi: %dmV", (int)(_analog_rc_rssi_volt * 1000.0f)); - } - -#endif - - perf_print_counter(_cycle_perf); - perf_print_counter(_publish_interval_perf); - - if (hrt_elapsed_time(&_rc_in.timestamp) < 1_s) { - print_message(ORB_ID(input_rc), _rc_in); - } - - return 0; -} - -int -RCInput::print_usage(const char *reason) -{ - if (reason) { - PX4_WARN("%s\n", reason); - } - - PRINT_MODULE_DESCRIPTION( - R"DESCR_STR( -### Description -This module does the RC input parsing and auto-selecting the method. Supported methods are: -- PPM -- SBUS -- DSM -- SUMD -- ST24 -- TBS Crossfire (CRSF) - -)DESCR_STR"); - - PRINT_MODULE_USAGE_NAME("rc_input", "driver"); - PRINT_MODULE_USAGE_COMMAND("start"); - PRINT_MODULE_USAGE_PARAM_STRING('d', "/dev/ttyS3", "", "RC device", true); - -#if defined(SPEKTRUM_POWER) - PRINT_MODULE_USAGE_COMMAND_DESCR("bind", "Send a DSM bind command (module must be running)"); -#endif /* SPEKTRUM_POWER */ - - PRINT_MODULE_USAGE_DEFAULT_COMMANDS(); - - return 0; -} - -extern "C" __EXPORT int rc_input_main(int argc, char *argv[]) -{ - return RCInput::main(argc, argv); -} diff --git a/src/drivers/rc_input/crsf_telemetry.cpp b/src/drivers/rc_input/crsf_telemetry.cpp deleted file mode 100644 index e11687b5d8..0000000000 --- a/src/drivers/rc_input/crsf_telemetry.cpp +++ /dev/null @@ -1,183 +0,0 @@ -/**************************************************************************** - * - * Copyright (c) 2018 PX4 Development Team. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name PX4 nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -#include "crsf_telemetry.h" -#include - -CRSFTelemetry::CRSFTelemetry(int uart_fd) : - _uart_fd(uart_fd) -{ -} - -bool CRSFTelemetry::update(const hrt_abstime &now) -{ - const int update_rate_hz = 10; - - if (now - _last_update <= 1_s / (update_rate_hz * num_data_types)) { - return false; - } - - bool sent = false; - - switch (_next_type) { - case 0: - sent = send_battery(); - break; - - case 1: - sent = send_gps(); - break; - - case 2: - sent = send_attitude(); - break; - - case 3: - sent = send_flight_mode(); - break; - } - - _last_update = now; - _next_type = (_next_type + 1) % num_data_types; - - return sent; -} - -bool CRSFTelemetry::send_battery() -{ - battery_status_s battery_status; - - if (!_battery_status_sub.update(&battery_status)) { - return false; - } - - uint16_t voltage = battery_status.voltage_filtered_v * 10; - uint16_t current = battery_status.current_filtered_a * 10; - int fuel = battery_status.discharged_mah; - uint8_t remaining = battery_status.remaining * 100; - return crsf_send_telemetry_battery(_uart_fd, voltage, current, fuel, remaining); -} - -bool CRSFTelemetry::send_gps() -{ - sensor_gps_s vehicle_gps_position; - - if (!_vehicle_gps_position_sub.update(&vehicle_gps_position)) { - return false; - } - - int32_t latitude = vehicle_gps_position.lat; - int32_t longitude = vehicle_gps_position.lon; - uint16_t groundspeed = vehicle_gps_position.vel_d_m_s / 3.6f * 10.f; - uint16_t gps_heading = math::degrees(vehicle_gps_position.cog_rad) * 100.f; - uint16_t altitude = vehicle_gps_position.alt + 1000; - uint8_t num_satellites = vehicle_gps_position.satellites_used; - - return crsf_send_telemetry_gps(_uart_fd, latitude, longitude, groundspeed, - gps_heading, altitude, num_satellites); -} - -bool CRSFTelemetry::send_attitude() -{ - vehicle_attitude_s vehicle_attitude; - - if (!_vehicle_attitude_sub.update(&vehicle_attitude)) { - return false; - } - - matrix::Eulerf attitude = matrix::Quatf(vehicle_attitude.q); - int16_t pitch = attitude(1) * 1e4f; - int16_t roll = attitude(0) * 1e4f; - int16_t yaw = attitude(2) * 1e4f; - return crsf_send_telemetry_attitude(_uart_fd, pitch, roll, yaw); -} - -bool CRSFTelemetry::send_flight_mode() -{ - vehicle_status_s vehicle_status; - - if (!_vehicle_status_sub.update(&vehicle_status)) { - return false; - } - - const char *flight_mode = "(unknown)"; - - switch (vehicle_status.nav_state) { - case vehicle_status_s::NAVIGATION_STATE_MANUAL: - flight_mode = "Manual"; - break; - - case vehicle_status_s::NAVIGATION_STATE_ALTCTL: - flight_mode = "Altitude"; - break; - - case vehicle_status_s::NAVIGATION_STATE_POSCTL: - flight_mode = "Position"; - break; - - case vehicle_status_s::NAVIGATION_STATE_AUTO_RTL: - flight_mode = "Return"; - break; - - case vehicle_status_s::NAVIGATION_STATE_AUTO_MISSION: - flight_mode = "Mission"; - break; - - case vehicle_status_s::NAVIGATION_STATE_AUTO_LOITER: - case vehicle_status_s::NAVIGATION_STATE_DESCEND: - case vehicle_status_s::NAVIGATION_STATE_AUTO_TAKEOFF: - case vehicle_status_s::NAVIGATION_STATE_AUTO_LAND: - case vehicle_status_s::NAVIGATION_STATE_AUTO_FOLLOW_TARGET: - case vehicle_status_s::NAVIGATION_STATE_AUTO_PRECLAND: - flight_mode = "Auto"; - break; - - case vehicle_status_s::NAVIGATION_STATE_ACRO: - flight_mode = "Acro"; - break; - - case vehicle_status_s::NAVIGATION_STATE_TERMINATION: - flight_mode = "Terminate"; - break; - - case vehicle_status_s::NAVIGATION_STATE_OFFBOARD: - flight_mode = "Offboard"; - break; - - case vehicle_status_s::NAVIGATION_STATE_STAB: - flight_mode = "Stabilized"; - break; - } - - return crsf_send_telemetry_flight_mode(_uart_fd, flight_mode); -} diff --git a/src/drivers/rc_input/crsf_telemetry.h b/src/drivers/rc_input/crsf_telemetry.h deleted file mode 100644 index 910a0ec871..0000000000 --- a/src/drivers/rc_input/crsf_telemetry.h +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** - * - * Copyright (c) 2018 PX4 Development Team. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name PX4 nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/** - * @file crsf_telemetry.h - * - * @author Beat Küng - */ - -#pragma once - -#include -#include -#include -#include -#include -#include - -#include -#include - -using namespace time_literals; - -/** - * High-level class that handles sending of CRSF telemetry data - */ -class CRSFTelemetry -{ -public: - /** - * @param uart_fd file descriptor for the UART to use. It is expected to be configured - * already. - */ - CRSFTelemetry(int uart_fd); - - ~CRSFTelemetry() = default; - - /** - * Send telemetry data. Call this regularly (i.e. at 100Hz), it will automatically - * limit the sending rate. - * @return true if new data sent - */ - bool update(const hrt_abstime &now); - -private: - bool send_battery(); - bool send_gps(); - bool send_attitude(); - bool send_flight_mode(); - - uORB::Subscription _vehicle_gps_position_sub{ORB_ID(vehicle_gps_position)}; - uORB::Subscription _battery_status_sub{ORB_ID(battery_status)}; - uORB::Subscription _vehicle_attitude_sub{ORB_ID(vehicle_attitude)}; - uORB::Subscription _vehicle_status_sub{ORB_ID(vehicle_status)}; - - hrt_abstime _last_update{0}; - - static constexpr int num_data_types{4}; ///< number of different telemetry data types - int _next_type{0}; - - int _uart_fd; -}; diff --git a/src/drivers/rc_input/ghst_telemetry.cpp b/src/drivers/rc_input/ghst_telemetry.cpp deleted file mode 100644 index 2b253bbc3f..0000000000 --- a/src/drivers/rc_input/ghst_telemetry.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/**************************************************************************** - * - * Copyright (c) 2021 PX4 Development Team. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name PX4 nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/** - * @file ghst_telemetry.cpp - * - * IRC Ghost (Immersion RC Ghost) telemetry. - * - * @author Igor Misic - * @author Juraj Ciberlin - */ - -#include "ghst_telemetry.hpp" -#include - -using time_literals::operator ""_s; - -GHSTTelemetry::GHSTTelemetry(int uart_fd) : - _uart_fd(uart_fd) -{ -} - -bool GHSTTelemetry::update(const hrt_abstime &now) -{ - bool success = false; - - if ((now - _last_update) > (1_s / (UPDATE_RATE_HZ * NUM_DATA_TYPES))) { - - switch (_next_type) { - case 0U: - success = send_battery_status(); - break; - - case 1U: - success = send_gps1_status(); - break; - - case 2U: - success = send_gps2_status(); - break; - - default: - success = false; - break; - } - - _last_update = now; - _next_type = (_next_type + 1U) % NUM_DATA_TYPES; - } - - return success; -} - -bool GHSTTelemetry::send_battery_status() -{ - bool success = false; - float voltage_in_10mV; - float current_in_10mA; - float fuel_in_10mAh; - battery_status_s battery_status; - - if (_battery_status_sub.update(&battery_status)) { - voltage_in_10mV = battery_status.voltage_filtered_v * FACTOR_VOLTS_TO_10MV; - current_in_10mA = battery_status.current_filtered_a * FACTOR_AMPS_TO_10MA; - fuel_in_10mAh = battery_status.discharged_mah * FACTOR_MAH_TO_10MAH; - success = ghst_send_telemetry_battery_status(_uart_fd, - static_cast(voltage_in_10mV), - static_cast(current_in_10mA), - static_cast(fuel_in_10mAh)); - } - - return success; -} - -bool GHSTTelemetry::send_gps1_status() -{ - sensor_gps_s vehicle_gps_position; - - if (!_vehicle_gps_position_sub.update(&vehicle_gps_position)) { - return false; - } - - int32_t latitude = vehicle_gps_position.lat; // 1e-7 degrees - int32_t longitude = vehicle_gps_position.lon; // 1e-7 degrees - uint16_t altitude = vehicle_gps_position.alt / 1000; // mm -> m - - return ghst_send_telemetry_gps1_status(_uart_fd, latitude, longitude, altitude); -} - -bool GHSTTelemetry::send_gps2_status() -{ - sensor_gps_s vehicle_gps_position; - - if (!_vehicle_gps_position_sub.update(&vehicle_gps_position)) { - return false; - } - - uint16_t ground_speed = (uint16_t)(vehicle_gps_position.vel_d_m_s / 3.6f * 10.f); - uint16_t ground_course = (uint16_t)(math::degrees(vehicle_gps_position.cog_rad) * 100.f); - uint8_t num_sats = vehicle_gps_position.satellites_used; - - // TBD: Can these be computed in a RC telemetry driver? - uint16_t home_dist = 0; - uint16_t home_dir = 0; - uint8_t flags = 0; - - return ghst_send_telemetry_gps2_status(_uart_fd, ground_speed, ground_course, num_sats, home_dist, home_dir, flags); -} - diff --git a/src/drivers/rc_input/module.yaml b/src/drivers/rc_input/module.yaml deleted file mode 100644 index d0f9040a6f..0000000000 --- a/src/drivers/rc_input/module.yaml +++ /dev/null @@ -1,35 +0,0 @@ -module_name: RC Input Driver -parameters: - - group: RC Input - definitions: - RC_INPUT_PROTO: - description: - short: RC input protocol - long: | - Select your RC input protocol or auto to scan. - category: System - type: enum - values: - -1: Auto - 0: None - 1: PPM - 2: SBUS - 3: DSM - 4: ST24 - 5: SUMD - 6: CRSF - 7: GHST - min: -1 - max: 7 - default: -1 - -serial_config: - - command: set RC_INPUT_ARGS "-d ${SERIAL_DEV}" - port_config_param: - name: RC_PORT_CONFIG - group: Serial - default: RC - description_extended: | - Setting this to 'Disabled' will use a board-specific default port - for RC input. - diff --git a/src/drivers/snapdragon_spektrum_rc/spektrum_rc.cpp b/src/drivers/snapdragon_spektrum_rc/spektrum_rc.cpp deleted file mode 100644 index ee39c6d970..0000000000 --- a/src/drivers/snapdragon_spektrum_rc/spektrum_rc.cpp +++ /dev/null @@ -1,298 +0,0 @@ -/**************************************************************************** - * - * Copyright (c) 2016 PX4 Development Team. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name PX4 nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - - -/** - * @file spektrum_rc.cpp - * - * This is a driver for a Spektrum satellite receiver connected to a Snapdragon - * on the serial port. By default port J12 (next to J13, power module side) is used. - */ - -#include - -#include -#include -#include - -#include -#include - -#include -#include - -// Snapdraogon: use J12 (next to J13, power module side) -#define SPEKTRUM_UART_DEVICE_PATH "/dev/tty-3" - -#define UNUSED(x) (void)(x) - -extern "C" { __EXPORT int spektrum_rc_main(int argc, char *argv[]); } - - -namespace spektrum_rc -{ - -volatile bool _task_should_exit = false; -static bool _is_running = false; -static px4_task_t _task_handle = -1; - -int start(); -int stop(); -int info(); -void usage(); -void task_main(int argc, char *argv[]); - -void fill_input_rc(uint16_t raw_rc_count, uint16_t raw_rc_values[input_rc_s::RC_INPUT_MAX_CHANNELS], - hrt_abstime now, bool frame_drop, bool failsafe, unsigned frame_drops, int rssi, - input_rc_s &input_rc); - -void task_main(int argc, char *argv[]) -{ - const char *device_path = SPEKTRUM_UART_DEVICE_PATH; - int ch; - int myoptind = 1; - const char *myoptarg = NULL; - - while ((ch = px4_getopt(argc, argv, "d:", &myoptind, &myoptarg)) != EOF) { - switch (ch) { - case 'd': - device_path = myoptarg; - break; - - default: - break; - } - } - - int uart_fd = dsm_init(device_path); - - if (uart_fd < 1) { - PX4_ERR("dsm init failed"); - return; - } - - orb_advert_t rc_pub = nullptr; - - // Use a buffer size of the double of the minimum, just to be safe. - uint8_t rx_buf[2 * DSM_BUFFER_SIZE]; - - _is_running = true; - uint16_t raw_rc_values[input_rc_s::RC_INPUT_MAX_CHANNELS]; - uint16_t raw_rc_count = 0; - - // Main loop - while (!_task_should_exit) { - - int newbytes = ::read(uart_fd, &rx_buf[0], sizeof(rx_buf)); - - if (newbytes < 0) { - PX4_WARN("read failed"); - continue; - } - - if (newbytes == 0) { - continue; - } - - const hrt_abstime now = hrt_absolute_time(); - - bool dsm_11_bit; - unsigned frame_drops; - int8_t dsm_rssi; - - // parse new data - bool rc_updated = dsm_parse(now, rx_buf, newbytes, &raw_rc_values[0], &raw_rc_count, - &dsm_11_bit, &frame_drops, &dsm_rssi, input_rc_s::RC_INPUT_MAX_CHANNELS); - UNUSED(dsm_11_bit); - - if (rc_updated) { - - input_rc_s input_rc = {}; - - fill_input_rc(raw_rc_count, raw_rc_values, now, false, false, frame_drops, dsm_rssi, - input_rc); - - if (rc_pub == nullptr) { - rc_pub = orb_advertise(ORB_ID(input_rc), &input_rc); - - } else { - orb_publish(ORB_ID(input_rc), rc_pub, &input_rc); - } - } - - // sleep since no poll for qurt - usleep(10000); - - } - - orb_unadvertise(rc_pub); - dsm_deinit(); - - _is_running = false; -} - -void fill_input_rc(uint16_t raw_rc_count, uint16_t raw_rc_values[input_rc_s::RC_INPUT_MAX_CHANNELS], - hrt_abstime now, bool frame_drop, bool failsafe, unsigned frame_drops, int rssi, - input_rc_s &input_rc) -{ - input_rc.input_source = input_rc_s::RC_INPUT_SOURCE_QURT; - - input_rc.channel_count = raw_rc_count; - - if (input_rc.channel_count > input_rc_s::RC_INPUT_MAX_CHANNELS) { - input_rc.channel_count = input_rc_s::RC_INPUT_MAX_CHANNELS; - } - - unsigned valid_chans = 0; - - for (unsigned i = 0; i < input_rc.channel_count; ++i) { - input_rc.values[i] = raw_rc_values[i]; - - if (raw_rc_values[i] != UINT16_MAX) { - valid_chans++; - } - } - - input_rc.timestamp = now; - input_rc.timestamp_last_signal = input_rc.timestamp; - input_rc.rc_ppm_frame_length = 0; - - /* fake rssi if no value was provided */ - if (rssi == -1) { - - input_rc.rssi = 255; - - } else { - input_rc.rssi = rssi; - } - - if (valid_chans == 0) { - input_rc.rssi = 0; - } - - input_rc.rc_failsafe = failsafe; - input_rc.rc_lost = (valid_chans == 0); - input_rc.rc_lost_frame_count = frame_drops; - input_rc.rc_total_frame_count = 0; - - input_rc.link_quality = -1; - input_rc.rssi_dbm = NAN; -} - -int start(int argc, char *argv[]) -{ - if (_is_running) { - PX4_WARN("already running"); - return -1; - } - - _task_should_exit = false; - - _task_handle = px4_task_spawn_cmd("spektrum_rc_main", - SCHED_DEFAULT, - SCHED_PRIORITY_DEFAULT, - 2000, - (px4_main_t)&task_main, - (char *const *)argv); - - if (_task_handle < 0) { - PX4_ERR("task start failed"); - return -1; - } - - return 0; -} - -int stop() -{ - if (!_is_running) { - PX4_WARN("not running"); - return -1; - } - - _task_should_exit = true; - - while (_is_running) { - usleep(200000); - PX4_INFO("."); - } - - _task_handle = -1; - return 0; -} - -int info() -{ - PX4_INFO("running: %s", _is_running ? "yes" : "no"); - - return 0; -} - -void -usage() -{ - PX4_INFO("Usage: spektrum_rc {start|info|stop}"); -} - -} // namespace spektrum_rc - - -int spektrum_rc_main(int argc, char *argv[]) -{ - int myoptind = 1; - - if (argc <= 1) { - spektrum_rc::usage(); - return 1; - } - - const char *verb = argv[myoptind]; - - - if (!strcmp(verb, "start")) { - return spektrum_rc::start(argc - 1, argv + 1); - } - - else if (!strcmp(verb, "stop")) { - return spektrum_rc::stop(); - } - - else if (!strcmp(verb, "info")) { - return spektrum_rc::info(); - } - - else { - spektrum_rc::usage(); - return 1; - } -} diff --git a/src/drivers/spektrum_rc/Kconfig b/src/drivers/spektrum_rc/Kconfig deleted file mode 100644 index 0d67ce18b2..0000000000 --- a/src/drivers/spektrum_rc/Kconfig +++ /dev/null @@ -1,5 +0,0 @@ -menuconfig DRIVERS_SPEKTRUM_RC - bool "spektrum_rc" - default n - ---help--- - Enable support for spektrum_rc \ No newline at end of file diff --git a/src/lib/rc/CMakeLists.txt b/src/lib/rc/CMakeLists.txt index e24cc0dcc9..075a44d12a 100644 --- a/src/lib/rc/CMakeLists.txt +++ b/src/lib/rc/CMakeLists.txt @@ -31,26 +31,11 @@ # ############################################################################ -add_library(rc - crsf.cpp - ghst.cpp - st24.cpp - sumd.cpp - sbus.cpp - dsm.cpp - common_rc.cpp -) -target_compile_options(rc - PRIVATE - #-DDEBUG_BUILD - -Wno-unused-result -) -target_link_libraries(rc PRIVATE prebuild_targets) +add_subdirectory(dsm) +add_subdirectory(sbus) +add_subdirectory(st24) +add_subdirectory(sumd) if(PX4_TESTING AND (${PX4_PLATFORM} MATCHES "posix")) add_subdirectory(rc_tests) endif() - -if(${PX4_PLATFORM} MATCHES "nuttx") - target_link_libraries(rc PRIVATE nuttx_fs) -endif() diff --git a/src/lib/rc/common_rc.cpp b/src/lib/rc/common_rc.cpp deleted file mode 100644 index 6cda37b9c3..0000000000 --- a/src/lib/rc/common_rc.cpp +++ /dev/null @@ -1,31 +0,0 @@ - -#include "common_rc.h" - -__EXPORT rc_decode_buf_t rc_decode_buf; - -uint8_t crc8_dvb_s2(uint8_t crc, uint8_t a) -{ - crc ^= a; - - for (int i = 0; i < 8; ++i) { - if (crc & 0x80) { - crc = (crc << 1) ^ 0xD5; - - } else { - crc = crc << 1; - } - } - - return crc; -} - -uint8_t crc8_dvb_s2_buf(uint8_t *buf, int len) -{ - uint8_t crc = 0; - - for (int i = 0; i < len; ++i) { - crc = crc8_dvb_s2(crc, buf[i]); - } - - return crc; -} diff --git a/src/lib/rc/common_rc.h b/src/lib/rc/common_rc.h deleted file mode 100644 index 4a94615045..0000000000 --- a/src/lib/rc/common_rc.h +++ /dev/null @@ -1,29 +0,0 @@ - -#pragma once - -#include - -#include "crsf.h" -#include "dsm.h" -#include "ghst.hpp" -#include "sbus.h" -#include "st24.h" -#include "sumd.h" - -#pragma pack(push, 1) -typedef struct rc_decode_buf_ { - union { - crsf_frame_t crsf_frame; - ghst_frame_t ghst_frame; - dsm_decode_t dsm; - sbus_frame_t sbus_frame; - ReceiverFcPacket _strxpacket; - ReceiverFcPacketHoTT _hottrxpacket; - }; -} rc_decode_buf_t; -#pragma pack(pop) - -extern rc_decode_buf_t rc_decode_buf; - -uint8_t crc8_dvb_s2(uint8_t crc, uint8_t a); -uint8_t crc8_dvb_s2_buf(uint8_t *buf, int len); diff --git a/src/lib/rc/crsf.cpp b/src/lib/rc/crsf.cpp deleted file mode 100644 index 383a0fbe71..0000000000 --- a/src/lib/rc/crsf.cpp +++ /dev/null @@ -1,478 +0,0 @@ -/**************************************************************************** - * - * Copyright (c) 2018 PX4 Development Team. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name PX4 nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -#if 0 // enable non-verbose debugging -#define CRSF_DEBUG PX4_WARN -#else -#define CRSF_DEBUG(...) -#endif - -#if 0 // verbose debugging. Careful when enabling: it leads to too much output, causing dropped bytes -#define CRSF_VERBOSE PX4_WARN -#else -#define CRSF_VERBOSE(...) -#endif - -#include -#include -#include -#include - -#include "crsf.h" -#include "common_rc.h" - -#define MIN(a,b) (((a)<(b))?(a):(b)) -#define MAX(a,b) (((a)>(b))?(a):(b)) - - -#define CRSF_BAUDRATE 420000 - -#define CRSF_SYNC_BYTE 0xC8 - -enum class crsf_frame_type_t : uint8_t { - gps = 0x02, - battery_sensor = 0x08, - link_statistics = 0x14, - rc_channels_packed = 0x16, - attitude = 0x1E, - flight_mode = 0x21, - - // Extended Header Frames, range: 0x28 to 0x96 - device_ping = 0x28, - device_info = 0x29, - parameter_settings_entry = 0x2B, - parameter_read = 0x2C, - parameter_write = 0x2D, - command = 0x32 -}; - -enum class crsf_payload_size_t : uint8_t { - gps = 15, - battery_sensor = 8, - link_statistics = 10, - rc_channels = 22, ///< 11 bits per channel * 16 channels = 22 bytes. - attitude = 6, -}; - - -enum class crsf_address_t : uint8_t { - broadcast = 0x00, - usb = 0x10, - tbs_core_pnp_pro = 0x80, - reserved1 = 0x8A, - current_sensor = 0xC0, - gps = 0xC2, - tbs_blackbox = 0xC4, - flight_controller = 0xC8, - reserved2 = 0xCA, - race_tag = 0xCC, - radio_transmitter = 0xEA, - crsf_receiver = 0xEC, - crsf_transmitter = 0xEE -}; - -#pragma pack(push, 1) -struct crsf_payload_RC_channels_packed_t { - // 176 bits of data (11 bits per channel * 16 channels) = 22 bytes - unsigned chan0 : 11; - unsigned chan1 : 11; - unsigned chan2 : 11; - unsigned chan3 : 11; - unsigned chan4 : 11; - unsigned chan5 : 11; - unsigned chan6 : 11; - unsigned chan7 : 11; - unsigned chan8 : 11; - unsigned chan9 : 11; - unsigned chan10 : 11; - unsigned chan11 : 11; - unsigned chan12 : 11; - unsigned chan13 : 11; - unsigned chan14 : 11; - unsigned chan15 : 11; -}; - -#pragma pack(pop) - -enum class crsf_parser_state_t : uint8_t { - unsynced = 0, - synced -}; - -static crsf_frame_t &crsf_frame = rc_decode_buf.crsf_frame; -static unsigned current_frame_position = 0; -static crsf_parser_state_t parser_state = crsf_parser_state_t::unsynced; - -/** - * parse the current crsf_frame buffer - */ -static bool crsf_parse_buffer(uint16_t *values, uint16_t *num_values, uint16_t max_channels); - -uint8_t crsf_frame_CRC(const crsf_frame_t &frame); - - -int -crsf_config(int uart_fd) -{ - struct termios t; - - /* no parity, one stop bit */ - tcgetattr(uart_fd, &t); - cfsetspeed(&t, CRSF_BAUDRATE); - t.c_cflag &= ~(CSTOPB | PARENB); - return tcsetattr(uart_fd, TCSANOW, &t); -} - -/** - * Convert from RC to PWM value - * @param chan_value channel value in [172, 1811] - * @return PWM channel value in [1000, 2000] - */ -static uint16_t convert_channel_value(unsigned chan_value); - - -bool crsf_parse(const uint64_t now, const uint8_t *frame, unsigned len, uint16_t *values, - uint16_t *num_values, uint16_t max_channels) -{ - bool ret = false; - uint8_t *crsf_frame_ptr = (uint8_t *)&crsf_frame; - - while (len > 0) { - - // fill in the crsf_buffer, as much as we can - const unsigned current_len = MIN(len, sizeof(crsf_frame_t) - current_frame_position); - memcpy(crsf_frame_ptr + current_frame_position, frame, current_len); - current_frame_position += current_len; - - // protection to guarantee parsing progress - if (current_len == 0) { - CRSF_DEBUG("========== parser bug: no progress (%i) ===========", len); - - for (unsigned i = 0; i < current_frame_position; ++i) { - CRSF_DEBUG("crsf_frame_ptr[%i]: 0x%x", i, (int)crsf_frame_ptr[i]); - } - - // reset the parser - current_frame_position = 0; - parser_state = crsf_parser_state_t::unsynced; - return false; - } - - len -= current_len; - frame += current_len; - - if (crsf_parse_buffer(values, num_values, max_channels)) { - ret = true; - } - } - - - return ret; -} - -uint8_t crsf_frame_CRC(const crsf_frame_t &frame) -{ - // CRC includes type and payload - uint8_t crc = crc8_dvb_s2(0, frame.type); - - for (int i = 0; i < frame.header.length - 2; ++i) { - crc = crc8_dvb_s2(crc, frame.payload[i]); - } - - return crc; -} - -static uint16_t convert_channel_value(unsigned chan_value) -{ - /* - * RC PWM - * min 172 -> 988us - * mid 992 -> 1500us - * max 1811 -> 2012us - */ - static constexpr float scale = (2012.f - 988.f) / (1811.f - 172.f); - static constexpr float offset = 988.f - 172.f * scale; - return (scale * chan_value) + offset; -} - -static bool crsf_parse_buffer(uint16_t *values, uint16_t *num_values, uint16_t max_channels) -{ - uint8_t *crsf_frame_ptr = (uint8_t *)&crsf_frame; - - if (parser_state == crsf_parser_state_t::unsynced) { - // there is no sync byte, try to find an RC packet by searching for a matching frame length and type - for (unsigned i = 1; i < current_frame_position - 1; ++i) { - if (crsf_frame_ptr[i] == (uint8_t)crsf_payload_size_t::rc_channels + 2 && - crsf_frame_ptr[i + 1] == (uint8_t)crsf_frame_type_t::rc_channels_packed) { - parser_state = crsf_parser_state_t::synced; - unsigned frame_offset = i - 1; - CRSF_VERBOSE("RC channels found at offset %i", frame_offset); - - // move the rest of the buffer to the beginning - if (frame_offset != 0) { - memmove(crsf_frame_ptr, crsf_frame_ptr + frame_offset, current_frame_position - frame_offset); - current_frame_position -= frame_offset; - } - - break; - } - } - } - - if (parser_state != crsf_parser_state_t::synced) { - if (current_frame_position >= sizeof(crsf_frame_t)) { - // discard most of the data, but keep the last 3 bytes (otherwise we could miss the frame start) - current_frame_position = 3; - - for (unsigned i = 0; i < current_frame_position; ++i) { - crsf_frame_ptr[i] = crsf_frame_ptr[sizeof(crsf_frame_t) - current_frame_position + i]; - } - - CRSF_VERBOSE("Discarding buffer"); - } - - return false; - } - - - if (current_frame_position < 3) { - // wait until we have the header & type - return false; - } - - // Now we have at least the header and the type - - const unsigned current_frame_length = crsf_frame.header.length + sizeof(crsf_frame_header_t); - - if (current_frame_length > sizeof(crsf_frame_t) || current_frame_length < 4) { - // frame too long or bogus -> discard everything and go into unsynced state - current_frame_position = 0; - parser_state = crsf_parser_state_t::unsynced; - CRSF_DEBUG("Frame too long/bogus (%i, type=%i) -> unsync", current_frame_length, crsf_frame.type); - return false; - } - - if (current_frame_position < current_frame_length) { - // we don't have the full frame yet -> wait for more data - CRSF_VERBOSE("waiting for more data (%i < %i)", current_frame_position, current_frame_length); - return false; - } - - bool ret = false; - - // Now we have the full frame - - if (crsf_frame.type == (uint8_t)crsf_frame_type_t::rc_channels_packed && - crsf_frame.header.length == (uint8_t)crsf_payload_size_t::rc_channels + 2) { - const uint8_t crc = crsf_frame.payload[crsf_frame.header.length - 2]; - - if (crc == crsf_frame_CRC(crsf_frame)) { - const crsf_payload_RC_channels_packed_t *const rc_channels = - (crsf_payload_RC_channels_packed_t *)&crsf_frame.payload; - *num_values = MIN(max_channels, 16); - - if (max_channels > 0) { values[0] = convert_channel_value(rc_channels->chan0); } - - if (max_channels > 1) { values[1] = convert_channel_value(rc_channels->chan1); } - - if (max_channels > 2) { values[2] = convert_channel_value(rc_channels->chan2); } - - if (max_channels > 3) { values[3] = convert_channel_value(rc_channels->chan3); } - - if (max_channels > 4) { values[4] = convert_channel_value(rc_channels->chan4); } - - if (max_channels > 5) { values[5] = convert_channel_value(rc_channels->chan5); } - - if (max_channels > 6) { values[6] = convert_channel_value(rc_channels->chan6); } - - if (max_channels > 7) { values[7] = convert_channel_value(rc_channels->chan7); } - - if (max_channels > 8) { values[8] = convert_channel_value(rc_channels->chan8); } - - if (max_channels > 9) { values[9] = convert_channel_value(rc_channels->chan9); } - - if (max_channels > 10) { values[10] = convert_channel_value(rc_channels->chan10); } - - if (max_channels > 11) { values[11] = convert_channel_value(rc_channels->chan11); } - - if (max_channels > 12) { values[12] = convert_channel_value(rc_channels->chan12); } - - if (max_channels > 13) { values[13] = convert_channel_value(rc_channels->chan13); } - - if (max_channels > 14) { values[14] = convert_channel_value(rc_channels->chan14); } - - if (max_channels > 15) { values[15] = convert_channel_value(rc_channels->chan15); } - - CRSF_VERBOSE("Got Channels"); - - ret = true; - - } else { - CRSF_DEBUG("CRC check failed"); - } - - } else { - CRSF_DEBUG("Got Non-RC frame (len=%i, type=%i)", current_frame_length, crsf_frame.type); - // We could check the CRC here and reset the parser into unsynced state if it fails. - // But in practise it's robust even without that. - } - - // Either reset or move the rest of the buffer - if (current_frame_position > current_frame_length) { - CRSF_VERBOSE("Moving buffer (%i > %i)", current_frame_position, current_frame_length); - memmove(crsf_frame_ptr, crsf_frame_ptr + current_frame_length, current_frame_position - current_frame_length); - current_frame_position -= current_frame_length; - - } else { - current_frame_position = 0; - } - - return ret; -} - -/** - * write an uint8_t value to a buffer at a given offset and increment the offset - */ -static inline void write_uint8_t(uint8_t *buf, int &offset, uint8_t value) -{ - buf[offset++] = value; -} -/** - * write an uint16_t value to a buffer at a given offset and increment the offset - */ -static inline void write_uint16_t(uint8_t *buf, int &offset, uint16_t value) -{ - // Big endian - buf[offset] = value >> 8; - buf[offset + 1] = value & 0xff; - offset += 2; -} -/** - * write an uint24_t value to a buffer at a given offset and increment the offset - */ -static inline void write_uint24_t(uint8_t *buf, int &offset, int value) -{ - // Big endian - buf[offset] = value >> 16; - buf[offset + 1] = (value >> 8) & 0xff; - buf[offset + 2] = value & 0xff; - offset += 3; -} - -/** - * write an int32_t value to a buffer at a given offset and increment the offset - */ -static inline void write_int32_t(uint8_t *buf, int &offset, int32_t value) -{ - // Big endian - buf[offset] = value >> 24; - buf[offset + 1] = (value >> 16) & 0xff; - buf[offset + 2] = (value >> 8) & 0xff; - buf[offset + 3] = value & 0xff; - offset += 4; -} - -static inline void write_frame_header(uint8_t *buf, int &offset, crsf_frame_type_t type, uint8_t payload_size) -{ - write_uint8_t(buf, offset, CRSF_SYNC_BYTE); // this got changed from the address to the sync byte - write_uint8_t(buf, offset, payload_size + 2); - write_uint8_t(buf, offset, (uint8_t)type); -} -static inline void write_frame_crc(uint8_t *buf, int &offset, int buf_size) -{ - // CRC does not include the address and length - write_uint8_t(buf, offset, crc8_dvb_s2_buf(buf + 2, buf_size - 3)); - - // check correctness of buffer size (only needed during development) - //if (buf_size != offset) { PX4_ERR("frame size mismatch (%i != %i)", buf_size, offset); } -} - -bool crsf_send_telemetry_battery(int uart_fd, uint16_t voltage, uint16_t current, int fuel, uint8_t remaining) -{ - uint8_t buf[(uint8_t)crsf_payload_size_t::battery_sensor + 4]; - int offset = 0; - write_frame_header(buf, offset, crsf_frame_type_t::battery_sensor, (uint8_t)crsf_payload_size_t::battery_sensor); - write_uint16_t(buf, offset, voltage); - write_uint16_t(buf, offset, current); - write_uint24_t(buf, offset, fuel); - write_uint8_t(buf, offset, remaining); - write_frame_crc(buf, offset, sizeof(buf)); - return write(uart_fd, buf, offset) == offset; -} - -bool crsf_send_telemetry_gps(int uart_fd, int32_t latitude, int32_t longitude, uint16_t groundspeed, - uint16_t gps_heading, uint16_t altitude, uint8_t num_satellites) -{ - uint8_t buf[(uint8_t)crsf_payload_size_t::gps + 4]; - int offset = 0; - write_frame_header(buf, offset, crsf_frame_type_t::gps, (uint8_t)crsf_payload_size_t::gps); - write_int32_t(buf, offset, latitude); - write_int32_t(buf, offset, longitude); - write_uint16_t(buf, offset, groundspeed); - write_uint16_t(buf, offset, gps_heading); - write_uint16_t(buf, offset, altitude); - write_uint8_t(buf, offset, num_satellites); - write_frame_crc(buf, offset, sizeof(buf)); - return write(uart_fd, buf, offset) == offset; -} - -bool crsf_send_telemetry_attitude(int uart_fd, int16_t pitch, int16_t roll, int16_t yaw) -{ - uint8_t buf[(uint8_t)crsf_payload_size_t::attitude + 4]; - int offset = 0; - write_frame_header(buf, offset, crsf_frame_type_t::attitude, (uint8_t)crsf_payload_size_t::attitude); - write_uint16_t(buf, offset, pitch); - write_uint16_t(buf, offset, roll); - write_uint16_t(buf, offset, yaw); - write_frame_crc(buf, offset, sizeof(buf)); - return write(uart_fd, buf, offset) == offset; -} - -bool crsf_send_telemetry_flight_mode(int uart_fd, const char *flight_mode) -{ - const int max_length = 16; - int length = strlen(flight_mode) + 1; - - if (length > max_length) { - length = max_length; - } - - uint8_t buf[max_length + 4]; - int offset = 0; - write_frame_header(buf, offset, crsf_frame_type_t::flight_mode, length); - memcpy(buf + offset, flight_mode, length); - offset += length; - buf[offset - 1] = 0; // ensure null-terminated string - write_frame_crc(buf, offset, length + 4); - return write(uart_fd, buf, offset) == offset; -} diff --git a/src/lib/rc/crsf.h b/src/lib/rc/crsf.h deleted file mode 100644 index 6840c685ee..0000000000 --- a/src/lib/rc/crsf.h +++ /dev/null @@ -1,134 +0,0 @@ -/**************************************************************************** - * - * Copyright (c) 2018 PX4 Development Team. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name PX4 nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/** - * @file crsf.h - * - * RC protocol definition for CSRF (TBS Crossfire). - * It is an uninverted protocol at 420000 baudrate. - * - * RC channels come in at 150Hz. - * - * @author Beat Küng - */ - -#pragma once - -#include -#include - -__BEGIN_DECLS - -#define CRSF_FRAME_SIZE_MAX 30 // the actual maximum length is 64, but we're only interested in RC channels and want to minimize buffer size -#define CRSF_PAYLOAD_SIZE_MAX (CRSF_FRAME_SIZE_MAX-4) - - -struct crsf_frame_header_t { - uint8_t device_address; ///< @see crsf_address_t - uint8_t length; ///< length of crsf_frame_t (including CRC) minus sizeof(crsf_frame_header_t) -}; - -struct crsf_frame_t { - crsf_frame_header_t header; - uint8_t type; ///< @see crsf_frame_type_t - uint8_t payload[CRSF_PAYLOAD_SIZE_MAX + 1]; ///< payload data including 1 byte CRC at end -}; - -/** - * Configure an UART port to be used for CRSF - * @param uart_fd UART file descriptor - * @return 0 on success, -errno otherwise - */ -__EXPORT int crsf_config(int uart_fd); - - -/** - * Parse the CRSF protocol and extract RC channel data. - * - * @param now current time - * @param frame data to parse - * @param len length of frame - * @param values output channel values, each in range [1000, 2000] - * @param num_values set to the number of parsed channels in values - * @param max_channels maximum length of values - * @return true if channels successfully decoded - */ -__EXPORT bool crsf_parse(const uint64_t now, const uint8_t *frame, unsigned len, uint16_t *values, - uint16_t *num_values, uint16_t max_channels); - - -/** - * Send telemetry battery information - * @param uart_fd UART file descriptor - * @param voltage Voltage [0.1V] - * @param current Current [0.1A] - * @param fuel drawn mAh - * @param remaining battery remaining [%] - * @return true on success - */ -__EXPORT bool crsf_send_telemetry_battery(int uart_fd, uint16_t voltage, uint16_t current, int fuel, uint8_t remaining); - -/** - * Send telemetry GPS information - * @param uart_fd UART file descriptor - * @param latitude latitude [degree * 1e7] - * @param longitude longitude [degree * 1e7] - * @param groundspeed Ground speed [km/h * 10] - * @param gps_heading GPS heading [degree * 100] - * @param altitude Altitude [meters + 1000m offset] - * @param num_satellites number of satellites used - * @return true on success - */ -__EXPORT bool crsf_send_telemetry_gps(int uart_fd, int32_t latitude, int32_t longitude, uint16_t groundspeed, - uint16_t gps_heading, uint16_t altitude, uint8_t num_satellites); - - -/** - * Send telemetry Attitude information - * @param uart_fd UART file descriptor - * @param pitch Pitch angle [rad * 1e4] - * @param roll Roll angle [rad * 1e4] - * @param yaw Yaw angle [rad * 1e4] - * @return true on success - */ -__EXPORT bool crsf_send_telemetry_attitude(int uart_fd, int16_t pitch, int16_t roll, int16_t yaw); - -/** - * Send telemetry Flight Mode information - * @param uart_fd UART file descriptor - * @param flight_mode Flight Mode string (max length = 15) - * @return true on success - */ -__EXPORT bool crsf_send_telemetry_flight_mode(int uart_fd, const char *flight_mode); - -__END_DECLS diff --git a/src/lib/rc/dsm/CMakeLists.txt b/src/lib/rc/dsm/CMakeLists.txt new file mode 100644 index 0000000000..623aa33f3a --- /dev/null +++ b/src/lib/rc/dsm/CMakeLists.txt @@ -0,0 +1,44 @@ +############################################################################ +# +# Copyright (c) 2015-2022 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +add_library(rc_dsm + dsm.cpp + dsm.h +) + +target_compile_options(rc_dsm + PRIVATE + #-DDEBUG_BUILD + #-Wno-unused-result +) +target_link_libraries(rc_dsm PRIVATE prebuild_targets) diff --git a/src/lib/rc/dsm.cpp b/src/lib/rc/dsm/dsm.cpp similarity index 93% rename from src/lib/rc/dsm.cpp rename to src/lib/rc/dsm/dsm.cpp index d1b78a99bf..a4c3ce7cd4 100644 --- a/src/lib/rc/dsm.cpp +++ b/src/lib/rc/dsm/dsm.cpp @@ -51,8 +51,7 @@ #include #include "dsm.h" -#include "spektrum_rssi.h" -#include "common_rc.h" + #include #include @@ -64,6 +63,47 @@ #define dsm_udelay(arg) px4_usleep(arg) #endif +#include + +/* +min_rssi_dbm = -92.0 +max_rssi_dbm = -42.0 + +def dbm_to_percent(abs_dbm): + if -abs_dbm < min_rssi_dbm: + return 0.0 + elif -abs_dbm > max_rssi_dbm: + return 100.0 + else: + return 100.0 * math.log10(1.0 + (float)(-abs_dbm - min_rssi_dbm) * (9.0 / (max_rssi_dbm - min_rssi_dbm))) +*/ +constexpr int8_t lu_dbm_percent[] = { + 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 99, 98, 98, 97, 96, + 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 79, + 78, 77, 75, 74, 73, 71, 70, 68, 66, 65, 63, 61, 59, 57, 55, 52, + 50, 47, 45, 42, 39, 35, 32, 28, 24, 19, 13, 7, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +#define MASK(n) (n >> (sizeof(n) * CHAR_BIT - 1)) + +/* constexpr-compatible version of abs() */ +static constexpr unsigned c_abs(int n) { return (n + MASK(n)) ^ MASK(n); } + +/* convert signed spektrum dbm (-92 to -42) to percentage */ +static constexpr int8_t spek_dbm_to_percent(int8_t dbm) { return lu_dbm_percent[c_abs(dbm)]; } + +static_assert(spek_dbm_to_percent(0) == 100, "0 dbm should be 100%"); +static_assert(spek_dbm_to_percent(-42) == 100, "-42 dbm should be 100%"); +static_assert(spek_dbm_to_percent(-80) == 50, "-80 dbm should be 50%"); +static_assert(spek_dbm_to_percent(-92) == 0, "-92 dbm should be 0%"); +static_assert(spek_dbm_to_percent(-128) == 0, "-128 dbm should be 0%"); + + // #define DSM_DEBUG static enum DSM_DECODE_STATE { @@ -81,8 +121,8 @@ static dsm_channel_t channel_buffer[DSM_MAX_CHANNEL_COUNT]; static int dsm_fd = -1; /**< File handle to the DSM UART */ static hrt_abstime dsm_last_rx_time; /**< Timestamp when we last received data */ static hrt_abstime dsm_last_frame_time; /**< Timestamp for start of last valid dsm frame */ -static dsm_frame_t &dsm_frame = rc_decode_buf.dsm.frame; /**< DSM_BUFFER_SIZE DSM dsm frame receive buffer */ -static dsm_buf_t &dsm_buf = rc_decode_buf.dsm.buf; /**< DSM_BUFFER_SIZE DSM dsm frame receive buffer */ +static dsm_frame_t dsm_frame; /**< DSM_BUFFER_SIZE DSM dsm frame receive buffer */ +static dsm_buf_t dsm_buf; /**< DSM_BUFFER_SIZE DSM dsm frame receive buffer */ static unsigned dsm_partial_frame_count; /**< Count of bytes received for current dsm frame */ static unsigned dsm_channel_shift = 0; /**< Channel resolution, 0=unknown, 10=10 bit (1024), 11=11 bit (2048) */ diff --git a/src/lib/rc/dsm.h b/src/lib/rc/dsm/dsm.h similarity index 98% rename from src/lib/rc/dsm.h rename to src/lib/rc/dsm/dsm.h index 8e607f7920..94cde80b4e 100644 --- a/src/lib/rc/dsm.h +++ b/src/lib/rc/dsm/dsm.h @@ -53,8 +53,6 @@ __BEGIN_DECLS #define DSM_MAX_CHANNEL_COUNT 20 /**< Max channel count of any DSM RC */ #define DSM_BUFFER_SIZE (DSM_FRAME_SIZE + DSM_FRAME_SIZE / 2) - -#pragma pack(push, 1) typedef uint8_t dsm_frame_t[DSM_BUFFER_SIZE]; /**< DSM dsm frame receive buffer */ typedef uint8_t dsm_buf_t[DSM_FRAME_SIZE * 2]; // Define working buffer @@ -63,8 +61,6 @@ typedef struct dsm_decode_t { dsm_buf_t buf; } dsm_decode_t; -#pragma pack(pop) - __EXPORT int dsm_init(const char *device); __EXPORT void dsm_deinit(void); __EXPORT void dsm_proto_init(void); diff --git a/src/lib/rc/rc_tests/CMakeLists.txt b/src/lib/rc/rc_tests/CMakeLists.txt index 61cf326748..2851d93950 100644 --- a/src/lib/rc/rc_tests/CMakeLists.txt +++ b/src/lib/rc/rc_tests/CMakeLists.txt @@ -39,5 +39,8 @@ px4_add_module( SRCS RCTest.cpp DEPENDS - rc + rc_dsm + rc_sbus + rc_st24 + rc_sumd ) diff --git a/src/lib/rc/rc_tests/RCTest.cpp b/src/lib/rc/rc_tests/RCTest.cpp index 07c45d33c0..f137380d8f 100644 --- a/src/lib/rc/rc_tests/RCTest.cpp +++ b/src/lib/rc/rc_tests/RCTest.cpp @@ -9,12 +9,10 @@ #include #define DSM_DEBUG -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include #if defined(CONFIG_ARCH_BOARD_PX4_SITL) #define TEST_DATA_PATH "./test_data/" @@ -30,8 +28,6 @@ public: bool run_tests() override; private: - bool crsfTest(); - bool ghstTest(); bool dsmTest(const char *filepath, unsigned expected_chancount, unsigned expected_dropcount, unsigned chan0); bool dsmTest10Ch(); bool dsmTest16Ch(); @@ -44,8 +40,6 @@ private: bool RCTest::run_tests() { - ut_run_test(crsfTest); - ut_run_test(ghstTest); ut_run_test(dsmTest10Ch); ut_run_test(dsmTest16Ch); ut_run_test(dsmTest22msDSMX16Ch); @@ -57,180 +51,6 @@ bool RCTest::run_tests() return (_tests_failed == 0); } -bool RCTest::crsfTest() -{ - const char *filepath = TEST_DATA_PATH "crsf_rc_channels.txt"; - - FILE *fp = fopen(filepath, "rt"); - - ut_test(fp); - //PX4_INFO("loading data from: %s", filepath); - - const int line_size = 500; - char line[line_size]; - bool has_decoded_values = false; - const int max_channels = 16; - uint16_t rc_values[max_channels]; - uint16_t num_values = 0; - int line_counter = 1; - - while (fgets(line, line_size, fp) != nullptr) { - - if (strncmp(line, "INPUT ", 6) == 0) { - - if (has_decoded_values) { - PX4_ERR("Parser decoded values that are not in the test file (line=%i)", line_counter); - return false; - } - - // read the values - const char *file_buffer = line + 6; - int frame_len = 0; - uint8_t frame[300]; - int offset; - int number; - - while (sscanf(file_buffer, "%x, %n", &number, &offset) > 0) { - frame[frame_len++] = number; - file_buffer += offset; - } - - // Pipe the data into the parser - hrt_abstime now = hrt_absolute_time(); - - bool result = crsf_parse(now, frame, frame_len, rc_values, &num_values, max_channels); - - if (result) { - has_decoded_values = true; - } - - } else if (strncmp(line, "DECODED ", 8) == 0) { - - if (!has_decoded_values) { - PX4_ERR("Test file contains decoded values but the parser did not decode anything (line=%i)", line_counter); - return false; - } - - // read the values - const char *file_buffer = line + 8; - int offset; - int expected_rc_value; - int expected_num_channels = 0; - - while (sscanf(file_buffer, "%x, %n", &expected_rc_value, &offset) > 0) { - - // allow a small difference - if (abs(expected_rc_value - (int)rc_values[expected_num_channels]) > 10) { - PX4_ERR("File line: %i, channel: %i", line_counter, expected_num_channels); - ut_compare("Wrong decoded channel", expected_rc_value, rc_values[expected_num_channels]); - } - - file_buffer += offset; - ++expected_num_channels; - } - - if (expected_num_channels != num_values) { - PX4_ERR("File line: %d", line_counter); - ut_compare("Unexpected number of decoded channels", expected_num_channels, num_values); - } - - has_decoded_values = false; - } - - ++line_counter; - } - - return true; -} - -bool RCTest::ghstTest() -{ - const char *filepath = TEST_DATA_PATH "ghst_rc_channels.txt"; - - FILE *fp = fopen(filepath, "rt"); - - ut_test(fp); - - int uart_fd = -1; - const int line_size = 500; - char line[line_size]; - bool has_decoded_values = false; - const int max_channels = 16; - uint16_t rc_values[max_channels]; - uint16_t num_values = 0; - int line_counter = 1; - int8_t ghst_rssi = -1; - ghst_config(uart_fd); - - while (fgets(line, line_size, fp) != nullptr) { - - if (strncmp(line, "INPUT ", 6) == 0) { - - if (has_decoded_values) { - PX4_ERR("Parser decoded values that are not in the test file (line=%i)", line_counter); - return false; - } - - // read the values - const char *file_buffer = line + 6; - int frame_len = 0; - uint8_t frame[300]; - int offset; - int number; - - while (sscanf(file_buffer, "%x, %n", &number, &offset) > 0) { - frame[frame_len++] = number; - file_buffer += offset; - } - - // Pipe the data into the parser - hrt_abstime now = hrt_absolute_time(); - - bool result = ghst_parse(now, frame, frame_len, rc_values, &ghst_rssi, &num_values, max_channels); - - if (result) { - has_decoded_values = true; - } - - } else if (strncmp(line, "DECODED ", 8) == 0) { - - if (!has_decoded_values) { - PX4_ERR("Test file contains decoded values but the parser did not decode anything (line=%i)", line_counter); - return false; - } - - // read the values - const char *file_buffer = line + 8; - int offset; - int expected_rc_value; - int expected_num_channels = 0; - - while (sscanf(file_buffer, "%x, %n", &expected_rc_value, &offset) > 0) { - - // allow a small difference - if (abs(expected_rc_value - (int)rc_values[expected_num_channels]) > 10) { - PX4_ERR("File line: %i, channel: %i", line_counter, expected_num_channels); - ut_compare("Wrong decoded channel", expected_rc_value, rc_values[expected_num_channels]); - } - - file_buffer += offset; - ++expected_num_channels; - } - - if (expected_num_channels != num_values) { - PX4_ERR("File line: %d", line_counter); - ut_compare("Unexpected number of decoded channels", expected_num_channels, num_values); - } - - has_decoded_values = false; - } - - ++line_counter; - } - - return true; -} - bool RCTest::dsmTest10Ch() { return dsmTest(TEST_DATA_PATH "dsm_x_data.txt", 10, 2, 1500); diff --git a/src/lib/rc/sbus/CMakeLists.txt b/src/lib/rc/sbus/CMakeLists.txt new file mode 100644 index 0000000000..021c015e42 --- /dev/null +++ b/src/lib/rc/sbus/CMakeLists.txt @@ -0,0 +1,48 @@ +############################################################################ +# +# Copyright (c) 2015-2022 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +add_library(rc_sbus + sbus.cpp + sbus.h +) + +target_compile_options(rc_sbus + PRIVATE + #-DDEBUG_BUILD + -Wno-unused-result +) +target_link_libraries(rc_sbus PRIVATE prebuild_targets) + +if(${PX4_PLATFORM} MATCHES "nuttx") + target_link_libraries(rc_sbus PRIVATE nuttx_fs) +endif() diff --git a/src/lib/rc/sbus.cpp b/src/lib/rc/sbus/sbus.cpp similarity index 99% rename from src/lib/rc/sbus.cpp rename to src/lib/rc/sbus/sbus.cpp index 04fd38d8fc..a21f4922d7 100644 --- a/src/lib/rc/sbus.cpp +++ b/src/lib/rc/sbus/sbus.cpp @@ -48,7 +48,7 @@ #endif #include "sbus.h" -#include "common_rc.h" + #include #include @@ -119,7 +119,7 @@ static enum SBUS2_DECODE_STATE { SBUS2_DECODE_STATE_SBUS2_DATA2 = 0x34 } sbus_decode_state = SBUS2_DECODE_STATE_DESYNC; -static sbus_frame_t &sbus_frame = rc_decode_buf.sbus_frame; +static sbus_frame_t sbus_frame; static unsigned partial_frame_count; static unsigned sbus1_frame_delay = (1000U * 1000U) / SBUS1_DEFAULT_RATE_HZ; diff --git a/src/lib/rc/sbus.h b/src/lib/rc/sbus/sbus.h similarity index 98% rename from src/lib/rc/sbus.h rename to src/lib/rc/sbus/sbus.h index 6085ae4aa7..dfd6eb6dd9 100644 --- a/src/lib/rc/sbus.h +++ b/src/lib/rc/sbus/sbus.h @@ -1,6 +1,6 @@ /**************************************************************************** * - * Copyright (c) 2012-2015 PX4 Development Team. All rights reserved. + * Copyright (c) 2012-2022 PX4 Development Team. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/src/lib/rc/spektrum_rssi.h b/src/lib/rc/spektrum_rssi.h deleted file mode 100644 index 25dd4d57a3..0000000000 --- a/src/lib/rc/spektrum_rssi.h +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************** - * - * Copyright (c) 2012-2015 PX4 Development Team. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name PX4 nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/** - * @file spektrum_rssi.h - * - * RSSI dBm to percentage conversion for Spektrum telemetry receivers - * - * @author Kurt Kiefer - */ - -#pragma once - -#include - -/* -min_rssi_dbm = -92.0 -max_rssi_dbm = -42.0 - -def dbm_to_percent(abs_dbm): - if -abs_dbm < min_rssi_dbm: - return 0.0 - elif -abs_dbm > max_rssi_dbm: - return 100.0 - else: - return 100.0 * math.log10(1.0 + (float)(-abs_dbm - min_rssi_dbm) * (9.0 / (max_rssi_dbm - min_rssi_dbm))) -*/ -constexpr int8_t lu_dbm_percent[] = { - 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 99, 98, 98, 97, 96, - 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 79, - 78, 77, 75, 74, 73, 71, 70, 68, 66, 65, 63, 61, 59, 57, 55, 52, - 50, 47, 45, 42, 39, 35, 32, 28, 24, 19, 13, 7, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, -}; - -#define MASK(n) (n >> (sizeof(n) * CHAR_BIT - 1)) - -/* constexpr-compatible version of abs() */ -constexpr unsigned c_abs(int n) -{ - return (n + MASK(n)) ^ MASK(n); -} - -/* convert signed spektrum dbm (-92 to -42) to percentage */ -constexpr int8_t spek_dbm_to_percent(int8_t dbm) -{ - return lu_dbm_percent[c_abs(dbm)]; -} - -static_assert(spek_dbm_to_percent(0) == 100, "0 dbm should be 100%"); -static_assert(spek_dbm_to_percent(-42) == 100, "-42 dbm should be 100%"); -static_assert(spek_dbm_to_percent(-80) == 50, "-80 dbm should be 50%"); -static_assert(spek_dbm_to_percent(-92) == 0, "-92 dbm should be 0%"); -static_assert(spek_dbm_to_percent(-128) == 0, "-128 dbm should be 0%"); diff --git a/src/lib/rc/st24/CMakeLists.txt b/src/lib/rc/st24/CMakeLists.txt new file mode 100644 index 0000000000..9d4c39f761 --- /dev/null +++ b/src/lib/rc/st24/CMakeLists.txt @@ -0,0 +1,44 @@ +############################################################################ +# +# Copyright (c) 2015-2022 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +add_library(rc_st24 + st24.cpp + st24.h +) + +target_compile_options(rc_st24 + PRIVATE + #-DDEBUG_BUILD + #-Wno-unused-result +) +target_link_libraries(rc_st24 PRIVATE prebuild_targets) diff --git a/src/lib/rc/st24.cpp b/src/lib/rc/st24/st24.cpp similarity index 96% rename from src/lib/rc/st24.cpp rename to src/lib/rc/st24/st24.cpp index 50a2f72769..41aa91ca02 100644 --- a/src/lib/rc/st24.cpp +++ b/src/lib/rc/st24/st24.cpp @@ -42,7 +42,6 @@ #include #include #include "st24.h" -#include "common_rc.h" const char *decode_states[] = {"UNSYNCED", "GOT_STX1", @@ -66,8 +65,15 @@ const char *decode_states[] = {"UNSYNCED", static enum ST24_DECODE_STATE _decode_state = ST24_DECODE_STATE_UNSYNCED; static uint8_t _rxlen; -static ReceiverFcPacket &_rxpacket = rc_decode_buf._strxpacket; +static ReceiverFcPacket _rxpacket; +/** + * CRC8 implementation for ST24 protocol + * + * @param prt Pointer to the data to CRC + * @param len number of bytes to accumulate in the checksum + * @return the checksum of these bytes over len + */ uint8_t st24_common_crc8(uint8_t *ptr, uint8_t len) { uint8_t i, crc ; diff --git a/src/lib/rc/st24.h b/src/lib/rc/st24/st24.h similarity index 95% rename from src/lib/rc/st24.h rename to src/lib/rc/st24/st24.h index 82932c0914..03f5e2ff7a 100644 --- a/src/lib/rc/st24.h +++ b/src/lib/rc/st24/st24.h @@ -147,15 +147,6 @@ typedef struct { #pragma pack(pop) -/** - * CRC8 implementation for ST24 protocol - * - * @param prt Pointer to the data to CRC - * @param len number of bytes to accumulate in the checksum - * @return the checksum of these bytes over len - */ -uint8_t st24_common_crc8(uint8_t *ptr, uint8_t len); - /** * Decoder for ST24 protocol * diff --git a/src/lib/rc/sumd/CMakeLists.txt b/src/lib/rc/sumd/CMakeLists.txt new file mode 100644 index 0000000000..59bd299c35 --- /dev/null +++ b/src/lib/rc/sumd/CMakeLists.txt @@ -0,0 +1,44 @@ +############################################################################ +# +# Copyright (c) 2015-2022 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +add_library(rc_sumd + sumd.cpp + sumd.h +) + +target_compile_options(rc_sumd + PRIVATE + #-DDEBUG_BUILD + #-Wno-unused-result +) +target_link_libraries(rc_sumd PRIVATE prebuild_targets) diff --git a/src/lib/rc/sumd.cpp b/src/lib/rc/sumd/sumd.cpp similarity index 94% rename from src/lib/rc/sumd.cpp rename to src/lib/rc/sumd/sumd.cpp index db02227c82..9af8da9dfd 100644 --- a/src/lib/rc/sumd.cpp +++ b/src/lib/rc/sumd/sumd.cpp @@ -42,7 +42,6 @@ #include #include #include "sumd.h" -#include "common_rc.h" enum SUMD_DECODE_STATE { SUMD_DECODE_STATE_UNSYNCED = 0, @@ -67,12 +66,11 @@ const char *decode_states[] = {"UNSYNCED", }; */ -uint8_t _crc8 = 0x00; +uint8_t _crc8 = 0x00; uint16_t _crc16 = 0x0000; -bool _sumd = true; -bool _crcOK = false; -bool _debug = false; - +bool _sumd = true; +bool _crcOK = false; +bool _debug = false; /* define range mapping here, -+100% -> 1000..2000 */ #define SUMD_RANGE_MIN 0.0f @@ -88,8 +86,15 @@ bool _debug = false; static enum SUMD_DECODE_STATE _decode_state = SUMD_DECODE_STATE_UNSYNCED; static uint8_t _rxlen; -static ReceiverFcPacketHoTT &_rxpacket = rc_decode_buf._hottrxpacket; +static ReceiverFcPacketHoTT _rxpacket; +/** + * CRC16 implementation for SUMD protocol + * + * @param crc Initial CRC Value + * @param value to accumulate in the checksum + * @return the checksum + */ uint16_t sumd_crc16(uint16_t crc, uint8_t value) { int i; @@ -102,7 +107,14 @@ uint16_t sumd_crc16(uint16_t crc, uint8_t value) return crc; } -uint8_t sumd_crc8(uint8_t crc, uint8_t value) +/** + * CRC8 implementation for SUMH protocol + * + * @param crc Initial CRC Value + * @param value to accumulate in the checksum + * @return the checksum + */ +static uint8_t sumd_crc8(uint8_t crc, uint8_t value) { crc += value; return crc; diff --git a/src/lib/rc/sumd.h b/src/lib/rc/sumd/sumd.h similarity index 85% rename from src/lib/rc/sumd.h rename to src/lib/rc/sumd/sumd.h index a9ac05ccee..b32a676b03 100644 --- a/src/lib/rc/sumd.h +++ b/src/lib/rc/sumd/sumd.h @@ -52,9 +52,6 @@ __BEGIN_DECLS #define SUMD_ID_SUMD 0x01 #define SUMD_ID_FAILSAFE 0x81 - - - #pragma pack(push, 1) typedef struct { uint8_t header; ///< 0xA8 for a valid packet @@ -68,25 +65,6 @@ typedef struct { } ReceiverFcPacketHoTT; #pragma pack(pop) - -/** - * CRC16 implementation for SUMD protocol - * - * @param crc Initial CRC Value - * @param value to accumulate in the checksum - * @return the checksum - */ -uint16_t sumd_crc16(uint16_t crc, uint8_t value); - -/** - * CRC8 implementation for SUMH protocol - * - * @param crc Initial CRC Value - * @param value to accumulate in the checksum - * @return the checksum - */ -uint8_t sumd_crc8(uint8_t crc, uint8_t value); - /** * Decoder for SUMD/SUMH protocol * @@ -98,10 +76,6 @@ uint8_t sumd_crc8(uint8_t crc, uint8_t value); * @param failsafe pointer to a boolean where the decoded failsafe flag is written back to * @return 0 for success (a decoded packet), 1 for no packet yet (accumulating), 2 for unknown packet, 3 for out of sync, 4 for checksum error */ -/* -__EXPORT int sumd_decode(uint8_t byte, uint8_t *rssi, uint8_t *rx_count, uint16_t *channel_count, - uint16_t *channels, uint16_t max_chan_count, bool *failsafe); -*/ __EXPORT int sumd_decode(uint8_t byte, uint8_t *rssi, uint8_t *rx_count, uint16_t *channel_count, uint16_t *channels, uint16_t max_chan_count, bool *failsafe); diff --git a/src/modules/px4iofirmware/CMakeLists.txt b/src/modules/px4iofirmware/CMakeLists.txt index 3df90ffdac..50bda7eb66 100644 --- a/src/modules/px4iofirmware/CMakeLists.txt +++ b/src/modules/px4iofirmware/CMakeLists.txt @@ -52,7 +52,10 @@ target_link_libraries(px4iofirmware nuttx_arch nuttx_c nuttx_mm - rc + rc_dsm + rc_sbus + rc_st24 + rc_sumd ) if(PX4IO_PERF) diff --git a/src/modules/px4iofirmware/controls.cpp b/src/modules/px4iofirmware/controls.cpp index f5259f62f7..0b7dd564d1 100644 --- a/src/modules/px4iofirmware/controls.cpp +++ b/src/modules/px4iofirmware/controls.cpp @@ -44,10 +44,10 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include #if defined(PX4IO_PERF) diff --git a/src/modules/px4iofirmware/mixer.cpp b/src/modules/px4iofirmware/mixer.cpp index 9fc40dcbde..24dee6c04b 100644 --- a/src/modules/px4iofirmware/mixer.cpp +++ b/src/modules/px4iofirmware/mixer.cpp @@ -51,7 +51,7 @@ #include #include -#include +#include extern "C" { /* #define DEBUG */ diff --git a/src/modules/px4iofirmware/registers.c b/src/modules/px4iofirmware/registers.c index a191577ef3..02d8ffaf60 100644 --- a/src/modules/px4iofirmware/registers.c +++ b/src/modules/px4iofirmware/registers.c @@ -48,8 +48,8 @@ #include #include #include -#include -#include +#include +#include #include "px4io.h" #include "protocol.h"