static irqreturn_t mag3110_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct mag3110_data *data = iio_priv(indio_dev); u8 buffer[16]; /* 3 16-bit channels + 1 byte temp + padding + ts */ int ret; ret = mag3110_read(data, (__be16 *) buffer); if (ret < 0) goto done; if (test_bit(3, indio_dev->active_scan_mask)) { ret = i2c_smbus_read_byte_data(data->client, MAG3110_DIE_TEMP); if (ret < 0) goto done; buffer[6] = ret; } iio_push_to_buffers_with_timestamp(indio_dev, buffer, iio_get_time_ns()); done: iio_trigger_notify_done(indio_dev->trig); return IRQ_HANDLED; }
void mag3110_init(void) { uint8_t deviceid; /* read sensor ID */ deviceid = mag3110_read(0x07); /* check available sensor */ if (deviceid != 0xC4) { printf("mag3110: Device not found\r\n"); } //CTRL_REG1 //DR2|DR1|DR0|OS1|OS0|FastRead|Trigger|ActiveMode| // 0 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | mag3110_write(0x10, 0x79); i2c_delay(); i2c_delay(); //CTRL_REG2: //AutoMagRst|---|Raw|Mag_Rst|---|---|---|---| // 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | mag3110_write(0x11, 0x80); }
static int mag3110_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) { struct mag3110_data *data = iio_priv(indio_dev); __be16 buffer[3]; int i, ret; switch (mask) { case IIO_CHAN_INFO_RAW: if (iio_buffer_enabled(indio_dev)) return -EBUSY; switch (chan->type) { case IIO_MAGN: /* in 0.1 uT / LSB */ ret = mag3110_read(data, buffer); if (ret < 0) return ret; *val = sign_extend32( be16_to_cpu(buffer[chan->scan_index]), 15); return IIO_VAL_INT; case IIO_TEMP: /* in 1 C / LSB */ mutex_lock(&data->lock); ret = mag3110_request(data); if (ret < 0) { mutex_unlock(&data->lock); return ret; } ret = i2c_smbus_read_byte_data(data->client, MAG3110_DIE_TEMP); mutex_unlock(&data->lock); if (ret < 0) return ret; *val = sign_extend32(ret, 7); return IIO_VAL_INT; default: return -EINVAL; } case IIO_CHAN_INFO_SCALE: switch (chan->type) { case IIO_MAGN: *val = 0; *val2 = 1000; return IIO_VAL_INT_PLUS_MICRO; case IIO_TEMP: *val = 1000; return IIO_VAL_INT; default: return -EINVAL; } case IIO_CHAN_INFO_SAMP_FREQ: i = data->ctrl_reg1 >> MAG3110_CTRL_DR_SHIFT; *val = mag3110_samp_freq[i][0]; *val2 = mag3110_samp_freq[i][1]; return IIO_VAL_INT_PLUS_MICRO; } return -EINVAL; }
static int read_mag(const void *dev, phydat_t *res) { mag3110_read((const mag3110_t *)dev, (mag3110_data_t *)res); res->unit = UNIT_GS; res->scale = 2; return 3; }
int main(void) { mag3110_t dev; int8_t temp; int16_t x, y, z; uint8_t status; puts("MAG3110 magnetometer driver test application\n"); printf("Initializing MAG3110 magnetometer at I2C_%i... ", TEST_MAG3110_I2C); if (mag3110_init(&dev, TEST_MAG3110_I2C, TEST_MAG3110_ADDR, MAG3110_DROS_DEFAULT) == 0) { puts("[OK]\n"); } else { puts("[Failed]"); return -1; } if (mag3110_set_user_offset(&dev, TEST_MAG3110_USER_OFFSET_X, TEST_MAG3110_USER_OFFSET_Y, TEST_MAG3110_USER_OFFSET_Z )) { puts("Set user offset correction failed."); return -1; } if (mag3110_set_active(&dev)) { puts("Measurement start failed."); return -1; } while (1) { xtimer_usleep(SLEEP); mag3110_read(&dev, &x, &y, &z, &status); printf("Field strength: X: %d Y: %d Z: %d S: %2x\n", x, y, z, status); mag3110_read_dtemp(&dev, &temp); printf("Die Temperature T: %d\n", temp); } return 0; }
// Read a signed 14-bit value from (reg, reg+1) int16_t mag3110_read_reg16(uint8_t reg) { return (int16_t)((mag3110_read(reg) << 8) | mag3110_read(reg + 1)); }