aboutsummaryrefslogtreecommitdiff
path: root/src/drivers/px4io/px4io.cpp
diff options
context:
space:
mode:
authorJean Cyr <jcyr@dillobits.com>2013-07-05 20:51:29 -0400
committerJean Cyr <jcyr@dillobits.com>2013-07-05 20:51:29 -0400
commit3f9f2018e20f4be23e7d62571ec0a3678d960108 (patch)
tree59f0a2cf6c7bc802d95fcc31143caa26353190a3 /src/drivers/px4io/px4io.cpp
parent697c0a1a1d7fb1043786533da3570f28acd661dc (diff)
downloadpx4-firmware-3f9f2018e20f4be23e7d62571ec0a3678d960108.tar.gz
px4-firmware-3f9f2018e20f4be23e7d62571ec0a3678d960108.tar.bz2
px4-firmware-3f9f2018e20f4be23e7d62571ec0a3678d960108.zip
Support binding DSM2 and DSMX satellite receivers
The px4io bind command allows you to put a DSM satellite receiver into bind mode. Since this feature requires that the dsm VCC line (red wire) be cut and routed through relay one, it is not enabled by default in order not to affect those not using a DSM satellite receiver or wising to use relay one for other purposes. NOTE: Binding DSM2 satellites in 11-bit mode is not supported due to potential bug in some DSM2 receiver streams when in 11-bit mode. Furthermore the px4io software folds 11 bit data down to 10 bits so there is no resolution advantage to to 11-bit mode. To enable the feature the RC_RL1_DSM_VCC parameter must be set to a non zero value from the console, or using QGroundControl: param set RC_RL1_DSM_VCC 1 From the console you can initiate DSM bind mode with: uorb start param set RC_RL1_DSM_VCC 1 px4io start px4io bind dsm2 For binding a DSMX satellite to a DSMX transmitter you would instead use: px4io bind dsmx Your receiver module should start a rapid flash and you can follow the normal binding sequence of your transmitter. Note: The value of parameter RC_RL1_DSM_VCC defaults to 0, so none of this will have any effect on an unmodified DSM receiver connection. For this feature to work, the power wire (red) must be cut and each side connected to a terminal on relay1 of the px4io board. This has been tested using Spektrum as well as Hobby King 'Orange' DSM satellite receivers. Both px4fmu and px4io images are updated.
Diffstat (limited to 'src/drivers/px4io/px4io.cpp')
-rw-r--r--src/drivers/px4io/px4io.cpp96
1 files changed, 91 insertions, 5 deletions
diff --git a/src/drivers/px4io/px4io.cpp b/src/drivers/px4io/px4io.cpp
index 19163cebe..54b9d50e4 100644
--- a/src/drivers/px4io/px4io.cpp
+++ b/src/drivers/px4io/px4io.cpp
@@ -89,6 +89,8 @@
#define PX4IO_SET_DEBUG _IOC(0xff00, 0)
#define PX4IO_INAIR_RESTART_ENABLE _IOC(0xff00, 1)
+static int dsm_vcc_ctl;
+
class PX4IO : public device::I2C
{
public:
@@ -700,8 +702,6 @@ PX4IO::io_set_control_state()
int
PX4IO::set_failsafe_values(const uint16_t *vals, unsigned len)
{
- uint16_t regs[_max_actuators];
-
if (len > _max_actuators)
/* fail with error */
return E2BIG;
@@ -1271,13 +1271,14 @@ PX4IO::print_status()
printf("%u bytes free\n",
io_reg_get(PX4IO_PAGE_STATUS, PX4IO_P_STATUS_FREEMEM));
uint16_t flags = io_reg_get(PX4IO_PAGE_STATUS, PX4IO_P_STATUS_FLAGS);
- printf("status 0x%04x%s%s%s%s%s%s%s%s%s%s%s%s\n",
+ printf("status 0x%04x%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
flags,
((flags & PX4IO_P_STATUS_FLAGS_ARMED) ? " ARMED" : ""),
((flags & PX4IO_P_STATUS_FLAGS_OVERRIDE) ? " OVERRIDE" : ""),
((flags & PX4IO_P_STATUS_FLAGS_RC_OK) ? " RC_OK" : " RC_FAIL"),
((flags & PX4IO_P_STATUS_FLAGS_RC_PPM) ? " PPM" : ""),
- ((flags & PX4IO_P_STATUS_FLAGS_RC_DSM) ? " DSM" : ""),
+ (((flags & PX4IO_P_STATUS_FLAGS_RC_DSM) && (!(flags & PX4IO_P_STATUS_FLAGS_RC_DSM11))) ? " DSM10" : ""),
+ (((flags & PX4IO_P_STATUS_FLAGS_RC_DSM) && (flags & PX4IO_P_STATUS_FLAGS_RC_DSM11)) ? " DSM11" : ""),
((flags & PX4IO_P_STATUS_FLAGS_RC_SBUS) ? " SBUS" : ""),
((flags & PX4IO_P_STATUS_FLAGS_FMU_OK) ? " FMU_OK" : " FMU_FAIL"),
((flags & PX4IO_P_STATUS_FLAGS_RAW_PWM) ? " RAW_PPM" : ""),
@@ -1424,6 +1425,26 @@ PX4IO::ioctl(file *filep, int cmd, unsigned long arg)
*(unsigned *)arg = _max_actuators;
break;
+ case DSM_BIND_START:
+ io_reg_set(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_DSM, dsm_bind_power_down);
+ usleep(500000);
+ io_reg_set(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_DSM, dsm_bind_set_rx_out);
+ usleep(1000);
+ io_reg_set(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_DSM, dsm_bind_power_up);
+ usleep(100000);
+ io_reg_set(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_DSM, dsm_bind_send_pulses | (arg << 4));
+ break;
+
+ case DSM_BIND_STOP:
+ io_reg_set(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_DSM, dsm_bind_power_down);
+ io_reg_set(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_DSM, dsm_bind_reinit_uart);
+ usleep(500000);
+ break;
+
+ case DSM_BIND_POWER_UP:
+ io_reg_set(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_DSM, dsm_bind_power_up);
+ break;
+
case PWM_SERVO_SET(0) ... PWM_SERVO_SET(PWM_OUTPUT_MAX_CHANNELS - 1): {
/* TODO: we could go lower for e.g. TurboPWM */
@@ -1614,10 +1635,72 @@ start(int argc, char *argv[])
errx(1, "driver init failed");
}
+ if (param_get(param_find("RC_RL1_DSM_VCC"), &dsm_vcc_ctl) == OK) {
+ if (dsm_vcc_ctl) {
+ int fd = open("/dev/px4io", O_WRONLY);
+ if (fd < 0)
+ errx(1, "failed to open device");
+ ioctl(fd, DSM_BIND_POWER_UP, 0);
+ close(fd);
+ }
+ }
exit(0);
}
void
+bind(int argc, char *argv[])
+{
+ int fd, pulses;
+
+ if (g_dev == nullptr)
+ errx(1, "px4io must be started first");
+
+ if (dsm_vcc_ctl == 0)
+ errx(1, "DSM bind feature not enabled");
+
+ if (argc < 3)
+ errx(0, "needs argument, use dsm2 or dsmx");
+
+ if (!strcmp(argv[2], "dsm2"))
+ pulses = 3;
+ else if (!strcmp(argv[2], "dsmx"))
+ pulses = 7;
+ else
+ errx(1, "unknown parameter %s, use dsm2 or dsmx", argv[2]);
+
+ fd = open("/dev/px4io", O_WRONLY);
+
+ if (fd < 0)
+ errx(1, "failed to open device");
+
+ ioctl(fd, DSM_BIND_START, pulses);
+
+ /* Open console directly to grab CTRL-C signal */
+ int console = open("/dev/console", O_NONBLOCK | O_RDONLY | O_NOCTTY);
+ if (!console)
+ errx(1, "failed opening console");
+
+ warnx("This command will only bind DSM if satellite VCC (red wire) is controlled by relay 1.");
+ warnx("Press CTRL-C or 'c' when done.");
+
+ for (;;) {
+ usleep(500000L);
+ /* Check if user wants to quit */
+ char c;
+ if (read(console, &c, 1) == 1) {
+ if (c == 0x03 || c == 0x63) {
+ warnx("Done\n");
+ ioctl(fd, DSM_BIND_STOP, 0);
+ ioctl(fd, DSM_BIND_POWER_UP, 0);
+ close(fd);
+ close(console);
+ exit(0);
+ }
+ }
+ }
+}
+
+void
test(void)
{
int fd;
@@ -1918,6 +2001,9 @@ px4io_main(int argc, char *argv[])
if (!strcmp(argv[1], "monitor"))
monitor();
+ if (!strcmp(argv[1], "bind"))
+ bind(argc, argv);
+
out:
- errx(1, "need a command, try 'start', 'stop', 'status', 'test', 'monitor', 'debug', 'recovery', 'limit', 'current', 'failsafe' or 'update'");
+ errx(1, "need a command, try 'start', 'stop', 'status', 'test', 'monitor', 'debug', 'recovery', 'limit', 'current', 'failsafe', 'bind', or 'update'");
}