Loading...
Searching...
No Matches
iam_20380.c
1/***********************************************************************************
2 * @file iam_20380.c *
3 * @author Matt Ricci *
4 * @addtogroup IAM_20380 *
5 * @{ *
6 ***********************************************************************************/
7
8#include "iam_20380.h"
9
10#include "string.h"
11
12static uint8_t IAM_20380_readRegister(IAM_20380_t *, uint8_t);
13static void IAM_20380_writeRegister(IAM_20380_t *, uint8_t, uint8_t);
14
15/* =============================================================================== */
28 IAM_20380_t *gyro,
29 SPI_t *spi,
30 GPIOpin_t cs,
31 float sensitivity,
32 const uint8_t *axes,
33 const int8_t *sign
34) {
35 gyro->spi = spi;
36 gyro->cs = cs;
37 gyro->base.sensitivity = sensitivity;
38 gyro->base.dataSize = IAM_20380_DATA_TOTAL;
43 gyro->base.bias = gyro->bias;
44 gyro->base.axes = gyro->axes;
45 gyro->base.sign = gyro->sign;
46 gyro->base.gyroData = gyro->gyroData;
47 gyro->base.rawGyroData = gyro->rawGyroData;
48 memcpy(gyro->base.axes, axes, IAM_20380_DATA_COUNT);
49 memcpy(gyro->base.sign, sign, IAM_20380_DATA_COUNT);
50
51 // TODO:
52 // Make scale & sensitivity for gyroscopes configurable on init.
53 // See kx134_1211.c for example.
54
55 // Reset chip and select clock source
56 IAM_20380_writeRegister(
57 gyro,
58 IAM_20380_PWR_MGMT_1,
59 (IAM_20380_PWR_MGMT_1_RESET // Manual software reset
60 | IAM_20380_PWR_MGMT_1_CLKSEL) // Auto clock select
61 );
62
63 // Apparently power-on reset delay also applies to soft resets.
64 // There is not indication of this whatsoever in the datasheet.
65 for (uint32_t i = 0; i < 0x1FFFF; i++);
66
67 // Set output data rate to 1kHz
68 IAM_20380_writeRegister(gyro, IAM_20380_SMPLRT_DIV, 0x07);
69
70 // Set resolution to 500dps
71 IAM_20380_writeRegister(gyro, IAM_20380_GYRO_CONFIG, IAM_20380_CONFIG_FS_SEL500);
72
73 // Configure filter for minimal noise
74 IAM_20380_writeRegister(gyro, IAM_20380_CONFIG, 6);
75
76 return *gyro;
77}
78
79/******************************** DEVICE METHODS ********************************/
80
81/* =============================================================================== */
90void IAM_20380_readGyro(Gyro_t *gyro, float *out) {
91 uint8_t bytes[IAM_20380_DATA_TOTAL];
92 gyro->readRawBytes(gyro, bytes);
93 gyro->processRawBytes(gyro, bytes, out);
94}
95
96/* =============================================================================== */
105 gyro->readRawBytes(gyro, gyro->rawGyroData);
106 gyro->processRawBytes(gyro, gyro->rawGyroData, gyro->gyroData);
107}
108
109/* =============================================================================== */
119void IAM_20380_processRawBytes(Gyro_t *gyro, uint8_t *bytes, float *out) {
120 for (int i = 0; i < IAM_20380_DATA_COUNT; i++) {
121 out[i] = (int16_t)(((uint16_t)bytes[i * 2] << 8) | bytes[i * 2 + 1]); // Process bytes
122 out[i] = (out[i] * gyro->sign[i] * gyro->sensitivity) - gyro->bias[i]; // Scale and offset
123 }
124}
125
126/* =============================================================================== */
135void IAM_20380_readRawBytes(Gyro_t *gyro, uint8_t *out) {
136#define INDEX_AXES(index, byte) 2 * gyro->axes[index] + byte
137 out[INDEX_AXES(0, 0)] = IAM_20380_readRegister((IAM_20380_t *)gyro, IAM_20380_XOUT_H); // gyro X high
138 out[INDEX_AXES(0, 1)] = IAM_20380_readRegister((IAM_20380_t *)gyro, IAM_20380_XOUT_L); // gyro X low
139 out[INDEX_AXES(1, 0)] = IAM_20380_readRegister((IAM_20380_t *)gyro, IAM_20380_YOUT_H); // gyro Y high
140 out[INDEX_AXES(1, 1)] = IAM_20380_readRegister((IAM_20380_t *)gyro, IAM_20380_YOUT_L); // gyro Y low
141 out[INDEX_AXES(2, 0)] = IAM_20380_readRegister((IAM_20380_t *)gyro, IAM_20380_ZOUT_H); // gyro Z high
142 out[INDEX_AXES(2, 1)] = IAM_20380_readRegister((IAM_20380_t *)gyro, IAM_20380_ZOUT_L); // gyro Z low
143#undef INDEX_AXES
144}
145
146/******************************** INTERFACE METHODS ********************************/
147
148void IAM_20380_writeRegister(IAM_20380_t *gyro, uint8_t address, uint8_t data) {
149 SPI_t *spi = gyro->spi;
150 GPIOpin_t cs = gyro->cs;
151
152 cs.reset(&cs);
153
154 // Send read command and address
155 uint8_t payload = address & 0x7F; // Load payload with address and read command
156 spi->transmit(spi, payload); // Transmit payload
157 spi->transmit(spi, data); // Transmit dummy data and read response data
158
159 cs.set(&cs);
160}
161
162uint8_t IAM_20380_readRegister(IAM_20380_t *gyro, uint8_t address) {
163 uint8_t response = 0;
164 SPI_t *spi = gyro->spi;
165 GPIOpin_t cs = gyro->cs;
166
167 cs.reset(&cs);
168
169 // Send read command and address
170 uint8_t payload = address | 0x80; // Load payload with address and read command
171 response = spi->transmit(spi, payload); // Transmit payload
172 response = spi->transmit(spi, 0xFF); // Transmit dummy data and read response data
173
174 cs.set(&cs);
175
176 return response;
177}
178
uint8_t * axes
Array defining axes of mounting.
Definition gyroscope.h:64
int8_t * sign
Array defining sign of axes.
Definition gyroscope.h:65
void(* readRawBytes)(struct Gyro *, uint8_t *)
Pointer to readRawBytes method.
Definition gyroscope.h:48
float * gyroData
Processed angular rates array.
Definition gyroscope.h:67
uint8_t * rawGyroData
Raw angular rates array.
Definition gyroscope.h:66
void(* update)(struct Gyro *gyro)
Pointer to update method.
Definition gyroscope.h:24
float * bias
Bias offset array.
Definition gyroscope.h:68
uint8_t dataSize
Total data size.
Definition gyroscope.h:63
void(* processRawBytes)(struct Gyro *, uint8_t *, float *)
Pointer to processRawBytes method.
Definition gyroscope.h:61
void(* readGyro)(struct Gyro *gyro, float *out)
Pointer to readGyro method.
Definition gyroscope.h:36
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 IAM_20380_processRawBytes(Gyro_t *, uint8_t *, float *)
Process raw 3-axis data to floating point gyro rates.
Definition iam_20380.c:119
IAM_20380_t IAM_20380_init(IAM_20380_t *gyro, SPI_t *spi, GPIOpin_t cs, float sensitivity, const uint8_t *axes, const int8_t *sign)
Initialiser for a IAM_20380 gyroscope.
Definition iam_20380.c:27
void IAM_20380_readRawBytes(Gyro_t *, uint8_t *)
Read raw 3-axis data.
Definition iam_20380.c:135
void IAM_20380_readGyro(Gyro_t *, float *)
Read 3-axis floating point gyro rates.
Definition iam_20380.c:90
void IAM_20380_update(Gyro_t *)
Updates internally stored gyro readings.
Definition iam_20380.c:104
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 rawGyroData[IAM_20380_DATA_TOTAL]
Raw gyro rates array.
Definition iam_20380.h:78
float gyroData[IAM_20380_DATA_COUNT]
Processed gyro rates array.
Definition iam_20380.h:79
float bias[IAM_20380_DATA_COUNT]
Bias offset array.
Definition iam_20380.h:80
GPIOpin_t cs
Chip select GPIO.
Definition iam_20380.h:73
Gyro_t base
Base gyroscope API.
Definition iam_20380.h:71
uint8_t axes[IAM_20380_DATA_COUNT]
Array defining axes of mounting.
Definition iam_20380.h:76
int8_t sign[IAM_20380_DATA_COUNT]
Array defining sign of axes.
Definition iam_20380.h:77
SPI_t * spi
Parent SPI interface.
Definition iam_20380.h:72