linux: Disable hardware pwm when it is set to zero

Only write "1" to the "enable" file when a non-zero pwm width is
requested.  Write "0" to the "enable" file when a zero pwm width is
requested.

This fixes a problem on the replicape servo lines that prevented them
from being fully disabled.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2020-07-19 23:59:44 -04:00
parent bc488c2161
commit 5f2cb5436c
2 changed files with 12 additions and 13 deletions

View File

@ -37,7 +37,7 @@ void spi_transfer(struct spi_config config, uint8_t receive_data
, uint8_t len, uint8_t *data);
struct gpio_pwm {
int fd;
int duty_fd, enable_fd;
uint32_t period;
};
struct gpio_pwm gpio_pwm_setup(uint32_t pin, uint32_t cycle_time, uint16_t val);

View File

@ -77,20 +77,18 @@ struct gpio_pwm gpio_pwm_setup(uint32_t pin, uint32_t cycle_time, uint16_t val)
report_errno("pwm duty_cycle", fd);
goto fail;
}
g.fd = fd;
gpio_pwm_write(g, val);
g.duty_fd = fd;
// enable PWM
snprintf(filename, sizeof(filename), pwm_path, chip_id, pwm_id, "enable");
fd = open(filename, O_WRONLY|O_CLOEXEC);
if (fd == -1) {
close(g.fd);
report_errno("pwm enable", fd);
close(g.duty_fd);
goto fail;
}
write(fd, "1", 2);
close(fd);
g.enable_fd = fd;
gpio_pwm_write(g, val);
return g;
@ -103,12 +101,13 @@ fail:
void gpio_pwm_write(struct gpio_pwm g, uint16_t val)
{
if (!val) {
write(g.enable_fd, "0", 2);
return;
}
char scratch[16];
uint32_t duty_cycle = g.period * (uint64_t)val / MAX_PWM;
snprintf(scratch, sizeof(scratch), "%u", duty_cycle);
if (g.fd != -1) {
write(g.fd, scratch, strlen(scratch));
} else {
report_errno("pwm set duty_cycle", g.fd);
}
int len = snprintf(scratch, sizeof(scratch), "%u", duty_cycle);
write(g.duty_fd, scratch, len + 1);
write(g.enable_fd, "1", 2);
}