4 #define TEST_REG_ERROR -1
6 #define LSM303D_WHO_ID 0x49
7 #define L3GD20H_WHO_ID 0xD7
8 #define LSM6DS33_WHO_ID 0x69
9 #define LIS3MDL_WHO_ID 0x3D
13 if (testReg(LSM303DLHC_ACC_ADDR, LSM303DLHC_REG_CTRL_REG1_A) != TEST_REG_ERROR)
18 type = ZumoIMUType::LSM303DLHC;
21 else if (testReg(LSM303D_ADDR, LSM303D_REG_WHO_AM_I) == LSM303D_WHO_ID &&
22 testReg(L3GD20H_ADDR, L3GD20H_REG_WHO_AM_I) == L3GD20H_WHO_ID)
24 type = ZumoIMUType::LSM303D_L3GD20H;
27 else if (testReg(LSM6DS33_ADDR, LSM6DS33_REG_WHO_AM_I) == LSM6DS33_WHO_ID &&
28 testReg( LIS3MDL_ADDR, LIS3MDL_REG_WHO_AM_I) == LIS3MDL_WHO_ID)
43 case ZumoIMUType::LSM303DLHC:
49 writeReg(LSM303DLHC_ACC_ADDR, LSM303DLHC_REG_CTRL_REG1_A, 0x47);
50 if (lastError) {
return; }
54 writeReg(LSM303DLHC_ACC_ADDR, LSM303DLHC_REG_CTRL_REG4_A, 0x08);
55 if (lastError) {
return; }
61 writeReg(LSM303DLHC_MAG_ADDR, LSM303DLHC_REG_CRA_REG_M, 0x0C);
62 if (lastError) {
return; }
66 writeReg(LSM303DLHC_MAG_ADDR, LSM303DLHC_REG_CRB_REG_M, 0x80);
67 if (lastError) {
return; }
71 writeReg(LSM303DLHC_MAG_ADDR, LSM303DLHC_REG_MR_REG_M, 0x00);
74 case ZumoIMUType::LSM303D_L3GD20H:
80 writeReg(LSM303D_ADDR, LSM303D_REG_CTRL1, 0x57);
81 if (lastError) {
return; }
85 writeReg(LSM303D_ADDR, LSM303D_REG_CTRL2, 0x00);
86 if (lastError) {
return; }
92 writeReg(LSM303D_ADDR, LSM303D_REG_CTRL5, 0x64);
93 if (lastError) {
return; }
97 writeReg(LSM303D_ADDR, LSM303D_REG_CTRL6, 0x20);
98 if (lastError) {
return; }
102 writeReg(LSM303D_ADDR, LSM303D_REG_CTRL7, 0x00);
103 if (lastError) {
return; }
109 writeReg(L3GD20H_ADDR, L3GD20H_REG_CTRL1, 0x7F);
110 if (lastError) {
return; }
114 writeReg(L3GD20H_ADDR, L3GD20H_REG_CTRL4, 0x00);
123 writeReg(LSM6DS33_ADDR, LSM6DS33_REG_CTRL1_XL, 0x30);
124 if (lastError) {
return; }
130 writeReg(LSM6DS33_ADDR, LSM6DS33_REG_CTRL2_G, 0x50);
131 if (lastError) {
return; }
137 writeReg(LSM6DS33_ADDR, LSM6DS33_REG_CTRL3_C, 0x04);
138 if (lastError) {
return; }
144 writeReg(LIS3MDL_ADDR, LIS3MDL_REG_CTRL_REG1, 0x70);
145 if (lastError) {
return; }
149 writeReg(LIS3MDL_ADDR, LIS3MDL_REG_CTRL_REG2, 0x00);
150 if (lastError) {
return; }
154 writeReg(LIS3MDL_ADDR, LIS3MDL_REG_CTRL_REG3, 0x00);
155 if (lastError) {
return; }
159 writeReg(LIS3MDL_ADDR, LIS3MDL_REG_CTRL_REG4, 0x0C);
168 case ZumoIMUType::LSM303DLHC:
174 writeReg(LSM303DLHC_MAG_ADDR, LSM303DLHC_REG_CRA_REG_M, 0x18);
177 case ZumoIMUType::LSM303D_L3GD20H:
183 writeReg(LSM303D_ADDR, LSM303D_REG_CTRL5, 0x70);
192 writeReg(LIS3MDL_ADDR, LIS3MDL_REG_CTRL_REG1, 0x7C);
199 Wire.beginTransmission(addr);
202 lastError = Wire.endTransmission();
207 Wire.beginTransmission(addr);
209 lastError = Wire.endTransmission();
210 if (lastError) {
return 0; }
212 uint8_t byteCount = Wire.requestFrom(addr, (uint8_t)1);
226 case ZumoIMUType::LSM303DLHC:
228 readAxes16Bit(LSM303DLHC_ACC_ADDR, LSM303DLHC_REG_OUT_X_L_A | (1 << 7),
a);
231 case ZumoIMUType::LSM303D_L3GD20H:
233 readAxes16Bit(LSM303D_ADDR, LSM303D_REG_OUT_X_L_A | (1 << 7),
a);
238 readAxes16Bit(LSM6DS33_ADDR, LSM6DS33_REG_OUTX_L_XL,
a);
248 case ZumoIMUType::LSM303D_L3GD20H:
250 readAxes16Bit(L3GD20H_ADDR, L3GD20H_REG_OUT_X_L | (1 << 7),
g);
255 readAxes16Bit(LSM6DS33_ADDR, LSM6DS33_REG_OUTX_L_G,
g);
265 case ZumoIMUType::LSM303DLHC:
268 readAxes16Bit(LSM303DLHC_MAG_ADDR, LSM303DLHC_REG_OUT_X_H_M,
m);
272 m = { swapBytes(
m.x), swapBytes(
m.z), swapBytes(
m.y) };
275 case ZumoIMUType::LSM303D_L3GD20H:
277 readAxes16Bit(LSM303D_ADDR, LSM303D_REG_OUT_X_L_M | (1 << 7),
m);
282 readAxes16Bit(LIS3MDL_ADDR, LIS3MDL_REG_OUT_X_L | (1 << 7),
m);
292 if (lastError) {
return; }
294 if (lastError) {
return; }
302 case ZumoIMUType::LSM303DLHC:
303 return readReg(LSM303DLHC_ACC_ADDR, LSM303DLHC_REG_STATUS_REG_A) & 0x08;
305 case ZumoIMUType::LSM303D_L3GD20H:
306 return readReg(LSM303D_ADDR, LSM303D_REG_STATUS_A) & 0x08;
309 return readReg(LSM6DS33_ADDR, LSM6DS33_REG_STATUS_REG) & 0x01;
318 case ZumoIMUType::LSM303D_L3GD20H:
319 return readReg(L3GD20H_ADDR, L3GD20H_REG_STATUS) & 0x08;
322 return readReg(LSM6DS33_ADDR, LSM6DS33_REG_STATUS_REG) & 0x02;
331 case ZumoIMUType::LSM303DLHC:
332 return readReg(LSM303DLHC_MAG_ADDR, LSM303DLHC_REG_SR_REG_M) & 0x01;
334 case ZumoIMUType::LSM303D_L3GD20H:
335 return readReg(LSM303D_ADDR, LSM303D_REG_STATUS_M) & 0x08;
338 return readReg(LIS3MDL_ADDR, LIS3MDL_REG_STATUS_REG) & 0x08;
343 int16_t ZumoIMU::testReg(uint8_t addr, uint8_t reg)
345 Wire.beginTransmission(addr);
347 if (Wire.endTransmission() != 0)
349 return TEST_REG_ERROR;
352 uint8_t byteCount = Wire.requestFrom(addr, (uint8_t)1);
355 return TEST_REG_ERROR;
360 void ZumoIMU::readAxes16Bit(uint8_t addr, uint8_t firstReg, vector<int16_t> & v)
362 Wire.beginTransmission(addr);
363 Wire.write(firstReg);
364 lastError = Wire.endTransmission();
365 if (lastError) {
return; }
367 uint8_t byteCount = (Wire.requestFrom(addr, (uint8_t)6));
373 uint8_t xl = Wire.read();
374 uint8_t xh = Wire.read();
375 uint8_t yl = Wire.read();
376 uint8_t yh = Wire.read();
377 uint8_t zl = Wire.read();
378 uint8_t zh = Wire.read();
381 v.x = (int16_t)(xh << 8 | xl);
382 v.y = (int16_t)(yh << 8 | yl);
383 v.z = (int16_t)(zh << 8 | zl);
386 uint16_t ZumoIMU::swapBytes(uint16_t value)
388 return ((value & 0xFF) << 8) | ((value >> 8) & 0xFF);