#include "p24Hxxxx.h"
#include <p24hj256gp210.h>
#include <stdlib.h> 
#include <string.h> 
#include <ctype.h> 
#define FCY 40000000UL
#include "libpic30.h"
#include "ILI9327.h"

const unsigned char FONT[51][5] ={0x00, 0x00, 0x00, 0x00, 0x00, // SPACE
                         0x00, 0x00, 0x5F, 0x00, 0x00, // !
                         0x00, 0x03, 0x00, 0x03, 0x00, // "
                         0x14, 0x3E, 0x14, 0x3E, 0x14, // #
                         0x24, 0x2A, 0x7F, 0x2A, 0x12, // $
                         0x43, 0x33, 0x08, 0x66, 0x61, // %
                         0x36, 0x49, 0x55, 0x22, 0x50, // &
                         0x00, 0x05, 0x03, 0x00, 0x00, // '
                         0x00, 0x1C, 0x22, 0x41, 0x00, // (
                         0x00, 0x41, 0x22, 0x1C, 0x00, // )
                         0x14, 0x08, 0x3E, 0x08, 0x14, // *
                         0x08, 0x08, 0x3E, 0x08, 0x08, // +
                         0x00, 0x50, 0x30, 0x00, 0x00, // ,
                         0x08, 0x08, 0x08, 0x08, 0x08, // -
                         0x00, 0x00, 0x60, 0x60, 0x00, // .
                         0x20, 0x10, 0x08, 0x04, 0x02, // /
                         0x3E, 0x51, 0x49, 0x45, 0x3E, // 0
                         0x00, 0x04, 0x02, 0x7F, 0x00, // 1
                         0x42, 0x61, 0x51, 0x49, 0x46, // 2
                         0x22, 0x41, 0x49, 0x49, 0x36, // 3
                         0x18, 0x14, 0x12, 0x7F, 0x10, // 4
                         0x27, 0x45, 0x45, 0x45, 0x39, // 5
                         0x3E, 0x49, 0x49, 0x49, 0x32, // 6
                         0x01, 0x01, 0x71, 0x09, 0x07, // 7
                         0x36, 0x49, 0x49, 0x49, 0x36, // 8
                         0x26, 0x49, 0x49, 0x49, 0x3E, // 9
                         0x00, 0x36, 0x36, 0x00, 0x00, // :
                         0x00, 0x56, 0x36, 0x00, 0x00, // ;
                         0x08, 0x14, 0x22, 0x41, 0x00, // <
                         0x14, 0x14, 0x14, 0x14, 0x14, // =
                         0x00, 0x41, 0x22, 0x14, 0x08, // >
                         0x02, 0x01, 0x51, 0x09, 0x06, // ?
                         0x3E, 0x41, 0x59, 0x55, 0x5E, // @
                         0x7E, 0x09, 0x09, 0x09, 0x7E, // A
                         0x7F, 0x49, 0x49, 0x49, 0x36, // B
                         0x3E, 0x41, 0x41, 0x41, 0x22, // C
                         0x7F, 0x41, 0x41, 0x41, 0x3E, // D
                         0x7F, 0x49, 0x49, 0x49, 0x41, // E
                         0x7F, 0x09, 0x09, 0x09, 0x01, // F
                         0x3E, 0x41, 0x41, 0x49, 0x3A, // G
                         0x7F, 0x08, 0x08, 0x08, 0x7F, // H
                         0x00, 0x41, 0x7F, 0x41, 0x00, // I
                         0x30, 0x40, 0x40, 0x40, 0x3F, // J
                         0x7F, 0x08, 0x14, 0x22, 0x41, // K
                         0x7F, 0x40, 0x40, 0x40, 0x40, // L
                         0x7F, 0x02, 0x0C, 0x02, 0x7F, // M
                         0x7F, 0x02, 0x04, 0x08, 0x7F, // N
                         0x3E, 0x41, 0x41, 0x41, 0x3E, // O
                         0x7F, 0x09, 0x09, 0x09, 0x06, // P
                         0x1E, 0x21, 0x21, 0x21, 0x5E, // Q
                         0x7F, 0x09, 0x09, 0x09, 0x76};// R

