diff --git a/ISSUES.txt b/ISSUES.txt deleted file mode 100644 index 77d9587..0000000 --- a/ISSUES.txt +++ /dev/null @@ -1,5 +0,0 @@ -SPI does not work properly --- writes may go to wrong addr --- FIFO read out addr 6 loop seems to not work - -FIFO WTM/OVRN on INT1 does not fire when FTH (watermark) is not 31 (default/max) \ No newline at end of file diff --git a/README.md b/README.md index 947341b..e0a94a5 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ See the `examples/` dir for complete code examples ## Implementation This driver requires the user to implement the following interface functions: -This project has example interface code for I2C and SPI used on Raspberry Pi 4. +This project has example interface code for I2C and SPI used on Raspberry Pi 4, and for STM32. ```c /* initialise the "interface" */ int init(void); @@ -40,8 +40,7 @@ If `init` and/or `deinit` are set to `NULL`, they will be ignored. Useful on mic --- -### Using i2c on STM32 -Example code because I couldn't previously find working examples. +### STM32 ```c #define LIS3DH_I2C_ADDR 0x18 diff --git a/example/README.md b/example/README.md index 8bfff7d..914cec7 100644 --- a/example/README.md +++ b/example/README.md @@ -4,10 +4,12 @@ Basic example of how to use this device ### file: fifo.c -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 `lis.cfg.mode`. The watermark level can be adjusted to a value [1-32] (0 disables FIFO) by modifying the `lis.cfg.fifo.size` property before calling `lis3dh_configure()`. +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. +Note: `pin1.wtm` will NOT trigger if the FIFO size is 32 (default). Use `pin1.overrun` if you want an interrupt when the FIFO is full at full size (32.) + ### 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/interrupts.c b/example/interrupts.c index e052b08..5ddb39e 100644 --- a/example/interrupts.c +++ b/example/interrupts.c @@ -42,8 +42,7 @@ int main() { 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.fifo.size = 15;*/ - lis.cfg.pin1.wtm = 1; /* trigger upon FIFO watermark level reached */ + 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; diff --git a/lis3dh.c b/lis3dh.c index 0b2c5e4..df180f8 100644 --- a/lis3dh.c +++ b/lis3dh.c @@ -147,7 +147,7 @@ int lis3dh_configure(lis3dh_t *lis3dh) { fifo_ctrl_reg |= ((lis3dh->cfg.fifo.trig & 1) << 5); } - /* set enable filter */ + /* set enable filter if mode is set */ if (lis3dh->cfg.filter.mode != 0xFF) { ctrl_reg2 |= ((lis3dh->cfg.filter.mode & 0x03) << 6); ctrl_reg2 |= ((lis3dh->cfg.filter.cutoff & 0x03) << 4); @@ -175,9 +175,10 @@ int lis3dh_configure(lis3dh_t *lis3dh) { ctrl_reg0 |= 0x10; ctrl_reg0 |= (lis3dh->cfg.sdo_pullup & 1) << 7; + + /* Registers have to be set in this order for SPI to function correctly */ err |= lis3dh->dev.write(REG_CTRL_REG4, ctrl_reg4); err |= lis3dh->dev.write(REG_CTRL_REG5, ctrl_reg5); - err |= lis3dh->dev.write(REG_FIFO_CTRL_REG, fifo_ctrl_reg); err |= lis3dh->dev.write(REG_INT1_CFG, int1_cfg); err |= lis3dh->dev.write(REG_INT1_THS, int1_ths); @@ -194,16 +195,13 @@ int lis3dh_configure(lis3dh_t *lis3dh) { err |= lis3dh->dev.write(REG_ACT_DUR, lis3dh->cfg.act_dur); err |= lis3dh->dev.write(REG_TEMP_CFG_REG, temp_cfg_reg); err |= lis3dh->dev.write(REG_REFERENCE, lis3dh->cfg.reference); - - err |= lis3dh->dev.write(REG_CTRL_REG1, ctrl_reg1); - err |= lis3dh->dev.write(REG_CTRL_REG6, ctrl_reg6); err |= lis3dh->dev.write(REG_CTRL_REG0, ctrl_reg0); err |= lis3dh->dev.write(REG_CTRL_REG2, ctrl_reg2); err |= lis3dh->dev.write(REG_CTRL_REG3, ctrl_reg3); + err |= lis3dh->dev.write(REG_CTRL_REG1, ctrl_reg1); - /* sleep for a period TBD ~ ODR */ - lis3dh->dev.sleep(1000); /* 50 ms */ + lis3dh->dev.sleep(100000); /* 100 ms */ return err; } @@ -257,7 +255,7 @@ static uint8_t acc_sensitivity(uint8_t mode, uint8_t range) { } } - +/* read a single [x y z] set. Assume configured and poll'd */ int lis3dh_read(lis3dh_t *lis3dh) { uint8_t data[6]; uint8_t shift, sens; diff --git a/main.c b/main.c index 7a8a30b..4ba5abb 100644 --- a/main.c +++ b/main.c @@ -1,14 +1,19 @@ #define _GNU_SOURCE -#include #include +#include +#include +#include #include "lis3dh.h" -#include "i2c.h" +#include "interrupt.h" #include "spi.h" +/* GPIO 12 or Pin 32 */ +#define GPIO_INTERRUPT_PIN 12 + int main() { lis3dh_t lis; - struct lis3dh_fifo_data data; + struct lis3dh_fifo_data fifo; int i; lis.dev.init = spi_init; @@ -17,49 +22,67 @@ int main() { lis.dev.sleep = usleep; lis.dev.deinit = spi_deinit; - /* initialise LIS3DH struct */ + /* initalise LIS3DH struct */ if (lis3dh_init(&lis)) { - puts("init()"); + /* error handling */ } /* reset device just in case */ if (lis3dh_reset(&lis)) { - puts("reset()"); + /* error handling */ } - lis.cfg.mode = LIS3DH_MODE_HR; - lis.cfg.range = LIS3DH_FS_2G; - lis.cfg.rate = LIS3DH_ODR_400_HZ; - lis.cfg.fifo.mode = LIS3DH_FIFO_MODE_STREAM_TO_FIFO; - lis.cfg.fifo.size = 20; + /* 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 = 1; /* remove this line, or set to 1 to enable filter */ + /* write device config */ if (lis3dh_configure(&lis)) { - puts("configure()"); + /* error handling */ } -A: - /* poll fifo register until it reports that the watermark level has - been reached, or that it has overwritten old data, whichever - happens first. */ - if (lis3dh_poll_fifo(&lis)) { - puts("poll_fifo()"); + /* 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 (fth) */ /* copy them to the fifo data struct given below as `fifo' */ - if (lis3dh_read_fifo(&lis, &data)) { - puts("read_fifo()"); + if (lis3dh_read_fifo(&lis, &fifo)) { + /* error handling */ } - /* read out fifo buffer data */ - for(i=0; i