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:
parent
bc488c2161
commit
5f2cb5436c
|
@ -37,7 +37,7 @@ void spi_transfer(struct spi_config config, uint8_t receive_data
|
||||||
, uint8_t len, uint8_t *data);
|
, uint8_t len, uint8_t *data);
|
||||||
|
|
||||||
struct gpio_pwm {
|
struct gpio_pwm {
|
||||||
int fd;
|
int duty_fd, enable_fd;
|
||||||
uint32_t period;
|
uint32_t period;
|
||||||
};
|
};
|
||||||
struct gpio_pwm gpio_pwm_setup(uint32_t pin, uint32_t cycle_time, uint16_t val);
|
struct gpio_pwm gpio_pwm_setup(uint32_t pin, uint32_t cycle_time, uint16_t val);
|
||||||
|
|
|
@ -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);
|
report_errno("pwm duty_cycle", fd);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
g.duty_fd = fd;
|
||||||
g.fd = fd;
|
|
||||||
gpio_pwm_write(g, val);
|
|
||||||
|
|
||||||
// enable PWM
|
// enable PWM
|
||||||
snprintf(filename, sizeof(filename), pwm_path, chip_id, pwm_id, "enable");
|
snprintf(filename, sizeof(filename), pwm_path, chip_id, pwm_id, "enable");
|
||||||
fd = open(filename, O_WRONLY|O_CLOEXEC);
|
fd = open(filename, O_WRONLY|O_CLOEXEC);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
close(g.fd);
|
|
||||||
report_errno("pwm enable", fd);
|
report_errno("pwm enable", fd);
|
||||||
|
close(g.duty_fd);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
write(fd, "1", 2);
|
g.enable_fd = fd;
|
||||||
close(fd);
|
gpio_pwm_write(g, val);
|
||||||
|
|
||||||
return g;
|
return g;
|
||||||
|
|
||||||
|
@ -103,12 +101,13 @@ fail:
|
||||||
|
|
||||||
void gpio_pwm_write(struct gpio_pwm g, uint16_t val)
|
void gpio_pwm_write(struct gpio_pwm g, uint16_t val)
|
||||||
{
|
{
|
||||||
|
if (!val) {
|
||||||
|
write(g.enable_fd, "0", 2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
char scratch[16];
|
char scratch[16];
|
||||||
uint32_t duty_cycle = g.period * (uint64_t)val / MAX_PWM;
|
uint32_t duty_cycle = g.period * (uint64_t)val / MAX_PWM;
|
||||||
snprintf(scratch, sizeof(scratch), "%u", duty_cycle);
|
int len = snprintf(scratch, sizeof(scratch), "%u", duty_cycle);
|
||||||
if (g.fd != -1) {
|
write(g.duty_fd, scratch, len + 1);
|
||||||
write(g.fd, scratch, strlen(scratch));
|
write(g.enable_fd, "1", 2);
|
||||||
} else {
|
|
||||||
report_errno("pwm set duty_cycle", g.fd);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue