Library for FTDI FT800, Support up to 512 x 512 pixel resolution.

Dependents:   FT800-Demo-Sliders FT800-Clock FT800-Demo-Bitmap

Hardware

https://os.mbed.com/media/uploads/nz/display-43.jpg

Info

FT800_Functions.cpp

Committer:
nz
Date:
2020-12-30
Revision:
5:b28ce8616b41
Parent:
4:5bcc69cb157a

File content as of revision 5:b28ce8616b41:

/* mbed Library for FTDI FT800 */
 
#include "FT800.h"

FT800::FT800(PinName mosi, PinName miso, PinName sck,
             PinName ss,   PinName intr, PinName pd)
    :
    _spi(mosi, miso, sck),
    _ss(ss),
    _pd(pd),
    _f800_isr(intr)  // _f800_isr(InterruptIn(intr))   !!!!!!!!!!!
    {
        _spi.format(8,0);           // 8 bit spi mode 0
        _spi.frequency(10000000);   // start with 10 MHz SPI clock
        _ss = 1;                    // cs high
        _pd = 1;                    // PD high
    }

//-----------------------------------------------------------------------------------
// Increment FIFO address offset
//-----------------------------------------------------------------------------------
void FT800::CMD_Offset_Inc(uint8_t command_size)
{
    CMD_Offset += command_size; 
    CMD_Offset %= 4096;
}

//-----------------------------------------------------------------------------------
// Set FIFO address offset
//-----------------------------------------------------------------------------------
void FT800::set_CMD_Offset(uint16_t offset)
{
    CMD_Offset = offset;
}

//-----------------------------------------------------------------------------------
// Get FIFO address offset
//-----------------------------------------------------------------------------------
uint16_t FT800::get_CMD_Offset(void)
{
    return CMD_Offset;
}

//-----------------------------------------------------------------------------------
// Write address. Most significant byte is sent first. mode: ADREAD, ADWRITE
//-----------------------------------------------------------------------------------
void FT800::WriteAddress(uint32_t addr, uint8_t mode)
{
    uint8_t byte = 0;
    
    byte = ((addr & 0x00FF0000) >> 16); // Mask the first byte to send
    byte = ((byte & 0x3F) | mode);      // the MSBs are forced to 00 for READ, 10 for WRITE, 01 CONFIG
    _spi.write(byte);                   // Call the low-level SPI transmit routine
    
    byte = ((addr & 0x0000FF00) >> 8);  // Mask the next byte to be sent
    _spi.write(byte);
    
    byte = (addr & 0x000000FF);         // Mask the next byte to be sent
    _spi.write(byte);
    
    if(mode==ADREAD)    _spi.write(0x00);
}   

//-----------------------------------------------------------------------------------
// Read 8 bits (BYTE) from address
//-----------------------------------------------------------------------------------
uint8_t FT800::Read08(uint32_t addr)
{
    uint8_t byte = 0;
    _ss = 0;                    // SPI: active
    WriteAddress(addr, ADREAD);
    byte = _spi.write(0);
    _ss = 1;                    // SPI: inactive
    return byte;
}

//-----------------------------------------------------------------------------------
// Read 16 bits (WORD) from address
//-----------------------------------------------------------------------------------
uint16_t FT800::Read16(uint32_t addr)
{
    uint16_t byte = 0;
    uint16_t word = 0;          //uint16_t data;
    _ss = 0;
    WriteAddress(addr, ADREAD); //TransferStart(addr, ADREAD);
    byte = _spi.write(0);
    word |= byte;
    byte = _spi.write(0); 
    word |= (byte<<8);          //data = Transfer16(0);
    _ss = 1;                    //TransferEnd( );
    return word;
}

//-----------------------------------------------------------------------------------
// Read 32 bits (DWORD) from address
//-----------------------------------------------------------------------------------
uint32_t FT800::Read32(uint32_t addr)
{
    uint32_t byte = 0;
    uint32_t dword= 0;      //uint32_t data;
    _ss = 0;
    WriteAddress(addr, ADREAD); //TransferStart(addr, ADREAD);
    byte = _spi.write(0);
    dword |= byte;
    byte = _spi.write(0);
    dword |= (byte<<8);
    byte = _spi.write(0);
    dword |= (byte<<16);
    byte = _spi.write(0);
    dword |= (byte<<24);
    _ss = 1;                //TransferEnd( );
    return dword;
}

//-----------------------------------------------------------------------------------
// Write 8 bits (BYTE) data at address
//-----------------------------------------------------------------------------------
void FT800::Write08(uint32_t addr, uint8_t data)
{
    if(addr==RAM_CMD)               // if writing to FIFO
    {
        addr += CMD_Offset;
        CMD_Offset_Inc(1);          // Move the CMD Offset 
    }
    _ss = 0;
    WriteAddress(addr, ADWRITE);    //TransferStart(addr, ADWRITE);
    _spi.write(data);               //Transfer08(data);
    _ss = 1;                        //TransferEnd( );
}

//-----------------------------------------------------------------------------------
// Write 16 bits (WORD) data at address
//-----------------------------------------------------------------------------------
void FT800::Write16(uint32_t addr, uint16_t data)
{
    if(addr==RAM_CMD)               // if writing to FIFO
    {
        addr += CMD_Offset;
        CMD_Offset_Inc(2);          // Move the CMD Offset
    }
    _ss = 0;
    WriteAddress(addr, ADWRITE);    //TransferStart(addr, ADWRITE);
    _spi.write( data & 0x00FF);
    _spi.write((data & 0xFF00)>>8); //Transfer16(data); 
    _ss = 1;                        //TransferEnd( );
}

//-----------------------------------------------------------------------------------
// Write 32 bits (DWORD) data at address
//-----------------------------------------------------------------------------------
void FT800::Write32(uint32_t addr, uint32_t data)
{
    if(addr==RAM_CMD)               // if writing to FIFO 
    {
        addr += CMD_Offset;
        CMD_Offset_Inc(4);          // Move the CMD Offset
    }
    _ss = 0;
    WriteAddress(addr, ADWRITE);    //TransferStart(addr, ADWRITE);
    _spi.write( data & 0x000000FF);
    _spi.write((data & 0x0000FF00)>>8);
    _spi.write((data & 0x00FF0000)>>16);
    _spi.write((data & 0xFF000000)>>24);    //Transfer32(data);
    _ss = 1;                        //TransferEnd( );
}

