Loading...
Searching...
No Matches
ais3624dq.c
1/***********************************************************************************
2 * @file ais3624dq.c *
3 * @author Matt Ricci *
4 * @addtogroup AIS3624DQ *
5 * @{ *
6 ***********************************************************************************/
7
8#include "ais3624dq.h"
9
10#include "string.h"
11
12static void AIS3624DQ_readRegisters(AIS3624DQ_t *, uint8_t, uint8_t, uint8_t *);
13static uint8_t AIS3624DQ_readRegister(AIS3624DQ_t *, uint8_t);
14static void AIS3624DQ_writeRegister(AIS3624DQ_t *, uint8_t, uint8_t);
15
16/* =============================================================================== */
28// TODO: Replace 'scale' uint8_t argument with device specific enum typedef
30 AIS3624DQ_t *accel,
31 SPI_t *spi,
32 GPIOpin_t cs,
33 uint8_t scale,
34 const uint8_t *axes,
35 const int8_t *sign
36) {
37 accel->spi = spi;
38 accel->cs = cs;
39 accel->base.dataSize = AIS3624DQ_DATA_TOTAL;
44 accel->base.axes = accel->axes;
45 accel->base.sign = accel->sign;
46 accel->base.accelData = accel->accelData;
47 accel->base.rawAccelData = accel->rawAccelData;
48 memcpy(accel->base.axes, axes, AIS3624DQ_DATA_COUNT);
49 memcpy(accel->base.sign, sign, AIS3624DQ_DATA_COUNT);
50
51 uint8_t FS = 0x00;
52 if (scale == 24) {
53 // 24G scale
54 FS = AIS3624DQ_CTRL_REG4_FS(24);
55 accel->base.sensitivity = AIS3624DQ_SENSITIVITY(24);
56 } else if (scale == 12) {
57 // 12G scale
58 FS = AIS3624DQ_CTRL_REG4_FS(12);
59 accel->base.sensitivity = AIS3624DQ_SENSITIVITY(12);
60 } else if (scale == 6) {
61 // 6G scale
62 FS = AIS3624DQ_CTRL_REG4_FS(6);
63 accel->base.sensitivity = AIS3624DQ_SENSITIVITY(6);
64 }
65
66 AIS3624DQ_writeRegister(
67 accel,
68 AIS3624DQ_CTRL_REG1,
69 (AIS3624DQ_CTRL_REG1_DR_1000 // 1kHz datarate
70 | AIS3624DQ_CTRL_REG1_PM_NORMAL // Power mode normal
71 | AIS3624DQ_CTRL_REG1_XEN // Enable x-axis measurement
72 | AIS3624DQ_CTRL_REG1_YEN // Enable y-axis measurement
73 | AIS3624DQ_CTRL_REG1_ZEN) // Enable z-axis measurement
74 );
75
76 // Set scale, enable block data updates
77 AIS3624DQ_writeRegister(accel, AIS3624DQ_CTRL_REG4, FS | AIS3624DQ_CTRL_REG4_BDU);
78
79 return *accel;
80}
81
82/********************************** DEVICE METHODS *********************************/
83
84/* =============================================================================== */
93void AIS3624DQ_readAccel(Accel_t *accel, float *out) {
94 accel->update(accel);
95 out = accel->accelData;
96}
97
98/* =============================================================================== */
107 accel->readRawBytes(accel, accel->rawAccelData);
108 accel->processRawBytes(accel, accel->rawAccelData, accel->accelData);
109}
110
111/* =============================================================================== */
121void AIS3624DQ_processRawBytes(Accel_t *accel, uint8_t *bytes, float *out) {
122 //
123 out[0] = accel->sign[0] * accel->sensitivity * (int16_t)(((uint16_t)bytes[0] << 8) | bytes[1]); // Accel X
124 out[1] = accel->sign[1] * accel->sensitivity * (int16_t)(((uint16_t)bytes[2] << 8) | bytes[3]); // Accel Y
125 out[2] = accel->sign[2] * accel->sensitivity * (int16_t)(((uint16_t)bytes[4] << 8) | bytes[5]); // Accel Z
126}
127
128/* =============================================================================== */
137void AIS3624DQ_readRawBytes(Accel_t *accel, uint8_t *out) {
138 // Map raw indices to mounting axis
139#define INDEX_AXES(index, byte) 2 * accel->axes[index] + byte
140 uint8_t tmp[AIS3624DQ_DATA_TOTAL];
141 AIS3624DQ_readRegisters((AIS3624DQ_t *)accel, AIS3624DQ_XOUT_L, AIS3624DQ_DATA_TOTAL, tmp);
142 out[INDEX_AXES(0, 1)] = tmp[0]; // Accel X high
143 out[INDEX_AXES(0, 0)] = tmp[1]; // Accel X low
144 out[INDEX_AXES(1, 1)] = tmp[2]; // Accel Y high
145 out[INDEX_AXES(1, 0)] = tmp[3]; // Accel Y low
146 out[INDEX_AXES(2, 1)] = tmp[4]; // Accel Z high
147 out[INDEX_AXES(2, 0)] = tmp[5]; // Accel Z low
148#undef INDEX_AXES
149}
150
151/******************************** INTERFACE METHODS ********************************/
152
153void AIS3624DQ_writeRegister(AIS3624DQ_t *accel, uint8_t address, uint8_t data) {
154 SPI_t *spi = accel->spi;
155 GPIOpin_t cs = accel->cs;
156
157 // Pull CS low
158 cs.reset(&cs);
159
160 // Send read command and address
161 uint8_t payload = address & 0x7F; // Load payload with address and write command
162 spi->transmit(spi, payload); // Transmit payload
163 spi->transmit(spi, data); // Transmit write data
164
165 // Set CS high
166 cs.set(&cs);
167}
168
169uint8_t AIS3624DQ_readRegister(AIS3624DQ_t *accel, uint8_t address) {
170 uint8_t response = 0;
171 SPI_t *spi = accel->spi;
172 GPIOpin_t cs = accel->cs;
173
174 // Pull CS low
175 cs.reset(&cs);
176
177 // Send read command and address
178 uint8_t payload = address | 0x80; // Load payload with address and read command
179 response = spi->transmit(spi, payload); // Transmit payload
180 response = spi->transmit(spi, 0xFF); // Transmit dummy data and read response data
181
182 // Set CS high
183 cs.set(&cs);
184
185 return response;
186}
187
188void AIS3624DQ_readRegisters(AIS3624DQ_t *accel, uint8_t address, uint8_t count, uint8_t *out) {
189 SPI_t *spi = accel->spi;
190 GPIOpin_t cs = accel->cs;
191
192 // Pull CS low
193 cs.reset(&cs);
194
195 // Send read command and address
196 uint8_t payload = address | 0xC0; // Load payload with address, MS and read command
197 spi->transmit(spi, payload); // Transmit payload
198
199 // Auto increment read through registers
200 for (uint8_t i = 0; i < count; i++) {
201 out[i] = spi->transmit(spi, 0xFF);
202 }
203
204 // Set CS high
205 cs.set(&cs);
206}
207
AIS3624DQ_t AIS3624DQ_init(AIS3624DQ_t *accel, SPI_t *spi, GPIOpin_t cs, uint8_t scale, const uint8_t *axes, const int8_t *sign)
Initialiser for a AIS3624DQ accelerometer.
Definition ais3624dq.c:29
void AIS3624DQ_readRawBytes(Accel_t *, uint8_t *)
Read raw 3-axis data.
Definition ais3624dq.c:137
void AIS3624DQ_processRawBytes(Accel_t *, uint8_t *, float *)
Process raw 3-axis data to floating point accelerations.
Definition ais3624dq.c:121
void AIS3624DQ_update(Accel_t *)
Updates internally stored acceleration readings.
Definition ais3624dq.c:106
void AIS3624DQ_readAccel(Accel_t *, float *)
Read 3-axis floating point accelerations.
Definition ais3624dq.c:93
void(* processRawBytes)(struct Accel *accel, uint8_t *bytes, float *out)
Pointer to processRawBytes method.
uint8_t * rawAccelData
Pointer to driver defined raw data array.
void(* update)(struct Accel *accel)
Pointer to update method.
void(* readAccel)(struct Accel *accel, float *out)
Pointer to readAccel method.
float * accelData
Pointer to driver defined data array.
uint8_t * axes
Pointer to driver defined axes.
int8_t * sign
Pointer to driver defined signs.
void(* readRawBytes)(struct Accel *accel, uint8_t *out)
Pointer to readRawBytes method.
uint8_t dataSize
Total data size.
void(* set)(struct GPIOpin *)
Definition gpiopin.h:155
void(* reset)(struct GPIOpin *)
Definition gpiopin.h:156
Struct definition for a GPIO pin.
Definition gpiopin.h:151
uint16_t(* transmit)(struct SPI *, uint16_t)
SPI transmit method.
Definition spi.h:139
Struct definition for SPI interface. Provides the interface for API consumers to interact with the SP...
Definition spi.h:134
uint8_t rawAccelData[AIS3624DQ_DATA_TOTAL]
Raw accelerations array.
Definition ais3624dq.h:70
uint8_t axes[AIS3624DQ_DATA_COUNT]
Array defining axes of mounting.
Definition ais3624dq.h:68
GPIOpin_t cs
Chip select GPIO.
Definition ais3624dq.h:66
float accelData[AIS3624DQ_DATA_COUNT]
Processed accelerations array.
Definition ais3624dq.h:71
Accel_t base
Base accelerometer API.
Definition ais3624dq.h:64
int8_t sign[AIS3624DQ_DATA_COUNT]
Array defining sign of axes.
Definition ais3624dq.h:69
SPI_t * spi
Parent SPI interface.
Definition ais3624dq.h:65