From 6dce57170e3ceaa3316446086f8a0cd12cc5e90c Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Thu, 19 Dec 2013 17:12:46 +0100 Subject: [PATCH 01/15] Hotfix: Fixed mapping of override channel --- src/drivers/px4io/px4io.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/drivers/px4io/px4io.cpp b/src/drivers/px4io/px4io.cpp index db882e6232..e898b3e605 100644 --- a/src/drivers/px4io/px4io.cpp +++ b/src/drivers/px4io/px4io.cpp @@ -1024,7 +1024,12 @@ PX4IO::io_set_rc_config() if ((ichan >= 0) && (ichan < (int)_max_rc_input)) input_map[ichan - 1] = 3; - ichan = 4; + param_get(param_find("RC_MAP_MODE_SW"), &ichan); + + if ((ichan >= 0) && (ichan < (int)_max_rc_input)) + input_map[ichan - 1] = 4; + + ichan = 5; for (unsigned i = 0; i < _max_rc_input; i++) if (input_map[i] == -1) From 9476ba522f0b174a64ff91061647bca30cf7b6ea Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Fri, 20 Dec 2013 08:48:45 +0100 Subject: [PATCH 02/15] PPM channel count detection is now using a more paranoid approach. --- src/drivers/drv_rc_input.h | 2 +- src/drivers/stm32/drv_hrt.c | 45 ++++++++++++++++++++++++++++++------- 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/src/drivers/drv_rc_input.h b/src/drivers/drv_rc_input.h index 86e5a149a0..7b18b5b15b 100644 --- a/src/drivers/drv_rc_input.h +++ b/src/drivers/drv_rc_input.h @@ -60,7 +60,7 @@ /** * Maximum number of R/C input channels in the system. S.Bus has up to 18 channels. */ -#define RC_INPUT_MAX_CHANNELS 18 +#define RC_INPUT_MAX_CHANNELS 20 /** * Input signal type, value is a control position from zero to 100 diff --git a/src/drivers/stm32/drv_hrt.c b/src/drivers/stm32/drv_hrt.c index 1bd251bc2a..36226c941f 100644 --- a/src/drivers/stm32/drv_hrt.c +++ b/src/drivers/stm32/drv_hrt.c @@ -338,7 +338,12 @@ static void hrt_call_invoke(void); # define PPM_MIN_START 2500 /* shortest valid start gap */ /* decoded PPM buffer */ -#define PPM_MAX_CHANNELS 12 +#define PPM_MIN_CHANNELS 5 +#define PPM_MAX_CHANNELS 20 + +/* Number of same-sized frames required to 'lock' */ +#define PPM_CHANNEL_LOCK 2 /* should be less than the input timeout */ + __EXPORT uint16_t ppm_buffer[PPM_MAX_CHANNELS]; __EXPORT unsigned ppm_decoded_channels = 0; __EXPORT uint64_t ppm_last_valid_decode = 0; @@ -440,7 +445,7 @@ hrt_ppm_decode(uint32_t status) if (status & SR_OVF_PPM) goto error; - /* how long since the last edge? */ + /* how long since the last edge? - this handles counter wrapping implicitely. */ width = count - ppm.last_edge; ppm.last_edge = count; @@ -455,14 +460,38 @@ hrt_ppm_decode(uint32_t status) */ if (width >= PPM_MIN_START) { - /* export the last set of samples if we got something sensible */ - if (ppm.next_channel > 4) { - for (i = 0; i < ppm.next_channel && i < PPM_MAX_CHANNELS; i++) - ppm_buffer[i] = ppm_temp_buffer[i]; + /* + * If the number of channels changes unexpectedly, we don't want + * to just immediately jump on the new count as it may be a result + * of noise or dropped edges. Instead, take a few frames to settle. + */ + if (ppm.next_channel != ppm_decoded_channels) { + static unsigned new_channel_count; + static unsigned new_channel_holdoff; - ppm_decoded_channels = i; - ppm_last_valid_decode = hrt_absolute_time(); + if (new_channel_count != ppm.next_channel) { + /* start the lock counter for the new channel count */ + new_channel_count = ppm.next_channel; + new_channel_holdoff = PPM_CHANNEL_LOCK; + } else if (new_channel_holdoff > 0) { + /* this frame matched the last one, decrement the lock counter */ + new_channel_holdoff--; + + } else { + /* we have seen PPM_CHANNEL_LOCK frames with the new count, accept it */ + ppm_decoded_channels = new_channel_count; + new_channel_count = 0; + } + + } else { + /* frame channel count matches expected, let's use it */ + if (ppm.next_channel > PPM_MIN_CHANNELS) { + for (i = 0; i < ppm.next_channel; i++) + ppm_buffer[i] = ppm_temp_buffer[i]; + + ppm_last_valid_decode = hrt_absolute_time(); + } } /* reset for the next frame */ From 8c518aa23710ba0b9ad0c7ad2c03428ce8ddb290 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Fri, 20 Dec 2013 14:25:35 +0100 Subject: [PATCH 03/15] Useful bits for high-rate logging --- ROMFS/px4fmu_common/init.d/rcS | 0 ROMFS/px4fmu_logging/init.d/rcS | 88 +++++++++++++++ ROMFS/px4fmu_test/init.d/rcS | 8 ++ makefiles/config_px4fmu-v2_logging.mk | 157 ++++++++++++++++++++++++++ src/systemcmds/tests/test_sensors.c | 87 ++++++++------ 5 files changed, 304 insertions(+), 36 deletions(-) mode change 100755 => 100644 ROMFS/px4fmu_common/init.d/rcS create mode 100644 ROMFS/px4fmu_logging/init.d/rcS mode change 100755 => 100644 ROMFS/px4fmu_test/init.d/rcS create mode 100644 makefiles/config_px4fmu-v2_logging.mk diff --git a/ROMFS/px4fmu_common/init.d/rcS b/ROMFS/px4fmu_common/init.d/rcS old mode 100755 new mode 100644 diff --git a/ROMFS/px4fmu_logging/init.d/rcS b/ROMFS/px4fmu_logging/init.d/rcS new file mode 100644 index 0000000000..7b88567197 --- /dev/null +++ b/ROMFS/px4fmu_logging/init.d/rcS @@ -0,0 +1,88 @@ +#!nsh +# +# PX4FMU startup script for logging purposes +# + +# +# Try to mount the microSD card. +# +echo "[init] looking for microSD..." +if mount -t vfat /dev/mmcsd0 /fs/microsd +then + echo "[init] card mounted at /fs/microsd" + # Start playing the startup tune + tone_alarm start +else + echo "[init] no microSD card found" + # Play SOS + tone_alarm error +fi + +uorb start + +# +# Start sensor drivers here. +# + +ms5611 start +adc start + +# mag might be external +if hmc5883 start +then + echo "using HMC5883" +fi + +if mpu6000 start +then + echo "using MPU6000" +fi + +if l3gd20 start +then + echo "using L3GD20(H)" +fi + +if lsm303d start +then + set BOARD fmuv2 +else + set BOARD fmuv1 +fi + +# Start airspeed sensors +if meas_airspeed start +then + echo "using MEAS airspeed sensor" +else + if ets_airspeed start + then + echo "using ETS airspeed sensor (bus 3)" + else + if ets_airspeed start -b 1 + then + echo "Using ETS airspeed sensor (bus 1)" + fi + fi +fi + +# +# Start the sensor collection task. +# IMPORTANT: this also loads param offsets +# ALWAYS start this task before the +# preflight_check. +# +if sensors start +then + echo "SENSORS STARTED" +fi + +sdlog2 start -r 250 -e -b 16 + +if sercon +then + echo "[init] USB interface connected" + + # Try to get an USB console + nshterm /dev/ttyACM0 & +fi \ No newline at end of file diff --git a/ROMFS/px4fmu_test/init.d/rcS b/ROMFS/px4fmu_test/init.d/rcS old mode 100755 new mode 100644 index 7f161b053a..6aa1d3d46b --- a/ROMFS/px4fmu_test/init.d/rcS +++ b/ROMFS/px4fmu_test/init.d/rcS @@ -2,3 +2,11 @@ # # PX4FMU startup script for test hackery. # + +if sercon +then + echo "[init] USB interface connected" + + # Try to get an USB console + nshterm /dev/ttyACM0 & +fi \ No newline at end of file diff --git a/makefiles/config_px4fmu-v2_logging.mk b/makefiles/config_px4fmu-v2_logging.mk new file mode 100644 index 0000000000..ed90f6464c --- /dev/null +++ b/makefiles/config_px4fmu-v2_logging.mk @@ -0,0 +1,157 @@ +# +# Makefile for the px4fmu_default configuration +# + +# +# Use the configuration's ROMFS, copy the px4iov2 firmware into +# the ROMFS if it's available +# +ROMFS_ROOT = $(PX4_BASE)/ROMFS/px4fmu_logging +ROMFS_OPTIONAL_FILES = $(PX4_BASE)/Images/px4io-v2_default.bin + +# +# Board support modules +# +MODULES += drivers/device +MODULES += drivers/stm32 +MODULES += drivers/stm32/adc +MODULES += drivers/stm32/tone_alarm +MODULES += drivers/led +MODULES += drivers/px4fmu +MODULES += drivers/px4io +MODULES += drivers/boards/px4fmu-v2 +MODULES += drivers/rgbled +MODULES += drivers/mpu6000 +MODULES += drivers/lsm303d +MODULES += drivers/l3gd20 +MODULES += drivers/hmc5883 +MODULES += drivers/ms5611 +MODULES += drivers/mb12xx +MODULES += drivers/gps +MODULES += drivers/hil +MODULES += drivers/hott/hott_telemetry +MODULES += drivers/hott/hott_sensors +MODULES += drivers/blinkm +MODULES += drivers/roboclaw +MODULES += drivers/airspeed +MODULES += drivers/ets_airspeed +MODULES += drivers/meas_airspeed +MODULES += modules/sensors + +# Needs to be burned to the ground and re-written; for now, +# just don't build it. +#MODULES += drivers/mkblctrl + +# +# System commands +# +MODULES += systemcmds/ramtron +MODULES += systemcmds/bl_update +MODULES += systemcmds/boardinfo +MODULES += systemcmds/mixer +MODULES += systemcmds/param +MODULES += systemcmds/perf +MODULES += systemcmds/preflight_check +MODULES += systemcmds/pwm +MODULES += systemcmds/esc_calib +MODULES += systemcmds/reboot +MODULES += systemcmds/top +MODULES += systemcmds/tests +MODULES += systemcmds/config +MODULES += systemcmds/nshterm + +# +# General system control +# +MODULES += modules/commander +MODULES += modules/navigator +MODULES += modules/mavlink +MODULES += modules/mavlink_onboard + +# +# Estimation modules (EKF/ SO3 / other filters) +# +MODULES += modules/attitude_estimator_ekf +MODULES += modules/attitude_estimator_so3 +MODULES += modules/att_pos_estimator_ekf +MODULES += modules/position_estimator_inav +MODULES += examples/flow_position_estimator + +# +# Vehicle Control +# +#MODULES += modules/segway # XXX Needs GCC 4.7 fix +MODULES += modules/fw_pos_control_l1 +MODULES += modules/fw_att_control +MODULES += modules/multirotor_att_control +MODULES += modules/multirotor_pos_control + +# +# Logging +# +MODULES += modules/sdlog2 + +# +# Unit tests +# +#MODULES += modules/unit_test +#MODULES += modules/commander/commander_tests + +# +# Library modules +# +MODULES += modules/systemlib +MODULES += modules/systemlib/mixer +MODULES += modules/controllib +MODULES += modules/uORB + +# +# Libraries +# +LIBRARIES += lib/mathlib/CMSIS +MODULES += lib/mathlib +MODULES += lib/mathlib/math/filter +MODULES += lib/ecl +MODULES += lib/external_lgpl +MODULES += lib/geo +MODULES += lib/conversion + +# +# Demo apps +# +#MODULES += examples/math_demo +# Tutorial code from +# https://pixhawk.ethz.ch/px4/dev/hello_sky +MODULES += examples/px4_simple_app + +# Tutorial code from +# https://pixhawk.ethz.ch/px4/dev/daemon +#MODULES += examples/px4_daemon_app + +# Tutorial code from +# https://pixhawk.ethz.ch/px4/dev/debug_values +#MODULES += examples/px4_mavlink_debug + +# Tutorial code from +# https://pixhawk.ethz.ch/px4/dev/example_fixedwing_control +#MODULES += examples/fixedwing_control + +# Hardware test +#MODULES += examples/hwtest + +# +# Transitional support - add commands from the NuttX export archive. +# +# In general, these should move to modules over time. +# +# Each entry here is ... but we use a helper macro +# to make the table a bit more readable. +# +define _B + $(strip $1).$(or $(strip $2),SCHED_PRIORITY_DEFAULT).$(or $(strip $3),CONFIG_PTHREAD_STACK_DEFAULT).$(strip $4) +endef + +# command priority stack entrypoint +BUILTIN_COMMANDS := \ + $(call _B, sercon, , 2048, sercon_main ) \ + $(call _B, serdis, , 2048, serdis_main ) diff --git a/src/systemcmds/tests/test_sensors.c b/src/systemcmds/tests/test_sensors.c index f6415b72f2..096106ff33 100644 --- a/src/systemcmds/tests/test_sensors.c +++ b/src/systemcmds/tests/test_sensors.c @@ -78,7 +78,8 @@ static int accel(int argc, char *argv[]); static int gyro(int argc, char *argv[]); static int mag(int argc, char *argv[]); static int baro(int argc, char *argv[]); -static int mpu6k(int argc, char *argv[]); +static int accel1(int argc, char *argv[]); +static int gyro1(int argc, char *argv[]); /**************************************************************************** * Private Data @@ -93,7 +94,8 @@ struct { {"gyro", "/dev/gyro", gyro}, {"mag", "/dev/mag", mag}, {"baro", "/dev/baro", baro}, - {"mpu6k", "/dev/mpu6k", mpu6k}, + {"accel1", "/dev/accel1", accel1}, + {"gyro1", "/dev/gyro1", gyro1}, {NULL, NULL, NULL} }; @@ -137,7 +139,7 @@ accel(int argc, char *argv[]) } if (fabsf(buf.x) > 30.0f || fabsf(buf.y) > 30.0f || fabsf(buf.z) > 30.0f) { - warnx("MPU6K acceleration values out of range!"); + warnx("ACCEL1 acceleration values out of range!"); return ERROR; } @@ -149,20 +151,19 @@ accel(int argc, char *argv[]) } static int -mpu6k(int argc, char *argv[]) +accel1(int argc, char *argv[]) { - printf("\tMPU6K: test start\n"); + printf("\tACCEL1: test start\n"); fflush(stdout); int fd; struct accel_report buf; - struct gyro_report gyro_buf; int ret; - fd = open("/dev/accel_mpu6k", O_RDONLY); + fd = open("/dev/accel1", O_RDONLY); if (fd < 0) { - printf("\tMPU6K: open fail, run first.\n"); + printf("\tACCEL1: open fail, run or first.\n"); return ERROR; } @@ -173,45 +174,21 @@ mpu6k(int argc, char *argv[]) ret = read(fd, &buf, sizeof(buf)); if (ret != sizeof(buf)) { - printf("\tMPU6K: read1 fail (%d)\n", ret); + printf("\tACCEL1: read1 fail (%d)\n", ret); return ERROR; } else { - printf("\tMPU6K accel: x:%8.4f\ty:%8.4f\tz:%8.4f m/s^2\n", (double)buf.x, (double)buf.y, (double)buf.z); + printf("\tACCEL1 accel: x:%8.4f\ty:%8.4f\tz:%8.4f m/s^2\n", (double)buf.x, (double)buf.y, (double)buf.z); } if (fabsf(buf.x) > 30.0f || fabsf(buf.y) > 30.0f || fabsf(buf.z) > 30.0f) { - warnx("MPU6K acceleration values out of range!"); + warnx("ACCEL1 acceleration values out of range!"); return ERROR; } /* Let user know everything is ok */ - printf("\tOK: MPU6K ACCEL passed all tests successfully\n"); + printf("\tOK: ACCEL1 passed all tests successfully\n"); - close(fd); - fd = open("/dev/gyro_mpu6k", O_RDONLY); - - if (fd < 0) { - printf("\tMPU6K GYRO: open fail, run or first.\n"); - return ERROR; - } - - /* wait at least 5 ms, sensor should have data after that */ - usleep(5000); - - /* read data - expect samples */ - ret = read(fd, &gyro_buf, sizeof(gyro_buf)); - - if (ret != sizeof(gyro_buf)) { - printf("\tMPU6K GYRO: read fail (%d)\n", ret); - return ERROR; - - } else { - printf("\tMPU6K GYRO rates: x:%8.4f\ty:%8.4f\tz:%8.4f rad/s\n", (double)gyro_buf.x, (double)gyro_buf.y, (double)gyro_buf.z); - } - - /* Let user know everything is ok */ - printf("\tOK: MPU6K GYRO passed all tests successfully\n"); close(fd); return OK; @@ -255,6 +232,44 @@ gyro(int argc, char *argv[]) return OK; } +static int +gyro1(int argc, char *argv[]) +{ + printf("\tGYRO1: test start\n"); + fflush(stdout); + + int fd; + struct gyro_report buf; + int ret; + + fd = open("/dev/gyro1", O_RDONLY); + + if (fd < 0) { + printf("\tGYRO1: open fail, run or first.\n"); + return ERROR; + } + + /* wait at least 5 ms, sensor should have data after that */ + usleep(5000); + + /* read data - expect samples */ + ret = read(fd, &buf, sizeof(buf)); + + if (ret != sizeof(buf)) { + printf("\tGYRO1: read fail (%d)\n", ret); + return ERROR; + + } else { + printf("\tGYRO1 rates: x:%8.4f\ty:%8.4f\tz:%8.4f rad/s\n", (double)buf.x, (double)buf.y, (double)buf.z); + } + + /* Let user know everything is ok */ + printf("\tOK: GYRO1 passed all tests successfully\n"); + close(fd); + + return OK; +} + static int mag(int argc, char *argv[]) { From 3ad9dd030c01e233a78aebfd2e20e67168962255 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Fri, 20 Dec 2013 21:10:33 +0100 Subject: [PATCH 04/15] Added performance counter for write IOCTL --- src/drivers/px4io/px4io.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/drivers/px4io/px4io.cpp b/src/drivers/px4io/px4io.cpp index e898b3e605..9e84bf9291 100644 --- a/src/drivers/px4io/px4io.cpp +++ b/src/drivers/px4io/px4io.cpp @@ -244,7 +244,8 @@ private: int _mavlink_fd; /// 0) { + + perf_begin(_perf_write); int ret = io_reg_set(PX4IO_PAGE_DIRECT_PWM, 0, (uint16_t *)buffer, count); + perf_end(_perf_write); if (ret != OK) return ret; From f174ca3ce5dfe338b79f52de46f127abf1c3aca1 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Fri, 20 Dec 2013 21:52:10 +0100 Subject: [PATCH 05/15] Added average as direct output --- src/modules/systemlib/perf_counter.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/modules/systemlib/perf_counter.c b/src/modules/systemlib/perf_counter.c index bf84b79450..b4ca0ed3ec 100644 --- a/src/modules/systemlib/perf_counter.c +++ b/src/modules/systemlib/perf_counter.c @@ -295,10 +295,11 @@ perf_print_counter(perf_counter_t handle) case PC_ELAPSED: { struct perf_ctr_elapsed *pce = (struct perf_ctr_elapsed *)handle; - printf("%s: %llu events, %lluus elapsed, min %lluus max %lluus\n", + printf("%s: %llu events, %lluus elapsed, %llu avg, min %lluus max %lluus\n", handle->name, pce->event_count, pce->time_total, + pce->time_total / pce->event_count, pce->time_least, pce->time_most); break; From 0f0dc5ba068d24fb8b339acc8ef850f5f6ea9e47 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Sat, 21 Dec 2013 12:45:04 +0100 Subject: [PATCH 06/15] Allowed custom battery scaling on IO --- src/drivers/px4io/px4io.cpp | 17 +++++++++++++++-- src/modules/sensors/sensor_params.c | 1 + 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/drivers/px4io/px4io.cpp b/src/drivers/px4io/px4io.cpp index 9e84bf9291..df96fa0bbd 100644 --- a/src/drivers/px4io/px4io.cpp +++ b/src/drivers/px4io/px4io.cpp @@ -896,8 +896,21 @@ PX4IO::task_main() /* re-upload RC input config as it may have changed */ io_set_rc_config(); - } - } + + /* re-set the battery scaling */ + int32_t voltage_scaling_val; + param_t voltage_scaling_param; + + /* see if bind parameter has been set, and reset it to -1 */ + param_get(voltage_scaling_param = param_find("BAT_V_SCALE_IO"), &voltage_scaling_val); + + /* send channel config to IO */ + uint16_t scaling = voltage_scaling_val; + int pret = io_reg_set(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_VBATT_SCALE, &scaling, 1); + + if (pret != OK) { + log("voltage scaling upload failed"); + } perf_end(_perf_update); } diff --git a/src/modules/sensors/sensor_params.c b/src/modules/sensors/sensor_params.c index 2aa15420af..78d4b410a8 100644 --- a/src/modules/sensors/sensor_params.c +++ b/src/modules/sensors/sensor_params.c @@ -195,6 +195,7 @@ PARAM_DEFINE_INT32(RC_RL1_DSM_VCC, 0); /* Relay 1 controls DSM VCC */ #endif PARAM_DEFINE_INT32(RC_DSM_BIND, -1); /* -1 = Idle, 0 = Start DSM2 bind, 1 = Start DSMX bind */ +PARAM_DEFINE_INT32(BAT_V_SCALE_IO, 10000); #ifdef CONFIG_ARCH_BOARD_PX4FMU_V2 PARAM_DEFINE_FLOAT(BAT_V_SCALING, 0.0082f); #else From 3e037d40de2a68b99aa4600f060eab3555f75832 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Sat, 21 Dec 2013 12:46:06 +0100 Subject: [PATCH 07/15] Fixed bracketing error --- src/drivers/px4io/px4io.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/drivers/px4io/px4io.cpp b/src/drivers/px4io/px4io.cpp index df96fa0bbd..a7f7fce453 100644 --- a/src/drivers/px4io/px4io.cpp +++ b/src/drivers/px4io/px4io.cpp @@ -901,16 +901,19 @@ PX4IO::task_main() int32_t voltage_scaling_val; param_t voltage_scaling_param; - /* see if bind parameter has been set, and reset it to -1 */ + /* set battery voltage scaling */ param_get(voltage_scaling_param = param_find("BAT_V_SCALE_IO"), &voltage_scaling_val); - /* send channel config to IO */ + /* send scaling voltage to IO */ uint16_t scaling = voltage_scaling_val; int pret = io_reg_set(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_VBATT_SCALE, &scaling, 1); if (pret != OK) { log("voltage scaling upload failed"); } + } + + } perf_end(_perf_update); } From b2e527ffa6f24a67903048ea157ee572f59f98a1 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Sat, 21 Dec 2013 16:13:04 +0100 Subject: [PATCH 08/15] Counting channel count changes --- src/drivers/px4io/px4io.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/drivers/px4io/px4io.cpp b/src/drivers/px4io/px4io.cpp index a7f7fce453..b80844c5b4 100644 --- a/src/drivers/px4io/px4io.cpp +++ b/src/drivers/px4io/px4io.cpp @@ -237,6 +237,7 @@ private: unsigned _update_interval; ///< Subscription interval limiting send rate bool _rc_handling_disabled; ///< If set, IO does not evaluate, but only forward the RC values + unsigned _rc_chan_count; ///< Internal copy of the last seen number of RC channels volatile int _task; /// 9) { ret = io_reg_get(PX4IO_PAGE_RAW_RC_INPUT, PX4IO_P_RAW_RC_BASE + 9, ®s[prolog + 9], channel_count - 9); From 831f153b7385fecb180c977727eb6b2f8bef1317 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Sat, 21 Dec 2013 16:37:45 +0100 Subject: [PATCH 09/15] Add tight RC test --- src/systemcmds/tests/module.mk | 3 +- src/systemcmds/tests/test_rc.c | 146 ++++++++++++++++++++++++++++++ src/systemcmds/tests/tests.h | 1 + src/systemcmds/tests/tests_main.c | 1 + 4 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 src/systemcmds/tests/test_rc.c diff --git a/src/systemcmds/tests/module.mk b/src/systemcmds/tests/module.mk index 5d5fe50d33..68a080c77c 100644 --- a/src/systemcmds/tests/module.mk +++ b/src/systemcmds/tests/module.mk @@ -27,4 +27,5 @@ SRCS = test_adc.c \ test_file.c \ tests_main.c \ test_param.c \ - test_ppm_loopback.c + test_ppm_loopback.c \ + test_rc.c diff --git a/src/systemcmds/tests/test_rc.c b/src/systemcmds/tests/test_rc.c new file mode 100644 index 0000000000..72619fc8ba --- /dev/null +++ b/src/systemcmds/tests/test_rc.c @@ -0,0 +1,146 @@ +/**************************************************************************** + * + * Copyright (c) 2012, 2013 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 test_ppm_loopback.c + * Tests the PWM outputs and PPM input + * + */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "tests.h" + +#include +#include + +int test_rc(int argc, char *argv[]) +{ + + int _rc_sub = orb_subscribe(ORB_ID(input_rc)); + + /* read low-level values from FMU or IO RC inputs (PPM, Spektrum, S.Bus) */ + struct rc_input_values rc_input; + struct rc_input_values rc_last; + orb_copy(ORB_ID(input_rc), _rc_sub, &rc_input); + usleep(100000); + + /* open PPM input and expect values close to the output values */ + + bool rc_updated; + orb_check(_rc_sub, &rc_updated); + + warnx("Reading PPM values - press any key to abort"); + warnx("This test guarantees: 10 Hz update rates, no glitches (channel values), no channel count changes."); + + if (rc_updated) { + + /* copy initial set */ + for (unsigned i = 0; i < rc_input.channel_count; i++) { + rc_last.values[i] = rc_input.values[i]; + } + + rc_last.channel_count = rc_input.channel_count; + + /* poll descriptor */ + struct pollfd fds[2]; + fds[0].fd = _rc_sub; + fds[0].events = POLLIN; + fds[1].fd = 0; + fds[1].events = POLLIN; + + while (true) { + + int ret = poll(fds, 2, 200); + + if (ret > 0) { + + if (fds[0].revents & POLLIN) { + + orb_copy(ORB_ID(input_rc), _rc_sub, &rc_input); + + /* go and check values */ + for (unsigned i = 0; i < rc_input.channel_count; i++) { + if (fabsf(rc_input.values[i] - rc_last.values[i]) > 20) { + warnx("comparison fail: RC: %d, expected: %d", rc_input.values[i], rc_last.values[i]); + (void)close(_rc_sub); + return ERROR; + } + + rc_last.values[i] = rc_input.values[i]; + } + + if (rc_last.channel_count != rc_input.channel_count) { + warnx("channel count mismatch: last: %d, now: %d", rc_last.channel_count, rc_input.channel_count); + (void)close(_rc_sub); + return ERROR; + } + + if (hrt_absolute_time() - rc_input.timestamp > 100000) { + warnx("TIMEOUT, less than 10 Hz updates"); + (void)close(_rc_sub); + return ERROR; + } + + } else { + /* key pressed, bye bye */ + return 0; + } + + } + } + + } else { + warnx("failed reading RC input data"); + return ERROR; + } + + warnx("PPM CONTINUITY TEST PASSED SUCCESSFULLY!"); + + return 0; +} diff --git a/src/systemcmds/tests/tests.h b/src/systemcmds/tests/tests.h index 5cbc5ad88f..a57d04be37 100644 --- a/src/systemcmds/tests/tests.h +++ b/src/systemcmds/tests/tests.h @@ -108,6 +108,7 @@ extern int test_param(int argc, char *argv[]); extern int test_bson(int argc, char *argv[]); extern int test_file(int argc, char *argv[]); extern int test_mixer(int argc, char *argv[]); +extern int test_rc(int argc, char *argv[]); __END_DECLS diff --git a/src/systemcmds/tests/tests_main.c b/src/systemcmds/tests/tests_main.c index cd998dd18d..1088a44076 100644 --- a/src/systemcmds/tests/tests_main.c +++ b/src/systemcmds/tests/tests_main.c @@ -105,6 +105,7 @@ const struct { {"bson", test_bson, 0}, {"file", test_file, 0}, {"mixer", test_mixer, OPT_NOJIGTEST | OPT_NOALLTEST}, + {"rc", test_rc, OPT_NOJIGTEST | OPT_NOALLTEST}, {"help", test_help, OPT_NOALLTEST | OPT_NOHELP | OPT_NOJIGTEST}, {NULL, NULL, 0} }; From a707e8cdb32b4b1b9c66b3e4010b56a2b0188a99 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Sat, 21 Dec 2013 18:58:28 +0100 Subject: [PATCH 10/15] Added missing folder --- ROMFS/px4fmu_logging/logging/conv.zip | Bin 0 -> 10087 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 ROMFS/px4fmu_logging/logging/conv.zip diff --git a/ROMFS/px4fmu_logging/logging/conv.zip b/ROMFS/px4fmu_logging/logging/conv.zip new file mode 100644 index 0000000000000000000000000000000000000000..7cb837e5666f51eca7ed803dfef4581f01bec1f3 GIT binary patch literal 10087 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 u{3`_dUvU4a?0?5mlL7u8okIcsrSt#bK|%jB3 Date: Mon, 23 Dec 2013 18:44:07 +0100 Subject: [PATCH 11/15] Added channel count to log format --- src/modules/sdlog2/sdlog2.c | 1 + src/modules/sdlog2/sdlog2_messages.h | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/modules/sdlog2/sdlog2.c b/src/modules/sdlog2/sdlog2.c index 2adb13f5c2..e94b1e13cb 100644 --- a/src/modules/sdlog2/sdlog2.c +++ b/src/modules/sdlog2/sdlog2.c @@ -1193,6 +1193,7 @@ int sdlog2_thread_main(int argc, char *argv[]) log_msg.msg_type = LOG_RC_MSG; /* Copy only the first 8 channels of 14 */ memcpy(log_msg.body.log_RC.channel, buf.rc.chan, sizeof(log_msg.body.log_RC.channel)); + log_msg.body.log_RC.channel_count = buf.rc.chan_count; LOGBUFFER_WRITE_AND_COUNT(RC); } diff --git a/src/modules/sdlog2/sdlog2_messages.h b/src/modules/sdlog2/sdlog2_messages.h index 90093a407c..ab4dc9b00d 100644 --- a/src/modules/sdlog2/sdlog2_messages.h +++ b/src/modules/sdlog2/sdlog2_messages.h @@ -159,6 +159,7 @@ struct log_STAT_s { #define LOG_RC_MSG 11 struct log_RC_s { float channel[8]; + uint8_t channel_count; }; /* --- OUT0 - ACTUATOR_0 OUTPUT --- */ @@ -281,7 +282,7 @@ static const struct log_format_s log_formats[] = { LOG_FORMAT(GPS, "QBffLLfffff", "GPSTime,FixType,EPH,EPV,Lat,Lon,Alt,VelN,VelE,VelD,Cog"), LOG_FORMAT(ATTC, "ffff", "Roll,Pitch,Yaw,Thrust"), LOG_FORMAT(STAT, "BBBfffBB", "MainState,NavState,ArmState,BatV,BatC,BatRem,BatWarn,Landed"), - LOG_FORMAT(RC, "ffffffff", "Ch0,Ch1,Ch2,Ch3,Ch4,Ch5,Ch6,Ch7"), + LOG_FORMAT(RC, "ffffffffB", "Ch0,Ch1,Ch2,Ch3,Ch4,Ch5,Ch6,Ch7,Count"), LOG_FORMAT(OUT0, "ffffffff", "Out0,Out1,Out2,Out3,Out4,Out5,Out6,Out7"), LOG_FORMAT(AIRS, "ff", "IndSpeed,TrueSpeed"), LOG_FORMAT(ARSP, "fff", "RollRateSP,PitchRateSP,YawRateSP"), From 107bb54b33dd4360fd5fee538f7a87b79279b8ab Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Mon, 23 Dec 2013 20:38:09 +0100 Subject: [PATCH 12/15] Robustifiying PPM parsing --- src/drivers/stm32/drv_hrt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drivers/stm32/drv_hrt.c b/src/drivers/stm32/drv_hrt.c index 36226c941f..f105251f0a 100644 --- a/src/drivers/stm32/drv_hrt.c +++ b/src/drivers/stm32/drv_hrt.c @@ -342,7 +342,7 @@ static void hrt_call_invoke(void); #define PPM_MAX_CHANNELS 20 /* Number of same-sized frames required to 'lock' */ -#define PPM_CHANNEL_LOCK 2 /* should be less than the input timeout */ +#define PPM_CHANNEL_LOCK 4 /* should be less than the input timeout */ __EXPORT uint16_t ppm_buffer[PPM_MAX_CHANNELS]; __EXPORT unsigned ppm_decoded_channels = 0; From a5023329920d5ce45c5bf48ae61d621947cdb349 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Wed, 25 Dec 2013 15:10:24 +0100 Subject: [PATCH 13/15] Greatly robustified PPM parsing, needs cross-checking with receiver models --- src/drivers/stm32/drv_hrt.c | 39 ++++++++++++++++++++++-------- src/modules/systemlib/ppm_decode.h | 1 + 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/drivers/stm32/drv_hrt.c b/src/drivers/stm32/drv_hrt.c index f105251f0a..5bfbe04b8a 100644 --- a/src/drivers/stm32/drv_hrt.c +++ b/src/drivers/stm32/drv_hrt.c @@ -282,6 +282,10 @@ static void hrt_call_invoke(void); * Note that we assume that M3 means STM32F1 (since we don't really care about the F2). */ # ifdef CONFIG_ARCH_CORTEXM3 +# undef GTIM_CCER_CC1NP +# undef GTIM_CCER_CC2NP +# undef GTIM_CCER_CC3NP +# undef GTIM_CCER_CC4NP # define GTIM_CCER_CC1NP 0 # define GTIM_CCER_CC2NP 0 # define GTIM_CCER_CC3NP 0 @@ -332,10 +336,10 @@ static void hrt_call_invoke(void); /* * PPM decoder tuning parameters */ -# define PPM_MAX_PULSE_WIDTH 550 /* maximum width of a valid pulse */ +# define PPM_MAX_PULSE_WIDTH 700 /* maximum width of a valid pulse */ # define PPM_MIN_CHANNEL_VALUE 800 /* shortest valid channel signal */ # define PPM_MAX_CHANNEL_VALUE 2200 /* longest valid channel signal */ -# define PPM_MIN_START 2500 /* shortest valid start gap */ +# define PPM_MIN_START 2400 /* shortest valid start gap (only 2nd part of pulse) */ /* decoded PPM buffer */ #define PPM_MIN_CHANNELS 5 @@ -345,6 +349,7 @@ static void hrt_call_invoke(void); #define PPM_CHANNEL_LOCK 4 /* should be less than the input timeout */ __EXPORT uint16_t ppm_buffer[PPM_MAX_CHANNELS]; +__EXPORT uint16_t ppm_frame_length = 0; __EXPORT unsigned ppm_decoded_channels = 0; __EXPORT uint64_t ppm_last_valid_decode = 0; @@ -362,7 +367,8 @@ static uint16_t ppm_temp_buffer[PPM_MAX_CHANNELS]; struct { uint16_t last_edge; /* last capture time */ uint16_t last_mark; /* last significant edge */ - unsigned next_channel; + uint16_t frame_start; /* the frame width */ + unsigned next_channel; /* next channel index */ enum { UNSYNCH = 0, ARM, @@ -447,7 +453,6 @@ hrt_ppm_decode(uint32_t status) /* how long since the last edge? - this handles counter wrapping implicitely. */ width = count - ppm.last_edge; - ppm.last_edge = count; ppm_edge_history[ppm_edge_next++] = width; @@ -491,6 +496,7 @@ hrt_ppm_decode(uint32_t status) ppm_buffer[i] = ppm_temp_buffer[i]; ppm_last_valid_decode = hrt_absolute_time(); + } } @@ -500,13 +506,14 @@ hrt_ppm_decode(uint32_t status) /* next edge is the reference for the first channel */ ppm.phase = ARM; + ppm.last_edge = count; return; } switch (ppm.phase) { case UNSYNCH: /* we are waiting for a start pulse - nothing useful to do here */ - return; + break; case ARM: @@ -515,14 +522,23 @@ hrt_ppm_decode(uint32_t status) goto error; /* pulse was too long */ /* record the mark timing, expect an inactive edge */ - ppm.last_mark = count; - ppm.phase = INACTIVE; - return; + ppm.last_mark = ppm.last_edge; + + /* frame length is everything including the start gap */ + ppm_frame_length = (uint16_t)(ppm.last_edge - ppm.frame_start); + ppm.frame_start = ppm.last_edge; + ppm.phase = ACTIVE; + break; case INACTIVE: + + /* we expect a short pulse */ + if (width > PPM_MAX_PULSE_WIDTH) + goto error; /* pulse was too long */ + /* this edge is not interesting, but now we are ready for the next mark */ ppm.phase = ACTIVE; - return; + break; case ACTIVE: /* determine the interval from the last mark */ @@ -543,10 +559,13 @@ hrt_ppm_decode(uint32_t status) ppm_temp_buffer[ppm.next_channel++] = interval; ppm.phase = INACTIVE; - return; + break; } + ppm.last_edge = count; + return; + /* the state machine is corrupted; reset it */ error: diff --git a/src/modules/systemlib/ppm_decode.h b/src/modules/systemlib/ppm_decode.h index 6c5e15345e..5a1ad84da9 100644 --- a/src/modules/systemlib/ppm_decode.h +++ b/src/modules/systemlib/ppm_decode.h @@ -57,6 +57,7 @@ __BEGIN_DECLS * PPM decoder state */ __EXPORT extern uint16_t ppm_buffer[PPM_MAX_CHANNELS]; /**< decoded PPM channel values */ +__EXPORT extern uint16_t ppm_frame_length; /**< length of the decoded PPM frame (includes gap) */ __EXPORT extern unsigned ppm_decoded_channels; /**< count of decoded channels */ __EXPORT extern hrt_abstime ppm_last_valid_decode; /**< timestamp of the last valid decode */ From edffade8cec2ea779040e97fb5478e0e9db12031 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Wed, 25 Dec 2013 15:11:48 +0100 Subject: [PATCH 14/15] Added PPM frame length feedback in IO comms and status command - allows to warn users about badly formatted PPM frames --- src/drivers/px4io/px4io.cpp | 10 ++++++++++ src/modules/px4iofirmware/controls.c | 10 +++++++--- src/modules/px4iofirmware/protocol.h | 3 ++- src/modules/px4iofirmware/registers.c | 6 ++++-- 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/drivers/px4io/px4io.cpp b/src/drivers/px4io/px4io.cpp index b80844c5b4..010272c6f4 100644 --- a/src/drivers/px4io/px4io.cpp +++ b/src/drivers/px4io/px4io.cpp @@ -1724,6 +1724,16 @@ PX4IO::print_status() printf(" %u", io_reg_get(PX4IO_PAGE_RAW_RC_INPUT, PX4IO_P_RAW_RC_BASE + i)); printf("\n"); + + if (raw_inputs > 0) { + int frame_len = io_reg_get(PX4IO_PAGE_STATUS, PX4IO_P_STATUS_RC_DATA); + printf("RC data (PPM frame len) %u us\n", frame_len); + + if ((frame_len - raw_inputs * 2000 - 3000) < 0) { + printf("WARNING WARNING WARNING! This RC receiver does not allow safe frame detection.\n"); + } + } + uint16_t mapped_inputs = io_reg_get(PX4IO_PAGE_RC_INPUT, PX4IO_P_RC_VALID); printf("mapped R/C inputs 0x%04x", mapped_inputs); diff --git a/src/modules/px4iofirmware/controls.c b/src/modules/px4iofirmware/controls.c index 194d8aab98..58af77997a 100644 --- a/src/modules/px4iofirmware/controls.c +++ b/src/modules/px4iofirmware/controls.c @@ -50,7 +50,7 @@ #define RC_CHANNEL_HIGH_THRESH 5000 #define RC_CHANNEL_LOW_THRESH -5000 -static bool ppm_input(uint16_t *values, uint16_t *num_values); +static bool ppm_input(uint16_t *values, uint16_t *num_values, uint16_t *frame_len); static perf_counter_t c_gather_dsm; static perf_counter_t c_gather_sbus; @@ -125,7 +125,7 @@ controls_tick() { * disable the PPM decoder completely if we have S.bus signal. */ perf_begin(c_gather_ppm); - bool ppm_updated = ppm_input(r_raw_rc_values, &r_raw_rc_count); + bool ppm_updated = ppm_input(r_raw_rc_values, &r_raw_rc_count, &r_page_status[PX4IO_P_STATUS_RC_DATA]); if (ppm_updated) { /* XXX sample RSSI properly here */ @@ -319,7 +319,7 @@ controls_tick() { } static bool -ppm_input(uint16_t *values, uint16_t *num_values) +ppm_input(uint16_t *values, uint16_t *num_values, uint16_t *frame_len) { bool result = false; @@ -343,6 +343,10 @@ ppm_input(uint16_t *values, uint16_t *num_values) /* clear validity */ ppm_last_valid_decode = 0; + /* store PPM frame length */ + if (num_values) + *frame_len = ppm_frame_length; + /* good if we got any channels */ result = (*num_values > 0); } diff --git a/src/modules/px4iofirmware/protocol.h b/src/modules/px4iofirmware/protocol.h index 11e3803976..500e0ed4b3 100644 --- a/src/modules/px4iofirmware/protocol.h +++ b/src/modules/px4iofirmware/protocol.h @@ -124,7 +124,8 @@ #define PX4IO_P_STATUS_VSERVO 6 /* [2] servo rail voltage in mV */ #define PX4IO_P_STATUS_VRSSI 7 /* [2] RSSI voltage */ #define PX4IO_P_STATUS_PRSSI 8 /* [2] RSSI PWM value */ -#define PX4IO_P_STATUS_NRSSI 9 /* [2] Normalized RSSI value, 0: no reception, 1000: perfect reception */ +#define PX4IO_P_STATUS_NRSSI 9 /* [2] Normalized RSSI value, 0: no reception, 255: perfect reception */ +#define PX4IO_P_STATUS_RC_DATA 10 /* [1] + [2] Details about the RC source (PPM frame length, Spektrum protocol type) */ /* array of post-mix actuator outputs, -10000..10000 */ #define PX4IO_PAGE_ACTUATORS 2 /* 0..CONFIG_ACTUATOR_COUNT-1 */ diff --git a/src/modules/px4iofirmware/registers.c b/src/modules/px4iofirmware/registers.c index 3f9e111baa..6aa3a5cd26 100644 --- a/src/modules/px4iofirmware/registers.c +++ b/src/modules/px4iofirmware/registers.c @@ -89,7 +89,9 @@ uint16_t r_page_status[] = { [PX4IO_P_STATUS_IBATT] = 0, [PX4IO_P_STATUS_VSERVO] = 0, [PX4IO_P_STATUS_VRSSI] = 0, - [PX4IO_P_STATUS_PRSSI] = 0 + [PX4IO_P_STATUS_PRSSI] = 0, + [PX4IO_P_STATUS_NRSSI] = 0, + [PX4IO_P_STATUS_RC_DATA] = 0 }; /** @@ -114,7 +116,7 @@ uint16_t r_page_servos[PX4IO_SERVO_COUNT]; uint16_t r_page_raw_rc_input[] = { [PX4IO_P_RAW_RC_COUNT] = 0, - [PX4IO_P_RAW_RC_BASE ... (PX4IO_P_RAW_RC_BASE + 24)] = 0 // XXX ensure we have enough space to decode beefy RX, will be replaced by patch soon + [PX4IO_P_RAW_RC_BASE ... (PX4IO_P_RAW_RC_BASE + PX4IO_CONTROL_CHANNELS)] = 0 // XXX ensure we have enough space to decode beefy RX, will be replaced by patch soon }; /** From 8d2950561d1889ab1d4c2fc5d832a2984048487d Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Wed, 25 Dec 2013 15:15:15 +0100 Subject: [PATCH 15/15] Changed RSSI range to 0..255 --- src/drivers/drv_rc_input.h | 2 +- src/modules/px4iofirmware/controls.c | 6 +++--- src/modules/px4iofirmware/sbus.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/drivers/drv_rc_input.h b/src/drivers/drv_rc_input.h index 7b18b5b15b..66771faaa4 100644 --- a/src/drivers/drv_rc_input.h +++ b/src/drivers/drv_rc_input.h @@ -89,7 +89,7 @@ struct rc_input_values { /** number of channels actually being seen */ uint32_t channel_count; - /** receive signal strength indicator (RSSI): < 0: Undefined, 0: no signal, 1000: full reception */ + /** receive signal strength indicator (RSSI): < 0: Undefined, 0: no signal, 255: full reception */ int32_t rssi; /** Input source */ diff --git a/src/modules/px4iofirmware/controls.c b/src/modules/px4iofirmware/controls.c index 58af77997a..ed29c83394 100644 --- a/src/modules/px4iofirmware/controls.c +++ b/src/modules/px4iofirmware/controls.c @@ -94,7 +94,7 @@ controls_tick() { * other. Don't do that. */ - /* receive signal strenght indicator (RSSI). 0 = no connection, 1000: perfect connection */ + /* receive signal strenght indicator (RSSI). 0 = no connection, 255: perfect connection */ uint16_t rssi = 0; perf_begin(c_gather_dsm); @@ -108,7 +108,7 @@ controls_tick() { else r_status_flags &= ~PX4IO_P_STATUS_FLAGS_RC_DSM11; - rssi = 1000; + rssi = 255; } perf_end(c_gather_dsm); @@ -129,7 +129,7 @@ controls_tick() { if (ppm_updated) { /* XXX sample RSSI properly here */ - rssi = 1000; + rssi = 255; r_status_flags |= PX4IO_P_STATUS_FLAGS_RC_PPM; } diff --git a/src/modules/px4iofirmware/sbus.c b/src/modules/px4iofirmware/sbus.c index 388502b403..3dcfe7f5b2 100644 --- a/src/modules/px4iofirmware/sbus.c +++ b/src/modules/px4iofirmware/sbus.c @@ -280,7 +280,7 @@ sbus_decode(hrt_abstime frame_time, uint16_t *values, uint16_t *num_values, uint *rssi = 100; // XXX magic number indicating bad signal, but not a signal loss (yet) } - *rssi = 1000; + *rssi = 255; return true; }