
//--------------------------------------------------------------------------
//
//               lcd.c  zhouyi 2008.5.10
//
//--------------------------------------------------------------------------
unsigned int TextColor;
unsigned int BackColor;

void PORT_INI() 
{ 
	
	PMMODEbits.MODE  = 0b10;  // Master 2
    PMMODEbits.WAITB = 0b00;
    PMMODEbits.WAITM = 0b0001;
    PMMODEbits.WAITE = 0b00;
    PMAENbits.PTEN15 = 1;     // Address line 0 is enabled
	PMAENbits.PTEN14 = 1;
    PMCONbits.CSF    = 0b10;   
	PMCONbits.CS2P   = 1;
	PMCONbits.CS1P   = 1;
    PMCONbits.PTRDEN = 1;    
    PMCONbits.PTWREN = 1;
    PMCONbits.PMPEN  = 1; 
    
	PMADDR = 0x0000;

	LCD_RST_DDR = 0;
	LCD_RST_L();
	
	return;
}
//-----------------------------------------------------------------------
//
//   write lcd index regster
//
//-----------------------------------------------------------------------
void LCD_WR_REG(unsigned char Lindex,unsigned int val)
{
	char Hindex = 0x00;

	PMADDR = 0x0000;
	PMDIN1 = Hindex;
	NOP();
	
	PMDIN1 = Lindex;
	PMADDR = 0x8000;

	PMDIN1 = (unsigned char)(val >> 8);
	NOP();
	PMDIN1 = (unsigned char)val;
	NOP();
	PMADDR |=  0x4000;
	
}

void LCD_Write_Start()
{
	 //disable interrupts
    PMADDR = 0x0000;
	PMDIN1 = 0x00;
	NOP();
   	PMDIN1 = 0x22;
	NOP();
	PMADDR = 0x8000;

}

void LCD_Write_Data(unsigned int val)
{	

	PMDIN1 = (unsigned char)(val >> 8);
	NOP();
    PMDIN1 = (unsigned char)val;
	NOP();

}
void LCD_Write_LCD_Data(unsigned char val)
{	

    PMDIN1 = (unsigned char)val;
	NOP();
}
void LCD_Write_End()
{
	PMADDR |=0x40;
}

void delay_ms(unsigned int iMs)
{
	int loop;
	while(iMs--)
	{
		for(loop=0;loop<1160;loop++)
		{
			Nop();
		}
	}
	return;
}

void Display_ON()  
{
	LCD_WR_REG(0x07,0x0173);
}

void Display_OFF() 
{	
	LCD_WR_REG(0x07,0x0000);
}

void LCD_Init()
{
	PORT_INI();

    LCD_RST_L();
    delay_ms(10);
    LCD_RST_H();

    //delay 10ms
    delay_ms(10);
  
    //initializing funciton 1
    LCD_WR_REG(0xe5,0x8000);  // Set the internal vcore voltage
    LCD_WR_REG(0x00,0x0001);  // start OSC
    LCD_WR_REG(0x2b,0x0010);  //Set the frame rate as 80 when the internal resistor is used for oscillator circuit
    LCD_WR_REG(0x01,0x0100);  //s720  to  s1 ; G1 to G320
    LCD_WR_REG(0x02,0x0700);  //set the line inversion
    LCD_WR_REG(0x03,0x1018);  //65536 colors 
    //LCD_WR_REG(0x03,0x1030);
    LCD_WR_REG(0x04,0x0000);
    LCD_WR_REG(0x08,0x0202);  //specify the line number of front and back porch periods respectively
    LCD_WR_REG(0x09,0x0000);
    LCD_WR_REG(0x0a,0x0000);
    LCD_WR_REG(0x0c,0x0000);  //select  internal system clock
    LCD_WR_REG(0x0d,0x0000);
    LCD_WR_REG(0x0f,0x0000); 
    LCD_WR_REG(0x50,0x0000);  //0x50 -->0x53 set windows adress
    LCD_WR_REG(0x51,0x00ef);
    LCD_WR_REG(0x52,0x0000);
    LCD_WR_REG(0x53,0x013f);
    LCD_WR_REG(0x60,0x2700);
    LCD_WR_REG(0x61,0x0001);
    LCD_WR_REG(0x6a,0x0000);
    LCD_WR_REG(0x80,0x0000);
    LCD_WR_REG(0x81,0x0000);
    LCD_WR_REG(0x82,0x0000);
    LCD_WR_REG(0x83,0x0000);
    LCD_WR_REG(0x84,0x0000);
    LCD_WR_REG(0x85,0x0000);
    LCD_WR_REG(0x90,0x0010);
    LCD_WR_REG(0x92,0x0000);
    LCD_WR_REG(0x93,0x0003);
    LCD_WR_REG(0x95,0x0110);
    LCD_WR_REG(0x97,0x0000);
    LCD_WR_REG(0x98,0x0000); 

    //power setting function
    LCD_WR_REG(0x10,0x0000);
    LCD_WR_REG(0x11,0x0000);
    LCD_WR_REG(0x12,0x0000);
    LCD_WR_REG(0x13,0x0000);
    delay_ms(200);
    LCD_WR_REG(0x10,0x17b0);
    LCD_WR_REG(0x11,0x0004);
    delay_ms(50);
    LCD_WR_REG(0x12,0x013e);
    delay_ms(50);
    LCD_WR_REG(0x13,0x1f00);
    LCD_WR_REG(0x29,0x000f);
    delay_ms(50);
    LCD_WR_REG(0x20,0x0000);
    LCD_WR_REG(0x21,0x0000);

    //initializing function 2

    LCD_WR_REG(0x30,0x0204);
    LCD_WR_REG(0x31,0x0001);
    LCD_WR_REG(0x32,0x0000);
    LCD_WR_REG(0x35,0x0206);
    LCD_WR_REG(0x36,0x0600);
    LCD_WR_REG(0x37,0x0500);
    LCD_WR_REG(0x38,0x0505);
    LCD_WR_REG(0x39,0x0407);
    LCD_WR_REG(0x3c,0x0500);
    LCD_WR_REG(0x3d,0x0503);

    //display on
    LCD_WR_REG(0x07,0x0173);  
     Display_ON();      
}


