

#include <stdint.h>
//#include "Simulated_8080.h"

#include "TFT_LCD.h"
#include "TM035HFZGZx.h"
#include "RTE_WDT.h"
#include "WDT.h"

#ifndef NULL
    #define NULL 0x00
#endif

TFTLCDDrawingFIFOStruct TFTLCDDrawingFIFO;

TFTLCDUpdateCtrlStruct TFTLCDUpdateCtrl;

void TFT_LCD_Startup(void)
{
    uint8_t i;

    WDT_Clear();
    LCD_Init( );

    for ( i = 0; i < TFT_LCD_REQ_FIFO_MAX_DEPTH; i++ )
        TFTLCDDrawingFIFO.Req [ i ].Mode = TFT_LCD_MODE_IDLE;

    TFTLCDDrawingFIFO.Iptr  = 0;
    TFTLCDDrawingFIFO.Optr  = 0;
    TFTLCDDrawingFIFO.Depth = 0;

    TFTLCDUpdateCtrl.Brightness = 0;
    TFTLCDUpdateCtrl.Enable     = 1;
}

void TFT_LCD_Shutdown(void)
{
    LCD_Shutdown( );

    TFTLCDUpdateCtrl.Enable = 0;
}

void TFT_LCD_Set_Brightness(uint8_t Br)
{
    if ( TFTLCDUpdateCtrl.Enable == 0 )
        return;

    if ( Br > 100 )
        Br = 100;

    if ( Br != TFTLCDUpdateCtrl.Brightness )
    {
        TFTLCDUpdateCtrl.Brightness = Br;
        // PWM_Channel_Set_Duty_Cycle(7, Br);
    }
}

uint8_t TFT_LCD_Busy_Check(void)
{
    if ( TFTLCDDrawingFIFO.Depth == 0 )
        return 0;
    else if ( TFTLCDDrawingFIFO.Depth < TFT_LCD_REQ_FIFO_MAX_DEPTH )
        return 1;

    return 2;
}

void TFT_LCD_Display_Update_Service(void)
{
    uint8_t Done;

    if ( TFTLCDDrawingFIFO.Depth )
    {
        switch ( TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Optr ].Mode )
        {
            case TFT_LCD_MODE_CLEAR:
                Done = TFT_LCD_Cls_Handler(&TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Optr ]);
                break;

            case TFT_LCD_MODE_DBMP:
                Done = TFT_LCD_Direct_Draw_Bmp_Handler(&TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Optr ]);
                break;

            case TFT_LCD_MODE_IBMP:
                Done = TFT_LCD_Insert_Draw_Bmp_Handler(&TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Optr ]);
                break;

            case TFT_LCD_MODE_DTBMP:
                Done = TFT_LCD_Direct_Draw_Transparent_Bmp_Handler(&TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Optr ]);
                break;

            case TFT_LCD_MODE_ITBMP:
                Done = TFT_LCD_Insert_Draw_Transparent_Bmp_Handler(&TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Optr ]);
                break;

            case TFT_LCD_MODE_PIXEL:
                Done = TFT_LCD_Draw_Pixel_Handler(&TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Optr ]);
                break;

            case TFT_LCD_MODE_HLINE:
                Done = TFT_LCD_Draw_Horizontal_Line_Handler(&TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Optr ]);
                break;

            case TFT_LCD_MODE_VLINE:
                Done = TFT_LCD_Draw_Vertical_Line_Handler(&TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Optr ]);
                break;

            case TFT_LCD_MODE_BBOX:
                Done = TFT_LCD_Draw_Box_Border_Handler(&TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Optr ]);
                break;

            case TFT_LCD_MODE_DFBOX:
                Done = TFT_LCD_Direct_Draw_Full_Box_Handler(&TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Optr ]);
                break;

            case TFT_LCD_MODE_IFBOX:
                Done = TFT_LCD_Insert_Draw_Full_Box_Handler(&TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Optr ]);
                break;
                //            case TFT_LCD_MODE_Traffic :Done =TFT_LCD_Insert_Draw_Traffic_Bmp_Handler( &TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Optr] );
                //              break;
            default:
                Done = 1;
                break;
        }

        if ( Done )
        {
            TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Optr ].Mode = TFT_LCD_MODE_IDLE;
            // FIFO����
            TFTLCDDrawingFIFO.Depth--;
            TFTLCDDrawingFIFO.Optr++;

            if ( TFTLCDDrawingFIFO.Optr >= TFT_LCD_REQ_FIFO_MAX_DEPTH )
                TFTLCDDrawingFIFO.Optr = 0;
        }
    }
}

void TFT_LCD_Cls(void)
{
    if ( TFTLCDDrawingFIFO.Depth >= TFT_LCD_REQ_FIFO_MAX_DEPTH )
        return;

    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].Mode        = TFT_LCD_MODE_CLEAR;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].State       = TFT_LCD_STATE_INIT;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].StartPage   = 0;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].StartCol    = 0;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].EndPage     = 39;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].EndCol      = 239;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].CurrentPage = 0;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].CurrentCol  = 0;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].Width       = 240;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].Length      = 9600;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].Offset      = 0;
    // FIFO����
    TFTLCDDrawingFIFO.Depth++;
    TFTLCDDrawingFIFO.Iptr++;

    if ( TFTLCDDrawingFIFO.Iptr >= TFT_LCD_REQ_FIFO_MAX_DEPTH )
        TFTLCDDrawingFIFO.Iptr = 0;
}

void TFT_LCD_Draw_Bmp(uint16_t StartX, uint16_t StartY, uint8_t *pBmp)
{
    if ( TFTLCDDrawingFIFO.Depth >= TFT_LCD_REQ_FIFO_MAX_DEPTH )
        return;

    if ( pBmp == NULL )
        return;

    if ( (StartX >= TFT_LCD_X_SIZE) || (StartY >= TFT_LCD_Y_SIZE) )
        return;

    if ( (StartX + pBmp [ 0 ] >= TFT_LCD_X_SIZE) || (StartY + pBmp [ 1 ] >= TFT_LCD_Y_SIZE) )
        return;

    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].StartPage   = (( uint8_t )(StartY >> 3));
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].StartCol    = ( uint8_t )StartX;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].EndPage     = (( uint8_t )((StartY + pBmp [ 1 ] - 1) >> 3));
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].EndCol      = ( uint8_t )(StartX + pBmp [ 0 ] - 1);
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].CurrentPage = TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].StartPage;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].CurrentCol  = TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].StartCol;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].Width       = pBmp [ 0 ];
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].Length      = (pBmp [ 1 ] >> 3) * pBmp [ 0 ];
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].Offset      = 0;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].BitShiftT   = (( uint8_t )(StartY & 0x0007));
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].pBmp        = pBmp + 2;

    if ( TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].BitShiftT == 0 )
    {
        TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].Mode  = TFT_LCD_MODE_DBMP;
        TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].State = TFT_LCD_STATE_INIT;
    }
    else
    {
        TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].Mode  = TFT_LCD_MODE_IBMP;
        TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].State = TFT_LCD_STATE_TOP;
    }

    // FIFO����
    TFTLCDDrawingFIFO.Depth++;
    TFTLCDDrawingFIFO.Iptr++;

    if ( TFTLCDDrawingFIFO.Iptr >= TFT_LCD_REQ_FIFO_MAX_DEPTH )
        TFTLCDDrawingFIFO.Iptr = 0;
}

void TFT_LCD_Draw_NEAR_Bmp(uint16_t StartX, uint16_t StartY, uint8_t *pBmp)
{
    if ( TFTLCDDrawingFIFO.Depth >= TFT_LCD_REQ_FIFO_MAX_DEPTH )
        return;

    if ( pBmp == NULL )
        return;

    if ( (StartX >= TFT_LCD_X_SIZE) || (StartY >= TFT_LCD_Y_SIZE) )
        return;

    if ( (StartX + pBmp [ 0 ] >= TFT_LCD_X_SIZE) || (StartY + pBmp [ 1 ] >= TFT_LCD_Y_SIZE) )
        return;

    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].StartPage   = (( uint8_t )(StartY >> 3));
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].StartCol    = ( uint8_t )StartX;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].EndPage     = (( uint8_t )((StartY + pBmp [ 1 ] - 1) >> 3));
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].EndCol      = ( uint8_t )(StartX + pBmp [ 0 ] - 1);
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].CurrentPage = TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].StartPage;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].CurrentCol  = TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].StartCol;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].Width       = pBmp [ 0 ];
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].Length      = (pBmp [ 1 ] >> 3) * pBmp [ 0 ];
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].Offset      = 0;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].BitShiftT   = (( uint8_t )(StartY & 0x0007));
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].pBmp        = pBmp + 2;

    if ( TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].BitShiftT == 0 )
    {
        TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].Mode  = TFT_LCD_MODE_DBMP;
        TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].State = TFT_LCD_STATE_INIT;
    }
    else
    {
        TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].Mode  = TFT_LCD_MODE_IBMP;
        TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].State = TFT_LCD_STATE_TOP;
    }

    // FIFO����
    TFTLCDDrawingFIFO.Depth++;
    TFTLCDDrawingFIFO.Iptr++;

    if ( TFTLCDDrawingFIFO.Iptr >= TFT_LCD_REQ_FIFO_MAX_DEPTH )
        TFTLCDDrawingFIFO.Iptr = 0;
}

