/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under Ultimate Liberty license
  * SLA0044, the "License"; You may not use this file except in compliance with
  * the License. You may obtain a copy of the License at:
  *                             www.st.com/SLA0044
  *
  ******************************************************************************
  */

#include "main.h"
#include "fatfs.h"
#include "fatfs_sd.h"
#include <stdlib.h>
#include "string.h"
#include <stdio.h>
#include "stm32_hal_legacy.h"
#define	LOW_BATTERY	3413
//#define uart_debug

ADC_HandleTypeDef hadc;

I2C_HandleTypeDef hi2c1;

RTC_HandleTypeDef hrtc;

SPI_HandleTypeDef hspi1;

UART_HandleTypeDef huart1;
UART_HandleTypeDef huart3;
DMA_HandleTypeDef hdma_usart1_tx;
DMA_HandleTypeDef hdma_usart3_tx;


void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_ADC_Init(void);
static void MX_I2C1_Init(void);
static void MX_RTC_Init(void);
static void MX_SPI1_Init(void);
static void MX_USART1_UART_Init(void);//FTDI
static void MX_USART3_UART_Init(void);//IOT
static uint16_t GetCRC(uint8_t *message, uint16_t length);

void Reset_IOT(void);
void Process_IOT_Received(void);
void remove_command(uint8_t *array, int sum);
/* IOT variables ---------------------------------------------------------*/
uint8_t iot_recv_data;
uint8_t iot_data_buffer[128];
uint32_t iot_count = 0;
uint8_t iot_command_count = 0;
uint8_t iot_command_index[32];
iot_states iot_state = idle;

/* FTDI function prototypes ---------------------------------------------------------*/
void Process_FTDI_Received(void);

/* FTDI variables ---------------------------------------------------------*/
uint8_t usb_recv_data[11];
uint8_t command_buffer[100];
uint8_t command_index[32];
uint8_t command_count = 0;

/* Sensors function prototypes ---------------------------------------------------------*/
void Start_measurement(void);
//void ReadTmp(uint32_t* sht);
void ReadTmp(uint16_t* sht);
//void ReadPressure(uint32_t* bme);
void ReadPressure(uint16_t* bme);
/* Sensors variables ---------------------------------------------------------*/
//uint32_t sht[2] = {0}; //Temperature, Humidity
uint16_t sht[2] = {0}; //Temperature, Humidity
//uint32_t bme[2] = {0}; //Temperature, Pressure
uint16_t bme[2] = {0}; //Temperature, Pressure

/* Device functions */
void Start_sending(void);

/* Device variables*/
/* 0 - Device is Not active, 0x55 - Active*/
uint8_t IsDev_active = 0;

/* 0 - Data are not saving on SD card, 0x55 - Data are saving on SD card */
uint8_t IsData_saving = 0;

/* 0 - Data are not sending to IOT, 0x55 - Data are sending to IOT */
uint8_t IsData_sending = 0;

char hex_data_buffer[99] = {'m','a','c',' ','t','x',' ','c','n','f',' ','4',' ', 0};

uint8_t hex_data_buffer_count = 13;
uint8_t measure_count = 0;

void clear_iot_buffers(void);
void Convert_To_Hex(void);
//uint32_t naiveHexString(uint32_t num, char *s);
uint16_t naiveHexString(uint16_t num, char *s);


char* power_mode = "radio set pwr 14\r\n";
uint8_t transmit_enable = 0;
uint16_t batt_ADC = 0;

volatile unsigned char flags=0;

/* SD card data*/
FATFS fs;//file system
FIL fil;//file
FRESULT fresult;
char buffer[154];

UINT br, bw;//file read, write count;

FATFS *pfs;
DWORD fre_clust;
uint32_t total, free_space;

void WriteToSD(RTC_TimeTypeDef* RTC_TimeRead, RTC_DateTypeDef* RTC_DateRead);
/* Data RTC */
RTC_TimeTypeDef RTC_TimeRead[7];
RTC_DateTypeDef RTC_DateRead[7];
void printmsg(char* string);
int sd_counter = 0;
long unsigned int m_counter = 0;
void SetDateTime(uint8_t Date, uint8_t Month, uint8_t Year, uint8_t Hours, uint8_t Min, uint8_t Sec);
uint8_t usb_recv = 0;
uint8_t command_buffer1[11];
char sd_file[17];
uint8_t sdfileselected = 0;
void GPIO_AnalogConfig(void);
void SystemClock_Config1(void);
static void SystemPower_Config(void);
static void EXTI15_10_IRQHandler_Config(void);
uint8_t CanSleepFTDI = 0;
uint8_t CanSleepSNC = 0;
uint8_t CanSleepIOT = 0;
uint8_t CanSleepSD = 0;
uint8_t slep = 0;
static void EXTI17_IRQHandler_Config(void);
void SystemClock_Config2(void);
volatile uint8_t exti_ir = 0;
volatile uint8_t exti_sleep = 0;
volatile uint8_t c_adc = 0;
int main(void)
{
  HAL_Init();
  SystemClock_Config();

  MX_GPIO_Init();
  GPIO_AnalogConfig();
  MX_DMA_Init();
  MX_ADC_Init();
  MX_I2C1_Init();
  MX_RTC_Init();
  HAL_PWR_EnableBkUpAccess();

  MX_SPI1_Init();
  //MX_USART1_UART_Init();
  MX_USART3_UART_Init();
  MX_FATFS_Init();

  HAL_GPIO_WritePin(IOT_VCC_GPIO_Port, IOT_VCC_Pin, GPIO_PIN_SET); //Turn off IOT
  HAL_GPIO_WritePin(SD_VCC_GPIO_Port, SD_VCC_Pin, GPIO_PIN_RESET); //Turn off sd card
  HAL_GPIO_WritePin(SNC_VCC_GPIO_Port, SNC_VCC_Pin, GPIO_PIN_SET); //Turn off IOT

  __HAL_UART_FLUSH_DRREGISTER(&huart1);
  __HAL_UART_FLUSH_DRREGISTER(&huart3);

  HAL_UART_Receive_IT(&huart3, &iot_recv_data, 1);
  volatile unsigned char local_flags;
  flags = 0;

  EXTI15_10_IRQHandler_Config();

  while (1)
  {
	  c_adc++;
	  __disable_irq();

	  if(IsDev_active == 0)
	  {
		  flags &= ~F_IOT_RECEIVED;
		  flags &= ~F_MEASURE_ALARM;
		  flags &= ~F_SEND_ALARM;
		  flags &= ~F_SD_CARD;
		  CanSleepIOT = 0;
		  CanSleepSD = 0;
		  CanSleepSNC = 0;
	  }


	  local_flags = flags;
	  flags = 0;
	  __enable_irq();


	  if(local_flags & F_FTDI_RECEIVED)
	  {
		  Process_FTDI_Received();
	  }
	  if(local_flags & F_IOT_RECEIVED)
	  {
		  Process_IOT_Received();
	  }
	  if(local_flags & F_MEASURE_ALARM)
	  {
		  Start_measurement();
	  }
	  if(local_flags & F_SEND_ALARM)
	  {
		  Start_sending();
	  }
	  if(local_flags & F_SD_CARD)
	  {
		  WriteToSD(RTC_TimeRead, RTC_DateRead);
	  }

	  if(c_adc > 10)
	  {
		  c_adc = 0;
		  HAL_ADC_Start(&hadc);
		  HAL_ADC_PollForConversion(&hadc, 100);
		  batt_ADC = HAL_ADC_GetValue(&hadc);
		  HAL_ADC_Stop(&hadc);
		  if(batt_ADC > LOW_BATTERY)
		  {
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, GPIO_PIN_SET); //DISCONNECT VOLTAGE SOURCE FROM BATTERY
		  }
		  else
		  {
			  HAL_GPIO_WritePin(GPIOC,  GPIO_PIN_3, GPIO_PIN_RESET); //CONNECT VOLTAGE SOURCE TO BATTERY
		  }
	  }


	  if((local_flags == 0) && (CanSleepFTDI == 0) && (CanSleepIOT==0) && (CanSleepSD==0) && (CanSleepSNC==0))
	  {
		  slep = 8;
		  HAL_SuspendTick();
		  SystemClock_Config1();

	      HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);
	      HAL_ResumeTick();
	      SystemClock_Config2();
	      HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
	      HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
	      uint32_t a = HAL_RCC_GetHCLKFreq();
	  }

  }

}


