Daniel Delsuc
/
RM3100BB_Sample_Code
Sample program for interfacing with PNI's RM3100 Breakout Board
Diff: RM3100MagDriver.cpp
- Revision:
- 0:6ddf88b49483
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/RM3100MagDriver.cpp Thu Oct 26 18:40:57 2017 +0000 @@ -0,0 +1,238 @@ +/** +* @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]; +} \ No newline at end of file