A library to interface with the LSM9DS1 IMU using SPI

Dependents:   LSM9DS1

Committer:
Anaesthetix
Date:
Wed Oct 18 09:22:00 2017 +0000
Revision:
0:dc98084cf6be
LSM9DS1 spi library

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Anaesthetix 0:dc98084cf6be 1 // Written by: Erik van de Coevering
Anaesthetix 0:dc98084cf6be 2
Anaesthetix 0:dc98084cf6be 3 #include "mbed.h"
Anaesthetix 0:dc98084cf6be 4 #include "LSM9DS1_SPI.h"
Anaesthetix 0:dc98084cf6be 5 #include "LSM9DS1_SPI_Registers.h"
Anaesthetix 0:dc98084cf6be 6
Anaesthetix 0:dc98084cf6be 7 lsm9ds1_spi::lsm9ds1_spi(SPI& _spi, PinName _csAG, PinName _csM) : spi(_spi), csAG(_csAG), csM(_csM) {}
Anaesthetix 0:dc98084cf6be 8
Anaesthetix 0:dc98084cf6be 9 unsigned int lsm9ds1_spi::WriteRegAG( uint8_t WriteAddr, uint8_t WriteData)
Anaesthetix 0:dc98084cf6be 10 {
Anaesthetix 0:dc98084cf6be 11 unsigned int temp_val;
Anaesthetix 0:dc98084cf6be 12 selectAG();
Anaesthetix 0:dc98084cf6be 13 spi.write(WriteAddr);
Anaesthetix 0:dc98084cf6be 14 temp_val=spi.write(WriteData);
Anaesthetix 0:dc98084cf6be 15 deselectAG();
Anaesthetix 0:dc98084cf6be 16 wait_us(5);
Anaesthetix 0:dc98084cf6be 17 return temp_val;
Anaesthetix 0:dc98084cf6be 18 }
Anaesthetix 0:dc98084cf6be 19
Anaesthetix 0:dc98084cf6be 20 unsigned int lsm9ds1_spi::WriteRegM( uint8_t WriteAddr, uint8_t WriteData)
Anaesthetix 0:dc98084cf6be 21 {
Anaesthetix 0:dc98084cf6be 22 unsigned int temp_val;
Anaesthetix 0:dc98084cf6be 23 selectM();
Anaesthetix 0:dc98084cf6be 24 spi.write(WriteAddr);
Anaesthetix 0:dc98084cf6be 25 temp_val=spi.write(WriteData);
Anaesthetix 0:dc98084cf6be 26 deselectM();
Anaesthetix 0:dc98084cf6be 27 wait_us(5);
Anaesthetix 0:dc98084cf6be 28 return temp_val;
Anaesthetix 0:dc98084cf6be 29 }
Anaesthetix 0:dc98084cf6be 30
Anaesthetix 0:dc98084cf6be 31 unsigned int lsm9ds1_spi::ReadRegAG( uint8_t WriteAddr, uint8_t WriteData)
Anaesthetix 0:dc98084cf6be 32 {
Anaesthetix 0:dc98084cf6be 33 return WriteRegAG(WriteAddr | READ_FLAG, WriteData);
Anaesthetix 0:dc98084cf6be 34 }
Anaesthetix 0:dc98084cf6be 35
Anaesthetix 0:dc98084cf6be 36 unsigned int lsm9ds1_spi::ReadRegM( uint8_t WriteAddr, uint8_t WriteData)
Anaesthetix 0:dc98084cf6be 37 {
Anaesthetix 0:dc98084cf6be 38 return WriteRegM(WriteAddr | READ_FLAG, WriteData);
Anaesthetix 0:dc98084cf6be 39 }
Anaesthetix 0:dc98084cf6be 40
Anaesthetix 0:dc98084cf6be 41 void lsm9ds1_spi::ReadRegsAG( uint8_t ReadAddr, uint8_t *ReadBuf, unsigned int Bytes )
Anaesthetix 0:dc98084cf6be 42 {
Anaesthetix 0:dc98084cf6be 43 unsigned int i = 0;
Anaesthetix 0:dc98084cf6be 44
Anaesthetix 0:dc98084cf6be 45 selectAG();
Anaesthetix 0:dc98084cf6be 46 spi.write(ReadAddr | READ_FLAG);
Anaesthetix 0:dc98084cf6be 47 for(i=0; i<Bytes; i++)
Anaesthetix 0:dc98084cf6be 48 ReadBuf[i] = spi.write(0x00);
Anaesthetix 0:dc98084cf6be 49 deselectAG();
Anaesthetix 0:dc98084cf6be 50 //wait_us(50);
Anaesthetix 0:dc98084cf6be 51 }
Anaesthetix 0:dc98084cf6be 52
Anaesthetix 0:dc98084cf6be 53 void lsm9ds1_spi::ReadRegsM( uint8_t ReadAddr, uint8_t *ReadBuf, unsigned int Bytes )
Anaesthetix 0:dc98084cf6be 54 {
Anaesthetix 0:dc98084cf6be 55 unsigned int i = 0;
Anaesthetix 0:dc98084cf6be 56
Anaesthetix 0:dc98084cf6be 57 selectM();
Anaesthetix 0:dc98084cf6be 58 spi.write(ReadAddr | READ_FLAG);
Anaesthetix 0:dc98084cf6be 59 for(i=0; i<Bytes; i++)
Anaesthetix 0:dc98084cf6be 60 ReadBuf[i] = spi.write(0x00);
Anaesthetix 0:dc98084cf6be 61 deselectM();
Anaesthetix 0:dc98084cf6be 62 }
Anaesthetix 0:dc98084cf6be 63
Anaesthetix 0:dc98084cf6be 64 #define LSM_InitRegNumAG 10
Anaesthetix 0:dc98084cf6be 65 #define LSM_InitRegNumM 6
Anaesthetix 0:dc98084cf6be 66
Anaesthetix 0:dc98084cf6be 67 /*--------------------------------------INIT-----------------------------------------------
Anaesthetix 0:dc98084cf6be 68 Possible values for BW / FS / ODR:
Anaesthetix 0:dc98084cf6be 69
Anaesthetix 0:dc98084cf6be 70 Gyroscope full-scale setting:
Anaesthetix 0:dc98084cf6be 71 FS_G_245DPS
Anaesthetix 0:dc98084cf6be 72 FS_G_500DPS
Anaesthetix 0:dc98084cf6be 73 FS_G_2000DPS
Anaesthetix 0:dc98084cf6be 74
Anaesthetix 0:dc98084cf6be 75 Gyroscope output data rate setting:
Anaesthetix 0:dc98084cf6be 76 ODR_G_15HZ
Anaesthetix 0:dc98084cf6be 77 ODR_G_60HZ
Anaesthetix 0:dc98084cf6be 78 ODR_G_119HZ
Anaesthetix 0:dc98084cf6be 79 ODR_G_238HZ
Anaesthetix 0:dc98084cf6be 80 ODR_G_476HZ
Anaesthetix 0:dc98084cf6be 81 ODR_G_952HZ
Anaesthetix 0:dc98084cf6be 82
Anaesthetix 0:dc98084cf6be 83 Gyro bandwidth dependant on ODR, these freq's are correct for ODR=476Hz or 952Hz. Check datasheet for other ODR's
Anaesthetix 0:dc98084cf6be 84 BW_G_33HZ
Anaesthetix 0:dc98084cf6be 85 BW_G_40HZ
Anaesthetix 0:dc98084cf6be 86 BW_G_58HZ
Anaesthetix 0:dc98084cf6be 87 BW_G_100HZ
Anaesthetix 0:dc98084cf6be 88
Anaesthetix 0:dc98084cf6be 89 Accelerometer full-scale setting:
Anaesthetix 0:dc98084cf6be 90 FS_A_2G
Anaesthetix 0:dc98084cf6be 91 FS_A_4G
Anaesthetix 0:dc98084cf6be 92 FS_A_8G
Anaesthetix 0:dc98084cf6be 93 FS_A_16G
Anaesthetix 0:dc98084cf6be 94
Anaesthetix 0:dc98084cf6be 95 Magnetometer full-scale setting:
Anaesthetix 0:dc98084cf6be 96 FS_M_4GAUSS
Anaesthetix 0:dc98084cf6be 97 FS_M_8GAUSS
Anaesthetix 0:dc98084cf6be 98 FS_M_12GAUSS
Anaesthetix 0:dc98084cf6be 99 FS_M_16GAUSS
Anaesthetix 0:dc98084cf6be 100
Anaesthetix 0:dc98084cf6be 101
Anaesthetix 0:dc98084cf6be 102 Set sensitivity according to full-scale settings. Possible values are:
Anaesthetix 0:dc98084cf6be 103 ACC_SENS_2G
Anaesthetix 0:dc98084cf6be 104 ACC_SENS_4G
Anaesthetix 0:dc98084cf6be 105 ACC_SENS_8G
Anaesthetix 0:dc98084cf6be 106 ACC_SENS_16G
Anaesthetix 0:dc98084cf6be 107 GYR_SENS_245DPS
Anaesthetix 0:dc98084cf6be 108 GYR_SENS_500DPS
Anaesthetix 0:dc98084cf6be 109 GYR_SENS_2000DPS
Anaesthetix 0:dc98084cf6be 110 MAG_SENS_4GAUSS
Anaesthetix 0:dc98084cf6be 111 MAG_SENS_8GAUSS
Anaesthetix 0:dc98084cf6be 112 MAG_SENS_12GAUSS
Anaesthetix 0:dc98084cf6be 113 MAG_SENS_16GAUSS
Anaesthetix 0:dc98084cf6be 114 */
Anaesthetix 0:dc98084cf6be 115
Anaesthetix 0:dc98084cf6be 116
Anaesthetix 0:dc98084cf6be 117 void lsm9ds1_spi::init() {
Anaesthetix 0:dc98084cf6be 118
Anaesthetix 0:dc98084cf6be 119 deselectAG();
Anaesthetix 0:dc98084cf6be 120 deselectM();
Anaesthetix 0:dc98084cf6be 121
Anaesthetix 0:dc98084cf6be 122 uint8_t LSM_Init_Data[LSM_InitRegNumAG][2] = {
Anaesthetix 0:dc98084cf6be 123 {ODR_G_952HZ | FS_G_500DPS | BW_G_100HZ, CTRL_REG1_G},
Anaesthetix 0:dc98084cf6be 124 {0x00, CTRL_REG2_G}, // enable FIFO, disable HPF/LPF2 <-- something seems to be wrong with the filters, check datasheet if you want to use them
Anaesthetix 0:dc98084cf6be 125 {0x09, CTRL_REG3_G}, // Disable HPF
Anaesthetix 0:dc98084cf6be 126 {0x00, ORIENT_CFG_G},
Anaesthetix 0:dc98084cf6be 127 {0x38, CTRL_REG4}, //Enable gyro outputs, no latched interrupt
Anaesthetix 0:dc98084cf6be 128 {0x38, CTRL_REG5_XL}, //No decimation of accel data, Enable accelerometer outputs
Anaesthetix 0:dc98084cf6be 129 {0xC0 | FS_A_2G, CTRL_REG6_XL}, // Accel ODR 952Hz, BW 408 Hz, +-2g
Anaesthetix 0:dc98084cf6be 130 {0xC0, CTRL_REG7_XL}, //LP cutoff ODR/9, LPF enabled, HPF bypassed, bypass LPF = 0xC0
Anaesthetix 0:dc98084cf6be 131 {0x16, CTRL_REG9}, //Temperature FIFO enabled, I2C disabled, FIFO enabled
Anaesthetix 0:dc98084cf6be 132 {0xC0, FIFO_CTRL}, //Continuous mode, overwrite if FIFO is full
Anaesthetix 0:dc98084cf6be 133 };
Anaesthetix 0:dc98084cf6be 134
Anaesthetix 0:dc98084cf6be 135 uint8_t LSM_Init_DataM[LSM_InitRegNumM][2] = {
Anaesthetix 0:dc98084cf6be 136 {0x7C, CTRL_REG1_M}, // Ultra-high performance mode (x & y axis), ODR 80Hz, no temp comp
Anaesthetix 0:dc98084cf6be 137 {FS_M_4GAUSS, CTRL_REG2_M}, // FS +- 4 gauss
Anaesthetix 0:dc98084cf6be 138 {0x84, CTRL_REG3_M}, // Disable I2C, enable SPI read/write, continuous-conversion mode
Anaesthetix 0:dc98084cf6be 139 {0x0C, CTRL_REG4_M}, // Ultra-high performance mode (z-axis)
Anaesthetix 0:dc98084cf6be 140 {0x00, CTRL_REG5_M}, // Fast read disabled, continuous update
Anaesthetix 0:dc98084cf6be 141 {0x02, INT_CFG_M},
Anaesthetix 0:dc98084cf6be 142 };
Anaesthetix 0:dc98084cf6be 143 spi.format(8,3);
Anaesthetix 0:dc98084cf6be 144 spi.frequency(10000000);
Anaesthetix 0:dc98084cf6be 145
Anaesthetix 0:dc98084cf6be 146 for(int i=0; i<LSM_InitRegNumAG; i++) {
Anaesthetix 0:dc98084cf6be 147 WriteRegAG(LSM_Init_Data[i][1], LSM_Init_Data[i][0]);
Anaesthetix 0:dc98084cf6be 148 }
Anaesthetix 0:dc98084cf6be 149
Anaesthetix 0:dc98084cf6be 150 for(int i=0; i<LSM_InitRegNumM; i++) {
Anaesthetix 0:dc98084cf6be 151 WriteRegM(LSM_Init_DataM[i][1], LSM_Init_DataM[i][0]);
Anaesthetix 0:dc98084cf6be 152 }
Anaesthetix 0:dc98084cf6be 153
Anaesthetix 0:dc98084cf6be 154 // Sensitivity settings
Anaesthetix 0:dc98084cf6be 155 acc_multiplier = ACC_SENS_2G;
Anaesthetix 0:dc98084cf6be 156 gyro_multiplier = GYR_SENS_500DPS;
Anaesthetix 0:dc98084cf6be 157 mag_multiplier = MAG_SENS_4GAUSS;
Anaesthetix 0:dc98084cf6be 158 }
Anaesthetix 0:dc98084cf6be 159
Anaesthetix 0:dc98084cf6be 160 void lsm9ds1_spi::read_acc()
Anaesthetix 0:dc98084cf6be 161 {
Anaesthetix 0:dc98084cf6be 162 uint8_t response[6];
Anaesthetix 0:dc98084cf6be 163 int16_t bit_data;
Anaesthetix 0:dc98084cf6be 164 float data;
Anaesthetix 0:dc98084cf6be 165 int i;
Anaesthetix 0:dc98084cf6be 166 ReadRegsAG(OUT_X_L_XL,response,6);
Anaesthetix 0:dc98084cf6be 167 for(i=0; i<3; i++) {
Anaesthetix 0:dc98084cf6be 168 bit_data=((int16_t)response[i*2+1]<<8)|response[i*2];
Anaesthetix 0:dc98084cf6be 169 data=(float)bit_data;
Anaesthetix 0:dc98084cf6be 170 accelerometer_data[i]=data*acc_multiplier;
Anaesthetix 0:dc98084cf6be 171 }
Anaesthetix 0:dc98084cf6be 172
Anaesthetix 0:dc98084cf6be 173 }
Anaesthetix 0:dc98084cf6be 174
Anaesthetix 0:dc98084cf6be 175 void lsm9ds1_spi::read_gyr()
Anaesthetix 0:dc98084cf6be 176 {
Anaesthetix 0:dc98084cf6be 177 uint8_t response[6];
Anaesthetix 0:dc98084cf6be 178 int16_t bit_data;
Anaesthetix 0:dc98084cf6be 179 float data;
Anaesthetix 0:dc98084cf6be 180 int i;
Anaesthetix 0:dc98084cf6be 181 ReadRegsAG(OUT_X_L_G,response,6);
Anaesthetix 0:dc98084cf6be 182 for(i=0; i<3; i++) {
Anaesthetix 0:dc98084cf6be 183 bit_data=((int16_t)response[i*2+1]<<8)|response[i*2];
Anaesthetix 0:dc98084cf6be 184 data=(float)bit_data;
Anaesthetix 0:dc98084cf6be 185 gyroscope_data[i]=data*gyro_multiplier;
Anaesthetix 0:dc98084cf6be 186 }
Anaesthetix 0:dc98084cf6be 187
Anaesthetix 0:dc98084cf6be 188 }
Anaesthetix 0:dc98084cf6be 189
Anaesthetix 0:dc98084cf6be 190 float lsm9ds1_spi::read_temp(){
Anaesthetix 0:dc98084cf6be 191 uint8_t response[2];
Anaesthetix 0:dc98084cf6be 192 int16_t bit_data;
Anaesthetix 0:dc98084cf6be 193 float data;
Anaesthetix 0:dc98084cf6be 194 ReadRegsAG(OUT_TEMP_L,response,2);
Anaesthetix 0:dc98084cf6be 195
Anaesthetix 0:dc98084cf6be 196 bit_data=((int16_t)response[1]<<8)|response[0];
Anaesthetix 0:dc98084cf6be 197 data=(float)bit_data;
Anaesthetix 0:dc98084cf6be 198 data = data/16;
Anaesthetix 0:dc98084cf6be 199 return (data+25);
Anaesthetix 0:dc98084cf6be 200 }
Anaesthetix 0:dc98084cf6be 201
Anaesthetix 0:dc98084cf6be 202 void lsm9ds1_spi::read_mag()
Anaesthetix 0:dc98084cf6be 203 {
Anaesthetix 0:dc98084cf6be 204 uint8_t response[6];
Anaesthetix 0:dc98084cf6be 205 int16_t bit_data;
Anaesthetix 0:dc98084cf6be 206 float data;
Anaesthetix 0:dc98084cf6be 207 int i;
Anaesthetix 0:dc98084cf6be 208 ReadRegsM(OUT_X_L_M,response,6);
Anaesthetix 0:dc98084cf6be 209 for(i=0; i<3; i++) {
Anaesthetix 0:dc98084cf6be 210 bit_data=((int16_t)response[i*2+1]<<8)|response[i*2];
Anaesthetix 0:dc98084cf6be 211 data=(float)bit_data;
Anaesthetix 0:dc98084cf6be 212 magnetometer_data[i]=data*mag_multiplier;
Anaesthetix 0:dc98084cf6be 213 }
Anaesthetix 0:dc98084cf6be 214
Anaesthetix 0:dc98084cf6be 215 }
Anaesthetix 0:dc98084cf6be 216
Anaesthetix 0:dc98084cf6be 217 void lsm9ds1_spi::read_all()
Anaesthetix 0:dc98084cf6be 218 {
Anaesthetix 0:dc98084cf6be 219 read_acc();
Anaesthetix 0:dc98084cf6be 220 read_gyr();
Anaesthetix 0:dc98084cf6be 221 read_mag();
Anaesthetix 0:dc98084cf6be 222 }
Anaesthetix 0:dc98084cf6be 223
Anaesthetix 0:dc98084cf6be 224 unsigned int lsm9ds1_spi::whoami()
Anaesthetix 0:dc98084cf6be 225 {
Anaesthetix 0:dc98084cf6be 226 return ReadRegAG(WHO_AM_I_XG, 0x00);
Anaesthetix 0:dc98084cf6be 227 }
Anaesthetix 0:dc98084cf6be 228
Anaesthetix 0:dc98084cf6be 229 unsigned int lsm9ds1_spi::whoamiM()
Anaesthetix 0:dc98084cf6be 230 {
Anaesthetix 0:dc98084cf6be 231 return ReadRegM(WHO_AM_I_M, 0x00);
Anaesthetix 0:dc98084cf6be 232 }
Anaesthetix 0:dc98084cf6be 233
Anaesthetix 0:dc98084cf6be 234 void lsm9ds1_spi::selectAG() {
Anaesthetix 0:dc98084cf6be 235 csAG = 0;
Anaesthetix 0:dc98084cf6be 236 }
Anaesthetix 0:dc98084cf6be 237
Anaesthetix 0:dc98084cf6be 238 void lsm9ds1_spi::selectM() {
Anaesthetix 0:dc98084cf6be 239 csM = 0;
Anaesthetix 0:dc98084cf6be 240 }
Anaesthetix 0:dc98084cf6be 241
Anaesthetix 0:dc98084cf6be 242 void lsm9ds1_spi::deselectAG() {
Anaesthetix 0:dc98084cf6be 243 csAG = 1;
Anaesthetix 0:dc98084cf6be 244 }
Anaesthetix 0:dc98084cf6be 245
Anaesthetix 0:dc98084cf6be 246 void lsm9ds1_spi::deselectM() {
Anaesthetix 0:dc98084cf6be 247 csM = 1;
Anaesthetix 0:dc98084cf6be 248 }
Anaesthetix 0:dc98084cf6be 249