From e7961a696e1fdcc6baf50d416a266dcece745240 Mon Sep 17 00:00:00 2001 From: zouboan Date: Tue, 28 Jun 2022 20:05:27 +0800 Subject: [PATCH] examples: add pwm input capture example Co-authored-by: Alan Carvalho de Assis --- examples/capture/Kconfig | 36 +++++ examples/capture/Make.defs | 23 +++ examples/capture/Makefile | 34 ++++ examples/capture/cap.h | 51 ++++++ examples/capture/cap_main.c | 305 ++++++++++++++++++++++++++++++++++++ 5 files changed, 449 insertions(+) create mode 100644 examples/capture/Kconfig create mode 100644 examples/capture/Make.defs create mode 100644 examples/capture/Makefile create mode 100644 examples/capture/cap.h create mode 100644 examples/capture/cap_main.c diff --git a/examples/capture/Kconfig b/examples/capture/Kconfig new file mode 100644 index 000000000..b5b5ba068 --- /dev/null +++ b/examples/capture/Kconfig @@ -0,0 +1,36 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config EXAMPLES_CAPTURE + tristate "PWM Capture example" + default n + depends on CAPTURE + ---help--- + Enable the pwm capture example + +if EXAMPLES_CAPTURE + +config EXAMPLES_CAPTURE_DEVPATH + string "Capture device path" + default "/dev/capture0" + ---help--- + The default path to the capture device + +config EXAMPLES_CAPTURE_NSAMPLES + int "Number of samples" + default 0 + ---help--- + This number of samples is collected and the program + terminates. If the value is 0, samples are collected indefinitely. + +config EXAMPLES_CAPTURE_DELAY + int "Delay between samples" + default 100 + ---help--- + This value provides the delay (in milliseconds) between each sample. + If CONFIG_NSH_BUILTIN_APPS is defined, then this value is the default + delay if no other delay is provided on the command line. + +endif diff --git a/examples/capture/Make.defs b/examples/capture/Make.defs new file mode 100644 index 000000000..de9fcd063 --- /dev/null +++ b/examples/capture/Make.defs @@ -0,0 +1,23 @@ +############################################################################ +# apps/examples/capture/Make.defs +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +ifneq ($(CONFIG_EXAMPLES_CAPTURE),) +CONFIGURED_APPS += $(APPDIR)/examples/capture +endif diff --git a/examples/capture/Makefile b/examples/capture/Makefile new file mode 100644 index 000000000..db92c71f0 --- /dev/null +++ b/examples/capture/Makefile @@ -0,0 +1,34 @@ +############################################################################ +# apps/examples/capture/Makefile +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(APPDIR)/Make.defs + +# PWM Input Capture Example. + +MAINSRC = cap_main.c + +# PWM input capture built-in application info + +PROGNAME = cap +PRIORITY = SCHED_PRIORITY_DEFAULT +STACKSIZE = $(CONFIG_DEFAULT_TASK_STACKSIZE) +MODULE = $(CONFIG_EXAMPLES_CAPTURE) + +include $(APPDIR)/Application.mk diff --git a/examples/capture/cap.h b/examples/capture/cap.h new file mode 100644 index 000000000..1e218ec44 --- /dev/null +++ b/examples/capture/cap.h @@ -0,0 +1,51 @@ +/**************************************************************************** + * apps/examples/capture/cap.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_EXAMPLES_CAPTURE_QE_H +#define __APPS_EXAMPLES_CAPTURE_QE_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct cap_example_s +{ + FAR char *devpath; /* Path to the capture device */ + unsigned int nloops; /* Collect this number of samples */ + unsigned int delay; /* Delay this number of seconds between samples */ +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +extern struct cap_example_s g_capexample; + +#endif /* __APPS_EXAMPLES_CAPTURE_QE_H */ diff --git a/examples/capture/cap_main.c b/examples/capture/cap_main.c new file mode 100644 index 000000000..11fac3721 --- /dev/null +++ b/examples/capture/cap_main.c @@ -0,0 +1,305 @@ +/**************************************************************************** + * apps/examples/capture/cap_main.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "cap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +struct cap_example_s g_capexample; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: cap_devpath + ****************************************************************************/ + +static void cap_devpath(FAR const char *devpath) +{ + /* Get rid of any old device path */ + + if (g_capexample.devpath) + { + free(g_capexample.devpath); + } + + /* The set-up the new device path by copying the string */ + + g_capexample.devpath = strdup(devpath); +} + +/**************************************************************************** + * Name: cap_help + ****************************************************************************/ + +static void cap_help(void) +{ + printf("\nUsage: cap [OPTIONS]\n\n"); + printf("OPTIONS include:\n"); + printf(" [-p devpath] Capture device path\n"); + printf(" [-n samples] Number of samples\n"); + printf(" [-t msec] Delay between samples (msec)\n"); + printf(" [-h] Shows this message and exits\n\n"); +} + +/**************************************************************************** + * Name: arg_string + ****************************************************************************/ + +static int arg_string(FAR char **arg, FAR char **value) +{ + FAR char *ptr = *arg; + + if (ptr[2] == '\0') + { + *value = arg[1]; + return 2; + } + else + { + *value = &ptr[2]; + return 1; + } +} + +/**************************************************************************** + * Name: arg_decimal + ****************************************************************************/ + +static int arg_decimal(FAR char **arg, FAR long *value) +{ + FAR char *string; + int ret; + + ret = arg_string(arg, &string); + *value = strtol(string, NULL, 10); + return ret; +} + +/**************************************************************************** + * Name: parse_args + ****************************************************************************/ + +static void parse_args(int argc, FAR char **argv) +{ + FAR char *ptr; + FAR char *str; + long value; + int index; + int nargs; + + g_capexample.nloops = CONFIG_EXAMPLES_CAPTURE_NSAMPLES; + g_capexample.delay = CONFIG_EXAMPLES_CAPTURE_DELAY; + + for (index = 1; index < argc; ) + { + ptr = argv[index]; + if (ptr[0] != '-') + { + printf("Invalid options format: %s\n", ptr); + exit(0); + } + + switch (ptr[1]) + { + case 'n': + nargs = arg_decimal(&argv[index], &value); + if (value < 0 || value > INT_MAX) + { + printf("Sample count out of range: %ld\n", value); + exit(1); + } + + g_capexample.nloops = (unsigned int)value; + index += nargs; + break; + + case 'p': + nargs = arg_string(&argv[index], &str); + cap_devpath(str); + index += nargs; + break; + + case 't': + nargs = arg_decimal(&argv[index], &value); + if (value < 0 || value > INT_MAX) + { + printf("Sample delay out of range: %ld\n", value); + exit(1); + } + + g_capexample.delay = (unsigned int)value; + index += nargs; + break; + + case 'h': + cap_help(); + exit(EXIT_SUCCESS); + + default: + printf("Unsupported option: %s\n", ptr); + cap_help(); + exit(EXIT_FAILURE); + } + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: cap_main + ****************************************************************************/ + +int main(int argc, FAR char *argv[]) +{ + int8_t dutycycle; + int32_t frequence; + int fd; + int exitval = EXIT_SUCCESS; + int ret; + int nloops; + + /* Set the default values */ + + cap_devpath(CONFIG_EXAMPLES_CAPTURE_DEVPATH); + + /* Parse command line arguments */ + + parse_args(argc, argv); + + /* Open the capture device for reading */ + + printf("cap_main: Hardware initialized. Opening the capture device: %s\n", + g_capexample.devpath); + + fd = open(g_capexample.devpath, O_RDONLY); + if (fd < 0) + { + printf("cap_main: open %s failed: %d\n", g_capexample.devpath, errno); + exitval = EXIT_FAILURE; + goto errout; + } + + /* Now loop the appropriate number of times, displaying the collected + * encoder samples. + */ + + printf("cap_main: Number of samples: %u\n", g_capexample.nloops); + for (nloops = 0; + !g_capexample.nloops || nloops < g_capexample.nloops; + nloops++) + { + /* Flush any output before the loop entered or from the previous pass + * through the loop. + */ + + fflush(stdout); + + /* Get the dutycycle data using the ioctl */ + + ret = ioctl(fd, CAPIOC_DUTYCYCLE, + (unsigned long)((uintptr_t)&dutycycle)); + if (ret < 0) + { + printf("cap_main: ioctl(CAPIOC_DUTYCYCLE) failed: %d\n", errno); + exitval = EXIT_FAILURE; + goto errout_with_dev; + } + + /* Print the sample data on successful return */ + + else + { + printf("pwm duty cycle: %d % \n", dutycycle); + } + + /* Get the frequence data using the ioctl */ + + ret = ioctl(fd, CAPIOC_FREQUENCE, + (unsigned long)((uintptr_t)&frequence)); + if (ret < 0) + { + printf("cap_main: ioctl(CAPIOC_FREQUENCE) failed: %d\n", errno); + exitval = EXIT_FAILURE; + goto errout_with_dev; + } + + /* Print the sample data on successful return */ + + else + { + printf("pwm frequence: %d Hz \n", frequence); + } + + /* Delay a little bit */ + + usleep(g_capexample.delay * 1000); + } + +errout_with_dev: + close(fd); + +errout: + printf("Terminating!\n"); + fflush(stdout); + return exitval; +}