/****************************************************************************/
/*               				INCLUDES E DEFINES                          */
/*					            ==================               			*/
/****************************************************************************/
 
#include "types.h"
#include "LPC214x.h"
#include "config.h"
#include "armVIC.h"
#include "uart.h"
//#include <stdio.h>

#define TX_BUFSIZE 80
#define IOPINS021 21
#define IOPINS028 28

typedef void (*IAP)(unsigned int [],unsigned int []);






/****************************************************************************/
/*               				 VARIAVEIS GLOBAIS	                        */
/*					             =================               			*/
/****************************************************************************/
IAP iap_bypointer;
static unsigned char txbuf[TX_BUFSIZE];
static unsigned char txptr = 0;
static unsigned char typtr = 0;


unsigned command[5];
unsigned result[5];
char Ram_Arry[] = "Hello World";
char *Ram_Pointer;
/****************************************************************************/
/*                DEFINICAO DOS PROTOTIPOS DAS FUNCOES                      */
/*                ====================================                      */
/****************************************************************************/
static void lowInit(void);
static void sysInit(void);
//void UART0_Init(void);
//void UART1_Init(void);
void RTC_Init(void);

static void SendString(char *serial);
static void UART0_Tx_Int(void);

static void _delay(uint32_t N);

static void PiscaLedVerde(void);
static void PiscaLedVermelho(void);

void insere_acesso(char acesso[], char serialNumber[]);
char intToChar(int n);
void converteNumero(int number, char acs[],int min, int max);




/****************************************************************************/
/*                				 FUNCOES         		                    */
/*                 				========         				            */
/****************************************************************************/
static void lowInit(void){

    //This  starts up the PLL then sets up the GPIO pins before
    //waiting for the PLL to lock.  It finally engages the PLL and returns
	// set PLL multiplier & divisor.
	// values computed from config
	PLLCFG = PLLCFG_MSEL | PLLCFG_PSEL;
	
	// enable PLL
	PLLCON = PLLCON_PLLE;
	PLLFEED = 0xAA;                       // Make it happen.  These two updates
	PLLFEED = 0x55;                       // MUST occur in sequence.
	
	// setup the parallel port pin
	
		
	
	
	// wait for PLL lock
	while (!(PLLSTAT & PLLSTAT_LOCK))
		continue;
	
	// enable & connect PLL
	PLLCON = PLLCON_PLLE | PLLCON_PLLC;
	PLLFEED = 0xAA;                       // Make it happen.  These two updates
	PLLFEED = 0x55;                       // MUST occur in sequence.
	
	// setup & enable the MAM
	MAMTIM = MAMTIM_CYCLES;
	MAMCR = MAMCR_FULL;
	
	// set the peripheral bus speed
	// value computed from config.h
	VPBDIV = VPBDIV_VALUE;                // set the peripheral bus clock speed
}
	
//==========================================================================================
//==========================================================================================

