Loading JPG to FT800 screen

Dependencies:   FT800 mbed

Test program to load a JPG to a FT800 controlled lcd screen. First the graphics data have to be load to the FT800 buffer. The FT800 will decode the JPG data into a bitmap. In the second step this bitmap will displayed on the LCD.

main.cpp

Committer:
dreschpe
Date:
2015-02-09
Revision:
1:c603024cbd1d
Parent:
0:a6545392ca42

File content as of revision 1:c603024cbd1d:

/* Demo for mbed Library for FTDI FT800  Enbedded Video Engine "EVE"
 * to show jpg file handling
 * c by Peter Drescher, DC2PD 2014
 * Released under the MIT License: http://mbed.org/license/mit */

#include "mbed.h"
#include "FT_Platform.h"

Serial pc(USBTX, USBRX); // tx, rx
DigitalOut myled(LED1);
FT800 TFT(p11,p12,p13,p14,p15,p16);       // the FT800 is connected to SPI 11-13

LocalFileSystem local("local");           // filesystem to load jpg


/* function to load jpg file from internal filesystem */
/* into FT800 buffer and decode JPG to bitmap         */        
/* return 0 if jpg is ok                              */
/* return x_size and y_size of jpg                    */

int load_jpg(char* filename, ft_int16_t* x_size, ft_int16_t* y_size)
{
    unsigned char pbuff[8291];
    unsigned short marker;
    unsigned short length;
    unsigned char data[4];


    ft_uint16_t blocklen;

    FILE *fp = fopen(filename, "r");
    if(fp == NULL) return (-1);         // connot open file

    // search for 0xFFC0 marker
    fseek(fp, 0, SEEK_END);
    unsigned int Fsize = ftell(fp);
    fseek(fp, 2, SEEK_SET);
    fread(data,4,1,fp);
    marker = data[0] << 8 | data[1];
    length = data[2] << 8 | data[3];
    do {
        if(marker == 0xFFC0) break;
        if(marker & 0xFF00 != 0xFF00) break;
        if (fseek(fp, length - 2,SEEK_CUR) != 0) break;
        fread(data,4,1,fp);
        marker = data[0] << 8 | data[1];
        length = data[2] << 8 | data[3];
    } while(1);
    if(marker != 0xFFC0) return (-2);  // no FFC0 Marker, wrong format no baseline DCT-based JPEG
    fseek(fp, 1,SEEK_CUR);
    fread(data,4,1,fp);
    *y_size = (data[0] << 8 | data[1]);
    *x_size = (data[2] << 8 | data[3]);

    if(*x_size > TFT.FT_DispWidth || *y_size > TFT.FT_DispHeight) return (-3);  // to big to fit on screen

    fseek(fp, 0, SEEK_SET);
    TFT.Ft_Gpu_Hal_WrCmd32(CMD_LOADIMAGE);
    TFT.Ft_Gpu_Hal_WrCmd32(0);//destination address of jpg decode
    TFT.Ft_Gpu_Hal_WrCmd32(0);//output format of the bitmap - default is rgb565
    while(Fsize > 0) {
        /* download the data into the command buffer by 8kb one shot */
        blocklen = Fsize>8192?8192:Fsize;
        /* copy the data into pbuff and then transfter it to command buffer */
        fread(pbuff,1,blocklen,fp);
        Fsize -= blocklen;
        /* copy data continuously into command memory */
        TFT.Ft_Gpu_Hal_WrCmdBuf(pbuff, blocklen); //alignment is already taken care by this api
    }
    fclose(fp);

    return(0);
}

int main()
{
    ft_int16_t x_size,y_size;
    int err;

    TFT.Ft_Gpu_CoCmd_Dlstart();                                   // start a new display command list
    TFT.Ft_App_WrCoCmd_Buffer(CLEAR_COLOR_RGB(255,255,255));      // set the clear color to white
    TFT.Ft_App_WrCoCmd_Buffer(CLEAR(1,1,1));                      // clear buffers -> color buffer,stencil buffer, tag buffer
    TFT.Ft_App_WrCoCmd_Buffer(COLOR_RGB(255,255,255));         // set current color


    err = load_jpg("/local/ARML2.jpg",& x_size,& y_size);      // load graphic data into buffer and decode jpg to bitmap
    if(err != 0) {                                           // something is wrong - display error   
        TFT.Ft_App_WrCoCmd_Buffer(COLOR_RGB(0,0,0));         // set current color
        TFT.Ft_Gpu_CoCmd_Text((TFT.FT_DispWidth/2), TFT.FT_DispHeight/2, 25, OPT_CENTERX, "Error"); // draw Text with font 31
        TFT.Ft_Gpu_CoCmd_Number(50,50,25,OPT_SIGNED,err);

    } else {   // jpg is loaded and decoded into bitmap

        TFT.Ft_App_WrCoCmd_Buffer(BEGIN(BITMAPS));
        TFT.Ft_Gpu_CoCmd_LoadIdentity();
        //TFT.Ft_Gpu_CoCmd_Rotate((45*65536/360));//rotate by 45 degrees anticlock wise
        //TFT.Ft_Gpu_CoCmd_Scale(32768,32768);//scale by  2x2
        TFT.Ft_Gpu_CoCmd_SetMatrix();
        TFT.Ft_App_WrCoCmd_Buffer(VERTEX2F(0,0));

        TFT.Ft_App_WrCoCmd_Buffer(DISPLAY());                                   // Display the image
        TFT.Ft_Gpu_CoCmd_Swap();                                                // Swap the current display list

        TFT.Ft_App_Flush_Co_Buffer();                                           // Download the commands into fifo
        TFT.Ft_Gpu_Hal_WaitCmdfifo_empty();                                     // Wait till coprocessor completes the operation

        wait(2);
        TFT.Ft_Gpu_CoCmd_Dlstart();
        TFT.Ft_App_WrCoCmd_Buffer(BEGIN(BITMAPS));
        TFT.Ft_Gpu_CoCmd_LoadIdentity();
        //TFT.Ft_Gpu_CoCmd_Scale(32768,32768);//scale by  0.5
        //TFT.Ft_Gpu_CoCmd_Translate(50,50);
        //TFT.Ft_Gpu_CoCmd_Rotate((45*65536/360));//rotate by 45 degrees anticlock wise
        //TFT.Ft_Gpu_CoCmd_Scale(32768,32768);//scale by  2x2
        TFT.Ft_Gpu_CoCmd_SetMatrix();
        TFT.Ft_App_WrCoCmd_Buffer(VERTEX2F(50,50));
    }
    TFT.Ft_App_WrCoCmd_Buffer(DISPLAY());                                   // Display the image
    TFT.Ft_Gpu_CoCmd_Swap();                                                // Swap the current display list

    TFT.Ft_App_Flush_Co_Buffer();                                           // Download the commands into fifo
    TFT.Ft_Gpu_Hal_WaitCmdfifo_empty();                                     // Wait till coprocessor completes the operation


}