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/* =============================================================================== */
26 KX134_1211 *accel,
27 char name[DEVICE_NAME_LENGTH],
28 GPIO_TypeDef *port,
29 unsigned long cs,
30 uint8_t scale,
31 const uint8_t *axes,
32 const int8_t *sign
33) {
34 SPI_init(&accel->base, SENSOR_ACCEL, SPI1, MODE8, port, cs);
39 memcpy(accel->axes, axes, KX134_1211_DATA_COUNT);
40 memcpy(accel->sign, sign, KX134_1211_DATA_COUNT);
41
42 // Set value of GSEL and sensitivity based on selected scale
43 uint8_t GSEL = 0x00;
44 if (scale == 32) {
45 GSEL = KX134_1211_CNTL1_GSEL(32);
46 accel->sensitivity = KX134_1211_SENSITIVITY(32);
47 } else if (scale == 16) {
48 GSEL = KX134_1211_CNTL1_GSEL(16);
49 accel->sensitivity = KX134_1211_SENSITIVITY(16);
50 }
51
52 // Perform powerup procedure as per datasheet
53 KX134_1211_writeRegister(accel, 0x7F, 0x00);
54 KX134_1211_writeRegister(accel, 0x1C, 0x00);
55 KX134_1211_writeRegister(accel, 0x1C, 0x80);
56
57 const uint32_t superDelay = 0xFFFF;
58 volatile uint8_t counter = 0;
59
60 // Wait for the spefified period - need to wait for 2ms here.
61 for (uint32_t i = 0; i < superDelay; i++) {
62 counter++;
63 }
64
65 uint8_t chipID = KX134_1211_readRegister(accel, 0x13);
66 uint8_t cotr = KX134_1211_readRegister(accel, 0x12);
67
68 // Configure accelerometer registers
69 KX134_1211_writeRegister(accel, KX134_1211_CNTL1, KX134_1211_CNTL1_RES | GSEL); // Accel select, selected sensitivity
70 uint8_t ODCNTL = KX134_1211_readRegister(accel, KX134_1211_ODCNTL); // Read from register for reserve mask
71 KX134_1211_writeRegister(accel, KX134_1211_ODCNTL, (KX134_1211_ODCNTL_RESERVED & ODCNTL) | 0x2A); // No filter, fast startup, 800Hz
72 KX134_1211_writeRegister(accel, KX134_1211_CNTL1, KX134_1211_CNTL1_PC1 | KX134_1211_CNTL1_RES | GSEL); // Enable PC1
73
74 DeviceHandle_t handle;
75 strcpy(handle.name, name);
76 handle.device = accel;
77 return handle;
78}
79
80/********************************** DEVICE METHODS *********************************/
81
82/* =============================================================================== */
91void KX134_1211_readAccel(KX134_1211 *accel, float *out) {
92 accel->update(accel);
93 out = accel->accelData;
94}
95
96/* =============================================================================== */
105 accel->readRawBytes(accel, accel->rawAccelData);
106 accel->processRawBytes(accel, accel->rawAccelData, accel->accelData);
107}
108
109/* =============================================================================== */
119void KX134_1211_processRawBytes(KX134_1211 *accel, uint8_t *bytes, float *out) {
120 out[0] = accel->sign[0] * accel->sensitivity * (int16_t)(((uint16_t)bytes[0] << 8) | bytes[1]); // Accel X
121 out[1] = accel->sign[1] * accel->sensitivity * (int16_t)(((uint16_t)bytes[2] << 8) | bytes[3]); // Accel Y
122 out[2] = accel->sign[2] * accel->sensitivity * (int16_t)(((uint16_t)bytes[4] << 8) | bytes[5]); // Accel Z
123}
124
125/* =============================================================================== */
134void KX134_1211_readRawBytes(KX134_1211 *accel, uint8_t *out) {
135// Map raw indices to mounting axis
136#define INDEX_AXES(index, byte) 2 * accel->axes[index] + byte
137 uint8_t tmp[KX134_1211_DATA_TOTAL];
138 KX134_1211_readRegisters(accel, KX134_1211_XOUT_L, KX134_1211_DATA_TOTAL, tmp);
139 out[INDEX_AXES(0, 1)] = tmp[0]; // Accel X high
140 out[INDEX_AXES(0, 0)] = tmp[1]; // Accel X low
141 out[INDEX_AXES(1, 1)] = tmp[2]; // Accel Y high
142 out[INDEX_AXES(1, 0)] = tmp[3]; // Accel Y low
143 out[INDEX_AXES(2, 1)] = tmp[4]; // Accel Z high
144 out[INDEX_AXES(2, 0)] = tmp[5]; // Accel Z low
145#undef INDEX_AXES
146}
147
148/******************************** INTERFACE METHODS ********************************/
149
150void KX134_1211_writeRegister(KX134_1211 *accel, uint8_t address, uint8_t data) {
151 SPI spi = accel->base;
152
153 spi.port->ODR &= ~spi.cs;
154
155 while ((spi.interface->SR & SPI_SR_TXE) == 0);
156 spi.interface->DR = (address & 0x7F); // Send out the device address
157 while ((spi.interface->SR & SPI_SR_RXNE) == 0); // Wait for the recieve to become available.
158 uint8_t response = spi.interface->DR; // Read the dummy response.
159 while ((spi.interface->SR & SPI_SR_TXE) == 0); // Wait for the SPI bus to become ready.
160 spi.interface->DR = data; // Send out the device address
161 while ((spi.interface->SR & SPI_SR_RXNE) == 0); // Wait for the recieve to become available.
162 response = spi.interface->DR; // Read the dummy response.
163 while ((spi.interface->SR & SPI_SR_BSY) == SPI_SR_BSY); // Wait for the peripheral to finsh.
164
165 spi.port->ODR |= spi.cs;
166}
167
168uint8_t KX134_1211_readRegister(KX134_1211 *accel, uint8_t address) {
169 uint8_t response = 0;
170 SPI spi = accel->base;
171
172 spi.port->ODR &= ~spi.cs;
173
174 // Send read command and address
175 uint8_t payload = address | 0x80; // Load payload with address and read command
176 response = spi.transmit(&spi, payload); // Transmit payload
177 response = spi.transmit(&spi, 0xFF); // Transmit dummy data and read response data
178
179 spi.port->ODR |= spi.cs;
180
181 return response;
182}
183
184void KX134_1211_readRegisters(KX134_1211 *accel, uint8_t address, uint8_t count, uint8_t *out) {
185 SPI spi = accel->base;
186
187 spi.port->ODR &= ~spi.cs; // Manually drop the chip select.
188
189 while ((spi.interface->SR & SPI_SR_TXE) == 0); // Wait for the SPI bus to become ready.
190 spi.interface->DR = (address | 0x80); // Send out the device address
191 while ((spi.interface->SR & SPI_SR_RXNE) == 0); // Wait for the recieve to become available.
192 uint8_t response = spi.interface->DR; // Read the dummy response.
193
194 for (int i = 0; i < count; i++) {
195 while ((spi.interface->SR & SPI_SR_TXE) == 0); // Wait for the SPI bus to become ready.
196 spi.interface->DR = 0xFF; // Send out the dummy data
197 while ((spi.interface->SR & SPI_SR_RXNE) == 0); // Wait for the recieve to become available.
198 out[i] = spi.interface->DR; // Read the dummy response.
199 }
200
201 while ((spi.interface->SR & SPI_SR_BSY) == SPI_SR_BSY); // Wait for the peripheral to finsh.
202 spi.port->ODR |= spi.cs; // Raise chip select
203}
204
void KX134_1211_readAccel(KX134_1211 *, float *)
Read 3-axis floating point accelerations.
Definition kx134_1211.c:91
void KX134_1211_processRawBytes(KX134_1211 *, uint8_t *, float *)
Process raw 3-axis data to floating point accelerations.
Definition kx134_1211.c:119
void KX134_1211_readRawBytes(KX134_1211 *, uint8_t *)
Read raw 3-axis data.
Definition kx134_1211.c:134
void KX134_1211_update(KX134_1211 *)
Updates internally stored acceleration readings.
Definition kx134_1211.c:104
DeviceHandle_t KX134_1211_init(KX134_1211 *accel, char name[DEVICE_NAME_LENGTH], GPIO_TypeDef *port, unsigned long cs, uint8_t scale, const uint8_t *axes, const int8_t *sign)
Initialiser for a KX134-1211 accelerometer.
Definition kx134_1211.c:25
void SPI_init(SPI *, DeviceType, SPI_TypeDef *, DataFormat, GPIO_TypeDef *, unsigned long)
Initialiser for an SPI device interface.
Definition spi.c:32
@ SENSOR_ACCEL
Accelerometer.
Definition spi.h:29
uint8_t axes[KX134_1211_DATA_COUNT]
Array defining axes of mounting.
Definition kx134_1211.h:60
void(* update)(struct KX134_1211 *)
Accel update method.
Definition kx134_1211.h:56
SPI base
Parent SPI interface.
Definition kx134_1211.h:54
void(* processRawBytes)(struct KX134_1211 *, uint8_t *, float *)
Process raw accel method.
Definition kx134_1211.h:59
void(* readRawBytes)(struct KX134_1211 *, uint8_t *)
Raw accel read method.
Definition kx134_1211.h:58
float accelData[KX134_1211_DATA_COUNT]
Processed accelerations array.
Definition kx134_1211.h:63
uint8_t rawAccelData[KX134_1211_DATA_TOTAL]
Raw accelerations array.
Definition kx134_1211.h:62
int8_t sign[KX134_1211_DATA_COUNT]
Array defining sign of axes.
Definition kx134_1211.h:61
float sensitivity
Accelerometer sensitivity.
Definition kx134_1211.h:55
void(* readAccel)(struct KX134_1211 *, float *)
Accel read method.
Definition kx134_1211.h:57
Struct definition for SPI interface. Provides the interface for API consumers to interact with the SP...
Definition spi.h:49
uint16_t(* transmit)(struct SPI *, uint16_t)
SPI transmit method.
Definition spi.h:56
GPIO_TypeDef * port
Pointer to GPIO port struct.
Definition spi.h:52
unsigned long cs
Device chip select address.
Definition spi.h:53
SPI_TypeDef * interface
Pointer to SPI interface struct.
Definition spi.h:51