void FT800::HostCommand(uint8_t cmd)
{
    _ss = 0;
    _spi.write(cmd);
    _spi.write(0);
    _spi.write(0);
    _ss = 1;
}

//-----------------------------------------------------------------------------------
// Wait ms
//-----------------------------------------------------------------------------------
void FT800::Sleep(uint16_t ms)
{
    thread_sleep_for(ms);   // C, ThisThread::sleep_for(ms); C++ //old wait_ms(ms);
}


//------------------------------MEMORY RAM_G-----------------------------------------
// Write zero to a block of memory
//-----------------------------------------------------------------------------------
void FT800::writeMemZero(uint32_t ptr, uint32_t numb)
{
    Write32(RAM_CMD, CMD_MEMZERO); 
    Write32(RAM_CMD, ptr);   
    Write32(RAM_CMD, numb); 
}

//-----------------------------------------------------------------------------------
// Write value to a block of memory
//-----------------------------------------------------------------------------------
void FT800::writeMemSet(uint32_t ptr, uint32_t value, uint32_t numb)
{
    Write32(RAM_CMD, CMD_MEMSET); 
    Write32(RAM_CMD, ptr); 
    Write32(RAM_CMD, value);
    Write32(RAM_CMD, numb);
}

//-----------------------------------------------------------------------------------
// Copy block of memory
//-----------------------------------------------------------------------------------
void FT800::writeMemCpy(uint32_t dest, uint32_t source, uint32_t numb)
{
    Write32(RAM_CMD, CMD_MEMCPY);
    Write32(RAM_CMD, dest);
    Write32(RAM_CMD, source);
    Write32(RAM_CMD, numb);
}

//-----------------------------------------------------------------------------------
// Write block of memory
//-----------------------------------------------------------------------------------
void FT800::writeMemWrt(uint32_t ptr, uint32_t numb)
{
    //Write32(RAM_CMD, CMD_MEMWRITE);
    //Write32(RAM_CMD, ptr);
    //Write32(RAM_CMD, numb);
}

//-----------------------------------------------------------------------------------
// Set Backlight brightness [0-128], 0 = off, 128 = brightness 100%
//-----------------------------------------------------------------------------------
void FT800::setBacklight(uint8_t brightness)
{
    if(brightness > 128) brightness = 128;
    Write16(REG_PWM_DUTY, brightness);
}

//-----------------------------------------------------------------------------------
// Set GPU PLL output clock, 36 or 48 MHz
//-----------------------------------------------------------------------------------
void FT800::setGPU_Frequency(uint8_t freq)
{
    if(freq == 36) HostCommand(GPU_PLL_36M);
    if(freq == 48) HostCommand(GPU_PLL_48M);
    Sleep(10);
}

//-----------------------------------------------------------------------------------
// Clear/reading interrupt flags
//----------------------------------------------------------------------------------- 
void FT800::clearIntFlags(void)
{
    Read08(REG_INT_FLAGS);
}

//-----------------------------------------------------------------------------------
// FT800 initialize
//-----------------------------------------------------------------------------------
void FT800::Init()
{
    uint8_t chipid;
        
    // Toggle PD_N from low to high for Reset the FT800
    _pd = 0;        Sleep(20);
    _pd = 1;        Sleep(20);
            
    // Configuration of GPU  
    HostCommand(GPU_ACTIVE_M);      Sleep(10);  // Access address 0 to wake up the FT800
    HostCommand(GPU_EXTERNAL_OSC);  Sleep(10);  // Set the clk to external clock
    HostCommand(GPU_PLL_48M);       Sleep(10);  // Switch PLL output to 48MHz
    HostCommand(GPU_CORE_RESET);                // Do a core reset for safer side

    chipid = Read08(REG_ID);            // Read Register ID to check if FT800 is ready.
    while(chipid != 0x7C)
        chipid = Read08(REG_ID);

    _spi.frequency(20000000);       // 20 Mhz SPI clock

    /* Configuration of LCD Display */
    Write16(REG_HSIZE, DISP_WIDTH);
    Write16(REG_HCYCLE, DISP_HCYCLE);
    Write16(REG_HOFFSET, DISP_HSYNC1+DISP_HSLEN);
    Write16(REG_HSYNC0, DISP_HSYNC0);
    Write16(REG_HSYNC1, DISP_HSYNC1);
    
    Write16(REG_VSIZE, DISP_HEIGHT);
    Write16(REG_VCYCLE, DISP_VCYCLE);
    Write16(REG_VOFFSET, DISP_VSYNC1+DISP_VSLEN);
    Write16(REG_VSYNC0, DISP_VSYNC0);
    Write16(REG_VSYNC1, DISP_VSYNC1);
    
    Write08(REG_SWIZZLE, DISP_SWIZZLE);
    Write08(REG_PCLK_POL, DISP_PCLK_POL);
    Write08(REG_PCLK, DISP_PCLK);
    Write08(REG_CSPREAD, 1);

    /* Configuration of Backlight */
    Write16(REG_PWM_HZ, DISP_PWM_HZ);
    Write16(REG_PWM_DUTY, DISP_PWM_DUTY); // full brightness
    
    /* Configuration of Touch Screen */
    Write16(REG_TOUCH_RZTHRESH, TOUCH_SENSITIVITY);    
    Write08(REG_TOUCH_MODE, TOUCH_MODE);
    Write08(REG_TOUCH_ADC_MODE, TOUCH_ADC_MODE);
    Write16(REG_TOUCH_CHARGE, TOUCH_CHARGE);
    Write08(REG_TOUCH_SETTLE, TOUCH_SETTLE);
    Write08(REG_TOUCH_OVERSAMPLE, TOUCH_OVERSAMPLE);
    
    /* Configuration of Touch Screen interrupt */
    //Write08(REG_INT_EN, 0x01);            Sleep(20);  // enable interrupt    
    //Write08(REG_INT_MASK,0b00000110); Sleep(20);  // mask interrupt
    //Read08(REG_INT_FLAGS);                            // Reading clears interrupt flags
    
    /* Configuration of GPIO */
    Write08(REG_GPIO_DIR, GPIO_DIR);
    Write08(REG_GPIO, GPIO_SET);
    
    Write32(RAM_DL, 0x02000000);        // Set the colour for clear Black   
    Write32(RAM_DL+4, 0x26000007);      // Clear the Colour, Stencil and Tag buffers
    Write32(RAM_DL+8, 0x00000000);      // Ends the display list
    Write32(REG_DLSWAP, 1);             // Writing to the DL_SWAP register...
}


