diff --git a/src/drivers/px4io/px4io.cpp b/src/drivers/px4io/px4io.cpp index e53bdbd0a4..9a91f35a16 100644 --- a/src/drivers/px4io/px4io.cpp +++ b/src/drivers/px4io/px4io.cpp @@ -228,7 +228,8 @@ public: * * @param[in] enable true=DSM satellite VCC is controlled by relay1, false=DSM satellite VCC not controlled */ - inline void set_dsm_vcc_ctl(bool enable) { + inline void set_dsm_vcc_ctl(bool enable) + { _dsm_vcc_ctl = enable; }; @@ -237,7 +238,8 @@ public: * * @return true=DSM satellite VCC is controlled by relay1, false=DSM satellite VCC not controlled */ - inline bool get_dsm_vcc_ctl() { + inline bool get_dsm_vcc_ctl() + { return _dsm_vcc_ctl; }; #endif @@ -476,8 +478,8 @@ private: void io_handle_vservo(uint16_t vservo, uint16_t vrssi); /* do not allow to copy this class due to ptr data members */ - PX4IO(const PX4IO&); - PX4IO operator=(const PX4IO&); + PX4IO(const PX4IO &); + PX4IO operator=(const PX4IO &); }; namespace @@ -560,11 +562,13 @@ PX4IO::~PX4IO() } /* well, kill it anyway, though this will probably crash */ - if (_task != -1) + if (_task != -1) { task_delete(_task); + } - if (_interface != nullptr) + if (_interface != nullptr) { delete _interface; + } /* deallocate perfs */ perf_free(_perf_update); @@ -584,8 +588,9 @@ PX4IO::detect() /* do regular cdev init */ ret = CDev::init(); - if (ret != OK) + if (ret != OK) { return ret; + } /* get some parameters */ unsigned protocol = io_reg_get(PX4IO_PAGE_CONFIG, PX4IO_P_CONFIG_PROTOCOL_VERSION); @@ -609,7 +614,8 @@ PX4IO::detect() } int -PX4IO::init(bool rc_handling_disabled) { +PX4IO::init(bool rc_handling_disabled) +{ _rc_handling_disabled = rc_handling_disabled; return init(); } @@ -624,6 +630,7 @@ PX4IO::init() ASSERT(_task == -1); sys_restart_param = param_find("SYS_RESTART_TYPE"); + if (sys_restart_param != PARAM_INVALID) { /* Indicate restart type is unknown */ param_set(sys_restart_param, &sys_restart_val); @@ -632,8 +639,9 @@ PX4IO::init() /* do regular cdev init */ ret = CDev::init(); - if (ret != OK) + if (ret != OK) { return ret; + } /* get some parameters */ unsigned protocol; @@ -672,8 +680,9 @@ PX4IO::init() return -1; } - if (_max_rc_input > input_rc_s::RC_INPUT_MAX_CHANNELS) + if (_max_rc_input > input_rc_s::RC_INPUT_MAX_CHANNELS) { _max_rc_input = input_rc_s::RC_INPUT_MAX_CHANNELS; + } param_get(param_find("RC_RSSI_PWM_CHAN"), &_rssi_pwm_chan); param_get(param_find("RC_RSSI_PWM_MAX"), &_rssi_pwm_max); @@ -691,8 +700,9 @@ PX4IO::init() /* get IO's last seen FMU state */ ret = io_reg_get(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_ARMING, ®, sizeof(reg)); - if (ret != OK) + if (ret != OK) { return ret; + } /* * in-air restart is only tried if the IO board reports it is @@ -857,11 +867,11 @@ PX4IO::init() /* start the IO interface task */ _task = px4_task_spawn_cmd("px4io", - SCHED_DEFAULT, - SCHED_PRIORITY_ACTUATOR_OUTPUTS, - 1800, - (main_t)&PX4IO::task_main_trampoline, - nullptr); + SCHED_DEFAULT, + SCHED_PRIORITY_ACTUATOR_OUTPUTS, + 1800, + (main_t)&PX4IO::task_main_trampoline, + nullptr); if (_task < 0) { DEVICE_DEBUG("task start failed: %d", errno); @@ -929,11 +939,13 @@ PX4IO::task_main() /* adjust update interval */ if (_update_interval != 0) { - if (_update_interval < UPDATE_INTERVAL_MIN) + if (_update_interval < UPDATE_INTERVAL_MIN) { _update_interval = UPDATE_INTERVAL_MIN; + } - if (_update_interval > 100) + if (_update_interval > 100) { _update_interval = 100; + } orb_set_interval(_t_actuator_controls_0, _update_interval); /* @@ -984,8 +996,9 @@ PX4IO::task_main() orb_check_last = now; /* try to claim the MAVLink log FD */ - if (_mavlink_fd < 0) + if (_mavlink_fd < 0) { _mavlink_fd = ::open(MAVLINK_LOG_DEVICE, 0); + } /* check updates on uORB topics and handle it */ bool updated = false; @@ -1068,6 +1081,7 @@ PX4IO::task_main() uint16_t failsafe_thr = failsafe_param_val; pret = io_reg_set(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_RC_THR_FAILSAFE_US, &failsafe_thr, 1); + if (pret != OK) { mavlink_and_console_log_critical(_mavlink_fd, "failsafe upload failed, FS: %d us", (int)failsafe_thr); } @@ -1119,18 +1133,21 @@ PX4IO::task_main() param_t parm_handle; parm_handle = param_find("TRIM_ROLL"); + if (parm_handle != PARAM_INVALID) { param_get(parm_handle, &trim_val); (void)io_reg_set(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_TRIM_ROLL, FLOAT_TO_REG(trim_val)); } parm_handle = param_find("TRIM_PITCH"); + if (parm_handle != PARAM_INVALID) { param_get(parm_handle, &trim_val); (void)io_reg_set(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_TRIM_PITCH, FLOAT_TO_REG(trim_val)); } parm_handle = param_find("TRIM_YAW"); + if (parm_handle != PARAM_INVALID) { param_get(parm_handle, &trim_val); (void)io_reg_set(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_TRIM_YAW, FLOAT_TO_REG(trim_val)); @@ -1139,17 +1156,22 @@ PX4IO::task_main() /* S.BUS output */ int sbus_mode; parm_handle = param_find("PWM_SBUS_MODE"); + if (parm_handle != PARAM_INVALID) { param_get(parm_handle, &sbus_mode); + if (sbus_mode == 1) { /* enable S.BUS 1 */ (void)io_reg_modify(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_FEATURES, 0, PX4IO_P_SETUP_FEATURES_SBUS1_OUT); + } else if (sbus_mode == 2) { /* enable S.BUS 2 */ (void)io_reg_modify(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_FEATURES, 0, PX4IO_P_SETUP_FEATURES_SBUS2_OUT); + } else { /* disable S.BUS */ - (void)io_reg_modify(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_FEATURES, (PX4IO_P_SETUP_FEATURES_SBUS1_OUT | PX4IO_P_SETUP_FEATURES_SBUS2_OUT), 0); + (void)io_reg_modify(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_FEATURES, + (PX4IO_P_SETUP_FEATURES_SBUS1_OUT | PX4IO_P_SETUP_FEATURES_SBUS2_OUT), 0); } } } @@ -1165,8 +1187,9 @@ out: DEVICE_DEBUG("exiting"); /* clean up the alternate device node */ - if (_primary_pwm_device) + if (_primary_pwm_device) { unregister_driver(PWM_OUTPUT0_DEVICE_PATH); + } /* tell the dtor that we are exiting */ _task = -1; @@ -1196,8 +1219,7 @@ PX4IO::io_set_control_state(unsigned group) bool changed = false; switch (group) { - case 0: - { + case 0: { orb_check(_t_actuator_controls_0, &changed); if (changed) { @@ -1206,8 +1228,8 @@ PX4IO::io_set_control_state(unsigned group) } } break; - case 1: - { + + case 1: { orb_check(_t_actuator_controls_1, &changed); if (changed) { @@ -1215,8 +1237,8 @@ PX4IO::io_set_control_state(unsigned group) } } break; - case 2: - { + + case 2: { orb_check(_t_actuator_controls_2, &changed); if (changed) { @@ -1224,8 +1246,8 @@ PX4IO::io_set_control_state(unsigned group) } } break; - case 3: - { + + case 3: { orb_check(_t_actuator_controls_3, &changed); if (changed) { @@ -1253,6 +1275,7 @@ PX4IO::io_set_control_state(unsigned group) if (ctrl < -1.0f) { ctrl = -1.0f; + } else if (ctrl > 1.0f) { ctrl = 1.0f; } @@ -1280,14 +1303,17 @@ PX4IO::io_set_arming_state() if (have_armed == OK) { _in_esc_calibration_mode = armed.in_esc_calibration_mode; + if (armed.armed || _in_esc_calibration_mode) { set |= PX4IO_P_SETUP_ARMING_FMU_ARMED; + } else { clear |= PX4IO_P_SETUP_ARMING_FMU_ARMED; } if (armed.lockdown && !_lockdown_override) { set |= PX4IO_P_SETUP_ARMING_LOCKDOWN; + } else { clear |= PX4IO_P_SETUP_ARMING_LOCKDOWN; } @@ -1295,6 +1321,7 @@ PX4IO::io_set_arming_state() /* Do not set failsafe if circuit breaker is enabled */ if (armed.force_failsafe && !_cb_flighttermination) { set |= PX4IO_P_SETUP_ARMING_FORCE_FAILSAFE; + } else { clear |= PX4IO_P_SETUP_ARMING_FORCE_FAILSAFE; } @@ -1318,6 +1345,7 @@ PX4IO::io_set_arming_state() if (have_control_mode == OK) { if (control_mode.flag_external_manual_override_ok) { set |= PX4IO_P_SETUP_ARMING_MANUAL_OVERRIDE_OK; + } else { clear |= PX4IO_P_SETUP_ARMING_MANUAL_OVERRIDE_OK; } @@ -1357,8 +1385,9 @@ PX4IO::io_set_rc_config() */ /* fill the mapping with an error condition triggering value */ - for (unsigned i = 0; i < _max_rc_input; i++) + for (unsigned i = 0; i < _max_rc_input; i++) { input_map[i] = UINT8_MAX; + } /* * NOTE: The indices for mapped channels are 1-based @@ -1368,54 +1397,63 @@ PX4IO::io_set_rc_config() /* ROLL */ param_get(param_find("RC_MAP_ROLL"), &ichan); + if ((ichan > 0) && (ichan <= (int)_max_rc_input)) { input_map[ichan - 1] = 0; } /* PITCH */ param_get(param_find("RC_MAP_PITCH"), &ichan); + if ((ichan > 0) && (ichan <= (int)_max_rc_input)) { input_map[ichan - 1] = 1; } /* YAW */ param_get(param_find("RC_MAP_YAW"), &ichan); + if ((ichan > 0) && (ichan <= (int)_max_rc_input)) { input_map[ichan - 1] = 2; } /* THROTTLE */ param_get(param_find("RC_MAP_THROTTLE"), &ichan); + if ((ichan > 0) && (ichan <= (int)_max_rc_input)) { input_map[ichan - 1] = 3; } /* FLAPS */ param_get(param_find("RC_MAP_FLAPS"), &ichan); + if ((ichan > 0) && (ichan <= (int)_max_rc_input)) { input_map[ichan - 1] = 4; } /* AUX 1*/ param_get(param_find("RC_MAP_AUX1"), &ichan); + if ((ichan > 0) && (ichan <= (int)_max_rc_input)) { input_map[ichan - 1] = 5; } /* AUX 2*/ param_get(param_find("RC_MAP_AUX2"), &ichan); + if ((ichan > 0) && (ichan <= (int)_max_rc_input)) { input_map[ichan - 1] = 6; } /* AUX 3*/ param_get(param_find("RC_MAP_AUX3"), &ichan); + if ((ichan > 0) && (ichan <= (int)_max_rc_input)) { input_map[ichan - 1] = 7; } /* MAIN MODE SWITCH */ param_get(param_find("RC_MAP_MODE_SW"), &ichan); + if ((ichan > 0) && (ichan <= (int)_max_rc_input)) { /* use out of normal bounds index to indicate special channel */ input_map[ichan - 1] = PX4IO_P_RC_CONFIG_ASSIGNMENT_MODESWITCH; @@ -1501,7 +1539,8 @@ PX4IO::io_handle_status(uint16_t status) if (_status & PX4IO_P_STATUS_FLAGS_SAFETY_OFF && !(status & PX4IO_P_STATUS_FLAGS_SAFETY_OFF) && !(status & PX4IO_P_STATUS_FLAGS_ARM_SYNC)) { /* set the arming flag */ - ret = io_reg_modify(PX4IO_PAGE_STATUS, PX4IO_P_STATUS_FLAGS, 0, PX4IO_P_STATUS_FLAGS_SAFETY_OFF | PX4IO_P_STATUS_FLAGS_ARM_SYNC); + ret = io_reg_modify(PX4IO_PAGE_STATUS, PX4IO_P_STATUS_FLAGS, 0, + PX4IO_P_STATUS_FLAGS_SAFETY_OFF | PX4IO_P_STATUS_FLAGS_ARM_SYNC); /* set new status */ _status = status; @@ -1552,10 +1591,12 @@ PX4IO::dsm_bind_ioctl(int dsmMode) { if (!(_status & PX4IO_P_STATUS_FLAGS_SAFETY_OFF)) { mavlink_log_info(_mavlink_fd, "[IO] binding DSM%s RX", (dsmMode == 0) ? "2" : ((dsmMode == 1) ? "-X" : "-X8")); - int ret = ioctl(nullptr, DSM_BIND_START, (dsmMode == 0) ? DSM2_BIND_PULSES : ((dsmMode == 1) ? DSMX_BIND_PULSES : DSMX8_BIND_PULSES)); + int ret = ioctl(nullptr, DSM_BIND_START, + (dsmMode == 0) ? DSM2_BIND_PULSES : ((dsmMode == 1) ? DSMX_BIND_PULSES : DSMX8_BIND_PULSES)); - if (ret) + if (ret) { mavlink_log_critical(_mavlink_fd, "binding failed."); + } } else { mavlink_log_info(_mavlink_fd, "[IO] system armed, bind request rejected"); @@ -1651,8 +1692,9 @@ PX4IO::io_get_status() * in that order */ ret = io_reg_get(PX4IO_PAGE_STATUS, PX4IO_P_STATUS_FLAGS, ®s[0], sizeof(regs) / sizeof(regs[0])); - if (ret != OK) + if (ret != OK) { return ret; + } io_handle_status(regs[0]); io_handle_alarms(regs[1]); @@ -1687,8 +1729,9 @@ PX4IO::io_get_raw_rc_input(rc_input_values &input_rc) */ ret = io_reg_get(PX4IO_PAGE_RAW_RC_INPUT, PX4IO_P_RAW_RC_COUNT, ®s[0], prolog + 9); - if (ret != OK) + if (ret != OK) { return ret; + } /* * Get the channel count any any extra channels. This is no more expensive than reading the @@ -1726,8 +1769,9 @@ PX4IO::io_get_raw_rc_input(rc_input_values &input_rc) if (channel_count > 9) { ret = io_reg_get(PX4IO_PAGE_RAW_RC_INPUT, PX4IO_P_RAW_RC_BASE + 9, ®s[prolog + 9], channel_count - 9); - if (ret != OK) + if (ret != OK) { return ret; + } } /* last thing set are the actual channel values as 16 bit values */ @@ -1738,7 +1782,7 @@ PX4IO::io_get_raw_rc_input(rc_input_values &input_rc) /* get RSSI from input channel */ if (_rssi_pwm_chan > 0 && _rssi_pwm_chan <= input_rc_s::RC_INPUT_MAX_CHANNELS && _rssi_pwm_max - _rssi_pwm_min != 0) { int rssi = (input_rc.values[_rssi_pwm_chan - 1] - _rssi_pwm_min) / - ((_rssi_pwm_max - _rssi_pwm_min) / 100); + ((_rssi_pwm_max - _rssi_pwm_min) / 100); rssi = rssi > 100 ? 100 : rssi; rssi = rssi < 0 ? 0 : rssi; input_rc.rssi = rssi; @@ -1759,8 +1803,9 @@ PX4IO::io_publish_raw_rc() int ret = io_get_raw_rc_input(rc_val); - if (ret != OK) + if (ret != OK) { return ret; + } /* sort out the source of the values */ if (_status & PX4IO_P_STATUS_FLAGS_RC_PPM) { @@ -1809,12 +1854,14 @@ PX4IO::io_publish_pwm_outputs() uint16_t ctl[_max_actuators]; int ret = io_reg_get(PX4IO_PAGE_SERVOS, 0, ctl, _max_actuators); - if (ret != OK) + if (ret != OK) { return ret; + } /* convert from register format to float */ - for (unsigned i = 0; i < _max_actuators; i++) + for (unsigned i = 0; i < _max_actuators; i++) { outputs.output[i] = ctl[i]; + } outputs.noutputs = _max_actuators; @@ -1822,7 +1869,7 @@ PX4IO::io_publish_pwm_outputs() if (_to_outputs == nullptr) { int instance; _to_outputs = orb_advertise_multi(ORB_ID(actuator_outputs), - &outputs, &instance, ORB_PRIO_MAX); + &outputs, &instance, ORB_PRIO_MAX); } else { orb_publish(ORB_ID(actuator_outputs), _to_outputs, &outputs); @@ -1830,17 +1877,19 @@ PX4IO::io_publish_pwm_outputs() /* get mixer status flags from IO */ uint16_t mixer_status; - ret = io_reg_get(PX4IO_PAGE_STATUS, PX4IO_P_STATUS_MIXER, &mixer_status,sizeof(mixer_status)/sizeof(uint16_t)); - memcpy(&motor_limits,&mixer_status,sizeof(motor_limits)); + ret = io_reg_get(PX4IO_PAGE_STATUS, PX4IO_P_STATUS_MIXER, &mixer_status, sizeof(mixer_status) / sizeof(uint16_t)); + memcpy(&motor_limits, &mixer_status, sizeof(motor_limits)); - if (ret != OK) + if (ret != OK) { return ret; + } /* publish mixer status */ - if(_to_mixer_status == nullptr) { + if (_to_mixer_status == nullptr) { _to_mixer_status = orb_advertise(ORB_ID(multirotor_motor_limits), &motor_limits); + } else { - orb_publish(ORB_ID(multirotor_motor_limits),_to_mixer_status, &motor_limits); + orb_publish(ORB_ID(multirotor_motor_limits), _to_mixer_status, &motor_limits); } return OK; @@ -1895,8 +1944,9 @@ PX4IO::io_reg_get(uint8_t page, uint8_t offset) { uint16_t value; - if (io_reg_get(page, offset, &value, 1) != OK) + if (io_reg_get(page, offset, &value, 1) != OK) { return _io_reg_get_error; + } return value; } @@ -1909,8 +1959,9 @@ PX4IO::io_reg_modify(uint8_t page, uint8_t offset, uint16_t clearbits, uint16_t ret = io_reg_get(page, offset, &value, 1); - if (ret != OK) + if (ret != OK) { return ret; + } value &= ~clearbits; value |= setbits; @@ -1981,8 +2032,9 @@ PX4IO::mixer_send(const char *buf, unsigned buflen, unsigned retries) do { unsigned count = buflen; - if (count > max_len) + if (count > max_len) { count = max_len; + } if (count > 0) { memcpy(&msg->text[0], buf, count); @@ -2015,6 +2067,7 @@ PX4IO::mixer_send(const char *buf, unsigned buflen, unsigned retries) if (ret) { usleep(333); + } else { break; } @@ -2050,13 +2103,15 @@ PX4IO::mixer_send(const char *buf, unsigned buflen, unsigned retries) if (ret) { usleep(333); + } else { break; } } - if (ret) + if (ret) { return ret; + } retries--; @@ -2087,7 +2142,7 @@ PX4IO::print_status(bool extended_status) io_reg_get(PX4IO_PAGE_CONFIG, PX4IO_P_CONFIG_BOOTLOADER_VERSION), io_reg_get(PX4IO_PAGE_CONFIG, PX4IO_P_CONFIG_MAX_TRANSFER), io_reg_get(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_CRC), - io_reg_get(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_CRC+1)); + io_reg_get(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_CRC + 1)); printf("%u controls %u actuators %u R/C inputs %u analog inputs %u relays\n", io_reg_get(PX4IO_PAGE_CONFIG, PX4IO_P_CONFIG_CONTROL_COUNT), io_reg_get(PX4IO_PAGE_CONFIG, PX4IO_P_CONFIG_ACTUATOR_COUNT), @@ -2149,22 +2204,26 @@ PX4IO::print_status(bool extended_status) printf("actuators"); - for (unsigned i = 0; i < _max_actuators; i++) + for (unsigned i = 0; i < _max_actuators; i++) { printf(" %hi", int16_t(io_reg_get(PX4IO_PAGE_ACTUATORS, i))); + } printf("\n"); printf("servos"); - for (unsigned i = 0; i < _max_actuators; i++) + for (unsigned i = 0; i < _max_actuators; i++) { printf(" %u", io_reg_get(PX4IO_PAGE_SERVOS, i)); + } uint16_t pwm_invert_mask = io_reg_get(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_PWM_REVERSE); printf("\n"); printf("reversed outputs: ["); + for (unsigned i = 0; i < _max_actuators; i++) { printf("%s", (pwm_invert_mask & (1 << i)) ? "x" : "_"); } + printf("]"); float trim_roll = REG_TO_FLOAT(io_reg_get(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_TRIM_ROLL)); @@ -2172,24 +2231,25 @@ PX4IO::print_status(bool extended_status) float trim_yaw = REG_TO_FLOAT(io_reg_get(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_TRIM_YAW)); printf(" trims: r: %8.4f p: %8.4f y: %8.4f\n", - (double)trim_roll, (double)trim_pitch, (double)trim_yaw); + (double)trim_roll, (double)trim_pitch, (double)trim_yaw); uint16_t raw_inputs = io_reg_get(PX4IO_PAGE_RAW_RC_INPUT, PX4IO_P_RAW_RC_COUNT); printf("%d raw R/C inputs", raw_inputs); - for (unsigned i = 0; i < raw_inputs; i++) + for (unsigned i = 0; i < raw_inputs; i++) { printf(" %u", io_reg_get(PX4IO_PAGE_RAW_RC_INPUT, PX4IO_P_RAW_RC_BASE + i)); + } printf("\n"); flags = io_reg_get(PX4IO_PAGE_RAW_RC_INPUT, PX4IO_P_RAW_RC_FLAGS); printf("R/C flags: 0x%04x%s%s%s%s%s\n", flags, - (((io_status_flags & PX4IO_P_STATUS_FLAGS_RC_DSM) && (!(flags & PX4IO_P_RAW_RC_FLAGS_RC_DSM11))) ? " DSM10" : ""), - (((io_status_flags & PX4IO_P_STATUS_FLAGS_RC_DSM) && (flags & PX4IO_P_RAW_RC_FLAGS_RC_DSM11)) ? " DSM11" : ""), - ((flags & PX4IO_P_RAW_RC_FLAGS_FRAME_DROP) ? " FRAME_DROP" : ""), - ((flags & PX4IO_P_RAW_RC_FLAGS_FAILSAFE) ? " FAILSAFE" : ""), - ((flags & PX4IO_P_RAW_RC_FLAGS_MAPPING_OK) ? " MAPPING_OK" : "") - ); + (((io_status_flags & PX4IO_P_STATUS_FLAGS_RC_DSM) && (!(flags & PX4IO_P_RAW_RC_FLAGS_RC_DSM11))) ? " DSM10" : ""), + (((io_status_flags & PX4IO_P_STATUS_FLAGS_RC_DSM) && (flags & PX4IO_P_RAW_RC_FLAGS_RC_DSM11)) ? " DSM11" : ""), + ((flags & PX4IO_P_RAW_RC_FLAGS_FRAME_DROP) ? " FRAME_DROP" : ""), + ((flags & PX4IO_P_RAW_RC_FLAGS_FAILSAFE) ? " FAILSAFE" : ""), + ((flags & PX4IO_P_RAW_RC_FLAGS_MAPPING_OK) ? " MAPPING_OK" : "") + ); if ((io_status_flags & PX4IO_P_STATUS_FLAGS_RC_PPM)) { int frame_len = io_reg_get(PX4IO_PAGE_RAW_RC_INPUT, PX4IO_P_RAW_RC_DATA); @@ -2204,27 +2264,29 @@ PX4IO::print_status(bool extended_status) printf("mapped R/C inputs 0x%04x", mapped_inputs); for (unsigned i = 0; i < _max_rc_input; i++) { - if (mapped_inputs & (1 << i)) + if (mapped_inputs & (1 << i)) { printf(" %u:%d", i, REG_TO_SIGNED(io_reg_get(PX4IO_PAGE_RC_INPUT, PX4IO_P_RC_BASE + i))); + } } printf("\n"); uint16_t adc_inputs = io_reg_get(PX4IO_PAGE_CONFIG, PX4IO_P_CONFIG_ADC_INPUT_COUNT); printf("ADC inputs"); - for (unsigned i = 0; i < adc_inputs; i++) + for (unsigned i = 0; i < adc_inputs; i++) { printf(" %u", io_reg_get(PX4IO_PAGE_RAW_ADC_INPUT, i)); + } printf("\n"); /* setup and state */ uint16_t features = io_reg_get(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_FEATURES); printf("features 0x%04x%s%s%s%s\n", features, - ((features & PX4IO_P_SETUP_FEATURES_SBUS1_OUT) ? " S.BUS1_OUT" : ""), - ((features & PX4IO_P_SETUP_FEATURES_SBUS2_OUT) ? " S.BUS2_OUT" : ""), - ((features & PX4IO_P_SETUP_FEATURES_PWM_RSSI) ? " RSSI_PWM" : ""), - ((features & PX4IO_P_SETUP_FEATURES_ADC_RSSI) ? " RSSI_ADC" : "") - ); + ((features & PX4IO_P_SETUP_FEATURES_SBUS1_OUT) ? " S.BUS1_OUT" : ""), + ((features & PX4IO_P_SETUP_FEATURES_SBUS2_OUT) ? " S.BUS2_OUT" : ""), + ((features & PX4IO_P_SETUP_FEATURES_PWM_RSSI) ? " RSSI_PWM" : ""), + ((features & PX4IO_P_SETUP_FEATURES_ADC_RSSI) ? " RSSI_ADC" : "") + ); uint16_t arming = io_reg_get(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_ARMING); printf("arming 0x%04x%s%s%s%s%s%s%s%s%s%s\n", arming, @@ -2238,7 +2300,7 @@ PX4IO::print_status(bool extended_status) ((arming & PX4IO_P_SETUP_ARMING_FORCE_FAILSAFE) ? " FORCE_FAILSAFE" : ""), ((arming & PX4IO_P_SETUP_ARMING_TERMINATION_FAILSAFE) ? " TERM_FAILSAFE" : ""), ((arming & PX4IO_P_SETUP_ARMING_OVERRIDE_IMMEDIATE) ? " OVERRIDE_IMMEDIATE" : "") - ); + ); #ifdef CONFIG_ARCH_BOARD_PX4FMU_V1 printf("rates 0x%04x default %u alt %u relays 0x%04x\n", io_reg_get(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_PWM_RATES), @@ -2253,11 +2315,13 @@ PX4IO::print_status(bool extended_status) io_reg_get(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_PWM_ALTRATE)); #endif printf("debuglevel %u\n", io_reg_get(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_SET_DEBUG)); + for (unsigned group = 0; group < 4; group++) { printf("controls %u:", group); - for (unsigned i = 0; i < _max_controls; i++) + for (unsigned i = 0; i < _max_controls; i++) { printf(" %d", (int16_t) io_reg_get(PX4IO_PAGE_CONTROLS, group * PX4IO_PROTOCOL_MAX_CONTROL_COUNT + i)); + } printf("\n"); } @@ -2281,19 +2345,21 @@ PX4IO::print_status(bool extended_status) printf("failsafe"); - for (unsigned i = 0; i < _max_actuators; i++) + for (unsigned i = 0; i < _max_actuators; i++) { printf(" %u", io_reg_get(PX4IO_PAGE_FAILSAFE_PWM, i)); + } printf("\ndisarmed values"); - for (unsigned i = 0; i < _max_actuators; i++) + for (unsigned i = 0; i < _max_actuators; i++) { printf(" %u", io_reg_get(PX4IO_PAGE_DISARMED_PWM, i)); + } printf("\n"); } int -PX4IO::ioctl(file * filep, int cmd, unsigned long arg) +PX4IO::ioctl(file *filep, int cmd, unsigned long arg) { int ret = OK; @@ -2359,79 +2425,99 @@ PX4IO::ioctl(file * filep, int cmd, unsigned long arg) break; case PWM_SERVO_SET_FAILSAFE_PWM: { - struct pwm_output_values* pwm = (struct pwm_output_values*)arg; - if (pwm->channel_count > _max_actuators) - /* fail with error */ - return -E2BIG; + struct pwm_output_values *pwm = (struct pwm_output_values *)arg; - /* copy values to registers in IO */ - ret = io_reg_set(PX4IO_PAGE_FAILSAFE_PWM, 0, pwm->values, pwm->channel_count); - break; - } + if (pwm->channel_count > _max_actuators) + /* fail with error */ + { + return -E2BIG; + } + + /* copy values to registers in IO */ + ret = io_reg_set(PX4IO_PAGE_FAILSAFE_PWM, 0, pwm->values, pwm->channel_count); + break; + } case PWM_SERVO_GET_FAILSAFE_PWM: - ret = io_reg_get(PX4IO_PAGE_FAILSAFE_PWM, 0, (uint16_t*)arg, _max_actuators); + ret = io_reg_get(PX4IO_PAGE_FAILSAFE_PWM, 0, (uint16_t *)arg, _max_actuators); + if (ret != OK) { ret = -EIO; } + break; case PWM_SERVO_SET_DISARMED_PWM: { - struct pwm_output_values* pwm = (struct pwm_output_values*)arg; - if (pwm->channel_count > _max_actuators) - /* fail with error */ - return -E2BIG; + struct pwm_output_values *pwm = (struct pwm_output_values *)arg; - /* copy values to registers in IO */ - ret = io_reg_set(PX4IO_PAGE_DISARMED_PWM, 0, pwm->values, pwm->channel_count); - break; - } + if (pwm->channel_count > _max_actuators) + /* fail with error */ + { + return -E2BIG; + } + + /* copy values to registers in IO */ + ret = io_reg_set(PX4IO_PAGE_DISARMED_PWM, 0, pwm->values, pwm->channel_count); + break; + } case PWM_SERVO_GET_DISARMED_PWM: - ret = io_reg_get(PX4IO_PAGE_DISARMED_PWM, 0, (uint16_t*)arg, _max_actuators); + ret = io_reg_get(PX4IO_PAGE_DISARMED_PWM, 0, (uint16_t *)arg, _max_actuators); + if (ret != OK) { ret = -EIO; } + break; case PWM_SERVO_SET_MIN_PWM: { - struct pwm_output_values* pwm = (struct pwm_output_values*)arg; - if (pwm->channel_count > _max_actuators) - /* fail with error */ - return -E2BIG; + struct pwm_output_values *pwm = (struct pwm_output_values *)arg; - /* copy values to registers in IO */ - ret = io_reg_set(PX4IO_PAGE_CONTROL_MIN_PWM, 0, pwm->values, pwm->channel_count); - break; - } + if (pwm->channel_count > _max_actuators) + /* fail with error */ + { + return -E2BIG; + } + + /* copy values to registers in IO */ + ret = io_reg_set(PX4IO_PAGE_CONTROL_MIN_PWM, 0, pwm->values, pwm->channel_count); + break; + } case PWM_SERVO_GET_MIN_PWM: - ret = io_reg_get(PX4IO_PAGE_CONTROL_MIN_PWM, 0, (uint16_t*)arg, _max_actuators); + ret = io_reg_get(PX4IO_PAGE_CONTROL_MIN_PWM, 0, (uint16_t *)arg, _max_actuators); + if (ret != OK) { ret = -EIO; } + break; case PWM_SERVO_SET_MAX_PWM: { - struct pwm_output_values* pwm = (struct pwm_output_values*)arg; - if (pwm->channel_count > _max_actuators) - /* fail with error */ - return -E2BIG; + struct pwm_output_values *pwm = (struct pwm_output_values *)arg; - /* copy values to registers in IO */ - ret = io_reg_set(PX4IO_PAGE_CONTROL_MAX_PWM, 0, pwm->values, pwm->channel_count); - break; - } + if (pwm->channel_count > _max_actuators) + /* fail with error */ + { + return -E2BIG; + } + + /* copy values to registers in IO */ + ret = io_reg_set(PX4IO_PAGE_CONTROL_MAX_PWM, 0, pwm->values, pwm->channel_count); + break; + } case PWM_SERVO_GET_MAX_PWM: - ret = io_reg_get(PX4IO_PAGE_CONTROL_MAX_PWM, 0, (uint16_t*)arg, _max_actuators); + ret = io_reg_get(PX4IO_PAGE_CONTROL_MAX_PWM, 0, (uint16_t *)arg, _max_actuators); + if (ret != OK) { ret = -EIO; } + break; case PWM_SERVO_GET_COUNT: @@ -2457,38 +2543,47 @@ PX4IO::ioctl(file * filep, int cmd, unsigned long arg) break; case PWM_SERVO_SET_FORCE_FAILSAFE: + /* force failsafe mode instantly */ if (arg == 0) { /* clear force failsafe flag */ ret = io_reg_modify(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_ARMING, PX4IO_P_SETUP_ARMING_FORCE_FAILSAFE, 0); + } else { /* set force failsafe flag */ ret = io_reg_modify(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_ARMING, 0, PX4IO_P_SETUP_ARMING_FORCE_FAILSAFE); } + break; case PWM_SERVO_SET_TERMINATION_FAILSAFE: + /* if failsafe occurs, do not allow the system to recover */ if (arg == 0) { /* clear termination failsafe flag */ ret = io_reg_modify(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_ARMING, PX4IO_P_SETUP_ARMING_TERMINATION_FAILSAFE, 0); + } else { /* set termination failsafe flag */ ret = io_reg_modify(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_ARMING, 0, PX4IO_P_SETUP_ARMING_TERMINATION_FAILSAFE); } + break; case PWM_SERVO_SET_OVERRIDE_IMMEDIATE: + /* control whether override on FMU failure is - immediate or waits for override threshold on mode - switch */ + immediate or waits for override threshold on mode + switch */ if (arg == 0) { /* clear override immediate flag */ ret = io_reg_modify(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_ARMING, PX4IO_P_SETUP_ARMING_OVERRIDE_IMMEDIATE, 0); + } else { /* set override immediate flag */ ret = io_reg_modify(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_ARMING, 0, PX4IO_P_SETUP_ARMING_OVERRIDE_IMMEDIATE); } + break; case DSM_BIND_START: @@ -2507,9 +2602,11 @@ PX4IO::ioctl(file * filep, int cmd, unsigned long arg) io_reg_set(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_DSM, dsm_bind_reinit_uart); ret = OK; + } else { ret = -EINVAL; } + break; case DSM_BIND_POWER_UP: @@ -2560,8 +2657,9 @@ PX4IO::ioctl(file * filep, int cmd, unsigned long arg) *(uint32_t *)arg = io_reg_get(PX4IO_PAGE_PWM_INFO, PX4IO_RATE_MAP_BASE + channel); - if (*(uint32_t *)arg == _io_reg_get_error) + if (*(uint32_t *)arg == _io_reg_get_error) { ret = -EIO; + } break; } @@ -2571,8 +2669,9 @@ PX4IO::ioctl(file * filep, int cmd, unsigned long arg) uint32_t bits = (1 << _max_relays) - 1; /* don't touch relay1 if it's controlling RX vcc */ - if (_dsm_vcc_ctl) + if (_dsm_vcc_ctl) { bits &= ~PX4IO_P_SETUP_RELAYS_POWER1; + } ret = io_reg_modify(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_RELAYS, bits, 0); #endif @@ -2620,8 +2719,9 @@ PX4IO::ioctl(file * filep, int cmd, unsigned long arg) #ifdef CONFIG_ARCH_BOARD_PX4FMU_V1 *(uint32_t *)arg = io_reg_get(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_RELAYS); - if (*(uint32_t *)arg == _io_reg_get_error) + if (*(uint32_t *)arg == _io_reg_get_error) { ret = -EIO; + } #endif #ifdef CONFIG_ARCH_BOARD_PX4FMU_V2 @@ -2649,8 +2749,9 @@ PX4IO::ioctl(file * filep, int cmd, unsigned long arg) ret = io_reg_get(PX4IO_PAGE_STATUS, PX4IO_P_STATUS_FLAGS, &status, 1); - if (ret != OK) + if (ret != OK) { break; + } /* if no R/C input, don't try to fetch anything */ if (!(status & PX4IO_P_STATUS_FLAGS_RC_OK)) { @@ -2686,8 +2787,9 @@ PX4IO::ioctl(file * filep, int cmd, unsigned long arg) break; case PX4IO_REBOOT_BOOTLOADER: - if (system_status() & PX4IO_P_STATUS_FLAGS_SAFETY_OFF) + if (system_status() & PX4IO_P_STATUS_FLAGS_SAFETY_OFF) { return -EINVAL; + } /* reboot into bootloader - arg must be PX4IO_REBOOT_BL_MAGIC */ io_reg_set(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_REBOOT_BL, arg); @@ -2696,17 +2798,21 @@ PX4IO::ioctl(file * filep, int cmd, unsigned long arg) break; case PX4IO_CHECK_CRC: { - /* check IO firmware CRC against passed value */ - uint32_t io_crc = 0; - ret = io_reg_get(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_CRC, (uint16_t *)&io_crc, 2); - if (ret != OK) - return ret; - if (io_crc != arg) { - DEVICE_DEBUG("crc mismatch 0x%08x 0x%08x", (unsigned)io_crc, arg); - return -EINVAL; + /* check IO firmware CRC against passed value */ + uint32_t io_crc = 0; + ret = io_reg_get(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_CRC, (uint16_t *)&io_crc, 2); + + if (ret != OK) { + return ret; + } + + if (io_crc != arg) { + DEVICE_DEBUG("crc mismatch 0x%08x 0x%08x", (unsigned)io_crc, arg); + return -EINVAL; + } + + break; } - break; - } case PX4IO_INAIR_RESTART_ENABLE: @@ -2724,6 +2830,7 @@ PX4IO::ioctl(file * filep, int cmd, unsigned long arg) if (arg) { ret = io_reg_modify(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_FEATURES, 0, PX4IO_P_SETUP_FEATURES_ADC_RSSI); + } else { ret = io_reg_modify(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_FEATURES, PX4IO_P_SETUP_FEATURES_ADC_RSSI, 0); } @@ -2734,6 +2841,7 @@ PX4IO::ioctl(file * filep, int cmd, unsigned long arg) if (arg) { ret = io_reg_modify(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_FEATURES, 0, PX4IO_P_SETUP_FEATURES_PWM_RSSI); + } else { ret = io_reg_modify(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_FEATURES, PX4IO_P_SETUP_FEATURES_PWM_RSSI, 0); } @@ -2744,39 +2852,45 @@ PX4IO::ioctl(file * filep, int cmd, unsigned long arg) if (arg == 1) { ret = io_reg_modify(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_FEATURES, 0, PX4IO_P_SETUP_FEATURES_SBUS1_OUT); + } else if (arg == 2) { ret = io_reg_modify(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_FEATURES, 0, PX4IO_P_SETUP_FEATURES_SBUS2_OUT); + } else { - ret = io_reg_modify(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_FEATURES, (PX4IO_P_SETUP_FEATURES_SBUS1_OUT | PX4IO_P_SETUP_FEATURES_SBUS2_OUT), 0); + ret = io_reg_modify(PX4IO_PAGE_SETUP, PX4IO_P_SETUP_FEATURES, + (PX4IO_P_SETUP_FEATURES_SBUS1_OUT | PX4IO_P_SETUP_FEATURES_SBUS2_OUT), 0); } break; case PWM_SERVO_SET_RC_CONFIG: { - /* enable setting of RC configuration without relying - on param_get() - */ - struct pwm_output_rc_config* config = (struct pwm_output_rc_config*)arg; - if (config->channel >= input_rc_s::RC_INPUT_MAX_CHANNELS) { - /* fail with error */ - return -E2BIG; - } + /* enable setting of RC configuration without relying + on param_get() + */ + struct pwm_output_rc_config *config = (struct pwm_output_rc_config *)arg; - /* copy values to registers in IO */ - uint16_t regs[PX4IO_P_RC_CONFIG_STRIDE]; - uint16_t offset = config->channel * PX4IO_P_RC_CONFIG_STRIDE; - regs[PX4IO_P_RC_CONFIG_MIN] = config->rc_min; - regs[PX4IO_P_RC_CONFIG_CENTER] = config->rc_trim; - regs[PX4IO_P_RC_CONFIG_MAX] = config->rc_max; - regs[PX4IO_P_RC_CONFIG_DEADZONE] = config->rc_dz; - regs[PX4IO_P_RC_CONFIG_ASSIGNMENT] = config->rc_assignment; - regs[PX4IO_P_RC_CONFIG_OPTIONS] = PX4IO_P_RC_CONFIG_OPTIONS_ENABLED; - if (config->rc_reverse) { - regs[PX4IO_P_RC_CONFIG_OPTIONS] |= PX4IO_P_RC_CONFIG_OPTIONS_REVERSE; + if (config->channel >= input_rc_s::RC_INPUT_MAX_CHANNELS) { + /* fail with error */ + return -E2BIG; + } + + /* copy values to registers in IO */ + uint16_t regs[PX4IO_P_RC_CONFIG_STRIDE]; + uint16_t offset = config->channel * PX4IO_P_RC_CONFIG_STRIDE; + regs[PX4IO_P_RC_CONFIG_MIN] = config->rc_min; + regs[PX4IO_P_RC_CONFIG_CENTER] = config->rc_trim; + regs[PX4IO_P_RC_CONFIG_MAX] = config->rc_max; + regs[PX4IO_P_RC_CONFIG_DEADZONE] = config->rc_dz; + regs[PX4IO_P_RC_CONFIG_ASSIGNMENT] = config->rc_assignment; + regs[PX4IO_P_RC_CONFIG_OPTIONS] = PX4IO_P_RC_CONFIG_OPTIONS_ENABLED; + + if (config->rc_reverse) { + regs[PX4IO_P_RC_CONFIG_OPTIONS] |= PX4IO_P_RC_CONFIG_OPTIONS_REVERSE; + } + + ret = io_reg_set(PX4IO_PAGE_RC_CONFIG, offset, regs, PX4IO_P_RC_CONFIG_STRIDE); + break; } - ret = io_reg_set(PX4IO_PAGE_RC_CONFIG, offset, regs, PX4IO_P_RC_CONFIG_STRIDE); - break; - } case PWM_SERVO_SET_OVERRIDE_OK: /* set the 'OVERRIDE OK' bit */ @@ -2803,8 +2917,9 @@ PX4IO::write(file * /*filp*/, const char *buffer, size_t len) { unsigned count = len / 2; - if (count > _max_actuators) + if (count > _max_actuators) { count = _max_actuators; + } if (count > 0) { @@ -2812,8 +2927,9 @@ PX4IO::write(file * /*filp*/, const char *buffer, size_t len) int ret = io_reg_set(PX4IO_PAGE_DIRECT_PWM, 0, (uint16_t *)buffer, count); perf_end(_perf_write); - if (ret != OK) + if (ret != OK) { return ret; + } } return count * 2; @@ -2858,20 +2974,24 @@ get_interface() #ifndef CONFIG_ARCH_BOARD_PX4FMU_V1 /* try for a serial interface */ - if (PX4IO_serial_interface != nullptr) + if (PX4IO_serial_interface != nullptr) { interface = PX4IO_serial_interface(); + } - if (interface != nullptr) + if (interface != nullptr) { goto got; + } #endif /* try for an I2C interface if we haven't got a serial one */ - if (PX4IO_i2c_interface != nullptr) + if (PX4IO_i2c_interface != nullptr) { interface = PX4IO_i2c_interface(); + } - if (interface != nullptr) + if (interface != nullptr) { goto got; + } errx(1, "cannot alloc interface"); @@ -2888,8 +3008,9 @@ got: void start(int argc, char *argv[]) { - if (g_dev != nullptr) + if (g_dev != nullptr) { errx(0, "already loaded"); + } /* allocate the interface */ device::Device *interface = get_interface(); @@ -2938,8 +3059,9 @@ start(int argc, char *argv[]) void detect(int argc, char *argv[]) { - if (g_dev != nullptr) + if (g_dev != nullptr) { errx(0, "already loaded"); + } /* allocate the interface */ device::Device *interface = get_interface(); @@ -2947,8 +3069,9 @@ detect(int argc, char *argv[]) /* create the driver - it will set g_dev */ (void)new PX4IO(interface); - if (g_dev == nullptr) + if (g_dev == nullptr) { errx(1, "driver alloc failed"); + } int ret = g_dev->detect(); @@ -2976,8 +3099,10 @@ checkcrc(int argc, char *argv[]) /* create the driver - it will set g_dev */ (void)new PX4IO(interface); - if (g_dev == nullptr) + if (g_dev == nullptr) { errx(1, "driver alloc failed"); + } + } else { /* its already running, don't kill the driver */ keep_running = true; @@ -2990,22 +3115,30 @@ checkcrc(int argc, char *argv[]) warnx("usage: px4io checkcrc filename"); exit(1); } + int fd = open(argv[1], O_RDONLY); + if (fd == -1) { warnx("open of %s failed: %d", argv[1], errno); exit(1); } + const uint32_t app_size_max = 0xf000; uint32_t fw_crc = 0; uint32_t nbytes = 0; + while (true) { uint8_t buf[16]; int n = read(fd, buf, sizeof(buf)); - if (n <= 0) break; + + if (n <= 0) { break; } + fw_crc = crc32part(buf, n, fw_crc); nbytes += n; } + close(fd); + while (nbytes < app_size_max) { uint8_t b = 0xff; fw_crc = crc32part(&b, 1, fw_crc); @@ -3023,6 +3156,7 @@ checkcrc(int argc, char *argv[]) warn("check CRC failed: %d", ret); exit(1); } + warnx("CRCs match"); exit(0); } @@ -3032,32 +3166,43 @@ bind(int argc, char *argv[]) { int pulses; - if (g_dev == nullptr) + if (g_dev == nullptr) { errx(1, "px4io must be started first"); + } #ifdef CONFIG_ARCH_BOARD_PX4FMU_V1 - if (!g_dev->get_dsm_vcc_ctl()) + if (!g_dev->get_dsm_vcc_ctl()) { errx(1, "DSM bind feature not enabled"); + } #endif - if (argc < 3) + if (argc < 3) { errx(0, "needs argument, use dsm2, dsmx or dsmx8"); + } - if (!strcmp(argv[2], "dsm2")) + if (!strcmp(argv[2], "dsm2")) { pulses = DSM2_BIND_PULSES; - else if (!strcmp(argv[2], "dsmx")) + + } else if (!strcmp(argv[2], "dsmx")) { pulses = DSMX_BIND_PULSES; - else if (!strcmp(argv[2], "dsmx8")) + + } else if (!strcmp(argv[2], "dsmx8")) { pulses = DSMX8_BIND_PULSES; - else + + } else { errx(1, "unknown parameter %s, use dsm2, dsmx or dsmx8", argv[2]); + } + // Test for custom pulse parameter - if (argc > 3) + if (argc > 3) { pulses = atoi(argv[3]); - if (g_dev->system_status() & PX4IO_P_STATUS_FLAGS_SAFETY_OFF) + } + + if (g_dev->system_status() & PX4IO_P_STATUS_FLAGS_SAFETY_OFF) { errx(1, "system must not be armed"); + } #ifdef CONFIG_ARCH_BOARD_PX4FMU_V1 warnx("This command will only bind DSM if satellite VCC (red wire) is controlled by relay 1."); @@ -3079,23 +3224,29 @@ test(void) fd = open(PX4IO_DEVICE_PATH, O_WRONLY); - if (fd < 0) + if (fd < 0) { err(1, "failed to open device"); + } - if (ioctl(fd, PWM_SERVO_GET_COUNT, (unsigned long)&servo_count)) + if (ioctl(fd, PWM_SERVO_GET_COUNT, (unsigned long)&servo_count)) { err(1, "failed to get servo count"); + } /* tell IO that its ok to disable its safety with the switch */ ret = ioctl(fd, PWM_SERVO_SET_ARM_OK, 0); - if (ret != OK) + if (ret != OK) { err(1, "PWM_SERVO_SET_ARM_OK"); + } - if (ioctl(fd, PWM_SERVO_ARM, 0)) + if (ioctl(fd, PWM_SERVO_ARM, 0)) { err(1, "failed to arm servos"); + } struct pollfd fds; + fds.fd = 0; /* stdin */ + fds.events = POLLIN; warnx("Press CTRL-C or 'c' to abort."); @@ -3105,13 +3256,15 @@ test(void) /* sweep all servos between 1000..2000 */ servo_position_t servos[servo_count]; - for (unsigned i = 0; i < servo_count; i++) + for (unsigned i = 0; i < servo_count; i++) { servos[i] = pwm_value; + } ret = write(fd, servos, sizeof(servos)); - if (ret != (int)sizeof(servos)) + if (ret != (int)sizeof(servos)) { err(1, "error writing PWM servo data, wrote %u got %d", sizeof(servos), ret); + } if (direction > 0) { if (pwm_value < 2000) { @@ -3134,11 +3287,13 @@ test(void) for (unsigned i = 0; i < servo_count; i++) { servo_position_t value; - if (ioctl(fd, PWM_SERVO_GET(i), (unsigned long)&value)) + if (ioctl(fd, PWM_SERVO_GET(i), (unsigned long)&value)) { err(1, "error reading PWM servo %d", i); + } - if (value != servos[i]) + if (value != servos[i]) { errx(1, "servo %d readback error, got %u expected %u", i, value, servos[i]); + } } /* Check if user wants to quit */ @@ -3170,6 +3325,7 @@ monitor(void) fds[0].fd = 0; fds[0].events = POLLIN; + if (poll(fds, 1, 2000) < 0) { errx(1, "poll fail"); } @@ -3207,6 +3363,7 @@ if_test(unsigned mode) if (interface) { result = interface->ioctl(1, mode); /* XXX magic numbers */ delete interface; + } else { errx(1, "interface not loaded, exiting"); } @@ -3219,53 +3376,57 @@ lockdown(int argc, char *argv[]) { if (g_dev != nullptr) { - if (argc > 2 && !strcmp(argv[2], "disable")) { + if (argc > 2 && !strcmp(argv[2], "disable")) { - warnx("WARNING: ACTUATORS WILL BE LIVE IN HIL! PROCEED?"); - warnx("Press 'y' to enable, any other key to abort."); + warnx("WARNING: ACTUATORS WILL BE LIVE IN HIL! PROCEED?"); + warnx("Press 'y' to enable, any other key to abort."); - /* check if user wants to abort */ - char c; + /* check if user wants to abort */ + char c; - struct pollfd fds; - int ret; - hrt_abstime start = hrt_absolute_time(); - const unsigned long timeout = 5000000; + struct pollfd fds; + int ret; + hrt_abstime start = hrt_absolute_time(); + const unsigned long timeout = 5000000; - while (hrt_elapsed_time(&start) < timeout) { - fds.fd = 0; /* stdin */ - fds.events = POLLIN; - ret = poll(&fds, 1, 0); + while (hrt_elapsed_time(&start) < timeout) { + fds.fd = 0; /* stdin */ + fds.events = POLLIN; + ret = poll(&fds, 1, 0); - if (ret > 0) { + if (ret > 0) { - if (read(0, &c, 1) > 0) { + if (read(0, &c, 1) > 0) { - if (c != 'y') { - exit(0); - } else if (c == 'y') { - break; - } + if (c != 'y') { + exit(0); + + } else if (c == 'y') { + break; } } - - usleep(10000); } - if (hrt_elapsed_time(&start) > timeout) - errx(1, "TIMEOUT! ABORTED WITHOUT CHANGES."); - - (void)g_dev->ioctl(0, PWM_SERVO_SET_DISABLE_LOCKDOWN, 1); - - warnx("WARNING: ACTUATORS ARE NOW LIVE IN HIL!"); - } else { - (void)g_dev->ioctl(0, PWM_SERVO_SET_DISABLE_LOCKDOWN, 0); - warnx("ACTUATORS ARE NOW SAFE IN HIL."); + usleep(10000); } + if (hrt_elapsed_time(&start) > timeout) { + errx(1, "TIMEOUT! ABORTED WITHOUT CHANGES."); + } + + (void)g_dev->ioctl(0, PWM_SERVO_SET_DISABLE_LOCKDOWN, 1); + + warnx("WARNING: ACTUATORS ARE NOW LIVE IN HIL!"); + } else { - errx(1, "driver not loaded, exiting"); + (void)g_dev->ioctl(0, PWM_SERVO_SET_DISABLE_LOCKDOWN, 0); + warnx("ACTUATORS ARE NOW SAFE IN HIL."); } + + } else { + errx(1, "driver not loaded, exiting"); + } + exit(0); } @@ -3275,17 +3436,21 @@ int px4io_main(int argc, char *argv[]) { /* check for sufficient number of arguments */ - if (argc < 2) + if (argc < 2) { goto out; + } - if (!strcmp(argv[1], "start")) + if (!strcmp(argv[1], "start")) { start(argc - 1, argv + 1); + } - if (!strcmp(argv[1], "detect")) + if (!strcmp(argv[1], "detect")) { detect(argc - 1, argv + 1); + } - if (!strcmp(argv[1], "checkcrc")) + if (!strcmp(argv[1], "checkcrc")) { checkcrc(argc - 1, argv + 1); + } if (!strcmp(argv[1], "update")) { @@ -3349,8 +3514,9 @@ px4io_main(int argc, char *argv[]) } if (!strcmp(argv[1], "iftest")) { - if (g_dev != nullptr) + if (g_dev != nullptr) { errx(1, "can't iftest when started"); + } if_test((argc > 2) ? strtol(argv[2], NULL, 0) : 0); } @@ -3364,6 +3530,7 @@ px4io_main(int argc, char *argv[]) warnx("usage: px4io forceupdate MAGIC filename"); exit(1); } + if (g_dev == nullptr) { warnx("px4io is not started, still attempting upgrade"); @@ -3381,6 +3548,7 @@ px4io_main(int argc, char *argv[]) uint16_t arg = atol(argv[2]); int ret = g_dev->ioctl(nullptr, PX4IO_REBOOT_BOOTLOADER, arg); + if (ret != OK) { warnx("reboot failed - %d", ret); exit(1); @@ -3402,8 +3570,9 @@ px4io_main(int argc, char *argv[]) /* commands below here require a started driver */ - if (g_dev == nullptr) + if (g_dev == nullptr) { errx(1, "not started"); + } if (!strcmp(argv[1], "limit")) { @@ -3412,6 +3581,7 @@ px4io_main(int argc, char *argv[]) if (limitrate > 0) { g_dev->set_update_rate(limitrate); + } else { errx(1, "invalid rate: %d", limitrate); } @@ -3438,19 +3608,23 @@ px4io_main(int argc, char *argv[]) if (!strcmp(argv[1], "safety_off")) { int ret = g_dev->ioctl(NULL, PWM_SERVO_SET_FORCE_SAFETY_OFF, 0); + if (ret != OK) { warnx("failed to disable safety"); exit(1); } + exit(0); } if (!strcmp(argv[1], "safety_on")) { int ret = g_dev->ioctl(NULL, PWM_SERVO_SET_FORCE_SAFETY_ON, 0); + if (ret != OK) { warnx("failed to enable safety"); exit(1); } + exit(0); } @@ -3512,20 +3686,25 @@ px4io_main(int argc, char *argv[]) !strcmp(argv[1], "rx_dsm_10bit") || !strcmp(argv[1], "rx_dsm_11bit") || !strcmp(argv[1], "rx_sbus") || - !strcmp(argv[1], "rx_ppm")) + !strcmp(argv[1], "rx_ppm")) { errx(0, "receiver type is automatically detected, option '%s' is deprecated", argv[1]); + } - if (!strcmp(argv[1], "test")) + if (!strcmp(argv[1], "test")) { test(); + } - if (!strcmp(argv[1], "monitor")) + if (!strcmp(argv[1], "monitor")) { monitor(); + } - if (!strcmp(argv[1], "bind")) + if (!strcmp(argv[1], "bind")) { bind(argc, argv); + } - if (!strcmp(argv[1], "lockdown")) + if (!strcmp(argv[1], "lockdown")) { lockdown(argc, argv); + } if (!strcmp(argv[1], "sbus1_out")) { /* we can cheat and call the driver directly, as it @@ -3581,6 +3760,6 @@ px4io_main(int argc, char *argv[]) out: errx(1, "need a command, try 'start', 'stop', 'status', 'test', 'monitor', 'debug ',\n" - "'recovery', 'limit ', 'current', 'bind', 'checkcrc', 'safety_on', 'safety_off',\n" - "'forceupdate', 'update', 'sbus1_out', 'sbus2_out', 'rssi_analog' or 'rssi_pwm'"); + "'recovery', 'limit ', 'current', 'bind', 'checkcrc', 'safety_on', 'safety_off',\n" + "'forceupdate', 'update', 'sbus1_out', 'sbus2_out', 'rssi_analog' or 'rssi_pwm'"); } diff --git a/src/drivers/px4io/px4io_i2c.cpp b/src/drivers/px4io/px4io_i2c.cpp index 4cceb5cf29..574a58f52a 100755 --- a/src/drivers/px4io/px4io_i2c.cpp +++ b/src/drivers/px4io/px4io_i2c.cpp @@ -31,11 +31,11 @@ * ****************************************************************************/ - /** - * @file px4io_i2c.cpp - * - * I2C interface for PX4IO - */ +/** + * @file px4io_i2c.cpp + * + * I2C interface for PX4IO + */ /* XXX trim includes */ #include @@ -94,8 +94,10 @@ PX4IO_I2C::init() int ret; ret = I2C::init(); - if (ret != OK) + + if (ret != OK) { goto out; + } /* XXX really should do something more here */ @@ -133,8 +135,11 @@ PX4IO_I2C::write(unsigned address, void *data, unsigned count) msgv[1].length = 2 * count; int ret = transfer(msgv, 2); - if (ret == OK) + + if (ret == OK) { ret = count; + } + return ret; } @@ -161,8 +166,11 @@ PX4IO_I2C::read(unsigned address, void *data, unsigned count) msgv[1].length = 2 * count; int ret = transfer(msgv, 2); - if (ret == OK) + + if (ret == OK) { ret = count; + } + return ret; } diff --git a/src/drivers/px4io/px4io_serial.cpp b/src/drivers/px4io/px4io_serial.cpp index 566d43fcb7..93f55f9486 100644 --- a/src/drivers/px4io/px4io_serial.cpp +++ b/src/drivers/px4io/px4io_serial.cpp @@ -31,11 +31,11 @@ * ****************************************************************************/ - /** - * @file px4io_serial.cpp - * - * Serial interface for PX4IO - */ +/** + * @file px4io_serial.cpp + * + * Serial interface for PX4IO + */ /* XXX trim includes */ #include @@ -159,7 +159,7 @@ private: /* do not allow top copying this class */ PX4IO_serial(PX4IO_serial &); - PX4IO_serial& operator = (const PX4IO_serial &); + PX4IO_serial &operator = (const PX4IO_serial &); }; @@ -199,6 +199,7 @@ PX4IO_serial::~PX4IO_serial() stm32_dmastop(_tx_dma); stm32_dmafree(_tx_dma); } + if (_rx_dma != nullptr) { stm32_dmastop(_rx_dma); stm32_dmafree(_rx_dma); @@ -232,8 +233,9 @@ PX4IO_serial::~PX4IO_serial() perf_free(_pc_idle); perf_free(_pc_badidle); - if (g_interface == this) + if (g_interface == this) { g_interface = nullptr; + } } int @@ -243,6 +245,7 @@ PX4IO_serial::init() /* allocate DMA */ _tx_dma = stm32_dmachannel(PX4IO_SERIAL_TX_DMAMAP); _rx_dma = stm32_dmachannel(PX4IO_SERIAL_RX_DMAMAP); + if ((_tx_dma == nullptr) || (_rx_dma == nullptr)) { return -1; } @@ -305,19 +308,22 @@ PX4IO_serial::ioctl(unsigned operation, unsigned &arg) for (;;) { while (!(rSR & USART_SR_TXE)) ; + rDR = 0x55; } + return 0; - case 1: - { + case 1: { unsigned fails = 0; + for (unsigned count = 0;; count++) { uint16_t value = count & 0xffff; - if (write((PX4IO_PAGE_TEST << 8) | PX4IO_P_TEST_LED, &value, 1) != 0) + if (write((PX4IO_PAGE_TEST << 8) | PX4IO_P_TEST_LED, &value, 1) != 0) { fails++; - + } + if (count >= 5000) { lowsyslog("==== test 1 : %u failures ====\n", fails); perf_print_counter(_pc_txns); @@ -333,12 +339,15 @@ PX4IO_serial::ioctl(unsigned operation, unsigned &arg) count = 0; } } + return 0; } + case 2: lowsyslog("test 2\n"); return 0; } + default: break; } @@ -353,20 +362,24 @@ PX4IO_serial::write(unsigned address, void *data, unsigned count) uint8_t offset = address & 0xff; const uint16_t *values = reinterpret_cast(data); - if (count > PKT_MAX_REGS) + if (count > PKT_MAX_REGS) { return -EINVAL; + } sem_wait(&_bus_semaphore); int result; + for (unsigned retries = 0; retries < 3; retries++) { _dma_buffer.count_code = count | PKT_CODE_WRITE; _dma_buffer.page = page; _dma_buffer.offset = offset; memcpy((void *)&_dma_buffer.regs[0], (void *)values, (2 * count)); - for (unsigned i = count; i < PKT_MAX_REGS; i++) + + for (unsigned i = count; i < PKT_MAX_REGS; i++) { _dma_buffer.regs[i] = 0x55aa; + } /* XXX implement check byte */ @@ -386,13 +399,16 @@ PX4IO_serial::write(unsigned address, void *data, unsigned count) break; } + perf_count(_pc_retries); } sem_post(&_bus_semaphore); - if (result == OK) + if (result == OK) { result = count; + } + return result; } @@ -403,12 +419,14 @@ PX4IO_serial::read(unsigned address, void *data, unsigned count) uint8_t offset = address & 0xff; uint16_t *values = reinterpret_cast(data); - if (count > PKT_MAX_REGS) + if (count > PKT_MAX_REGS) { return -EINVAL; + } sem_wait(&_bus_semaphore); int result; + for (unsigned retries = 0; retries < 3; retries++) { _dma_buffer.count_code = count | PKT_CODE_READ; @@ -428,14 +446,16 @@ PX4IO_serial::read(unsigned address, void *data, unsigned count) result = -EINVAL; perf_count(_pc_protoerrs); - /* compare the received count with the expected count */ + /* compare the received count with the expected count */ + } else if (PKT_COUNT(_dma_buffer) != count) { /* IO returned the wrong number of registers - no point retrying */ result = -EIO; perf_count(_pc_protoerrs); - /* successful read */ + /* successful read */ + } else { /* copy back the result */ @@ -444,13 +464,16 @@ PX4IO_serial::read(unsigned address, void *data, unsigned count) break; } + perf_count(_pc_retries); } sem_post(&_bus_semaphore); - if (result == OK) + if (result == OK) { result = count; + } + return result; } @@ -517,14 +540,16 @@ PX4IO_serial::_wait_complete() /* compute the deadline for a 10ms timeout */ struct timespec abstime; clock_gettime(CLOCK_REALTIME, &abstime); - abstime.tv_nsec += 10*1000*1000; - if (abstime.tv_nsec >= 1000*1000*1000) { + abstime.tv_nsec += 10 * 1000 * 1000; + + if (abstime.tv_nsec >= 1000 * 1000 * 1000) { abstime.tv_sec++; - abstime.tv_nsec -= 1000*1000*1000; + abstime.tv_nsec -= 1000 * 1000 * 1000; } /* wait for the transaction to complete - 64 bytes @ 1.5Mbps ~426µs */ int ret; + for (;;) { ret = sem_timedwait(&_completion_semaphore, &abstime); @@ -539,6 +564,7 @@ PX4IO_serial::_wait_complete() /* check packet CRC - corrupt packet errors mean IO receive CRC error */ uint8_t crc = _dma_buffer.crc; _dma_buffer.crc = 0; + if ((crc != crc_packet(&_dma_buffer)) | (PKT_CODE(_dma_buffer) == PKT_CODE_CORRUPT)) { perf_count(_pc_crcerrs); ret = -EIO; @@ -588,6 +614,7 @@ PX4IO_serial::_do_rx_dma_callback(unsigned status) /* check for packet overrun - this will occur after DMA completes */ uint32_t sr = rSR; + if (sr & (USART_SR_ORE | USART_SR_RXNE)) { (void)rDR; status = DMA_STATUS_TEIF; @@ -607,8 +634,10 @@ PX4IO_serial::_do_rx_dma_callback(unsigned status) int PX4IO_serial::_interrupt(int irq, void *context) { - if (g_interface != nullptr) + if (g_interface != nullptr) { g_interface->_do_interrupt(); + } + return 0; } @@ -619,10 +648,10 @@ PX4IO_serial::_do_interrupt() (void)rDR; /* read DR to clear status */ if (sr & (USART_SR_ORE | /* overrun error - packet was too big for DMA or DMA was too slow */ - USART_SR_NE | /* noise error - we have lost a byte due to noise */ - USART_SR_FE)) { /* framing error - start/stop bit lost or line break */ - - /* + USART_SR_NE | /* noise error - we have lost a byte due to noise */ + USART_SR_FE)) { /* framing error - start/stop bit lost or line break */ + + /* * If we are in the process of listening for something, these are all fatal; * abort the DMA with an error. */ @@ -649,6 +678,7 @@ PX4IO_serial::_do_interrupt() /* verify that the received packet is complete */ size_t length = sizeof(_dma_buffer) - stm32_dmaresidual(_rx_dma); + if ((length < 1) || (length < PKT_SIZE(_dma_buffer))) { perf_count(_pc_badidle); diff --git a/src/drivers/px4io/px4io_uploader.cpp b/src/drivers/px4io/px4io_uploader.cpp index 027253905f..70337c5a0c 100644 --- a/src/drivers/px4io/px4io_uploader.cpp +++ b/src/drivers/px4io/px4io_uploader.cpp @@ -126,8 +126,10 @@ PX4IO_Uploader::upload(const char *filenames[]) /* look for the bootloader for 150 ms */ for (int i = 0; i < 15; i++) { ret = sync(); + if (ret == OK) { break; + } else { usleep(10000); } @@ -143,6 +145,7 @@ PX4IO_Uploader::upload(const char *filenames[]) } struct stat st; + if (stat(filename, &st) != 0) { log("Failed to stat %s - %d\n", filename, (int)errno); tcsetattr(_io_fd, TCSANOW, &t_original); @@ -150,6 +153,7 @@ PX4IO_Uploader::upload(const char *filenames[]) _io_fd = -1; return -errno; } + fw_size = st.st_size; if (_fw_fd == -1) { @@ -180,6 +184,7 @@ PX4IO_Uploader::upload(const char *filenames[]) if (ret == OK) { if (bl_rev <= BL_REV) { log("found bootloader revision: %d", bl_rev); + } else { log("found unsupported bootloader revision %d, exiting", bl_rev); tcsetattr(_io_fd, TCSANOW, &t_original); @@ -205,6 +210,7 @@ PX4IO_Uploader::upload(const char *filenames[]) if (bl_rev <= 2) { ret = verify_rev2(fw_size); + } else { /* verify rev 3 and higher. Every version *needs* to be verified. */ ret = verify_rev3(fw_size); @@ -240,7 +246,7 @@ PX4IO_Uploader::upload(const char *filenames[]) // sleep for enough time for the IO chip to boot. This makes // forceupdate more reliably startup IO again after update - up_udelay(100*1000); + up_udelay(100 * 1000); return ret; } @@ -274,12 +280,15 @@ int PX4IO_Uploader::recv_bytes(uint8_t *p, unsigned count) { int ret = OK; + while (count--) { ret = recv_byte_with_timeout(p++, 5000); - if (ret != OK) + if (ret != OK) { break; + } } + return ret; } @@ -296,9 +305,11 @@ PX4IO_Uploader::drain() ret = recv_byte_with_timeout(&c, 40); #ifdef UDEBUG + if (ret == OK) { log("discard 0x%02x", c); } + #endif } while (ret == OK); } @@ -309,8 +320,11 @@ PX4IO_Uploader::send(uint8_t c) #ifdef UDEBUG log("send 0x%02x", c); #endif - if (write(_io_fd, &c, 1) != 1) + + if (write(_io_fd, &c, 1) != 1) { return -errno; + } + return OK; } @@ -318,11 +332,15 @@ int PX4IO_Uploader::send(uint8_t *p, unsigned count) { int ret; + while (count--) { ret = send(*p++); - if (ret != OK) + + if (ret != OK) { break; + } } + return ret; } @@ -334,13 +352,15 @@ PX4IO_Uploader::get_sync(unsigned timeout) ret = recv_byte_with_timeout(c, timeout); - if (ret != OK) + if (ret != OK) { return ret; + } ret = recv_byte_with_timeout(c + 1, timeout); - if (ret != OK) + if (ret != OK) { return ret; + } if ((c[0] != PROTO_INSYNC) || (c[1] != PROTO_OK)) { log("bad sync 0x%02x,0x%02x", c[0], c[1]); @@ -356,8 +376,9 @@ PX4IO_Uploader::sync() drain(); /* complete any pending program operation */ - for (unsigned i = 0; i < (PROG_MULTI_MAX + 6); i++) + for (unsigned i = 0; i < (PROG_MULTI_MAX + 6); i++) { send(0); + } send(PROTO_GET_SYNC); send(PROTO_EOC); @@ -375,8 +396,9 @@ PX4IO_Uploader::get_info(int param, uint32_t &val) ret = recv_bytes((uint8_t *)&val, sizeof(val)); - if (ret != OK) + if (ret != OK) { return ret; + } return get_sync(); } @@ -395,14 +417,17 @@ static int read_with_retry(int fd, void *buf, size_t n) { int ret; uint8_t retries = 0; + do { ret = read(fd, buf, n); } while (ret == -1 && retries++ < 100); + if (retries != 0) { printf("read of %u bytes needed %u retries\n", (unsigned)n, (unsigned)retries); } + return ret; } @@ -415,6 +440,7 @@ PX4IO_Uploader::program(size_t fw_size) size_t sent = 0; file_buf = new uint8_t[PROG_MULTI_MAX]; + if (!file_buf) { log("Can't allocate program buffer"); return -ENOMEM; @@ -430,13 +456,15 @@ PX4IO_Uploader::program(size_t fw_size) while (sent < fw_size) { /* get more bytes to program */ size_t n = fw_size - sent; + if (n > PROG_MULTI_MAX) { n = PROG_MULTI_MAX; } + count = read_with_retry(_fw_fd, file_buf, n); if (count != (ssize_t)n) { - log("firmware read of %u bytes at %u failed -> %d errno %d", + log("firmware read of %u bytes at %u failed -> %d errno %d", (unsigned)n, (unsigned)sent, (int)count, @@ -478,32 +506,37 @@ PX4IO_Uploader::verify_rev2(size_t fw_size) send(PROTO_EOC); ret = get_sync(); - if (ret != OK) + if (ret != OK) { return ret; + } while (sent < fw_size) { /* get more bytes to verify */ size_t n = fw_size - sent; + if (n > sizeof(file_buf)) { n = sizeof(file_buf); } + count = read_with_retry(_fw_fd, file_buf, n); if (count != (ssize_t)n) { - log("firmware read of %u bytes at %u failed -> %d errno %d", + log("firmware read of %u bytes at %u failed -> %d errno %d", (unsigned)n, (unsigned)sent, (int)count, (int)errno); } - if (count == 0) + if (count == 0) { break; + } sent += count; - if (count < 0) + if (count < 0) { return -errno; + } ASSERT((count % 4) == 0); @@ -564,13 +597,15 @@ PX4IO_Uploader::verify_rev3(size_t fw_size_local) /* read through the firmware file again and calculate the checksum*/ while (bytes_read < fw_size_local) { size_t n = fw_size_local - bytes_read; + if (n > sizeof(file_buf)) { n = sizeof(file_buf); } + count = read_with_retry(_fw_fd, file_buf, n); if (count != (ssize_t)n) { - log("firmware read of %u bytes at %u failed -> %d errno %d", + log("firmware read of %u bytes at %u failed -> %d errno %d", (unsigned)n, (unsigned)bytes_read, (int)count, @@ -581,9 +616,11 @@ PX4IO_Uploader::verify_rev3(size_t fw_size_local) if (count == 0) { break; } + /* stop if the file cannot be read */ - if (count < 0) + if (count < 0) { return -errno; + } /* calculate crc32 sum */ sum = crc32part((uint8_t *)&file_buf, sizeof(file_buf), sum); @@ -601,7 +638,7 @@ PX4IO_Uploader::verify_rev3(size_t fw_size_local) send(PROTO_GET_CRC); send(PROTO_EOC); - ret = recv_bytes((uint8_t*)(&crc), sizeof(crc)); + ret = recv_bytes((uint8_t *)(&crc), sizeof(crc)); if (ret != OK) { log("did not receive CRC checksum"); @@ -621,7 +658,7 @@ int PX4IO_Uploader::reboot() { send(PROTO_REBOOT); - up_udelay(100*1000); // Ensure the farend is in wait for char. + up_udelay(100 * 1000); // Ensure the farend is in wait for char. send(PROTO_EOC); return OK;