void LCD_Set_XY(unsigned int x, unsigned int y)
{
    LCD_WR_REG(0x20,x);
    LCD_WR_REG(0x21,y);
}

void LCD_Set_Window(unsigned int startX,unsigned int startY,unsigned int endX,unsigned int endY)
{
    LCD_Set_XY(startX,startY);
    LCD_WR_REG(0x50, startX);
    LCD_WR_REG(0x51, endX);
    LCD_WR_REG(0x52, startY);
    LCD_WR_REG(0x53, endY);    
    //LCD_Set_XY(endX, endY);
}

void LCD_test()
{
    unsigned int i,j;
    LCD_Set_Window(0,0,239,319);
    LCD_Write_Start();
    for(i=0;i<320;i++)
    {    for(j=0;j<240;j++)
        {
            if(i>279)LCD_Write_Data(0x0000);
            else if(i>239)LCD_Write_Data(0x001f);
            else if(i>199)LCD_Write_Data(0x07e0);
            else if(i>159)LCD_Write_Data(0x07ff);
            else if(i>119)LCD_Write_Data(0xf800);
            else if(i>79)LCD_Write_Data(0xf81f);
            else if(i>39)LCD_Write_Data(0xffe0);
            else LCD_Write_Data(0xffff);
        }
    }
    LCD_Write_End();
} 


void fillrect(unsigned int startX,unsigned int startY,unsigned int endX,unsigned int endY,unsigned int color)
{
    int x,y;
    int totalPixels;

    if((startX < 0)||(startY < 0)||(endX > 239)||(endY > 319))
    {
        return ;
    }


    x = (endX >= startX) ? (endX - startX):(startX - endX);  
    y = (endY >= startY) ? (endY - startY):(startY - endY);
    
    totalPixels = x*y;
    LCD_Set_Window(startX,startY, endX,endY);
    LCD_Write_Start();
    __asm__ volatile( "disi #0x3FFF" ); //disable interrupts 
    while(totalPixels--)
    {
            LCD_Write_Data(color);
    }
    __asm__ volatile( "disi #0x0000" );
    LCD_Write_End();
    draw_v_line(startY,endY,endX,color);        
}


void  putpixel(unsigned int x,unsigned int y,unsigned int color)
{
    if((x < 0)||(y < 0)||(x > 239)||(y > 319))
    {
        return ;
    }

    LCD_Set_Window(x,y,x+1,y+1);
//    LCD_Set_XY(x,y);
    LCD_Write_Start();
    LCD_Write_Data(color);
    LCD_Write_End();
    return;
}
         
void LCD_SetTextColor(unsigned int Color) 
{ 
      TextColor = Color; 
    
    return;
} 

void LCD_SetBackColor(unsigned int Color) 
{ 
      BackColor = Color; 
    
    return;
} 

void draw_h_line(int x_start, int x_end, int y,unsigned int color)
{
    unsigned    int    i;
    unsigned    int    real_start    = x_start;
    unsigned    int    real_end    = x_end;

    if(real_start >= real_end)
    {
        x_start    = real_end;
        x_end    = real_start;
    }

    for(i = x_start; i <=x_end; i ++)
    {
        putpixel(i, y, color);
    }

    return;
}

void draw_v_line(int y_start, int y_end, int x,unsigned int color)
{
    unsigned    int        i;

    unsigned    int    start    = y_start;
    unsigned    int    end        = y_end;

    if(y_start >= y_end)
    {
        start    = y_end;
        end        = y_start;
    }
    
    for(i = start; i <= end; i ++)
    {
        putpixel(x, i, color);
    }
    
    return;
}
void    Octant0(unsigned int x_bgn, unsigned int y_bgn,    unsigned int x_delta, unsigned int y_delta, int XDirection,unsigned int color)
{
    int y_deltax2;
    int y_deltax2Minusx_deltax2;
    int ErrorTerm;


    y_deltax2 = (y_delta <<1);
    y_deltax2Minusx_deltax2 = y_deltax2 - (int) ( x_delta <<1 );
    ErrorTerm = y_deltax2 - (int) x_delta;

    putpixel(x_bgn, y_bgn, color);
    while ( x_delta-- )
    {

      if ( ErrorTerm >= 0 )
      {

         y_bgn++;
         ErrorTerm += y_deltax2Minusx_deltax2;
      }
      else
      {

         ErrorTerm += y_deltax2;
      }
      x_bgn += XDirection;    //    advance the X coordinate
      putpixel(x_bgn, y_bgn, color);    //    draw a pixel
   }
    
    return;
}


