Sample program for interfacing with PNI's RM3100 Breakout Board

Dependencies:   mbed

RM3100MagDriver.cpp

Committer:
ddelsuc
Date:
2017-10-26
Revision:
0:6ddf88b49483

File content as of revision 0:6ddf88b49483:

/**
* @file        RM3100MagDriver.cpp
*
* @brief       Sensor driver for RM3100 magnetometer.
* @authors     Betty Zhang, Daniel Delsuc
* @date        03/03/2017
* @copyright   (C) 2017 PNI Corp
*
* @copyright   This sample code is provided "as is" without express or implied warranty.
*
*/

#include "main.h"
#include "RM3100MagDriver.h"

/*****************************/
/*        Static variables   */
/*****************************/
static unsigned short int           mSampleRate;
static SensorPowerMode              mSensorMode;
static char                         mSamples[9];

/*****************************/
/*        Functions          */
/*****************************/
/**
 * @fn SensorStatus mag_enable_interrupts();
 *
 * @brief Enables the interrupt request from the sensor.
 *
 * @returns Status of the sensor. Not supported in AKM8975
 */
SensorStatus mag_enable_interrupts()
{
    static char data[] = { RM3100_ENABLED };

    if (mSensorMode == SensorPowerModeActive) 
    {
        rm3100_i2c_write(RM3100_BEACON_REG, data, sizeof(data)/sizeof(char));
    }
    return SensorOK;
}

/**
 * @fn SensorStatus mag_disable_interrupts();
 *
 * @brief Disables the interrupt request from the sensor.
 *
 * @returns Status of the sensor.
 */
SensorStatus mag_disable_interrupts()
{
    static char data[] = { RM3100_DISABLED };
    rm3100_i2c_write(RM3100_BEACON_REG, data, sizeof(data)/sizeof(char));
    return SensorOK;
}

/**
 * @fn SensorMode mag_set_power_mode(SensorPowerMode mode);
 *
 * @brief If possible, sets the sensor to the requested power mode. 
 *  *
 * @param mode  The requested sensor mode.
 * @returns     The actual state the sensor was set to.
 */
SensorPowerMode mag_set_power_mode(SensorPowerMode mode)
{
    switch(mode)
    {
        default:
            return mSensorMode;
            
        case SensorPowerModePowerDown:
        case SensorPowerModeSuspend:
            mSensorMode = mode;
            mag_disable_interrupts();
            break;

        case SensorPowerModeActive:
            mSensorMode = SensorPowerModeActive;
            mag_enable_interrupts();
            break;
    }

    return mSensorMode;
}

/**
 * @fn SensorStatus mag_initialize_sensor();
 *
 * @brief Initializes the sensor into a known state.
 *
 * @retval SensorOK                         The sensor has already been initialized
 * @retval SensorErrorUnexpectedDevice      The sensor did not return expected results.
 * @retval SensorUnknownError               An unknown error has occured.
 */
SensorStatus mag_initialize_sensor()
{
    char i2cbuffer[2];
    char settings[7];
     
    if(rm3100_i2c_read(RM3100_LROSCADJ_REG, i2cbuffer, 2) != SensorOK)
    {
        return SensorErrorNonExistant;
    }

    if (    (i2cbuffer[0] != RM3100_LROSCADJ_VALUE) ||
            (i2cbuffer[1] != RM3100_SLPOSCADJ_VALUE))
    {
        return SensorErrorUnexpectedDevice;
    }

    /* Zero buffer content */
    i2cbuffer[0]=0; 
    i2cbuffer[1]=0;
    
    /* Clears MAG and BEACON register and any pending measurement */
    rm3100_i2c_write(RM3100_MAG_REG, i2cbuffer, 2);
    
    /* Initialize settings */
    settings[0]=CCP1; /* CCPX1 */
    settings[1]=CCP0; /* CCPX0 */
    settings[2]=CCP1; /* CCPY1 */
    settings[3]=CCP0; /* CCPY0 */
    settings[4]=CCP1; /* CCPZ1 */
    settings[5]=CCP0; /* CCPZ0 */
    settings[6]=NOS;
    /* settings[7]=TMRC;  */
    
    /*  Write register settings */
    rm3100_i2c_write(RM3100_CCPX1_REG, settings, 7);
    
    mag_set_power_mode(SensorPowerModePowerDown);
        
    return SensorOK;
}

/**
 * @fn SensorMode mag_get_power_mode();
 *
 * @brief Used to determine the current power mode of the sensor.
 *
 * @returns The current power mode of the sensor.
 */
SensorPowerMode mag_get_power_mode()
{
    return mSensorMode;
}

/**
 * @fn unsigned short int mag_set_sample_rate(unsigned short int sample_rate);
 *
 * @brief Requests the hardware to perform sample conversions at the specified rate.
 *
 * @param sample_rate The requested sample rate of the sensor in Hz.
 *
 * @returns The actual sample rate of the sensor.
 */
unsigned short mag_set_sample_rate(unsigned short sample_rate)
{
    int i;
    static char i2cbuffer[1];
    const unsigned short int supported_rates[][2] = \
    {
        /* [Hz], register value */
        {   2, 0x0A},   // up to 2Hz
        {   4, 0x09},   // up to 4Hz
        {   8, 0x08},   // up to 8Hz
        {  16, 0x07},   // up to 16Hz
        {  31, 0x06},   // up to 31Hz
        {  62, 0x05},   // up to 62Hz
        {  125, 0x04},  // up to 125Hz
        {  220, 0x03}   // up to 250Hz
        };
        
    for(i = 0; i < sizeof(supported_rates)/(sizeof(unsigned short int)*2) - 1; i++)
    {
        if(sample_rate <= supported_rates[i][0]) break;
    }
            
    if (mSensorMode == SensorPowerModeActive) 
    {
        mag_disable_interrupts();
    }
    
    mSampleRate = supported_rates[i][0];
    i2cbuffer[0]= (char)supported_rates[i][1];
  
    rm3100_i2c_write(RM3100_TMRC_REG, i2cbuffer, 1);
    
    if (mSensorMode == SensorPowerModeActive) 
    {
        mag_enable_interrupts();
    }

    return mSampleRate;

}

/**
 * @fn unsigned short int mag_get_sample_rate();
 *
 * @brief Retrieves the mset sample rate of the sensor.
 *
 * @returns The actual sample rate of the sensor.
 */
unsigned short mag_get_sample_rate()
{
    return mSampleRate;
}

/**
 * @fn SensorStatus mag_get_sample_data(signed int *x, signed int *y, signed int *z);
 *
 * @brief Initiates an i2c read of the RM3100's sensor result registers.
 * @Each sensor reading consists of 3 bytes of data which are stored in 2’s
 * @complement format (range: -8388608 to 8388607) in the Results Registers
 *
 * @output: 3-axis Sensor data in Count 
 * 
 */
void mag_get_sample_data(int * XYZ)
{
    // read out sensor data
    rm3100_i2c_read(RM3100_QX2_REG, (char*)&mSamples, sizeof(mSamples)/sizeof(char));
    
    XYZ[0] = ((signed char)mSamples[0]) * 256 * 256;
    XYZ[0] |= mSamples[1] * 256;
    XYZ[0] |= mSamples[2];

    XYZ[1] = ((signed char)mSamples[3]) * 256 * 256;
    XYZ[1] |= mSamples[4] * 256;
    XYZ[1] |= mSamples[5];

    XYZ[2] = ((signed char)mSamples[6]) * 256 * 256;
    XYZ[2] |= mSamples[7] * 256;
    XYZ[2] |= mSamples[8];
}