void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	if(slep == 8)
	{
		HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
		HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
		HAL_ResumeTick();

		SystemClock_Config2();

		HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
		HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

		slep = 0;
		MX_USART1_UART_Init();
		CanSleepFTDI = 0x55;
		exti_ir++;
		HAL_NVIC_DisableIRQ(EXTI15_10_IRQn);

		HAL_UART_Receive_IT(&huart1, usb_recv_data, 11);
	}
	else
	{
		CanSleepFTDI = 0;
		EXTI15_10_IRQHandler_Config();
	}
}

static void EXTI15_10_IRQHandler_Config(void)
{
  GPIO_InitTypeDef   GPIO_InitStructure = {0};

  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_SYSCFG_CLK_ENABLE();

  GPIO_InitStructure.Mode = GPIO_MODE_IT_RISING;
  GPIO_InitStructure.Pull = GPIO_NOPULL;
  GPIO_InitStructure.Pin = GPIO_PIN_10;
  GPIO_InitStructure.Alternate = GPIO_AF0_TRACE;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
  __HAL_GPIO_EXTI_CLEAR_FLAG(GPIO_PIN_10);
  NVIC_ClearPendingIRQ(EXTI15_10_IRQn);

  HAL_NVIC_SetPriority(EXTI15_10_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
}

static void SystemPower_Config(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  /* Enable GPIOs clock */
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOH_CLK_ENABLE();

  /* Configure all GPIO port pins in Analog Input mode (floating input trigger OFF) */
  GPIO_InitStructure.Pin = GPIO_PIN_All;
  GPIO_InitStructure.Mode = GPIO_MODE_ANALOG;
  GPIO_InitStructure.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
  HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
  HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
  HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);
  HAL_GPIO_Init(GPIOH, &GPIO_InitStructure);

  /* Disable GPIOs clock */
  __HAL_RCC_GPIOA_CLK_DISABLE();
  __HAL_RCC_GPIOB_CLK_DISABLE();
  __HAL_RCC_GPIOC_CLK_DISABLE();
  __HAL_RCC_GPIOD_CLK_DISABLE();
  __HAL_RCC_GPIOH_CLK_DISABLE();

}

uint8_t uart_error = 0;
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{

}

void printmsg(char* string)
{
	uint8_t len = strlen (string);
	HAL_UART_Transmit(&huart1, (uint8_t *) string, len, 2000);  // transmit in blocking mode
}

void WriteToSD(RTC_TimeTypeDef* RTC_TimeRead, RTC_DateTypeDef* RTC_DateRead)
{
	MX_SPI1_Init();
	MX_FATFS_Init();
	for(int i = 0; i < 10000; ++i)
	{

	}
	fresult = f_mount(&fs, "", 0);
	if (fresult != FR_OK)
	{

	}
	if(sdfileselected ==1)
		fresult = f_open(&fil, sd_file, FA_OPEN_APPEND | FA_READ | FA_WRITE);
	else
		fresult = f_open(&fil, "file104.txt", FA_OPEN_APPEND | FA_READ | FA_WRITE);

	char text[99];
	memcpy(text, hex_data_buffer + 13, 84);

	char temp[4];
	char humd[4];
	char pres[4];
	int count = 0;
	char str[16];
	for(int i = 0; i < 10; ++i)
	{
		memcpy(temp, text+i+count, 4);
		memcpy(humd, text+i+count + 4, 4);
		memcpy(pres, text+i+count + 8, 4);
		memcpy(str, temp, 4);
		str[4] = '\t';
		memcpy(str+5, humd, 4);
		str[9] = '\t';
		memcpy(str+10, pres, 4);
		str[14] = '\n';
		str[15] = '\0';
		fresult = f_printf(&fil, "%02d-%2d-%2d ", RTC_DateRead[i].Month,RTC_DateRead[i].Date,RTC_DateRead[i].Year);
		fresult = f_printf(&fil, "%02d:%02d:%02d ", RTC_TimeRead[i].Hours, RTC_TimeRead[i].Minutes,RTC_TimeRead[i].Seconds);
		fresult = f_puts(str, &fil);
		count = count + 11;
	}

	f_close (&fil);
	fresult = f_mount(NULL, "", 1);
	measure_count = 0;
	HAL_SPI_DeInit(&hspi1);
	CanSleepSD = 0;
#ifdef uart_debug
	printmsg("sdcard written\n");
#endif
	if (fresult == FR_OK)
	{

	}
}

void GetDateTime(RTC_TimeTypeDef* RTC_TimeRead, RTC_DateTypeDef* RTC_DateRead, int index)
{
	HAL_RTC_GetTime(&hrtc, &RTC_TimeRead[index],RTC_FORMAT_BIN);

	HAL_RTC_GetDate(&hrtc, &RTC_DateRead[index],RTC_FORMAT_BIN);
#ifdef uart_debug
	sprintf (buffer, "sd_counter: \t%lu\t%d\n",sd_counter, RTC_TimeRead[sd_counter].Minutes);
	printmsg(buffer);

	if(sd_counter == 3)
		sd_counter = 0;
	else
		sd_counter++;
#endif
}

/* IOT functions*/
void Reset_IOT(void)
{
	iot_state = reset;
	HAL_GPIO_WritePin(IOT_RESET_GPIO_Port, IOT_RESET_Pin, GPIO_PIN_RESET);
	for(int i = 0; i < 150000; ++i)
	{

	}

	HAL_GPIO_WritePin(IOT_RESET_GPIO_Port, IOT_RESET_Pin, GPIO_PIN_SET);
	for(int i = 0; i < 500000; ++i)
	{

	}

	iot_state = idle;
}

void Process_IOT_Received(void)
{
	iot_states l_iot_state = iot_state;
	switch(l_iot_state)
	{
	case power:
	{
		uint8_t command[iot_command_index[1]-iot_command_index[0]];
		memcpy(command, iot_data_buffer+iot_command_index[0], (iot_command_index[1]-iot_command_index[0])* sizeof(uint8_t));
		if(memcmp((char*)command, "ok\r\n", 4) == 0)
		{
			iot_state = idle2;
			flags |= F_SEND_ALARM;
			if(iot_command_index[2] == 0)
				flags &= ~F_IOT_RECEIVED;
		}
		else
		{
			//iot_state = idle;
			iot_state = sleep;
			HAL_UART_DeInit(&huart3);
			HAL_GPIO_WritePin(IOT_VCC_GPIO_Port, IOT_VCC_Pin, GPIO_PIN_SET); //Turn off IOT
			CanSleepIOT = 0;
			clear_iot_buffers();
		}
		break;}
	case joining:
	{
		uint8_t command[iot_command_index[2]-iot_command_index[1]];
		memcpy(command, iot_data_buffer+iot_command_index[1], (iot_command_index[2]-iot_command_index[1])* sizeof(uint8_t));
		if(memcmp((char*)command, "ok\r\n", 4) == 0)
		{
			iot_state = joined_ok;
			if(iot_command_index[2] == 0)
				flags &= ~F_IOT_RECEIVED;
		}
		else
		{
			//iot_state = idle;
			iot_state = sleep;
			HAL_UART_DeInit(&huart3);
			HAL_GPIO_WritePin(IOT_VCC_GPIO_Port, IOT_VCC_Pin, GPIO_PIN_SET); //Turn off IOT
			CanSleepIOT = 0;
			clear_iot_buffers();
		}
		break;}
	case joined_ok:
	{
		uint8_t command[iot_command_index[3]-iot_command_index[2]];
		memcpy(command, iot_data_buffer+iot_command_index[2], (iot_command_index[3]-iot_command_index[2]) * sizeof(uint8_t));
		if(memcmp((char*)command, "accepted\r\n", 10) == 0)
		{
			iot_state = joined;
			flags |= F_SEND_ALARM;
		}
		else
		{
			//iot_state = idle;
			iot_state = sleep;
			HAL_UART_DeInit(&huart3);
			HAL_GPIO_WritePin(IOT_VCC_GPIO_Port, IOT_VCC_Pin, GPIO_PIN_SET); //Turn off IOT
			CanSleepIOT = 0;
			clear_iot_buffers();
		}
		break;}

	case transmitting:
	{
		uint8_t command[iot_command_index[4]-iot_command_index[3]];
		memcpy(command, iot_data_buffer+iot_command_index[3], (iot_command_index[4]-iot_command_index[3]) * sizeof(uint8_t));
		if(memcmp((char*)command, "ok\r\n", 4) == 0)
		{
			iot_state = transmitting_ok;
		}
		else
		{
			//iot_state = idle;
			iot_state = sleep;
			HAL_UART_DeInit(&huart3);
			HAL_GPIO_WritePin(IOT_VCC_GPIO_Port, IOT_VCC_Pin, GPIO_PIN_SET); //Turn off IOT
			CanSleepIOT = 0;
			clear_iot_buffers();
		}

		break;}
	case transmitting_ok:
	{
		uint8_t command[iot_command_index[5]-iot_command_index[4]];
		memcpy(command, iot_data_buffer+iot_command_index[4], (iot_command_index[5]-iot_command_index[4]) * sizeof(uint8_t));
		if(strcmp((char*)command, "mac_tx_ok\r\n") == 0)
		{
			HAL_GPIO_WritePin(IOT_VCC_GPIO_Port, IOT_VCC_Pin, GPIO_PIN_SET); //Turn off IOT
			iot_state = sleep;
			CanSleepIOT = 0;
			HAL_UART_DeInit(&huart3);
			//iot_state = idle;
			clear_iot_buffers();
		}
		else
		{
			//iot_state = idle;
			iot_state = sleep;
			HAL_UART_DeInit(&huart3);
			HAL_GPIO_WritePin(IOT_VCC_GPIO_Port, IOT_VCC_Pin, GPIO_PIN_SET); //Turn off IOT
			CanSleepIOT = 0;
			clear_iot_buffers();
		}

		break;}
	default:
	{
		break;}
	}

}

/* Sensors functions */
void Start_measurement(void)
{
	MX_I2C1_Init();
	HAL_GPIO_WritePin(SNC_VCC_GPIO_Port, SNC_VCC_Pin, GPIO_PIN_RESET);//Turn on Sensors_Vcc

	ReadTmp(sht);
	ReadPressure(bme);
	GetDateTime(RTC_TimeRead, RTC_DateRead, measure_count);
	flags &= ~F_MEASURE_ALARM;
	Convert_To_Hex();
	measure_count++;
	HAL_GPIO_WritePin(SNC_VCC_GPIO_Port, SNC_VCC_Pin, GPIO_PIN_SET);//Turn off Sensors_Vcc
	if(measure_count == 7)
	{
		hex_data_buffer_count = 13;
		measure_count = 0;
	}

	CanSleepSNC = 0;
	HAL_I2C_DeInit(&hi2c1);
}

/* Device functions */
void Start_sending(void)
{
	iot_states l_iot_state = iot_state;
	switch(l_iot_state)
	{
	case sleep:
	{

		break;}
	case idle:
		MX_USART3_UART_Init();
		HAL_UART_Receive_IT(&huart3, &iot_recv_data, 1);
		__disable_irq();
		HAL_GPIO_WritePin(IOT_VCC_GPIO_Port, IOT_VCC_Pin, GPIO_PIN_RESET); //Turn on IOT_Vcc
		__enable_irq();
		Reset_IOT();
		if( HAL_UART_Transmit_DMA(&huart3, (uint8_t*)power_mode, (uint16_t)strlen(power_mode)) != HAL_OK)
		{
			Error_Handler();
		}
		flags &= ~F_IOT_RECEIVED;
		iot_state = power;
		break;
	case idle2:
	{
		char* user_data1 = "mac join otaa\r\n";

		if( HAL_UART_Transmit_DMA(&huart3, (uint8_t*)user_data1, (uint16_t)strlen(user_data1)) != HAL_OK)
		{
			Error_Handler();
		}
		iot_state = joining;
		break;}
	case joined:
	{
		iot_state = transmitting;
		hex_data_buffer[97] = '\r';
		hex_data_buffer[98] = '\n';

		if( HAL_UART_Transmit_DMA(&huart3, (uint8_t*)hex_data_buffer, 99) != HAL_OK)
		{
			Error_Handler();
		}
		break;}
	default:
		break;
	}
}

/* FTDI functions */
void Process_FTDI_Received(void)
{
	RTC_TimeTypeDef sTime;
	RTC_DateTypeDef sDate;
	HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN);
	HAL_RTC_GetDate(&hrtc, &sDate,RTC_FORMAT_BIN);
	uint8_t meas_vars[16];
	meas_vars[0] = 0x7E;
	meas_vars[1] = IsDev_active;
	meas_vars[2] = (sht[0] >> 8) & 0xFF;
	meas_vars[3] = sht[0] & 0xFF;
	meas_vars[4] = (sht[1] >> 8) & 0xFF;
	meas_vars[5] = sht[1] & 0xFF;
	meas_vars[6] = (bme[1] >> 8) & 0xFF;
	meas_vars[7] = bme[1] & 0xFF;

	meas_vars[8] = sDate.Date;
	meas_vars[9] = sDate.Month;
	meas_vars[10] = sDate.Year;
	meas_vars[11] = sTime.Hours;
	meas_vars[12] = sTime.Minutes;
	meas_vars[13] = sTime.Seconds;

	uint16_t crc = GetCRC(meas_vars, 14);
	meas_vars[14] = crc >> 8;
	meas_vars[15] = (crc & 0x00FF);
	if(command_buffer1[2]==0x04) //Send actual values
	{

		if(transmit_enable == 0)
		{
			transmit_enable = 0xA3;
			HAL_UART_Transmit_DMA(&huart1, meas_vars, 16);
			while(transmit_enable != 0)
			{

			}

		}

	}
	else if(command_buffer1[2]==0x12) //Start command
	{
		IsDev_active = 0x55;
		if(transmit_enable == 0)
		{
			transmit_enable = 0xA3;
			HAL_UART_Transmit_DMA(&huart1, meas_vars, 16);


			while(transmit_enable != 0)
			{

			}
		}

	}
	else if(command_buffer1[2]==0xDA) //Stop command
	{
		IsDev_active = 0;
		if(transmit_enable == 0)
		{
			transmit_enable = 0xA3;
			HAL_UART_Transmit_DMA(&huart1, meas_vars, 16);


			while(transmit_enable != 0)
			{

			}
		}

	}
	else if(command_buffer1[2]==0xC6) //Set Datetime command
	{
		if(IsDev_active == 0)
		{
			SetDateTime(command_buffer1[3], command_buffer1[4], command_buffer1[5], command_buffer1[6], command_buffer1[7], command_buffer1[8]);
		}
		if(transmit_enable == 0)
		{
			transmit_enable = 0xA3;
			HAL_UART_Transmit_DMA(&huart1, meas_vars, 16);


			while(transmit_enable != 0)
			{

			}
		}

	}
	else if(command_buffer1[2]==0x4D)
	{
		transmit_enable = 0xA3;
		HAL_UART_Transmit_DMA(&huart1, meas_vars, 16);
		while(transmit_enable != 0)
		{

		}

		HAL_UART_DeInit(&huart1);

		EXTI15_10_IRQHandler_Config();
		CanSleepFTDI = 0;
		exti_sleep++;
	}
	else
	{
		flags &= ~F_FTDI_RECEIVED;
	}

}

void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance == USART1)
		transmit_enable = 0;
}




void SetDateTime(uint8_t Date, uint8_t Month, uint8_t Year, uint8_t Hours, uint8_t Min, uint8_t Sec)
{
	char ss[12];
	sprintf(ss,"%.2d%.2d%.2d%.2d%.2d%.2d", Date, Month, Year, Hours, Min, Sec);
	memcpy(sd_file, ss, 12);
	memcpy(sd_file+12, ".txt", 5);
	sdfileselected = 1;
	RTC_TimeTypeDef sTime;
	RTC_DateTypeDef sDate;

	sTime.Hours = RTC_ByteToBcd2(Hours);
	sTime.Minutes = RTC_ByteToBcd2(Min);
	sTime.Seconds = RTC_ByteToBcd2(Sec);
	sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
	sTime.StoreOperation = RTC_STOREOPERATION_RESET;
	if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK)
	{
		Error_Handler();
	}
	sDate.WeekDay = RTC_WEEKDAY_MONDAY;
	sDate.Month = RTC_ByteToBcd2(Month);
	sDate.Date = RTC_ByteToBcd2(Date);
	sDate.Year = RTC_ByteToBcd2(Year);

	if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK)
	{
		Error_Handler();
	}

	HAL_RTC_DeactivateAlarm(&hrtc, RTC_ALARM_A);
	HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN);
	HAL_RTC_GetDate(&hrtc, &sDate,RTC_FORMAT_BIN);
	uint8_t next_minutea = sTime.Minutes + 1;
	if(next_minutea > 59) next_minutea = 0;
	uint8_t next_seca = sTime.Seconds + 1;
	if(next_seca > 59) next_seca = next_seca - 60;

	RTC_AlarmTypeDef sAlarm = {0};
	sAlarm.AlarmTime.Minutes = RTC_ByteToBcd2(next_minutea);
	sAlarm.AlarmTime.Seconds = RTC_ByteToBcd2(next_seca);
	//sAlarm.AlarmTime.SubSeconds = 0x0;
	sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
	sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
	sAlarm.AlarmMask = RTC_ALARMMASK_HOURS | RTC_ALARMMASK_DATEWEEKDAY | RTC_ALARMMASK_SECONDS;
	sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_NONE;
	//sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
	//sAlarm.AlarmDateWeekDay = 0x1;
	sAlarm.Alarm = RTC_ALARM_A;
	if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BCD) != HAL_OK)
	{
	Error_Handler();
	}

	HAL_RTC_DeactivateAlarm(&hrtc, RTC_ALARM_B);
	HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN);
	HAL_RTC_GetDate(&hrtc, &sDate,RTC_FORMAT_BIN);
	uint8_t next_minute = sTime.Minutes + 7;
	if(next_minute > 59) next_minute = next_minute - 60;
	uint8_t next_sec = sTime.Seconds + 20;
	if(next_sec > 59) next_sec = next_sec - 60;

	RTC_AlarmTypeDef sAlarmb = {0};
	sAlarmb.AlarmTime.Minutes = RTC_ByteToBcd2(next_minute);
	sAlarmb.AlarmTime.Seconds = RTC_ByteToBcd2(next_sec);
	//sAlarm.AlarmTime.SubSeconds = 0x0;
	sAlarmb.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
	sAlarmb.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
	sAlarmb.AlarmMask = RTC_ALARMMASK_HOURS | RTC_ALARMMASK_DATEWEEKDAY | RTC_ALARMMASK_SECONDS;
	sAlarmb.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_NONE;
	//sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
	//sAlarm.AlarmDateWeekDay = 0x1;
	sAlarmb.Alarm = RTC_ALARM_B;
	if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarmb, RTC_FORMAT_BCD) != HAL_OK)
	{
	Error_Handler();
	}

}


void clear_iot_buffers(void)
{
	memset(iot_data_buffer, 0, iot_count);
	memset(iot_command_index, 0, iot_command_count);
	iot_command_count = 0;
	iot_count = 0;
}

void remove_command(uint8_t *array, int sum)
{
	int j = 0;

	for(int i = 0; i < 100; ++i)
	{
		if(i < sum)
		{
			array[j] = array[i + sum];
			j++;
		}
		if(i >= sum)
			array[i] = 0;
	}
}

/* Sensors functions */
//void ReadTmp(uint32_t* sht)
void ReadTmp(uint16_t* sht)
{
	uint8_t sht_srt_msb = 0x24;
	uint8_t sht_srt_lsb = 0x00;
	uint8_t pData[2] = {sht_srt_msb, sht_srt_lsb};
	uint8_t data[6] = { 0, };
	HAL_I2C_Master_Transmit(&hi2c1, 0x44 << 1, pData, 2, 10000);

	for(int i = 0; i < 10000; ++i)
	{

	}

	if(HAL_I2C_IsDeviceReady(&hi2c1, (0x44 << 1) | 0x01, 2, 100) == HAL_OK)
	{
		  sht[0] = 3;
	}
	HAL_I2C_Master_Receive(&hi2c1, (0x44 << 1) | 0x01, data, 6, 10000);

	uint16_t rawHValue = (data[3] << 8) | data[4];
	float TValue = ((175.0f * (float)((data[0] << 8) | data[1]) / 65535.0f - 45.0f) * 100);
	if(TValue < 0)
		sht[0] = ((uint16_t)(TValue) | (1 << 16));
	else
		sht[0] = (uint16_t)(TValue);

	sht[1] = (uint16_t)((100.0f * (float)rawHValue / 65535.0f)*100);
}
int uart_counter = 0;
uint8_t usb_buffer[11];
uint8_t thrown_byte = 0;



void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance == USART1)
	{

		if((usb_recv_data[0] == 0x7E) & (usb_recv_data[1] == 0x05))
		{
			uint16_t crc = GetCRC(usb_recv_data, 9);
			uint16_t crc1 = (usb_recv_data[9] << 8) | usb_recv_data[10];
			if(crc == crc1)
			{
				for(unsigned i = 0; i < 11; ++i)
				{
					command_buffer1[i] = usb_recv_data[i];
				}
				flags |= F_FTDI_RECEIVED;
			}
		}
		else
		{
			thrown_byte = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
			CLEAR_BIT(huart->Instance->SR, USART_SR_RXNE);

		}


		HAL_UART_Receive_IT(&huart1, usb_recv_data, 11);
	}
	else if(huart->Instance == USART3)
	{
		if(iot_recv_data == '\n')
		{
			iot_data_buffer[iot_count++]='\n';
			iot_command_index[iot_command_count++] = iot_count;
			flags |= F_IOT_RECEIVED;
		}
		else
		{
			iot_data_buffer[iot_count++] = iot_recv_data;
		}

		HAL_UART_Receive_IT(&huart3, &iot_recv_data, 1);
	}
}


void Convert_To_Hex(void)
{
	char hex[8];
	for(int i = 0; i < 2; ++i)
	{
		naiveHexString(sht[i], hex);
		memcpy(hex_data_buffer + hex_data_buffer_count, hex, 4 * sizeof(char));
		hex_data_buffer_count += 4;
	}
	naiveHexString(bme[1], hex);
	memcpy(hex_data_buffer + hex_data_buffer_count, hex, 4 * sizeof(char));
	hex_data_buffer_count += 4;
}

uint16_t naiveHexString(uint16_t num, char *s)
{
	uint16_t x = (uint16_t)num;
	int i = 3;
	while (i >= 0)
	{
		int digit = (x & 0x0F);
		uint8_t ch = digit + '0';
		if (ch > '9')
			ch += 7;

		s[i] = ch;
		x >>= 4;
		i -= 1;
	}
	return 0;
}


void SystemClock_Config1(void)
{
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

  __HAL_RCC_PWR_CLK_ENABLE();

  //HAL_PWR_EnableBkUpAccess();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);


  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI | RCC_OSCILLATORTYPE_LSI;// | RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.MSIState = RCC_MSI_ON;
  RCC_OscInitStruct.LSIState = RCC_LSI_ON;
  //RCC_OscInitStruct.HSIState = RCC_HSI_OFF;
  RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_0;
  RCC_OscInitStruct.MSICalibrationValue = 0x00;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {

    Error_Handler();
  }

  RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV2;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  {

    Error_Handler();
  }

	HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
	HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);


  __HAL_RCC_MSI_RANGE_CONFIG(RCC_MSIRANGE_0);

}
 /*my config*/
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);

  //HAL_PWR_EnableBkUpAccess();
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_MSI | RCC_OSCILLATORTYPE_LSE;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.LSEState = RCC_LSE_ON;
  //RCC_OscInitStruct.LSIState = RCC_LSI_ON;
  RCC_OscInitStruct.MSIState = RCC_MSI_ON;
  RCC_OscInitStruct.MSICalibrationValue = 0;
  RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_5;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }


  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV8;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  {
    Error_Handler();
  }
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC;
  PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    Error_Handler();
  }

}

void SystemClock_Config2(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);

  //HAL_PWR_EnableBkUpAccess();
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;// | RCC_OSCILLATORTYPE_MSI | RCC_OSCILLATORTYPE_LSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;

  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }


  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV8;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  {
    Error_Handler();
  }

}

static void MX_ADC_Init(void)
{
  ADC_ChannelConfTypeDef sConfig = {0};
  hadc.Instance = ADC1;
  hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
  hadc.Init.Resolution = ADC_RESOLUTION_12B;
  hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc.Init.ScanConvMode = ADC_SCAN_DISABLE;
  hadc.Init.EOCSelection = ADC_EOC_SEQ_CONV;
  hadc.Init.LowPowerAutoWait = ADC_AUTOWAIT_DISABLE;
  hadc.Init.LowPowerAutoPowerOff = ADC_AUTOPOWEROFF_DISABLE;
  hadc.Init.ChannelsBank = ADC_CHANNELS_BANK_A;
  hadc.Init.ContinuousConvMode = DISABLE;
  hadc.Init.NbrOfConversion = 1;
  hadc.Init.DiscontinuousConvMode = DISABLE;
  hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc.Init.DMAContinuousRequests = DISABLE;
  if (HAL_ADC_Init(&hadc) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. 
  */
  sConfig.Channel = ADC_CHANNEL_1;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_4CYCLES;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
}

static void MX_I2C1_Init(void)
{
  hi2c1.Instance = I2C1;
  hi2c1.Init.ClockSpeed = 100000;
  hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
  hi2c1.Init.OwnAddress1 = 0;
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c1.Init.OwnAddress2 = 0;
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c1) != HAL_OK)
  {
    Error_Handler();
  }
}


void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
{
	if(slep == 8)
	{
		HAL_ResumeTick();
		HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
		HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
		HAL_ResumeTick();

		SystemClock_Config2();

		HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
		HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
		slep = 0;
	}

	RTC_TimeTypeDef sTime;
	RTC_DateTypeDef sDate;
	HAL_RTC_DeactivateAlarm(hrtc, RTC_ALARM_A);
	HAL_RTC_GetTime(hrtc, &sTime, RTC_FORMAT_BIN);
	HAL_RTC_GetDate(hrtc, &sDate,RTC_FORMAT_BIN);
	uint8_t next_minute = sTime.Minutes + 1;
	if(next_minute > 59) next_minute = 0;
	uint8_t next_sec = sTime.Seconds + 1;
	if(next_sec > 59) next_sec = next_sec - 60;

	RTC_AlarmTypeDef sAlarm = {0};
	sAlarm.AlarmTime.Minutes = RTC_ByteToBcd2(next_minute);
	sAlarm.AlarmTime.Seconds = RTC_ByteToBcd2(next_sec);
	//sAlarm.AlarmTime.SubSeconds = 0x0;
	sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
	sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
	sAlarm.AlarmMask = RTC_ALARMMASK_HOURS | RTC_ALARMMASK_DATEWEEKDAY | RTC_ALARMMASK_SECONDS;
	sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_NONE;
	//sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
	//sAlarm.AlarmDateWeekDay = 0x1;
	sAlarm.Alarm = RTC_ALARM_A;
	if (HAL_RTC_SetAlarm_IT(hrtc, &sAlarm, RTC_FORMAT_BCD) != HAL_OK)
	{
	Error_Handler();
	}
#ifdef uart_debug
	printmsg("alarma\n");
#endif
	CanSleepSNC = 0x55;
	flags |= F_MEASURE_ALARM;
}

void HAL_RTCEx_AlarmBEventCallback(RTC_HandleTypeDef *hrtc)
{
	if(slep == 8)
	{
		HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
		HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
	HAL_ResumeTick();

	SystemClock_Config2();

	HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
	HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
	slep = 0;
	}



	RTC_TimeTypeDef sTime;
	RTC_DateTypeDef sDate;
	HAL_RTC_DeactivateAlarm(hrtc, RTC_ALARM_B);
	HAL_RTC_GetTime(hrtc, &sTime, RTC_FORMAT_BIN);
	HAL_RTC_GetDate(hrtc, &sDate,RTC_FORMAT_BIN);
	uint8_t next_minute = sTime.Minutes + 7;
	if(next_minute > 59) next_minute = next_minute - 60;
	uint8_t next_sec = sTime.Seconds + 20;
	if(next_sec > 59) next_sec = next_sec - 60;

	RTC_AlarmTypeDef sAlarm = {0};
	sAlarm.AlarmTime.Minutes = RTC_ByteToBcd2(next_minute);
	sAlarm.AlarmTime.Seconds = RTC_ByteToBcd2(next_sec);
	//sAlarm.AlarmTime.SubSeconds = 0x0;
	sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
	sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
	sAlarm.AlarmMask = RTC_ALARMMASK_HOURS | RTC_ALARMMASK_DATEWEEKDAY | RTC_ALARMMASK_SECONDS;
	sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_NONE;
	//sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
	//sAlarm.AlarmDateWeekDay = 0x1;
	sAlarm.Alarm = RTC_ALARM_B;
	if (HAL_RTC_SetAlarm_IT(hrtc, &sAlarm, RTC_FORMAT_BCD) != HAL_OK)
	{
	Error_Handler();
	}

	CanSleepIOT = 0x55;
	CanSleepSD = 0x55;
	flags |= F_SEND_ALARM;
	iot_state = idle;
	flags |= F_SD_CARD;

}

static void MX_RTC_Init(void)
{
  RTC_TimeTypeDef sTime = {0};
  RTC_DateTypeDef sDate = {0};
  RTC_AlarmTypeDef sAlarm = {0};

  /** Initialize RTC Only 
  */
  hrtc.Instance = RTC;
  hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
  hrtc.Init.AsynchPrediv = 127;
  hrtc.Init.SynchPrediv = 255;
  hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
  hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
  hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
  if (HAL_RTC_Init(&hrtc) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initialize RTC and set the Time and Date 
  */
  sTime.Hours = 0x0;
  sTime.Minutes = 0x0;
  sTime.Seconds = 0x0;
  sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
  sTime.StoreOperation = RTC_STOREOPERATION_RESET;
  if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK)
  {
    Error_Handler();
  }
  sDate.WeekDay = RTC_WEEKDAY_MONDAY;
  sDate.Month = RTC_MONTH_JANUARY;
  sDate.Date = 0x1;
  sDate.Year = 0x0;

  if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK)
  {
    Error_Handler();
  }
  /** Enable the Alarm A 
  */

  memset(&sAlarm, 0, sizeof(sAlarm));
  //sAlarm.AlarmTime.Hours = 0x0;
  //sAlarm.AlarmTime.Minutes = 0x0;
  sAlarm.AlarmTime.Minutes = RTC_ByteToBcd2(1);
  //sAlarm.AlarmTime.Seconds = RTC_ByteToBcd2(59);
  //sAlarm.AlarmTime.SubSeconds = 0x0;
  //sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
  //sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
  sAlarm.AlarmMask = RTC_ALARMMASK_HOURS | RTC_ALARMMASK_DATEWEEKDAY | RTC_ALARMMASK_SECONDS;
  //sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;
  //sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
  //sAlarm.AlarmDateWeekDay = 0x1;
  sAlarm.Alarm = RTC_ALARM_A;
  if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BCD) != HAL_OK)
  {
    Error_Handler();
  }
  /** Enable the Alarm B 
  */
  memset(&sAlarm, 0, sizeof(sAlarm));

  HAL_RTC_DeactivateAlarm(&hrtc, RTC_ALARM_B);
  sAlarm.AlarmTime.Seconds = RTC_ByteToBcd2(20);
  sAlarm.AlarmTime.Minutes = RTC_ByteToBcd2(7);
//sAlarm.AlarmTime.SubSeconds = 0x0;
//sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
//sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
  sAlarm.AlarmMask = RTC_ALARMMASK_HOURS | RTC_ALARMMASK_DATEWEEKDAY;// | RTC_ALARMMASK_MINUTES;
//sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_NONE;
//sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
//sAlarm.AlarmDateWeekDay = 0x1;
  sAlarm.Alarm = RTC_ALARM_B;

  if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BCD) != HAL_OK)
  {
	  Error_Handler();
  }
}

static void MX_SPI1_Init(void)
{
  /* SPI1 parameter configuration*/
  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_MASTER;
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
  hspi1.Init.NSS = SPI_NSS_SOFT;
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 10;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    Error_Handler();
  }
}

static void MX_USART1_UART_Init(void)
{
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 38400;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
}

static void MX_USART3_UART_Init(void)
{
  huart3.Instance = USART3;
  huart3.Init.BaudRate = 57600;
  huart3.Init.WordLength = UART_WORDLENGTH_8B;
  huart3.Init.StopBits = UART_STOPBITS_1;
  huart3.Init.Parity = UART_PARITY_NONE;
  huart3.Init.Mode = UART_MODE_TX_RX;
  huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart3.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart3) != HAL_OK)
  {
    Error_Handler();
  }
}

/** 
  * Enable DMA controller clock
  */
static void MX_DMA_Init(void) 
{

  /* DMA controller clock enable */
  __HAL_RCC_DMA1_CLK_ENABLE();
  //__HAL_RCC_DMA1_CLK_SLEEP_DISABLE();

  /* DMA interrupt init */
  /* DMA1_Channel2_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Channel2_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel2_IRQn);
  /* DMA1_Channel4_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Channel4_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel4_IRQn);

}

static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3|SPI1_CS_Pin|SD_VCC_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, SNC_VCC_Pin|GPIO_PIN_5|GPIO_PIN_8|GPIO_PIN_9, GPIO_PIN_RESET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(IOT_VCC_GPIO_Port, IOT_VCC_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pins : PC3 SPI1_CS_Pin SD_VCC_Pin */
  GPIO_InitStruct.Pin = GPIO_PIN_3|SPI1_CS_Pin|SD_VCC_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  /*Configure GPIO pins : SNC_VCC_Pin PB5 PB8 PB9 */
  GPIO_InitStruct.Pin = SNC_VCC_Pin;//|GPIO_PIN_5|GPIO_PIN_8|GPIO_PIN_9;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  /*Configure GPIO pin : IOT_VCC_Pin */
  GPIO_InitStruct.Pin = IOT_VCC_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(IOT_VCC_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pin : IOT_RESET_Pin */
  GPIO_InitStruct.Pin = IOT_RESET_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(IOT_RESET_GPIO_Port, &GPIO_InitStruct);



}

//void ReadPressure(uint32_t* bme)
void ReadPressure(uint16_t* bme)
{
	uint8_t bme_set = 0b00000000;
	bme_set = bme_set |0b11100001;
	bme_set = bme_set |0b00011101;

	volatile int32_t teplota = 0;
	//i2cdata[0] = 0xFB;
	uint8_t data_bmp[8] = { 0, };
	uint8_t calib_tmp[6] = { 0, };

	HAL_I2C_Mem_Write(&hi2c1, 0x77 << 1, 0xF4, I2C_MEMADD_SIZE_8BIT, &bme_set,1, 10000);// startup measurement

	HAL_Delay(100);		//time for measure

	HAL_I2C_Mem_Read(&hi2c1, 0x77 << 1, 0xF7, I2C_MEMADD_SIZE_8BIT, data_bmp, 8, 10000);
	HAL_I2C_Mem_Read(&hi2c1, 0x77 << 1, 0x88, I2C_MEMADD_SIZE_8BIT, calib_tmp,6, 10000);

	int32_t adc_T = (int32_t)((((uint32_t) (data_bmp[3]))<< 12) |(((uint32_t)(data_bmp[4]))	<< 4)| ((uint32_t)data_bmp[5] >>4));

	uint16_t dig_T1 = (uint16_t)((((uint16_t)((uint8_t)calib_tmp[1])) <<8)| calib_tmp[0]);
	int16_t dig_T2 = (int16_t)((((int16_t)((int8_t)calib_tmp[3])) <<8)| calib_tmp[2]);
	int16_t dig_T3 = (int16_t)((((int16_t)((int8_t)calib_tmp[5])) <<8)| calib_tmp[4]);

	int32_t var1 = ((((adc_T >> 3) - ((int32_t)dig_T1 << 1))) * ((int32_t)dig_T2)) >> 11;

	int32_t var2 = (((((adc_T >> 4) - ((int32_t)dig_T1)) * ((adc_T >> 4) - ((int32_t)dig_T1)))>> 12) * ((int32_t)dig_T3)) >> 14;
	int32_t t_fine = 0;
	t_fine = var1 + var2;
	teplota = (t_fine * 5 + 128) >> 8;

	uint8_t calib_pre[18] = { 0, };
	volatile uint32_t tlak = 0;
	HAL_I2C_Mem_Read(&hi2c1, 0x77 << 1, 0x8E, I2C_MEMADD_SIZE_8BIT, calib_pre, 18, 10000);		//Pressure calibration data

	int32_t adc_P =(int32_t)((((uint32_t)(data_bmp[0]))<< 12)|(((uint32_t)(data_bmp[1]))<< 4)|((uint32_t)data_bmp[2] >>4));

	uint16_t dig_P1 = (uint16_t)((((uint16_t)((uint8_t)calib_pre[1])) <<8)| calib_pre[0]);
	int16_t dig_P2 = (int16_t)((((int16_t)((int8_t)calib_pre[3])) <<8)| calib_pre[2]);
	int16_t dig_P3 = (int16_t)((((int16_t)((int8_t)calib_pre[5])) <<8)| calib_pre[4]);
	int16_t dig_P4 = (int16_t)((((int16_t)((int8_t)calib_pre[7])) <<8)| calib_pre[6]);
	int16_t dig_P5 = (int16_t)((((int16_t)((int8_t)calib_pre[9])) <<8)| calib_pre[8]);
	int16_t dig_P6 = (int16_t)((((int16_t)((int8_t)calib_pre[11])) <<8)| calib_pre[10]);
	int16_t dig_P7 = (int16_t)((((int16_t)((int8_t)calib_pre[13])) <<8)| calib_pre[12]);
	int16_t dig_P8 = (int16_t)((((int16_t)((int8_t)calib_pre[15])) <<8)| calib_pre[14]);
	int16_t dig_P9 = (int16_t)((((int16_t)((int8_t)calib_pre[17])) <<8)| calib_pre[16]);

	int32_t pvar1 = (((int32_t) t_fine)>>1) - (int32_t)64000;
	int32_t pvar2 = (((pvar1 >> 2)* (pvar1 >> 2)	) >> 11)* ((int32_t)dig_P6);
	pvar2 = pvar2 + ((pvar1 *((int32_t)dig_P5))<< 1);
	pvar2 = (pvar2 >> 2) +(((int32_t)dig_P4)<< 16);
	pvar1 = (((dig_P3 *(((pvar1 >> 2) *(pvar1>> 2))	>> 13))	>> 3) +	((((int32_t)dig_P2) *pvar1) >> 1))	>> 18;
	pvar1 = ((((32768 + pvar1)) *((int32_t)dig_P1))	>> 15);
	uint32_t p_fine = (((uint32_t)(((int32_t)1048576) - adc_P)- (pvar2 >> 12))) * 3125;
	if(p_fine<0x80000000)
		if(pvar1!=0)
			p_fine = (p_fine<<1)/((uint32_t)pvar1);
		else
			p_fine = 0;
	else
		if(pvar1!=0)
			p_fine=(p_fine/(uint32_t)pvar1)*2;
		else
			p_fine = 0;

	if(p_fine!=0)
	{
		pvar1=(((int32_t)dig_P9) *((int32_t)(((p_fine>> 3)* (p_fine >> 3))>> 13)))>> 12;
		pvar2 = (((int32_t)(p_fine>> 2)) *((int32_t)dig_P8))>> 13;
		p_fine= (uint32_t)((int32_t)p_fine +((pvar1+ pvar2 + dig_P7)>> 4));
	}

	tlak = ((uint32_t) p_fine);
	bme[0] = (uint16_t)teplota;
	bme[1] = (uint16_t)(((float)(tlak))/10);
}

static uint16_t GetCRC(uint8_t *message, uint16_t length)
{
	uint16_t CRCFull = 0xFFFF;
	char CRCLSB;

	for (int i = 0; i < (length) - 2; i++)
	{
		CRCFull = (uint16_t)(CRCFull ^ message[i]);

		for (int j = 0; j < 8; j++)
		{
			CRCLSB = (char)(CRCFull & 0x0001);
			CRCFull = (uint16_t)((CRCFull >> 1) & 0x7FFF);

			if (CRCLSB == 1)
				CRCFull = (uint16_t)(CRCFull ^ 0xA001);
		}
	}

	//CRCFull = (ushort)(((CRCFull & 0x00FF) << 8) | (CRCFull >> 8));

	return CRCFull;
}

void GPIO_AnalogConfig(void)
{
	  __HAL_RCC_GPIOA_CLK_ENABLE();
	  __HAL_RCC_GPIOB_CLK_ENABLE();
	  __HAL_RCC_GPIOC_CLK_ENABLE();
	  __HAL_RCC_GPIOD_CLK_ENABLE();
	  __HAL_RCC_GPIOH_CLK_ENABLE();

	GPIO_InitTypeDef Gpio;
	uint32_t gpio_pins = GPIO_PIN_0 | \
						 GPIO_PIN_3 | GPIO_PIN_4 | \
						 GPIO_PIN_8 | \
						 GPIO_PIN_11 | GPIO_PIN_12;

	Gpio.Pin = gpio_pins;
	Gpio.Mode = GPIO_MODE_ANALOG;
	Gpio.Pull = GPIO_NOPULL;
	HAL_GPIO_Init(GPIOA, &Gpio);

	gpio_pins = 0;
	gpio_pins = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | \
						 GPIO_PIN_10 | \
						 GPIO_PIN_11 | GPIO_PIN_13 | \
						 GPIO_PIN_14 | GPIO_PIN_15;

	Gpio.Pin = gpio_pins;
	Gpio.Mode = GPIO_MODE_ANALOG;
	Gpio.Pull = GPIO_NOPULL;
	HAL_GPIO_Init(GPIOB, &Gpio);

	gpio_pins = 0;
	gpio_pins = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | \
						 GPIO_PIN_6 | GPIO_PIN_7 | \
						 GPIO_PIN_8 | GPIO_PIN_9 | \
						 GPIO_PIN_12 | GPIO_PIN_13;

	Gpio.Pin = gpio_pins;
	Gpio.Mode = GPIO_MODE_ANALOG;
	Gpio.Pull = GPIO_NOPULL;
	HAL_GPIO_Init(GPIOC, &Gpio);

	gpio_pins = 0;
	gpio_pins = GPIO_PIN_0 | GPIO_PIN_1 | \
							 GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | \
							 GPIO_PIN_6 | GPIO_PIN_7 | \
							 GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | \
							 GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | \
							 GPIO_PIN_14 | GPIO_PIN_15;

	Gpio.Pin = gpio_pins;
	Gpio.Mode = GPIO_MODE_ANALOG;
	Gpio.Pull = GPIO_NOPULL;
	HAL_GPIO_Init(GPIOD, &Gpio);

	gpio_pins = 0;
	gpio_pins = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | \
							 GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | \
							 GPIO_PIN_6 | GPIO_PIN_7 | \
							 GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | \
							 GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | \
							 GPIO_PIN_14 | GPIO_PIN_15;

	Gpio.Pin = gpio_pins;
	Gpio.Mode = GPIO_MODE_ANALOG;
	Gpio.Pull = GPIO_NOPULL;
	HAL_GPIO_Init(GPIOE, &Gpio);

	gpio_pins = 0;
	gpio_pins = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | \
							 GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | \
							 GPIO_PIN_6 | GPIO_PIN_7 | \
							 GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | \
							 GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | \
							 GPIO_PIN_14 | GPIO_PIN_15;

	Gpio.Pin = gpio_pins;
	Gpio.Mode = GPIO_MODE_ANALOG;
	Gpio.Pull = GPIO_NOPULL;
	HAL_GPIO_Init(GPIOF, &Gpio);

	gpio_pins = 0;
	gpio_pins = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | \
							 GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | \
							 GPIO_PIN_6 | GPIO_PIN_7 | \
							 GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | \
							 GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | \
							 GPIO_PIN_14 | GPIO_PIN_15;

	Gpio.Pin = gpio_pins;
	Gpio.Mode = GPIO_MODE_ANALOG;
	Gpio.Pull = GPIO_NOPULL;
	HAL_GPIO_Init(GPIOG, &Gpio);

	gpio_pins = 0;
	gpio_pins = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | \
							 GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | \
							 GPIO_PIN_6 | GPIO_PIN_7 | \
							 GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | \
							 GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | \
							 GPIO_PIN_14 | GPIO_PIN_15;

	Gpio.Pin = gpio_pins;
	Gpio.Mode = GPIO_MODE_ANALOG;
	Gpio.Pull = GPIO_NOPULL;
	HAL_GPIO_Init(GPIOH, &Gpio);
}


void Error_Handler(void)
{

}

static void EXTI17_IRQHandler_Config(void)
{
	  GPIO_InitTypeDef   GPIO_InitStructure = {0};

	  //__HAL_RCC_GPIOA_CLK_ENABLE();
	  __HAL_RCC_SYSCFG_CLK_ENABLE();

	  GPIO_InitStructure.Mode = GPIO_MODE_IT_RISING;
	  GPIO_InitStructure.Pull = GPIO_NOPULL;

	  HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
	  __HAL_GPIO_EXTI_CLEAR_FLAG(GPIO_PIN_10);
	  NVIC_ClearPendingIRQ(EXTI15_10_IRQn);

	  HAL_NVIC_SetPriority(EXTI15_10_IRQn, 0, 0);
	  HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
}

#ifdef  USE_FULL_ASSERT

void assert_failed(uint8_t *file, uint32_t line)
{ 

}
#endif /* USE_FULL_ASSERT */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