static void sysInit(void)
{
	lowInit();                            // setup clocks and processor port pins
	
	// set the interrupt controller defaults
	
#if defined(RAM_RUN)
	MEMMAP = MEMMAP_SRAM;                 // map interrupt vectors space into SRAM
#elif defined(ROM_RUN)
	MEMMAP = MEMMAP_FLASH;                // map interrupt vectors space into FLASH
#else
#error RUN_MODE not defined!
#endif

	VICIntEnClear = 0xFFFFFFFF;           // clear all interrupts
	VICIntSelect = 0x00000000;            // clear all FIQ selections
	VICDefVectAddr = (uint32_t)reset;     // point unvectored IRQs to reset()
	
}
//==========================================================================================
//==========================================================================================
void UART0_Init(void) {
  // Fpclk = 12.000.000 MHz
  // DLM,DLH = Fpclk / (19200*16) = 39 = 0x27
  PINSEL0 |= 0x00000005; // Select UART0 RXD/TXD
  U0FCR = 7; // Enable and clear FIFO's
  U0LCR = 0x83; // 8N1, enable Divisor latch bit
//  U0DLL = 0x27; // baud rate fixed to 19200 @ PCLK = 12 Mhz
//  U0FDR = 0x36;
  U0DLL = 0x4E; // baud rate fixed to 19200 @ PCLK = 12 Mhz
  U0DLM = 0;
  U0LCR = 3; // Disable Divisor latch bit
}
//==========================================================================================
//==========================================================================================
void UART1_Init(void) {
  // Fpclk = 12.000.000 MHz
  // DLM,DLH = Fpclk / (19200*16) = 39 = 0x27
  PINSEL0 |= 0x00050000; // Select UART1 RXD/TXD
  U1RBR = 0;
  U1FCR = 7; // Enable and clear FIFO's
//  U1FDR = 0x36;
  U1LCR = 0x83; // 8N1, enable Divisor latch bit
  U1DLL = 0x4E; // baud rate fixed to 19200 @ PCLK = 12 Mhz
  U1DLM = 0;
  U1LCR = 3; // Disable Divisor latch bit
}
//==========================================================================================
//==========================================================================================
void RTC_Init(void){

//PREINT = (int) (12000000/32768) - 1 = 365 = 16D
//PREFRAC = 12000000 - (PREINT+1)*32768 = 6912 = 1B00
 PREINT = 0x0000016D;
 PREFRAC= 0x00001B00;

 HOUR=16;
 MIN=00;
 SEC=00;
 DOM=19; // Dia do mes
 MONTH=11;
 YEAR=2007;
 CCR = 0x00000001;
}
//==========================================================================================
//==========================================================================================
static void SendString(char *serial) {
 if (txptr == 0) { // previous message send ?
  typtr = 0;
  while(*serial) {
     txbuf[txptr++] = *serial++;
     if(txptr >= TX_BUFSIZE)
     txptr = 0;
  }
 }
}
//==========================================================================================
//==========================================================================================
static void UART0_Tx_Int(void) {// Transmite os dados do buffer
  char i = 16;
  if (U0LCR && 0x20) {// transmit FIFO empty ?
    while (i && txptr) {
      U0THR = txbuf[typtr++];
      txptr --;
      i --;
    }
   }
}
//==========================================================================================
//==========================================================================================

static void _delay(uint32_t N)//Função simples para atraso
{
	for (uint32_t i=0; i<N;i++);
}
//==========================================================================================

//==========================================================================================
static void PiscaLedVerde(void)
{
	IO0CLR = (1<<IOPINS021);	// clear the ZEROs output
	IO0SET &= ~(1<<IOPINS021);	// set the ONEs output
	IO0DIR =(1<<IOPINS021);	// set the output bit direction
	IO0CLR = (1<<IOPINS021);	// clear the ZEROs output		
		_delay(900000);
	    //uart0Puts("liga\r\n\0");
		//uart0Putch('l');
		IO0SET = (1<<IOPINS021);	// set the ONEs output		
		_delay(500000);
}
//==========================================================================================
//==========================================================================================
static void PiscaLedVermelho(void)
{
IO0CLR = (1<<IOPINS028);	// clear the ZEROs output
IO0SET &= ~(1<<IOPINS028);	// set the ONEs output
IO0DIR =(1<<IOPINS028);	// set the output bit direction
IO0CLR = (1<<IOPINS028);	// clear the ZEROs output		
		_delay(500000);
	    //uart0Puts("liga\r\n\0");
		//uart0Putch('l');
		IO0SET = (1<<IOPINS028);	// set the ONEs output		
		_delay(900000);
}
//==========================================================================================
//==========================================================================================
void insere_acesso(char acesso[], char serialNumber[]){
	int i;
	
	for(i=0;i<8;i++) {acesso[i]=serialNumber[i];}
	converteNumero(HOUR,acesso,8,9);
	converteNumero(MIN,acesso,10,11);                                                
	converteNumero(DOM,acesso,12,13);
	converteNumero(MONTH,acesso,14,15);
	converteNumero(YEAR,acesso,16,19);
}
//==========================================================================================
//==========================================================================================
char intToChar(int n){
    
    switch (n)
    {
      case 0:  return '0';     
      case 1:  return '1'; 
      case 2:  return '2'; 
      case 3:  return '3';     
      case 4:  return '4'; 
      case 5:  return '5';
      case 6:  return '6';     
      case 7:  return '7'; 
      case 8:  return '8';
      case 9:  return '9';
    }  
return '0';
}
 
