altos: Add bmx160 driver
authorKeith Packard <keithp@keithp.com>
Mon, 16 Sep 2019 19:39:09 +0000 (12:39 -0700)
committerKeith Packard <keithp@keithp.com>
Mon, 16 Sep 2019 19:39:09 +0000 (12:39 -0700)
This just adds the driver, it doesn't hook it up yet

Signed-off-by: Keith Packard <keithp@keithp.com>
src/drivers/ao_bmx160.c [new file with mode: 0644]
src/drivers/ao_bmx160.h [new file with mode: 0644]
src/kernel/ao.h
src/kernel/ao_data.h

diff --git a/src/drivers/ao_bmx160.c b/src/drivers/ao_bmx160.c
new file mode 100644 (file)
index 0000000..4c3c2a9
--- /dev/null
@@ -0,0 +1,422 @@
+/*
+ * Copyright © 2019 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include <ao.h>
+#include <ao_bmx160.h>
+#include <ao_exti.h>
+
+static uint8_t ao_bmx160_configured;
+
+#define ao_bmx160_spi_get()    ao_spi_get(AO_BMX160_SPI_BUS, AO_SPI_SPEED_8MHz)
+#define ao_bmx160_spi_put()    ao_spi_put(AO_BMX160_SPI_BUS)
+
+#define ao_bmx160_spi_start()  ao_spi_set_cs(AO_BMX160_SPI_CS_PORT,    \
+                                             (1 << AO_BMX160_SPI_CS_PIN))
+
+#define ao_bmx160_spi_end()    ao_spi_clr_cs(AO_BMX160_SPI_CS_PORT,    \
+                                             (1 << AO_BMX160_SPI_CS_PIN))
+
+static void
+_ao_bmx160_reg_write(uint8_t addr, uint8_t value)
+{
+       uint8_t d[2] = { addr, value };
+       ao_bmx160_spi_start();
+       ao_spi_send(d, 2, AO_BMX160_SPI_BUS);
+       ao_bmx160_spi_end();
+}
+
+static void
+_ao_bmx160_read(uint8_t addr, void *data, uint8_t len)
+{
+       addr |= 0x80;
+       ao_bmx160_spi_start();
+       ao_spi_send(&addr, 1, AO_BMX160_SPI_BUS);
+       ao_spi_recv(data, len, AO_BMX160_SPI_BUS);
+       ao_bmx160_spi_end();
+}
+
+static uint8_t
+_ao_bmx160_reg_read(uint8_t addr)
+{
+       uint8_t value;
+       addr |= 0x80;
+       ao_bmx160_spi_start();
+       ao_spi_send(&addr, 1, AO_BMX160_SPI_BUS);
+       ao_spi_recv(&value, 1, AO_BMX160_SPI_BUS);
+       ao_bmx160_spi_end();
+       return value;
+}
+
+static void
+_ao_bmx160_cmd(uint8_t cmd)
+{
+       _ao_bmx160_reg_write(BMX160_CMD, cmd);
+       ao_delay(AO_MS_TO_TICKS(100));
+}
+
+static void
+_ao_bmx160_mag_setup(void)
+{
+       _ao_bmx160_reg_write(BMX160_MAG_IF_0, 0x80);
+}
+
+static void
+_ao_bmm150_wait_manual(void)
+{
+       while (_ao_bmx160_reg_read(BMX160_STATUS) & (1 << BMX160_STATUS_MAG_MAN_OP))
+               ;
+}
+
+static void
+_ao_bmm150_reg_write(uint8_t addr, uint8_t data)
+{
+       _ao_bmx160_reg_write(BMX160_MAG_IF_3, data);
+       _ao_bmx160_reg_write(BMX160_MAG_IF_2, addr);
+       _ao_bmm150_wait_manual();
+}
+
+static uint8_t
+_ao_bmm150_reg_read(uint8_t addr)
+{
+       _ao_bmx160_reg_write(BMX160_MAG_IF_1, addr);
+       _ao_bmm150_wait_manual();
+       return _ao_bmx160_reg_read(BMX160_DATA_0);
+}
+
+static void
+_ao_bmx160_sample(struct ao_bmx160_sample *sample)
+{
+       _ao_bmx160_read(BMX160_MAG_X_0_7, sample, sizeof (*sample));
+#if __BYTE_ORDER != __LITTLE_ENDIAN
+       int             i = sizeof (*sample) / 2;
+       uint16_t        *d = (uint16_t *) sample;
+
+       /* byte swap */
+       while (i--) {
+               uint16_t        t = *d;
+               *d++ = (t >> 8) | (t << 8);
+       }
+#endif
+}
+
+#define G      981     /* in cm/s² */
+
+#if 0
+static int16_t /* cm/s² */
+ao_bmx160_accel(int16_t v)
+{
+       return (int16_t) ((v * (int32_t) (16.0 * 980.665 + 0.5)) / 32767);
+}
+
+static int16_t /* deg*10/s */
+ao_bmx160_gyro(int16_t v)
+{
+       return (int16_t) ((v * (int32_t) 20000) / 32767);
+}
+
+static uint8_t
+ao_bmx160_accel_check(int16_t normal, int16_t test)
+{
+       int16_t diff = test - normal;
+
+       if (diff < BMX160_ST_ACCEL(16) / 4) {
+               return 1;
+       }
+       if (diff > BMX160_ST_ACCEL(16) * 4) {
+               return 1;
+       }
+       return 0;
+}
+
+static uint8_t
+ao_bmx160_gyro_check(int16_t normal, int16_t test)
+{
+       int16_t diff = test - normal;
+
+       if (diff < 0)
+               diff = -diff;
+       if (diff < BMX160_ST_GYRO(2000) / 4) {
+               return 1;
+       }
+       if (diff > BMX160_ST_GYRO(2000) * 4) {
+               return 1;
+       }
+       return 0;
+}
+#endif
+
+static void
+_ao_bmx160_wait_alive(void)
+{
+       uint8_t i;
+
+       /* Wait for the chip to wake up */
+       for (i = 0; i < 30; i++) {
+               ao_delay(AO_MS_TO_TICKS(100));
+               if (_ao_bmx160_reg_read(BMX160_CHIPID) == BMX160_CHIPID_BMX160)
+                       break;
+       }
+       if (i == 30)
+               ao_panic(AO_PANIC_SELF_TEST_BMX160);
+}
+
+#define ST_TRIES       10
+#define MAG_TRIES      10
+
+static void
+_ao_bmx160_setup(void)
+{
+       if (ao_bmx160_configured)
+               return;
+
+       /* Make sure the chip is responding */
+       _ao_bmx160_wait_alive();
+
+       /* Reboot */
+       _ao_bmx160_cmd(BMX160_CMD_SOFTRESET);
+
+       /* Force SPI mode */
+       _ao_bmx160_reg_write(BMX160_NV_CONF, 1 << BMX160_NV_CONF_SPI_EN);
+
+       /* Configure accelerometer:
+        *
+        *      undersampling disabled
+        *      normal filter
+        *      200Hz sampling rate
+        *      16g range
+        *
+        * This yields a 3dB cutoff frequency of 80Hz
+        */
+       _ao_bmx160_reg_write(BMX160_ACC_CONF,
+                            (0 << BMX160_ACC_CONF_ACC_US) |
+                            (BMX160_ACC_CONF_ACC_BWP_NORMAL << BMX160_ACC_CONF_ACC_BWP) |
+                            (BMX160_ACC_CONF_ACC_ODR_200 << BMX160_ACC_CONF_ACC_ODR));
+       _ao_bmx160_reg_write(BMX160_ACC_RANGE,
+                            BMX160_ACC_RANGE_16G);
+
+       /* Configure gyro:
+        *
+        *      200Hz sampling rate
+        *      Normal filter mode
+        *      ±2000°/s
+        */
+       _ao_bmx160_reg_write(BMX160_GYR_CONF,
+                            (BMX160_GYR_CONF_GYR_BWP_NORMAL << BMX160_GYR_CONF_GYR_BWP) |
+                            (BMX160_GYR_CONF_GYR_ODR_200 << BMX160_GYR_CONF_GYR_ODR));
+       _ao_bmx160_reg_write(BMX160_GYR_RANGE,
+                            BMX160_GYR_RANGE_2000);
+
+
+       /* Configure magnetometer:
+        *
+        *      30Hz sampling rate
+        *      power on
+        *      axes enabled
+        */
+       _ao_bmx160_cmd(BMX160_CMD_MAG_IF_SET_PMU_MODE(BMX160_PMU_STATUS_MAG_IF_PMU_STATUS_NORMAL));
+
+       /* Enter setup mode */
+       _ao_bmx160_mag_setup();
+
+       /* Place in suspend mode to reboot the chip */
+       _ao_bmm150_reg_write(BMM150_POWER_MODE,
+                            (0 << BMM150_POWER_MODE_POWER_CONTROL));
+
+       /* Power on */
+       _ao_bmm150_reg_write(BMM150_POWER_MODE,
+                            (1 << BMM150_POWER_MODE_POWER_CONTROL));
+
+       /* Set data rate and place in sleep mode */
+       _ao_bmm150_reg_write(BMM150_CONTROL,
+                            (BMM150_CONTROL_DATA_RATE_30 << BMM150_CONTROL_DATA_RATE) |
+                            (BMM150_CONTROL_OP_MODE_SLEEP << BMM150_CONTROL_OP_MODE));
+
+       /* enable all axes (should already be enabled) */
+       _ao_bmm150_reg_write(BMM150_INT_CONF,
+                            (0 << BMM150_INT_CONF_X_DISABLE) |
+                            (0 << BMM150_INT_CONF_Y_DISABLE) |
+                            (0 << BMM150_INT_CONF_Z_DISABLE));
+
+       /* Set repetition values (?) */
+       _ao_bmm150_reg_write(BMM150_REPXY, BMM150_REPXY_VALUE(9));
+       _ao_bmm150_reg_write(BMM150_REPZ, BMM150_REPZ_VALUE(15));
+
+       /* To get data out of the magnetometer, set the control op mode to 'forced', then read
+        * from the data registers
+        */
+       _ao_bmx160_reg_write(BMX160_MAG_IF_3, (BMM150_CONTROL_OP_MODE_FORCED << BMM150_CONTROL_OP_MODE));
+       _ao_bmx160_reg_write(BMX160_MAG_IF_2, BMM150_CONTROL);
+       _ao_bmx160_reg_write(BMX160_MAG_IF_1, BMM150_DATA_X_0_4);
+
+       /* Set data rate to 200Hz */
+       _ao_bmx160_reg_write(BMX160_MAG_CONF,
+                            (BMX160_MAG_CONF_MAG_ODR_200 << BMX160_MAG_CONF_MAG_ODR));
+
+       /* Put magnetometer interface back into 'normal mode'
+        */
+       _ao_bmx160_reg_write(BMX160_MAG_IF_0,
+                            (0 << BMX160_MAG_IF_0_MAG_MANUAL_EN) |
+                            (0 << BMX160_MAG_IF_0_MAG_OFFSET) |
+                            (0 << BMX160_MAG_IF_0_MAG_RD_BURST));
+
+       /* Enable acc and gyr
+        */
+
+       _ao_bmx160_cmd(BMX160_CMD_ACC_SET_PMU_MODE(BMX160_PMU_STATUS_ACC_PMU_STATUS_NORMAL));
+       _ao_bmx160_cmd(BMX160_CMD_GYR_SET_PMU_MODE(BMX160_PMU_STATUS_GYR_PMU_STATUS_NORMAL));
+       ao_bmx160_configured = 1;
+}
+
+struct ao_bmx160_sample        ao_bmx160_current;
+
+static void
+ao_bmx160(void)
+{
+       struct ao_bmx160_sample sample;
+
+       /* ao_bmx160_init already grabbed the SPI bus and mutex */
+       _ao_bmx160_setup();
+       ao_bmx160_spi_put();
+       for (;;)
+       {
+               ao_bmx160_spi_get();
+               _ao_bmx160_sample(&sample);
+               ao_bmx160_spi_put();
+               ao_arch_block_interrupts();
+               ao_bmx160_current = sample;
+               AO_DATA_PRESENT(AO_DATA_BMX160);
+               AO_DATA_WAIT();
+               ao_arch_release_interrupts();
+       }
+}
+
+static struct ao_task ao_bmx160_task;
+
+static void
+ao_bmx160_show(void)
+{
+       printf ("Accel: %7d %7d %7d Gyro: %7d %7d %7d Mag: %7d %7d %7d\n",
+               ao_bmx160_current.acc_x,
+               ao_bmx160_current.acc_y,
+               ao_bmx160_current.acc_z,
+               ao_bmx160_current.gyr_x,
+               ao_bmx160_current.gyr_y,
+               ao_bmx160_current.gyr_z,
+               ao_bmx160_current.mag_x,
+               ao_bmx160_current.mag_y,
+               ao_bmx160_current.mag_z);
+}
+
+#if BMX160_TEST
+
+static void
+ao_bmx160_read(void)
+{
+       uint8_t addr;
+       uint8_t val;
+
+       addr = ao_cmd_hex();
+       if (ao_cmd_status != ao_cmd_success)
+               return;
+       ao_bmx160_spi_get();
+       val = _ao_bmx160_reg_read(addr);
+       ao_bmx160_spi_put();
+       printf("Addr %02x val %02x\n", addr, val);
+}
+
+static void
+ao_bmx160_write(void)
+{
+       uint8_t addr;
+       uint8_t val;
+
+       addr = ao_cmd_hex();
+       if (ao_cmd_status != ao_cmd_success)
+               return;
+       val = ao_cmd_hex();
+       if (ao_cmd_status != ao_cmd_success)
+               return;
+       printf("Addr %02x val %02x\n", addr, val);
+       ao_bmx160_spi_get();
+       _ao_bmx160_reg_write(addr, val);
+       ao_bmx160_spi_put();
+}
+
+static void
+ao_bmm150_read(void)
+{
+       uint8_t addr;
+       uint8_t val;
+
+       addr = ao_cmd_hex();
+       if (ao_cmd_status != ao_cmd_success)
+               return;
+       ao_bmx160_spi_get();
+       val = _ao_bmm150_reg_read(addr);
+       ao_bmx160_spi_put();
+       printf("Addr %02x val %02x\n", addr, val);
+}
+
+static void
+ao_bmm150_write(void)
+{
+       uint8_t addr;
+       uint8_t val;
+
+       addr = ao_cmd_hex();
+       if (ao_cmd_status != ao_cmd_success)
+               return;
+       val = ao_cmd_hex();
+       if (ao_cmd_status != ao_cmd_success)
+               return;
+       printf("Addr %02x val %02x\n", addr, val);
+       ao_bmx160_spi_get();
+       _ao_bmm150_reg_write(addr, val);
+       ao_bmx160_spi_put();
+}
+
+#endif /* BMX160_TEST */
+
+static const struct ao_cmds ao_bmx160_cmds[] = {
+       { ao_bmx160_show,       "I\0Show BMX160 status" },
+#if BMX160_TEST
+       { ao_bmx160_read,       "R <addr>\0Read BMX160 register" },
+       { ao_bmx160_write,      "W <addr> <val>\0Write BMX160 register" },
+       { ao_bmm150_read,       "M <addr>\0Read BMM150 register" },
+       { ao_bmm150_write,      "N <addr> <val>\0Write BMM150 register" },
+#endif
+       { 0, NULL }
+};
+
+void
+ao_bmx160_init(void)
+{
+       ao_add_task(&ao_bmx160_task, ao_bmx160, "bmx160");
+
+       ao_spi_init_cs(AO_BMX160_SPI_CS_PORT, (1 << AO_BMX160_SPI_CS_PIN));
+
+       /* Pretend to be the bmx160 task. Grab the SPI bus right away and
+        * hold it for the task so that nothing else uses the SPI bus before
+        * we get the I2C mode disabled in the chip
+        */
+
+       ao_cur_task = &ao_bmx160_task;
+       ao_bmx160_spi_get();
+       ao_cur_task = NULL;
+       ao_cmd_register(&ao_bmx160_cmds[0]);
+}
diff --git a/src/drivers/ao_bmx160.h b/src/drivers/ao_bmx160.h
new file mode 100644 (file)
index 0000000..265be99
--- /dev/null
@@ -0,0 +1,253 @@
+/*
+ * Copyright © 2019 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#ifndef _AO_BMX160_H_
+#define _AO_BMX160_H_
+
+struct ao_bmx160_sample {
+       int16_t         mag_x;
+       int16_t         mag_y;
+       int16_t         mag_z;
+       int16_t         rhall;
+       int16_t         gyr_x;
+       int16_t         gyr_y;
+       int16_t         gyr_z;
+       int16_t         acc_x;
+       int16_t         acc_y;
+       int16_t         acc_z;
+};
+
+extern struct ao_bmx160_sample ao_bmx160_current;
+
+struct ao_bmx160_offset {
+       int8_t          off_acc_x;
+       int8_t          off_acc_y;
+       int8_t          off_acc_z;
+       int8_t          off_gyr_x;
+       int8_t          off_gyr_y;
+       int8_t          off_gyr_z;
+       uint8_t         offset_6;
+};
+
+void
+ao_bmx160_init(void);
+
+#define BMX160_CHIPID                  0x00
+#define  BMX160_CHIPID_BMX160                  0xd8
+#define BMX160_ERR_REG                 0x02
+#define BMX160_PMU_STATUS              0x03
+#define  BMX160_PMU_STATUS_MAG_IF_PMU_STATUS   0
+#define   BMX160_PMU_STATUS_MAG_IF_PMU_STATUS_SUSPEND          0
+#define   BMX160_PMU_STATUS_MAG_IF_PMU_STATUS_NORMAL           1
+#define   BMX160_PMU_STATUS_MAG_IF_PMU_STATUS_LOW_POWER                2
+#define  BMX160_PMU_STATUS_GYR_PMU_STATUS      2
+#define   BMX160_PMU_STATUS_GYR_PMU_STATUS_SUSPEND             0
+#define   BMX160_PMU_STATUS_GYR_PMU_STATUS_NORMAL              1
+#define   BMX160_PMU_STATUS_GYR_PMU_STATUS_FAST_START_UP       3
+#define  BMX160_PMU_STATUS_ACC_PMU_STATUS      4
+#define   BMX160_PMU_STATUS_ACC_PMU_STATUS_SUSPEND             0
+#define   BMX160_PMU_STATUS_ACC_PMU_STATUS_NORMAL              1
+#define   BMX160_PMU_STATUS_ACC_PMU_STATUS_LOW_POWER           2
+#define BMX160_DATA_0                  0x04
+#define BMX160_MAG_X_0_7               0x04
+#define BMX160_MAG_X_8_15              0x05
+#define BMX160_MAG_Y_0_7               0x06
+#define BMX160_MAG_Y_8_15              0x07
+#define BMX160_MAG_Z_0_7               0x08
+#define BMX160_MAG_Z_8_15              0x09
+#define BMX160_RHALL_0_7               0x0A
+#define BMX160_RHALL_8_15              0x0B
+#define BMX160_GYRO_X_0_7              0x0C
+#define BMX160_GYRO_X_8_15             0x0D
+#define BMX160_GYRO_Y_0_7              0x0E
+#define BMX160_GYRO_Y_8_15             0x0F
+#define BMX160_GYRO_Z_0_7              0x10
+#define BMX160_GYRO_Z_8_15             0x11
+#define BMX160_ACCEL_X_0_7             0x12
+#define BMX160_ACCEL_X_8_15            0x13
+#define BMX160_ACCEL_Y_0_7             0x14
+#define BMX160_ACCEL_Y_8_15            0x15
+#define BMX160_ACCEL_Z_0_7             0x16
+#define BMX160_ACCEL_Z_8_15            0x17
+#define BMX160_SENSORTIME_0_7          0x18
+#define BMX160_SENSORTIME_8_15         0x19
+#define BMX160_SENSORTIME_16_23                0x1A
+#define BMX160_STATUS                  0x1B
+#define  BMX160_STATUS_GYR_SELF_TEST_OK                1
+#define  BMX160_STATUS_MAG_MAN_OP              2
+#define  BMX160_STATUS_FOC_RDY                 3
+#define  BMX160_STATUS_NVM_RDY                 4
+#define  BMX160_STATUS_DRDY_MAG                        5
+#define  BMX160_STATUS_DRDY_GYR                        6
+#define  BMX160_STATUS_DRDY_ACC                        7
+#define BMX160_INT_STATUS_0            0x1C-0x1F
+#define BMX160_INT_STATUS_1            0x1D
+#define BMX160_INT_STATUS_2            0x1E
+#define BMX160_INT_STATUS_3            0x1F
+#define BMX160_TEMPERATURE_0_7         0x20
+#define BMX160_TEMPERATURE_8_15                0x21
+#define BMX160_FIFO_LENGTH_0_7         0x22
+#define BMX160_FIFO_LENGTH_8_15                0x23
+#define BMX160_FIFO_DATA               0x24
+#define BMX160_ACC_CONF                        0x40
+#define  BMX160_ACC_CONF_ACC_ODR               0
+#define   BMX160_ACC_CONF_ACC_ODR_25_32                        0x1
+#define   BMX160_ACC_CONF_ACC_ODR_25_16                        0x2
+#define   BMX160_ACC_CONF_ACC_ODR_25_8                 0x3
+#define   BMX160_ACC_CONF_ACC_ODR_25_4                 0x4
+#define   BMX160_ACC_CONF_ACC_ODR_25_2                 0x5
+#define   BMX160_ACC_CONF_ACC_ODR_25                   0x6
+#define   BMX160_ACC_CONF_ACC_ODR_50                   0x7
+#define   BMX160_ACC_CONF_ACC_ODR_100                  0x8
+#define   BMX160_ACC_CONF_ACC_ODR_200                  0x9
+#define   BMX160_ACC_CONF_ACC_ODR_400                  0xa
+#define   BMX160_ACC_CONF_ACC_ODR_800                  0xb
+#define   BMX160_ACC_CONF_ACC_ODR_1600                 0xc
+#define  BMX160_ACC_CONF_ACC_BWP               4
+#define   BMX160_ACC_CONF_ACC_BWP_NORMAL                       0x2
+#define   BMX160_ACC_CONF_ACC_BWP_OSR2                         0x1
+#define   BMX160_ACC_CONF_ACC_BWP_OSR4                         0x0
+#define  BMX160_ACC_CONF_ACC_US                        7
+#define BMX160_ACC_RANGE               0x41
+#define  BMX160_ACC_RANGE_2G                   0x3
+#define  BMX160_ACC_RANGE_4G                   0x5
+#define  BMX160_ACC_RANGE_8G                   0x8
+#define  BMX160_ACC_RANGE_16G                  0xc
+#define  BMX160_ACC_RANGE_
+#define  BMX160_ACC_RANGE_
+#define BMX160_GYR_CONF                        0x42
+#define  BMX160_GYR_CONF_GYR_ODR               0
+#define   BMX160_GYR_CONF_GYR_ODR_25                   0x6
+#define   BMX160_GYR_CONF_GYR_ODR_50                   0x7
+#define   BMX160_GYR_CONF_GYR_ODR_100                  0x8
+#define   BMX160_GYR_CONF_GYR_ODR_200                  0x9
+#define   BMX160_GYR_CONF_GYR_ODR_400                  0xa
+#define   BMX160_GYR_CONF_GYR_ODR_800                  0xb
+#define   BMX160_GYR_CONF_GYR_ODR_1600                 0xc
+#define   BMX160_GYR_CONF_GYR_ODR_3200                 0xd
+#define  BMX160_GYR_CONF_GYR_BWP               4
+#define   BMX160_GYR_CONF_GYR_BWP_NORMAL                       0x2
+#define   BMX160_GYR_CONF_GYR_BWP_OSR2                         0x1
+#define   BMX160_GYR_CONF_GYR_BWP_OSR4                         0x0
+#define BMX160_GYR_RANGE               0x43
+#define  BMX160_GYR_RANGE_2000                                 0x0
+#define  BMX160_GYR_RANGE_1000                                 0x1
+#define  BMX160_GYR_RANGE_500                                  0x2
+#define  BMX160_GYR_RANGE_250                                  0x3
+#define  BMX160_GYR_RANGE_125                                  0x4
+#define BMX160_MAG_CONF                        0x44
+#define  BMX160_MAG_CONF_MAG_ODR                       0
+#define   BMX160_MAG_CONF_MAG_ODR_25_32                                0x1
+#define   BMX160_MAG_CONF_MAG_ODR_25_16                                0x2
+#define   BMX160_MAG_CONF_MAG_ODR_25_8                         0x3
+#define   BMX160_MAG_CONF_MAG_ODR_25_4                         0x4
+#define   BMX160_MAG_CONF_MAG_ODR_25_2                         0x5
+#define   BMX160_MAG_CONF_MAG_ODR_25                           0x6
+#define   BMX160_MAG_CONF_MAG_ODR_50                           0x7
+#define   BMX160_MAG_CONF_MAG_ODR_100                          0x8
+#define   BMX160_MAG_CONF_MAG_ODR_200                          0x9
+#define   BMX160_MAG_CONF_MAG_ODR_400                          0xa
+#define   BMX160_MAG_CONF_MAG_ODR_800                          0xb
+#define BMX160_FIFO_DOWNS              0x45
+#define BMX160_FIFO_CONFIG_0           0x46
+#define BMX160_FIFO_CONFIG_1           0x47
+#define BMX160_MAG_IF_0                        0x4C
+#define  BMX160_MAG_IF_0_MAG_RD_BURST          0
+#define  BMX160_MAG_IF_0_MAG_OFFSET            2
+#define  BMX160_MAG_IF_0_MAG_MANUAL_EN         7
+#define BMX160_MAG_IF_1                        0x4D
+#define BMX160_MAG_IF_2                        0x4E
+#define BMX160_MAG_IF_3                        0x4F
+#define BMX160_INT_EN                  0x50-0x52
+#define BMX160_INT_OUT_CTRL            0x53
+#define BMX160_INT_LATCH               0x54
+#define BMX160_INT_MAP                 0x55-0x57
+#define BMX160_INT_DATA                        0x58-0x59
+#define BMX160_INT_LOWHIGH             0x5A-0x5E
+#define BMX160_INT_MOTION              0x5F-0x62
+#define BMX160_INT_TAP                 0x63-0x64
+#define BMX160_INT_ORIENT              0x65-0x66
+#define BMX160_INT_FLAT                        0x67-0x68
+#define BMX160_FOC_CONF                        0x69
+#define BMX160_CONF                    0x6A
+#define BMX160_IF_CONF                 0x6B
+#define BMX160_PMU_TRIGGER             0x6C
+#define BMX160_SELF_TEST               0x6D
+#define BMX160_NV_CONF                 0x70
+#define  BMX160_NV_CONF_SPI_EN                 0
+#define  BMX160_NV_CONF_I2C_WDT_SEL            1
+#define  BMX160_NV_CONF_I2C_WDT_EN             2
+#define BMX160_OFFSET                  0x71-0x77
+#define BMX160_STEP_CNT                        0x78-0x79
+#define BMX160_STEP_CONF               0x7A-0x7B
+#define BMX160_CMD                     0x7E
+#define  BMX160_CMD_START_FOC                  0x03
+#define  BMX160_CMD_ACC_SET_PMU_MODE(n)                (0x10 | (n))
+#define  BMX160_CMD_GYR_SET_PMU_MODE(n)                (0x14 | (n))
+#define  BMX160_CMD_MAG_IF_SET_PMU_MODE(n)     (0x18 | (n))
+#define  BMX160_CMD_PROG_NVM                   0xa0
+#define  BMX160_CMD_FIFO_FLUSH                 0xb0
+#define  BMX160_CMD_INT_RESET                  0xb1
+#define  BMX160_CMD_SOFTRESET                  0xb6
+#define  BMX160_CMD_STEP_CNT_CLR               0xb2
+
+#define BMM150_CHIP_ID                         0x40
+#define BMM150_DATA_X_0_4                      0x42
+#define BMM150_DATA_X_5_12                     0x43
+#define BMM150_DATA_Y_0_4                      0x44
+#define BMM150_DATA_Y_5_12                     0x45
+#define BMM150_DATA_Z_0_6                      0x46
+#define BMM150_DATA_Z_7_14                     0x47
+#define BMM150_RHALL_0_5                       0x48
+#define BMM150_RHALL_6_13                      0x49
+#define BMM150_INT_STATUS                      0x4a
+#define BMM150_POWER_MODE                      0x4b
+#define  BMM150_POWER_MODE_SOFT_RESET_HI               7
+#define  BMM150_POWER_MODE_SPI3EN                      2
+#define  BMM150_POWER_MODE_SOFT_RESET_LO               1
+#define  BMM150_POWER_MODE_POWER_CONTROL               0
+#define BMM150_CONTROL                         0x4c
+#define  BMM150_CONTROL_ADV_ST_1                       7
+#define  BMM150_CONTROL_ADV_ST_0                       6
+#define  BMM150_CONTROL_DATA_RATE                      3
+#define   BMM150_CONTROL_DATA_RATE_10                          0
+#define   BMM150_CONTROL_DATA_RATE_2                           1
+#define   BMM150_CONTROL_DATA_RATE_6                           2
+#define   BMM150_CONTROL_DATA_RATE_8                           3
+#define   BMM150_CONTROL_DATA_RATE_15                          4
+#define   BMM150_CONTROL_DATA_RATE_20                          5
+#define   BMM150_CONTROL_DATA_RATE_25                          6
+#define   BMM150_CONTROL_DATA_RATE_30                          7
+#define  BMM150_CONTROL_OP_MODE                                1
+#define   BMM150_CONTROL_OP_MODE_NORMAL                                0
+#define   BMM150_CONTROL_OP_MODE_FORCED                                1
+#define   BMM150_CONTROL_OP_MODE_SLEEP                         3
+#define  BMM150_CONTROL_SELF_TEST                      0
+#define BMM150_INT_EN                          0x4d
+#define BMM150_INT_CONF                                0x4e
+#define  BMM150_INT_CONF_X_DISABLE                     3
+#define  BMM150_INT_CONF_Y_DISABLE                     4
+#define  BMM150_INT_CONF_Z_DISABLE                     5
+#define BMM150_LOW_THRESHOLD                   0x4f
+#define BMM150_HIGH_THRESHOLD                  0x50
+#define BMM150_REPXY                           0x51
+#define  BMM150_REPXY_VALUE(n)                         (((n)-1) >> 1)
+#define BMM150_REPZ                            0x52
+#define  BMM150_REPZ_VALUE(n)                          ((n) -1)
+
+#endif /* _BMX160_H_ */
index 21ab274..fb7af24 100644 (file)
@@ -75,6 +75,7 @@ typedef AO_PORT_TYPE ao_port_t;
 #define AO_PANIC_SELF_TEST_HMC5883     0x40 | 2        /* Self test failure */
 #define AO_PANIC_SELF_TEST_MPU6000     0x40 | 3        /* Self test failure */
 #define AO_PANIC_SELF_TEST_MPU9250     0x40 | 3        /* Self test failure */