const unsigned  char FONT2[44][5]={0x26, 0x49, 0x49, 0x49, 0x32, // S
                         0x01, 0x01, 0x7F, 0x01, 0x01, // T
                         0x3F, 0x40, 0x40, 0x40, 0x3F, // U
                         0x1F, 0x20, 0x40, 0x20, 0x1F, // V
                         0x7F, 0x20, 0x10, 0x20, 0x7F, // W
                         0x41, 0x22, 0x1C, 0x22, 0x41, // X
                         0x07, 0x08, 0x70, 0x08, 0x07, // Y
                         0x61, 0x51, 0x49, 0x45, 0x43, // Z
                         0x00, 0x7F, 0x41, 0x00, 0x00, // [
                         0x02, 0x04, 0x08, 0x10, 0x20, // 
                         0x00, 0x00, 0x41, 0x7F, 0x00, // ]
                         0x04, 0x02, 0x01, 0x02, 0x04, // ^
                         0x40, 0x40, 0x40, 0x40, 0x40, // _
                         0x00, 0x01, 0x02, 0x04, 0x00, // `
                         0x20, 0x54, 0x54, 0x54, 0x78, // a
                         0x7F, 0x44, 0x44, 0x44, 0x38, // b
                         0x38, 0x44, 0x44, 0x44, 0x44, // c
                         0x38, 0x44, 0x44, 0x44, 0x7F, // d
                         0x38, 0x54, 0x54, 0x54, 0x18, // e
                         0x04, 0x04, 0x7E, 0x05, 0x05, // f
                         0x08, 0x54, 0x54, 0x54, 0x3C, // g
                         0x7F, 0x08, 0x04, 0x04, 0x78, // h
                         0x00, 0x44, 0x7D, 0x40, 0x00, // i
                         0x20, 0x40, 0x44, 0x3D, 0x00, // j
                         0x7F, 0x10, 0x28, 0x44, 0x00, // k
                         0x00, 0x41, 0x7F, 0x40, 0x00, // l
                         0x7C, 0x04, 0x78, 0x04, 0x78, // m
                         0x7C, 0x08, 0x04, 0x04, 0x78, // n
                         0x38, 0x44, 0x44, 0x44, 0x38, // o
                         0x7C, 0x14, 0x14, 0x14, 0x08, // p
                         0x08, 0x14, 0x14, 0x14, 0x7C, // q
                         0x00, 0x7C, 0x08, 0x04, 0x04, // r
                         0x48, 0x54, 0x54, 0x54, 0x20, // s
                         0x04, 0x04, 0x3F, 0x44, 0x44, // t
                         0x3C, 0x40, 0x40, 0x20, 0x7C, // u
                         0x1C, 0x20, 0x40, 0x20, 0x1C, // v
                         0x3C, 0x40, 0x30, 0x40, 0x3C, // w
                         0x44, 0x28, 0x10, 0x28, 0x44, // x
                         0x0C, 0x50, 0x50, 0x50, 0x3C, // y
                         0x44, 0x64, 0x54, 0x4C, 0x44, // z
                         0x00, 0x08, 0x36, 0x41, 0x41, // {
                         0x00, 0x00, 0x7F, 0x00, 0x00, // |
                         0x41, 0x41, 0x36, 0x08, 0x00, // }
                         0x00, 0x07, 0x05, 0x07, 0x00};// °
                         //0x02, 0x01, 0x02, 0x04, 0x02};// ~



void Lcd_Init()
{
TRISD 			= 0;
LCD_CS			= 1;
tris_LCD_RS 	= 0;
tris_LCD_REST 	= 0;
tris_LCD_WR 	= 0;
tris_LCD_CS 	= 0;


  LCD_REST		= 1;
  __delay_ms(5); 
  LCD_REST		= 0;
  __delay_ms(15);
  LCD_REST		= 1;
  __delay_ms(15);
   LCD_CS			= 0;
   Lcd_Write_Com(0x00E9);
   Lcd_Write_Data(0x0020);
   Lcd_Write_Com(0x0011); //Exit Sleep
   __delay_ms(100);
   Lcd_Write_Com(0x00D1);                       
   Lcd_Write_Data(0x0000);
   Lcd_Write_Data(0x0071);
   Lcd_Write_Data(0x0019);
   Lcd_Write_Com(0x00D0);                                
   Lcd_Write_Data(0x0007);
   Lcd_Write_Data(0x0001);
   Lcd_Write_Data(0x0008);
   Lcd_Write_Com(0x0036);                        
   Lcd_Write_Data(0x0008);
   Lcd_Write_Com(0x003A);
   Lcd_Write_Data(0x0005);                          
   Lcd_Write_Com(0x00C1);
   Lcd_Write_Data(0x0010);
   Lcd_Write_Data(0x0010);
   Lcd_Write_Data(0x0002);
   Lcd_Write_Data(0x0002);
   Lcd_Write_Com(0x00C0); //Set Default Gamma
   Lcd_Write_Data(0x0000);
   Lcd_Write_Data(0x0035);
   Lcd_Write_Data(0x0000);
   Lcd_Write_Data(0x0000);
   Lcd_Write_Data(0x0001);
   Lcd_Write_Data(0x0002);
   Lcd_Write_Com(0x00C5); //Set frame rate
   Lcd_Write_Data(0x0004);
   Lcd_Write_Com(0x00D2); //power setting      
   Lcd_Write_Data(0x0001);
   Lcd_Write_Data(0x0044);
   Lcd_Write_Com(0x00C8); //Set Gamma
   Lcd_Write_Data(0x0004);
   Lcd_Write_Data(0x0067);
   Lcd_Write_Data(0x0035);
   Lcd_Write_Data(0x0004);
   Lcd_Write_Data(0x0008);
   Lcd_Write_Data(0x0006);
   Lcd_Write_Data(0x0024);
   Lcd_Write_Data(0x0001);
   Lcd_Write_Data(0x0037);
   Lcd_Write_Data(0x0040);
   Lcd_Write_Data(0x0003);                     
   Lcd_Write_Data(0x0010);
   Lcd_Write_Data(0x0008);
   Lcd_Write_Data(0x0080);
   Lcd_Write_Data(0x0000);
   Lcd_Write_Com(0x002A); 
   Lcd_Write_Data(0x0000);
   Lcd_Write_Data(0x0000);
   Lcd_Write_Data(0x0000);
   Lcd_Write_Data(0x00eF);
   Lcd_Write_Com(0x002B);                                      
   Lcd_Write_Data(0x0000);
   Lcd_Write_Data(0x0000);
   Lcd_Write_Data(0x0001);
   Lcd_Write_Data(0x008F);                         
   Lcd_Write_Com(0x0029); //display on       
   Lcd_Write_Com(0x002C); //display on
   LCD_CS			= 1;
}///

void LCD_Writ_Bus(unsigned short dato)
{
   	LATD = dato;
	LCD_WR			= 0;
    LCD_WR			= 1;
}//
                                                                                        
void Lcd_Write_Com(unsigned short dato)
{       
	LCD_RS			= 0;
  	LCD_Writ_Bus(dato);
}//
                                                
void Lcd_Write_Data(unsigned short dato)
{
	LCD_RS			= 1;
  	LCD_Writ_Bus(dato);                              
}//

void Address_set(short x1,short y1,short x2,short y2)
{
  	Lcd_Write_Com(0x02b);
 	Lcd_Write_Data(x1>>8);
  	Lcd_Write_Data(x1);
   	Lcd_Write_Data(x2>>8);
    Lcd_Write_Data(x2);
	Lcd_Write_Com(0x2a);
	Lcd_Write_Data(y1>>8);
	Lcd_Write_Data(y1);
	Lcd_Write_Data(y2>>8);
 	Lcd_Write_Data(y2);
	Lcd_Write_Com(0x2c);
}///

void Lcd_pixel(short x, short y, unsigned short color)

{
	LCD_CS			= 0;
	Address_set(x,y,x,y);
	Lcd_Write_Data(color);
}//

