Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: Hello_RM3100 RM3100
Rm3100.hpp
00001 #ifndef RM3100_HPP 00002 #define RM3100_HPP 00003 00004 #include <stdint.h> 00005 #include "mbed.h" 00006 00007 /** 00008 * An interface for the RM3100 3-axis magnetometer from PNI Sensor Corp. 00009 * 00010 * @code 00011 * #include "mbed.h" 00012 * #include "Rm3100.hpp" 00013 * 00014 * int main(void) 00015 * { 00016 * Serial pc(USBTX, USBRX); 00017 * pc.baud(115200); 00018 * 00019 * printf("### Hello RM3100 ###\r\n"); 00020 * 00021 * int addr = ((Rm3100::RM3100_ADDR | Rm3100::RM3100_ADDR_SSN) << 1); 00022 * struct Rm3100::Status status = { 0 }; 00023 * struct Rm3100::Sample sample = { 0 }; 00024 * 00025 * Rm3100 sensor(I2C_SDA, I2C_SCL, addr); 00026 * 00027 * sensor.Begin(); 00028 * osDelay(1); 00029 * 00030 * sensor.SetCycleCounts(200); 00031 * osDelay(1); 00032 * 00033 * sensor.SetRate(100.0f); 00034 * osDelay(1); 00035 * 00036 * sensor.SetContinuousMeasurementMode(true); 00037 * osDelay(1); 00038 * 00039 * while (true) { 00040 * sensor.GetStatus(&status); 00041 * if (status.drdy) { 00042 * sensor.GetSample(&sample); 00043 * printf("x: %f, y: %f, z: %f\r\n", sample.x, sample.y, sample.z); 00044 * } 00045 * osDelay(10); 00046 * } 00047 * } 00048 * @endcode 00049 */ 00050 class Rm3100 00051 { 00052 public: 00053 00054 enum ReturnCode { 00055 RM3100_RET_EIO = -22, 00056 RM3100_RET_ENODEV = -19, 00057 RM3100_RET_EINVAL = -5, 00058 RM3100_RET_OK = 0, 00059 }; 00060 00061 enum I2CAddress { 00062 RM3100_ADDR_SA0 = 0x01, // address bit 0 00063 RM3100_ADDR_SA1 = 0x02, // address bit 1 00064 RM3100_ADDR_MASK = 0x03, 00065 RM3100_ADDR = 0x20, // 7-bit base address 00066 RM3100_ADDR_SSN = RM3100_ADDR_SA0, // SSN high = address bit 0 00067 RM3100_ADDR_SO = RM3100_ADDR_SA1, // SO high = address bit 1 00068 }; 00069 00070 enum Register { 00071 RM3100_REG_POLL = 0x00, // polls for a single measurement 00072 RM3100_REG_CMM = 0x01, // initiates continuous measurement mode 00073 RM3100_REG_CCX = 0x04, // cycle counts -- X axis 00074 RM3100_REG_CCY = 0x06, // cycle counts -- Y axis 00075 RM3100_REG_CCZ = 0x08, // cycle counts -- Z axis 00076 RM3100_REG_TMRC = 0x0B, // sets continuous mode data rate 00077 RM3100_REG_MX = 0x24, // measurement results -- X axis 00078 RM3100_REG_MY = 0x27, // measurement results -- Y axis 00079 RM3100_REG_MZ = 0x2A, // measurement results -- Z axis 00080 RM3100_REG_BIST = 0x33, // built-in self test 00081 RM3100_REG_STATUS = 0x34, // status of DRDY 00082 RM3100_REG_HSHAKE = 0x35, // handshake register 00083 RM3100_REG_REVID = 0x36, // MagI2C revision identification 00084 }; 00085 00086 struct SingleMeasurementMode { 00087 uint8_t res0:4; 00088 uint8_t pmx:1; 00089 uint8_t pmy:1; 00090 uint8_t pmz:1; 00091 uint8_t res7:1; 00092 }; 00093 00094 enum DataReadyMode { 00095 RM3100_DRDM_RES0 = 0x00, // reserved 00096 RM3100_DRDM_ANY_AXES = 0x01, // drdy on measurement complete on any axis 00097 RM3100_DRDM_ALL_AXES = 0x02, // drdy on measurement complete on all axes 00098 RM3100_DRDM_MASK = 0x03, 00099 }; 00100 00101 struct ContinuousMeasurementMode { 00102 uint8_t start:1; // continuous measurement mode enabled 00103 uint8_t res1:1; 00104 uint8_t drdm:2; // data ready mode 00105 uint8_t cmx:1; // X axis measurement enabled in CMM 00106 uint8_t cmy:1; // Y axis measurement enabled in CMM 00107 uint8_t cmz:1; // Z axis measurement enabled in CMM 00108 uint8_t res7:1; 00109 }; 00110 00111 struct CycleCounts { 00112 uint16_t x; 00113 uint16_t y; 00114 uint16_t z; 00115 }; 00116 00117 enum ContinuousMeasurementModeUpdateRate { 00118 RM3100_CMM_RATE_600_0_HZ = 0x02, // ~600 Hz 00119 RM3100_CMM_RATE_300_0_HZ = 0x03, // ~300 Hz 00120 RM3100_CMM_RATE_150_0_HZ = 0x04, // ~150 Hz 00121 RM3100_CMM_RATE_75_0_HZ = 0x05, // ~75 Hz 00122 RM3100_CMM_RATE_37_0_HZ = 0x06, // ~37 Hz 00123 RM3100_CMM_RATE_18_0_HZ = 0x07, // ~18 Hz 00124 RM3100_CMM_RATE_9_0_HZ = 0x08, // ~9 Hz 00125 RM3100_CMM_RATE_4_5_HZ = 0x09, // ~4.5 Hz 00126 RM3100_CMM_RATE_2_3_HZ = 0x0A, // ~2.3 Hz 00127 RM3100_CMM_RATE_1_2_HZ = 0x0B, // ~1.2 Hz 00128 RM3100_CMM_RATE_0_6_HZ = 0x0C, // ~0.6 Hz 00129 RM3100_CMM_RATE_0_3_HZ = 0x0D, // ~0.3 Hz 00130 RM3100_CMM_RATE_0_015_HZ = 0x0E, // ~0.015 Hz 00131 RM3100_CMM_RATE_0_075_HZ = 0x0F, // ~0.075 Hz 00132 RM3100_CMM_RATE_MASK = RM3100_CMM_RATE_0_075_HZ, 00133 RM3100_CMM_RATE_MSB = 0x90, 00134 }; 00135 00136 enum StatusFlag { 00137 RM3100_STATUS_FLAG_DRDY = (1 << 7), 00138 }; 00139 00140 struct Status { 00141 uint8_t res0:7; 00142 uint8_t drdy:1; 00143 }; 00144 00145 struct Measurement { 00146 int32_t x; 00147 int32_t y; 00148 int32_t z; 00149 }; 00150 00151 struct Sample { 00152 float x; 00153 float y; 00154 float z; 00155 }; 00156 00157 struct MeasurementScale { 00158 float x; 00159 float y; 00160 float z; 00161 MeasurementScale(float _x, float _y, float _z) : x(_x), y(_y), z(_z) {} 00162 }; 00163 00164 enum SelfTestCount { 00165 RM3100_SELF_TEST_COUNT_1 = 0x01, // 1 LR periods 00166 RM3100_SELF_TEST_COUNT_2 = 0x02, // 2 LR periods 00167 RM3100_SELF_TEST_COUNT_4 = 0x03, // 4 LR periods 00168 RM3100_SELF_TEST_COUNT_MASK = RM3100_SELF_TEST_COUNT_4, 00169 }; 00170 00171 enum SelfTestTimeout { 00172 RM3100_SELF_TEST_TIMEOUT_30_US = 0x01, // 1 cycle -- 30 µs 00173 RM3100_SELF_TEST_TIMEOUT_60_US = 0x02, // 2 cycles -- 60 µs 00174 RM3100_SELF_TEST_TIMEOUT_120_US = 0x03, // 4 cycles -- 120 µs 00175 RM3100_SELF_TEST_TIMEOUT_MASK = RM3100_SELF_TEST_TIMEOUT_120_US, 00176 }; 00177 00178 struct SelfTestConfig { 00179 uint8_t bp:2; // test count (LR periods) 00180 uint8_t bw:2; // timeout (sleep oscillation cycles) 00181 uint8_t xok:1; // X result -- 0 = error, 1 = ok 00182 uint8_t yok:1; // Y result -- 0 = error, 1 = ok 00183 uint8_t zok:1; // Z result -- 0 = error, 1 = ok 00184 uint8_t ste:1; // self test enable -- 0 = disable, 1 = enable 00185 }; 00186 00187 struct HandShakeConfig { 00188 uint8_t drc0:1; // clear drdy on any register write 00189 uint8_t drc1:1; // clear drdy on measurement read 00190 uint8_t res2:1; // 0 00191 uint8_t res3:1; // 1 00192 uint8_t nack0:1; // 1 when undef register write 00193 uint8_t nack1:1; // 1 when write SMM when CMM or visa versa 00194 uint8_t nack2:1; // 1 when measurement read before data ready 00195 }; 00196 00197 static const uint8_t RM3100_REVID = 0x22; 00198 00199 /** 00200 * Creates a new instance attached to the specified I2C pins and address 00201 * 00202 * @param sda I2C data pin 00203 * @param scl I2C clock pin 00204 * @param addr 8-bit I2C address 00205 */ 00206 Rm3100(PinName sda, PinName scl, uint8_t addr); 00207 00208 virtual ~Rm3100(); 00209 00210 /** 00211 * Checks hardware id and sets the data scale 00212 * 00213 * @return 0 on success 00214 */ 00215 int Begin(void); 00216 00217 /** 00218 * Gets the current single measurement mode config 00219 * 00220 * @param smm pointer to read config into 00221 * @return 0 on success 00222 */ 00223 int GetSingleMeasurementMode(struct SingleMeasurementMode *smm); 00224 00225 /** 00226 * Sets the current single measurement mode config 00227 * 00228 * @param smm pointer to write config from 00229 * @return 0 on success 00230 */ 00231 int SetSingleMeasurementMode(struct SingleMeasurementMode *smm); 00232 00233 /** 00234 * Sets the current single measurement mode config 00235 * 00236 * @param x enable measurement on X axis 00237 * @param y enable measurement on Y axis 00238 * @param z enable measurement on Z axis 00239 * @return 0 on success 00240 */ 00241 int SetSingleMeasurementMode(bool x, bool y, bool z); 00242 00243 /** 00244 * Gets the current continuous measurement mode config 00245 * 00246 * @param cmm pointer to read config into 00247 * @return 0 on success 00248 */ 00249 int GetContinuousMeasurementMode(struct ContinuousMeasurementMode *cmm); 00250 00251 /** 00252 * Sets the current continuous measurement mode config 00253 * 00254 * @param cmm pointer to write config from 00255 * @return 0 on success 00256 */ 00257 int SetContinuousMeasurementMode(struct ContinuousMeasurementMode *cmm); 00258 00259 /** 00260 * Sets the current continuous measurement mode config 00261 * 00262 * @param enabled enable CMM -- true = enabled, false = disabled 00263 * @param drdm data ready mode 00264 * @param x enable measurement on X axis 00265 * @param y enable measurement on Y axis 00266 * @param z enable measurement on Z axis 00267 * @return 0 on success 00268 */ 00269 int SetContinuousMeasurementMode(bool enabled, uint8_t drdm, bool x, 00270 bool y, bool z); 00271 00272 /** 00273 * Sets the current continuous measurement mode config 00274 * 00275 * @param enabled enable CMM -- true = enabled on all axes, false = disabled 00276 * @return 0 on success 00277 */ 00278 int SetContinuousMeasurementMode(bool enabled); 00279 00280 /** 00281 * Gets the current cycle counts 00282 * 00283 * @param cc pointer to read into 00284 * @return 0 on success 00285 */ 00286 int GetCycleCounts(struct CycleCounts *cc); 00287 00288 /** 00289 * Sets the current cycle counts 00290 * 00291 * @param cc pointer to write from 00292 * @return 0 on success 00293 */ 00294 int SetCycleCounts(struct CycleCounts *cc); 00295 00296 /* 00297 * Sets the current cycle counts (x, y, z) 00298 * 00299 * @param x cycle counts for X axis 00300 * @param y cycle counts for Y axis 00301 * @param z cycle counts for Z axis 00302 * @return 0 on success 00303 */ 00304 int SetCycleCounts(uint16_t x, uint16_t y, uint16_t z); 00305 00306 /* 00307 * Sets the current cycle counts (x = y, z) 00308 * 00309 * @param xy cycle counts for X and Y axes 00310 * @param z cycle counts for Z axis 00311 * @return 0 on success 00312 */ 00313 int SetCycleCounts(uint16_t xy, uint16_t z); 00314 00315 /* 00316 * Sets the current cycle counts (x = y = z) 00317 * 00318 * @param xyz cycle counts for all axes 00319 * @return 0 on success 00320 */ 00321 int SetCycleCounts(uint16_t xyz); 00322 00323 /** 00324 * Updates the measurement scale based on the given cycle counts 00325 * 00326 * @param cc pointer to cycle counts 00327 * @return 0 on success 00328 */ 00329 void UpdateMeasurementScale(struct CycleCounts *cc); 00330 00331 /** 00332 * Gets the continuous mode update rate 00333 * 00334 * @param tmrc pointer to read into 00335 * @return 0 on success 00336 */ 00337 int GetContinuousMeasurementModeUpdateRate(uint8_t *tmrc); 00338 00339 /** 00340 * Sets the continuous mode update rate (TMRC) 00341 * 00342 * @param tmrc rate to set according to TMRC table 00343 * @return 0 on success 00344 */ 00345 int SetContinuousMeasurementModeUpdateRate(uint8_t tmrc); 00346 00347 /** 00348 * Sets the contiunous mode update rate (Hz) 00349 * 00350 * @param rate rate to set in Hz 00351 * @return 0 on success 00352 */ 00353 int SetRate(float rate); 00354 00355 /** 00356 * Gets the current status 00357 * 00358 * @param status pointer to read into 00359 * @return 0 on success 00360 */ 00361 int GetStatus(struct Status *status); 00362 00363 /** 00364 * Gets the current measurement data (24-bit signed) 00365 * 00366 * @param m pointer to read into 00367 * @return 0 on success 00368 */ 00369 int GetMeasurement(struct Measurement *m); 00370 00371 /** 00372 * Gets the current measurement sample (scale to µT) 00373 * 00374 * @param s pointer to read into 00375 * @return 0 on success 00376 */ 00377 int GetSample(struct Sample *s); 00378 00379 /** 00380 * Gets the current self-test config/result 00381 * 00382 * @param cfg pointer to read into 00383 * @return 0 on success 00384 */ 00385 int GetSelfTestConfig(struct SelfTestConfig *cfg); 00386 00387 /** 00388 * Sets the current self-test config 00389 * 00390 * @param cfg pointer to write from 00391 * @return 0 on success 00392 */ 00393 int SetSelfTestConfig(struct SelfTestConfig *cfg); 00394 00395 /** 00396 * Sets the current self-test config 00397 * 00398 * @param count LR periods 00399 * @param timeout sleep oscillation cycles 00400 * @return 0 on success 00401 */ 00402 int SetSelfTestConfig(uint8_t count, uint8_t timeout, bool enabled); 00403 00404 /** 00405 * Performs a self-test, returning result 00406 * 00407 * @param count LR periods 00408 * @param timeout sleep oscillation cycles 00409 * @param result pointer to read result into 00410 * @return 0 on success 00411 */ 00412 int PerformSelfTest(uint8_t count, uint8_t timeout, 00413 struct SelfTestConfig *result); 00414 00415 /** 00416 * Clears the self-test config 00417 * 00418 * @return 0 on success 00419 */ 00420 int ClearSelfTest(); 00421 00422 /** 00423 * Gets the current handshake config 00424 * 00425 * @param cfg pointer to read into 00426 * @return 0 on success 00427 */ 00428 int GetHandShakeConfig(struct HandShakeConfig *cfg); 00429 00430 /** 00431 * Sets the current handshake config 00432 * 00433 * @param cfg pointer to write from 00434 * @return 0 on success 00435 */ 00436 int SetHandShakeConfig(struct HandShakeConfig *cfg); 00437 00438 /** 00439 * Sets the current data ready config 00440 * 00441 * @param on_write 1 = drdy cleared on any register write 00442 * @param on_read_measurement 1 = drdy cleared on measurement register read 00443 * @return 0 on success 00444 */ 00445 int SetDrdyClearConfig(bool on_write, bool on_read_measurement); 00446 00447 /** 00448 * Gets the current hardware revision 00449 * 00450 * @param rev pointer to read into 00451 * @return 0 on success 00452 */ 00453 int GetHardwareRevision(uint8_t *rev); 00454 00455 private: 00456 I2C _i2c; 00457 uint8_t _addr; 00458 struct MeasurementScale _scale; 00459 int _sample_delay_ms; 00460 int Read(uint8_t reg, uint8_t *buffer, uint8_t count); 00461 int Write(uint8_t reg, uint8_t *buffer, uint8_t count); 00462 }; 00463 00464 #endif /* RM3100_HPP */
Generated on Wed Jul 13 2022 05:33:02 by
1.7.2
RM3100 Geomagnetic Sensor