diff --git a/lis3dh.c b/lis3dh.c index afe2640..1a3d17c 100644 --- a/lis3dh.c +++ b/lis3dh.c @@ -58,6 +58,12 @@ int lis3dh_init(lis3dh_t *lis3dh) { lis3dh->cfg.fifo.mode = 0xFF; /* in use if neq 0xFF */ lis3dh->cfg.fifo.trig = 0; lis3dh->cfg.fifo.fth = 0; + lis3dh->cfg.filter.mode = 0xFF; /* in use if neq 0xFF */ + lis3dh->cfg.filter.cutoff = 0; + lis3dh->cfg.filter.fds = 0; + lis3dh->cfg.filter.hpclick = 0; + lis3dh->cfg.filter.ia1 = 0; + lis3dh->cfg.filter.ia2 = 0; err |= lis3dh_reset(lis3dh); @@ -66,13 +72,14 @@ int lis3dh_init(lis3dh_t *lis3dh) { int lis3dh_configure(lis3dh_t *lis3dh) { - uint8_t ctrl_reg1, ctrl_reg4, ctrl_reg5; + uint8_t ctrl_reg1, ctrl_reg2, ctrl_reg4, ctrl_reg5; uint8_t fifo_ctrl_reg; uint8_t ref; int err = 0; /* last 0b111 enables Z, Y and X axis */ ctrl_reg1 = 0 | (lis3dh->cfg.rate << 4) | 0b111; + ctrl_reg2 = 0; ctrl_reg4 = 0 | (lis3dh->cfg.range << 4); ctrl_reg5 = 0; fifo_ctrl_reg = 0; @@ -85,6 +92,16 @@ int lis3dh_configure(lis3dh_t *lis3dh) { fifo_ctrl_reg |= ((lis3dh->cfg.fifo.trig & 1) << 5); } + /* set enable filter */ + if (lis3dh->cfg.filter.mode != 0xFF) { + ctrl_reg2 |= ((lis3dh->cfg.filter.mode & 0b11) << 6); + ctrl_reg2 |= ((lis3dh->cfg.filter.cutoff & 0b11) << 4); + ctrl_reg2 |= ((lis3dh->cfg.filter.fds & 1) << 3); + ctrl_reg2 |= ((lis3dh->cfg.filter.hpclick & 1) << 2); + ctrl_reg2 |= ((lis3dh->cfg.filter.ia1 & 1) << 1); + ctrl_reg2 |= (lis3dh->cfg.filter.ia2 & 1); + } + /* always set block update */ ctrl_reg4 |= 0x80; @@ -99,6 +116,7 @@ int lis3dh_configure(lis3dh_t *lis3dh) { } err |= lis3dh->dev.write(REG_CTRL_REG1, ctrl_reg1); + err |= lis3dh->dev.write(REG_CTRL_REG2, ctrl_reg2); 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); diff --git a/lis3dh.h b/lis3dh.h index 5000e44..00c3ea7 100644 --- a/lis3dh.h +++ b/lis3dh.h @@ -37,6 +37,24 @@ #define LIS3DH_FIFO_TRIG_INT1 0b0 #define LIS3DH_FIFO_TRIG_INT2 0b1 +/* filter modes */ +/* this one is reset by reading REFERENCE (0x26) */ +#define LIS3DH_FILTER_MODE_NORMAL 0b00 +#define LIS3DH_FILTER_MODE_REFERENCE 0b01 +#define LIS3DH_FILTER_MODE_NORMAL2 0b10 /* same as 00? */ +#define LIS3DH_FILTER_MODE_AUTORESET 0b11 + +/* filter cutoff */ +/* unfortunately, there is only a table for low-power mode, + and the actual cutoff-frequency depends on the ODR. + Naming scheme after ODR@400Hz + AN3308 > section 4.3.1.1 */ +#define LIS3DH_FILTER_CUTOFF_8 0b00 /* highest freq */ +#define LIS3DH_FILTER_CUTOFF_4 0b01 +#define LIS3DH_FILTER_CUTOFF_2 0b10 +#define LIS3DH_FILTER_CUTOFF_1 0b11 /* lowest freq */ + + struct lis3dh_device { int (*init)(void); int (*read)(uint8_t reg, uint8_t *dst, uint32_t size); @@ -45,6 +63,15 @@ struct lis3dh_device { int (*deinit)(void); }; +struct lis3dh_filter_config { + uint8_t mode; + uint8_t cutoff; + uint8_t fds; /* 1 -> use this filter */ + uint8_t hpclick; /* 1 -> use for "CLICK" function */ + uint8_t ia2; /* 1 -> use for AOI func on INT 2 */ + uint8_t ia1; /* 1 -> use for AOI func on INT 1 */ +}; + struct lis3dh_fifo_config { uint8_t fth; uint8_t trig; @@ -56,6 +83,7 @@ struct lis3dh_config { uint8_t range; /* FS */ uint8_t mode; /* LPen and HR */ struct lis3dh_fifo_config fifo; + struct lis3dh_filter_config filter; }; struct lis3dh_acceleration { diff --git a/main.c b/main.c index 7644411..07e62ee 100644 --- a/main.c +++ b/main.c @@ -32,6 +32,9 @@ int main() { lis.cfg.range = LIS3DH_FS_2G; 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_2; + lis.cfg.filter.fds = 1; if (lis3dh_configure(&lis)) { puts("configure ERR");