diff --git a/README.md b/README.md index 59ac6e8..dcaed2f 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ A C89 driver for the 3-axis accelerometer LIS3DH. Supports both I2C and SPI. ## Examples -See the `examples/` dir for complete code examples +See the `examples/` dir for complete code examples and explanations of LIS3DH terminology ## Implementation This driver requires the user to implement the following interface functions: diff --git a/example/README.md b/example/README.md index e29025d..47f82ff 100644 --- a/example/README.md +++ b/example/README.md @@ -3,16 +3,22 @@ ### file: simple.c Basic example of how to use this device -### file: fifo.c +# FIFO Instead of polling for every single [x y z] set, a FIFO with programmable capacity ("watermark") can be used, and then dumped into memory once full. All FIFO readings use 10-bit resolution regardless of the mode set in `cfg.mode`. The watermark level can be adjusted to a value [1-32] (0 disables FIFO) by modifying the `cfg.fifo.size` property before calling `lis3dh_configure()`. -The LIS3DH can optionally apply a HP filter on the sampling to reduce 'static acceleration' from the data. +The FIFO "engine" samples/appends another set of [x y z] values at 1/ODR. The maximum ODR supported by the FIFO "engine" is 200 Hz. + +| FIFO mode | symbol | description | +|------------------|-----------------------|----------------------------| +| Bypass | `LIS3DH_FIFO_MODE_BYPASS` | FIFO is inoperational | +| FIFO | `LIS3DH_FIFO_MODE_FIFO` | FIFO can be read/emptied at any time but once overrun has to be reset. See file: `fifo-mode-fifo.c` | +| Stream | `LIS3DH_FIFO_MODE_STREAM` | FIFO continously writes new data at 1/ODR and will overwrite old data until it is read/emptied. See file: `fifo-mode-stream.c` | +| Stream_to_FIFO | `LIS3DH_FIFO_STREAM_TO_FIFO` | FIFO behaves like Stream mode until a set interrupt is activated, then changes to a mode FIFO. | -Note: it seems that the highest data rate (ODR) possible using FIFO is 200 Hz, faster than that and it does not want to restart after 1 FIFO buffer. To sample faster, such as at the advertised 5 KHz rate, you have to use `lis3dh_read()` with `LP` mode. ### file: interrupts.c This device supports two different interrupt "output pins," `INT1` and `INT2`. The appropriate flag must be set in either `cfg.pin1` or `cfg.pin2` and the interrupt source must be configured to trigger into `INT1` or `INT2`. diff --git a/example/fifo-mode-stream.c b/example/fifo-mode-stream.c new file mode 100644 index 0000000..b66ddd4 --- /dev/null +++ b/example/fifo-mode-stream.c @@ -0,0 +1,48 @@ +#define _GNU_SOURCE +#include +#include +#include "lis3dh.h" +#include "i2c.h" +#include "interrupt.h" + +#define GPIO_INTERRUPT_PIN_INT1 12 + +int main() { + + lis3dh_t lis; + struct lis3dh_fifo_data fifo; + 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; + + lis3dh_init(&lis); + lis3dh_reset(&lis); + int_register(GPIO_INTERRUPT_PIN_INT1); + + lis.cfg.mode = LIS3DH_MODE_HR; + lis.cfg.range = LIS3DH_FS_2G; + lis.cfg.rate = LIS3DH_ODR_100_HZ; + lis.cfg.pin1.overrun = 1; + lis.cfg.fifo.mode = LIS3DH_FIFO_MODE_STREAM; + lis.cfg.fifo.trig = LIS3DH_FIFO_TRIG_INT1; + + lis3dh_configure(&lis); + + for ( ;; ) { + + int_poll(GPIO_INTERRUPT_PIN_INT1); + lis3dh_read_fifo(&lis, &fifo); + for(i=0; i -#include -#include "lis3dh.h" -#include "i2c.h" - -int main() { - - lis3dh_t lis; - struct lis3dh_fifo_data fifo; - 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; - - /* initialise LIS3DH struct */ - if (lis3dh_init(&lis)) { - /* error handling */ - } - - /* reset device just in case */ - if (lis3dh_reset(&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; - - /* write device config */ - if (lis3dh_configure(&lis)) { - /* error handling */ - } - - /* read as many [x y z] sets as specified by watermark level (size) default (max/32) */ - /* copy them to the fifo data struct `fifo' */ - if (lis3dh_read_fifo(&lis, &fifo)) { - /* 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 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; - - /* initalise LIS3DH struct */ - if (lis3dh_init(&lis)) { - /* error handling */ - } - - /* reset device just in case */ - if (lis3dh_reset(&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 interrupt into int pin1 */ - lis.cfg.pin1.overrun = 1; /* trigger upon FIFO overrun */ - - /* set up HP filter to remove DC component */ - lis.cfg.filter.mode = LIS3DH_FILTER_MODE_NORMAL_REF; - lis.cfg.filter.cutoff = LIS3DH_FILTER_CUTOFF_4; - lis.cfg.filter.fds = 0; /* remove this line, or set to 1 to enable filter */ - - /* write device config */ - if (lis3dh_configure(&lis)) { - /* error handling */ - } - - /* read REFERENCE to set filter to current accel field */ - if (lis3dh_reference(&lis)) { - /* error handling */ - } - - /* wait for interrupt from LIS3DH */ - if (int_poll(GPIO_INTERRUPT_PIN)) { - /* error handling */ - } - - /* read as many [x y z] sets as specified by watermark level (size) */ - /* copy them to the fifo data struct given below as `fifo' */ - if (lis3dh_read_fifo(&lis, &fifo)) { - /* error handling */ - } - - for(i=0; i