#include "stm32f0xx.h"
#include "stm32f0xx_rcc.h"
#include "stm32f0xx_gpio.h"
#include "stm32f0xx_i2c.h"
#include "ugui.h"
#include "stdio.h"
#include "stdlib.h"
#include "strings.h"
#include "string.h"
#include "iprintf.h"
#include "DS3231.h"
#include "ADE7953.h"
#include "ESP8266.h"
#include "CAP1296.h"
#include "OUTPUT.h"
#include "LEDS.h"
#include "SysTick.h"
#include "stm32f0xx_exti.h"


void UI_process(void);
void show_idle_window(void);
void show_main_window(uint32_t tlacitko);
void show_settings_window(uint32_t tlacitko);
uint32_t read_keys(void);
void UI_TIMER_Init(void);
void ADE7953_meas(void);
volatile uint8_t *textbuff3[150];
void EXTI0_Config(void);
void HyperTerminal_Interrupt(void);
void initialization (void);

RTC_time_t cas;
volatile uint8_t jas=100;
extern volatile uint8_t pokus;
volatile uint32_t spotreba=0;
volatile uint32_t pripojeno=0;
volatile uint32_t vystup=0;
volatile uint32_t aktualizovat_cas=0;
RTC_time_t prijaty_cas;



void initialization (void)
{
	SystemInit();
	SystemCoreClockUpdate();
	SysTick_Config(SystemCoreClock/1000);

	RELAY_Init();
	BUZZER_Init();
	LEDS_Init();

	//I2C Init
	GPIO_InitTypeDef GP;
	I2C_InitTypeDef IT;
	uint32_t var;
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
	GP.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
	GP.GPIO_Mode = GPIO_Mode_OUT;
	GP.GPIO_OType = GPIO_OType_PP;
	GP.GPIO_Speed = GPIO_Speed_Level_3;
	GPIO_Init(GPIOB, &GP);

	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
	GP.GPIO_Pin = GPIO_Pin_7;
	GP.GPIO_Mode = GPIO_Mode_OUT;
	GP.GPIO_OType = GPIO_OType_PP;
	GP.GPIO_Speed = GPIO_Speed_Level_3;
	GPIO_Init(GPIOA, &GP);

	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
	GP.GPIO_Pin = GPIO_Pin_13;
	GP.GPIO_Mode = GPIO_Mode_IN;
	GP.GPIO_OType = GPIO_OType_PP;
	GP.GPIO_Speed = GPIO_Speed_Level_3;
	GP.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_Init(GPIOC, &GP);

	GPIO_SetBits(GPIOB,GPIO_Pin_10);
	GPIO_SetBits(GPIOB,GPIO_Pin_11);
	for (var = 0; var < 0xffff; ++var);

	GP.GPIO_Pin = GPIO_Pin_1;
	GP.GPIO_Mode = GPIO_Mode_OUT;
	GP.GPIO_OType = GPIO_OType_PP;
	GP.GPIO_Speed = GPIO_Speed_Level_3;
	GPIO_Init(GPIOB, &GP);


	GP.GPIO_Pin = GPIO_Pin_8;		//ESP8266
	GP.GPIO_Mode = GPIO_Mode_OUT;
	GP.GPIO_OType = GPIO_OType_PP;
	GP.GPIO_Speed = GPIO_Speed_Level_3;
	GPIO_Init(GPIOA, &GP);


	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
	GP.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
	GP.GPIO_Mode = GPIO_Mode_AF;
	GP.GPIO_OType = GPIO_OType_OD;
	GP.GPIO_Speed = GPIO_Speed_Level_1;
	GPIO_Init(GPIOB, &GP);


	//Configure the pins to the I2C AF


	RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
	//Setup the I2C struct. The timing variable is acquired
	//from the STM32F0 I2C timing calculator sheet. Pretty
	//standard stuff really, its using the Analog filter
	//to clean up any noisy edges (not really required though
	//if you wish to disable it, you will need a different
	//I2C_Timing value).
	IT.I2C_Ack = I2C_Ack_Enable;
	IT.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
	IT.I2C_DigitalFilter = 0;
	IT.I2C_Mode = I2C_Mode_I2C;
	IT.I2C_OwnAddress1 = 0xAB;
	IT.I2C_Timing = 0x00901850;
	IT.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
	I2C_Init(I2C2, &IT);

	GPIO_PinAFConfig(GPIOB,GPIO_PinSource10,GPIO_AF_1);
	GPIO_PinAFConfig(GPIOB,GPIO_PinSource11,GPIO_AF_1);
	I2C_Cmd(I2C2, ENABLE);
}



