#include "NBiot.h"
#include "systick.h"
#include "uart.h"
#include "systick.h"
#include "LIS331DLH.h"
#include "sht31.h"
#include "CRC.h"
#include <stdio.h>
#include <string.h>


#define BUFFERSIZE 500

	int8_t parse(uint32_t timeout);
			
	__IO uint16_t nack;
  __IO char RXbuffer[BUFFERSIZE];
	 char* check =(char*)RXbuffer; 
	__IO char *tail=(char*)RXbuffer;
	uint32_t timeout;
			

	uint8_t BR[]= "AT+IPR=115200\r\n";			//Set UART baudrate comunication to 115200
	uint8_t PIN[]	="AT+CPIN?\r\n";					//Ask if pin is needed
	uint8_t CIMI[]	="AT+CIMI\r\n";						//Request International Mobile Subscriber Identity
	uint8_t SIMID[]	="AT+QCCID\r\n";					//Reads ICCID of the USIM card
	uint8_t connection[]	="AT+QCGDEFCONT=\"IP\",\"nb.m2mc\"\r\n";			//PSD connectio setiings
	uint8_t EVENT[]	="AT+QNBIOTEVENT?\r\n";		//Enable/Disable NB-IoT Related Event Report
	uint8_t CEREG[]	="AT+CEREG=5\r\n";				//EPS Network Registration Status
	uint8_t CGATT[]	="AT+CGATT?\r\n";					//PS attachment state
	uint8_t BAND[]	="AT+QBAND=1,20\r\n";					//EPS network registration.
	uint8_t IPaddr[]	="AT+CGPADDR?\r\n";				//query the IP address which is allocated by the network
	
	uint8_t	connect[]=	"AT+QIOPEN=1,0,\"UDP\",192.168.0.20,4242,0,0,0\r\n";		//open comunication
	uint8_t	connectstat[]="AT+QISTATE?\r\n";											//chceck comunication status
	uint8_t	PSM[]="at+cpsms=0\r\n";																//power saving mode
	uint8_t	qualtest[] = "AT+CESQ\r\n";														//signal quality
	uint8_t	dataformat[]="AT+QICFG=\"dataformat\",1,1\r\n";				//send format of data send as hexa
	uint8_t	send_hex[50];																					//send data
	uint8_t close[]="AT+QICLOSE=0\r\n";														//close session
	uint8_t NTP[]="AT+QNTP=1,\"ntp5.pvt.net\"\r\n";	

	int8_t NBiot_init(void)
	{
		
		
		RCC->AHB2ENR   |=   RCC_AHB2ENR_GPIOAEN;			//LD39050PUR EN																								
		GPIOA->MODER   &= ~0x03U<<2;
		GPIOA->MODER   |=  0x01U<<2;
		GPIOA->OTYPER  &= ~0x01U<<1;
		GPIOA->OSPEEDR &= ~0x03U<<2;
		GPIOA->PUPDR   &= ~0x03U<<2;
		GPIOA->BSRR		  =  0x01U<<1;
		
		
		RCC->AHB2ENR   |=   RCC_AHB2ENR_GPIOBEN;		//GPIOB13 = reset, GPIOB14	= PWRKEY																									
		GPIOB->MODER   &= ~(0x03U<<26|0x03U<<28);
		GPIOB->MODER   |=  (0x01U<<26|0x01U<<28);
		GPIOB->OTYPER  |=  (0x01U<<13|0x01U<<14);
		GPIOB->OSPEEDR &= ~(0x03U<<26|0x03U<<28);
		GPIOB->PUPDR   &= ~(0x03U<<26|0x03U<<28);
		GPIOB->BSRR		  = 	0x01U<<13|0x01U<<14;


		delay_ms(100);
		GPIOB->BSRR		  = 	0x01U<<30;
		delay_ms(600);
		GPIOB->BSRR		  = 	0x01U<<14;		//unlocking module
		delay_ms(1000);
		
		//DBGUART_transmit(BR,15);
		NBUART_transmit(BR,15);
		if(parse(1500)!=0)
			return -1;
		
		
		//DBGUART_transmit(PIN,sizeof(PIN));
		NBUART_transmit(PIN,sizeof(PIN));
		if(parse(1500)!=0)
			return -1;
		
		//DBGUART_transmit(CIMI,sizeof(CIMI));
		NBUART_transmit(CIMI,sizeof(CIMI));
		if(parse(1500)!=0)
			return -1;
		
		//DBGUART_transmit(SIMID,sizeof(SIMID));
		NBUART_transmit(SIMID,sizeof(SIMID));
		if(parse(1500)!=0)
			return -1;

				
		//DBGUART_transmit(BAND,sizeof(BAND));
		NBUART_transmit(BAND,sizeof(BAND));
		if(parse(1500)!=0)
			return -1;	
		
		//DBGUART_transmit(connection,sizeof(connection));
		NBUART_transmit(connection,sizeof(connection));
		if(parse(1500)!=0)
			return -1;
		
		//DBGUART_transmit(EVENT,sizeof(EVENT));
		NBUART_transmit(EVENT,sizeof(EVENT));
		if(parse(1500)!=0)
			return -1;
		
		//DBGUART_transmit(CEREG,sizeof(CEREG));
		NBUART_transmit(CEREG,sizeof(CEREG));
		if(parse(1500)!=0)
			return -1;
		
		//DBGUART_transmit(CGATT,sizeof(CGATT));
		NBUART_transmit(CGATT,sizeof(CGATT));
		if(parse(1500)!=0)
			return -1;

	
		//DBGUART_transmit(IPaddr,sizeof(IPaddr));
		NBUART_transmit(IPaddr,sizeof(IPaddr));
		if(parse(1500)!=0)
			return -1;
		
				
		//DBGUART_transmit(dataformat,sizeof(dataformat));
		NBUART_transmit(dataformat,sizeof(dataformat));
		if(parse(1000)!=0)
			return -1;
		//DBGUART_transmit(PSM,sizeof(PSM));
		NBUART_transmit(PSM,sizeof(PSM));
		if(parse(1000)!=0)
			return -1;
		delay_ms(200);
		//DBGUART_transmit(connect,sizeof(connect));
		NBUART_transmit(connect,sizeof(connect));
		if(parse(1000)!=0)
			return -1;
	return 0;
	}

	
	int8_t send_data(void)
	{
		uint16_t crc = 0xFFFF;
		__align(2) data_t data; 
		
		LIS3DH_ReadXYZ(&data.LISX,&data.LISY,&data.LISZ);	// accelerometer data measure
		SHT31_ReadTRH(&data.T,&data.RH);									//humudity and temperature measure

		crc = CRC16_calc(&data);	//crc of measured data to be send
		delay_ms(1);

	//	DBGUART_transmit(qualtest,sizeof(qualtest));
		NBUART_transmit(qualtest,sizeof(qualtest));
		if(parse(1000)!=0)
			return -1;
	//	DBGUART_transmit(connectstat,sizeof(connectstat));
		NBUART_transmit(connectstat,sizeof(connectstat));
		if(parse(1000)!=0)
			return -1;
		//packet to be sent
		sprintf((char*)send_hex,"AT+QISENDEX=0,12,%0.4x%0.4x%0.4x%0.4x%0.4x%0.4x\r\n",(uint16_t)data.LISX,(uint16_t)data.LISY,(uint16_t)data.LISZ,data.T,data.RH,crc);
		delay_ms(200);
	//	DBGUART_transmit(send_hex,sizeof(send_hex));
		NBUART_transmit(send_hex,sizeof(send_hex));
		if(parse(1000)!=0)
			return -1;


		return 0;
	}
	
	int8_t parse(uint32_t timeout)
	{
		uint32_t start = get_tick();
		int8_t status=0x0F;
		while(status == 0x0F)
		{
			if(*check == '\r')
			{
			if(*(check-2)=='O'&&*(check-1)=='K')	// response OK
				status = 0;
			if(*(check-5)=='E'&&*(check-4)=='R'&&*(check-3)=='R'&&*(check-2)=='O'&&*(check-1)=='R')	//error in response
				status = -1;
			}
			if((get_tick()-start) > timeout)	// module response timeout
				status = -2;
			if(check != tail)
				check++;
				delay_ms(1);
		}	
		check = (char*)& RXbuffer[0];	// buffer reload 
		tail = (char*)& RXbuffer[0];
		delay_ms(500);
				return status;
	}
	
	
		//UART recieving interupt hendler
	void USART1_IRQHandler(void)
	{
		*tail++=USART1->RDR;
		//USART2->TDR=*tail++;													//sending response through debug UART
		if(tail ==(char*)& RXbuffer[BUFFERSIZE-1])			//if buffer overflow, set pointer to beginig 
			tail= (char*)& RXbuffer[0];
		USART1->RQR |= USART_RQR_RXFRQ;									//flag clearing
		USART1->ICR    =   USART_ICR_IDLECF|USART_ICR_ORECF|USART_ICR_PECF|USART_ICR_LBDCF|USART_ICR_NCF|USART_ICR_FECF|USART_ICR_CMCF;
	}