//-----------------------------------------------------------------------------------
// Start of display list
//-----------------------------------------------------------------------------------
void FT800::DLstart(void)
{          
    Write32(RAM_CMD, CMD_DLSTART);
}
void FT800::DLstart(uint32_t color)
{          
    Write32(RAM_CMD, CMD_DLSTART);
    Write32(RAM_CMD, 0x02000000|(color&0x00FFFFFF));// set clear color
    Write32(RAM_CMD, 0x26000007);                   // clear all
}
void FT800::DLstart(uint32_t color, uint8_t br)     // br -> brightness
{          
    Write32(RAM_CMD, CMD_DLSTART);
    Write32(RAM_CMD, 0x02000000|(color&0x00FFFFFF));// set clear color
    Write32(RAM_CMD, 0x26000007);                   // clear all
    if(br > 128) br = 128;
    Write16(REG_PWM_DUTY, br);                      // set brightness
}

//-----------------------------------------------------------------------------------
// End of display list
//-----------------------------------------------------------------------------------
void FT800::DLend(void)
{    
    Write32(RAM_CMD, 0x00000000);    
    Write32(RAM_CMD, CMD_SWAP);  
    Write16(REG_CMD_WRITE, get_CMD_Offset());  
}

//-----------------------------------------------------------------------------------
// Finish display list
//-----------------------------------------------------------------------------------
void FT800::finishList(void)
{
    uint32_t cmdBufferWr, cmdBufferRd;
    do
    {
        cmdBufferWr = Read16(REG_CMD_WRITE);// Read the vaulue of the REG_CMD_WRITE register
        cmdBufferRd = Read16(REG_CMD_READ); // Read the vaulue of the REG_CMD_READ register
    } while(cmdBufferWr != cmdBufferRd);
    set_CMD_Offset(Read16(REG_CMD_WRITE)); 
}

//-----------------------------------------------------------------------------------
// Set color RGB, format 0xRRGGBB
//-----------------------------------------------------------------------------------
void FT800::setColor(uint32_t color)
{
    Write32(RAM_CMD, 0x04000000|(color&0x00FFFFFF));
}

//-----------------------------------------------------------------------------------
// Set Color Alpha, alpha [0-255], alpha=128 (50% transparency), alpha=255 100%
//-----------------------------------------------------------------------------------
void FT800::setColorA(uint8_t alpha)
{
    Write32(RAM_CMD, 0x10000000|alpha);
}

//-----------------------------------------------------------------------------------
// Set Clear Color - 0x00RRGGBB
//-----------------------------------------------------------------------------------
void FT800::setClearColor(uint32_t color)
{         
    Write32(RAM_CMD, 0x02000000|(color&0x00FFFFFF));
}
//-----------------------------------------------------------------------------------
// Set Clear Color Alpha
//-----------------------------------------------------------------------------------
void FT800::setClearColorA(uint8_t alpha)
{
    Write32(RAM_CMD, 0x0F0000000|alpha);
}

//-----------------------------------------------------------------------------------
// Set Background Color, default dark blue (0x002040)
//-----------------------------------------------------------------------------------
void FT800::setBgColor(uint32_t color)
{
    Write32(RAM_CMD, CMD_BGCOLOR);
    Write32(RAM_CMD, (color&0x00FFFFFF));
}

//-----------------------------------------------------------------------------------
// Set Foreground Color, default light blue (0x003870)
//-----------------------------------------------------------------------------------
void FT800::setFgColor(uint32_t color)
{
    Write32(RAM_CMD, CMD_FGCOLOR);   
    Write32(RAM_CMD, (color&0x00FFFFFF));
}

//-----------------------------------------------------------------------------------
// Set Gradient Color, default white (0xffffff)
//-----------------------------------------------------------------------------------
void FT800::setGrColor(uint32_t color)
{
    Write32(RAM_CMD, CMD_GRADCOLOR);   
    Write32(RAM_CMD, (color&0x00FFFFFF));
}

//-----------------------------------------------------------------------------------
// Clear display - clear 0x2600000X
//-----------------------------------------------------------------------------------
void FT800::clear(uint8_t clr)                  // 0b0001 or 1 - clear tag buffer
{                                               // 0b0010 or 2 - clear stencil buffer
    Write32(RAM_CMD, 0x26000000|(clr&0x07));    // 0b0100 or 4 - clear color buffer
}                                               // 0b0111 or 7 - clear all

//-----------------------------------------------------------------------------------
// Set Line Width - width [1-255] *16
//-----------------------------------------------------------------------------------
void FT800::setLineWidth(uint16_t width)
{
    Write32(RAM_CMD, 0x0E000000|(width*16));
}

//-----------------------------------------------------------------------------------
// Set Point Size - size [1-512] *16
//-----------------------------------------------------------------------------------
void FT800::setPointSize(uint16_t size)
{
    Write32(RAM_CMD, 0x0D000000|(size*16));
}

//-----------------------------------------------------------------------------------
// Set Scissor Size width & height [0-512]
//-----------------------------------------------------------------------------------
void FT800::setScissorSize(uint16_t width, uint16_t height)
{
    uint32_t scissorSize = 0x1C000000;    
    scissorSize |= (width&0x03FF)<<10;
    scissorSize |= (height&0x03FF);
    Write32(RAM_CMD, scissorSize);
}

//-----------------------------------------------------------------------------------
// Set Scissor XY - position (x,y) the top left corner of the scissor clip rectangle
//-----------------------------------------------------------------------------------
void FT800::setScissorXY(int16_t x, int16_t y)
{
    uint32_t scissorXY = 0x1B000000;
    scissorXY |= (x&0x01FF)<<9;
    scissorXY |= (y&0x01FF);
    Write32(RAM_CMD, scissorXY);
}

