Commit eed80f1a authored by Brenden Tisler's avatar Brenden Tisler
Browse files

Adding DEV-IOT6U demo

parent bdaec2f1
/*
* SPI testing utility (using spidev driver)
*
* Copyright (c) 2007 MontaVista Software, Inc.
* Copyright (c) 2007 Anton Vorontsov <avorontsov@ru.mvista.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License.
*/
/*
* Copyright (C) 2017-2018 Bartosz Golaszewski <bartekgola@gmail.com>
* Polling functions from libgpiod gpiomon.c
*/
#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <gpiod.h>
#include <stdlib.h>
#include <getopt.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>
#include <sys/signalfd.h>
#include <signal.h>
#include <limits.h>
#include <poll.h>
#include <string.h>
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
static void pabort(const char *s)
{
perror(s);
abort();
}
static const char *device = "/dev/spidev3.0";
static uint8_t mode;
static uint8_t bits = 8;
static uint32_t speed = 1000000;
static uint16_t delay;
struct spi_ioc_transfer tr = {
.delay_usecs = 0,
.speed_hz = 1000000,
.bits_per_word = 8,
};
static void transfer(uint8_t *tx, uint8_t *rx, int size)
{
int ret;
int fd;
tr.tx_buf = (unsigned long)tx;
tr.rx_buf = (unsigned long)rx;
tr.len = size;
fd = open(device, O_RDWR);
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
close(fd);
if (ret < 1)
pabort("can't send spi message");
}
static void spi_init()
{
int ret = 0;
int fd;
fd = open(device, O_RDWR);
if (fd < 0)
pabort("can't open device");
/* spi mode */
ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
if (ret == -1)
pabort("can't set spi mode");
ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);
if (ret == -1)
pabort("can't get spi mode");
/* bits per word */
ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
if (ret == -1)
pabort("can't set bits per word");
ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
if (ret == -1)
pabort("can't get bits per word");
/* max speed hz */
ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
if (ret == -1)
pabort("can't set max speed hz");
ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
if (ret == -1)
pabort("can't get max speed hz");
close(fd);
}
/* LIBGPIOD gpiomon */
struct mon_ctx {
unsigned int offset;
unsigned int events_done;
int sigfd;
};
/*static void event_print_human_readable(unsigned int offset,
const struct timespec *ts,
int event_type)
{
char *evname;
if (event_type == GPIOD_CTXLESS_EVENT_CB_RISING_EDGE)
evname = " RISING EDGE";
else
evname = "FALLING EDGE";
printf("event: %s offset: %u timestamp: [%8ld.%09ld]\n",
evname, offset, ts->tv_sec, ts->tv_nsec);
}*/
static int poll_callback(unsigned int num_lines,
struct gpiod_ctxless_event_poll_fd *fds,
const struct timespec *timeout, void *data)
{
struct pollfd pfds[GPIOD_LINE_BULK_MAX_LINES + 1];
struct mon_ctx *ctx = data;
int cnt, ts, rv;
unsigned int i;
for (i = 0; i < num_lines; i++) {
pfds[i].fd = fds[i].fd;
pfds[i].events = POLLIN | POLLPRI;
}
pfds[i].fd = ctx->sigfd;
pfds[i].events = POLLIN | POLLPRI;
ts = timeout->tv_sec * 1000 + timeout->tv_nsec / 1000000;
cnt = poll(pfds, num_lines + 1, ts);
if (cnt < 0)
return GPIOD_CTXLESS_EVENT_POLL_RET_ERR;
else if (cnt == 0)
return GPIOD_CTXLESS_EVENT_POLL_RET_TIMEOUT;
rv = cnt;
for (i = 0; i < num_lines; i++) {
if (pfds[i].revents) {
fds[i].event = true;
if (!--cnt)
return rv;
}
}
/*
* If we're here, then there's a signal pending. No need to read it,
* we know we should quit now.
*/
close(ctx->sigfd);
return GPIOD_CTXLESS_EVENT_POLL_RET_STOP;
}
static void handle_event(struct mon_ctx *ctx, int event_type,
unsigned int line_offset,
const struct timespec *timestamp)
{
//event_print_human_readable(line_offset, timestamp, event_type);
ctx->events_done++;
printf("VALUE %d\n",ctx->events_done );
/* TODO modify value of data[] based on events_done % 16*/
uint8_t data[] = { ((ctx->events_done) % 0x80), ((ctx->events_done) % 0x80) }; // <<<<<<<<<<< this array will take 2 integers (0-127), can be in dec, hex, or bin format
// each binary bit in the integer is associated with an LED starting with 1 clockwise to 8, and 9-16
uint8_t set_rx[ARRAY_SIZE(data)] = {0,};
transfer(data, set_rx, ARRAY_SIZE(data));
}
static int event_callback(int event_type, unsigned int line_offset,
const struct timespec *timestamp, void *data)
{
struct mon_ctx *ctx = data;
switch (event_type) {
case GPIOD_CTXLESS_EVENT_CB_RISING_EDGE:
case GPIOD_CTXLESS_EVENT_CB_FALLING_EDGE:
handle_event(ctx, event_type, line_offset, timestamp);
break;
default:
/*
* REVISIT: This happening would indicate a problem in the
* library.
*/
return GPIOD_CTXLESS_EVENT_CB_RET_OK;
}
return GPIOD_CTXLESS_EVENT_CB_RET_OK;
}
static int make_signalfd(void)
{
sigset_t sigmask;
int sigfd, rv;
sigemptyset(&sigmask);
sigaddset(&sigmask, SIGTERM);
sigaddset(&sigmask, SIGINT);
rv = sigprocmask(SIG_BLOCK, &sigmask, NULL);
if (rv < 0)
pabort("error masking signals");
sigfd = signalfd(-1, &sigmask, 0);
if (sigfd < 0)
pabort("error creating signalfd");
return sigfd;
}
/* END LIBGPIOD gpiomon */
int main(int argc, char *argv[])
{
int ret;
int rv;
int event_type;
bool active_low = false;
struct timespec timeout = { 10, 0 };
struct mon_ctx ctx;
unsigned int offsets[GPIOD_LINE_BULK_MAX_LINES];
memset(&ctx, 0, sizeof(ctx));
/* High byte first - active high */
uint8_t data[] = { 0x00, 0x00 };
if (argc == 2)
device = argv[1];
printf("Device %s\n",device);
/* Read Array */
uint8_t set_rx[ARRAY_SIZE(data)] = {0,};
spi_init();
/* Send the data */
transfer(data, set_rx, ARRAY_SIZE(data));
/*Read back */
/*for (ret = 0; ret < ARRAY_SIZE(set_rx); ret++) {
printf("%.2X ", set_rx[ret]);
}*/
puts("");
event_type = GPIOD_CTXLESS_EVENT_BOTH_EDGES;
offsets[0] = 6; // GPIO PIN OFFSET - ENC_B is 6
ctx.sigfd = make_signalfd();
rv = gpiod_ctxless_event_monitor_multiple("gpiochip0", event_type, // gpiochip for ENC_B is 0
offsets, 1, // << Only 1 pin to monitor
active_low, "gpiomon",
&timeout, poll_callback,
event_callback, &ctx);
return 0;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment