/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2025 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "adc.h"
#include "can.h"
#include "i2c.h"
#include "rtc.h"
#include "spi.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"








/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "dallas_tools.h"

#include "def.h"
#include <stdio.h>
#include "modbus.h"
#include "eeprom_emul.h"
#include "stdio.h"




/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
int fputc(int ch, FILE *f)
{
    HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
    return ch;
}
/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
uint16_t iter,cnt=5;

uint8_t ralay_5v_on_var=0;
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
		float temperature;
		uint8_t roms[MAX_DEVICES][8];
		Flags_TypeDef flag;
		//extern uint8_t devices_found ;
		uint8_t _debug_init=0;
		//TEMP_TypeDef temp_sense[30];
		float set_temp_old[30];
		char rx_buffer[64];
		uint8_t rx_index = 0;
		char command_ready = 0;
		uint8_t uart_byte = 0;
		uint8_t first_in=1;
		DALLAS_SensorHandleTypeDef sens[30];
		int init_sens=0;
 

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */
	
  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */


  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM1_Init();
  MX_USART1_UART_Init();
  MX_TIM2_Init();
  MX_ADC1_Init();
  MX_CAN_Init();
  MX_I2C1_Init();
  MX_RTC_Init();
  MX_SPI1_Init();
  /* USER CODE BEGIN 2 */

	led_blink(GPIOC,13,rest_iter,reset_blink_delay);
	  MODBUS_FirstInit(&hmodbus1, &mb_huart, &mb_htim);
    MODBUS_Config(&hmodbus1, MODBUS_DEVICE_ID, MODBUS_TIMEOUT, MODBUS_MODE_SLAVE);
    
    // Запуск приема Modbus
    MODBUS_SlaveStart(&hmodbus1, NULL);
	uint8_t uart_byte = 0;
  
  Dallas_BusFirstInit(&htim1);
	// ������������� �� ������� ��������� ��������
	// ������������� �� ������� (����������� ������ ���������� �������)
	reinit_t_sens();

	MB_DATA.InRegs.num_Tsens=hdallas.onewire->RomCnt;
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		Field_modbus(&MB_DATA,&flag);

	

	 if( hmodbus1.pMessagePtr->FuncCode&FC_ERR_VALUES_START)
	 {
		 static int pause_Alarm_led;
		while (1) 
		{
			if (pause_Alarm_led>36000000)
			{
				GPIOC->ODR^=1<<13;
				pause_Alarm_led=0;
				
			}
			pause_Alarm_led++;
		}
		
		 
	 }

	 Check_Tconnect(&MB_DATA,&flag,&hdallas, 0);

		if (_debug_init||MB_DATA.Coils.init_param)
		{
			_debug_init=0;
			
			MB_DATA.Coils.init_param=0;
			for(int i=0;i<hdallas.onewire->RomCnt;i++)
			{
				sens[i].set_temp=MB_DATA.HoldRegs.set_Temp[i];
				sens[i].hyst=MB_DATA.HoldRegs.set_hyst[i];
			}
		
			

		}
		
			
			Dallas_StartConvertTAll(&hdallas,DALLAS_WAIT_BUS,0);

			for(int i=0;i<hdallas.onewire->RomCnt;i++)
			{
				if(sens[i].isLost)
				{
					sens[i].lost_cnt ++;
				}
				Dallas_ReadTemperature(&sens[i]);
				sens[i].set_temp = MB_DATA.HoldRegs.set_Temp[i];				
				MB_DATA.InRegs.sens_Temp[i]=sens[i].temperature*10;
				
		
/////////////////////////заменить на define ralay_5v_on_var GPIOA->ODR|=1<<10; 
				
				ralay_5v_on_var=MB_DATA.Coils.coils[1].state_val_bit.state_val_05;
				if (ralay_5v_on_var)
				{
					GPIOA->ODR|=1<<10;
				}
				else
					{
						GPIOA->ODR&=~(1<<10);
					}
			 value_control();

			}
			
			
		
			
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		//iwdg_refresh();
	
		//HAL_Delay(200);
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.LSIState = RCC_LSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_ADC;
  PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
  PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */
	void iwdg_refresh(void)
		{
				IWDG->KR = 0xAAAA;         // �������� ������
		}