//-----------------------------------------------------------------------------------
// Blend function - specifies how the source blending factor is computed.
//-----------------------------------------------------------------------------------
void FT800::setBlendFunc(uint8_t src, uint8_t dst)
{
    uint32_t blend=0x0B000000;    
    blend|=((src&0x07)<<3);
    blend|=(dst&0x07);    
    Write32(RAM_CMD, blend);  
}

//-----------------------------------------------------------------------------------
// align - used filling up to 32 bit (4 bytes)
//-----------------------------------------------------------------------------------
void FT800::align(uint8_t n)
{
    while((n++) & 3)
        Write08(RAM_CMD, 0);
}

//-----------------------------------------------------------------------------------
// Base Functions of Primitives
//-----------------------------------------------------------------------------------
void FT800::beginBitmap()   { Write32(RAM_CMD, 0x1F000001); }
void FT800::beginPoint()    { Write32(RAM_CMD, 0x1F000002); }
void FT800::beginLine()     { Write32(RAM_CMD, 0x1F000003); }
void FT800::beginLineStrip(){ Write32(RAM_CMD, 0x1F000004); }
void FT800::beginRect()     { Write32(RAM_CMD, 0x1F000009); }

void FT800::drawBitmapXY(int16_t x, int16_t y) { Vertex2II(x,y,0,0); }
void FT800::drawPointXY(int16_t x, int16_t y) { Vertex2F(x<<4,y<<4); }
void FT800::drawLineXY(int16_t x1,int16_t y1,int16_t x2,int16_t y2) {Vertex2F(x1<<4,y1<<4);Vertex2F(x2<<4,y2<<4);}

void FT800::end() { Write32(RAM_CMD, 0x21000000); }

//-----------------------------------------------------------------------------------
// Vertex2F - x & y [-16384,16383], in 1/16 of the pixel, or [-1024,1023]
//-----------------------------------------------------------------------------------
void FT800::Vertex2F(int16_t x, int16_t y)
{
    uint32_t xy=0x40000000;           
    xy |= ((x&0x7FFF)<<15); //11 bits for +-x coordinate and 4 bits for x fraction (1/16 of pixel)
    xy |= (y&0x7FFF);       //11 bits for +-y coordinate and 4 bits for y fraction (1/16 of pixel)   
    Write32(RAM_CMD, xy); 
}

//-----------------------------------------------------------------------------------
// Vertex2II - x[0,511], y[0,511], handle [0-31], cell [0-127]  
//-----------------------------------------------------------------------------------
void FT800::Vertex2II(uint16_t x, uint16_t y, uint8_t handle, uint8_t cell)
{
    uint32_t xyhc=0x80000000;
    xyhc|=((x&0x01FF)<<21);
    xyhc|=((y&0x01FF)<<12);
    xyhc|=((handle&0x1F)<<7);
    xyhc|=(cell&0x7F);
    Write32(RAM_CMD, xyhc); 
} 

//-----------------------------------------------------------------------------------
// Draw Char at position (x,y), font [16-31], color, char
//-----------------------------------------------------------------------------------
void FT800::drawChar(uint16_t x, uint16_t y, uint8_t font, uint32_t color, char c)
{
    Write32(RAM_CMD, 0x04000000|(color&0x00FFFFFF));// set color
    Write32(RAM_CMD, 0x1F000001);                   // begin drawing bitmap
    if(font>31)font=31;
    if(font<16)font=16;
    Vertex2II(x, y, font, c);                       // draw char
    Write32(RAM_CMD, 0x21000000);                   // draw end
}

//-----------------------------------------------------------------------------------
// Draw Point center (x,y), color, size
//-----------------------------------------------------------------------------------
void FT800::drawPoint(int16_t x, int16_t y, uint32_t color, uint16_t size)
{
    Write32(RAM_CMD, 0x04000000|(color&0x00FFFFFF));    // set color
    Write32(RAM_CMD, 0x0D000000|(size*16));             // set size (radius)
    Write32(RAM_CMD, 0x1F000002);                       // begin drawing point
    Vertex2F(x<<4,y<<4);                                // draw coordinates
    Write32(RAM_CMD, 0x21000000);                       // draw end
}

//-----------------------------------------------------------------------------------
// Draw Line from (x1,y1) to (x2,y2) of color color and linewidth width
//-----------------------------------------------------------------------------------
void FT800::drawLine(int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint32_t color, uint16_t width)
{     
    Write32(RAM_CMD, 0x04000000|(color&0x00FFFFFF));    // set color rgb
    Write32(RAM_CMD, 0x0E000000|((width*16)&0x0FFF));   // set width of line
    Write32(RAM_CMD, 0x1F000003);                       // begin drawing line
    Vertex2F(x1<<4, y1<<4);                             // draw coordinates x1, y1
    Vertex2F(x2<<4, y2<<4);                             // draw coordinates x2, y2
    Write32(RAM_CMD, 0x21000000);                       // draw end
}

//-----------------------------------------------------------------------------------
// Draw Rectangle starting from (x1,y1) and ending at (x2,y2) of color color and linewidth width
//-----------------------------------------------------------------------------------
void FT800::drawRect(int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint32_t color, uint16_t width)
{  
    Write32(RAM_CMD, 0x04000000|(color&0x00FFFFFF));    // set color rgb
    Write32(RAM_CMD, 0x0E000000|((width*16)&0x0FFF));   // set linewidth/
    Write32(RAM_CMD, 0x1F000009);                       // begin drawing rect
    Vertex2F(x1<<4, y1<<4);                             // draw coordinates
    Vertex2F(x2<<4, y2<<4);                             // draw coordinates
    Write32(RAM_CMD, 0x21000000);                       // draw end
}

//-----------------------------------------------------------------------------------
// Draw Line Strip in number of points
//-----------------------------------------------------------------------------------
void FT800::drawLineStrips(int16_t x[], int16_t y[], uint16_t points, uint16_t width, uint32_t color)
{
    uint16_t i;
    Write32(RAM_CMD, 0x04000000|(color&0x00FFFFFF));    // set color rgb
    Write32(RAM_CMD, 0x0E000000|((width*16)&0x0FFF));   // set linewidth
    Write32(RAM_CMD, 0x1F000004);                       // begin drawing linestrip
    for(i=0; i<points; i++) Vertex2F(x[i]<<4,y[i]<<4);  // draw coordinates
    Write32(RAM_CMD, 0x21000000);                       // draw end
} 

