diff --git a/Makefile b/Makefile index 9514ba9..1932f3c 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,8 @@ CC=gcc -CFLAGS=-O2 -std=c89 -W -Werror -Wall -Wextra -pedantic -I. +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 LFLAGS=-lm -CFILES=$(wildcard ./*.c) +CFILES=$(wildcard *.c) all: $(CC) $(CFLAGS) $(CFILES) -o lis3dh $(LFLAGS) diff --git a/README.md b/README.md index 4128a20..f7b3e78 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,8 @@ int deinit(void); ``` 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 @@ -146,6 +148,7 @@ x: 0.518000, y: -0.846000, z: -0.100000 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 diff --git a/lis3dh.c b/lis3dh.c index 5b21aba..45b2c4e 100644 --- a/lis3dh.c +++ b/lis3dh.c @@ -1,3 +1,5 @@ +#include +#include #include "lis3dh.h" #include "registers.h" @@ -38,8 +40,11 @@ int lis3dh_init(lis3dh_t *lis3dh) { uint8_t result; int err = 0; - if (lis3dh->dev.init() != 0) { - return 1; + /* if init has been given, check it */ + if (lis3dh->dev.init != NULL) { + if (lis3dh->dev.init() != 0) { + return 1; + } } err |= lis3dh->dev.read(REG_WHO_AM_I, &result, 1); @@ -97,10 +102,10 @@ int lis3dh_configure(lis3dh_t *lis3dh) { int err = 0; /* the 0x07 enables Z, Y and X axis in that order */ - ctrl_reg1 = 0 | (lis3dh->cfg.rate << 4) | 0x07; + ctrl_reg1 = (lis3dh->cfg.rate << 4) | 0x07; ctrl_reg2 = 0; ctrl_reg3 = 0; - ctrl_reg4 = 0 | (lis3dh->cfg.range << 4); + ctrl_reg4 = (lis3dh->cfg.range << 4); ctrl_reg5 = 0; ctrl_reg6 = 0; fifo_ctrl_reg = 0; @@ -204,77 +209,36 @@ int lis3dh_poll_fifo(lis3dh_t *lis3dh) { /* the real size of the int you get back from reading the acc u16 depends on the power mode. shift down the 16 bit word by this amount: */ -static uint8_t acc_shift(lis3dh_t *lis3dh) { - switch (lis3dh->cfg.mode) { - case LIS3DH_MODE_HR: - return 4; /* i12 */ - case LIS3DH_MODE_NORMAL: - return 6; /* i10 */ - case LIS3DH_MODE_LP: - return 8; /* i8 */ +static uint8_t acc_shift(uint8_t mode) { + switch (mode) { + case LIS3DH_MODE_HR: return 4; /* i12 */ + case LIS3DH_MODE_NORMAL: return 6; /* i10 */ + case LIS3DH_MODE_LP: return 8; /* i8 */ + default: return 0; } - - return 0; } /* returns a scalar that when multiplied with axis reading turns it to a multiple of mg. */ -static uint8_t acc_sensitivity(lis3dh_t *lis3dh) { - uint8_t mode = lis3dh->cfg.mode; - - switch (lis3dh->cfg.range) { - case LIS3DH_FS_2G: - if (mode == LIS3DH_MODE_LP) { - return 16; - } else if (mode == LIS3DH_MODE_NORMAL) { - return 4; - } else { - return 1; - } - break; - - case LIS3DH_FS_4G: - if (mode == LIS3DH_MODE_LP) { - return 32; - } else if (mode == LIS3DH_MODE_NORMAL) { - return 8; - } else { - return 2; - } - break; - - case LIS3DH_FS_8G: - if (mode == LIS3DH_MODE_LP) { - return 64; - } else if (mode == LIS3DH_MODE_NORMAL) { - return 16; - } else { - return 4; - } - break; - - case LIS3DH_FS_16G: - if (mode == LIS3DH_MODE_LP) { - return 192; - } else if (mode == LIS3DH_MODE_NORMAL) { - return 48; - } else { - return 12; - } - break; +static uint8_t acc_sensitivity(uint8_t mode, uint8_t range) { + switch (range) { + case LIS3DH_FS_2G: return (mode == LIS3DH_MODE_LP) ? 16 : (mode == LIS3DH_MODE_NORMAL) ? 4 : 1; + case LIS3DH_FS_4G: return (mode == LIS3DH_MODE_LP) ? 32 : (mode == LIS3DH_MODE_NORMAL) ? 8 : 2; + case LIS3DH_FS_8G: return (mode == LIS3DH_MODE_LP) ? 64 : (mode == LIS3DH_MODE_NORMAL) ? 16 : 4; + case LIS3DH_FS_16G: return (mode == LIS3DH_MODE_LP) ? 192 : (mode == LIS3DH_MODE_NORMAL) ? 48 : 12; + default: return 0; } - - return 0; } + int lis3dh_read(lis3dh_t *lis3dh) { uint8_t data[6]; int32_t x, y, z; uint8_t scale, sens; int err = 0; - scale = acc_shift(lis3dh); - sens = acc_sensitivity(lis3dh); + scale = acc_shift(lis3dh->cfg.mode); + sens = acc_sensitivity(lis3dh->cfg.mode, lis3dh->cfg.range); /* must set MSbit of the address to multi-read and have the device auto-increment the address. */ @@ -301,17 +265,7 @@ int lis3dh_read_fifo(lis3dh_t *lis3dh, struct lis3dh_fifo_data *fifo) { /* FIFO is always 10-bit */ scale = 6; - - /* normal mode */ - if (lis3dh->cfg.range == LIS3DH_FS_2G) { - sens = 4; - } else if (lis3dh->cfg.range == LIS3DH_FS_4G) { - sens = 8; - } else if (lis3dh->cfg.range == LIS3DH_FS_8G) { - sens = 16; - } else { /* 16G */ - sens = 48; - } + sens = acc_sensitivity(lis3dh->cfg.mode, lis3dh->cfg.range); /* fifo buffer is max 32 */ fifo->size = lis3dh->cfg.fifo.fth > 32 ? 32 : lis3dh->cfg.fifo.fth; @@ -334,8 +288,13 @@ int lis3dh_read_fifo(lis3dh_t *lis3dh, struct lis3dh_fifo_data *fifo) { return err; } +/* if NULL, this function doesn't have to be called */ int lis3dh_deinit(lis3dh_t *lis3dh) { - return lis3dh->dev.deinit(); + if (lis3dh->dev.deinit != NULL) { + return lis3dh->dev.deinit(); + } + + return 0; } /* read INT1_SRC to clear latched INT1 irq */ diff --git a/main.c b/main.c index 6c005d0..88b08cd 100644 --- a/main.c +++ b/main.c @@ -10,12 +10,12 @@ #define GPIO_INTERRUPT_PIN 12 /* calc magnitude of accel [x y z] vector */ -float mag(float x, float y, float z) { +static float mag(float x, float y, float z) { return sqrt( powf(x, 2) + powf(y, 2) + powf(z, 2) ); } /* print message then exit */ -void quit(const char *msg, lis3dh_t *lis) { +static void quit(const char *msg, lis3dh_t *lis) { lis->dev.deinit(); fprintf(stderr, "%s\n", msg); exit(1); @@ -25,7 +25,7 @@ int main() { lis3dh_t lis; struct lis3dh_fifo_data fifo; - int k; + int i, k; /* set fn ptrs to rw on bus (i2c or SPI) */ lis.dev.init = i2c_init; @@ -53,6 +53,8 @@ int main() { lis.cfg.fifo.trig = LIS3DH_FIFO_TRIG_INT1; lis.cfg.int1.wtm = 1; lis.cfg.int1.latch = 1; + lis.cfg.filter.mode = LIS3DH_FILTER_MODE_REFERENCE; + lis.cfg.filter.cutoff = LIS3DH_FILTER_CUTOFF_8; /* write device config */ @@ -60,24 +62,28 @@ int main() { quit("configure()", &lis); } - /* wait for interrupt from LIS3DH */ - if (int_poll(GPIO_INTERRUPT_PIN)) { - quit("int_poll()", &lis); - } + for(i=0; i<50; i++) { + /* wait for interrupt from LIS3DH */ + if (int_poll(GPIO_INTERRUPT_PIN)) { + quit("int_poll()", &lis); + } - if (lis3dh_clear_int1(&lis)) { - quit("clear_int1()", &lis); - } + if (lis3dh_clear_int1(&lis)) { + quit("clear_int1()", &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