34 #if defined(PIOS_INCLUDE_BMM150)
39 #include "physical_constants.h"
44 #define PIOS_BMM_TASK_PRIORITY PIOS_THREAD_PRIO_HIGHEST
46 #define PIOS_BMM_TASK_STACK 640
48 #define PIOS_BMM_QUEUE_LEN 2
50 #define PIOS_BMM_SPI_SPEED 10000000
57 enum pios_bmm150_dev_magic {
58 PIOS_BMM_DEV_MAGIC = 0x586e6f42
64 struct pios_bmm150_dev {
65 enum pios_bmm150_dev_magic
magic;
68 uint32_t spi_slave_mag;
72 struct pios_thread *task_handle;
92 static struct pios_bmm150_dev *bmm_dev;
104 static int32_t PIOS_BMM_Validate(
struct pios_bmm150_dev *dev);
106 static void PIOS_BMM_Task(
void *parameters);
109 int16_t mag_data_x, uint16_t data_r);
111 int16_t mag_data_y, uint16_t data_r);
113 int16_t mag_data_z, uint16_t data_r);
118 static int32_t PIOS_BMM_ClaimBus();
124 static int32_t PIOS_BMM_ReleaseBus();
126 static int32_t PIOS_BMM_ReadReg(uint8_t address, uint8_t *buffer);
127 static int32_t PIOS_BMM_WriteReg(uint8_t address, uint8_t buffer);
131 struct pios_bmm150_dev *dev;
133 dev = (
struct pios_bmm150_dev *)
PIOS_malloc(
sizeof(*bmm_dev));
137 dev->magic = PIOS_BMM_DEV_MAGIC;
140 if (dev->mag_queue == NULL) {
148 static int32_t PIOS_BMM_Validate(
struct pios_bmm150_dev *dev)
152 if (dev->magic != PIOS_BMM_DEV_MAGIC)
154 if (dev->spi_id == 0)
159 static int32_t AssertReg(uint8_t address, uint8_t expect) {
162 int32_t ret = PIOS_BMM_ReadReg(address, &c);
169 DEBUG_PRINTF(2,
"BMM: Assertion failed: *(%02x) == %02x (expect %02x)\n",
174 DEBUG_PRINTF(2,
"BMM: Assertion passed: *(%02x) == %02x\n", address,
184 ret = PIOS_BMM_ReadReg(
BMM150_DIG_X1, (uint8_t *) &dev->dig_x1);
187 ret = PIOS_BMM_ReadReg(
BMM150_DIG_X2, (uint8_t *) &dev->dig_x2);
190 ret = PIOS_BMM_ReadReg(
BMM150_DIG_Y1, (uint8_t *) &dev->dig_y1);
193 ret = PIOS_BMM_ReadReg(
BMM150_DIG_Y2, (uint8_t *) &dev->dig_y2);
199 ret = PIOS_BMM_ReadReg(
BMM150_DIG_X2, (uint8_t *) &dev->dig_xy2);
211 dev->dig_z1 = (tmp[1] << 8) | tmp[0];
217 dev->dig_z2 = (tmp[1] << 8) | tmp[0];
223 dev->dig_z3 = (tmp[1] << 8) | tmp[0];
229 dev->dig_z4 = (tmp[1] << 8) | tmp[0];
235 dev->dig_xyz1 = (tmp[1] << 8) | tmp[0];
237 DEBUG_PRINTF(2,
"BMM: x1=%d y1=%d x2=%d y2=%d xy1=%d xy2=%d\n",
238 dev->dig_x1, dev->dig_y1, dev->dig_x2, dev->dig_y2,
239 dev->dig_xy1, dev->dig_xy2);
241 DEBUG_PRINTF(2,
"BMM: z1=%d z2=%d z3=%d z4=%d xyz1=%d\n",
242 dev->dig_z1, dev->dig_z2, dev->dig_z3, dev->dig_z4,
251 bmm_dev = PIOS_BMM_Alloc(cfg);
256 bmm_dev->spi_id = spi_id;
257 bmm_dev->spi_slave_mag = slave_mag;
287 ret = PIOS_BMM150_ReadTrims(bmm_dev);
328 PIOS_BMM_Task,
"pios_bmm", PIOS_BMM_TASK_STACK,
329 NULL, PIOS_BMM_TASK_PRIORITY);
336 static int32_t PIOS_BMM_ClaimBus()
338 if (PIOS_BMM_Validate(bmm_dev) != 0)
351 static int32_t PIOS_BMM_ReleaseBus()
353 if (PIOS_BMM_Validate(bmm_dev) != 0)
363 static int32_t PIOS_BMM_ReadReg(uint8_t address, uint8_t *buffer)
365 if (PIOS_BMM_ClaimBus() != 0)
371 PIOS_BMM_ReleaseBus();
376 static int32_t PIOS_BMM_WriteReg(uint8_t address, uint8_t buffer)
378 if (PIOS_BMM_ClaimBus() != 0)
384 PIOS_BMM_ReleaseBus();
389 static void PIOS_BMM_Task(
void *parameters)
412 if (PIOS_BMM_ClaimBus() != 0)
422 sizeof(sensor_buf)) < 0) {
423 PIOS_BMM_ReleaseBus();
427 PIOS_BMM_ReleaseBus();
439 #define PACK_REG13_ADDR_OFFSET(b, reg, off) ((int16_t) ( (b[reg-off] & 0xf8) | (b[reg-off+1] << 8) ))
440 #define PACK_REG14_ADDR_OFFSET(b, reg, off) ((int16_t) ( (b[reg-off] & 0xfc) | (b[reg-off+1] << 8) ))
441 #define PACK_REG15_ADDR_OFFSET(b, reg, off) ((int16_t) ( (b[reg-off] & 0xfe) | (b[reg-off+1] << 8) ))
443 int16_t raw_x, raw_y, raw_z, raw_r;
453 raw_r = PACK_REG14_ADDR_OFFSET(sensor_buf,
466 float mag_x = bmm050_compensate_X_float(bmm_dev,
468 float mag_y = bmm050_compensate_Y_float(bmm_dev,
470 float mag_z = bmm050_compensate_Z_float(bmm_dev,
473 switch (bmm_dev->cfg->orientation) {
573 int16_t mag_data_x, uint16_t data_r)
581 inter_retval = ((((float)p_bmm050->dig_xyz1)
582 * 16384.0f / data_r) - 16384.0
f);
587 inter_retval = (((mag_data_x * ((((((float)p_bmm050->dig_xy2) *
588 (inter_retval*inter_retval /
590 inter_retval * ((
float)p_bmm050->dig_xy1)
591 / 16384.0
f)) + 256.0
f) *
592 (((float)p_bmm050->dig_x2) + 160.0f)))
594 + (((float)p_bmm050->dig_x1) *
615 int16_t mag_data_y, uint16_t data_r)
623 inter_retval = ((((float)p_bmm050->dig_xyz1)
625 /data_r) - 16384.0
f);
630 inter_retval = (((mag_data_y * ((((((float)p_bmm050->dig_xy2) *
631 (inter_retval*inter_retval
633 inter_retval * ((
float)p_bmm050->dig_xy1)
636 (((float)p_bmm050->dig_y2) + 160.0f)))
638 (((float)p_bmm050->dig_y1) * 8.0f))
660 int16_t mag_data_z, uint16_t data_r)
669 inter_retval = ((((((float)mag_data_z)-
670 ((float)p_bmm050->dig_z4)) * 131072.0
f)-
671 (((float)p_bmm050->dig_z3)*(((float)data_r)
672 -((float)p_bmm050->dig_xyz1))))
673 /((((
float)p_bmm050->dig_z2)+
674 ((
float)p_bmm050->dig_z1)*((
float)data_r) /
675 32768.0f) * 4.0f)) / 16.0f;
682 #endif // PIOS_INCLUDE_BMM150
#define BMM150_REG_MAG_OPERATION_MODE
struct pios_queue * PIOS_Queue_Create(size_t queue_length, size_t item_size)
Main PiOS header to include all the compiled in PiOS options.
int32_t PIOS_BMM150_SPI_Init(pios_bmm150_dev_t *dev, pios_spi_t spi_id, uint32_t slave_mag, const struct pios_bmm150_cfg *cfg)
Initialize the BMM-xxxx 6/9-axis sensor on SPI.
int32_t PIOS_SPI_RC_PinSet(pios_spi_t spi_dev, uint32_t slave_id, bool pin_value)
#define BMM050_FLIP_OVERFLOW_ADCVAL
#define BMM150_REG_MAG_X_LSB
int32_t PIOS_SPI_ClaimBus(pios_spi_t spi_dev)
#define BMM150_DIG_XYZ1_MSB
#define BMM150_DIG_Z4_MSB
void * PIOS_malloc(size_t size)
bool PIOS_Queue_Send(struct pios_queue *queuep, const void *itemp, uint32_t timeout_ms)
#define BMM150_DIG_Z1_MSB
#define BMM150_DIG_Z1_LSB
#define BMM050_INIT_VALUE
#define BMM150_DIG_Z3_LSB
#define DEBUG_PRINTF(level,...)
static struct flyingpicmd_cfg_fa cfg
#define BMM150_REG_MAG_Y_LSB
#define BMM150_REG_MAG_CHIPID
#define BMM150_DIG_Z2_MSB
#define BMM050_OVERFLOW_OUTPUT_FLOAT
uint8_t PIOS_SPI_TransferByte(pios_spi_t spi_dev, uint8_t b)
int32_t PIOS_SPI_SetClockSpeed(pios_spi_t spi_dev, uint32_t speed)
int32_t PIOS_SPI_TransferBlock(pios_spi_t spi_dev, const uint8_t *send_buffer, uint8_t *receive_buffer, uint16_t len)
struct pios_thread * PIOS_Thread_Create(void(*fp)(void *), const char *namep, size_t stack_bytes, void *argp, enum pios_thread_prio_e prio)
int32_t PIOS_SENSORS_Register(enum pios_sensor_type type, struct pios_queue *queue)
Register a queue-based sensor with the PIOS_SENSORS interface.
static float mag_scale[3]
#define BMM150_VAL_MAG_CHIPID
#define BMM150_REG_MAG_Z_AXIS_REP
#define BMM150_DIG_Z4_LSB
#define BMM150_VAL_MAG_OPERATION_MODE_OPMODE_NORMAL
#define BMM050_HALL_OVERFLOW_ADCVAL
#define BMM150_VAL_MAG_POWER_CONTROL_POWEROFF
void PIOS_free(void *buf)
void PIOS_Thread_Sleep(uint32_t time_ms)
Pios sensor structure for generic mag data.
struct pios_bmm150_dev * pios_bmm150_dev_t
#define BMM150_REG_MAG_POWER_CONTROL
#define BMM150_REG_MAG_HALL_RESISTANCE_LSB
#define BMM150_DIG_Z2_LSB
Includes PiOS and core architecture components.
#define BMM150_REG_MAG_Z_LSB
#define BMM150_REG_MAG_X_Y_AXIS_REP
int32_t PIOS_SPI_ReleaseBus(pios_spi_t spi_dev)
#define BMM150_VAL_MAG_POWER_CONTROL_POWERON
#define BMM150_REG_MAG_HALL_RESISTANCE_MSB
#define BMM150_VAL_MAG_OPERATION_MODE_ODR30
#define BMM150_VAL_MAG_HALL_RESISTANCE_LSB_DRDY
int32_t PIOS_DELAY_WaitmS(uint32_t mS)
#define BMM150_DIG_Z3_MSB
#define BMM150_DIG_XYZ1_LSB