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/>.
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;
64 ack
= owDev
->owSingleBit(owDev
, OW_SINGLE_BIT_WRITE1_READ
, &sbr
);
65 if (!ack
) return false;
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;
122 ack
= owDev
->owSingleBit(owDev
, OW_SINGLE_BIT_WRITE1_READ
, &read_bit
);
123 if (!ack
) return false;
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;
136 bool ds18b20ReadTemperature(owDev_t
*owDev
, uint64_t rom
, int16_t *temperature
)
138 bool ack
= owDev
->owMatchRom(owDev
, rom
);
139 if (!ack
) return false;
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) */