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