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:
committed by
Brendan Le Foll
parent
2558866d4a
commit
af051d820a
@@ -77,8 +77,13 @@ static int mmap_fd = 0;
|
|||||||
static int mmap_size;
|
static int mmap_size;
|
||||||
static unsigned int mmap_count = 0;
|
static unsigned int mmap_count = 0;
|
||||||
|
|
||||||
// PWM 0% duty workaround state array
|
// Pin state for PWM 0% duty and enable/disable bug workaround
|
||||||
static int pwm_disabled[4] = { 0 };
|
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_result_t
|
||||||
mraa_intel_edison_spi_lsbmode_replace(mraa_spi_context dev, mraa_boolean_t lsb)
|
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) {
|
mraa_intel_edison_pwm_enable_pre(mraa_pwm_context dev, int enable) {
|
||||||
// PWM 0% duty workaround: update state array
|
// PWM 0% duty workaround: update state array
|
||||||
// if someone first ran write(0) and then enable(1).
|
// if someone first ran write(0) and then enable(1).
|
||||||
if ((pwm_disabled[dev->pin] == 1) && (enable == 1)) {
|
if ((pwm_wa_state[dev->pin].pwm_disabled == 1) && (enable == 1)) {
|
||||||
pwm_disabled[dev->pin] = 0;
|
pwm_wa_state[dev->pin].pwm_disabled = 0;
|
||||||
return MRAA_SUCCESS;
|
return MRAA_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enable == 0) {
|
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
|
// Edison PWM output stuck at high if disabled during ON period
|
||||||
mraa_pwm_pulsewidth_us(dev, 0);
|
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);
|
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;
|
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
|
// PWM 0% duty workaround: set the state array and enable/disable pin accordingly
|
||||||
if (percentage == 0.0f) {
|
if (percentage == 0.0f) {
|
||||||
syslog(LOG_INFO, "edison_pwm_write_pre (pwm%i): requested zero duty cycle, disabling PWM on the pin", dev->pin);
|
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);
|
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);
|
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);
|
return mraa_pwm_enable(dev, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -456,7 +468,8 @@ mraa_intel_edison_pwm_init_pre(int pin)
|
|||||||
mraa_result_t
|
mraa_result_t
|
||||||
mraa_intel_edison_pwm_init_post(mraa_pwm_context pwm)
|
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);
|
return mraa_gpio_write(tristate, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user