1 /*
2 * Copyright 2020 Google LLC
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Emulator for the Bosch BMI160 accelerometer / gyro. This supports basic
7 * init and reading of canned samples. It supports both I2C and SPI buses.
8 */
9
10 #define DT_DRV_COMPAT bosch_bmi160
11
12 #define LOG_LEVEL CONFIG_SPI_LOG_LEVEL
13 #include <zephyr/logging/log.h>
14 LOG_MODULE_REGISTER(bosch_bmi160);
15
16 #include <zephyr/sys/byteorder.h>
17 #include <bmi160.h>
18 #include <zephyr/device.h>
19 #include <zephyr/drivers/emul.h>
20 #include <zephyr/drivers/emul_sensor.h>
21 #include <zephyr/drivers/i2c.h>
22 #include <zephyr/drivers/i2c_emul.h>
23 #include <zephyr/drivers/spi.h>
24 #include <zephyr/drivers/spi_emul.h>
25 #include <zephyr/sys/util.h>
26
27 /** Run-time data used by the emulator */
28 struct bmi160_emul_data {
29 uint8_t pmu_status;
30 /** Current register to read (address) */
31 uint32_t cur_reg;
32 };
33
34 /** Static configuration for the emulator */
35 struct bmi160_emul_cfg {
36 /** Chip registers */
37 uint8_t *reg;
38 union {
39 /** Unit address (chip select ordinal) of emulator */
40 uint16_t chipsel;
41 /** I2C address of emulator */
42 uint16_t addr;
43 };
44 };
45
46 /* Names for the PMU components */
47 static const char *const pmu_name[] = {"acc", "gyr", "mag", "INV"};
48
emul_bmi160_get_reg_value(const struct emul * target,int reg_number,uint8_t * out,size_t count)49 int emul_bmi160_get_reg_value(const struct emul *target, int reg_number, uint8_t *out, size_t count)
50 {
51 const struct bmi160_emul_cfg *cfg = target->cfg;
52
53 if (reg_number < 0 || reg_number + count > BMI160_REG_COUNT) {
54 return -EINVAL;
55 }
56
57 memcpy(out, cfg->reg + reg_number, count);
58 return 0;
59 }
60
reg_write(const struct emul * target,int regn,int val)61 static void reg_write(const struct emul *target, int regn, int val)
62 {
63 struct bmi160_emul_data *data = target->data;
64 const struct bmi160_emul_cfg *cfg = target->cfg;
65
66 LOG_DBG("write %x = %x", regn, val);
67 cfg->reg[regn] = val;
68 switch (regn) {
69 case BMI160_REG_ACC_CONF:
70 LOG_DBG(" * acc conf");
71 break;
72 case BMI160_REG_ACC_RANGE:
73 LOG_DBG(" * acc range");
74 break;
75 case BMI160_REG_GYR_CONF:
76 LOG_DBG(" * gyr conf");
77 break;
78 case BMI160_REG_GYR_RANGE:
79 LOG_DBG(" * gyr range");
80 break;
81 case BMI160_REG_CMD:
82 switch (val) {
83 case BMI160_CMD_SOFT_RESET:
84 LOG_DBG(" * soft reset");
85 break;
86 default:
87 if ((val & BMI160_CMD_PMU_BIT) == BMI160_CMD_PMU_BIT) {
88 int which = (val & BMI160_CMD_PMU_MASK) >> BMI160_CMD_PMU_SHIFT;
89 int shift;
90 int pmu_val = val & BMI160_CMD_PMU_VAL_MASK;
91
92 switch (which) {
93 case 0:
94 shift = BMI160_PMU_STATUS_ACC_POS;
95 break;
96 case 1:
97 shift = BMI160_PMU_STATUS_GYR_POS;
98 break;
99 case 2:
100 default:
101 shift = BMI160_PMU_STATUS_MAG_POS;
102 break;
103 }
104 data->pmu_status &= 3 << shift;
105 data->pmu_status |= pmu_val << shift;
106 LOG_DBG(" * pmu %s = %x, new status %x", pmu_name[which], pmu_val,
107 data->pmu_status);
108 } else {
109 LOG_DBG("Unknown command %x", val);
110 }
111 break;
112 }
113 break;
114 default:
115 LOG_DBG("Unknown write %x", regn);
116 }
117 }
118
reg_read(const struct emul * target,int regn)119 static int reg_read(const struct emul *target, int regn)
120 {
121 struct bmi160_emul_data *data = target->data;
122 const struct bmi160_emul_cfg *cfg = target->cfg;
123 int val;
124
125 LOG_DBG("read %x =", regn);
126 val = cfg->reg[regn];
127 switch (regn) {
128 case BMI160_REG_CHIPID:
129 LOG_DBG(" * get chipid");
130 break;
131 case BMI160_REG_PMU_STATUS:
132 LOG_DBG(" * get pmu");
133 val = data->pmu_status;
134 break;
135 case BMI160_REG_STATUS:
136 LOG_DBG(" * status");
137 val |= BMI160_DATA_READY_BIT_MASK;
138 break;
139 case BMI160_REG_ACC_CONF:
140 LOG_DBG(" * acc conf");
141 break;
142 case BMI160_REG_GYR_CONF:
143 LOG_DBG(" * gyr conf");
144 break;
145 case BMI160_SPI_START:
146 LOG_DBG(" * Bus start");
147 break;
148 case BMI160_REG_ACC_RANGE:
149 LOG_DBG(" * acc range");
150 break;
151 case BMI160_REG_GYR_RANGE:
152 LOG_DBG(" * gyr range");
153 break;
154 default:
155 LOG_DBG("Unknown read %x", regn);
156 }
157 LOG_DBG(" = %x", val);
158
159 return val;
160 }
161
162 #if BMI160_BUS_SPI
bmi160_emul_io_spi(const struct emul * target,const struct spi_config * config,const struct spi_buf_set * tx_bufs,const struct spi_buf_set * rx_bufs)163 static int bmi160_emul_io_spi(const struct emul *target, const struct spi_config *config,
164 const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs)
165 {
166 struct bmi160_emul_data *data;
167 const struct spi_buf *tx, *txd, *rxd;
168 unsigned int regn, val;
169 int count;
170
171 ARG_UNUSED(config);
172
173 data = target->data;
174
175 __ASSERT_NO_MSG(tx_bufs || rx_bufs);
176 __ASSERT_NO_MSG(!tx_bufs || !rx_bufs || tx_bufs->count == rx_bufs->count);
177 count = tx_bufs ? tx_bufs->count : rx_bufs->count;
178
179 if (count != 2) {
180 LOG_DBG("Unknown tx_bufs->count %d", count);
181 return -EIO;
182 }
183 tx = tx_bufs->buffers;
184 txd = &tx_bufs->buffers[1];
185 rxd = rx_bufs ? &rx_bufs->buffers[1] : NULL;
186
187 if (tx->len != 1) {
188 LOG_DBG("Unknown tx->len %d", tx->len);
189 return -EIO;
190 }
191
192 regn = *(uint8_t *)tx->buf;
193 if ((regn & BMI160_REG_READ) && rxd == NULL) {
194 LOG_ERR("Cannot read without rxd");
195 return -EPERM;
196 }
197
198 if (txd->len == 1) {
199 if (regn & BMI160_REG_READ) {
200 regn &= BMI160_REG_MASK;
201 val = reg_read(target, regn);
202 *(uint8_t *)rxd->buf = val;
203 } else {
204 val = *(uint8_t *)txd->buf;
205 reg_write(target, regn, val);
206 }
207 } else {
208 if (regn & BMI160_REG_READ) {
209 regn &= BMI160_REG_MASK;
210 for (int i = 0; i < txd->len; ++i) {
211 ((uint8_t *)rxd->buf)[i] = reg_read(target, regn + i);
212 }
213 } else {
214 LOG_ERR("Unknown sample write");
215 return -EIO;
216 }
217 }
218
219 return 0;
220 }
221 #endif
222
223 #if BMI160_BUS_I2C
bmi160_emul_transfer_i2c(const struct emul * target,struct i2c_msg * msgs,int num_msgs,int addr)224 static int bmi160_emul_transfer_i2c(const struct emul *target, struct i2c_msg *msgs, int num_msgs,
225 int addr)
226 {
227 struct bmi160_emul_data *data;
228
229 data = target->data;
230
231 __ASSERT_NO_MSG(msgs && num_msgs);
232
233 i2c_dump_msgs_rw(target->dev, msgs, num_msgs, addr, false);
234 switch (num_msgs) {
235 case 2:
236 if (msgs->flags & I2C_MSG_READ) {
237 LOG_ERR("Unexpected read");
238 return -EIO;
239 }
240 if (msgs->len != 1) {
241 LOG_ERR("Unexpected msg0 length %d", msgs->len);
242 return -EIO;
243 }
244 data->cur_reg = msgs->buf[0];
245
246 /* Now process the 'read' part of the message */
247 msgs++;
248 if (msgs->flags & I2C_MSG_READ) {
249 for (int i = 0; i < msgs->len; ++i) {
250 msgs->buf[i] = reg_read(target, data->cur_reg + i);
251 }
252 } else {
253 if (msgs->len != 1) {
254 LOG_ERR("Unexpected msg1 length %d", msgs->len);
255 }
256 reg_write(target, data->cur_reg, msgs->buf[0]);
257 }
258 break;
259 default:
260 LOG_ERR("Invalid number of messages: %d", num_msgs);
261 return -EIO;
262 }
263
264 return 0;
265 }
266 #endif
267
268 /* Device instantiation */
269
270 #if BMI160_BUS_SPI
271 static struct spi_emul_api bmi160_emul_api_spi = {
272 .io = bmi160_emul_io_spi,
273 };
274 #endif
275
276 #if BMI160_BUS_I2C
277 static struct i2c_emul_api bmi160_emul_api_i2c = {
278 .transfer = bmi160_emul_transfer_i2c,
279 };
280 #endif
281
bmi160_emul_backend_set_channel(const struct emul * target,struct sensor_chan_spec ch,const q31_t * value,int8_t shift)282 static int bmi160_emul_backend_set_channel(const struct emul *target, struct sensor_chan_spec ch,
283 const q31_t *value, int8_t shift)
284 {
285 const struct bmi160_emul_cfg *cfg = target->cfg;
286 int64_t intermediate = *value;
287 q31_t scale;
288 int8_t scale_shift = 0;
289 int reg_lsb;
290
291 switch (ch.chan_type) {
292 case SENSOR_CHAN_ACCEL_X:
293 case SENSOR_CHAN_ACCEL_Y:
294 case SENSOR_CHAN_ACCEL_Z:
295 reg_lsb = BMI160_REG_DATA_ACC_X + (ch.chan_type - SENSOR_CHAN_ACCEL_X) * 2;
296 scale = 0x4e7404ea;
297
298 switch (FIELD_GET(GENMASK(3, 0), cfg->reg[BMI160_REG_ACC_RANGE])) {
299 case BMI160_ACC_RANGE_4G:
300 scale_shift = 6;
301 break;
302 case BMI160_ACC_RANGE_8G:
303 scale_shift = 7;
304 break;
305 case BMI160_ACC_RANGE_16G:
306 scale_shift = 8;
307 break;
308 default:
309 scale_shift = 5;
310 break;
311 }
312 break;
313 case SENSOR_CHAN_GYRO_X:
314 case SENSOR_CHAN_GYRO_Y:
315 case SENSOR_CHAN_GYRO_Z:
316 reg_lsb = BMI160_REG_DATA_GYR_X + (ch.chan_type - SENSOR_CHAN_GYRO_X) * 2;
317 scale = 0x45d02bea;
318
319 switch (FIELD_GET(GENMASK(2, 0), cfg->reg[BMI160_REG_GYR_RANGE])) {
320 case BMI160_GYR_RANGE_2000DPS:
321 scale_shift = 6;
322 break;
323 case BMI160_GYR_RANGE_1000DPS:
324 scale_shift = 5;
325 break;
326 case BMI160_GYR_RANGE_500DPS:
327 scale_shift = 4;
328 break;
329 case BMI160_GYR_RANGE_250DPS:
330 scale_shift = 3;
331 break;
332 case BMI160_GYR_RANGE_125DPS:
333 scale_shift = 2;
334 break;
335 default:
336 return -EINVAL;
337 }
338 break;
339 case SENSOR_CHAN_DIE_TEMP:
340 reg_lsb = BMI160_REG_TEMPERATURE0;
341 scale = 0x8000;
342 scale_shift = 7;
343 break;
344 default:
345 return -EINVAL;
346 }
347
348 if (shift < scale_shift) {
349 /* Original value doesn't have enough int bits, fix it */
350 intermediate >>= scale_shift - shift;
351 } else if (shift > 0 && shift > scale_shift) {
352 /* Original value might be out-of-bounds, fix it (we're going to lose precision) */
353 intermediate <<= shift - scale_shift;
354 }
355
356 if (ch.chan_type == SENSOR_CHAN_DIE_TEMP) {
357 /* Need to subtract 23C */
358 intermediate -= INT64_C(23) << (31 - scale_shift);
359 }
360
361 intermediate =
362 CLAMP(DIV_ROUND_CLOSEST(intermediate * INT16_MAX, scale), INT16_MIN, INT16_MAX);
363
364 cfg->reg[reg_lsb] = FIELD_GET(GENMASK64(7, 0), intermediate);
365 cfg->reg[reg_lsb + 1] = FIELD_GET(GENMASK64(15, 8), intermediate);
366 return 0;
367 }
368
bmi160_emul_backend_get_sample_range(const struct emul * target,struct sensor_chan_spec ch,q31_t * lower,q31_t * upper,q31_t * epsilon,int8_t * shift)369 static int bmi160_emul_backend_get_sample_range(const struct emul *target,
370 struct sensor_chan_spec ch, q31_t *lower,
371 q31_t *upper, q31_t *epsilon, int8_t *shift)
372 {
373 const struct bmi160_emul_cfg *cfg = target->cfg;
374
375 switch (ch.chan_type) {
376 case SENSOR_CHAN_ACCEL_X:
377 case SENSOR_CHAN_ACCEL_Y:
378 case SENSOR_CHAN_ACCEL_Z:
379 case SENSOR_CHAN_ACCEL_XYZ: {
380 uint8_t acc_range = cfg->reg[BMI160_REG_ACC_RANGE];
381
382 switch (acc_range) {
383 case BMI160_ACC_RANGE_2G:
384 *shift = 5;
385 break;
386 case BMI160_ACC_RANGE_4G:
387 *shift = 6;
388 break;
389 case BMI160_ACC_RANGE_8G:
390 *shift = 7;
391 break;
392 case BMI160_ACC_RANGE_16G:
393 *shift = 8;
394 break;
395 default:
396 return -EINVAL;
397 }
398 int64_t intermediate = ((int64_t)(2 * 9.80665 * INT32_MAX)) >> 5;
399
400 *upper = intermediate;
401 *lower = -(*upper);
402 *epsilon = intermediate * 2 / (1 << (16 - *shift));
403 return 0;
404 }
405 case SENSOR_CHAN_GYRO_X:
406 case SENSOR_CHAN_GYRO_Y:
407 case SENSOR_CHAN_GYRO_Z:
408 case SENSOR_CHAN_GYRO_XYZ: {
409 uint8_t gyro_range = cfg->reg[BMI160_REG_GYR_RANGE];
410
411 switch (gyro_range) {
412 case BMI160_GYR_RANGE_125DPS:
413 *shift = 2;
414 break;
415 case BMI160_GYR_RANGE_250DPS:
416 *shift = 3;
417 break;
418 case BMI160_GYR_RANGE_500DPS:
419 *shift = 4;
420 break;
421 case BMI160_GYR_RANGE_1000DPS:
422 *shift = 5;
423 break;
424 case BMI160_GYR_RANGE_2000DPS:
425 *shift = 6;
426 break;
427 default:
428 return -EINVAL;
429 }
430
431 int64_t intermediate = (int64_t)(125 * 3.141592654 * INT32_MAX / 180) >> 2;
432
433 *upper = intermediate;
434 *lower = -(*upper);
435 *epsilon = intermediate * 2 / (1 << (16 - *shift));
436 return 0;
437 }
438 default:
439 return -EINVAL;
440 }
441 }
442
bmi160_emul_backend_set_offset(const struct emul * target,struct sensor_chan_spec ch,const q31_t * values,int8_t shift)443 static int bmi160_emul_backend_set_offset(const struct emul *target, struct sensor_chan_spec ch,
444 const q31_t *values, int8_t shift)
445 {
446 if (ch.chan_type != SENSOR_CHAN_ACCEL_XYZ && ch.chan_type != SENSOR_CHAN_GYRO_XYZ) {
447 return -EINVAL;
448 }
449
450 const struct bmi160_emul_cfg *cfg = target->cfg;
451 q31_t scale;
452 int8_t scale_shift = 0;
453
454 if (values[0] == 0 && values[1] == 0 && values[2] == 0) {
455 if (ch.chan_type == SENSOR_CHAN_ACCEL_XYZ) {
456 cfg->reg[BMI160_REG_OFFSET_EN] &= ~BIT(BMI160_ACC_OFS_EN_POS);
457 } else {
458 cfg->reg[BMI160_REG_OFFSET_EN] &= ~BIT(BMI160_GYR_OFS_EN_POS);
459 }
460 } else {
461 if (ch.chan_type == SENSOR_CHAN_ACCEL_XYZ) {
462 cfg->reg[BMI160_REG_OFFSET_EN] |= BIT(BMI160_ACC_OFS_EN_POS);
463 } else {
464 cfg->reg[BMI160_REG_OFFSET_EN] |= BIT(BMI160_GYR_OFS_EN_POS);
465 }
466 }
467
468 if (ch.chan_type == SENSOR_CHAN_ACCEL_XYZ) {
469 /*
470 * bits = (values[i]mps2 / 9.80665g/mps2) / 0.0039g
471 * = values[i] / 0.038245935mps2/bit
472 * 0.038245935 in Q31 format is 0x4e53e28 with shift 0
473 */
474 scale = 0x4e53e28;
475 } else {
476 /*
477 * bits = (values[i]rad/s * 180 / pi) / 0.061deg/s
478 * = values[i] / 0.001064651rad/s
479 */
480 scale = 0x22e2f0;
481 }
482
483 for (int i = 0; i < 3; ++i) {
484 int64_t intermediate = values[i];
485
486 if (shift > scale_shift) {
487 /* Input uses a bigger scale, we need to increase its value to match */
488 intermediate <<= (shift - scale_shift);
489 } else if (shift < scale_shift) {
490 /* Scale uses a bigger shift, we need to decrease its value to match */
491 scale >>= (scale_shift - shift);
492 }
493
494 int64_t reg_value = intermediate / scale;
495
496 __ASSERT_NO_MSG(ch.chan_type != SENSOR_CHAN_ACCEL_XYZ ||
497 (reg_value >= INT8_MIN && reg_value <= INT8_MAX));
498 __ASSERT_NO_MSG(ch.chan_type != SENSOR_CHAN_GYRO_XYZ ||
499 (reg_value >= -0x1ff - 1 && reg_value <= 0x1ff));
500 if (ch.chan_type == SENSOR_CHAN_ACCEL_XYZ) {
501 cfg->reg[BMI160_REG_OFFSET_ACC_X + i] = reg_value & 0xff;
502 } else {
503 cfg->reg[BMI160_REG_OFFSET_GYR_X + i] = reg_value & 0xff;
504 cfg->reg[BMI160_REG_OFFSET_EN] =
505 (cfg->reg[BMI160_REG_OFFSET_EN] & ~GENMASK(i * 2 + 1, i * 2)) |
506 (reg_value & GENMASK(9, 8));
507 }
508 }
509
510 return 0;
511 }
512
bmi160_emul_backend_set_attribute(const struct emul * target,struct sensor_chan_spec ch,enum sensor_attribute attribute,const void * value)513 static int bmi160_emul_backend_set_attribute(const struct emul *target, struct sensor_chan_spec ch,
514 enum sensor_attribute attribute, const void *value)
515 {
516 if (attribute == SENSOR_ATTR_OFFSET &&
517 (ch.chan_type == SENSOR_CHAN_ACCEL_XYZ || ch.chan_type == SENSOR_CHAN_GYRO_XYZ)) {
518 const struct sensor_three_axis_attribute *attribute_value = value;
519
520 return bmi160_emul_backend_set_offset(target, ch, attribute_value->values,
521 attribute_value->shift);
522 }
523 return -EINVAL;
524 }
525
bmi160_emul_backend_get_attribute_metadata(const struct emul * target,struct sensor_chan_spec ch,enum sensor_attribute attribute,q31_t * min,q31_t * max,q31_t * increment,int8_t * shift)526 static int bmi160_emul_backend_get_attribute_metadata(const struct emul *target,
527 struct sensor_chan_spec ch,
528 enum sensor_attribute attribute, q31_t *min,
529 q31_t *max, q31_t *increment, int8_t *shift)
530 {
531 ARG_UNUSED(target);
532 switch (ch.chan_type) {
533 case SENSOR_CHAN_ACCEL_X:
534 case SENSOR_CHAN_ACCEL_Y:
535 case SENSOR_CHAN_ACCEL_Z:
536 case SENSOR_CHAN_ACCEL_XYZ:
537 if (attribute == SENSOR_ATTR_OFFSET) {
538 /* Offset uses 3.9mg per bit in an 8 bit register:
539 * 0.0039g * 9.8065m/s2: yields the increment in SI units
540 * * INT8_MIN (or MAX) : yields the minimum (or maximum) values
541 * * INT32_MAX >> 3 : converts to q31 format within range [-8, 8]
542 */
543 *min = (q31_t)((int64_t)(0.0039 * 9.8065 * INT8_MIN * INT32_MAX) >> 3);
544 *max = (q31_t)((int64_t)(0.0039 * 9.8065 * INT8_MAX * INT32_MAX) >> 3);
545 *increment = (q31_t)((int64_t)(0.0039 * 9.8065 * INT32_MAX) >> 3);
546 *shift = 3;
547 return 0;
548 }
549 return -EINVAL;
550 case SENSOR_CHAN_GYRO_X:
551 case SENSOR_CHAN_GYRO_Y:
552 case SENSOR_CHAN_GYRO_Z:
553 case SENSOR_CHAN_GYRO_XYZ:
554 if (attribute == SENSOR_ATTR_OFFSET) {
555 /* Offset uses 0.061deg/s per bit in an 10 bit register:
556 * 0.061deg/s * pi / 180: yields the increment in SI units
557 * * INT10_MIN (or MAX) : yields the minimum (or maximum) values
558 * * INT32_MAX : converts to q31 format within range [-1, 1]
559 */
560 *min = (q31_t)(0.061 * 3.141593 / 180.0 * -512 * INT32_MAX);
561 *max = (q31_t)(0.061 * 3.141593 / 180.0 * 511 * INT32_MAX);
562 *increment = (q31_t)(0.061 * 3.141593 / 180.0 * INT32_MAX);
563 *shift = 0;
564 return 0;
565 }
566 return -EINVAL;
567 default:
568 return -EINVAL;
569 }
570 }
571
572 static const struct emul_sensor_driver_api backend_api = {
573 .set_channel = bmi160_emul_backend_set_channel,
574 .get_sample_range = bmi160_emul_backend_get_sample_range,
575 .set_attribute = bmi160_emul_backend_set_attribute,
576 .get_attribute_metadata = bmi160_emul_backend_get_attribute_metadata,
577 };
578
emul_bosch_bmi160_init(const struct emul * target,const struct device * parent)579 static int emul_bosch_bmi160_init(const struct emul *target, const struct device *parent)
580 {
581 const struct bmi160_emul_cfg *cfg = target->cfg;
582 struct bmi160_emul_data *data = target->data;
583 uint8_t *reg = cfg->reg;
584
585 ARG_UNUSED(parent);
586
587 data->pmu_status = 0;
588
589 reg[BMI160_REG_CHIPID] = BMI160_CHIP_ID;
590
591 return 0;
592 }
593
594 #define BMI160_EMUL_DATA(n) \
595 static uint8_t bmi160_emul_reg_##n[BMI160_REG_COUNT]; \
596 static struct bmi160_emul_data bmi160_emul_data_##n;
597
598 #define BMI160_EMUL_DEFINE(n, bus_api) \
599 EMUL_DT_INST_DEFINE(n, emul_bosch_bmi160_init, &bmi160_emul_data_##n, \
600 &bmi160_emul_cfg_##n, &bus_api, &backend_api)
601
602 /* Instantiation macros used when a device is on a SPI bus */
603 #define BMI160_EMUL_SPI(n) \
604 BMI160_EMUL_DATA(n) \
605 static const struct bmi160_emul_cfg bmi160_emul_cfg_##n = { \
606 .reg = bmi160_emul_reg_##n, .chipsel = DT_INST_REG_ADDR(n)}; \
607 BMI160_EMUL_DEFINE(n, bmi160_emul_api_spi)
608
609 #define BMI160_EMUL_I2C(n) \
610 BMI160_EMUL_DATA(n) \
611 static const struct bmi160_emul_cfg bmi160_emul_cfg_##n = {.reg = bmi160_emul_reg_##n, \
612 .addr = DT_INST_REG_ADDR(n)}; \
613 BMI160_EMUL_DEFINE(n, bmi160_emul_api_i2c)
614
615 /*
616 * Main instantiation macro. Use of COND_CODE_1() selects the right
617 * bus-specific macro at preprocessor time.
618 */
619 #define BMI160_EMUL(n) \
620 COND_CODE_1(DT_INST_ON_BUS(n, spi), (BMI160_EMUL_SPI(n)), (BMI160_EMUL_I2C(n)))
621
622 DT_INST_FOREACH_STATUS_OKAY(BMI160_EMUL)
623