//------------------------------------------------------------------------------
// Draw Edge Line Strip (color filling) in number of points num_of_points
//------------------------------------------------------------------------------
void FT800::drawEdgeStrips(int16_t x[], int16_t y[], uint16_t num_of_points, uint8_t choice, uint32_t color)
{
    uint32_t c = 0;
    uint16_t i;       
    switch(choice) //choose edge side
    {
        case'R': c = 0x00000005; break;     // edge side Right
        case'L': c = 0x00000006; break;     // edge side Left                    
        case'A': c = 0x00000007; break;     // edge side Above
        case'B': c = 0x00000008; break;     // edge side Below
    }
    Write32(RAM_CMD, 0x04000000|(color&0x00FFFFFF));    // set color rgb
    Write32(RAM_CMD, 0x1F000000|c);                     // begin drawing linestrip
    for(i=0; i<num_of_points; i++) Vertex2F(x[i]<<4,y[i]<<4);
    Write32(RAM_CMD, 0x21000000);                       // draw end
}

//-----------------------------------------------------------------------------------
// Draw String - used text draw and object naming
//-----------------------------------------------------------------------------------
void FT800::drawString(const char *s)
{
    uint16_t string_length = 0;
    string_length = strlen(s)+1;
    while(*s)
    {
        char c = *s++;
        Write08(RAM_CMD, c);
    }
    Write08(RAM_CMD, 0);
    align(string_length);  
}

//-----------------------------------------------------------------------------------
// Draw Text at position (x,y), font [16-31], color, options [ie. OPT_RIGHTX], text s
//-----------------------------------------------------------------------------------
void FT800::drawText(int16_t x, int16_t y, uint8_t font, uint32_t color, uint16_t option, const char *s)   
{ 
    Write32(RAM_CMD, 0x04000000|(color&0x00FFFFFF));// set color
    Write32(RAM_CMD, CMD_TEXT);
    Write16(RAM_CMD, x);
    Write16(RAM_CMD, y);
    if(font>31)font=31;
    if(font<16)font=16;
    Write16(RAM_CMD, font);
    Write16(RAM_CMD, option);
    drawString(s);
}

//-----------------------------------------------------------------------------------
// Draw Decimal Number
//-----------------------------------------------------------------------------------
void FT800::drawNumber(int16_t x, int16_t y, uint8_t font, uint32_t color, uint16_t option, uint32_t n)
{
    Write32(RAM_CMD, 0x04000000|(color&0x00FFFFFF));// set color
    Write32(RAM_CMD, CMD_NUMBER);
    Write16(RAM_CMD, x);
    Write16(RAM_CMD, y);
    if(font>31)font=31;
    if(font<16)font=16;
    Write16(RAM_CMD, font);
    Write16(RAM_CMD, option);
    Write32(RAM_CMD, n);
}



//-----------------------------------------------------------------------------------
// Set Bitmap Handle
//-----------------------------------------------------------------------------------
void FT800::bitmapHandle(uint8_t handle)
{
    Write32(RAM_CMD, 0x05000000|(handle&0x1F));
}
//-----------------------------------------------------------------------------------
// Bitmap Transform - scaling, rotation and translation
// x1=x*A+y*B+C y1=x*D+y*E+F
//-----------------------------------------------------------------------------------
void FT800::bitmapTransformA(int32_t value) {
    Write32(RAM_CMD, 0x15000000|(value&0x00FFFFFF)); }  // BMP_TRANSFORM_A  0x15000000
void FT800::bitmapTransformB(int32_t value) {
    Write32(RAM_CMD, 0x16000000|(value&0x00FFFFFF)); }  // BMP_TRANSFORM_B  0x16000000
void FT800::bitmapTransformC(int32_t value) {
    Write32(RAM_CMD, 0x17000000|(value&0x00FFFFFF)); }  // BMP_TRANSFORM_C  0x17000000
void FT800::bitmapTransformD(int32_t value) {
    Write32(RAM_CMD, 0x18000000|(value&0x00FFFFFF)); }  // BMP_TRANSFORM_D  0x18000000
void FT800::bitmapTransformE(int32_t value) {
    Write32(RAM_CMD, 0x19000000|(value&0x00FFFFFF)); }  // BMP_TRANSFORM_E  0x19000000
void FT800::bitmapTransformF(int32_t value) {
    Write32(RAM_CMD, 0x1A000000|(value&0x00FFFFFF)); }  // BMP_TRANSFORM_F  0x1A000000

