diff --git a/README.md b/README.md index 1e45abd..59ac6e8 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,7 @@ int lis3dh_reference(lis3dh_t *lis3dh); int lis3dh_reset(lis3dh_t *lis3dh); int lis3dh_read_adc(lis3dh_t *lis3dh); int lis3dh_read_temp(lis3dh_t *lis3dh); +int lis3dh_fifo_reset(lis3dh_t *lis3dh); ``` All functions return `0` on success, and any non-zero value on error. diff --git a/example/fifo-mode-fifo.c b/example/fifo-mode-fifo.c new file mode 100644 index 0000000..038fc80 --- /dev/null +++ b/example/fifo-mode-fifo.c @@ -0,0 +1,49 @@ +#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_FIFO; + 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; icfg.fifo.size - 1 && !LIS3DH_FIFO_SRC_EMPTY(fifo_src) && !err); /* the device stores FIFO offsets rather than `size' so a size-32 FIFO */ - /* has an offset of 31 */ - + /* has an offset of 31 ^ */ fifo->size = idx; return err; @@ -396,3 +395,28 @@ int lis3dh_read_temp(lis3dh_t *lis3dh) { lis3dh->adc.adc3 = (int8_t)data + 25; return err; } + +/* This function is meant to be used to reset the FIFO in `FIFO' mode. */ +int lis3dh_fifo_reset(lis3dh_t *lis3dh) { + /* 1. write BYPASS cfg */ + /* 2. maybe sleep */ + /* 3. write FIFO cfg as in configure() */ + int err = 0; + uint8_t fifo_ctrl_reg = 0; + + fifo_ctrl_reg |= ((lis3dh->cfg.fifo.size - 1) & 0x1F); + fifo_ctrl_reg |= (LIS3DH_FIFO_MODE_BYPASS << 6); + fifo_ctrl_reg |= ((lis3dh->cfg.fifo.trig & 1) << 5); + + err |= lis3dh->dev.write(REG_FIFO_CTRL_REG, fifo_ctrl_reg); + lis3dh->dev.sleep(1000); + + fifo_ctrl_reg |= ((lis3dh->cfg.fifo.size - 1) & 0x1F); + fifo_ctrl_reg |= (lis3dh->cfg.fifo.mode << 6); + fifo_ctrl_reg |= ((lis3dh->cfg.fifo.trig & 1) << 5); + + err |= lis3dh->dev.write(REG_FIFO_CTRL_REG, fifo_ctrl_reg); + + return err; + +} diff --git a/lis3dh.h b/lis3dh.h index 79ecca0..2f82e3d 100644 --- a/lis3dh.h +++ b/lis3dh.h @@ -53,20 +53,24 @@ #define LIS3DH_ODR_LP_5376_HZ 0x09 /* range/sens */ -#define LIS3DH_FS_2G 0x00 -#define LIS3DH_FS_4G 0x01 -#define LIS3DH_FS_8G 0x02 -#define LIS3DH_FS_16G 0x03 +#define LIS3DH_FS_2G 0x00 /* Full-scale sensing range: ± 2G */ +#define LIS3DH_FS_4G 0x01 /* Full-scale sensing range: ± 4G */ +#define LIS3DH_FS_8G 0x02 /* Full-scale sensing range: ± 8G */ +#define LIS3DH_FS_16G 0x03 /* Full-scale sensing range: ± 16G */ /* operating modes */ -#define LIS3DH_MODE_HR 0x00 -#define LIS3DH_MODE_LP 0x01 -#define LIS3DH_MODE_NORMAL 0x02 +#define LIS3DH_MODE_HR 0x00 /* High resolution: 12-bit */ +#define LIS3DH_MODE_LP 0x01 /* Low-power: 8-bit */ +#define LIS3DH_MODE_NORMAL 0x02 /* Normal: 10-bit */ /* FIFO modes */ -#define LIS3DH_FIFO_MODE_BYPASS 0x00 -#define LIS3DH_FIFO_MODE_NORMAL 0x01 /* "FIFO" */ -#define LIS3DH_FIFO_MODE_STREAM 0x02 +/* FIFO is not operational, and the buffer is reset. Must be used for switching FIFO modes */ +#define LIS3DH_FIFO_MODE_BYPASS 0x00 +/* Once FIFO fills up completely, it must be reset to be used again */ +#define LIS3DH_FIFO_MODE_FIFO 0x01 +/* Continously (over)writes buffer until it is read */ +#define LIS3DH_FIFO_MODE_STREAM 0x02 +/* Stream mode, but automatically switches to FIFO mode once a set interrupt has occurred */ #define LIS3DH_FIFO_MODE_STREAM_TO_FIFO 0x03 /* FIFO trigger pin selection */ @@ -307,5 +311,6 @@ int lis3dh_reference(lis3dh_t *lis3dh); int lis3dh_reset(lis3dh_t *lis3dh); int lis3dh_read_adc(lis3dh_t *lis3dh); int lis3dh_read_temp(lis3dh_t *lis3dh); +int lis3dh_fifo_reset(lis3dh_t *lis3dh); #endif \ No newline at end of file diff --git a/main.c b/main.c index cd92f0d..038fc80 100644 --- a/main.c +++ b/main.c @@ -1,34 +1,46 @@ #define _GNU_SOURCE -#include -#include #include -#include +#include #include "lis3dh.h" -#include "spi.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 = spi_init; - lis.dev.read = spi_read; - lis.dev.write = spi_write; + lis.dev.init = i2c_init; + lis.dev.read = i2c_read; + lis.dev.write = i2c_write; lis.dev.sleep = usleep; - lis.dev.deinit = spi_deinit; + lis.dev.deinit = i2c_deinit; lis3dh_init(&lis); lis3dh_reset(&lis); + int_register(GPIO_INTERRUPT_PIN_INT1); - lis.cfg.mode = LIS3DH_MODE_LP; - lis.cfg.range = LIS3DH_FS_16G; - lis.cfg.rate = LIS3DH_ODR_LP_5376_HZ; + 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_FIFO; + lis.cfg.fifo.trig = LIS3DH_FIFO_TRIG_INT1; lis3dh_configure(&lis); for ( ;; ) { - lis3dh_read(&lis); - printf("x: %4.4d mg, y: %4.4d mg, z: %4.4d mg\n", lis.acc.x, lis.acc.y, lis.acc.z); + int_poll(GPIO_INTERRUPT_PIN_INT1); + lis3dh_read_fifo(&lis, &fifo); + for(i=0; i