From 5bde365c65ba83a76dc72c659f356ac3aff806ba Mon Sep 17 00:00:00 2001 From: William Clark Date: Sat, 30 Dec 2023 13:10:40 +0000 Subject: [PATCH] examples and more debug flags --- Makefile | 3 +- README.md | 325 -------------------------------- example/README.md | 12 ++ example/fifo/fifo.c | 50 +++++ example/fifo/fifo2.c | 52 +++++ example/interrupts/interrupts.c | 68 +++++++ example/simple/simple.c | 44 +++++ example/simple/simple2.c | 48 +++++ i2c.c | 8 +- main.c | 14 +- 10 files changed, 287 insertions(+), 337 deletions(-) create mode 100644 example/README.md create mode 100644 example/fifo/fifo.c create mode 100644 example/fifo/fifo2.c create mode 100644 example/interrupts/interrupts.c create mode 100644 example/simple/simple.c create mode 100644 example/simple/simple2.c diff --git a/Makefile b/Makefile index 1932f3c..7b182ff 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,7 @@ CC=gcc CFLAGS=-O0 -g3 -ggdb -std=c89 -W -Werror -Wall -Wextra -Wpedantic -pedantic-errors -Wformat-signedness -I. -CFLAGS+=-Wlogical-op -Wmissing-declarations -Wswitch-default -Wundef -Wformat=2 +CFLAGS+=-Wlogical-op -Wmissing-declarations -Wswitch-default -Wundef -Wformat=2 -lasan +CFLAGS+=-fsanitize=pointer-overflow,undefined,shift,shift-exponent,shift-base,integer-divide-by-zero,null,signed-integer-overflow,bounds LFLAGS=-lm CFILES=$(wildcard *.c) all: diff --git a/README.md b/README.md index f7b3e78..5256e8e 100644 --- a/README.md +++ b/README.md @@ -32,331 +32,6 @@ All above functions return `0` on success. The `init` and `deinit` pointers can both be set to `NULL` and they won't be run. -## Usage -Simple example: -```c -#define _GNU_SOURCE -#include /* usleep() */ -#include -#include "lis3dh.h" -#include "i2c.h" - -int main() { - - lis3dh_t lis; - - lis.dev.init = i2c_init; - lis.dev.read = i2c_read; - lis.dev.write = i2c_write; - lis.dev.sleep = usleep; - lis.dev.deinit = i2c_deinit; - - if (lis3dh_init(&lis)) { - /* error handling */ - } - - lis.cfg.mode = LIS3DH_MODE_HR; - lis.cfg.range = LIS3DH_FS_4G; - lis.cfg.rate = LIS3DH_ODR_100_HZ; - - if (lis3dh_configure(&lis)) { - /* error handling */ - } - - if (lis3dh_poll(&lis)) { - /* error handling */ - } - - if (lis3dh_read(&lis)) { - /* error handling */ - } - - printf("x: %f, y: %f, z: %f\n", lis.acc.x, lis.acc.y, lis.acc.z); - - if (lis3dh_deinit(&lis)) { - /* error handling */ - } - - return 0; -} -``` -The output should be something similar to this: -``` -$ ./lis3dh -x: 0.540000, y: -0.882000, z: -0.100000 -``` -poll() and read() can be indefinitely looped for a constant data stream, like this: -```c -#define _GNU_SOURCE -#include -#include -#include "lis3dh.h" -#include "i2c.h" - -int main() { - - lis3dh_t lis; - int i; - - lis.dev.init = i2c_init; - lis.dev.read = i2c_read; - lis.dev.write = i2c_write; - lis.dev.sleep = usleep; - lis.dev.deinit = i2c_deinit; - - if (lis3dh_init(&lis)) { - /* error handling */ - } - - lis.cfg.mode = LIS3DH_MODE_HR; - lis.cfg.range = LIS3DH_FS_4G; - lis.cfg.rate = LIS3DH_ODR_100_HZ; - - if (lis3dh_configure(&lis)) { - /* error handling */ - } - - for(i=0; i<10; i++) { - - if (lis3dh_poll(&lis)) { - /* error handling */ - } - - if (lis3dh_read(&lis)) { - /* error handling */ - } - - printf("x: %f, y: %f, z: %f\n", lis.acc.x, lis.acc.y, lis.acc.z); - } - - if (lis3dh_deinit(&lis)) { - /* error handling */ - } - - return 0; -} -``` -Output: -``` -$ ./lis3dh -x: 0.534000, y: -0.882000, z: -0.102000 -x: 0.538000, y: -0.866000, z: -0.136000 -x: 0.518000, y: -0.846000, z: -0.100000 -... -``` -## Using FIFO -Instead of polling for every single [x y z] set, a FIFO with programmable capacity ("watermark") can be used like such: - -All FIFO readings use 10-bit resolution regardless of the mode set in `lis.cfg.mode`. - -The watermark level can also be adjusted to a value [0-31] inclusive by modifying the `lis.cfg.fifo.fth` property before calling configure(). -```c -#define _GNU_SOURCE -#include -#include -#include "lis3dh.h" -#include "i2c.h" - -int main() { - - lis3dh_t lis; - struct lis3dh_fifo_data data; - int i; - - lis.dev.init = i2c_init; - lis.dev.read = i2c_read; - lis.dev.write = i2c_write; - lis.dev.sleep = usleep; - lis.dev.deinit = i2c_deinit; - - if (lis3dh_init(&lis)) { - /* error handling */ - } - - lis.cfg.mode = LIS3DH_MODE_HR; - lis.cfg.range = LIS3DH_FS_4G; - lis.cfg.rate = LIS3DH_ODR_100_HZ; - lis.cfg.fifo.mode = LIS3DH_FIFO_MODE_NORMAL; - - if (lis3dh_configure(&lis)) { - /* error handling */ - } - - if (lis3dh_poll_fifo(&lis)) { - /* error handling */ - } - - if (lis3dh_read_fifo(&lis, &data)) { - /* error handling */ - } - - /* read out fifo buffer data */ - for(i=0; i -#include -#include "lis3dh.h" -#include "i2c.h" - -int main() { - - lis3dh_t lis; - struct lis3dh_fifo_data data; - int i; - - lis.dev.init = i2c_init; - lis.dev.read = i2c_read; - lis.dev.write = i2c_write; - lis.dev.sleep = usleep; - lis.dev.deinit = i2c_deinit; - - if (lis3dh_init(&lis)) { - /* error handling */ - } - - lis.cfg.mode = LIS3DH_MODE_HR; - lis.cfg.range = LIS3DH_FS_4G; - lis.cfg.rate = LIS3DH_ODR_100_HZ; - lis.cfg.fifo.mode = LIS3DH_FIFO_MODE_NORMAL; - lis.cfg.filter.mode = LIS3DH_FILTER_MODE_AUTORESET; - lis.cfg.filter.cutoff = LIS3DH_FILTER_CUTOFF_8; - - if (lis3dh_configure(&lis)) { - /* error handling */ - } - - if (lis3dh_poll_fifo(&lis)) { - /* error handling */ - } - - if (lis3dh_read_fifo(&lis, &data)) { - /* error handling */ - } - - /* read out fifo buffer data */ - for(i=0; i -#include -#include -#include -#include "lis3dh.h" -#include "interrupt.h" -#include "i2c.h" - -/* GPIO 12 or Pin 32 */ -#define GPIO_INTERRUPT_PIN 12 - -int main() { - - lis3dh_t lis; - struct lis3dh_fifo_data fifo; - int k; - - lis.dev.init = i2c_init; - lis.dev.read = i2c_read; - lis.dev.write = i2c_write; - lis.dev.sleep = usleep; - lis.dev.deinit = i2c_deinit; - - if (lis3dh_init(&lis)) { - /* error handling */ - } - - /* register interrupt */ - if (int_register(GPIO_INTERRUPT_PIN)) { - /* error handling */ - } - - 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; /* trigger into INT1 */ - lis.cfg.int1.wtm = 1; /* trigger upon watermark level reached */ - - if (lis3dh_configure(&lis)) { - /* error handling */ - } - - /* wait for interrupt from LIS3DH */ - if (int_poll(GPIO_INTERRUPT_PIN)) { - /* error handling */ - } - - if (lis3dh_read_fifo(&lis, &fifo)) { - /* error handling */ - } - - for(k=0; k +#include +#include "lis3dh.h" +#include "i2c.h" + +int main() { + + lis3dh_t lis; + struct lis3dh_fifo_data data; + int i; + + lis.dev.init = i2c_init; + lis.dev.read = i2c_read; + lis.dev.write = i2c_write; + lis.dev.sleep = usleep; + lis.dev.deinit = i2c_deinit; + + if (lis3dh_init(&lis)) { + /* error handling */ + } + + lis.cfg.mode = LIS3DH_MODE_HR; + lis.cfg.range = LIS3DH_FS_4G; + lis.cfg.rate = LIS3DH_ODR_100_HZ; + lis.cfg.fifo.mode = LIS3DH_FIFO_MODE_NORMAL; + + if (lis3dh_configure(&lis)) { + /* error handling */ + } + + if (lis3dh_poll_fifo(&lis)) { + /* error handling */ + } + + if (lis3dh_read_fifo(&lis, &data)) { + /* error handling */ + } + + /* read out fifo buffer data */ + for(i=0; i +#include +#include "lis3dh.h" +#include "i2c.h" + +int main() { + + lis3dh_t lis; + struct lis3dh_fifo_data data; + int i; + + lis.dev.init = i2c_init; + lis.dev.read = i2c_read; + lis.dev.write = i2c_write; + lis.dev.sleep = usleep; + lis.dev.deinit = i2c_deinit; + + if (lis3dh_init(&lis)) { + /* error handling */ + } + + lis.cfg.mode = LIS3DH_MODE_HR; + lis.cfg.range = LIS3DH_FS_4G; + lis.cfg.rate = LIS3DH_ODR_100_HZ; + lis.cfg.fifo.mode = LIS3DH_FIFO_MODE_NORMAL; + lis.cfg.filter.mode = LIS3DH_FILTER_MODE_AUTORESET; + lis.cfg.filter.cutoff = LIS3DH_FILTER_CUTOFF_8; + + if (lis3dh_configure(&lis)) { + /* error handling */ + } + + if (lis3dh_poll_fifo(&lis)) { + /* error handling */ + } + + if (lis3dh_read_fifo(&lis, &data)) { + /* error handling */ + } + + /* read out fifo buffer data */ + for(i=0; i +#include +#include +#include +#include "lis3dh.h" +#include "interrupt.h" +#include "i2c.h" + +/* GPIO 12 or Pin 32 */ +#define GPIO_INTERRUPT_PIN 12 + +int main() { + + lis3dh_t lis; + struct lis3dh_fifo_data fifo; + int k; + + lis.dev.init = i2c_init; + lis.dev.read = i2c_read; + lis.dev.write = i2c_write; + lis.dev.sleep = usleep; + lis.dev.deinit = i2c_deinit; + + if (lis3dh_init(&lis)) { + /* error handling */ + } + + /* register interrupt */ + if (int_register(GPIO_INTERRUPT_PIN)) { + /* error handling */ + } + + 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; /* trigger into INT1 */ + lis.cfg.int1.wtm = 1; /* trigger upon watermark level reached */ + + if (lis3dh_configure(&lis)) { + /* error handling */ + } + + /* wait for interrupt from LIS3DH */ + if (int_poll(GPIO_INTERRUPT_PIN)) { + /* error handling */ + } + + if (lis3dh_read_fifo(&lis, &fifo)) { + /* error handling */ + } + + for(k=0; k /* usleep() */ +#include +#include "lis3dh.h" +#include "i2c.h" + +int main() { + + lis3dh_t lis; + + lis.dev.init = i2c_init; + lis.dev.read = i2c_read; + lis.dev.write = i2c_write; + lis.dev.sleep = usleep; + lis.dev.deinit = i2c_deinit; + + if (lis3dh_init(&lis)) { + /* error handling */ + } + + lis.cfg.mode = LIS3DH_MODE_HR; + lis.cfg.range = LIS3DH_FS_4G; + lis.cfg.rate = LIS3DH_ODR_100_HZ; + + if (lis3dh_configure(&lis)) { + /* error handling */ + } + + if (lis3dh_poll(&lis)) { + /* error handling */ + } + + if (lis3dh_read(&lis)) { + /* error handling */ + } + + printf("x: %f, y: %f, z: %f\n", lis.acc.x, lis.acc.y, lis.acc.z); + + if (lis3dh_deinit(&lis)) { + /* error handling */ + } + + return 0; +} \ No newline at end of file diff --git a/example/simple/simple2.c b/example/simple/simple2.c new file mode 100644 index 0000000..e85c5fd --- /dev/null +++ b/example/simple/simple2.c @@ -0,0 +1,48 @@ +#define _GNU_SOURCE +#include +#include +#include "lis3dh.h" +#include "i2c.h" + +int main() { + + lis3dh_t lis; + int i; + + lis.dev.init = i2c_init; + lis.dev.read = i2c_read; + lis.dev.write = i2c_write; + lis.dev.sleep = usleep; + lis.dev.deinit = i2c_deinit; + + if (lis3dh_init(&lis)) { + /* error handling */ + } + + lis.cfg.mode = LIS3DH_MODE_HR; + lis.cfg.range = LIS3DH_FS_4G; + lis.cfg.rate = LIS3DH_ODR_100_HZ; + + if (lis3dh_configure(&lis)) { + /* error handling */ + } + + for(i=0; i<10; i++) { + + if (lis3dh_poll(&lis)) { + /* error handling */ + } + + if (lis3dh_read(&lis)) { + /* error handling */ + } + + printf("x: %f, y: %f, z: %f\n", lis.acc.x, lis.acc.y, lis.acc.z); + } + + if (lis3dh_deinit(&lis)) { + /* error handling */ + } + + return 0; +} \ No newline at end of file diff --git a/i2c.c b/i2c.c index bf7e2a0..d4c9dcc 100644 --- a/i2c.c +++ b/i2c.c @@ -23,12 +23,12 @@ static int fd; int i2c_init(void) { fd = open(I2C_DEVICE, O_RDWR); if (fd < 0) { - fprintf(stderr, "could not open device: %s\n", I2C_DEVICE); + fprintf(stderr, "[i2c] could not open device: %s\n", I2C_DEVICE); return 1; } if (ioctl(fd, I2C_SLAVE, I2C_LIS3DH_ADDRESS) < 0) { - fprintf(stderr, "failed to acquire bus/talk to slave\n"); + fprintf(stderr, "[i2c] failed to acquire bus/talk to slave\n"); close(fd); return 1; } @@ -46,7 +46,7 @@ int i2c_read(uint8_t reg, uint8_t *dst, uint32_t size) { write(fd, cmd, 2); if (read(fd, dst, size) != (ssize_t)size) { - fprintf(stderr, "error read()\n"); + fprintf(stderr, "[i2c] error read()\n"); return 1; } @@ -62,7 +62,7 @@ int i2c_write(uint8_t reg, uint8_t value) { cmd[1] = value; if (write(fd, cmd, 2) != 2) { - fprintf(stderr, "error write()\n"); + fprintf(stderr, "[i2c] error write()\n"); return 1; } diff --git a/main.c b/main.c index 88b08cd..5e9d83a 100644 --- a/main.c +++ b/main.c @@ -7,7 +7,8 @@ #include "interrupt.h" #include "i2c.h" -#define GPIO_INTERRUPT_PIN 12 +#define GPIO_INTERRUPT_PIN_INT1 12 +#define GPIO_INTERRUPT_PIN_INT2 16 /* calc magnitude of accel [x y z] vector */ static float mag(float x, float y, float z) { @@ -41,7 +42,7 @@ int main() { } /* register interrupt */ - if (int_register(GPIO_INTERRUPT_PIN)) { + if (int_register(GPIO_INTERRUPT_PIN_INT1)) { quit("int_register()", &lis); } @@ -50,10 +51,10 @@ int main() { 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.fifo.trig = LIS3DH_FIFO_TRIG_INT2; lis.cfg.int1.wtm = 1; lis.cfg.int1.latch = 1; - lis.cfg.filter.mode = LIS3DH_FILTER_MODE_REFERENCE; + lis.cfg.filter.mode = LIS3DH_FILTER_MODE_AUTORESET; lis.cfg.filter.cutoff = LIS3DH_FILTER_CUTOFF_8; @@ -64,7 +65,7 @@ int main() { for(i=0; i<50; i++) { /* wait for interrupt from LIS3DH */ - if (int_poll(GPIO_INTERRUPT_PIN)) { + if (int_poll(GPIO_INTERRUPT_PIN_INT1)) { quit("int_poll()", &lis); } @@ -83,11 +84,10 @@ int main() { mag(fifo.x[k], fifo.y[k], fifo.z[k])); } - lis3dh_reference(&lis); } /* unregister interrupt */ - if (int_unregister(GPIO_INTERRUPT_PIN)) { + if (int_unregister(GPIO_INTERRUPT_PIN_INT1)) { quit("int_unregister()", &lis); }