AK8963

Dependents:   FreeIMU

Committer:
tyftyftyf
Date:
Wed Mar 28 20:25:57 2018 +0000
Revision:
0:ec59a31e784b
Child:
1:f8ba8df44aab
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 0:ec59a31e784b 37
tyftyftyf 0:ec59a31e784b 38 /** Default constructor, uses default I2C address.
tyftyftyf 0:ec59a31e784b 39 * @see AK8963_DEFAULT_ADDRESS
tyftyftyf 0:ec59a31e784b 40 */
tyftyftyf 0:ec59a31e784b 41 AK8963::AK8963() {
tyftyftyf 0:ec59a31e784b 42 devAddr = AK8963_DEFAULT_ADDRESS;
tyftyftyf 0:ec59a31e784b 43 }
tyftyftyf 0:ec59a31e784b 44
tyftyftyf 0:ec59a31e784b 45 /** Specific address constructor.
tyftyftyf 0:ec59a31e784b 46 * @param address I2C address
tyftyftyf 0:ec59a31e784b 47 * @see AK8963_DEFAULT_ADDRESS
tyftyftyf 0:ec59a31e784b 48 * @see AK8963_ADDRESS_00
tyftyftyf 0:ec59a31e784b 49 */
tyftyftyf 0:ec59a31e784b 50 AK8963::AK8963(bool useSPI, uint8_t address) {
tyftyftyf 0:ec59a31e784b 51 bSPI = useSPI;
tyftyftyf 0:ec59a31e784b 52 devAddr = address;
tyftyftyf 0:ec59a31e784b 53 }
tyftyftyf 0:ec59a31e784b 54
tyftyftyf 0:ec59a31e784b 55 /** Power on and prepare for general usage.
tyftyftyf 0:ec59a31e784b 56 * No specific pre-configuration is necessary for this device.
tyftyftyf 0:ec59a31e784b 57 */
tyftyftyf 0:ec59a31e784b 58 void AK8963::initialize() {
tyftyftyf 0:ec59a31e784b 59
tyftyftyf 0:ec59a31e784b 60 }
tyftyftyf 0:ec59a31e784b 61
tyftyftyf 0:ec59a31e784b 62 /** Verify the I2C connection.
tyftyftyf 0:ec59a31e784b 63 * Make sure the device is connected and responds as expected.
tyftyftyf 0:ec59a31e784b 64 * @return True if connection is valid, false otherwise
tyftyftyf 0:ec59a31e784b 65 */
tyftyftyf 0:ec59a31e784b 66 bool AK8963::testConnection() {
tyftyftyf 0:ec59a31e784b 67 if (i2Cdev.readByte(devAddr, AK8963_RA_WIA, buffer) == 1) {
tyftyftyf 0:ec59a31e784b 68 return (buffer[0] == 0x48);
tyftyftyf 0:ec59a31e784b 69 }
tyftyftyf 0:ec59a31e784b 70 return false;
tyftyftyf 0:ec59a31e784b 71 }
tyftyftyf 0:ec59a31e784b 72
tyftyftyf 0:ec59a31e784b 73 // WIA register
tyftyftyf 0:ec59a31e784b 74
tyftyftyf 0:ec59a31e784b 75 uint8_t AK8963::getDeviceID() {
tyftyftyf 0:ec59a31e784b 76 i2Cdev.readByte(devAddr, AK8963_RA_WIA, buffer);
tyftyftyf 0:ec59a31e784b 77 return buffer[0];
tyftyftyf 0:ec59a31e784b 78 }
tyftyftyf 0:ec59a31e784b 79
tyftyftyf 0:ec59a31e784b 80 // INFO register
tyftyftyf 0:ec59a31e784b 81
tyftyftyf 0:ec59a31e784b 82 uint8_t AK8963::getInfo() {
tyftyftyf 0:ec59a31e784b 83 i2Cdev.readByte(devAddr, AK8963_RA_INFO, buffer);
tyftyftyf 0:ec59a31e784b 84 return buffer[0];
tyftyftyf 0:ec59a31e784b 85 }
tyftyftyf 0:ec59a31e784b 86
tyftyftyf 0:ec59a31e784b 87 // ST1 register
tyftyftyf 0:ec59a31e784b 88
tyftyftyf 0:ec59a31e784b 89 bool AK8963::getDataReady() {
tyftyftyf 0:ec59a31e784b 90 i2Cdev.readBit(devAddr, AK8963_RA_ST1, AK8963_ST1_DRDY_BIT, buffer);
tyftyftyf 0:ec59a31e784b 91 return buffer[0];
tyftyftyf 0:ec59a31e784b 92 }
tyftyftyf 0:ec59a31e784b 93
tyftyftyf 0:ec59a31e784b 94 bool AK8963::getDataOverRun() {
tyftyftyf 0:ec59a31e784b 95 i2Cdev.readBit(devAddr, AK8963_RA_ST1, AK8963_ST1_DOR_BIT, buffer);
tyftyftyf 0:ec59a31e784b 96 return buffer[0];
tyftyftyf 0:ec59a31e784b 97 }
tyftyftyf 0:ec59a31e784b 98
tyftyftyf 0:ec59a31e784b 99 // H* registers
tyftyftyf 0:ec59a31e784b 100 void AK8963::getHeading(int16_t *x, int16_t *y, int16_t *z) {
tyftyftyf 0:ec59a31e784b 101 //I2Cdev::writeByte(devAddr, AK8963_RA_CNTL1, AK8963_MODE_SINGLE);
tyftyftyf 0:ec59a31e784b 102 //delay(10);
tyftyftyf 0:ec59a31e784b 103
tyftyftyf 0:ec59a31e784b 104 if (getDataReady() & 0x01) {
tyftyftyf 0:ec59a31e784b 105 i2Cdev.readBytes(devAddr, AK8963_RA_HXL, 7, buffer);
tyftyftyf 0:ec59a31e784b 106 uint8_t c = buffer[6]; // End data read by reading ST2 register
tyftyftyf 0:ec59a31e784b 107 if(!(c & 0x08)) { // Check if magnetic sensor overflow set, if not then report data
tyftyftyf 0:ec59a31e784b 108 *x = (((int16_t)buffer[1]) << 8) | buffer[0];
tyftyftyf 0:ec59a31e784b 109 *y = (((int16_t)buffer[3]) << 8) | buffer[2];
tyftyftyf 0:ec59a31e784b 110 *z = (((int16_t)buffer[5]) << 8) | buffer[4];
tyftyftyf 0:ec59a31e784b 111 }
tyftyftyf 0:ec59a31e784b 112 }
tyftyftyf 0:ec59a31e784b 113 }
tyftyftyf 0:ec59a31e784b 114
tyftyftyf 0:ec59a31e784b 115 void AK8963::getSelfTest(int16_t *x, int16_t *y, int16_t *z) {
tyftyftyf 0:ec59a31e784b 116 i2Cdev.writeByte(devAddr, AK8963_RA_CNTL1, AK8963_MODE_POWERDOWN); // Power down magnetometer
tyftyftyf 0:ec59a31e784b 117 Thread::wait(10);
tyftyftyf 0:ec59a31e784b 118 setSelfTest(true); // Set Self Test Bit
tyftyftyf 0:ec59a31e784b 119 Thread::wait(10);
tyftyftyf 0:ec59a31e784b 120 // Read mag registers
tyftyftyf 0:ec59a31e784b 121 if(getDataReady() & 0x01) {
tyftyftyf 0:ec59a31e784b 122 i2Cdev.readBytes(devAddr, AK8963_RA_HXL, 7, buffer);
tyftyftyf 0:ec59a31e784b 123 uint8_t c = buffer[6]; // End data read by reading ST2 register
tyftyftyf 0:ec59a31e784b 124 if(!(c & 0x08)) { // Check if magnetic sensor overflow set, if not then report data
tyftyftyf 0:ec59a31e784b 125 *x = (((int16_t)buffer[1]) << 8) | buffer[0];
tyftyftyf 0:ec59a31e784b 126 *y = (((int16_t)buffer[3]) << 8) | buffer[2];
tyftyftyf 0:ec59a31e784b 127 *z = (((int16_t)buffer[5]) << 8) | buffer[4];
tyftyftyf 0:ec59a31e784b 128 }
tyftyftyf 0:ec59a31e784b 129 }
tyftyftyf 0:ec59a31e784b 130 setSelfTest(false); // Set Self Test Bit
tyftyftyf 0:ec59a31e784b 131 Thread::wait(10);
tyftyftyf 0:ec59a31e784b 132 i2Cdev.writeByte(devAddr, AK8963_RA_CNTL1, AK8963_MODE_POWERDOWN); // Power down magnetometer
tyftyftyf 0:ec59a31e784b 133 Thread::wait(10);
tyftyftyf 0:ec59a31e784b 134
tyftyftyf 0:ec59a31e784b 135 }
tyftyftyf 0:ec59a31e784b 136
tyftyftyf 0:ec59a31e784b 137 // ST2 register
tyftyftyf 0:ec59a31e784b 138 bool AK8963::getOverflowStatus() {
tyftyftyf 0:ec59a31e784b 139 i2Cdev.readBit(devAddr, AK8963_RA_ST2, AK8963_ST2_HOFL_BIT, buffer);
tyftyftyf 0:ec59a31e784b 140 return buffer[0];
tyftyftyf 0:ec59a31e784b 141 }
tyftyftyf 0:ec59a31e784b 142
tyftyftyf 0:ec59a31e784b 143 bool AK8963::getOutBitST() {
tyftyftyf 0:ec59a31e784b 144 i2Cdev.readBit(devAddr, AK8963_RA_ST2, AK8963_ST2_BITM, buffer);
tyftyftyf 0:ec59a31e784b 145 return buffer[0];
tyftyftyf 0:ec59a31e784b 146 }
tyftyftyf 0:ec59a31e784b 147
tyftyftyf 0:ec59a31e784b 148 // CNTL1 register
tyftyftyf 0:ec59a31e784b 149 uint8_t AK8963::getMode() {
tyftyftyf 0:ec59a31e784b 150 //I2Cdev::readBits(devAddr, AK8963_RA_CNTL1, AK8963_CNTL1_MODE_BIT, AK8963_CNTL1_MODE_LENGTH, buffer);
tyftyftyf 0:ec59a31e784b 151 i2Cdev.readByte(devAddr, AK8963_RA_CNTL1, buffer);
tyftyftyf 0:ec59a31e784b 152 return buffer[0];
tyftyftyf 0:ec59a31e784b 153 }
tyftyftyf 0:ec59a31e784b 154
tyftyftyf 0:ec59a31e784b 155 //Configure magenetometer mode and resolution
tyftyftyf 0:ec59a31e784b 156 void AK8963::setModeRes(uint8_t mode, uint8_t Mscale) {
tyftyftyf 0:ec59a31e784b 157 //I2Cdev::writeBits(devAddr, AK8963_RA_CNTL1, AK8963_CNTL1_MODE_BIT, AK8963_CNTL1_MODE_LENGTH, mode);
tyftyftyf 0:ec59a31e784b 158 i2Cdev.writeByte(devAddr, AK8963_RA_CNTL1, Mscale << 4 | mode);
tyftyftyf 0:ec59a31e784b 159 Thread::wait(10);
tyftyftyf 0:ec59a31e784b 160 }
tyftyftyf 0:ec59a31e784b 161
tyftyftyf 0:ec59a31e784b 162 // CNTL2 register
tyftyftyf 0:ec59a31e784b 163 void AK8963::reset() {
tyftyftyf 0:ec59a31e784b 164 i2Cdev.writeBytes(devAddr, AK8963_RA_CNTL2, AK8963_CNTL2_RESET, buffer);
tyftyftyf 0:ec59a31e784b 165 }
tyftyftyf 0:ec59a31e784b 166
tyftyftyf 0:ec59a31e784b 167 // ASTC register
tyftyftyf 0:ec59a31e784b 168 void AK8963::setSelfTest(bool enabled) {
tyftyftyf 0:ec59a31e784b 169 i2Cdev.writeBit(devAddr, AK8963_RA_ASTC, AK8963_ASTC_SELF_BIT, enabled);
tyftyftyf 0:ec59a31e784b 170 }
tyftyftyf 0:ec59a31e784b 171
tyftyftyf 0:ec59a31e784b 172 // I2CDIS
tyftyftyf 0:ec59a31e784b 173 void AK8963::disableI2C() {
tyftyftyf 0:ec59a31e784b 174 i2Cdev.writeBit(devAddr, AK8963_RA_I2CDIS, AK8963_I2CDIS_BIT, true);
tyftyftyf 0:ec59a31e784b 175 }
tyftyftyf 0:ec59a31e784b 176
tyftyftyf 0:ec59a31e784b 177 // ASA* registers
tyftyftyf 0:ec59a31e784b 178 void AK8963::getAdjustment(uint8_t *x, uint8_t *y, uint8_t *z) {
tyftyftyf 0:ec59a31e784b 179 i2Cdev.writeByte(devAddr, AK8963_RA_CNTL1, AK8963_MODE_POWERDOWN); // Power down magnetometer
tyftyftyf 0:ec59a31e784b 180 Thread::wait(10);
tyftyftyf 0:ec59a31e784b 181 i2Cdev.writeByte(devAddr, AK8963_RA_CNTL1, AK8963_MODE_FUSEROM); // Enter Fuse ROM access mode
tyftyftyf 0:ec59a31e784b 182 Thread::wait(10);
tyftyftyf 0:ec59a31e784b 183
tyftyftyf 0:ec59a31e784b 184 i2Cdev.readBytes(devAddr, AK8963_RA_ASAX, 3, buffer); // Read the x-, y-, and z-axis calibration values
tyftyftyf 0:ec59a31e784b 185 *x = buffer[0];
tyftyftyf 0:ec59a31e784b 186 *y = buffer[1];
tyftyftyf 0:ec59a31e784b 187 *z = buffer[2];
tyftyftyf 0:ec59a31e784b 188
tyftyftyf 0:ec59a31e784b 189 i2Cdev.writeByte(devAddr, AK8963_RA_CNTL1, AK8963_MODE_POWERDOWN); // Power down magnetometer
tyftyftyf 0:ec59a31e784b 190 Thread::wait(10);
tyftyftyf 0:ec59a31e784b 191 }