int main(void)
{
	uint32_t var;
	initialization();

	GPIO_ResetBits(GPIOB,GPIO_Pin_1);	//OLED
	GPIO_ResetBits(GPIOA,GPIO_Pin_7);	//ADE7953
	GPIO_ResetBits(GPIOA,GPIO_Pin_8);	//ESP8266
	for (var = 0; var < 0xffff; ++var);
	GPIO_SetBits(GPIOB,GPIO_Pin_1);
	GPIO_SetBits(GPIOA,GPIO_Pin_7);
	GPIO_SetBits(GPIOA,GPIO_Pin_8);
	for (var = 0; var < 0xffff; ++var);
	GPIO_ResetBits(GPIOB,GPIO_Pin_1);	//OLED
	GPIO_ResetBits(GPIOA,GPIO_Pin_7);	//ADE
	GPIO_ResetBits(GPIOA,GPIO_Pin_8);
	for (var = 0; var < 0xffff; ++var);
	GPIO_SetBits(GPIOB,GPIO_Pin_1);
	GPIO_SetBits(GPIOA,GPIO_Pin_7);
	GPIO_SetBits(GPIOA,GPIO_Pin_8);
	for (var = 0; var < 0xffff; ++var);


	OLED_init();

	#define MAX_OBJECTS 10
	UG_GUI gui;
	UG_Init(&gui,pixelset,128,64);
	UG_FontSelect(&FONT_6X8_CZECH);
	UG_SetBackcolor(0);
	UG_SetForecolor(1);

	UG_FillScreen(0);
	uint8_t textbuff[100];
	uint8_t textbuff2[100];

	update_display();

	ESP8266_Init();
	ESP8266_send_cmd("AT+RST\r\n",1,"ready\r\n");

	ESP8266_send_cmd("AT+CWMODE=1\r\n",1,"no change\r\n");

	pripojeno=ESP8266_send_cmd("AT+CWJAP=\"android\",\"asdfghjk\"\r\n",2,"OK\r\n","ERROR\r\n");

	delay(2000);


	ADE7953_init();


	LEDS_SetPWM(100);

	DS3232_squareWave();

	while(1)
    {
    	DS3231_read_time(&cas);

    	update_display();

    	CAP1296_init();

    	TIM_Cmd(TIM6, DISABLE);	//VYPNUTI OTACENI KRUHU
		UI_TIMER_Init();

		ESP8266_send_cmd("AT+CIPSTART=\"TCP\",\"smartplug.smartsys.cz\",80\r\n",1,"OK\r\nLinked\r\n");
		delay(300);
		ESP8266_send_cmd("AT+CIPSEND=108\r\n",1,"> ");
		moba_siprintf(textbuff3,"GET /receiver.php?data=%05d%05d%05d%05d%05d%05d%02d%02d%02d%02d%02d%02d%d HTTP/1.1\r\nHost: smartplug.smartsys.cz\r\n\r\n",(uint32_t)napeti_server/10,(uint32_t)proud_server,(int32_t)active_power_server/100,(int32_t)apparent_power_server/100,(int32_t)active_energy_server,(int32_t)ucinik_server/10,cas.Hour,cas.Minute,cas.Second,cas.Day,cas.Month,cas.Year,vystup);
		ESP8266_transfer(textbuff3, textbuff2);
		string_2_DateTime(textbuff2,&prijaty_cas);
		aktualizovat_cas=1;

		while(1)
		{

			if(pripojeno==1)
			{
				ESP8266_send_cmd("AT+CIPSTART=\"TCP\",\"smartplug.smartsys.cz\",80\r\n",1,"OK\r\nLinked\r\n");
				delay(300);
				ESP8266_send_cmd("AT+CIPSEND=108\r\n",1,"> ");
				moba_siprintf(textbuff3,"GET /receiver.php?data=%05d%05d%05d%05d%05d%05d%02d%02d%02d%02d%02d%02d%d HTTP/1.1\r\nHost: smartplug.smartsys.cz\r\n\r\n",(uint32_t)napeti_server/10,(uint32_t)proud_server,(int32_t)active_power_server/100,(int32_t)apparent_power_server/100,(int32_t)active_energy_server,(int32_t)ucinik_server/10,cas.Hour,cas.Minute,cas.Second,cas.Day,cas.Month,cas.Year,vystup);
				ESP8266_transfer(textbuff3, textbuff2);

				if(textbuff2[13]=='0')
				{
					vystup=0;
					RELAY(0);
				}
				else if(textbuff2[13]=='1')
				{
					vystup=1;
					RELAY(1);
				}

				ESP8266_send_cmd("AT+CIPCLOSE\r\n",1,"Unlink\r\n");
			}
		}

    }
}

void EXTI0_Config(void)
{
	EXTI_InitTypeDef   EXTI_InitStructure;
	GPIO_InitTypeDef   GPIO_InitStructure;
	NVIC_InitTypeDef   NVIC_InitStructure;

	/* Enable GPIOA clock */
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);

	/* Configure PA0 pin as input floating */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_Init(GPIOC, &GPIO_InitStructure);

	/* Enable SYSCFG clock */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

	/* Connect EXTI0 Line to PC14 pin */
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC, EXTI_PinSource13);

	/* Configure EXTI0 line */
	EXTI_InitStructure.EXTI_Line = EXTI_Line13;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStructure);




	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOF, ENABLE);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_Init(GPIOF, &GPIO_InitStructure);

	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOF, EXTI_PinSource6);


	EXTI_InitStructure.EXTI_Line = EXTI_Line6;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStructure);


	NVIC_InitStructure.NVIC_IRQChannel = EXTI4_15_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPriority = 0x02;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);



	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_Init(GPIOF, &GPIO_InitStructure);

	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource3);


	EXTI_InitStructure.EXTI_Line = EXTI_Line3;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStructure);


	NVIC_InitStructure.NVIC_IRQChannel = EXTI2_3_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPriority = 0x01;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
}

void EXTI4_15_IRQHandler(void)
{
	if(EXTI_GetITStatus(EXTI_Line6) != RESET)
	{
		EXTI_ClearITPendingBit(EXTI_Line6);
		//Beep(20);
		cas.Second++;
		if(cas.Second>59)
		{
			cas.Second=0;
			cas.Minute++;
				if(cas.Minute>59)
				{
					cas.Minute=0;
					cas.Hour++;
					if(cas.Hour>23)
					{
						cas.Hour=0;
					}
				}
		}
	}
}


void EXTI2_3_IRQHandler(void)
{
  if(EXTI_GetITStatus(EXTI_Line3) != RESET)
  	{
  		EXTI_ClearITPendingBit(EXTI_Line3);
  		//Beep(5);
  		spotreba++;
  	}
}