void TFT_LCD_Draw_Traffic_Bmp(uint16_t StartX, uint16_t StartY, uint8_t *pBmp)
{
}

void TFT_LCD_Draw_Transparent_Bmp(uint16_t StartX, uint16_t StartY, uint8_t *pBmp, uint8_t Type)
{
    if ( TFTLCDDrawingFIFO.Depth >= TFT_LCD_REQ_FIFO_MAX_DEPTH )
        return;

    if ( pBmp == NULL )
        return;

    if ( (StartX >= TFT_LCD_X_SIZE) || (StartY >= TFT_LCD_Y_SIZE) )
        return;

    if ( (StartX + pBmp [ 0 ] >= TFT_LCD_X_SIZE) || (StartY + pBmp [ 1 ] >= TFT_LCD_Y_SIZE) )
        return;

    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].StartPage   = (( uint8_t )(StartY >> 3));
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].StartCol    = ( uint8_t )StartX;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].EndPage     = (( uint8_t )((StartY + pBmp [ 1 ] - 1) >> 3));
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].EndCol      = ( uint8_t )(StartX + pBmp [ 0 ] - 1);
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].CurrentPage = TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].StartPage;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].CurrentCol  = TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].StartCol;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].Width       = pBmp [ 0 ];
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].Length      = (pBmp [ 1 ] >> 3) * pBmp [ 0 ];
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].Offset      = 0;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].Type        = Type;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].BitShiftT   = (( uint8_t )(StartY & 0x0007));
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].pBmp        = pBmp + 2;

    if ( TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].BitShiftT == 0 )
    {
        TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].Mode  = TFT_LCD_MODE_DTBMP;
        TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].State = TFT_LCD_STATE_DRAW;
    }
    else
    {
        TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].Mode  = TFT_LCD_MODE_ITBMP;
        TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].State = TFT_LCD_STATE_TOP;
    }

    // FIFO����
    TFTLCDDrawingFIFO.Depth++;
    TFTLCDDrawingFIFO.Iptr++;

    if ( TFTLCDDrawingFIFO.Iptr >= TFT_LCD_REQ_FIFO_MAX_DEPTH )
        TFTLCDDrawingFIFO.Iptr = 0;
}

void TFT_LCD_Draw_Pixel(uint16_t PosX, uint16_t PosY, uint8_t Type)
{
    if ( TFTLCDDrawingFIFO.Depth >= TFT_LCD_REQ_FIFO_MAX_DEPTH )
        return;

    if ( (PosX >= TFT_LCD_X_SIZE) || (PosY >= TFT_LCD_Y_SIZE) )
        return;

    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].Mode        = TFT_LCD_MODE_PIXEL;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].State       = TFT_LCD_STATE_DRAW;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].StartPage   = (( uint8_t )(PosY >> 3));
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].StartCol    = ( uint8_t )PosX;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].EndPage     = TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].StartPage;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].EndCol      = TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].StartCol;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].CurrentPage = TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].StartPage;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].CurrentCol  = TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].StartCol;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].Type        = Type;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].BitShiftT   = (( uint8_t )(PosY & 0x0007));
    // FIFO����
    TFTLCDDrawingFIFO.Depth++;
    TFTLCDDrawingFIFO.Iptr++;

    if ( TFTLCDDrawingFIFO.Iptr >= TFT_LCD_REQ_FIFO_MAX_DEPTH )
        TFTLCDDrawingFIFO.Iptr = 0;
}

void TFT_LCD_Draw_Horizontal_Line(uint16_t StartX, uint16_t EndX, uint16_t PosY, uint8_t Type)
{
    if ( TFTLCDDrawingFIFO.Depth >= TFT_LCD_REQ_FIFO_MAX_DEPTH )
        return;

    if ( (StartX >= TFT_LCD_X_SIZE) || (EndX >= TFT_LCD_X_SIZE) || (PosY >= TFT_LCD_Y_SIZE) )
        return;

    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].Mode        = TFT_LCD_MODE_HLINE;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].State       = TFT_LCD_STATE_DRAW;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].StartPage   = (( uint8_t )(PosY >> 3));
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].StartCol    = ( uint8_t )StartX;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].EndPage     = TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].StartPage;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].EndCol      = ( uint8_t )EndX;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].CurrentPage = TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].StartPage;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].CurrentCol  = TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].StartCol;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].Type        = Type;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].BitShiftT   = (( uint8_t )(PosY & 0x0007));
    // FIFO����
    TFTLCDDrawingFIFO.Depth++;
    TFTLCDDrawingFIFO.Iptr++;

    if ( TFTLCDDrawingFIFO.Iptr >= TFT_LCD_REQ_FIFO_MAX_DEPTH )
        TFTLCDDrawingFIFO.Iptr = 0;
}

void TFT_LCD_Draw_Vertical_Line(uint16_t PosX, uint16_t StartY, uint16_t EndY, uint8_t Type)
{
    if ( TFTLCDDrawingFIFO.Depth >= TFT_LCD_REQ_FIFO_MAX_DEPTH )
        return;

    if ( (PosX >= TFT_LCD_X_SIZE) || (StartY >= TFT_LCD_Y_SIZE) || (EndY >= TFT_LCD_Y_SIZE) )
        return;

    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].Mode        = TFT_LCD_MODE_VLINE;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].StartPage   = (( uint8_t )(StartY >> 3));
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].StartCol    = ( uint8_t )PosX;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].EndPage     = (( uint8_t )(EndY >> 3));
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].EndCol      = ( uint8_t )PosX;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].CurrentPage = TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].StartPage;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].CurrentCol  = TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].StartCol;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].Type        = Type;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].BitShiftT   = (( uint8_t )(StartY & 0x0007));
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].BitShiftB   = (( uint8_t )(EndY & 0x0007));

    if ( TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].EndPage > TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].StartPage + 1 )
        TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].State = TFT_LCD_STATE_DRAW;
    else
        TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].State = TFT_LCD_STATE_VERTEX;

    // FIFO����
    TFTLCDDrawingFIFO.Depth++;
    TFTLCDDrawingFIFO.Iptr++;

    if ( TFTLCDDrawingFIFO.Iptr >= TFT_LCD_REQ_FIFO_MAX_DEPTH )
        TFTLCDDrawingFIFO.Iptr = 0;
}

void TFT_LCD_Draw_Box(uint16_t StartX, uint16_t StartY, uint16_t EndX, uint16_t EndY, uint8_t Fill, uint8_t Type)
{
    if ( TFTLCDDrawingFIFO.Depth >= TFT_LCD_REQ_FIFO_MAX_DEPTH )
        return;

    if ( (StartX >= TFT_LCD_X_SIZE) || (EndX >= TFT_LCD_X_SIZE) || (StartY >= TFT_LCD_Y_SIZE) || (EndY >= TFT_LCD_Y_SIZE) )
        return;

    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].StartPage   = (( uint8_t )(StartY >> 3));
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].StartCol    = ( uint8_t )StartX;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].EndPage     = (( uint8_t )(EndY >> 3));
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].EndCol      = ( uint8_t )EndX;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].CurrentPage = TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].StartPage;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].CurrentCol  = TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].StartCol;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].Width       = EndX - StartX + 1;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].Length      = (((EndY - StartY) >> 3) + 1) * TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].Width;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].Offset      = 0;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].Type        = Type;
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].BitShiftT   = (( uint8_t )(StartY & 0x0007));
    TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].BitShiftB   = (( uint8_t )(EndY & 0x0007));

    if ( Fill )
    {
        if ( (TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].BitShiftT == 0x00) && (TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].BitShiftB == 0x07) )
        {
            TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].Mode  = TFT_LCD_MODE_DFBOX;
            TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].State = TFT_LCD_STATE_INIT;
        }
        else
        {
            TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].Mode  = TFT_LCD_MODE_IFBOX;
            TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].State = TFT_LCD_STATE_TOP;
        }
    }
    else
    {
        TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].Mode = TFT_LCD_MODE_BBOX;

        if ( TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].EndCol > TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].StartCol + 1 )
            TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].State = TFT_LCD_STATE_TOP;
        else
        {
            if ( TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].EndPage > TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].StartPage + 1 )
                TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].State = TFT_LCD_STATE_LEFT;
            else
                TFTLCDDrawingFIFO.Req [ TFTLCDDrawingFIFO.Iptr ].State = TFT_LCD_STATE_VERTEX;
        }
    }

    // FIFO����
    TFTLCDDrawingFIFO.Depth++;
    TFTLCDDrawingFIFO.Iptr++;

    if ( TFTLCDDrawingFIFO.Iptr >= TFT_LCD_REQ_FIFO_MAX_DEPTH )
        TFTLCDDrawingFIFO.Iptr = 0;
}

