Merge branch 'master' of gitlab:wintermute/hackover2013-badge-firmware
[hackover2013-badge-firmware.git] / drivers / sensors / mpl115a2 / mpl115a2.c
1 /**************************************************************************/
2 /*!
3 @file mpl115a2.c
4 @author K. Townsend (microBuilder.eu)
5
6 @brief Drivers for the Freescale MPL115A2 I2C Digital Barometer
7
8 @section DESCRIPTION
9
10 The MPL115A2 is an I2C absolute pressure sensor, employing a MEMS
11 pressure sensor with a conditioning IC to provide accurate pressure
12 measurements from 50 to 115 kPa.
13
14 @section LICENSE
15
16 Software License Agreement (BSD License)
17
18 Copyright (c) 2012, K. Townsend
19 All rights reserved.
20
21 Redistribution and use in source and binary forms, with or without
22 modification, are permitted provided that the following conditions are met:
23 1. Redistributions of source code must retain the above copyright
24 notice, this list of conditions and the following disclaimer.
25 2. Redistributions in binary form must reproduce the above copyright
26 notice, this list of conditions and the following disclaimer in the
27 documentation and/or other materials provided with the distribution.
28 3. Neither the name of the copyright holders nor the
29 names of its contributors may be used to endorse or promote products
30 derived from this software without specific prior written permission.
31
32 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
33 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
34 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
35 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
36 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
38 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
39 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
40 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
41 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 */
43 /**************************************************************************/
44 #include "mpl115a2.h"
45 #include "core/systick/systick.h"
46
47 extern volatile uint8_t I2CMasterBuffer[I2C_BUFSIZE];
48 extern volatile uint8_t I2CSlaveBuffer[I2C_BUFSIZE];
49 extern volatile uint32_t I2CReadLength, I2CWriteLength;
50
51 static float _mpl115a2_a0;
52 static float _mpl115a2_b1;
53 static float _mpl115a2_b2;
54 static float _mpl115a2_c12;
55
56 static bool _mpl115a2Initialised = false;
57
58 /**************************************************************************/
59 /*!
60 @brief Reads an 8 bit value over I2C
61 */
62 /**************************************************************************/
63 mpl115a2Error_t mpl115a2ReadPressureTemp(uint16_t *pressure, uint16_t *temp)
64 {
65 // Clear write buffers
66 uint32_t i;
67 for ( i = 0; i < I2C_BUFSIZE; i++ )
68 {
69 I2CMasterBuffer[i] = 0x00;
70 I2CSlaveBuffer[i] = 0x00;
71 }
72
73 I2CWriteLength = 3;
74 I2CReadLength = 1;
75 I2CMasterBuffer[0] = MPL115A2_ADDRESS;
76 I2CMasterBuffer[1] = MPL115A2_REGISTER_STARTCONVERSION;
77 I2CMasterBuffer[2] = 0x00; // Why is this necessary to get results?
78 i2cEngine();
79
80 // Wait a bit for the conversion to complete (3ms max)
81 systickDelay(5);
82
83 I2CWriteLength = 2;
84 I2CReadLength = 4;
85 I2CMasterBuffer[0] = MPL115A2_ADDRESS;
86 I2CMasterBuffer[1] = MPL115A2_REGISTER_PRESSURE_MSB;
87 I2CMasterBuffer[2] = MPL115A2_ADDRESS | MPL115A2_READBIT;
88 i2cEngine();
89
90 // Shift values to create properly formed integers
91 *pressure = ((I2CSlaveBuffer[0] << 8) | (I2CSlaveBuffer[1])) >> 6;
92 *temp = ((I2CSlaveBuffer[2] << 8) | (I2CSlaveBuffer[3])) >> 6;
93
94 return MPL115A2_ERROR_OK;
95 }
96
97 /**************************************************************************/
98 /*!
99 @brief Reads the factory-set coefficients
100 */
101 /**************************************************************************/
102 mpl115a2Error_t mpl115a2ReadCoefficients(void)
103 {
104 int16_t a0coeff;
105 int16_t b1coeff;
106 int16_t b2coeff;
107 int16_t c12coeff;
108
109 // Clear write buffers
110 uint32_t i;
111 for ( i = 0; i < I2C_BUFSIZE; i++ )
112 {
113 I2CMasterBuffer[i] = 0x00;
114 I2CSlaveBuffer[i] = 0x00;
115 }
116
117 I2CWriteLength = 2;
118 I2CReadLength = 8;
119 I2CMasterBuffer[0] = MPL115A2_ADDRESS;
120 I2CMasterBuffer[1] = MPL115A2_REGISTER_A0_COEFF_MSB;
121 I2CMasterBuffer[2] = MPL115A2_ADDRESS | MPL115A2_READBIT;
122 i2cEngine();
123
124 a0coeff = (I2CSlaveBuffer[0] << 8 ) | I2CSlaveBuffer[1];
125 b1coeff = (I2CSlaveBuffer[2] << 8 ) | I2CSlaveBuffer[3];
126 b2coeff = (I2CSlaveBuffer[4] << 8 ) | I2CSlaveBuffer[5];
127 c12coeff = ((I2CSlaveBuffer[6] << 8 ) | I2CSlaveBuffer[7]) >> 2;
128
129 _mpl115a2_a0 = (float)a0coeff / 8;
130 _mpl115a2_b1 = (float)b1coeff / 8192;
131 _mpl115a2_b2 = (float)b2coeff / 16384;
132 _mpl115a2_c12 = (float)c12coeff / 4194304;
133
134 return MPL115A2_ERROR_OK;
135 }
136
137 /**************************************************************************/
138 /*!
139 @brief Initialises the I2C block
140 */
141 /**************************************************************************/
142 mpl115a2Error_t mpl115a2Init(void)
143 {
144 mpl115a2Error_t error = MPL115A2_ERROR_OK;
145
146 // Initialise I2C
147 if (i2cInit(I2CMASTER) == false)
148 {
149 return MPL115A2_ERROR_I2CINIT; /* Fatal error */
150 }
151
152 // Coefficients only need to be read once
153 mpl115a2ReadCoefficients();
154
155 _mpl115a2Initialised = true;
156 return error;
157 }
158
159 /**************************************************************************/
160 /*!
161 @brief Gets the compensated pressure level in kPa
162 */
163 /**************************************************************************/
164 mpl115a2Error_t mpl115a2GetPressure(float *pressure)
165 {
166 uint16_t Padc, Tadc;
167 float Pcomp;
168
169 mpl115a2Error_t error = MPL115A2_ERROR_OK;
170
171 // Make sure the coefficients have been read, etc.
172 if (!_mpl115a2Initialised) mpl115a2Init();
173
174 // Get raw pressure and temperature settings
175 error = mpl115a2ReadPressureTemp(&Padc, &Tadc);
176 if (error) return error;
177
178 // See datasheet p.6 for evaluation sequence
179 Pcomp = _mpl115a2_a0 + (_mpl115a2_b1 + _mpl115a2_c12 * Tadc ) * Padc + _mpl115a2_b2 * Tadc;
180
181 // Return pressure as floating point value
182 *pressure = ((65.0F / 1023.0F)*(float)Pcomp) + 50;
183
184 return error;
185 }
This page took 0.071882 seconds and 5 git commands to generate.