[Xenomai-git] Jorge Ramirez-Ortiz : gpiopwm: pwm signal generator and servo motor control demo code
Module: xenomai-3 Branch: next Commit: ad1e755fd6fffdae0b08bfe5e7160b953611c226 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=ad1e755fd6fffdae0b08bfe5e7160b953611c226 Author: Jorge Ramirez-Ortiz Date: Tue Mar 15 19:18:15 2016 -0400 gpiopwm: pwm signal generator and servo motor control demo code --- demo/posix/cobalt/Makefile.am|6 + demo/posix/cobalt/gpiopwm.c | 448 ++ include/cobalt/kernel/rtdm/gpiopwm.h | 24 ++ include/rtdm/uapi/gpiopwm.h | 56 + include/rtdm/uapi/rtdm.h |1 + kernel/drivers/Kconfig |1 + kernel/drivers/Makefile |2 +- kernel/drivers/gpiopwm/Kconfig |9 + kernel/drivers/gpiopwm/Makefile |5 + kernel/drivers/gpiopwm/gpiopwm.c | 301 +++ 10 files changed, 852 insertions(+), 1 deletion(-) diff --git a/demo/posix/cobalt/Makefile.am b/demo/posix/cobalt/Makefile.am index cba9247..2a22967 100644 --- a/demo/posix/cobalt/Makefile.am +++ b/demo/posix/cobalt/Makefile.am @@ -3,6 +3,7 @@ demodir = @XENO_DEMO_DIR@ CCLD = $(top_srcdir)/scripts/wrap-link.sh $(CC) demo_PROGRAMS =\ + gpiopwm \ bufp-label \ bufp-readwrite \ can_rtt \ @@ -24,6 +25,11 @@ ldadd = \ @XENO_USER_LDADD@ \ -lpthread -lrt +gpiopwm_SOURCES = gpiopwm.c +gpiopwm_CPPFLAGS = $(cppflags) -I$(top_srcdir)/include/rtdm/uapi +gpiopwm_LDFLAGS = $(ldflags) +gpiopwm_LDADD = $(ldadd) + bufp_label_SOURCES = bufp-label.c bufp_label_CPPFLAGS = $(cppflags) bufp_label_LDFLAGS = $(ldflags) diff --git a/demo/posix/cobalt/gpiopwm.c b/demo/posix/cobalt/gpiopwm.c new file mode 100644 index 000..e093fbe --- /dev/null +++ b/demo/posix/cobalt/gpiopwm.c @@ -0,0 +1,448 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MIN_DUTY_CYCLE 0 +#define MAX_DUTY_CYCLE 100 + +typedef void *(*gpiopwm_control_thread)(void *cookie); +#define DEVICE_NAME "/dev/rtdm/gpiopwm" +char *device_name; +int dev; + +static sem_t synch; +static sem_t setup; +static int stop; +static int step = 1; +static int port = 6; + +#define GPIO_PWM_SERVO_CONFIG \ +{ \ + .duty_cycle = 50, \ + .range_min = 950,\ + .range_max = 2050, \ + .period = 2000, \ + .gpio = 1, \ +} + +static struct gpiopwm config = GPIO_PWM_SERVO_CONFIG; + +static void fail(const char *reason) +{ + perror(reason); + exit(EXIT_FAILURE); +} + +static void sem_sync(sem_t *sem) +{ + int ret; + + for (;;) { + ret = sem_wait(sem); + if (ret == 0) + return; + if (errno != EINTR) + fail("sem_wait"); + } +} + +static inline void clear_screen(void) +{ + const char* cmd = "\e[1;1H\e[2J"; + int ret; + + ret = write(2, cmd, strlen(cmd)); + if (!ret) + error(1, ret, "clear screen error"); +} + +static inline void print_config(char *str) +{ + printf("Config: %s\n", str); + printf(" device : %s\n", device_name); + printf(" range : [%d, %d]\n", config.range_min, config.range_max); + printf(" period : %d nsec\n", config.period); + printf(" gpio pin : %d\n", config.gpio); + printf(" duty cycle : %d\n", config.duty_cycle); +} + +static inline void input_message(void) +{ + print_config(""); + printf("\n GPIO PWM Control\n"); + printf( " Enter duty_cycle [0-100] : "); +} + +static void setup_sched_parameters(pthread_attr_t *attr, int prio) +{ + struct sched_param p; + int ret; + + ret = pthread_attr_init(attr); + if (ret) + error(1, ret, "pthread_attr_init()"); + + ret = pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED); + if (ret) + error(1, ret, "pthread_attr_setinheritsched()"); + + ret = pthread_attr_setschedpolicy(attr, prio ? SCHED_FIFO : SCHED_OTHER); + if (ret) + error(1, ret, "pthread_attr_setschedpolicy()"); + + p.sched_priority = prio; + ret = pthread_attr_setschedparam(attr, &p); + if (ret) + error(1, ret, "pthread_attr_setschedparam()"); +} + +static void *gpiopwm_init_thread(void *cookie) +{ + int ret; + + pthread_setname_np(pthread_self(), "gpio-pwm-handler"); + ret = ioctl(dev, GPIOPWM_RTIOC_SET_CONFIG, config); + if (ret) + error(1, ret, "failed to set config"); + + ioctl(dev, GPIOPWM_RTIOC_START); + + /* setup compl
[Xenomai-git] Jorge Ramirez-Ortiz : gpiopwm: pwm signal generator and servo motor control demo code
Module: xenomai-3 Branch: next Commit: a9ef7ba7067e95e5a2a65067d3daa53b050968df URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=a9ef7ba7067e95e5a2a65067d3daa53b050968df Author: Jorge Ramirez-Ortiz Date: Tue Mar 15 19:18:15 2016 -0400 gpiopwm: pwm signal generator and servo motor control demo code --- demo/posix/cobalt/Makefile.am|6 + demo/posix/cobalt/gpiopwm.c | 448 ++ include/cobalt/kernel/rtdm/gpiopwm.h | 24 ++ include/rtdm/uapi/gpiopwm.h | 56 + include/rtdm/uapi/rtdm.h |1 + kernel/drivers/Kconfig |1 + kernel/drivers/Makefile |2 +- kernel/drivers/gpiopwm/Kconfig |9 + kernel/drivers/gpiopwm/Makefile |5 + kernel/drivers/gpiopwm/gpiopwm.c | 301 +++ 10 files changed, 852 insertions(+), 1 deletion(-) diff --git a/demo/posix/cobalt/Makefile.am b/demo/posix/cobalt/Makefile.am index cba9247..2a22967 100644 --- a/demo/posix/cobalt/Makefile.am +++ b/demo/posix/cobalt/Makefile.am @@ -3,6 +3,7 @@ demodir = @XENO_DEMO_DIR@ CCLD = $(top_srcdir)/scripts/wrap-link.sh $(CC) demo_PROGRAMS =\ + gpiopwm \ bufp-label \ bufp-readwrite \ can_rtt \ @@ -24,6 +25,11 @@ ldadd = \ @XENO_USER_LDADD@ \ -lpthread -lrt +gpiopwm_SOURCES = gpiopwm.c +gpiopwm_CPPFLAGS = $(cppflags) -I$(top_srcdir)/include/rtdm/uapi +gpiopwm_LDFLAGS = $(ldflags) +gpiopwm_LDADD = $(ldadd) + bufp_label_SOURCES = bufp-label.c bufp_label_CPPFLAGS = $(cppflags) bufp_label_LDFLAGS = $(ldflags) diff --git a/demo/posix/cobalt/gpiopwm.c b/demo/posix/cobalt/gpiopwm.c new file mode 100644 index 000..e093fbe --- /dev/null +++ b/demo/posix/cobalt/gpiopwm.c @@ -0,0 +1,448 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MIN_DUTY_CYCLE 0 +#define MAX_DUTY_CYCLE 100 + +typedef void *(*gpiopwm_control_thread)(void *cookie); +#define DEVICE_NAME "/dev/rtdm/gpiopwm" +char *device_name; +int dev; + +static sem_t synch; +static sem_t setup; +static int stop; +static int step = 1; +static int port = 6; + +#define GPIO_PWM_SERVO_CONFIG \ +{ \ + .duty_cycle = 50, \ + .range_min = 950,\ + .range_max = 2050, \ + .period = 2000, \ + .gpio = 1, \ +} + +static struct gpiopwm config = GPIO_PWM_SERVO_CONFIG; + +static void fail(const char *reason) +{ + perror(reason); + exit(EXIT_FAILURE); +} + +static void sem_sync(sem_t *sem) +{ + int ret; + + for (;;) { + ret = sem_wait(sem); + if (ret == 0) + return; + if (errno != EINTR) + fail("sem_wait"); + } +} + +static inline void clear_screen(void) +{ + const char* cmd = "\e[1;1H\e[2J"; + int ret; + + ret = write(2, cmd, strlen(cmd)); + if (!ret) + error(1, ret, "clear screen error"); +} + +static inline void print_config(char *str) +{ + printf("Config: %s\n", str); + printf(" device : %s\n", device_name); + printf(" range : [%d, %d]\n", config.range_min, config.range_max); + printf(" period : %d nsec\n", config.period); + printf(" gpio pin : %d\n", config.gpio); + printf(" duty cycle : %d\n", config.duty_cycle); +} + +static inline void input_message(void) +{ + print_config(""); + printf("\n GPIO PWM Control\n"); + printf( " Enter duty_cycle [0-100] : "); +} + +static void setup_sched_parameters(pthread_attr_t *attr, int prio) +{ + struct sched_param p; + int ret; + + ret = pthread_attr_init(attr); + if (ret) + error(1, ret, "pthread_attr_init()"); + + ret = pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED); + if (ret) + error(1, ret, "pthread_attr_setinheritsched()"); + + ret = pthread_attr_setschedpolicy(attr, prio ? SCHED_FIFO : SCHED_OTHER); + if (ret) + error(1, ret, "pthread_attr_setschedpolicy()"); + + p.sched_priority = prio; + ret = pthread_attr_setschedparam(attr, &p); + if (ret) + error(1, ret, "pthread_attr_setschedparam()"); +} + +static void *gpiopwm_init_thread(void *cookie) +{ + int ret; + + pthread_setname_np(pthread_self(), "gpio-pwm-handler"); + ret = ioctl(dev, GPIOPWM_RTIOC_SET_CONFIG, config); + if (ret) + error(1, ret, "failed to set config"); + + ioctl(dev, GPIOPWM_RTIOC_START); + + /* setup compl
[Xenomai-git] Jorge Ramirez-Ortiz : gpiopwm: pwm signal generator and servo motor control demo code
Module: xenomai-3 Branch: next Commit: c5358a8135eac0fa4967d53c0dce238b70f8bb1c URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=c5358a8135eac0fa4967d53c0dce238b70f8bb1c Author: Jorge Ramirez-Ortiz Date: Tue Mar 15 19:18:15 2016 -0400 gpiopwm: pwm signal generator and servo motor control demo code --- demo/posix/cobalt/Makefile.am|6 + demo/posix/cobalt/gpiopwm.c | 448 ++ include/cobalt/kernel/rtdm/gpiopwm.h | 24 ++ include/rtdm/uapi/gpiopwm.h | 56 + include/rtdm/uapi/rtdm.h |1 + kernel/drivers/Kconfig |1 + kernel/drivers/Makefile |2 +- kernel/drivers/gpiopwm/Kconfig |9 + kernel/drivers/gpiopwm/Makefile |5 + kernel/drivers/gpiopwm/gpiopwm.c | 301 +++ 10 files changed, 852 insertions(+), 1 deletion(-) diff --git a/demo/posix/cobalt/Makefile.am b/demo/posix/cobalt/Makefile.am index cba9247..2a22967 100644 --- a/demo/posix/cobalt/Makefile.am +++ b/demo/posix/cobalt/Makefile.am @@ -3,6 +3,7 @@ demodir = @XENO_DEMO_DIR@ CCLD = $(top_srcdir)/scripts/wrap-link.sh $(CC) demo_PROGRAMS =\ + gpiopwm \ bufp-label \ bufp-readwrite \ can_rtt \ @@ -24,6 +25,11 @@ ldadd = \ @XENO_USER_LDADD@ \ -lpthread -lrt +gpiopwm_SOURCES = gpiopwm.c +gpiopwm_CPPFLAGS = $(cppflags) -I$(top_srcdir)/include/rtdm/uapi +gpiopwm_LDFLAGS = $(ldflags) +gpiopwm_LDADD = $(ldadd) + bufp_label_SOURCES = bufp-label.c bufp_label_CPPFLAGS = $(cppflags) bufp_label_LDFLAGS = $(ldflags) diff --git a/demo/posix/cobalt/gpiopwm.c b/demo/posix/cobalt/gpiopwm.c new file mode 100644 index 000..e093fbe --- /dev/null +++ b/demo/posix/cobalt/gpiopwm.c @@ -0,0 +1,448 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MIN_DUTY_CYCLE 0 +#define MAX_DUTY_CYCLE 100 + +typedef void *(*gpiopwm_control_thread)(void *cookie); +#define DEVICE_NAME "/dev/rtdm/gpiopwm" +char *device_name; +int dev; + +static sem_t synch; +static sem_t setup; +static int stop; +static int step = 1; +static int port = 6; + +#define GPIO_PWM_SERVO_CONFIG \ +{ \ + .duty_cycle = 50, \ + .range_min = 950,\ + .range_max = 2050, \ + .period = 2000, \ + .gpio = 1, \ +} + +static struct gpiopwm config = GPIO_PWM_SERVO_CONFIG; + +static void fail(const char *reason) +{ + perror(reason); + exit(EXIT_FAILURE); +} + +static void sem_sync(sem_t *sem) +{ + int ret; + + for (;;) { + ret = sem_wait(sem); + if (ret == 0) + return; + if (errno != EINTR) + fail("sem_wait"); + } +} + +static inline void clear_screen(void) +{ + const char* cmd = "\e[1;1H\e[2J"; + int ret; + + ret = write(2, cmd, strlen(cmd)); + if (!ret) + error(1, ret, "clear screen error"); +} + +static inline void print_config(char *str) +{ + printf("Config: %s\n", str); + printf(" device : %s\n", device_name); + printf(" range : [%d, %d]\n", config.range_min, config.range_max); + printf(" period : %d nsec\n", config.period); + printf(" gpio pin : %d\n", config.gpio); + printf(" duty cycle : %d\n", config.duty_cycle); +} + +static inline void input_message(void) +{ + print_config(""); + printf("\n GPIO PWM Control\n"); + printf( " Enter duty_cycle [0-100] : "); +} + +static void setup_sched_parameters(pthread_attr_t *attr, int prio) +{ + struct sched_param p; + int ret; + + ret = pthread_attr_init(attr); + if (ret) + error(1, ret, "pthread_attr_init()"); + + ret = pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED); + if (ret) + error(1, ret, "pthread_attr_setinheritsched()"); + + ret = pthread_attr_setschedpolicy(attr, prio ? SCHED_FIFO : SCHED_OTHER); + if (ret) + error(1, ret, "pthread_attr_setschedpolicy()"); + + p.sched_priority = prio; + ret = pthread_attr_setschedparam(attr, &p); + if (ret) + error(1, ret, "pthread_attr_setschedparam()"); +} + +static void *gpiopwm_init_thread(void *cookie) +{ + int ret; + + pthread_setname_np(pthread_self(), "gpio-pwm-handler"); + ret = ioctl(dev, GPIOPWM_RTIOC_SET_CONFIG, config); + if (ret) + error(1, ret, "failed to set config"); + + ioctl(dev, GPIOPWM_RTIOC_START); + + /* setup compl
[Xenomai-git] Jorge Ramirez-Ortiz : gpiopwm: pwm signal generator and servo motor control demo code
Module: xenomai-3 Branch: next Commit: 73bbea7066f72d9d6feca24880d4c276b3221868 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=73bbea7066f72d9d6feca24880d4c276b3221868 Author: Jorge Ramirez-Ortiz Date: Tue Mar 15 19:18:15 2016 -0400 gpiopwm: pwm signal generator and servo motor control demo code --- demo/posix/cobalt/Makefile.am|6 + demo/posix/cobalt/gpiopwm.c | 448 ++ include/cobalt/kernel/rtdm/gpiopwm.h | 24 ++ include/rtdm/uapi/gpiopwm.h | 56 + include/rtdm/uapi/rtdm.h |1 + kernel/drivers/Kconfig |1 + kernel/drivers/Makefile |2 +- kernel/drivers/gpiopwm/Kconfig |9 + kernel/drivers/gpiopwm/Makefile |5 + kernel/drivers/gpiopwm/gpiopwm.c | 301 +++ 10 files changed, 852 insertions(+), 1 deletion(-) diff --git a/demo/posix/cobalt/Makefile.am b/demo/posix/cobalt/Makefile.am index cba9247..2a22967 100644 --- a/demo/posix/cobalt/Makefile.am +++ b/demo/posix/cobalt/Makefile.am @@ -3,6 +3,7 @@ demodir = @XENO_DEMO_DIR@ CCLD = $(top_srcdir)/scripts/wrap-link.sh $(CC) demo_PROGRAMS =\ + gpiopwm \ bufp-label \ bufp-readwrite \ can_rtt \ @@ -24,6 +25,11 @@ ldadd = \ @XENO_USER_LDADD@ \ -lpthread -lrt +gpiopwm_SOURCES = gpiopwm.c +gpiopwm_CPPFLAGS = $(cppflags) -I$(top_srcdir)/include/rtdm/uapi +gpiopwm_LDFLAGS = $(ldflags) +gpiopwm_LDADD = $(ldadd) + bufp_label_SOURCES = bufp-label.c bufp_label_CPPFLAGS = $(cppflags) bufp_label_LDFLAGS = $(ldflags) diff --git a/demo/posix/cobalt/gpiopwm.c b/demo/posix/cobalt/gpiopwm.c new file mode 100644 index 000..e093fbe --- /dev/null +++ b/demo/posix/cobalt/gpiopwm.c @@ -0,0 +1,448 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MIN_DUTY_CYCLE 0 +#define MAX_DUTY_CYCLE 100 + +typedef void *(*gpiopwm_control_thread)(void *cookie); +#define DEVICE_NAME "/dev/rtdm/gpiopwm" +char *device_name; +int dev; + +static sem_t synch; +static sem_t setup; +static int stop; +static int step = 1; +static int port = 6; + +#define GPIO_PWM_SERVO_CONFIG \ +{ \ + .duty_cycle = 50, \ + .range_min = 950,\ + .range_max = 2050, \ + .period = 2000, \ + .gpio = 1, \ +} + +static struct gpiopwm config = GPIO_PWM_SERVO_CONFIG; + +static void fail(const char *reason) +{ + perror(reason); + exit(EXIT_FAILURE); +} + +static void sem_sync(sem_t *sem) +{ + int ret; + + for (;;) { + ret = sem_wait(sem); + if (ret == 0) + return; + if (errno != EINTR) + fail("sem_wait"); + } +} + +static inline void clear_screen(void) +{ + const char* cmd = "\e[1;1H\e[2J"; + int ret; + + ret = write(2, cmd, strlen(cmd)); + if (!ret) + error(1, ret, "clear screen error"); +} + +static inline void print_config(char *str) +{ + printf("Config: %s\n", str); + printf(" device : %s\n", device_name); + printf(" range : [%d, %d]\n", config.range_min, config.range_max); + printf(" period : %d nsec\n", config.period); + printf(" gpio pin : %d\n", config.gpio); + printf(" duty cycle : %d\n", config.duty_cycle); +} + +static inline void input_message(void) +{ + print_config(""); + printf("\n GPIO PWM Control\n"); + printf( " Enter duty_cycle [0-100] : "); +} + +static void setup_sched_parameters(pthread_attr_t *attr, int prio) +{ + struct sched_param p; + int ret; + + ret = pthread_attr_init(attr); + if (ret) + error(1, ret, "pthread_attr_init()"); + + ret = pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED); + if (ret) + error(1, ret, "pthread_attr_setinheritsched()"); + + ret = pthread_attr_setschedpolicy(attr, prio ? SCHED_FIFO : SCHED_OTHER); + if (ret) + error(1, ret, "pthread_attr_setschedpolicy()"); + + p.sched_priority = prio; + ret = pthread_attr_setschedparam(attr, &p); + if (ret) + error(1, ret, "pthread_attr_setschedparam()"); +} + +static void *gpiopwm_init_thread(void *cookie) +{ + int ret; + + pthread_setname_np(pthread_self(), "gpio-pwm-handler"); + ret = ioctl(dev, GPIOPWM_RTIOC_SET_CONFIG, config); + if (ret) + error(1, ret, "failed to set config"); + + ioctl(dev, GPIOPWM_RTIOC_START); + + /* setup compl
[Xenomai-git] Jorge Ramirez-Ortiz : gpiopwm: pwm signal generator and servo motor control demo code
Module: xenomai-3 Branch: next Commit: 27f7a3ce542a581d7767bb2765d83c131ec02ba5 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=27f7a3ce542a581d7767bb2765d83c131ec02ba5 Author: Jorge Ramirez-Ortiz Date: Tue Mar 15 19:18:15 2016 -0400 gpiopwm: pwm signal generator and servo motor control demo code --- demo/posix/cobalt/Makefile.am|6 + demo/posix/cobalt/gpiopwm.c | 448 ++ include/cobalt/kernel/rtdm/gpiopwm.h | 24 ++ include/rtdm/uapi/gpiopwm.h | 56 + include/rtdm/uapi/rtdm.h |1 + kernel/drivers/Kconfig |1 + kernel/drivers/Makefile |2 +- kernel/drivers/gpiopwm/Kconfig |9 + kernel/drivers/gpiopwm/Makefile |5 + kernel/drivers/gpiopwm/gpiopwm.c | 301 +++ 10 files changed, 852 insertions(+), 1 deletion(-) diff --git a/demo/posix/cobalt/Makefile.am b/demo/posix/cobalt/Makefile.am index cba9247..2a22967 100644 --- a/demo/posix/cobalt/Makefile.am +++ b/demo/posix/cobalt/Makefile.am @@ -3,6 +3,7 @@ demodir = @XENO_DEMO_DIR@ CCLD = $(top_srcdir)/scripts/wrap-link.sh $(CC) demo_PROGRAMS =\ + gpiopwm \ bufp-label \ bufp-readwrite \ can_rtt \ @@ -24,6 +25,11 @@ ldadd = \ @XENO_USER_LDADD@ \ -lpthread -lrt +gpiopwm_SOURCES = gpiopwm.c +gpiopwm_CPPFLAGS = $(cppflags) -I$(top_srcdir)/include/rtdm/uapi +gpiopwm_LDFLAGS = $(ldflags) +gpiopwm_LDADD = $(ldadd) + bufp_label_SOURCES = bufp-label.c bufp_label_CPPFLAGS = $(cppflags) bufp_label_LDFLAGS = $(ldflags) diff --git a/demo/posix/cobalt/gpiopwm.c b/demo/posix/cobalt/gpiopwm.c new file mode 100644 index 000..e093fbe --- /dev/null +++ b/demo/posix/cobalt/gpiopwm.c @@ -0,0 +1,448 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MIN_DUTY_CYCLE 0 +#define MAX_DUTY_CYCLE 100 + +typedef void *(*gpiopwm_control_thread)(void *cookie); +#define DEVICE_NAME "/dev/rtdm/gpiopwm" +char *device_name; +int dev; + +static sem_t synch; +static sem_t setup; +static int stop; +static int step = 1; +static int port = 6; + +#define GPIO_PWM_SERVO_CONFIG \ +{ \ + .duty_cycle = 50, \ + .range_min = 950,\ + .range_max = 2050, \ + .period = 2000, \ + .gpio = 1, \ +} + +static struct gpiopwm config = GPIO_PWM_SERVO_CONFIG; + +static void fail(const char *reason) +{ + perror(reason); + exit(EXIT_FAILURE); +} + +static void sem_sync(sem_t *sem) +{ + int ret; + + for (;;) { + ret = sem_wait(sem); + if (ret == 0) + return; + if (errno != EINTR) + fail("sem_wait"); + } +} + +static inline void clear_screen(void) +{ + const char* cmd = "\e[1;1H\e[2J"; + int ret; + + ret = write(2, cmd, strlen(cmd)); + if (!ret) + error(1, ret, "clear screen error"); +} + +static inline void print_config(char *str) +{ + printf("Config: %s\n", str); + printf(" device : %s\n", device_name); + printf(" range : [%d, %d]\n", config.range_min, config.range_max); + printf(" period : %d nsec\n", config.period); + printf(" gpio pin : %d\n", config.gpio); + printf(" duty cycle : %d\n", config.duty_cycle); +} + +static inline void input_message(void) +{ + print_config(""); + printf("\n GPIO PWM Control\n"); + printf( " Enter duty_cycle [0-100] : "); +} + +static void setup_sched_parameters(pthread_attr_t *attr, int prio) +{ + struct sched_param p; + int ret; + + ret = pthread_attr_init(attr); + if (ret) + error(1, ret, "pthread_attr_init()"); + + ret = pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED); + if (ret) + error(1, ret, "pthread_attr_setinheritsched()"); + + ret = pthread_attr_setschedpolicy(attr, prio ? SCHED_FIFO : SCHED_OTHER); + if (ret) + error(1, ret, "pthread_attr_setschedpolicy()"); + + p.sched_priority = prio; + ret = pthread_attr_setschedparam(attr, &p); + if (ret) + error(1, ret, "pthread_attr_setschedparam()"); +} + +static void *gpiopwm_init_thread(void *cookie) +{ + int ret; + + pthread_setname_np(pthread_self(), "gpio-pwm-handler"); + ret = ioctl(dev, GPIOPWM_RTIOC_SET_CONFIG, config); + if (ret) + error(1, ret, "failed to set config"); + + ioctl(dev, GPIOPWM_RTIOC_START); + + /* setup compl
[Xenomai-git] Jorge Ramirez-Ortiz : gpiopwm: pwm signal generator and servo motor control demo code
Module: xenomai-3 Branch: next Commit: c0084cb601a0444c9f3f56a6065c3e7e718f9a5b URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=c0084cb601a0444c9f3f56a6065c3e7e718f9a5b Author: Jorge Ramirez-Ortiz Date: Tue Mar 15 19:18:15 2016 -0400 gpiopwm: pwm signal generator and servo motor control demo code --- demo/posix/cobalt/Makefile.am|6 + demo/posix/cobalt/gpiopwm.c | 448 ++ include/cobalt/kernel/rtdm/gpiopwm.h | 24 ++ include/rtdm/uapi/gpiopwm.h | 56 + include/rtdm/uapi/rtdm.h |1 + kernel/drivers/Kconfig |1 + kernel/drivers/Makefile |2 +- kernel/drivers/gpiopwm/Kconfig |9 + kernel/drivers/gpiopwm/Makefile |5 + kernel/drivers/gpiopwm/gpiopwm.c | 301 +++ 10 files changed, 852 insertions(+), 1 deletion(-) diff --git a/demo/posix/cobalt/Makefile.am b/demo/posix/cobalt/Makefile.am index cba9247..2a22967 100644 --- a/demo/posix/cobalt/Makefile.am +++ b/demo/posix/cobalt/Makefile.am @@ -3,6 +3,7 @@ demodir = @XENO_DEMO_DIR@ CCLD = $(top_srcdir)/scripts/wrap-link.sh $(CC) demo_PROGRAMS =\ + gpiopwm \ bufp-label \ bufp-readwrite \ can_rtt \ @@ -24,6 +25,11 @@ ldadd = \ @XENO_USER_LDADD@ \ -lpthread -lrt +gpiopwm_SOURCES = gpiopwm.c +gpiopwm_CPPFLAGS = $(cppflags) -I$(top_srcdir)/include/rtdm/uapi +gpiopwm_LDFLAGS = $(ldflags) +gpiopwm_LDADD = $(ldadd) + bufp_label_SOURCES = bufp-label.c bufp_label_CPPFLAGS = $(cppflags) bufp_label_LDFLAGS = $(ldflags) diff --git a/demo/posix/cobalt/gpiopwm.c b/demo/posix/cobalt/gpiopwm.c new file mode 100644 index 000..e093fbe --- /dev/null +++ b/demo/posix/cobalt/gpiopwm.c @@ -0,0 +1,448 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MIN_DUTY_CYCLE 0 +#define MAX_DUTY_CYCLE 100 + +typedef void *(*gpiopwm_control_thread)(void *cookie); +#define DEVICE_NAME "/dev/rtdm/gpiopwm" +char *device_name; +int dev; + +static sem_t synch; +static sem_t setup; +static int stop; +static int step = 1; +static int port = 6; + +#define GPIO_PWM_SERVO_CONFIG \ +{ \ + .duty_cycle = 50, \ + .range_min = 950,\ + .range_max = 2050, \ + .period = 2000, \ + .gpio = 1, \ +} + +static struct gpiopwm config = GPIO_PWM_SERVO_CONFIG; + +static void fail(const char *reason) +{ + perror(reason); + exit(EXIT_FAILURE); +} + +static void sem_sync(sem_t *sem) +{ + int ret; + + for (;;) { + ret = sem_wait(sem); + if (ret == 0) + return; + if (errno != EINTR) + fail("sem_wait"); + } +} + +static inline void clear_screen(void) +{ + const char* cmd = "\e[1;1H\e[2J"; + int ret; + + ret = write(2, cmd, strlen(cmd)); + if (!ret) + error(1, ret, "clear screen error"); +} + +static inline void print_config(char *str) +{ + printf("Config: %s\n", str); + printf(" device : %s\n", device_name); + printf(" range : [%d, %d]\n", config.range_min, config.range_max); + printf(" period : %d nsec\n", config.period); + printf(" gpio pin : %d\n", config.gpio); + printf(" duty cycle : %d\n", config.duty_cycle); +} + +static inline void input_message(void) +{ + print_config(""); + printf("\n GPIO PWM Control\n"); + printf( " Enter duty_cycle [0-100] : "); +} + +static void setup_sched_parameters(pthread_attr_t *attr, int prio) +{ + struct sched_param p; + int ret; + + ret = pthread_attr_init(attr); + if (ret) + error(1, ret, "pthread_attr_init()"); + + ret = pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED); + if (ret) + error(1, ret, "pthread_attr_setinheritsched()"); + + ret = pthread_attr_setschedpolicy(attr, prio ? SCHED_FIFO : SCHED_OTHER); + if (ret) + error(1, ret, "pthread_attr_setschedpolicy()"); + + p.sched_priority = prio; + ret = pthread_attr_setschedparam(attr, &p); + if (ret) + error(1, ret, "pthread_attr_setschedparam()"); +} + +static void *gpiopwm_init_thread(void *cookie) +{ + int ret; + + pthread_setname_np(pthread_self(), "gpio-pwm-handler"); + ret = ioctl(dev, GPIOPWM_RTIOC_SET_CONFIG, config); + if (ret) + error(1, ret, "failed to set config"); + + ioctl(dev, GPIOPWM_RTIOC_START); + + /* setup compl
[Xenomai-git] Jorge Ramirez-Ortiz : gpiopwm: pwm signal generator and servo motor control demo code
Module: xenomai-3 Branch: next Commit: b4ba63759880ee32778da967c9c63a94c6c8ad4c URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=b4ba63759880ee32778da967c9c63a94c6c8ad4c Author: Jorge Ramirez-Ortiz Date: Tue Mar 15 19:18:15 2016 -0400 gpiopwm: pwm signal generator and servo motor control demo code --- demo/posix/cobalt/Makefile.am|6 + demo/posix/cobalt/gpiopwm.c | 448 ++ include/cobalt/kernel/rtdm/gpiopwm.h | 24 ++ include/rtdm/uapi/gpiopwm.h | 56 + include/rtdm/uapi/rtdm.h |1 + kernel/drivers/Kconfig |1 + kernel/drivers/Makefile |2 +- kernel/drivers/gpiopwm/Kconfig |9 + kernel/drivers/gpiopwm/Makefile |5 + kernel/drivers/gpiopwm/gpiopwm.c | 301 +++ 10 files changed, 852 insertions(+), 1 deletion(-) diff --git a/demo/posix/cobalt/Makefile.am b/demo/posix/cobalt/Makefile.am index cba9247..2a22967 100644 --- a/demo/posix/cobalt/Makefile.am +++ b/demo/posix/cobalt/Makefile.am @@ -3,6 +3,7 @@ demodir = @XENO_DEMO_DIR@ CCLD = $(top_srcdir)/scripts/wrap-link.sh $(CC) demo_PROGRAMS =\ + gpiopwm \ bufp-label \ bufp-readwrite \ can_rtt \ @@ -24,6 +25,11 @@ ldadd = \ @XENO_USER_LDADD@ \ -lpthread -lrt +gpiopwm_SOURCES = gpiopwm.c +gpiopwm_CPPFLAGS = $(cppflags) -I$(top_srcdir)/include/rtdm/uapi +gpiopwm_LDFLAGS = $(ldflags) +gpiopwm_LDADD = $(ldadd) + bufp_label_SOURCES = bufp-label.c bufp_label_CPPFLAGS = $(cppflags) bufp_label_LDFLAGS = $(ldflags) diff --git a/demo/posix/cobalt/gpiopwm.c b/demo/posix/cobalt/gpiopwm.c new file mode 100644 index 000..e093fbe --- /dev/null +++ b/demo/posix/cobalt/gpiopwm.c @@ -0,0 +1,448 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MIN_DUTY_CYCLE 0 +#define MAX_DUTY_CYCLE 100 + +typedef void *(*gpiopwm_control_thread)(void *cookie); +#define DEVICE_NAME "/dev/rtdm/gpiopwm" +char *device_name; +int dev; + +static sem_t synch; +static sem_t setup; +static int stop; +static int step = 1; +static int port = 6; + +#define GPIO_PWM_SERVO_CONFIG \ +{ \ + .duty_cycle = 50, \ + .range_min = 950,\ + .range_max = 2050, \ + .period = 2000, \ + .gpio = 1, \ +} + +static struct gpiopwm config = GPIO_PWM_SERVO_CONFIG; + +static void fail(const char *reason) +{ + perror(reason); + exit(EXIT_FAILURE); +} + +static void sem_sync(sem_t *sem) +{ + int ret; + + for (;;) { + ret = sem_wait(sem); + if (ret == 0) + return; + if (errno != EINTR) + fail("sem_wait"); + } +} + +static inline void clear_screen(void) +{ + const char* cmd = "\e[1;1H\e[2J"; + int ret; + + ret = write(2, cmd, strlen(cmd)); + if (!ret) + error(1, ret, "clear screen error"); +} + +static inline void print_config(char *str) +{ + printf("Config: %s\n", str); + printf(" device : %s\n", device_name); + printf(" range : [%d, %d]\n", config.range_min, config.range_max); + printf(" period : %d nsec\n", config.period); + printf(" gpio pin : %d\n", config.gpio); + printf(" duty cycle : %d\n", config.duty_cycle); +} + +static inline void input_message(void) +{ + print_config(""); + printf("\n GPIO PWM Control\n"); + printf( " Enter duty_cycle [0-100] : "); +} + +static void setup_sched_parameters(pthread_attr_t *attr, int prio) +{ + struct sched_param p; + int ret; + + ret = pthread_attr_init(attr); + if (ret) + error(1, ret, "pthread_attr_init()"); + + ret = pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED); + if (ret) + error(1, ret, "pthread_attr_setinheritsched()"); + + ret = pthread_attr_setschedpolicy(attr, prio ? SCHED_FIFO : SCHED_OTHER); + if (ret) + error(1, ret, "pthread_attr_setschedpolicy()"); + + p.sched_priority = prio; + ret = pthread_attr_setschedparam(attr, &p); + if (ret) + error(1, ret, "pthread_attr_setschedparam()"); +} + +static void *gpiopwm_init_thread(void *cookie) +{ + int ret; + + pthread_setname_np(pthread_self(), "gpio-pwm-handler"); + ret = ioctl(dev, GPIOPWM_RTIOC_SET_CONFIG, config); + if (ret) + error(1, ret, "failed to set config"); + + ioctl(dev, GPIOPWM_RTIOC_START); + + /* setup compl
[Xenomai-git] Jorge Ramirez-Ortiz : gpiopwm: pwm signal generator and servo motor control demo code
Module: xenomai-3 Branch: next Commit: 0c9068e847785befd12c5cdcd024a069fc0eb592 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=0c9068e847785befd12c5cdcd024a069fc0eb592 Author: Jorge Ramirez-Ortiz Date: Tue Mar 15 19:18:15 2016 -0400 gpiopwm: pwm signal generator and servo motor control demo code --- demo/posix/cobalt/Makefile.am|6 + demo/posix/cobalt/gpiopwm.c | 448 ++ include/cobalt/kernel/rtdm/gpiopwm.h | 24 ++ include/rtdm/uapi/gpiopwm.h | 56 + include/rtdm/uapi/rtdm.h |1 + kernel/drivers/Kconfig |1 + kernel/drivers/Makefile |2 +- kernel/drivers/gpiopwm/Kconfig |9 + kernel/drivers/gpiopwm/Makefile |5 + kernel/drivers/gpiopwm/gpiopwm.c | 301 +++ 10 files changed, 852 insertions(+), 1 deletion(-) diff --git a/demo/posix/cobalt/Makefile.am b/demo/posix/cobalt/Makefile.am index cba9247..2a22967 100644 --- a/demo/posix/cobalt/Makefile.am +++ b/demo/posix/cobalt/Makefile.am @@ -3,6 +3,7 @@ demodir = @XENO_DEMO_DIR@ CCLD = $(top_srcdir)/scripts/wrap-link.sh $(CC) demo_PROGRAMS =\ + gpiopwm \ bufp-label \ bufp-readwrite \ can_rtt \ @@ -24,6 +25,11 @@ ldadd = \ @XENO_USER_LDADD@ \ -lpthread -lrt +gpiopwm_SOURCES = gpiopwm.c +gpiopwm_CPPFLAGS = $(cppflags) -I$(top_srcdir)/include/rtdm/uapi +gpiopwm_LDFLAGS = $(ldflags) +gpiopwm_LDADD = $(ldadd) + bufp_label_SOURCES = bufp-label.c bufp_label_CPPFLAGS = $(cppflags) bufp_label_LDFLAGS = $(ldflags) diff --git a/demo/posix/cobalt/gpiopwm.c b/demo/posix/cobalt/gpiopwm.c new file mode 100644 index 000..e093fbe --- /dev/null +++ b/demo/posix/cobalt/gpiopwm.c @@ -0,0 +1,448 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MIN_DUTY_CYCLE 0 +#define MAX_DUTY_CYCLE 100 + +typedef void *(*gpiopwm_control_thread)(void *cookie); +#define DEVICE_NAME "/dev/rtdm/gpiopwm" +char *device_name; +int dev; + +static sem_t synch; +static sem_t setup; +static int stop; +static int step = 1; +static int port = 6; + +#define GPIO_PWM_SERVO_CONFIG \ +{ \ + .duty_cycle = 50, \ + .range_min = 950,\ + .range_max = 2050, \ + .period = 2000, \ + .gpio = 1, \ +} + +static struct gpiopwm config = GPIO_PWM_SERVO_CONFIG; + +static void fail(const char *reason) +{ + perror(reason); + exit(EXIT_FAILURE); +} + +static void sem_sync(sem_t *sem) +{ + int ret; + + for (;;) { + ret = sem_wait(sem); + if (ret == 0) + return; + if (errno != EINTR) + fail("sem_wait"); + } +} + +static inline void clear_screen(void) +{ + const char* cmd = "\e[1;1H\e[2J"; + int ret; + + ret = write(2, cmd, strlen(cmd)); + if (!ret) + error(1, ret, "clear screen error"); +} + +static inline void print_config(char *str) +{ + printf("Config: %s\n", str); + printf(" device : %s\n", device_name); + printf(" range : [%d, %d]\n", config.range_min, config.range_max); + printf(" period : %d nsec\n", config.period); + printf(" gpio pin : %d\n", config.gpio); + printf(" duty cycle : %d\n", config.duty_cycle); +} + +static inline void input_message(void) +{ + print_config(""); + printf("\n GPIO PWM Control\n"); + printf( " Enter duty_cycle [0-100] : "); +} + +static void setup_sched_parameters(pthread_attr_t *attr, int prio) +{ + struct sched_param p; + int ret; + + ret = pthread_attr_init(attr); + if (ret) + error(1, ret, "pthread_attr_init()"); + + ret = pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED); + if (ret) + error(1, ret, "pthread_attr_setinheritsched()"); + + ret = pthread_attr_setschedpolicy(attr, prio ? SCHED_FIFO : SCHED_OTHER); + if (ret) + error(1, ret, "pthread_attr_setschedpolicy()"); + + p.sched_priority = prio; + ret = pthread_attr_setschedparam(attr, &p); + if (ret) + error(1, ret, "pthread_attr_setschedparam()"); +} + +static void *gpiopwm_init_thread(void *cookie) +{ + int ret; + + pthread_setname_np(pthread_self(), "gpio-pwm-handler"); + ret = ioctl(dev, GPIOPWM_RTIOC_SET_CONFIG, config); + if (ret) + error(1, ret, "failed to set config"); + + ioctl(dev, GPIOPWM_RTIOC_START); + + /* setup compl
[Xenomai-git] Jorge Ramirez-Ortiz : gpiopwm: pwm signal generator and servo motor control demo code
Module: xenomai-3 Branch: next Commit: 477006f93072807a16272c60c3dcdecb6d17a7bb URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=477006f93072807a16272c60c3dcdecb6d17a7bb Author: Jorge Ramirez-Ortiz Date: Tue Mar 15 19:18:15 2016 -0400 gpiopwm: pwm signal generator and servo motor control demo code --- demo/posix/cobalt/Makefile.am|6 + demo/posix/cobalt/gpiopwm.c | 448 ++ include/cobalt/kernel/rtdm/gpiopwm.h | 24 ++ include/rtdm/uapi/gpiopwm.h | 56 + include/rtdm/uapi/rtdm.h |1 + kernel/drivers/Kconfig |1 + kernel/drivers/Makefile |2 +- kernel/drivers/gpiopwm/Kconfig |9 + kernel/drivers/gpiopwm/Makefile |5 + kernel/drivers/gpiopwm/gpiopwm.c | 301 +++ 10 files changed, 852 insertions(+), 1 deletion(-) diff --git a/demo/posix/cobalt/Makefile.am b/demo/posix/cobalt/Makefile.am index cba9247..2a22967 100644 --- a/demo/posix/cobalt/Makefile.am +++ b/demo/posix/cobalt/Makefile.am @@ -3,6 +3,7 @@ demodir = @XENO_DEMO_DIR@ CCLD = $(top_srcdir)/scripts/wrap-link.sh $(CC) demo_PROGRAMS =\ + gpiopwm \ bufp-label \ bufp-readwrite \ can_rtt \ @@ -24,6 +25,11 @@ ldadd = \ @XENO_USER_LDADD@ \ -lpthread -lrt +gpiopwm_SOURCES = gpiopwm.c +gpiopwm_CPPFLAGS = $(cppflags) -I$(top_srcdir)/include/rtdm/uapi +gpiopwm_LDFLAGS = $(ldflags) +gpiopwm_LDADD = $(ldadd) + bufp_label_SOURCES = bufp-label.c bufp_label_CPPFLAGS = $(cppflags) bufp_label_LDFLAGS = $(ldflags) diff --git a/demo/posix/cobalt/gpiopwm.c b/demo/posix/cobalt/gpiopwm.c new file mode 100644 index 000..e093fbe --- /dev/null +++ b/demo/posix/cobalt/gpiopwm.c @@ -0,0 +1,448 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MIN_DUTY_CYCLE 0 +#define MAX_DUTY_CYCLE 100 + +typedef void *(*gpiopwm_control_thread)(void *cookie); +#define DEVICE_NAME "/dev/rtdm/gpiopwm" +char *device_name; +int dev; + +static sem_t synch; +static sem_t setup; +static int stop; +static int step = 1; +static int port = 6; + +#define GPIO_PWM_SERVO_CONFIG \ +{ \ + .duty_cycle = 50, \ + .range_min = 950,\ + .range_max = 2050, \ + .period = 2000, \ + .gpio = 1, \ +} + +static struct gpiopwm config = GPIO_PWM_SERVO_CONFIG; + +static void fail(const char *reason) +{ + perror(reason); + exit(EXIT_FAILURE); +} + +static void sem_sync(sem_t *sem) +{ + int ret; + + for (;;) { + ret = sem_wait(sem); + if (ret == 0) + return; + if (errno != EINTR) + fail("sem_wait"); + } +} + +static inline void clear_screen(void) +{ + const char* cmd = "\e[1;1H\e[2J"; + int ret; + + ret = write(2, cmd, strlen(cmd)); + if (!ret) + error(1, ret, "clear screen error"); +} + +static inline void print_config(char *str) +{ + printf("Config: %s\n", str); + printf(" device : %s\n", device_name); + printf(" range : [%d, %d]\n", config.range_min, config.range_max); + printf(" period : %d nsec\n", config.period); + printf(" gpio pin : %d\n", config.gpio); + printf(" duty cycle : %d\n", config.duty_cycle); +} + +static inline void input_message(void) +{ + print_config(""); + printf("\n GPIO PWM Control\n"); + printf( " Enter duty_cycle [0-100] : "); +} + +static void setup_sched_parameters(pthread_attr_t *attr, int prio) +{ + struct sched_param p; + int ret; + + ret = pthread_attr_init(attr); + if (ret) + error(1, ret, "pthread_attr_init()"); + + ret = pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED); + if (ret) + error(1, ret, "pthread_attr_setinheritsched()"); + + ret = pthread_attr_setschedpolicy(attr, prio ? SCHED_FIFO : SCHED_OTHER); + if (ret) + error(1, ret, "pthread_attr_setschedpolicy()"); + + p.sched_priority = prio; + ret = pthread_attr_setschedparam(attr, &p); + if (ret) + error(1, ret, "pthread_attr_setschedparam()"); +} + +static void *gpiopwm_init_thread(void *cookie) +{ + int ret; + + pthread_setname_np(pthread_self(), "gpio-pwm-handler"); + ret = ioctl(dev, GPIOPWM_RTIOC_SET_CONFIG, config); + if (ret) + error(1, ret, "failed to set config"); + + ioctl(dev, GPIOPWM_RTIOC_START); + + /* setup compl
[Xenomai-git] Jorge Ramirez-Ortiz : gpiopwm: pwm signal generator and servo motor control demo code
Module: xenomai-3 Branch: next Commit: 28376dd3d121e59de6e8609a60acddbf8a958610 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=28376dd3d121e59de6e8609a60acddbf8a958610 Author: Jorge Ramirez-Ortiz Date: Tue Mar 15 19:18:15 2016 -0400 gpiopwm: pwm signal generator and servo motor control demo code --- demo/posix/cobalt/Makefile.am|6 + demo/posix/cobalt/gpiopwm.c | 448 ++ include/cobalt/kernel/rtdm/gpiopwm.h | 24 ++ include/rtdm/uapi/gpiopwm.h | 56 + include/rtdm/uapi/rtdm.h |1 + kernel/drivers/Kconfig |1 + kernel/drivers/Makefile |2 +- kernel/drivers/gpiopwm/Kconfig |9 + kernel/drivers/gpiopwm/Makefile |5 + kernel/drivers/gpiopwm/gpiopwm.c | 301 +++ 10 files changed, 852 insertions(+), 1 deletion(-) diff --git a/demo/posix/cobalt/Makefile.am b/demo/posix/cobalt/Makefile.am index eedc346..9e35cf1 100644 --- a/demo/posix/cobalt/Makefile.am +++ b/demo/posix/cobalt/Makefile.am @@ -3,6 +3,7 @@ demodir = @XENO_DEMO_DIR@ CCLD = $(top_srcdir)/scripts/wrap-link.sh $(CC) demo_PROGRAMS =\ + gpiopwm \ bufp-label \ bufp-readwrite \ can_rtt \ @@ -24,6 +25,11 @@ ldadd = \ @XENO_USER_LDADD@ \ -lpthread -lrt +gpiopwm_SOURCES = gpiopwm.c +gpiopwm_CPPFLAGS = $(cppflags) -I$(top_srcdir)/include/rtdm/uapi +gpiopwm_LDFLAGS = $(ldflags) +gpiopwm_LDADD = $(ldadd) + bufp_label_SOURCES = bufp-label.c bufp_label_CPPFLAGS = $(cppflags) bufp_label_LDFLAGS = $(ldflags) diff --git a/demo/posix/cobalt/gpiopwm.c b/demo/posix/cobalt/gpiopwm.c new file mode 100644 index 000..e093fbe --- /dev/null +++ b/demo/posix/cobalt/gpiopwm.c @@ -0,0 +1,448 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MIN_DUTY_CYCLE 0 +#define MAX_DUTY_CYCLE 100 + +typedef void *(*gpiopwm_control_thread)(void *cookie); +#define DEVICE_NAME "/dev/rtdm/gpiopwm" +char *device_name; +int dev; + +static sem_t synch; +static sem_t setup; +static int stop; +static int step = 1; +static int port = 6; + +#define GPIO_PWM_SERVO_CONFIG \ +{ \ + .duty_cycle = 50, \ + .range_min = 950,\ + .range_max = 2050, \ + .period = 2000, \ + .gpio = 1, \ +} + +static struct gpiopwm config = GPIO_PWM_SERVO_CONFIG; + +static void fail(const char *reason) +{ + perror(reason); + exit(EXIT_FAILURE); +} + +static void sem_sync(sem_t *sem) +{ + int ret; + + for (;;) { + ret = sem_wait(sem); + if (ret == 0) + return; + if (errno != EINTR) + fail("sem_wait"); + } +} + +static inline void clear_screen(void) +{ + const char* cmd = "\e[1;1H\e[2J"; + int ret; + + ret = write(2, cmd, strlen(cmd)); + if (!ret) + error(1, ret, "clear screen error"); +} + +static inline void print_config(char *str) +{ + printf("Config: %s\n", str); + printf(" device : %s\n", device_name); + printf(" range : [%d, %d]\n", config.range_min, config.range_max); + printf(" period : %d nsec\n", config.period); + printf(" gpio pin : %d\n", config.gpio); + printf(" duty cycle : %d\n", config.duty_cycle); +} + +static inline void input_message(void) +{ + print_config(""); + printf("\n GPIO PWM Control\n"); + printf( " Enter duty_cycle [0-100] : "); +} + +static void setup_sched_parameters(pthread_attr_t *attr, int prio) +{ + struct sched_param p; + int ret; + + ret = pthread_attr_init(attr); + if (ret) + error(1, ret, "pthread_attr_init()"); + + ret = pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED); + if (ret) + error(1, ret, "pthread_attr_setinheritsched()"); + + ret = pthread_attr_setschedpolicy(attr, prio ? SCHED_FIFO : SCHED_OTHER); + if (ret) + error(1, ret, "pthread_attr_setschedpolicy()"); + + p.sched_priority = prio; + ret = pthread_attr_setschedparam(attr, &p); + if (ret) + error(1, ret, "pthread_attr_setschedparam()"); +} + +static void *gpiopwm_init_thread(void *cookie) +{ + int ret; + + pthread_setname_np(pthread_self(), "gpio-pwm-handler"); + ret = ioctl(dev, GPIOPWM_RTIOC_SET_CONFIG, config); + if (ret) + error(1, ret, "failed to set config"); + + ioctl(dev, GPIOPWM_RTIOC_START); + + /* setup compl
[Xenomai-git] Jorge Ramirez-Ortiz : gpiopwm: pwm signal generator and servo motor control demo code
Module: xenomai-3 Branch: next Commit: ea4a140e31286aee23505c0495303c6d0825aaf4 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=ea4a140e31286aee23505c0495303c6d0825aaf4 Author: Jorge Ramirez-Ortiz Date: Tue Mar 15 19:18:15 2016 -0400 gpiopwm: pwm signal generator and servo motor control demo code --- demo/posix/cobalt/Makefile.am|6 + demo/posix/cobalt/gpiopwm.c | 448 ++ include/cobalt/kernel/rtdm/gpiopwm.h | 24 ++ include/rtdm/uapi/gpiopwm.h | 56 + include/rtdm/uapi/rtdm.h |1 + kernel/drivers/Kconfig |1 + kernel/drivers/Makefile |2 +- kernel/drivers/gpiopwm/Kconfig |9 + kernel/drivers/gpiopwm/Makefile |5 + kernel/drivers/gpiopwm/gpiopwm.c | 301 +++ 10 files changed, 852 insertions(+), 1 deletion(-) diff --git a/demo/posix/cobalt/Makefile.am b/demo/posix/cobalt/Makefile.am index eedc346..9e35cf1 100644 --- a/demo/posix/cobalt/Makefile.am +++ b/demo/posix/cobalt/Makefile.am @@ -3,6 +3,7 @@ demodir = @XENO_DEMO_DIR@ CCLD = $(top_srcdir)/scripts/wrap-link.sh $(CC) demo_PROGRAMS =\ + gpiopwm \ bufp-label \ bufp-readwrite \ can_rtt \ @@ -24,6 +25,11 @@ ldadd = \ @XENO_USER_LDADD@ \ -lpthread -lrt +gpiopwm_SOURCES = gpiopwm.c +gpiopwm_CPPFLAGS = $(cppflags) -I$(top_srcdir)/include/rtdm/uapi +gpiopwm_LDFLAGS = $(ldflags) +gpiopwm_LDADD = $(ldadd) + bufp_label_SOURCES = bufp-label.c bufp_label_CPPFLAGS = $(cppflags) bufp_label_LDFLAGS = $(ldflags) diff --git a/demo/posix/cobalt/gpiopwm.c b/demo/posix/cobalt/gpiopwm.c new file mode 100644 index 000..e093fbe --- /dev/null +++ b/demo/posix/cobalt/gpiopwm.c @@ -0,0 +1,448 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MIN_DUTY_CYCLE 0 +#define MAX_DUTY_CYCLE 100 + +typedef void *(*gpiopwm_control_thread)(void *cookie); +#define DEVICE_NAME "/dev/rtdm/gpiopwm" +char *device_name; +int dev; + +static sem_t synch; +static sem_t setup; +static int stop; +static int step = 1; +static int port = 6; + +#define GPIO_PWM_SERVO_CONFIG \ +{ \ + .duty_cycle = 50, \ + .range_min = 950,\ + .range_max = 2050, \ + .period = 2000, \ + .gpio = 1, \ +} + +static struct gpiopwm config = GPIO_PWM_SERVO_CONFIG; + +static void fail(const char *reason) +{ + perror(reason); + exit(EXIT_FAILURE); +} + +static void sem_sync(sem_t *sem) +{ + int ret; + + for (;;) { + ret = sem_wait(sem); + if (ret == 0) + return; + if (errno != EINTR) + fail("sem_wait"); + } +} + +static inline void clear_screen(void) +{ + const char* cmd = "\e[1;1H\e[2J"; + int ret; + + ret = write(2, cmd, strlen(cmd)); + if (!ret) + error(1, ret, "clear screen error"); +} + +static inline void print_config(char *str) +{ + printf("Config: %s\n", str); + printf(" device : %s\n", device_name); + printf(" range : [%d, %d]\n", config.range_min, config.range_max); + printf(" period : %d nsec\n", config.period); + printf(" gpio pin : %d\n", config.gpio); + printf(" duty cycle : %d\n", config.duty_cycle); +} + +static inline void input_message(void) +{ + print_config(""); + printf("\n GPIO PWM Control\n"); + printf( " Enter duty_cycle [0-100] : "); +} + +static void setup_sched_parameters(pthread_attr_t *attr, int prio) +{ + struct sched_param p; + int ret; + + ret = pthread_attr_init(attr); + if (ret) + error(1, ret, "pthread_attr_init()"); + + ret = pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED); + if (ret) + error(1, ret, "pthread_attr_setinheritsched()"); + + ret = pthread_attr_setschedpolicy(attr, prio ? SCHED_FIFO : SCHED_OTHER); + if (ret) + error(1, ret, "pthread_attr_setschedpolicy()"); + + p.sched_priority = prio; + ret = pthread_attr_setschedparam(attr, &p); + if (ret) + error(1, ret, "pthread_attr_setschedparam()"); +} + +static void *gpiopwm_init_thread(void *cookie) +{ + int ret; + + pthread_setname_np(pthread_self(), "gpio-pwm-handler"); + ret = ioctl(dev, GPIOPWM_RTIOC_SET_CONFIG, config); + if (ret) + error(1, ret, "failed to set config"); + + ioctl(dev, GPIOPWM_RTIOC_START); + + /* setup compl
[Xenomai-git] Jorge Ramirez-Ortiz : gpiopwm: pwm signal generator and servo motor control demo code
Module: xenomai-3 Branch: next Commit: cb4339bd38ed71567bb006f4c0bb15c3e43e1761 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=cb4339bd38ed71567bb006f4c0bb15c3e43e1761 Author: Jorge Ramirez-Ortiz Date: Tue Mar 15 19:18:15 2016 -0400 gpiopwm: pwm signal generator and servo motor control demo code --- demo/posix/cobalt/Makefile.am|6 + demo/posix/cobalt/gpiopwm.c | 448 ++ include/cobalt/kernel/rtdm/gpiopwm.h | 24 ++ include/rtdm/uapi/gpiopwm.h | 56 + include/rtdm/uapi/rtdm.h |1 + kernel/drivers/Kconfig |1 + kernel/drivers/Makefile |2 +- kernel/drivers/gpiopwm/Kconfig |9 + kernel/drivers/gpiopwm/Makefile |5 + kernel/drivers/gpiopwm/gpiopwm.c | 301 +++ 10 files changed, 852 insertions(+), 1 deletion(-) diff --git a/demo/posix/cobalt/Makefile.am b/demo/posix/cobalt/Makefile.am index eedc346..9e35cf1 100644 --- a/demo/posix/cobalt/Makefile.am +++ b/demo/posix/cobalt/Makefile.am @@ -3,6 +3,7 @@ demodir = @XENO_DEMO_DIR@ CCLD = $(top_srcdir)/scripts/wrap-link.sh $(CC) demo_PROGRAMS =\ + gpiopwm \ bufp-label \ bufp-readwrite \ can_rtt \ @@ -24,6 +25,11 @@ ldadd = \ @XENO_USER_LDADD@ \ -lpthread -lrt +gpiopwm_SOURCES = gpiopwm.c +gpiopwm_CPPFLAGS = $(cppflags) -I$(top_srcdir)/include/rtdm/uapi +gpiopwm_LDFLAGS = $(ldflags) +gpiopwm_LDADD = $(ldadd) + bufp_label_SOURCES = bufp-label.c bufp_label_CPPFLAGS = $(cppflags) bufp_label_LDFLAGS = $(ldflags) diff --git a/demo/posix/cobalt/gpiopwm.c b/demo/posix/cobalt/gpiopwm.c new file mode 100644 index 000..e093fbe --- /dev/null +++ b/demo/posix/cobalt/gpiopwm.c @@ -0,0 +1,448 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MIN_DUTY_CYCLE 0 +#define MAX_DUTY_CYCLE 100 + +typedef void *(*gpiopwm_control_thread)(void *cookie); +#define DEVICE_NAME "/dev/rtdm/gpiopwm" +char *device_name; +int dev; + +static sem_t synch; +static sem_t setup; +static int stop; +static int step = 1; +static int port = 6; + +#define GPIO_PWM_SERVO_CONFIG \ +{ \ + .duty_cycle = 50, \ + .range_min = 950,\ + .range_max = 2050, \ + .period = 2000, \ + .gpio = 1, \ +} + +static struct gpiopwm config = GPIO_PWM_SERVO_CONFIG; + +static void fail(const char *reason) +{ + perror(reason); + exit(EXIT_FAILURE); +} + +static void sem_sync(sem_t *sem) +{ + int ret; + + for (;;) { + ret = sem_wait(sem); + if (ret == 0) + return; + if (errno != EINTR) + fail("sem_wait"); + } +} + +static inline void clear_screen(void) +{ + const char* cmd = "\e[1;1H\e[2J"; + int ret; + + ret = write(2, cmd, strlen(cmd)); + if (!ret) + error(1, ret, "clear screen error"); +} + +static inline void print_config(char *str) +{ + printf("Config: %s\n", str); + printf(" device : %s\n", device_name); + printf(" range : [%d, %d]\n", config.range_min, config.range_max); + printf(" period : %d nsec\n", config.period); + printf(" gpio pin : %d\n", config.gpio); + printf(" duty cycle : %d\n", config.duty_cycle); +} + +static inline void input_message(void) +{ + print_config(""); + printf("\n GPIO PWM Control\n"); + printf( " Enter duty_cycle [0-100] : "); +} + +static void setup_sched_parameters(pthread_attr_t *attr, int prio) +{ + struct sched_param p; + int ret; + + ret = pthread_attr_init(attr); + if (ret) + error(1, ret, "pthread_attr_init()"); + + ret = pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED); + if (ret) + error(1, ret, "pthread_attr_setinheritsched()"); + + ret = pthread_attr_setschedpolicy(attr, prio ? SCHED_FIFO : SCHED_OTHER); + if (ret) + error(1, ret, "pthread_attr_setschedpolicy()"); + + p.sched_priority = prio; + ret = pthread_attr_setschedparam(attr, &p); + if (ret) + error(1, ret, "pthread_attr_setschedparam()"); +} + +static void *gpiopwm_init_thread(void *cookie) +{ + int ret; + + pthread_setname_np(pthread_self(), "gpio-pwm-handler"); + ret = ioctl(dev, GPIOPWM_RTIOC_SET_CONFIG, config); + if (ret) + error(1, ret, "failed to set config"); + + ioctl(dev, GPIOPWM_RTIOC_START); + + /* setup compl
[Xenomai-git] Jorge Ramirez-Ortiz : gpiopwm: pwm signal generator and servo motor control demo code
Module: xenomai-3 Branch: next Commit: 0aa540d26c292d2b0da41c377437ed178d71c003 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=0aa540d26c292d2b0da41c377437ed178d71c003 Author: Jorge Ramirez-Ortiz Date: Tue Mar 15 19:18:15 2016 -0400 gpiopwm: pwm signal generator and servo motor control demo code --- demo/posix/cobalt/Makefile.am|6 + demo/posix/cobalt/gpiopwm.c | 448 ++ include/cobalt/kernel/rtdm/gpiopwm.h | 24 ++ include/rtdm/uapi/gpiopwm.h | 56 + include/rtdm/uapi/rtdm.h |1 + kernel/drivers/Kconfig |1 + kernel/drivers/Makefile |3 +- kernel/drivers/gpiopwm/Kconfig |9 + kernel/drivers/gpiopwm/Makefile |5 + kernel/drivers/gpiopwm/gpiopwm.c | 301 +++ 10 files changed, 853 insertions(+), 1 deletion(-) diff --git a/demo/posix/cobalt/Makefile.am b/demo/posix/cobalt/Makefile.am index eedc346..9e35cf1 100644 --- a/demo/posix/cobalt/Makefile.am +++ b/demo/posix/cobalt/Makefile.am @@ -3,6 +3,7 @@ demodir = @XENO_DEMO_DIR@ CCLD = $(top_srcdir)/scripts/wrap-link.sh $(CC) demo_PROGRAMS =\ + gpiopwm \ bufp-label \ bufp-readwrite \ can_rtt \ @@ -24,6 +25,11 @@ ldadd = \ @XENO_USER_LDADD@ \ -lpthread -lrt +gpiopwm_SOURCES = gpiopwm.c +gpiopwm_CPPFLAGS = $(cppflags) -I$(top_srcdir)/include/rtdm/uapi +gpiopwm_LDFLAGS = $(ldflags) +gpiopwm_LDADD = $(ldadd) + bufp_label_SOURCES = bufp-label.c bufp_label_CPPFLAGS = $(cppflags) bufp_label_LDFLAGS = $(ldflags) diff --git a/demo/posix/cobalt/gpiopwm.c b/demo/posix/cobalt/gpiopwm.c new file mode 100644 index 000..e093fbe --- /dev/null +++ b/demo/posix/cobalt/gpiopwm.c @@ -0,0 +1,448 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MIN_DUTY_CYCLE 0 +#define MAX_DUTY_CYCLE 100 + +typedef void *(*gpiopwm_control_thread)(void *cookie); +#define DEVICE_NAME "/dev/rtdm/gpiopwm" +char *device_name; +int dev; + +static sem_t synch; +static sem_t setup; +static int stop; +static int step = 1; +static int port = 6; + +#define GPIO_PWM_SERVO_CONFIG \ +{ \ + .duty_cycle = 50, \ + .range_min = 950,\ + .range_max = 2050, \ + .period = 2000, \ + .gpio = 1, \ +} + +static struct gpiopwm config = GPIO_PWM_SERVO_CONFIG; + +static void fail(const char *reason) +{ + perror(reason); + exit(EXIT_FAILURE); +} + +static void sem_sync(sem_t *sem) +{ + int ret; + + for (;;) { + ret = sem_wait(sem); + if (ret == 0) + return; + if (errno != EINTR) + fail("sem_wait"); + } +} + +static inline void clear_screen(void) +{ + const char* cmd = "\e[1;1H\e[2J"; + int ret; + + ret = write(2, cmd, strlen(cmd)); + if (!ret) + error(1, ret, "clear screen error"); +} + +static inline void print_config(char *str) +{ + printf("Config: %s\n", str); + printf(" device : %s\n", device_name); + printf(" range : [%d, %d]\n", config.range_min, config.range_max); + printf(" period : %d nsec\n", config.period); + printf(" gpio pin : %d\n", config.gpio); + printf(" duty cycle : %d\n", config.duty_cycle); +} + +static inline void input_message(void) +{ + print_config(""); + printf("\n GPIO PWM Control\n"); + printf( " Enter duty_cycle [0-100] : "); +} + +static void setup_sched_parameters(pthread_attr_t *attr, int prio) +{ + struct sched_param p; + int ret; + + ret = pthread_attr_init(attr); + if (ret) + error(1, ret, "pthread_attr_init()"); + + ret = pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED); + if (ret) + error(1, ret, "pthread_attr_setinheritsched()"); + + ret = pthread_attr_setschedpolicy(attr, prio ? SCHED_FIFO : SCHED_OTHER); + if (ret) + error(1, ret, "pthread_attr_setschedpolicy()"); + + p.sched_priority = prio; + ret = pthread_attr_setschedparam(attr, &p); + if (ret) + error(1, ret, "pthread_attr_setschedparam()"); +} + +static void *gpiopwm_init_thread(void *cookie) +{ + int ret; + + pthread_setname_np(pthread_self(), "gpio-pwm-handler"); + ret = ioctl(dev, GPIOPWM_RTIOC_SET_CONFIG, config); + if (ret) + error(1, ret, "failed to set config"); + + ioctl(dev, GPIOPWM_RTIOC_START); + + /* setup compl
[Xenomai-git] Jorge Ramirez-Ortiz : gpiopwm: pwm signal generator and servo motor control demo code
Module: xenomai-3 Branch: next Commit: a84d034b62808710ba9b9532000254722e4aa19c URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=a84d034b62808710ba9b9532000254722e4aa19c Author: Jorge Ramirez-Ortiz Date: Tue Mar 15 19:18:15 2016 -0400 gpiopwm: pwm signal generator and servo motor control demo code --- demo/posix/cobalt/Makefile.am|6 + demo/posix/cobalt/gpiopwm.c | 448 ++ include/cobalt/kernel/rtdm/gpiopwm.h | 24 ++ include/rtdm/uapi/gpiopwm.h | 56 + include/rtdm/uapi/rtdm.h |1 + kernel/drivers/Kconfig |1 + kernel/drivers/Makefile |3 +- kernel/drivers/gpiopwm/Kconfig |9 + kernel/drivers/gpiopwm/Makefile |5 + kernel/drivers/gpiopwm/gpiopwm.c | 301 +++ 10 files changed, 853 insertions(+), 1 deletion(-) diff --git a/demo/posix/cobalt/Makefile.am b/demo/posix/cobalt/Makefile.am index eedc346..9e35cf1 100644 --- a/demo/posix/cobalt/Makefile.am +++ b/demo/posix/cobalt/Makefile.am @@ -3,6 +3,7 @@ demodir = @XENO_DEMO_DIR@ CCLD = $(top_srcdir)/scripts/wrap-link.sh $(CC) demo_PROGRAMS =\ + gpiopwm \ bufp-label \ bufp-readwrite \ can_rtt \ @@ -24,6 +25,11 @@ ldadd = \ @XENO_USER_LDADD@ \ -lpthread -lrt +gpiopwm_SOURCES = gpiopwm.c +gpiopwm_CPPFLAGS = $(cppflags) -I$(top_srcdir)/include/rtdm/uapi +gpiopwm_LDFLAGS = $(ldflags) +gpiopwm_LDADD = $(ldadd) + bufp_label_SOURCES = bufp-label.c bufp_label_CPPFLAGS = $(cppflags) bufp_label_LDFLAGS = $(ldflags) diff --git a/demo/posix/cobalt/gpiopwm.c b/demo/posix/cobalt/gpiopwm.c new file mode 100644 index 000..e093fbe --- /dev/null +++ b/demo/posix/cobalt/gpiopwm.c @@ -0,0 +1,448 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MIN_DUTY_CYCLE 0 +#define MAX_DUTY_CYCLE 100 + +typedef void *(*gpiopwm_control_thread)(void *cookie); +#define DEVICE_NAME "/dev/rtdm/gpiopwm" +char *device_name; +int dev; + +static sem_t synch; +static sem_t setup; +static int stop; +static int step = 1; +static int port = 6; + +#define GPIO_PWM_SERVO_CONFIG \ +{ \ + .duty_cycle = 50, \ + .range_min = 950,\ + .range_max = 2050, \ + .period = 2000, \ + .gpio = 1, \ +} + +static struct gpiopwm config = GPIO_PWM_SERVO_CONFIG; + +static void fail(const char *reason) +{ + perror(reason); + exit(EXIT_FAILURE); +} + +static void sem_sync(sem_t *sem) +{ + int ret; + + for (;;) { + ret = sem_wait(sem); + if (ret == 0) + return; + if (errno != EINTR) + fail("sem_wait"); + } +} + +static inline void clear_screen(void) +{ + const char* cmd = "\e[1;1H\e[2J"; + int ret; + + ret = write(2, cmd, strlen(cmd)); + if (!ret) + error(1, ret, "clear screen error"); +} + +static inline void print_config(char *str) +{ + printf("Config: %s\n", str); + printf(" device : %s\n", device_name); + printf(" range : [%d, %d]\n", config.range_min, config.range_max); + printf(" period : %d nsec\n", config.period); + printf(" gpio pin : %d\n", config.gpio); + printf(" duty cycle : %d\n", config.duty_cycle); +} + +static inline void input_message(void) +{ + print_config(""); + printf("\n GPIO PWM Control\n"); + printf( " Enter duty_cycle [0-100] : "); +} + +static void setup_sched_parameters(pthread_attr_t *attr, int prio) +{ + struct sched_param p; + int ret; + + ret = pthread_attr_init(attr); + if (ret) + error(1, ret, "pthread_attr_init()"); + + ret = pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED); + if (ret) + error(1, ret, "pthread_attr_setinheritsched()"); + + ret = pthread_attr_setschedpolicy(attr, prio ? SCHED_FIFO : SCHED_OTHER); + if (ret) + error(1, ret, "pthread_attr_setschedpolicy()"); + + p.sched_priority = prio; + ret = pthread_attr_setschedparam(attr, &p); + if (ret) + error(1, ret, "pthread_attr_setschedparam()"); +} + +static void *gpiopwm_init_thread(void *cookie) +{ + int ret; + + pthread_setname_np(pthread_self(), "gpio-pwm-handler"); + ret = ioctl(dev, GPIOPWM_RTIOC_SET_CONFIG, config); + if (ret) + error(1, ret, "failed to set config"); + + ioctl(dev, GPIOPWM_RTIOC_START); + + /* setup compl