Daniel Delsuc
/
RM3100BB_Sample_Code
Sample program for interfacing with PNI's RM3100 Breakout Board
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]; }