
/* Includes ------------------------------------------------------------------*/
#include <stdlib.h>
#include <string.h>
#include "global_defines.h"
#include "peripherals.h"
#include "lcd2x16.h"
#include "error.h"
#include "menu.h"
#include "gpio.h"
#include "adc.h"
#include "flash.h"
#include "comms.h"
#include "mensajes.h"

/* Global variables ----------------------------------------------------------*/
IWDG_HandleTypeDef IwdgHandle;	// Handle del iwdg
int backlightTicks;				// Ticks en la última pulsación de tecla
int sistema;


/////////////////////////////
GPIO_InitTypeDef GPIO_InitStruct;

void gpio_set_input (void)
{
  GPIO_InitStruct.Pin = GPIO_PIN_8;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
}


void gpio_set_output (void)
{
  GPIO_InitStruct.Pin = GPIO_PIN_8;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
}


uint8_t check =2, temp_l, temp_h;
uint16_t temp;
float temperature;

uint8_t ds18b20_init (void)
{
   gpio_set_output ();   // set the pin as output
   HAL_GPIO_WritePin (GPIOE, GPIO_PIN_8, 0);  // pull the pin low
   HAL_Delay(480);   // delay according to datasheet

   gpio_set_input ();    // set the pin as input
   HAL_Delay(80);    // delay according to datasheet

   if (!(HAL_GPIO_ReadPin (GPIOE, GPIO_PIN_8)))    // if the pin is low i.e the presence pulse is there
   {
      HAL_Delay(400);  // wait for 400 us
      return 0;
   }

   else
   {
      HAL_Delay(400);
      return 1;
   }
}



void write (uint8_t data)
{
   gpio_set_output ();   // set as output

   for (int i=0; i<8; i++)
   {

      if ((data & (1<<i))!=0)  // if the bit is high
      {
         // write 1

         gpio_set_output ();  // set as output
         HAL_GPIO_WritePin (GPIOE, GPIO_PIN_8, 0);  // pull the pin LOW
         HAL_Delay(1);  // wait for  us

         gpio_set_input ();  // set as input
         HAL_Delay(60);  // wait for 60 us
      }

      else  // if the bit is low
      {
         // write 0

         gpio_set_output ();
         HAL_GPIO_WritePin (GPIOE, GPIO_PIN_8, 0);  // pull the pin LOW
         HAL_Delay(60);  // wait for 60 us

         gpio_set_input ();
      }
   }
}



uint8_t read (void)
{
   uint8_t value=0;
   gpio_set_input ();

   for (int i=0;i<8;i++)
   {
      gpio_set_output ();   // set as output

      HAL_GPIO_WritePin (GPIOE, GPIO_PIN_8, 0);  // pull the data pin LOW
      HAL_Delay(2);  // wait for 2 us

      gpio_set_input ();  // set as input
      if (HAL_GPIO_ReadPin (GPIOE, GPIO_PIN_8))  // if the pin is HIGH
      {
         value |= 1<<i;  // read = 1
      }
      HAL_Delay(60);  // wait for 60 us
   }
   return value;
}

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);


int main(void) {

	char line[41];					// To build lines for the lcd

	// STM32F7xx HAL library initialization
	if (HAL_Init() != HAL_OK) {
		blink_error_code(ERROR_HAL_INIT);
	}

	// Configure the system clock
	SystemClock_Config();
	lcdInit();
	backlightInit();
	ledErrorInit();
	ledPressInit();
	ledCO2Init();
	presostatoInit();
	co2Init();
	sistema = sistemaInit();

	// Inicializar iwdg
	IwdgHandle.Instance = IWDG;
	IwdgHandle.Init.Prescaler = IWDG_PRESCALER_128;
	IwdgHandle.Init.Reload = 0x8ff;

	HAL_IWDG_Init(&IwdgHandle);



	////// Main loop //////
	while (1) {

	      check = ds18b20_init ();
	      write (0xCC);  // skip ROM
	      write (0x44);  // convert t

	      HAL_Delay (800);

	      ds18b20_init ();
	      write (0xCC);  // skip ROM
	      write (0xBE);  // Read Scratchpad

	      temp_l = read();
	      temp_h = read();
	      temp = (temp_h<<8)|temp_l;
	      temperature = (float)temp/16;



		// Refrescar watch dog
		HAL_IWDG_Refresh(&IwdgHandle);

		startConversion();
		waitConversion();
		sprintf(line, "TEM = %d ",(int)(temperature));
		lcdPutsCenter(0, line);

		}


/**
 * @brief  System Clock Configuration
 * @param  None
 * @retval None
 */
void SystemClock_Config(void) {
	RCC_ClkInitTypeDef RCC_ClkInitStruct;
	RCC_OscInitTypeDef RCC_OscInitStruct;
	HAL_StatusTypeDef ret = HAL_OK;

	/* Enable HSE Oscillator and activate PLL with HSE as source */
	RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
	RCC_OscInitStruct.HSEState = RCC_HSE_ON;
	RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
	RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
#ifdef STM32F746G
	RCC_OscInitStruct.PLL.PLLM = 25;
	RCC_OscInitStruct.PLL.PLLN = 432;	// 400
	RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
	RCC_OscInitStruct.PLL.PLLQ = 9;		// 8
#else
	RCC_OscInitStruct.PLL.PLLM = 8;
	RCC_OscInitStruct.PLL.PLLN = 336;
	RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
	RCC_OscInitStruct.PLL.PLLQ = 7;
#endif

	ret = HAL_RCC_OscConfig(&RCC_OscInitStruct);
	if (ret != HAL_OK) {
		blink_error_code(ERROR_HAL_RCC_OSC);
	}

	/* Activate the OverDrive to reach the 200 MHz Frequency */
	ret = HAL_PWREx_EnableOverDrive();
	if (ret != HAL_OK) {
		blink_error_code(ERROR_HAL_PWR);
	}

	/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */
	RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK
			| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
	RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
	RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
	RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
	RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

#ifdef STM32F746G
	ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7);	// FLASH_LATENCY_6
#else
	ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);
#endif
	if (ret != HAL_OK) {
		blink_error_code(ERROR_HAL_RCC_CLOCK);
	}
}

