tidying and testing new functions

This commit is contained in:
William Clark 2023-12-29 23:24:15 +00:00
parent 9c3f912d1a
commit 30508a8378
4 changed files with 62 additions and 93 deletions

View File

@ -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)

View File

@ -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

View File

@ -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
View File

@ -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);