static uint8_t TFT_LCD_Cls_Handler(TFTLCDDrawingReqStruct *pReq)
{
    uint8_t i;
    uint8_t Rtn;
    Rtn = 0;

    switch ( pReq->State )
    {
        case TFT_LCD_STATE_INIT:
            LCD_Set_Window(pReq->StartCol, pReq->StartPage, pReq->EndCol, pReq->EndPage);
            LCD_Start_Data_Writing( );
            pReq->State = TFT_LCD_STATE_DRAW;
            break;

        case TFT_LCD_STATE_DRAW:
            for ( i = 0; i < 30; i++ )
                LCD_Write_Data(0x00);

            pReq->Offset += 30;

            if ( pReq->Offset >= pReq->Length )
            {
                pReq->State = TFT_LCD_STATE_IDLE;
                Rtn         = 1;
            }

            break;

        default:
            pReq->State = TFT_LCD_STATE_IDLE;
            Rtn         = 1;
            break;
    }

    return Rtn;
}

static uint8_t TFT_LCD_Direct_Draw_Bmp_Handler(TFTLCDDrawingReqStruct *pReq)
{
    uint8_t i;
    uint8_t Rtn;
    uint8_t ColInc;
    Rtn = 0;

    switch ( pReq->State )
    {
        case TFT_LCD_STATE_INIT:
            LCD_Set_Window(pReq->StartCol, pReq->StartPage, pReq->EndCol, pReq->EndPage);
            LCD_Start_Data_Writing( );
            pReq->State = TFT_LCD_STATE_DRAW;
            break;

        case TFT_LCD_STATE_DRAW:
            if ( pReq->Length - pReq->Offset > 30 )
                ColInc = 30;
            else
                ColInc = ( uint8_t )(pReq->Length - pReq->Offset);

            for ( i = 0; i < ColInc; i++ )
            {
                LCD_Write_Data(pReq->pBmp [ pReq->Offset ]);
                pReq->Offset++;
            }

            if ( pReq->Offset >= pReq->Length )
            {
                pReq->State = TFT_LCD_STATE_IDLE;
                Rtn         = 1;
            }

            break;

        default:
            pReq->State = TFT_LCD_STATE_IDLE;
            Rtn         = 1;
            break;
    }

    return Rtn;
}

static uint8_t TFT_LCD_Insert_Draw_Bmp_Handler(TFTLCDDrawingReqStruct *pReq)
{
    uint8_t  i;
    uint8_t  Rtn;
    uint8_t  BmpDat [ 50 ];
    uint8_t  ColInc;
    uint8_t  ShiftL;
    uint8_t  ShiftR;
    uint8_t  Mask;
    uint16_t IndexH;
    uint16_t IndexL;
    Rtn = 0;

    switch ( pReq->State )
    {
        case TFT_LCD_STATE_TOP:    //��ҳͼƬ��Ҫ����ԭ����������ƴ��
            //��д��ͼƬ���ݵĵ�λȡ��ƴ����ԭ�������ݵĸ�λ
            ColInc = pReq->EndCol - pReq->CurrentCol + 1;

            if ( ColInc > 50 )
                ColInc = 50;

            ShiftL = pReq->BitShiftT;
            Mask   = TFTLCDBitMask [ pReq->BitShiftT ];
            //����ԭ��������
            LCD_Set_Window(pReq->CurrentCol, pReq->CurrentPage, pReq->EndCol, pReq->EndPage);
            LCD_Start_Data_Reading( );
            BmpDat [ 0 ] = LCD_Read_Data( );    //�����ĵ�һ���ֽ�Ϊ��Ч����,����

            for ( i = 0; i < ColInc; i++ )
                BmpDat [ i ] = LCD_Read_Data( ) & Mask;

            //ƴ�Ӳ���д����
            LCD_Set_Window(pReq->CurrentCol, pReq->CurrentPage, pReq->EndCol, pReq->EndPage);
            LCD_Start_Data_Writing( );

            for ( i = 0; i < ColInc; i++ )
            {
                IndexH = pReq->Offset + ( uint16_t )i;
                BmpDat [ i ] |= pReq->pBmp [ IndexH ] << ShiftL;
                LCD_Write_Data(BmpDat [ i ]);
            }

            pReq->Offset += ColInc;
            pReq->CurrentCol += ColInc;

            if ( pReq->CurrentCol > pReq->EndCol )
            {
                pReq->CurrentCol = pReq->StartCol;
                pReq->CurrentPage++;

                if ( pReq->CurrentPage >= pReq->EndPage )
                    pReq->State = TFT_LCD_STATE_BOT;
                else
                {
                    //��ҳ���ݿ�������д��
                    LCD_Set_Window(pReq->CurrentCol, pReq->CurrentPage, pReq->EndCol, pReq->EndPage);
                    LCD_Start_Data_Writing( );
                    pReq->State = TFT_LCD_STATE_MID;
                }
            }

            break;

        case TFT_LCD_STATE_MID:    //��ҳͼƬ�������ԭ��������
            //ֻ��Ҫ��д��ͼƬ��������ƴ��д�����ϼ���
            ColInc = pReq->EndCol - pReq->CurrentCol + 1;

            if ( ColInc > 50 )
                ColInc = 50;

            ShiftL = pReq->BitShiftT;
            ShiftR = 8 - pReq->BitShiftT;

            for ( i = 0; i < ColInc; i++ )
            {
                IndexH       = pReq->Offset + ( uint16_t )i;
                IndexL       = IndexH - pReq->Width;
                BmpDat [ 0 ] = pReq->pBmp [ IndexH ] << ShiftL;
                BmpDat [ 0 ] |= pReq->pBmp [ IndexL ] >> ShiftR;
                LCD_Write_Data(BmpDat [ 0 ]);
            }

            pReq->Offset += ColInc;
            pReq->CurrentCol += ColInc;

            if ( pReq->CurrentCol > pReq->EndCol )
            {
                pReq->CurrentCol = pReq->StartCol;
                pReq->CurrentPage++;

                if ( pReq->CurrentPage >= pReq->EndPage )
                    pReq->State = TFT_LCD_STATE_BOT;
            }

            break;

        case TFT_LCD_STATE_BOT:    //βҳͼƬ��Ҫ����ԭ����������ƴ��
            //��д��ͼƬ���ݵĵ�λȡ��ƴ����ԭ�������ݵĸ�λ
            ColInc = pReq->EndCol - pReq->CurrentCol + 1;

            if ( ColInc > 50 )
                ColInc = 50;

            ShiftR = 8 - pReq->BitShiftT;
            Mask   = ~TFTLCDBitMask [ pReq->BitShiftT ];
            //����ԭ��������
            LCD_Set_Window(pReq->CurrentCol, pReq->CurrentPage, pReq->EndCol, pReq->EndPage);
            LCD_Start_Data_Reading( );
            BmpDat [ 0 ] = LCD_Read_Data( );    //�����ĵ�һ���ֽ�Ϊ��Ч����,����

            for ( i = 0; i < ColInc; i++ )
                BmpDat [ i ] = LCD_Read_Data( ) & Mask;

            //ƴ�Ӳ���д����
            LCD_Set_Window(pReq->CurrentCol, pReq->CurrentPage, pReq->EndCol, pReq->EndPage);
            LCD_Start_Data_Writing( );

            for ( i = 0; i < ColInc; i++ )
            {
                IndexL = pReq->Offset - pReq->Width + ( uint16_t )i;
                BmpDat [ i ] |= pReq->pBmp [ IndexL ] >> ShiftR;
                LCD_Write_Data(BmpDat [ i ]);
            }

            pReq->Offset += ColInc;
            pReq->CurrentCol += ColInc;

            if ( pReq->CurrentCol > pReq->EndCol )
            {
                pReq->CurrentCol = pReq->StartCol;
                pReq->CurrentPage++;

                if ( pReq->CurrentPage > pReq->EndPage )
                {
                    pReq->State = TFT_LCD_STATE_IDLE;
                    Rtn         = 1;
                }
            }

            break;

        default:
            pReq->State = TFT_LCD_STATE_IDLE;
            Rtn         = 1;
            break;
    }

    return Rtn;
}

