#ifndef ULCD32PT
#define ULCD32PT

#define ON 1
#define OFF 0

VOID lcd4d_init (VOID);
VOID lcd_fat (INT modo);
VOID lcd_image_format (INT1 modo);
VOID lcd_touch (INT modo);
VOID lcd_orientation (INT modo);
VOID lcd_mode (INT1 modo);
VOID lcd_contrast (INT valor);
VOID lcd_display (INT1 mode);
VOID lcd_backlight (INT1 modo);
VOID lcd_clear (VOID);
VOID lcd_volume (INT valor);
VOID lcd_sleep (INT modo, INT tiempo);
VOID lcd_background (INT16 color);

VOID lcd_write_pin (INT pin, INT valor);
INT lcd_read_pin (INT pin);
INT read_bus (VOID);
VOID write_bus (INT valor);

INT1 get_touch (VOID);

VOID lcd_fill (INT1 modo);
VOID lcd_circle (INT16 x, INT16 y, INT16 radio, INT16 color, INT1 fill);
VOID lcd_triangle (INT16 x1, INT16 y1, INT16 x2, INT16 y2, INT16 x3, INT16 y3, INT16 color, INT1 fill);
VOID lcd_line (INT16 x1, INT16 y1, INT16 x2, INT16 y2, INT16 color);
VOID lcd_polygon(INT vertices, INT16 *xptr, INT16 *yptr, INT16 color); 
VOID lcd_rectangle (INT16 x1, INT16 y1, INT16 x2, INT16 y2, INT16 color, INT1 fill);
VOID lcd_elipse (INT16 x, INT16 y, INT16 rx, INT16 ry, INT16 color, INT1 fill);
VOID lcd_pixel (INT16 x, INT16 y, INT16 color);
INT16 lcd_read_pixel (INT16 x, INT16 y);
VOID lcd_copy_paste (INT16 xs, INT16 ys, INT16 xd, INT16 yd, INT16 ancho, INT16 alto);
VOID lcd_replace_color (INT x1, INT y1, INT x2, INT y2, INT16 old_color, INT16 new_color);

//Rellena o no todo lo dibujado
//modo = 0 = todo se rellena
//modo = 1 = se dibuja normalmente con el contorno
VOID lcd_fill (INT1 modo){
   putc('c');
   putc(modo);
}

//Dibuja un circulo en con su centro coordenadas "x" e "y"
//color define el color en RGB
//radio es el radio en píxeles
//fill puede ser 1 o 0 y define si se llena o no el circulo (0 se llena)
VOID lcd_circle (INT16 x, INT16 y, INT16 radio, INT16 color, INT1 fill){
   lcd_fill(fill);      //relleno o no la figura a dibujar
   putc('C');     //comando
   putc(make8(x,1));  //msb del eje x
   putc(make8(x,0));  //lsb del eje x
   putc(make8(y,1));  //msb del eje y
   putc(make8(y,0));  //lsb del eje y
   putc(make8(radio,1));  //msb del radio
   putc(make8(radio,0));  //lsb del radio
   putc(make8(color,1));  //msb del color
   putc(make8(color,0));  //lsb del color 
}

//Dibuja un tríangulo, cada par de coordenadas "x" e "y" definen un vértice del triángulo en sentido antihorario
//el color define el color del triangulo en RGB
//fill rellena o no el triángulo (0 rellena)
VOID lcd_triangle (INT16 x1, INT16 y1, INT16 x2, INT16 y2, INT16 x3, INT16 y3, INT16 color, INT1 fill){
   lcd_fill(fill);
   putc('G');     //comando
   putc(make8(x1,1));  //msb del eje x1
   putc(make8(x1,0));  //lsb del eje x1
   putc(make8(y1,1));  //msb del eje y1
   putc(make8(y1,0));  //lsb del eje y1
   putc(make8(x2,1));  //msb del eje x2
   putc(make8(x2,0));  //lsb del eje x2
   putc(make8(y2,1));  //msb del eje y2
   putc(make8(y2,0));  //lsb del eje y2
   putc(make8(x3,1));  //msb del eje x3
   putc(make8(x3,0));  //lsb del eje x3
   putc(make8(y3,1));  //msb del eje y3
   putc(make8(y3,0));  //lsb del eje y3
   putc(make8(color,1));  //msb del color
   putc(make8(color,0));  //lsb del color 
}

//Dibuja una linea que comienza en x1,y1 y termina en x2,y2 del color definido
VOID lcd_line (INT16 x1, INT16 y1, INT16 x2, INT16 y2, INT16 color){
   putc('L');     //comando
   putc(make8(x1,1));  //msb del eje x1
   putc(make8(x1,0));  //lsb del eje x1
   putc(make8(y1,1));  //msb del eje y1
   putc(make8(y1,0));  //lsb del eje y1
   putc(make8(x2,1));  //msb del eje x2
   putc(make8(x2,0));  //lsb del eje x2
   putc(make8(y2,1));  //msb del eje y2
   putc(make8(y2,0));  //lsb del eje y2
   putc(make8(color,1));  //msb del color
   putc(make8(color,0));  //lsb del color
}  

//Dibuja un polígono desde 3 a 7 vértices
//vertices es el número de vertices
//si no se implementa algun vertice se coloca 0 en su "x" e "y" correspondiente
//los vértices se colocan en una matriz para cada eje
VOID lcd_polygon(INT vertices, INT16 *xptr, INT16 *yptr, INT16 color){
int n;
   putc('g');     //comando
   FOR(n=0;n<=7;++n,++xptr,++yptr){    //voy pasando a través de los 7 ejes de cada matriz (numero máximo)
      IF(*xptr != 0 && *yptr != 0){    //envío el juego de ejes x,y si no son 0 (0 es no implementado)
         putc(make8(*xptr,1));  //msb del eje x correspondiente
         putc(make8(*xptr,0));  //lsb del eje x correspondiente
         putc(make8(*yptr,1));  //msb del eje y correspondiente
         putc(make8(*yptr,0));  //lsb del eje y correspondiente
      }
   }
   putc(make8(color,1));  //msb del color
   putc(make8(color,0));  //lsb del color 
}

//Dibuja un rectágulo con las esquina superior izquierda en x1,y2 y la inferior derecha en x2,y2
VOID lcd_rectangle (INT16 x1, INT16 y1, INT16 x2, INT16 y2, INT16 color, INT1 fill){
   lcd_fill(fill);
   putc('r');     //comando
   putc(make8(x1,1));  //msb del eje x1
   putc(make8(x1,0));  //lsb del eje x1
   putc(make8(y1,1));  //msb del eje y1
   putc(make8(y1,0));  //lsb del eje y1
   putc(make8(x2,1));  //msb del eje x2
   putc(make8(x2,0));  //lsb del eje x2
   putc(make8(y2,1));  //msb del eje y2
   putc(make8(y2,0));  //lsb del eje y2
   putc(make8(color,1));  //msb del color
   putc(make8(color,0));  //lsb del color 
}

//Dibuja un elipse con su centro en x,y
//rx y ry son el radio de los ejes "x" e "y" del elipse
VOID lcd_elipse (INT16 x, INT16 y, INT16 rx, INT16 ry, INT16 color, INT1 fill){
   lcd_fill(fill);
   putc('e');
   putc(make8(x,1));  //msb del eje x
   putc(make8(x,0));  //lsb del eje x
   putc(make8(y,1));  //msb del eje y
   putc(make8(y,0));  //lsb del eje y
   putc(make8(rx,1));  //msb del radio x
   putc(make8(rx,0));  //lsb del radio x
   putc(make8(ry,1));  //msb del radio y
   putc(make8(ry,0));  //lsb del radio y
   putc(make8(color,1));  //msb del color
   putc(make8(color,0));  //lsb del color 
}
   
//Dibuja un píxel en x,y del color definido
VOID lcd_pixel (INT16 x, INT16 y, INT16 color){
   putc('P');     //comando
   putc(make8(x,1));  //msb del eje x
   putc(make8(x,0));  //lsb del eje x
   putc(make8(y,1));  //msb del eje y
   putc(make8(y,0));  //lsb del eje y
   putc(make8(color,1));  //msb del color
   putc(make8(color,0));  //lsb del color 
}

//Lee el color del píxel en la posición x,y
INT16 lcd_read_pixel (INT16 x, INT16 y){
int msb,lsb;   //bytes del color

   putc('R');     //comando
   putc(make8(x,1));  //msb del eje x
   putc(make8(x,0));  //lsb del eje x
   putc(make8(y,1));  //msb del eje y
   putc(make8(y,0));  //lsb del eje y
   msb = getc();      //recibo los 2 bytes del color
   lsb = getc();
   return make16(msb,lsb); //retorno el color  
}
   
//Copia una parte de la pantalla que comienza en xs,ys con su ancho y alto determinado y la copia en xd,yd
VOID lcd_copy_paste (INT16 xs, INT16 ys, INT16 xd, INT16 yd, INT16 ancho, INT16 alto){
   putc('c');
   putc(make8(xs,1));  //msb del eje xs
   putc(make8(xs,0));  //lsb del eje xs
   putc(make8(ys,1));  //msb del eje ys
   putc(make8(ys,0));  //lsb del eje ys
   putc(make8(xd,1));  //msb del eje xd
   putc(make8(xd,0));  //lsb del eje xd
   putc(make8(yd,1));  //msb del eje yd
   putc(make8(yd,0));  //lsb del eje yd
   putc(make8(ancho,1));  //msb del ancho
   putc(make8(ancho,0));  //lsb del ancho
   putc(make8(alto,1));   //msb del alto
   putc(make8(alto,0));   //lsb del alto
}

VOID lcd_replace_color (INT16 x1, INT16 y1, INT16 x2, INT16 y2, INT16 old_color, INT16 new_color){
   putc('k');     //comando
   putc(x1);      //ejes
   putc(y1);
   putc(x2);
   putc(y2);
   putc(make8(old_color,1));   //msb de old_color
   putc(make8(old_color,0));   //lsb de old_color
   putc(make8(new_color,1));   //msb de new_color
   putc(make8(new_color,0));   //lsb de new_color
}
   
//Inicia el LCD uLCD-32PT de 4D Systems vía el RS232
VOID lcd4d_init (VOID){
set_uart_speed(9600);      //velocidad inicial del LCD a 9600 baudios
putc('U');                 //auto baud al LCD
delay_ms(1);

lcd_touch(0);              //enciendo touchscreen
WHILE(getc() != 0x06);
lcd_orientation(1);        //orientacion LANDSCAPE
WHILE(getc() != 0x06);
lcd_mode(1);               //no bajo consumo
WHILE(getc() != 0x06);
lcd_contrast(7);           //contraste 7
WHILE(getc() != 0x06);
lcd_display(1);            //display encendido
WHILE(getc() != 0x06);
lcd_backlight(1);          //backlight encendido
WHILE(getc() != 0x06);

}

//escribe en el bus del LCD siendo de P8 a P15
VOID write_bus (INT valor){
   putc('W');
   putc(valor);
}

//devuelve el valor del bus de 8 bits del LCD siendo de P8 a P15
INT read_bus (VOID){
   putc('a');     //comando
   return getc();    //retorno los 8 bits del bus
}

//Pone a 1 o 0 un pin determinado del LCD
//pin va de 1 a 15 siendo de P0 a P15
//valor puede ser 1 o 0
VOID lcd_write_pin (INT pin, INT valor){
   putc('y');     //comando
   putc(pin);
   putc(valor);
}

//Lee el estado del pin P0 a P15 y devuelve 1 o 0 según el estado
//pin va de 0 a 15
INT lcd_read_pin (INT pin){
   putc('i');     //comando
   putc(pin);     //pin a leer
   return getc();    //retorno el valor del pin que manda el LCD
}

//Pone al LCD en diferentes modos de sleep y por un tiempo determinado
//modo = 128 = apaga uSD y debe reiniciarse manualmente
//modo = 64 = apaga audio y se reiniciara automaticamente cuando se use
//modo = 32 = apaga touchscreen
//modo = 8 = despertarse por cambio de estado en P1
//modo = 4 = despertarse por cambio de estado en P0
//modo = 2 = despertarse por actividad en touchscreen
//modo = 1 = despertarse por actividad en el UART
//time = 0 = se pone en sleep por siempre (despierta en reset y cambio de estado en P0 o P1)
//time 1-255 = tiempo en segundos de sleep
VOID lcd_sleep (INT modo, INT tiempo){
   putc('Z');     //comando
   putc(modo);
   putc(tiempo);
}

//Define el color de fondo del LCD
//color define el color de fondo RGB
VOID lcd_background (INT16 color){
   putc('B');     //comando
   putc(make8(color,1));  //msb de color
   putc(make8(color,0));  //lsb de color
}

//Valor del volumen del LCD
//valor va de 8 a 127
//valor = 0 = mute
//valor = 1 = volumen baja 8 niveles
//valor = 3 = volumen baja 1 nivel
//valor = 253 = volumen sube 1 nivel
//valor = 254 = volumen sube 8 niveles
//valor = 255 = mute OFF
VOID lcd_volume (INT valor){
   putc('v');     //comando
   putc(valor);    //protejido o no
}

//Coloca o no al display en bajo consumo
//modo = 0 = proteje FAT
//modo = 2 = no proteje FAT
VOID lcd_fat (INT modo){
   putc('Y');     //comando
   putc(8);       //FAT
   putc(modo);    //protejido o no
}

//Formato de las imágenes del LCD
//modo = 1 = formato viejo con header
//modo = 0 = formato nuevo sin header
VOID lcd_image_format (INT1 modo){
   putc('Y');     //comando
   putc(6);       //formato de imagen
   putc(modo);    //formato
}

//Configura el touchscreen
//modo = 0 = activado
//modo = 1 = apagado
//modo = 2 = reinicia la región activa a todo el LCD
VOID lcd_touch (INT modo){
   putc('Y');     //comando
   putc(5);       //touchscreen
   putc(modo);    //modo
}

//Orientación del LCD
//modo = 1 = LANDSCAPE
//modo = 2 = LANDSCAPE ROTADO
//modo = 3 = PORTRAIT
//modo = 4 = PORTRAIT ROTADO
VOID lcd_orientation (INT modo){
   putc('Y');     //comando
   putc(4);       //orientación
   putc(modo);    //valor
}

//Coloca o no al display en bajo consumo
//modo = 1 = encendido
//modo = 0 = apagado
VOID lcd_mode (INT1 modo){
   putc('Y');     //comando
   putc(3);       //bajo consumo
   putc(modo);    //ON/OFF
}

//Contraste del LCD
//Valor va de 0 a 15
VOID lcd_contrast (INT valor){
  IF(valor>15) valor = 1;  //si me paso del valor máximo lo reinicia
   putc('Y');     //comando
   putc(2);       //contraste
   putc(valor);   //ON/OFF
}

//Enciende o apaga el display
//modo = 1 = encendido
//modo = 0 = apagado
VOID lcd_display (INT1 modo){
   putc('Y');     //comando
   putc(1);       //display
   putc(modo);    //ON/OFF
}

//Enciende o apaga el backlight
//modo = 1 = encendido
//modo = 0 = apagado
VOID lcd_backlight (INT1 modo){
   putc('Y');     //comando
   putc(0);       //backlight
   putc(modo);    //ON/OFF
}

//Borra la pantalla del LCD y la deja con el color de fondo
VOID lcd_clear (VOID){
putc('E');
}

//Obtiene las coordenadas de la pantalla táctil y las guarda en dos variables GLOBALES llamadas "x" e "y"
//Retorna un 1 si el panel fue tocado y devuelve las coordenadas
//Retorna un 0 si el panel no fue tocado y no devuelve las coordenadas
INT1 get_touch (VOID){

int status;                         //estado del touch
int cor1,cor2,cor3,cor4;            //bytes de las coordenadas

//desabilito interrupciones del UART porque uso getc()
disable_interrupts(INT_RDA);
//primero pido el estado de la pantalla táctil
putc('o');        //comando touch
putc(0x04);       //pido estado
status = getc();

//si el touchscreen no fue tocado
IF(status == 0){
   enable_interrupts(INT_RDA);   //habilito de nueva las interrupciones
   return 0;                     //retorno un 0
   }
ELSE{                         //sino pido las nuevas coordenadas
   putc('o');     //comando touch
   putc(0x05);    //pido coordenadas touch
   cor1 = getc(); //msb eje x
   cor2 = getc(); //lsb eje x
   cor3 = getc(); //msb eje y
   cor4 = getc(); //lsb eje y
   x = make16(cor1,cor2);  //uno las coordenadas en int16
   y = make16(cor3,cor4);
   enable_interrupts(INT_RDA);   //habilito de nuevo las interrupciones
   return 1;               //retorno 1 indicando que tome nuevas coordenadas
   }
}

#endif