void Octant1(unsigned int x_bgn, unsigned int y_bgn,unsigned int  x_delta,unsigned int y_delta, int XDirection,unsigned int color)               
{
   int x_deltax2;
   int x_deltax2Minusy_deltax2;
   int ErrorTerm;

   
   x_deltax2 = x_delta <<1;
   x_deltax2Minusy_deltax2 = x_deltax2 - (int) ( y_delta <<1 );
   ErrorTerm = x_deltax2 - (int) y_delta;
   putpixel(x_bgn, y_bgn, color);           
   while ( y_delta-- ) 
   {
      
      if ( ErrorTerm >= 0 ) 
     {     

         x_bgn += XDirection;
         ErrorTerm += x_deltax2Minusy_deltax2;
      } 
      else 
      {
         
             ErrorTerm += x_deltax2;
      }
      y_bgn++;                   
      putpixel(x_bgn, y_bgn, color);        
   }
    
    return;
}

void line(int x_bgn, int y_bgn, int x_end, int y_end,unsigned int color)
{
    int    x_delta;
    int    y_delta;

    int    temp;

    if(y_bgn == y_end)
    {
        draw_h_line(x_bgn, x_end, y_bgn,color);
        return;
    }
    else if(x_bgn == x_end)
    {
        draw_v_line(y_bgn, y_end, x_bgn,color);
        return;
    }

    if(y_bgn > y_end)
    {
        temp    = y_bgn;
        y_bgn    = y_end;
        y_end    = temp;

        temp    = x_bgn;
        x_bgn    = x_end;
        x_end    = temp;
    }

    x_delta = x_end - x_bgn;
    y_delta = y_end - y_bgn;

    if(x_delta > 0)
    {
        if(x_delta > y_delta)
        {
            Octant0(x_bgn, y_bgn, x_delta, y_delta, 1,color);
        }
        else
        {
            Octant1(x_bgn, y_bgn, x_delta, y_delta, 1,color);
        }
    }
    else
    {
    
        x_delta = -x_delta;
        if(x_delta > y_delta)
        {
            Octant0(x_bgn, y_bgn, x_delta, y_delta, -1,color);
        }
        else
        {
            Octant1(x_bgn, y_bgn, x_delta, y_delta, -1,color);
        }
    }
    return;
}

void rectangle(int left,int top,int right,int bottom,unsigned int color)
{

        line(left,top,right,top,color);
        line(left,bottom,right,bottom,color);
        line(left,top,left,bottom,color);
        line(right,top,right,bottom,color);
        return ;

}
//?????? 
void roundrect(int left, int top, int right, int bottom, int a, int b,unsigned int color)
{
    BOOL flag = FALSE;
    int  x;
    int  y;
    long aa;
    long bb;
    long d;
    int  t;


    /* + draw rectangle */
    draw_h_line( left, right, top - b,color);   //????????
    draw_h_line( left, right, bottom + b,color);
    draw_v_line( top, bottom, left - a ,color);
    draw_v_line( top, bottom, right + a, color);
    /* - draw rectangle */

    /* + draw ellipse */
    if (a < b)
    {
        flag = TRUE;
        t = a;
        a = b;
        b = t;
    }
    aa = (long)a * a;
    bb = (long)b * b;

    x = 0;
    y = b;
    d = 4 * bb + aa * (-b * 4 + 1);
    while (4 * bb * (x + 1) < aa * (4 * y - 2))
    {
        if (!flag) putpixel(right + x, bottom + y, color);
        else putpixel(right + y, bottom + x, color);
        if (!flag) putpixel(right + x, top - y, color);
        else putpixel(right + y, top - x, color);
        if (!flag) putpixel(left - x, bottom + y, color);
        else putpixel(left - y, bottom + x, color);
        if (!flag) putpixel(left - x, top - y, color);
        else putpixel(left - y, top - x, color);
        if (d < 0)
        {
            d += 4 * bb * (2 * x + 3);
            x++;
        }
        else
        {
            d += 4 * bb * (2 * x + 3) + 4 * aa * (-2 * y + 2);
            x++;
            y--;
        }
    }

    y = 0;
    x = a;
    d = 4 * aa + bb * (-a * 4 + 1);
    while (4 * bb * (x + 1) > aa * (4 * y - 2))
    {
        if (!flag) putpixel( right + x, bottom + y, color);
        else putpixel( right + y, bottom + x, color);
        if (!flag) putpixel(right + x, top - y, color);
        else putpixel( right + y, top - x, color);
        if (!flag) putpixel(left - x, bottom + y,color);
        else putpixel( left - y, bottom + x, color);
        if (!flag) putpixel( left - x, top - y,color);
        else putpixel(left - y, top - x, color);
        if (d < 0)
        {
            d += 4 * aa * (2 * y + 3);
            y++;
        }
        else
        {
            d += 4 * aa * (2 * y + 3) + 4 * bb * (-2 * x + 2);
            y++;
            x--;
        }
    }
    /* - draw ellipse */
}

