#include "scanner_lib.h"
#include "stm32f4xx.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_usart.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_exti.h"
#include "stm32f4xx_syscfg.h"
#include "misc.h"


uint8_t task[askmax];
uint8_t answer[ansmax];


unsigned short int p_distances[541];

void usartInit(uint32_t br)
{
	/*zapnout hodiny pro usart1°*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
	/*nastavit piny portuB pro USART1*/
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	/*namapovat piny na usart1*/
	GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_USART1); /*Tx*/
	GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1); /*Rx*/
	/*nastaveni usart1*/
	USART_InitStructure.USART_BaudRate = br;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_OverSampling8Cmd(USART1,ENABLE);
	USART_Init(USART1, &USART_InitStructure);
	/*zapnout usart1*/
	USART_Cmd(USART1, ENABLE);
}

void answerInit()
{
	uint32_t a;
	for(a = 0; a<ansmax ; a++)
	{
		answer[a] = 0;
	}
}

unsigned char *sendTask_getAns(unsigned char *r)
{
	while(*r != etx)
	{
		USART_SendData(USART1, (*r));
		Delay(0x000000FF);
		r++;
	}
	USART_SendData(USART1, (*r));

	r = &answer[0];
	while(1)
	{
		while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) != SET)
		{;} //čekej na data
		*r = USART_ReceiveData(USART1);
		if(*r == etx)
		{
			USART_ClearFlag(USART1, USART_FLAG_RXNE);
			break;
		}

		if(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == SET)
		{}
		else {r++;}
	}
	return &answer[0];
}


unsigned short int dataprocessing(unsigned char p_ans[])
{
	uint32_t count = 0;
	uint32_t count2 = 0;
	uint32_t count3 = 0;
	uint8_t *t;
	uint8_t buffer[5];
	uint8_t *ptr_buf;
	t = &p_ans[125];
	while(count < 541)
	{
		while(*t != 0x20)
		{
			buffer[count2] = *t;
			count2++;
			t++;
		}
		buffer[count2+1] = '\0';
		ptr_buf = &buffer[0];
		p_distances[count] = strtol((char*)ptr_buf,'\0',16);
		count++;
		t++;
		count2 = 0;
		for(count3 = 0 ; count3 < 5 ; count3++)
		{
			buffer[count3] = 0;
		}
	}
	return p_distances[0];
}


unsigned char ansCheck(uint8_t* s)
{
	uint8_t d;
	uint8_t *e;
	e = s + 2;
	if(*e == 'R')
	{
		d = 1;
	}
	else if(*e == 'W')
	{
		d = 1;
	}
	else if(*e == 'A')
	{
		d = 1;
	}
	else
		d = 0;

	return d;
}


unsigned char *taskInit(char* t)
{
	uint32_t j = 0;
	task[j]=stx;
	while(*t != '<')
	{
		j++;
		task[j] = *t;
		t++;
	}
	j++;
	task[j] = etx;

	return &task[0];
}

