From d3e0b78f7c94dd6a462caa51933293254fffbdd5 Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Sun, 10 Feb 2019 16:38:49 +0100 Subject: [PATCH] cpu/esp8266: fix of set func in periph/pwm In the `pwm_set` function, the switch-on and switch-off times for PWM channels were only determined for the following phase, but not for the current phase. This could result in a missing duty cycle when calling the function `pwm_set` if the switch-on time of the current phase was not yet reached or to an extended duty cycle if the switch-off time of the current phase had not yet been reached. --- cpu/esp8266/periph/pwm.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/cpu/esp8266/periph/pwm.c b/cpu/esp8266/periph/pwm.c index 4f72a574f5ac..58f7437ab928 100644 --- a/cpu/esp8266/periph/pwm.c +++ b/cpu/esp8266/periph/pwm.c @@ -183,23 +183,35 @@ void pwm_set(pwm_t pwm, uint8_t channel, uint16_t value) CHECK_PARAM (value <= _pwm_dev.res); uint32_t state = irq_disable(); - uint32_t phase = _pwm_dev.cycles - _pwm_dev.cycles % _pwm_dev.res + _pwm_dev.res; + uint32_t phase = _pwm_dev.cycles - _pwm_dev.cycles % _pwm_dev.res; + uint32_t next_on = phase; + uint32_t next_off; switch (_pwm_dev.mode) { case PWM_LEFT: - _pwm_dev.chn[channel].next_on = phase; + next_on = phase; break; case PWM_RIGHT: - _pwm_dev.chn[channel].next_on = phase + _pwm_dev.res - value; + next_on = phase + _pwm_dev.res - value; break; case PWM_CENTER: - _pwm_dev.chn[channel].next_on = phase + (_pwm_dev.res - value) / 2; + next_on = phase + (_pwm_dev.res - value) / 2; break; } - _pwm_dev.chn[channel].next_off = _pwm_dev.chn[channel].next_on + value; + next_off = next_on + value; + + if (_pwm_dev.cycles >= next_on) { + next_on += _pwm_dev.res; + } + if (_pwm_dev.cycles >= next_off) { + next_off += _pwm_dev.res; + } + + _pwm_dev.chn[channel].next_on = next_on; + _pwm_dev.chn[channel].next_off = next_off; _pwm_dev.chn[channel].duty = value; irq_restore(state);