New SPI API supporting DMA
[betaflight.git] / src / main / drivers / barometer / barometer_lps.c
blob15ec7146e5c481afb714f99957ce2870f9af0ed1
1 /*
2 * This file is part of Cleanflight and Betaflight.
4 * Cleanflight and Betaflight are free software. You can redistribute
5 * this software and/or modify this software under the terms of the
6 * GNU General Public License as published by the Free Software
7 * Foundation, either version 3 of the License, or (at your option)
8 * any later version.
10 * Cleanflight and Betaflight are distributed in the hope that they
11 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this software.
18 * If not, see <http://www.gnu.org/licenses/>.
21 #include <stdbool.h>
22 #include <stdint.h>
24 #include "platform.h"
26 #if defined(USE_BARO) && defined(USE_BARO_SPI_LPS)
28 #include "build/build_config.h"
30 #include "barometer.h"
31 #include "barometer_lps.h"
33 #include "drivers/bus_spi.h"
34 #include "drivers/io.h"
35 #include "drivers/time.h"
37 // 10 MHz max SPI frequency
38 #define LPS_MAX_SPI_CLK_HZ 10000000
39 //====================================Registers Addresses=========================================//
40 #define LPS_REF_P_XL 0x08
41 #define LPS_REF_P_L 0x09
42 #define LPS_REF_P_H 0x0A
43 #define LPS_WHO_AM_I 0x0F
45 * RES_CONF (10h)
47 * Bits 3-2 AVGT - Temperature internal average configuration.
48 * Default: 11 (64)
49 * Bits 1-0 AVGP - Pressure internal average configuration.
50 * Default: 11 (512)
53 #define LPS_RES_CONF 0x10
55 * CTRL_REG1(20h)
57 * Bit 7 PD - Power-down control.
58 * Default value: 0
59 * (0: power-down mode; 1: active mode)
60 * Bits 6-4 ODR - Output data rate selection.
61 * Default value: 000 (One shot mode)
62 * 000 - One Shot
63 * 001 - 1Hz
64 * 010 - 7Hz
65 * 011 - 12.5Hz
66 * 100 - 25Hz
67 * 101 - Resv
68 * Bit 3 DIFF_EN - Interrupt generation enable.
69 * Default value: 0
70 * (0: interrupt generation disabled; 1: interrupt generation enabled)
71 * Bit 2 BDU - Block data update.
72 * Default value: 0
73 * (0: continuous update; 1: output registers not updated until MSB and LSB have been read)
74 * Bit 1 RESET_AZ - Reset Autozero function.
75 * Default value: 0
76 * (0: normal mode; 1: reset Autozero function)
77 * Bit 0 SIM - SPI Serial Interface Mode selection.
78 * Default value: 0
79 * (0: 4-wire interface; 1: 3-wire interface)
82 #define LPS_CTRL1 0x20
84 * CTRL_REG2(21h)
86 * Bit 7 BOOT - Reboot memory content.
87 * Default value: 0.
88 * (0: normal mode; 1: reboot memory content).
89 * The bit is self-cleared when the BOOT is completed.
90 * Bit 6 FIFO_EN - FIFO enable.
91 * Default value: 0.
92 * (0: disable; 1: enable)
93 * Bit 5 STOP_ON_FTH - Enable the FTH_FIFO bit in FIFO_STATUS (2Fh) for monitoring of FIFO level.
94 * Default value: 0
95 * (0: disable; 1: enable).
96 * Bit 4 FIFO_MEAN_DEC - Enable to decimate the output pressure to 1Hz with FIFO Mean mode.
97 * Default value: 0
98 * (0: disable / 1: enable)
99 * Bit 3 I2C_DIS - I2C interface enabled.
100 * Default value 0.
101 * (0: I2C enabled;1: I2C disabled)
102 * Bit 2 SWRESET - Software reset.
103 * Default value: 0.
104 * (0: normal mode; 1: software reset).
105 * The bit is self-cleared when the reset is completed.
106 * Bit 1 AUTOZERO - Autozero enable.
107 * Default value: 0.
108 * (0: normal mode; 1: Autozero enabled)
109 * Bit 0 ONE_SHOT - One shot mode enable.
110 * Default value: 0.
111 * (0: idle mode; 1: a new dataset is acquired)
114 #define LPS_CTRL2 0x21
116 * CTRL_REG3(21h)
118 * Bit 7 INT_H_L - Interrupt active high, low.
119 * Default value: 0.
120 * (0: active high; 1: active low)
121 * Bit 6 PP_OD - Push-pull/open drain selection on interrupt pads.
122 * Default value: 0.
123 * (0: push-pull; 1: open drain)
124 * Bits 1-0 INT_S - Data signal on INT_DRDY pin control bits.
125 * Default value: 00.
127 #define LPS_CTRL3 0x22
129 * CTRL_REG4(23h)
131 * Bit 3 F_EMPTY - FIFO empty flag on INT_DRDY pin.
132 * Default value: 0.
133 * (0: disable; 1: enable)
134 * Bit 2 F_FTH - FIFO threshold (watermark) status on INT_DRDY pin to indicate that FIFO is filled up to the threshold level.
135 * Default value: 0.
136 * (0: disable; 1: enable)
137 * Bit 1 F_OVR - FIFO overrun interrupt on INT_DRDY pin to indicate that FIFO is full in FIFO mode or that an overrun occurred in Stream mode.
138 * Default value: 0.
139 * (0: disable; 1: enable)
140 * Bit 0 DRDY - Data-ready signal on INT_DRDY pin.
141 * Default value: 0.
142 * (0: disable; 1: enable)
144 #define LPS_CTRL4 0x23
145 #define LPS_INT_CFG 0x24
146 #define LPS_INT_SOURCE 0x25
147 #define LPS_STATUS 0x27
148 #define LPS_OUT_XL 0x28
149 #define LPS_OUT_L 0x29
150 #define LPS_OUT_H 0x2A
151 #define LPS_TEMP_OUT_L 0x2B
152 #define LPS_TEMP_OUT_H 0x2C
153 #define LPS_FIFO_CTRL 0x2E
154 #define LPS_FIFO_STATUS 0x2F
155 #define LPS_THS_PL 0x30
156 #define LPS_THS_PH 0x31
157 #define LPS_RPDS_L 0x39
158 #define LPS_RPDS_H 0x3A
159 //=======================================Constants=============================================//
160 #define LPS22_ID 0xB1
161 #define LPS25_ID 0xBD
162 #define LPS33_ID 0xB1
163 #define LPS35_ID 0xB1
164 #define LPS_READ 0x80
165 #define LPS_MULT 0x40
166 //======================================ODR Values=============================================//
167 // CTRL1 value
168 #define LPS_ODR_ONE_SHOT 0x00
169 #define LPS_ODR_1 0x10
170 #define LPS_ODR_7 0x20
171 #define LPS_ODR_12_5 0x30
172 #define LPS_ODR_25 0x40
173 //======================================Average number=============================================//
174 #define LPS_AVP_8 0x00
175 #define LPS_AVP_32 0x01
176 #define LPS_AVP_128 0x02
177 #define LPS_AVP_512 0x03
178 #define LPS_AVT_8 0x00
179 #define LPS_AVT_16 0x04
180 #define LPS_AVT_32 0x08
181 #define LPS_AVT_64 0x0C
182 //======================================Moving average number=============================================//
183 #define LPS_NO_MA 0x00
184 #define LPS_MA_2 0x01
185 #define LPS_MA_4 0x03
186 #define LPS_MA_8 0x07
187 #define LPS_MA_16 0x0F
188 #define LPS_MA_32 0x1F
190 //Raw register values
191 static uint32_t rawP = 0;
192 static uint16_t rawT = 0;
194 bool lpsWriteCommand(const extDevice_t *dev, uint8_t cmd, uint8_t byte)
196 return spiWriteRegRB(dev, cmd, byte);
199 bool lpsReadCommand(const extDevice_t *dev, uint8_t cmd, uint8_t *data, uint8_t len)
201 return spiReadRegMskBufRB(dev, cmd | 0x80 | 0x40, data, len);
204 bool lpsWriteVerify(const extDevice_t *dev, uint8_t cmd, uint8_t byte)
206 uint8_t temp = 0xff;
207 spiWriteReg(dev, cmd, byte);
208 temp = spiReadRegMsk(dev, cmd);
209 if (byte == temp) return true;
210 return false;
213 static void lpsOn(const extDevice_t *dev, uint8_t CTRL1_val)
215 lpsWriteCommand(dev, LPS_CTRL1, CTRL1_val | 0x80);
216 //Instead of delay let's ready status reg
219 static void lpsOff(const extDevice_t *dev)
221 lpsWriteCommand(dev, LPS_CTRL1, 0x00 | (0x01 << 2));
224 static void lpsNothing(baroDev_t *baro)
226 UNUSED(baro);
227 return;
230 static bool lpsNothingBool(baroDev_t *baro)
232 UNUSED(baro);
233 return true;
236 static bool lpsRead(baroDev_t *baro)
238 uint8_t status = 0x00;
239 lpsReadCommand(&baro->dev, LPS_STATUS, &status, 1);
240 if (status & 0x03) {
241 uint8_t temp[5];
242 lpsReadCommand(&baro->dev, LPS_OUT_XL, temp, 5);
244 /* Build the raw data */
245 rawP = temp[0] | (temp[1] << 8) | (temp[2] << 16) | ((temp[2] & 0x80) ? 0xff000000 : 0);
246 rawT = (temp[4] << 8) | temp[3];
247 } else {
248 rawP = 0;
249 rawT = 0;
252 return true;
255 static void lpsCalculate(int32_t *pressure, int32_t *temperature)
257 *pressure = (int32_t)rawP * 100 / 4096;
258 *temperature = (int32_t)rawT * 10 / 48 + 4250;
261 bool lpsDetect(baroDev_t *baro)
263 //Detect
264 extDevice_t *dev = &baro->dev;
266 if (dev->bus->busType != BUS_TYPE_SPI) {
267 return false;
270 IOInit(dev->busType_u.spi.csnPin, OWNER_BARO_CS, 0);
271 IOConfigGPIO(dev->busType_u.spi.csnPin, IOCFG_OUT_PP);
272 IOHi(dev->busType_u.spi.csnPin); // Disable
273 spiSetClkDivisor(dev, spiCalculateDivider(LPS_MAX_SPI_CLK_HZ));
275 uint8_t temp = 0x00;
276 lpsReadCommand(&baro->dev, LPS_WHO_AM_I, &temp, 1);
277 if (temp != LPS25_ID && temp != LPS22_ID && temp != LPS33_ID && temp != LPS35_ID) {
278 return false;
281 //Init, if writeVerify is false fallback to false on detect
282 bool ret = false;
283 lpsOff(dev);
284 ret = lpsWriteVerify(dev, LPS_CTRL2, (0x00 << 1)); if (ret != true) return false;
285 ret = lpsWriteVerify(dev, LPS_RES_CONF, (LPS_AVT_64 | LPS_AVP_512)); if (ret != true) return false;
286 ret = lpsWriteVerify(dev, LPS_CTRL4, 0x01); if (ret != true) return false;
287 lpsOn(dev, (0x04 << 4) | (0x01 << 1) | (0x01 << 2) | (0x01 << 3));
289 lpsReadCommand(dev, LPS_CTRL1, &temp, 1);
291 baro->combined_read = true;
292 baro->ut_delay = 1;
293 baro->up_delay = 1000000 / 24;
294 baro->start_ut = lpsNothing;
295 baro->get_ut = lpsNothingBool;
296 baro->read_ut = lpsNothingBool;
297 baro->start_up = lpsNothing;
298 baro->get_up = lpsRead;
299 baro->read_up = lpsNothingBool;
300 baro->calculate = lpsCalculate;
301 uint32_t timeout = millis();
302 do {
303 lpsRead(baro);
304 if ((millis() - timeout) > 500) return false;
305 } while (rawT == 0 && rawP == 0);
306 rawT = 0;
307 rawP = 0;
308 return true;
310 #endif