Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
extras/replicape: add support for Linux hardware PWM
The servo pins (P9_14/P9_16) are muxed to the SOCs hardware PWM unit driven by a 13MHz GP timer. They have to be driven by the linux host mcu for example by the sysfs user space interface. The easiest way to ensure the hardware pwm commands are used is to make the servo pins replicape specific. Fixes #1105. Signed-off-by: Janne Grunau <janne-3d@jannau.net>
- Loading branch information
Janne Grunau
committed
Mar 25, 2019
1 parent
9aadc3c
commit 63fed25
Showing
8 changed files
with
119 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
// HW PWM upport via Linux PWM sysfs interface | ||
// | ||
// Copyright (C) 2019 Janne Grunau <janne-3d@jannau.net> | ||
// | ||
// This file may be distributed under the terms of the GNU GPLv3 license. | ||
|
||
#include <stdio.h> | ||
#include <string.h> | ||
#include <unistd.h> | ||
#include <sys/types.h> | ||
#include <sys/stat.h> | ||
#include <fcntl.h> | ||
|
||
#include "gpio.h" // struct gpio_pwm | ||
#include "internal.h" // NSECS_PER_TICK | ||
#include "command.h" // shutdown | ||
#include "sched.h" // sched_shutdown | ||
|
||
#define MAX_PWM 255 | ||
DECL_CONSTANT("PWM_MAX", MAX_PWM); | ||
|
||
#define NUM_PWM_PINS 2 | ||
#define PWM_PIN_START 8 | ||
|
||
DECL_ENUMERATION("pin", "P9_14", PWM_PIN_START); | ||
DECL_ENUMERATION("pin", "P9_16", PWM_PIN_START + 1); | ||
|
||
#define PWM_PATH "/sys/class/pwm/pwmchip%u/pwm%u/%s" | ||
|
||
struct gpio_pwm gpio_pwm_setup(uint8_t pin, uint32_t cycle_time, uint8_t val) | ||
{ | ||
char filename[256]; | ||
char scratch[16]; | ||
uint8_t chip_id = 0, pwm_id = pin - PWM_PIN_START; | ||
|
||
struct gpio_pwm g = {}; | ||
g.period = cycle_time * NSECS_PER_TICK; | ||
|
||
// configure period/cycle time. Always in nanoseconds | ||
snprintf(filename, sizeof(filename), PWM_PATH, chip_id, pwm_id, "period"); | ||
int fd = open(filename, O_WRONLY|O_CLOEXEC); | ||
if (fd == -1) { | ||
report_errno("pwm period", fd); | ||
goto fail; | ||
} | ||
snprintf(scratch, sizeof(scratch), "%u", cycle_time * NSECS_PER_TICK); | ||
write(fd, scratch, strlen(scratch)); | ||
close(fd); | ||
|
||
// write duty cycle | ||
snprintf(filename, sizeof(filename), PWM_PATH, chip_id, pwm_id, | ||
"duty_cycle"); | ||
fd = open(filename, O_WRONLY|O_CLOEXEC); | ||
if (fd == -1) { | ||
report_errno("pwm duty_cycle", fd); | ||
goto fail; | ||
} | ||
|
||
g.fd = fd; | ||
gpio_pwm_write(g, val); | ||
|
||
// 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); | ||
goto fail; | ||
} | ||
write(fd, "1", 2); | ||
close(fd); | ||
|
||
return g; | ||
|
||
fail: | ||
if (fd >= 0) | ||
close(fd); | ||
shutdown("Unable to config pwm device"); | ||
} | ||
|
||
|
||
void gpio_pwm_write(struct gpio_pwm g, uint8_t val) | ||
{ | ||
char scratch[16]; | ||
snprintf(scratch, sizeof(scratch), "%u", g.period * val / 255); | ||
if (g.fd != -1) { | ||
write(g.fd, scratch, strlen(scratch)); | ||
} else { | ||
report_errno("pwm set duty_cycle", g.fd); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters