A library to interface with the LSM9DS1 IMU using SPI
LSM9DS1_SPI.cpp@0:dc98084cf6be, 2017-10-18 (annotated)
- Committer:
- Anaesthetix
- Date:
- Wed Oct 18 09:22:00 2017 +0000
- Revision:
- 0:dc98084cf6be
LSM9DS1 spi library
Who changed what in which revision?
User | Revision | Line number | New 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 |