static uint8_t TFT_LCD_Insert_Draw_Traffic_Bmp_Handler(TFTLCDDrawingReqStruct *pReq)
{

    uint8_t  i;
    uint8_t  Rtn;
    uint8_t  BmpDat [ 10 ];
    uint8_t  ColInc;
    uint8_t  ShiftL;
    uint8_t  ShiftR;
    uint8_t  Mask;
    uint16_t IndexH;
    uint16_t IndexL;
    Rtn = 0;
    while ( Rtn != 0 )
    {
        //   wdt_reset();
        switch ( pReq->State )
        {
            case TFT_LCD_STATE_TOP:    //��ҳͼƬ��Ҫ����ԭ����������ƴ��
                //��д��ͼƬ���ݵĵ�λȡ��ƴ����ԭ�������ݵĸ�λ
                ColInc = pReq->EndCol - pReq->CurrentCol + 1;

                if ( ColInc > 10 )
                    ColInc = 10;

                ShiftL = pReq->BitShiftT;
                Mask   = TFTLCDBitMask [ pReq->BitShiftT ];
                //����ԭ��������
                LCD_Set_Window(pReq->CurrentCol, pReq->CurrentPage, pReq->EndCol, pReq->EndPage);
                LCD_Start_Data_Reading( );
                BmpDat [ 0 ] = LCD_Read_Data( );    //�����ĵ�һ���ֽ�Ϊ��Ч����,����

                for ( i = 0; i < ColInc; i++ )
                    BmpDat [ i ] = LCD_Read_Data( ) & Mask;

                //ƴ�Ӳ���д����
                LCD_Set_Window(pReq->CurrentCol, pReq->CurrentPage, pReq->EndCol, pReq->EndPage);
                LCD_Start_Data_Writing( );

                for ( i = 0; i < ColInc; i++ )
                {
                    IndexH = pReq->Offset + ( uint16_t )i;
                    BmpDat [ i ] |= pReq->pBmp [ IndexH ] << ShiftL;
                    LCD_Write_Data(BmpDat [ i ]);
                }

                pReq->Offset += ColInc;
                pReq->CurrentCol += ColInc;

                if ( pReq->CurrentCol > pReq->EndCol )
                {
                    pReq->CurrentCol = pReq->StartCol;
                    pReq->CurrentPage++;

                    if ( pReq->CurrentPage >= pReq->EndPage )
                        pReq->State = TFT_LCD_STATE_BOT;
                    else
                    {
                        //��ҳ���ݿ�������д��
                        LCD_Set_Window(pReq->CurrentCol, pReq->CurrentPage, pReq->EndCol, pReq->EndPage);
                        LCD_Start_Data_Writing( );
                        pReq->State = TFT_LCD_STATE_MID;
                    }
                }

                break;

            case TFT_LCD_STATE_MID:    //��ҳͼƬ�������ԭ��������
                //ֻ��Ҫ��д��ͼƬ��������ƴ��д�����ϼ���
                ColInc = pReq->EndCol - pReq->CurrentCol + 1;

                if ( ColInc > 10 )
                    ColInc = 10;

                ShiftL = pReq->BitShiftT;
                ShiftR = 8 - pReq->BitShiftT;

                for ( i = 0; i < ColInc; i++ )
                {
                    IndexH       = pReq->Offset + ( uint16_t )i;
                    IndexL       = IndexH - pReq->Width;
                    BmpDat [ 0 ] = pReq->pBmp [ IndexH ] << ShiftL;
                    BmpDat [ 0 ] |= pReq->pBmp [ IndexL ] >> ShiftR;
                    LCD_Write_Data(BmpDat [ 0 ]);
                }

                pReq->Offset += ColInc;
                pReq->CurrentCol += ColInc;

                if ( pReq->CurrentCol > pReq->EndCol )
                {
                    pReq->CurrentCol = pReq->StartCol;
                    pReq->CurrentPage++;

                    if ( pReq->CurrentPage >= pReq->EndPage )
                        pReq->State = TFT_LCD_STATE_BOT;
                }

                break;

            case TFT_LCD_STATE_BOT:    //βҳͼƬ��Ҫ����ԭ����������ƴ��
                //��д��ͼƬ���ݵĵ�λȡ��ƴ����ԭ�������ݵĸ�λ
                ColInc = pReq->EndCol - pReq->CurrentCol + 1;

                if ( ColInc > 10 )
                    ColInc = 10;

                ShiftR = 8 - pReq->BitShiftT;
                Mask   = ~TFTLCDBitMask [ pReq->BitShiftT ];
                //����ԭ��������
                LCD_Set_Window(pReq->CurrentCol, pReq->CurrentPage, pReq->EndCol, pReq->EndPage);
                LCD_Start_Data_Reading( );
                BmpDat [ 0 ] = LCD_Read_Data( );    //�����ĵ�һ���ֽ�Ϊ��Ч����,����

                for ( i = 0; i < ColInc; i++ )
                    BmpDat [ i ] = LCD_Read_Data( ) & Mask;

                //ƴ�Ӳ���д����
                LCD_Set_Window(pReq->CurrentCol, pReq->CurrentPage, pReq->EndCol, pReq->EndPage);
                LCD_Start_Data_Writing( );

                for ( i = 0; i < ColInc; i++ )
                {
                    IndexL = pReq->Offset - pReq->Width + ( uint16_t )i;
                    BmpDat [ i ] |= pReq->pBmp [ IndexL ] >> ShiftR;
                    LCD_Write_Data(BmpDat [ i ]);
                }

                pReq->Offset += ColInc;
                pReq->CurrentCol += ColInc;

                if ( pReq->CurrentCol > pReq->EndCol )
                {
                    pReq->CurrentCol = pReq->StartCol;
                    pReq->CurrentPage++;

                    if ( pReq->CurrentPage > pReq->EndPage )
                    {
                        pReq->State = TFT_LCD_STATE_IDLE;
                        Rtn         = 1;
                    }
                }

                break;

            default:
                pReq->State = TFT_LCD_STATE_IDLE;
                Rtn         = 1;
                break;
        }

        // return Rtn;
    }
}

static uint8_t TFT_LCD_Direct_Draw_Transparent_Bmp_Handler(TFTLCDDrawingReqStruct *pReq)
{
    uint8_t i;
    uint8_t Rtn;
    uint8_t BmpDat [ 10 ];
    uint8_t ColInc;

    if ( pReq->State != TFT_LCD_STATE_DRAW )
    {
        pReq->State = TFT_LCD_STATE_IDLE;
        return 1;
    }

    Rtn    = 0;
    ColInc = pReq->EndCol - pReq->CurrentCol + 1;

    if ( ColInc > 10 )
        ColInc = 10;

    //����ԭ��������
    LCD_Set_Window(pReq->CurrentCol, pReq->CurrentPage, pReq->EndCol, pReq->EndPage);
    LCD_Start_Data_Reading( );
    BmpDat [ 0 ] = LCD_Read_Data( );    //�����ĵ�һ���ֽ�Ϊ��Ч����,����

    for ( i = 0; i < ColInc; i++ )
        BmpDat [ i ] = LCD_Read_Data( );

    //ƴ�Ӳ���д����
    LCD_Set_Window(pReq->CurrentCol, pReq->CurrentPage, pReq->EndCol, pReq->EndPage);
    LCD_Start_Data_Writing( );

    if ( pReq->Type == TFT_LCD_TYPE_CLR )
    {
        for ( i = 0; i < ColInc; i++ )
        {
            BmpDat [ i ] &= ~(pReq->pBmp [ pReq->Offset ]);
            LCD_Write_Data(BmpDat [ i ]);
            pReq->Offset++;
        }
    }
    else if ( pReq->Type == TFT_LCD_TYPE_INV )
    {
        for ( i = 0; i < ColInc; i++ )
        {
            BmpDat [ i ] ^= pReq->pBmp [ pReq->Offset ];
            LCD_Write_Data(BmpDat [ i ]);
            pReq->Offset++;
        }
    }
    else
    {
        for ( i = 0; i < ColInc; i++ )
        {
            BmpDat [ i ] |= pReq->pBmp [ pReq->Offset ];
            LCD_Write_Data(BmpDat [ i ]);
            pReq->Offset++;
        }
    }

    pReq->CurrentCol += ColInc;

    if ( pReq->CurrentCol > pReq->EndCol )
    {
        pReq->CurrentCol = pReq->StartCol;
        pReq->CurrentPage++;

        if ( pReq->CurrentPage > pReq->EndPage )
        {
            pReq->State = TFT_LCD_STATE_IDLE;
            Rtn         = 1;
        }
    }

    return Rtn;
}