+#define AO_PANIC_SELF_TEST_BMX160      0x40 | 3        /* Self test failure */
 #define AO_PANIC_SELF_TEST_MS5607      0x40 | 4        /* Self test failure */
 #define AO_PANIC_SELF_TEST_ADS124S0X   0x40 | 5        /* Self test failure */
 
index 4fc9db8..55d82e4 100644 (file)
 #define AO_DATA_MAX6691 0
 #endif
 
+#if HAS_BMX160
+#include <ao_bmx160.h>
+#define AO_DATA_BMX160 (1 << 2)
+#else
+#define AO_DATA_BMX160 0
+#endif
+
 #ifndef HAS_SENSOR_ERRORS
 #if HAS_IMU || HAS_MMA655X || HAS_MS5607 || HAS_MS5611
 #define HAS_SENSOR_ERRORS      1
@@ -88,7 +95,7 @@ extern uint8_t                        ao_sensor_errors;
 
 #ifdef AO_DATA_RING
 
-#define AO_DATA_ALL    (AO_DATA_ADC|AO_DATA_MS5607|AO_DATA_MPU6000|AO_DATA_HMC5883|AO_DATA_MMA655X|AO_DATA_MPU9250|AO_DATA_ADXL375)
+#define AO_DATA_ALL    (AO_DATA_ADC|AO_DATA_MS5607|AO_DATA_MPU6000|AO_DATA_HMC5883|AO_DATA_MMA655X|AO_DATA_MPU9250|AO_DATA_ADXL375|AO_DATA_BMX160)
 
 struct ao_data {
        uint16_t                        tick;
@@ -123,6 +130,9 @@ struct ao_data {
 #if HAS_ADS131A0X
        struct ao_ads131a0x_sample      ads131a0x;
 #endif
+#if HAS_BMX160
+       struct ao_bmx160_sample         bmx160;
+#endif
 };
 
 #define ao_data_ring_next(n)   (((n) + 1) & (AO_DATA_RING - 1))