Sample program for interfacing with PNI's RM3100 Breakout Board

Dependencies:   mbed

Committer:
ddelsuc
Date:
Thu Oct 26 18:40:57 2017 +0000
Revision:
0:6ddf88b49483
Sample program for interfacing with PNI's RM3100 Breakout Board

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ddelsuc 0:6ddf88b49483 1 /**
ddelsuc 0:6ddf88b49483 2 * @file RM3100MagDriver.cpp
ddelsuc 0:6ddf88b49483 3 *
ddelsuc 0:6ddf88b49483 4 * @brief Sensor driver for RM3100 magnetometer.
ddelsuc 0:6ddf88b49483 5 * @authors Betty Zhang, Daniel Delsuc
ddelsuc 0:6ddf88b49483 6 * @date 03/03/2017
ddelsuc 0:6ddf88b49483 7 * @copyright (C) 2017 PNI Corp
ddelsuc 0:6ddf88b49483 8 *
ddelsuc 0:6ddf88b49483 9 * @copyright This sample code is provided "as is" without express or implied warranty.
ddelsuc 0:6ddf88b49483 10 *
ddelsuc 0:6ddf88b49483 11 */
ddelsuc 0:6ddf88b49483 12
ddelsuc 0:6ddf88b49483 13 #include "main.h"
ddelsuc 0:6ddf88b49483 14 #include "RM3100MagDriver.h"
ddelsuc 0:6ddf88b49483 15
ddelsuc 0:6ddf88b49483 16 /*****************************/
ddelsuc 0:6ddf88b49483 17 /* Static variables */
ddelsuc 0:6ddf88b49483 18 /*****************************/
ddelsuc 0:6ddf88b49483 19 static unsigned short int mSampleRate;
ddelsuc 0:6ddf88b49483 20 static SensorPowerMode mSensorMode;
ddelsuc 0:6ddf88b49483 21 static char mSamples[9];
ddelsuc 0:6ddf88b49483 22
ddelsuc 0:6ddf88b49483 23 /*****************************/
ddelsuc 0:6ddf88b49483 24 /* Functions */
ddelsuc 0:6ddf88b49483 25 /*****************************/
ddelsuc 0:6ddf88b49483 26 /**
ddelsuc 0:6ddf88b49483 27 * @fn SensorStatus mag_enable_interrupts();
ddelsuc 0:6ddf88b49483 28 *
ddelsuc 0:6ddf88b49483 29 * @brief Enables the interrupt request from the sensor.
ddelsuc 0:6ddf88b49483 30 *
ddelsuc 0:6ddf88b49483 31 * @returns Status of the sensor. Not supported in AKM8975
ddelsuc 0:6ddf88b49483 32 */
ddelsuc 0:6ddf88b49483 33 SensorStatus mag_enable_interrupts()
ddelsuc 0:6ddf88b49483 34 {
ddelsuc 0:6ddf88b49483 35 static char data[] = { RM3100_ENABLED };
ddelsuc 0:6ddf88b49483 36
ddelsuc 0:6ddf88b49483 37 if (mSensorMode == SensorPowerModeActive)
ddelsuc 0:6ddf88b49483 38 {
ddelsuc 0:6ddf88b49483 39 rm3100_i2c_write(RM3100_BEACON_REG, data, sizeof(data)/sizeof(char));
ddelsuc 0:6ddf88b49483 40 }
ddelsuc 0:6ddf88b49483 41 return SensorOK;
ddelsuc 0:6ddf88b49483 42 }
ddelsuc 0:6ddf88b49483 43
ddelsuc 0:6ddf88b49483 44 /**
ddelsuc 0:6ddf88b49483 45 * @fn SensorStatus mag_disable_interrupts();
ddelsuc 0:6ddf88b49483 46 *
ddelsuc 0:6ddf88b49483 47 * @brief Disables the interrupt request from the sensor.
ddelsuc 0:6ddf88b49483 48 *
ddelsuc 0:6ddf88b49483 49 * @returns Status of the sensor.
ddelsuc 0:6ddf88b49483 50 */
ddelsuc 0:6ddf88b49483 51 SensorStatus mag_disable_interrupts()
ddelsuc 0:6ddf88b49483 52 {
ddelsuc 0:6ddf88b49483 53 static char data[] = { RM3100_DISABLED };
ddelsuc 0:6ddf88b49483 54 rm3100_i2c_write(RM3100_BEACON_REG, data, sizeof(data)/sizeof(char));
ddelsuc 0:6ddf88b49483 55 return SensorOK;
ddelsuc 0:6ddf88b49483 56 }
ddelsuc 0:6ddf88b49483 57
ddelsuc 0:6ddf88b49483 58 /**
ddelsuc 0:6ddf88b49483 59 * @fn SensorMode mag_set_power_mode(SensorPowerMode mode);
ddelsuc 0:6ddf88b49483 60 *
ddelsuc 0:6ddf88b49483 61 * @brief If possible, sets the sensor to the requested power mode.
ddelsuc 0:6ddf88b49483 62 * *
ddelsuc 0:6ddf88b49483 63 * @param mode The requested sensor mode.
ddelsuc 0:6ddf88b49483 64 * @returns The actual state the sensor was set to.
ddelsuc 0:6ddf88b49483 65 */
ddelsuc 0:6ddf88b49483 66 SensorPowerMode mag_set_power_mode(SensorPowerMode mode)
ddelsuc 0:6ddf88b49483 67 {
ddelsuc 0:6ddf88b49483 68 switch(mode)
ddelsuc 0:6ddf88b49483 69 {
ddelsuc 0:6ddf88b49483 70 default:
ddelsuc 0:6ddf88b49483 71 return mSensorMode;
ddelsuc 0:6ddf88b49483 72
ddelsuc 0:6ddf88b49483 73 case SensorPowerModePowerDown:
ddelsuc 0:6ddf88b49483 74 case SensorPowerModeSuspend:
ddelsuc 0:6ddf88b49483 75 mSensorMode = mode;
ddelsuc 0:6ddf88b49483 76 mag_disable_interrupts();
ddelsuc 0:6ddf88b49483 77 break;
ddelsuc 0:6ddf88b49483 78
ddelsuc 0:6ddf88b49483 79 case SensorPowerModeActive:
ddelsuc 0:6ddf88b49483 80 mSensorMode = SensorPowerModeActive;
ddelsuc 0:6ddf88b49483 81 mag_enable_interrupts();
ddelsuc 0:6ddf88b49483 82 break;
ddelsuc 0:6ddf88b49483 83 }
ddelsuc 0:6ddf88b49483 84
ddelsuc 0:6ddf88b49483 85 return mSensorMode;
ddelsuc 0:6ddf88b49483 86 }
ddelsuc 0:6ddf88b49483 87
ddelsuc 0:6ddf88b49483 88 /**
ddelsuc 0:6ddf88b49483 89 * @fn SensorStatus mag_initialize_sensor();
ddelsuc 0:6ddf88b49483 90 *
ddelsuc 0:6ddf88b49483 91 * @brief Initializes the sensor into a known state.
ddelsuc 0:6ddf88b49483 92 *
ddelsuc 0:6ddf88b49483 93 * @retval SensorOK The sensor has already been initialized
ddelsuc 0:6ddf88b49483 94 * @retval SensorErrorUnexpectedDevice The sensor did not return expected results.
ddelsuc 0:6ddf88b49483 95 * @retval SensorUnknownError An unknown error has occured.
ddelsuc 0:6ddf88b49483 96 */
ddelsuc 0:6ddf88b49483 97 SensorStatus mag_initialize_sensor()
ddelsuc 0:6ddf88b49483 98 {
ddelsuc 0:6ddf88b49483 99 char i2cbuffer[2];
ddelsuc 0:6ddf88b49483 100 char settings[7];
ddelsuc 0:6ddf88b49483 101
ddelsuc 0:6ddf88b49483 102 if(rm3100_i2c_read(RM3100_LROSCADJ_REG, i2cbuffer, 2) != SensorOK)
ddelsuc 0:6ddf88b49483 103 {
ddelsuc 0:6ddf88b49483 104 return SensorErrorNonExistant;
ddelsuc 0:6ddf88b49483 105 }
ddelsuc 0:6ddf88b49483 106
ddelsuc 0:6ddf88b49483 107 if ( (i2cbuffer[0] != RM3100_LROSCADJ_VALUE) ||
ddelsuc 0:6ddf88b49483 108 (i2cbuffer[1] != RM3100_SLPOSCADJ_VALUE))
ddelsuc 0:6ddf88b49483 109 {
ddelsuc 0:6ddf88b49483 110 return SensorErrorUnexpectedDevice;
ddelsuc 0:6ddf88b49483 111 }
ddelsuc 0:6ddf88b49483 112
ddelsuc 0:6ddf88b49483 113 /* Zero buffer content */
ddelsuc 0:6ddf88b49483 114 i2cbuffer[0]=0;
ddelsuc 0:6ddf88b49483 115 i2cbuffer[1]=0;
ddelsuc 0:6ddf88b49483 116
ddelsuc 0:6ddf88b49483 117 /* Clears MAG and BEACON register and any pending measurement */
ddelsuc 0:6ddf88b49483 118 rm3100_i2c_write(RM3100_MAG_REG, i2cbuffer, 2);
ddelsuc 0:6ddf88b49483 119
ddelsuc 0:6ddf88b49483 120 /* Initialize settings */
ddelsuc 0:6ddf88b49483 121 settings[0]=CCP1; /* CCPX1 */
ddelsuc 0:6ddf88b49483 122 settings[1]=CCP0; /* CCPX0 */
ddelsuc 0:6ddf88b49483 123 settings[2]=CCP1; /* CCPY1 */
ddelsuc 0:6ddf88b49483 124 settings[3]=CCP0; /* CCPY0 */
ddelsuc 0:6ddf88b49483 125 settings[4]=CCP1; /* CCPZ1 */
ddelsuc 0:6ddf88b49483 126 settings[5]=CCP0; /* CCPZ0 */
ddelsuc 0:6ddf88b49483 127 settings[6]=NOS;
ddelsuc 0:6ddf88b49483 128 /* settings[7]=TMRC; */
ddelsuc 0:6ddf88b49483 129
ddelsuc 0:6ddf88b49483 130 /* Write register settings */
ddelsuc 0:6ddf88b49483 131 rm3100_i2c_write(RM3100_CCPX1_REG, settings, 7);
ddelsuc 0:6ddf88b49483 132
ddelsuc 0:6ddf88b49483 133 mag_set_power_mode(SensorPowerModePowerDown);
ddelsuc 0:6ddf88b49483 134
ddelsuc 0:6ddf88b49483 135 return SensorOK;
ddelsuc 0:6ddf88b49483 136 }
ddelsuc 0:6ddf88b49483 137
ddelsuc 0:6ddf88b49483 138 /**
ddelsuc 0:6ddf88b49483 139 * @fn SensorMode mag_get_power_mode();
ddelsuc 0:6ddf88b49483 140 *
ddelsuc 0:6ddf88b49483 141 * @brief Used to determine the current power mode of the sensor.
ddelsuc 0:6ddf88b49483 142 *
ddelsuc 0:6ddf88b49483 143 * @returns The current power mode of the sensor.
ddelsuc 0:6ddf88b49483 144 */
ddelsuc 0:6ddf88b49483 145 SensorPowerMode mag_get_power_mode()
ddelsuc 0:6ddf88b49483 146 {
ddelsuc 0:6ddf88b49483 147 return mSensorMode;
ddelsuc 0:6ddf88b49483 148 }
ddelsuc 0:6ddf88b49483 149
ddelsuc 0:6ddf88b49483 150 /**
ddelsuc 0:6ddf88b49483 151 * @fn unsigned short int mag_set_sample_rate(unsigned short int sample_rate);
ddelsuc 0:6ddf88b49483 152 *
ddelsuc 0:6ddf88b49483 153 * @brief Requests the hardware to perform sample conversions at the specified rate.
ddelsuc 0:6ddf88b49483 154 *
ddelsuc 0:6ddf88b49483 155 * @param sample_rate The requested sample rate of the sensor in Hz.
ddelsuc 0:6ddf88b49483 156 *
ddelsuc 0:6ddf88b49483 157 * @returns The actual sample rate of the sensor.
ddelsuc 0:6ddf88b49483 158 */
ddelsuc 0:6ddf88b49483 159 unsigned short mag_set_sample_rate(unsigned short sample_rate)
ddelsuc 0:6ddf88b49483 160 {
ddelsuc 0:6ddf88b49483 161 int i;
ddelsuc 0:6ddf88b49483 162 static char i2cbuffer[1];
ddelsuc 0:6ddf88b49483 163 const unsigned short int supported_rates[][2] = \
ddelsuc 0:6ddf88b49483 164 {
ddelsuc 0:6ddf88b49483 165 /* [Hz], register value */
ddelsuc 0:6ddf88b49483 166 { 2, 0x0A}, // up to 2Hz
ddelsuc 0:6ddf88b49483 167 { 4, 0x09}, // up to 4Hz
ddelsuc 0:6ddf88b49483 168 { 8, 0x08}, // up to 8Hz
ddelsuc 0:6ddf88b49483 169 { 16, 0x07}, // up to 16Hz
ddelsuc 0:6ddf88b49483 170 { 31, 0x06}, // up to 31Hz
ddelsuc 0:6ddf88b49483 171 { 62, 0x05}, // up to 62Hz
ddelsuc 0:6ddf88b49483 172 { 125, 0x04}, // up to 125Hz
ddelsuc 0:6ddf88b49483 173 { 220, 0x03} // up to 250Hz
ddelsuc 0:6ddf88b49483 174 };
ddelsuc 0:6ddf88b49483 175
ddelsuc 0:6ddf88b49483 176 for(i = 0; i < sizeof(supported_rates)/(sizeof(unsigned short int)*2) - 1; i++)
ddelsuc 0:6ddf88b49483 177 {
ddelsuc 0:6ddf88b49483 178 if(sample_rate <= supported_rates[i][0]) break;
ddelsuc 0:6ddf88b49483 179 }
ddelsuc 0:6ddf88b49483 180
ddelsuc 0:6ddf88b49483 181 if (mSensorMode == SensorPowerModeActive)
ddelsuc 0:6ddf88b49483 182 {
ddelsuc 0:6ddf88b49483 183 mag_disable_interrupts();
ddelsuc 0:6ddf88b49483 184 }
ddelsuc 0:6ddf88b49483 185
ddelsuc 0:6ddf88b49483 186 mSampleRate = supported_rates[i][0];
ddelsuc 0:6ddf88b49483 187 i2cbuffer[0]= (char)supported_rates[i][1];
ddelsuc 0:6ddf88b49483 188
ddelsuc 0:6ddf88b49483 189 rm3100_i2c_write(RM3100_TMRC_REG, i2cbuffer, 1);
ddelsuc 0:6ddf88b49483 190
ddelsuc 0:6ddf88b49483 191 if (mSensorMode == SensorPowerModeActive)
ddelsuc 0:6ddf88b49483 192 {
ddelsuc 0:6ddf88b49483 193 mag_enable_interrupts();
ddelsuc 0:6ddf88b49483 194 }
ddelsuc 0:6ddf88b49483 195
ddelsuc 0:6ddf88b49483 196 return mSampleRate;
ddelsuc 0:6ddf88b49483 197
ddelsuc 0:6ddf88b49483 198 }
ddelsuc 0:6ddf88b49483 199
ddelsuc 0:6ddf88b49483 200 /**
ddelsuc 0:6ddf88b49483 201 * @fn unsigned short int mag_get_sample_rate();
ddelsuc 0:6ddf88b49483 202 *
ddelsuc 0:6ddf88b49483 203 * @brief Retrieves the mset sample rate of the sensor.
ddelsuc 0:6ddf88b49483 204 *
ddelsuc 0:6ddf88b49483 205 * @returns The actual sample rate of the sensor.
ddelsuc 0:6ddf88b49483 206 */
ddelsuc 0:6ddf88b49483 207 unsigned short mag_get_sample_rate()
ddelsuc 0:6ddf88b49483 208 {
ddelsuc 0:6ddf88b49483 209 return mSampleRate;
ddelsuc 0:6ddf88b49483 210 }
ddelsuc 0:6ddf88b49483 211
ddelsuc 0:6ddf88b49483 212 /**
ddelsuc 0:6ddf88b49483 213 * @fn SensorStatus mag_get_sample_data(signed int *x, signed int *y, signed int *z);
ddelsuc 0:6ddf88b49483 214 *
ddelsuc 0:6ddf88b49483 215 * @brief Initiates an i2c read of the RM3100's sensor result registers.
ddelsuc 0:6ddf88b49483 216 * @Each sensor reading consists of 3 bytes of data which are stored in 2’s
ddelsuc 0:6ddf88b49483 217 * @complement format (range: -8388608 to 8388607) in the Results Registers
ddelsuc 0:6ddf88b49483 218 *
ddelsuc 0:6ddf88b49483 219 * @output: 3-axis Sensor data in Count
ddelsuc 0:6ddf88b49483 220 *
ddelsuc 0:6ddf88b49483 221 */
ddelsuc 0:6ddf88b49483 222 void mag_get_sample_data(int * XYZ)
ddelsuc 0:6ddf88b49483 223 {
ddelsuc 0:6ddf88b49483 224 // read out sensor data
ddelsuc 0:6ddf88b49483 225 rm3100_i2c_read(RM3100_QX2_REG, (char*)&mSamples, sizeof(mSamples)/sizeof(char));
ddelsuc 0:6ddf88b49483 226
ddelsuc 0:6ddf88b49483 227 XYZ[0] = ((signed char)mSamples[0]) * 256 * 256;
ddelsuc 0:6ddf88b49483 228 XYZ[0] |= mSamples[1] * 256;
ddelsuc 0:6ddf88b49483 229 XYZ[0] |= mSamples[2];
ddelsuc 0:6ddf88b49483 230
ddelsuc 0:6ddf88b49483 231 XYZ[1] = ((signed char)mSamples[3]) * 256 * 256;
ddelsuc 0:6ddf88b49483 232 XYZ[1] |= mSamples[4] * 256;
ddelsuc 0:6ddf88b49483 233 XYZ[1] |= mSamples[5];
ddelsuc 0:6ddf88b49483 234
ddelsuc 0:6ddf88b49483 235 XYZ[2] = ((signed char)mSamples[6]) * 256 * 256;
ddelsuc 0:6ddf88b49483 236 XYZ[2] |= mSamples[7] * 256;
ddelsuc 0:6ddf88b49483 237 XYZ[2] |= mSamples[8];
ddelsuc 0:6ddf88b49483 238 }