#ifndef PORTABLE_DS18B20_H #define PORTABLE_DS18B20_H #include #include #ifdef __cplusplus extern "C" { #endif #define DS18B20_ROM_SIZE 8U #define DS18B20_SCRATCHPAD_SIZE 9U typedef enum { DS18B20_OK = 0, DS18B20_E_ARGUMENT = -1, DS18B20_E_IO = -2, DS18B20_E_NO_DEVICE = -3, DS18B20_E_CRC = -4, DS18B20_E_TIMEOUT = -5, DS18B20_E_BUSY = -6, DS18B20_E_CAPACITY = -7, DS18B20_E_ROM = -8, DS18B20_E_POWER = -9 } ds18b20_status_t; typedef struct { void (*drive_low)(void *context); void (*release)(void *context); uint8_t (*read)(void *context); void (*delay_us)(void *context, uint32_t us); uint32_t (*tick_ms)(void *context); void (*critical_enter)(void *context); void (*critical_exit)(void *context); /* Optional callback used only while parasite-powered EEPROM is copied. */ void (*strong_pullup)(void *context, uint8_t enable); } ds18b20_onewire_ops_t; typedef struct { uint16_t attempts; uint16_t retries; uint16_t crc_errors; uint16_t io_errors; uint8_t passes_finished; uint8_t complete_passes; uint8_t last_error_bit; /* 1..64; 0 = reset or overall attempt limit. */ uint8_t last_error_pair; /* bit 1 = id, bit 0 = complement; 0xFF = no pair. */ ds18b20_status_t last_error; } ds18b20_search_diagnostics_t; typedef struct { const ds18b20_onewire_ops_t *ops; void *platform_context; uint8_t (*roms)[DS18B20_ROM_SIZE]; size_t rom_capacity; size_t rom_count; uint8_t search_rom[DS18B20_ROM_SIZE]; uint8_t last_discrepancy; uint8_t last_family_discrepancy; uint8_t last_device; uint8_t strong_pullup_active; uint8_t search_active; uint8_t search_retries; ds18b20_status_t search_result; ds18b20_search_diagnostics_t search_diagnostics; } ds18b20_t; ds18b20_status_t ds18b20_init(ds18b20_t *instance, const ds18b20_onewire_ops_t *ops, void *platform_context, uint8_t (*rom_storage)[DS18B20_ROM_SIZE], size_t rom_capacity); ds18b20_status_t ds18b20_search(ds18b20_t *instance); /* Incremental search keeps application services responsive by processing one * physical ROM attempt per call. Begin clears the previous result table. * BUSY includes internal retries/passes. All other results are terminal; * a failed search may still contain validated partial results. */ ds18b20_status_t ds18b20_search_begin(ds18b20_t *instance); ds18b20_status_t ds18b20_search_step(ds18b20_t *instance); /* Add a validated known ROM without bus traffic; duplicates are idempotent. * Call only outside an active search/conversion. Presence is checked by reads. */ ds18b20_status_t ds18b20_add_known_rom(ds18b20_t *instance, const uint8_t rom[DS18B20_ROM_SIZE]); size_t ds18b20_count(const ds18b20_t *instance); const uint8_t *ds18b20_rom(const ds18b20_t *instance, size_t index); uint8_t ds18b20_crc8(const void *data, size_t length); ds18b20_status_t ds18b20_validate_rom(const uint8_t rom[DS18B20_ROM_SIZE]); ds18b20_status_t ds18b20_start_all(ds18b20_t *instance); ds18b20_status_t ds18b20_start(ds18b20_t *instance, const uint8_t rom[DS18B20_ROM_SIZE]); ds18b20_status_t ds18b20_conversion_ready(ds18b20_t *instance); ds18b20_status_t ds18b20_wait(ds18b20_t *instance, uint32_t timeout_ms); ds18b20_status_t ds18b20_read_scratchpad( ds18b20_t *instance, const uint8_t rom[DS18B20_ROM_SIZE], uint8_t scratchpad[DS18B20_SCRATCHPAD_SIZE]); ds18b20_status_t ds18b20_decode_temperature( const uint8_t scratchpad[DS18B20_SCRATCHPAD_SIZE], float *temperature_c); ds18b20_status_t ds18b20_set_resolution( ds18b20_t *instance, const uint8_t rom[DS18B20_ROM_SIZE], uint8_t bits); ds18b20_status_t ds18b20_write_user_bytes( ds18b20_t *instance, const uint8_t rom[DS18B20_ROM_SIZE], int16_t bytes12, int16_t bytes34, uint8_t mask); ds18b20_status_t ds18b20_write_scratchpad( ds18b20_t *instance, const uint8_t rom[DS18B20_ROM_SIZE], uint8_t th, uint8_t tl, uint8_t configuration); ds18b20_status_t ds18b20_copy_scratchpad_start( ds18b20_t *instance, const uint8_t rom[DS18B20_ROM_SIZE], uint8_t parasite_power); ds18b20_status_t ds18b20_copy_scratchpad_finish( ds18b20_t *instance, uint8_t parasite_power); ds18b20_status_t ds18b20_recall_e2( ds18b20_t *instance, const uint8_t rom[DS18B20_ROM_SIZE]); ds18b20_status_t ds18b20_recall_ready(ds18b20_t *instance); void ds18b20_recover_bus(ds18b20_t *instance); uint8_t ds18b20_search_retry_due(const ds18b20_t *instance, uint8_t conversion_active, uint32_t now_ms, uint32_t last_attempt_ms, uint32_t retry_period_ms); /* Экземпляр не синхронизируется внутри: один вызов на одной шине должен быть * завершён до следующего. Из ISR API вызывать нельзя из-за задержек до 750 ms. */ #ifdef __cplusplus } #endif #endif