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


/* Includes ----------------------------------------------------------------*/

#include "pch_sensors.h"
#include "modbus_data.h"

/* Declarations and definitions --------------------------------------------*/
 
/* Functions ---------------------------------------------------------------*/
HAL_StatusTypeDef PCHSens_InitNewSensor(DALLAS_HandleTypeDef *hdallas, PCHSens_SensorTypeDef* sensor, uint64_t ROM)
{  
  DALLAS_SensorHandleTypeDef tempsens;  
  HAL_StatusTypeDef result;
  if(hdallas == NULL)
    return HAL_ERROR;
  if(sensor == NULL)
    return HAL_ERROR;
    
//  sensor->UserBytes = (PCHSens_LocationTypeDef *)&sensor->sens.scratchpad.tHighRegister;
  
  sensor->sens.Init.InitParam = ROM;  
  sensor->sens.Init.init_func = &Dallas_SensorInitByROM;
    
  result = Dallas_AddNewSensors(hdallas, &sensor->sens);
  if(result != HAL_OK)
  {
    sensor->not_found = 1;
    return result;
  }
  
  result = Dallas_WriteUserBytes(&sensor->sens, sensor->Location.all, sensor->Location.all, USED_USER_BYTES);
  if(result != HAL_OK)
    return result;

  sensor->sens.Init.InitParam = sensor->Location.all;
  sensor->sens.Init.init_func = &Dallas_SensorInitByUserBytes;
  
  result = Dallas_AddNewSensors(hdallas, &sensor->sens);  
  if(result == HAL_OK)
  {
    sensor->not_found = 0;
  }
  else
  {
    sensor->not_found = 1;
  }
  
  return result;
}




HAL_StatusTypeDef PCHSens_AddSensor(DALLAS_HandleTypeDef *hdallas, PCHSens_SensorTypeDef* sensor)
{   
  HAL_StatusTypeDef result;
  if(hdallas == NULL)
    return HAL_ERROR;
  if(sensor == NULL)
    return HAL_ERROR;
    
  sensor->sens.Init.InitParam = sensor->Location.all;
  
  sensor->sens.Init.init_func = &Dallas_SensorInitByUserBytes;
  
  result = Dallas_AddNewSensors(hdallas, &sensor->sens);
  
  if(result == HAL_OK)
  {
    sensor->not_found = 0;
  }
  else
  {
    sensor->not_found = 1;
  }
  
  return result;
}

HAL_StatusTypeDef PCHSens_InitModule(DALLAS_HandleTypeDef *hdallas, PCHSens_ModuleTypeDef* module, uint16_t param)
{
  if(hdallas == NULL)
    return HAL_ERROR;
  if(module == NULL)
    return HAL_ERROR;
  
  PCHSens_LocationTypeDef initlocation;
  initlocation.all = param;
  
  module->hdallas = hdallas;
  module->refLocation = initlocation;
  
  module->sens1.Location.all = module->refLocation.all;
  module->sens1.Location.param.Location = 0;
  PCHSens_AddSensor(hdallas, &module->sens1);
  
  module->sens2.Location.all = module->refLocation.all;
  module->sens2.Location.param.Location = 1;  
  PCHSens_AddSensor(hdallas, &module->sens2);
  
  module->sens3.Location.all = module->refLocation.all;
  module->sens3.Location.param.Location = 2;
  PCHSens_AddSensor(hdallas, &module->sens3);
  
  module->sens4.Location.all = module->refLocation.all;
  module->sens4.Location.param.Location = 3;
  PCHSens_AddSensor(hdallas, &module->sens4);
  return HAL_OK;
}


