Private
Public Access
2
0

intel_edison_fab_c.c: further fix for PWM disable problem

This adds logic to save PWM duty when disabling the pin (which sets
the duty to 0), and restore it when re-enabling the pin.

Signed-off-by: Alex Tereschenko <alext.mkrs@gmail.com>
Signed-off-by: Brendan Le Foll <brendan.le.foll@intel.com>
This commit is contained in:
Alex Tereschenko
2016-12-11 15:52:59 +01:00
committed by Brendan Le Foll
parent 2558866d4a
commit af051d820a

View File

@@ -77,8 +77,13 @@ static int mmap_fd = 0;
static int mmap_size;
static unsigned int mmap_count = 0;
// PWM 0% duty workaround state array
static int pwm_disabled[4] = { 0 };
// Pin state for PWM 0% duty and enable/disable bug workaround
typedef struct {
float duty_cycle;
int pwm_disabled;
} mraa_edison_pwm_wa_pinstate_t;
static mraa_edison_pwm_wa_pinstate_t pwm_wa_state[4] = {{.duty_cycle = 0, .pwm_disabled = 0}};
mraa_result_t
mraa_intel_edison_spi_lsbmode_replace(mraa_spi_context dev, mraa_boolean_t lsb)
@@ -378,16 +383,23 @@ mraa_result_t
mraa_intel_edison_pwm_enable_pre(mraa_pwm_context dev, int enable) {
// PWM 0% duty workaround: update state array
// if someone first ran write(0) and then enable(1).
if ((pwm_disabled[dev->pin] == 1) && (enable == 1)) {
pwm_disabled[dev->pin] = 0;
if ((pwm_wa_state[dev->pin].pwm_disabled == 1) && (enable == 1)) {
pwm_wa_state[dev->pin].pwm_disabled = 0;
return MRAA_SUCCESS;
}
if (enable == 0) {
// Set duty cycle to 0 before disable pwm.
// Set duty cycle to 0 before disabling PWM, but save it first
pwm_wa_state[dev->pin].duty_cycle = mraa_pwm_read(dev);
// Edison PWM output stuck at high if disabled during ON period
mraa_pwm_pulsewidth_us(dev, 0);
// Sleep 2 period to allow change take effect
// Sleep for 2 periods to allow the change to take effect
usleep(dev->period / 500);
} else if (enable == 1) {
// Restore the duty before re-enabling, but not if it's 0, to avoid recursion
if (pwm_wa_state[dev->pin].duty_cycle != 0) {
mraa_pwm_write(dev, pwm_wa_state[dev->pin].duty_cycle);
}
}
return MRAA_SUCCESS;
@@ -398,11 +410,11 @@ mraa_intel_edison_pwm_write_pre(mraa_pwm_context dev, float percentage) {
// PWM 0% duty workaround: set the state array and enable/disable pin accordingly
if (percentage == 0.0f) {
syslog(LOG_INFO, "edison_pwm_write_pre (pwm%i): requested zero duty cycle, disabling PWM on the pin", dev->pin);
pwm_disabled[dev->pin] = 1;
pwm_wa_state[dev->pin].pwm_disabled = 1;
return mraa_pwm_enable(dev, 0);
} else if (pwm_disabled[dev->pin] == 1) {
} else if (pwm_wa_state[dev->pin].pwm_disabled == 1) {
syslog(LOG_INFO, "edison_pwm_write_pre (pwm%i): Re-enabling the pin after setting non-zero duty", dev->pin);
pwm_disabled[dev->pin] = 0;
pwm_wa_state[dev->pin].pwm_disabled = 0;
return mraa_pwm_enable(dev, 1);
}
@@ -456,7 +468,8 @@ mraa_intel_edison_pwm_init_pre(int pin)
mraa_result_t
mraa_intel_edison_pwm_init_post(mraa_pwm_context pwm)
{
pwm_disabled[pwm->pin] = 0;
pwm_wa_state[pwm->pin].pwm_disabled = 0;
pwm_wa_state[pwm->pin].duty_cycle = 0.0f;
return mraa_gpio_write(tristate, 1);
}