Driver for the LSM303D digital compass. Permits access to all LSM303D registers by name, including multi-byte register sets, and has convenience methods for floating-point accelerometer and magnetometer reads scaled according to the device settings. Written from scratch for Mbed 6.0

Dependents:   UoY-32C-lab8-exercise UoY-32C-lab5-lsm303d

Driver for the LSM303D digital compass

Permits access to all LSM303D registers by name, including multi-byte register sets. Convenience methods are included for sensor reads, including floating-point accelerometer and magnetometer reads scaled according to the device settings, and for the more common settings (data rates and scales).

I2C connection only. Written from scratch for Mbed 6.0.

The interface is subject to minor changes with each version. Deprecation warnings will be issued where possible.

Defaults

The class constructor checks that an LSM303D is present on the I2C bus, then enables all sensors. The accelerometer and magnetometer update rates are both set to 50Hz, and the scales are left at their device defaults of +-2g for the accelerometer and +-4gauss for the magnetometer.

Basic usage

Some usage examples

#include "lsm303d.h"

LSM303D lsm303d(D14, D15);  // SDA and SCL pins for I2C

lsm303d.setAccelScale(LSM303D::AccelScale::scale_4g); // set +-4g range

lsm303d.INT1_enable_DRDY_A(); // set DRDY_A bit in CTRL3 register (enable INT1 on accel data ready)

short rawX = lsm303d.getAccelX(); // returns 16-bit signed result, unscaled

float x, y, z;
lsm303d.getAccelInto(x, y, z); // overwrites parameters, values in g