void glcd_fillScreen(unsigned short color)
{   
unsigned short i;
unsigned short j;

   	LCD_CS			= 0;
	Address_set(0,0,400,400);
	for(i=0;i<400;i++)
   		{
    	for (j=0;j<240;j++)
			{
			Lcd_Write_Data(color);
			}//
    	}//
   	LCD_CS			= 1;
}//
   
void glcd_line(short x1, short y1, short x2, short y2, unsigned short color)
{
   	short  	dy;
    short  	dx;
   	short  	addx=1;
   	short  	addy=1;
   	short 	P;
   	short  	diff;
	short 	i=0;

   dx = abs(x2 - x1);
   dy = abs(y2 - y1);

   if(x1 > x2)
      addx = -1;
   if(y1 > y2)
      addy = -1;

   if(dx >= dy)
   {
      dy *= 2;
      P = dy - dx;
      diff = P - dx;

      for(; i<=dx; ++i)
      {
         Lcd_pixel(x1, y1, color);

         if(P < 0)
         {
            P  += dy;
            x1 += addx;
         }
         else
         {
            P  += diff;
            x1 += addx;
            y1 += addy;
         }
      }
   }
   else
   {
      dx *= 2;
      P = dx - dy;
      diff = P - dy;

      for(; i<=dy; ++i)
      {
         Lcd_pixel(x1, y1, color);

         if(P < 0)
         {
            P  += dx;
            y1 += addy;
         }
         else
         {
            P  += diff;
            x1 += addx;
            y1 += addy;
         }
      }
   }
}/////////////////////////////////////////////////////////////////////////

void glcd_rect(short x1, short y1, short x2, short y2, unsigned char fill, unsigned short color)
{
   if(fill)
   {
      	//short i;
		short xmin;
		short xmax;
		short ymin;
		short ymax;

      if(x1 < x2)                            //  Find x min and max
      {
         xmin = x1;
         xmax = x2;
      }
      else
      {
         xmin = x2;
         xmax = x1;
      }

      if(y1 < y2)                            // Find the y min and max
      {
         ymin = y1;
         ymax = y2;
      }
      else
      {
         ymin = y2;
         ymax = y1;
      }


unsigned short i;
unsigned short j;

   	LCD_CS			= 0;
	Address_set(xmin,ymin,xmax,ymax);
	for(i=0;i<xmax;i++)
   		{
    	for (j=0;j<ymax;j++)
			{
			Lcd_Write_Data(color);
			}//
    	}//
   	LCD_CS			= 1;


	/*

      for(; xmin <= xmax; ++xmin)
      {
         for(i=ymin; i<=ymax; ++i)
         {
            Lcd_pixel(xmin, i, color);
         }
      }*/
   }
   else
   {
      glcd_line(x1, y1, x2, y1, color);      // Draw the 4 sides
      glcd_line(x1, y2, x2, y2, color);
      glcd_line(x1, y1, x1, y2, color);
      glcd_line(x2, y1, x2, y2, color);
   }
}//

void glcd_bar(short x1, short y1,short x2,short y2, unsigned short width, unsigned short color)
{
   short	half_width;
   short 	dy;
   short 	dx;
   short  	addx=1;
   short 	addy=1;
   short 	j;
   short 	P;
   short 	diff;
   short 	c1;
   short 	c2;
   short 	i=0;

   dx = abs(x2 - x1);
   dy = abs(y2 - y1);

   half_width = width/2;
   c1 = -(dx*x1 + dy*y1);
   c2 = -(dx*x2 + dy*y2);

   if(x1 > x2)
   {
      signed temp;
      temp = c1;
      c1 = c2;
      c2 = temp;
      addx = -1;
   }
   if(y1 > y2)
   {
      signed temp;
      temp = c1;
      c1 = c2;
      c2 = temp;
      addy = -1;
   }

   if(dx >= dy)
   {
      P = 2*dy - dx;
      diff = P - dx;

      for(i=0; i<=dx; ++i)
      {
         for(j=-half_width; j<half_width+width%2; ++j)
         {
            short temp;

            temp = dx*x1+dy*(y1+j);    // Use more RAM to increase speed
            if(temp+c1 >= 0 && temp+c2 <=0)
               Lcd_pixel(x1, y1+j, color);
         }
         if(P < 0)
         {
            P  += 2*dy;
            x1 += addx;
         }
         else
         {
            P  += diff;
            x1 += addx;
            y1 += addy;
         }
      }
   }
   else
   {
      P = 2*dx - dy;
      diff = P - dy;

      for(i=0; i<=dy; ++i)
      {
         if(P < 0)
         {
            P  += 2*dx;
            y1 += addy;
         }
         else
         {
            P  += diff;
            x1 += addx;
            y1 += addy;
         }
         for(j=-half_width; j<half_width+width%2; ++j)
         {
            short temp;

            temp = dx*x1+dy*(y1+j);    // Use more RAM to increase speed
            if(temp+c1 >= 0 && temp+c2 <=0)
               Lcd_pixel(x1+j, y1, color);
         }
      }
   }
}///

