tidying and testing new functions
This commit is contained in:
parent
9c3f912d1a
commit
30508a8378
5
Makefile
5
Makefile
@ -1,7 +1,8 @@
|
|||||||
CC=gcc
|
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
|
LFLAGS=-lm
|
||||||
CFILES=$(wildcard ./*.c)
|
CFILES=$(wildcard *.c)
|
||||||
all:
|
all:
|
||||||
$(CC) $(CFLAGS) $(CFILES) -o lis3dh $(LFLAGS)
|
$(CC) $(CFLAGS) $(CFILES) -o lis3dh $(LFLAGS)
|
||||||
|
|
||||||
|
@ -30,6 +30,8 @@ int deinit(void);
|
|||||||
```
|
```
|
||||||
All above functions return `0` on success.
|
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
|
## Usage
|
||||||
Simple example:
|
Simple example:
|
||||||
```c
|
```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:
|
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`.
|
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().
|
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
|
```c
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
|
97
lis3dh.c
97
lis3dh.c
@ -1,3 +1,5 @@
|
|||||||
|
#include <stddef.h>
|
||||||
|
#include <string.h>
|
||||||
#include "lis3dh.h"
|
#include "lis3dh.h"
|
||||||
#include "registers.h"
|
#include "registers.h"
|
||||||
|
|
||||||
@ -38,9 +40,12 @@ int lis3dh_init(lis3dh_t *lis3dh) {
|
|||||||
uint8_t result;
|
uint8_t result;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
|
/* if init has been given, check it */
|
||||||
|
if (lis3dh->dev.init != NULL) {
|
||||||
if (lis3dh->dev.init() != 0) {
|
if (lis3dh->dev.init() != 0) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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) {
|
||||||
@ -97,10 +102,10 @@ int lis3dh_configure(lis3dh_t *lis3dh) {
|
|||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
/* the 0x07 enables Z, Y and X axis in that order */
|
/* 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_reg2 = 0;
|
||||||
ctrl_reg3 = 0;
|
ctrl_reg3 = 0;
|
||||||
ctrl_reg4 = 0 | (lis3dh->cfg.range << 4);
|
ctrl_reg4 = (lis3dh->cfg.range << 4);
|
||||||
ctrl_reg5 = 0;
|
ctrl_reg5 = 0;
|
||||||
ctrl_reg6 = 0;
|
ctrl_reg6 = 0;
|
||||||
fifo_ctrl_reg = 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
|
/* the real size of the int you get back from reading the acc u16
|
||||||
depends on the power mode.
|
depends on the power mode.
|
||||||
shift down the 16 bit word by this amount: */
|
shift down the 16 bit word by this amount: */
|
||||||
static uint8_t acc_shift(lis3dh_t *lis3dh) {
|
static uint8_t acc_shift(uint8_t mode) {
|
||||||
switch (lis3dh->cfg.mode) {
|
switch (mode) {
|
||||||
case LIS3DH_MODE_HR:
|
case LIS3DH_MODE_HR: return 4; /* i12 */
|
||||||
return 4; /* i12 */
|
case LIS3DH_MODE_NORMAL: return 6; /* i10 */
|
||||||
case LIS3DH_MODE_NORMAL:
|
case LIS3DH_MODE_LP: return 8; /* i8 */
|
||||||
return 6; /* i10 */
|
default: return 0;
|
||||||
case LIS3DH_MODE_LP:
|
|
||||||
return 8; /* i8 */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* returns a scalar that when multiplied with axis reading
|
/* returns a scalar that when multiplied with axis reading
|
||||||
turns it to a multiple of mg. */
|
turns it to a multiple of mg. */
|
||||||
static uint8_t acc_sensitivity(lis3dh_t *lis3dh) {
|
static uint8_t acc_sensitivity(uint8_t mode, uint8_t range) {
|
||||||
uint8_t mode = lis3dh->cfg.mode;
|
switch (range) {
|
||||||
|
case LIS3DH_FS_2G: return (mode == LIS3DH_MODE_LP) ? 16 : (mode == LIS3DH_MODE_NORMAL) ? 4 : 1;
|
||||||
switch (lis3dh->cfg.range) {
|
case LIS3DH_FS_4G: return (mode == LIS3DH_MODE_LP) ? 32 : (mode == LIS3DH_MODE_NORMAL) ? 8 : 2;
|
||||||
case LIS3DH_FS_2G:
|
case LIS3DH_FS_8G: return (mode == LIS3DH_MODE_LP) ? 64 : (mode == LIS3DH_MODE_NORMAL) ? 16 : 4;
|
||||||
if (mode == LIS3DH_MODE_LP) {
|
case LIS3DH_FS_16G: return (mode == LIS3DH_MODE_LP) ? 192 : (mode == LIS3DH_MODE_NORMAL) ? 48 : 12;
|
||||||
return 16;
|
default: return 0;
|
||||||
} else if (mode == LIS3DH_MODE_NORMAL) {
|
|
||||||
return 4;
|
|
||||||
} else {
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
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) {
|
int lis3dh_read(lis3dh_t *lis3dh) {
|
||||||
uint8_t data[6];
|
uint8_t data[6];
|
||||||
@ -273,8 +237,8 @@ int lis3dh_read(lis3dh_t *lis3dh) {
|
|||||||
uint8_t scale, sens;
|
uint8_t scale, sens;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
scale = acc_shift(lis3dh);
|
scale = acc_shift(lis3dh->cfg.mode);
|
||||||
sens = acc_sensitivity(lis3dh);
|
sens = acc_sensitivity(lis3dh->cfg.mode, lis3dh->cfg.range);
|
||||||
|
|
||||||
/* must set MSbit of the address to multi-read and
|
/* must set MSbit of the address to multi-read and
|
||||||
have the device auto-increment the address. */
|
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 */
|
/* FIFO is always 10-bit */
|
||||||
scale = 6;
|
scale = 6;
|
||||||
|
sens = acc_sensitivity(lis3dh->cfg.mode, lis3dh->cfg.range);
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* fifo buffer is max 32 */
|
/* fifo buffer is max 32 */
|
||||||
fifo->size = lis3dh->cfg.fifo.fth > 32 ? 32 : lis3dh->cfg.fifo.fth;
|
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;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* if NULL, this function doesn't have to be called */
|
||||||
int lis3dh_deinit(lis3dh_t *lis3dh) {
|
int lis3dh_deinit(lis3dh_t *lis3dh) {
|
||||||
|
if (lis3dh->dev.deinit != NULL) {
|
||||||
return lis3dh->dev.deinit();
|
return lis3dh->dev.deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* read INT1_SRC to clear latched INT1 irq */
|
/* read INT1_SRC to clear latched INT1 irq */
|
||||||
int lis3dh_clear_int1(lis3dh_t *lis3dh) {
|
int lis3dh_clear_int1(lis3dh_t *lis3dh) {
|
||||||
uint8_t res;
|
uint8_t res;
|
||||||
|
12
main.c
12
main.c
@ -10,12 +10,12 @@
|
|||||||
#define GPIO_INTERRUPT_PIN 12
|
#define GPIO_INTERRUPT_PIN 12
|
||||||
|
|
||||||
/* calc magnitude of accel [x y z] vector */
|
/* 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) );
|
return sqrt( powf(x, 2) + powf(y, 2) + powf(z, 2) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* print message then exit */
|
/* print message then exit */
|
||||||
void quit(const char *msg, lis3dh_t *lis) {
|
static void quit(const char *msg, lis3dh_t *lis) {
|
||||||
lis->dev.deinit();
|
lis->dev.deinit();
|
||||||
fprintf(stderr, "%s\n", msg);
|
fprintf(stderr, "%s\n", msg);
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -25,7 +25,7 @@ int main() {
|
|||||||
|
|
||||||
lis3dh_t lis;
|
lis3dh_t lis;
|
||||||
struct lis3dh_fifo_data fifo;
|
struct lis3dh_fifo_data fifo;
|
||||||
int k;
|
int i, k;
|
||||||
|
|
||||||
/* set fn ptrs to rw on bus (i2c or SPI) */
|
/* set fn ptrs to rw on bus (i2c or SPI) */
|
||||||
lis.dev.init = i2c_init;
|
lis.dev.init = i2c_init;
|
||||||
@ -53,6 +53,8 @@ int main() {
|
|||||||
lis.cfg.fifo.trig = LIS3DH_FIFO_TRIG_INT1;
|
lis.cfg.fifo.trig = LIS3DH_FIFO_TRIG_INT1;
|
||||||
lis.cfg.int1.wtm = 1;
|
lis.cfg.int1.wtm = 1;
|
||||||
lis.cfg.int1.latch = 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 */
|
/* write device config */
|
||||||
@ -60,6 +62,7 @@ int main() {
|
|||||||
quit("configure()", &lis);
|
quit("configure()", &lis);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(i=0; i<50; i++) {
|
||||||
/* wait for interrupt from LIS3DH */
|
/* wait for interrupt from LIS3DH */
|
||||||
if (int_poll(GPIO_INTERRUPT_PIN)) {
|
if (int_poll(GPIO_INTERRUPT_PIN)) {
|
||||||
quit("int_poll()", &lis);
|
quit("int_poll()", &lis);
|
||||||
@ -80,6 +83,9 @@ int main() {
|
|||||||
mag(fifo.x[k], fifo.y[k], fifo.z[k]));
|
mag(fifo.x[k], fifo.y[k], fifo.z[k]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lis3dh_reference(&lis);
|
||||||
|
}
|
||||||
|
|
||||||
/* unregister interrupt */
|
/* unregister interrupt */
|
||||||
if (int_unregister(GPIO_INTERRUPT_PIN)) {
|
if (int_unregister(GPIO_INTERRUPT_PIN)) {
|
||||||
quit("int_unregister()", &lis);
|
quit("int_unregister()", &lis);
|
||||||
|
Loading…
Reference in New Issue
Block a user