static uint8_t TFT_LCD_Insert_Draw_Transparent_Bmp_Handler(TFTLCDDrawingReqStruct *pReq)
{
    uint8_t  i;
    uint8_t  Rtn;
    uint8_t  Mask;
    uint8_t  BmpDat [ 10 ];
    uint8_t  ColInc;
    uint8_t  ShiftL;
    uint8_t  ShiftR;
    uint16_t IndexH;
    uint16_t IndexL;
    Rtn    = 0;
    ColInc = pReq->EndCol - pReq->CurrentCol + 1;

    if ( ColInc > 10 )
        ColInc = 10;

    //����ԭ��������
    LCD_Set_Window(pReq->CurrentCol, pReq->CurrentPage, pReq->EndCol, pReq->EndPage);
    LCD_Start_Data_Reading( );
    BmpDat [ 0 ] = LCD_Read_Data( );    //�����ĵ�һ���ֽ�Ϊ��Ч����,����

    for ( i = 0; i < ColInc; i++ )
        BmpDat [ i ] = LCD_Read_Data( );

    //ƴ�Ӳ���д����
    LCD_Set_Window(pReq->CurrentCol, pReq->CurrentPage, pReq->EndCol, pReq->EndPage);
    LCD_Start_Data_Writing( );

    switch ( pReq->State )
    {
        case TFT_LCD_STATE_TOP:
            ShiftL = pReq->BitShiftT;

            if ( pReq->Type == TFT_LCD_TYPE_CLR )
            {
                for ( i = 0; i < ColInc; i++ )
                {
                    IndexH = pReq->Offset + ( uint16_t )i;
                    BmpDat [ i ] &= ~(pReq->pBmp [ IndexH ] << ShiftL);
                    LCD_Write_Data(BmpDat [ i ]);
                }
            }
            else if ( pReq->Type == TFT_LCD_TYPE_INV )
            {
                for ( i = 0; i < ColInc; i++ )
                {
                    IndexH = pReq->Offset + ( uint16_t )i;
                    BmpDat [ i ] ^= (pReq->pBmp [ IndexH ] << ShiftL);
                    LCD_Write_Data(BmpDat [ i ]);
                }
            }
            else
            {
                for ( i = 0; i < ColInc; i++ )
                {
                    IndexH = pReq->Offset + ( uint16_t )i;
                    BmpDat [ i ] |= pReq->pBmp [ IndexH ] << ShiftL;
                    LCD_Write_Data(BmpDat [ i ]);
                }
            }

            break;

        case TFT_LCD_STATE_MID:
            ShiftL = pReq->BitShiftT;
            ShiftR = (8 - pReq->BitShiftT) & 0x07;

            if ( pReq->Type == TFT_LCD_TYPE_CLR )
            {
                for ( i = 0; i < ColInc; i++ )
                {
                    IndexH = pReq->Offset + ( uint16_t )i;
                    IndexL = IndexH - pReq->Width;
                    Mask   = pReq->pBmp [ IndexH ] << ShiftL | pReq->pBmp [ IndexL ] >> ShiftR;
                    BmpDat [ i ] &= ~Mask;
                    LCD_Write_Data(BmpDat [ i ]);
                }
            }
            else if ( pReq->Type == TFT_LCD_TYPE_INV )
            {
                for ( i = 0; i < ColInc; i++ )
                {
                    IndexH = pReq->Offset + ( uint16_t )i;
                    IndexL = IndexH - pReq->Width;
                    Mask   = pReq->pBmp [ IndexH ] << ShiftL | pReq->pBmp [ IndexL ] >> ShiftR;
                    BmpDat [ i ] ^= Mask;
                    LCD_Write_Data(BmpDat [ i ]);
                }
            }
            else
            {
                for ( i = 0; i < ColInc; i++ )
                {
                    IndexH = pReq->Offset + ( uint16_t )i;
                    IndexL = IndexH - pReq->Width;
                    Mask   = pReq->pBmp [ IndexH ] << ShiftL | pReq->pBmp [ IndexL ] >> ShiftR;
                    BmpDat [ i ] |= Mask;
                    LCD_Write_Data(BmpDat [ i ]);
                }
            }

            break;

        case TFT_LCD_STATE_BOT:
            ShiftR = (8 - pReq->BitShiftT) & 0x07;

            if ( pReq->Type == TFT_LCD_TYPE_CLR )
            {
                for ( i = 0; i < ColInc; i++ )
                {
                    IndexL = pReq->Offset - pReq->Width + ( uint16_t )i;
                    BmpDat [ i ] &= ~(pReq->pBmp [ IndexL ] >> ShiftR);
                    LCD_Write_Data(BmpDat [ i ]);
                }
            }
            else if ( pReq->Type == TFT_LCD_TYPE_INV )
            {
                for ( i = 0; i < ColInc; i++ )
                {
                    IndexL = pReq->Offset - pReq->Width + ( uint16_t )i;
                    BmpDat [ i ] ^= pReq->pBmp [ IndexL ] >> ShiftR;
                    LCD_Write_Data(BmpDat [ i ]);
                }
            }
            else
            {
                for ( i = 0; i < ColInc; i++ )
                {
                    IndexL = pReq->Offset - pReq->Width + ( uint16_t )i;
                    BmpDat [ i ] |= pReq->pBmp [ IndexL ] >> ShiftR;
                    LCD_Write_Data(BmpDat [ i ]);
                }
            }

            break;

        default:
            pReq->State = TFT_LCD_STATE_IDLE;
            return 1;
            break;
    }

    pReq->Offset += ColInc;
    pReq->CurrentCol += ColInc;

    if ( pReq->CurrentCol > pReq->EndCol )
    {
        pReq->CurrentCol = pReq->StartCol;
        pReq->CurrentPage++;

        if ( pReq->CurrentPage < pReq->EndPage )
            pReq->State = TFT_LCD_STATE_MID;
        else if ( pReq->CurrentPage == pReq->EndPage )
            pReq->State = TFT_LCD_STATE_BOT;
        else
        {
            pReq->State = TFT_LCD_STATE_IDLE;
            return 1;
        }
    }

    return Rtn;
}

static uint8_t TFT_LCD_Draw_Pixel_Handler(TFTLCDDrawingReqStruct *pReq)
{
    uint8_t DispData;

    if ( pReq->State == TFT_LCD_STATE_DRAW )
    {
        //����ԭ��������
        LCD_Set_Window(pReq->StartCol, pReq->StartPage, pReq->EndCol, pReq->EndPage);
        LCD_Start_Data_Reading( );
        DispData = LCD_Read_Data( );    //�����ĵ�һ���ֽ�Ϊ��Ч����,����
        DispData = LCD_Read_Data( );

        if ( pReq->Type == TFT_LCD_TYPE_CLR )
            DispData &= ~TFTLCDBitTable [ pReq->BitShiftT ];
        else if ( pReq->Type == TFT_LCD_TYPE_INV )
            DispData ^= TFTLCDBitTable [ pReq->BitShiftT ];
        else
            DispData |= TFTLCDBitTable [ pReq->BitShiftT ];

        //��д����
        LCD_Set_Window(pReq->StartCol, pReq->StartPage, pReq->EndCol, pReq->EndPage);
        LCD_Start_Data_Writing( );
        LCD_Write_Data(DispData);
    }

    pReq->State = TFT_LCD_STATE_IDLE;
    return 1;
}

static uint8_t TFT_LCD_Draw_Horizontal_Line_Handler(TFTLCDDrawingReqStruct *pReq)
{
    uint8_t i;
    uint8_t ColInc;
    uint8_t Mask;
    uint8_t DispData [ 10 ];

    if ( pReq->State != TFT_LCD_STATE_DRAW )
    {
        pReq->State = TFT_LCD_STATE_IDLE;
        return 1;
    }

    Mask   = TFTLCDBitTable [ pReq->BitShiftT ];
    ColInc = pReq->EndCol - pReq->CurrentCol + 1;

    if ( ColInc > 10 )
        ColInc = 10;

    //����ԭ��������
    LCD_Set_Window(pReq->CurrentCol, pReq->StartPage, pReq->EndCol, pReq->StartPage);
    LCD_Start_Data_Reading( );
    DispData [ 0 ] = LCD_Read_Data( );    //�����ĵ�һ���ֽ�Ϊ��Ч����,����

    for ( i = 0; i < ColInc; i++ )
        DispData [ i ] = LCD_Read_Data( );

    //������д����
    LCD_Set_Window(pReq->CurrentCol, pReq->StartPage, pReq->EndCol, pReq->StartPage);
    LCD_Start_Data_Writing( );

    if ( pReq->Type == TFT_LCD_TYPE_CLR )
    {
        for ( i = 0; i < ColInc; i++ )
        {
            DispData [ i ] &= ~Mask;
            LCD_Write_Data(DispData [ i ]);
        }
    }
    else if ( pReq->Type == TFT_LCD_TYPE_INV )
    {
        for ( i = 0; i < ColInc; i++ )
        {
            DispData [ i ] ^= Mask;
            LCD_Write_Data(DispData [ i ]);
        }
    }
    else
    {
        for ( i = 0; i < ColInc; i++ )
        {
            DispData [ i ] |= Mask;
            LCD_Write_Data(DispData [ i ]);
        }
    }

    pReq->CurrentCol += ColInc;

    if ( pReq->CurrentCol > pReq->EndCol )
    {
        pReq->State = TFT_LCD_STATE_IDLE;
        return 1;
    }

    return 0;
}