/* ?????????????l??? */
void fillroundrect( int left, int top, int right, int bottom, int a, int b,unsigned int color)
{
    BOOL flag = FALSE;
    int  x;
    int  y;
    long aa;
    long bb;
    long d;
    int  t;

    /* + draw filled rectangle */
    for (y=top; y<bottom; y++) draw_h_line( left - a, right + a, y,color);
    /* - draw filled rectangle */

    /* + draw filled ellipse */
    if (a < b)
    {
        flag = TRUE;
        t = a;
        a = b;
        b = t;
    }
    aa = (long)a * a;
    bb = (long)b * b;

    x = 0;
    y = b;
    d = 4 * bb + aa * (-b * 4 + 1);
    while (4 * bb * (x + 1) < aa * (4 * y - 2))
    {
        if (flag)
        {
               draw_h_line( right + y, left - y, bottom + x,color);
            if (x != 0)draw_h_line(right + y, left - y, top - x,color);
        }
        if (d < 0)
        {
            d += 4 * bb * (2 * x + 3);
            x++;
        }
        else
        {
            if (!flag)
            {
                draw_h_line(right + x, left- x, bottom + y ,color);
                draw_h_line(right + x, left- x, top - y,color);
            }
            d += 4 * bb * (2 * x + 3) + 4 * aa * (-2 * y + 2);
            x++;
            y--;
        }
    }

    y = 0;
    x = a;
    d = 4 * aa + bb * (-a * 4 + 1);
    while (4 * bb * (x + 1) > aa * (4 * y - 2))
    {
        if (!flag)
        {
             draw_h_line( right + x, left - x, bottom + y,color);
            if (y != 0) draw_h_line(right + x, left - x, top - y,color);
        }
        if (d < 0)
        {
            d += 4 * aa * (2 * y + 3);
            y++;
        }
        else
        {
            if (flag)
            {
                draw_h_line( right + y, left - y, bottom + x,color);
                draw_h_line( right + y, left - y, top - x,color );
            }
            d += 4 * aa * (2 * y + 3) + 4 * bb * (-2 * x + 2);
            y++;
            x--;
        }
    }
}

void arrow(int startx,int starty,int baseline,unsigned char direct,unsigned int color)
{    
        int    h;
        int    loop;
        int    x1 =0,x2 = 0;
        int    y1 =0,y2 = 0;
        int    dirflg = 0;
        int    sw;
        
        h    =        ((baseline-1)>>1)+1;

        sw    =        0;

        switch(direct)
        {
            case ARROW_UP:    
            dirflg        =    1;    
            sw            =    1;
            x1            =    startx;
            x2            =    startx+baseline-1;
            y1            =    starty;
            break;
            case ARROW_DOWN:
            dirflg        =    -1;
            sw            =    1;
            x1            =    startx;
            x2            =    startx+baseline-1;
            y1            =    starty;
            break;
            case ARROW_LEFT:
            dirflg        =    -1;    
            sw            =    2;
            x1            =    startx;            
            y1            =    starty;
            y2            =    starty+baseline-1;
            break;
            case ARROW_RIGHT:
            dirflg        =    1;
            sw            =    2;
            x1            =    startx;            
            y1            =    starty;
            y2            =    starty+baseline-1;
            break;
    
        }
        for(loop=0;    loop<h;loop++)
       {            
            switch(sw)
            {
                case 1:    
                    line(x1,y1,x2,y1,color);
                    y1+=dirflg;
                    x1++;
                    x2--;
                break;
                case 2:
                    line(x1,y1,x1,y2,color);
                    x1+=dirflg;
                    y1++;
                    y2--;                    
                break;            
            }        
        }    
        return ;
}


unsigned char LCD_DrawICON(unsigned char startX, unsigned char startY, unsigned int index,const IMAGESTYLE mImage)
{
    unsigned int endX,endY;
    unsigned long totalPixels,addr,i;
    unsigned int sizeX, sizeY;
    unsigned char lcd_buf,     cTemp;


    switch(mImage)
    {    
        case Image22X10:
            sizeX = 22;
            sizeY = 10;
            totalPixels = 440;
            break;
        case Image33X44:
            sizeX = 33;
            sizeY = 44;
            totalPixels = 2904;
            break;
        case Image44X44:
            sizeX = 44;
            sizeY = 44;
            totalPixels = 3872;
            break;
        case Image56X36:
            sizeX = 56;
            sizeY = 36;
            totalPixels = 2*56*36;
            break;
        case Image20X26:
            sizeX = 20;
            sizeY = 26;
            totalPixels = 1040;
            break;
        case Image24X24:
            sizeX = 24;
            sizeY = 24;
            totalPixels = 1152;
            break;
        case Image320X26:
            sizeX = 320;
            sizeY = 26;
            totalPixels = 16640;
            break;
        default:
            return 1;
    }
    endX = startX+sizeX-1;
    endY = startY+sizeY-1;
    LCD_Set_XY(startX,startY);
    if(index == 290)
    {
        LCD_Set_Window(214,0,239,319);
    }
    else if(297 == index)
    {
        LCD_Set_Window(0,0,26,319);
    }
    else
    {
        LCD_Set_Window(startY,startX,endY,endX);
    }
    //---------------------------------------------------------------------------
                    //??flash??????
    addr = (unsigned long)index << 12;
    
      LATCbits.LATC14        =    0;    
    LATGbits.LATG6        =    0;
    
    while(SPI2STAT&0x02);    
    SPI2BUF        =    0x0B;
    while(SPI2STAT&0x02);        
    SPI2STATbits.SPIROV        =    0;    
    while(!(SPI2STAT&0x01));
    cTemp        =    SPI2BUF;

    SPI2BUF        =    (addr&0xffffff) >> 16;
    while(SPI2STAT&0x02);        
    SPI2STATbits.SPIROV        =    0;    
    while(!(SPI2STAT&0x01));
    cTemp        =    SPI2BUF;

    SPI2BUF        =    (addr&0xffff) >> 8;
    while(SPI2STAT&0x02);        
    SPI2STATbits.SPIROV        =    0;    
    while(!(SPI2STAT&0x01));;
    cTemp        =    SPI2BUF;

    SPI2BUF        =    addr&0xff;
    while(SPI2STAT&0x02);        
    SPI2STATbits.SPIROV        =    0;    
    while(!(SPI2STAT&0x01));
    cTemp        =    SPI2BUF;
    
     SPI2BUF        =    0xff;            
    while(SPI2STAT&0x02);
    while(!(SPI2STAT&0x01));
    cTemp        =    SPI2BUF;

    LCD_Write_Start();
    __asm__ volatile( "disi #0x3FFF" );
    for(i = 0; i< totalPixels;i++)
    {    
        SPI2BUF        =    0xff;        
        while(SPI2STAT&0x02);    
        SPI2STATbits.SPIROV        =    0;    
        while(!(SPI2STAT&0x01));
        lcd_buf        =    SPI2BUF;
        LCD_Write_LCD_Data(lcd_buf);
    }
    LCD_Write_End();
    __asm__ volatile( "disi #0x0000" );
    LATGbits.LATG6        =    1;
    LATCbits.LATC14        =    1;

    return 0;
} 

unsigned char cmp_w[8]={128,64,32,16,8,4,2,1};



void * memmove_kk(unsigned char * dest,const unsigned char *src,unsigned int count)
{
    char *tmp, *s;

    if (dest <= src) 
    {
        tmp = (char *) dest;
        s = (char *) src;
        while (count--)
            *tmp++ = *s++;
    }          
    else
    {
        tmp = (char *) dest + count;
        s = (char *) src + count;
        while (count--)
            *--tmp = *--s;
     }
    return dest;
}

void outtext(int x,int y,unsigned char *str,int fontStyle,unsigned int color)
{
    unsigned int                    address = 0;
    unsigned char                    xWidthByte = 0;    
    const unsigned char                *pFont = NULL;    
    unsigned char                   poffset[128];    
    unsigned char                     chtmp;    
    unsigned char                     choffset,number = 0;

    unsigned char row,c;
    
    switch(fontStyle)
    {
        case FONT_16X24:
            xWidthByte = 48;
            pFont = FONT16X24;
            break;
        case FONT_12X16:
            //xWidthByte = 24;
            xWidthByte = 16;
            pFont = FONT12X16;
            break;
        case FONT_32X32:
            xWidthByte = 128;
            pFont = FONT32X32; 
            break; 
        default:
            break;
    }

    while(*str)
    {
         chtmp = *str;
                
        ++number;
                
        if(chtmp>=0x30&&chtmp<=0x39)
        {
            choffset = chtmp-0x30;
            if(fontStyle == FONT_32X32)
            {
                address = choffset * xWidthByte;
            }
            else
            {
                address = 52*xWidthByte + choffset * xWidthByte; 
            }
        }
        else if(chtmp >= 'A' && chtmp <= 'Z')
        {
            choffset = chtmp-'A';
            address = 26*xWidthByte + choffset * xWidthByte;
        } 
        else if(chtmp >= 'a' && chtmp <= 'z')
        {
            choffset = chtmp-'a';    
            address = choffset * xWidthByte;                
        }
        else
        {     
                switch(chtmp)
                {

                        case ':':
                            address = (52 + 10)*xWidthByte ;
                            break;
                        case '-':
                            address = (52 + 10)*xWidthByte + xWidthByte;
                            break;
                        case '.':
                            address = (52 + 10)*xWidthByte + 2*xWidthByte;
                            break;
                        case '/':
                            address = (52 + 10)*xWidthByte + 3*xWidthByte;
                            break;    
                        case '?':
                            address = (52 + 10)*xWidthByte + 4*xWidthByte;
                            break;
                        default:
                            break;
                } 
        }

        if(0x20==chtmp)
        {
              memset(poffset,0x00,xWidthByte);
        }
        else
        {    
             memmove(poffset,pFont+address,xWidthByte);
        }

         str++;


        if(fontStyle == FONT_16X24)
        {
            for(row=0;row<16;row++)
            { 
                for(c=0;c<8;c++)
                {
                    if((poffset[row*3]&cmp_w[c])!=0)
                    putpixel(c+x,row+y+number*11,color);
                } 
                for(c=0;c<8;c++)
                {
                    if((poffset[row*3+1]&cmp_w[c])!=0)
                    putpixel(c+8+x,row+y+number*11,color);
                }
                for(c=0;c<8;c++)
                {
                    if((poffset[row*3+2]&cmp_w[c])!=0)
                    putpixel(c+16+x,row+y+number*11,color); 
                }
            }
        } 
       if(fontStyle == FONT_8X16)
        {
            for(row=0;row<8;row++)
            {     
                for(c=0;c<8;c++)
                {
                    if((poffset[row*2]&cmp_w[c])!=0)
                        putpixel(c+x,row+y+number*8,color);
                } 
                for(c=0;c<8;c++)
                {
                    if((poffset[row*2+1]&cmp_w[c])!=0)
                    putpixel(c+8+x,row+y+number*8,color);
                }
            }
        }
        if(fontStyle == FONT_12X16)
        {
            for(row=0;row<8;row++)
            {     
                for(c=0;c<8;c++)
                {
                    if((poffset[row*2]&cmp_w[c])!=0)
                        putpixel(c+x,row+y+number*9,color);
                } 
                for(c=0;c<8;c++)
                {
                    if((poffset[row*2+1]&cmp_w[c])!=0)
                    putpixel(c+8+x,row+y+number*9,color);
                }
            }
        }
        if(fontStyle == FONT_32X32)
        {
            for(row=0;row<32;row++)
            {     
                for(c=0;c<8;c++)
                {
                    if((poffset[row*4]&cmp_w[c])!=0)
                    putpixel(c+x,row+y+number*18,color);
                } 
                for(c=0;c<8;c++)
                {
                    if((poffset[row*4+1]&cmp_w[c])!=0)
                    putpixel(c+8+x,row+y+number*18,color);
                }
                for(c=0;c<8;c++)
                {
                    if((poffset[row*4+2]&cmp_w[c])!=0)
                    putpixel(c+16+x,row+y+number*18,color);
                }        
                for(c=0;c<8;c++)
                {
                    if((poffset[row*4+3]&cmp_w[c])!=0)
                    putpixel(c+24+x,row+y+number*18,color);
                }
            }
        }
    }    
}    
void bar( int x0, int y0, int width, int height,unsigned color)
{
   
    int i;
    int j;
    LCD_Set_Window(x0,y0,x0+width,y0+height);
    LCD_Write_Start();
    __asm__ volatile( "disi #0x3FFF" );
    for (i=y0; i<y0+height; i++)
    {
        for (j=x0; j<x0+width; j++)
        {
            LCD_Write_Data(color);
        }
    }
    __asm__ volatile( "disi #0x0000" ); //enable interrupts
    LCD_Write_End();
    draw_v_line(y0,y0 + height,x0 + width,color);
    draw_v_line(y0,y0 + height,x0 + width-1,color);
    draw_v_line(y0,y0 + height,x0 ,color);
       
} 














LCD                MCU
DB10~DB17   <--->  RE0~RE7      
CS          <----  RD11          chip select signal   low : ILI9320 is selected
RS          <----  RD10          a register select signal   low: index or status register is selected. high: select a control register
WR          <----  RD4           a write strobe signal and enables an opreation to write data when the signal is low
RD          <----  RD5           a read strobe singal and enables an operation to read data when the signal is low
RESET       <----  RD9 

??        08.6.9
-------------------------------------------------------------------------------*/
#define NOP() asm("NOP");

#define DATA_DDR     TRISE 
#define DATA_PORT    PORTE
#define DATA_PIN     LATE

#define LCD_CS_DDR   TRISDbits.TRISD11
#define LCD_CS_PORT  PORTDbits.RD11
#define LCD_CS_PIN   LATDbits.LATD11

#define LCD_RS_DDR   TRISDbits.TRISD10
#define LCD_RS_PORT  PORTDbits.RD10
#define LCD_RS_PIN   LATDbits.LATD10

#define LCD_WR_DDR   TRISDbits.TRISD4
#define LCD_WR_PORT  PORTDbits.RD4
#define LCD_WR_PIN   LATDbits.LATD4

#define LCD_RD_DDR   TRISDbits.TRISD5
#define LCD_RD_PORT  PORTDbits.RD5
#define LCD_RD_PIN   LATDbits.LATD5

#define LCD_RST_DDR  TRISDbits.TRISD9
#define LCD_RST_PORT PORTDbits.RD9
#define LCD_RST_PIN  LATDbits.LATD9

#define DATA_INPUT()  DATA_DDR   = 0xff					
#define DATA_OUTPUT() DATA_DDR   = 0x00
										
