#include "ds18b20_ds2480.h" #include static ds2480_status write_byte(ds2480 *bus, uint8_t value) { uint8_t echoed; ds2480_status status = ds2480_byte(bus, value, &echoed); if (status != DS2480_OK) return status; return echoed == value ? DS2480_OK : DS2480_DATA; } static ds2480_status select_rom(ds2480 *bus, const uint8_t *rom) { uint8_t i; ds2480_status status; if (rom && (rom[0] != 0x28 || ds2480_crc8(rom, 8))) return DS2480_ARGUMENT; status = ds2480_reset(bus); if (status != DS2480_OK) return status; status = write_byte(bus, rom ? 0x55 : 0xCC); if (status != DS2480_OK || !rom) return status; for (i = 0; i < 8; ++i) { status = write_byte(bus, rom[i]); if (status != DS2480_OK) return status; } return DS2480_OK; } ds2480_status ds18b20_ds2480_next(ds2480 *bus, ds2480_search *search) { ds2480_status status; do { status = ds2480_search_next(bus, search); if (status != DS2480_OK) return status; } while (search->rom[0] != 0x28); return DS2480_OK; } ds2480_status ds18b20_ds2480_convert(ds2480 *bus, const uint8_t rom[8]) { ds2480_status status = select_rom(bus, rom); if (status != DS2480_OK) return status; return ds2480_power_byte(bus, 0x44, 750); } ds2480_status ds18b20_ds2480_read(ds2480 *bus, const uint8_t rom[8], uint8_t scratchpad[9]) { uint8_t data[9], i; ds2480_status status; if (!rom || !scratchpad) return DS2480_ARGUMENT; status = select_rom(bus, rom); if (status != DS2480_OK) return status; status = write_byte(bus, 0xBE); if (status != DS2480_OK) return status; for (i = 0; i < 9; ++i) { status = ds2480_byte(bus, 0xFF, &data[i]); if (status != DS2480_OK) return status; } if (ds2480_crc8(data, 9)) return DS2480_CRC; /* All-zero data has valid CRC but cannot be a DS18B20 scratchpad. */ if ((data[4] & 0x9F) != 0x1F) return DS2480_DATA; memcpy(scratchpad, data, sizeof data); return DS2480_OK; } ds2480_status ds18b20_ds2480_temperature(ds2480 *bus, const uint8_t rom[8], int16_t *raw) { uint8_t data[9], undefined; uint16_t value; int32_t signed_value; ds2480_status status; if (!raw) return DS2480_ARGUMENT; status = ds18b20_ds2480_read(bus, rom, data); if (status != DS2480_OK) return status; undefined = (uint8_t)(3 - ((data[4] >> 5) & 3)); value = (uint16_t)((uint16_t)data[0] | ((uint16_t)data[1] << 8)); value &= (uint16_t)~((1U << undefined) - 1U); signed_value = value & 0x8000 ? (int32_t)value - 65536 : (int32_t)value; if (signed_value < -55 * 16 || signed_value > 125 * 16) return DS2480_DATA; *raw = (int16_t)signed_value; return DS2480_OK; } ds2480_status ds18b20_ds2480_configure(ds2480 *bus, const uint8_t rom[8], int8_t th, int8_t tl, uint8_t resolution, uint8_t save) { uint8_t data[9], config; ds2480_status status; if (!rom || resolution < 9 || resolution > 12) return DS2480_ARGUMENT; config = (uint8_t)(0x1F | ((resolution - 9) << 5)); status = select_rom(bus, rom); if (status != DS2480_OK) return status; status = write_byte(bus, 0x4E); if (status != DS2480_OK) return status; status = write_byte(bus, (uint8_t)th); if (status != DS2480_OK) return status; status = write_byte(bus, (uint8_t)tl); if (status != DS2480_OK) return status; status = write_byte(bus, config); if (status != DS2480_OK) return status; status = ds18b20_ds2480_read(bus, rom, data); if (status != DS2480_OK) return status; if (data[2] != (uint8_t)th || data[3] != (uint8_t)tl || data[4] != config) return DS2480_DATA; if (!save) return DS2480_OK; status = select_rom(bus, rom); if (status != DS2480_OK) return status; return ds2480_power_byte(bus, 0x48, 12); }