static uint8_t TFT_LCD_Draw_Vertical_Line_Handler(TFTLCDDrawingReqStruct *pReq)
{
    uint8_t i;
    uint8_t Rtn;
    uint8_t PageInc;
    uint8_t Mask;
    uint8_t DispData [ 10 ];
    Rtn = 0;

    switch ( pReq->State )
    {
        case TFT_LCD_STATE_DRAW:
            pReq->CurrentPage += 1;
            PageInc = pReq->EndPage - pReq->CurrentPage;

            if ( pReq->Type == TFT_LCD_TYPE_INV )
            {
                if ( PageInc > 10 )
                    PageInc = 10;

                //����ԭ��������
                LCD_Set_Window(pReq->StartCol, pReq->CurrentPage, pReq->StartCol, pReq->EndPage);
                LCD_Start_Data_Reading( );
                DispData [ 0 ] = LCD_Read_Data( );    //�����ĵ�һ���ֽ�Ϊ��Ч����,����

                for ( i = 0; i < PageInc; i++ )
                    DispData [ i ] = LCD_Read_Data( );

                //������д����
                LCD_Set_Window(pReq->StartCol, pReq->CurrentPage, pReq->StartCol, pReq->EndPage);
                LCD_Start_Data_Writing( );

                for ( i = 0; i < PageInc; i++ )
                    LCD_Write_Data(~DispData [ i ]);
            }
            else
            {
                if ( PageInc > 30 )
                    PageInc = 30;

                LCD_Set_Window(pReq->StartCol, pReq->CurrentPage, pReq->StartCol, pReq->EndPage);
                LCD_Start_Data_Writing( );

                if ( pReq->Type == TFT_LCD_TYPE_CLR )
                {
                    for ( i = 0; i < PageInc; i++ )
                        LCD_Write_Data(0x00);
                }
                else
                {
                    for ( i = 0; i < PageInc; i++ )
                        LCD_Write_Data(0xFF);
                }
            }

            pReq->CurrentPage += PageInc;

            if ( pReq->CurrentPage >= pReq->EndPage )
                pReq->State = TFT_LCD_STATE_VERTEX;

            break;

        case TFT_LCD_STATE_VERTEX:
            if ( pReq->StartPage == pReq->EndPage )
                Mask = ~TFTLCDBitMask [ pReq->BitShiftT ] & TFTLCDBitMask [ pReq->BitShiftB + 1 ];
            else
                Mask = ~TFTLCDBitMask [ pReq->BitShiftT ];

            LCD_Set_Window(pReq->StartCol, pReq->StartPage, pReq->StartCol, pReq->StartPage);
            LCD_Start_Data_Reading( );
            DispData [ 0 ] = LCD_Read_Data( );    //�����ĵ�һ���ֽ�Ϊ��Ч����,����
            DispData [ 0 ] = LCD_Read_Data( );
            //������д����
            LCD_Set_Window(pReq->StartCol, pReq->StartPage, pReq->StartCol, pReq->StartPage);
            LCD_Start_Data_Writing( );

            if ( pReq->Type == TFT_LCD_TYPE_INV )
                LCD_Write_Data(DispData [ 0 ] ^ Mask);
            else if ( pReq->Type == TFT_LCD_TYPE_CLR )
                LCD_Write_Data(DispData [ 0 ] & ~Mask);
            else
                LCD_Write_Data(DispData [ 0 ] | Mask);

            if ( pReq->StartPage != pReq->EndPage )
            {
                Mask = TFTLCDBitMask [ pReq->BitShiftB + 1 ];
                LCD_Set_Window(pReq->StartCol, pReq->EndPage, pReq->StartCol, pReq->EndPage);
                LCD_Start_Data_Reading( );
                DispData [ 0 ] = LCD_Read_Data( );    //�����ĵ�һ���ֽ�Ϊ��Ч����,����
                DispData [ 0 ] = LCD_Read_Data( );
                //������д����
                LCD_Set_Window(pReq->StartCol, pReq->EndPage, pReq->StartCol, pReq->EndPage);
                LCD_Start_Data_Writing( );

                if ( pReq->Type == TFT_LCD_TYPE_INV )
                    LCD_Write_Data(DispData [ 0 ] ^ Mask);
                else if ( pReq->Type == TFT_LCD_TYPE_CLR )
                    LCD_Write_Data(DispData [ 0 ] & ~Mask);
                else
                    LCD_Write_Data(DispData [ 0 ] | Mask);
            }

            pReq->State = TFT_LCD_STATE_IDLE;
            Rtn         = 1;
            break;

        default:
            pReq->State = TFT_LCD_STATE_IDLE;
            Rtn         = 1;
            break;
    }

    return Rtn;
}

