drivers: pwm_nrfx: Wait until PWM is stopped before restarting it
Change adds waiting until PWM is stopped before restarting it. Without the change, calling the pwm_nrfx_pin_set function multiple times in quick succession could cause a race condition causing the PWM to remain stopped in case it should be restarted. Signed-off-by: Marek Pieta <Marek.Pieta@nordicsemi.no>
This commit is contained in:
parent
cd679452b2
commit
75e36ed352
1 changed files with 18 additions and 4 deletions
|
@ -134,6 +134,7 @@ static int pwm_nrfx_pin_set(struct device *dev, u32_t pwm,
|
||||||
const struct pwm_nrfx_config *config = dev->config->config_info;
|
const struct pwm_nrfx_config *config = dev->config->config_info;
|
||||||
struct pwm_nrfx_data *data = dev->driver_data;
|
struct pwm_nrfx_data *data = dev->driver_data;
|
||||||
u8_t channel;
|
u8_t channel;
|
||||||
|
bool was_stopped;
|
||||||
|
|
||||||
if (flags) {
|
if (flags) {
|
||||||
/* PWM polarity not supported (yet?) */
|
/* PWM polarity not supported (yet?) */
|
||||||
|
@ -151,6 +152,14 @@ static int pwm_nrfx_pin_set(struct device *dev, u32_t pwm,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if nrfx_pwm_stop function was called in previous
|
||||||
|
* pwm_nrfx_pin_set call. Relying only on state returned by
|
||||||
|
* nrfx_pwm_is_stopped may cause race condition if the pwm_nrfx_pin_set
|
||||||
|
* is called multiple times in quick succession.
|
||||||
|
*/
|
||||||
|
was_stopped = !pwm_channel_is_active(channel, data) &&
|
||||||
|
!any_other_channel_is_active(channel, data);
|
||||||
|
|
||||||
/* If this PWM is in center-aligned mode, pulse and period lengths
|
/* If this PWM is in center-aligned mode, pulse and period lengths
|
||||||
* are effectively doubled by the up-down count, so halve them here
|
* are effectively doubled by the up-down count, so halve them here
|
||||||
* to compensate.
|
* to compensate.
|
||||||
|
@ -223,7 +232,12 @@ static int pwm_nrfx_pin_set(struct device *dev, u32_t pwm,
|
||||||
* playing. The new channel values will be used
|
* playing. The new channel values will be used
|
||||||
* immediately when they are written into the seq array.
|
* immediately when they are written into the seq array.
|
||||||
*/
|
*/
|
||||||
if (nrfx_pwm_is_stopped(&config->pwm)) {
|
if (was_stopped) {
|
||||||
|
/* Wait until PWM will be stopped and then start the
|
||||||
|
* sequence.
|
||||||
|
*/
|
||||||
|
while (!nrfx_pwm_is_stopped(&config->pwm)) {
|
||||||
|
};
|
||||||
nrfx_pwm_simple_playback(&config->pwm,
|
nrfx_pwm_simple_playback(&config->pwm,
|
||||||
&config->seq,
|
&config->seq,
|
||||||
1,
|
1,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue