/**
******************************************************************************
* @file           pch_sensors.h
* @brief          Работа с датчиками температуры DS18B20 в ПЧ
******************************************************************************
*****************************************************************************/

#ifndef PCH_SENSORS_H
#define PCH_SENSORS_H



/* Includes -----------------------------------------------------------------*/
#include "dallas_tools.h"

/* Declarations and definitions ---------------------------------------------*/
#define USED_USER_BYTES               DALLAS_USER_BYTE_12

/* Позиции параметров в UserBytes */
#define REG_SENS_LOCATION_Pos         (0)     /*!< @brief Позиция параметра "Локация внутри модуля" */

#define REG_PCH_LOCATION_Pos          (8)     /*!< @brief Позиция параметра "Расположение в ПЧ" */
#define REG_PCH_DIOD_PHASE_Pos        (10)    /*!< @brief Позиция параметра "Диодный или фазный модуль" @ref REG_PCH_LOCATION_Pos */
#define REG_PCH_MODULE_NUMB_Pos       (8)     /*!< @brief Позиция параметра "Порядковый номер диодного/фазного модуля" @ref REG_PCH_LOCATION_Pos */

#define REG_PCH_NUMB_Pos              (11)    /*!< @brief Позиция параметра "Преобразователь частоты" */
#define REG_PCH_NUMB_DIGIT_1_Pos      (13)    /*!< @brief Позиция параметра "Первая цифра номера преобразователя частоты" @ref REG_PCH_NUMB_Pos */
#define REG_PCH_NUMB_DIGIT_2_Pos      (11)    /*!< @brief Позиция параметра "Вторая цифра номера преобразователя частоты" @ref REG_PCH_NUMB_Pos */
    
#define REG_ZIP_Pos                   (15)    /*!< @brief Позиция параметра "ЗИП/не ЗИП" */

/* Маски параметров в UserBytes */
#define REG_SENS_LOCATION_Mask        ((uint16_t)0x3 << REG_SENS_LOCATION_Pos)      /*!< @brief Маска параметра "Локация внутри модуля" */

#define REG_PCH_LOCATION_Mask         ((uint16_t)0x7 << REG_PCH_LOCATION_Pos)       /*!< @brief Маска параметра "Расположение в ПЧ" */
#define REG_PCH_DIOD_PHASE_Mask       ((uint16_t)0x1 << REG_PCH_DIOD_PHASE_Pos)     /*!< @brief Маска параметра "Диодный или фазный модуль" */
#define REG_PCH_MODULE_NUMB_Mask      ((uint16_t)0x3 << REG_PCH_MODULE_NUMB_Pos)    /*!< @brief Маска параметра "Порядковый номер диодного/фазного модуля" */

#define REG_PCH_NUMB_Mask             ((uint16_t)0xF << REG_PCH_NUMB_Pos)           /*!< @brief Маска параметра "Преобразователь частоты" */
#define REG_PCH_NUMB_DIGIT_1_Mask     ((uint16_t)0x3 << REG_PCH_NUMB_DIGIT_1_Pos)   /*!< @brief Маска параметра "Первая цифра номера преобразователя частоты" */
#define REG_PCH_NUMB_DIGIT_2_Mask     ((uint16_t)0x3 << REG_PCH_NUMB_DIGIT_2_Pos)   /*!< @brief Маска параметра "Вторая цифра номера преобразователя частоты" */
    
#define REG_ZIP_Mask                  ((uint16_t)0x1 << REG_ZIP_Pos)                /*!< @brief Маска параметра "ЗИП/не ЗИП" */

/* Варианты параметров в UserBytes */
#define REG_PCH_NUMB_11               ((1 << REG_PCH_NUMB_DIGIT_1_Pos) | (1 << REG_PCH_NUMB_DIGIT_2_Pos))
#define REG_PCH_NUMB_12               ((1 << REG_PCH_NUMB_DIGIT_1_Pos) | (2 << REG_PCH_NUMB_DIGIT_2_Pos))
#define REG_PCH_NUMB_21               ((2 << REG_PCH_NUMB_DIGIT_1_Pos) | (1 << REG_PCH_NUMB_DIGIT_2_Pos))
#define REG_PCH_NUMB_22               ((2 << REG_PCH_NUMB_DIGIT_1_Pos) | (2 << REG_PCH_NUMB_DIGIT_2_Pos))
#define REG_PCH_NUMB_31               ((3 << REG_PCH_NUMB_DIGIT_1_Pos) | (1 << REG_PCH_NUMB_DIGIT_2_Pos))
#define REG_PCH_NUMB_32               ((3 << REG_PCH_NUMB_DIGIT_1_Pos) | (2 << REG_PCH_NUMB_DIGIT_2_Pos))

#define REG_PCH_DIODE_NUMB_1          ((0 << REG_PCH_DIOD_PHASE_Pos) | (1 << REG_PCH_MODULE_NUMB_Pos))
#define REG_PCH_DIODE_NUMB_2          ((0 << REG_PCH_DIOD_PHASE_Pos) | (2 << REG_PCH_MODULE_NUMB_Pos))
#define REG_PCH_DIODE_NUMB_3          ((0 << REG_PCH_DIOD_PHASE_Pos) | (3 << REG_PCH_MODULE_NUMB_Pos))
#define REG_PCH_PHASE_NUMB_1          ((1 << REG_PCH_DIOD_PHASE_Pos) | (1 << REG_PCH_MODULE_NUMB_Pos))
#define REG_PCH_PHASE_NUMB_2          ((1 << REG_PCH_DIOD_PHASE_Pos) | (2 << REG_PCH_MODULE_NUMB_Pos))
#define REG_PCH_PHASE_NUMB_3          ((1 << REG_PCH_DIOD_PHASE_Pos) | (3 << REG_PCH_MODULE_NUMB_Pos))

/* Получить параметр из UserBytes */
#define GET_REG_SENS_LOCATION(_REG_)      ((_REG_) & REG_SENS_LOCATION_Mask)      /*!< @brief Получить параметр "Локация внутри модуля" */

#define GET_REG_PCH_LOCATION(_REG_)       ((_REG_) & REG_PCH_LOCATION_Mask)       /*!< @brief Получить параметр "Расположение в ПЧ" */
#define GET_REG_PCH_DIOD_PHASE(_REG_)     ((_REG_) & REG_PCH_DIOD_PHASE_Mask)     /*!< @brief Получить параметр "Диодный или фазный модуль" */
#define GET_REG_PCH_MODULE_NUMB(_REG_)    ((_REG_) & REG_PCH_MODULE_NUMB_Mask)    /*!< @brief Получить параметр "Порядковый номер диодного/фазного модуля" */

#define GET_REG_PCH_NUMB(_REG_)           ((_REG_) & REG_PCH_NUMB_Mask)           /*!< @brief Получить параметр "Преобразователь частоты" */
#define GET_REG_PCH_NUMB_DIGIT_1(_REG_)   ((_REG_) & REG_PCH_NUMB_DIGIT_1_Mask)   /*!< @brief Получить параметр "Первая цифра номера преобразователя частоты" */
#define GET_REG_PCH_NUMB_DIGIT_2(_REG_)   ((_REG_) & REG_PCH_NUMB_DIGIT_2_Mask)   /*!< @brief Получить параметр "Вторая цифра номера преобразователя частоты" */
    
#define GET_REG_ZIP(_REG_)                ((_REG_) & REG_ZIP_Mask)                /*!< @brief Получить параметр "ЗИП/не ЗИП" */

/* Диапазоны параметров из UserBytes */
#define REG_SENS_LOCATION_MAX     3
#define REG_SENS_LOCATION_MIN     0
#define REG_PCH_DIOD_PHASE_MAX    1
#define REG_PCH_DIOD_PHASE_MIN    0
#define REG_PCH_MODULE_NUMB_MAX   3
#define REG_PCH_MODULE_NUMB_MIN   0
#define REG_PCH_NUMB_DIGIT_1_MAX  3
#define REG_PCH_NUMB_DIGIT_1_MIN  1
#define REG_PCH_NUMB_DIGIT_2_MAX  2
#define REG_PCH_NUMB_DIGIT_2_MIN  1


/** @brief Получить параметр "Локация внутри модуля" */
#define IS_REG_SENS_LOCATION(_REG_)      (((_REG_)->param.Location <= REG_SENS_LOCATION_MAX) && ((_REG_)->param.Location >= REG_SENS_LOCATION_MIN))

/*!< @brief Получить параметр "Расположение в ПЧ" */
#define IS_REG_PCH_LOCATION(_REG_)       (IS_REG_PCH_DIOD_PHASE(_REG_) && IS_REG_PCH_MODULE_NUMB(_REG_))
/*!< @brief Получить параметр "Диодный или фазный модуль" */
#define IS_REG_PCH_DIOD_PHASE(_REG_)     (((_REG_)->param.DiodeOrPhase <= REG_PCH_DIOD_PHASE_MAX) && ((_REG_)->param.DiodeOrPhase >= REG_PCH_DIOD_PHASE_MIN))
/*!< @brief Получить параметр "Порядковый номер диодного/фазного модуля" */
#define IS_REG_PCH_MODULE_NUMB(_REG_)    (((_REG_)->param.ModuleNumb <= REG_PCH_MODULE_NUMB_MAX) && ((_REG_)->param.ModuleNumb >= REG_PCH_MODULE_NUMB_MIN))

/*!< @brief Получить параметр "Преобразователь частоты" */
#define IS_REG_PCH_NUMB(_REG_)           (IS_REG_PCH_NUMB_DIGIT_1(_REG_) && IS_REG_PCH_NUMB_DIGIT_2(_REG_)) 
/*!< @brief Получить параметр "Первая цифра номера преобразователя частоты" */
#define IS_REG_PCH_NUMB_DIGIT_1(_REG_)   (((_REG_)->param.PCHdig1 <= REG_PCH_NUMB_DIGIT_1_MAX) && ((_REG_)->param.PCHdig1 >= REG_PCH_NUMB_DIGIT_1_MIN))
/*!< @brief Получить параметр "Вторая цифра номера преобразователя частоты" */
#define IS_REG_PCH_NUMB_DIGIT_2(_REG_)   (((_REG_)->param.PCHdig2 <= REG_PCH_NUMB_DIGIT_2_MAX) && ((_REG_)->param.PCHdig2 >= REG_PCH_NUMB_DIGIT_2_MIN))
/*!< @brief Получить параметр "ЗИП/не ЗИП" */
#define IS_REG_ZIP(_REG_)                (GET_REG_ZIP(_REG_))

typedef union
{
  uint16_t all;
  struct
  {
    unsigned Location:2; 
    unsigned reserved:6;
    unsigned ModuleNumb:2;
    unsigned DiodeOrPhase:1;
    unsigned PCHdig2:2;
    unsigned PCHdig1:2;
    unsigned ZIP:1;
  }param;
}PCHSens_LocationTypeDef;


typedef struct
{
  unsigned convertion;
  uint64_t connectROM;
  unsigned read;
  unsigned deinit;
}PCHSens_SensorActionsTypeDef;
extern PCHSens_SensorActionsTypeDef action;

typedef struct
{
  DALLAS_SensorHandleTypeDef    sens;
  PCHSens_LocationTypeDef       Location;
  unsigned                      not_found:1;
}PCHSens_SensorTypeDef;

typedef struct
{
  DALLAS_HandleTypeDef      *hdallas;
  
  PCHSens_SensorTypeDef     sens1;
  PCHSens_SensorTypeDef     sens2;
  PCHSens_SensorTypeDef     sens3;
  PCHSens_SensorTypeDef     sens4;
  
  PCHSens_LocationTypeDef   refLocation; 
  
}PCHSens_ModuleTypeDef;

typedef struct
{
  DALLAS_HandleTypeDef        *hdallas;
  uint8_t                     UnknownCnt;
}PCHSens_DallasBusHandle;


typedef struct
{
  PCHSens_ModuleTypeDef module1;
  PCHSens_ModuleTypeDef module2;
  PCHSens_ModuleTypeDef module3;
  PCHSens_ModuleTypeDef module4;
  PCHSens_ModuleTypeDef module5;
  PCHSens_ModuleTypeDef module6;
}PCHSens_TypeDef;

/* Functions ---------------------------------------------------------------*/
HAL_StatusTypeDef PCHSens_InitNewSensor(DALLAS_HandleTypeDef *hdallas, PCHSens_SensorTypeDef* sensor, uint64_t ROM);
HAL_StatusTypeDef PCHSens_AddSensor(DALLAS_HandleTypeDef *hdallas, PCHSens_SensorTypeDef* sensor);
HAL_StatusTypeDef PCHSens_InitModule(DALLAS_HandleTypeDef *hdallas, PCHSens_ModuleTypeDef* module, uint16_t param);
HAL_StatusTypeDef PCHSens_ModuleReadTemperature(PCHSens_ModuleTypeDef* module);
HAL_StatusTypeDef PCHSens_SensorReadTemperature(DALLAS_HandleTypeDef *hdallas, PCHSens_SensorTypeDef *sensor);
HAL_StatusTypeDef PCHSens_ReadTemperature(PCHSens_SensorTypeDef* sensor);
HAL_StatusTypeDef PCHSens_StartCovert(PCHSens_DallasBusHandle *hbus);
HAL_StatusTypeDef PCHSens_CheckSensor(DALLAS_HandleTypeDef *hdallas, PCHSens_SensorTypeDef* sensor);
HAL_StatusTypeDef PCHSens_FindUnknownSensors(PCHSens_DallasBusHandle *hbus);
HAL_StatusTypeDef PCHSens_UndefineSensor(PCHSens_SensorTypeDef *sensor);
HAL_StatusTypeDef PCHSens_GetSensorByLocation(PCHSens_TypeDef *pchsens, PCHSens_LocationTypeDef Location, PCHSens_SensorTypeDef **sensor);
#endif // #ifndef PCH_SENSORS_H