pwm_apix_sample: add an example for the pwm digi apix

https://jira.digi.com/browse/DEL-4881

Signed-off-by: Francisco Gil Martinez <francisco.gilmartinez@digi.com>
This commit is contained in:
Francisco Gil Martinez 2017-09-01 11:57:06 +02:00
parent 2302b7c2e2
commit 372d338d3f
3 changed files with 345 additions and 0 deletions

43
apix-pwm-example/Makefile Normal file
View File

@ -0,0 +1,43 @@
#
# Copyright (c) 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.
#
#
EXECUTABLE = pwm-digiapix-sample
SRC = .
CFLAGS += -Wall
CFLAGS += $(shell pkg-config --cflags libdigiapix)
LDLIBS += $(shell pkg-config --libs libdigiapix)
SRCS = $(wildcard $(SRC)/*.c)
OBJS = $(SRCS:.c=.o)
.PHONY: all
all: $(EXECUTABLE)
$(EXECUTABLE): $(OBJS)
$(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
.PHONY: install
install: $(EXECUTABLE)
install -d $(DESTDIR)/usr/bin
install -m 0755 $(EXECUTABLE) $(DESTDIR)/usr/bin/
.PHONY: clean
clean:
-rm -f $(EXECUTABLE) $(OBJS)

105
apix-pwm-example/README.md Normal file
View File

@ -0,0 +1,105 @@
Digi APIX PWM Sample Application
===================================
Sample application to access and manage PWM lines using the Digi APIX library.
The application enables one PWM line of the board using a frequency of
1000Hz. Then, progressively modifies the duty cycle in a loop from 10% to
90% and vice-versa.
The PWM lines used in the sample are mapped as follows in the Digi Boards:
- **CCIMX6 SBC**: PWM1 - Pin **10** of the parallel video (LCD) connector.
- **CCIMX6UL SBC Express**: PWM1 - Pin **27** of the expansion connector.
- **CCIMX6UL SBC Pro**: PWM4 - Pin **11** of the GPIO connector.
The following device tree modifications are required for the sample to work:
- **CCIMX6 SBC**:
```
/* PWM1 */
&pwm1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm1>;
status = "okay";
};
/* Pin mux configuration */
&iomuxc {
imx6q-ccimx6sbc {
pinctrl_pwm1: pwm1grp {
fsl,pins = <
MX6QDL_PAD_DISP0_DAT8__PWM1_OUT 0x110b0
>;
};
};
};
```
- **CCIMX6UL SBC Express**:
_No device tree modifications are required._
- **CCIMX6UL SBC Pro**:
```
/* PWM4 */
&pwm4 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm4>;
clocks = <&clks IMX6UL_CLK_PWM4>,
<&clks IMX6UL_CLK_PWM4>;
status = "okay";
};
/* Pin mux configuration */
&iomuxc {
imx6ul-ccimx6ul {
pinctrl_pwm4: pwm4grp {
fsl,pins = <
MX6UL_PAD_GPIO1_IO05__PWM4_OUT 0x110b0
>;
};
};
};
```
Running the application
-----------------------
Once the binary is in the target, launch the application:
```
#> pwm-digiapix-sample
```
The sample applicaion is ready to work with all Digi platforms using the corresponding
PWM chip (0 by default) and a frequency of 1000Hz. If a different PWM chip or frequency
is required, the application allows 2 additional parameters in order to customize
these values:
```
#> pwm-digiapix-sample [pwm-chip pwm-freq]
```
Where:
- 'pwm-chip' is an optional PWM chip number.
- 'pwm-freq' is an optional frequency to use (Hz).
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:
```
$> . <DEY-toolchain-path>/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.

197
apix-pwm-example/main.c Normal file
View File

