[PX4IO/PWM driver] Added trim values to the PWM output drivers

This commit is contained in:
Bartosz Wawrzacz
2016-12-10 12:56:39 +01:00
committed by Lorenz Meier
parent 4494182bfc
commit 619efa7b45
12 changed files with 222 additions and 41 deletions
+34 -24
View File
@@ -111,6 +111,11 @@ __BEGIN_DECLS
*/
#define PWM_DEFAULT_MAX 2000
/**
* Default trim PWM in us
*/
#define PWM_DEFAULT_TRIM 0
/**
* Lowest PWM allowed as the maximum PWM
*/
@@ -217,57 +222,62 @@ struct pwm_output_rc_config {
/** get the maximum PWM value the output will send */
#define PWM_SERVO_GET_MAX_PWM _PX4_IOC(_PWM_SERVO_BASE, 19)
/** set the maximum PWM value the output will send */
#define PWM_SERVO_SET_TRIM_PWM _PX4_IOC(_PWM_SERVO_BASE, 20)
/** get the maximum PWM value the output will send */
#define PWM_SERVO_GET_TRIM_PWM _PX4_IOC(_PWM_SERVO_BASE, 21)
/** set the number of servos in (unsigned)arg - allows change of
* split between servos and GPIO */
#define PWM_SERVO_SET_COUNT _PX4_IOC(_PWM_SERVO_BASE, 20)
#define PWM_SERVO_SET_COUNT _PX4_IOC(_PWM_SERVO_BASE, 22)
/** set the lockdown override flag to enable outputs in HIL */
#define PWM_SERVO_SET_DISABLE_LOCKDOWN _PX4_IOC(_PWM_SERVO_BASE, 21)
#define PWM_SERVO_SET_DISABLE_LOCKDOWN _PX4_IOC(_PWM_SERVO_BASE, 23)
/** get the lockdown override flag to enable outputs in HIL */
#define PWM_SERVO_GET_DISABLE_LOCKDOWN _PX4_IOC(_PWM_SERVO_BASE, 22)
#define PWM_SERVO_GET_DISABLE_LOCKDOWN _PX4_IOC(_PWM_SERVO_BASE, 24)
/** force safety switch off (to disable use of safety switch) */
#define PWM_SERVO_SET_FORCE_SAFETY_OFF _PX4_IOC(_PWM_SERVO_BASE, 23)
#define PWM_SERVO_SET_FORCE_SAFETY_OFF _PX4_IOC(_PWM_SERVO_BASE, 25)
/** force failsafe mode (failsafe values are set immediately even if failsafe condition not met) */
#define PWM_SERVO_SET_FORCE_FAILSAFE _PX4_IOC(_PWM_SERVO_BASE, 24)
#define PWM_SERVO_SET_FORCE_FAILSAFE _PX4_IOC(_PWM_SERVO_BASE, 26)
/** make failsafe non-recoverable (termination) if it occurs */
#define PWM_SERVO_SET_TERMINATION_FAILSAFE _PX4_IOC(_PWM_SERVO_BASE, 25)
#define PWM_SERVO_SET_TERMINATION_FAILSAFE _PX4_IOC(_PWM_SERVO_BASE, 27)
/** force safety switch on (to enable use of safety switch) */
#define PWM_SERVO_SET_FORCE_SAFETY_ON _PX4_IOC(_PWM_SERVO_BASE, 26)
#define PWM_SERVO_SET_FORCE_SAFETY_ON _PX4_IOC(_PWM_SERVO_BASE, 28)
/** set RC config for a channel. This takes a pointer to pwm_output_rc_config */
#define PWM_SERVO_SET_RC_CONFIG _PX4_IOC(_PWM_SERVO_BASE, 27)
#define PWM_SERVO_SET_RC_CONFIG _PX4_IOC(_PWM_SERVO_BASE, 29)
/** set the 'OVERRIDE OK' bit, which allows for RC control on FMU loss */
#define PWM_SERVO_SET_OVERRIDE_OK _PX4_IOC(_PWM_SERVO_BASE, 28)
#define PWM_SERVO_SET_OVERRIDE_OK _PX4_IOC(_PWM_SERVO_BASE, 30)
/** clear the 'OVERRIDE OK' bit, which allows for RC control on FMU loss */
#define PWM_SERVO_CLEAR_OVERRIDE_OK _PX4_IOC(_PWM_SERVO_BASE, 29)
#define PWM_SERVO_CLEAR_OVERRIDE_OK _PX4_IOC(_PWM_SERVO_BASE, 31)
/** setup OVERRIDE_IMMEDIATE behaviour on FMU fail */
#define PWM_SERVO_SET_OVERRIDE_IMMEDIATE _PX4_IOC(_PWM_SERVO_BASE, 30)
#define PWM_SERVO_SET_OVERRIDE_IMMEDIATE _PX4_IOC(_PWM_SERVO_BASE, 32)
/** set SBUS output frame rate in Hz */
#define PWM_SERVO_SET_SBUS_RATE _PX4_IOC(_PWM_SERVO_BASE, 31)
#define PWM_SERVO_SET_SBUS_RATE _PX4_IOC(_PWM_SERVO_BASE, 33)
/** set auxillary output mode. These correspond to enum Mode in px4fmu/fmu.cpp */
#define PWM_SERVO_MODE_NONE 0
#define PWM_SERVO_MODE_1PWM 1
#define PWM_SERVO_MODE_2PWM 2
#define PWM_SERVO_MODE_2PWM2CAP 3
#define PWM_SERVO_MODE_3PWM 4
#define PWM_SERVO_MODE_3PWM1CAP 5
#define PWM_SERVO_MODE_4PWM 6
#define PWM_SERVO_MODE_6PWM 7
#define PWM_SERVO_MODE_8PWM 8
#define PWM_SERVO_MODE_4CAP 9
#define PWM_SERVO_MODE_5CAP 10
#define PWM_SERVO_MODE_6CAP 11
#define PWM_SERVO_SET_MODE _PX4_IOC(_PWM_SERVO_BASE, 32)
#define PWM_SERVO_MODE_2PWM 1
#define PWM_SERVO_MODE_2PWM2CAP 2
#define PWM_SERVO_MODE_3PWM 3
#define PWM_SERVO_MODE_3PWM1CAP 4
#define PWM_SERVO_MODE_4PWM 5
#define PWM_SERVO_MODE_6PWM 6
#define PWM_SERVO_MODE_8PWM 7
#define PWM_SERVO_MODE_4CAP 8
#define PWM_SERVO_MODE_5CAP 9
#define PWM_SERVO_MODE_6CAP 10
#define PWM_SERVO_SET_MODE _PX4_IOC(_PWM_SERVO_BASE, 34)
/*
*
+3 -1
View File
@@ -426,18 +426,20 @@ void task_main(int argc, char *argv[])
uint16_t disarmed_pwm[4];
uint16_t min_pwm[4];
uint16_t max_pwm[4];
uint16_t trim_pwm[4];
for (unsigned int i = 0; i < 4; i++) {
disarmed_pwm[i] = _pwm_disarmed;
min_pwm[i] = _pwm_min;
max_pwm[i] = _pwm_max;
trim_pwm[i] = 0;
}
uint16_t pwm[4];
// TODO FIXME: pre-armed seems broken
pwm_limit_calc(_armed.armed, false/*_armed.prearmed*/, _outputs.noutputs, reverse_mask,
disarmed_pwm, min_pwm, max_pwm, _outputs.output, pwm, &_pwm_limit);
disarmed_pwm, min_pwm, max_pwm, trim_pwm, _outputs.output, pwm, &_pwm_limit);
send_outputs_mavlink(pwm, 4);
+43 -1
View File
@@ -220,6 +220,7 @@ private:
uint16_t _disarmed_pwm[_max_actuators];
uint16_t _min_pwm[_max_actuators];
uint16_t _max_pwm[_max_actuators];
uint16_t _trim_pwm[_max_actuators];
uint16_t _reverse_pwm_mask;
unsigned _num_failsafe_set;
unsigned _num_disarmed_set;
@@ -342,6 +343,7 @@ PX4FMU::PX4FMU() :
for (unsigned i = 0; i < _max_actuators; i++) {
_min_pwm[i] = PWM_DEFAULT_MIN;
_max_pwm[i] = PWM_DEFAULT_MAX;
_trim_pwm[i] = PWM_DEFAULT_TRIM;
}
_control_topics[0] = ORB_ID(actuator_controls_0);
@@ -1115,7 +1117,7 @@ PX4FMU::cycle()
/* the PWM limit call takes care of out of band errors, NaN and constrains */
pwm_limit_calc(_throttle_armed, arm_nothrottle(), num_outputs, _reverse_pwm_mask,
_disarmed_pwm, _min_pwm, _max_pwm, outputs, pwm_limited, &_pwm_limit);
_trim_pwm, _disarmed_pwm, _min_pwm, _max_pwm, outputs, pwm_limited, &_pwm_limit);
/* overwrite outputs in case of lockdown with disarmed PWM values */
@@ -1881,6 +1883,46 @@ PX4FMU::pwm_ioctl(file *filp, int cmd, unsigned long arg)
break;
}
case PWM_SERVO_SET_TRIM_PWM: {
struct pwm_output_values *pwm = (struct pwm_output_values *)arg;
/* discard if too many values are sent */
if (pwm->channel_count > _max_actuators) {
ret = -EINVAL;
break;
}
for (unsigned i = 0; i < pwm->channel_count; i++) {
if (pwm->values[i] == 0) {
/* allow 0 - turns the trim option off */
_trim_pwm[i] = 0;
} else if (pwm->values[i] < PWM_LOWEST_MAX) {
_trim_pwm[i] = PWM_LOWEST_MAX;
} else if (pwm->values[i] > PWM_HIGHEST_MAX) {
_trim_pwm[i] = PWM_HIGHEST_MAX;
} else {
_trim_pwm[i] = pwm->values[i];
}
}
break;
}
case PWM_SERVO_GET_TRIM_PWM: {
struct pwm_output_values *pwm = (struct pwm_output_values *)arg;
for (unsigned i = 0; i < _max_actuators; i++) {
pwm->values[i] = _trim_pwm[i];
}
pwm->channel_count = _max_actuators;
arg = (unsigned long)&pwm;
break;
}
#if defined(BOARD_HAS_PWM) && BOARD_HAS_PWM >= 8
case PWM_SERVO_SET(7):
+24
View File
@@ -2688,6 +2688,30 @@ PX4IO::ioctl(file *filep, int cmd, unsigned long arg)
break;
case PWM_SERVO_SET_TRIM_PWM: {
struct pwm_output_values *pwm = (struct pwm_output_values *)arg;
if (pwm->channel_count > _max_actuators)
/* fail with error */
{
return -E2BIG;
}
/* copy values to registers in IO */
ret = io_reg_set(PX4IO_PAGE_CONTROL_TRIM_PWM, 0, pwm->values, pwm->channel_count);
break;
}
case PWM_SERVO_GET_TRIM_PWM:
ret = io_reg_get(PX4IO_PAGE_CONTROL_TRIM_PWM, 0, (uint16_t *)arg, _max_actuators);
if (ret != OK) {
ret = -EIO;
}
break;
case PWM_SERVO_GET_COUNT:
*(unsigned *)arg = _max_actuators;
break;