#define LCD_CS_H()    LCD_CS_PIN  = 1  
#define LCD_CS_L()    LCD_CS_PIN  = 0

#define LCD_RS_H()    LCD_RS_PIN  = 1
#define LCD_RS_L()    LCD_RS_PIN  = 0

#define LCD_WR_H()    LCD_WR_PIN  = 1
#define LCD_WR_L()    LCD_WR_PIN  = 0

#define LCD_RD_H()    LCD_RD_PIN  = 1
#define LCD_RD_L()    LCD_RD_PIN  = 0

#define LCD_RST_H()   LCD_RST_PIN = 1
#define LCD_RST_L()   LCD_RD_PIN  = 0

//--------------LCD backlight define---------------------------------------------
#define LCD_BACKLIGHT_DDR()  TRISDbits.TRISD1 = 0
#define LCD_BACKLIGHT_H()    LATDbits.LATD1 = 1
#define LCD_BACKLIGHT_L()    LATDbits.LATD1 = 0

//-----------define color--------------------------------------------------------
#define White         		0xFFFF  //?
#define Black          	    0x0000  //?
#define Grey           		0xF7DE  //?
#define Blue                0x001F  //?
#define Blue2               0x051F
#define Red                 0xF800  //?
#define Magenta             0xF81F  //??
#define Green               0x07E0  //?
#define Cyan          	    0x7FFF  //??
#define Yellow         	    0xFFE0  //?

#define BLACK              (WORD)0b0000000000000000
#define BRIGHTBLUE         (WORD)0b0000000000011111
#define BRIGHTGREEN        (WORD)0b0000011111100000
#define BRIGHTCYAN         (WORD)0b0000011111111111
#define BRIGHTRED          (WORD)0b1111100000000000
#define BRIGHTMAGENTA      (WORD)0b1111100000011111
#define BRIGHTYELLOW       (WORD)0b1111111111100000
#define BLUE               (WORD)0b0000000000010000
#define GREEN              (WORD)0b0000010000000000
#define CYAN               (WORD)0b0000010000010000
#define RED                (WORD)0b1000000000000000
#define MAGENTA            (WORD)0b1000000000010000
#define BROWN              (WORD)0b1111110000000000
#define LIGHTGRAY          (WORD)0b1000010000010000
#define DARKGRAY           (WORD)0b0100001000001000
#define LIGHTBLUE          (WORD)0b1000010000011111
#define LIGHTGREEN         (WORD)0b1000011111110000
#define LIGHTCYAN          (WORD)0b1000011111111111
#define LIGHTRED           (WORD)0b1111110000010000
#define LIGHTMAGENTA       (WORD)0b1111110000011111
#define YELLOW             (WORD)0b1111111111110000
#define WHITE              (WORD)0b1111111111111111

#define GRAY0       	   (WORD)0b1110011100011100
#define GRAY1         	   (WORD)0b1100011000011000   
#define GRAY2              (WORD)0b1010010100010100   
#define GRAY3              (WORD)0b1000010000010000
#define GRAY4              (WORD)0b0110001100001100
#define GRAY5              (WORD)0b0100001000001000
#define GRAY6	           (WORD)0b0010000100000100
//-------------------------------------------------------------------------------

#define		ARROW_UP		0
#define		ARROW_DOWN		1
#define		ARROW_LEFT		2
#define		ARROW_RIGHT		3	
//--------------------------------------------------------------------------------

#define     RGB(x,y,z)  ((int)(x/8) << 11)| ((int)(y/4) << 5) | ((int)z/8)

typedef enum
{    
	Image24X24 = 2,
	Image9X26 ,
	Image22X10,
	Image20X26,
	Image32X26,
	Image33X44,
	Image40X26,
	Image18X26,
	Image56X36,
	Image41X45,
	Image45X36,
	Image43X45,
	Image44X44,
	Image88X44,
	Image146X44,
	Image320X26,
	Image269X26,
}IMAGESTYLE; 
//--------------------------------------------------------------------------------

#define		SCREEN_ORIGIN				15
#define		SCREEN_LEFT					0
#define		SCREEN_TOP					0
#define		SCREEN_RIGHT				239
#define		SCREEN_BOTTOM				319

//--------------------------------------------------------------------------------
void LCD_WR_REG(unsigned char index,unsigned int val);
unsigned int LCD_RD_REG(unsigned char index);
void LCD_Write_Start();
void LCD_Write_Data(unsigned int val);
void LCD_Write_End();
void LCD_Read_Start();
unsigned int LCD_RD_DATA();
void LCD_Read_End();
void delay_ms(unsigned int iMs);
void Display_ON();
void Display_OFF();
void LCD_Init();
void LCD_SetTextColor(unsigned int Color);
void LCD_BackColor(unsigned int Color);
void LCD_Set_XY(unsigned int x, unsigned int y);