@ -0,0 +1,197 @@
/*
* Copyright (c) 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 <libgen.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pwm.h>
/*------------------------------------------------------------------------------
D E F I N I T I O N S
------------------------------------------------------------------------------*/
#define DEFAULT_PWM_CHANNEL 0
#define DEFAULT_FREQUENCY 1000 /* In Hz */
#define DEFAULT_PWM_ALIAS "DEFAULT_PWM"
#define BUFF_SIZE 256
#define USAGE \
"Usage:\n" \
"%s [pwm-chip pwm-freq]\n\n" \
"Where:\n" \
" 'pwm-chip' is an optional PWM chip number\n" \
" 'pwm-freq' is an optional frequency to use (Hz)\n\n" \
/*------------------------------------------------------------------------------
F U N C T I O N D E C L A R A T I O N S
------------------------------------------------------------------------------*/
static void cleanup();
static void add_sigkill_signal(void);
static void graceful_shutdown(void);
static void sigint_handler(int signum);
static void usage(char const * const name);
/**
* sigint_handler() - Manage signal received.
*
* @signum: Received signal.
*/
static void sigint_handler(int signum)
{
exit(EXIT_SUCCESS);
}
/**
* usage() - Print usage information
*
* @name: Name of the application.
*/
static void usage(char const * const name)
{
printf(USAGE, name);
}
/*------------------------------------------------------------------------------
G L O B A L V A R I A B L E S
------------------------------------------------------------------------------*/
static pwm_t *pwm_line;
static int running = 1;
int main(int argc, char **argv)
{
unsigned int pwm_freq = DEFAULT_FREQUENCY;
int ret, duty_cycle = 10, ascending = 1;
char *name = basename(argv[0]);
/* Check if the PWM values are passed in the command line. */
if (argc == 3) {
unsigned int pwm_chip = atoi(argv[1]);
pwm_freq = atoi(argv[2]);
pwm_line = pwm_request(pwm_chip, DEFAULT_PWM_CHANNEL, REQUEST_SHARED);
} else if (argc == 1) {
/* Initialize the PWM. */
pwm_line = pwm_request_by_alias(DEFAULT_PWM_ALIAS, REQUEST_SHARED);
} else if (argc <= 2 || argc > 3) {
usage(name);
return EXIT_FAILURE;
}
/* Check PWM. */
if (!pwm_line) {
printf("Failed to initialize PWM\n");
return EXIT_FAILURE;
}
add_sigkill_signal();
printf("Setting PWM frequency to %dHz...", pwm_freq);
/* Set a duty cycle of 0 to avoid errors configuring the frequency */
pwm_set_duty_cycle(pwm_line, 0);
ret = pwm_set_freq(pwm_line, pwm_freq);
if (ret != PWM_CONFIG_ERROR_NONE) {
printf("Failed\n");
return EXIT_FAILURE;
}
/* Check the frequency. */
ret = pwm_get_freq(pwm_line);
printf("%s\n", ret >= 0 ? "Done" : "Failed");
if (ret == -1) {
return EXIT_FAILURE;
}
printf("Enabling PWM %d:%d...", pwm_line->chip, pwm_line->channel);
ret = pwm_enable(pwm_line, PWM_ENABLED);
if (ret != EXIT_SUCCESS) {
printf("Failed\n");
return EXIT_FAILURE;
}
ret = pwm_is_enabled(pwm_line);
printf("%s\n", ret == PWM_ENABLED ? "Done" : "Failed");
if (ret != PWM_ENABLED) {
return EXIT_FAILURE;
}
/* Main application loop.*/
while (running) {
/* Set the duty cycle. */
ret = pwm_set_duty_cycle_percentage(pwm_line, duty_cycle);
if (ret != PWM_CONFIG_ERROR_NONE) {
printf("Failed to set the duty cycle\n");
return EXIT_FAILURE;
}
if (ascending) {
duty_cycle += 10;
if (duty_cycle == 100) {
duty_cycle = 80;
ascending = 0;
}
} else {
duty_cycle -= 10;
if (duty_cycle == 0) {
duty_cycle = 20;
ascending = 1;
}
}
sleep(1);
}
return EXIT_SUCCESS;
}
/**
* cleanup() - Frees and leaves PWM into a known state before exit
*/
static void cleanup()
{
if (pwm_line) {
pwm_enable(pwm_line, PWM_DISABLED);
pwm_free(pwm_line);
}
}
/**
* add_sigkill_signal() - Add the kill signal to the process
*/
static void add_sigkill_signal(void)
{
struct sigaction new_action;
struct sigaction old_action;
/* Setup signal hander. */
atexit(graceful_shutdown);
new_action.sa_handler = sigint_handler;
sigemptyset(&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction(SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction(SIGINT, &new_action, NULL);
}
/**
* graceful_shutdown() - Stop main loop
*/
void graceful_shutdown(void)
{
running = 0;
cleanup();
}