examples refactor the examples

Signed-off-by: Francisco Gil Martinez <francisco.gilmartinez@digi.com>
This commit is contained in:
Francisco Gil Martinez 2017-10-03 16:45:44 +02:00
parent 5bc334c320
commit d574d6b748
10 changed files with 327 additions and 263 deletions

View File

@ -29,6 +29,9 @@ install: $(BINARY)
install -d $(DESTDIR)/usr/bin install -d $(DESTDIR)/usr/bin
install -m 0755 $^ $(DESTDIR)/usr/bin/ install -m 0755 $^ $(DESTDIR)/usr/bin/
.PHONY: all
all: $(BINARY)
.PHONY: clean .PHONY: clean
clean: clean:
-rm -f *.o $(BINARY) -rm -f *.o $(BINARY)

View File

@ -36,8 +36,11 @@ struct gpio_interrupt_cb_data {
}; };
/* /*
* Function: usage_and_exit * usage_and_exit() - Show usage information and exit with 'exitval' return
* Description: show usage information and exit with 'exitval' return value * value
*
* @name: Application name.
* @exitval: The exit code.
*/ */
static void usage_and_exit(char *name, int exitval) static void usage_and_exit(char *name, int exitval)
{ {
@ -54,22 +57,33 @@ static void usage_and_exit(char *name, int exitval)
exit(exitval); exit(exitval);
} }
/*
* cleanup() - Frees all the allocated memory before exiting
*/
static void cleanup(void) static void cleanup(void)
{ {
/* Stop the interrupt handler thread */ /* Stop the interrupt handler thread */
gpio_stop_wait_interrupt(gpio_input); ldx_gpio_stop_wait_interrupt(gpio_input);
/* Free gpios */ /* Free gpios */
gpio_free(gpio_input); ldx_gpio_free(gpio_input);
gpio_free(gpio_output); ldx_gpio_free(gpio_output);
} }
/*
* sigaction_handler() - Handler to execute after receiving a signal
*
* @signum: Received signal.
*/
static void sigaction_handler(int signum) static void sigaction_handler(int signum)
{ {
/* 'atexit' executes the cleanup function */ /* 'atexit' executes the cleanup function */
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
/*
* register_signals() - Registers program signals
*/
static void register_signals(void) static void register_signals(void)
{ {
struct sigaction action; struct sigaction action;
@ -83,22 +97,14 @@ static void register_signals(void)
sigaction(SIGTERM, &action, NULL); sigaction(SIGTERM, &action, NULL);
} }
static int gpio_interrupt_cb(void *arg) /*
{ * parse_argument() - Parses the given string argument and returns the
struct gpio_interrupt_cb_data *data = arg; * corresponding integer value
*
printf("Input GPIO interrupt detected; toggling output GPIO\n"); * @argv: Argument to parse in string format.
*
/* Toggle output GPIO */ * Return: The parsed integer argument, -1 on error.
data->value = data->value ? GPIO_LOW : GPIO_HIGH; */
gpio_set_value(data->gpio, data->value);
/* Decrease remaining loops */
data->remaining_loops -= 1;
return 0;
}
static int parse_argument(char *argv) static int parse_argument(char *argv)
{ {
char *endptr; char *endptr;
@ -112,11 +118,32 @@ static int parse_argument(char *argv)
return -1; return -1;
if (endptr == argv) if (endptr == argv)
return gpio_get_kernel_number(endptr); return ldx_gpio_get_kernel_number(endptr);
return value; return value;
} }
/*
* gpio_interrupt_cb() - GPIO callback for interrupts
*
* @arg: GPIO interrupt data (struct gpio_interrupt_cb_data).
*/
static int gpio_interrupt_cb(void *arg)
{
struct gpio_interrupt_cb_data *data = arg;
printf("Input GPIO interrupt detected; toggling output GPIO\n");
/* Toggle output GPIO */
data->value = data->value ? GPIO_LOW : GPIO_HIGH;
ldx_gpio_set_value(data->gpio, data->value);
/* Decrease remaining loops */
data->remaining_loops -= 1;
return 0;
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
int button, led, i; int button, led, i;
@ -142,7 +169,7 @@ int main(int argc, char *argv[])
/* Request input GPIO */ /* Request input GPIO */
gpio_input = gpio_input =
gpio_request((unsigned)button, GPIO_IRQ_EDGE_RISING, ldx_gpio_request((unsigned int)button, GPIO_IRQ_EDGE_RISING,
REQUEST_SHARED); REQUEST_SHARED);
if (!gpio_input) { if (!gpio_input) {
printf("Failed to initialize input GPIO\n"); printf("Failed to initialize input GPIO\n");
@ -151,14 +178,14 @@ int main(int argc, char *argv[])
/* Request output GPIO */ /* Request output GPIO */
gpio_output = gpio_output =
gpio_request((unsigned)led, GPIO_OUTPUT_LOW, REQUEST_SHARED); ldx_gpio_request((unsigned int)led, GPIO_OUTPUT_LOW, REQUEST_SHARED);
if (!gpio_output) { if (!gpio_output) {
printf("Failed to initialize output GPIO\n"); printf("Failed to initialize output GPIO\n");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
/* Configure input GPIO to active HIGH */ /* Configure input GPIO to active HIGH */
gpio_set_active_mode(gpio_input, GPIO_ACTIVE_HIGH); ldx_gpio_set_active_mode(gpio_input, GPIO_ACTIVE_HIGH);
/* /*
* Test blocking interrupt mode * Test blocking interrupt mode
@ -166,10 +193,10 @@ int main(int argc, char *argv[])
printf("[INFO] Testing interrupt blocking mode\n"); printf("[INFO] Testing interrupt blocking mode\n");
printf("Press the button (for %d events):\n", TEST_LOOPS); printf("Press the button (for %d events):\n", TEST_LOOPS);
for (i = 0; i < TEST_LOOPS; i++) { for (i = 0; i < TEST_LOOPS; i++) {
if (gpio_wait_interrupt(gpio_input, -1) == GPIO_IRQ_ERROR_NONE) { if (ldx_gpio_wait_interrupt(gpio_input, -1) == GPIO_IRQ_ERROR_NONE) {
printf("Press %d; toggling output GPIO\n", i + 1); printf("Press %d; toggling output GPIO\n", i + 1);
output_value = output_value ? GPIO_LOW : GPIO_HIGH; output_value = output_value ? GPIO_LOW : GPIO_HIGH;
gpio_set_value(gpio_output, output_value); ldx_gpio_set_value(gpio_output, output_value);
} }
} }
@ -187,7 +214,7 @@ int main(int argc, char *argv[])
("Parent process will wait until %d interrupts have been detected\n", ("Parent process will wait until %d interrupts have been detected\n",
TEST_LOOPS); TEST_LOOPS);
if (gpio_start_wait_interrupt(gpio_input, &gpio_interrupt_cb, &cb_data) if (ldx_gpio_start_wait_interrupt(gpio_input, &gpio_interrupt_cb, &cb_data)
!= EXIT_SUCCESS) { != EXIT_SUCCESS) {
printf("Failed to start interrupt handler thread\n"); printf("Failed to start interrupt handler thread\n");
return EXIT_FAILURE; return EXIT_FAILURE;

View File

@ -1,6 +0,0 @@
apix-i2c-example
*.o
.cproject
.project
.settings/
*~

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2017 Digi International Inc. # Copyright 2017, Digi International Inc.
# #
# Permission to use, copy, modify, and/or distribute this software for any # Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above # purpose with or without fee is hereby granted, provided that the above
@ -9,35 +9,29 @@
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, # AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE. # PERFORMANCE OF THIS SOFTWARE.
# #
#
EXECUTABLE = apix-i2c-example BINARY := apix-i2c-example
SRC = .
CFLAGS += -Wall -O2 CFLAGS += -Wall -O2
CFLAGS += $(shell pkg-config --cflags libdigiapix) CFLAGS += $(shell pkg-config --cflags libdigiapix)
LDLIBS += $(shell pkg-config --libs libdigiapix) LDLIBS += $(shell pkg-config --libs libdigiapix)
SRCS = $(wildcard $(SRC)/*.c) $(BINARY): main.o
OBJS = $(SRCS:.c=.o)
.PHONY: all
all: $(EXECUTABLE)
$(EXECUTABLE): $(OBJS)
$(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@ $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
.PHONY: install .PHONY: install
install: $(EXECUTABLE) install: $(BINARY)
install -d $(DESTDIR)/usr/bin install -d $(DESTDIR)/usr/bin
install -m 0755 $(EXECUTABLE) $(DESTDIR)/usr/bin/ install -m 0755 $^ $(DESTDIR)/usr/bin/
.PHONY: all
all: $(BINARY)
.PHONY: clean .PHONY: clean
clean: clean:
-rm -f $(EXECUTABLE) $(OBJS) -rm -f *.o $(BINARY)

View File

@ -37,6 +37,9 @@ static uint8_t *rx_buf;
/* /*
* usage_and_exit() - Show usage information and exit with 'exitval' return * usage_and_exit() - Show usage information and exit with 'exitval' return
* value * value
*
* @name: Application name.
* @exitval: The exit code.
*/ */
static void usage_and_exit(char *name, int exitval) static void usage_and_exit(char *name, int exitval)
{ {
@ -62,22 +65,22 @@ static void usage_and_exit(char *name, int exitval)
static void cleanup(void) static void cleanup(void)
{ {
/* Free i2c */ /* Free i2c */
i2c_free(i2c_bus); ldx_i2c_free(i2c_bus);
/* Free buffers */ /* Free buffers */
free(rx_buf); free(rx_buf);
free(tx_buf); free(tx_buf);
} }
/** /*
* sigaction_handler() - Handler to execute after receiving a signal. * sigaction_handler() - Handler to execute after receiving a signal
* *
* @signum: Received signal. * @signum: Received signal.
*/ */
static void sigaction_handler(int signum) static void sigaction_handler(int signum)
{ {
/* 'atexit' executes the cleanup function */ /* 'atexit' executes the cleanup function */
exit(EXIT_SUCCESS); exit(EXIT_FAILURE);
} }
/* /*
@ -96,6 +99,40 @@ static void register_signals(void)
sigaction(SIGTERM, &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.
*
* Return: The parsed integer argument, -1 on error.
*/
static int parse_argument(char *argv)
{
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)
return ldx_i2c_get_bus(endptr);
return value;
}
/*
* write_page() - Writes an EEPROM page with the given data
*
* @page_index: index of the EEPROM page to write.
* @data: the data to write.
*
* Return: EXIT_SUCCESS on success, EXIT_FAILURE otherwise.
*/
static int write_page(int page_index, uint8_t *data) static int write_page(int page_index, uint8_t *data)
{ {
unsigned int page_address = eeprom_page_size * page_index; unsigned int page_address = eeprom_page_size * page_index;
@ -103,7 +140,7 @@ static int write_page(int page_index, uint8_t *data)
uint8_t *write_data; uint8_t *write_data;
/* Create write buffer */ /* Create write buffer */
write_data = (uint8_t*)calloc(eeprom_page_size + eeprom_addr_size, sizeof(uint8_t)); write_data = (uint8_t *)calloc(eeprom_page_size + eeprom_addr_size, sizeof(uint8_t));
if (write_data == NULL) { if (write_data == NULL) {
printf("Error: allocating page memory\n"); printf("Error: allocating page memory\n");
return EXIT_FAILURE; return EXIT_FAILURE;
@ -113,7 +150,7 @@ static int write_page(int page_index, uint8_t *data)
page_index, page_address); page_index, page_address);
for (i = 0; i < eeprom_addr_size; i++) { for (i = 0; i < eeprom_addr_size; i++) {
write_data[i] = (page_address >> (8 * (eeprom_addr_size - i -1))); write_data[i] = (page_address >> (8 * (eeprom_addr_size - i - 1)));
} }
/* Fill the data array. */ /* Fill the data array. */
@ -121,7 +158,7 @@ static int write_page(int page_index, uint8_t *data)
write_data[(i + eeprom_addr_size)] = data[i]; write_data[(i + eeprom_addr_size)] = data[i];
} }
if (i2c_write(i2c_bus, i2c_address, write_data, (uint16_t)(eeprom_page_size + eeprom_addr_size)) != EXIT_SUCCESS) { if (ldx_i2c_write(i2c_bus, i2c_address, write_data, (uint16_t)(eeprom_page_size + eeprom_addr_size)) != EXIT_SUCCESS) {
printf("Error: Data written failed.\n"); printf("Error: Data written failed.\n");
free(write_data); free(write_data);
return EXIT_FAILURE; return EXIT_FAILURE;
@ -131,7 +168,7 @@ static int write_page(int page_index, uint8_t *data)
we get a success result). */ we get a success result). */
do { do {
printf("Write in progress...\n"); printf("Write in progress...\n");
ret = i2c_write(i2c_bus, i2c_address, write_data, (uint16_t)eeprom_addr_size); ret = ldx_i2c_write(i2c_bus, i2c_address, write_data, (uint16_t)eeprom_addr_size);
usleep(1); usleep(1);
} while (ret == EXIT_FAILURE); } while (ret == EXIT_FAILURE);
printf("Write finished!\n"); printf("Write finished!\n");
@ -141,6 +178,14 @@ static int write_page(int page_index, uint8_t *data)
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
/*
* read_page() - Reads an EEPROM page
*
* @page_index: index of the EEPROM page to read.
* @data: buffer to store the read data in.
*
* Return: EXIT_SUCCESS on success, EXIT_FAILURE otherwise.
*/
static int read_page(int page_index, uint8_t *data) static int read_page(int page_index, uint8_t *data)
{ {
unsigned int page_address = eeprom_page_size * page_index; unsigned int page_address = eeprom_page_size * page_index;
@ -148,7 +193,7 @@ static int read_page(int page_index, uint8_t *data)
int i; int i;
/* Create write buffer */ /* Create write buffer */
write_data = (uint8_t*)calloc(eeprom_addr_size, sizeof(uint8_t)); write_data = (uint8_t *)calloc(eeprom_addr_size, sizeof(uint8_t));
if (write_data == NULL) { if (write_data == NULL) {
printf("Error: allocating page memory\n"); printf("Error: allocating page memory\n");
return EXIT_FAILURE; return EXIT_FAILURE;
@ -158,10 +203,10 @@ static int read_page(int page_index, uint8_t *data)
page_index, page_address); page_index, page_address);
for (i = 0; i < eeprom_addr_size; i++) { for (i = 0; i < eeprom_addr_size; i++) {
write_data[i] = (page_address >> (8 * (eeprom_addr_size - i -1))); write_data[i] = (page_address >> (8 * (eeprom_addr_size - i - 1)));
} }
if (i2c_transfer(i2c_bus, i2c_address, write_data, (uint16_t)eeprom_addr_size, if (ldx_i2c_transfer(i2c_bus, i2c_address, write_data, (uint16_t)eeprom_addr_size,
data, (uint16_t)eeprom_page_size) != EXIT_SUCCESS) { data, (uint16_t)eeprom_page_size) != EXIT_SUCCESS) {
printf("Failed to read data\n"); printf("Failed to read data\n");
free(write_data); free(write_data);
@ -186,8 +231,8 @@ int main(int argc, char **argv)
return EXIT_FAILURE; return EXIT_FAILURE;
} }
i2c_bus_nb = atoi(argv[1]); i2c_bus_nb = parse_argument(argv[1]);
i2c_address = (unsigned int)strtol(argv[2],NULL,16); i2c_address = (unsigned int)strtol(argv[2], NULL, 16);
eeprom_addr_size = atoi(argv[3]); eeprom_addr_size = atoi(argv[3]);
eeprom_page_size = atoi(argv[4]); eeprom_page_size = atoi(argv[4]);
page_index = atoi(argv[5]); page_index = atoi(argv[5]);
@ -217,14 +262,14 @@ int main(int argc, char **argv)
register_signals(); register_signals();
/* Request I2C */ /* Request I2C */
i2c_bus = i2c_request((unsigned int)i2c_bus_nb); i2c_bus = ldx_i2c_request((unsigned int)i2c_bus_nb);
if (!i2c_bus) { if (!i2c_bus) {
printf("Failed to initialize I2C\n"); printf("Failed to initialize I2C\n");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
/* Set the timeout for the I2C slave. */ /* Set the timeout for the I2C slave. */
if (i2c_set_timeout(i2c_bus, I2C_TIMEOUT) != EXIT_SUCCESS) { if (ldx_i2c_set_timeout(i2c_bus, I2C_TIMEOUT) != EXIT_SUCCESS) {
printf("Failed to set I2C timeout\n"); printf("Failed to set I2C timeout\n");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -232,7 +277,7 @@ int main(int argc, char **argv)
printf("Preparing I2C data to write...\n"); printf("Preparing I2C data to write...\n");
/* Create write buffer */ /* Create write buffer */
tx_buf = (uint8_t*)calloc(eeprom_page_size + eeprom_addr_size, sizeof(uint8_t)); tx_buf = (uint8_t *)calloc(eeprom_page_size + eeprom_addr_size, sizeof(uint8_t));
if (tx_buf == NULL) { if (tx_buf == NULL) {
printf("Error: allocating page memory\n"); printf("Error: allocating page memory\n");
return EXIT_FAILURE; return EXIT_FAILURE;
@ -262,7 +307,7 @@ int main(int argc, char **argv)
} }
/* Create read buffer */ /* Create read buffer */
rx_buf = (uint8_t*)calloc(eeprom_page_size, sizeof(uint8_t)); rx_buf = (uint8_t *)calloc(eeprom_page_size, sizeof(uint8_t));
if (rx_buf == NULL) { if (rx_buf == NULL) {
printf("Error: allocating page memory\n"); printf("Error: allocating page memory\n");
return EXIT_FAILURE; return EXIT_FAILURE;

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2017 Digi International Inc. # Copyright 2017, Digi International Inc.
# #
# Permission to use, copy, modify, and/or distribute this software for any # Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above # purpose with or without fee is hereby granted, provided that the above
@ -9,35 +9,29 @@
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, # AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE. # PERFORMANCE OF THIS SOFTWARE.
# #
#
EXECUTABLE = pwm-digiapix-sample BINARY := apix-pwm-example
SRC = . CFLAGS += -Wall -O2
CFLAGS += -Wall
CFLAGS += $(shell pkg-config --cflags libdigiapix) CFLAGS += $(shell pkg-config --cflags libdigiapix)
LDLIBS += $(shell pkg-config --libs libdigiapix) LDLIBS += $(shell pkg-config --libs libdigiapix)
SRCS = $(wildcard $(SRC)/*.c) $(BINARY): main.o
OBJS = $(SRCS:.c=.o)
.PHONY: all
all: $(EXECUTABLE)
$(EXECUTABLE): $(OBJS)
$(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@ $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
.PHONY: install .PHONY: install
install: $(EXECUTABLE) install: $(BINARY)
install -d $(DESTDIR)/usr/bin install -d $(DESTDIR)/usr/bin
install -m 0755 $(EXECUTABLE) $(DESTDIR)/usr/bin/ install -m 0755 $^ $(DESTDIR)/usr/bin/
.PHONY: all
all: $(BINARY)
.PHONY: clean .PHONY: clean
clean: clean:
-rm -f $(EXECUTABLE) $(OBJS) -rm -f *.o $(BINARY)

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017 Digi International Inc. * Copyright 2017, Digi International Inc.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -9,122 +9,169 @@
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE. * PERFORMANCE OF THIS SOFTWARE.
* =======================================================================
*/ */
#include <errno.h>
#include <libgen.h> #include <libgen.h>
#include <limits.h>
#include <signal.h> #include <signal.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <pwm.h> #include <libdigiapix/pwm.h>
/*------------------------------------------------------------------------------
D E F I N I T I O N S
------------------------------------------------------------------------------*/
#define DEFAULT_PWM_CHANNEL 0 #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 pwm_t *pwm_line;
static int running = 1; static int running = 1;
/*
* 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 PWM support\n"
"\n"
"Usage: %s <pwm-chip> <pwm-freq>\n\n"
"<pwm-chip> PWM chip number or alias\n"
"<pwm-freq> Frequency to use (Hz)\n\n", name);
exit(exitval);
}
/*
* cleanup() - Frees all the allocated memory before exiting
*/
static void cleanup(void)
{
running = 0;
if (pwm_line) {
ldx_pwm_enable(pwm_line, PWM_DISABLED);
ldx_pwm_free(pwm_line);
}
}
/*
* 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.
*
* Return: The parsed integer argument, -1 on error.
*/
static int parse_argument(char *argv)
{
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)
return ldx_pwm_get_channel(endptr);
return value;
}
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
unsigned int pwm_freq = DEFAULT_FREQUENCY;
int ret, duty_cycle = 10, ascending = 1; int ret, duty_cycle = 10, ascending = 1;
char *name = basename(argv[0]); char *name = basename(argv[0]);
unsigned int pwm_chip, pwm_freq = 0;
/* Check if the PWM values are passed in the command line. */ /* Check if the PWM values are passed in the command line. */
if (argc == 3) { if (argc != 3)
unsigned int pwm_chip = atoi(argv[1]); usage_and_exit(name, EXIT_FAILURE);
pwm_chip = parse_argument(argv[1]);
pwm_freq = atoi(argv[2]); pwm_freq = atoi(argv[2]);
pwm_line = pwm_request(pwm_chip, DEFAULT_PWM_CHANNEL, REQUEST_SHARED);
} else if (argc == 1) { if (pwm_chip < 0) {
/* Initialize the PWM. */ printf("Unable to parse PWM chip\n");
pwm_line = pwm_request_by_alias(DEFAULT_PWM_ALIAS, REQUEST_SHARED);
} else if (argc <= 2 || argc > 3) {
usage(name);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (pwm_freq <= 0) {
printf("Frequency must be greater than 0\n");
return EXIT_FAILURE;
}
pwm_line = ldx_pwm_request(pwm_chip, DEFAULT_PWM_CHANNEL, REQUEST_SHARED);
/* Check PWM. */ /* Check PWM. */
if (!pwm_line) { if (!pwm_line) {
printf("Failed to initialize PWM\n"); printf("Failed to initialize PWM\n");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
add_sigkill_signal(); /* Register signals and exit cleanup function */
atexit(cleanup);
register_signals();
printf("Setting PWM frequency to %dHz...", pwm_freq); printf("Setting PWM frequency to %dHz...", pwm_freq);
/* Set a duty cycle of 0 to avoid errors configuring the frequency */ /* Set a duty cycle of 0 to avoid errors configuring the frequency */
pwm_set_duty_cycle(pwm_line, 0); ldx_pwm_set_duty_cycle(pwm_line, 0);
ret = pwm_set_freq(pwm_line, pwm_freq); ret = ldx_pwm_set_freq(pwm_line, pwm_freq);
if (ret != PWM_CONFIG_ERROR_NONE) { if (ret != PWM_CONFIG_ERROR_NONE) {
printf("Failed\n"); printf("Failed\n");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
/* Check the frequency. */ /* Check the frequency. */
ret = pwm_get_freq(pwm_line); ret = ldx_pwm_get_freq(pwm_line);
printf("%s\n", ret >= 0 ? "Done" : "Failed"); printf("%s\n", ret >= 0 ? "Done" : "Failed");
if (ret == -1) { if (ret == -1) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
printf("Enabling PWM %d:%d...", pwm_line->chip, pwm_line->channel); printf("Enabling PWM %d:%d...", pwm_line->chip, pwm_line->channel);
ret = pwm_enable(pwm_line, PWM_ENABLED); ret = ldx_pwm_enable(pwm_line, PWM_ENABLED);
if (ret != EXIT_SUCCESS) { if (ret != EXIT_SUCCESS) {
printf("Failed\n"); printf("Failed\n");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
ret = pwm_is_enabled(pwm_line); ret = ldx_pwm_is_enabled(pwm_line);
printf("%s\n", ret == PWM_ENABLED ? "Done" : "Failed"); printf("%s\n", ret == PWM_ENABLED ? "Done" : "Failed");
if (ret != PWM_ENABLED) { if (ret != PWM_ENABLED) {
return EXIT_FAILURE; return EXIT_FAILURE;
@ -133,7 +180,7 @@ int main(int argc, char **argv)
/* Main application loop.*/ /* Main application loop.*/
while (running) { while (running) {
/* Set the duty cycle. */ /* Set the duty cycle. */
ret = pwm_set_duty_cycle_percentage(pwm_line, duty_cycle); ret = ldx_pwm_set_duty_cycle_percentage(pwm_line, duty_cycle);
if (ret != PWM_CONFIG_ERROR_NONE) { if (ret != PWM_CONFIG_ERROR_NONE) {
printf("Failed to set the duty cycle\n"); printf("Failed to set the duty cycle\n");
return EXIT_FAILURE; return EXIT_FAILURE;
@ -156,42 +203,3 @@ int main(int argc, char **argv)
return EXIT_SUCCESS; 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();
}

View File

@ -1,6 +0,0 @@
apix-spi-example
*.o
.cproject
.project
.settings/
*~

View File

@ -21,9 +21,6 @@ CFLAGS += -Wall -O2
CFLAGS += $(shell pkg-config --cflags libdigiapix) CFLAGS += $(shell pkg-config --cflags libdigiapix)
LDLIBS += $(shell pkg-config --libs libdigiapix) LDLIBS += $(shell pkg-config --libs libdigiapix)
.PHONY: all
all: $(BINARY)
$(BINARY): main.o $(BINARY): main.o
$(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@ $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
@ -32,6 +29,9 @@ install: $(BINARY)
install -d $(DESTDIR)/usr/bin install -d $(DESTDIR)/usr/bin
install -m 0755 $^ $(DESTDIR)/usr/bin/ install -m 0755 $^ $(DESTDIR)/usr/bin/
.PHONY: all
all: $(BINARY)
.PHONY: clean .PHONY: clean
clean: clean:
-rm -f *.o $(BINARY) -rm -f *.o $(BINARY)

View File

@ -53,6 +53,9 @@ static uint8_t *rx_buffer;
/* /*
* usage_and_exit() - Show usage information and exit with 'exitval' return * usage_and_exit() - Show usage information and exit with 'exitval' return
* value * value
*
* @name: Application name.
* @exitval: The exit code.
*/ */
static void usage_and_exit(char *name, int exitval) static void usage_and_exit(char *name, int exitval)
{ {
@ -78,7 +81,7 @@ static void usage_and_exit(char *name, int exitval)
static void cleanup(void) static void cleanup(void)
{ {
/* Free spi */ /* Free spi */
spi_free(spi_dev); ldx_spi_free(spi_dev);
/* Free buffers */ /* Free buffers */
free(tx_buffer); free(tx_buffer);
@ -87,6 +90,8 @@ static void cleanup(void)
/* /*
* sigaction_handler() - Handler to execute after receiving a signal * sigaction_handler() - Handler to execute after receiving a signal
*
* @signum: Received signal.
*/ */
static void sigaction_handler(int signum) static void sigaction_handler(int signum)
{ {
@ -111,7 +116,42 @@ static void register_signals(void)
} }
/* /*
* enable_write() - Sets the SPI write enable bit. * 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_SPI_DEVICE:
return ldx_spi_get_device(endptr);
case ARG_SPI_SLAVE:
return ldx_spi_get_slave(endptr);
default:
return -1;
}
}
return value;
}
/*
* enable_write() - Sets the SPI write enable bit
* *
* Return: EXIT_SUCCESS on success, EXIT_FAILURE otherwise. * Return: EXIT_SUCCESS on success, EXIT_FAILURE otherwise.
*/ */
@ -122,11 +162,11 @@ static int enable_write(void)
printf("[INFO] Setting write enable bit...\n"); printf("[INFO] Setting write enable bit...\n");
write_data[0] = WREN; write_data[0] = WREN;
return spi_write(spi_dev, write_data, sizeof(write_data)); return ldx_spi_write(spi_dev, write_data, sizeof(write_data));
} }
/* /*
* read_status_register() - Reads the SPI status register. * read_status_register() - Reads the SPI status register
* *
* @status: Variable to store the read status. * @status: Variable to store the read status.
* *
@ -139,7 +179,7 @@ static int read_status_register(uint8_t *status)
printf("[INFO] Reading status register...\n"); printf("[INFO] Reading status register...\n");
write_data[0] = RDSR; write_data[0] = RDSR;
if (spi_transfer(spi_dev, write_data, read_data, 2) != EXIT_SUCCESS) { if (ldx_spi_transfer(spi_dev, write_data, read_data, 2) != EXIT_SUCCESS) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -150,7 +190,7 @@ static int read_status_register(uint8_t *status)
} }
/* /*
* write_page() - Writes an EEPROM page with the given data. * write_page() - Writes an EEPROM page with the given data
* *
* @page_index: index of the EEPROM page to write. * @page_index: index of the EEPROM page to write.
* @data: the data to write. * @data: the data to write.
@ -177,7 +217,7 @@ static int write_page(int page_index, uint8_t* data)
write_data[0] = WRITE; // Operation. write_data[0] = WRITE; // Operation.
for (i = 0; i < address_bytes; i++) { for (i = 0; i < address_bytes; i++) {
write_data[i + OPERATION_BYTES] = (page_address >> (8 * (address_bytes - write_data[i + OPERATION_BYTES] = (page_address >> (8 * (address_bytes -
i -1))); i - 1)));
} }
/* Fill the data array. */ /* Fill the data array. */
@ -186,7 +226,7 @@ static int write_page(int page_index, uint8_t* data)
} }
/* Perform the write operation. */ /* Perform the write operation. */
if (spi_write(spi_dev, write_data, page_size + OPERATION_BYTES + if (ldx_spi_write(spi_dev, write_data, page_size + OPERATION_BYTES +
address_bytes) != EXIT_SUCCESS) { address_bytes) != EXIT_SUCCESS) {
free(write_data); free(write_data);
return EXIT_FAILURE; return EXIT_FAILURE;
@ -215,7 +255,7 @@ static int write_page(int page_index, uint8_t* data)
} }
/* /*
* read_page() - Reads an EEPROM page. * read_page() - Reads an EEPROM page
* *
* @page_index: index of the EEPROM page to read. * @page_index: index of the EEPROM page to read.
* @data: buffer to store the read data in. * @data: buffer to store the read data in.
@ -246,11 +286,11 @@ static int read_page(int page_index, uint8_t* data)
write_data[0] = READ; // Operation. write_data[0] = READ; // Operation.
for (i = 0; i < address_bytes; i++) { for (i = 0; i < address_bytes; i++) {
write_data[i + OPERATION_BYTES] = (page_address >> (8 * (address_bytes - write_data[i + OPERATION_BYTES] = (page_address >> (8 * (address_bytes -
i -1))); i - 1)));
} }
/* Perform the read operation with a transfer */ /* Perform the read operation with a transfer */
if (spi_transfer(spi_dev, write_data, read_data, page_size + if (ldx_spi_transfer(spi_dev, write_data, read_data, page_size +
OPERATION_BYTES + address_bytes) != EXIT_SUCCESS) { OPERATION_BYTES + address_bytes) != EXIT_SUCCESS) {
free(write_data); free(write_data);
free(read_data); free(read_data);
@ -266,41 +306,6 @@ static int read_page(int page_index, uint8_t* data)
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
/*
* 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_SPI_DEVICE:
return spi_get_device(endptr);
case ARG_SPI_SLAVE:
return spi_get_slave(endptr);
default:
return -1;
}
}
return value;
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
int spi_device, spi_slave, page_index, i = 0; int spi_device, spi_slave, page_index, i = 0;
@ -339,7 +344,7 @@ int main(int argc, char *argv[])
register_signals(); register_signals();
/* Request SPI */ /* Request SPI */
spi_dev = spi_request((unsigned)spi_device, (unsigned)spi_slave); spi_dev = ldx_spi_request((unsigned int)spi_device, (unsigned int)spi_slave);
if (!spi_dev) { if (!spi_dev) {
printf("Failed to initialize SPI\n"); printf("Failed to initialize SPI\n");
return EXIT_FAILURE; return EXIT_FAILURE;
@ -349,19 +354,19 @@ int main(int argc, char *argv[])
transfer_mode.clk_mode = CLK_MODE; transfer_mode.clk_mode = CLK_MODE;
transfer_mode.chip_select = CHIP_SELECT; transfer_mode.chip_select = CHIP_SELECT;
transfer_mode.bit_order = BIT_ORDER; transfer_mode.bit_order = BIT_ORDER;
if (spi_set_transfer_mode(spi_dev, &transfer_mode) != EXIT_SUCCESS) { if (ldx_spi_set_transfer_mode(spi_dev, &transfer_mode) != EXIT_SUCCESS) {
printf("Failed to configure SPI transfer mode\n"); printf("Failed to configure SPI transfer mode\n");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
/* Configure the bits-per-word */ /* Configure the bits-per-word */
if (spi_set_bits_per_word(spi_dev, BITS_PER_WORD) != EXIT_SUCCESS) { if (ldx_spi_set_bits_per_word(spi_dev, BITS_PER_WORD) != EXIT_SUCCESS) {
printf("Failed to configure SPI bits-per-word\n"); printf("Failed to configure SPI bits-per-word\n");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
/* Configure the max bus speed */ /* Configure the max bus speed */
if (spi_set_speed(spi_dev, MAX_BUS_SPEED) != EXIT_SUCCESS) { if (ldx_spi_set_speed(spi_dev, MAX_BUS_SPEED) != EXIT_SUCCESS) {
printf("Failed to configure SPI max bus speed\n"); printf("Failed to configure SPI max bus speed\n");
return EXIT_FAILURE; return EXIT_FAILURE;
} }