static uint8_t TFT_LCD_Draw_Box_Border_Handler(TFTLCDDrawingReqStruct *pReq)
{
    uint8_t i;
    uint8_t Rtn;
    uint8_t Inc;
    uint8_t Mask;
    uint8_t DispData [ 10 ];
    Rtn = 0;

    switch ( pReq->State )
    {
        case TFT_LCD_STATE_TOP:
            if ( pReq->StartPage == pReq->EndPage )
                Mask = TFTLCDBitTable [ pReq->BitShiftT ] | TFTLCDBitTable [ pReq->BitShiftB ];
            else
                Mask = TFTLCDBitTable [ pReq->BitShiftT ];

            //��ˮƽ��ʱ�������Ҷ���,���Ҷ���������
            pReq->CurrentCol += 1;
            Inc = pReq->EndCol - pReq->CurrentCol;

            if ( Inc > 10 )
                Inc = 10;

            //����ԭ��������
            LCD_Set_Window(pReq->CurrentCol, pReq->StartPage, pReq->EndCol, pReq->StartPage);
            LCD_Start_Data_Reading( );
            DispData [ 0 ] = LCD_Read_Data( );    //�����ĵ�һ���ֽ�Ϊ��Ч����,����

            for ( i = 0; i < Inc; i++ )
                DispData [ i ] = LCD_Read_Data( );

            //������д����
            LCD_Set_Window(pReq->CurrentCol, pReq->StartPage, pReq->EndCol, pReq->StartPage);
            LCD_Start_Data_Writing( );

            if ( pReq->Type == TFT_LCD_TYPE_CLR )
            {
                for ( i = 0; i < Inc; i++ )
                {
                    DispData [ i ] &= ~Mask;
                    LCD_Write_Data(DispData [ i ]);
                }
            }
            else if ( pReq->Type == TFT_LCD_TYPE_INV )
            {
                for ( i = 0; i < Inc; i++ )
                {
                    DispData [ i ] ^= Mask;
                    LCD_Write_Data(DispData [ i ]);
                }
            }
            else
            {
                for ( i = 0; i < Inc; i++ )
                {
                    DispData [ i ] |= Mask;
                    LCD_Write_Data(DispData [ i ]);
                }
            }

            pReq->CurrentCol += Inc;

            if ( pReq->CurrentCol >= pReq->EndCol )
            {
                if ( pReq->StartPage == pReq->EndPage )
                {
                    if ( pReq->EndPage > pReq->StartPage + 1 )
                        pReq->State = TFT_LCD_STATE_LEFT;
                    else
                        pReq->State = TFT_LCD_STATE_VERTEX;
                }
                else
                {
                    pReq->CurrentCol = pReq->StartCol + 1;
                    pReq->State      = TFT_LCD_STATE_BOT;
                }
            }

            break;

        case TFT_LCD_STATE_BOT:
            Mask = TFTLCDBitTable [ pReq->BitShiftB ];
            Inc  = pReq->EndCol - pReq->CurrentCol;

            if ( Inc > 10 )
                Inc = 10;

            //����ԭ��������
            LCD_Set_Window(pReq->CurrentCol, pReq->EndPage, pReq->EndCol, pReq->EndPage);
            LCD_Start_Data_Reading( );
            DispData [ 0 ] = LCD_Read_Data( );    //�����ĵ�һ���ֽ�Ϊ��Ч����,����

            for ( i = 0; i < Inc; i++ )
                DispData [ i ] = LCD_Read_Data( );

            //������д����
            LCD_Set_Window(pReq->CurrentCol, pReq->EndPage, pReq->EndCol, pReq->EndPage);
            LCD_Start_Data_Writing( );

            if ( pReq->Type == TFT_LCD_TYPE_CLR )
            {
                for ( i = 0; i < Inc; i++ )
                {
                    DispData [ i ] &= ~Mask;
                    LCD_Write_Data(DispData [ i ]);
                }
            }
            else if ( pReq->Type == TFT_LCD_TYPE_INV )
            {
                for ( i = 0; i < Inc; i++ )
                {
                    DispData [ i ] ^= Mask;
                    LCD_Write_Data(DispData [ i ]);
                }
            }
            else
            {
                for ( i = 0; i < Inc; i++ )
                {
                    DispData [ i ] |= Mask;
                    LCD_Write_Data(DispData [ i ]);
                }
            }

            pReq->CurrentCol += Inc;

            if ( pReq->CurrentCol >= pReq->EndCol )
            {
                if ( pReq->EndPage > pReq->StartPage + 1 )
                    pReq->State = TFT_LCD_STATE_LEFT;
                else
                    pReq->State = TFT_LCD_STATE_VERTEX;
            }

            break;

        case TFT_LCD_STATE_LEFT:    //����ֱ��ʱ�������¶���,���¶���������
            pReq->CurrentPage += 1;
            Inc = pReq->EndPage - pReq->CurrentPage;

            if ( pReq->Type == TFT_LCD_TYPE_INV )
            {
                if ( Inc > 10 )
                    Inc = 10;

                //����ԭ��������
                LCD_Set_Window(pReq->StartCol, pReq->CurrentPage, pReq->StartCol, pReq->EndPage);
                LCD_Start_Data_Reading( );
                DispData [ 0 ] = LCD_Read_Data( );    //�����ĵ�һ���ֽ�Ϊ��Ч����,����

                for ( i = 0; i < Inc; i++ )
                    DispData [ i ] = LCD_Read_Data( );

                //������д����
                LCD_Set_Window(pReq->StartCol, pReq->CurrentPage, pReq->StartCol, pReq->EndPage);
                LCD_Start_Data_Writing( );

                for ( i = 0; i < Inc; i++ )
                    LCD_Write_Data(~DispData [ i ]);
            }
            else
            {
                if ( Inc > 30 )
                    Inc = 30;

                LCD_Set_Window(pReq->StartCol, pReq->CurrentPage, pReq->StartCol, pReq->EndPage);
                LCD_Start_Data_Writing( );

                if ( pReq->Type == TFT_LCD_TYPE_CLR )
                {
                    for ( i = 0; i < Inc; i++ )
                        LCD_Write_Data(0x00);
                }
                else
                {
                    for ( i = 0; i < Inc; i++ )
                        LCD_Write_Data(0xFF);
                }
            }

            pReq->CurrentPage += Inc;

            if ( pReq->CurrentPage >= pReq->EndPage )
            {
                if ( pReq->StartCol == pReq->EndCol )
                    pReq->State = TFT_LCD_STATE_VERTEX;
                else
                {
                    pReq->CurrentPage = pReq->StartPage + 1;
                    pReq->State       = TFT_LCD_STATE_RIGHT;
                }
            }

            break;

        case TFT_LCD_STATE_RIGHT:    //����ֱ��ʱ�������¶���,���¶���������
            Inc = pReq->EndPage - pReq->CurrentPage;

            if ( pReq->Type == TFT_LCD_TYPE_INV )
            {
                if ( Inc > 10 )
                    Inc = 10;

                //����ԭ��������
                LCD_Set_Window(pReq->EndCol, pReq->CurrentPage, pReq->EndCol, pReq->EndPage);
                LCD_Start_Data_Reading( );
                DispData [ 0 ] = LCD_Read_Data( );    //�����ĵ�һ���ֽ�Ϊ��Ч����,����

                for ( i = 0; i < Inc; i++ )
                    DispData [ i ] = LCD_Read_Data( );

                //������д����
                LCD_Set_Window(pReq->EndCol, pReq->CurrentPage, pReq->EndCol, pReq->EndPage);
                LCD_Start_Data_Writing( );

                for ( i = 0; i < Inc; i++ )
                    LCD_Write_Data(~DispData [ i ]);
            }
            else
            {
                if ( Inc > 30 )
                    Inc = 30;

                LCD_Set_Window(pReq->EndCol, pReq->CurrentPage, pReq->EndCol, pReq->EndPage);
                LCD_Start_Data_Writing( );

                if ( pReq->Type == TFT_LCD_TYPE_CLR )
                {
                    for ( i = 0; i < Inc; i++ )
                        LCD_Write_Data(0x00);
                }
                else
                {
                    for ( i = 0; i < Inc; i++ )
                        LCD_Write_Data(0xFF);
                }
            }

            pReq->CurrentPage += Inc;

            if ( pReq->CurrentPage >= pReq->EndPage )
                pReq->State = TFT_LCD_STATE_VERTEX;

            break;

        case TFT_LCD_STATE_VERTEX:
            if ( pReq->StartPage == pReq->EndPage )
                Mask = ~TFTLCDBitMask [ pReq->BitShiftT ] & TFTLCDBitMask [ pReq->BitShiftB + 1 ];
            else
                Mask = ~TFTLCDBitMask [ pReq->BitShiftT ];

            LCD_Set_Window(pReq->StartCol, pReq->StartPage, pReq->StartCol, pReq->StartPage);
            LCD_Start_Data_Reading( );
            DispData [ 0 ] = LCD_Read_Data( );    //�����ĵ�һ���ֽ�Ϊ��Ч����,����
            DispData [ 0 ] = LCD_Read_Data( );
            //������д����
            LCD_Set_Window(pReq->StartCol, pReq->StartPage, pReq->StartCol, pReq->StartPage);
            LCD_Start_Data_Writing( );

            if ( pReq->Type == TFT_LCD_TYPE_INV )
                LCD_Write_Data(DispData [ 0 ] ^ Mask);
            else if ( pReq->Type == TFT_LCD_TYPE_CLR )
                LCD_Write_Data(DispData [ 0 ] & ~Mask);
            else
                LCD_Write_Data(DispData [ 0 ] | Mask);

            if ( pReq->StartPage != pReq->EndPage )
            {
                Mask = TFTLCDBitMask [ pReq->BitShiftB + 1 ];
                LCD_Set_Window(pReq->StartCol, pReq->EndPage, pReq->StartCol, pReq->EndPage);
                LCD_Start_Data_Reading( );
                DispData [ 0 ] = LCD_Read_Data( );    //�����ĵ�һ���ֽ�Ϊ��Ч����,����
                DispData [ 0 ] = LCD_Read_Data( );
                //������д����
                LCD_Set_Window(pReq->StartCol, pReq->EndPage, pReq->StartCol, pReq->EndPage);
                LCD_Start_Data_Writing( );

                if ( pReq->Type == TFT_LCD_TYPE_INV )
                    LCD_Write_Data(DispData [ 0 ] ^ Mask);
                else if ( pReq->Type == TFT_LCD_TYPE_CLR )
                    LCD_Write_Data(DispData [ 0 ] & ~Mask);
                else
                    LCD_Write_Data(DispData [ 0 ] | Mask);
            }

            if ( pReq->StartCol != pReq->EndCol )
            {
                if ( pReq->StartPage == pReq->EndPage )
                    Mask = ~TFTLCDBitMask [ pReq->BitShiftT ] & TFTLCDBitMask [ pReq->BitShiftB + 1 ];
                else
                    Mask = ~TFTLCDBitMask [ pReq->BitShiftT ];

                LCD_Set_Window(pReq->EndCol, pReq->StartPage, pReq->EndCol, pReq->StartPage);
                LCD_Start_Data_Reading( );
                DispData [ 0 ] = LCD_Read_Data( );    //�����ĵ�һ���ֽ�Ϊ��Ч����,����
                DispData [ 0 ] = LCD_Read_Data( );
                //������д����
                LCD_Set_Window(pReq->EndCol, pReq->StartPage, pReq->EndCol, pReq->StartPage);
                LCD_Start_Data_Writing( );

                if ( pReq->Type == TFT_LCD_TYPE_INV )
                    LCD_Write_Data(DispData [ 0 ] ^ Mask);
                else if ( pReq->Type == TFT_LCD_TYPE_CLR )
                    LCD_Write_Data(DispData [ 0 ] & ~Mask);
                else
                    LCD_Write_Data(DispData [ 0 ] | Mask);

                if ( pReq->StartPage != pReq->EndPage )
                {
                    Mask = TFTLCDBitMask [ pReq->BitShiftB + 1 ];
                    LCD_Set_Window(pReq->EndCol, pReq->EndPage, pReq->EndCol, pReq->EndPage);
                    LCD_Start_Data_Reading( );
                    DispData [ 0 ] = LCD_Read_Data( );    //�����ĵ�һ���ֽ�Ϊ��Ч����,����
                    DispData [ 0 ] = LCD_Read_Data( );
                    //������д����
                    LCD_Set_Window(pReq->EndCol, pReq->EndPage, pReq->EndCol, pReq->EndPage);
                    LCD_Start_Data_Writing( );

                    if ( pReq->Type == TFT_LCD_TYPE_INV )
                        LCD_Write_Data(DispData [ 0 ] ^ Mask);
                    else if ( pReq->Type == TFT_LCD_TYPE_CLR )
                        LCD_Write_Data(DispData [ 0 ] & ~Mask);
                    else
                        LCD_Write_Data(DispData [ 0 ] | Mask);
                }
            }

            pReq->State = TFT_LCD_STATE_IDLE;
            Rtn         = 1;
            break;

        default:
            pReq->State = TFT_LCD_STATE_IDLE;
            Rtn         = 1;
            break;
    }

    return Rtn;
}

static uint8_t TFT_LCD_Direct_Draw_Full_Box_Handler(TFTLCDDrawingReqStruct *pReq)
{
    uint8_t i;
    uint8_t Rtn;
    uint8_t ColInc;
    uint8_t DispData [ 10 ];
    Rtn = 0;

    if ( pReq->Type == TFT_LCD_TYPE_INV )
    {
        switch ( pReq->State )
        {
            case TFT_LCD_STATE_INIT:
                pReq->State = TFT_LCD_STATE_DRAW;

            case TFT_LCD_STATE_DRAW:
                ColInc = pReq->EndCol - pReq->CurrentCol + 1;

                if ( ColInc > 10 )
                    ColInc = 10;

                //����ԭ��������
                LCD_Set_Window(pReq->CurrentCol, pReq->CurrentPage, pReq->EndCol, pReq->EndPage);
                LCD_Start_Data_Reading( );
                DispData [ 0 ] = LCD_Read_Data( );    //�����ĵ�һ���ֽ�Ϊ��Ч����,����

                for ( i = 0; i < ColInc; i++ )
                    DispData [ i ] = LCD_Read_Data( );

                //��ת����д����
                LCD_Set_Window(pReq->CurrentCol, pReq->CurrentPage, pReq->EndCol, pReq->EndPage);
                LCD_Start_Data_Writing( );

                for ( i = 0; i < ColInc; i++ )
                    LCD_Write_Data(~DispData [ i ]);

                pReq->CurrentCol += ColInc;

                if ( pReq->CurrentCol > pReq->EndCol )
                {
                    pReq->CurrentCol = pReq->StartCol;
                    pReq->CurrentPage++;

                    if ( pReq->CurrentPage > pReq->EndPage )
                    {
                        pReq->State = TFT_LCD_STATE_IDLE;
                        Rtn         = 1;
                    }
                }

                break;

            default:
                pReq->State = TFT_LCD_STATE_IDLE;
                Rtn         = 1;
                break;
        }
    }
    else
    {
        switch ( pReq->State )
        {
            case TFT_LCD_STATE_INIT:
                LCD_Set_Window(pReq->StartCol, pReq->StartPage, pReq->EndCol, pReq->EndPage);
                LCD_Start_Data_Writing( );
                pReq->State = TFT_LCD_STATE_DRAW;
                break;

            case TFT_LCD_STATE_DRAW:
                if ( pReq->Length - pReq->Offset > 30 )
                    ColInc = 30;
                else
                    ColInc = ( uint8_t )(pReq->Length - pReq->Offset);

                if ( pReq->Type == TFT_LCD_TYPE_CLR )
                {
                    for ( i = 0; i < ColInc; i++ )
                    {
                        LCD_Write_Data(0x00);
                        pReq->Offset++;
                    }
                }
                else
                {
                    for ( i = 0; i < ColInc; i++ )
                    {
                        LCD_Write_Data(0xFF);
                        pReq->Offset++;
                    }
                }

                if ( pReq->Offset >= pReq->Length )
                {
                    pReq->State = TFT_LCD_STATE_IDLE;
                    Rtn         = 1;
                }

                break;

            default:
                pReq->State = TFT_LCD_STATE_IDLE;
                Rtn         = 1;
                break;
        }
    }

    return Rtn;
}

