From 1485a4ec1aa8328cc50d99a1195b20df2b11045e Mon Sep 17 00:00:00 2001 From: px4dev Date: Mon, 3 Dec 2012 23:20:28 -0800 Subject: Fix breakage to the DSM parser introduced with the input prioritisation logic. Back out to a "any input wins" strategy; connecting multiple receivers to I/O at the same time is currently not supported (read: strange things will happen). --- apps/px4io/px4io.h | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'apps/px4io/px4io.h') diff --git a/apps/px4io/px4io.h b/apps/px4io/px4io.h index 483b9bcc8..63a55d840 100644 --- a/apps/px4io/px4io.h +++ b/apps/px4io/px4io.h @@ -69,12 +69,8 @@ struct sys_state_s { - bool armed; /* IO armed */ - bool arm_ok; /* FMU says OK to arm */ - - bool ppm_input_ok; /* valid PPM input data */ - bool dsm_input_ok; /* valid Spektrum DSM data */ - bool sbus_input_ok; /* valid Futaba S.Bus data */ + bool armed; /* IO armed */ + bool arm_ok; /* FMU says OK to arm */ /* * Data from the remote control input(s) -- cgit v1.2.3 From 7c3b28d503123121403b4ad68c934bb91b05d878 Mon Sep 17 00:00:00 2001 From: px4dev Date: Tue, 4 Dec 2012 09:52:16 -0800 Subject: Lock out the PPM decoder if the DSM or S.bus decoders have seen a frame recently. --- apps/px4io/controls.c | 22 ++++++++++++++++++---- apps/px4io/dsm.c | 12 +++++++++--- apps/px4io/px4io.h | 4 ++-- apps/px4io/sbus.c | 16 +++++++++++++--- 4 files changed, 42 insertions(+), 12 deletions(-) (limited to 'apps/px4io/px4io.h') diff --git a/apps/px4io/controls.c b/apps/px4io/controls.c index 6cf3c80ac..3b3782918 100644 --- a/apps/px4io/controls.c +++ b/apps/px4io/controls.c @@ -86,15 +86,29 @@ controls_main(void) * one control input source, they're going to fight each * other. Don't do that. */ + bool locked = false; + if (fds[0].revents & POLLIN) - dsm_input(); + locked |= dsm_input(); if (fds[1].revents & POLLIN) - sbus_input(); - ppm_input(); + locked |= sbus_input(); + + /* + * If we don't have lock from one of the serial receivers, + * look for PPM. It shares an input with S.bus, so there's + * a possibility it will mis-parse an S.bus frame. + * + * XXX each S.bus frame will cause a PPM decoder interrupt + * storm (lots of edges). It might be sensible to actually + * disable the PPM decoder completely if we have an alternate + * receiver lock. + */ + if (!locked) + ppm_input(); /* * If we haven't seen any new control data in 200ms, assume we - * have lost input and tell FMU + * have lost input and tell FMU. */ if ((hrt_absolute_time() - system_state.rc_channels_timestamp) > 200000) { diff --git a/apps/px4io/dsm.c b/apps/px4io/dsm.c index 5841f29a3..04aca709b 100644 --- a/apps/px4io/dsm.c +++ b/apps/px4io/dsm.c @@ -104,7 +104,7 @@ dsm_init(const char *device) return dsm_fd; } -void +bool dsm_input(void) { ssize_t ret; @@ -141,7 +141,7 @@ dsm_input(void) /* if the read failed for any reason, just give up here */ if (ret < 1) - return; + goto out; last_rx_time = now; /* @@ -153,7 +153,7 @@ dsm_input(void) * If we don't have a full frame, return */ if (partial_frame_count < DSM_FRAME_SIZE) - return; + goto out; /* * Great, it looks like we might have a frame. Go ahead and @@ -161,6 +161,12 @@ dsm_input(void) */ dsm_decode(now); partial_frame_count = 0; + +out: + /* + * If we have seen a frame in the last 200ms, we consider ourselves 'locked' + */ + return (now - last_frame_time) < 200000; } static bool diff --git a/apps/px4io/px4io.h b/apps/px4io/px4io.h index 63a55d840..0032e6d80 100644 --- a/apps/px4io/px4io.h +++ b/apps/px4io/px4io.h @@ -165,9 +165,9 @@ extern void comms_main(void) __attribute__((noreturn)); */ extern void controls_main(void); extern int dsm_init(const char *device); -extern void dsm_input(void); +extern bool dsm_input(void); extern int sbus_init(const char *device); -extern void sbus_input(void); +extern bool sbus_input(void); /* * Assertion codes diff --git a/apps/px4io/sbus.c b/apps/px4io/sbus.c index 25fe0cf38..a8f628a84 100644 --- a/apps/px4io/sbus.c +++ b/apps/px4io/sbus.c @@ -58,6 +58,7 @@ static int sbus_fd = -1; static hrt_abstime last_rx_time; +static hrt_abstime last_frame_time; static uint8_t frame[SBUS_FRAME_SIZE]; @@ -94,7 +95,7 @@ sbus_init(const char *device) return sbus_fd; } -void +bool sbus_input(void) { ssize_t ret; @@ -131,7 +132,7 @@ sbus_input(void) /* if the read failed for any reason, just give up here */ if (ret < 1) - return; + goto out; last_rx_time = now; /* @@ -143,7 +144,7 @@ sbus_input(void) * If we don't have a full frame, return */ if (partial_frame_count < SBUS_FRAME_SIZE) - return; + goto out; /* * Great, it looks like we might have a frame. Go ahead and @@ -151,6 +152,12 @@ sbus_input(void) */ sbus_decode(now); partial_frame_count = 0; + +out: + /* + * If we have seen a frame in the last 200ms, we consider ourselves 'locked' + */ + return (now - last_frame_time) < 200000; } /* @@ -203,6 +210,9 @@ sbus_decode(hrt_abstime frame_time) return; } + /* we have received something we think is a frame */ + last_frame_time = frame_time; + unsigned chancount = (PX4IO_INPUT_CHANNELS > SBUS_INPUT_CHANNELS) ? SBUS_INPUT_CHANNELS : PX4IO_INPUT_CHANNELS; -- cgit v1.2.3 From fd771f67f2a2392d5ba2b7dd74100338859af6d7 Mon Sep 17 00:00:00 2001 From: px4dev Date: Tue, 4 Dec 2012 22:00:24 -0800 Subject: Adjust the control mapping from DSM receivers to correspond to the standard PPM control mapping for channels 0-4. --- apps/px4io/comms.c | 2 +- apps/px4io/dsm.c | 26 ++++++++++++++++++++++---- apps/px4io/px4io.h | 2 +- 3 files changed, 24 insertions(+), 6 deletions(-) (limited to 'apps/px4io/px4io.h') diff --git a/apps/px4io/comms.c b/apps/px4io/comms.c index 480e3f5cc..83a006d43 100644 --- a/apps/px4io/comms.c +++ b/apps/px4io/comms.c @@ -130,7 +130,7 @@ comms_main(void) last_report_time = now; /* populate the report */ - for (int i = 0; i < system_state.rc_channels; i++) + for (unsigned i = 0; i < system_state.rc_channels; i++) report.rc_channel[i] = system_state.rc_channel_data[i]; report.channel_count = system_state.rc_channels; report.armed = system_state.armed; diff --git a/apps/px4io/dsm.c b/apps/px4io/dsm.c index 04aca709b..2611f3a03 100644 --- a/apps/px4io/dsm.c +++ b/apps/px4io/dsm.c @@ -322,10 +322,28 @@ dsm_decode(hrt_abstime frame_time) /* convert 0-1024 / 0-2048 values to 1000-2000 ppm encoding in a very sloppy fashion */ if (channel_shift == 11) value /= 2; - - /* stuff the decoded channel into the PPM input buffer */ - /* XXX check actual values */ - system_state.rc_channel_data[channel] = 988 + value; + value += 998; + + /* + * Store the decoded channel into the R/C input buffer, taking into + * account the different ideas about channel assignement that we have. + * + * Specifically, the first four channels in rc_channel_data are roll, pitch, thrust, yaw, + * but the first four channels from the DSM receiver are thrust, roll, pitch, yaw. + */ + switch (channel) { + case 0: + channel = 2; + break; + case 1: + channel = 0; + break; + case 2: + channel = 1; + default: + break; + } + system_state.rc_channel_data[channel] = value; } /* and note that we have received data from the R/C controller */ diff --git a/apps/px4io/px4io.h b/apps/px4io/px4io.h index 0032e6d80..45b7cf847 100644 --- a/apps/px4io/px4io.h +++ b/apps/px4io/px4io.h @@ -75,7 +75,7 @@ struct sys_state_s /* * Data from the remote control input(s) */ - int rc_channels; + unsigned rc_channels; uint16_t rc_channel_data[PX4IO_INPUT_CHANNELS]; uint64_t rc_channels_timestamp; -- cgit v1.2.3