41 #include <px4_platform_common/px4_config.h> 42 #include <px4_platform_common/tasks.h> 43 #include <px4_platform_common/sem.hpp> 45 #include <sys/types.h> 61 #include <arch/board/board.h> 107 #define PX4IO_SET_DEBUG _IOC(0xff00, 0) 108 #define PX4IO_INAIR_RESTART_ENABLE _IOC(0xff00, 1) 109 #define PX4IO_REBOOT_BOOTLOADER _IOC(0xff00, 2) 110 #define PX4IO_CHECK_CRC _IOC(0xff00, 3) 115 #define ORB_CHECK_INTERVAL 200000 // 200 ms -> 5 Hz 116 #define IO_POLL_INTERVAL 20000 // 20 ms -> 50 Hz 157 int init(
bool disable_rc_handling,
bool hitl_mode);
175 virtual int ioctl(
file *filp,
int cmd,
unsigned long arg);
187 virtual ssize_t
write(
file *filp,
const char *buffer,
size_t len);
195 int set_update_rate(
int rate);
200 int disable_rc_handling();
223 _test_fmu_fail = is_fail;
297 bool in_test_mode{
false};
316 int io_set_control_state(
unsigned group);
321 int io_set_control_groups();
326 int io_set_arming_state();
331 int io_set_rc_config();
343 int io_disable_rc_handling();
351 int io_get_raw_rc_input(
input_rc_s &input_rc);
356 int io_publish_raw_rc();
361 int io_publish_pwm_outputs();
372 int io_reg_set(uint8_t page, uint8_t offset,
const uint16_t *values,
unsigned num_values);
382 int io_reg_set(uint8_t page, uint8_t offset,
const uint16_t value);
393 int io_reg_get(uint8_t page, uint8_t offset, uint16_t *values,
unsigned num_values);
402 uint32_t io_reg_get(uint8_t page, uint8_t offset);
403 static const uint32_t _io_reg_get_error = 0x80000000;
413 int io_reg_modify(uint8_t page, uint8_t offset, uint16_t clearbits, uint16_t setbits);
418 int mixer_send(
const char *buf,
unsigned buflen,
unsigned retries = 3);
427 int io_handle_status(uint16_t
status);
436 int io_handle_alarms(uint16_t alarms);
443 void dsm_bind_ioctl(
int dsmMode);
453 void io_handle_vservo(uint16_t vservo, uint16_t vrssi);
458 void handle_motor_test();
470 #define PX4IO_DEVICE_PATH "/dev/px4io" 474 _interface(interface),
482 _rc_handling_disabled(false),
487 _mavlink_log_pub(nullptr),
493 _last_written_arming_s(0),
494 _last_written_arming_c(0),
495 _t_actuator_controls_0(-1),
496 _param_update_force(false),
497 _primary_pwm_device(false),
498 _lockdown_override(false),
500 _override_available(false),
501 _cb_flighttermination(true),
502 _in_esc_calibration_mode(false),
506 _thermal_control(-1),
507 _analog_rc_rssi_stable(false),
508 _analog_rc_rssi_volt(-1.0
f),
509 _test_fmu_fail(false),
522 for (
unsigned i = 0; (i < 10) && (
_task != -1); i++) {
563 PX4_ERR(
"IO not installed");
566 PX4_ERR(
"IO version error");
574 PX4_INFO(
"IO found");
594 sys_restart_param =
param_find(
"SYS_RESTART_TYPE");
645 PX4_ERR(
"config read error");
712 if (actuator_armed_sub.update(&actuator_armed)) {
736 errx(1,
"PRM SYSID");
739 if (
param_get(comp_id_param, &comp_id)) {
740 errx(1,
"PRM CMPID");
756 vcmd.
command = vehicle_command_s::VEHICLE_CMD_DO_FLIGHTTERMINATION;
760 vcmd_pub.publish(vcmd);
764 actuator_armed_sub.update(&actuator_armed);
776 if (!actuator_armed.force_failsafe) {
777 vcmd_pub.publish(vcmd);
778 PX4_WARN(
"re-sending flight termination cmd");
782 }
while (!actuator_armed.force_failsafe);
788 vcmd.
command = vehicle_command_s::VEHICLE_CMD_COMPONENT_ARM_DISARM;
792 vcmd_pub.publish(vcmd);
796 actuator_armed_sub.update(&actuator_armed);
808 if (!actuator_armed.armed) {
809 vcmd_pub.publish(vcmd);
810 PX4_WARN(
"re-sending arm cmd");
814 }
while (!actuator_armed.armed);
821 if (prev_val != sys_restart_val) {
822 param_set(sys_restart_param, &sys_restart_val);
831 PX4IO_P_SETUP_ARMING_FMU_ARMED |
832 PX4IO_P_SETUP_ARMING_INAIR_RESTART_OK |
841 PX4_ERR(
"failed disabling RC handling");
860 if (prev_val != sys_restart_val) {
861 param_set(sys_restart_param, &sys_restart_val);
875 PX4_INFO(
"default PWM output device");
880 _task = px4_task_spawn_cmd(
"px4io",
882 SCHED_PRIORITY_ACTUATOR_OUTPUTS,
888 PX4_ERR(
"task start failed: %d", errno);
915 PX4_ERR(
"actuator subscription failed");
925 fds[0].events = POLLIN;
949 int ret =
::poll(fds, 1, 20);
954 warnx(
"poll error %d", errno);
962 if (fds[0].revents & POLLIN) {
990 bool updated =
false;
1006 orb_check_last = now;
1014 if (((
unsigned int)cmd.command == vehicle_command_s::VEHICLE_CMD_START_RX_PAIR) && ((
int)cmd.param1 == 0)) {
1039 int32_t failsafe_param_val;
1044 param_get(failsafe_param, &failsafe_param_val);
1046 if (failsafe_param_val > 0) {
1048 uint16_t failsafe_thr = failsafe_param_val;
1098 int16_t pwm_invert_mask = 0;
1105 sprintf(pname,
"PWM_MAIN_REV%u", i + 1);
1110 pwm_invert_mask |= ((int16_t)(ival != 0)) << i;
1127 sprintf(pname,
"PWM_MAIN_TRIM%u", i + 1);
1133 pwm_values.
values[i] = (int16_t)(10000 * pval);
1192 if (sbus_mode == 1) {
1196 }
else if (sbus_mode == 2) {
1227 int32_t param_val_int;
1241 PX4_DEBUG(
"exiting");
1272 bool changed =
false;
1303 memset(&controls, 0,
sizeof(controls));
1306 controls.control[3] = 1.0f;
1315 if (!isfinite(ctrl)) {
1316 regs[i] = INT16_MAX;
1345 bool in_test_mode = test_motor.
action == test_motor_s::ACTION_RUN;
1362 if (test_motor.
value < 0.f) {
1376 uint16_t value = math::constrain<uint16_t>(pwm_min.
values[idx] +
1502 unsigned offset = 0;
1515 input_map[i] = UINT8_MAX;
1527 if ((ichan > 0) && (ichan <= (
int)_max_rc_input)) {
1528 input_map[ichan - 1] = 0;
1534 if ((ichan > 0) && (ichan <= (
int)_max_rc_input)) {
1535 input_map[ichan - 1] = 1;
1541 if ((ichan > 0) && (ichan <= (
int)_max_rc_input)) {
1542 input_map[ichan - 1] = 2;
1548 if ((ichan > 0) && (ichan <= (
int)_max_rc_input)) {
1549 input_map[ichan - 1] = 3;
1555 if ((ichan > 0) && (ichan <= (
int)_max_rc_input)) {
1556 input_map[ichan - 1] = 4;
1562 if ((ichan > 0) && (ichan <= (
int)_max_rc_input)) {
1563 input_map[ichan - 1] = 5;
1569 if ((ichan > 0) && (ichan <= (
int)_max_rc_input)) {
1570 input_map[ichan - 1] = 6;
1576 if ((ichan > 0) && (ichan <= (
int)_max_rc_input)) {
1577 input_map[ichan - 1] = 7;
1583 if ((ichan > 0) && (ichan <= (
int)_max_rc_input)) {
1605 sprintf(pname,
"RC%u_MIN", i + 1);
1609 sprintf(pname,
"RC%u_TRIM", i + 1);
1613 sprintf(pname,
"RC%u_MAX", i + 1);
1617 sprintf(pname,
"RC%u_DZ", i + 1);
1624 sprintf(pname,
"RC%u_REV", i + 1);
1640 PX4_ERR(
"rc config upload failed");
1669 PX4IO_P_STATUS_FLAGS_SAFETY_OFF | PX4IO_P_STATUS_FLAGS_ARM_SYNC);
1675 }
else if (!(
_status & PX4IO_P_STATUS_FLAGS_ARM_SYNC)) {
1743 servorail_status.voltage_v = vservo * 0.001f;
1744 servorail_status.rssi_v = vrssi * 0.001f;
1791 input_rc.
input_source = input_rc_s::RC_INPUT_SOURCE_UNKNOWN;
1794 uint16_t regs[input_rc_s::RC_INPUT_MAX_CHANNELS + prolog];
1814 if (channel_count > input_rc_s::RC_INPUT_MAX_CHANNELS) {
1815 channel_count = input_rc_s::RC_INPUT_MAX_CHANNELS;
1830 if (rssi_analog > 100.0
f) {
1831 rssi_analog = 100.0f;
1834 if (rssi_analog < 0.0
f) {
1838 input_rc.
rssi = rssi_analog;
1857 if (channel_count > 9) {
1867 input_rc.
values[i] = regs[prolog + i];
1871 for (
unsigned i = channel_count; i < (
sizeof(input_rc.
values) /
sizeof(input_rc.
values[0])); i++) {
1879 rssi = rssi > 100 ? 100 : rssi;
1880 rssi = rssi < 0 ? 0 : rssi;
1881 input_rc.
rssi = rssi;
1905 rc_val.
input_source = input_rc_s::RC_INPUT_SOURCE_PX4IO_PPM;
1908 rc_val.
input_source = input_rc_s::RC_INPUT_SOURCE_PX4IO_SPEKTRUM;
1911 rc_val.
input_source = input_rc_s::RC_INPUT_SOURCE_PX4IO_SBUS;
1914 rc_val.
input_source = input_rc_s::RC_INPUT_SOURCE_PX4IO_ST24;
1917 rc_val.
input_source = input_rc_s::RC_INPUT_SOURCE_UNKNOWN;
1952 outputs.
output[i] = ctl[i];
1969 motor_limits.saturation_status = saturation_status.
value;
1982 PX4_DEBUG(
"io_reg_set: too many registers (%u, max %u)", num_values,
_max_transfer / 2);
1986 int ret =
_interface->
write((page << 8) | offset, (
void *)values, num_values);
1988 if (ret != (
int)num_values) {
1989 PX4_DEBUG(
"io_reg_set(%hhu,%hhu,%u): error %d", page, offset, num_values, ret);
2007 PX4_DEBUG(
"io_reg_get: too many registers (%u, max %u)", num_values,
_max_transfer / 2);
2011 int ret =
_interface->
read((page << 8) | offset, reinterpret_cast<void *>(values), num_values);
2013 if (ret != (
int)num_values) {
2014 PX4_DEBUG(
"io_reg_get(%hhu,%hhu,%u): data error %d", page, offset, num_values, ret);
2045 value &= ~clearbits;
2054 #ifdef CONFIG_ARCH_BOARD_PX4_FMU_V2 2058 io_fd =
::open(
"/dev/ttyS0", O_RDONLY | O_NONBLOCK | O_NOCTTY);
2065 fds[0].events = POLLIN;
2068 int pret =
::poll(fds,
sizeof(fds) /
sizeof(fds[0]), 0);
2075 count =
::read(io_fd, buf,
sizeof(buf) - 1);
2080 warnx(
"IO CONSOLE: %s", buf);
2083 }
while (count > 0);
2112 unsigned count = buflen;
2114 if (count > max_len) {
2119 memcpy(&msg->
text[0], buf, count);
2136 if (total_len % 2) {
2137 msg->
text[count] =
'\0';
2143 for (
int i = 0; i < 30; i++) {
2156 if (debuglevel > 5 || ret) {
2165 PX4_ERR(
"mixer send error %d", ret);
2171 }
while (buflen > 0);
2176 msg->
text[0] =
'\n';
2177 msg->
text[1] =
'\0';
2179 for (
int i = 0; i < 30; i++) {
2198 }
while (retries > 0);
2215 printf(
"protocol %u hardware %u bootloader %u buffer %uB crc 0x%04x%04x\n",
2222 printf(
"%u controls %u actuators %u R/C inputs %u analog inputs %u relays\n",
2230 printf(
"%u bytes free\n",
2233 uint16_t io_status_flags = flags;
2234 printf(
"status 0x%04hx%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
2251 printf(
"alarms 0x%04hx%s%s%s%s%s%s%s%s\n",
2265 printf(
"vservo %u mV vservo scale %u\n",
2271 printf(
"actuators");
2287 printf(
"reversed outputs: [");
2290 printf(
"%s", (pwm_invert_mask & (1 << i)) ?
"x" :
"_");
2299 printf(
" trims: r: %8.4f p: %8.4f y: %8.4f\n",
2300 (
double)trim_roll, (
double)trim_pitch, (
double)trim_yaw);
2303 printf(
"%hu raw R/C inputs", raw_inputs);
2305 for (
unsigned i = 0; i < raw_inputs; i++) {
2312 printf(
"R/C flags: 0x%04hx%s%s%s%s%s\n", flags,
2314 (((io_status_flags & PX4IO_P_STATUS_FLAGS_RC_DSM) && (flags & PX4IO_P_RAW_RC_FLAGS_RC_DSM11)) ?
" DSM11" :
""),
2320 if ((io_status_flags & PX4IO_P_STATUS_FLAGS_RC_PPM)) {
2322 printf(
"RC data (PPM frame len) %d us\n", frame_len);
2324 if ((frame_len - raw_inputs * 2000 - 3000) < 0) {
2325 printf(
"WARNING WARNING WARNING! This RC receiver does not allow safe frame detection.\n");
2330 printf(
"mapped R/C inputs 0x%04hx", mapped_inputs);
2333 if (mapped_inputs & (1 << i)) {
2340 printf(
"ADC inputs");
2342 for (
unsigned i = 0; i < adc_inputs; i++) {
2350 printf(
"features 0x%04hx%s%s%s%s\n", features,
2357 printf(
"arming 0x%04hx%s%s%s%s%s%s%s%s%s%s\n",
2371 printf(
"rates 0x%04x default %u alt %u sbus %u\n",
2378 for (
unsigned group = 0; group < 4; group++) {
2379 printf(
"controls %u:", group);
2388 if (extended_status) {
2392 printf(
"input %u min %u center %u max %u deadzone %u assigned %u options 0x%04hx%s%s\n",
2411 printf(
"\ndisarmed values");
2420 if (heater_level != UINT16_MAX) {
2422 printf(
"\nIMU heater off");
2425 printf(
"\nIMU heater level %d", heater_level);
2430 printf(
"\nHITL Mode");
2439 SmartLock lock_guard(
_lock);
2818 const char *buf = (
const char *)arg;
2842 uint32_t io_crc = 0;
2849 if (io_crc != arg) {
2850 PX4_DEBUG(
"crc mismatch 0x%08x 0x%08lx", io_crc, arg);
2896 }
else if (arg == 2) {
2908 ret = CDev::ioctl(filep, cmd, arg);
2919 unsigned count = len / 2;
2949 unsigned interval_ms = 1000 / rate;
2966 #ifdef PX4IO_SERIAL_BASE 2970 if (interface !=
nullptr) {
2974 errx(1,
"cannot alloc interface");
2978 if (interface->init() !=
OK) {
2980 errx(1,
"interface init failed");
2987 start(
int argc,
char *argv[])
2989 if (
g_dev !=
nullptr) {
2990 errx(0,
"already loaded");
2997 (void)
new PX4IO(interface);
2999 if (
g_dev ==
nullptr) {
3001 errx(1,
"driver allocation failed");
3004 bool rc_handling_disabled =
false;
3005 bool hitl_mode =
false;
3008 for (
int extra_args = 1; extra_args < argc; extra_args++) {
3009 if (!strcmp(argv[extra_args],
"norc")) {
3010 rc_handling_disabled =
true;
3012 }
else if (!strcmp(argv[extra_args],
"hil")) {
3016 warnx(
"unknown argument: %s", argv[1]);
3020 if (
OK !=
g_dev->
init(rc_handling_disabled, hitl_mode)) {
3023 errx(1,
"driver init failed");
3030 detect(
int argc,
char *argv[])
3032 if (
g_dev !=
nullptr) {
3033 errx(0,
"already loaded");
3040 (void)
new PX4IO(interface);
3042 if (
g_dev ==
nullptr) {
3043 errx(1,
"driver allocation failed");
3046 int ret =
g_dev->detect();
3061 checkcrc(
int argc,
char *argv[])
3063 bool keep_running =
false;
3065 if (
g_dev ==
nullptr) {
3070 (void)
new PX4IO(interface);
3072 if (
g_dev ==
nullptr) {
3073 errx(1,
"driver allocation failed");
3078 keep_running =
true;
3085 warnx(
"usage: px4io checkcrc filename");
3089 int fd =
open(argv[1], O_RDONLY);
3092 warnx(
"open of %s failed: %d", argv[1], errno);
3096 const uint32_t app_size_max = 0xf000;
3097 uint32_t fw_crc = 0;
3098 uint32_t nbytes = 0;
3102 int n =
read(fd, buf,
sizeof(buf));
3104 if (n <= 0) {
break; }
3106 fw_crc = crc32part(buf, n, fw_crc);
3112 while (nbytes < app_size_max) {
3114 fw_crc = crc32part(&b, 1, fw_crc);
3120 if (!keep_running) {
3126 warn(
"check CRC failed: %d", ret);
3134 bind(
int argc,
char *argv[])
3138 if (
g_dev ==
nullptr) {
3139 errx(1,
"px4io must be started first");
3143 errx(0,
"needs argument, use dsm2, dsmx or dsmx8");
3146 if (!strcmp(argv[2],
"dsm2")) {
3149 }
else if (!strcmp(argv[2],
"dsmx")) {
3152 }
else if (!strcmp(argv[2],
"dsmx8")) {
3156 errx(1,
"unknown parameter %s, use dsm2, dsmx or dsmx8", argv[2]);
3161 pulses = atoi(argv[3]);
3165 errx(1,
"system must not be armed");
3178 unsigned servo_count = 0;
3179 unsigned pwm_value = 1000;
3186 err(1,
"failed to open device");
3190 err(1,
"failed to get servo count");
3197 err(1,
"PWM_SERVO_SET_ARM_OK");
3201 err(1,
"failed to arm servos");
3208 fds.events = POLLIN;
3210 warnx(
"Press CTRL-C or 'c' to abort.");
3217 for (
unsigned i = 0; i < servo_count; i++) {
3218 servos[i] = pwm_value;
3221 ret =
write(fd, servos,
sizeof(servos));
3223 if (ret != (
int)
sizeof(servos)) {
3224 err(1,
"error writing PWM servo data, wrote %zu got %d",
sizeof(servos), ret);
3227 if (direction > 0) {
3228 if (pwm_value < 2000) {
3236 if (pwm_value > 1000) {
3247 for (
unsigned i = 0; i < servo_count; i++) {
3251 err(1,
"error reading PWM servo %u", i);
3254 if (value != servos[i]) {
3255 warnx(
"servo %u readback error, got %hu expected %hu", i, value, servos[i]);
3261 ret =
poll(&fds, 1, 0);
3267 if (c == 0x03 || c == 0x63 || c ==
'q') {
3268 warnx(
"User abort\n");
3281 unsigned cancels = 2;
3287 fds[0].events = POLLIN;
3289 if (
poll(fds, 1, 2000) < 0) {
3290 errx(1,
"poll fail");
3293 if (fds[0].revents == POLLIN) {
3296 (void)
read(0, &c, 1);
3298 if (cancels-- == 0) {
3299 printf(
"\033[2J\033[H");
3304 if (
g_dev !=
nullptr) {
3306 printf(
"\033[2J\033[H");
3307 (void)
g_dev->print_status(
false);
3308 (void)
g_dev->print_debug();
3309 printf(
"\n\n\n[ Use 'px4io debug <N>' for more output. Hit <enter> three times to exit monitor mode ]\n");
3312 errx(1,
"driver not loaded, exiting");
3318 if_test(
unsigned mode)
3324 result = interface->
ioctl(1, mode);
3328 errx(1,
"interface not loaded, exiting");
3331 errx(0,
"test returned %d", result);
3335 lockdown(
int argc,
char *argv[])
3337 if (
g_dev !=
nullptr) {
3339 if (argc > 2 && !strcmp(argv[2],
"disable")) {
3341 warnx(
"WARNING: ACTUATORS WILL BE LIVE IN HIL! PROCEED?");
3342 warnx(
"Press 'y' to enable, any other key to abort.");
3350 const unsigned long timeout = 5000000;
3354 fds.events = POLLIN;
3355 ret =
poll(&fds, 1, 0);
3359 if (
read(0, &c, 1) > 0) {
3364 }
else if (c ==
'y') {
3374 errx(1,
"TIMEOUT! ABORTED WITHOUT CHANGES.");
3379 warnx(
"WARNING: ACTUATORS ARE NOW LIVE IN HIL!");
3383 warnx(
"ACTUATORS ARE NOW SAFE IN HIL.");
3387 errx(1,
"driver not loaded, exiting");
3403 if (!PX4_MFT_HW_SUPPORTED(PX4_MFT_PX4IO)) {
3404 errx(1,
"PX4IO Not Supported");
3407 if (!strcmp(argv[1],
"start")) {
3408 start(argc - 1, argv + 1);
3411 if (!strcmp(argv[1],
"detect")) {
3412 detect(argc - 1, argv + 1);
3415 if (!strcmp(argv[1],
"checkcrc")) {
3416 checkcrc(argc - 1, argv + 1);
3419 if (!strcmp(argv[1],
"update")) {
3421 if (
g_dev !=
nullptr) {
3422 warnx(
"loaded, detaching first");
3432 const char *
fn[4] = PX4IO_FW_SEARCH_PATHS;
3441 int ret = up->
upload(&fn[0]);
3449 errx(1,
"PX4IO firmware file not found");
3453 errx(1,
"error updating PX4IO - check that bootloader mode is enabled");
3456 errx(1,
"verify failed - retry the update");
3459 errx(1,
"timed out waiting for bootloader - power-cycle and try again");
3462 errx(1,
"unexpected error %d", ret);
3468 if (!strcmp(argv[1],
"iftest")) {
3469 if (
g_dev !=
nullptr) {
3470 errx(1,
"can't iftest when started");
3473 if_test((argc > 2) ? strtol(argv[2], NULL, 0) : 0);
3476 if (!strcmp(argv[1],
"forceupdate")) {
3482 warnx(
"usage: px4io forceupdate MAGIC filename");
3486 if (
g_dev ==
nullptr) {
3487 warnx(
"px4io is not started, still attempting upgrade");
3493 (void)
new PX4IO(interface);
3495 if (
g_dev ==
nullptr) {
3497 errx(1,
"driver allocation failed");
3501 uint16_t arg = atol(argv[2]);
3505 warnx(
"reboot failed - %d", ret);
3525 if (
g_dev ==
nullptr) {
3526 errx(1,
"not started");
3529 if (!strcmp(argv[1],
"limit")) {
3532 int limitrate = atoi(argv[2]);
3534 if (limitrate > 0) {
3535 g_dev->set_update_rate(limitrate);
3538 errx(1,
"invalid rate: %d", limitrate);
3542 errx(1,
"missing argument (50 - 500 Hz)");
3549 if (!strcmp(argv[1],
"safety_off")) {
3553 warnx(
"failed to disable safety");
3560 if (!strcmp(argv[1],
"safety_on")) {
3564 warnx(
"failed to enable safety");
3571 if (!strcmp(argv[1],
"recovery")) {
3582 if (!strcmp(argv[1],
"stop")) {
3591 if (!strcmp(argv[1],
"status")) {
3594 g_dev->print_status(
true);
3599 if (!strcmp(argv[1],
"debug")) {
3601 warnx(
"usage: px4io debug LEVEL");
3605 if (
g_dev ==
nullptr) {
3606 warnx(
"not started");
3610 uint8_t level = atoi(argv[2]);
3617 warnx(
"SET_DEBUG failed: %d", ret);
3621 warnx(
"SET_DEBUG %hhu OK", level);
3625 if (!strcmp(argv[1],
"rx_dsm") ||
3626 !strcmp(argv[1],
"rx_dsm_10bit") ||
3627 !strcmp(argv[1],
"rx_dsm_11bit") ||
3628 !strcmp(argv[1],
"rx_sbus") ||
3629 !strcmp(argv[1],
"rx_ppm")) {
3630 errx(0,
"receiver type is automatically detected, option '%s' is deprecated", argv[1]);
3633 if (!strcmp(argv[1],
"test")) {
3637 if (!strcmp(argv[1],
"monitor")) {
3641 if (!strcmp(argv[1],
"bind")) {
3645 if (!strcmp(argv[1],
"lockdown")) {
3646 lockdown(argc, argv);
3649 if (!strcmp(argv[1],
"sbus1_out")) {
3656 errx(ret,
"S.BUS v1 failed");
3662 if (!strcmp(argv[1],
"sbus2_out")) {
3669 errx(ret,
"S.BUS v2 failed");
3675 if (!strcmp(argv[1],
"rssi_analog")) {
3682 errx(ret,
"RSSI analog failed");
3688 if (!strcmp(argv[1],
"rssi_pwm")) {
3695 errx(ret,
"RSSI PWM failed");
3701 if (!strcmp(argv[1],
"test_fmu_fail")) {
3702 if (
g_dev !=
nullptr) {
3703 g_dev->test_fmu_fail(
true);
3708 errx(1,
"px4io must be started first");
3712 if (!strcmp(argv[1],
"test_fmu_ok")) {
3713 if (
g_dev !=
nullptr) {
3714 g_dev->test_fmu_fail(
false);
3719 errx(1,
"px4io must be started first");
3724 errx(1,
"need a command, try 'start', 'stop', 'status', 'test', 'monitor', 'debug <level>',\n" 3725 "'recovery', 'limit <rate>', 'bind', 'checkcrc', 'safety_on', 'safety_off',\n" 3726 "'forceupdate', 'update', 'sbus1_out', 'sbus2_out', 'rssi_analog' or 'rssi_pwm',\n" 3727 "'test_fmu_fail', 'test_fmu_ok'");
volatile bool _task_should_exit
#define PX4IO_P_STATUS_VSERVO
#define mavlink_log_info(_pub, _text,...)
Send a mavlink info message (not printed to console).
#define PX4IO_PAGE_RAW_RC_INPUT
#define PARAM_INVALID
Handle returned when a parameter cannot be found.
constexpr _Tp constrain(_Tp val, _Tp min_val, _Tp max_val)
#define PX4IO_PAGE_DISARMED_PWM
#define PX4IO_P_SETUP_ARMING_ALWAYS_PWM_ENABLE
void io_handle_vservo(uint16_t vservo, uint16_t vrssi)
Handle a servorail update from IO.
#define PX4IO_P_SETUP_TRIM_PITCH
Pitch trim, in actuator units.
#define PX4IO_P_STATUS_FLAGS_FMU_OK
#define PWM_SERVO_GET_SELECT_UPDATE_RATE
check the selected update rates
#define mavlink_log_critical(_pub, _text,...)
Send a mavlink critical message and print to console.
#define PX4IO_P_CONFIG_CONTROL_COUNT
int orb_copy(const struct orb_metadata *meta, int handle, void *buffer)
#define PX4IO_PAGE_ACTUATORS
#define MIXERIOCLOADBUF
Add mixer(s) from the buffer in (const char *)arg.
#define PX4IO_P_CONFIG_ADC_INPUT_COUNT
int32_t _rssi_pwm_chan
RSSI PWM input channel.
#define PWM_SERVO_SET_ARM_OK
set the 'ARM ok' bit, which activates the safety switch
virtual int init()
Initialize the PX4IO class.
#define FLOAT_TO_REG(_float)
void print_status(bool extended_status)
Print IO status.
#define PX4IO_P_SETUP_FORCE_SAFETY_OFF
#define PX4IO_P_RC_CONFIG_OPTIONS_REVERSE
unsigned _update_interval
Subscription interval limiting send rate.
uORB::Subscription _parameter_update_sub
parameter update topic
unsigned _hardware
Hardware revision.
static struct vehicle_status_s status
uORB::PublicationMulti< multirotor_motor_limits_s > _to_mixer_status
RC protocol definition for Spektrum RC.
int32_t _thermal_control
thermal control state
virtual int open(file_t *filep)
Handle an open of the device.
int io_set_rc_config()
Push RC channel configuration to IO.
int io_publish_raw_rc()
Fetch and publish raw RC input data.
uint16_t servo_position_t
Servo output signal type, value is actual servo output pulse width in microseconds.
Futaba S.BUS / S.BUS 2 compatible interface.
#define SIGNED_TO_REG(_signed)
#define F2I_MIXER_ACTION_APPEND
measure the time elapsed performing an event
#define PX4IO_P_SETUP_SET_DEBUG
px4_sem_t _lock
lock to protect access to all class members (also for derived classes)
#define DSM_BIND_START
start DSM bind
#define PWM_SERVO_SET_FORCE_SAFETY_ON
force safety switch on (to enable use of safety switch)
#define PX4IO_P_SETUP_PWM_DEFAULTRATE
uORB::Publication< safety_s > _to_safety
unsigned _max_actuators
Maximum # of actuators supported by PX4IO.
#define PX4IO_P_RAW_FRAME_COUNT
perf_counter_t _perf_write
local performance counter for PWM control writes
#define PX4IO_PAGE_RC_INPUT
__EXPORT int param_get(param_t param, void *val)
Copy the value of a parameter.
#define PWM_SERVO_GET_COUNT
get the number of servos in *(unsigned *)arg
#define PX4IO_P_SETUP_SCALE_PITCH
Pitch scale, in actuator units.
#define PX4IO_P_SETUP_PWM_REVERSE
Bitmask to reverse PWM channels 1-8.
#define PWM_SERVO_ARM
arm all servo outputs handle by this driver
#define PWM_SERVO_SET_OVERRIDE_IMMEDIATE
setup OVERRIDE_IMMEDIATE behaviour on FMU fail
#define PX4IO_PAGE_FAILSAFE_PWM
0..CONFIG_ACTUATOR_COUNT-1
#define PX4IO_P_SETUP_SBUS_RATE
frame rate of SBUS1 output in Hz
#define PX4IO_P_CONFIG_RC_INPUT_COUNT
volatile int _task
worker task id
void handle_motor_test()
check and handle test_motor topic updates
float _analog_rc_rssi_volt
analog RSSI voltage
#define PX4IO_THERMAL_IGNORE
orb_advert_t _mavlink_log_pub
mavlink log pub
#define PX4IO_P_STATUS_FLAGS_RC_SBUS
#define PX4IO_PROTOCOL_MAX_CONTROL_COUNT
The protocol does not support more than set here, individual units might support less - see PX4IO_P_C...
__EXPORT int param_set_no_notification(param_t param, const void *val)
Set the value of a parameter, but do not notify the system about the change.
#define PX4IO_P_RAW_RC_BASE
int _t_actuator_controls_0
actuator controls group 0 topic
#define CBRK_IO_SAFETY_KEY
int io_reg_set(uint8_t page, uint8_t offset, const uint16_t *values, unsigned num_values)
write register(s)
bool circuit_breaker_enabled(const char *breaker, int32_t magic)
#define PX4IO_P_CONFIG_RELAY_COUNT
void lock()
Take the driver lock.
static constexpr unsigned UPDATE_INTERVAL_MIN
#define PX4IO_P_SETUP_ARMING_MANUAL_OVERRIDE_OK
int orb_set_interval(int handle, unsigned interval)
__EXPORT int param_set(param_t param, const void *val)
Set the value of a parameter.
#define PX4IO_P_SETUP_FORCE_SAFETY_ON
#define PX4IO_INAIR_RESTART_ENABLE
static void task_main_trampoline(int argc, char *argv[])
int io_reg_modify(uint8_t page, uint8_t offset, uint16_t clearbits, uint16_t setbits)
modify a register
#define PX4IO_PAGE_MIXERLOAD
#define PX4IO_P_SETUP_PWM_ALTRATE
int io_publish_pwm_outputs()
Fetch and publish the PWM servo outputs.
void perf_set_elapsed(perf_counter_t handle, int64_t elapsed)
Register a measurement.
#define PWM_SERVO_GET_UPDATE_RATE
get alternate servo update rate
#define PWM_SERVO_GET_DISARMED_PWM
get the PWM value when disarmed
#define PX4IO_P_STATUS_ALARMS_SERVO_CURRENT
#define PX4IO_P_SETUP_CRC
#define PWM_SERVO_CLEAR_ARM_OK
clear the 'ARM ok' bit, which deactivates the safety switch
bool flag_external_manual_override_ok
perf_counter_t _perf_sample_latency
total system latency (based on passed-through timestamp)
uORB::Subscription _t_actuator_controls_1
actuator controls group 1 topic
#define PX4IO_P_SETUP_ARMING_INAIR_RESTART_OK
#define PX4IO_P_STATUS_ALARMS_RC_LOST
#define PWM_SERVO_SET_SBUS_RATE
set SBUS output frame rate in Hz
#define PX4IO_P_STATUS_ALARMS_PWM_ERROR
bool safety_switch_available
#define PWM_SERVO_SET_SELECT_UPDATE_RATE
selects servo update rates, one bit per servo.
bool _analog_rc_rssi_stable
true when analog RSSI input is stable
static const px4_file_operations_t fops
Pointer to the default cdev file operations table; useful for registering clone devices etc...
PX4IO interface protocol.
virtual ssize_t read(file_t *filep, char *buffer, size_t buflen)
Perform a read from the device.
unsigned _max_controls
Maximum # of controls supported by PX4IO.
#define PX4IO_P_SETUP_TRIM_YAW
Yaw trim, in actuator units.
High-resolution timer with callouts and timekeeping.
#define PX4IO_P_STATUS_MIXER
#define mavlink_and_console_log_info(_pub, _text,...)
Send a mavlink emergency message and print to console.
As-needed mixer data upload.
virtual int close(file_t *filep)
Handle a close of the device.
int io_handle_status(uint16_t status)
Handle a status update from IO.
Global flash based parameter store.
int io_set_control_state(unsigned group)
Send controls for one group to IO.
#define PX4IO_P_STATUS_FLAGS
#define PX4IO_P_STATUS_ALARMS_TEMPERATURE
#define PWM_SERVO_SET(_servo)
set a single servo to a specific value
#define PX4IO_P_RC_CONFIG_MAX
highest input value
static char msg[NUM_MSG][CONFIG_USART1_TXBUFSIZE]
#define PX4IO_P_SETUP_ARMING_FAILSAFE_CUSTOM
__EXPORT int px4io_main(int argc, char *argv[])
PX4IO(device::Device *interface)
Constructor.
int orb_subscribe(const struct orb_metadata *meta)
#define REG_TO_FLOAT(_reg)
static struct safety_s safety
#define PX4IO_P_STATUS_ALARMS_FMU_LOST
int print_debug()
Fetch and print debug console output.
#define PX4IO_P_SETUP_PWM_RATES
#define PX4IO_PAGE_CONTROL_MAX_PWM
0..CONFIG_ACTUATOR_COUNT-1
#define ORB_CHECK_INTERVAL
int io_get_status()
Fetch status and alarms from IO.
#define PX4IO_P_RAW_LOST_FRAME_COUNT
#define PX4IO_P_CONFIG_MAX_TRANSFER
bool in_esc_calibration_mode
#define ORB_ID(_name)
Generates a pointer to the uORB metadata structure for a given topic.
uORB::PublicationMulti< actuator_outputs_s > _to_outputs
#define PX4IO_P_SETUP_ENABLE_FLIGHTTERMINATION
flight termination; false if the circuit breaker (CBRK_FLIGHTTERM) is set
#define PWM_SERVO_GET_DEFAULT_UPDATE_RATE
get default servo update rate
virtual int ioctl(file *filp, int cmd, unsigned long arg)
IO Control handler.
#define PX4IO_P_SETUP_REBOOT_BL
int mixer_send(const char *buf, unsigned buflen, unsigned retries=3)
Send mixer definition text to IO.
#define PWM_OUTPUT0_DEVICE_PATH
#define F2I_MIXER_ACTION_RESET
int io_set_control_groups()
Send all controls to IO.
int io_disable_rc_handling()
Disable RC input handling.
bool publish(const T &data)
Publish the struct.
#define PWM_SERVO_SET_FAILSAFE_PWM
set the PWM value for failsafe
Abstract class for any character device.
uint16_t values[PWM_OUTPUT_MAX_CHANNELS]
#define PX4IO_P_RAW_RC_FLAGS
void perf_free(perf_counter_t handle)
Free a counter.
virtual int ioctl(device::file_t *filp, int cmd, unsigned long arg)
volatile bool _task_should_exit
worker terminate flag
void init()
Activates/configures the hardware registers.
#define PX4IO_P_SETUP_THR_MDL_FAC
factor for modelling motor control signal output to static thrust relationship
#define PX4IO_THERMAL_OFF
uORB::Subscription test_motor_sub
#define PX4IO_PAGE_CONTROL_MIN_PWM
0..CONFIG_ACTUATOR_COUNT-1
#define PX4IO_P_SETUP_DSM
#define PWM_SERVO_SET_DISARMED_PWM
set the PWM value when disarmed - should be no PWM (zero) by default
#define PX4IO_P_SETUP_FEATURES
#define DSMX8_BIND_PULSES
#define PX4IO_P_SETUP_ARMING_RC_HANDLING_DISABLED
#define PWM_SERVO_SET_TERMINATION_FAILSAFE
make failsafe non-recoverable (termination) if it occurs
bool _primary_pwm_device
true if we are the default PWM output
Firmware uploader definitions for PX4IO.
void test_fmu_fail(bool is_fail)
#define PX4IO_PAGE_SERVOS
#define PX4IO_P_RAW_RC_COUNT
device::Device * _interface
#define PWM_SERVO_SET_TRIM_PWM
set the TRIM value the output will send
#define PWM_SERVO_ENTER_TEST_MODE
#define PX4IO_P_SETUP_ARMING_IO_ARM_OK
#define PX4IO_P_STATUS_VRSSI
static struct actuator_armed_s armed
int io_set_arming_state()
Update IO's arming-related state.
#define PX4IO_P_STATUS_FLAGS_MIXER_OK
Vector< float, 6 > f(float t, const Matrix< float, 6, 1 > &, const Matrix< float, 3, 1 > &)
perf_counter_t _perf_update
local performance counter for status updates
static hrt_abstime hrt_elapsed_time(const hrt_abstime *then)
Compute the delta between a timestamp taken in the past and now.
bool _param_update_force
force a parameter update
uORB::Subscription _t_actuator_armed
actuator controls group 3 topic
#define PWM_SERVO_GET_TRIM_PWM
get the TRIM value the output will send
#define PX4IO_P_CONFIG_PROTOCOL_VERSION
#define PWM_OUTPUT_MAX_CHANNELS
#define PX4IO_P_STATUS_FLAGS_ARM_SYNC
#define PX4IO_P_SETUP_MOTOR_SLEW_MAX
max motor slew rate
Simple error/warning functions, heavily inspired by the BSD functions of the same names...
#define PX4IO_P_SETUP_VSERVO_SCALE
#define PWM_SERVO_SET_FORCE_SAFETY_OFF
force safety switch off (to disable use of safety switch)
#define PX4IO_P_RC_CONFIG_DEADZONE
band around center that is ignored
void task_main(int argc, char *argv[])
bool _hitl_mode
Hardware-in-the-loop simulation mode - don't publish actuator_outputs.
uint16_t system_status() const
int32_t _rssi_pwm_min
min RSSI input on PWM channel
void perf_end(perf_counter_t handle)
End a performance event.
#define PX4IO_PAGE_PWM_INFO
virtual ~PX4IO()
Destructor.
int io_get_raw_rc_input(input_rc_s &input_rc)
Fetch RC inputs from IO.
static void task_main_trampoline(int argc, char *argv[])
Trampoline to the worker task.
void test(enum LPS25H_BUS busid)
Perform some basic functional tests on the driver; make sure we can collect data from the sensor in p...
#define PX4IO_P_RC_CONFIG_ASSIGNMENT_MODESWITCH
magic value for mode switch
#define PX4IO_P_CONFIG_ACTUATOR_COUNT
int(* fn)(int argc, char *argv[])
bool updated()
Check if there is a new update.
#define PX4IO_PAGE_RC_CONFIG
R/C input configuration.
int disable_rc_handling()
Disable RC input handling.
#define PX4IO_P_STATUS_FLAGS_OVERRIDE
#define PWM_SERVO_GET_RATEGROUP(_n)
get the _n'th rate group's channels; *(uint32_t *)arg returns a bitmap of channels whose update rates...
uORB::Publication< servorail_status_s > _to_servorail
__BEGIN_DECLS typedef uint64_t hrt_abstime
Absolute time, in microsecond units.
unsigned _max_rc_input
Maximum receiver channels supported by PX4IO.
virtual int write(unsigned address, void *data, unsigned count)
Write directly to the device.
uORB::PublicationMulti< input_rc_s > _to_input_rc
#define PX4IO_P_STATUS_FREEMEM
#define PX4IO_P_RAW_RC_FLAGS_FRAME_DROP
#define PWM_SERVO_GET(_servo)
get a single specific servo value
__BEGIN_DECLS typedef void * orb_advert_t
ORB topic advertiser handle.
int io_handle_alarms(uint16_t alarms)
Handle an alarm update from IO.
unsigned _rc_chan_count
Internal copy of the last seen number of RC channels.
#define PX4IO_P_STATUS_FLAGS_SAFETY_OFF
#define PX4IO_FORCE_SAFETY_MAGIC
#define PX4IO_P_RAW_RC_FLAGS_RC_DSM11
#define PWM_SERVO_SET_MIN_PWM
set the minimum PWM value the output will send
virtual int ioctl(unsigned operation, unsigned &arg)
Perform a device-specific operation.
#define PX4IO_P_RAW_RC_FLAGS_RC_OK
#define PX4IO_P_SETUP_TRIM_ROLL
Roll trim, in actuator units.
#define PX4IO_P_STATUS_ALARMS
#define PX4IO_PAGE_STATUS
__EXPORT param_t param_find(const char *name)
Look up a parameter by name.
#define MIXERIOCRESET
reset (clear) the mixer configuration
#define PX4IO_P_RC_CONFIG_ASSIGNMENT
mapped input value
#define PX4IO_P_STATUS_ALARMS_VSERVO_FAULT
bool _override_available
true if manual reversion mode is enabled
#define PX4IO_P_RC_CONFIG_STRIDE
spacing between channel config data
#define PX4IO_PAGE_CONTROL_TRIM_PWM
0..CONFIG_ACTUATOR_COUNT-1
#define PX4IO_PAGE_DIRECT_PWM
0..CONFIG_ACTUATOR_COUNT-1
#define PX4IO_P_RC_CONFIG_CENTER
center input value
#define DSM_BIND_POWER_UP
power up DSM receiver
#define PWM_SERVO_SET_MAX_PWM
set the maximum PWM value the output will send
uint16_t _alarms
Various IO alarms.
#define PX4IO_REBOOT_BL_MAGIC
#define PX4IO_P_RC_CONFIG_OPTIONS_ENABLED
static void write(bootloader_app_shared_t *pshared)
#define PX4IO_P_STATUS_FLAGS_RAW_PWM
#define PWM_SERVO_SET_MODE
#define PX4IO_P_SETUP_THERMAL
thermal management
#define PWM_SERVO_SET_FORCE_FAILSAFE
force failsafe mode (failsafe values are set immediately even if failsafe condition not met) ...
#define PX4IO_P_STATUS_FLAGS_RC_OK
#define PX4IO_DEVICE_PATH
#define PX4IO_P_SETUP_ARMING_FMU_ARMED
virtual ssize_t write(file *filp, const char *buffer, size_t len)
write handler.
uint16_t _last_written_arming_c
the last written arming state reg
int upload(const char *filenames[])
#define PX4IO_P_STATUS_FLAGS_INIT_OK
unsigned _max_relays
Maximum relays supported by PX4IO.
#define PX4IO_P_STATUS_FLAGS_RC_ST24
#define PX4IO_PROTOCOL_VERSION
#define PX4IO_P_SETUP_ARMING_FORCE_FAILSAFE
#define PX4IO_P_SETUP_RC_THR_FAILSAFE_US
the throttle failsafe pulse length in microseconds
uORB::Subscription _t_actuator_controls_3
actuator controls group 2 topic
#define PWM_SERVO_GET_MIN_PWM
get the minimum PWM value the output will send
struct @83::@85::@87 file
int orb_check(int handle, bool *updated)
uORB::Subscription _t_vehicle_command
vehicle command topic
bool _armed
wether the system is armed
#define PX4IO_P_RAW_RC_FLAGS_MAPPING_OK
#define PX4IO_P_SETUP_ARMING
#define PX4IO_P_SETUP_FEATURES_PWM_RSSI
enable PWM RSSI parsing
bool _rc_handling_disabled
If set, IO does not evaluate, but only forward the RC values.
#define PWM_SERVO_GET_DISABLE_LOCKDOWN
get the lockdown override flag to enable outputs in HIL
int32_t _rssi_pwm_max
max RSSI input on PWM channel
#define PX4IO_PAGE_CONFIG
Fundamental base class for all physical drivers (I2C, SPI).
#define PX4IO_P_SETUP_FEATURES_ADC_RSSI
enable ADC RSSI parsing
#define mavlink_log_emergency(_pub, _text,...)
Send a mavlink emergency message and print to console.
uORB::Subscription _t_actuator_controls_2
#define PX4IO_P_STATUS_FLAGS_FAILSAFE
void dsm_bind_ioctl(int dsmMode)
Handle issuing dsm bind ioctl to px4io.
#define PX4IO_P_SETUP_SCALE_ROLL
Roll scale, in actuator units.
#define PX4IO_P_SETUP_SCALE_YAW
Yaw scale, in actuator units.
static constexpr unsigned UPDATE_INTERVAL_MAX
device::Device * PX4IO_serial_interface()
uint16_t _status
Various IO status flags.
#define PX4IO_P_SETUP_ARMING_FMU_PREARMED
bool _test_fmu_fail
To test what happens if IO loses FMU.
#define PX4IO_P_STATUS_FLAGS_OUTPUTS_ARMED
#define PX4IO_P_RAW_RC_NRSSI
#define PX4IO_P_SETUP_ARMING_OVERRIDE_IMMEDIATE
uORB::Subscription _t_vehicle_control_mode
vehicle control mode topic
#define PX4IO_P_STATUS_ALARMS_ACC_CURRENT
#define REG_TO_SIGNED(_reg)
#define PX4IO_PAGE_CONTROLS
actuator control groups, one after the other, 8 wide
#define PX4IO_P_SETUP_ARMING_LOCKDOWN
bool update(void *dst)
Update the struct.
unsigned _max_transfer
Maximum number of I2C transfers supported by PX4IO.
void task_main()
worker task
#define PX4IO_RATE_MAP_BASE
#define PWM_HIGHEST_MAX
Highest maximum PWM in us.
static const uint32_t _io_reg_get_error
virtual int detect()
Detect if a PX4IO is connected.
#define PX4IO_P_SETUP_FEATURES_SBUS2_OUT
enable S.Bus v2 output
#define CBRK_FLIGHTTERM_KEY
bool _in_esc_calibration_mode
do not send control outputs to IO (used for esc calibration)
#define PX4IO_P_RAW_RC_DATA
uint64_t _rc_last_valid
last valid timestamp
#define SBUS_SET_PROTO_VERSION
Enable S.BUS version 1 / 2 output (0 to disable)
bool publish(const T &data)
Publish the struct.
#define PX4IO_P_RC_CONFIG_MIN
lowest input value
#define PX4IO_P_STATUS_ALARMS_VBATT_LOW
void unlock()
Release the driver lock.
#define PX4IO_P_RC_CONFIG_OPTIONS
channel options bitmask
#define PWM_SERVO_GET_FAILSAFE_PWM
get the PWM value for failsafe
#define PX4IO_P_CONFIG_BOOTLOADER_VERSION
bool _lockdown_override
allow to override the safety lockdown
int io_reg_get(uint8_t page, uint8_t offset, uint16_t *values, unsigned num_values)
read register(s)
bool copy(void *dst)
Copy the struct.
#define PX4IO_P_SETUP_FEATURES_SBUS1_OUT
enable S.Bus v1 output
uint16_t _last_written_arming_s
the last written arming state reg
#define PX4IO_P_SETUP_AIRMODE
air-mode
void perf_begin(perf_counter_t handle)
Begin a performance event.
#define PX4IO_PAGE_RAW_ADC_INPUT
int set_update_rate(int rate)
Set the update rate for actuator outputs from FMU to IO.
#define PX4IO_P_CONFIG_HARDWARE_VERSION
struct MultirotorMixer::saturation_status::@66 flags
bool _cb_flighttermination
true if the flight termination circuit breaker is enabled
#define PX4IO_P_RAW_RC_FLAGS_FAILSAFE
#define PWM_SERVO_SET_DISABLE_LOCKDOWN
set the lockdown override flag to enable outputs in HIL
__EXPORT hrt_abstime hrt_absolute_time(void)
Get absolute time in [us] (does not wrap).
uint32_t param_t
Parameter handle.
virtual int read(unsigned address, void *data, unsigned count)
Read directly from the device.
#define PWM_LOWEST_MIN
Lowest minimum PWM in us.
virtual int poll(file_t *filep, px4_pollfd_struct_t *fds, bool setup)
Perform a poll setup/teardown operation.
#define PWM_SERVO_DISARM
disarm all servo outputs (stop generating pulses)
#define PX4IO_P_STATUS_FLAGS_RC_PPM
Performance measuring tools.
#define PX4IO_P_STATUS_FLAGS_RC_DSM
#define PX4IO_P_SETUP_ARMING_TERMINATION_FAILSAFE
#define PWM_SERVO_GET_MAX_PWM
get the maximum PWM value the output will send
#define PWM_SERVO_SET_UPDATE_RATE
set alternate servo update rate
#define PX4IO_REBOOT_BOOTLOADER
#define PWM_SERVO_EXIT_TEST_MODE