Loading...
Searching...
No Matches
kx134_1211.c
1/***********************************************************************************
2 * @file KX134_1211.c *
3 * @author Matt Ricci *
4 * @addtogroup KX134_1211 *
5 * *
6 * @todo Move private interface methods (read/write register) to static functions *
7 * with internal prototypes. *
8 * @{ *
9 ***********************************************************************************/
10
11#include "kx134_1211.h"
12
13#include "string.h"
14
15/* =============================================================================== */
28 KX134_1211_t *accel,
29 SPI_t *spi,
30 GPIOpin_t cs,
31 uint8_t scale,
32 const uint8_t *axes,
33 const int8_t *sign
34) {
35 accel->base = spi;
36 accel->cs = cs;
41 memcpy(accel->axes, axes, KX134_1211_DATA_COUNT);
42 memcpy(accel->sign, sign, KX134_1211_DATA_COUNT);
43
44 // Set value of GSEL and sensitivity based on selected scale
45 uint8_t GSEL = 0x00;
46 if (scale == 32) {
47 GSEL = KX134_1211_CNTL1_GSEL(32);
48 accel->sensitivity = KX134_1211_SENSITIVITY(32);
49 } else if (scale == 16) {
50 GSEL = KX134_1211_CNTL1_GSEL(16);
51 accel->sensitivity = KX134_1211_SENSITIVITY(16);
52 }
53
54 // Perform software reset as per datasheet
55 KX134_1211_writeRegister(accel, 0x7F, 0x00);
56 KX134_1211_writeRegister(accel, 0x1C, 0x00);
57 KX134_1211_writeRegister(accel, 0x1C, 0x80);
58
59 // Wait for the spefified period - need to wait for 2ms here.
60 for (uint32_t i = 0; i < 0xFFFF; i++);
61
62 // Make sure reset was successful - must add real checks here
63 // @TODO: add in error checking
64 uint8_t chipID = KX134_1211_readRegister(accel, 0x13);
65 uint8_t cotr = KX134_1211_readRegister(accel, 0x12);
66
67 // Configure accelerometer registers
68 KX134_1211_writeRegister(accel, KX134_1211_CNTL1, KX134_1211_CNTL1_RES | GSEL); // Accel select, selected sensitivity
69 uint8_t ODCNTL = KX134_1211_readRegister(accel, KX134_1211_ODCNTL); // Read from register for reserve mask
70 KX134_1211_writeRegister(accel, KX134_1211_ODCNTL, (KX134_1211_ODCNTL_RESERVED & ODCNTL) | 0x2A); // No filter, fast startup, 800Hz
71 KX134_1211_writeRegister(accel, KX134_1211_CNTL1, KX134_1211_CNTL1_PC1 | KX134_1211_CNTL1_RES | GSEL); // Enable PC1
72
73 return *accel;
74}
75
76/********************************** DEVICE METHODS *********************************/
77
78/* =============================================================================== */
87void KX134_1211_readAccel(KX134_1211_t *accel, float *out) {
88 accel->update(accel);
89 out = accel->accelData;
90}
91
92/* =============================================================================== */
101 accel->readRawBytes(accel, accel->rawAccelData);
102 accel->processRawBytes(accel, accel->rawAccelData, accel->accelData);
103}
104
105/* =============================================================================== */
115void KX134_1211_processRawBytes(KX134_1211_t *accel, uint8_t *bytes, float *out) {
116 out[0] = accel->sign[0] * accel->sensitivity * (int16_t)(((uint16_t)bytes[0] << 8) | bytes[1]); // Accel X
117 out[1] = accel->sign[1] * accel->sensitivity * (int16_t)(((uint16_t)bytes[2] << 8) | bytes[3]); // Accel Y
118 out[2] = accel->sign[2] * accel->sensitivity * (int16_t)(((uint16_t)bytes[4] << 8) | bytes[5]); // Accel Z
119}
120
121/* =============================================================================== */
130void KX134_1211_readRawBytes(KX134_1211_t *accel, uint8_t *out) {
131 // Map raw indices to mounting axis
132#define INDEX_AXES(index, byte) 2 * accel->axes[index] + byte
133 uint8_t tmp[KX134_1211_DATA_TOTAL];
134 KX134_1211_readRegisters(accel, KX134_1211_XOUT_L, KX134_1211_DATA_TOTAL, tmp);
135 out[INDEX_AXES(0, 1)] = tmp[0]; // Accel X high
136 out[INDEX_AXES(0, 0)] = tmp[1]; // Accel X low
137 out[INDEX_AXES(1, 1)] = tmp[2]; // Accel Y high
138 out[INDEX_AXES(1, 0)] = tmp[3]; // Accel Y low
139 out[INDEX_AXES(2, 1)] = tmp[4]; // Accel Z high
140 out[INDEX_AXES(2, 0)] = tmp[5]; // Accel Z low
141#undef INDEX_AXES
142}
143
144/******************************** INTERFACE METHODS ********************************/
145
146void KX134_1211_writeRegister(KX134_1211_t *accel, uint8_t address, uint8_t data) {
147 SPI_t *spi = accel->base;
148 GPIOpin_t cs = accel->cs;
149
150 // Pull CS low
151 cs.reset(&cs);
152
153 // Send read command and address
154 uint8_t payload = address & 0x7F; // Load payload with address and write command
155 spi->transmit(spi, payload); // Transmit payload
156 spi->transmit(spi, data); // Transmit write data
157
158 // Set CS high
159 cs.set(&cs);
160}
161
162uint8_t KX134_1211_readRegister(KX134_1211_t *accel, uint8_t address) {
163 uint8_t response = 0;
164 SPI_t *spi = accel->base;
165 GPIOpin_t cs = accel->cs;
166
167 // Pull CS low
168 cs.reset(&cs);
169
170 // Send read command and address
171 uint8_t payload = address | 0x80; // Load payload with address and read command
172 response = spi->transmit(spi, payload); // Transmit payload
173 response = spi->transmit(spi, 0xFF); // Transmit dummy data and read response data
174
175 // Set CS high
176 cs.set(&cs);
177
178 return response;
179}
180
181void KX134_1211_readRegisters(KX134_1211_t *accel, uint8_t address, uint8_t count, uint8_t *out) {
182 SPI_t *spi = accel->base;
183 GPIOpin_t cs = accel->cs;
184
185 // Pull CS low
186 cs.reset(&cs);
187
188 // Send read command and address
189 uint8_t payload = address | 0x80; // Load payload with address and read command
190 spi->transmit(spi, payload); // Transmit payload
191
192 // Auto increment read through registers
193 for (uint8_t i = 0; i < count; i++) {
194 out[i] = spi->transmit(spi, 0xFF);
195 }
196
197 // Set CS high
198 cs.set(&cs);
199}
200
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
void KX134_1211_processRawBytes(KX134_1211_t *, uint8_t *, float *)
Process raw 3-axis data to floating point accelerations.
Definition kx134_1211.c:115
void KX134_1211_readAccel(KX134_1211_t *, float *)
Read 3-axis floating point accelerations.
Definition kx134_1211.c:87
void KX134_1211_update(KX134_1211_t *)
Updates internally stored acceleration readings.
Definition kx134_1211.c:100
void KX134_1211_readRawBytes(KX134_1211_t *, uint8_t *)
Read raw 3-axis data.
Definition kx134_1211.c:130
KX134_1211_t KX134_1211_init(KX134_1211_t *accel, SPI_t *spi, GPIOpin_t cs, uint8_t scale, const uint8_t *axes, const int8_t *sign)
Initialiser for a KX134-1211 accelerometer.
Definition kx134_1211.c:27
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 axes[KX134_1211_DATA_COUNT]
Array defining axes of mounting.
Definition kx134_1211.h:58
void(* update)(struct KX134_1211 *)
Accel update method.
Definition kx134_1211.h:54
GPIOpin_t cs
Chip select GPIO.
Definition kx134_1211.h:52
void(* processRawBytes)(struct KX134_1211 *, uint8_t *, float *)
Process raw accel method.
Definition kx134_1211.h:57
void(* readRawBytes)(struct KX134_1211 *, uint8_t *)
Raw accel read method.
Definition kx134_1211.h:56
SPI_t * base
Parent SPI interface.
Definition kx134_1211.h:51
float accelData[KX134_1211_DATA_COUNT]
Processed accelerations array.
Definition kx134_1211.h:61
uint8_t rawAccelData[KX134_1211_DATA_TOTAL]
Raw accelerations array.
Definition kx134_1211.h:60
int8_t sign[KX134_1211_DATA_COUNT]
Array defining sign of axes.
Definition kx134_1211.h:59
float sensitivity
Accelerometer sensitivity.
Definition kx134_1211.h:53
void(* readAccel)(struct KX134_1211 *, float *)
Accel read method.
Definition kx134_1211.h:55