diff --git a/apix-adc-example/Makefile b/apix-adc-example/Makefile new file mode 100644 index 0000000..4176fbe --- /dev/null +++ b/apix-adc-example/Makefile @@ -0,0 +1,37 @@ +# +# Copyright 2017, Digi International Inc. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. +# + +BINARY := apix-adc-example + +CFLAGS += -Wall -O2 + +CFLAGS += $(shell pkg-config --cflags libdigiapix) +LDLIBS += $(shell pkg-config --libs libdigiapix) + +$(BINARY): main.o + $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@ -lm + +.PHONY: install +install: $(BINARY) + install -d $(DESTDIR)/usr/bin + install -m 0755 $^ $(DESTDIR)/usr/bin/ + +.PHONY: all +all: $(BINARY) + +.PHONY: clean +clean: + -rm -f *.o $(BINARY) diff --git a/apix-adc-example/README.md b/apix-adc-example/README.md new file mode 100644 index 0000000..6dbda34 --- /dev/null +++ b/apix-adc-example/README.md @@ -0,0 +1,93 @@ +Digi APIX ADC Sample Application +=================================== + +Sample application to access and manage ADC channels using the Digi APIX library. + +The application enables one ADC channel on the board. After that, the application +takes periodic samples and calculates the rms and mean value of the samples batch. + +The ADC lines used in the sample are mapped as follows in the Digi Boards: + - **CCIMX6 SBC**: PMIC_ADCIN1 (GPIO Connector Pin 1). + - **CCIMX6UL SBC Express**: ADC1_IN4 (Expansion Connector Pin 7). + - **CCIMX6UL SBC Pro**: ADC1_IN2 (GPIO Connector Pin 13). + +The following device tree modifications are required for the sample to work: + - **CCIMX6 SBC**: _No device tree modifications are required._ + - **CCIMX6UL SBC Express**: +``` +&adc1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_adc1>; + adc-ch-list = <4>; + status = "okay"; +}; + +&iomuxc { + imx6ul-ccimx6ul { + pinctrl_adc1: adc1grp { + fsl,pins = < + MX6UL_PAD_GPIO1_IO04__GPIO1_IO04 0xb0 + >; + }; + }; +}; +``` + - **CCIMX6UL SBC Pro**: +``` +&adc1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_adc1>; + adc-ch-list = <2>; + status = "okay"; +}; + +&iomuxc { + imx6ul-ccimx6ul { + pinctrl_adc1: adc1grp { + fsl,pins = < + MX6UL_PAD_GPIO1_IO02__GPIO1_IO02 0xb0 + >; + }; + }; +}; +``` + +Running the application +----------------------- +Once the binary is in the target, launch the application: +``` +#> apix-adc-example [adc_chip adc_channel interval number_of_samples] +``` +Where: + - 'adc_chip' the ADC chip number. + - 'adc_channel' the ADC channel number. + - 'interval' is the time interval between samples. + - 'number_of_samples' is the number of samples to take. + +Compiling the application +------------------------- +This demo can be compiled using a Digi Embedded Yocto based toolchain. Make +sure to source the corresponding toolchain of the platform you are using, e.g: + +``` +$> . /environment-setup-cortexa7hf-vfp-neon-dey-linux-gnueabi +$> make +``` + +More information about [Digi Embedded Yocto](https://github.com/digi-embedded/meta-digi). + +License +------- +Copyright 2017, Digi International Inc. + +Permission to use, copy, modify, and/or distribute this software for any purpose +with or without fee is hereby granted, provided that the above copyright notice +and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS +OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. \ No newline at end of file diff --git a/apix-adc-example/main.c b/apix-adc-example/main.c new file mode 100644 index 0000000..23f7591 --- /dev/null +++ b/apix-adc-example/main.c @@ -0,0 +1,229 @@ +/* + * Copyright 2017, Digi International Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libdigiapix/adc.h" + +#define ARG_ADC_CHIP 0 +#define ARG_ADC_CHANNEL 1 + +static adc_t *adc; + +struct adc_sampling_cb_data { + adc_t *adc; + int total_value; + int total_value_rms; + int number_of_samples; +}; + +/* + * usage_and_exit() - Show usage information and exit with 'exitval' return + * value + * + * @name: Application name. + * @exitval: The exit code. + */ +static void usage_and_exit(char *name, int exitval) +{ + fprintf(stdout, + "Example application using libdigiapix ADC support\n" + "\n" + "Usage: %s \n\n" + " ADC chip number\n" + " ADC channel number\n" + " Time interval for sampling\n" + " Number of samples to get\n" + "\n\n" + "\n", name); + + exit(exitval); +} + +/* + * cleanup() - Frees all the allocated memory before exiting + */ +static void cleanup(void) +{ + /* Free adc */ + ldx_adc_stop_sampling(adc); + ldx_adc_free(adc); +} + +/* + * sigaction_handler() - Handler to execute after receiving a signal + * + * @signum: Received signal. + */ +static void sigaction_handler(int signum) +{ + /* 'atexit' executes the cleanup function */ + exit(EXIT_FAILURE); +} + +/* + * register_signals() - Registers program signals + */ +static void register_signals(void) +{ + struct sigaction action; + + action.sa_handler = sigaction_handler; + action.sa_flags = 0; + sigemptyset(&action.sa_mask); + + sigaction(SIGHUP, &action, NULL); + sigaction(SIGINT, &action, NULL); + sigaction(SIGTERM, &action, NULL); +} + +/* + * parse_argument() - Parses the given string argument and returns the + * corresponding integer value + * + * @argv: Argument to parse in string format. + * @arg_type: Type of the argument to parse. + * + * Return: The parsed integer argument, -1 on error. + */ +static int parse_argument(char *argv, int arg_type) +{ + char *endptr; + long value; + + errno = 0; + value = strtol(argv, &endptr, 10); + + if ((errno == ERANGE && (value == LONG_MAX || value == LONG_MIN)) + || (errno != 0 && value == 0)) + return -1; + + if (endptr == argv) { + switch (arg_type) { + case ARG_ADC_CHIP: + return ldx_adc_get_chip(endptr); + case ARG_ADC_CHANNEL: + return ldx_adc_get_channel(endptr); + default: + return -1; + } + } + + return value; +} + +/* + * adc_sampling_cb() - ADC callback for sampling + * + * @arg: ADC sampling data (struct adc_sampling_cb_data). + * @sample: The ADC read sample. + */ +static int adc_sampling_cb(int sample, void *arg) +{ + struct adc_sampling_cb_data *data = arg; + float sample_mv = 0; + + data->total_value += sample; + data->total_value_rms += powf(sample, 2); + data->number_of_samples--; + sample_mv = ldx_adc_convert_sample_to_mv(data->adc, sample); + + printf("ADC sample acquired: %d (raw) - %2.f (mV)\n", sample, sample_mv); + + return EXIT_SUCCESS; +} + +int main(int argc, char *argv[]) +{ + unsigned int channel, chip, interval; + int number_of_samples; + char *name = basename(argv[0]); + struct adc_sampling_cb_data cb_data; + + /* Check input parameters */ + if (argc != 5) { + usage_and_exit(name, EXIT_FAILURE); + return EXIT_FAILURE; + } + + /* Parse command line arguments */ + chip = parse_argument(argv[1], ARG_ADC_CHIP); + channel = parse_argument(argv[2], ARG_ADC_CHANNEL); + interval = atoi(argv[3]); + number_of_samples = atoi(argv[4]); + + if (chip < 0) { + printf("Invalid chip number\n"); + return EXIT_FAILURE; + } + + if (channel < 0) { + printf("Invalid channel number\n"); + return EXIT_FAILURE; + } + + if (interval <= 0) { + printf("Time interval must be greater than 0\n"); + return EXIT_FAILURE; + } + + if (number_of_samples <= 0) { + printf("Number of samples must be greater than 0\n"); + return EXIT_FAILURE; + } + + cb_data.number_of_samples = number_of_samples; + cb_data.total_value = 0; + cb_data.total_value_rms = 0; + + /* Register signals and exit cleanup function */ + atexit(cleanup); + register_signals(); + + adc = ldx_adc_request(chip,channel); + + if (!adc) { + printf("Failed to initialize ADC\n"); + return EXIT_FAILURE; + } + + cb_data.adc = adc; + + if (ldx_adc_start_sampling(adc, &adc_sampling_cb, interval, &cb_data)) { + printf("Failed to initialize the sampling data\n"); + return EXIT_FAILURE; + } + + while (cb_data.number_of_samples > 0) { + printf("Waiting for samples, %d samples remaining\n", + cb_data.number_of_samples); + sleep(1); + } + + printf("The mean value of the samples is: %d mV\n", + cb_data.total_value/number_of_samples); + printf("The RMS value of the samples is: %.2f mV\n", + sqrt(cb_data.total_value_rms/number_of_samples)); + + return EXIT_SUCCESS; +} diff --git a/libdigiapix-examples.mk b/libdigiapix-examples.mk index effd7ca..67aa9bf 100644 --- a/libdigiapix-examples.mk +++ b/libdigiapix-examples.mk @@ -14,7 +14,7 @@ # PERFORMANCE OF THIS SOFTWARE. # -SUBDIRS := apix-gpio-example apix-i2c-example apix-pwm-example apix-spi-example +SUBDIRS := apix-gpio-example apix-i2c-example apix-pwm-example apix-spi-example apix-adc-example all: $(SUBDIRS) diff --git a/samples-manifest.xml b/samples-manifest.xml index f468535..3f9a984 100644 --- a/samples-manifest.xml +++ b/samples-manifest.xml @@ -64,4 +64,18 @@ the number of address bytes. ccimx6ulsbc + + Digi APIX ADC Sample + +Sample application to access and manage ADC channels using the Digi APIX library. +The application enables one ADC channel on the board. After that, the application takes periodic samples and calculates the rms and mean value of the samples batch. + + apix-adc-example + + ccimx6sbc + ccimx6qpsbc + ccimx6ulstarter + ccimx6ulsbc + +