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:
parent
2302b7c2e2
commit
372d338d3f
|
|
@ -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)
|
||||||
|
|
@ -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.
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue