Compare commits

...

2 Commits

3 changed files with 99 additions and 36 deletions

View File

@ -47,26 +47,19 @@ int lis3dh_init(lis3dh_t *lis3dh) {
} }
} }
/* check WHO_AM_I to equal to 0x33 */ /* check WHO_AM_I equal to 0x33 */
err |= lis3dh->dev.read(REG_WHO_AM_I, &result, 1); err |= lis3dh->dev.read(REG_WHO_AM_I, &result, 1);
if (result != 0x33) { if (result != 0x33) {
return 1; return 1;
} }
/* zero device struct */ /* zero device struct */
lis3dh->cfg.rate = 0; memset(&lis3dh->acc, 0, sizeof lis3dh->acc);
lis3dh->cfg.range = 0; memset(&lis3dh->cfg, 0, sizeof lis3dh->cfg);
lis3dh->cfg.mode = 0;
lis3dh->cfg.fifo.mode = 0xFF; /* in use if neq 0xFF */ lis3dh->cfg.fifo.mode = 0xFF; /* in use if neq 0xFF */
lis3dh->cfg.fifo.trig = 0;
lis3dh->cfg.fifo.fth = 31; /* default watermark level. */ lis3dh->cfg.fifo.fth = 31; /* default watermark level. */
memset(&lis3dh->acc, 0, sizeof lis3dh->acc);
memset(&lis3dh->cfg.int1, 0, sizeof lis3dh->cfg.int1);
memset(&lis3dh->cfg.int2, 0, sizeof lis3dh->cfg.int2);
memset(&lis3dh->cfg.filter, 0, sizeof lis3dh->cfg.filter);
lis3dh->cfg.filter.mode = 0xFF; /* in use if neq 0xFF */ lis3dh->cfg.filter.mode = 0xFF; /* in use if neq 0xFF */
lis3dh->cfg.filter.fds = 1; /* bypass OFF by default */ lis3dh->cfg.filter.fds = 1; /* bypass OFF by default */
@ -78,7 +71,8 @@ int lis3dh_init(lis3dh_t *lis3dh) {
int lis3dh_configure(lis3dh_t *lis3dh) { int lis3dh_configure(lis3dh_t *lis3dh) {
uint8_t ctrl_reg1, ctrl_reg2, ctrl_reg3; uint8_t ctrl_reg1, ctrl_reg2, ctrl_reg3;
uint8_t ctrl_reg4, ctrl_reg5, ctrl_reg6; uint8_t ctrl_reg4, ctrl_reg5, ctrl_reg6;
uint8_t fifo_ctrl_reg; uint8_t fifo_ctrl_reg, int1_cfg, int2_cfg;
uint8_t int1_ths, int2_ths, int1_dur, int2_dur;
uint8_t ref; /* dummy */ uint8_t ref; /* dummy */
int err = 0; int err = 0;
@ -90,33 +84,64 @@ int lis3dh_configure(lis3dh_t *lis3dh) {
ctrl_reg5 = 0; ctrl_reg5 = 0;
ctrl_reg6 = 0; ctrl_reg6 = 0;
fifo_ctrl_reg = 0; fifo_ctrl_reg = 0;
int1_cfg = 0;
int2_cfg = 0;
int1_ths = 0;
int2_ths = 0;
int1_dur = 0;
int2_dur = 0;
/* set interrupt registers */ /* set interrupt registers */
ctrl_reg3 |= (lis3dh->cfg.int1.click & 1) << 7; ctrl_reg3 |= (lis3dh->cfg.int_pin1.click & 1) << 7;
ctrl_reg3 |= (lis3dh->cfg.int1.ia1 & 1) << 6; ctrl_reg3 |= (lis3dh->cfg.int_pin1.ia1 & 1) << 6;
ctrl_reg3 |= (lis3dh->cfg.int1.ia2 & 1) << 5; ctrl_reg3 |= (lis3dh->cfg.int_pin1.ia2 & 1) << 5;
ctrl_reg3 |= (lis3dh->cfg.int1.drdy_zyxda & 1) << 4; ctrl_reg3 |= (lis3dh->cfg.int_pin1.drdy_zyxda & 1) << 4;
ctrl_reg3 |= (lis3dh->cfg.int1.drdy_321 & 1) << 3; ctrl_reg3 |= (lis3dh->cfg.int_pin1.drdy_321 & 1) << 3;
ctrl_reg3 |= (lis3dh->cfg.int1.wtm & 1) << 2; ctrl_reg3 |= (lis3dh->cfg.int_pin1.wtm & 1) << 2;
ctrl_reg3 |= (lis3dh->cfg.int1.overrun & 1) << 1; ctrl_reg3 |= (lis3dh->cfg.int_pin1.overrun & 1) << 1;
ctrl_reg6 |= (lis3dh->cfg.int2.click & 1) << 7; ctrl_reg6 |= (lis3dh->cfg.int_pin2.click & 1) << 7;
ctrl_reg6 |= (lis3dh->cfg.int2.ia1 & 1) << 6; ctrl_reg6 |= (lis3dh->cfg.int_pin2.ia1 & 1) << 6;
ctrl_reg6 |= (lis3dh->cfg.int2.ia2 & 1) << 5; ctrl_reg6 |= (lis3dh->cfg.int_pin2.ia2 & 1) << 5;
ctrl_reg6 |= (lis3dh->cfg.int2.boot & 1) << 4; ctrl_reg6 |= (lis3dh->cfg.int_pin2.boot & 1) << 4;
ctrl_reg6 |= (lis3dh->cfg.int2.act & 1) << 3; ctrl_reg6 |= (lis3dh->cfg.int_pin2.act & 1) << 3;
ctrl_reg6 |= (lis3dh->cfg.int2.polarity & 1) << 1; ctrl_reg6 |= (lis3dh->cfg.int_pin2.polarity & 1) << 1;
ctrl_reg5 |= (lis3dh->cfg.int1.latch & 1) << 3; ctrl_reg5 |= (lis3dh->cfg.int_pin1.latch & 1) << 3;
ctrl_reg5 |= (lis3dh->cfg.int2.latch & 1) << 1; ctrl_reg5 |= (lis3dh->cfg.int_pin2.latch & 1) << 1;
/* set INT1_CFG and INT2_CFG */
int1_cfg |= (lis3dh->cfg.int1_cfg.xl);
int1_cfg |= (lis3dh->cfg.int1_cfg.xh) << 1;
int1_cfg |= (lis3dh->cfg.int1_cfg.yl) << 2;
int1_cfg |= (lis3dh->cfg.int1_cfg.yh) << 3;
int1_cfg |= (lis3dh->cfg.int1_cfg.zl) << 4;
int1_cfg |= (lis3dh->cfg.int1_cfg.zh) << 5;
int1_cfg |= (lis3dh->cfg.int1_cfg.det_6d) << 6;
int1_cfg |= (lis3dh->cfg.int1_cfg.aoi) << 7;
int2_cfg |= (lis3dh->cfg.int2_cfg.xl);
int2_cfg |= (lis3dh->cfg.int2_cfg.xh) << 1;
int2_cfg |= (lis3dh->cfg.int2_cfg.yl) << 2;
int2_cfg |= (lis3dh->cfg.int2_cfg.yh) << 3;
int2_cfg |= (lis3dh->cfg.int2_cfg.zl) << 4;
int2_cfg |= (lis3dh->cfg.int2_cfg.zh) << 5;
int2_cfg |= (lis3dh->cfg.int2_cfg.det_6d) << 6;
int2_cfg |= (lis3dh->cfg.int2_cfg.aoi) << 7;
int1_dur = lis3dh->cfg.int1_dur & 0x7F;
int2_dur = lis3dh->cfg.int2_dur & 0x7F;
int1_ths = lis3dh->cfg.int1_ths & 0x7F;
int2_ths = lis3dh->cfg.int2_ths & 0x7F;
/* set enable FIFO */ /* set enable FIFO */
if (lis3dh->cfg.fifo.mode != 0xFF) { if (lis3dh->cfg.fifo.mode != 0xFF) {
ctrl_reg5 |= 0x40; /* bit FIFO_EN */ ctrl_reg5 |= 0x40; /* bit FIFO_EN */
/* restrict maximum fifo size */ /* restrict maximum fifo size */
if (lis3dh->cfg.fifo.fth > 32) { if (lis3dh->cfg.fifo.fth > 31) {
lis3dh->cfg.fifo.fth = 32; lis3dh->cfg.fifo.fth = 31;
} }
fifo_ctrl_reg |= (lis3dh->cfg.fifo.fth); fifo_ctrl_reg |= (lis3dh->cfg.fifo.fth);
@ -154,6 +179,12 @@ int lis3dh_configure(lis3dh_t *lis3dh) {
err |= lis3dh->dev.write(REG_CTRL_REG5, ctrl_reg5); err |= lis3dh->dev.write(REG_CTRL_REG5, ctrl_reg5);
err |= lis3dh->dev.write(REG_CTRL_REG6, ctrl_reg6); err |= lis3dh->dev.write(REG_CTRL_REG6, ctrl_reg6);
err |= lis3dh->dev.write(REG_FIFO_CTRL_REG, fifo_ctrl_reg); 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);
err |= lis3dh->dev.write(REG_INT1_DURATION, int1_dur);
err |= lis3dh->dev.write(REG_INT2_CFG, int2_cfg);
err |= lis3dh->dev.write(REG_INT2_THS, int2_ths);
err |= lis3dh->dev.write(REG_INT2_DURATION, int2_dur);
/* read REFERENCE to clear internal filter struct */ /* read REFERENCE to clear internal filter struct */
err |= lis3dh->dev.read(REG_REFERENCE, &ref, 1); err |= lis3dh->dev.read(REG_REFERENCE, &ref, 1);

View File

@ -4,6 +4,7 @@
#include <stdint.h> #include <stdint.h>
/* rates */ /* rates */
/* all power modes */
#define LIS3DH_ODR_POWEROFF 0x00 #define LIS3DH_ODR_POWEROFF 0x00
#define LIS3DH_ODR_1_HZ 0x01 #define LIS3DH_ODR_1_HZ 0x01
#define LIS3DH_ODR_10_HZ 0x02 #define LIS3DH_ODR_10_HZ 0x02
@ -12,7 +13,9 @@
#define LIS3DH_ODR_100_HZ 0x05 #define LIS3DH_ODR_100_HZ 0x05
#define LIS3DH_ODR_200_HZ 0x06 #define LIS3DH_ODR_200_HZ 0x06
#define LIS3DH_ODR_400_HZ 0x07 #define LIS3DH_ODR_400_HZ 0x07
/* only normal mode */
#define LIS3DH_ODR_NORM_1344_HZ 0x09 #define LIS3DH_ODR_NORM_1344_HZ 0x09
/* only low-power mode */
#define LIS3DH_ODR_LP_1600_HZ 0x08 #define LIS3DH_ODR_LP_1600_HZ 0x08
#define LIS3DH_ODR_LP_5376_HZ 0x09 #define LIS3DH_ODR_LP_5376_HZ 0x09
@ -64,8 +67,20 @@ struct lis3dh_device {
int (*deinit)(void); int (*deinit)(void);
}; };
/* INT1_CFG and INT2_CFG have identical struct */
struct lis3dh_int_config {
uint8_t aoi; /* AND/OR combination of int events */
uint8_t det_6d; /* 6 direction detection */
uint8_t zh; /* interrupt generation on Z high event / Dir. recog. */
uint8_t zl; /* interrupt generation on Z low event / Dir. recog. */
uint8_t yh; /* interrupt generation on Y high event / Dir. recog. */
uint8_t yl; /* interrupt generation on Y low event / Dir. recog. */
uint8_t xh; /* interrupt generation on X high event / Dir. recog. */
uint8_t xl; /* interrupt generation on X low event / Dir. recog. */
};
/* config for INT2 trigger output */ /* config for INT2 trigger output */
struct lis3dh_int2_config { struct lis3dh_int_pin2_config {
uint8_t click; /* CLICK interrupt */ uint8_t click; /* CLICK interrupt */
uint8_t ia1; /* IA1 interrupt */ uint8_t ia1; /* IA1 interrupt */
uint8_t ia2; /* IA2 interrupt */ uint8_t ia2; /* IA2 interrupt */
@ -76,7 +91,7 @@ struct lis3dh_int2_config {
}; };
/* config for INT1 trigger output */ /* config for INT1 trigger output */
struct lis3dh_int1_config { struct lis3dh_int_pin1_config {
uint8_t click; /* CLICK interrupt */ uint8_t click; /* CLICK interrupt */
uint8_t ia1; /* IA1 interrupt */ uint8_t ia1; /* IA1 interrupt */
uint8_t ia2; /* IA2 interrupt */ uint8_t ia2; /* IA2 interrupt */
@ -108,10 +123,27 @@ struct lis3dh_config {
uint8_t rate; /* ODR */ uint8_t rate; /* ODR */
uint8_t range; /* FS */ uint8_t range; /* FS */
uint8_t mode; /* LPen and HR */ uint8_t mode; /* LPen and HR */
struct lis3dh_fifo_config fifo; struct lis3dh_fifo_config fifo;
struct lis3dh_filter_config filter; struct lis3dh_filter_config filter;
struct lis3dh_int1_config int1; struct lis3dh_int_pin1_config int_pin1;
struct lis3dh_int2_config int2; struct lis3dh_int_pin2_config int_pin2;
struct lis3dh_int_config int1_cfg;
struct lis3dh_int_config int2_cfg;
/* 1 LSb = 16 mg @ FS_2G
* 1 LSb = 32 mg @ FS_4G
* 1 LSb = 62 mg @ FS_8G
* 1 LSb = 186 mg @ FS_16G
*/
uint8_t int1_ths; /* 7-bit INT 1 threshold value */
uint8_t int2_ths; /* 7-bit INT 2 threshold value */
/* Duration time is measured in N/ODR where:
* --- N = The content of the intX_dur integer
* --- ODR = the data rate, eg 100, 400...
*/
uint8_t int1_dur; /* 7-bit INT 1 duration value */
uint8_t int2_dur; /* 7-bit INT 2 duration value */
}; };
/* data read not from FIFO is put here */ /* data read not from FIFO is put here */

4
main.c
View File

@ -52,8 +52,8 @@ int main() {
lis.cfg.rate = LIS3DH_ODR_100_HZ; lis.cfg.rate = LIS3DH_ODR_100_HZ;
lis.cfg.fifo.mode = LIS3DH_FIFO_MODE_STREAM; lis.cfg.fifo.mode = LIS3DH_FIFO_MODE_STREAM;
lis.cfg.fifo.trig = LIS3DH_FIFO_TRIG_INT2; lis.cfg.fifo.trig = LIS3DH_FIFO_TRIG_INT2;
lis.cfg.int1.wtm = 1; lis.cfg.int_pin1.wtm = 1;
lis.cfg.int1.latch = 1; lis.cfg.int_pin1.latch = 1;
lis.cfg.filter.mode = LIS3DH_FILTER_MODE_AUTORESET; lis.cfg.filter.mode = LIS3DH_FILTER_MODE_AUTORESET;
lis.cfg.filter.cutoff = LIS3DH_FILTER_CUTOFF_8; lis.cfg.filter.cutoff = LIS3DH_FILTER_CUTOFF_8;