void dataCooker(unsigned char *t, sdata *datastruct )
{
	uint32_t count = 0;
	uint32_t count2 = 0;

	while(*t != etx)
	{
		if(*t == stx)
		{
			/*command type*/
			t++;
			while(*t != 0x20)
			{
				datastruct->CmdType[count] = *t;
				count++;
				t++;
			}

			/*command*/
			count = 0;
			t++;
			while(*t != 0x20)
			{
				datastruct->Cmd[count] = *t;
				count++;
				t++;
			}

			/*version number*/
			count = 0;
			t++;
			while(*t != 0x20)
			{
				datastruct->VerNum[count] = *t;
				count++;
				t++;
			}

			/*device number*/
			count = 0;
			t++;
			while(*t != 0x20)
			{
				datastruct->DevNum[count] = *t;
				count++;
				t++;
			}

			/*serial number*/
			count = 0;
			t++;
			while(*t != 0x20)
			{
				datastruct->SerialNum[count] = *t;
				count++;
				t++;
			}

			/*device status1*/
			count = 0;
			t++;
			while(*t != 0x20)
			{
				datastruct->DeviceStatus1 = *t;
				count++;
				t++;
			}

			/*device status2*/
			count = 0;
			t++;
			while(*t != 0x20)
			{
				datastruct->DeviceStatus2 = *t;
				count++;
				t++;
			}

			/*telegram counter*/
			count = 0;
			t++;
			while(*t != 0x20)
			{
				datastruct->TelegramCnt[count] = *t;
				count++;
				t++;
			}

			/*scan counter*/
			count = 0;
			t++;
			while(*t != 0x20)
			{
				datastruct->ScanCnt[count] = *t;
				count++;
				t++;
			}

			/*time elapsed*/
			count = 0;
			t++;
			while(*t != 0x20)
			{
				datastruct->TimeElapsed[count] = *t;
				count++;
				t++;
			}

			/*time trans*/
			count = 0;
			t++;
			while(*t != 0x20)
			{
				datastruct->TimeTrans[count] = *t;
				count++;
				t++;
			}

			/*input status*/
			count = 0;
			t++;
			while(*t != 0x20)
			{
				datastruct->InputStatus[count] = *t;
				count++;
				t++;
			}
			t++;
			while(*t != 0x20)
			{
				datastruct->InputStatus[count] = *t;
				count++;
				t++;
			}

			/*output status*/
			count = 0;
			t++;
			while(*t != 0x20)
			{
				datastruct->OutputStatus[count] = *t;
				count++;
				t++;
			}
			t++;
			while(*t != 0x20)
			{
				datastruct->OutputStatus[count] = *t;
				count++;
				t++;
			}

			/*reserved*/
			count = 0;
			t++;
			while(*t != 0x20)
			{
				datastruct->Reserved[count] = *t;
				count++;
				t++;
			}

			/*scan frequency*/
			count = 0;
			t++;
			while(*t != 0x20)
			{
				datastruct->ScanFreq[count] = *t;
				count++;
				t++;
			}

			/*meas frequency*/
			count = 0;
			t++;
			while(*t != 0x20)
			{
				datastruct->MeasFreq[count] = *t;
				count++;
				t++;
			}

			/*scan frequency*/
			count = 0;
			t++;
			while(*t != 0x20)
			{
				datastruct->EncoderData[count] = *t;
				count++;
				t++;
			}

			/*num of channels*/
			count = 0;
			t++;
			while(*t != 0x20)
			{
				datastruct->ChannelsNum[count] = *t;
				count++;
				t++;
			}

			/*content*/
			count = 0;
			t++;
			while(*t != 0x20)
			{
				datastruct->Content[count] = *t;
				count++;
				t++;
			}

			/*scale factor*/
			count = 0;
			t++;
			while(*t != 0x20)
			{
				datastruct->ScaleFactor[count] = *t;
				count++;
				t++;
			}

			/*scale factor offset*/
			count = 0;
			t++;
			while(*t != 0x20)
			{
				datastruct->ScaleFactorOffset[count] = *t;
				count++;
				t++;
			}

			/*start angle*/
			count = 0;
			t++;
			while(*t != 0x20)
			{
				datastruct->StartAngle[count] = *t;
				count++;
				t++;
			}

			/*steps*/
			count = 0;
			t++;
			while(*t != 0x20)
			{
				datastruct->Steps[count] = *t;
				count++;
				t++;
			}

			/*amount of data*/
			count = 0;
			t++;
			while(*t != 0x20)
			{
				datastruct->AmountOfData[count] = *t;
				count++;
				t++;
			}


			datastruct->MeasuredDistances = &p_distances[0];

			count = 0;
			t++;
			char buffer[5];
			char *ptr_buf;
			unsigned char count3;

			while(count < 541)
			{
					while(*t != 0x20)
					{
						buffer[count2] = *t;
						count2++;
						t++;
					}
					buffer[count2+1] = '\0';
					ptr_buf = &buffer[0];

					p_distances[count] = strtol((char*)ptr_buf,'\0',16);
					count++;
					t++;
					count2 = 0;
					for(count3 = 0 ; count3 < 5 ; count3++)
					{
						buffer[count3] = 0;
					}
			}

			*t = etx;
		}

	}

}

uint8_t scannerSetup(void)
{
	/*vynuluje answer*/
	answerInit();
	/*login do scanneru*/
	c = (taskInit(login));
	p = sendTask_getAns(c);
	k = ansCheck(p);
	if ( k == 1)
	{
		GPIO_ToggleBits(GPIOD, GPIO_Pin_12);
		Delay(0x0000FFFF);
		GPIO_ToggleBits(GPIOD, GPIO_Pin_12);
	}
	else
	{
		GPIO_ToggleBits(GPIOD, GPIO_Pin_14);
		Delay(0x0000FFFF);
		GPIO_ToggleBits(GPIOD, GPIO_Pin_14);
		return 0;
	}

	/*nastaveni scanneru*/
	answerInit();
	k = 0;
	c = (taskInit(set_freq_and_res));
	p = sendTask_getAns(c);
	k = ansCheck(p);
	if ( k == 1)
	{
		GPIO_ToggleBits(GPIOD, GPIO_Pin_15);
	}
	else
	{
		GPIO_ToggleBits(GPIOD, GPIO_Pin_14);
		Delay(0x0000FFFF);
		GPIO_ToggleBits(GPIOD, GPIO_Pin_14);
		return 0;
	}

	answerInit();
	k = 0;
	c = (taskInit(set_angle));
	p = sendTask_getAns(c);
	k = ansCheck(p);
	if ( k == 1)
	{
		GPIO_ToggleBits(GPIOD, GPIO_Pin_12);
	}
	else
	{
		GPIO_ToggleBits(GPIOD, GPIO_Pin_14);
		Delay(0x0000FFFF);
		GPIO_ToggleBits(GPIOD, GPIO_Pin_14);
		return 0;
	}


	/*nastaveni vystupnich dat scannerru*/
	answerInit();
	k = 0;
	c = (taskInit(output_conf));
	p = sendTask_getAns(c);
	k = ansCheck(p);
	if ( k == 1)
	{
		GPIO_ToggleBits(GPIOD, GPIO_Pin_13);
	}
	else
	{
		GPIO_ToggleBits(GPIOD, GPIO_Pin_14);
		Delay(0x0000FFFF);
		GPIO_ToggleBits(GPIOD, GPIO_Pin_14);
		return 0;
	}


	/*logout*/
	answerInit();
	k = 0;
	c = (taskInit(logout));
	p = sendTask_getAns(c);
	k = ansCheck(p);
	if ( k == 1)
	{
		GPIO_ToggleBits(GPIOD, GPIO_Pin_15);
		GPIO_ToggleBits(GPIOD, GPIO_Pin_13);
		GPIO_ToggleBits(GPIOD, GPIO_Pin_12);
	}
	else
	{
		GPIO_ToggleBits(GPIOD, GPIO_Pin_14);
		Delay(0x0000FFFF);
		GPIO_ToggleBits(GPIOD, GPIO_Pin_14);
		return 0;
	}

	return 1;
}







