Blackbox device type 'file' (SITL) considered working when file handler is available
[inav.git] / src / main / drivers / temperature / ds18b20.c
blob918ff870f4b1f643374eba162e2451f16d4121a4
1 /*
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/>.
18 #include <stdbool.h>
19 #include <stdint.h>
21 #include "platform.h"
23 #include "build/debug.h"
25 #include "drivers/1-wire.h"
26 #include "drivers/1-wire/ds2482.h"
27 #include "drivers/1-wire/ds_crc.h"
28 #include "drivers/temperature/ds18b20.h"
31 #define DS18B20_FAMILY_CODE 0x28
33 #define DS18B20_ALARM_SEARCH_CMD 0xEC
34 #define DS18B20_START_CONVERSION_CMD 0x44
35 #define DS18B20_WRITE_SCRATCHPAD_CMD 0x4E
36 #define DS18B20_READ_SCRATCHPAD_CMD 0xBE
37 #define DS18B20_COPY_SCRATCHPAD_CMD 0x48
38 #define DS18B20_RECALL_EEPROM_CMD 0xB8
39 #define DS18B20_READ_POWER_SUPPLY_CMD 0xB4
41 #if defined(USE_1WIRE) && defined(USE_TEMPERATURE_DS18B20)
44 bool ds18b20Enumerate(owDev_t *owDev, uint64_t *rom_table, uint8_t *rom_table_len)
46 return owDev->owSearchRom(owDev, DS18B20_FAMILY_CODE, rom_table, rom_table_len);
49 bool ds18b20Configure(owDev_t *owDev, uint64_t rom, uint8_t config)
51 bool ack = owDev->owMatchRom(owDev, rom);
52 if (!ack) return false;
54 uint8_t buf[4] = { DS18B20_WRITE_SCRATCHPAD_CMD, 0, 0, config };
55 return owDev->owWriteBuf(owDev, buf, sizeof(buf));
58 static bool readPowerSupply(owDev_t *owDev, bool *result)
60 bool ack = owDev->owWriteByte(owDev, DS18B20_READ_POWER_SUPPLY_CMD);
61 if (!ack) return false;
63 bool sbr;
64 ack = owDev->owSingleBit(owDev, OW_SINGLE_BIT_WRITE1_READ, &sbr);
65 if (!ack) return false;
67 *result = !sbr;
68 return true;
71 bool ds18b20ParasiticPoweredPresent(owDev_t *owDev, bool *result)
73 bool ack = owDev->owSkipRom(owDev);
74 if (!ack) return false;
76 return readPowerSupply(owDev, result);
79 bool ds18b20ReadPowerSupply(owDev_t *owDev, uint64_t rom, bool *parasiticPowered)
81 bool ack = owDev->owMatchRom(owDev, rom);
82 if (!ack) return false;
84 return readPowerSupply(owDev, parasiticPowered);
87 bool ds18b20ReadScratchpadCommand(owDev_t *owDev)
89 return owDev->owWriteByteCommand(owDev, DS18B20_READ_SCRATCHPAD_CMD);
92 static bool ds18b20ReadScratchpadBuf(owDev_t *owDev, uint8_t *buf, uint8_t len)
94 bool ack = ds18b20ReadScratchpadCommand(owDev);
95 if (!ack) return false;
96 ack = owDev->waitForBus(owDev);
97 if (!ack) return false;
98 return owDev->owReadBuf(owDev, buf, len);
101 bool ds18b20StartConversionCommand(owDev_t *owDev)
103 return owDev->owWriteByteCommand(owDev, DS18B20_START_CONVERSION_CMD);
106 // start conversion on all devices present on the bus
107 // note: parasitic power only supports one device converting at a time
108 bool ds18b20StartConversion(owDev_t *owDev)
110 bool ack = owDev->owSkipRom(owDev);
111 if (!ack) return false;
112 return ds18b20StartConversionCommand(owDev);
115 bool ds18b20WaitForConversion(owDev_t *owDev)
117 bool ack = owDev->waitForBus(owDev);
118 if (!ack) return false;
120 bool read_bit;
121 do {
122 ack = owDev->owSingleBit(owDev, OW_SINGLE_BIT_WRITE1_READ, &read_bit);
123 if (!ack) return false;
124 } while (!read_bit);
126 return true;
129 bool ds18b20ReadTemperatureFromScratchPadBuf(const uint8_t *buf, int16_t *temperature)
131 if (buf[8] != ds_crc8(buf, 8)) return false;
132 *temperature = (int16_t)(((buf[0] | (buf[1] << 8)) >> 3) | ((buf[1] & 0x80) ? 0xE000 : 0)) * 5;
133 return true;
136 bool ds18b20ReadTemperature(owDev_t *owDev, uint64_t rom, int16_t *temperature)
138 bool ack = owDev->owMatchRom(owDev, rom);
139 if (!ack) return false;
141 uint8_t buf[9];
142 ack = ds18b20ReadScratchpadBuf(owDev, buf, 9);
143 if (!ack) return false;
145 return ds18b20ReadTemperatureFromScratchPadBuf(buf, temperature);
148 #endif /* defined(USE_1WIRE) && defined(USE_TEMPERATURE_DS18B20) */