void  putpixel(unsigned int x,unsigned int y,unsigned int color);
void fillrect(unsigned int startX,unsigned int startY,unsigned int endX,unsigned int endY,unsigned int color);
//void Clear(unsigned char x_start,unsigned char x_stop,unsigned char y_start,unsigned char y_stop,unsigned int color);
void Clear(unsigned int x_start,unsigned int x_stop,unsigned int y_start,unsigned int y_stop,unsigned int color);
void draw_v_line(int y_start, int y_end, int x,unsigned int color);
void draw_h_line(int x_start, int x_end, int y,unsigned int color);
void Octant0(unsigned int x_bgn, unsigned int y_bgn,unsigned int x_delta, unsigned int y_delta, int XDirection,unsigned int color);
void Octant1(unsigned int x_bgn, unsigned int y_bgn,unsigned int  x_delta,unsigned int y_delta, int XDirection,unsigned int color);	
void line(int x_bgn, int y_bgn, int x_end, int y_end,unsigned int color);
void rectangle(int left,int top,int right,int bottom,unsigned int color);
void roundrect(int left, int top, int right, int bottom, int a, int b,unsigned int color);
void fillroundrect(int left, int top, int right, int bottom, int a, int b,unsigned int color);
void arrow(int startx,int starty,int baseline,unsigned char direct,unsigned int color);
void bar( int x0, int y0, int width, int height,unsigned color);

void LCD_DrawChar(unsigned int Xpos, unsigned int Ypos, unsigned char *pic); 
void outtext(int x,int y,unsigned char *str,int fontsytle ,unsigned int color);
void FontDisplay(int x, int y, unsigned char * FontModule);
void Drawicon16X16(int x, int y, unsigned char * FontModule,unsigned color);
void Drawicon24X24(int x, int y, unsigned char * FontModule,unsigned int color);
void Drawicon32X32(int x, int y, unsigned char * FontModule,unsigned int color);
void Drawicon48X48(int x, int y, unsigned char * FontModule,unsigned int color);

unsigned char LCD_DrawICON(unsigned char startX, unsigned char startY, unsigned int index,const IMAGESTYLE mImage);
#endif




 


                    // Expect 9325h or 9320h       //1=H
 /*
    LCD_PORT_INI();
    LCD_RST_L();
    delay_ms(400);
    LCD_RST_H();
     
    DATA_OUTPUT(); // <change port to output>
            
    LCD_CS_L();                    // Enable LCD
    //LCD_WR_REG(0xe5, 0x8000);      // start osc ILI9320
    LCD_WR_REG(0x0000,0x0001);  //start oscillation
    delay_us(10);

    LCD_CS_H();    // CS = 1  deselect the chip
    LCD_WR_H();    // WR = 1  put strobe to idle
    LCD_RD_H();    // RD = 1  put read to idle
    LCD_RS_L();    // RS = 0  select an index/status register  
         
    LCD_LO_PORT=0; // <16 address DATA on Port>
    LCD_HI_PORT=0; // <16 address DATA on Port> 

    LCD_CS_L();    // CS = 0  select the chip
    LCD_WR_L();	   // WR = 0  strobe wr to write

    LCD_CS_H();    // CS = 1  deselect the chip
    LCD_WR_H();    // WR = 1  put wr to idle
    LCD_RD_H();    // RD = 1  read to idle
    LCD_RS_H();    // RS = 1  select a control register

    DATA_INPUT();  //<change port to input>

    LCD_CS_L();    // CS = 0  select the chip
    LCD_RD_L();    // RD = 0  strobe rd to read and put data value on port
       
    printf("REG 0x0000 Read : 0x%02X%02X \n\r ",GET_LCD_HI,GET_LCD_LO); 
                                                                            
    LCD_CS_L();    // CS = 1  deselect the chip
    LCD_RD_L();    // RD = 1  put rd to idle 

    DATA_OUTPUT(); //<change port to output>

    LCD_BL_L(); 
    delay_ms(1000); 
//--------------------------------------------------------------------------
    LCD_BL_H(); 
    delay_ms(1000); 
                    // Expect 9325h or 9320h       //1=H

    LCD_PORT_INI();
    LCD_RST_L();
    delay_ms(400);
    LCD_RST_H();
     
    DATA_OUTPUT(); // <change port to output>
            
    LCD_CS_L();
      */  
      
      
      
/*
void LCD_WR_DATA16(unsigned int data)//д
{
     LCD_RD_H();
	 LCD_RS_H();
     LCD_CS_L();  
     LCD_WR_L();
     LCD_HI_PORT = data>>8; 
     LCD_WR_H();
     LCD_WR_L();
     LCD_LO_PORT=data; 
     LCD_WR_H();
     LCD_CS_H();
  
}
//-------------------------------------------------------------
void LCD_WR_REG16(unsigned int index)//д
{
     LCD_RD_H();
	 LCD_RS_L();
     LCD_CS_L();  
     LCD_WR_L();
     LCD_HI_PORT=index>>8; 
     LCD_WR_H();
     LCD_WR_L();
     LCD_LO_PORT=index; 
     LCD_WR_H();
     LCD_CS_H();   
     
  void LCD_WR_REG(unsigned int index,unsigned int data)
{
     LCD_WR_REG16(index);
     LCD_WR_DATA16(data); 
     
  //   printf("INIT reg : 0x00%02X Write : 0x%02X        ",index,data);
}        
                  */