tidying and testing new functions
This commit is contained in:
parent
9c3f912d1a
commit
30508a8378
5
Makefile
5
Makefile
@ -1,7 +1,8 @@
|
||||
CC=gcc
|
||||
CFLAGS=-O2 -std=c89 -W -Werror -Wall -Wextra -pedantic -I.
|
||||
CFLAGS=-O0 -g3 -ggdb -std=c89 -W -Werror -Wall -Wextra -Wpedantic -pedantic-errors -Wformat-signedness -I.
|
||||
CFLAGS+=-Wlogical-op -Wmissing-declarations -Wswitch-default -Wundef -Wformat=2
|
||||
LFLAGS=-lm
|
||||
CFILES=$(wildcard ./*.c)
|
||||
CFILES=$(wildcard *.c)
|
||||
all:
|
||||
$(CC) $(CFLAGS) $(CFILES) -o lis3dh $(LFLAGS)
|
||||
|
||||
|
@ -30,6 +30,8 @@ int deinit(void);
|
||||
```
|
||||
All above functions return `0` on success.
|
||||
|
||||
The `init` and `deinit` pointers can both be set to `NULL` and they won't be run.
|
||||
|
||||
## Usage
|
||||
Simple example:
|
||||
```c
|
||||
@ -146,6 +148,7 @@ x: 0.518000, y: -0.846000, z: -0.100000
|
||||
Instead of polling for every single [x y z] set, a FIFO with programmable capacity ("watermark") can be used like such:
|
||||
|
||||
All FIFO readings use 10-bit resolution regardless of the mode set in `lis.cfg.mode`.
|
||||
|
||||
The watermark level can also be adjusted to a value [0-31] inclusive by modifying the `lis.cfg.fifo.fth` property before calling configure().
|
||||
```c
|
||||
#define _GNU_SOURCE
|
||||
|
97
lis3dh.c
97
lis3dh.c
@ -1,3 +1,5 @@
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include "lis3dh.h"
|
||||
#include "registers.h"
|
||||
|
||||
@ -38,9 +40,12 @@ int lis3dh_init(lis3dh_t *lis3dh) {
|
||||
uint8_t result;
|
||||
int err = 0;
|
||||
|
||||
/* if init has been given, check it */
|
||||
if (lis3dh->dev.init != NULL) {
|
||||
if (lis3dh->dev.init() != 0) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
err |= lis3dh->dev.read(REG_WHO_AM_I, &result, 1);
|
||||
if (result != 0x33) {
|
||||
@ -97,10 +102,10 @@ int lis3dh_configure(lis3dh_t *lis3dh) {
|
||||
int err = 0;
|
||||
|
||||
/* the 0x07 enables Z, Y and X axis in that order */
|
||||
ctrl_reg1 = 0 | (lis3dh->cfg.rate << 4) | 0x07;
|
||||
ctrl_reg1 = (lis3dh->cfg.rate << 4) | 0x07;
|
||||
ctrl_reg2 = 0;
|
||||
ctrl_reg3 = 0;
|
||||
ctrl_reg4 = 0 | (lis3dh->cfg.range << 4);
|
||||
ctrl_reg4 = (lis3dh->cfg.range << 4);
|
||||
ctrl_reg5 = 0;
|
||||
ctrl_reg6 = 0;
|
||||
fifo_ctrl_reg = 0;
|
||||
@ -204,68 +209,27 @@ int lis3dh_poll_fifo(lis3dh_t *lis3dh) {
|
||||
/* the real size of the int you get back from reading the acc u16
|
||||
depends on the power mode.
|
||||
shift down the 16 bit word by this amount: */
|
||||
static uint8_t acc_shift(lis3dh_t *lis3dh) {
|
||||
switch (lis3dh->cfg.mode) {
|
||||
case LIS3DH_MODE_HR:
|
||||
return 4; /* i12 */
|
||||
case LIS3DH_MODE_NORMAL:
|
||||
return 6; /* i10 */
|
||||
case LIS3DH_MODE_LP:
|
||||
return 8; /* i8 */
|
||||
static uint8_t acc_shift(uint8_t mode) {
|
||||
switch (mode) {
|
||||
case LIS3DH_MODE_HR: return 4; /* i12 */
|
||||
case LIS3DH_MODE_NORMAL: return 6; /* i10 */
|
||||
case LIS3DH_MODE_LP: return 8; /* i8 */
|
||||
default: return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* returns a scalar that when multiplied with axis reading
|
||||
turns it to a multiple of mg. */
|
||||
static uint8_t acc_sensitivity(lis3dh_t *lis3dh) {
|
||||
uint8_t mode = lis3dh->cfg.mode;
|
||||
|
||||
switch (lis3dh->cfg.range) {
|
||||
case LIS3DH_FS_2G:
|
||||
if (mode == LIS3DH_MODE_LP) {
|
||||
return 16;
|
||||
} else if (mode == LIS3DH_MODE_NORMAL) {
|
||||
return 4;
|
||||
} else {
|
||||
return 1;
|
||||
static uint8_t acc_sensitivity(uint8_t mode, uint8_t range) {
|
||||
switch (range) {
|
||||
case LIS3DH_FS_2G: return (mode == LIS3DH_MODE_LP) ? 16 : (mode == LIS3DH_MODE_NORMAL) ? 4 : 1;
|
||||
case LIS3DH_FS_4G: return (mode == LIS3DH_MODE_LP) ? 32 : (mode == LIS3DH_MODE_NORMAL) ? 8 : 2;
|
||||
case LIS3DH_FS_8G: return (mode == LIS3DH_MODE_LP) ? 64 : (mode == LIS3DH_MODE_NORMAL) ? 16 : 4;
|
||||
case LIS3DH_FS_16G: return (mode == LIS3DH_MODE_LP) ? 192 : (mode == LIS3DH_MODE_NORMAL) ? 48 : 12;
|
||||
default: return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case LIS3DH_FS_4G:
|
||||
if (mode == LIS3DH_MODE_LP) {
|
||||
return 32;
|
||||
} else if (mode == LIS3DH_MODE_NORMAL) {
|
||||
return 8;
|
||||
} else {
|
||||
return 2;
|
||||
}
|
||||
break;
|
||||
|
||||
case LIS3DH_FS_8G:
|
||||
if (mode == LIS3DH_MODE_LP) {
|
||||
return 64;
|
||||
} else if (mode == LIS3DH_MODE_NORMAL) {
|
||||
return 16;
|
||||
} else {
|
||||
return 4;
|
||||
}
|
||||
break;
|
||||
|
||||
case LIS3DH_FS_16G:
|
||||
if (mode == LIS3DH_MODE_LP) {
|
||||
return 192;
|
||||
} else if (mode == LIS3DH_MODE_NORMAL) {
|
||||
return 48;
|
||||
} else {
|
||||
return 12;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lis3dh_read(lis3dh_t *lis3dh) {
|
||||
uint8_t data[6];
|
||||
@ -273,8 +237,8 @@ int lis3dh_read(lis3dh_t *lis3dh) {
|
||||
uint8_t scale, sens;
|
||||
int err = 0;
|
||||
|
||||
scale = acc_shift(lis3dh);
|
||||
sens = acc_sensitivity(lis3dh);
|
||||
scale = acc_shift(lis3dh->cfg.mode);
|
||||
sens = acc_sensitivity(lis3dh->cfg.mode, lis3dh->cfg.range);
|
||||
|
||||
/* must set MSbit of the address to multi-read and
|
||||
have the device auto-increment the address. */
|
||||
@ -301,17 +265,7 @@ int lis3dh_read_fifo(lis3dh_t *lis3dh, struct lis3dh_fifo_data *fifo) {
|
||||
|
||||
/* FIFO is always 10-bit */
|
||||
scale = 6;
|
||||
|
||||
/* normal mode */
|
||||
if (lis3dh->cfg.range == LIS3DH_FS_2G) {
|
||||
sens = 4;
|
||||
} else if (lis3dh->cfg.range == LIS3DH_FS_4G) {
|
||||
sens = 8;
|
||||
} else if (lis3dh->cfg.range == LIS3DH_FS_8G) {
|
||||
sens = 16;
|
||||
} else { /* 16G */
|
||||
sens = 48;
|
||||
}
|
||||
sens = acc_sensitivity(lis3dh->cfg.mode, lis3dh->cfg.range);
|
||||
|
||||
/* fifo buffer is max 32 */
|
||||
fifo->size = lis3dh->cfg.fifo.fth > 32 ? 32 : lis3dh->cfg.fifo.fth;
|
||||
@ -334,10 +288,15 @@ int lis3dh_read_fifo(lis3dh_t *lis3dh, struct lis3dh_fifo_data *fifo) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* if NULL, this function doesn't have to be called */
|
||||
int lis3dh_deinit(lis3dh_t *lis3dh) {
|
||||
if (lis3dh->dev.deinit != NULL) {
|
||||
return lis3dh->dev.deinit();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* read INT1_SRC to clear latched INT1 irq */
|
||||
int lis3dh_clear_int1(lis3dh_t *lis3dh) {
|
||||
uint8_t res;
|
||||
|
12
main.c
12
main.c
@ -10,12 +10,12 @@
|
||||
#define GPIO_INTERRUPT_PIN 12
|
||||
|
||||
/* calc magnitude of accel [x y z] vector */
|
||||
float mag(float x, float y, float z) {
|
||||
static float mag(float x, float y, float z) {
|
||||
return sqrt( powf(x, 2) + powf(y, 2) + powf(z, 2) );
|
||||
}
|
||||
|
||||
/* print message then exit */
|
||||
void quit(const char *msg, lis3dh_t *lis) {
|
||||
static void quit(const char *msg, lis3dh_t *lis) {
|
||||
lis->dev.deinit();
|
||||
fprintf(stderr, "%s\n", msg);
|
||||
exit(1);
|
||||
@ -25,7 +25,7 @@ int main() {
|
||||
|
||||
lis3dh_t lis;
|
||||
struct lis3dh_fifo_data fifo;
|
||||
int k;
|
||||
int i, k;
|
||||
|
||||
/* set fn ptrs to rw on bus (i2c or SPI) */
|
||||
lis.dev.init = i2c_init;
|
||||
@ -53,6 +53,8 @@ int main() {
|
||||
lis.cfg.fifo.trig = LIS3DH_FIFO_TRIG_INT1;
|
||||
lis.cfg.int1.wtm = 1;
|
||||
lis.cfg.int1.latch = 1;
|
||||
lis.cfg.filter.mode = LIS3DH_FILTER_MODE_REFERENCE;
|
||||
lis.cfg.filter.cutoff = LIS3DH_FILTER_CUTOFF_8;
|
||||
|
||||
|
||||
/* write device config */
|
||||
@ -60,6 +62,7 @@ int main() {
|
||||
quit("configure()", &lis);
|
||||
}
|
||||
|
||||
for(i=0; i<50; i++) {
|
||||
/* wait for interrupt from LIS3DH */
|
||||
if (int_poll(GPIO_INTERRUPT_PIN)) {
|
||||
quit("int_poll()", &lis);
|
||||
@ -80,6 +83,9 @@ int main() {
|
||||
mag(fifo.x[k], fifo.y[k], fifo.z[k]));
|
||||
}
|
||||
|
||||
lis3dh_reference(&lis);
|
||||
}
|
||||
|
||||
/* unregister interrupt */
|
||||
if (int_unregister(GPIO_INTERRUPT_PIN)) {
|
||||
quit("int_unregister()", &lis);
|
||||
|
Loading…
Reference in New Issue
Block a user