static uint8_t TFT_LCD_Insert_Draw_Full_Box_Handler(TFTLCDDrawingReqStruct *pReq)
{
    uint8_t i;
    uint8_t Rtn;
    uint8_t DispData [ 10 ];
    uint8_t ColInc;
    uint8_t Mask;
    Rtn = 0;

    switch ( pReq->State )
    {
        case TFT_LCD_STATE_TOP:
            ColInc = pReq->EndCol - pReq->CurrentCol + 1;

            if ( ColInc > 10 )
                ColInc = 10;

            if ( pReq->StartPage == pReq->EndPage )
                Mask = TFTLCDBitMask [ pReq->BitShiftT ] | (~TFTLCDBitMask [ pReq->BitShiftB + 1 ]);
            else
                Mask = TFTLCDBitMask [ pReq->BitShiftT ];

            //����ԭ��������
            LCD_Set_Window(pReq->CurrentCol, pReq->CurrentPage, pReq->EndCol, pReq->EndPage);
            LCD_Start_Data_Reading( );
            DispData [ 0 ] = LCD_Read_Data( );    //�����ĵ�һ���ֽ�Ϊ��Ч����,����

            for ( i = 0; i < ColInc; i++ )
                DispData [ i ] = LCD_Read_Data( );

            //ƴ�Ӳ���д����
            LCD_Set_Window(pReq->CurrentCol, pReq->CurrentPage, pReq->EndCol, pReq->EndPage);
            LCD_Start_Data_Writing( );

            if ( pReq->Type == TFT_LCD_TYPE_INV )
            {
                for ( i = 0; i < ColInc; i++ )
                {
                    DispData [ i ] ^= ~Mask;
                    LCD_Write_Data(DispData [ i ]);
                }
            }
            else if ( pReq->Type == TFT_LCD_TYPE_CLR )
            {
                for ( i = 0; i < ColInc; i++ )
                {
                    DispData [ i ] &= Mask;
                    LCD_Write_Data(DispData [ i ]);
                }
            }
            else
            {
                for ( i = 0; i < ColInc; i++ )
                {
                    DispData [ i ] |= ~Mask;
                    LCD_Write_Data(DispData [ i ]);
                }
            }

            pReq->Offset += ColInc;
            pReq->CurrentCol += ColInc;

            if ( pReq->CurrentCol > pReq->EndCol )
            {
                pReq->CurrentCol = pReq->StartCol;
                pReq->CurrentPage++;

                if ( pReq->CurrentPage > pReq->EndPage )
                {
                    pReq->State = TFT_LCD_STATE_IDLE;
                    Rtn         = 1;
                }
                else if ( pReq->CurrentPage == pReq->EndPage )
                    pReq->State = TFT_LCD_STATE_BOT;
                else
                {
                    if ( pReq->Type != TFT_LCD_TYPE_INV )
                    {
                        LCD_Set_Window(pReq->CurrentCol, pReq->CurrentPage, pReq->EndCol, pReq->EndPage);
                        LCD_Start_Data_Writing( );
                    }

                    pReq->State = TFT_LCD_STATE_MID;
                }
            }

            break;

        case TFT_LCD_STATE_MID:
            if ( pReq->Type == TFT_LCD_TYPE_INV )
            {
                ColInc = pReq->EndCol - pReq->CurrentCol + 1;

                if ( ColInc > 10 )
                    ColInc = 10;

                //����ԭ��������
                LCD_Set_Window(pReq->CurrentCol, pReq->CurrentPage, pReq->EndCol, pReq->EndPage);
                LCD_Start_Data_Reading( );
                DispData [ 0 ] = LCD_Read_Data( );    //�����ĵ�һ���ֽ�Ϊ��Ч����,����

                for ( i = 0; i < ColInc; i++ )
                    DispData [ i ] = LCD_Read_Data( );

                //��ת����д����
                LCD_Set_Window(pReq->CurrentCol, pReq->CurrentPage, pReq->EndCol, pReq->EndPage);
                LCD_Start_Data_Writing( );

                for ( i = 0; i < ColInc; i++ )
                    LCD_Write_Data(~DispData [ i ]);

                pReq->Offset += ColInc;
                pReq->CurrentCol += ColInc;

                if ( pReq->CurrentCol > pReq->EndCol )
                {
                    pReq->CurrentCol = pReq->StartCol;
                    pReq->CurrentPage++;

                    if ( pReq->CurrentPage >= pReq->EndPage )
                        pReq->State = TFT_LCD_STATE_BOT;
                }
            }
            else
            {
                if ( pReq->Length - pReq->Width - pReq->Offset > 30 )
                    ColInc = 30;
                else
                    ColInc = ( uint8_t )(pReq->Length - pReq->Width - pReq->Offset);

                if ( pReq->Type == TFT_LCD_TYPE_CLR )
                {
                    for ( i = 0; i < ColInc; i++ )
                    {
                        LCD_Write_Data(0x00);
                        pReq->Offset++;
                    }
                }
                else
                {
                    for ( i = 0; i < ColInc; i++ )
                    {
                        LCD_Write_Data(0xFF);
                        pReq->Offset++;
                    }
                }

                if ( pReq->Offset >= pReq->Length - pReq->Width )
                {
                    pReq->CurrentCol  = pReq->StartCol;
                    pReq->CurrentPage = pReq->EndPage;
                    pReq->State       = TFT_LCD_STATE_BOT;
                }
            }

            break;

        case TFT_LCD_STATE_BOT:
            ColInc = pReq->EndCol - pReq->CurrentCol + 1;

            if ( ColInc > 10 )
                ColInc = 10;

            Mask = TFTLCDBitMask [ pReq->BitShiftB + 1 ];
            //����ԭ��������
            LCD_Set_Window(pReq->CurrentCol, pReq->CurrentPage, pReq->EndCol, pReq->EndPage);
            LCD_Start_Data_Reading( );
            DispData [ 0 ] = LCD_Read_Data( );    //�����ĵ�һ���ֽ�Ϊ��Ч����,����

            for ( i = 0; i < ColInc; i++ )
                DispData [ i ] = LCD_Read_Data( );

            //ƴ�Ӳ���д����
            LCD_Set_Window(pReq->CurrentCol, pReq->CurrentPage, pReq->EndCol, pReq->EndPage);
            LCD_Start_Data_Writing( );

            if ( pReq->Type == TFT_LCD_TYPE_INV )
            {
                for ( i = 0; i < ColInc; i++ )
                {
                    DispData [ i ] ^= Mask;
                    LCD_Write_Data(DispData [ i ]);
                }
            }
            else if ( pReq->Type == TFT_LCD_TYPE_CLR )
            {
                for ( i = 0; i < ColInc; i++ )
                {
                    DispData [ i ] &= ~Mask;
                    LCD_Write_Data(DispData [ i ]);
                }
            }
            else
            {
                for ( i = 0; i < ColInc; i++ )
                {
                    DispData [ i ] |= Mask;
                    LCD_Write_Data(DispData [ i ]);
                }
            }

            pReq->Offset += ColInc;
            pReq->CurrentCol += ColInc;

            if ( pReq->CurrentCol > pReq->EndCol )
            {
                pReq->CurrentCol = pReq->StartCol;
                pReq->CurrentPage++;

                if ( pReq->CurrentPage > pReq->EndPage )
                {
                    pReq->State = TFT_LCD_STATE_IDLE;
                    Rtn         = 1;
                }
            }

            break;

        default:
            pReq->State = TFT_LCD_STATE_IDLE;
            Rtn         = 1;
            break;
    }

    return Rtn;
}