float mX = lsm303d.getMagX(); // returns value in gauss
Committer:
ajp109
Date:
Wed Feb 17 13:13:13 2021 +0000
Revision:
11:0bb2931123d0
Parent:
lsm303d.h@10:392fa35ca17c
Capitalise filenames to match class name

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ajp109 0:b07c3d3e3d9c 1 #include "mbed.h"
ajp109 0:b07c3d3e3d9c 2
ajp109 0:b07c3d3e3d9c 3 typedef unsigned char u8;
ajp109 0:b07c3d3e3d9c 4 typedef signed short i16;
ajp109 0:b07c3d3e3d9c 5 typedef unsigned short u16;
ajp109 0:b07c3d3e3d9c 6
ajp109 0:b07c3d3e3d9c 7 #pragma pack(push)
ajp109 0:b07c3d3e3d9c 8 #pragma pack(1)
ajp109 0:b07c3d3e3d9c 9 typedef struct {
ajp109 0:b07c3d3e3d9c 10 u8 x;
ajp109 0:b07c3d3e3d9c 11 u8 y;
ajp109 0:b07c3d3e3d9c 12 u8 z;
ajp109 0:b07c3d3e3d9c 13 } u8_3;
ajp109 0:b07c3d3e3d9c 14 typedef struct {
ajp109 0:b07c3d3e3d9c 15 i16 x;
ajp109 0:b07c3d3e3d9c 16 i16 y;
ajp109 0:b07c3d3e3d9c 17 i16 z;
ajp109 0:b07c3d3e3d9c 18 } i16_3;
ajp109 0:b07c3d3e3d9c 19 #pragma pack(pop)
ajp109 0:b07c3d3e3d9c 20
ajp109 2:27d2a1082572 21 /** LSM303D class.
ajp109 9:a96e9bbad3ee 22 * Communicates with LSM303D electronic compass over I<sup>2</sup>C. Accelerometer,
ajp109 2:27d2a1082572 23 * magnetometer and temperature sensor supported. Configurable sample rates
ajp109 2:27d2a1082572 24 * and full-scale ranges. All LSM303D config registers available for raw
ajp109 2:27d2a1082572 25 * reads and writes if needed.
ajp109 2:27d2a1082572 26 *
ajp109 2:27d2a1082572 27 * Example:
ajp109 2:27d2a1082572 28 * @code
ajp109 2:27d2a1082572 29 * #include "mbed.h"
ajp109 2:27d2a1082572 30 * #include "lsm303d.h"
ajp109 2:27d2a1082572 31 *
ajp109 2:27d2a1082572 32 * LSM303D lsm303d(SDA, SCL);
ajp109 2:27d2a1082572 33 * lsm303d.setAccelRate(LSM303D::AccelRate::rate_25Hz);
ajp109 2:27d2a1082572 34 * lsm303d.setAccelScale(LSM303D::AccelScale::scale_8g);
ajp109 2:27d2a1082572 35 *
ajp109 2:27d2a1082572 36 * int main() {
ajp109 2:27d2a1082572 37 * short x, y, z;
ajp109 2:27d2a1082572 38 * lsm303d.getRawAccelInto(x, y, z); // 16-bit signed, unscaled
ajp109 2:27d2a1082572 39 * float xf, yf, zf;
ajp109 2:27d2a1082572 40 * lsm303d.getAccelInto(xf, yf, zf); // floats, in g
ajp109 2:27d2a1082572 41 * }
ajp109 2:27d2a1082572 42 * @endcode
ajp109 2:27d2a1082572 43 */
ajp109 0:b07c3d3e3d9c 44 class LSM303D {
ajp109 0:b07c3d3e3d9c 45
ajp109 1:a74f8c175f6c 46 friend class AccelScaleOption;
ajp109 1:a74f8c175f6c 47 friend class MagScaleOption;
ajp109 0:b07c3d3e3d9c 48
ajp109 0:b07c3d3e3d9c 49 unsigned char const addr_8bit_;
ajp109 0:b07c3d3e3d9c 50 unsigned char accel_scale_;
ajp109 0:b07c3d3e3d9c 51 unsigned char mag_scale_;
ajp109 0:b07c3d3e3d9c 52 I2C i2c_;
ajp109 0:b07c3d3e3d9c 53
ajp109 9:a96e9bbad3ee 54 protected:
ajp109 7:c8cddf7562ff 55 // These classes are protected (rather than private) for inlusion in docs.
ajp109 7:c8cddf7562ff 56 // Wouldn't be necessary if mbed online toolchain allowed local Doxyfiles.
ajp109 6:7d624356069e 57
ajp109 8:fe7c2ddc41b6 58 template <class T>
ajp109 8:fe7c2ddc41b6 59 class RWRegister;
ajp109 8:fe7c2ddc41b6 60
ajp109 6:7d624356069e 61 /** Read-only register class.
ajp109 6:7d624356069e 62 * @tparam T The underlying data type of the register.
ajp109 6:7d624356069e 63 * Provides an interface onto the read-only registers of the LSM303D.
ajp109 6:7d624356069e 64 * Operator overloading means that it can be treated as a const variable of
ajp109 9:a96e9bbad3ee 65 * type T for most purposes. Every read initiates an explicit
ajp109 9:a96e9bbad3ee 66 * I<sup>2</sup>C transfer.
ajp109 6:7d624356069e 67 */
ajp109 0:b07c3d3e3d9c 68 template <class T>
ajp109 0:b07c3d3e3d9c 69 class Register {
ajp109 1:a74f8c175f6c 70 friend class LSM303D;
ajp109 8:fe7c2ddc41b6 71 friend class RWRegister<T>;
ajp109 8:fe7c2ddc41b6 72 private:
ajp109 0:b07c3d3e3d9c 73 unsigned char addr_;
ajp109 1:a74f8c175f6c 74 LSM303D &parent_;
ajp109 0:b07c3d3e3d9c 75 Register(LSM303D &parent, unsigned char addr) :
ajp109 1:a74f8c175f6c 76 parent_(parent),
ajp109 1:a74f8c175f6c 77 addr_(addr | (sizeof(T)>1 ? 0x80 : 0x00)) {}
ajp109 6:7d624356069e 78 /// Explicit read method.
ajp109 6:7d624356069e 79 /// \return The current value of the register.
ajp109 0:b07c3d3e3d9c 80 virtual T read() const {
ajp109 0:b07c3d3e3d9c 81 T result;
ajp109 1:a74f8c175f6c 82 parent_.i2c_.lock();
ajp109 0:b07c3d3e3d9c 83 parent_.i2c_.write(parent_.addr_8bit_, (char *)&addr_, 1);
ajp109 0:b07c3d3e3d9c 84 parent_.i2c_.read(parent_.addr_8bit_, (char *)&result, sizeof(T));
ajp109 1:a74f8c175f6c 85 parent_.i2c_.unlock();
ajp109 0:b07c3d3e3d9c 86 return result;
ajp109 0:b07c3d3e3d9c 87 }
ajp109 6:7d624356069e 88 /// Explicit cast to type T
ajp109 1:a74f8c175f6c 89 inline operator T() const {
ajp109 0:b07c3d3e3d9c 90 return read();
ajp109 0:b07c3d3e3d9c 91 }
ajp109 0:b07c3d3e3d9c 92 };
ajp109 0:b07c3d3e3d9c 93
ajp109 5:e96d56fc0884 94 /** Read-write register class.
ajp109 6:7d624356069e 95 * @tparam T The underlying data type of the register.
ajp109 5:e96d56fc0884 96 * Provides an interface onto the writable registers of the LSM303D.
ajp109 5:e96d56fc0884 97 * Operator overloading means that it can be treated as a variable of type
ajp109 5:e96d56fc0884 98 * T for most purposes. Assignment from int is also explicitly supported
ajp109 5:e96d56fc0884 99 * to allow integer literals to be used without qualification or casting.
ajp109 5:e96d56fc0884 100 * The register value is cached on first read and updated on write, so read
ajp109 9:a96e9bbad3ee 101 * accesses do not use the I<sup>2</sup>C bus.
ajp109 5:e96d56fc0884 102 */
ajp109 0:b07c3d3e3d9c 103 template<class T>
ajp109 0:b07c3d3e3d9c 104 class RWRegister : public Register<T> {
ajp109 1:a74f8c175f6c 105 friend class LSM303D;
ajp109 0:b07c3d3e3d9c 106 using Register<T>::parent_;
ajp109 0:b07c3d3e3d9c 107 using Register<T>::addr_;
ajp109 1:a74f8c175f6c 108 private:
ajp109 0:b07c3d3e3d9c 109 mutable T cache_;
ajp109 0:b07c3d3e3d9c 110 mutable bool cached_;
ajp109 1:a74f8c175f6c 111 protected:
ajp109 0:b07c3d3e3d9c 112 RWRegister(LSM303D &parent, unsigned char addr) :
ajp109 0:b07c3d3e3d9c 113 Register<T>(parent, addr), cached_(false) {}
ajp109 6:7d624356069e 114 /// Explicit write method.
ajp109 6:7d624356069e 115 /// @param data The new value to write to the register.
ajp109 1:a74f8c175f6c 116 void write(T const &data) {
ajp109 0:b07c3d3e3d9c 117 char packet[sizeof(T)+1];
ajp109 0:b07c3d3e3d9c 118 packet[0] = addr_;
ajp109 0:b07c3d3e3d9c 119 memcpy(&packet[1], &data, sizeof(T));
ajp109 1:a74f8c175f6c 120 cache_ = data;
ajp109 1:a74f8c175f6c 121 cached_ = true;
ajp109 1:a74f8c175f6c 122 parent_.i2c_.lock();
ajp109 0:b07c3d3e3d9c 123 parent_.i2c_.write(parent_.addr_8bit_, packet, sizeof(T)+1);
ajp109 1:a74f8c175f6c 124 parent_.i2c_.unlock();
ajp109 0:b07c3d3e3d9c 125 }
ajp109 6:7d624356069e 126 /// Explicit read method with cache.
ajp109 6:7d624356069e 127 /// @return The current value of the register, from cache if available.
ajp109 0:b07c3d3e3d9c 128 virtual T read() const {
ajp109 0:b07c3d3e3d9c 129 if (!cached_) {
ajp109 0:b07c3d3e3d9c 130 cache_ = Register<T>::read();
ajp109 0:b07c3d3e3d9c 131 cached_ = true;
ajp109 0:b07c3d3e3d9c 132 }
ajp109 0:b07c3d3e3d9c 133 return cache_;
ajp109 0:b07c3d3e3d9c 134 }
ajp109 6:7d624356069e 135 /// Equivalent to write().
ajp109 6:7d624356069e 136 /// @param data The new value to write to the register.
ajp109 6:7d624356069e 137 /// @return A reference to this object.
ajp109 1:a74f8c175f6c 138 inline RWRegister & operator= (T const &data) {
ajp109 0:b07c3d3e3d9c 139 write(data);
ajp109 0:b07c3d3e3d9c 140 return *this;
ajp109 0:b07c3d3e3d9c 141 }
ajp109 9:a96e9bbad3ee 142 /// Equivalent to write(), with an explicit int parameter.
ajp109 6:7d624356069e 143 /// @param data The new value to write to the register.
ajp109 6:7d624356069e 144 /// @return A reference to this object.
ajp109 1:a74f8c175f6c 145 inline RWRegister & operator= (int const &data) {
ajp109 1:a74f8c175f6c 146 write(T(data));
ajp109 1:a74f8c175f6c 147 return *this;
ajp109 1:a74f8c175f6c 148 }
ajp109 9:a96e9bbad3ee 149 /// Or-assignment operator.
ajp109 9:a96e9bbad3ee 150 /// @param data The value to OR with the register's existing contents.
ajp109 9:a96e9bbad3ee 151 /// @return A reference to this object.
ajp109 1:a74f8c175f6c 152 inline RWRegister & operator|= (T const &data) {
ajp109 9:a96e9bbad3ee 153 write(read() | data);
ajp109 1:a74f8c175f6c 154 return *this;
ajp109 1:a74f8c175f6c 155 }
ajp109 9:a96e9bbad3ee 156 /// Or-assignment operator, with an explicit int parameter.
ajp109 9:a96e9bbad3ee 157 /// @param data The value to OR with the register's existing contents.
ajp109 9:a96e9bbad3ee 158 /// @return A reference to this object.
ajp109 1:a74f8c175f6c 159 inline RWRegister & operator|= (int const &data) {
ajp109 9:a96e9bbad3ee 160 write(read() | T(data));
ajp109 1:a74f8c175f6c 161 return *this;
ajp109 1:a74f8c175f6c 162 }
ajp109 9:a96e9bbad3ee 163 /// And-assignment operator.
ajp109 9:a96e9bbad3ee 164 /// @param data The value to AND with the register's existing contents.
ajp109 9:a96e9bbad3ee 165 /// @return A reference to this object.
ajp109 1:a74f8c175f6c 166 inline RWRegister & operator&= (T const &data) {
ajp109 9:a96e9bbad3ee 167 write(read() & data);
ajp109 1:a74f8c175f6c 168 return *this;
ajp109 1:a74f8c175f6c 169 }
ajp109 9:a96e9bbad3ee 170 /// And-assignment operator, with an explicit int parameter.
ajp109 9:a96e9bbad3ee 171 /// @param data The value to AND with the register's existing contents.
ajp109 9:a96e9bbad3ee 172 /// @return A reference to this object.
ajp109 1:a74f8c175f6c 173 inline RWRegister & operator&= (int const &data) {
ajp109 9:a96e9bbad3ee 174 write(read() & T(data));
ajp109 0:b07c3d3e3d9c 175 return *this;
ajp109 0:b07c3d3e3d9c 176 }
ajp109 0:b07c3d3e3d9c 177 };
ajp109 0:b07c3d3e3d9c 178
ajp109 6:7d624356069e 179 /** Class representing binary (on/off) options.
ajp109 6:7d624356069e 180 * @tparam T The underlying data type of the register used to set the option.
ajp109 6:7d624356069e 181 * Provides a user-friendly interface onto LSM303D options.
ajp109 6:7d624356069e 182 */
ajp109 1:a74f8c175f6c 183 template <class T>
ajp109 1:a74f8c175f6c 184 class Option {
ajp109 1:a74f8c175f6c 185 friend class LSM303D;
ajp109 1:a74f8c175f6c 186 protected:
ajp109 1:a74f8c175f6c 187 T const bits_;
ajp109 1:a74f8c175f6c 188 RWRegister<T> & reg_;
ajp109 1:a74f8c175f6c 189 Option(RWRegister<T> & reg, int bits) :
ajp109 1:a74f8c175f6c 190 reg_(reg), bits_(T(bits)) {}
ajp109 1:a74f8c175f6c 191 public:
ajp109 6:7d624356069e 192 /// Set the option 'on'.
ajp109 1:a74f8c175f6c 193 inline void operator() () const { reg_ |= bits_; };
ajp109 6:7d624356069e 194 /// Set the option 'on' or 'off'.
ajp109 6:7d624356069e 195 /// @param sr Option status: set to true for 'on', false for 'off'.
ajp109 1:a74f8c175f6c 196 inline void operator() (bool sr) const
ajp109 1:a74f8c175f6c 197 { if (sr) reg_ |= bits_; else reg_ &= ~bits_; };
ajp109 1:a74f8c175f6c 198 };
ajp109 1:a74f8c175f6c 199
ajp109 5:e96d56fc0884 200 const Register <i16_3> OUT_M; ///< Triple magnetometer register
ajp109 5:e96d56fc0884 201 const Register <i16_3> OFFSET_M; ///< Triple magnetometer offset register
ajp109 5:e96d56fc0884 202 const Register <u8_3> REFERENCE; ///< Triple reference register
ajp109 5:e96d56fc0884 203 const Register <i16_3> OUT_A; ///< Triple accelerometer register
ajp109 1:a74f8c175f6c 204
ajp109 0:b07c3d3e3d9c 205 public:
ajp109 3:93343cd8cafe 206 const Register <i16> TEMP_OUT; ///< TEMP_OUT register, read-only
ajp109 3:93343cd8cafe 207 const Register <u8> STATUS_M; ///< STATUS_M register, read-only
ajp109 3:93343cd8cafe 208 const Register <i16> OUT_X_M; ///< OUT_X_M register, read-only
ajp109 3:93343cd8cafe 209 const Register <i16> OUT_Y_M; ///< OUT_Y_M register, read-only
ajp109 3:93343cd8cafe 210 const Register <i16> OUT_Z_M; ///< OUT_Z_M register, read-only
ajp109 3:93343cd8cafe 211 const Register <u8> WHO_AM_I; ///< WHO_AM_I register, read-only
ajp109 3:93343cd8cafe 212 const Register <u8> INT_SRC_M; ///< INT_SRC_M register, read-only
ajp109 3:93343cd8cafe 213 const Register <i16> OFFSET_X_M; ///< OFFSET_X_M register, read-only
ajp109 3:93343cd8cafe 214 const Register <i16> OFFSET_Y_M; ///< OFFSET_Y_M register, read-only
ajp109 3:93343cd8cafe 215 const Register <i16> OFFSET_Z_M; ///< OFFSET_Z_M register, read-only
ajp109 3:93343cd8cafe 216 const Register <u8> STATUS_A; ///< STATUS_A register, read-only
ajp109 3:93343cd8cafe 217 const Register <i16> OUT_X_A; ///< OUT_X_A register, read-only
ajp109 3:93343cd8cafe 218 const Register <i16> OUT_Y_A; ///< OUT_Y_A register, read-only
ajp109 3:93343cd8cafe 219 const Register <i16> OUT_Z_A; ///< OUT_Z_A register, read-only
ajp109 3:93343cd8cafe 220 const Register <u8> FIFO_SRC; ///< FIFO_SRC register, read-only
ajp109 3:93343cd8cafe 221 const Register <u8> IG_SRC1; ///< IG_SRC1 register, read-only
ajp109 3:93343cd8cafe 222 const Register <u8> IG_SRC2; ///< IG_SRC2 register, read-only
ajp109 3:93343cd8cafe 223 const Register <u8> CLICK_SRC; ///< CLICK_SRC register, read-only
ajp109 1:a74f8c175f6c 224
ajp109 3:93343cd8cafe 225 RWRegister <u8> INT_CTRL_M; ///< INT_CTRL_M register, read-write
ajp109 3:93343cd8cafe 226 RWRegister <u16> INT_THS_M; ///< INT_THS_M register, read-write
ajp109 3:93343cd8cafe 227 RWRegister <u8> REFERENCE_X; ///< REFERENCE_X register, read-write
ajp109 3:93343cd8cafe 228 RWRegister <u8> REFERENCE_Y; ///< REFERENCE_Y register, read-write
ajp109 3:93343cd8cafe 229 RWRegister <u8> REFERENCE_Z; ///< REFERENCE_Z register, read-write
ajp109 3:93343cd8cafe 230 RWRegister <u8> CTRL0; ///< CTRL0 register, read-write
ajp109 3:93343cd8cafe 231 RWRegister <u8> CTRL1; ///< CTRL1 register, read-write
ajp109 3:93343cd8cafe 232 RWRegister <u8> CTRL2; ///< CTRL2 register, read-write
ajp109 3:93343cd8cafe 233 RWRegister <u8> CTRL3; ///< CTRL3 register, read-write
ajp109 3:93343cd8cafe 234 RWRegister <u8> CTRL4; ///< CTRL4 register, read-write
ajp109 3:93343cd8cafe 235 RWRegister <u8> CTRL5; ///< CTRL5 register, read-write
ajp109 3:93343cd8cafe 236 RWRegister <u8> CTRL6; ///< CTRL6 register, read-write
ajp109 3:93343cd8cafe 237 RWRegister <u8> CTRL7; ///< CTRL7 register, read-write
ajp109 3:93343cd8cafe 238 RWRegister <u8> FIFO_CTRL; ///< FIFO_CTRL register, read-write
ajp109 3:93343cd8cafe 239 RWRegister <u8> IG_CFG1; ///< IG_CFG1 register, read-write
ajp109 3:93343cd8cafe 240 RWRegister <u8> IG_THS1; ///< IG_THS1 register, read-write
ajp109 3:93343cd8cafe 241 RWRegister <u8> IG_DUR1; ///< IG_DUR1 register, read-write
ajp109 3:93343cd8cafe 242 RWRegister <u8> IG_CFG2; ///< IG_CFG2 register, read-write
ajp109 3:93343cd8cafe 243 RWRegister <u8> IG_THS2; ///< IG_THS2 register, read-write
ajp109 3:93343cd8cafe 244 RWRegister <u8> IG_DUR2; ///< IG_DUR2 register, read-write
ajp109 3:93343cd8cafe 245 RWRegister <u8> CLICK_CFG; ///< CLICK_CFG register, read-write
ajp109 3:93343cd8cafe 246 RWRegister <u8> CLICK_THS; ///< CLICK_THS register, read-write
ajp109 3:93343cd8cafe 247 RWRegister <u8> TIME_LIMIT; ///< TIME_LIMIT register, read-write
ajp109 3:93343cd8cafe 248 RWRegister <u8> TIME_LATENCY;///< TIME_LATENCY register, read-write
ajp109 3:93343cd8cafe 249 RWRegister <u8> TIME_WINDOW; ///< TIME_WINDOW register, read-write
ajp109 3:93343cd8cafe 250 RWRegister <u8> Act_THS; ///< Act_THS register, read-write
ajp109 3:93343cd8cafe 251 RWRegister <u8> Act_DUR; ///< Act_DUR register, read-write
ajp109 1:a74f8c175f6c 252
ajp109 1:a74f8c175f6c 253 // CTRL1
ajp109 3:93343cd8cafe 254 /** AccelRate enum.
ajp109 3:93343cd8cafe 255 * Provides friendly names for the accelerometer update rates
ajp109 3:93343cd8cafe 256 * that are provided by the device.
ajp109 3:93343cd8cafe 257 */
ajp109 1:a74f8c175f6c 258 enum class AccelRate {
ajp109 9:a96e9bbad3ee 259 powerdown = 0x00, ///< power-down mode
ajp109 3:93343cd8cafe 260 rate_3_125Hz = 0x10, ///< 3.125Hz update rate
ajp109 3:93343cd8cafe 261 rate_6_25Hz = 0x20, ///< 6.25Hz update rate
ajp109 3:93343cd8cafe 262 rate_12_5Hz = 0x30, ///< 12.5Hz update rate
ajp109 3:93343cd8cafe 263 rate_25Hz = 0x40, ///< 25Hz update rate
ajp109 3:93343cd8cafe 264 rate_50Hz = 0x50, ///< 50Hz update rate
ajp109 3:93343cd8cafe 265 rate_100Hz = 0x60, ///< 100Hz update rate
ajp109 3:93343cd8cafe 266 rate_200Hz = 0x70, ///< 200Hz update rate
ajp109 3:93343cd8cafe 267 rate_400Hz = 0x80, ///< 400Hz update rate
ajp109 3:93343cd8cafe 268 rate_800Hz = 0x90, ///< 800Hz update rate
ajp109 3:93343cd8cafe 269 rate_1600Hz = 0xA0 ///< 1600Hz update rate
ajp109 1:a74f8c175f6c 270 };
ajp109 3:93343cd8cafe 271 /** Sets the accelerometer update rate.
ajp109 9:a96e9bbad3ee 272 * @param rate The new update rate.
ajp109 3:93343cd8cafe 273 * Available values are:
ajp109 9:a96e9bbad3ee 274 * - AccelRate::powerdown (power-down mode)
ajp109 9:a96e9bbad3ee 275 * - AccelRate::rate_3_125Hz (3.125Hz)
ajp109 9:a96e9bbad3ee 276 * - AccelRate::rate_6_25Hz (6.25Hz)
ajp109 9:a96e9bbad3ee 277 * - AccelRate::rate_12_5Hz (12.5Hz)
ajp109 9:a96e9bbad3ee 278 * - AccelRate::rate_25Hz (25Hz)
ajp109 9:a96e9bbad3ee 279 * - AccelRate::rate_50Hz (50Hz)
ajp109 9:a96e9bbad3ee 280 * - AccelRate::rate_100Hz (100Hz)
ajp109 9:a96e9bbad3ee 281 * - AccelRate::rate_200Hz (200Hz)
ajp109 9:a96e9bbad3ee 282 * - AccelRate::rate_400Hz (400Hz)
ajp109 9:a96e9bbad3ee 283 * - AccelRate::rate_800Hz (800Hz)
ajp109 9:a96e9bbad3ee 284 * - AccelRate::rate_1600Hz (1600Hz)
ajp109 5:e96d56fc0884 285 */
ajp109 1:a74f8c175f6c 286 void setAccelRate(AccelRate const &rate);
ajp109 1:a74f8c175f6c 287
ajp109 5:e96d56fc0884 288
ajp109 9:a96e9bbad3ee 289 const Option<u8> accel_enableX; ///< Enable or disable x-axis accelerometer
ajp109 9:a96e9bbad3ee 290 const Option<u8> accel_enableY; ///< Enable or disable y-axis accelerometer
ajp109 9:a96e9bbad3ee 291 const Option<u8> accel_enableZ; ///< Enable or disable z-axis accelerometer
ajp109 9:a96e9bbad3ee 292 const Option<u8> accel_enableAll; ///< Enable or disable all accelerometers
ajp109 1:a74f8c175f6c 293
ajp109 1:a74f8c175f6c 294 // CTRL2
ajp109 10:392fa35ca17c 295 /** AccelFilter enum.
ajp109 10:392fa35ca17c 296 * Provides friendly names for the accelerometer antialiasing filter
ajp109 10:392fa35ca17c 297 * frequencies that are provided by the device.
ajp109 10:392fa35ca17c 298 */
ajp109 10:392fa35ca17c 299 enum class AccelFilter {
ajp109 10:392fa35ca17c 300 filter_773Hz = 0x00, ///< 773Hz corner frequency
ajp109 10:392fa35ca17c 301 filter_194Hz = 0x40, ///< 194Hz corner frequency
ajp109 10:392fa35ca17c 302 filter_362Hz = 0x80, ///< 362Hz corner frequency
ajp109 10:392fa35ca17c 303 filter_50Hz = 0xC0 ///< 50Hz corner frequency
ajp109 10:392fa35ca17c 304 };
ajp109 10:392fa35ca17c 305 /** Sets the accelerometer antialiasing filter frequency.
ajp109 10:392fa35ca17c 306 * @param freq The new frequency.
ajp109 10:392fa35ca17c 307 * Available values are:
ajp109 10:392fa35ca17c 308 * - AccelFilter::filter_773Hz
ajp109 10:392fa35ca17c 309 * - AccelFilter::filter_194Hz
ajp109 10:392fa35ca17c 310 * - AccelFilter::filter_362Hz
ajp109 10:392fa35ca17c 311 * - AccelFilter::filter_50Hz
ajp109 10:392fa35ca17c 312 */
ajp109 10:392fa35ca17c 313 void setAccelFilterFreq(AccelFilter const &freq);
ajp109 9:a96e9bbad3ee 314 /** AccelScale enum.
ajp109 9:a96e9bbad3ee 315 * Provides friendly names for the accelerometer scale ranges
ajp109 9:a96e9bbad3ee 316 * that are provided by the device.
ajp109 9:a96e9bbad3ee 317 */
ajp109 1:a74f8c175f6c 318 enum class AccelScale {
ajp109 9:a96e9bbad3ee 319 scale_2g = 0x00, ///< +-2g full scale
ajp109 9:a96e9bbad3ee 320 scale_4g = 0x08, ///< +-4g full scale
ajp109 9:a96e9bbad3ee 321 scale_6g = 0x10, ///< +-6g full scale
ajp109 9:a96e9bbad3ee 322 scale_8g = 0x18, ///< +-8g full scale
ajp109 9:a96e9bbad3ee 323 scale_16g = 0x20 ///< +-16g full scale
ajp109 1:a74f8c175f6c 324 };
ajp109 9:a96e9bbad3ee 325 /** Sets the accelerometer scale range.
ajp109 9:a96e9bbad3ee 326 * @param scale The new scale.
ajp109 9:a96e9bbad3ee 327 * Available values are:
ajp109 9:a96e9bbad3ee 328 * - AccelScale::scale_2g (+-2g)
ajp109 9:a96e9bbad3ee 329 * - AccelScale::scale_4g (+-4g)
ajp109 9:a96e9bbad3ee 330 * - AccelScale::scale_6g (+-6g)
ajp109 9:a96e9bbad3ee 331 * - AccelScale::scale_8g (+-8g)
ajp109 9:a96e9bbad3ee 332 * - AccelScale::scale_16g (+-16g)
ajp109 9:a96e9bbad3ee 333 */
ajp109 1:a74f8c175f6c 334 void setAccelScale(AccelScale const &scale);
ajp109 1:a74f8c175f6c 335
ajp109 1:a74f8c175f6c 336 // CTRL3
ajp109 9:a96e9bbad3ee 337 const Option<u8> INT1_enable_BOOT; ///< Enable or disable "boot" source for INT1
ajp109 9:a96e9bbad3ee 338 const Option<u8> INT1_enable_CLICK; ///< Enable or disable "click" source for INT1
ajp109 9:a96e9bbad3ee 339 const Option<u8> INT1_enable_IG1; ///< Enable or disable "inertial 1" source for INT1
ajp109 9:a96e9bbad3ee 340 const Option<u8> INT1_enable_IG2; ///< Enable or disable "inertial 2" source for INT1
ajp109 9:a96e9bbad3ee 341 const Option<u8> INT1_enable_IGM; ///< Enable or disable "magnetic" source for INT1
ajp109 9:a96e9bbad3ee 342 const Option<u8> INT1_enable_DRDY_A;///< Enable or disable "accelerometer data ready" source for INT1
ajp109 9:a96e9bbad3ee 343 const Option<u8> INT1_enable_DRDY_M;///< Enable or disable "magnetometer data ready" source for INT1
ajp109 9:a96e9bbad3ee 344 const Option<u8> INT1_enable_EMPTY; ///< Enable or disable "FIFO empty" source for INT1
ajp109 1:a74f8c175f6c 345
ajp109 1:a74f8c175f6c 346 // CTRL4 concerns INT2 which is not broken out on the Pimoroni board
ajp109 1:a74f8c175f6c 347
ajp109 1:a74f8c175f6c 348 // CTRL5
ajp109 9:a96e9bbad3ee 349 const Option<u8> temp_enable; ///< Enable or disable temperature sensor
ajp109 9:a96e9bbad3ee 350 const Option<u8> LIR1_enable; ///< Enable or disable latching interrupt requests for INT1
ajp109 1:a74f8c175f6c 351
ajp109 9:a96e9bbad3ee 352 /** MagRes enum.
ajp109 9:a96e9bbad3ee 353 * Provides friendly names for the magnetometer resolution options
ajp109 9:a96e9bbad3ee 354 * that are provided by the device.
ajp109 9:a96e9bbad3ee 355 */
ajp109 1:a74f8c175f6c 356 enum class MagRes {
ajp109 9:a96e9bbad3ee 357 high = 0x60, ///< High resolution
ajp109 9:a96e9bbad3ee 358 low = 0x00, ///< Low resolution
ajp109 1:a74f8c175f6c 359 };
ajp109 9:a96e9bbad3ee 360 /** Sets the magnetometer resolution.
ajp109 9:a96e9bbad3ee 361 * @param res The new resolution.
ajp109 9:a96e9bbad3ee 362 * Available values are:
ajp109 9:a96e9bbad3ee 363 * - MagRes::high (high resolution)
ajp109 9:a96e9bbad3ee 364 * - MagRes::low (low resolution)
ajp109 9:a96e9bbad3ee 365 */
ajp109 1:a74f8c175f6c 366 void setMagRes(MagRes const &res);
ajp109 1:a74f8c175f6c 367
ajp109 9:a96e9bbad3ee 368 /** MagRate enum.
ajp109 9:a96e9bbad3ee 369 * Provides friendly names for the magnetometer update rates
ajp109 9:a96e9bbad3ee 370 * that are provided by the device.
ajp109 9:a96e9bbad3ee 371 */
ajp109 1:a74f8c175f6c 372 enum class MagRate {
ajp109 9:a96e9bbad3ee 373 rate_3_125Hz = 0x00, ///< 3.125Hz update rate
ajp109 9:a96e9bbad3ee 374 rate_6_25Hz = 0x04, ///< 6.25Hz update rate
ajp109 9:a96e9bbad3ee 375 rate_12_5Hz = 0x08, ///< 12.5Hz update rate
ajp109 9:a96e9bbad3ee 376 rate_25Hz = 0x0C, ///< 25Hz update rate
ajp109 9:a96e9bbad3ee 377 rate_50Hz = 0x10, ///< 50Hz update rate
ajp109 9:a96e9bbad3ee 378 rate_100Hz = 0x14 ///< 100Hz update rate
ajp109 9:a96e9bbad3ee 379 };
ajp109 9:a96e9bbad3ee 380 /** Sets the magnetometer update rate.
ajp109 9:a96e9bbad3ee 381 * @param rate The new update rate.
ajp109 9:a96e9bbad3ee 382 * Available values are:
ajp109 9:a96e9bbad3ee 383 * - MagRate::rate_3_125Hz (3.125Hz)
ajp109 9:a96e9bbad3ee 384 * - MagRate::rate_6_25Hz (6.25Hz)
ajp109 9:a96e9bbad3ee 385 * - MagRate::rate_12_5Hz (12.5Hz)
ajp109 9:a96e9bbad3ee 386 * - MagRate::rate_25Hz (25Hz)
ajp109 9:a96e9bbad3ee 387 * - MagRate::rate_50Hz (50Hz)
ajp109 9:a96e9bbad3ee 388 * - MagRate::rate_100Hz (100Hz)
ajp109 9:a96e9bbad3ee 389 * Note that the 100Hz update rate is available only if the accelerometer
ajp109 9:a96e9bbad3ee 390 * update rate is set to 50Hz or higher or the accelerometer is set to
ajp109 9:a96e9bbad3ee 391 * power-down mode (see setAccelRate()). Failing to meet these conditions
ajp109 9:a96e9bbad3ee 392 * will lead to undefined behaviour.
ajp109 9:a96e9bbad3ee 393 */
ajp109 1:a74f8c175f6c 394 void setMagRate(MagRate const &rate);
ajp109 1:a74f8c175f6c 395
ajp109 1:a74f8c175f6c 396 // CTRL6
ajp109 9:a96e9bbad3ee 397 /** MagScale enum.
ajp109 9:a96e9bbad3ee 398 * Provides friendly names for the magnetometer scale ranges
ajp109 9:a96e9bbad3ee 399 * that are provided by the device.
ajp109 9:a96e9bbad3ee 400 */
ajp109 1:a74f8c175f6c 401 enum class MagScale {
ajp109 9:a96e9bbad3ee 402 scale_2G = 0x00, ///< +-2 Gauss
ajp109 9:a96e9bbad3ee 403 scale_4G = 0x20, ///< +-4 Gauss
ajp109 9:a96e9bbad3ee 404 scale_8G = 0x40, ///< +-8 Gauss
ajp109 9:a96e9bbad3ee 405 scale_12G = 0x60 ///< +-12 Gauss
ajp109 1:a74f8c175f6c 406 };
ajp109 9:a96e9bbad3ee 407 /** Sets the magnetometer scale range.
ajp109 9:a96e9bbad3ee 408 * @param scale The new scale.
ajp109 9:a96e9bbad3ee 409 * Available values are:
ajp109 9:a96e9bbad3ee 410 * - MagScale::scale_2G (+-2 Gauss)
ajp109 9:a96e9bbad3ee 411 * - MagScale::scale_4G (+-4 Gauss)
ajp109 9:a96e9bbad3ee 412 * - MagScale::scale_8G (+-8 Gauss)
ajp109 9:a96e9bbad3ee 413 * - MagScale::scale_12G (+-16 Gauss)
ajp109 9:a96e9bbad3ee 414 */
ajp109 1:a74f8c175f6c 415 void setMagScale(MagScale const &scale);
ajp109 1:a74f8c175f6c 416
ajp109 1:a74f8c175f6c 417 // CTRL7
ajp109 9:a96e9bbad3ee 418 /** MagScale enum.
ajp109 9:a96e9bbad3ee 419 * Provides friendly names for the magnetometer modes that are supported
ajp109 9:a96e9bbad3ee 420 * by the device.
ajp109 9:a96e9bbad3ee 421 */
ajp109 1:a74f8c175f6c 422 enum class MagMode {
ajp109 9:a96e9bbad3ee 423 continuous = 0x00, ///< Continous conversion mode
ajp109 9:a96e9bbad3ee 424 single = 0x01, ///< Single conversion mode
ajp109 9:a96e9bbad3ee 425 powerdown = 0x02 ///< Magnetometer power-down mode
ajp109 1:a74f8c175f6c 426 };
ajp109 9:a96e9bbad3ee 427 /** Sets the magnetometer mode.
ajp109 9:a96e9bbad3ee 428 * @param mode The new mode.
ajp109 9:a96e9bbad3ee 429 * Available values are:
ajp109 9:a96e9bbad3ee 430 * - MagMode::continuous (continuous conversion mode)
ajp109 9:a96e9bbad3ee 431 * - MagMode::single (single-conversion mode)
ajp109 9:a96e9bbad3ee 432 * - MagMode::powerdown (power-down mode)
ajp109 9:a96e9bbad3ee 433 */
ajp109 1:a74f8c175f6c 434 void setMagMode(MagMode const &mode);
ajp109 0:b07c3d3e3d9c 435
ajp109 9:a96e9bbad3ee 436 /** Constructor.
ajp109 9:a96e9bbad3ee 437 * @param sda The pin to use for the I^^2^^C SDA signal.
ajp109 9:a96e9bbad3ee 438 * @param scl The pin to use for the I^^2^^C SCL signal.
ajp109 9:a96e9bbad3ee 439 * @param i2c_addr The 7-bit I<sup>2</sup>C address. Defaults to 0x1D, but
ajp109 9:a96e9bbad3ee 440 * this can be overridden to 0x1E with a jumper setting on the device allowing
ajp109 9:a96e9bbad3ee 441 * two LSM303D devices to coexist on a bus.
ajp109 9:a96e9bbad3ee 442 */
ajp109 0:b07c3d3e3d9c 443 LSM303D(PinName sda, PinName scl, unsigned char i2c_addr = 0x1D);
ajp109 0:b07c3d3e3d9c 444
ajp109 9:a96e9bbad3ee 445 /** Gets the raw (signed 16-bit integer) X-axis acceleration value.
ajp109 9:a96e9bbad3ee 446 * @return The raw acceleration value.
ajp109 9:a96e9bbad3ee 447 */
ajp109 1:a74f8c175f6c 448 inline i16 getRawAccelX() { return OUT_X_A; };
ajp109 9:a96e9bbad3ee 449 /** Gets the raw (signed 16-bit integer) Y-axis acceleration value.
ajp109 9:a96e9bbad3ee 450 * @return The raw acceleration value.
ajp109 9:a96e9bbad3ee 451 */
ajp109 1:a74f8c175f6c 452 inline i16 getRawAccelY() { return OUT_Y_A; };
ajp109 9:a96e9bbad3ee 453 /** Gets the raw (signed 16-bit integer) Z-axis acceleration value.
ajp109 9:a96e9bbad3ee 454 * @return The raw acceleration value.
ajp109 9:a96e9bbad3ee 455 */
ajp109 1:a74f8c175f6c 456 inline i16 getRawAccelZ() { return OUT_Z_A; };
ajp109 9:a96e9bbad3ee 457 /** Gets the scaled (float) X-axis acceleration value in g.
ajp109 9:a96e9bbad3ee 458 * @return The scaled acceleration value in g.
ajp109 9:a96e9bbad3ee 459 */
ajp109 1:a74f8c175f6c 460 inline float getAccelX() { return (float)OUT_X_A / accel_scale_ / 32768; };
ajp109 9:a96e9bbad3ee 461 /** Gets the scaled (float) Y-axis acceleration value in g.
ajp109 9:a96e9bbad3ee 462 * @return The scaled acceleration value in g.
ajp109 9:a96e9bbad3ee 463 */
ajp109 1:a74f8c175f6c 464 inline float getAccelY() { return (float)OUT_Y_A / accel_scale_ / 32768; };
ajp109 9:a96e9bbad3ee 465 /** Gets the scaled (float) Z-axis acceleration value in g.
ajp109 9:a96e9bbad3ee 466 * @return The scaled acceleration value in g.
ajp109 9:a96e9bbad3ee 467 */
ajp109 1:a74f8c175f6c 468 inline float getAccelZ() { return (float)OUT_Z_A / accel_scale_ / 32768; };
ajp109 9:a96e9bbad3ee 469 /** Reads the raw (signed 16-bit integer) acceleration values into the three
ajp109 9:a96e9bbad3ee 470 * axis value containers provided.
ajp109 9:a96e9bbad3ee 471 * @param x Container for the X value.
ajp109 9:a96e9bbad3ee 472 * @param y Container for the Y value.
ajp109 9:a96e9bbad3ee 473 * @param z Container for the Z value.
ajp109 9:a96e9bbad3ee 474 */
ajp109 0:b07c3d3e3d9c 475 void getRawAccelInto(short &x, short &y, short &z);
ajp109 9:a96e9bbad3ee 476 /** Reads the scaled (float) acceleration values in g into the three
ajp109 9:a96e9bbad3ee 477 * axis value containers provided.
ajp109 9:a96e9bbad3ee 478 * @param x Container for the X value.
ajp109 9:a96e9bbad3ee 479 * @param y Container for the Y value.
ajp109 9:a96e9bbad3ee 480 * @param z Container for the Z value.
ajp109 9:a96e9bbad3ee 481 */
ajp109 0:b07c3d3e3d9c 482 void getAccelInto(float &x, float &y, float &z);
ajp109 0:b07c3d3e3d9c 483
ajp109 9:a96e9bbad3ee 484 /** Gets the raw (signed 16-bit integer) X-axis magnetometer value.
ajp109 9:a96e9bbad3ee 485 * @return The raw magnetometer value.
ajp109 9:a96e9bbad3ee 486 */
ajp109 1:a74f8c175f6c 487 inline i16 getRawMagX() { return OUT_X_M; };
ajp109 9:a96e9bbad3ee 488 /** Gets the raw (signed 16-bit integer) Y-axis magnetometer value.
ajp109 9:a96e9bbad3ee 489 * @return The raw magnetometer value.
ajp109 9:a96e9bbad3ee 490 */
ajp109 1:a74f8c175f6c 491 inline i16 getRawMagY() { return OUT_Y_M; };
ajp109 9:a96e9bbad3ee 492 /** Gets the raw (signed 16-bit integer) Z-axis magnetometer value.
ajp109 9:a96e9bbad3ee 493 * @return The raw magnetometer value.
ajp109 9:a96e9bbad3ee 494 */
ajp109 1:a74f8c175f6c 495 inline i16 getRawMagZ() { return OUT_Z_M; };
ajp109 9:a96e9bbad3ee 496 /** Gets the scaled (float) X-axis magnetometer value in Gauss.
ajp109 9:a96e9bbad3ee 497 * @return The scaled magnetometer value in Gauss.
ajp109 9:a96e9bbad3ee 498 */
ajp109 1:a74f8c175f6c 499 inline float getMagX() { return (float)OUT_X_M / mag_scale_ / 32768; };
ajp109 9:a96e9bbad3ee 500 /** Gets the scaled (float) Y-axis magnetometer value in Gauss.
ajp109 9:a96e9bbad3ee 501 * @return The scaled magnetometer value in Gauss.
ajp109 9:a96e9bbad3ee 502 */
ajp109 1:a74f8c175f6c 503 inline float getMagY() { return (float)OUT_Y_M / mag_scale_ / 32768; };
ajp109 9:a96e9bbad3ee 504 /** Gets the scaled (float) Z-axis magnetometer value in Gauss.
ajp109 9:a96e9bbad3ee 505 * @return The scaled magnetometer value in Gauss.
ajp109 9:a96e9bbad3ee 506 */
ajp109 1:a74f8c175f6c 507 inline float getMagZ() { return (float)OUT_Z_M / mag_scale_ / 32768; };
ajp109 9:a96e9bbad3ee 508 /** Reads the raw (signed 16-bit integer) magnetometer values into the three
ajp109 9:a96e9bbad3ee 509 * axis value containers provided.
ajp109 9:a96e9bbad3ee 510 * @param x Container for the X value.
ajp109 9:a96e9bbad3ee 511 * @param y Container for the Y value.
ajp109 9:a96e9bbad3ee 512 * @param z Container for the Z value.
ajp109 9:a96e9bbad3ee 513 */
ajp109 0:b07c3d3e3d9c 514 void getRawMagInto(short &x, short &y, short &z);
ajp109 9:a96e9bbad3ee 515 /** Reads the scaled (float) magnetometer values in Gauss into the three
ajp109 9:a96e9bbad3ee 516 * axis value containers provided.
ajp109 9:a96e9bbad3ee 517 * @param x Container for the X value.
ajp109 9:a96e9bbad3ee 518 * @param y Container for the Y value.
ajp109 9:a96e9bbad3ee 519 * @param z Container for the Z value.
ajp109 9:a96e9bbad3ee 520 */
ajp109 0:b07c3d3e3d9c 521 void getMagInto(float &x, float &y, float &z);
ajp109 0:b07c3d3e3d9c 522
ajp109 9:a96e9bbad3ee 523 /** Reads the scaled (float) temperature values in &deg; C.
ajp109 9:a96e9bbad3ee 524 * @return The current temperature.
ajp109 9:a96e9bbad3ee 525 * Note that testing suggests this to be an inaccurate temperature sensor!
ajp109 9:a96e9bbad3ee 526 * To read the raw temperature value, simply use the TEMP_OUT register directly.
ajp109 9:a96e9bbad3ee 527 */
ajp109 1:a74f8c175f6c 528 inline float getTemp() { return TEMP_OUT / 8.0 + 25; };
ajp109 0:b07c3d3e3d9c 529
ajp109 0:b07c3d3e3d9c 530 };