Browse Source

fix pwm: only update oneshot timers owned by the current pwm_out instance

This fixes the case where oneshot was enabled with multi-instance pwm_out,
triggering oneshot updates too close to each other and as a result could
lead to spinning motors while disarmed.
master
Beat Küng 3 years ago committed by Daniel Agar
parent
commit
da1df5352c
  1. 2
      platforms/nuttx/src/px4/nxp/imxrt/include/px4_arch/io_timer.h
  2. 4
      platforms/nuttx/src/px4/nxp/imxrt/io_pins/io_timer.c
  3. 4
      platforms/nuttx/src/px4/nxp/imxrt/io_pins/pwm_servo.c
  4. 2
      platforms/nuttx/src/px4/nxp/kinetis/include/px4_arch/io_timer.h
  5. 4
      platforms/nuttx/src/px4/nxp/kinetis/io_pins/io_timer.c
  6. 4
      platforms/nuttx/src/px4/nxp/kinetis/io_pins/pwm_servo.c
  7. 2
      platforms/nuttx/src/px4/nxp/s32k1xx/include/px4_arch/io_timer.h
  8. 4
      platforms/nuttx/src/px4/nxp/s32k1xx/io_pins/io_timer.c
  9. 4
      platforms/nuttx/src/px4/nxp/s32k1xx/io_pins/pwm_servo.c
  10. 2
      platforms/nuttx/src/px4/stm/stm32_common/include/px4_arch/io_timer.h
  11. 4
      platforms/nuttx/src/px4/stm/stm32_common/io_pins/io_timer.c
  12. 4
      platforms/nuttx/src/px4/stm/stm32_common/io_pins/pwm_servo.c
  13. 2
      src/drivers/drv_pwm_output.h
  14. 2
      src/drivers/pwm_out/PWMOut.cpp
  15. 2
      src/modules/px4iofirmware/registers.c
  16. 2
      src/systemcmds/pwm/pwm.cpp

2
platforms/nuttx/src/px4/nxp/imxrt/include/px4_arch/io_timer.h

