interrupt generation
This commit is contained in:
parent
e1f2040e6c
commit
7ec153d397
3
Makefile
3
Makefile
@ -1,8 +1,9 @@
|
||||
CC=gcc
|
||||
CFLAGS=-O2 -std=c89 -W -Werror -Wall -Wextra -pedantic -I.
|
||||
LFLAGS=-lm
|
||||
CFILES=$(wildcard ./*.c)
|
||||
all:
|
||||
$(CC) $(CFLAGS) main.c i2c.c lis3dh.c -o lis3dh $(LFLAGS)
|
||||
$(CC) $(CFLAGS) $(CFILES) -o lis3dh $(LFLAGS)
|
||||
|
||||
clean:
|
||||
rm -rf lis3dh
|
||||
|
119
interrupt.c
Normal file
119
interrupt.c
Normal file
@ -0,0 +1,119 @@
|
||||
/*
|
||||
SYSFS gpio interrupt example for Raspberry Pi
|
||||
*/
|
||||
#define _GNU_SOURCE
|
||||
#include <stddef.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <poll.h>
|
||||
#include "interrupt.h"
|
||||
|
||||
|
||||
static int write_file(const char *path, const char *str) {
|
||||
int fd = 0;
|
||||
|
||||
if ((fd = open(path, O_WRONLY)) == 0) {
|
||||
fprintf(stderr, "unable to open %s\n", path);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (write(fd, str, strlen(str)) < 1) {
|
||||
fprintf(stderr, "unable to write to %s\n", path);
|
||||
close(fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Register a sysfs GPIO pin to be interruptable
|
||||
similar to:
|
||||
$ echo 12 > /sys/class/gpio/export
|
||||
$ echo both > /sys/class/gpio12/edge
|
||||
$ echo in > /sys/class/gpio12/direction
|
||||
|
||||
*/
|
||||
int int_register(int pin) {
|
||||
|
||||
char path[1024];
|
||||
char buffer[64];
|
||||
|
||||
/* begin by unregistering supplied pin, just in case */
|
||||
(void) int_unregister(pin);
|
||||
|
||||
memset(buffer, 0, 64);
|
||||
sprintf(buffer, "%d", pin);
|
||||
if (write_file("/sys/class/gpio/export", buffer) != 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* sleep 500 ms to let linux set up the dir .. */
|
||||
usleep(500000);
|
||||
|
||||
memset(path, 0, 1024);
|
||||
sprintf(path, "%s%d/%s", "/sys/class/gpio/gpio", pin, "edge");
|
||||
if (write_file(path, "both") != 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
memset(path, 0, 1024);
|
||||
sprintf(path, "%s%d/%s", "/sys/class/gpio/gpio", pin, "direction");
|
||||
if (write_file(path, "in") != 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* unregister an interrupt gpio config
|
||||
similar to:
|
||||
$ echo 12 > /sys/class/gpio/unexport
|
||||
*/
|
||||
int int_unregister(int pin) {
|
||||
char buffer[64];
|
||||
|
||||
memset(buffer, 0, 64);
|
||||
sprintf(buffer, "%d", pin);
|
||||
if (write_file("/sys/class/gpio/unexport", buffer) != 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* poll a gpio pin for interrupt event
|
||||
blocking
|
||||
*/
|
||||
int int_poll(int pin) {
|
||||
int fd;
|
||||
struct pollfd pfd;
|
||||
char path[1024];
|
||||
char buf[16];
|
||||
|
||||
memset(path, 0, 1024);
|
||||
sprintf(path, "%s%d/%s", "/sys/class/gpio/gpio", pin, "value");
|
||||
|
||||
if ((fd = open(path, O_RDONLY)) == 0) {
|
||||
fprintf(stderr, "unable to open %s\n", path);
|
||||
return 1;
|
||||
}
|
||||
|
||||
pfd.fd = fd;
|
||||
pfd.events = POLLPRI | POLLERR;
|
||||
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
read(fd, buf, sizeof buf);
|
||||
|
||||
poll(&pfd, 1, -1);
|
||||
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
read(fd, buf, sizeof buf);
|
||||
|
||||
return 0;
|
||||
}
|
11
interrupt.h
Normal file
11
interrupt.h
Normal file
@ -0,0 +1,11 @@
|
||||
#ifndef INTERRUPT_H
|
||||
#define INTERRUPT_H
|
||||
|
||||
/*
|
||||
Note: `pin' is GPIO No.
|
||||
*/
|
||||
int int_register(int pin);
|
||||
int int_unregister(int pin);
|
||||
int int_poll(int pin);
|
||||
|
||||
#endif
|
46
main.c
46
main.c
@ -4,8 +4,11 @@
|
||||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
#include "lis3dh.h"
|
||||
#include "interrupt.h"
|
||||
#include "i2c.h"
|
||||
|
||||
#define GPIO_INTERRUPT_PIN 12
|
||||
|
||||
/* calc magnitude of accel [x y z] vector */
|
||||
float mag(float x, float y, float z) {
|
||||
return sqrt( powf(x, 2) + powf(y, 2) + powf(z, 2) );
|
||||
@ -14,6 +17,7 @@ float mag(float x, float y, float z) {
|
||||
/* print message then exit */
|
||||
void quit(const char *msg, lis3dh_t *lis) {
|
||||
lis->dev.deinit();
|
||||
int_unregister(GPIO_INTERRUPT_PIN);
|
||||
fprintf(stderr, "%s\n", msg);
|
||||
exit(1);
|
||||
}
|
||||
@ -22,7 +26,7 @@ int main() {
|
||||
|
||||
lis3dh_t lis;
|
||||
struct lis3dh_fifo_data fifo;
|
||||
int i, k;
|
||||
int k;
|
||||
|
||||
/* set fn ptrs to rw on bus (i2c or SPI) */
|
||||
lis.dev.init = i2c_init;
|
||||
@ -37,34 +41,44 @@ int main() {
|
||||
quit("init()", &lis);
|
||||
}
|
||||
|
||||
/* register interrupt */
|
||||
if (int_register(GPIO_INTERRUPT_PIN)) {
|
||||
quit("int_register()", &lis);
|
||||
}
|
||||
|
||||
/* set up config */
|
||||
lis.cfg.mode = LIS3DH_MODE_NORMAL;
|
||||
lis.cfg.range = LIS3DH_FS_2G;
|
||||
lis.cfg.rate = LIS3DH_ODR_100_HZ;
|
||||
lis.cfg.fifo.mode = LIS3DH_FIFO_MODE_STREAM;
|
||||
lis.cfg.fifo.trig = LIS3DH_FIFO_TRIG_INT1;
|
||||
lis.cfg.pin1.overrun = 1;
|
||||
|
||||
|
||||
/* write device config */
|
||||
if (lis3dh_configure(&lis)) {
|
||||
quit("configure()", &lis);
|
||||
}
|
||||
|
||||
for (i=0; i<100; i++) {
|
||||
|
||||
/* poll fifo reg */
|
||||
if (lis3dh_poll_fifo(&lis)) {
|
||||
quit("poll_fifo()", &lis);
|
||||
}
|
||||
/* wait for interrupt from LIS3DH */
|
||||
if (int_poll(GPIO_INTERRUPT_PIN)) {
|
||||
quit("int_poll()", &lis);
|
||||
}
|
||||
|
||||
/* read stored fifo data into `fifo' struct */
|
||||
if (lis3dh_read_fifo(&lis, &fifo)) {
|
||||
quit("read_fifo()", &lis);
|
||||
}
|
||||
/* read stored fifo data into `fifo' struct */
|
||||
if (lis3dh_read_fifo(&lis, &fifo)) {
|
||||
quit("read_fifo()", &lis);
|
||||
}
|
||||
|
||||
for(k=0; k<fifo.size; k++) {
|
||||
printf("%04.04f %04.04f %04.04f %04.04f\n",
|
||||
fifo.x[k], fifo.y[k], fifo.z[k],
|
||||
mag(fifo.x[k], fifo.y[k], fifo.z[k]));
|
||||
}
|
||||
for(k=0; k<fifo.size; k++) {
|
||||
printf("%04.04f %04.04f %04.04f %04.04f\n",
|
||||
fifo.x[k], fifo.y[k], fifo.z[k],
|
||||
mag(fifo.x[k], fifo.y[k], fifo.z[k]));
|
||||
}
|
||||
|
||||
/* unregister interrupt */
|
||||
if (int_unregister(GPIO_INTERRUPT_PIN)) {
|
||||
quit("int_unregister()", &lis);
|
||||
}
|
||||
|
||||
/* deinitalise struct */
|
||||
|
Loading…
Reference in New Issue
Block a user