//-----------------------------------------------------------------------------------
// Bitmap Layout
//-----------------------------------------------------------------------------------
void FT800::bitmapLayout(uint8_t format, int16_t linestride, int16_t heigth)
{
    uint32_t bitmap_layout = 0x07000000;
   
    if(format>11) format = 11; //The valid range is from  0 to 11
    bitmap_layout |= (uint32_t)(format&0x1F)<<19;
    bitmap_layout |= (uint32_t)(linestride&0x03FF)<<9;
    bitmap_layout |= (heigth&0x01FF);  
    
    Write32(RAM_CMD, bitmap_layout);
}
//-----------------------------------------------------------------------------------
// FT800 bitmap Size
//-----------------------------------------------------------------------------------
void FT800::bitmapSize(uint8_t filter, uint8_t wrapx, uint8_t wrapy, int16_t width, int16_t heigth)
{
    uint32_t bitmap_size = 0x08000000;
    
    bitmap_size |= (uint32_t)(filter&0x01)<<20;
    bitmap_size |= (uint32_t)(wrapx&0x01)<<19;
    bitmap_size |= (uint32_t)(wrapy&0x01)<<18;
    bitmap_size |= (uint32_t)(width&0x01FF)<<9;
    bitmap_size |= (uint32_t)(heigth&0x01FF);
    
    Write32(RAM_CMD, bitmap_size);
}
//-----------------------------------------------------------------------------------
// Bitmap Source
//-----------------------------------------------------------------------------------
void FT800::bitmapSource(uint32_t add)
{  
    Write32(RAM_CMD, 0x01000000|(add&0x000FFFFF));
}
//-----------------------------------------------------------------------------------
// Load matrix
//-----------------------------------------------------------------------------------
void FT800::loadIdentity(void)
{
    Write32(RAM_CMD, CMD_LOADIDENTITY);
}
//-----------------------------------------------------------------------------------
// Set matrix
//-----------------------------------------------------------------------------------
void FT800::setMatrix(void)
{
    Write32(RAM_CMD, CMD_SETMATRIX);
}
//-----------------------------------------------------------------------------------
// Scale command
//-----------------------------------------------------------------------------------
void FT800::scale(int16_t sx, int16_t sy)
{
    Write32(RAM_CMD, CMD_SCALE);
    Write32(RAM_CMD, (int32_t)sx<<16);
    Write32(RAM_CMD, (int32_t)sy<<16);
}
//-----------------------------------------------------------------------------------
// Translate command
//-----------------------------------------------------------------------------------
void FT800::translate(int16_t tx, int16_t ty)
{
    Write32(RAM_CMD, CMD_TRANSLATE);
    Write32(RAM_CMD, (int32_t)tx<<16);
    Write32(RAM_CMD, (int32_t)ty<<16);    
}
//-----------------------------------------------------------------------------------
// Rotate command
//-----------------------------------------------------------------------------------
void FT800::rotate(int16_t a)
{
    Write32(RAM_CMD, CMD_ROTATE);
    Write32(RAM_CMD, ((int32_t)a<<16)/360);   
}
//-----------------------------------------------------------------------------------
// Inflate command     NEW
//-----------------------------------------------------------------------------------
void FT800::inflate(uint32_t ptr)
{
    Write32(RAM_CMD, CMD_INFLATE);
    Write32(RAM_CMD, ptr);
}
//-----------------------------------------------------------------------------------
// Load Image command. The default format for the image is RGB565. OPT_MONO - Format L8
//-----------------------------------------------------------------------------------
void FT800::loadJpgCMD(uint32_t ptr, uint32_t opt)
{
    Write32(RAM_CMD, CMD_LOADIMAGE);
    Write32(RAM_CMD, ptr);
    Write32(RAM_CMD, opt);
}


//-----------------------------------------------------------------------------------
// Assign Tag and Track given area for touch 
// all object in the given area will have the same tag - to prevent use tag mask
//-----------------------------------------------------------------------------------
void FT800::track(int16_t x, int16_t y, uint16_t w, uint16_t h, uint8_t tag)
{
    Write32(RAM_CMD, CMD_TRACK);
    Write16(RAM_CMD, x);
    Write16(RAM_CMD, y);
    Write16(RAM_CMD, w);
    Write16(RAM_CMD, h);
    Write32(RAM_CMD, tag);
    Write32(RAM_CMD,0x03000000|(tag&0xFF)); 
}
//-----------------------------------------------------------------------------------
// tag mask - disable(0) or enable(1) object tag
//-----------------------------------------------------------------------------------
void FT800::tagMask(uint8_t mask)
{
    Write32(RAM_CMD,0x14000000|(mask&0x01));
}
//-----------------------------------------------------------------------------------
// Read Tag value
//-----------------------------------------------------------------------------------
uint8_t FT800::readTag(void)
{
    uint32_t tag;
    tag = Read32(REG_TRACKER)&0x000000FF;    
    return (uint8_t)tag;
}
//-----------------------------------------------------------------------------------
// Read Value tagged object
//-----------------------------------------------------------------------------------
uint16_t FT800::readValue(void)
{
    uint32_t value;
    value = Read32(REG_TRACKER)&(0xFFFF0000);
    return (uint16_t)(value>>16);
}
//-----------------------------------------------------------------------------------
// Draw Button
//-----------------------------------------------------------------------------------
void FT800::drawButton(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t option,
        uint32_t colorBG, uint32_t colorTXT, uint8_t font, const char*s, uint8_t tag)
{
    if(tag)
    {
        tagMask(1);
        track(x,y,w,h,tag);
    }
    setFgColor(colorBG); //button color
    setColor(colorTXT); //text color
    Write32(RAM_CMD, CMD_BUTTON);
    Write16(RAM_CMD, x);
    Write16(RAM_CMD, y);
    Write16(RAM_CMD, w);
    Write16(RAM_CMD, h);
    if(font>31)font=31;
    if(font<16)font=16;
    Write16(RAM_CMD, font);
    Write16(RAM_CMD, option);
    drawString(s);
    tagMask(0);
}
//-----------------------------------------------------------------------------------
// Draw analog Clock
//-----------------------------------------------------------------------------------
void FT800::drawClock(int16_t x, int16_t y, uint16_t r, uint16_t option, uint32_t colorBG,
        uint32_t colorNeedle, uint16_t h, uint16_t m, uint16_t s, uint16_t ms, uint8_t tag)
{
    if(tag)
    {
        tagMask(1);
        track(x,y,1,1,tag);
    }
    setBgColor(colorBG);
    setColor(colorNeedle);
    Write32(RAM_CMD, CMD_CLOCK);
    Write16(RAM_CMD, x);
    Write16(RAM_CMD, y);
    Write16(RAM_CMD, r);
    Write16(RAM_CMD, option);
    Write16(RAM_CMD, h);
    Write16(RAM_CMD, m);
    Write16(RAM_CMD, s);
    Write16(RAM_CMD, ms);
    tagMask(0);
}

//-----------------------------------------------------------------------------------
// Draw Dial potentiometer
//-----------------------------------------------------------------------------------
void FT800::drawDial(int16_t x, int16_t y, uint16_t r, uint16_t option,
        uint32_t colorMarker, uint32_t colorKnob, uint16_t value, uint8_t tag)
{
    if(tag)
    {
        tagMask(1);
        track(x,y,1,1,tag);//rotary tracker
    }
    setColor(colorKnob);
    setFgColor(colorMarker);
    Write32(RAM_CMD, CMD_DIAL);
    Write16(RAM_CMD, x);
    Write16(RAM_CMD, y);
    Write16(RAM_CMD, r);
    Write16(RAM_CMD, option);    
    Write16(RAM_CMD, value);
    Write16(RAM_CMD, 0); // align to 32
    tagMask(0);
}