HAL_StatusTypeDef PCHSens_ModuleReadTemperature(PCHSens_ModuleTypeDef* module)
{
  HAL_StatusTypeDef result;
  
  if(module == NULL)
    return HAL_ERROR;
    
  result = PCHSens_SensorReadTemperature(module->hdallas, &module->sens1);
  result = PCHSens_SensorReadTemperature(module->hdallas, &module->sens2);
  result = PCHSens_SensorReadTemperature(module->hdallas, &module->sens3);
  result = PCHSens_SensorReadTemperature(module->hdallas, &module->sens4);

  return result;
}
HAL_StatusTypeDef PCHSens_SensorReadTemperature(DALLAS_HandleTypeDef *hdallas, PCHSens_SensorTypeDef *sensor)
{
  HAL_StatusTypeDef result;
  if(hdallas == NULL)
    return HAL_ERROR;
  if(sensor == NULL)
    return HAL_ERROR;
  
  result = PCHSens_ReadTemperature(sensor);
  if(result != HAL_OK)
    PCHSens_CheckSensor(hdallas, sensor);
  
  return result;
}
HAL_StatusTypeDef PCHSens_StartCovert(PCHSens_DallasBusHandle *hbus)
{
  return Dallas_StartConvertTAll(hbus->hdallas, DALLAS_WAIT_NONE, 0);
}
HAL_StatusTypeDef PCHSens_ReadTemperature(PCHSens_SensorTypeDef* sensor)
{
  HAL_StatusTypeDef result;
  
  if(sensor == NULL)
    return HAL_ERROR;
  if(sensor->sens.isInitialized == 0)
    return HAL_ERROR;
    
  result = Dallas_ReadTemperature(&sensor->sens); 
  
  return result;
}
HAL_StatusTypeDef PCHSens_CheckSensor(DALLAS_HandleTypeDef *hdallas, PCHSens_SensorTypeDef* sensor)
{
  HAL_StatusTypeDef result;
  unsigned unknow_sensors_flag = 0;
  
  if(sensor == NULL)
    return HAL_ERROR;
  
  if((sensor->sens.isLost == 1) || (sensor->sens.isInitialized == 0))
  {
    if(Dallas_ReplaceLostedSensor(&sensor->sens) == HAL_ERROR)
    {
      sensor->not_found = 1;
    }
    else
    {
      sensor->not_found = 0;     
    }
  }
  else
  {
    sensor->not_found = 0;     
  }
  return HAL_OK;
}


HAL_StatusTypeDef PCHSens_FindUnknownSensors(PCHSens_DallasBusHandle *hbus)
{  
  HAL_StatusTypeDef result;
  if(hbus == NULL)
    return HAL_ERROR;
    
  hbus->UnknownCnt = 0;
  
  PCHSens_LocationTypeDef *param = (PCHSens_LocationTypeDef *)&hbus->hdallas->scratchpad.tHighRegister;
  for(int i = 0; i < hbus->hdallas->onewire->RomCnt; i++)
  {    
    /* Проверка присутствует ли выбранный датчик на линии */
    result = DS18B20_ReadScratchpad(hbus->hdallas->onewire, (uint8_t *)&hbus->hdallas->ds_devices->DevAddr[i], (uint8_t *)&hbus->hdallas->scratchpad);
    if(result != HAL_OK)
      __NOP();
    
    if((IS_REG_SENS_LOCATION(param) == 0) ||
      (IS_REG_PCH_LOCATION(param) == 0) ||
      (IS_REG_PCH_NUMB(param) == 0) )
    {
//      unknowns->unknown_sensors[unknowns->UnknownCnt].Init.InitParam = i;
//      unknowns->unknown_sensors[unknowns->UnknownCnt].Init.init_func = &Dallas_SensorInitByInd;
//      result = Dallas_AddNewSensors(hbus, &unknowns->unknown_sensors[unknowns->UnknownCnt]);
      hbus->UnknownCnt++;
      if(result != HAL_OK)
        __NOP();
    }
  }
  return HAL_OK;
}
HAL_StatusTypeDef PCHSens_UndefineSensor(PCHSens_SensorTypeDef *sensor)
{
  HAL_StatusTypeDef result;
  if(sensor == NULL)
    return HAL_ERROR;
  
  result = Dallas_WriteUserBytes(&sensor->sens, 0, 0, USED_USER_BYTES);
  if(result != HAL_OK)
  {
    return result;
  }
  
  result = Dallas_SensorDeInit(&sensor->sens);  
  return result;
}

HAL_StatusTypeDef PCHSens_GetSensorByLocation(PCHSens_TypeDef *pchsens, PCHSens_LocationTypeDef Location, PCHSens_SensorTypeDef **sensor)
{
  PCHSens_ModuleTypeDef *module;
  uint8_t pch_numb = (Location.param.PCHdig1 - 1)*3 + (Location.param.PCHdig2 - 1);
  
  switch(pch_numb)
  {
    case 0: 
      module = &pchsens->module1; break;
    case 1: 
      module = &pchsens->module2; break;
    case 2: 
      module = &pchsens->module3; break;
    case 3: 
      module = &pchsens->module4; break;
    case 4: 
      module = &pchsens->module5; break;
    case 5: 
      module = &pchsens->module6; break;
    default:
      return HAL_ERROR;
  }
  
  switch(Location.param.Location)
  {
    case 0:
      *sensor = &module->sens1; break;
    case 1:
      *sensor = &module->sens2; break;
    case 2:
      *sensor = &module->sens3; break;
    case 3:
      *sensor = &module->sens4; break;
  }
  
  return HAL_OK;
}
