MPL3115A2 driver

Dependents:   lmic_NAmote_GPS_tjm lmic_NAmote_GPS_tjm Senet NAMote scpi_sx127x ... more

Committer:
dudmuck
Date:
Mon Aug 31 21:37:41 2015 +0000
Revision:
2:0eb8b0ad292b
Parent:
1:3cd1f21925e8
correct altitude reading

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dudmuck 0:6bba2efea51e 1 #include "mpl3115a2.h"
dudmuck 0:6bba2efea51e 2
dudmuck 0:6bba2efea51e 3 #define MPL3115A_I2C_ADDRESS 0xc0 //0x60
dudmuck 0:6bba2efea51e 4
dudmuck 1:3cd1f21925e8 5 MPL3115A2::MPL3115A2(I2C& r, DigitalIn& int_pin) : m_i2c(r), m_int_pin(int_pin)
dudmuck 0:6bba2efea51e 6 {
dudmuck 1:3cd1f21925e8 7 write(CTRL_REG3, 0x10); // PP_OD1: INT1 to open-drain
dudmuck 0:6bba2efea51e 8 }
dudmuck 0:6bba2efea51e 9
dudmuck 0:6bba2efea51e 10 MPL3115A2::~MPL3115A2()
dudmuck 0:6bba2efea51e 11 {
dudmuck 0:6bba2efea51e 12 }
dudmuck 0:6bba2efea51e 13
dudmuck 0:6bba2efea51e 14 void MPL3115A2::init()
dudmuck 0:6bba2efea51e 15 {
dudmuck 0:6bba2efea51e 16 //MPL3115Reset( );
dudmuck 2:0eb8b0ad292b 17 ctrl_reg1.octet = 0;
dudmuck 2:0eb8b0ad292b 18 ctrl_reg1.bits.RST = 1;
dudmuck 2:0eb8b0ad292b 19 write(CTRL_REG1, /*4*/ ctrl_reg1.octet);
dudmuck 0:6bba2efea51e 20 wait(0.05);
dudmuck 0:6bba2efea51e 21
dudmuck 0:6bba2efea51e 22 do
dudmuck 0:6bba2efea51e 23 { // Wait for the RST bit to clear
dudmuck 2:0eb8b0ad292b 24 wait(0.01);
dudmuck 2:0eb8b0ad292b 25 ctrl_reg1.octet = read(CTRL_REG1);
dudmuck 2:0eb8b0ad292b 26 } while (ctrl_reg1.octet);
dudmuck 0:6bba2efea51e 27
dudmuck 0:6bba2efea51e 28 write( PT_DATA_CFG_REG, 0x07 ); // Enable data flags
dudmuck 0:6bba2efea51e 29 write( CTRL_REG3, 0x11 ); // Open drain, active low interrupts
dudmuck 0:6bba2efea51e 30 write( CTRL_REG4, 0x80 ); // Enable DRDY interrupt
dudmuck 0:6bba2efea51e 31 write( CTRL_REG5, 0x00 ); // DRDY interrupt routed to INT2 - PTD3
dudmuck 2:0eb8b0ad292b 32
dudmuck 2:0eb8b0ad292b 33 ctrl_reg1.bits.ALT = 1; // altitude mode
dudmuck 2:0eb8b0ad292b 34 ctrl_reg1.bits.OS = 5; // OSR = 32
dudmuck 2:0eb8b0ad292b 35 ctrl_reg1.bits.SBYB = 1; // Active
dudmuck 2:0eb8b0ad292b 36 write(CTRL_REG1, ctrl_reg1.octet);
dudmuck 0:6bba2efea51e 37
dudmuck 0:6bba2efea51e 38 SetModeActive( );
dudmuck 0:6bba2efea51e 39 }
dudmuck 0:6bba2efea51e 40
dudmuck 2:0eb8b0ad292b 41 void MPL3115A2::setOSR(uint8_t osr)
dudmuck 2:0eb8b0ad292b 42 {
dudmuck 2:0eb8b0ad292b 43 ctrl_reg1.bits.OS = osr;
dudmuck 2:0eb8b0ad292b 44 write(CTRL_REG1, ctrl_reg1.octet);
dudmuck 2:0eb8b0ad292b 45 }
dudmuck 2:0eb8b0ad292b 46
dudmuck 2:0eb8b0ad292b 47 uint8_t MPL3115A2::getOSR(void)
dudmuck 2:0eb8b0ad292b 48 {
dudmuck 2:0eb8b0ad292b 49 ctrl_reg1.octet = read(CTRL_REG1);
dudmuck 2:0eb8b0ad292b 50 return ctrl_reg1.bits.OS;
dudmuck 2:0eb8b0ad292b 51 }
dudmuck 2:0eb8b0ad292b 52
dudmuck 1:3cd1f21925e8 53 bool MPL3115A2::GetModeActive( )
dudmuck 1:3cd1f21925e8 54 {
dudmuck 2:0eb8b0ad292b 55 ctrl_reg1.octet = read(CTRL_REG1);
dudmuck 2:0eb8b0ad292b 56 return ctrl_reg1.bits.SBYB;
dudmuck 1:3cd1f21925e8 57 }
dudmuck 1:3cd1f21925e8 58
dudmuck 0:6bba2efea51e 59 void MPL3115A2::SetModeActive( )
dudmuck 0:6bba2efea51e 60 {
dudmuck 2:0eb8b0ad292b 61 ctrl_reg1.bits.SBYB = 1;
dudmuck 2:0eb8b0ad292b 62 write(CTRL_REG1, ctrl_reg1.octet);
dudmuck 0:6bba2efea51e 63 }
dudmuck 0:6bba2efea51e 64
dudmuck 0:6bba2efea51e 65 void MPL3115A2::SetModeStandby( )
dudmuck 0:6bba2efea51e 66 {
dudmuck 2:0eb8b0ad292b 67 ctrl_reg1.bits.SBYB = 0;
dudmuck 2:0eb8b0ad292b 68 write(CTRL_REG1, ctrl_reg1.octet);
dudmuck 0:6bba2efea51e 69 }
dudmuck 0:6bba2efea51e 70
dudmuck 0:6bba2efea51e 71 void MPL3115A2::write(uint8_t a, uint8_t d)
dudmuck 0:6bba2efea51e 72 {
dudmuck 0:6bba2efea51e 73 char cmd[2];
dudmuck 0:6bba2efea51e 74
dudmuck 0:6bba2efea51e 75 cmd[0] = a;
dudmuck 0:6bba2efea51e 76 cmd[1] = d;
dudmuck 0:6bba2efea51e 77
dudmuck 0:6bba2efea51e 78 if (m_i2c.write(MPL3115A_I2C_ADDRESS, cmd, 2))
dudmuck 1:3cd1f21925e8 79 printf("MPL write-fail %02x %02x\n", cmd[0], cmd[1]);
dudmuck 1:3cd1f21925e8 80
dudmuck 1:3cd1f21925e8 81 if (a == CTRL_REG4)
dudmuck 1:3cd1f21925e8 82 ctrl_reg4 = d;
dudmuck 0:6bba2efea51e 83 }
dudmuck 0:6bba2efea51e 84
dudmuck 0:6bba2efea51e 85 uint8_t MPL3115A2::read(uint8_t a)
dudmuck 0:6bba2efea51e 86 {
dudmuck 0:6bba2efea51e 87 char cmd[2];
dudmuck 0:6bba2efea51e 88
dudmuck 0:6bba2efea51e 89 cmd[0] = a;
dudmuck 0:6bba2efea51e 90 if (m_i2c.write(MPL3115A_I2C_ADDRESS, cmd, 1, true))
dudmuck 1:3cd1f21925e8 91 printf("MPL write-fail %02x\n", cmd[0]);
dudmuck 0:6bba2efea51e 92 if (m_i2c.read(MPL3115A_I2C_ADDRESS, cmd, 1))
dudmuck 1:3cd1f21925e8 93 printf("MPL read-fail\n");
dudmuck 1:3cd1f21925e8 94
dudmuck 1:3cd1f21925e8 95 if (a == CTRL_REG4)
dudmuck 1:3cd1f21925e8 96 ctrl_reg4 = cmd[0];
dudmuck 1:3cd1f21925e8 97
dudmuck 0:6bba2efea51e 98 return cmd[0];
dudmuck 0:6bba2efea51e 99 }
dudmuck 0:6bba2efea51e 100
dudmuck 2:0eb8b0ad292b 101 float MPL3115A2::ReadBarometer(void)
dudmuck 2:0eb8b0ad292b 102 {
dudmuck 2:0eb8b0ad292b 103 uint32_t pasc;
dudmuck 2:0eb8b0ad292b 104 volatile uint8_t stat;
dudmuck 2:0eb8b0ad292b 105
dudmuck 2:0eb8b0ad292b 106 SetModeBarometer();
dudmuck 2:0eb8b0ad292b 107 ToggleOneShot( );
dudmuck 2:0eb8b0ad292b 108
dudmuck 2:0eb8b0ad292b 109 stat = read(STATUS_REG);
dudmuck 2:0eb8b0ad292b 110 while( (stat & 0x04) != 0x04 ) {
dudmuck 2:0eb8b0ad292b 111 wait(0.01);
dudmuck 2:0eb8b0ad292b 112 stat = read(STATUS_REG);
dudmuck 2:0eb8b0ad292b 113 }
dudmuck 2:0eb8b0ad292b 114
dudmuck 2:0eb8b0ad292b 115 pasc = read(OUT_P_MSB_REG);
dudmuck 2:0eb8b0ad292b 116 pasc <<= 8;
dudmuck 2:0eb8b0ad292b 117 pasc |= read(OUT_P_CSB_REG);
dudmuck 2:0eb8b0ad292b 118 pasc <<= 8;
dudmuck 2:0eb8b0ad292b 119 pasc |= read(OUT_P_LSB_REG);
dudmuck 2:0eb8b0ad292b 120
dudmuck 2:0eb8b0ad292b 121 return pasc / 64.0;
dudmuck 2:0eb8b0ad292b 122 }
dudmuck 2:0eb8b0ad292b 123
dudmuck 0:6bba2efea51e 124 float MPL3115A2::ReadAltitude( void )
dudmuck 0:6bba2efea51e 125 {
dudmuck 0:6bba2efea51e 126 uint8_t counter = 0;
dudmuck 0:6bba2efea51e 127 uint8_t val = 0;
dudmuck 0:6bba2efea51e 128 uint8_t msb = 0, csb = 0, lsb = 0;
dudmuck 0:6bba2efea51e 129 float decimal = 0;
dudmuck 0:6bba2efea51e 130
dudmuck 0:6bba2efea51e 131 /*if( MPL3115Initialized == false )
dudmuck 0:6bba2efea51e 132 {
dudmuck 0:6bba2efea51e 133 return 0;
dudmuck 0:6bba2efea51e 134 }*/
dudmuck 0:6bba2efea51e 135
dudmuck 0:6bba2efea51e 136 SetModeAltimeter( );
dudmuck 0:6bba2efea51e 137 ToggleOneShot( );
dudmuck 0:6bba2efea51e 138
dudmuck 0:6bba2efea51e 139 while( ( val & 0x04 ) != 0x04 )
dudmuck 0:6bba2efea51e 140 {
dudmuck 0:6bba2efea51e 141 val = read( STATUS_REG);
dudmuck 0:6bba2efea51e 142 wait(0.01); //DelayMs( 10 );
dudmuck 0:6bba2efea51e 143 counter++;
dudmuck 0:6bba2efea51e 144
dudmuck 0:6bba2efea51e 145 if( counter > 20 )
dudmuck 0:6bba2efea51e 146 {
dudmuck 0:6bba2efea51e 147 //MPL3115Initialized = false;
dudmuck 0:6bba2efea51e 148 init( );
dudmuck 0:6bba2efea51e 149 SetModeAltimeter( );
dudmuck 0:6bba2efea51e 150 ToggleOneShot( );
dudmuck 0:6bba2efea51e 151 counter = 0;
dudmuck 0:6bba2efea51e 152 while( ( val & 0x04 ) != 0x04 )
dudmuck 0:6bba2efea51e 153 {
dudmuck 0:6bba2efea51e 154 val = read( STATUS_REG);
dudmuck 0:6bba2efea51e 155 wait(0.01); //DelayMs( 10 );
dudmuck 0:6bba2efea51e 156 counter++;
dudmuck 0:6bba2efea51e 157 if( counter > 20 )
dudmuck 0:6bba2efea51e 158 {
dudmuck 1:3cd1f21925e8 159 write( CTRL_REG4, 0x00 );
dudmuck 0:6bba2efea51e 160 return( 0 ); //Error out after max of 512ms for a read
dudmuck 0:6bba2efea51e 161 }
dudmuck 0:6bba2efea51e 162 }
dudmuck 0:6bba2efea51e 163 }
dudmuck 0:6bba2efea51e 164 }
dudmuck 0:6bba2efea51e 165
dudmuck 0:6bba2efea51e 166 msb = read( OUT_P_MSB_REG); // High byte of integer part of altitude,
dudmuck 0:6bba2efea51e 167 csb = read( OUT_P_CSB_REG); // Low byte of integer part of altitude
dudmuck 0:6bba2efea51e 168 lsb = read( OUT_P_LSB_REG); // Decimal part of altitude in bits 7-4
dudmuck 0:6bba2efea51e 169
dudmuck 0:6bba2efea51e 170 decimal = ( ( float )( lsb >> 4 ) ) / 16.0;
dudmuck 0:6bba2efea51e 171 //Altitude = ( float )( ( msb << 8 ) | csb ) + decimal;
dudmuck 0:6bba2efea51e 172 Altitude = ( float )( ( int16_t )( ( msb << 8 ) | csb ) ) + decimal;
dudmuck 1:3cd1f21925e8 173
dudmuck 1:3cd1f21925e8 174 write( CTRL_REG4, 0x00 );
dudmuck 0:6bba2efea51e 175
dudmuck 0:6bba2efea51e 176 return( Altitude );
dudmuck 0:6bba2efea51e 177 }
dudmuck 0:6bba2efea51e 178
dudmuck 0:6bba2efea51e 179 void MPL3115A2::SetModeAltimeter( void )
dudmuck 0:6bba2efea51e 180 {
dudmuck 0:6bba2efea51e 181 SetModeStandby( );
dudmuck 0:6bba2efea51e 182
dudmuck 2:0eb8b0ad292b 183 ctrl_reg1.bits.ALT = 1;
dudmuck 2:0eb8b0ad292b 184 write(CTRL_REG1, ctrl_reg1.octet);
dudmuck 2:0eb8b0ad292b 185
dudmuck 2:0eb8b0ad292b 186 SetModeActive( );
dudmuck 2:0eb8b0ad292b 187 }
dudmuck 0:6bba2efea51e 188
dudmuck 2:0eb8b0ad292b 189 void MPL3115A2::SetModeBarometer(void)
dudmuck 2:0eb8b0ad292b 190 {
dudmuck 2:0eb8b0ad292b 191 SetModeStandby( );
dudmuck 2:0eb8b0ad292b 192
dudmuck 2:0eb8b0ad292b 193 ctrl_reg1.bits.ALT = 0;
dudmuck 2:0eb8b0ad292b 194 write(CTRL_REG1, ctrl_reg1.octet);
dudmuck 2:0eb8b0ad292b 195
dudmuck 2:0eb8b0ad292b 196 SetModeActive( );
dudmuck 0:6bba2efea51e 197 }
dudmuck 0:6bba2efea51e 198
dudmuck 0:6bba2efea51e 199 void MPL3115A2::ToggleOneShot( void )
dudmuck 0:6bba2efea51e 200 {
dudmuck 0:6bba2efea51e 201 SetModeStandby( );
dudmuck 2:0eb8b0ad292b 202
dudmuck 2:0eb8b0ad292b 203 ctrl_reg1.bits.OST = 0;
dudmuck 2:0eb8b0ad292b 204 write(CTRL_REG1, ctrl_reg1.octet);
dudmuck 2:0eb8b0ad292b 205
dudmuck 2:0eb8b0ad292b 206 ctrl_reg1.bits.OST = 1;
dudmuck 2:0eb8b0ad292b 207 write(CTRL_REG1, ctrl_reg1.octet);
dudmuck 0:6bba2efea51e 208
dudmuck 0:6bba2efea51e 209 SetModeActive( );
dudmuck 0:6bba2efea51e 210 }
dudmuck 0:6bba2efea51e 211
dudmuck 0:6bba2efea51e 212 float MPL3115A2::ReadTemperature( void )
dudmuck 0:6bba2efea51e 213 {
dudmuck 0:6bba2efea51e 214 uint8_t counter = 0;
dudmuck 0:6bba2efea51e 215 bool negSign = false;
dudmuck 0:6bba2efea51e 216 uint8_t val = 0;
dudmuck 0:6bba2efea51e 217 uint8_t msb = 0, lsb = 0;
dudmuck 0:6bba2efea51e 218
dudmuck 0:6bba2efea51e 219 /*if( MPL3115Initialized == false )
dudmuck 0:6bba2efea51e 220 {
dudmuck 0:6bba2efea51e 221 return 0;
dudmuck 0:6bba2efea51e 222 }*/
dudmuck 0:6bba2efea51e 223
dudmuck 0:6bba2efea51e 224 ToggleOneShot( );
dudmuck 0:6bba2efea51e 225
dudmuck 0:6bba2efea51e 226 while( ( val & 0x02 ) != 0x02 )
dudmuck 0:6bba2efea51e 227 {
dudmuck 0:6bba2efea51e 228 val = read( STATUS_REG);
dudmuck 0:6bba2efea51e 229 wait(0.01);
dudmuck 0:6bba2efea51e 230 counter++;
dudmuck 0:6bba2efea51e 231
dudmuck 0:6bba2efea51e 232 if( counter > 20 )
dudmuck 0:6bba2efea51e 233 {
dudmuck 0:6bba2efea51e 234 //MPL3115Initialized = false;
dudmuck 0:6bba2efea51e 235 init( );
dudmuck 0:6bba2efea51e 236 ToggleOneShot( );
dudmuck 0:6bba2efea51e 237 counter = 0;
dudmuck 0:6bba2efea51e 238 while( ( val & 0x02 ) != 0x02 )
dudmuck 0:6bba2efea51e 239 {
dudmuck 0:6bba2efea51e 240 val = read( STATUS_REG);
dudmuck 0:6bba2efea51e 241 wait(0.01);
dudmuck 0:6bba2efea51e 242 counter++;
dudmuck 0:6bba2efea51e 243
dudmuck 0:6bba2efea51e 244 if( counter > 20 )
dudmuck 0:6bba2efea51e 245 {
dudmuck 1:3cd1f21925e8 246 write( CTRL_REG4, 0x00 );
dudmuck 0:6bba2efea51e 247 return( 0 ); //Error out after max of 512ms for a read
dudmuck 0:6bba2efea51e 248 }
dudmuck 0:6bba2efea51e 249 }
dudmuck 0:6bba2efea51e 250
dudmuck 0:6bba2efea51e 251 }
dudmuck 0:6bba2efea51e 252 }
dudmuck 0:6bba2efea51e 253
dudmuck 0:6bba2efea51e 254 msb = read( OUT_T_MSB_REG); // Integer part of temperature
dudmuck 0:6bba2efea51e 255 lsb = read( OUT_T_LSB_REG); // Decimal part of temperature in bits 7-4
dudmuck 0:6bba2efea51e 256
dudmuck 0:6bba2efea51e 257 if( msb > 0x7F )
dudmuck 0:6bba2efea51e 258 {
dudmuck 0:6bba2efea51e 259 val = ~( ( msb << 8 ) + lsb ) + 1; //2?s complement
dudmuck 0:6bba2efea51e 260 msb = val >> 8;
dudmuck 0:6bba2efea51e 261 lsb = val & 0x00F0;
dudmuck 0:6bba2efea51e 262 negSign = true;
dudmuck 0:6bba2efea51e 263 }
dudmuck 0:6bba2efea51e 264
dudmuck 0:6bba2efea51e 265 if( negSign == true )
dudmuck 0:6bba2efea51e 266 {
dudmuck 0:6bba2efea51e 267 Temperature = 0 - ( msb + ( float )( ( lsb >> 4 ) / 16.0 ) );
dudmuck 0:6bba2efea51e 268 }
dudmuck 0:6bba2efea51e 269 else
dudmuck 0:6bba2efea51e 270 {
dudmuck 0:6bba2efea51e 271 Temperature = msb + ( float )( ( lsb >> 4 ) / 16.0 );
dudmuck 0:6bba2efea51e 272 }
dudmuck 0:6bba2efea51e 273
dudmuck 0:6bba2efea51e 274 ToggleOneShot( );
dudmuck 0:6bba2efea51e 275
dudmuck 1:3cd1f21925e8 276 write( CTRL_REG4, 0x00 );
dudmuck 1:3cd1f21925e8 277
dudmuck 0:6bba2efea51e 278 return( Temperature );
dudmuck 0:6bba2efea51e 279 }
dudmuck 0:6bba2efea51e 280
dudmuck 1:3cd1f21925e8 281 void MPL3115A2::service()
dudmuck 1:3cd1f21925e8 282 {
dudmuck 1:3cd1f21925e8 283 mpl_int_source_t int_src;
dudmuck 1:3cd1f21925e8 284
dudmuck 1:3cd1f21925e8 285 if ((ctrl_reg4 == 0x00) || m_int_pin) // if no interrupts enabled and no interrupt occuring
dudmuck 1:3cd1f21925e8 286 return;
dudmuck 1:3cd1f21925e8 287
dudmuck 1:3cd1f21925e8 288 int_src.octet = read(INT_SOURCE_REG);
dudmuck 1:3cd1f21925e8 289
dudmuck 1:3cd1f21925e8 290 if (int_src.bits.SRC_TCHG) {
dudmuck 1:3cd1f21925e8 291 }
dudmuck 1:3cd1f21925e8 292 if (int_src.bits.SRC_PCHG) {
dudmuck 1:3cd1f21925e8 293 }
dudmuck 1:3cd1f21925e8 294 if (int_src.bits.SRC_TTH) {
dudmuck 1:3cd1f21925e8 295 }
dudmuck 1:3cd1f21925e8 296 if (int_src.bits.SRC_PTH) {
dudmuck 1:3cd1f21925e8 297 }
dudmuck 1:3cd1f21925e8 298 if (int_src.bits.SRC_TW) {
dudmuck 1:3cd1f21925e8 299 }
dudmuck 1:3cd1f21925e8 300 if (int_src.bits.SRC_PW) {
dudmuck 1:3cd1f21925e8 301 }
dudmuck 1:3cd1f21925e8 302 if (int_src.bits.SRC_FIFO) {
dudmuck 1:3cd1f21925e8 303 read(F_STATUS_REG);
dudmuck 1:3cd1f21925e8 304 }
dudmuck 1:3cd1f21925e8 305 if (int_src.bits.SRC_DRDY) {
dudmuck 1:3cd1f21925e8 306 read(STATUS_REG);
dudmuck 1:3cd1f21925e8 307
dudmuck 1:3cd1f21925e8 308 read( OUT_T_MSB_REG); // Integer part of temperature
dudmuck 1:3cd1f21925e8 309 read( OUT_T_LSB_REG); // Decimal part of temperature in bits 7-4
dudmuck 1:3cd1f21925e8 310
dudmuck 1:3cd1f21925e8 311 read( OUT_P_MSB_REG); // High byte of integer part of altitude,
dudmuck 1:3cd1f21925e8 312 read( OUT_P_CSB_REG); // Low byte of integer part of altitude
dudmuck 1:3cd1f21925e8 313 read( OUT_P_LSB_REG); // Decimal part of altitude in bits 7-4
dudmuck 1:3cd1f21925e8 314 }
dudmuck 1:3cd1f21925e8 315
dudmuck 1:3cd1f21925e8 316 }