Forked from Jose R. Padron and Aaron Berk's library, customized for my specific application using 9DoF-Stick by Sparkfun.

Fork of HMC5843 by Jose R Padron

HMC5843 is triple axis, digital interface compass (geomagnetic sensor).

This library is forked from Jose R. Padron and Aaron Berk's work.

This library is for specific application using 9DoF-Stick.

Datasheet:

http://www.sparkfun.com/datasheets/Sensors/Magneto/HMC5843.pdf

HMC5843 は3軸のデジタルインターフェースを備えたコンパス(地磁気センサ)です。

このライブラリは 9DoF-Stick を使用した特定の企画のために保守しています。

mbed IDEが日本語をサポートするまでは英語でコメントを書いていきますが、サポートした後もきっと英語で書いていくでしょう。

Files at this revision

API Documentation at this revision

Comitter:
gltest26
Date:
Wed Sep 12 22:53:13 2012 +0000
Parent:
4:7a90125eedcf
Child:
6:05aa3555fce6
Commit message:
Collected common codes into a function getWord() to reduce duplicate codes.; Also made byte ordering and sign extending portable.

Changed in this revision

HMC5843.cpp Show annotated file Show diff for this revision Revisions of this file
HMC5843.h Show annotated file Show diff for this revision Revisions of this file
--- a/HMC5843.cpp	Wed Sep 12 15:54:13 2012 +0000
+++ b/HMC5843.cpp	Wed Sep 12 22:53:13 2012 +0000
@@ -114,53 +114,20 @@
     // Burst read all registers to enhance bus speed.
     i2c_.read(HMC5843_I2C_READ, rx, 6);
 
-    // Readings are expressed in 16bit 2's complement, so we must first
-    // concatenate two bytes to make a word and sign extend it to obtain
-    // correct negative values.
-    readings[0] = int(int16_t(unsigned(rx[0]) << 8 | unsigned(rx[1])));
-    readings[1] = int(int16_t(unsigned(rx[2]) << 8 | unsigned(rx[3])));
-    readings[2] = int(int16_t(unsigned(rx[4]) << 8 | unsigned(rx[5])));
-
-}
-
-int HMC5843::getMx() {
-
-    char tx[1];
-    char rx[2];
-    
-    
-    tx[0]=HMC5843_X_MSB;
-    i2c_.write(HMC5843_I2C_READ,tx,1);
-    i2c_.read(HMC5843_I2C_READ,rx,2);
-    return ((int)rx[0]<<8|(int)rx[1]);
+    readings[0] = swapExtend(&rx[0]);
+    readings[1] = swapExtend(&rx[2]);
+    readings[2] = swapExtend(&rx[4]);
 
 }
 
-int HMC5843::getMy() {
+int HMC5843::getWord(int regi){
 
-    char tx[1];
+    char tx = regi;
     char rx[2];
     
+    i2c_.write(I2C_ADDRESS, &tx, 1);
     
-    tx[0]=HMC5843_Y_MSB;
-    i2c_.write(HMC5843_I2C_READ,tx,1);
-    i2c_.read(HMC5843_I2C_READ,rx,2);
-    return ((int)rx[0]<<8|(int)rx[1]);
- 
+    i2c_.read(I2C_ADDRESS, rx, 2);
+    
+    return swapExtend(rx);
 }
-
-
-int HMC5843::getMz(){
-
-    char tx[1];
-    char rx[2];
-    
-    
-    tx[0]=HMC5843_Z_MSB;
-    i2c_.write(HMC5843_I2C_READ,tx,1);
-    i2c_.read(HMC5843_I2C_READ,rx,2);
-    return ((int)rx[0]<<8|(int)rx[1]);
- 
-}
-
-     
--- a/HMC5843.h	Wed Sep 12 15:54:13 2012 +0000
+++ b/HMC5843.h	Wed Sep 12 22:53:13 2012 +0000
@@ -114,6 +114,14 @@
 public:
 
     /**
+     * The I2C address that can be passed directly to i2c object (it's already shifted 1 bit left).
+     *
+     * You don't need to manually set or clear the LSB when calling I2C::read() or I2C::write(),
+     * the library takes care of it.  We just always clear the LSB.
+     */
+    static const int I2C_ADDRESS = HMC5843_I2C_WRITE;
+
+    /**
      * Constructor.
      *
      * @param sda mbed pin to use for SDA line of I2C interface.
@@ -179,21 +187,21 @@
      *
      * @return x-axis magnetic value
      */
-    int getMx();
+    int getMx(){ return getWord(HMC5843_X_MSB); }
     
     /**
      * Get the output of Y axis.
      *
      * @return y-axis magnetic value
      */
-    int getMy();
+    int getMy(){ return getWord(HMC5843_Y_MSB); }
     
     /**
      * Get the output of Z axis.
      *
      * @return z-axis magnetic value
      */
-    int getMz();
+    int getMz(){ return getWord(HMC5843_Z_MSB); }
    
     
     /**
@@ -203,6 +211,20 @@
      */
     int getStatus(void);
 
+
+protected:
+
+    /**
+     * Reads a word (2 bytes) from the sensor via I2C bus.
+     *
+     * The queried value is assumed big-endian, 2's complement value.
+     *
+     * This protected function is added because we shouldn't write getMx(), getMy() and getMz()
+     * independently, but collect common codes.
+     *
+     * @param regi Register address to be read.
+     */
+    int getWord(int regi);
   
 private:
 
@@ -217,7 +239,22 @@
      */
     I2C i2c_;
 
-   
+    /**
+     * Converts big-endian 2's complement byte pair to native byte order of
+     * the CPU and then sign extend it to the CPU's register size.
+     *
+     * Implemented here to make the compiler inline expand it.
+     */
+    int swapExtend(const char rx[2]){
+        // Readings are expressed in 16bit 2's complement, so we must first
+        // concatenate two bytes to make a word and sign extend it to obtain
+        // correct negative values.
+        // ARMCC compiles char as unsigned, which means no sign extension is
+        // performed during bitwise operations to chars. But we should make sure
+        // that lower byte won't extend its sign past upper byte for other
+        // compilers if we want to keep it portable.
+        return int16_t(((unsigned char)rx[0] << 8) | (unsigned char)rx[1]);
+    }
 
 };