void led_blink(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin,uint8_t iter,uint16_t delay)
		{
			for(int i=0;i<iter;i++)
			{
				GPIOx->ODR^=(1<<GPIO_Pin);
				HAL_Delay(delay);
			}
		}

void  Check_Tconnect(MB_DataStructureTypeDef* MB_DATA,	Flags_TypeDef* flag ,DALLAS_HandleTypeDef* hdallas, int a[0])
{
	 for(int i=0;i<hdallas->onewire->RomCnt;i++)
	{
		if(sens[i].isLost)
			{
				//init_sens=1;
			}
		
	}
	if (init_sens||flag->init_tsens)
			{
				init_sens=0;
				flag->init_tsens=0;		
			//Dallas_BusFirstInit(&htim1);		
				DS18B20_Search(&DS, &OW) ;				
				reinit_t_sens();				
				MB_DATA->InRegs.num_Tsens = hdallas->onewire->RomCnt;
			}
}	

void reinit_t_sens(void)
{
	for ( int i=0; i<hdallas.onewire->RomCnt;i++)
			{   
				// ������������� �� ROM-������
				//sens[i].Init.init_func = &Dallas_SensorInitByROM;
				//	sens[i].Init.InitParam.ROM = rom_address;
				sens[i].Init.InitParam.Ind = i; 
				sens[i].Init.init_func = &Dallas_SensorInitByInd;  
				sens[i].Init.Resolution = DALLAS_CONFIG_9_BITS;  
				MB_DATA.HoldRegs.set_Temp[i] =sens[i].set_temp =20.;
				MB_DATA.HoldRegs.set_hyst[i]=sens[i].hyst =1;
				Dallas_AddNewSensors(&hdallas, &sens[i]);
				
			}	
		}			
FuncStat packStruct(MB_DataStructureTypeDef* MB_DATA,int sizeARR)
		{
			for(int i=0;i<sizeARR;i++)
			{
				for(int sens_num=0;sens_num<hdallas.onewire->RomCnt;sens_num++)
					{
						 switch(sens_num)
							{
								case 0:
										MB_DATA->Coils.status_tSens[i].state_val_bit.Temp1_isConnected = sens[i*16+sens_num ].isConnected;
										break;
								case 1:
										MB_DATA->Coils.status_tSens[i].state_val_bit.Temp2_isConnected = sens[i*16+sens_num ].isConnected;
										break;
								case 2:
										MB_DATA->Coils.status_tSens[i].state_val_bit.Temp3_isConnected = sens[i*16+sens_num ].isConnected;
										break;
								case 3:
										MB_DATA->Coils.status_tSens[i].state_val_bit.Temp4_isConnected = sens[i*16+sens_num ].isConnected;
										break;
								case 4:
										MB_DATA->Coils.status_tSens[i].state_val_bit.Temp5_isConnected = sens[i*16+sens_num ].isConnected;
										break;
								case 5:
										MB_DATA->Coils.status_tSens[i].state_val_bit.Temp6_isConnected = sens[i*16+sens_num ].isConnected;
										break;
								case 6:
										MB_DATA->Coils.status_tSens[i].state_val_bit.Temp7_isConnected = sens[i*16+sens_num ].isConnected;
										break;
								case 7:
										MB_DATA->Coils.status_tSens[i].state_val_bit.Temp8_isConnected = sens[i*16+sens_num ].isConnected;
										break;
								case 8:
										MB_DATA->Coils.status_tSens[i].state_val_bit.Temp9_isConnected = sens[i*16+sens_num ].isConnected;
										break;
								case 9:
										MB_DATA->Coils.status_tSens[i].state_val_bit.Temp10_isConnected = sens[i*16+sens_num ].isConnected;
										break;
								case 10:
										MB_DATA->Coils.status_tSens[i].state_val_bit.Temp11_isConnected = sens[i*16+sens_num ].isConnected;
										break;
								case 11:
										MB_DATA->Coils.status_tSens[i].state_val_bit.Temp12_isConnected = sens[i*16+sens_num ].isConnected;
										break;
								case 12:
										MB_DATA->Coils.status_tSens[i].state_val_bit.Temp13_isConnected = sens[i*16+sens_num ].isConnected;
										break;
								case 13:
										MB_DATA->Coils.status_tSens[i].state_val_bit.Temp14_isConnected = sens[i*16+sens_num ].isConnected;
										break;
								case 14:
										MB_DATA->Coils.status_tSens[i].state_val_bit.Temp15_isConnected = sens[i*16+sens_num ].isConnected;
										break;
								case 15:
										MB_DATA->Coils.status_tSens[i].state_val_bit.Temp16_isConnected = sens[i*16+sens_num ].isConnected;
										break;
							}
					}
			}
		return FuncOK;	
	
		}
