Skip to content

Commit 64d29e3

Browse files
committed
Preliminary driver for AK8975
Will wait for the delivery of the physical chips to test.
1 parent c8ea875 commit 64d29e3

File tree

2 files changed

+133
-0
lines changed

2 files changed

+133
-0
lines changed

src/mgos_imu_ak8975.c

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*
2+
* Copyright 2018 Google Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include "mgos.h"
18+
#include "mgos_i2c.h"
19+
#include "mgos_imu_ak8975.h"
20+
21+
bool mgos_imu_ak8975_detect(struct mgos_imu_mag *dev) {
22+
int device_id;
23+
24+
if (!dev) {
25+
return false;
26+
}
27+
28+
device_id = mgos_i2c_read_reg_b(dev->i2c, dev->i2caddr, MGOS_AK8975_REG_WHO_AM_I);
29+
if (device_id == MGOS_AK8975_DEVID) {
30+
return true;
31+
}
32+
LOG(LL_ERROR, ("Failed to detect AK8975 at I2C 0x%02x (device_id=0x%02x)", dev->i2caddr, device_id));
33+
return false;
34+
}
35+
36+
bool mgos_imu_ak8975_create(struct mgos_imu_mag *dev) {
37+
if (!dev) {
38+
return false;
39+
}
40+
41+
// Reset
42+
mgos_i2c_write_reg_b(dev->i2c, dev->i2caddr, MGOS_AK8975_REG_CNTL, 0x00);
43+
mgos_usleep(10000);
44+
45+
// Fuse ROM access mode
46+
mgos_i2c_write_reg_b(dev->i2c, dev->i2caddr, MGOS_AK8975_REG_CNTL, 0x0F);
47+
mgos_usleep(10000);
48+
49+
uint8_t data[3];
50+
if (!mgos_i2c_read_reg_n(dev->i2c, dev->i2caddr, MGOS_AK8975_REG_ASAX, 3, data)) {
51+
LOG(LL_ERROR, ("Could not read magnetometer adjustment registers"));
52+
return false;
53+
}
54+
dev->bias[0] = (float)(data[0] - 128) / 256. + 1.;
55+
dev->bias[1] = (float)(data[1] - 128) / 256. + 1.;
56+
dev->bias[2] = (float)(data[2] - 128) / 256. + 1.;
57+
58+
LOG(LL_DEBUG, ("Magnetometer adjustment bias %.2f %.2f %.2f", dev->bias[0], dev->bias[1], dev->bias[2]));
59+
60+
// Reset
61+
mgos_i2c_write_reg_b(dev->i2c, dev->i2caddr, MGOS_AK8975_REG_CNTL, 0x00);
62+
mgos_usleep(10000);
63+
64+
dev->scale = 1229.0 / 4096.0;
65+
66+
return true;
67+
}
68+
69+
bool mgos_imu_ak8975_read(struct mgos_imu_mag *dev) {
70+
uint8_t data[6];
71+
int drdy;
72+
73+
if (!dev) {
74+
return false;
75+
}
76+
77+
// Set single shot measurement
78+
mgos_i2c_write_reg_b(dev->i2c, dev->i2caddr, MGOS_AK8975_REG_CNTL, 0x01);
79+
mgos_usleep(9500);
80+
81+
// Check Data Ready
82+
drdy = mgos_i2c_read_reg_b(dev->i2c, dev->i2caddr, MGOS_AK8975_REG_ST1);
83+
if (drdy != 0x01)
84+
return false;
85+
86+
if (!mgos_i2c_read_reg_n(dev->i2c, dev->i2caddr, MGOS_AK8975_REG_XOUT_L, 6, data)) {
87+
return false;
88+
}
89+
90+
dev->mx = (data[1] << 8) | (data[0]);
91+
dev->my = (data[3] << 8) | (data[2]);
92+
dev->mz = (data[5] << 8) | (data[4]);
93+
LOG(LL_DEBUG, ("mx=%d my=%d mz=%d", dev->mx, dev->my, dev->mz));
94+
return true;
95+
}

src/mgos_imu_ak8975.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright 2018 Google Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#pragma once
18+
19+
#include "mgos.h"
20+
#include "mgos_imu_internal.h"
21+
22+
#define MGOS_AK8975_DEFAULT_I2CADDR (0x0C)
23+
#define MGOS_AK8975_DEVID (0x48)
24+
25+
// AK8975 Magnetometer Registers
26+
#define MGOS_AK8975_REG_WHO_AM_I (0x00)
27+
#define MGOS_AK8975_REG_INFO (0x01)
28+
#define MGOS_AK8975_REG_ST1 (0x02)
29+
#define MGOS_AK8975_REG_XOUT_L (0x03)
30+
#define MGOS_AK8975_REG_ST2 (0x09)
31+
#define MGOS_AK8975_REG_CNTL (0x0A)
32+
#define MGOS_AK8975_REG_ASAX (0x10)
33+
#define MGOS_AK8975_REG_ASAY (0x11)
34+
#define MGOS_AK8975_REG_ASAZ (0x12)
35+
36+
bool mgos_imu_ak8975_detect(struct mgos_imu_mag *dev);
37+
bool mgos_imu_ak8975_create(struct mgos_imu_mag *dev);
38+
bool mgos_imu_ak8975_read(struct mgos_imu_mag *dev);

0 commit comments

Comments
 (0)