mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-11-01 08:11:36 +08:00
FMU: Ensure an all-low output set on boot with direct start of the PWM sequence
This commit is contained in:
+88
-50
@@ -120,6 +120,7 @@ public:
|
|||||||
virtual int init();
|
virtual int init();
|
||||||
|
|
||||||
int set_mode(Mode mode);
|
int set_mode(Mode mode);
|
||||||
|
Mode get_mode() { return _mode; }
|
||||||
|
|
||||||
int set_pwm_alt_rate(unsigned rate);
|
int set_pwm_alt_rate(unsigned rate);
|
||||||
int set_pwm_alt_channels(uint32_t channels);
|
int set_pwm_alt_channels(uint32_t channels);
|
||||||
@@ -173,6 +174,8 @@ private:
|
|||||||
volatile bool _initialized;
|
volatile bool _initialized;
|
||||||
bool _throttle_armed;
|
bool _throttle_armed;
|
||||||
bool _pwm_on;
|
bool _pwm_on;
|
||||||
|
uint32_t _pwm_mask;
|
||||||
|
bool _pwm_initialized;
|
||||||
|
|
||||||
MixerGroup *_mixers;
|
MixerGroup *_mixers;
|
||||||
|
|
||||||
@@ -205,13 +208,15 @@ private:
|
|||||||
uint8_t control_group,
|
uint8_t control_group,
|
||||||
uint8_t control_index,
|
uint8_t control_index,
|
||||||
float &input);
|
float &input);
|
||||||
void capture_callback(uint32_t chan_index,
|
void capture_callback(uint32_t chan_index,
|
||||||
hrt_abstime edge_time, uint32_t edge_state, uint32_t overflow);
|
hrt_abstime edge_time, uint32_t edge_state, uint32_t overflow);
|
||||||
void subscribe();
|
void subscribe();
|
||||||
int set_pwm_rate(unsigned rate_map, unsigned default_rate, unsigned alt_rate);
|
int set_pwm_rate(unsigned rate_map, unsigned default_rate, unsigned alt_rate);
|
||||||
int pwm_ioctl(file *filp, int cmd, unsigned long arg);
|
int pwm_ioctl(file *filp, int cmd, unsigned long arg);
|
||||||
void update_pwm_rev_mask();
|
void update_pwm_rev_mask();
|
||||||
void publish_pwm_outputs(uint16_t *values, size_t numvalues);
|
void publish_pwm_outputs(uint16_t *values, size_t numvalues);
|
||||||
|
void update_pwm_out_state(bool on);
|
||||||
|
void pwm_output_set(unsigned i, unsigned value);
|
||||||
|
|
||||||
struct GPIOConfig {
|
struct GPIOConfig {
|
||||||
uint32_t input;
|
uint32_t input;
|
||||||
@@ -328,6 +333,8 @@ PX4FMU::PX4FMU() :
|
|||||||
_initialized(false),
|
_initialized(false),
|
||||||
_throttle_armed(false),
|
_throttle_armed(false),
|
||||||
_pwm_on(false),
|
_pwm_on(false),
|
||||||
|
_pwm_mask(0),
|
||||||
|
_pwm_initialized(false),
|
||||||
_mixers(nullptr),
|
_mixers(nullptr),
|
||||||
_groups_required(0),
|
_groups_required(0),
|
||||||
_groups_subscribed(0),
|
_groups_subscribed(0),
|
||||||
@@ -418,6 +425,8 @@ PX4FMU::init()
|
|||||||
int
|
int
|
||||||
PX4FMU::set_mode(Mode mode)
|
PX4FMU::set_mode(Mode mode)
|
||||||
{
|
{
|
||||||
|
unsigned old_mask = _pwm_mask;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Configure for PWM output.
|
* Configure for PWM output.
|
||||||
*
|
*
|
||||||
@@ -439,10 +448,8 @@ PX4FMU::set_mode(Mode mode)
|
|||||||
_pwm_default_rate = 50;
|
_pwm_default_rate = 50;
|
||||||
_pwm_alt_rate = 50;
|
_pwm_alt_rate = 50;
|
||||||
_pwm_alt_rate_channels = 0;
|
_pwm_alt_rate_channels = 0;
|
||||||
|
_pwm_mask = 0x3;
|
||||||
/* XXX magic numbers */
|
_pwm_initialized = false;
|
||||||
up_pwm_servo_init(0x3);
|
|
||||||
set_pwm_rate(_pwm_alt_rate_channels, _pwm_default_rate, _pwm_alt_rate);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -458,10 +465,8 @@ PX4FMU::set_mode(Mode mode)
|
|||||||
_pwm_default_rate = 50;
|
_pwm_default_rate = 50;
|
||||||
_pwm_alt_rate = 50;
|
_pwm_alt_rate = 50;
|
||||||
_pwm_alt_rate_channels = 0;
|
_pwm_alt_rate_channels = 0;
|
||||||
|
_pwm_mask = 0x7;
|
||||||
/* XXX magic numbers */
|
_pwm_initialized = false;
|
||||||
up_pwm_servo_init(0x7);
|
|
||||||
set_pwm_rate(_pwm_alt_rate_channels, _pwm_default_rate, _pwm_alt_rate);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MODE_4PWM: // v1 or v2 multi-port as 4 PWM outs
|
case MODE_4PWM: // v1 or v2 multi-port as 4 PWM outs
|
||||||
@@ -471,10 +476,8 @@ PX4FMU::set_mode(Mode mode)
|
|||||||
_pwm_default_rate = 50;
|
_pwm_default_rate = 50;
|
||||||
_pwm_alt_rate = 50;
|
_pwm_alt_rate = 50;
|
||||||
_pwm_alt_rate_channels = 0;
|
_pwm_alt_rate_channels = 0;
|
||||||
|
_pwm_mask = 0xf;
|
||||||
/* XXX magic numbers */
|
_pwm_initialized = false;
|
||||||
up_pwm_servo_init(0xf);
|
|
||||||
set_pwm_rate(_pwm_alt_rate_channels, _pwm_default_rate, _pwm_alt_rate);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -485,10 +488,8 @@ PX4FMU::set_mode(Mode mode)
|
|||||||
_pwm_default_rate = 50;
|
_pwm_default_rate = 50;
|
||||||
_pwm_alt_rate = 50;
|
_pwm_alt_rate = 50;
|
||||||
_pwm_alt_rate_channels = 0;
|
_pwm_alt_rate_channels = 0;
|
||||||
|
_pwm_mask = 0x3f;
|
||||||
/* XXX magic numbers */
|
_pwm_initialized = false;
|
||||||
up_pwm_servo_init(0x3f);
|
|
||||||
set_pwm_rate(_pwm_alt_rate_channels, _pwm_default_rate, _pwm_alt_rate);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -500,10 +501,8 @@ PX4FMU::set_mode(Mode mode)
|
|||||||
_pwm_default_rate = 50;
|
_pwm_default_rate = 50;
|
||||||
_pwm_alt_rate = 50;
|
_pwm_alt_rate = 50;
|
||||||
_pwm_alt_rate_channels = 0;
|
_pwm_alt_rate_channels = 0;
|
||||||
|
_pwm_mask = 0xff;
|
||||||
/* XXX magic numbers */
|
_pwm_initialized = false;
|
||||||
up_pwm_servo_init(0xff);
|
|
||||||
set_pwm_rate(_pwm_alt_rate_channels, _pwm_default_rate, _pwm_alt_rate);
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -513,9 +512,13 @@ PX4FMU::set_mode(Mode mode)
|
|||||||
_pwm_default_rate = 10; /* artificially reduced output rate */
|
_pwm_default_rate = 10; /* artificially reduced output rate */
|
||||||
_pwm_alt_rate = 10;
|
_pwm_alt_rate = 10;
|
||||||
_pwm_alt_rate_channels = 0;
|
_pwm_alt_rate_channels = 0;
|
||||||
|
_pwm_mask = 0x0;
|
||||||
|
_pwm_initialized = false;
|
||||||
|
|
||||||
/* disable servo outputs - no need to set rates */
|
if (old_mask != _pwm_mask) {
|
||||||
up_pwm_servo_deinit();
|
/* disable servo outputs - no need to set rates */
|
||||||
|
up_pwm_servo_deinit();
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -688,15 +691,18 @@ PX4FMU::capture_trampoline(void *context, uint32_t chan_index,
|
|||||||
dev->capture_callback(chan_index, edge_time, edge_state, overflow);
|
dev->capture_callback(chan_index, edge_time, edge_state, overflow);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PX4FMU::capture_callback(uint32_t chan_index,
|
void
|
||||||
hrt_abstime edge_time, uint32_t edge_state, uint32_t overflow)
|
PX4FMU::capture_callback(uint32_t chan_index,
|
||||||
|
hrt_abstime edge_time, uint32_t edge_state, uint32_t overflow)
|
||||||
{
|
{
|
||||||
fprintf(stdout, "FMU: Capture chan:%d time:%lld state:%d overflow:%d\n", chan_index, edge_time, edge_state, overflow);
|
fprintf(stdout, "FMU: Capture chan:%d time:%lld state:%d overflow:%d\n", chan_index, edge_time, edge_state, overflow);
|
||||||
}
|
}
|
||||||
void PX4FMU::fill_rc_in(uint16_t raw_rc_count,
|
|
||||||
uint16_t raw_rc_values[input_rc_s::RC_INPUT_MAX_CHANNELS],
|
void
|
||||||
hrt_abstime now, bool frame_drop, bool failsafe,
|
PX4FMU::fill_rc_in(uint16_t raw_rc_count,
|
||||||
unsigned frame_drops, int rssi = -1)
|
uint16_t raw_rc_values[input_rc_s::RC_INPUT_MAX_CHANNELS],
|
||||||
|
hrt_abstime now, bool frame_drop, bool failsafe,
|
||||||
|
unsigned frame_drops, int rssi = -1)
|
||||||
{
|
{
|
||||||
// fill rc_in struct for publishing
|
// fill rc_in struct for publishing
|
||||||
_rc_in.channel_count = raw_rc_count;
|
_rc_in.channel_count = raw_rc_count;
|
||||||
@@ -747,13 +753,33 @@ void PX4FMU::rc_io_invert(bool invert)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
PX4FMU::pwm_output_set(unsigned i, unsigned value)
|
||||||
|
{
|
||||||
|
if (_pwm_initialized) {
|
||||||
|
up_pwm_servo_set(i, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PX4FMU::update_pwm_out_state(bool on)
|
||||||
|
{
|
||||||
|
if (on && !_pwm_initialized && _pwm_mask != 0) {
|
||||||
|
up_pwm_servo_init(_pwm_mask);
|
||||||
|
set_pwm_rate(_pwm_alt_rate_channels, _pwm_default_rate, _pwm_alt_rate);
|
||||||
|
_pwm_initialized = true;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
_pwm_initialized = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
up_pwm_servo_arm(on);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PX4FMU::cycle()
|
PX4FMU::cycle()
|
||||||
{
|
{
|
||||||
if (!_initialized) {
|
if (!_initialized) {
|
||||||
/* reset GPIOs */
|
|
||||||
gpio_reset();
|
|
||||||
|
|
||||||
/* force a reset of the update rate */
|
/* force a reset of the update rate */
|
||||||
_current_update_rate = 0;
|
_current_update_rate = 0;
|
||||||
|
|
||||||
@@ -913,7 +939,7 @@ PX4FMU::cycle()
|
|||||||
|
|
||||||
/* output to the servos */
|
/* output to the servos */
|
||||||
for (size_t i = 0; i < num_outputs; i++) {
|
for (size_t i = 0; i < num_outputs; i++) {
|
||||||
up_pwm_servo_set(i, pwm_limited[i]);
|
pwm_output_set(i, pwm_limited[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
publish_pwm_outputs(pwm_limited, num_outputs);
|
publish_pwm_outputs(pwm_limited, num_outputs);
|
||||||
@@ -935,7 +961,8 @@ PX4FMU::cycle()
|
|||||||
|
|
||||||
if (_pwm_on != pwm_on) {
|
if (_pwm_on != pwm_on) {
|
||||||
_pwm_on = pwm_on;
|
_pwm_on = pwm_on;
|
||||||
up_pwm_servo_arm(pwm_on);
|
|
||||||
|
update_pwm_out_state(pwm_on);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1018,7 +1045,7 @@ PX4FMU::cycle()
|
|||||||
case RC_SCAN_DSM:
|
case RC_SCAN_DSM:
|
||||||
if (_rc_scan_begin == 0) {
|
if (_rc_scan_begin == 0) {
|
||||||
_rc_scan_begin = now;
|
_rc_scan_begin = now;
|
||||||
// // Configure serial port for DSM
|
// Configure serial port for DSM
|
||||||
dsm_config(_rcs_fd);
|
dsm_config(_rcs_fd);
|
||||||
rc_io_invert(false);
|
rc_io_invert(false);
|
||||||
|
|
||||||
@@ -1049,7 +1076,7 @@ PX4FMU::cycle()
|
|||||||
case RC_SCAN_ST24:
|
case RC_SCAN_ST24:
|
||||||
if (_rc_scan_begin == 0) {
|
if (_rc_scan_begin == 0) {
|
||||||
_rc_scan_begin = now;
|
_rc_scan_begin = now;
|
||||||
// // Configure serial port for DSM
|
// Configure serial port for DSM
|
||||||
dsm_config(_rcs_fd);
|
dsm_config(_rcs_fd);
|
||||||
rc_io_invert(false);
|
rc_io_invert(false);
|
||||||
|
|
||||||
@@ -1088,7 +1115,7 @@ PX4FMU::cycle()
|
|||||||
case RC_SCAN_SUMD:
|
case RC_SCAN_SUMD:
|
||||||
if (_rc_scan_begin == 0) {
|
if (_rc_scan_begin == 0) {
|
||||||
_rc_scan_begin = now;
|
_rc_scan_begin = now;
|
||||||
// // Configure serial port for DSM
|
// Configure serial port for DSM
|
||||||
dsm_config(_rcs_fd);
|
dsm_config(_rcs_fd);
|
||||||
rc_io_invert(false);
|
rc_io_invert(false);
|
||||||
|
|
||||||
@@ -1313,7 +1340,7 @@ PX4FMU::pwm_ioctl(file *filp, int cmd, unsigned long arg)
|
|||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case PWM_SERVO_ARM:
|
case PWM_SERVO_ARM:
|
||||||
up_pwm_servo_arm(true);
|
update_pwm_out_state(true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PWM_SERVO_SET_ARM_OK:
|
case PWM_SERVO_SET_ARM_OK:
|
||||||
@@ -1324,7 +1351,7 @@ PX4FMU::pwm_ioctl(file *filp, int cmd, unsigned long arg)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PWM_SERVO_DISARM:
|
case PWM_SERVO_DISARM:
|
||||||
up_pwm_servo_arm(false);
|
update_pwm_out_state(false);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PWM_SERVO_GET_DEFAULT_UPDATE_RATE:
|
case PWM_SERVO_GET_DEFAULT_UPDATE_RATE:
|
||||||
@@ -2372,9 +2399,7 @@ fmu_new_mode(PortMode new_mode)
|
|||||||
{
|
{
|
||||||
uint32_t gpio_bits;
|
uint32_t gpio_bits;
|
||||||
PX4FMU::Mode servo_mode;
|
PX4FMU::Mode servo_mode;
|
||||||
|
bool mode_with_input = false;
|
||||||
/* reset to all-inputs */
|
|
||||||
g_fmu->ioctl(0, GPIO_RESET, 0);
|
|
||||||
|
|
||||||
gpio_bits = 0;
|
gpio_bits = 0;
|
||||||
servo_mode = PX4FMU::MODE_NONE;
|
servo_mode = PX4FMU::MODE_NONE;
|
||||||
@@ -2382,7 +2407,6 @@ fmu_new_mode(PortMode new_mode)
|
|||||||
switch (new_mode) {
|
switch (new_mode) {
|
||||||
case PORT_FULL_GPIO:
|
case PORT_FULL_GPIO:
|
||||||
case PORT_MODE_UNSET:
|
case PORT_MODE_UNSET:
|
||||||
/* nothing more to do here */
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PORT_FULL_PWM:
|
case PORT_FULL_PWM:
|
||||||
@@ -2413,6 +2437,7 @@ fmu_new_mode(PortMode new_mode)
|
|||||||
case PORT_PWM3CAP1:
|
case PORT_PWM3CAP1:
|
||||||
/* select 3-pin PWM mode 1 capture */
|
/* select 3-pin PWM mode 1 capture */
|
||||||
servo_mode = PX4FMU::MODE_3PWM1CAP;
|
servo_mode = PX4FMU::MODE_3PWM1CAP;
|
||||||
|
mode_with_input = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PORT_PWM2:
|
case PORT_PWM2:
|
||||||
@@ -2423,6 +2448,7 @@ fmu_new_mode(PortMode new_mode)
|
|||||||
case PORT_PWM2CAP2:
|
case PORT_PWM2CAP2:
|
||||||
/* select 2-pin PWM mode 2 capture */
|
/* select 2-pin PWM mode 2 capture */
|
||||||
servo_mode = PX4FMU::MODE_2PWM2CAP;
|
servo_mode = PX4FMU::MODE_2PWM2CAP;
|
||||||
|
mode_with_input = true;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -2432,11 +2458,13 @@ fmu_new_mode(PortMode new_mode)
|
|||||||
case PORT_FULL_SERIAL:
|
case PORT_FULL_SERIAL:
|
||||||
/* set all multi-GPIOs to serial mode */
|
/* set all multi-GPIOs to serial mode */
|
||||||
gpio_bits = GPIO_MULTI_1 | GPIO_MULTI_2 | GPIO_MULTI_3 | GPIO_MULTI_4;
|
gpio_bits = GPIO_MULTI_1 | GPIO_MULTI_2 | GPIO_MULTI_3 | GPIO_MULTI_4;
|
||||||
|
mode_with_input = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PORT_GPIO_AND_SERIAL:
|
case PORT_GPIO_AND_SERIAL:
|
||||||
/* set RX/TX multi-GPIOs to serial mode */
|
/* set RX/TX multi-GPIOs to serial mode */
|
||||||
gpio_bits = GPIO_MULTI_3 | GPIO_MULTI_4;
|
gpio_bits = GPIO_MULTI_3 | GPIO_MULTI_4;
|
||||||
|
mode_with_input = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PORT_PWM_AND_SERIAL:
|
case PORT_PWM_AND_SERIAL:
|
||||||
@@ -2444,11 +2472,13 @@ fmu_new_mode(PortMode new_mode)
|
|||||||
servo_mode = PX4FMU::MODE_2PWM;
|
servo_mode = PX4FMU::MODE_2PWM;
|
||||||
/* set RX/TX multi-GPIOs to serial mode */
|
/* set RX/TX multi-GPIOs to serial mode */
|
||||||
gpio_bits = GPIO_MULTI_3 | GPIO_MULTI_4;
|
gpio_bits = GPIO_MULTI_3 | GPIO_MULTI_4;
|
||||||
|
mode_with_input = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PORT_PWM_AND_GPIO:
|
case PORT_PWM_AND_GPIO:
|
||||||
/* select 2-pin PWM mode */
|
/* select 2-pin PWM mode */
|
||||||
servo_mode = PX4FMU::MODE_2PWM;
|
servo_mode = PX4FMU::MODE_2PWM;
|
||||||
|
mode_with_input = true;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -2456,13 +2486,21 @@ fmu_new_mode(PortMode new_mode)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* adjust GPIO config for serial mode(s) */
|
if (servo_mode != g_fmu->get_mode()) {
|
||||||
if (gpio_bits != 0) {
|
|
||||||
g_fmu->ioctl(0, GPIO_SET_ALT_1, gpio_bits);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (re)set the PWM output mode */
|
/* reset to all-inputs */
|
||||||
g_fmu->set_mode(servo_mode);
|
if (mode_with_input) {
|
||||||
|
g_fmu->ioctl(0, GPIO_RESET, 0);
|
||||||
|
|
||||||
|
/* adjust GPIO config for serial mode(s) */
|
||||||
|
if (gpio_bits != 0) {
|
||||||
|
g_fmu->ioctl(0, GPIO_SET_ALT_1, gpio_bits);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (re)set the PWM output mode */
|
||||||
|
g_fmu->set_mode(servo_mode);
|
||||||
|
}
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user