2 * This file is part of Cleanflight.
4 * Cleanflight is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * Cleanflight is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
22 #include <build/debug.h>
24 #include "common/log.h"
25 #include "common/utils.h"
26 #include "common/maths.h"
27 #include "drivers/bus_i2c.h"
28 #include "drivers/time.h"
29 #include "drivers/pitotmeter/pitotmeter.h"
31 #define DLVR_L10D_ADDR 0x28 // this var is not used !!!
33 // //---------------------------------------------------
34 // // Gas Constant is from Aerodynamics for Engineering Students, Third Edition, E.L.Houghton and N.B.Carruthers
35 // #define ISA_GAS_CONSTANT 287.26f
36 // #define ISA_LAPSE_RATE 0.0065f
38 // // Standard Sea Level values
39 // // Ref: https://en.wikipedia.org/wiki/Standard_sea_level
40 // #define SSL_AIR_DENSITY 1.225f // kg/m^3
41 // #define SSL_AIR_PRESSURE 101325.01576f // Pascal
42 // #define SSL_AIR_TEMPERATURE 288.15f // K
43 // //---------------------------------------------------
45 #define INCH_OF_H2O_TO_PASCAL 248.84f
47 #define INCH_H2O_TO_PASCAL(press) (INCH_OF_H2O_TO_PASCAL * (press))
49 #define RANGE_INCH_H2O 10
50 #define DLVR_OFFSET 8192.0f
51 #define DLVR_SCALE 16384.0f
52 // NOTE :: DLVR_OFFSET_CORR can be used for offset correction. Now firmware relies on zero calibration
53 #define DLVR_OFFSET_CORR 0.0f //-9.0f
56 typedef struct __attribute__ ((__packed__
)) dlvrCtx_s
{
62 STATIC_ASSERT(sizeof(dlvrCtx_t
) < BUS_SCRATCHPAD_MEMORY_SIZE
, busDevice_scratchpad_memory_too_small
);
64 static bool dlvr_start(pitotDev_t
* pitot
)
70 static bool dlvr_read(pitotDev_t
* pitot
)
74 dlvrCtx_t
* ctx
= busDeviceGetScratchpadMemory(pitot
->busDev
);
75 ctx
->dataValid
= false;
77 if (!busReadBuf(pitot
->busDev
, 0xFF, rxbuf1
, 4)) {
81 // status = 00 -> ok, new data
82 // status = 01 -> reserved
83 // status = 10 -> ok, data stale
84 // status = 11 -> error
85 const uint8_t status
= ((rxbuf1
[0] & 0xC0) >> 6);
88 // anything other then 00 in the status bits is an error
89 LOG_DEBUG( PITOT
, "DLVR: Bad status read. status = %u", (unsigned int)(status
) );
93 int16_t dP_raw1
, dT_raw1
;
95 dP_raw1
= 0x3FFF & ((rxbuf1
[0] << 8) + rxbuf1
[1]);
96 dT_raw1
= (0xFFE0 & ((rxbuf1
[2] << 8) + rxbuf1
[3])) >> 5;
98 // Data valid, update ut/up values
99 ctx
->dataValid
= true;
100 ctx
->dlvr_up
= dP_raw1
;
101 ctx
->dlvr_ut
= dT_raw1
;
106 static void dlvr_calculate(pitotDev_t
* pitot
, float *pressure
, float *temperature
)
108 dlvrCtx_t
* ctx
= busDeviceGetScratchpadMemory(pitot
->busDev
);
111 // pressure in inchH2O
112 float dP_inchH2O
= 1.25f
* 2.0f
* RANGE_INCH_H2O
* (((float)ctx
->dlvr_up
- (DLVR_OFFSET
+ DLVR_OFFSET_CORR
) ) / DLVR_SCALE
);
114 // temperature in deg C
115 float T_C
= (float)ctx
->dlvr_ut
* (200.0f
/ 2047.0f
) - 50.0f
;
117 // result must fit inside the max pressure range
118 if ((dP_inchH2O
> RANGE_INCH_H2O
) || (dP_inchH2O
< -RANGE_INCH_H2O
)) {
119 LOG_DEBUG( PITOT
,"DLVR: Out of range. pressure = %f", (double)(dP_inchH2O
) );
124 *pressure
= INCH_H2O_TO_PASCAL( dP_inchH2O
); // Pa
128 *temperature
= C_TO_KELVIN( T_C
); // K
132 bool dlvrDetect(pitotDev_t
* pitot
)
137 pitot
->busDev
= busDeviceInit(BUSTYPE_I2C
, DEVHW_DLVR
, 0, OWNER_AIRSPEED
);
138 if (pitot
->busDev
== NULL
) {
142 // Read twice to fix:
143 // Sending a start-stop condition without any transitions on the SCL line (no clock pulses in between) creates a
144 // communication error for the next communication, even if the next start condition is correct and the clock pulse is applied.
145 // An additional start condition must be sent, which results in restoration of proper communication.
146 ack
= busReadBuf(pitot
->busDev
, 0xFF, rxbuf
, 4);
147 ack
= busReadBuf(pitot
->busDev
, 0xFF, rxbuf
, 4);
152 // Initialize busDev data
153 dlvrCtx_t
* ctx
= busDeviceGetScratchpadMemory(pitot
->busDev
);
154 ctx
->dataValid
= false;
158 // Initialize pitotDev object
159 pitot
->delay
= 10000;
160 pitot
->calibThreshold
= 0.00001f
; // low noise sensor
161 pitot
->start
= dlvr_start
;
162 pitot
->get
= dlvr_read
;
163 pitot
->calculate
= dlvr_calculate
;