AK8963

Dependents:   FreeIMU

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers AK8963.cpp Source File

AK8963.cpp

00001 // I2Cdev library collection - AK8963 I2C device class header file
00002 // Based on AKM AK8963/B datasheet, 12/2009
00003 // 8/27/2011 by Jeff Rowberg <jeff@rowberg.net> for 8975
00004 // 6/14/2014 modified for AKM AK8963
00005 // Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib for 8975
00006 //
00007 // Changelog:
00008 //     2011-08-27 - initial release
00009 //     2014-06-14 - modified for AK8963 based on Kris Wieners MPU-9250 Sketch
00010 
00011 /* ============================================
00012 I2Cdev device library code is placed under the MIT license
00013 Copyright (c) 2011 Jeff Rowberg
00014 
00015 Permission is hereby granted, free of charge, to any person obtaining a copy
00016 of this software and associated documentation files (the "Software"), to deal
00017 in the Software without restriction, including without limitation the rights
00018 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00019 copies of the Software, and to permit persons to whom the Software is
00020 furnished to do so, subject to the following conditions:
00021 
00022 The above copyright notice and this permission notice shall be included in
00023 all copies or substantial portions of the Software.
00024 
00025 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00026 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00027 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00028 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00029 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00030 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00031 THE SOFTWARE.
00032 ===============================================
00033 */
00034 
00035 #include "AK8963.h"
00036 
00037 using namespace AK8963I2C;
00038 
00039 
00040 /** Default constructor, uses default I2C address.
00041  * @see AK8963_DEFAULT_ADDRESS
00042  */
00043 AK8963::AK8963() {
00044     devAddr = AK8963_DEFAULT_ADDRESS;
00045 }
00046 
00047 /** Specific address constructor.
00048  * @param address I2C address
00049  * @see AK8963_DEFAULT_ADDRESS
00050  * @see AK8963_ADDRESS_00
00051  */
00052 AK8963::AK8963(bool useSPI, uint8_t address) {
00053     bSPI = useSPI;
00054     devAddr = address;
00055 }
00056 
00057 /** Power on and prepare for general usage.
00058  * No specific pre-configuration is necessary for this device.
00059  */
00060 void AK8963::initialize() {
00061 
00062 }
00063 
00064 /** Verify the I2C connection.
00065  * Make sure the device is connected and responds as expected.
00066  * @return True if connection is valid, false otherwise
00067  */
00068 bool AK8963::testConnection() {
00069     if (i2Cdev.readByte(devAddr, AK8963_RA_WIA, buffer) == 1) {
00070         return (buffer[0] == 0x48);
00071     }
00072     return false;
00073 }
00074 
00075 // WIA register
00076 
00077 uint8_t AK8963::getDeviceID() {
00078     i2Cdev.readByte(devAddr, AK8963_RA_WIA, buffer);
00079     return buffer[0];
00080 }
00081 
00082 // INFO register
00083 
00084 uint8_t AK8963::getInfo() {
00085     i2Cdev.readByte(devAddr, AK8963_RA_INFO, buffer);
00086     return buffer[0];
00087 }
00088 
00089 // ST1 register
00090 
00091 bool AK8963::getDataReady() {
00092     i2Cdev.readBit(devAddr, AK8963_RA_ST1, AK8963_ST1_DRDY_BIT, buffer);
00093     return buffer[0];
00094 }
00095 
00096 bool AK8963::getDataOverRun() {
00097     i2Cdev.readBit(devAddr, AK8963_RA_ST1, AK8963_ST1_DOR_BIT, buffer);
00098     return buffer[0];
00099 }
00100 
00101 // H* registers
00102 void AK8963::getHeading(int16_t *x, int16_t *y, int16_t *z) {
00103     //I2Cdev::writeByte(devAddr, AK8963_RA_CNTL1, AK8963_MODE_SINGLE);
00104     //delay(10);
00105     
00106     if (getDataReady() & 0x01) {
00107         i2Cdev.readBytes(devAddr, AK8963_RA_HXL, 7, buffer);
00108         uint8_t c = buffer[6]; // End data read by reading ST2 register
00109         if(!(c & 0x08)) { // Check if magnetic sensor overflow set, if not then report data
00110             *x = (((int16_t)buffer[1]) << 8) | buffer[0];
00111             *y = (((int16_t)buffer[3]) << 8) | buffer[2];
00112             *z = (((int16_t)buffer[5]) << 8) | buffer[4];
00113         }
00114     }   
00115 }
00116 
00117 void AK8963::getSelfTest(int16_t *x, int16_t *y, int16_t *z) {
00118     i2Cdev.writeByte(devAddr, AK8963_RA_CNTL1, AK8963_MODE_POWERDOWN); // Power down magnetometer  
00119     Thread::wait(10);
00120     setSelfTest(true);      // Set Self Test Bit
00121     Thread::wait(10);
00122     // Read mag registers
00123     if(getDataReady() & 0x01) {
00124         i2Cdev.readBytes(devAddr, AK8963_RA_HXL, 7, buffer);
00125         uint8_t c = buffer[6]; // End data read by reading ST2 register
00126         if(!(c & 0x08)) { // Check if magnetic sensor overflow set, if not then report data
00127             *x = (((int16_t)buffer[1]) << 8) | buffer[0];
00128             *y = (((int16_t)buffer[3]) << 8) | buffer[2];
00129             *z = (((int16_t)buffer[5]) << 8) | buffer[4];
00130         }
00131     }
00132     setSelfTest(false);     // Set Self Test Bit
00133     Thread::wait(10);
00134     i2Cdev.writeByte(devAddr, AK8963_RA_CNTL1, AK8963_MODE_POWERDOWN); // Power down magnetometer  
00135     Thread::wait(10);
00136     
00137 }
00138 
00139 // ST2 register
00140 bool AK8963::getOverflowStatus() {
00141     i2Cdev.readBit(devAddr, AK8963_RA_ST2, AK8963_ST2_HOFL_BIT, buffer);
00142     return buffer[0];
00143 }
00144 
00145 bool AK8963::getOutBitST() {
00146     i2Cdev.readBit(devAddr, AK8963_RA_ST2, AK8963_ST2_BITM, buffer);
00147     return buffer[0];
00148 }
00149 
00150 // CNTL1 register
00151 uint8_t AK8963::getMode() {
00152     //I2Cdev::readBits(devAddr, AK8963_RA_CNTL1, AK8963_CNTL1_MODE_BIT, AK8963_CNTL1_MODE_LENGTH, buffer);
00153     i2Cdev.readByte(devAddr, AK8963_RA_CNTL1, buffer);
00154     return buffer[0];
00155 }
00156 
00157 //Configure magenetometer mode and resolution
00158 void AK8963::setModeRes(uint8_t mode, uint8_t Mscale) {
00159     //I2Cdev::writeBits(devAddr, AK8963_RA_CNTL1, AK8963_CNTL1_MODE_BIT, AK8963_CNTL1_MODE_LENGTH, mode);
00160     i2Cdev.writeByte(devAddr, AK8963_RA_CNTL1, Mscale << 4 | mode);
00161     Thread::wait(10);
00162 }
00163 
00164 // CNTL2 register
00165 void AK8963::reset() {
00166     i2Cdev.writeBytes(devAddr, AK8963_RA_CNTL2, AK8963_CNTL2_RESET, buffer);
00167 }
00168 
00169 // ASTC register
00170 void AK8963::setSelfTest(bool enabled) {
00171     i2Cdev.writeBit(devAddr, AK8963_RA_ASTC, AK8963_ASTC_SELF_BIT, enabled);
00172 }
00173 
00174 // I2CDIS
00175 void AK8963::disableI2C() {
00176     i2Cdev.writeBit(devAddr, AK8963_RA_I2CDIS, AK8963_I2CDIS_BIT, true);
00177 }
00178 
00179 // ASA* registers
00180 void AK8963::getAdjustment(uint8_t *x, uint8_t *y, uint8_t *z) {
00181     i2Cdev.writeByte(devAddr, AK8963_RA_CNTL1, AK8963_MODE_POWERDOWN); // Power down magnetometer  
00182     Thread::wait(10);
00183     i2Cdev.writeByte(devAddr, AK8963_RA_CNTL1, AK8963_MODE_FUSEROM); // Enter Fuse ROM access mode
00184     Thread::wait(10);
00185     
00186     i2Cdev.readBytes(devAddr, AK8963_RA_ASAX, 3, buffer);     // Read the x-, y-, and z-axis calibration values
00187     *x = buffer[0];
00188     *y = buffer[1];
00189     *z = buffer[2];
00190     
00191     i2Cdev.writeByte(devAddr, AK8963_RA_CNTL1, AK8963_MODE_POWERDOWN); // Power down magnetometer  
00192     Thread::wait(10);
00193 }