LSM303DLHC Full Driver: Readings For Acc, Mag and Temp; Class Method for frequently-used 13 sensor parameters; Class Method to direct modify registers; Support Calibration (offset+scale);
Diff: LSM303DLHC.h
- Revision:
- 0:7864abfabe2f
- Child:
- 1:e68ce5025dad
diff -r 000000000000 -r 7864abfabe2f LSM303DLHC.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LSM303DLHC.h Mon Jun 06 07:40:45 2016 +0000 @@ -0,0 +1,182 @@ +#ifndef LSM303DLHC_H +#define LSM303DLHC_H +#include "mbed.h" +// ACC SAD +#define ACC_ADDRESS 0x32 +// ACC CTRL SUB +#define CTRL_REG1_A 0x20 //RW ODR(4) LPen Zen Yen Xen +#define CTRL_REG2_A 0x21 //RW HPM(2) HPCF(2) FDS HPCLICK HPIS2 HPIS1 +#define CTRL_REG3_A 0x22 //RW I1_CLICK I1_AOI1 I1_AOI2 I1_DRDY1 I1_DRDY2 I1_WTM I1_OVERRUN - +#define CTRL_REG4_A 0x23 //RW BDU BLE FS1 FS0 HR 0(2) SIM +#define CTRL_REG5_A 0x24 //RW BOOT FIFO_EN - - LIR_INT1 D4D_INT1 LIR_INT2 D4D_INT2 +#define CTRL_REG6_A 0x25 //RW I2_CLICKen I2_INT1 I2_INT2 BOOT_I1 P2_ACT - H_LACTIVE - +#define REFERENCE_A 0x26 //RW Ref7 Ref6 Ref5 Ref4 Ref3 Ref2 Ref1 Ref0 +#define STATUS_REG_A 0x27 //R ZYXOR ZOR YOR XOR ZYXDA ZDA YDA XDA +// ACC OUT SUB +#define OUT_X_L_A 0x28 //R MSB(8) +#define OUT_X_H_A 0x29 //R LSB(4) 0(4) +#define OUT_Y_L_A 0x2A //R ditto +#define OUT_Y_H_A 0x2B //R ditto +#define OUT_Z_L_A 0x2C //R ditto +#define OUT_Z_H_A 0x2D //R ditto +// ACC INT SUB +#define INT1_CFG_A 0x30 +#define INT1_SRC_A 0x31 +#define INT1_THS_A 0x32 +#define INT1_DURATION_A 0x33 +#define INT2_CFG_A 0x34 +#define INT2_SRC_A 0x35 +#define INT2_THS_A 0x36 +#define INT2_DURATION_A 0x37 +// ACC CLICK SUB +#define CLICK_CFG_A 0x38 +#define CLICK_SRC_A 0x39 +#define CLICK_THS_A 0x3A +#define TIME_LIMIT_A 0x3B +#define TIME_LATENCY_A 0x3C +#define TIME_WINDOW_A 0x3D + +// MAG SAD +#define MAG_ADDRESS 0x3C +// MAG CTRL SUB +#define CRA_REG_M 0x00 //RW TEMP_EN 0(2) DR(3) 0(2) +#define CRB_REG_M 0x01 //RW GN(3) 0(5) +#define MR_REG_M 0x02 //RW 0(6) MD(2) +// MAG OUT SUB +#define OUT_X_H_M 0x03 //R LSB(8) +#define OUT_X_L_M 0x04 //R 0(4) MSB(4) +#define OUT_Z_H_M 0x05 //R ditto +#define OUT_Z_L_M 0x06 //R ditto +#define OUT_Y_H_M 0x07 //R ditto +#define OUT_Y_L_M 0x08 //R ditto +#define SR_REG_M 0x09 //R -(6) LOCK DRDY +#define IRA_REG_M 0x0A //R +#define IRB_REG_M 0x0B //R +#define IRC_REG_M 0x0C //R +// Temprature OUT SUB +#define TEMP_OUT_H_M 0x31 //R MSB(8) +#define TEMP_OUT_L_M 0x32 //R LSB(4) 0(4) + +class LSM303DLHC { + public: + //// PORT + LSM303DLHC(PinName sda, PinName scl); + + //// REG CTRL + // modify the default in LSM303DLHC.cpp + + //// CTRL_REG1_A (20h) + // ACC Low Power Mode ON/OFF + enum ACC_LPen { LP_OFF = 0, LP_ON = 1} ; + void ACtrl(ACC_LPen cmd); + // ACC Data Rate NOTE: ACC SWITCH IS HERE + enum ACC_ODR { PW_D = 0, ODR1 = 1, ODR2 = 2, ODR3 = 3, ODR4 = 4, + // PW Down 1Hz 10Hz 25Hz 50Hz + ODR5 = 5, ODR6 = 6, ODR7 = 7, ODR8 = 8, ODR9 = 9}; + // 100Hz 200Hz 400Hz 1620Hz@LP 1344Hz@NM/5376HZ@LP + void ACtrl(ACC_ODR cmd); + + //// CTRL_REG2_A (21h) + // ACC HPF Mode + enum ACC_HPM { HPF_NORM_R = 0, HPF_REF = 1, HPF_NORM = 2, HPF_AUTO = 3 }; + void ACtrl(ACC_HPM cmd); + // ACC HPF Cutoff Freq + enum ACC_HPCF { HPF_CF0 = 0, HPF_CF1 = 1, HPF_CF2 = 2, HPF_CF3 = 3}; + void ACtrl(ACC_HPCF cmd); + // ACC HPF ON/OFF for output + enum ACC_FDS { HPF_OFF = 0, HPF_ON = 1 }; + void ACtrl(ACC_FDS cmd); + + //// CTRL_REG4_A (23h) + // ACC Block Date Update Mode + enum ACC_BDU { BDU_CONT = 0, BDU_HOLD = 1 }; + void ACtrl(ACC_BDU cmd); + // ACC Output Full-Scale SEL + enum ACC_FS {G2 = 0b00, G4 = 0b01, G8 = 0b10, G16= 0b11 }; + // +/-2g +/-4g +/-8g +/-16g + void ACtrl(ACC_FS cmd); + // ACC Output in High/Low Resolution (Precision SEL) + enum ACC_HR { LOW_R = 0, HIGH_R = 1 }; + // 10bit 12bit + void ACtrl(ACC_HR cmd); + + //// CRA_REG_M (00h) + // TEMP Sensor En NOTE: TEMP SWITCH IS HERE + enum TEMP_EN { TEMP_OFF = 0, TEMP_ON = 1}; + void TCtrl(TEMP_EN cmd); + // MAG Data Rate (Note: MAG_DR determines DRDY pin) + enum MAG_DR { DR0 = 0, DR1 = 1, DR2 = 2, DR3 = 3, + // 0.75Hz 1.5Hz 3Hz 7.5Hz + DR4 = 4, DR5 = 5, DR6 = 6, DR7 = 7}; + // 15Hz 30Hz 75Hz 220Hz + void MCtrl(MAG_DR cmd); // MAG Date Rate + + //// CRB_REG_M (01h) + // MAG Gain (Range SEL) + enum MAG_GN { GN1 = 1, GN2 = 2, GN3 = 3, GN4 = 4, + // 1.3 1.9 2.5 4.0 (+/- Gauss) + GN5 = 5, GN6 = 6, GN7 = 7}; + // 4.7 5.6 8.1 (+/- Gauss) + void MCtrl(MAG_GN cmd); // MAG Measure Range + + //// MR_REG_M (02h) + // MAG Mode NOTE: MAG SWITCH IS HERE + enum MAG_MD { MD_CONT = 0, MD_SING = 1, MD_SLP = 2, MD_SLP2 = 3}; + // Continuous single-conv sleep-mode sleep-mode + void MCtrl(MAG_MD cmd); + + //// Change more regs + void WriteReg(int sad, char d[2]); // Write value to reg + // CAUTION: THE FUNTION USES UNFRIENDLY ASSIGN + // CAUTION: WRITING TO RESERVED REG MAY CAUSE PERMANENT DAMAGE + // PLEASE FOLLOW DATASHEET RIGIDLY + // sad = ACC_ADDRESS or MAG_ADDRESS + // d[0] = Register Address + // d[1] = Register Value + + //// Get Data + void GetAcc(float arr[3]); // Get acceleration using current HPF setting + // range -2048 ~ +2047 + void GetMag(float arr[3]); // Get magnetic flux density + // range -2048 to 2047 + void GetTemp(float arr[1]); // Get temperature + // range -2048 to 2047 + + //// sensor reading calibration + void AccCal(float offset[3], float scale[3]); // Acc Calibration + // affect the reading by output = scale * ( offset + original ) + // but if internal HPF enable then output = scale * original + void MagCal(float offset[3], float scale[3]); // Mag Calibration + // affect the reading by output = scale * ( offset + original ) + void TempCal(float offset[1], float scale[1]); // Mag Calibration + // affect the reading by output = scale * ( offset + original ) + + //// Other functions + bool isHPFEn(); // report HPF ON/OFF state for output + // return HPF_state + + //// Not implemented function + bool isAccRdy(); // Check if acc has new data + // one way is to use high freq ticker to check STATUS_REG_A (27h) + // I2C@400kHz just enough to check Max Normal Mode Data Rate (1344Hz) + bool isMagRdy(); // check if mag has new data + // one way is to use InterruptIn to trigger from DRDY pin + // DRDY pin freq defined by MAG_DR + + private: + I2C i2c; + char data[6]; // used as main data exchange + bool HPF_state; // state of internal HPF + + // use offset to calibrate zero reading + float acc_offset[3]; + float mag_offset[3]; + float temp_offset[1]; + + //use scale to adjust the range to required + float acc_scale[3]; + float mag_scale[3]; + float temp_scale[1]; +}; + +#endif \ No newline at end of file