From 4fcf5a31f5c6d84749b3ae85be9482161fd33815 Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Wed, 8 Jun 2016 19:44:34 -0400 Subject: pwmcmds: Add Kconfig option to allow boards to disable hardware PWM commands Some boards may not support hardware based PWM. Update the build so that those commands do not need to be compiled if they are not available. Signed-off-by: Kevin O'Connor --- src/pwmcmds.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 src/pwmcmds.c (limited to 'src/pwmcmds.c') diff --git a/src/pwmcmds.c b/src/pwmcmds.c new file mode 100644 index 00000000..bc9fec03 --- /dev/null +++ b/src/pwmcmds.c @@ -0,0 +1,78 @@ +// Commands for controlling hardware based pulse-width-modulator pins +// +// Copyright (C) 2016 Kevin O'Connor +// +// This file may be distributed under the terms of the GNU GPLv3 license. + +#include "basecmd.h" // alloc_oid +#include "board/gpio.h" // struct gpio_pwm +#include "command.h" // DECL_COMMAND +#include "sched.h" // sched_timer + +struct pwm_out_s { + struct timer timer; + struct gpio_pwm pin; + uint32_t max_duration; + uint8_t value, default_value; +}; + +static uint8_t +pwm_end_event(struct timer *timer) +{ + shutdown("Missed scheduling of next hard pwm event"); +} + +static uint8_t +pwm_event(struct timer *timer) +{ + struct pwm_out_s *p = container_of(timer, struct pwm_out_s, timer); + gpio_pwm_write(p->pin, p->value); + if (p->value == p->default_value || !p->max_duration) + return SF_DONE; + p->timer.waketime += p->max_duration; + p->timer.func = pwm_end_event; + return SF_RESCHEDULE; +} + +void +command_config_pwm_out(uint32_t *args) +{ + struct pwm_out_s *p = alloc_oid(args[0], command_config_pwm_out, sizeof(*p)); + p->default_value = args[3]; + p->pin = gpio_pwm_setup(args[1], args[2], p->default_value); + p->max_duration = args[4]; +} +DECL_COMMAND(command_config_pwm_out, + "config_pwm_out oid=%c pin=%u cycle_ticks=%u default_value=%c" + " max_duration=%u"); + +void +command_schedule_pwm_out(uint32_t *args) +{ + struct pwm_out_s *p = lookup_oid(args[0], command_config_pwm_out); + sched_del_timer(&p->timer); + p->timer.func = pwm_event; + p->timer.waketime = args[1]; + p->value = args[2]; + sched_timer(&p->timer); +} +DECL_COMMAND(command_schedule_pwm_out, + "schedule_pwm_out oid=%c clock=%u value=%c"); + +static void +pwm_shutdown(void) +{ + uint8_t i; + struct pwm_out_s *p; + foreach_oid(i, p, command_config_pwm_out) { + gpio_pwm_write(p->pin, p->default_value); + } +} +DECL_SHUTDOWN(pwm_shutdown); + +void +command_set_pwm_out(uint32_t *args) +{ + gpio_pwm_setup(args[0], args[1], args[2]); +} +DECL_COMMAND(command_set_pwm_out, "set_pwm_out pin=%u cycle_ticks=%u value=%c"); -- cgit v1.2.3-70-g09d2