//==========================================================================================
//==========================================================================================   
void converteNumero(int number, char acs[],int min, int max){
    int i;
    for(i=max;i>=min;i--){
		acs[i]=intToChar(number%10);
        number=number/10;                                    
    }                                                
}


//==========================================================================================
//==========================================================================================
//==========================================================================================
int main(void) 
{
    
	char serialNumber[8];//Numero Serial do TAG de Teste
	char acesso[20];
	
	serialNumber[0]= 0x77;
	serialNumber[1]= 0xE7;
	serialNumber[2]= 0x07;
	serialNumber[3]= 0xE6;
	serialNumber[4]= 0x57;
	serialNumber[5]= 0x98;
	serialNumber[6]= 0x67;
	serialNumber[7]= 0xE7;
	
	
	//77 E7 07 E6 57 98 67 E7
	
	char serialBuffer[16]="";
	
	sysInit();
    UART0_Init();
	UART1_Init();
	RTC_Init();
	
	
	
	//char ano[4]="2007";
	
	unsigned char index;
	
	
	
	iap_bypointer = (IAP) 0x7FFFFFF1;			//set IAP entry address in function pointer

	Ram_Pointer = 0x40000100;					//Set pointer to RAM 
	for (index = 0; index<0x0B; index++)		//Copy data to be written to flash into the RAM
	{
	*Ram_Pointer = acesso[index];
	Ram_Pointer++;
	}

	
	command[0] = 54; 				   			//command code for "Read part ID"
	iap_bypointer(command,result);
	//iap_byfunction(command,result,0x7FFFFFF0);	//Call IAP functions by function method

	
	command[0] = 50;							//Prepare sector five for a write operayion
	command[1] = 5;
	command[2] = 5;
	iap_bypointer(command,result);

	command[0] = 52;						   //erase sector five
	command[1] = 5;
	command[2] = 5;
	command[3] = 12000;						   //Cclk == 12Mhz Pll is disabled in startup code
	iap_bypointer(command,result);

	command[0] = 50;							//Prepare sector five for a write operayion
	command[1] = 5;
	command[2] = 5;
	iap_bypointer(command,result);

	command[0] = 51;						   //write 512 bytes from address 0x40000100
	command[1] = 0x0000A000;				   //to 0x0000A000 in flash memory;
	command[2] = 0x40000100;
	command[3] = 256;
	command[4] = 12000;
	iap_bypointer(command,result);
	//unsigned int aux;
	unsigned int *acs=0x0000A000;
	int j;
	char acss[20];
	for(j=0;j<20;j++){
		acss[j]=acs;
		acs++;
		
	}
					  
	//iap_byfunction(command,result,0x7FFFFFF0);
	SendString("acss");
	UART0_Tx_Int();
	
	PiscaLedVerde();
	for (;;)
	{
		
	    
		if(U1LSR & 1)// quando U1RBR contem um dado valido faça 
		{	
			int i=0;
            	
			PiscaLedVerde();
			while(U1RBR && i<16){
			serialBuffer[i]=U1RBR++;
			i++;
			}
			insere_acesso(acesso,serialNumber);
			
			
			
			
			int j=0;      
			while(j<8){// Esse loop descarta os bits de CRC e paridade pegando somente o numero serial do TAG
				if(serialNumber[j]!=serialBuffer[j])// e checa com uma base de dados que nesse caso é a variavel serialNumber
				{
				  
				  SendString("ERRO!");// se o serial nao for identico ao da base de dados acuse erro
				  UART0_Tx_Int();
				}
				j++;
			}
			
			
			
		}
        //SendString("Yes,Beibe!\r\n");
        else PiscaLedVermelho();
		
		
	    //uart0Puts("desliga\r\n\0");
		//uart0Putch('d');
		//PiscaLedVermelho();
		
		
		
		
		
		
	}

	return 0;
}