//-----------------------------------------------------------------------------------
// Draw Gauge indicator
//-----------------------------------------------------------------------------------
void FT800::drawGauge(int16_t x, int16_t y, uint16_t r, uint16_t option, uint32_t colorBCG,
    uint32_t colorNeedle, uint8_t major, uint8_t minor, uint16_t value, uint16_t range, uint8_t tag)
{
    if(tag)
    {
        tagMask(1);
        track(x,y,1,1,tag);
    }
    setColor(colorNeedle);
    setBgColor(colorBCG);
    Write32(RAM_CMD, CMD_GAUGE);
    Write16(RAM_CMD, x);
    Write16(RAM_CMD, y);
    Write16(RAM_CMD, r);
    Write16(RAM_CMD, option);
    Write16(RAM_CMD, major);
    Write16(RAM_CMD, minor);
    Write16(RAM_CMD, value);
    Write16(RAM_CMD, range);
    tagMask(0);
}

//-----------------------------------------------------------------------------------
// Draw gradient from color0 to color1 (use in combination with scissors)
//-----------------------------------------------------------------------------------
void FT800::drawGradient(int16_t x0, int16_t y0, uint32_t color0, int16_t x1, int16_t y1, uint32_t color1)
{
    Write32(RAM_CMD, CMD_GRADIENT);
    Write16(RAM_CMD, x0);
    Write16(RAM_CMD, y0);
    Write32(RAM_CMD, 0x04000000|(color0&0x00FFFFFF));
    Write16(RAM_CMD, x1);
    Write16(RAM_CMD, y1);
    Write32(RAM_CMD, 0x04000000|(color1&0x00FFFFFF));
}
//-----------------------------------------------------------------------------------
// Draw Keys - number of keys=number of letters in string s
//-----------------------------------------------------------------------------------
void FT800::drawKeys(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t option,
        uint32_t colorBG, uint32_t colorTXT, uint8_t font, const char*s, uint8_t tag)
{
    if(tag)
    {
        tagMask(1);
        track(x,y,w,h,tag);
    }
    setFgColor(colorBG);
    setColor(colorTXT);
    Write32(RAM_CMD, CMD_KEYS);
    Write16(RAM_CMD, x);
    Write16(RAM_CMD, y);
    Write16(RAM_CMD, w);
    Write16(RAM_CMD, h);
    if(font>31)font=31;
    if(font<16)font=16;
    Write16(RAM_CMD, font);
    Write16(RAM_CMD, option);
    drawString(s);
    tagMask(0);
}
//-----------------------------------------------------------------------------------
// Scroll bar - if w>h: horizontal else: vertical 
//-----------------------------------------------------------------------------------
void FT800::drawScrollBar(int16_t x, int16_t y, uint16_t w, uint16_t h, uint32_t colorBG, uint32_t colorSCR,
            uint16_t option, uint16_t value, uint16_t size, uint16_t range, uint8_t tag)
{
    if(tag)
    {
        tagMask(1);
        track(x,y,w,h,tag);
    }
    setFgColor(colorBG);
    setBgColor(colorSCR);
    Write32(RAM_CMD, CMD_SCROLLBAR);
    Write16(RAM_CMD, x);
    Write16(RAM_CMD, y);
    Write16(RAM_CMD, w);
    Write16(RAM_CMD, h);
    Write16(RAM_CMD, option);
    Write16(RAM_CMD, value);
    Write16(RAM_CMD, size);
    Write16(RAM_CMD, range);
    tagMask(0);
}
//-----------------------------------------------------------------------------------
// Draw Toggle button
//-----------------------------------------------------------------------------------
void FT800::drawToggle(int16_t x, int16_t y, uint16_t w, uint8_t font,
    uint16_t option, uint32_t colorKnob, uint32_t colorBCG, uint32_t colorTXT,
    uint16_t state, const char *s, uint8_t tag)
{
    if(tag)
    {
        tagMask(1);
        track(x,y,w,font,tag);
    }    
    setFgColor(colorKnob);
    setBgColor(colorBCG);
    setColor(colorTXT);
    Write32(RAM_CMD, CMD_TOGGLE);
    Write16(RAM_CMD, x);
    Write16(RAM_CMD, y);
    Write16(RAM_CMD, w);
    if(font>31)font=31;
    if(font<16)font=16;
    Write16(RAM_CMD, font);
    Write16(RAM_CMD, option);
    Write16(RAM_CMD, state);
    drawString(s);
    tagMask(0);
}
//-----------------------------------------------------------------------------------
// Draw Slider - if w>h: horizontal else: vertical 
//-----------------------------------------------------------------------------------
void FT800::drawSlider(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t option, 
    uint32_t colorR, uint32_t colorKnob, uint32_t colorL, uint16_t value, uint16_t range,  uint8_t tag)
{
    if(tag)
    {
        tagMask(1);
        track(x,y,w,h,tag);
    }
    setColor(colorR);
    setFgColor(colorKnob);
    setBgColor(colorL);
    Write32(RAM_CMD, CMD_SLIDER);
    Write16(RAM_CMD, x);
    Write16(RAM_CMD, y);
    Write16(RAM_CMD, w);
    Write16(RAM_CMD, h);
    Write16(RAM_CMD, option);
    Write16(RAM_CMD, value);
    Write16(RAM_CMD, range);
    Write16(RAM_CMD, 0);
    tagMask(0);
}
//-----------------------------------------------------------------------------------
// Draw Progress bar - if w>h: horizontal else: vertical 
//-----------------------------------------------------------------------------------
void FT800::drawProgress(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t option,
    uint32_t colorBCG, uint32_t colorPRO, uint16_t value, uint16_t range, uint8_t tag)
{
    if(tag)
    {
        tagMask(1);
        track(x,y,w,h,tag);
    }
    setColor(colorBCG);
    setBgColor(colorPRO);
    Write32(RAM_CMD, CMD_PROGRESS);
    Write16(RAM_CMD, x);
    Write16(RAM_CMD, y);
    Write16(RAM_CMD, w);
    Write16(RAM_CMD, h);
    Write16(RAM_CMD, option);
    Write16(RAM_CMD, value);
    Write16(RAM_CMD, range);
    Write16(RAM_CMD, 0); // align to 32
    tagMask(0);
}

//-----------------------------------------------------------------------------------
// Write graphic RAM_G with 1 byte per pixel
//-----------------------------------------------------------------------------------
void FT800::writeRAMG(uint32_t addr, const uint8_t data[], uint32_t lng)
{
    uint32_t  i;
    _ss = 0;
    WriteAddress(addr, ADWRITE);
    for(i = 0; i < lng; i++)  _spi.write(data[i]);
    _ss = 1;
}
//-----------------------------------------------------------------------------------
// Write graphic RAM with 2 bytes per pixel (uint_6t)
//-----------------------------------------------------------------------------------
void FT800::writeRAMG16(uint32_t addr, const uint16_t data[], uint16_t lng)
{
    uint16_t  i;
    _ss = 0;
    WriteAddress(addr, ADWRITE);
    for(i = 0; i < lng; i++)
    {
        _spi.write( data[i] & 0x00FF);      // first byte  //_spi.write((data[i] & 0xFF00)>>8);
        _spi.write((data[i] & 0xFF00)>>8);  // second byte //_spi.write( data[i] & 0x00FF);
    }
    _ss = 1;
}
//-----------------------------------------------------------------------------------
// Draw Char16, n- Number(or Unicode) of Char
//-----------------------------------------------------------------------------------
void FT800::drawChar16(int16_t x, int16_t y, const uint16_t font[], uint16_t n)
{
    uint16_t address;           // font[1]- start address, 0
    address = font[1] + font[2]*(n - font[3]);  // font[2]- next, 40 bytes per char
                                                // font[3]=31, offset
    bitmapSource(address);                      // read bitmap
    bitmapLayout(L1, 2, 20);                    // font[4], font[5], font[6]
    bitmapSize(NEAREST, BORDER, BORDER, 10, 20); // font[7], font[8]
    Write32(RAM_CMD, 0x1F000001);           // begin Bitmap
    Vertex2II(x, y, 0, 0);
    Write32(RAM_CMD, 0x21000000);           // end
}
//-----------------------------------------------------------------------------------
// Draw Char16, n- Number(or Unicode) of Char, with color & scale
//-----------------------------------------------------------------------------------
void FT800::drawChar16(int16_t x, int16_t y, uint32_t color, int16_t scl, uint16_t n)
{
    uint16_t start;
    if (n > 1039)   n -= 784;
    start = 40*(n - 32);
    
    Write32(RAM_CMD, 0x04000000|(color&0x00FFFFFF));// set color    
    bitmapSource(start);       // 
    bitmapLayout(L1, 2, 20);
    if (scl == 2) {
        Write32(RAM_CMD, 0x15000080);   // 128->0x80
        Write32(RAM_CMD, 0x19000080);   // 128->0x80
    }
    if (scl == 1) {
        Write32(RAM_CMD, 0x15000100);   // 256->0x100
        Write32(RAM_CMD, 0x19000100);   // 256->0x100
    }
    bitmapSize(NEAREST, BORDER, BORDER, 10*scl,20*scl);
    Write32(RAM_CMD, 0x1F000001);           // begin Bitmap
    Vertex2II(x, y, 0, 0);
    Write32(RAM_CMD, 0x21000000);           // end
}


//-----------------------------------------------------------------------------------
// Run Touch screen Calibration
//-----------------------------------------------------------------------------------
void FT800::runTouchCalibration(void)
{
    Write32(RAM_CMD, CMD_CALIBRATE);
}

//-----------------------------------------------------------------------------------
// Draw Animated Spinner
//-----------------------------------------------------------------------------------
void FT800::drawAnimSpinner(int16_t x, int16_t y, uint8_t style, uint8_t scale)
{
    Write32(RAM_CMD, CMD_SPINNER);      
    Write16(RAM_CMD, x);
    Write16(RAM_CMD, y);
    if(style>3) style=0;
    Write16(RAM_CMD, style);    
    Write16(RAM_CMD, scale);
}

//-----------------------------------------------------------------------------------
// Draw FTDI animated Lgo
//-----------------------------------------------------------------------------------
void FT800::drawLogo(void)
{
    Write32(RAM_CMD, CMD_LOGO);
}

//-----------------------------------------------------------------------------------
// Wait Logo to finish 
//-----------------------------------------------------------------------------------
void FT800::waitLogo(void)
{
    Write16(REG_CMD_WRITE, get_CMD_Offset());   //executeCommands();
    Sleep(1);                                   //DELAY(1);
    while((Read16(REG_CMD_WRITE) != 0));
    Sleep(1);                                   //DELAY(1); 
    finishList();
}

//-----------------------------------------------------------------------------------
// Draw Screensaver
//-----------------------------------------------------------------------------------
void FT800::drawScreensaver(void)
{
   Write32(RAM_CMD, CMD_SCREENSAVER); 
}

//-----------------------------------------------------------------------------------
// Draw Sketch
//-----------------------------------------------------------------------------------
void FT800::drawSketch(int16_t x, int16_t y, uint16_t w, uint16_t h, uint32_t pointer, uint16_t format)
{
    Write32(RAM_CMD, CMD_SKETCH); 
    Write16(RAM_CMD, x);
    Write16(RAM_CMD, y);    
    Write16(RAM_CMD, w);
    Write16(RAM_CMD, h);
    Write32(RAM_CMD, pointer); 
    Write16(RAM_CMD, format); 
    Write16(RAM_CMD, 0x0000);  //align      
}

//-----------------------------------------------------------------------------------
// Macro
//-----------------------------------------------------------------------------------
void FT800::macro(uint8_t m)
{
    uint32_t macro = 0x25000000;

    macro |= (m&0x01);
    Write32(RAM_CMD, macro); 
}

//-----------------------------------------------------------------------------------
// Stop Spinner, Screensaver or Sketch
//-----------------------------------------------------------------------------------
void FT800::stop(void)
{
    Write32(RAM_CMD, CMD_STOP);      
}