/**
******************************************************************************
* @file           dallas_tools.h
* @brief          Драйвер датчиков температуры DALLAS
******************************************************************************
* Этот файл предоставляет объявления и определения для работы с датчиками 
* температуры DS18B20. Он включает структуры данных, макросы и прототипы 
* функций для инициализации, чтения температуры 
* и управления датчиками.
*
* Работа с датчиками ведётся через протокол OneWire.
*****************************************************************************/

#ifndef DALLAS_TOOLS_H
#define DALLAS_TOOLS_H

/* Includes -----------------------------------------------------------------*/
#include "ds18b20_driver.h"
#include "onewire.h"


/* Определения пользовательских байтов для записи чтения */
#define DALLAS_USER_BYTE_1    (1<<0)  ///< Первый пользовательский байт
#define DALLAS_USER_BYTE_2    (1<<1)  ///< Второй пользовательский байт
#define DALLAS_USER_BYTE_3    (1<<2)  ///< Третий пользовательский байт
#define DALLAS_USER_BYTE_4    (1<<3)  ///< Четвёртый пользовательский байт

#define DALLAS_USER_BYTE_12   (DALLAS_USER_BYTE_1|DALLAS_USER_BYTE_2) ///< Первые два байта
#define DALLAS_USER_BYTE_34   (DALLAS_USER_BYTE_3|DALLAS_USER_BYTE_4) ///< Вторые два байта
#define DALLAS_USER_BYTE_ALL  (DALLAS_USER_BYTE_12|DALLAS_USER_BYTE_34) ///< Все пользовательские байты

/* Declarations and definitions ---------------------------------------------*/
#define DALLAS_ROM_SIZE                                                   8

#define DALLAS_CONFIG_9_BITS                                              0x1F
#define DALLAS_CONFIG_10_BITS                                             0x3F
#define DALLAS_CONFIG_11_BITS                                             0x5F
#define DALLAS_CONFIG_12_BITS                                             0x7F

#define DALLAS_DELAY_MS_9_BITS                                            94
#define DALLAS_DELAY_MS_10_BITS                                           188
#define DALLAS_DELAY_MS_11_BITS                                           375
#define DALLAS_DELAY_MS_12_BITS                                           750
#define DALLAS_DELAY_MS_MAX                                               DALLAS_DELAY_MS_12_BITS

typedef struct _SensorHandleStruct DALLAS_SensorHandleTypeDef;
typedef struct _DallasHandleStruct DALLAS_HandleTypeDef;

/** @brief Структура Scratchpad датчика DALLAS */
typedef struct
{
  uint8_t TemperatureLSB;   ///< Младший байт температуры
  uint8_t TemperatureMSB;   ///< Старший байт температуры
  uint8_t tHighRegister;    ///< Верхний температурный порог
  uint8_t tLowRegister;     ///< Нижний температурный порог
  uint8_t ConfigRegister;   ///< Конфигурационный регистр
  uint8_t reserved;         ///< Зарезервировано
  uint8_t UserByte3;        ///< Пользовательский байт 3
  uint8_t UserByte4;        ///< Пользовательский байт 4
  uint8_t ScratchpadCRC;    ///< Контрольная сумма
}DALLAS_ScratchpadTypeDef;

/** @brief Структура флагов ошибок датчиков DALLAS */
typedef struct
{
  uint8_t disconnect_cnt;            ///< Счетчик отключений датчика
  uint8_t read_temperature_err_cnt;  ///< Счетчик ошибок чтения температуры
  uint8_t timeout_convertion_cnt;    ///< Счетчик ошибок таймаута конвертации
  uint8_t write_err_cnt;             ///< Счетчик других ошибок
}DALLAS_FlagsTypeDef;


/** @brief Структура инициализации датчика DALLAS */
typedef struct __packed
{
  union
  {
    uint64_t  Ind;          ///< порядковый номер датчика
    uint64_t  ROM;          ///< ROM датчика
    struct  
    {
      uint8_t UserByte1;    ///< Младший байт (бит 0–7)
      uint8_t UserByte2;    ///< Следующий байт (бит 8–15)
      uint8_t UserByte3;    ///< Байт (бит 16–23)
      uint8_t UserByte4;    ///< Байт (бит 24–31)
      uint8_t Reserved[4];  ///< Остальные байты (бит 32–63, если нужно)
    } UserBytes;            ///< UserBytes датчика
  }InitParam;                           ///< Параметр для инициализации: ROM/UserBytes/Индекс
  uint8_t             Resolution;       ///< Разрешение датчика
  HAL_StatusTypeDef   (*init_func)(DALLAS_HandleTypeDef *, DALLAS_SensorHandleTypeDef *);   ///< Функция инициализации
} DALLAS_InitStructTypeDef;



/** @brief Cтруктура обработчика DALLAS для общения с датчиком*/
struct _DallasHandleStruct
{
  OneWire_t                   *onewire;
  DS18B20_Drv_t               *ds_devices;
  DALLAS_ScratchpadTypeDef    scratchpad;  
};
extern DALLAS_HandleTypeDef hdallas;

/** @brief Основная структура обработчика датчика DALLAS */
struct  _SensorHandleStruct 
{
  unsigned                  isConnected:1;            ///< Флаг соединения
  unsigned                  isInitialized:1;          ///< Флаг инициализации
  unsigned                  isLost:1;                 ///< Флаг потери связи
	uint16_t 									lost_cnt;
	DALLAS_FlagsTypeDef       f;                        ///< Флаги
	
	
	float 										set_temp;	
	uint16_t 									hyst;
  
  DALLAS_HandleTypeDef      *hdallas;
  uint64_t                  sensROM;                  ///< ROM-код датчика
  
  float                     temperature;              ///< Текущая температура
  
  DALLAS_InitStructTypeDef  Init;                     ///< Структура инициализации
  
  
};



/** @brief Варианты ожидания окончания конверсии */
typedef enum
{
  DALLAS_WAIT_NONE      = 0x00,   ///< Без ожидания окончания конверсии
  DALLAS_WAIT_BUS       = 0x01,   ///< Ожидание окончания конверсии по шине (опрос датчиков - чтение бита)
  DALLAS_WAIT_DELAY     = 0x02,   ///< Без ожидания окончания через задержку (максимальная задержка для заданной разрядности)
} DALLAS_WaitConvertionTypeDef;



/* Functions ---------------------------------------------------------------*/

HAL_StatusTypeDef Dallas_BusFirstInit(TIM_HandleTypeDef *htim);
/* Функция для иниицализации нового датчика в структуре */
HAL_StatusTypeDef Dallas_AddNewSensors(DALLAS_HandleTypeDef *hdallas, DALLAS_SensorHandleTypeDef *sensor);
/* Инициализирует структуру датчика по ROM */
HAL_StatusTypeDef Dallas_SensorInitByROM(DALLAS_HandleTypeDef *hdallas, DALLAS_SensorHandleTypeDef *sensor);
/* Инициализирует структуру датчика по пользовательским байтам */
HAL_StatusTypeDef Dallas_SensorInitByUserBytes(DALLAS_HandleTypeDef *hdallas, DALLAS_SensorHandleTypeDef *sensor);
/* Инициализирует структуру датчика по порядковому номеру */
HAL_StatusTypeDef Dallas_SensorInitByInd(DALLAS_HandleTypeDef *hdallas, DALLAS_SensorHandleTypeDef *sensor);
/* Инициализирует датчик для работы */
HAL_StatusTypeDef Dallas_SensorInit(DALLAS_HandleTypeDef *hdallas, DALLAS_SensorHandleTypeDef *sensor, uint8_t (*ROM)[DALLAS_ROM_SIZE]);
/* Деинициализирует структуру датчика */
HAL_StatusTypeDef Dallas_SensorDeInit(DALLAS_SensorHandleTypeDef *sensor);
/* Функция для нахождения нового датчика на место потерянного */
HAL_StatusTypeDef Dallas_ReplaceLostedSensor(DALLAS_SensorHandleTypeDef *sensor);
/* Запускает измерение температуры на всех датчиках */
HAL_StatusTypeDef Dallas_StartConvertTAll(DALLAS_HandleTypeDef *hdallas, DALLAS_WaitConvertionTypeDef waitCondition, uint8_t dallas_delay_ms);
/* Измеряет температуру на датчике */
HAL_StatusTypeDef Dallas_ConvertT(DALLAS_SensorHandleTypeDef *sensor, DALLAS_WaitConvertionTypeDef waitCondition);
/* Читает измеренную датчиком температуру */
HAL_StatusTypeDef Dallas_ReadTemperature(DALLAS_SensorHandleTypeDef *sensor);
/* Проверяет подключен ли датчик (чтение scratchpad) */
HAL_StatusTypeDef Dallas_IsConnected(DALLAS_SensorHandleTypeDef *sensor);
/* Записывает пользовательские байты */
HAL_StatusTypeDef Dallas_WriteUserBytes(DALLAS_SensorHandleTypeDef *sensor, uint16_t UserBytes12, uint16_t UserBytes34, uint8_t UserBytesMask);
/* Записывает пользовательские байты */
HAL_StatusTypeDef Dallas_ReadScratchpad(DALLAS_SensorHandleTypeDef *sensor);


#endif // #ifndef DALLAS_TOOLS_H