void glcd_circle(short x, short y, short radius, short fill, unsigned short color)
{
short  a;
short  b;
short  P;

   a = 0;
   b = radius;
   P = 1 - radius;

   do
   {
      if(fill)
      {
         glcd_line(x-a, y+b, x+a, y+b, color);
         glcd_line(x-a, y-b, x+a, y-b, color);
         glcd_line(x-b, y+a, x+b, y+a, color);
         glcd_line(x-b, y-a, x+b, y-a, color);
      }
      else
      {
         Lcd_pixel(a+x, b+y, color);
         Lcd_pixel(b+x, a+y, color);
         Lcd_pixel(x-a, b+y, color);
         Lcd_pixel(x-b, a+y, color);
         Lcd_pixel(b+x, y-a, color);
         Lcd_pixel(a+x, y-b, color);
         Lcd_pixel(x-a, y-b, color);
         Lcd_pixel(x-b, y-a, color);
      }

      if(P < 0)
         P += 3 + 2 * a++;
      else
         P += 5 + 2 * (a++ - b--);
    } while(a <= b);
}//

void glcd_text57(short x, short y, char* textptr, unsigned short size, unsigned short color, unsigned short color_fondo)
{
	unsigned short	j;
	unsigned short	k;
	unsigned short	l;
	unsigned short	m;
   	unsigned char	pixelData[6]; 


   for(; *textptr != '\0'; ++textptr, ++x)// Loop through the passed string
   {

	//_p2 = *textptr;
      if(*textptr < 'S') // Checks if the letter is in the first font array
         memcpy(pixelData, FONT[*textptr - ' '], 5);
      else if(*textptr <= '~') // Check if the letter is in the second font array
         memcpy(pixelData, FONT2[*textptr - 'S'], 5);
      else
         memcpy(pixelData, FONT[0], 5);   // Default to space



      // Handles newline and carriage returns
      switch(*textptr)
      {
         case '\n':
            y += 7*size + 1;
            continue;
         case '\r':
            x = 0;
            continue;
      }


      if(x+5*size >= GLCD_WIDTH)          // Performs character wrapping
      {
         x = 0;                           // Set x at far left position
         y += 7*size + 1;                 // Set y at next position down
      }

	pixelData[5] = 0;

     for(j=0; j<5; ++j, x+=size)         // recorre cada columna del caracter
      {
         for(k=0; k < 7; ++k)             //recorre cada pixel de cada columna
         {
			unsigned char _des = 1;
			_des <<= k;
			_des = pixelData[j] & _des;
            if(_des) 						// verifica si el pixel debe ser o no dibujado
            {
               for(l=0; l < size; ++l)    	// estos FOR cambian el tamaņo del caracter
               {                          
                  for(m=0; m < size; ++m)
                  {
                     Lcd_pixel(x+m, y+k*size+l, color); // Draws the pixel
                  }//
               }//
			}
            else              ///CON ESTO LIMPIO LOS PIXELES NO USADOS
            {       
               for(l=0; l<size; ++l)      // The next two loops change the
               {                          // character's size
                  for(m=0; m<size; ++m)
                  {
                     Lcd_pixel(x+m, y+k*size+l, color_fondo); // Draws the pixel
                  }
               }
            }




            //
         }//
      }//
   }//
}//




