Sample program for interfacing with PNI's RM3100 Breakout Board

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers RM3100MagDriver.cpp Source File

RM3100MagDriver.cpp

Go to the documentation of this file.
00001 /**
00002 * @file        RM3100MagDriver.cpp
00003 *
00004 * @brief       Sensor driver for RM3100 magnetometer.
00005 * @authors     Betty Zhang, Daniel Delsuc
00006 * @date        03/03/2017
00007 * @copyright   (C) 2017 PNI Corp
00008 *
00009 * @copyright   This sample code is provided "as is" without express or implied warranty.
00010 *
00011 */
00012 
00013 #include "main.h"
00014 #include "RM3100MagDriver.h"
00015 
00016 /*****************************/
00017 /*        Static variables   */
00018 /*****************************/
00019 static unsigned short int           mSampleRate;
00020 static SensorPowerMode              mSensorMode;
00021 static char                         mSamples[9];
00022 
00023 /*****************************/
00024 /*        Functions          */
00025 /*****************************/
00026 /**
00027  * @fn SensorStatus mag_enable_interrupts();
00028  *
00029  * @brief Enables the interrupt request from the sensor.
00030  *
00031  * @returns Status of the sensor. Not supported in AKM8975
00032  */
00033 SensorStatus mag_enable_interrupts()
00034 {
00035     static char data[] = { RM3100_ENABLED };
00036 
00037     if (mSensorMode == SensorPowerModeActive) 
00038     {
00039         rm3100_i2c_write(RM3100_BEACON_REG, data, sizeof(data)/sizeof(char));
00040     }
00041     return SensorOK;
00042 }
00043 
00044 /**
00045  * @fn SensorStatus mag_disable_interrupts();
00046  *
00047  * @brief Disables the interrupt request from the sensor.
00048  *
00049  * @returns Status of the sensor.
00050  */
00051 SensorStatus mag_disable_interrupts()
00052 {
00053     static char data[] = { RM3100_DISABLED };
00054     rm3100_i2c_write(RM3100_BEACON_REG, data, sizeof(data)/sizeof(char));
00055     return SensorOK;
00056 }
00057 
00058 /**
00059  * @fn SensorMode mag_set_power_mode(SensorPowerMode mode);
00060  *
00061  * @brief If possible, sets the sensor to the requested power mode. 
00062  *  *
00063  * @param mode  The requested sensor mode.
00064  * @returns     The actual state the sensor was set to.
00065  */
00066 SensorPowerMode mag_set_power_mode(SensorPowerMode mode)
00067 {
00068     switch(mode)
00069     {
00070         default:
00071             return mSensorMode;
00072             
00073         case SensorPowerModePowerDown:
00074         case SensorPowerModeSuspend:
00075             mSensorMode = mode;
00076             mag_disable_interrupts();
00077             break;
00078 
00079         case SensorPowerModeActive:
00080             mSensorMode = SensorPowerModeActive;
00081             mag_enable_interrupts();
00082             break;
00083     }
00084 
00085     return mSensorMode;
00086 }
00087 
00088 /**
00089  * @fn SensorStatus mag_initialize_sensor();
00090  *
00091  * @brief Initializes the sensor into a known state.
00092  *
00093  * @retval SensorOK                         The sensor has already been initialized
00094  * @retval SensorErrorUnexpectedDevice      The sensor did not return expected results.
00095  * @retval SensorUnknownError               An unknown error has occured.
00096  */
00097 SensorStatus mag_initialize_sensor()
00098 {
00099     char i2cbuffer[2];
00100     char settings[7];
00101      
00102     if(rm3100_i2c_read(RM3100_LROSCADJ_REG, i2cbuffer, 2) != SensorOK)
00103     {
00104         return SensorErrorNonExistant;
00105     }
00106 
00107     if (    (i2cbuffer[0] != RM3100_LROSCADJ_VALUE) ||
00108             (i2cbuffer[1] != RM3100_SLPOSCADJ_VALUE))
00109     {
00110         return SensorErrorUnexpectedDevice;
00111     }
00112 
00113     /* Zero buffer content */
00114     i2cbuffer[0]=0; 
00115     i2cbuffer[1]=0;
00116     
00117     /* Clears MAG and BEACON register and any pending measurement */
00118     rm3100_i2c_write(RM3100_MAG_REG, i2cbuffer, 2);
00119     
00120     /* Initialize settings */
00121     settings[0]=CCP1; /* CCPX1 */
00122     settings[1]=CCP0; /* CCPX0 */
00123     settings[2]=CCP1; /* CCPY1 */
00124     settings[3]=CCP0; /* CCPY0 */
00125     settings[4]=CCP1; /* CCPZ1 */
00126     settings[5]=CCP0; /* CCPZ0 */
00127     settings[6]=NOS;
00128     /* settings[7]=TMRC;  */
00129     
00130     /*  Write register settings */
00131     rm3100_i2c_write(RM3100_CCPX1_REG, settings, 7);
00132     
00133     mag_set_power_mode(SensorPowerModePowerDown);
00134         
00135     return SensorOK;
00136 }
00137 
00138 /**
00139  * @fn SensorMode mag_get_power_mode();
00140  *
00141  * @brief Used to determine the current power mode of the sensor.
00142  *
00143  * @returns The current power mode of the sensor.
00144  */
00145 SensorPowerMode mag_get_power_mode()
00146 {
00147     return mSensorMode;
00148 }
00149 
00150 /**
00151  * @fn unsigned short int mag_set_sample_rate(unsigned short int sample_rate);
00152  *
00153  * @brief Requests the hardware to perform sample conversions at the specified rate.
00154  *
00155  * @param sample_rate The requested sample rate of the sensor in Hz.
00156  *
00157  * @returns The actual sample rate of the sensor.
00158  */
00159 unsigned short mag_set_sample_rate(unsigned short sample_rate)
00160 {
00161     int i;
00162     static char i2cbuffer[1];
00163     const unsigned short int supported_rates[][2] = \
00164     {
00165         /* [Hz], register value */
00166         {   2, 0x0A},   // up to 2Hz
00167         {   4, 0x09},   // up to 4Hz
00168         {   8, 0x08},   // up to 8Hz
00169         {  16, 0x07},   // up to 16Hz
00170         {  31, 0x06},   // up to 31Hz
00171         {  62, 0x05},   // up to 62Hz
00172         {  125, 0x04},  // up to 125Hz
00173         {  220, 0x03}   // up to 250Hz
00174         };
00175         
00176     for(i = 0; i < sizeof(supported_rates)/(sizeof(unsigned short int)*2) - 1; i++)
00177     {
00178         if(sample_rate <= supported_rates[i][0]) break;
00179     }
00180             
00181     if (mSensorMode == SensorPowerModeActive) 
00182     {
00183         mag_disable_interrupts();
00184     }
00185     
00186     mSampleRate = supported_rates[i][0];
00187     i2cbuffer[0]= (char)supported_rates[i][1];
00188   
00189     rm3100_i2c_write(RM3100_TMRC_REG, i2cbuffer, 1);
00190     
00191     if (mSensorMode == SensorPowerModeActive) 
00192     {
00193         mag_enable_interrupts();
00194     }
00195 
00196     return mSampleRate;
00197 
00198 }
00199 
00200 /**
00201  * @fn unsigned short int mag_get_sample_rate();
00202  *
00203  * @brief Retrieves the mset sample rate of the sensor.
00204  *
00205  * @returns The actual sample rate of the sensor.
00206  */
00207 unsigned short mag_get_sample_rate()
00208 {
00209     return mSampleRate;
00210 }
00211 
00212 /**
00213  * @fn SensorStatus mag_get_sample_data(signed int *x, signed int *y, signed int *z);
00214  *
00215  * @brief Initiates an i2c read of the RM3100's sensor result registers.
00216  * @Each sensor reading consists of 3 bytes of data which are stored in 2’s
00217  * @complement format (range: -8388608 to 8388607) in the Results Registers
00218  *
00219  * @output: 3-axis Sensor data in Count 
00220  * 
00221  */
00222 void mag_get_sample_data(int * XYZ)
00223 {
00224     // read out sensor data
00225     rm3100_i2c_read(RM3100_QX2_REG, (char*)&mSamples, sizeof(mSamples)/sizeof(char));
00226     
00227     XYZ[0] = ((signed char)mSamples[0]) * 256 * 256;
00228     XYZ[0] |= mSamples[1] * 256;
00229     XYZ[0] |= mSamples[2];
00230 
00231     XYZ[1] = ((signed char)mSamples[3]) * 256 * 256;
00232     XYZ[1] |= mSamples[4] * 256;
00233     XYZ[1] |= mSamples[5];
00234 
00235     XYZ[2] = ((signed char)mSamples[6]) * 256 * 256;
00236     XYZ[2] |= mSamples[7] * 256;
00237     XYZ[2] |= mSamples[8];
00238 }