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


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

#include "pch_sensors.h"
#include "modbus_data.h"
PCHSens_DallasBusHandle DallasBus;
PCHSens_SensorActionsTypeDef  action;

/* Declarations and definitions --------------------------------------------*/

PCHSens_ModuleTypeDef module1;
PCHSens_ModuleTypeDef module2;
PCHSens_ModuleTypeDef module3;
PCHSens_ModuleTypeDef module4;
PCHSens_ModuleTypeDef module5;
PCHSens_ModuleTypeDef module6;
/* 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->UserBytes = (PCHSens_LocationTypeDef *)&sensor->sens.scratchpad.tHighRegister;
  
  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;
  action.read = 1;
  
  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_ModuleHandleAction(PCHSens_ModuleTypeDef* module)
{
  HAL_StatusTypeDef result;
  
  if(module == NULL)
    return HAL_ERROR;
    
  result = PCHSens_SensorHandleActions(module->hdallas, &module->sens1);
  result = PCHSens_SensorHandleActions(module->hdallas, &module->sens2);
  result = PCHSens_SensorHandleActions(module->hdallas, &module->sens3);
  result = PCHSens_SensorHandleActions(module->hdallas, &module->sens4);
     
  return result;
}
HAL_StatusTypeDef PCHSens_Covert(PCHSens_DallasBusHandle *hbus)
{
  return Dallas_StartConvertTAll(hbus->hdallas, DALLAS_WAIT_BUS, 0);
}
HAL_StatusTypeDef PCHSens_ReadTemperature(PCHSens_SensorTypeDef* sensor)
{
  HAL_StatusTypeDef result;
  
  if(sensor == NULL)
    return HAL_ERROR;
    
  result = Dallas_ReadTemperature(&sensor->sens);  
  PCHSens_StoreToModbus(sensor);
  
  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.isInitialized == 0)
    return HAL_ERROR;
  
  if((sensor->sens.isLost == 1))
  {
    if(Dallas_ReplaceLostedSensor(&sensor->sens) != HAL_OK)
    {
      sensor->not_found = 1;
    }
    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 *)&DS.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_DefineUnknownSensor(PCHSens_UnknownSensorsTypeDef *unknowns, PCHSens_SensorTypeDef *sensor)
//{
//  HAL_StatusTypeDef result;
//  if(sensor == NULL)
//    return HAL_ERROR;
//  
//  if((unknowns->ROMtoDefine != NULL) && (unknowns->LocationtoDefine.all != NULL) && (unknowns->senstoDefine != NULL))
//  {
//    result = PCHSens_InitNewSensor(unknowns->onewire, unknowns->senstoDefine, unknowns->ROMtoDefine);    
//    unknowns->ROMtoDefine = 0;
//    unknowns->LocationtoDefine.all = 0;
//    unknowns->senstoDefine = 0;
//    return result;
//  }
//  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_SensorHandleActions(DALLAS_HandleTypeDef *hdallas, PCHSens_SensorTypeDef *sensor)
{
  HAL_StatusTypeDef result;
  if(sensor == NULL)
    return HAL_ERROR;
  
  if(action.connectROM != NULL)
  {
    result = PCHSens_InitNewSensor(hdallas, sensor, action.connectROM);    
    action.connectROM = 0;
  }
  
  if(action.read != NULL)
  {
    result = PCHSens_ReadTemperature(sensor);
    if(result != HAL_OK)
      PCHSens_CheckSensor(hdallas, sensor);
  }
  
  if(action.deinit != NULL)
  {
    action.deinit = 0;
    result = PCHSens_UndefineSensor(sensor);
  }
  
  return result;
}

void PCHSens_FirstInit(void)
{  
  int init_find = 0;
  OW.DataPin = DS_Pin;
  OW.DataPort = DS_GPIO_Port;
  DS.Resolution = DS18B20_RESOLUTION_9BITS;  
  
	OneWire_Init(&OW);
  DS18B20_Search(&DS, &OW);
  
  DallasBus.hdallas = &hdallas1;
  DallasBus.hdallas->onewire = &OW;
  
  
  
  PCHSens_InitModule(&hdallas1, &module1, REG_PCH_NUMB_11|REG_PCH_DIODE_NUMB_1);
  PCHSens_InitModule(&hdallas1, &module2, REG_PCH_NUMB_12|REG_PCH_DIODE_NUMB_1);
  PCHSens_InitModule(&hdallas1, &module3, REG_PCH_NUMB_13|REG_PCH_DIODE_NUMB_1);
  PCHSens_InitModule(&hdallas1, &module4, REG_PCH_NUMB_21|REG_PCH_DIODE_NUMB_1);
  PCHSens_InitModule(&hdallas1, &module5, REG_PCH_NUMB_22|REG_PCH_DIODE_NUMB_1);
  PCHSens_InitModule(&hdallas1, &module6, REG_PCH_NUMB_23|REG_PCH_DIODE_NUMB_1);
  
  PCHSens_FindUnknownSensors(&DallasBus);
}


void PCHSens_StoreToModbus(PCHSens_SensorTypeDef *sensor)
{
  uint8_t pch_numb = (sensor->Location.param.PCHdig1 - 1)*3 + (sensor->Location.param.PCHdig2 - 1);
  uint8_t location = (sensor->Location.param.Location);
  
  uint8_t mb_location = pch_numb*4 + location;
  
  if (mb_location < DS18B20_DEVICE_AMOUNT)
    MB_DATA.InRegs.SensTemperature[mb_location] = sensor->sens.temperature*100;
}