@ -142,7 +142,7 @@ __EXPORT int io_timer_allocate_channel(unsigned channel, io_timer_channel_mode_t @@ -142,7 +142,7 @@ __EXPORT int io_timer_allocate_channel(unsigned channel, io_timer_channel_mode_t
__EXPORT int io_timer_unallocate_channel(unsigned channel);
__EXPORT int io_timer_get_channel_mode(unsigned channel);
__EXPORT int io_timer_get_mode_channels(io_timer_channel_mode_t mode);
__EXPORT extern void io_timer_trigger(void);
__EXPORT extern void io_timer_trigger(unsigned channel_mask);
/**
* Reserve a timer

4
platforms/nuttx/src/px4/nxp/imxrt/io_pins/io_timer.c

@ -429,9 +429,9 @@ static inline void io_timer_set_PWM_mode(unsigned channel) @@ -429,9 +429,9 @@ static inline void io_timer_set_PWM_mode(unsigned channel)
px4_leave_critical_section(flags);
}
void io_timer_trigger(void)
void io_timer_trigger(unsigned channel_mask)
{
int oneshots = io_timer_get_mode_channels(IOTimerChanMode_OneShot);
int oneshots = io_timer_get_mode_channels(IOTimerChanMode_OneShot) & channel_mask;
struct {
uint32_t base;
uint16_t triggers;

4
platforms/nuttx/src/px4/nxp/imxrt/io_pins/pwm_servo.c

@ -144,9 +144,9 @@ int up_pwm_servo_set_rate_group_update(unsigned channel, unsigned rate) @@ -144,9 +144,9 @@ int up_pwm_servo_set_rate_group_update(unsigned channel, unsigned rate)
return io_timer_set_pwm_rate(channel, rate);
}
void up_pwm_update(void)
void up_pwm_update(unsigned channel_mask)
{
io_timer_trigger();
io_timer_trigger(channel_mask);
}
uint32_t up_pwm_servo_get_rate_group(unsigned group)

2
platforms/nuttx/src/px4/nxp/kinetis/include/px4_arch/io_timer.h

@ -138,7 +138,7 @@ __EXPORT int io_timer_allocate_channel(unsigned channel, io_timer_channel_mode_t @@ -138,7 +138,7 @@ __EXPORT int io_timer_allocate_channel(unsigned channel, io_timer_channel_mode_t
__EXPORT int io_timer_unallocate_channel(unsigned channel);
__EXPORT int io_timer_get_channel_mode(unsigned channel);
__EXPORT int io_timer_get_mode_channels(io_timer_channel_mode_t mode);
__EXPORT extern void io_timer_trigger(void);
__EXPORT extern void io_timer_trigger(unsigned channel_mask);
/**
* Reserve a timer

4
platforms/nuttx/src/px4/nxp/kinetis/io_pins/io_timer.c

@ -518,9 +518,9 @@ static inline void io_timer_set_PWM_mode(unsigned timer) @@ -518,9 +518,9 @@ static inline void io_timer_set_PWM_mode(unsigned timer)
px4_leave_critical_section(flags);
}
void io_timer_trigger(void)
void io_timer_trigger(unsigned channel_mask)
{
int oneshots = io_timer_get_mode_channels(IOTimerChanMode_OneShot);
int oneshots = io_timer_get_mode_channels(IOTimerChanMode_OneShot) & channel_mask;
uint32_t action_cache[MAX_IO_TIMERS] = {0};
int actions = 0;

4
platforms/nuttx/src/px4/nxp/kinetis/io_pins/pwm_servo.c

@ -143,9 +143,9 @@ int up_pwm_servo_set_rate_group_update(unsigned group, unsigned rate) @@ -143,9 +143,9 @@ int up_pwm_servo_set_rate_group_update(unsigned group, unsigned rate)
return io_timer_set_pwm_rate(group, rate);
}
void up_pwm_update(void)
void up_pwm_update(unsigned channel_mask)
{
io_timer_trigger();
io_timer_trigger(channel_mask);
}
uint32_t up_pwm_servo_get_rate_group(unsigned group)

2
platforms/nuttx/src/px4/nxp/s32k1xx/include/px4_arch/io_timer.h

@ -131,7 +131,7 @@ __EXPORT int io_timer_allocate_channel(unsigned channel, io_timer_channel_mode_t @@ -131,7 +131,7 @@ __EXPORT int io_timer_allocate_channel(unsigned channel, io_timer_channel_mode_t
__EXPORT int io_timer_unallocate_channel(unsigned channel);
__EXPORT int io_timer_get_channel_mode(unsigned channel);
__EXPORT int io_timer_get_mode_channels(io_timer_channel_mode_t mode);
__EXPORT extern void io_timer_trigger(void);
__EXPORT extern void io_timer_trigger(unsigned channel_mask);
/**
* Reserve a timer

4
platforms/nuttx/src/px4/nxp/s32k1xx/io_pins/io_timer.c

@ -514,9 +514,9 @@ static inline void io_timer_set_PWM_mode(unsigned timer) @@ -514,9 +514,9 @@ static inline void io_timer_set_PWM_mode(unsigned timer)
px4_leave_critical_section(flags);
}
void io_timer_trigger(void)
void io_timer_trigger(unsigned channel_mask)
{
int oneshots = io_timer_get_mode_channels(IOTimerChanMode_OneShot);
int oneshots = io_timer_get_mode_channels(IOTimerChanMode_OneShot) & channel_mask;
uint32_t action_cache[MAX_IO_TIMERS] = {0};
int actions = 0;

4
platforms/nuttx/src/px4/nxp/s32k1xx/io_pins/pwm_servo.c

@ -142,9 +142,9 @@ int up_pwm_servo_set_rate_group_update(unsigned group, unsigned rate) @@ -142,9 +142,9 @@ int up_pwm_servo_set_rate_group_update(unsigned group, unsigned rate)
return io_timer_set_pwm_rate(group, rate);
}
void up_pwm_update(void)
void up_pwm_update(unsigned channel_mask)
{
io_timer_trigger();
io_timer_trigger(channel_mask);
}
uint32_t up_pwm_servo_get_rate_group(unsigned group)

2
platforms/nuttx/src/px4/stm/stm32_common/include/px4_arch/io_timer.h

@ -147,7 +147,7 @@ __EXPORT int io_timer_allocate_channel(unsigned channel, io_timer_channel_mode_t @@ -147,7 +147,7 @@ __EXPORT int io_timer_allocate_channel(unsigned channel, io_timer_channel_mode_t
__EXPORT int io_timer_unallocate_channel(unsigned channel);
__EXPORT int io_timer_get_channel_mode(unsigned channel);
__EXPORT int io_timer_get_mode_channels(io_timer_channel_mode_t mode);
__EXPORT extern void io_timer_trigger(void);
__EXPORT extern void io_timer_trigger(unsigned channels_mask);
__EXPORT void io_timer_update_dma_req(uint8_t timer, bool enable);
/**

4
platforms/nuttx/src/px4/stm/stm32_common/io_pins/io_timer.c

@ -579,9 +579,9 @@ static inline void io_timer_set_PWM_mode(unsigned timer) @@ -579,9 +579,9 @@ static inline void io_timer_set_PWM_mode(unsigned timer)
rPSC(timer) = (io_timers[timer].clock_freq / BOARD_PWM_FREQ) - 1;
}
void io_timer_trigger(void)
void io_timer_trigger(unsigned channels_mask)
{
int oneshots = io_timer_get_mode_channels(IOTimerChanMode_OneShot);
int oneshots = io_timer_get_mode_channels(IOTimerChanMode_OneShot) & channels_mask;
if (oneshots != 0) {
uint32_t action_cache[MAX_IO_TIMERS] = {0};

4
platforms/nuttx/src/px4/stm/stm32_common/io_pins/pwm_servo.c

@ -141,9 +141,9 @@ int up_pwm_servo_set_rate_group_update(unsigned group, unsigned rate) @@ -141,9 +141,9 @@ int up_pwm_servo_set_rate_group_update(unsigned group, unsigned rate)
return io_timer_set_pwm_rate(group, rate);
}
void up_pwm_update(void)
void up_pwm_update(unsigned channels_mask)
{
io_timer_trigger();
io_timer_trigger(channels_mask);
}
uint32_t up_pwm_servo_get_rate_group(unsigned group)

2
src/drivers/drv_pwm_output.h

@ -358,7 +358,7 @@ __EXPORT extern int up_pwm_servo_set_rate_group_update(unsigned group, unsigned @@ -358,7 +358,7 @@ __EXPORT extern int up_pwm_servo_set_rate_group_update(unsigned group, unsigned
* Nothing is done if not in oneshot mode.
*
*/
__EXPORT extern void up_pwm_update(void);
__EXPORT extern void up_pwm_update(unsigned channel_mask);
/**
* Set the current output value for a channel.

2
src/drivers/pwm_out/PWMOut.cpp

@ -438,7 +438,7 @@ bool PWMOut::updateOutputs(bool stop_motors, uint16_t outputs[MAX_ACTUATORS], @@ -438,7 +438,7 @@ bool PWMOut::updateOutputs(bool stop_motors, uint16_t outputs[MAX_ACTUATORS],
* the oneshots with updated values.
*/
if (num_control_groups_updated > 0) {
up_pwm_update(); // TODO: review for multi
up_pwm_update(_pwm_mask);
}
return true;

2
src/modules/px4iofirmware/registers.c

@ -207,7 +207,7 @@ registers_set(uint8_t page, uint8_t offset, const uint16_t *values, unsigned num @@ -207,7 +207,7 @@ registers_set(uint8_t page, uint8_t offset, const uint16_t *values, unsigned num
/* Trigger all timer's channels in Oneshot mode to fire
* the oneshots with updated values.
*/
up_pwm_update();
up_pwm_update(0xff);
break;

2
src/systemcmds/pwm/pwm.cpp

@ -701,7 +701,7 @@ pwm_main(int argc, char *argv[]) @@ -701,7 +701,7 @@ pwm_main(int argc, char *argv[])
* the oneshots with updated values.
*/
up_pwm_update();
up_pwm_update(0xff);
#endif
}
rv = 0;

Loading…
Cancel
Save