From 70dd2c9a1ba146744d65626b601cb3ff3864eecb Mon Sep 17 00:00:00 2001 From: William Clark Date: Sun, 31 Dec 2023 15:24:40 +0000 Subject: [PATCH] ADC --- lis3dh.c | 31 +++++++++++++++++++++++++++++-- lis3dh.h | 24 +++++++++++++++++++++--- main.c | 17 ++++++++++++----- 3 files changed, 62 insertions(+), 10 deletions(-) diff --git a/lis3dh.c b/lis3dh.c index 902ed8a..94c2fb6 100644 --- a/lis3dh.c +++ b/lis3dh.c @@ -24,6 +24,7 @@ int lis3dh_init(lis3dh_t *lis3dh) { /* zero device struct */ memset(&lis3dh->acc, 0, sizeof lis3dh->acc); memset(&lis3dh->cfg, 0, sizeof lis3dh->cfg); + memset(&lis3dh->adc, 0, sizeof lis3dh->adc); lis3dh->cfg.fifo.mode = 0xFF; /* in use if neq 0xFF */ lis3dh->cfg.fifo.fth = 31; /* default watermark level. */ @@ -305,8 +306,8 @@ int lis3dh_read_fifo(lis3dh_t *lis3dh, struct lis3dh_fifo_data *fifo) { scale = 6; 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; + /* fifo buffer is max 31 */ + fifo->size = lis3dh->cfg.fifo.fth > 31 ? 31 : lis3dh->cfg.fifo.fth; /* must set MSbit of the address to multi-read and have the device auto-increment the address. @@ -353,6 +354,7 @@ int lis3dh_reference(lis3dh_t *lis3dh) { uint8_t res; return lis3dh->dev.read(REG_REFERENCE, &res, 1); } + /* reset user regs and reload trim params */ int lis3dh_reset(lis3dh_t *lis3dh) { int err = 0; @@ -383,5 +385,30 @@ int lis3dh_reset(lis3dh_t *lis3dh) { err |= lis3dh->dev.write(REG_ACT_THS, 0x00); err |= lis3dh->dev.write(REG_ACT_DUR, 0x00); + return err; +} + +/* read all 3 ADCs and convert readings depending on power mode + st 1 LSb is equal to 1 millivolt */ +int lis3dh_read_adc(lis3dh_t *lis3dh) { + uint8_t data[6]; + int err = 0; + uint8_t shift; + float divisor; + /* read adc{1,2,3} LSB and MSB */ + err |= lis3dh->dev.read(REG_OUT_ADC1_L | 0x80, data, 6); + + if (lis3dh->cfg.mode == LIS3DH_MODE_LP) { + shift = 8; + divisor = 256.0; + } else { + shift = 6; + divisor = 1024.0; + } + + lis3dh->adc.adc1 = 1200.0 + (400.0 * (float)(((int16_t)(data[1] | (data[0] << 8))) >> shift) / divisor); + lis3dh->adc.adc2 = 1200.0 + (400.0 * (float)(((int16_t)(data[3] | (data[2] << 8))) >> shift) / divisor); + lis3dh->adc.adc3 = 1200.0 + (400.0 * (float)(((int16_t)(data[5] | (data[4] << 8))) >> shift) / divisor); + return err; } \ No newline at end of file diff --git a/lis3dh.h b/lis3dh.h index 172ad9f..e0a1b17 100644 --- a/lis3dh.h +++ b/lis3dh.h @@ -173,8 +173,24 @@ struct lis3dh_config { uint8_t en_temp; /* enable temp sensor on ADC 3 */ }; -/* data read not from FIFO is put here */ -struct lis3dh_acceleration { +/* reads from internal ADCs. + * Input range: 800 mV to 1600 mV + * Resolution: + * 8-bit in LP mode + * 10-bit in normal and in HR mode. + * Sampling frequency: + * same as ODR + * Output: + * actual value in mV + */ +struct lis3dh_adc { + float adc1; + float adc2; + float adc3; +}; + +/* accel data not read from FIFO is put here */ +struct lis3dh_accel { float x; float y; float z; @@ -183,7 +199,8 @@ struct lis3dh_acceleration { struct lis3dh { struct lis3dh_device dev; struct lis3dh_config cfg; - struct lis3dh_acceleration acc; + struct lis3dh_accel acc; + struct lis3dh_adc adc; }; typedef struct lis3dh lis3dh_t; @@ -207,5 +224,6 @@ int lis3dh_clear_int1(lis3dh_t *lis3dh); int lis3dh_clear_int2(lis3dh_t *lis3dh); int lis3dh_reference(lis3dh_t *lis3dh); int lis3dh_reset(lis3dh_t *lis3dh); +int lis3dh_read_adc(lis3dh_t *lis3dh); #endif \ No newline at end of file diff --git a/main.c b/main.c index 9a6793a..e297b7a 100644 --- a/main.c +++ b/main.c @@ -35,7 +35,6 @@ int main() { lis.dev.sleep = usleep; lis.dev.deinit = i2c_deinit; - /* initialise LIS3DH struct */ if (lis3dh_init(&lis)) { quit("init()", &lis); @@ -61,19 +60,21 @@ int main() { lis.cfg.pin1.latch = 1; lis.cfg.filter.mode = LIS3DH_FILTER_MODE_AUTORESET; lis.cfg.filter.cutoff = LIS3DH_FILTER_CUTOFF_8; - + lis.cfg.en_adc = 1; + /* write device config */ if (lis3dh_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_INT1)) { quit("int_poll()", &lis); } + /* clear latched interrupt on INT1 */ if (lis3dh_clear_int1(&lis)) { quit("clear_int1()", &lis); } @@ -83,10 +84,16 @@ int main() { quit("read_fifo()", &lis); } + /* read ADCs */ + if (lis3dh_read_adc(&lis)) { + quit("read_adc()", &lis); + } + for(k=0; k