1 /*
2 * Copyright (C) 2018 InvenSense Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <algos/time_sync.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <timer.h>
21 #include <sensors.h>
22 #include <heap.h>
23 #include <spi.h>
24 #include <slab.h>
25 #include <limits.h>
26 #include <atomic.h>
27 #include <plat/rtc.h>
28 #include <plat/gpio.h>
29 #include <plat/exti.h>
30 #include <plat/syscfg.h>
31 #include <seos.h>
32 #include <gpio.h>
33 #include <isr.h>
34 #include <halIntf.h>
35 #include <hostIntf.h>
36 #include <nanohubPacket.h>
37 #include <cpu/cpuMath.h>
38 #include <nanohub_math.h>
39 #include <variant/sensType.h>
40 #include <variant/variant.h>
41 #include <common/math/macros.h>
42
43 #ifdef ACCEL_CAL_ENABLED
44 #include <calibration/accelerometer/accel_cal.h>
45 #endif
46 #ifdef GYRO_CAL_ENABLED
47 #include <calibration/gyroscope/gyro_cal.h>
48 #endif
49
50 #define INFO_PRINT(fmt, ...) do { \
51 osLog(LOG_INFO, "%s " fmt, "[ICM40600]", ##__VA_ARGS__); \
52 } while (0);
53
54 #define ERROR_PRINT(fmt, ...) do { \
55 osLog(LOG_ERROR, "%s " fmt, "[ICM40600] ERROR:", ##__VA_ARGS__); \
56 } while (0);
57
58 #define DEBUG_PRINT(fmt, ...) do { \
59 if (DBG_ENABLE) { \
60 INFO_PRINT(fmt, ##__VA_ARGS__); \
61 } \
62 } while (0);
63
64 #define DEBUG_PRINT_IF(cond, fmt, ...) do { \
65 if ((cond) && DBG_ENABLE) { \
66 INFO_PRINT(fmt, ##__VA_ARGS__); \
67 } \
68 } while (0);
69
70 #define DBG_ENABLE 0
71 #define DBG_STATE 0
72 #define DBG_TIMESTAMP 0
73
74 #define ICM40600_APP_ID APP_ID_MAKE(NANOHUB_VENDOR_INVENSENSE, 0x2)
75 #define ICM40600_APP_VERSION 1
76
77 #define ICM40600_SPI_WRITE 0x00
78 #define ICM40600_SPI_READ 0x80
79
80 // SPI speeds officialy supported: 5MHz (low speed), 17MHz (high speed)
81 #define ICM40600_SPI_LOW_SPEED_HZ 5000000
82 #define ICM40600_SPI_HIGH_SPEED_HZ 17000000
83 #define ICM40600_SPI_DEFAULT_SPEED_HZ ICM40600_SPI_LOW_SPEED_HZ
84 #define ICM40600_SPI_MODE 3
85
86 #ifndef ICM40600_SPI_BUS_ID
87 #define ICM40600_SPI_BUS_ID 1
88 #endif
89 #ifndef ICM40600_INT1_PIN
90 #define ICM40600_INT1_PIN GPIO_PB(6)
91 #endif
92 #ifndef ICM40600_INT1_IRQ
93 #define ICM40600_INT1_IRQ EXTI9_5_IRQn
94 #endif
95 #define ICM40600_SPI_SPEED_HZ ICM40600_SPI_HIGH_SPEED_HZ
96
97 // set SPI speed register value
98 #if ICM40600_SPI_SPEED_HZ == ICM40600_SPI_LOW_SPEED_HZ
99 #define ICM40600_SPI_SPEED_REG_VALUE BIT_SPI_SPEED_5MHZ
100 #elif ICM40600_SPI_SPEED_HZ == ICM40600_SPI_HIGH_SPEED_HZ
101 #define ICM40600_SPI_SPEED_REG_VALUE BIT_SPI_SPEED_17MHZ
102 #else
103 #error "Invalid ICM40600_SPI_SPEED_HZ setting: valid values are 5MHz or 17MHz"
104 #endif
105
106 /*
107 **********************
108 * Chip configuration
109 **********************
110 */
111 /* Full-scale range */
112 // Default accel range is 8g
113 #ifndef ICM40600_ACC_RANGE_G
114 #define ICM40600_ACC_RANGE_G 8
115 #endif
116 // Default gyro range is 2000dps
117 #ifndef ICM40600_GYR_RANGE_DPS
118 #define ICM40600_GYR_RANGE_DPS 2000
119 #endif
120 // 0 -> +-16g, 1 -> +-8g, 2 -> +-4g, 3 -> +-2g, 4 -> +-1g
121 #if ICM40600_ACC_RANGE_G == 16
122 #define ICM40600_ACC_FS 0
123 #elif ICM40600_ACC_RANGE_G == 8
124 #define ICM40600_ACC_FS 1
125 #elif ICM40600_ACC_RANGE_G == 4
126 #define ICM40600_ACC_FS 2
127 #else
128 #error "Invalid ICM40600_ACC_RANGE_G setting: valid values are 16, 8, 4 (no HiFi)"
129 #endif
130 // 0 -> +-2000dps, 1 -> +-1000dps, 2 -> +-500dps, 3 -> +-250dps, 4 -> +-125dps, 5 -> +-62.5dps, 6 -> +-31.25dps, 7 -> +-15.6225dps
131 #if ICM40600_GYR_RANGE_DPS == 2000
132 #define ICM40600_GYR_FS 0
133 #elif ICM40600_GYR_RANGE_DPS == 1000
134 #define ICM40600_GYR_FS 1
135 #else
136 #error "Invalid ICM40600_GYR_RANGE_DPS setting: valid values are 2000, 1000"
137 #endif
138 // Bandwidth for low-pass filters, using ODR/2 FIR
139 #define ICM40600_ACC_BW_IND BIT_ACCEL_UI_BW_2_FIR
140 #define ICM40600_GYR_BW_IND BIT_GYRO_UI_BW_2_FIR
141
142 /* INT1 configuration */
143 // Polarity: 0 -> Active Low, 1 -> Active High
144 #define INT1_POLARITY 1
145 // Drive circuit: 0 -> Open Drain, 1 -> Push-Pull, fixed for INT1 do not change!
146 #define INT1_DRIVE_CIRCUIT 1
147 // Mode: 0 -> Pulse, 1 -> Latch
148 #define INT1_MODE 0
149
150 /* Wake-on-Motion/No-Motion */
151 #define ICM40600_WOM_THRESHOLD_MG 160 // 160mg @ 25Hz
152 #define ICM40600_WOM_COMPUTE(val_mg) ((256 * val_mg) / 1000)
153 // No-Motion duration: 5s
154 #define ICM40600_NOM_DURATION_NS (5 * 1000000000ULL)
155
156 /*
157 **********************
158 * Factory calibration
159 **********************
160 */
161 #define CALIBRATION_ODR 7 // 200Hz (support both LPM and LNM)
162 #define CALIBRATION_ACC_FS 0 // +-16g (= resolution of offset register)
163 #define CALIBRATION_GYR_FS 1 // +-1000dps (= resolution of offset register)
164 #define CALIBRATION_ACC_1G 2048 // LSB/g @+-16g
165 #define CALIBRATION_ACC_BW_IND BIT_ACCEL_UI_BW_4_IIR
166 #define CALIBRATION_GYR_BW_IND BIT_GYRO_UI_BW_4_IIR
167
168 #define CALIBRATION_READ_INTERVAL_US (200 * 1000) // 200ms (200/5ms=40 packets -> 40 * 16 = 640 bytes)
169 #define CALIBRATION_SAMPLE_NB 200 // 200/40packets = 5 loops
170 #define RETRY_CNT_CALIBRATION 10 // > 5 loops
171
172 /*
173 **********************
174 * Selftest
175 **********************
176 */
177 #define SELF_TEST_ODR 6 // 1000Hz
178 #define SELF_TEST_ACC_FS 3 // +-2g
179 #define SELF_TEST_GYR_FS 3 // +-250dps
180 #define SELF_TEST_ACC_BW_IND BIT_ACCEL_UI_BW_10_IIR
181 #define SELF_TEST_GYR_BW_IND BIT_GYRO_UI_BW_10_IIR
182 #define SELF_TEST_MIN_ACC_MG 225 // mg
183 #define SELF_TEST_MAX_ACC_MG 675 // mg
184 #define SELF_TEST_MIN_GYR_DPS 60 // dps
185 #define SELF_TEST_MAX_GYR_OFF_DPS 20 // dps
186 #define SELF_TEST_ACC_SHIFT_DELTA 500 // = 0.5
187 #define SELF_TEST_GYR_SHIFT_DELTA 500 // = 0.5
188
189 #define SELF_TEST_ACC_SCALE 32768 / (16 >> SELF_TEST_ACC_FS) / 1000
190 #define SELF_TEST_GYR_SCALE 32768 / (2000 >> SELF_TEST_GYR_FS)
191
192 #define SELF_TEST_READ_INTERVAL_US (20 * 1000) // 20ms (20/1ms=20 packets -> 20 * 16 = 320 bytes)
193 #define SELF_TEST_SAMPLE_NB 200 // 200/20packets = 10 loops
194 #define RETRY_CNT_SELF_TEST 20 // > 10 loops
195 #define SELF_TEST_PRECISION 1000
196 #define SELF_TEST_SETTLE_TIME_MS 25
197
198 #define SELF_TEST_MIN_ACC (SELF_TEST_MIN_ACC_MG * SELF_TEST_ACC_SCALE * SELF_TEST_PRECISION)
199 #define SELF_TEST_MAX_ACC (SELF_TEST_MAX_ACC_MG * SELF_TEST_ACC_SCALE * SELF_TEST_PRECISION)
200 #define SELF_TEST_MIN_GYR (SELF_TEST_MIN_GYR_DPS * SELF_TEST_GYR_SCALE * SELF_TEST_PRECISION)
201 #define SELF_TEST_MAX_GYR (SELF_TEST_MAX_GYR_DPS * SELF_TEST_GYR_SCALE * SELF_TEST_PRECISION)
202 #define SELF_TEST_MAX_GYR_OFFSET (SELF_TEST_MAX_GYR_OFF_DPS * SELF_TEST_GYR_SCALE * SELF_TEST_PRECISION)
203
204 /*
205 ****************
206 * register map *
207 ****************
208 */
209 /* Bank 0 */
210 #define REG_DEVICE_CONFIG 0x11
211 #define REG_SPI_SPEED 0x13
212 #define REG_INT_CONFIG 0x14
213 #define REG_FIFO_CONFIG 0x16
214 #define REG_INT_STATUS 0x2D
215 #define REG_FIFO_BYTE_COUNT1 0x2E
216 #define REG_FIFO_BYTE_COUNT2 0x2F
217 #define REG_FIFO_DATA 0x30
218 #define REG_SIGNAL_PATH_RESET 0x4B
219 #define REG_INTF_CONFIG0 0x4C
220 #define REG_PWR_MGMT_0 0x4E
221 #define REG_GYRO_CONFIG0 0x4F
222 #define REG_ACCEL_CONFIG0 0x50
223 #define REG_GYRO_CONFIG1 0x51
224 #define REG_GYRO_ACCEL_CONFIG0 0x52
225 #define REG_ACCEL_CONFIG1 0x53
226 #define REG_ACCEL_WOM_X_THR 0x54
227 #define REG_ACCEL_WOM_Y_THR 0x55
228 #define REG_ACCEL_WOM_Z_THR 0x56
229 #define REG_SMD_CONFIG 0x57
230 #define REG_INT_STATUS2 0x59
231 #define REG_TMST_CONFIG 0x5A
232 #define REG_FIFO_CONFIG1 0x5F
233 #define REG_FIFO_CONFIG2 0x60
234 #define REG_FIFO_CONFIG3 0x61
235 #define REG_INT_CONFIG0 0x63
236 #define REG_INT_CONFIG1 0x64
237 #define REG_INT_SOURCE0 0x65
238 #define REG_INT_SOURCE1 0x66
239 #define REG_SELF_TEST_CONFIG 0x70
240 #define REG_WHO_AM_I 0x75
241 #define REG_REG_BANK_SEL 0x76
242 #define REG_GOS_USER0 0x77
243 #define REG_GOS_USER1 0x78
244 #define REG_GOS_USER2 0x79
245 #define REG_GOS_USER3 0x7A
246 #define REG_GOS_USER4 0x7B
247 #define REG_GOS_USER5 0x7C
248 #define REG_GOS_USER6 0x7D
249 #define REG_GOS_USER7 0x7E
250 #define REG_GOS_USER8 0x7F
251 /* Bank 1 */
252 #define REG_XG_ST_DATA 0x5F
253 #define REG_YG_ST_DATA 0x60
254 #define REG_ZG_ST_DATA 0x61
255 /* Bank 2 */
256 #define REG_XA_ST_DATA 0x3B
257 #define REG_YA_ST_DATA 0x3C
258 #define REG_ZA_ST_DATA 0x3D
259
260 /* REG_WHO_AM_I */
261 #define WHO_AM_I_ICM40604 0x32
262 #define WHO_AM_I_ICM40605 0x33
263 /* REG_REG_BANK_SEL */
264 #define BIT_BANK_SEL_0 0x00
265 #define BIT_BANK_SEL_1 0x01
266 #define BIT_BANK_SEL_2 0x02
267 /* REG_DEVICE_CONFIG */
268 #define BIT_SOFT_RESET 0x01
269 /* REG_SPI_SPEED */
270 #define BIT_SPI_SPEED_5MHZ 0x03
271 #define BIT_SPI_SPEED_17MHZ 0x05
272 /* REG_GYRO_CONFIG0/REG_ACCEL_CONFIG0 */
273 #define SHIFT_GYRO_FS_SEL 5
274 #define SHIFT_ACCEL_FS_SEL 5
275 #define SHIFT_ODR_CONF 0
276 /* REG_INT_CONFIG */
277 #define SHIFT_INT1_POLARITY 0
278 #define SHIFT_INT1_DRIVE_CIRCUIT 1
279 #define SHIFT_INT1_MODE 2
280 /* REG_PWR_MGMT_0 */
281 #define BIT_TEMP_DIS 0x20
282 #define BIT_IDLE 0x10
283 #define BIT_GYRO_MODE_OFF 0x00
284 #define BIT_GYRO_MODE_STBY 0x04
285 #define BIT_GYRO_MODE_LN 0x0C
286 #define BIT_ACCEL_MODE_OFF 0x00
287 #define BIT_ACCEL_MODE_LN 0x03
288 /* REG_SIGNAL_PATH_RESET */
289 #define BIT_FIFO_FLUSH 0x02
290 /* REG_INTF_CONFIG0 */
291 #define BIT_FIFO_COUNT_REC 0x40
292 #define BIT_COUNT_BIG_ENDIAN 0x20
293 #define BIT_SENS_DATA_BIG_ENDIAN 0x10
294 #define BIT_UI_SIFS_DISABLE_SPI 0x02
295 #define BIT_UI_SIFS_DISABLE_I2C 0x03
296 /* REG_FIFO_CONFIG1 */
297 #define BIT_FIFO_ACCEL_EN 0x01
298 #define BIT_FIFO_GYRO_EN 0x02
299 #define BIT_FIFO_TEMP_EN 0x04
300 #define BIT_FIFO_TMST_FSYNC_EN 0x08
301 #define BIT_FIFO_HIRES_EN 0x10
302 #define BIT_FIFO_WM_TH 0x20
303 #define BIT_FIFO_RESUME_PART_RD 0x40
304 /* REG_INT_CONFIG1 */
305 #define BIT_INT_ASY_RST_DISABLE 0x10
306 /* REG_INT_SOURCE0 */
307 #define BIT_INT_UI_AGC_RDY_INT1_EN 0x01
308 #define BIT_INT_FIFO_FULL_INT1_EN 0x02
309 #define BIT_INT_FIFO_THS_INT1_EN 0x04
310 #define BIT_INT_UI_DRDY_INT1_EN 0x08
311 #define BIT_INT_RESET_DONE_INT1_EN 0x10
312 #define BIT_INT_PLL_RDY_INT1_EN 0x20
313 #define BIT_INT_UI_FSYNC_INT1_EN 0x40
314 /* REG_INT_SOURCE1 */
315 #define BIT_INT_WOM_X_INT1_EN 0x01
316 #define BIT_INT_WOM_Y_INT1_EN 0x02
317 #define BIT_INT_WOM_Z_INT1_EN 0x04
318 #define BIT_INT_SMD_INT1_EN 0x08
319 #define BIT_INT_WOM_XYZ_INT1_EN (BIT_INT_WOM_X_INT1_EN | BIT_INT_WOM_Y_INT1_EN | BIT_INT_WOM_Z_INT1_EN)
320 /* REG_SELF_TEST_CONFIG */
321 #define BIT_SELF_TEST_REGULATOR_EN 0x40
322 #define BIT_TEST_AZ_EN 0x20
323 #define BIT_TEST_AY_EN 0x10
324 #define BIT_TEST_AX_EN 0x08
325 #define BIT_TEST_GZ_EN 0x04
326 #define BIT_TEST_GY_EN 0x02
327 #define BIT_TEST_GX_EN 0x01
328 /* REG_INT_STATUS */
329 #define BIT_INT_STATUS_AGC_RDY 0x01
330 #define BIT_INT_STATUS_FIFO_FULL 0x02
331 #define BIT_INT_STATUS_FIFO_THS 0x04
332 #define BIT_INT_STATUS_DRDY 0x08
333 #define BIT_INT_STATUS_RESET_DONE 0x10
334 #define BIT_INT_STATUS_PLL_DRY 0x20
335 #define BIT_INT_STATUS_UI_FSYNC 0x40
336 /* REG_INT_STATUS2 */
337 #define BIT_INT_STATUS_WOM_X 0x01
338 #define BIT_INT_STATUS_WOM_Y 0x02
339 #define BIT_INT_STATUS_WOM_Z 0x04
340 #define BIT_INT_STATUS_SMD 0x08
341 #define BIT_INT_STATUS_WOM_XYZ (BIT_INT_STATUS_WOM_X | BIT_INT_STATUS_WOM_Y | BIT_INT_STATUS_WOM_Z)
342 /* REG_FIFO_CONFIG */
343 #define BIT_FIFO_MODE_BYPASS 0x00
344 #define BIT_FIFO_MODE_STREAM 0x40
345 #define BIT_FIFO_MODE_STOP_FULL 0x80
346 /* REG_GYRO_ACCEL_CONFIG0 */
347 #define BIT_ACCEL_UI_BW_2_FIR 0x00
348 #define BIT_ACCEL_UI_BW_4_IIR 0x10
349 #define BIT_ACCEL_UI_BW_5_IIR 0x20
350 #define BIT_ACCEL_UI_BW_8_IIR 0x30
351 #define BIT_ACCEL_UI_BW_10_IIR 0x40
352 #define BIT_ACCEL_UI_BW_16_IIR 0x50
353 #define BIT_ACCEL_UI_BW_20_IIR 0x60
354 #define BIT_ACCEL_UI_BW_40_IIR 0x70
355 #define BIT_GYRO_UI_BW_2_FIR 0x00
356 #define BIT_GYRO_UI_BW_4_IIR 0x01
357 #define BIT_GYRO_UI_BW_5_IIR 0x02
358 #define BIT_GYRO_UI_BW_8_IIR 0x03
359 #define BIT_GYRO_UI_BW_10_IIR 0x04
360 #define BIT_GYRO_UI_BW_16_IIR 0x05
361 #define BIT_GYRO_UI_BW_20_IIR 0x06
362 #define BIT_GYRO_UI_BW_40_IIR 0x07
363 /* fifo data packet header */
364 #define BIT_FIFO_HEAD_MSG 0x80
365 #define BIT_FIFO_HEAD_ACCEL 0x40
366 #define BIT_FIFO_HEAD_GYRO 0x20
367 #define BIT_FIFO_HEAD_TMSP_ODR 0x08
368 #define BIT_FIFO_HEAD_TMSP_NO_ODR 0x04
369 #define BIT_FIFO_HEAD_TMSP_FSYNC 0x0C
370 #define BIT_FIFO_HEAD_ODR_ACCEL 0x02
371 #define BIT_FIFO_HEAD_ODR_GYRO 0x01
372 /* REG_SMD_CONFIG */
373 #define BIT_WOM_INT_MODE_OR 0x00
374 #define BIT_WOM_INT_MODE_AND 0x08
375 #define BIT_WOM_MODE_INITIAL 0x00
376 #define BIT_WOM_MODE_PREV 0x04
377 #define BIT_SMD_MODE_OFF 0x00
378 #define BIT_SMD_MODE_OLD 0x01
379 #define BIT_SMD_MODE_SHORT 0x02
380 #define BIT_SMD_MODE_LONG 0x03
381 /* REG_TMST_CONFIG */
382 #define BIT_EN_DREG_FIFO_D2A 0x20
383 #define BIT_TMST_TO_REGS_EN 0x10
384 #define BIT_TMST_RESOL 0x08
385 #define BIT_TMST_DELTA_EN 0x04
386 #define BIT_TMST_FSYNC_EN 0x02
387 #define BIT_TMST_EN 0x01
388
389 /* FIFO data definitions */
390 #define FIFO_PACKET_SIZE 16
391 #define FIFO_MAX_PACKET_NB 65
392 #define FIFO_MIN_PACKET_NB 62
393
394 /* sensor startup time */
395 #define ICM40600_GYRO_START_TIME_MS 40
396 #define ICM40600_ACCEL_START_TIME_MS 10
397
398 /* temperature sensor */
399 #define TEMP_SCALE (128.0f / 115.49f) // scale, #9447
400 #define TEMP_OFFSET 25 // 25 degC offset
401
402 #define SPI_WRITE_0(addr, data) spiQueueWrite(addr, data, 2)
403 #define SPI_WRITE_1(addr, data, delay) spiQueueWrite(addr, data, delay)
404 #define GET_SPI_WRITE_MACRO(_1,_2,_3,NAME,...) NAME
405 #define SPI_WRITE(...) GET_SPI_WRITE_MACRO(__VA_ARGS__, SPI_WRITE_1, SPI_WRITE_0)(__VA_ARGS__)
406
407 #define SPI_READ_0(addr, size, buf) spiQueueRead(addr, size, buf, 0)
408 #define SPI_READ_1(addr, size, buf, delay) spiQueueRead(addr, size, buf, delay)
409 #define GET_SPI_READ_MACRO(_1,_2,_3,_4,NAME,...) NAME
410 #define SPI_READ(...) GET_SPI_READ_MACRO(__VA_ARGS__, SPI_READ_1, SPI_READ_0)(__VA_ARGS__)
411
412 #define EVT_SENSOR_MAG_DATA_RDY sensorGetMyEventType(SENS_TYPE_MAG)
413 #define EVT_SENSOR_NO_MOTION sensorGetMyEventType(SENS_TYPE_NO_MOTION)
414 #define EVT_SENSOR_ANY_MOTION sensorGetMyEventType(SENS_TYPE_ANY_MOTION)
415
416 #define MAX_NUM_COMMS_EVENT_SAMPLES 15
417
418 #define SPI_PACKET_SIZE 30
419 #define FIFO_READ_SIZE (FIFO_MAX_PACKET_NB * FIFO_PACKET_SIZE)
420 #define BUF_MARGIN 32 // some extra buffer for additional reg RW when a FIFO read happens
421 #define SPI_BUF_SIZE (FIFO_READ_SIZE + BUF_MARGIN)
422
423 #define ACC_FS_RANGE (16 >> ICM40600_ACC_FS)
424 #define GYR_FS_RANGE (2000 >> ICM40600_GYR_FS)
425 #define GRAVITY_NORM 9.80665f
426 #define kScale_acc (GRAVITY_NORM * ACC_FS_RANGE / 32768.0f)
427 #define kScale_gyr (NANO_PI / 180.0f * GYR_FS_RANGE / 32768.0f)
428
429 #define RATE_TO_HZ SENSOR_HZ(1.0f)
430 #define DECIMATION_HIGH_RATE SENSOR_HZ(1000.0f)
431 #define DECIMATION_LOW_RATE SENSOR_HZ(25.0f)
432 #define NO_DECIMATION_MAX_RATE SENSOR_HZ(200.0f) // will set ODR to DECIMATION_HIGH_RATE if more than this rate
433 #define NO_DECIMATION_MIN_RATE SENSOR_HZ(25.0f) // will set ODR to DECIMATION_LOW_RATE if less than this rate
434 #define MAX_BATCH_SIZE (((FIFO_MIN_PACKET_NB * 90) / 100) * FIFO_PACKET_SIZE) // 90% of FIFO size
435
436 /* skip first some samples */
437 #define ACC_SKIP_SAMPLE_NB 0
438 #define GYR_SKIP_SAMPLE_NB 3
439
440 #define CHIP_TIME_RES_US 1
441 #define CHIP_TIME_OFFSET_US 64000000ULL // 64sec
442 #define MIN_INCREMENT_TIME_NS 1000000ULL // 1ms for 1000Hz
443
444 enum SensorIndex {
445 FIRST_CONT_SENSOR = 0,
446 ACC = FIRST_CONT_SENSOR,
447 GYR,
448 NUM_CONT_SENSOR,
449 FIRST_ONESHOT_SENSOR = NUM_CONT_SENSOR,
450 WOM = FIRST_ONESHOT_SENSOR,
451 NOMO,
452 NUM_OF_SENSOR,
453 };
454
455 enum SensorEvents {
456 NO_EVT = -1,
457 EVT_SPI_DONE = EVT_APP_START + 1,
458 EVT_SENSOR_INTERRUPT_1,
459 };
460
461 enum IntState {
462 INT_READ_STATUS,
463 INT_PROCESS_STATUS,
464 INT_READ_FIFO_DATA,
465 INT_DONE,
466 };
467
468 enum InitState {
469 RESET_ICM40600,
470 INIT_ICM40600,
471 INIT_DONE,
472 };
473
474 enum CalibrationState {
475 CALIBRATION_START,
476 CALIBRATION_READ_STATUS,
477 CALIBRATION_READ_DATA,
478 CALIBRATION_SET_OFFSET,
479 CALIBRATION_DONE
480 };
481
482 enum SelfTestState {
483 TEST_START,
484 TEST_READ_STATUS,
485 TEST_READ_DATA,
486 TEST_READ_OTP,
487 TEST_REPORT,
488 TEST_DONE
489 };
490
491 enum SensorState {
492 // keep this in sync with getStateName
493 SENSOR_BOOT,
494 SENSOR_VERIFY_ID,
495 SENSOR_INITIALIZING,
496 SENSOR_IDLE,
497 SENSOR_POWERING_UP,
498 SENSOR_POWERING_DOWN,
499 SENSOR_CONFIG_CHANGING,
500 SENSOR_INT_1_HANDLING,
501 SENSOR_CALIBRATING,
502 SENSOR_TESTING,
503 SENSOR_SAVE_CALIBRATION,
504 SENSOR_NUM_OF_STATE
505 };
506 #if DBG_STATE
507 #define PRI_STATE "s"
getStateName(int32_t s)508 static const char * getStateName(int32_t s) {
509 // keep this in sync with SensorState
510 static const char* const l[] = {"BOOT", "VERIFY_ID", "INIT", "IDLE", "PWR_UP",
511 "PWR_DN", "CFG_CHANGE", "INT1", "CALIB", "TEST", "SAVE_CALIB"};
512 if (s >= 0 && s < SENSOR_NUM_OF_STATE) {
513 return l[s];
514 }
515 return "???";
516 #else
517 #define PRI_STATE PRIi32
518 static int32_t getStateName(int32_t s) {
519 return s;
520 #endif
521 }
522
523 #if DBG_TIMESTAMP
524 struct StatisticsSet {
525 uint32_t sync_reset_count;
526 uint32_t sync_count;
527 uint32_t sync_adjust_plus;
528 uint32_t sync_adjust_minus;
529 uint32_t sync_truncate;
530 };
531 #endif
532
533 struct ConfigStat {
534 uint64_t latency;
535 uint32_t rate;
536 bool enable;
537 };
538
539 struct CalibrationData {
540 struct HostHubRawPacket header;
541 struct SensorAppEventHeader data_header;
542 int32_t xBias;
543 int32_t yBias;
544 int32_t zBias;
545 } __attribute__((packed));
546
547 struct TestResultData {
548 struct HostHubRawPacket header;
549 struct SensorAppEventHeader data_header;
550 } __attribute__((packed));
551
552 struct ICM40600Sensor {
553 struct ConfigStat pConfig; // pending config status request
554 struct TripleAxisDataEvent *data_evt;
555 uint32_t handle;
556 uint32_t rate;
557 uint64_t latency;
558 uint64_t prev_rtc_time;
559 int16_t offset[3];
560 int16_t data[3];
561 bool updated;
562 bool powered; // activate status
563 bool configed; // configure status
564 bool wait_for_odr;
565 enum SensorIndex idx;
566 uint8_t flush;
567 uint8_t decimator;
568 uint8_t data_cnt;
569 uint8_t skip_sample_cnt;
570 };
571
572 struct FifoPacketData {
573 int16_t accel[3];
574 int16_t gyro[3];
575 uint16_t timestamp;
576 bool odr_accel;
577 bool odr_gyro;
578 bool valid_accel;
579 bool valid_gyro;
580 int8_t temp;
581 };
582
583 struct ICM40600FactoryCal {
584 int32_t data[3];
585 int32_t data_count;
586 };
587
588 struct ICM40600SelfTest {
589 int32_t data[3];
590 int32_t data_st_on[3];
591 int32_t data_st_off[3];
592 int32_t data_count;
593 bool st_mode;
594 uint8_t otp_st_data_gyro[3];
595 uint8_t otp_st_data_accel[3];
596 };
597
598 struct ICM40600Config {
599 uint32_t accel_rate;
600 uint32_t gyro_rate;
601 uint32_t wom_threshold;
602 uint32_t fifo_rate;
603 uint16_t fifo_watermark;
604 uint8_t fifo_sample_size;
605 bool accel_on;
606 bool gyro_on;
607 bool wom_on;
608 };
609
610 struct ICM40600Task {
611 uint32_t tid;
612 struct ICM40600Sensor sensors[NUM_OF_SENSOR];
613
614 // spi and interrupt
615 spi_cs_t cs;
616 struct SpiMode mode;
617 struct SpiPacket packets[SPI_PACKET_SIZE];
618 struct SpiDevice *spiDev;
619 struct Gpio *Int1;
620 IRQn_Type Irq1;
621 struct ChainedIsr Isr1;
622 bool Int1_EN;
623
624 // spi buffers
625 uint8_t *dataBuffer[3];
626 uint8_t txrxBuffer[SPI_BUF_SIZE];
627
628 // states
629 volatile uint8_t state; //task state, type enum SensorState, do NOT change this directly
630 enum InitState init_state;
631 enum IntState int_state;
632 enum CalibrationState calibration_state;
633 enum SelfTestState selftest_state;
634
635 // pending config
636 bool pending_int[1];
637 bool pending_flush;
638 bool pending_config[NUM_OF_SENSOR];
639 bool pending_calibration_save;
640
641 struct ICM40600Config config;
642 uint32_t noMotionTimerHandle;
643 uint16_t fifo_count;
644 bool powered;
645 bool flush;
646
647 // calibration
648 #ifdef ACCEL_CAL_ENABLED
649 struct AccelCal accel_cal;
650 #endif
651 #ifdef GYRO_CAL_ENABLED
652 struct GyroCal gyro_cal;
653 #endif
654
655 // timestamping
656 time_sync_t gSensorTime2RTC;
657 uint64_t data_timestamp;
658 uint64_t chip_time_us;
659 uint64_t last_sync_time;
660 uint64_t last_sync_data_ts;
661 uint16_t chip_timestamp;
662 bool fifo_start_sync;
663
664 // temperature data from chip in degC
665 float chip_temperature;
666
667 // spi rw
668 struct SlabAllocator *mDataSlab;
669 uint16_t mWbufCnt;
670 uint8_t mRegCnt;
671 uint8_t mRetryLeft;
672 bool spiInUse;
673
674 struct ICM40600FactoryCal factory_cal;
675
676 struct ICM40600SelfTest self_test;
677
678 #if DBG_TIMESTAMP
679 struct StatisticsSet statistics_set;
680 #endif
681 };
682
683 static uint32_t AccRates[] = {
684 SENSOR_HZ(25.0f/8.0f),
685 SENSOR_HZ(25.0f/4.0f),
686 SENSOR_HZ(25.0f/2.0f),
687 SENSOR_HZ(25.0f),
688 SENSOR_HZ(50.0f),
689 SENSOR_HZ(100.0f),
690 SENSOR_HZ(200.0f),
691 SENSOR_HZ(500.0f),
692 0,
693 };
694
695 static uint32_t GyrRates[] = {
696 SENSOR_HZ(25.0f/8.0f),
697 SENSOR_HZ(25.0f/4.0f),
698 SENSOR_HZ(25.0f/2.0f),
699 SENSOR_HZ(25.0f),
700 SENSOR_HZ(50.0f),
701 SENSOR_HZ(100.0f),
702 SENSOR_HZ(200.0f),
703 SENSOR_HZ(500.0f),
704 0,
705 };
706
707 static struct ICM40600Task mTask;
708
709 #define DEC_INFO(name, type, axis, inter, samples) \
710 .sensorName = name, \
711 .sensorType = type, \
712 .numAxis = axis, \
713 .interrupt = inter, \
714 .minSamples = samples
715
716 #define DEC_INFO_RATE(name, rates, type, axis, inter, samples) \
717 DEC_INFO(name, type, axis, inter, samples), \
718 .supportedRates = rates
719
720 #define DEC_INFO_RATE_RAW(name, rates, type, axis, inter, samples, raw, scale) \
721 DEC_INFO(name, type, axis, inter, samples), \
722 .supportedRates = rates, \
723 .flags1 = SENSOR_INFO_FLAGS1_RAW, \
724 .rawType = raw, \
725 .rawScale = scale
726
727 #define DEC_INFO_RATE_BIAS(name, rates, type, axis, inter, samples, bias) \
728 DEC_INFO(name, type, axis, inter, samples), \
729 .supportedRates = rates, \
730 .flags1 = SENSOR_INFO_FLAGS1_BIAS, \
731 .biasType = bias
732
733 #define DEC_INFO_RATE_RAW_BIAS(name, rates, type, axis, inter, samples, raw, scale, bias) \
734 DEC_INFO_RATE_RAW(name, rates, type, axis, inter, samples, raw, scale), \
735 .flags1 = SENSOR_INFO_FLAGS1_RAW | SENSOR_INFO_FLAGS1_BIAS, \
736 .biasType = bias
737
738 typedef struct ICM40600Task _Task;
739 #define TASK _Task* const _task
740
741 // To get rid of static variables all task functions should have a task structure pointer input.
742 // This is an intermediate step.
743 #define TDECL() TASK = &mTask; (void)_task
744
745 // Access task variables without explicitly specify the task structure pointer.
746 #define T(v) (_task->v)
747
748 // Atomic get state
749 #define GET_STATE() (atomicReadByte(&(_task->state)))
750
751 // Atomic set state, this set the state to arbitrary value, use with caution
752 #define SET_STATE(s) do{\
753 DEBUG_PRINT_IF(DBG_STATE, "set state %" PRI_STATE "\n", getStateName(s));\
754 atomicWriteByte(&(_task->state), (s));\
755 }while(0)
756
757 // Atomic switch state from IDLE to desired state.
758 static bool trySwitchState_(TASK, enum SensorState newState) {
759 #if DBG_STATE
760 bool ret = atomicCmpXchgByte(&T(state), SENSOR_IDLE, newState);
761 uint8_t prevState = ret ? SENSOR_IDLE : GET_STATE();
762 DEBUG_PRINT("switch state %" PRI_STATE "->%" PRI_STATE ", %s\n",
763 getStateName(prevState), getStateName(newState), ret ? "ok" : "failed");
764 return ret;
765 #else
766 return atomicCmpXchgByte(&T(state), SENSOR_IDLE, newState);
767 #endif
768 }
769 // Short-hand
770 #define trySwitchState(s) trySwitchState_(_task, (s))
771
772 static const struct SensorInfo mSensorInfo[NUM_OF_SENSOR] =
773 {
774 #ifdef ACCEL_CAL_ENABLED
775 { DEC_INFO_RATE_RAW_BIAS("Accelerometer", AccRates, SENS_TYPE_ACCEL, NUM_AXIS_THREE,
776 NANOHUB_INT_NONWAKEUP, 3000, SENS_TYPE_ACCEL_RAW, 1.0 / kScale_acc, SENS_TYPE_ACCEL_BIAS) },
777 #else
778 { DEC_INFO_RATE_RAW("Accelerometer", AccRates, SENS_TYPE_ACCEL, NUM_AXIS_THREE,
779 NANOHUB_INT_NONWAKEUP, 3000, SENS_TYPE_ACCEL_RAW, 1.0 / kScale_acc) },
780 #endif
781 #ifdef GYRO_CAL_ENABLED
782 { DEC_INFO_RATE_BIAS("Gyroscope", GyrRates, SENS_TYPE_GYRO, NUM_AXIS_THREE,
783 NANOHUB_INT_NONWAKEUP, 20, SENS_TYPE_GYRO_BIAS) },
784 #else
785 { DEC_INFO_RATE("Gyroscope", GyrRates, SENS_TYPE_GYRO, NUM_AXIS_THREE,
786 NANOHUB_INT_NONWAKEUP, 20) },
787 #endif
788 { DEC_INFO("Wake-on-Motion", SENS_TYPE_ANY_MOTION, NUM_AXIS_EMBEDDED, NANOHUB_INT_NONWAKEUP, 20) },
789 { DEC_INFO("No-Motion", SENS_TYPE_NO_MOTION, NUM_AXIS_EMBEDDED, NANOHUB_INT_NONWAKEUP, 20) },
790 };
791
792 static void time_init(TASK)
793 {
794 time_sync_init(&T(gSensorTime2RTC));
795 }
796
797 static bool sensortime_to_rtc_time(TASK, uint64_t sensor_time, uint64_t *rtc_time_ns)
798 {
799 return time_sync_estimate_time1(&T(gSensorTime2RTC), sensor_time, rtc_time_ns);
800 }
801
802 static void map_sensortime_to_rtc_time(TASK, uint64_t sensor_time, uint64_t rtc_time_ns)
803 {
804 #if DBG_TIMESTAMP
805 T(statistics_set).sync_count++;
806 #endif
807 time_sync_add(&T(gSensorTime2RTC), rtc_time_ns, sensor_time);
808 }
809
810 static void invalidate_sensortime_to_rtc_time(TASK)
811 {
812 #if DBG_TIMESTAMP
813 T(statistics_set).sync_reset_count++;
814 #endif
815 time_sync_reset(&T(gSensorTime2RTC));
816 }
817
818 static void dataEvtFree(void *ptr)
819 {
820 TDECL();
821 struct TripleAxisDataEvent *ev = (struct TripleAxisDataEvent *)ptr;
822
823 slabAllocatorFree(T(mDataSlab), ev);
824 }
825
826 static void spiQueueWrite(uint8_t addr, uint8_t data, uint32_t delay)
827 {
828 TDECL();
829
830 if (T(spiInUse)) {
831 ERROR_PRINT("SPI in use, cannot queue write\n");
832 return;
833 }
834 T(packets[T(mRegCnt)]).size = 2;
835 T(packets[T(mRegCnt)]).txBuf = &T(txrxBuffer[T(mWbufCnt)]);
836 T(packets[T(mRegCnt)]).rxBuf = &T(txrxBuffer[T(mWbufCnt)]);
837 T(packets[T(mRegCnt)]).delay = delay * 1000;
838 T(txrxBuffer[T(mWbufCnt++)]) = ICM40600_SPI_WRITE | addr;
839 T(txrxBuffer[T(mWbufCnt++)]) = data;
840 T(mRegCnt)++;
841 }
842
843 /*
844 * need to be sure size of buf is larger than read size
845 */
846 static void spiQueueRead(uint8_t addr, size_t size, uint8_t **buf, uint32_t delay)
847 {
848 TDECL();
849
850 if (T(spiInUse)) {
851 ERROR_PRINT("SPI in use, cannot queue read %d %d\n", (int)addr, (int)size);
852 return;
853 }
854
855 *buf = &T(txrxBuffer[T(mWbufCnt)]);
856 T(packets[T(mRegCnt)]).size = size + 1; // first byte will not contain valid data
857 T(packets[T(mRegCnt)]).txBuf = &T(txrxBuffer[T(mWbufCnt)]);
858 T(packets[T(mRegCnt)]).rxBuf = *buf;
859 T(packets[T(mRegCnt)]).delay = delay * 1000;
860 T(txrxBuffer[T(mWbufCnt)++]) = ICM40600_SPI_READ | addr;
861 T(mWbufCnt) += size;
862 T(mRegCnt)++;
863 }
864
865 static void spiBatchTxRx(struct SpiMode *mode,
866 SpiCbkF callback, void *cookie, const char * src)
867 {
868 TDECL();
869
870 if (T(mRegCnt) == 0) {
871 callback(cookie, 0);
872 return;
873 }
874
875 if (T(mWbufCnt) > SPI_BUF_SIZE) {
876 ERROR_PRINT("NO enough SPI buffer space, dropping transaction.\n");
877 return;
878 }
879 if (T(mRegCnt) > SPI_PACKET_SIZE) {
880 ERROR_PRINT("spiBatchTxRx too many packets!\n");
881 return;
882 }
883
884 T(spiInUse) = true;
885 T(mWbufCnt) = 0;
886
887 // Reset variables before issuing SPI transaction.
888 // SPI may finish before spiMasterRxTx finish
889 uint8_t regCount = T(mRegCnt);
890 T(mRegCnt) = 0;
891
892 if (spiMasterRxTx(T(spiDev), T(cs), T(packets), regCount, mode, callback, cookie) < 0) {
893 ERROR_PRINT("spiMasterRxTx failed!\n");
894 }
895 }
896
897 static bool icm40600Isr1(struct ChainedIsr *isr)
898 {
899 TASK = container_of(isr, struct ICM40600Task, Isr1);
900
901 if (!extiIsPendingGpio(T(Int1))) {
902 return false;
903 }
904
905 /* better to use atomic read for the pending flag but not serious even not atomic */
906 if (!T(pending_int[0])) {
907 osEnqueuePrivateEvt(EVT_SENSOR_INTERRUPT_1, _task, NULL, T(tid));
908 }
909 extiClearPendingGpio(T(Int1));
910 return true;
911 }
912
913 static void sensorSpiCallback(void *cookie, int err)
914 {
915 TDECL();
916
917 T(spiInUse) = false;
918
919 if (!osEnqueuePrivateEvt(EVT_SPI_DONE, cookie, NULL, T(tid)))
920 ERROR_PRINT("sensorSpiCallback: osEnqueuePrivateEvt() failed\n");
921 }
922
923 static void noMotionCallback(uint32_t timerId, void *data)
924 {
925 const struct ICM40600Sensor *sensor = (const struct ICM40600Sensor *)data;
926
927 if (!sensor->configed)
928 return;
929
930 osEnqueueEvt(EVT_SENSOR_NO_MOTION, NULL, NULL);
931 }
932
933 static void setOffsetReg(TASK)
934 {
935 uint8_t val;
936 const int16_t * const acc_offset = T(sensors[ACC]).offset;
937 const int16_t * const gyr_offset = T(sensors[GYR]).offset;
938
939 DEBUG_PRINT("Set ACC hw offset %d %d %d\n",
940 -acc_offset[0], -acc_offset[1], -acc_offset[2]);
941 DEBUG_PRINT("Set GYR hw offset %d %d %d\n",
942 -gyr_offset[0], -gyr_offset[1], -gyr_offset[2]);
943
944 // GX_L
945 val = (-gyr_offset[0]) & 0xff;
946 SPI_WRITE(REG_GOS_USER0, val);
947 // GY_H / GX_H
948 val = (-gyr_offset[1] >> 4) & 0xf0;
949 val |= ((-gyr_offset[0] >> 8) & 0x0f);
950 SPI_WRITE(REG_GOS_USER1, val);
951 // GY_L
952 val = (-gyr_offset[1]) & 0xff;
953 SPI_WRITE(REG_GOS_USER2, val);
954 // GZ_L
955 val = (-gyr_offset[2]) & 0xff;
956 SPI_WRITE(REG_GOS_USER3, val);
957 // AX_H / GZ_H
958 val = (-acc_offset[0] >> 4) & 0xf0;
959 val |= ((-gyr_offset[2] >> 8) & 0x0f);
960 SPI_WRITE(REG_GOS_USER4, val);
961 // AX_H / GZ_H
962 val = (-acc_offset[0] >> 4) & 0xf0;
963 val |= ((-gyr_offset[2] >> 8) & 0x0f);
964 SPI_WRITE(REG_GOS_USER4, val);
965 // AX_L
966 val = (-acc_offset[0]) & 0xff;
967 SPI_WRITE(REG_GOS_USER5, val);
968 // AY_L
969 val = (-acc_offset[1]) & 0xff;
970 SPI_WRITE(REG_GOS_USER6, val);
971 // AZ_H / AY_H
972 val = (-acc_offset[2] >> 4) & 0xf0;
973 val |= ((-acc_offset[1] >> 8) & 0x0f);
974 SPI_WRITE(REG_GOS_USER7, val);
975 // AZ_L
976 val = (-acc_offset[2]) & 0xff;
977 SPI_WRITE(REG_GOS_USER8, val);
978 }
979
980 static void resetOffsetReg(TASK, enum SensorIndex idx)
981 {
982 uint8_t val;
983
984 DEBUG_PRINT("Reset offset registers sensor=%d\n", idx);
985
986 if (idx == ACC) {
987 val = (-T(sensors[GYR]).offset[2] >> 8) & 0x0f;
988 SPI_WRITE(REG_GOS_USER4, val); // AX_H / GZ_H
989 SPI_WRITE(REG_GOS_USER5, 0x00); // AX_L
990 SPI_WRITE(REG_GOS_USER6, 0x00); // AY_L
991 SPI_WRITE(REG_GOS_USER7, 0x00); // AZ_H / AY_H
992 SPI_WRITE(REG_GOS_USER8, 0x00); // AZ_L
993 } else if (idx == GYR) {
994 SPI_WRITE(REG_GOS_USER0, 0x00); // GX_L
995 SPI_WRITE(REG_GOS_USER1, 0x00); // GY_H / GX_H
996 SPI_WRITE(REG_GOS_USER2, 0x00); // GY_L
997 SPI_WRITE(REG_GOS_USER3, 0x00); // GZ_L
998 val = (-T(sensors[ACC]).offset[0] >> 4) & 0xf0;
999 SPI_WRITE(REG_GOS_USER4, val); // AX_H / GZ_H
1000 }
1001 }
1002
1003 static bool saveCalibration(TASK)
1004 {
1005 if (trySwitchState(SENSOR_SAVE_CALIBRATION)) {
1006 setOffsetReg(_task);
1007 spiBatchTxRx(&T(mode), sensorSpiCallback, _task, __FUNCTION__);
1008 return true;
1009 } else {
1010 return false;
1011 }
1012 }
1013
1014 static bool accCfgData(void *data, void *cookie)
1015 {
1016 TDECL();
1017 struct ICM40600Sensor *sensor = &T(sensors[ACC]);
1018 struct CfgData {
1019 int32_t hw[3]; // chip frame (hw unit @FSR=factory calibration)
1020 float sw[3]; // body frame
1021 };
1022 struct CfgData *values = data;
1023 int i;
1024
1025 for (i = 0; i < 3; i++) {
1026 // offset register is 12bit
1027 if (values->hw[i] > 2047) {
1028 sensor->offset[i] = 2047;
1029 } else if (values->hw[i] < -2048) {
1030 sensor->offset[i] = -2048;
1031 } else {
1032 sensor->offset[i] = values->hw[i];
1033 }
1034 }
1035 #ifdef ACCEL_CAL_ENABLED
1036 accelCalBiasSet(&T(accel_cal), values->sw[0], values->sw[1], values->sw[2]);
1037 #endif
1038 if (!saveCalibration(_task)) {
1039 T(pending_calibration_save) = true;
1040 }
1041 INFO_PRINT("accCfgData hw bias: data=%d, %d, %d\n",
1042 sensor->offset[0], sensor->offset[1], sensor->offset[2]);
1043
1044 return true;
1045 }
1046
1047 static bool gyrCfgData(void *data, void *cookie)
1048 {
1049 TDECL();
1050 struct ICM40600Sensor *sensor = &T(sensors[GYR]);
1051 const struct AppToSensorHalDataPayload *p = data;
1052 int i;
1053
1054 if (p->type == HALINTF_TYPE_GYRO_CAL_BIAS && p->size == sizeof(struct GyroCalBias)) {
1055 const struct GyroCalBias *bias = p->gyroCalBias;
1056 for (i = 0; i < 3; i++) {
1057 // offset register is 12bit
1058 if (bias->hardwareBias[i] > 2047) {
1059 sensor->offset[i] = 2047;
1060 } else if (bias->hardwareBias[i] < -2048) {
1061 sensor->offset[i] = -2048;
1062 } else {
1063 sensor->offset[i] = bias->hardwareBias[i];
1064 }
1065 }
1066 #ifdef GYRO_CAL_ENABLED
1067 gyroCalSetBias(&T(gyro_cal), bias->softwareBias[0], bias->softwareBias[1],
1068 bias->softwareBias[2], sensorGetTime());
1069 #endif
1070 if (!saveCalibration(_task)) {
1071 T(pending_calibration_save) = true;
1072 }
1073 INFO_PRINT("gyrCfgData hw bias: data=%d, %d, %d\n",
1074 sensor->offset[0], sensor->offset[1], sensor->offset[2]);
1075 } else if (p->type == HALINTF_TYPE_GYRO_OTC_DATA && p->size == sizeof(struct GyroOtcData)) {
1076 // Over-temperature gyro calibration not supported
1077 } else {
1078 ERROR_PRINT("Unknown gyro config data type 0x%04x, size %d\n", p->type, p->size);
1079 }
1080
1081 return true;
1082 }
1083
1084 static bool validateFifoData(const int16_t data[3])
1085 {
1086 bool ret = true;
1087
1088 if ((data[0] == -32768) && (data[1] == -32768) && (data[2] == -32768))
1089 ret = false;
1090
1091 return ret;
1092 }
1093
1094 static void getFifoData(const uint8_t *data, int idx, struct FifoPacketData *out)
1095 {
1096 /* invalidate all flags */
1097 out->valid_accel = false;
1098 out->valid_gyro = false;
1099
1100 /* Header : 1 byte
1101 * Accel : 6 byte
1102 * Gyro : 6 byte
1103 * Temp : 1 byte
1104 * Timestamp : 2 byte */
1105 if (data[idx] & BIT_FIFO_HEAD_ACCEL) {
1106 out->accel[0] = (data[idx + 2] << 8) | data[idx + 1];
1107 out->accel[1] = (data[idx + 4] << 8) | data[idx + 3];
1108 out->accel[2] = (data[idx + 6] << 8) | data[idx + 5];
1109 out->valid_accel = validateFifoData(out->accel);
1110 }
1111 out->odr_accel = (data[idx] & BIT_FIFO_HEAD_ODR_ACCEL) ? true : false;
1112
1113 if (data[idx] & BIT_FIFO_HEAD_GYRO) {
1114 out->gyro[0] = (data[idx + 8] << 8) | data[idx + 7];
1115 out->gyro[1] = (data[idx + 10] << 8) | data[idx + 9];
1116 out->gyro[2] = (data[idx + 12] << 8) | data[idx + 11];
1117 out->valid_gyro = validateFifoData(out->gyro);
1118 }
1119 out->odr_gyro = (data[idx] & BIT_FIFO_HEAD_ODR_GYRO) ? true : false;
1120
1121 out->temp = (int8_t)data[idx + 13];
1122 out->timestamp = (data[idx + 15] << 8) | data[idx + 14];
1123 }
1124
1125 static bool calSelftestGetOneData(enum SensorIndex sensor_idx, const uint8_t *data, int idx, int16_t raw_data[3])
1126 {
1127 struct FifoPacketData fifo_data;
1128 bool ret = false;
1129
1130 getFifoData(data, idx, &fifo_data);
1131
1132 switch (sensor_idx) {
1133 case ACC:
1134 if (fifo_data.valid_accel) {
1135 raw_data[0] = fifo_data.accel[0];
1136 raw_data[1] = fifo_data.accel[1];
1137 raw_data[2] = fifo_data.accel[2];
1138 ret = true;
1139 }
1140 break;
1141 case GYR:
1142 if (fifo_data.valid_gyro) {
1143 raw_data[0] = fifo_data.gyro[0];
1144 raw_data[1] = fifo_data.gyro[1];
1145 raw_data[2] = fifo_data.gyro[2];
1146 ret = true;
1147 }
1148 break;
1149 default:
1150 break;
1151 }
1152
1153 return ret;
1154 }
1155
1156 static void calSelftestFifoEnable(TASK, enum SensorIndex idx, bool en, uint32_t delay)
1157 {
1158 uint8_t val;
1159
1160 if (en) {
1161 // enable FIFO output
1162 T(config).fifo_sample_size = FIFO_PACKET_SIZE;
1163 val = BIT_FIFO_ACCEL_EN | BIT_FIFO_GYRO_EN |
1164 BIT_FIFO_TEMP_EN | BIT_FIFO_TMST_FSYNC_EN;
1165 SPI_WRITE(REG_FIFO_CONFIG, BIT_FIFO_MODE_STREAM);
1166 SPI_WRITE(REG_FIFO_CONFIG1, val, delay); // with wait
1167 } else {
1168 // disable FIFO output
1169 T(config).fifo_sample_size = 0;
1170 SPI_WRITE(REG_FIFO_CONFIG, BIT_FIFO_MODE_BYPASS);
1171 SPI_WRITE(REG_FIFO_CONFIG1, 0);
1172 }
1173 }
1174
1175 /*
1176 * Factory calibration
1177 */
1178 static void sendCalibrationResult(uint8_t status, uint8_t sensorType,
1179 int32_t xBias, int32_t yBias, int32_t zBias)
1180 {
1181 struct CalibrationData *data = heapAlloc(sizeof(struct CalibrationData));
1182 if (!data) {
1183 ERROR_PRINT("Couldn't alloc cal result pkt");
1184 return;
1185 }
1186
1187 data->header.appId = ICM40600_APP_ID;
1188 data->header.dataLen = (sizeof(struct CalibrationData) - sizeof(struct HostHubRawPacket));
1189 data->data_header.msgId = SENSOR_APP_MSG_ID_CAL_RESULT;
1190 data->data_header.sensorType = sensorType;
1191 data->data_header.status = status;
1192
1193 data->xBias = xBias;
1194 data->yBias = yBias;
1195 data->zBias = zBias;
1196
1197 if (!osEnqueueEvtOrFree(EVT_APP_TO_HOST, data, heapFree))
1198 ERROR_PRINT("Couldn't send cal result evt");
1199 }
1200
1201 static void calibrationInit(TASK, enum SensorIndex idx)
1202 {
1203 uint8_t val;
1204
1205 // Disable Interrupt
1206 SPI_WRITE(REG_INT_SOURCE0, 0);
1207 SPI_WRITE(REG_INT_SOURCE1, 0);
1208
1209 // reset offset registers
1210 resetOffsetReg(_task, idx);
1211
1212 // stop FIFO
1213 calSelftestFifoEnable(_task, idx, false, 0);
1214
1215 // set rate
1216 SPI_WRITE(REG_GYRO_CONFIG0, (CALIBRATION_GYR_FS << SHIFT_GYRO_FS_SEL) |
1217 (CALIBRATION_ODR << SHIFT_ODR_CONF));
1218 SPI_WRITE(REG_ACCEL_CONFIG0, (CALIBRATION_ACC_FS << SHIFT_ACCEL_FS_SEL) |
1219 (CALIBRATION_ODR << SHIFT_ODR_CONF));
1220
1221 // set filter
1222 SPI_WRITE(REG_GYRO_ACCEL_CONFIG0, CALIBRATION_ACC_BW_IND | CALIBRATION_GYR_BW_IND);
1223
1224 // turn on sensors
1225 switch (idx) {
1226 case ACC:
1227 val = BIT_ACCEL_MODE_LN;
1228 break;
1229 case GYR:
1230 val = BIT_GYRO_MODE_LN;
1231 break;
1232 default:
1233 val = 0;
1234 break;
1235 }
1236 SPI_WRITE(REG_PWR_MGMT_0, val, 200 * 1000);
1237
1238 calSelftestFifoEnable(_task, idx, true, CALIBRATION_READ_INTERVAL_US);
1239 }
1240
1241 static void calibrationDeinit(TASK, enum SensorIndex idx)
1242 {
1243 calSelftestFifoEnable(_task, idx, false, 0);
1244
1245 SPI_WRITE(REG_GYRO_ACCEL_CONFIG0, ICM40600_ACC_BW_IND | ICM40600_GYR_BW_IND);
1246 SPI_WRITE(REG_PWR_MGMT_0, 0, 200); // 9136
1247
1248 // make register accesses happen when sensor is enabled next time
1249 T(config).gyro_rate = 0;
1250 T(config).accel_rate = 0;
1251 T(config).fifo_rate = 0;
1252 T(config).fifo_watermark = 0;
1253 T(config).accel_on = false;
1254 T(config).gyro_on = false;
1255 T(config).wom_on = false;
1256 }
1257
1258 static void calibrationHandling(TASK, enum SensorIndex idx)
1259 {
1260 const uint8_t *buf, *data;
1261 uint8_t int_status;
1262 uint16_t fifo_count;
1263 int i, t;
1264 bool r;
1265 int16_t raw_data[3] = { 0, 0, 0 };
1266
1267 if (idx != ACC && idx != GYR) {
1268 ERROR_PRINT("Invalid sensor index\n");
1269 return;
1270 }
1271
1272 switch (T(calibration_state)) {
1273 case CALIBRATION_START:
1274 T(mRetryLeft) = RETRY_CNT_CALIBRATION;
1275 calibrationInit(_task, idx);
1276 for (i = 0; i < 3; i++) {
1277 T(factory_cal).data[i] = 0;
1278 }
1279 SPI_READ(REG_INT_STATUS, 1, &T(dataBuffer[0]));
1280 SPI_READ(REG_FIFO_BYTE_COUNT1, 2, &T(dataBuffer[1]));
1281 T(calibration_state) = CALIBRATION_READ_STATUS;
1282 T(factory_cal).data_count = CALIBRATION_SAMPLE_NB;
1283 spiBatchTxRx(&T(mode), sensorSpiCallback, &T(sensors[idx]), __FUNCTION__);
1284 break;
1285 case CALIBRATION_READ_STATUS:
1286 buf = T(dataBuffer[0]);
1287 int_status = buf[1];
1288 buf = T(dataBuffer[1]);
1289 fifo_count = buf[2] << 8 | buf[1];
1290 fifo_count = fifo_count - fifo_count % T(config).fifo_sample_size;
1291 T(fifo_count) = fifo_count;
1292 DEBUG_PRINT("fifo_count = %d\n", fifo_count);
1293 if (int_status & BIT_INT_STATUS_FIFO_FULL) {
1294 ERROR_PRINT("fifo overflow\n");
1295 calibrationDeinit(_task, idx);
1296 T(calibration_state) = CALIBRATION_DONE;
1297 sendCalibrationResult(SENSOR_APP_EVT_STATUS_ERROR, mSensorInfo[idx].sensorType, 0, 0, 0);
1298 } else {
1299 T(calibration_state) = CALIBRATION_READ_DATA;
1300 SPI_READ(REG_FIFO_DATA, fifo_count, &T(dataBuffer[0]));
1301 }
1302 spiBatchTxRx(&T(mode), sensorSpiCallback, &T(sensors[idx]), __FUNCTION__);
1303 break;
1304 case CALIBRATION_READ_DATA:
1305 buf = T(dataBuffer[0]);
1306 data = &buf[1];
1307 for (i = 0; i < T(fifo_count); i += T(config).fifo_sample_size) {
1308 r = calSelftestGetOneData(idx, data, i, raw_data);
1309 if (r == false) {
1310 ERROR_PRINT("invalid data packet\n");
1311 calibrationDeinit(_task, idx);
1312 T(calibration_state) = CALIBRATION_DONE;
1313 sendCalibrationResult(SENSOR_APP_EVT_STATUS_ERROR, mSensorInfo[idx].sensorType, 0, 0, 0);
1314 break;
1315 }
1316 for (t = 0; t < 3; t++) {
1317 T(factory_cal).data[t] += raw_data[t];
1318 }
1319 T(factory_cal).data_count--;
1320 if (T(factory_cal).data_count == 0) {
1321 break;
1322 }
1323 }
1324 if (T(factory_cal).data_count > 0) {
1325 if (--T(mRetryLeft) == 0) {
1326 ERROR_PRINT("calibration timeout\n");
1327 calibrationDeinit(_task, idx);
1328 T(calibration_state) = CALIBRATION_DONE;
1329 sendCalibrationResult(SENSOR_APP_EVT_STATUS_ERROR, mSensorInfo[idx].sensorType, 0, 0, 0);
1330 } else {
1331 calSelftestFifoEnable(_task, idx, false, 0); // toggle FIFO to reset
1332 calSelftestFifoEnable(_task, idx, true, CALIBRATION_READ_INTERVAL_US);
1333 SPI_READ(REG_INT_STATUS, 1, &T(dataBuffer[0]));
1334 SPI_READ(REG_FIFO_BYTE_COUNT1, 2, &T(dataBuffer[1]));
1335 T(calibration_state) = CALIBRATION_READ_STATUS;
1336 }
1337 spiBatchTxRx(&T(mode), sensorSpiCallback, &T(sensors[idx]), __FUNCTION__);
1338 break;
1339 }
1340 T(calibration_state) = CALIBRATION_SET_OFFSET;
1341 // fall-through
1342 case CALIBRATION_SET_OFFSET:
1343 DEBUG_PRINT("calibration total: %ld, %ld, %ld, data count=%d\n",
1344 T(factory_cal).data[0],
1345 T(factory_cal).data[1],
1346 T(factory_cal).data[2],
1347 CALIBRATION_SAMPLE_NB);
1348 for (i = 0; i < 3; i++) {
1349 T(factory_cal).data[i] /= CALIBRATION_SAMPLE_NB;
1350 }
1351 DEBUG_PRINT("average: %ld, %ld, %ld\n",
1352 T(factory_cal).data[0],
1353 T(factory_cal).data[1],
1354 T(factory_cal).data[2]);
1355 if (idx == ACC) {
1356 // assume the largest data axis shows +1 or -1 gee
1357 t = 0;
1358 for (i = 0; i < 3; i++) {
1359 if (abs(T(factory_cal).data[i]) > abs(T(factory_cal).data[t]))
1360 t = i;
1361 }
1362 if (T(factory_cal).data[t] > 0) {
1363 DEBUG_PRINT("assume axis %d is %d\n", t, CALIBRATION_ACC_1G);
1364 T(factory_cal).data[t] -= CALIBRATION_ACC_1G;
1365 } else {
1366 DEBUG_PRINT("assume axis %d is %d\n", t, -CALIBRATION_ACC_1G);
1367 T(factory_cal).data[t] += CALIBRATION_ACC_1G;
1368 }
1369 }
1370 // set bias to offset registers
1371 for (i = 0; i < 3; i++) {
1372 T(sensors[idx]).offset[i] = T(factory_cal).data[i];
1373 }
1374 setOffsetReg(_task);
1375 calibrationDeinit(_task, idx);
1376
1377 sendCalibrationResult(SENSOR_APP_EVT_STATUS_SUCCESS,
1378 mSensorInfo[idx].sensorType,
1379 T(factory_cal).data[0],
1380 T(factory_cal).data[1],
1381 T(factory_cal).data[2]);
1382 INFO_PRINT("reported: %ld, %ld, %ld\n",
1383 T(factory_cal).data[0],
1384 T(factory_cal).data[1],
1385 T(factory_cal).data[2]);
1386 T(calibration_state) = CALIBRATION_DONE;
1387 spiBatchTxRx(&T(mode), sensorSpiCallback, &T(sensors[idx]), __FUNCTION__);
1388 break;
1389 default:
1390 break;
1391 }
1392 }
1393
1394 static bool accCalibration(void *cookie)
1395 {
1396 TDECL();
1397
1398 INFO_PRINT("Accel Calibration\n");
1399
1400 if (!T(powered) && trySwitchState(SENSOR_CALIBRATING)) {
1401 T(calibration_state) = CALIBRATION_START;
1402 calibrationHandling(_task, ACC);
1403 return true;
1404 } else {
1405 ERROR_PRINT("Cannot run calibration because sensor is busy\n");
1406 sendCalibrationResult(SENSOR_APP_EVT_STATUS_BUSY, SENS_TYPE_ACCEL, 0, 0, 0);
1407 return false;
1408 }
1409 }
1410
1411 static bool gyrCalibration(void *cookie)
1412 {
1413 TDECL();
1414
1415 INFO_PRINT("Gyro Calibration\n");
1416
1417 if (!T(powered) && trySwitchState(SENSOR_CALIBRATING)) {
1418 T(calibration_state) = CALIBRATION_START;
1419 calibrationHandling(_task, GYR);
1420 return true;
1421 } else {
1422 ERROR_PRINT("Cannot run calibration because sensor is busy\n");
1423 sendCalibrationResult(SENSOR_APP_EVT_STATUS_BUSY, SENS_TYPE_GYRO, 0, 0, 0);
1424 return false;
1425 }
1426 }
1427
1428 /*
1429 * Selftest
1430 */
1431 static void sendTestResult(uint8_t status, uint8_t sensorType)
1432 {
1433 struct TestResultData *data = heapAlloc(sizeof(struct TestResultData));
1434 if (!data) {
1435 ERROR_PRINT("Couldn't alloc test result packet");
1436 return;
1437 }
1438
1439 data->header.appId = ICM40600_APP_ID;
1440 data->header.dataLen = (sizeof(struct TestResultData) - sizeof(struct HostHubRawPacket));
1441 data->data_header.msgId = SENSOR_APP_MSG_ID_TEST_RESULT;
1442 data->data_header.sensorType = sensorType;
1443 data->data_header.status = status;
1444
1445 if (!osEnqueueEvtOrFree(EVT_APP_TO_HOST, data, heapFree))
1446 ERROR_PRINT("Couldn't send test result packet");
1447 }
1448
1449 static const uint16_t SelfTestEquation[256] = {
1450 2620, 2646, 2672, 2699, 2726, 2753, 2781, 2808,
1451 2837, 2865, 2894, 2923, 2952, 2981, 3011, 3041,
1452 3072, 3102, 3133, 3165, 3196, 3228, 3261, 3293,
1453 3326, 3359, 3393, 3427, 3461, 3496, 3531, 3566,
1454 3602, 3638, 3674, 3711, 3748, 3786, 3823, 3862,
1455 3900, 3939, 3979, 4019, 4059, 4099, 4140, 4182,
1456 4224, 4266, 4308, 4352, 4395, 4439, 4483, 4528,
1457 4574, 4619, 4665, 4712, 4759, 4807, 4855, 4903,
1458 4953, 5002, 5052, 5103, 5154, 5205, 5257, 5310,
1459 5363, 5417, 5471, 5525, 5581, 5636, 5693, 5750,
1460 5807, 5865, 5924, 5983, 6043, 6104, 6165, 6226,
1461 6289, 6351, 6415, 6479, 6544, 6609, 6675, 6742,
1462 6810, 6878, 6946, 7016, 7086, 7157, 7229, 7301,
1463 7374, 7448, 7522, 7597, 7673, 7750, 7828, 7906,
1464 7985, 8065, 8145, 8227, 8309, 8392, 8476, 8561,
1465 8647, 8733, 8820, 8909, 8998, 9088, 9178, 9270,
1466 9363, 9457, 9551, 9647, 9743, 9841, 9939, 10038,
1467 10139, 10240, 10343, 10446, 10550, 10656, 10763, 10870,
1468 10979, 11089, 11200, 11312, 11425, 11539, 11654, 11771,
1469 11889, 12008, 12128, 12249, 12371, 12495, 12620, 12746,
1470 12874, 13002, 13132, 13264, 13396, 13530, 13666, 13802,
1471 13940, 14080, 14221, 14363, 14506, 14652, 14798, 14946,
1472 15096, 15247, 15399, 15553, 15709, 15866, 16024, 16184,
1473 16346, 16510, 16675, 16842, 17010, 17180, 17352, 17526,
1474 17701, 17878, 18057, 18237, 18420, 18604, 18790, 18978,
1475 19167, 19359, 19553, 19748, 19946, 20145, 20347, 20550,
1476 20756, 20963, 21173, 21385, 21598, 21814, 22033, 22253,
1477 22475, 22700, 22927, 23156, 23388, 23622, 23858, 24097,
1478 24338, 24581, 24827, 25075, 25326, 25579, 25835, 26093,
1479 26354, 26618, 26884, 27153, 27424, 27699, 27976, 28255,
1480 28538, 28823, 29112, 29403, 29697, 29994, 30294, 30597,
1481 30903, 31212, 31524, 31839, 32157, 32479, 32804
1482 };
1483
1484 static void selfTestInit(TASK, enum SensorIndex idx)
1485 {
1486 uint8_t val;
1487
1488 // Disable Interrupt
1489 SPI_WRITE(REG_INT_SOURCE0, 0);
1490 SPI_WRITE(REG_INT_SOURCE1, 0);
1491
1492 // reset offset registers
1493 resetOffsetReg(_task, idx);
1494
1495 // stop FIFO
1496 calSelftestFifoEnable(_task, idx, false, 0);
1497
1498 // self-test mode set
1499 val = 0;
1500 if (T(self_test).st_mode) {
1501 if (idx == ACC) {
1502 val |= (BIT_TEST_AX_EN | BIT_TEST_AY_EN | BIT_TEST_AZ_EN);
1503 val |= BIT_SELF_TEST_REGULATOR_EN;
1504 } else if (idx == GYR) {
1505 val |= (BIT_TEST_GX_EN | BIT_TEST_GY_EN | BIT_TEST_GZ_EN);
1506 }
1507 }
1508 SPI_WRITE(REG_SELF_TEST_CONFIG, val);
1509
1510 // set rate
1511 SPI_WRITE(REG_GYRO_CONFIG0, (SELF_TEST_GYR_FS << SHIFT_GYRO_FS_SEL) |
1512 (SELF_TEST_ODR << SHIFT_ODR_CONF));
1513 SPI_WRITE(REG_ACCEL_CONFIG0, (SELF_TEST_ACC_FS << SHIFT_ACCEL_FS_SEL) |
1514 (SELF_TEST_ODR << SHIFT_ODR_CONF));
1515
1516 // set filter
1517 val = 0;
1518 if (idx == ACC) {
1519 val |= SELF_TEST_ACC_BW_IND;
1520 } else if (idx == GYR) {
1521 val |= SELF_TEST_GYR_BW_IND;
1522 }
1523 SPI_WRITE(REG_GYRO_ACCEL_CONFIG0, val);
1524
1525 // turn on sensors
1526 val = 0;
1527 if (idx == ACC) {
1528 val |= BIT_ACCEL_MODE_LN;
1529 } else if (idx == GYR) {
1530 val |= BIT_GYRO_MODE_LN;
1531 }
1532 SPI_WRITE(REG_PWR_MGMT_0, val, 200 * 1000);
1533
1534 calSelftestFifoEnable(_task, idx, true, SELF_TEST_READ_INTERVAL_US);
1535 }
1536
1537 static void selfTestDeinit(TASK, enum SensorIndex idx)
1538 {
1539 calSelftestFifoEnable(_task, idx, false, 0);
1540
1541 SPI_WRITE(REG_SELF_TEST_CONFIG, 0);
1542 SPI_WRITE(REG_GYRO_ACCEL_CONFIG0, ICM40600_ACC_BW_IND | ICM40600_GYR_BW_IND);
1543 SPI_WRITE(REG_PWR_MGMT_0, 0, 200); // 9136
1544
1545 // make register accesses happen when sensor is enabled next time
1546 T(config).gyro_rate = 0;
1547 T(config).accel_rate = 0;
1548 T(config).fifo_rate = 0;
1549 T(config).fifo_watermark = 0;
1550 T(config).accel_on = false;
1551 T(config).gyro_on = false;
1552 T(config).wom_on = false;
1553 }
1554
1555 static bool checkAccelSelftest(TASK)
1556 {
1557 int32_t st_res;
1558 uint32_t st_otp[3];
1559 int i;
1560 int32_t ratio;
1561 bool pass = true;
1562 bool otp_value_zero = false;
1563
1564 /* calculate ST_OTP */
1565 for (i = 0; i < 3; i++) {
1566 if (T(self_test.otp_st_data_accel[i] != 0))
1567 st_otp[i] = SelfTestEquation[T(self_test).otp_st_data_accel[i] - 1];
1568 else
1569 otp_value_zero = true;
1570 }
1571
1572 if (!otp_value_zero) {
1573 /* criteria a */
1574 for (i = 0; i < 3; i++) {
1575 st_res = T(self_test).data_st_on[i] - T(self_test).data_st_off[i];
1576 ratio = abs(st_res / st_otp[i] - SELF_TEST_PRECISION);
1577 if (ratio >= SELF_TEST_ACC_SHIFT_DELTA) {
1578 INFO_PRINT("error accel[%d] : st_res = %ld, st_otp = %ld\n", i, st_res, st_otp[i]);
1579 pass = false;
1580 }
1581 }
1582 } else {
1583 /* criteria b */
1584 for (i = 0; i < 3; i++) {
1585 st_res = abs(T(self_test).data_st_on[i] - T(self_test).data_st_off[i]);
1586 if (st_res < SELF_TEST_MIN_ACC || st_res > SELF_TEST_MAX_ACC) {
1587 INFO_PRINT("error accel[%d] : st_res = %ld, min = %d, max = %d\n", i, st_res, SELF_TEST_MIN_ACC, SELF_TEST_MAX_ACC);
1588 pass = false;
1589 }
1590 }
1591 }
1592
1593 return pass;
1594 }
1595
1596 static bool checkGyroSelftest(TASK)
1597 {
1598 int32_t st_res;
1599 uint32_t st_otp[3];
1600 int i;
1601 bool pass = true;
1602 bool otp_value_zero = false;
1603
1604 /* calculate ST_OTP */
1605 for (i = 0; i < 3; i++) {
1606 if (T(self_test).otp_st_data_gyro[i] != 0)
1607 st_otp[i] = SelfTestEquation[T(self_test).otp_st_data_gyro[i] - 1];
1608 else
1609 otp_value_zero = true;
1610 }
1611
1612 if (!otp_value_zero) {
1613 /* criteria a */
1614 for (i = 0; i < 3; i++) {
1615 st_res = T(self_test).data_st_on[i] - T(self_test).data_st_off[i];
1616 if (st_res <= st_otp[i] * SELF_TEST_GYR_SHIFT_DELTA) {
1617 INFO_PRINT("error gyro[%d] : st_res = %ld, st_otp = %ld\n", i, st_res, st_otp[i]);
1618 pass = false;
1619 }
1620 }
1621 } else {
1622 /* criteria b */
1623 for (i = 0; i < 3; i++) {
1624 st_res = abs(T(self_test).data_st_on[i] - T(self_test).data_st_off[i]);
1625 if (st_res < SELF_TEST_MIN_GYR) {
1626 INFO_PRINT("error gyro[%d] : st_res = %ld, min = %d\n", i, st_res, SELF_TEST_MIN_GYR);
1627 pass = false;
1628 }
1629 }
1630 }
1631
1632 if (pass) {
1633 /* criteria c */
1634 for (i = 0; i < 3; i++) {
1635 if (abs(T(self_test).data_st_off[i]) > SELF_TEST_MAX_GYR_OFFSET) {
1636 INFO_PRINT("error gyro[%d] = %d, max = %d\n", i, abs(T(self_test).data_st_off[i]), SELF_TEST_MAX_GYR_OFFSET);
1637 pass = false;
1638 }
1639 }
1640 }
1641
1642 return pass;
1643 }
1644
1645 static void selfTestHandling(TASK, enum SensorIndex idx)
1646 {
1647 const uint8_t *buf, *data;
1648 uint8_t int_status;
1649 uint16_t fifo_count;
1650 int i, t;
1651 bool r;
1652 int16_t raw_data[3] = { 0, 0, 0 };
1653 bool pass;
1654
1655 if (idx != ACC && idx != GYR) {
1656 ERROR_PRINT("Invalid sensor index\n");
1657 return;
1658 }
1659
1660 switch (T(selftest_state)) {
1661 case TEST_START:
1662 T(mRetryLeft) = RETRY_CNT_SELF_TEST;
1663 selfTestInit(_task, idx);
1664 for (i = 0; i < 3; i++) {
1665 T(self_test).data[i] = 0;
1666 }
1667 SPI_READ(REG_INT_STATUS, 1, &T(dataBuffer[0]));
1668 SPI_READ(REG_FIFO_BYTE_COUNT1, 2, &T(dataBuffer[1]));
1669 T(selftest_state) = TEST_READ_STATUS;
1670 T(self_test).data_count = SELF_TEST_SAMPLE_NB;
1671 spiBatchTxRx(&T(mode), sensorSpiCallback, &T(sensors[idx]), __FUNCTION__);
1672 break;
1673 case TEST_READ_STATUS:
1674 buf = T(dataBuffer[0]);
1675 int_status = buf[1];
1676 buf = T(dataBuffer[1]);
1677 fifo_count = buf[2] << 8 | buf[1];
1678 fifo_count = fifo_count - fifo_count % T(config).fifo_sample_size;
1679 T(fifo_count) = fifo_count;
1680 DEBUG_PRINT("fifo_count = %d\n", fifo_count);
1681 if (int_status & BIT_INT_STATUS_FIFO_FULL) {
1682 ERROR_PRINT("fifo overflow\n");
1683 selfTestDeinit(_task, idx);
1684 T(selftest_state) = TEST_DONE;
1685 sendTestResult(SENSOR_APP_EVT_STATUS_ERROR, mSensorInfo[idx].sensorType);
1686 } else {
1687 T(selftest_state) = TEST_READ_DATA;
1688 SPI_READ(REG_FIFO_DATA, fifo_count, &T(dataBuffer[0]));
1689 }
1690 spiBatchTxRx(&T(mode), sensorSpiCallback, &T(sensors[idx]), __FUNCTION__);
1691 break;
1692 case TEST_READ_DATA:
1693 buf = T(dataBuffer[0]);
1694 data = &buf[1];
1695 for (i = 0; i < T(fifo_count); i += T(config).fifo_sample_size) {
1696 r = calSelftestGetOneData(idx, data, i, raw_data);
1697 if (r == false) {
1698 ERROR_PRINT("invalid data packet\n");
1699 selfTestDeinit(_task, idx);
1700 T(selftest_state) = TEST_DONE;
1701 sendTestResult(SENSOR_APP_EVT_STATUS_ERROR, mSensorInfo[idx].sensorType);
1702 break;
1703 }
1704 for (t = 0; t < 3; t++) {
1705 T(self_test).data[t] += raw_data[t];
1706 }
1707 T(self_test).data_count--;
1708 if (T(self_test).data_count == 0) {
1709 break;
1710 }
1711 }
1712 if (T(self_test).data_count > 0) {
1713 if (--T(mRetryLeft) == 0) {
1714 ERROR_PRINT("selftest timeout\n");
1715 selfTestDeinit(_task, idx);
1716 T(selftest_state) = TEST_DONE;
1717 sendTestResult(SENSOR_APP_EVT_STATUS_ERROR, mSensorInfo[idx].sensorType);
1718 } else {
1719 calSelftestFifoEnable(_task, idx, false, 0); // toggle FIFO to reset
1720 calSelftestFifoEnable(_task, idx, true, SELF_TEST_READ_INTERVAL_US);
1721 SPI_READ(REG_INT_STATUS, 1, &T(dataBuffer[0]));
1722 SPI_READ(REG_FIFO_BYTE_COUNT1, 2, &T(dataBuffer[1]));
1723 T(selftest_state) = TEST_READ_STATUS;
1724 }
1725 spiBatchTxRx(&T(mode), sensorSpiCallback, &T(sensors[idx]), __FUNCTION__);
1726 break;
1727 }
1728 T(selftest_state) = TEST_READ_OTP;
1729 // fall-through
1730 case TEST_READ_OTP:
1731 for (i = 0; i < 3; i++) {
1732 T(self_test).data[i] = T(self_test).data[i] / SELF_TEST_SAMPLE_NB * SELF_TEST_PRECISION;
1733 }
1734 INFO_PRINT("st_mode=%d average (scaled) : %ld, %ld, %ld\n",
1735 T(self_test).st_mode,
1736 T(self_test).data[0],
1737 T(self_test).data[1],
1738 T(self_test).data[2]);
1739
1740 selfTestDeinit(_task, idx);
1741
1742 for (i = 0; i < 3; i++) {
1743 if (T(self_test).st_mode) {
1744 T(self_test).data_st_on[i] = T(self_test).data[i];
1745 } else {
1746 T(self_test).data_st_off[i] = T(self_test).data[i];
1747 }
1748 }
1749
1750 // Run again with self-test mode on
1751 if (!T(self_test).st_mode) {
1752 T(self_test).st_mode = true;
1753 T(selftest_state) = TEST_START;
1754 } else {
1755 INFO_PRINT("st mode on : %ld %ld %ld\n",
1756 T(self_test).data_st_on[0],
1757 T(self_test).data_st_on[1],
1758 T(self_test).data_st_on[2]);
1759 INFO_PRINT("st mode off : %ld %ld %ld\n",
1760 T(self_test).data_st_off[0],
1761 T(self_test).data_st_off[1],
1762 T(self_test).data_st_off[2]);
1763
1764 // read OTP
1765 if (idx == ACC) {
1766 SPI_WRITE(REG_REG_BANK_SEL, BIT_BANK_SEL_2);
1767 SPI_READ(REG_XA_ST_DATA, 3, &T(dataBuffer[0]));
1768 } else if (idx == GYR) {
1769 SPI_WRITE(REG_REG_BANK_SEL, BIT_BANK_SEL_1);
1770 SPI_READ(REG_XG_ST_DATA, 3, &T(dataBuffer[0]));
1771 }
1772 SPI_WRITE(REG_REG_BANK_SEL, BIT_BANK_SEL_0);
1773
1774 T(selftest_state) = TEST_REPORT;
1775 }
1776 spiBatchTxRx(&T(mode), sensorSpiCallback, &T(sensors[idx]), __FUNCTION__);
1777 break;
1778 case TEST_REPORT:
1779 buf = T(dataBuffer[0]);
1780 if (idx == ACC) {
1781 T(self_test).otp_st_data_accel[0] = buf[1];
1782 T(self_test).otp_st_data_accel[1] = buf[2];
1783 T(self_test).otp_st_data_accel[2] = buf[3];
1784 INFO_PRINT("otp accel : %d %d %d\n",
1785 T(self_test).otp_st_data_accel[0],
1786 T(self_test).otp_st_data_accel[1],
1787 T(self_test).otp_st_data_accel[2]);
1788 } else if (idx == GYR) {
1789 T(self_test).otp_st_data_gyro[0] = buf[1];
1790 T(self_test).otp_st_data_gyro[1] = buf[2];
1791 T(self_test).otp_st_data_gyro[2] = buf[3];
1792 INFO_PRINT("otp gyro : %d %d %d\n",
1793 T(self_test).otp_st_data_gyro[0],
1794 T(self_test).otp_st_data_gyro[1],
1795 T(self_test).otp_st_data_gyro[2]);
1796 }
1797
1798 pass = false;
1799 if (idx == ACC) {
1800 pass = checkAccelSelftest(_task);
1801 } else if (idx == GYR) {
1802 pass = checkGyroSelftest(_task);
1803 }
1804 if (pass) {
1805 sendTestResult(SENSOR_APP_EVT_STATUS_SUCCESS,
1806 mSensorInfo[idx].sensorType);
1807 } else {
1808 sendTestResult(SENSOR_APP_EVT_STATUS_ERROR,
1809 mSensorInfo[idx].sensorType);
1810 }
1811
1812 T(selftest_state) = TEST_DONE;
1813 selfTestDeinit(_task, idx);
1814 spiBatchTxRx(&T(mode), sensorSpiCallback, &T(sensors[idx]), __FUNCTION__);
1815 break;
1816 default:
1817 break;
1818 }
1819 }
1820
1821 static bool accSelfTest(void *cookie)
1822 {
1823 TDECL();
1824
1825 INFO_PRINT("Accel Selftest\n");
1826
1827 if (!T(powered) && trySwitchState(SENSOR_TESTING)) {
1828 T(self_test).st_mode = false;
1829 T(selftest_state) = TEST_START;
1830 selfTestHandling(_task, ACC);
1831 return true;
1832 } else {
1833 ERROR_PRINT("cannot test accel because sensor is busy\n");
1834 sendTestResult(SENSOR_APP_EVT_STATUS_BUSY, SENS_TYPE_ACCEL);
1835 return false;
1836 }
1837 }
1838
1839 static bool gyrSelfTest(void *cookie)
1840 {
1841 TDECL();
1842
1843 INFO_PRINT("Gyro Selftest\n");
1844
1845 if (!T(powered) && trySwitchState(SENSOR_TESTING)) {
1846 T(self_test).st_mode = false;
1847 T(selftest_state) = TEST_START;
1848 selfTestHandling(_task, GYR);
1849 return true;
1850 } else {
1851 ERROR_PRINT("cannot test accel because sensor is busy\n");
1852 sendTestResult(SENSOR_APP_EVT_STATUS_BUSY, SENS_TYPE_GYRO);
1853 return false;
1854 }
1855 }
1856
1857 static bool sensorFirmwareUpload(void *cookie)
1858 {
1859 TDECL();
1860 int i = (long int)cookie;
1861
1862 sensorSignalInternalEvt(T(sensors[i]).handle, SENSOR_INTERNAL_EVT_FW_STATE_CHG, 1, 0);
1863
1864 return true;
1865 }
1866
1867 static bool enableInterrupt(struct Gpio *pin, IRQn_Type irq, struct ChainedIsr *isr)
1868 {
1869 gpioConfigInput(pin, GPIO_SPEED_LOW, GPIO_PULL_NONE);
1870 syscfgSetExtiPort(pin);
1871 extiEnableIntGpio(pin, EXTI_TRIGGER_RISING);
1872 extiChainIsr(irq, isr);
1873 return true;
1874 }
1875
1876 static bool disableInterrupt(struct Gpio *pin, IRQn_Type irq, struct ChainedIsr *isr)
1877 {
1878 extiUnchainIsr(irq, isr);
1879 extiDisableIntGpio(pin);
1880 return true;
1881 }
1882
1883 static void configInt1(TASK, bool on)
1884 {
1885 enum SensorIndex i;
1886 bool powered = false;
1887
1888 if (on && !T(Int1_EN)) {
1889 enableInterrupt(T(Int1), T(Irq1), &T(Isr1));
1890 T(Int1_EN) = true;
1891 } else if (!on && T(Int1_EN)) {
1892 for (i = 0; i < NUM_OF_SENSOR; i++) {
1893 if (T(sensors[i]).powered) {
1894 powered = true;
1895 break;
1896 }
1897 }
1898 if (!powered) {
1899 disableInterrupt(T(Int1), T(Irq1), &T(Isr1));
1900 T(Int1_EN) = false;
1901 }
1902 }
1903 }
1904
1905 static uint8_t computeOdrConf(uint32_t rate)
1906 {
1907 switch (rate) {
1908 case SENSOR_HZ(1000.0f):
1909 return 6;
1910 case SENSOR_HZ(200.0f):
1911 return 7;
1912 case SENSOR_HZ(100.0f):
1913 return 8;
1914 case SENSOR_HZ(50.0f):
1915 return 9;
1916 case SENSOR_HZ(25.0f):
1917 default:
1918 return 10;
1919 }
1920 }
1921
1922 static void computeConfig(TASK, struct ICM40600Config *config)
1923 {
1924 uint64_t latency;
1925 uint64_t val;
1926 uint32_t latency_ms;
1927 int i;
1928
1929 // copy current parameters
1930 *config = T(config);
1931
1932 // compute sensors on
1933 if (T(sensors[ACC]).configed || T(sensors[WOM]).configed || T(sensors[NOMO]).configed) {
1934 config->accel_on = true;
1935 } else {
1936 config->accel_on = false;
1937 }
1938 config->gyro_on = T(sensors[GYR]).configed;
1939 if (T(sensors[WOM]).configed || T(sensors[NOMO]).configed) {
1940 config->wom_on = true;
1941 } else {
1942 config->wom_on = false;
1943 }
1944
1945 // compute accel and gyro rates
1946 if (config->accel_on) {
1947 if (T(sensors[ACC]).configed) {
1948 if (T(sensors[ACC]).rate > NO_DECIMATION_MAX_RATE) {
1949 config->accel_rate = DECIMATION_HIGH_RATE;
1950 } else if (T(sensors[ACC]).rate < NO_DECIMATION_MIN_RATE) {
1951 config->accel_rate = DECIMATION_LOW_RATE;
1952 } else {
1953 config->accel_rate = T(sensors[ACC]).rate;
1954 }
1955 } else {
1956 config->accel_rate = NO_DECIMATION_MIN_RATE;
1957 }
1958 }
1959 if (config->gyro_on) {
1960 if (T(sensors[GYR]).configed) {
1961 if (T(sensors[GYR]).rate > NO_DECIMATION_MAX_RATE) {
1962 config->gyro_rate = DECIMATION_HIGH_RATE;
1963 } else if (T(sensors[GYR]).rate < NO_DECIMATION_MIN_RATE) {
1964 config->gyro_rate = DECIMATION_LOW_RATE;
1965 } else {
1966 config->gyro_rate = T(sensors[GYR]).rate;
1967 }
1968 } else {
1969 config->gyro_rate = NO_DECIMATION_MIN_RATE;
1970 }
1971 }
1972
1973 // compute wom threshold
1974 if (config->wom_on) {
1975 config->wom_threshold = ICM40600_WOM_THRESHOLD_MG / (config->accel_rate / NO_DECIMATION_MIN_RATE);
1976 }
1977
1978 // compute fifo configuration
1979 if (T(sensors[ACC]).configed || T(sensors[GYR]).configed) {
1980 config->fifo_sample_size = FIFO_PACKET_SIZE;
1981 } else {
1982 config->fifo_sample_size = 0;
1983 }
1984
1985 // compute fifo rate and latency/watermark
1986 config->fifo_rate = 0;
1987 latency = SENSOR_LATENCY_NODATA;
1988 for (i = FIRST_CONT_SENSOR; i < NUM_CONT_SENSOR; ++i) {
1989 if (T(sensors[i]).configed) {
1990 // look for the highest rate
1991 if (T(sensors[i]).rate > config->fifo_rate) {
1992 config->fifo_rate = T(sensors[i]).rate;
1993 }
1994 // look for the shortest latency
1995 if (T(sensors[i]).latency < latency) {
1996 latency = T(sensors[i]).latency;
1997 }
1998 }
1999 }
2000 if (config->fifo_rate > NO_DECIMATION_MAX_RATE) {
2001 config->fifo_rate = DECIMATION_HIGH_RATE;
2002 } else if (config->fifo_rate < NO_DECIMATION_MIN_RATE) {
2003 config->fifo_rate = DECIMATION_LOW_RATE;
2004 }
2005
2006 // add 0.5ms for rounding
2007 latency_ms = cpuMathU64DivByU16(cpuMathU64DivByU16(latency + 500000, 1000), 1000);
2008 val = (uint64_t)latency_ms * (uint64_t)config->fifo_rate;
2009 config->fifo_watermark = cpuMathU64DivByU16(cpuMathU64DivByU16(val, 1000), RATE_TO_HZ);
2010 config->fifo_watermark *= config->fifo_sample_size;
2011 if (config->fifo_watermark < config->fifo_sample_size) {
2012 config->fifo_watermark = config->fifo_sample_size;
2013 }
2014 if (config->fifo_watermark > MAX_BATCH_SIZE) {
2015 config->fifo_watermark = MAX_BATCH_SIZE - (MAX_BATCH_SIZE % config->fifo_sample_size);
2016 }
2017 }
2018
2019 static void updateConfig(TASK, const struct ICM40600Config *config)
2020 {
2021 uint32_t delay_us;
2022 uint8_t val, val2;
2023
2024 // Disable Interrupt
2025 SPI_WRITE(REG_INT_SOURCE0, 0);
2026 SPI_WRITE(REG_INT_SOURCE1, 0);
2027
2028 // set rate and WoM threshold
2029 if (config->gyro_rate != T(config).gyro_rate) {
2030 val = computeOdrConf(config->gyro_rate);
2031 SPI_WRITE(REG_GYRO_CONFIG0, (ICM40600_GYR_FS << SHIFT_GYRO_FS_SEL) |
2032 (val << SHIFT_ODR_CONF));
2033 }
2034 if (config->accel_rate != T(config).accel_rate) {
2035 val = computeOdrConf(config->accel_rate);
2036 SPI_WRITE(REG_ACCEL_CONFIG0, (ICM40600_ACC_FS << SHIFT_ACCEL_FS_SEL) |
2037 (val << SHIFT_ODR_CONF));
2038 }
2039 if (config->wom_threshold != T(config).wom_threshold) {
2040 val = ICM40600_WOM_COMPUTE(config->wom_threshold);
2041 SPI_WRITE(REG_ACCEL_WOM_X_THR, val);
2042 SPI_WRITE(REG_ACCEL_WOM_Y_THR, val);
2043 SPI_WRITE(REG_ACCEL_WOM_Z_THR, val);
2044 }
2045
2046 // set WM
2047 if (config->fifo_watermark != T(config).fifo_watermark) {
2048 SPI_WRITE(REG_FIFO_CONFIG2, config->fifo_watermark & 0xFF);
2049 SPI_WRITE(REG_FIFO_CONFIG3, (config->fifo_watermark >> 8) & 0xFF);
2050 }
2051
2052 // turn on/off accel and gyro if any change
2053 if (config->gyro_on != T(config).gyro_on || config->accel_on != T(config).accel_on) {
2054 val = 0;
2055 if (config->gyro_on) {
2056 val |= BIT_GYRO_MODE_LN;
2057 }
2058 if (config->accel_on) {
2059 val |= BIT_ACCEL_MODE_LN;
2060 }
2061 // delay needed if gyro or accel turning on
2062 if ((config->gyro_on && !T(config).gyro_on) || (config->accel_on && !T(config).accel_on)) {
2063 delay_us = 200; // 9136
2064 } else {
2065 delay_us = 0;
2066 }
2067 SPI_WRITE(REG_PWR_MGMT_0, val, delay_us);
2068 }
2069
2070 // turn on/off WOM
2071 if (config->wom_on != T(config).wom_on) {
2072 if (config->wom_on) {
2073 val = BIT_WOM_INT_MODE_OR | BIT_WOM_MODE_PREV | BIT_SMD_MODE_OLD;
2074 } else {
2075 val = 0;
2076 }
2077 SPI_WRITE(REG_SMD_CONFIG, val);
2078 }
2079
2080 // turn on/off FIFO
2081 if (config->fifo_sample_size != T(config).fifo_sample_size) {
2082 if (config->fifo_sample_size != 0) {
2083 // enabling FIFO
2084 val = BIT_FIFO_MODE_STREAM;
2085 val2 = BIT_FIFO_ACCEL_EN | BIT_FIFO_GYRO_EN | BIT_FIFO_TEMP_EN |
2086 BIT_FIFO_TMST_FSYNC_EN | BIT_FIFO_WM_TH;
2087 // reset chip time
2088 T(chip_time_us) = 0;
2089 T(chip_timestamp) = 0;
2090 T(fifo_start_sync) = true;
2091 invalidate_sensortime_to_rtc_time(_task);
2092 } else {
2093 // disabling FIFO
2094 val = BIT_FIFO_MODE_BYPASS;
2095 val2 = 0;
2096 }
2097 SPI_WRITE(REG_FIFO_CONFIG, val);
2098 SPI_WRITE(REG_FIFO_CONFIG1, val2);
2099 if (val == BIT_FIFO_MODE_BYPASS) {
2100 SPI_READ(REG_FIFO_BYTE_COUNT1, 2, &T(dataBuffer[0])); // 9052
2101 }
2102 }
2103
2104 // enable/disable FIFO data interrupt
2105 if (config->fifo_sample_size != 0) {
2106 val = BIT_INT_FIFO_THS_INT1_EN;
2107 } else {
2108 val = 0;
2109 }
2110 SPI_WRITE(REG_INT_SOURCE0, val);
2111
2112 // enable/disable WOM interrupt (only when FIFO disabled or batch mode)
2113 if (config->wom_on && (config->fifo_sample_size == 0 || config->fifo_watermark > config->fifo_sample_size)) {
2114 val = BIT_INT_WOM_XYZ_INT1_EN;
2115 } else {
2116 val = 0;
2117 }
2118 SPI_WRITE(REG_INT_SOURCE1, val);
2119 }
2120
2121 static void applyConfig(TASK, const struct ICM40600Config *config)
2122 {
2123 uint32_t duration_us;
2124 uint32_t decimator;
2125 int i;
2126
2127 // setup wait for odr change
2128 if (config->accel_rate != T(config).accel_rate) {
2129 T(sensors[ACC]).wait_for_odr = true;
2130 }
2131 if (config->gyro_rate != T(config).gyro_rate) {
2132 T(sensors[GYR]).wait_for_odr = true;
2133 }
2134
2135 // setup first samples skip
2136 if (config->gyro_on && !T(config).gyro_on) {
2137 // gyro turning on
2138 duration_us = (1000000 * RATE_TO_HZ) / config->gyro_rate;
2139 if (duration_us * GYR_SKIP_SAMPLE_NB > ICM40600_GYRO_START_TIME_MS * 1000) {
2140 T(sensors[GYR]).skip_sample_cnt = GYR_SKIP_SAMPLE_NB;
2141 } else {
2142 T(sensors[GYR]).skip_sample_cnt = (ICM40600_GYRO_START_TIME_MS * 1000) / duration_us;
2143 if ((ICM40600_GYRO_START_TIME_MS * 1000) % duration_us) {
2144 T(sensors[GYR]).skip_sample_cnt++;
2145 }
2146 }
2147 }
2148 if (config->accel_on && !T(config).accel_on) {
2149 // accel turning on
2150 duration_us = (1000000 * RATE_TO_HZ) / config->accel_rate;
2151 if (duration_us * ACC_SKIP_SAMPLE_NB > ICM40600_ACCEL_START_TIME_MS * 1000) {
2152 T(sensors[ACC]).skip_sample_cnt = ACC_SKIP_SAMPLE_NB;
2153 } else {
2154 T(sensors[ACC]).skip_sample_cnt = (ICM40600_ACCEL_START_TIME_MS * 1000) / duration_us;
2155 if ((ICM40600_ACCEL_START_TIME_MS * 1000) % duration_us) {
2156 T(sensors[ACC]).skip_sample_cnt++;
2157 }
2158 }
2159 }
2160
2161 // update all sensors decimators
2162 for (i = 0; i <= GYR; i++) {
2163 if (!T(sensors[i]).configed || T(sensors[i]).rate == 0) {
2164 decimator = 1;
2165 } else {
2166 if (i == ACC) {
2167 decimator = config->accel_rate / T(sensors[i]).rate;
2168 } else if (i == GYR) {
2169 decimator = config->gyro_rate / T(sensors[i]).rate;
2170 }
2171 }
2172 if (decimator != T(sensors[i]).decimator) {
2173 T(sensors[i]).decimator = decimator;
2174 T(sensors[i]).data_cnt = 0;
2175 }
2176 }
2177
2178 // setup NOMO timer
2179 if (T(sensors[NOMO]).configed && !T(noMotionTimerHandle)) {
2180 T(noMotionTimerHandle) = timTimerSet(ICM40600_NOM_DURATION_NS, 0, 100, noMotionCallback, &T(sensors[NOMO]), false);
2181 } else if (!T(sensors[NOMO]).configed && T(noMotionTimerHandle)) {
2182 timTimerCancel(T(noMotionTimerHandle));
2183 T(noMotionTimerHandle) = 0;
2184 }
2185
2186 // update config
2187 T(config) = *config;
2188
2189 DEBUG_PRINT("config: accel(%d, %luHz/%u), gyro(%d, %luHz/%u), wom(%d, %lu), "
2190 "fifo(%u/%u, %luHz)\n",
2191 T(config).accel_on, T(config).accel_rate / RATE_TO_HZ, T(sensors[ACC]).decimator,
2192 T(config).gyro_on, T(config).gyro_rate / RATE_TO_HZ, T(sensors[GYR]).decimator,
2193 T(config).wom_on, T(config).wom_threshold,
2194 T(config).fifo_sample_size, T(config).fifo_watermark, T(config).fifo_rate / RATE_TO_HZ);
2195 }
2196
2197 static void configSensor(TASK)
2198 {
2199 struct ICM40600Config config;
2200
2201 computeConfig(_task, &config);
2202 updateConfig(_task, &config);
2203 applyConfig(_task, &config);
2204 }
2205
2206 static void sensorTurnOn(TASK)
2207 {
2208 /* enable chip timestamp */
2209 SPI_WRITE(REG_TMST_CONFIG, BIT_EN_DREG_FIFO_D2A | BIT_TMST_EN);
2210
2211 T(powered) = true;
2212 #if DBG_TIMESTAMP
2213 memset(&T(statistics_set), 0, sizeof(struct StatisticsSet));
2214 #endif
2215 DEBUG_PRINT("chip on\n");
2216 }
2217
2218 static void sensorTurnOff(TASK)
2219 {
2220 /* disable chip timestamp */
2221 SPI_WRITE(REG_TMST_CONFIG, BIT_EN_DREG_FIFO_D2A);
2222
2223 T(powered) = false;
2224 #if DBG_TIMESTAMP
2225 DEBUG_PRINT("time sync stats: reset: %ld, sync: %ld, adjust+: %ld, adjust-: %ld, truncate: %ld\n",
2226 T(statistics_set).sync_reset_count,
2227 T(statistics_set).sync_count,
2228 T(statistics_set).sync_adjust_plus,
2229 T(statistics_set).sync_adjust_minus,
2230 T(statistics_set).sync_truncate);
2231 #endif
2232 DEBUG_PRINT("chip off\n");
2233 }
2234
2235 static void sensorPower(TASK, int sensorType, bool on)
2236 {
2237 bool chip_on;
2238 int i;
2239
2240 if (on) {
2241 // turn on chip if needed
2242 if (!T(powered)) {
2243 sensorTurnOn(_task);
2244 }
2245 } else {
2246 // change chip configuration
2247 configSensor(_task);
2248 // turn chip off if needed
2249 chip_on = false;
2250 for (i = 0; i < NUM_OF_SENSOR; ++i) {
2251 if (T(sensors[i]).powered) {
2252 chip_on = true;
2253 break;
2254 }
2255 }
2256 if (!chip_on) {
2257 sensorTurnOff(_task);
2258 }
2259 }
2260 }
2261
2262 static bool sensorSetPower(bool on, void *cookie)
2263 {
2264 TDECL();
2265 int sensor_type = (int)cookie;
2266 struct ICM40600Sensor *sensor = &T(sensors[sensor_type]);
2267
2268 DEBUG_PRINT("%s: on=%d, state=%" PRI_STATE "\n", mSensorInfo[sensor_type].sensorName, on, getStateName(GET_STATE()));
2269
2270 if (trySwitchState(on ? SENSOR_POWERING_UP : SENSOR_POWERING_DOWN)) {
2271 sensor->powered = on;
2272 if (!on) {
2273 sensor->configed = false;
2274 }
2275 configInt1(_task, on);
2276 sensorPower(_task, sensor_type, on);
2277 spiBatchTxRx(&T(mode), sensorSpiCallback, sensor, __FUNCTION__);
2278 } else {
2279 T(pending_config[sensor_type]) = true;
2280 sensor->pConfig.enable = on;
2281 }
2282
2283 return true;
2284 }
2285
2286 static bool sensorSetRate(uint32_t rate, uint64_t latency, void *cookie)
2287 {
2288 TDECL();
2289 int sensor_type = (int)cookie;
2290 struct ICM40600Sensor *sensor = &T(sensors[sensor_type]);
2291
2292 DEBUG_PRINT("%s: rate=%lu, latency=%llu, state=%" PRI_STATE "\n",
2293 mSensorInfo[sensor_type].sensorName, rate, latency, getStateName(GET_STATE()));
2294
2295 if (trySwitchState(SENSOR_CONFIG_CHANGING)) {
2296 sensor->rate = rate;
2297 sensor->latency = latency;
2298 sensor->configed = true;
2299 configSensor(_task);
2300 spiBatchTxRx(&T(mode), sensorSpiCallback, sensor, __FUNCTION__);
2301 } else {
2302 T(pending_config[sensor_type]) = true;
2303 sensor->pConfig.enable = sensor->powered;
2304 sensor->pConfig.rate = rate;
2305 sensor->pConfig.latency = latency;
2306 }
2307
2308 return true;
2309 }
2310
2311 static void sendFlushEvt(void)
2312 {
2313 TDECL();
2314 uint32_t evtType = 0;
2315 int i;
2316
2317 for (i = FIRST_CONT_SENSOR; i < NUM_CONT_SENSOR; i++) {
2318 while (T(sensors[i]).flush > 0) {
2319 evtType = sensorGetMyEventType(mSensorInfo[i].sensorType);
2320 osEnqueueEvt(evtType, SENSOR_DATA_EVENT_FLUSH, NULL);
2321 T(sensors[i]).flush--;
2322 }
2323 }
2324 }
2325
2326 static void int1Evt(TASK, bool flush);
2327
2328 static bool flushSensor(void *cookie)
2329 {
2330 TDECL();
2331 int sensor_idx = (int)cookie;
2332 uint32_t evtType;
2333
2334 DEBUG_PRINT("%s flush\n", mSensorInfo[sensor_idx].sensorName);
2335
2336 if (sensor_idx >= FIRST_CONT_SENSOR && sensor_idx < NUM_CONT_SENSOR) {
2337 T(sensors[sensor_idx]).flush++;
2338 int1Evt(_task, true);
2339 return true;
2340 }
2341 if (sensor_idx >= FIRST_ONESHOT_SENSOR && sensor_idx < NUM_OF_SENSOR) {
2342 evtType = sensorGetMyEventType(mSensorInfo[sensor_idx].sensorType);
2343 osEnqueueEvt(evtType, SENSOR_DATA_EVENT_FLUSH, NULL);
2344 return true;
2345 }
2346
2347 return false;
2348 }
2349
2350 static bool flushData(struct ICM40600Sensor *sensor, uint32_t eventId)
2351 {
2352 bool success = false;
2353
2354 if (sensor->data_evt) {
2355 success = osEnqueueEvtOrFree(eventId, sensor->data_evt, dataEvtFree);
2356 sensor->data_evt = NULL;
2357 }
2358
2359 return success;
2360 }
2361
2362 static void flushAllData(void)
2363 {
2364 TDECL();
2365 int i;
2366
2367 for (i = FIRST_CONT_SENSOR; i < NUM_CONT_SENSOR; i++) {
2368 flushData(&T(sensors[i]),
2369 EVENT_TYPE_BIT_DISCARDABLE | sensorGetMyEventType(mSensorInfo[i].sensorType));
2370 }
2371 }
2372
2373 static bool allocateDataEvt(struct ICM40600Sensor *mSensor, uint64_t rtc_time)
2374 {
2375 TDECL();
2376
2377 mSensor->data_evt = slabAllocatorAlloc(T(mDataSlab));
2378 if (mSensor->data_evt == NULL) {
2379 // slab allocation failed
2380 ERROR_PRINT("slabAllocatorAlloc() failed\n");
2381 return false;
2382 }
2383
2384 // delta time for the first sample is sample count
2385 memset(&mSensor->data_evt->samples[0].firstSample, 0x00, sizeof(struct SensorFirstSample));
2386 mSensor->data_evt->referenceTime = rtc_time;
2387 mSensor->prev_rtc_time = rtc_time;
2388
2389 return true;
2390 }
2391
2392 static void parseOnePacket(TASK, const uint8_t *data, int idx)
2393 {
2394 struct FifoPacketData fifo_data;
2395 uint16_t diff;
2396
2397 getFifoData(data, idx, &fifo_data);
2398
2399 /* wait for odr */
2400 if (T(sensors[ACC]).wait_for_odr) {
2401 if (fifo_data.odr_accel) {
2402 T(sensors[ACC]).wait_for_odr = false;
2403 } else {
2404 fifo_data.valid_accel = false;
2405 }
2406 }
2407 if (T(sensors[GYR]).wait_for_odr) {
2408 if (fifo_data.odr_gyro) {
2409 T(sensors[GYR]).wait_for_odr = false;
2410 } else {
2411 fifo_data.valid_gyro = false;
2412 }
2413 }
2414
2415 /* drop first some samples */
2416 if (fifo_data.valid_accel) {
2417 if (T(sensors[ACC]).skip_sample_cnt > 0) {
2418 fifo_data.valid_accel = false;
2419 T(sensors[ACC]).skip_sample_cnt--;
2420 }
2421 }
2422 if (fifo_data.valid_gyro) {
2423 if (T(sensors[GYR]).skip_sample_cnt > 0) {
2424 fifo_data.valid_gyro = false;
2425 T(sensors[GYR]).skip_sample_cnt--;
2426 }
2427 }
2428
2429 /* update sensors data */
2430 if (fifo_data.valid_accel) {
2431 ICM40600_TO_ANDROID_COORDINATE(fifo_data.accel[0], fifo_data.accel[1], fifo_data.accel[2]);
2432 if (T(sensors[ACC]).configed) {
2433 T(sensors[ACC]).data[0] = fifo_data.accel[0];
2434 T(sensors[ACC]).data[1] = fifo_data.accel[1];
2435 T(sensors[ACC]).data[2] = fifo_data.accel[2];
2436 T(sensors[ACC]).updated = true;
2437 T(sensors[ACC]).data_cnt++;
2438 }
2439 }
2440 if (fifo_data.valid_gyro) {
2441 ICM40600_TO_ANDROID_COORDINATE(fifo_data.gyro[0], fifo_data.gyro[1], fifo_data.gyro[2]);
2442 if (T(sensors[GYR]).configed) {
2443 T(sensors[GYR]).data[0] = fifo_data.gyro[0];
2444 T(sensors[GYR]).data[1] = fifo_data.gyro[1];
2445 T(sensors[GYR]).data[2] = fifo_data.gyro[2];
2446 T(sensors[GYR]).updated = true;
2447 T(sensors[GYR]).data_cnt++;
2448 }
2449 }
2450
2451 // update temperature
2452 T(chip_temperature) = fifo_data.temp * TEMP_SCALE + TEMP_OFFSET;
2453
2454 // count up chip time
2455 if (T(chip_time_us) == 0) {
2456 T(chip_time_us) = (uint64_t)fifo_data.timestamp * CHIP_TIME_RES_US + CHIP_TIME_OFFSET_US;
2457 } else {
2458 // unsigned difference handle counter roll-up
2459 diff = fifo_data.timestamp - T(chip_timestamp);
2460 T(chip_time_us) += diff * CHIP_TIME_RES_US;
2461 }
2462 T(chip_timestamp) = fifo_data.timestamp;
2463 }
2464
2465 static void pushSensorData(TASK, struct ICM40600Sensor *mSensor, uint64_t rtc_time)
2466 {
2467 float x, y, z;
2468 float offset[3];
2469 bool new_offset_update = false;
2470 struct TripleAxisDataPoint *sample;
2471 uint32_t delta_time;
2472
2473 switch (mSensor->idx) {
2474 case ACC:
2475 // scale data to android units
2476 x = mSensor->data[0] * kScale_acc;
2477 y = mSensor->data[1] * kScale_acc;
2478 z = mSensor->data[2] * kScale_acc;
2479 // run and apply calibration on sensor data
2480 #ifdef ACCEL_CAL_ENABLED
2481 accelCalRun(&T(accel_cal), rtc_time, x, y, z, T(chip_temperature));
2482 accelCalBiasRemove(&T(accel_cal), &x, &y, &z);
2483 # ifdef ACCEL_CAL_DBG_ENABLED
2484 accelCalDebPrint(&T(accel_cal), T(chip_temperature));
2485 # endif
2486 #endif
2487 #ifdef GYRO_CAL_ENABLED
2488 gyroCalUpdateAccel(&T(gyro_cal), rtc_time, x, y, z);
2489 #endif
2490 break;
2491 case GYR:
2492 // scale data to android units
2493 x = mSensor->data[0] * kScale_gyr;
2494 y = mSensor->data[1] * kScale_gyr;
2495 z = mSensor->data[2] * kScale_gyr;
2496 // run and apply calibration on sensor data
2497 #ifdef GYRO_CAL_ENABLED
2498 gyroCalUpdateGyro(&T(gyro_cal), rtc_time, x, y, z, T(chip_temperature));
2499 gyroCalRemoveBias(&T(gyro_cal), x, y, z, &x, &y, &z);
2500 new_offset_update = gyroCalNewBiasAvailable(&T(gyro_cal));
2501 if (new_offset_update) {
2502 float gyro_offset_temperature_celsius;
2503 gyroCalGetBias(&T(gyro_cal), &offset[0], &offset[1], &offset[2],
2504 &gyro_offset_temperature_celsius);
2505 }
2506 #endif
2507 break;
2508 default:
2509 return;
2510 }
2511
2512 if (mSensor->data_evt == NULL) {
2513 if (!allocateDataEvt(mSensor, rtc_time))
2514 return;
2515 }
2516
2517 if (mSensor->data_evt->samples[0].firstSample.numSamples >= MAX_NUM_COMMS_EVENT_SAMPLES) {
2518 ERROR_PRINT("samples bad index\n");
2519 return;
2520 }
2521
2522 // handle bias sending
2523 if (new_offset_update) {
2524 if (mSensor->data_evt->samples[0].firstSample.numSamples > 0) {
2525 // flush existing samples so the bias appears after them.
2526 flushData(mSensor, EVENT_TYPE_BIT_DISCARDABLE | sensorGetMyEventType(mSensorInfo[mSensor->idx].sensorType));
2527 if (!allocateDataEvt(mSensor, rtc_time)) {
2528 return;
2529 }
2530 }
2531 mSensor->data_evt->samples[0].firstSample.biasCurrent = true;
2532 mSensor->data_evt->samples[0].firstSample.biasPresent = 1;
2533 mSensor->data_evt->samples[0].firstSample.biasSample = mSensor->data_evt->samples[0].firstSample.numSamples;
2534 sample = &mSensor->data_evt->samples[mSensor->data_evt->samples[0].firstSample.numSamples++];
2535 // Updates the offset in HAL.
2536 sample->x = offset[0];
2537 sample->y = offset[1];
2538 sample->z = offset[2];
2539 flushData(mSensor, sensorGetMyEventType(mSensorInfo[mSensor->idx].biasType));
2540 DEBUG_PRINT("send new gyro bias\n");
2541 if (!allocateDataEvt(mSensor, rtc_time)) {
2542 return;
2543 }
2544 }
2545
2546 sample = &mSensor->data_evt->samples[mSensor->data_evt->samples[0].firstSample.numSamples++];
2547
2548 // the first deltatime is for sample size
2549 if (mSensor->data_evt->samples[0].firstSample.numSamples > 1) {
2550 delta_time = rtc_time - mSensor->prev_rtc_time;
2551 delta_time = delta_time < 0 ? 0 : delta_time;
2552 sample->deltaTime = delta_time;
2553 mSensor->prev_rtc_time = rtc_time;
2554 }
2555
2556 sample->x = x;
2557 sample->y = y;
2558 sample->z = z;
2559
2560 if (mSensor->data_evt->samples[0].firstSample.numSamples == MAX_NUM_COMMS_EVENT_SAMPLES) {
2561 flushAllData();
2562 }
2563 }
2564
2565 static void computeTimeSync(TASK, const uint8_t *data, uint32_t count, uint64_t data_timestamp)
2566 {
2567 const uint64_t now = sensorGetTime();
2568 uint64_t chip_time_us;
2569 uint32_t sample_index;
2570 uint32_t duration_us;
2571 struct FifoPacketData packet;
2572 uint16_t sample_nb;
2573 uint16_t chip_timestamp;
2574 uint16_t diff;
2575 bool first_sync = false;
2576 bool sync = false;
2577
2578 /* scan fifo data for the latest chip timestamp */
2579 chip_time_us = T(chip_time_us);
2580 chip_timestamp = T(chip_timestamp);
2581 sample_index = 0;
2582 sample_nb = 0;
2583 while (count >= T(config).fifo_sample_size) {
2584 sample_nb++;
2585 getFifoData(data, sample_index, &packet);
2586 sample_index += T(config).fifo_sample_size;
2587 count -= T(config).fifo_sample_size;
2588 // count up chip time
2589 if (chip_time_us == 0) {
2590 // first chip timestamp
2591 chip_time_us = (uint64_t)packet.timestamp * CHIP_TIME_RES_US + CHIP_TIME_OFFSET_US;
2592 } else {
2593 // unsigned difference handle counter roll-up
2594 diff = packet.timestamp - chip_timestamp;
2595 chip_time_us += diff * CHIP_TIME_RES_US;
2596 }
2597 chip_timestamp = packet.timestamp;
2598 }
2599
2600 /* first time sync after FIFO enable */
2601 if (T(fifo_start_sync)) {
2602 if (T(config).fifo_rate != 0) {
2603 duration_us = (1000000 * RATE_TO_HZ) / T(config).fifo_rate;
2604 } else {
2605 duration_us = 0;
2606 }
2607 // use estimated duration
2608 map_sensortime_to_rtc_time(_task,
2609 chip_time_us - duration_us * sample_nb,
2610 data_timestamp - (uint64_t)duration_us * 1000ULL * sample_nb);
2611 T(fifo_start_sync) = false;
2612 T(last_sync_time) = now;
2613 first_sync = true;
2614 }
2615
2616 /* periodical time sync */
2617 if ((now - T(last_sync_time)) > MSEC_TO_NANOS(100)) {
2618 // every 100ms
2619 uint64_t estimated_rtc;
2620 uint64_t min_rtc, max_rtc;
2621 uint64_t limit_ns, adjust_ns;
2622 uint64_t updated_data_timestamp = data_timestamp;
2623 bool valid = sensortime_to_rtc_time(_task, chip_time_us, &estimated_rtc);
2624 // check if appropriate to inject to time sync algorithm
2625 // adjust rtc time if necessary not to make large jitters
2626 if (valid) {
2627 limit_ns = U64_DIV_BY_CONST_U16((data_timestamp - T(last_sync_data_ts)) * 10, 1000); // 1% (100ms * 1% = 1ms)
2628 adjust_ns = U64_DIV_BY_CONST_U16((data_timestamp - T(last_sync_data_ts)) * 1, 10000); // 0.01% (100ms * 0.01% = 10us)
2629 min_rtc = data_timestamp - limit_ns; // actual ts - x
2630 max_rtc = data_timestamp + limit_ns; // actual ts + x
2631 if ((estimated_rtc >= min_rtc) && (estimated_rtc <= max_rtc)) {
2632 sync = true;
2633 } else if (estimated_rtc < min_rtc) {
2634 sync = true;
2635 updated_data_timestamp = updated_data_timestamp - adjust_ns;
2636 #if DBG_TIMESTAMP
2637 T(statistics_set).sync_adjust_minus++;
2638 #endif
2639 } else if (estimated_rtc > max_rtc) {
2640 sync = true;
2641 updated_data_timestamp = updated_data_timestamp + adjust_ns;
2642 #if DBG_TIMESTAMP
2643 T(statistics_set).sync_adjust_plus++;
2644 #endif
2645 }
2646 // limit the adjustment
2647 if (sync) {
2648 if (updated_data_timestamp > (data_timestamp + MSEC_TO_NANOS(1))) {
2649 updated_data_timestamp = data_timestamp + MSEC_TO_NANOS(1);
2650 }
2651 }
2652 }
2653 if (sync) {
2654 data_timestamp = updated_data_timestamp;
2655 }
2656 }
2657
2658 /* do time sync */
2659 if (first_sync || sync) {
2660 map_sensortime_to_rtc_time(_task, chip_time_us, data_timestamp);
2661 T(last_sync_time) = now;
2662 T(last_sync_data_ts) = data_timestamp;
2663 }
2664 }
2665
2666 static void dispatchData(TASK, const uint8_t *data, uint32_t count)
2667 {
2668 uint64_t ts = 0;
2669 uint32_t sample_index = 0;
2670 int i;
2671
2672 if (count == 0) {
2673 return;
2674 }
2675
2676 /* do time sync if no flush or fist time starting FIFO */
2677 if (T(fifo_start_sync) || !T(flush)) {
2678 computeTimeSync(_task, data, count, T(data_timestamp));
2679 }
2680
2681 /* process FIFO data */
2682 while (count >= T(config).fifo_sample_size) {
2683 for (i = FIRST_CONT_SENSOR; i < NUM_CONT_SENSOR; ++i) {
2684 T(sensors[i]).updated = false;
2685 }
2686 parseOnePacket(_task, data, sample_index);
2687 sample_index += T(config).fifo_sample_size;
2688 count -= T(config).fifo_sample_size;
2689 // compute timestamp
2690 if (!sensortime_to_rtc_time(_task, T(chip_time_us), &ts)) {
2691 continue;
2692 }
2693 // add data
2694 for (i = FIRST_CONT_SENSOR; i < NUM_CONT_SENSOR; ++i) {
2695 if (!T(sensors[i]).configed || !T(sensors[i]).updated) {
2696 continue;
2697 }
2698 if (T(sensors[i]).data_cnt % T(sensors[i]).decimator == 0) {
2699 if (ts <= T(sensors[i]).prev_rtc_time) {
2700 ts = T(sensors[i]).prev_rtc_time + MIN_INCREMENT_TIME_NS;
2701 #if DBG_TIMESTAMP
2702 T(statistics_set).sync_truncate++;
2703 #endif
2704 }
2705 pushSensorData(_task, &T(sensors[i]), ts);
2706 }
2707 }
2708 }
2709
2710 flushAllData();
2711 }
2712
2713 static void int1Handling(TASK)
2714 {
2715 uint8_t int_status;
2716 uint8_t int_status2;
2717 uint16_t fifo_count = 0;
2718 union EmbeddedDataPoint trigger_axies;
2719 const uint8_t *buf;
2720
2721 switch (T(int_state)) {
2722 case INT_READ_STATUS:
2723 T(int_state) = INT_PROCESS_STATUS;
2724 // read INT status1, status2 and fifo_count registers
2725 SPI_READ(REG_INT_STATUS, 1, &T(dataBuffer[0]));
2726 SPI_READ(REG_INT_STATUS2, 1, &T(dataBuffer[1]));
2727 SPI_READ(REG_FIFO_BYTE_COUNT1, 2, &T(dataBuffer[2]));
2728 T(data_timestamp) = sensorGetTime();
2729 spiBatchTxRx(&T(mode), sensorSpiCallback, _task, __FUNCTION__);
2730 break;
2731 case INT_PROCESS_STATUS:
2732 buf = T(dataBuffer[0]);
2733 int_status = buf[1];
2734 buf = T(dataBuffer[1]);
2735 int_status2 = buf[1];
2736 buf = T(dataBuffer[2]);
2737 fifo_count = buf[2] << 8 | buf[1];
2738 // INT status handling
2739 if (int_status2 & BIT_INT_STATUS_WOM_XYZ) {
2740 if (T(sensors[WOM]).configed) {
2741 trigger_axies.idata = ((int_status2 & BIT_INT_STATUS_WOM_X) >> 0) | ((int_status2 & BIT_INT_STATUS_WOM_Y) >> 1) | ((int_status2 & BIT_INT_STATUS_WOM_Z) >> 2);
2742 osEnqueueEvt(EVT_SENSOR_ANY_MOTION, trigger_axies.vptr, NULL);
2743 }
2744 if (T(sensors[NOMO]).configed && T(noMotionTimerHandle)) {
2745 timTimerCancel(T(noMotionTimerHandle));
2746 T(noMotionTimerHandle) = timTimerSet(ICM40600_NOM_DURATION_NS, 0, 100, noMotionCallback, (void *)&T(sensors[NOMO]), false);
2747 }
2748 }
2749 // FIFO overflow
2750 if (int_status & BIT_INT_STATUS_FIFO_FULL) {
2751 ERROR_PRINT("fifo overflow\n");
2752 }
2753 // FIFO WM status handling
2754 if ((int_status & BIT_INT_STATUS_FIFO_THS) || T(flush)) {
2755 T(int_state) = INT_READ_FIFO_DATA;
2756 } else {
2757 T(int_state) = INT_DONE;
2758 T(fifo_count) = 0;
2759 sensorSpiCallback(_task, 0);
2760 break;
2761 }
2762 // fall-through
2763 case INT_READ_FIFO_DATA:
2764 T(int_state) = INT_DONE;
2765 // compute fifo count and delete partial sample
2766 fifo_count -= fifo_count % T(config).fifo_sample_size;
2767 // read FIFO data
2768 T(fifo_count) = fifo_count;
2769 if (fifo_count > 0) {
2770 SPI_READ(REG_FIFO_DATA, fifo_count, &T(dataBuffer[0]));
2771 spiBatchTxRx(&T(mode), sensorSpiCallback, _task, __FUNCTION__);
2772 } else {
2773 sensorSpiCallback(_task, 0);
2774 }
2775 break;
2776 default:
2777 T(int_state) = INT_DONE;
2778 T(fifo_count) = 0;
2779 sensorSpiCallback(_task, 0);
2780 break;
2781 }
2782 }
2783
2784 static void int1Evt(TASK, bool flush)
2785 {
2786 if (trySwitchState(SENSOR_INT_1_HANDLING)) {
2787 T(flush) = flush;
2788 T(int_state) = INT_READ_STATUS;
2789 int1Handling(_task);
2790 } else {
2791 if (flush) {
2792 T(pending_flush) = true;
2793 } else {
2794 T(pending_int[0]) = true;
2795 }
2796 }
2797 }
2798
2799 #define DEC_OPS(power, firmware, rate, flush) \
2800 .sensorPower = power, \
2801 .sensorFirmwareUpload = firmware, \
2802 .sensorSetRate = rate, \
2803 .sensorFlush = flush
2804
2805 #define DEC_OPS_CAL_CFG_TEST(power, firmware, rate, flush, cal, cfg, test) \
2806 DEC_OPS(power, firmware, rate, flush), \
2807 .sensorCalibrate = cal, \
2808 .sensorCfgData = cfg, \
2809 .sensorSelfTest = test,
2810
2811 #define DEC_OPS_CFG(power, firmware, rate, flush, cfg) \
2812 DEC_OPS(power, firmware, rate, flush), \
2813 .sensorCfgData = cfg
2814
2815 static const struct SensorOps mSensorOps[NUM_OF_SENSOR] =
2816 {
2817 { DEC_OPS_CAL_CFG_TEST(sensorSetPower, sensorFirmwareUpload, sensorSetRate, flushSensor, accCalibration,
2818 accCfgData, accSelfTest) },
2819 { DEC_OPS_CAL_CFG_TEST(sensorSetPower, sensorFirmwareUpload, sensorSetRate, flushSensor, gyrCalibration,
2820 gyrCfgData, gyrSelfTest) },
2821 { DEC_OPS(sensorSetPower, sensorFirmwareUpload, sensorSetRate, flushSensor) },
2822 { DEC_OPS(sensorSetPower, sensorFirmwareUpload, sensorSetRate, flushSensor) },
2823 };
2824
2825 static void configEvent(struct ICM40600Sensor *mSensor, struct ConfigStat *ConfigData)
2826 {
2827 TDECL();
2828 int i;
2829
2830 for (i = 0; &T(sensors[i]) != mSensor; i++) ;
2831
2832 if (ConfigData->enable == 0 && mSensor->powered) {
2833 mSensorOps[i].sensorPower(false, (void *)i);
2834 } else if (ConfigData->enable == 1 && !mSensor->powered) {
2835 mSensorOps[i].sensorPower(true, (void *)i);
2836 } else {
2837 mSensorOps[i].sensorSetRate(ConfigData->rate, ConfigData->latency, (void *)i);
2838 }
2839 }
2840
2841 static void processPendingEvt(TASK)
2842 {
2843 enum SensorIndex i;
2844
2845 if (T(pending_int[0])) {
2846 T(pending_int[0]) = false;
2847 int1Evt(_task, false);
2848 return;
2849 }
2850
2851 if (T(pending_flush)) {
2852 T(pending_flush) = false;
2853 int1Evt(_task, true);
2854 return;
2855 }
2856
2857 for (i = 0; i < NUM_OF_SENSOR; i++) {
2858 if (T(pending_config[i])) {
2859 T(pending_config[i]) = false;
2860 configEvent(&T(sensors[i]), &T(sensors[i]).pConfig);
2861 return;
2862 }
2863 }
2864
2865 if (T(pending_calibration_save)) {
2866 T(pending_calibration_save) = !saveCalibration(_task);
2867 return;
2868 }
2869 }
2870
2871 static void sensorInit(TASK)
2872 {
2873 const uint8_t *buf;
2874
2875 switch (T(init_state)) {
2876 case RESET_ICM40600:
2877 // reset chip and turn on
2878 SPI_WRITE(REG_DEVICE_CONFIG, BIT_SOFT_RESET, 100 * 1000);
2879 SPI_READ(REG_INT_STATUS, 1, &T(dataBuffer[0]));
2880 T(powered) = false;
2881 sensorTurnOn(_task);
2882 // set SPI speed register
2883 SPI_WRITE(REG_SPI_SPEED, ICM40600_SPI_SPEED_REG_VALUE);
2884 T(init_state) = INIT_ICM40600;
2885 spiBatchTxRx(&T(mode), sensorSpiCallback, _task, __FUNCTION__);
2886 break;
2887 case INIT_ICM40600:
2888 buf = T(dataBuffer[0]);
2889 if (!(buf[1] & BIT_INT_STATUS_RESET_DONE)) {
2890 ERROR_PRINT("chip reset failed!\n");
2891 }
2892 // reconfigure SPI speed
2893 T(mode).speed = ICM40600_SPI_SPEED_HZ;
2894 // configure interface
2895 // i2c disabled
2896 // fifo_count: little endian
2897 // sensor data: little endian
2898 SPI_WRITE(REG_INTF_CONFIG0, BIT_UI_SIFS_DISABLE_I2C);
2899 // configure interrupt
2900 SPI_WRITE(REG_INT_CONFIG, (INT1_POLARITY << SHIFT_INT1_POLARITY) |
2901 (INT1_DRIVE_CIRCUIT << SHIFT_INT1_DRIVE_CIRCUIT) |
2902 (INT1_MODE << SHIFT_INT1_MODE));
2903 SPI_WRITE(REG_INT_CONFIG1, BIT_INT_ASY_RST_DISABLE); // 9139
2904 // static config of sensors
2905 SPI_WRITE(REG_GYRO_ACCEL_CONFIG0, ICM40600_ACC_BW_IND | ICM40600_GYR_BW_IND);
2906 SPI_WRITE(REG_GYRO_CONFIG1, 0x1A); // default reset value
2907 SPI_WRITE(REG_ACCEL_CONFIG1, 0x15); // default reset value
2908 // turn off FIFO and sensors
2909 SPI_WRITE(REG_FIFO_CONFIG, BIT_FIFO_MODE_BYPASS);
2910 SPI_WRITE(REG_FIFO_CONFIG1, 0);
2911 SPI_WRITE(REG_FIFO_CONFIG2, 0);
2912 SPI_WRITE(REG_FIFO_CONFIG3, 0);
2913 SPI_WRITE(REG_SMD_CONFIG, BIT_SMD_MODE_OFF);
2914 SPI_WRITE(REG_PWR_MGMT_0, BIT_GYRO_MODE_OFF | BIT_ACCEL_MODE_OFF, 200); // 9136
2915 sensorTurnOff(_task);
2916 T(init_state) = INIT_DONE;
2917 spiBatchTxRx(&T(mode), sensorSpiCallback, _task, __FUNCTION__);
2918 break;
2919 default:
2920 break;
2921 }
2922 }
2923
2924 static void handleSpiDoneEvt(const void* evtData)
2925 {
2926 TDECL();
2927 struct ICM40600Sensor *mSensor;
2928 bool returnIdle = false;
2929 uint32_t i;
2930 const uint8_t *buf;
2931 #ifdef ACCEL_CAL_ENABLED
2932 bool accelCalNewBiasAvailable;
2933 struct TripleAxisDataPoint *sample;
2934 float accelCalBiasX, accelCalBiasY, accelCalBiasZ;
2935 bool fallThrough;
2936 #endif
2937
2938 switch (GET_STATE()) {
2939 case SENSOR_BOOT:
2940 SET_STATE(SENSOR_VERIFY_ID);
2941 SPI_READ(REG_WHO_AM_I, 1, &T(dataBuffer[0]));
2942 spiBatchTxRx(&T(mode), sensorSpiCallback, _task, __FUNCTION__);
2943 break;
2944 case SENSOR_VERIFY_ID:
2945 buf = T(dataBuffer[0]);
2946 if (buf[1] != WHO_AM_I_ICM40604 && buf[1] != WHO_AM_I_ICM40605) {
2947 ERROR_PRINT("chip not found (id=0x%x)\n", buf[1]);
2948 break;
2949 }
2950 INFO_PRINT("chip found (id=0x%x)\n", buf[1]);
2951 SET_STATE(SENSOR_INITIALIZING);
2952 T(init_state) = RESET_ICM40600;
2953 sensorInit(_task);
2954 break;
2955 case SENSOR_INITIALIZING:
2956 if (T(init_state) == INIT_DONE) {
2957 for (i = 0; i < NUM_OF_SENSOR; i++) {
2958 sensorRegisterInitComplete(T(sensors[i]).handle);
2959 }
2960 returnIdle = true;
2961 } else {
2962 sensorInit(_task);
2963 }
2964 break;
2965 case SENSOR_POWERING_UP:
2966 mSensor = (struct ICM40600Sensor *)evtData;
2967 sensorSignalInternalEvt(mSensor->handle, SENSOR_INTERNAL_EVT_POWER_STATE_CHG, 1, 0);
2968 returnIdle = true;
2969 break;
2970 case SENSOR_POWERING_DOWN:
2971 mSensor = (struct ICM40600Sensor *)evtData;
2972 #ifdef ACCEL_CAL_ENABLED
2973 if (mSensor->idx == ACC) {
2974 // https://source.android.com/devices/sensors/sensor-types.html
2975 // "The bias and scale calibration must only be updated while the sensor is deactivated,
2976 // so as to avoid causing jumps in values during streaming."
2977 accelCalNewBiasAvailable = accelCalUpdateBias(&T(accel_cal), &accelCalBiasX, &accelCalBiasY, &accelCalBiasZ);
2978 // notify HAL about new accel bias calibration
2979 if (accelCalNewBiasAvailable) {
2980 fallThrough = true;
2981 if (mSensor->data_evt->samples[0].firstSample.numSamples > 0) {
2982 // flush existing samples so the bias appears after them
2983 flushData(mSensor, EVENT_TYPE_BIT_DISCARDABLE | sensorGetMyEventType(mSensorInfo[ACC].sensorType));
2984 // try to allocate another data event and break if unsuccessful
2985 if (!allocateDataEvt(mSensor, sensorGetTime())) {
2986 fallThrough = false;
2987 }
2988 }
2989 if (fallThrough) {
2990 mSensor->data_evt->samples[0].firstSample.biasCurrent = true;
2991 mSensor->data_evt->samples[0].firstSample.biasPresent = 1;
2992 mSensor->data_evt->samples[0].firstSample.biasSample =
2993 mSensor->data_evt->samples[0].firstSample.numSamples;
2994 sample = &mSensor->data_evt->samples[mSensor->data_evt->samples[0].firstSample.numSamples++];
2995 sample->x = accelCalBiasX;
2996 sample->y = accelCalBiasY;
2997 sample->z = accelCalBiasZ;
2998 flushData(mSensor, sensorGetMyEventType(mSensorInfo[ACC].biasType));
2999 DEBUG_PRINT("send new accel bias\n");
3000 allocateDataEvt(mSensor, sensorGetTime());
3001 }
3002 }
3003 }
3004 #endif
3005 sensorSignalInternalEvt(mSensor->handle, SENSOR_INTERNAL_EVT_POWER_STATE_CHG, 0, 0);
3006 returnIdle = true;
3007 break;
3008 case SENSOR_INT_1_HANDLING:
3009 if (T(int_state) == INT_DONE) {
3010 buf = T(dataBuffer[0]);
3011 dispatchData(_task, &buf[1], T(fifo_count));
3012 if (T(flush)) {
3013 sendFlushEvt();
3014 }
3015 returnIdle = true;
3016 } else {
3017 int1Handling(_task);
3018 }
3019 break;
3020 case SENSOR_CONFIG_CHANGING:
3021 mSensor = (struct ICM40600Sensor *)evtData;
3022 sensorSignalInternalEvt(mSensor->handle, SENSOR_INTERNAL_EVT_RATE_CHG, mSensor->rate, mSensor->latency);
3023 returnIdle = true;
3024 break;
3025 case SENSOR_CALIBRATING:
3026 mSensor = (struct ICM40600Sensor *)evtData;
3027 if (mSensor->idx == ACC) {
3028 if (T(calibration_state) == CALIBRATION_DONE) {
3029 INFO_PRINT("Accel Calibration done\n");
3030 returnIdle = true;
3031 } else {
3032 calibrationHandling(_task, ACC);
3033 }
3034 } else if (mSensor->idx == GYR) {
3035 if (T(calibration_state) == CALIBRATION_DONE) {
3036 INFO_PRINT("Gyro Calibration done\n");
3037 returnIdle = true;
3038 } else {
3039 calibrationHandling(_task, GYR);
3040 }
3041 }
3042 break;
3043 case SENSOR_TESTING:
3044 mSensor = (struct ICM40600Sensor *)evtData;
3045 if (mSensor->idx == ACC) {
3046 if (T(selftest_state) == TEST_DONE) {
3047 INFO_PRINT("Accel Selftest done\n");
3048 returnIdle = true;
3049 } else {
3050 selfTestHandling(_task, ACC);
3051 }
3052 } else if (mSensor->idx == GYR) {
3053 if (T(selftest_state) == TEST_DONE) {
3054 INFO_PRINT("Gyro Selftest done\n");
3055 returnIdle = true;
3056 } else {
3057 selfTestHandling(_task, GYR);
3058 }
3059 }
3060 break;
3061 case SENSOR_SAVE_CALIBRATION:
3062 returnIdle = true;
3063 break;
3064 default:
3065 break;
3066 }
3067
3068 if (returnIdle) {
3069 SET_STATE(SENSOR_IDLE);
3070 processPendingEvt(_task);
3071 }
3072 }
3073
3074 #ifdef GYRO_CAL_ENABLED
3075 static void processMagEvents(TASK, const struct TripleAxisDataEvent *evtData)
3076 {
3077 const struct SensorFirstSample * const first = &evtData->samples[0].firstSample;
3078 const struct TripleAxisDataPoint *sample;
3079 uint64_t ts = evtData->referenceTime;
3080 unsigned int i;
3081
3082 for (i = 0; i < first->numSamples; ++i) {
3083 sample = &evtData->samples[i];
3084 if (i > 0) {
3085 ts += sample->deltaTime;
3086 }
3087 gyroCalUpdateMag(&T(gyro_cal), ts, sample->x, sample->y, sample->z);
3088 }
3089 }
3090 #endif
3091
3092 static void handleEvent(uint32_t evtType, const void* evtData)
3093 {
3094 TDECL();
3095
3096 switch (evtType) {
3097 case EVT_APP_START:
3098 SET_STATE(SENSOR_BOOT);
3099 osEventUnsubscribe(T(tid), EVT_APP_START);
3100 #ifdef GYRO_CAL_ENABLED
3101 osEventSubscribe(T(tid), EVT_SENSOR_MAG_DATA_RDY);
3102 #endif
3103 // fall through
3104 case EVT_SPI_DONE:
3105 handleSpiDoneEvt(evtData);
3106 break;
3107 case EVT_SENSOR_INTERRUPT_1:
3108 int1Evt(_task, false);
3109 break;
3110 #ifdef GYRO_CAL_ENABLED
3111 case EVT_SENSOR_MAG_DATA_RDY:
3112 if (evtData != SENSOR_DATA_EVENT_FLUSH) {
3113 processMagEvents(_task, (const struct TripleAxisDataEvent *)evtData);
3114 }
3115 break;
3116 #endif
3117 default:
3118 break;
3119 }
3120 }
3121
3122 static void initSensorStruct(struct ICM40600Sensor *sensor, enum SensorIndex idx)
3123 {
3124 sensor->data_evt = NULL;
3125 sensor->rate = 0;
3126 sensor->latency = 0;
3127 sensor->decimator = 1;
3128 sensor->data_cnt = 0;
3129 sensor->prev_rtc_time = 0;
3130 sensor->skip_sample_cnt = 0;
3131 sensor->data[0] = 0;
3132 sensor->data[1] = 0;
3133 sensor->data[2] = 0;
3134 sensor->offset[0] = 0;
3135 sensor->offset[1] = 0;
3136 sensor->offset[2] = 0;
3137 sensor->updated = false;
3138 sensor->powered = false;
3139 sensor->configed = false;
3140 sensor->wait_for_odr = false;
3141 sensor->idx = idx;
3142 sensor->flush = 0;
3143 }
3144
3145 static bool startTask(uint32_t task_id)
3146 {
3147 TDECL();
3148 enum SensorIndex i;
3149 size_t slabSize;
3150
3151 time_init(_task);
3152
3153 T(tid) = task_id;
3154
3155 T(Int1) = gpioRequest(ICM40600_INT1_PIN);
3156 T(Irq1) = ICM40600_INT1_IRQ;
3157 T(Isr1).func = icm40600Isr1;
3158 T(Int1_EN) = false;
3159 T(pending_int[0]) = false;
3160 T(pending_flush) = false;
3161 T(pending_calibration_save) = false;
3162
3163 T(mode).speed = ICM40600_SPI_DEFAULT_SPEED_HZ;
3164 T(mode).bitsPerWord = 8;
3165 T(mode).cpol = SPI_CPOL_IDLE_HI;
3166 T(mode).cpha = SPI_CPHA_TRAILING_EDGE;
3167 T(mode).nssChange = true;
3168 T(mode).format = SPI_FORMAT_MSB_FIRST;
3169 T(cs) = GPIO_PB(12);
3170 T(config).accel_rate = 0;
3171 T(config).gyro_rate = 0;
3172 T(config).fifo_rate = 0;
3173 T(config).wom_threshold = 0;
3174 T(config).fifo_watermark = 0;
3175 T(config).fifo_sample_size = 0;
3176 T(config).accel_on = false;
3177 T(config).gyro_on = false;
3178 T(config).wom_on = false;
3179 T(noMotionTimerHandle) = 0;
3180 T(fifo_count) = 0;
3181 T(powered) = false;
3182 T(flush) = false;
3183 T(data_timestamp) = 0;
3184 T(chip_time_us) = 0;
3185 T(last_sync_time) = 0;
3186 T(last_sync_data_ts) = 0;
3187 T(chip_timestamp) = 0;
3188 T(fifo_start_sync) = false;
3189 T(chip_temperature) = TEMP_OFFSET;
3190
3191 spiMasterRequest(ICM40600_SPI_BUS_ID, &T(spiDev));
3192
3193 for (i = 0; i < NUM_OF_SENSOR; i++) {
3194 initSensorStruct(&T(sensors[i]), i);
3195 T(sensors[i]).handle = sensorRegister(&mSensorInfo[i], &mSensorOps[i], (void *)i, false);
3196 T(pending_config[i]) = false;
3197 }
3198
3199 osEventSubscribe(T(tid), EVT_APP_START);
3200
3201 #ifdef ACCEL_CAL_ENABLED
3202 // Init Accel Cal
3203 accelCalInit(&T(accel_cal),
3204 800000000, // Stillness Time in ns (0.8s)
3205 5, // Minimum Sample Number
3206 0.00025, // Threshold
3207 15, // nx bucket count
3208 15, // nxb bucket count
3209 15, // ny bucket count
3210 15, // nyb bucket count
3211 15, // nz bucket count
3212 15, // nzb bucket count
3213 15); // nle bucket count
3214 #endif
3215 #ifdef GYRO_CAL_ENABLED
3216 // Init Gyro Cal
3217 gyroCalInit(&T(gyro_cal),
3218 SEC_TO_NANOS(5.0f), // Min stillness period = 5.0 seconds
3219 SEC_TO_NANOS(5.9f), // Max stillness period = 6.0 seconds (NOTE 1)
3220 0, 0, 0, // Initial bias offset calibration
3221 0, // Time stamp of initial bias calibration
3222 SEC_TO_NANOS(1.5f), // Analysis window length = 1.5 seconds
3223 7.5e-5f, // Gyroscope variance threshold [rad/sec]^2
3224 1.5e-5f, // Gyroscope confidence delta [rad/sec]^2
3225 4.5e-3f, // Accelerometer variance threshold [m/sec^2]^2
3226 9.0e-4f, // Accelerometer confidence delta [m/sec^2]^2
3227 5.0f, // Magnetometer variance threshold [uT]^2
3228 1.0f, // Magnetometer confidence delta [uT]^2
3229 0.95f, // Stillness threshold [0,1]
3230 40.0f * MDEG_TO_RAD, // Stillness mean variation limit [rad/sec]
3231 1.5f, // Max temperature delta during stillness [C]
3232 true); // Gyro calibration enable
3233 // NOTE 1: This parameter is set to 5.9 seconds to achieve a max stillness
3234 // period of 6.0 seconds and avoid buffer boundary conditions that could push
3235 // the max stillness to the next multiple of the analysis window length
3236 // (i.e., 7.5 seconds).
3237 #endif
3238
3239 slabSize = sizeof(struct TripleAxisDataEvent) +
3240 MAX_NUM_COMMS_EVENT_SAMPLES * sizeof(struct TripleAxisDataPoint);
3241 // TODO: need to investigate slab items number
3242 T(mDataSlab) = slabAllocatorNew(slabSize, 4, 20);
3243 if (!T(mDataSlab)) {
3244 ERROR_PRINT("slabAllocatorNew() failed\n");
3245 return false;
3246 }
3247 T(mWbufCnt) = 0;
3248 T(mRegCnt) = 0;
3249 T(spiInUse) = false;
3250
3251 return true;
3252 }
3253
3254 static void endTask(void)
3255 {
3256 TDECL();
3257
3258 #ifdef ACCEL_CAL_ENABLED
3259 accelCalDestroy(&T(accel_cal));
3260 #endif
3261 #ifdef GYRO_CAL_ENABLED
3262 gyroCalDestroy(&T(gyro_cal));
3263 #endif
3264 slabAllocatorDestroy(T(mDataSlab));
3265 spiMasterRelease(T(spiDev));
3266
3267 // disable and release interrupt.
3268 disableInterrupt(T(Int1), T(Irq1), &T(Isr1));
3269 gpioRelease(T(Int1));
3270 }
3271
3272 INTERNAL_APP_INIT(ICM40600_APP_ID, ICM40600_APP_VERSION, startTask, endTask, handleEvent);
3273