FuncStat Field_modbus(MB_DataStructureTypeDef* MB_DATA, Flags_TypeDef* flag)
		{
		
			MB_DATA->InRegs.ID= *hdallas.ds_devices;		
			flag->init_tsens=MB_DATA->Coils.init_Tsens;
			packStruct(MB_DATA,MAX_SENSE/16);		
			
		
			return FuncOK;
		};
		
		
FuncStat value_control(void )
		{
			
			for(int i=0;i<10;i++)
			{
				if (sens[i].temperature<sens[i].set_temp-sens[i].hyst)
				
			{
					
					MB_DATA.Coils.coils[0].all|=1<<i;
				
			}
				
			else
				
			if (sens[i].temperature>sens[i].set_temp+sens[i].hyst)				
			{
							
					MB_DATA.Coils.coils[0].all&=~(1<<i);			
				
			}		
			if(GPIOB11_valve)
				{
					GPIOB->ODR|=1<<11;
				}
				else 
				{
					GPIOB->ODR&=~(1<<11);
					
				}
			
			
		}
			return  FuncOK;
	}			
	

uint16_t handle_valves(TEMP_TypeDef* temp_sense[MAX_SENSE] )
{
		
	if (temp_sense[0]->state==STATE_OPEN_VALVE)
		{
			GPIOC->ODR|=1<<14;
		}
		else 
			if (temp_sense[0]->state==STATE_CLOSE_VALVE)
		{
			GPIOC->ODR&=~(1<<14);
		} 
		
	return 1;
	
}

void init_setpoint_all_T_sense(TEMP_TypeDef* temp_sense[MAX_SENSE])
{	
	//ds_search_devices();
	 for(int i=0;i<hdallas.onewire->RomCnt;i++)
{	
			temp_sense[i]->id[0]=roms[i][0]<<0|roms[i][1]<<8|roms[i][2]<<16|roms[i][3]<<24;
			temp_sense[i]->id[1]=roms[i][4]<<0|roms[i][5]<<8|roms[i][6]<<16|roms[i][7]<<24;
			temp_sense[i]->count =i+1;
			temp_sense[i]->location=1;
			temp_sense[i]->t_open=22;
			temp_sense[i]->t_close=18;
	    temp_sense[i]->status_T_sense=1;
}
}
/* USER CODE END 4 */

/**
  * @brief  Period elapsed callback in non blocking mode
  * @note   This function is called  when TIM3 interrupt took place, inside
  * HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment
  * a global variable "uwTick" used as application time base.
  * @param  htim : TIM handle
  * @retval None
  */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  /* USER CODE BEGIN Callback 0 */

  /* USER CODE END Callback 0 */
  if (htim->Instance == TIM3)
  {
    HAL_IncTick();
  }
  /* USER CODE BEGIN Callback 1 */

  /* USER CODE END Callback 1 */
}

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
