AK8963

Dependents:   FreeIMU

Committer:
tyftyftyf
Date:
Wed Mar 28 21:06:51 2018 +0000
Revision:
1:f8ba8df44aab
Parent:
0:ec59a31e784b
wip

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tyftyftyf 0:ec59a31e784b 1 // I2Cdev library collection - AK8963 I2C device class header file
tyftyftyf 0:ec59a31e784b 2 // Based on AKM AK8963/B datasheet, 12/2009
tyftyftyf 0:ec59a31e784b 3 // 8/27/2011 by Jeff Rowberg <jeff@rowberg.net> for 8975
tyftyftyf 0:ec59a31e784b 4 // 6/14/2014 modified for AKM AK8963
tyftyftyf 0:ec59a31e784b 5 // Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib for 8975
tyftyftyf 0:ec59a31e784b 6 //
tyftyftyf 0:ec59a31e784b 7 // Changelog:
tyftyftyf 0:ec59a31e784b 8 // 2011-08-27 - initial release
tyftyftyf 0:ec59a31e784b 9 // 2014-06-14 - modified for AK8963 based on Kris Wieners MPU-9250 Sketch
tyftyftyf 0:ec59a31e784b 10
tyftyftyf 0:ec59a31e784b 11 /* ============================================
tyftyftyf 0:ec59a31e784b 12 I2Cdev device library code is placed under the MIT license
tyftyftyf 0:ec59a31e784b 13 Copyright (c) 2011 Jeff Rowberg
tyftyftyf 0:ec59a31e784b 14
tyftyftyf 0:ec59a31e784b 15 Permission is hereby granted, free of charge, to any person obtaining a copy
tyftyftyf 0:ec59a31e784b 16 of this software and associated documentation files (the "Software"), to deal
tyftyftyf 0:ec59a31e784b 17 in the Software without restriction, including without limitation the rights
tyftyftyf 0:ec59a31e784b 18 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
tyftyftyf 0:ec59a31e784b 19 copies of the Software, and to permit persons to whom the Software is
tyftyftyf 0:ec59a31e784b 20 furnished to do so, subject to the following conditions:
tyftyftyf 0:ec59a31e784b 21
tyftyftyf 0:ec59a31e784b 22 The above copyright notice and this permission notice shall be included in
tyftyftyf 0:ec59a31e784b 23 all copies or substantial portions of the Software.
tyftyftyf 0:ec59a31e784b 24
tyftyftyf 0:ec59a31e784b 25 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
tyftyftyf 0:ec59a31e784b 26 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
tyftyftyf 0:ec59a31e784b 27 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
tyftyftyf 0:ec59a31e784b 28 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
tyftyftyf 0:ec59a31e784b 29 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
tyftyftyf 0:ec59a31e784b 30 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
tyftyftyf 0:ec59a31e784b 31 THE SOFTWARE.
tyftyftyf 0:ec59a31e784b 32 ===============================================
tyftyftyf 0:ec59a31e784b 33 */
tyftyftyf 0:ec59a31e784b 34
tyftyftyf 0:ec59a31e784b 35 #include "AK8963.h"
tyftyftyf 0:ec59a31e784b 36
tyftyftyf 1:f8ba8df44aab 37 using namespace AK8963I2C;
tyftyftyf 1:f8ba8df44aab 38
tyftyftyf 0:ec59a31e784b 39
tyftyftyf 0:ec59a31e784b 40 /** Default constructor, uses default I2C address.
tyftyftyf 0:ec59a31e784b 41 * @see AK8963_DEFAULT_ADDRESS
tyftyftyf 0:ec59a31e784b 42 */
tyftyftyf 0:ec59a31e784b 43 AK8963::AK8963() {
tyftyftyf 0:ec59a31e784b 44 devAddr = AK8963_DEFAULT_ADDRESS;
tyftyftyf 0:ec59a31e784b 45 }
tyftyftyf 0:ec59a31e784b 46
tyftyftyf 0:ec59a31e784b 47 /** Specific address constructor.
tyftyftyf 0:ec59a31e784b 48 * @param address I2C address
tyftyftyf 0:ec59a31e784b 49 * @see AK8963_DEFAULT_ADDRESS
tyftyftyf 0:ec59a31e784b 50 * @see AK8963_ADDRESS_00
tyftyftyf 0:ec59a31e784b 51 */
tyftyftyf 0:ec59a31e784b 52 AK8963::AK8963(bool useSPI, uint8_t address) {
tyftyftyf 0:ec59a31e784b 53 bSPI = useSPI;
tyftyftyf 0:ec59a31e784b 54 devAddr = address;
tyftyftyf 0:ec59a31e784b 55 }
tyftyftyf 0:ec59a31e784b 56
tyftyftyf 0:ec59a31e784b 57 /** Power on and prepare for general usage.
tyftyftyf 0:ec59a31e784b 58 * No specific pre-configuration is necessary for this device.
tyftyftyf 0:ec59a31e784b 59 */
tyftyftyf 0:ec59a31e784b 60 void AK8963::initialize() {
tyftyftyf 0:ec59a31e784b 61
tyftyftyf 0:ec59a31e784b 62 }
tyftyftyf 0:ec59a31e784b 63
tyftyftyf 0:ec59a31e784b 64 /** Verify the I2C connection.
tyftyftyf 0:ec59a31e784b 65 * Make sure the device is connected and responds as expected.
tyftyftyf 0:ec59a31e784b 66 * @return True if connection is valid, false otherwise
tyftyftyf 0:ec59a31e784b 67 */
tyftyftyf 0:ec59a31e784b 68 bool AK8963::testConnection() {
tyftyftyf 0:ec59a31e784b 69 if (i2Cdev.readByte(devAddr, AK8963_RA_WIA, buffer) == 1) {
tyftyftyf 0:ec59a31e784b 70 return (buffer[0] == 0x48);
tyftyftyf 0:ec59a31e784b 71 }
tyftyftyf 0:ec59a31e784b 72 return false;
tyftyftyf 0:ec59a31e784b 73 }
tyftyftyf 0:ec59a31e784b 74
tyftyftyf 0:ec59a31e784b 75 // WIA register
tyftyftyf 0:ec59a31e784b 76
tyftyftyf 0:ec59a31e784b 77 uint8_t AK8963::getDeviceID() {
tyftyftyf 0:ec59a31e784b 78 i2Cdev.readByte(devAddr, AK8963_RA_WIA, buffer);
tyftyftyf 0:ec59a31e784b 79 return buffer[0];
tyftyftyf 0:ec59a31e784b 80 }
tyftyftyf 0:ec59a31e784b 81
tyftyftyf 0:ec59a31e784b 82 // INFO register
tyftyftyf 0:ec59a31e784b 83
tyftyftyf 0:ec59a31e784b 84 uint8_t AK8963::getInfo() {
tyftyftyf 0:ec59a31e784b 85 i2Cdev.readByte(devAddr, AK8963_RA_INFO, buffer);
tyftyftyf 0:ec59a31e784b 86 return buffer[0];
tyftyftyf 0:ec59a31e784b 87 }
tyftyftyf 0:ec59a31e784b 88
tyftyftyf 0:ec59a31e784b 89 // ST1 register
tyftyftyf 0:ec59a31e784b 90
tyftyftyf 0:ec59a31e784b 91 bool AK8963::getDataReady() {
tyftyftyf 0:ec59a31e784b 92 i2Cdev.readBit(devAddr, AK8963_RA_ST1, AK8963_ST1_DRDY_BIT, buffer);
tyftyftyf 0:ec59a31e784b 93 return buffer[0];
tyftyftyf 0:ec59a31e784b 94 }
tyftyftyf 0:ec59a31e784b 95
tyftyftyf 0:ec59a31e784b 96 bool AK8963::getDataOverRun() {
tyftyftyf 0:ec59a31e784b 97 i2Cdev.readBit(devAddr, AK8963_RA_ST1, AK8963_ST1_DOR_BIT, buffer);
tyftyftyf 0:ec59a31e784b 98 return buffer[0];
tyftyftyf 0:ec59a31e784b 99 }
tyftyftyf 0:ec59a31e784b 100
tyftyftyf 0:ec59a31e784b 101 // H* registers
tyftyftyf 0:ec59a31e784b 102 void AK8963::getHeading(int16_t *x, int16_t *y, int16_t *z) {
tyftyftyf 0:ec59a31e784b 103 //I2Cdev::writeByte(devAddr, AK8963_RA_CNTL1, AK8963_MODE_SINGLE);
tyftyftyf 0:ec59a31e784b 104 //delay(10);
tyftyftyf 0:ec59a31e784b 105
tyftyftyf 0:ec59a31e784b 106 if (getDataReady() & 0x01) {
tyftyftyf 0:ec59a31e784b 107 i2Cdev.readBytes(devAddr, AK8963_RA_HXL, 7, buffer);
tyftyftyf 0:ec59a31e784b 108 uint8_t c = buffer[6]; // End data read by reading ST2 register
tyftyftyf 0:ec59a31e784b 109 if(!(c & 0x08)) { // Check if magnetic sensor overflow set, if not then report data
tyftyftyf 0:ec59a31e784b 110 *x = (((int16_t)buffer[1]) << 8) | buffer[0];
tyftyftyf 0:ec59a31e784b 111 *y = (((int16_t)buffer[3]) << 8) | buffer[2];
tyftyftyf 0:ec59a31e784b 112 *z = (((int16_t)buffer[5]) << 8) | buffer[4];
tyftyftyf 0:ec59a31e784b 113 }
tyftyftyf 0:ec59a31e784b 114 }
tyftyftyf 0:ec59a31e784b 115 }
tyftyftyf 0:ec59a31e784b 116
tyftyftyf 0:ec59a31e784b 117 void AK8963::getSelfTest(int16_t *x, int16_t *y, int16_t *z) {
tyftyftyf 0:ec59a31e784b 118 i2Cdev.writeByte(devAddr, AK8963_RA_CNTL1, AK8963_MODE_POWERDOWN); // Power down magnetometer
tyftyftyf 0:ec59a31e784b 119 Thread::wait(10);
tyftyftyf 0:ec59a31e784b 120 setSelfTest(true); // Set Self Test Bit
tyftyftyf 0:ec59a31e784b 121 Thread::wait(10);
tyftyftyf 0:ec59a31e784b 122 // Read mag registers
tyftyftyf 0:ec59a31e784b 123 if(getDataReady() & 0x01) {
tyftyftyf 0:ec59a31e784b 124 i2Cdev.readBytes(devAddr, AK8963_RA_HXL, 7, buffer);
tyftyftyf 0:ec59a31e784b 125 uint8_t c = buffer[6]; // End data read by reading ST2 register
tyftyftyf 0:ec59a31e784b 126 if(!(c & 0x08)) { // Check if magnetic sensor overflow set, if not then report data
tyftyftyf 0:ec59a31e784b 127 *x = (((int16_t)buffer[1]) << 8) | buffer[0];
tyftyftyf 0:ec59a31e784b 128 *y = (((int16_t)buffer[3]) << 8) | buffer[2];
tyftyftyf 0:ec59a31e784b 129 *z = (((int16_t)buffer[5]) << 8) | buffer[4];
tyftyftyf 0:ec59a31e784b 130 }
tyftyftyf 0:ec59a31e784b 131 }
tyftyftyf 0:ec59a31e784b 132 setSelfTest(false); // Set Self Test Bit
tyftyftyf 0:ec59a31e784b 133 Thread::wait(10);
tyftyftyf 0:ec59a31e784b 134 i2Cdev.writeByte(devAddr, AK8963_RA_CNTL1, AK8963_MODE_POWERDOWN); // Power down magnetometer
tyftyftyf 0:ec59a31e784b 135 Thread::wait(10);
tyftyftyf 0:ec59a31e784b 136
tyftyftyf 0:ec59a31e784b 137 }
tyftyftyf 0:ec59a31e784b 138
tyftyftyf 0:ec59a31e784b 139 // ST2 register
tyftyftyf 0:ec59a31e784b 140 bool AK8963::getOverflowStatus() {
tyftyftyf 0:ec59a31e784b 141 i2Cdev.readBit(devAddr, AK8963_RA_ST2, AK8963_ST2_HOFL_BIT, buffer);
tyftyftyf 0:ec59a31e784b 142 return buffer[0];
tyftyftyf 0:ec59a31e784b 143 }
tyftyftyf 0:ec59a31e784b 144
tyftyftyf 0:ec59a31e784b 145 bool AK8963::getOutBitST() {
tyftyftyf 0:ec59a31e784b 146 i2Cdev.readBit(devAddr, AK8963_RA_ST2, AK8963_ST2_BITM, buffer);
tyftyftyf 0:ec59a31e784b 147 return buffer[0];
tyftyftyf 0:ec59a31e784b 148 }
tyftyftyf 0:ec59a31e784b 149
tyftyftyf 0:ec59a31e784b 150 // CNTL1 register
tyftyftyf 0:ec59a31e784b 151 uint8_t AK8963::getMode() {
tyftyftyf 0:ec59a31e784b 152 //I2Cdev::readBits(devAddr, AK8963_RA_CNTL1, AK8963_CNTL1_MODE_BIT, AK8963_CNTL1_MODE_LENGTH, buffer);
tyftyftyf 0:ec59a31e784b 153 i2Cdev.readByte(devAddr, AK8963_RA_CNTL1, buffer);
tyftyftyf 0:ec59a31e784b 154 return buffer[0];
tyftyftyf 0:ec59a31e784b 155 }
tyftyftyf 0:ec59a31e784b 156
tyftyftyf 0:ec59a31e784b 157 //Configure magenetometer mode and resolution
tyftyftyf 0:ec59a31e784b 158 void AK8963::setModeRes(uint8_t mode, uint8_t Mscale) {
tyftyftyf 0:ec59a31e784b 159 //I2Cdev::writeBits(devAddr, AK8963_RA_CNTL1, AK8963_CNTL1_MODE_BIT, AK8963_CNTL1_MODE_LENGTH, mode);
tyftyftyf 0:ec59a31e784b 160 i2Cdev.writeByte(devAddr, AK8963_RA_CNTL1, Mscale << 4 | mode);
tyftyftyf 0:ec59a31e784b 161 Thread::wait(10);
tyftyftyf 0:ec59a31e784b 162 }
tyftyftyf 0:ec59a31e784b 163
tyftyftyf 0:ec59a31e784b 164 // CNTL2 register
tyftyftyf 0:ec59a31e784b 165 void AK8963::reset() {
tyftyftyf 0:ec59a31e784b 166 i2Cdev.writeBytes(devAddr, AK8963_RA_CNTL2, AK8963_CNTL2_RESET, buffer);
tyftyftyf 0:ec59a31e784b 167 }
tyftyftyf 0:ec59a31e784b 168
tyftyftyf 0:ec59a31e784b 169 // ASTC register
tyftyftyf 0:ec59a31e784b 170 void AK8963::setSelfTest(bool enabled) {
tyftyftyf 0:ec59a31e784b 171 i2Cdev.writeBit(devAddr, AK8963_RA_ASTC, AK8963_ASTC_SELF_BIT, enabled);
tyftyftyf 0:ec59a31e784b 172 }
tyftyftyf 0:ec59a31e784b 173
tyftyftyf 0:ec59a31e784b 174 // I2CDIS
tyftyftyf 0:ec59a31e784b 175 void AK8963::disableI2C() {
tyftyftyf 0:ec59a31e784b 176 i2Cdev.writeBit(devAddr, AK8963_RA_I2CDIS, AK8963_I2CDIS_BIT, true);
tyftyftyf 0:ec59a31e784b 177 }
tyftyftyf 0:ec59a31e784b 178
tyftyftyf 0:ec59a31e784b 179 // ASA* registers
tyftyftyf 0:ec59a31e784b 180 void AK8963::getAdjustment(uint8_t *x, uint8_t *y, uint8_t *z) {
tyftyftyf 0:ec59a31e784b 181 i2Cdev.writeByte(devAddr, AK8963_RA_CNTL1, AK8963_MODE_POWERDOWN); // Power down magnetometer
tyftyftyf 0:ec59a31e784b 182 Thread::wait(10);
tyftyftyf 0:ec59a31e784b 183 i2Cdev.writeByte(devAddr, AK8963_RA_CNTL1, AK8963_MODE_FUSEROM); // Enter Fuse ROM access mode
tyftyftyf 0:ec59a31e784b 184 Thread::wait(10);
tyftyftyf 0:ec59a31e784b 185
tyftyftyf 0:ec59a31e784b 186 i2Cdev.readBytes(devAddr, AK8963_RA_ASAX, 3, buffer); // Read the x-, y-, and z-axis calibration values
tyftyftyf 0:ec59a31e784b 187 *x = buffer[0];
tyftyftyf 0:ec59a31e784b 188 *y = buffer[1];
tyftyftyf 0:ec59a31e784b 189 *z = buffer[2];
tyftyftyf 0:ec59a31e784b 190
tyftyftyf 0:ec59a31e784b 191 i2Cdev.writeByte(devAddr, AK8963_RA_CNTL1, AK8963_MODE_POWERDOWN); // Power down magnetometer
tyftyftyf 0:ec59a31e784b 192 Thread::wait(10);
tyftyftyf 0:ec59a31e784b 193 }