x

Dependencies:   AP3000 ARM_RTC Beep BurstSPI FRAMSPI FT813 I2CEEBlockDevice I2CList MCP79412 NMEA0183 PCA9745B SDBlockDevice SPIFBlockDevice SystemClock WDT nmea_parser

main.cpp

Committer:
JackB
Date:
15 months ago
Revision:
0:a3b629f6dab5

File content as of revision 0:a3b629f6dab5:

#include "mbed.h"
// string::substr
//#include <iostream>
//#include <string>

#include "main.h"

#include "AP3000.h"
#include "SetupPage.h"

// https://github.com/ARMmbed/sd-driver
// https://github.com/ARMmbed/mbed-os-example-fat-filesystem/blob/master/main.cpp
// https://github.com/RudolphRiedel/FT800-FT813
// https://github.com/RudolphRiedel/FT800-FT813/blob/master/FT8_commands.c
// https://os.mbed.com/components/EVE-FT800/
// https://os.mbed.com/users/dreschpe/code/FT800_2/file/16e22c789f7d/FT_CoPro_Cmds.cpp/
// https://os.mbed.com/users/dreschpe/code/FT800_RGB_demo2/
// https://os.mbed.com/users/dreschpe/code/FT800_RGB_demo2/docs/tip/main_8cpp_source.html
// https://os.mbed.com/users/dreschpe/code/FT800_2/file/16e22c789f7d/FT_CoPro_Cmds.cpp/
// https://os.mbed.com/users/dreschpe/code/FT800_JPG/
// https://os.mbed.com/users/dreschpe/code/FT800_JPG/file/c603024cbd1d/main.cpp/
// https://os.mbed.com/users/cpm219/code/FT810/rev/2d0ef4830603/
// https://os.mbed.com/users/davidchilds/code/FT810_RGB_demo/file/7a29cc1298ef/main.cpp/
// https://os.mbed.com/users/mozillain/code/FT810/
// https://os.mbed.com/teams/The-Best/code/FT800_3/rev/a69ac4d39afd/
// https://www.mikrocontroller.net/topic/395608
// https://os.mbed.com/users/cpm219/code/FT810/docs/ca6a7c6a2f4b/FT__GPU__Hal_8cpp_source.html
// https://os.mbed.com/users/mozillain/code/FT810/file/74108436751e/src/FT_Hal_Utils.cpp/
// https://os.mbed.com/teams/mbed-os-examples/code/mbed-os-example-fat-filesystem/rev/ab69df6f1c47/
// https://os.mbed.com/questions/79055/How-can-I-get-a-library-for-a-SD-card-re/
// https://docs.mbed.com/docs/mbed-os-api-reference/en/latest/APIs/storage/filesystem/
// Existing block devices:
// SDBlockDevice - block device for SD cards.
// SPIFBlockDevice - block device for NOR based SPI flash devices.
// I2CEEBlockDevice - block device for EEPROM based I2C devices.
// HeapBlockDevice - block device backed by the heap for quick testing.
// https://github.com/armmbed/sd-driver
// https://github.com/ARMmbed/spif-driver
// https://github.com/ARMmbed/i2cee-driver
// https://www.mikroe.com/flash-click
// https://www.tindie.com/products/Bazinga/micron-1gb-serial-nor-flash-memory-breakout/
// https://os.mbed.com/teams/Embedded-Artists/wiki/LPC4088DM-Using-Images
// https://github.com/ARMmbed/spif-driver
// http://nl.farnell.com/integrated-silicon-solution-issi/is25lp128-jble/nor-flash-memory-128mbit-133mhz/dp/2787056 € 2,36
// http://nl.farnell.com/cypress-semiconductor/s25fl128lagmfv010/flash-memory-128mbit-133mhz-soic/dp/2771141 € 3,81
// http://nl.farnell.com/spansion/s25fl256sagmfi011/memory-flash-256mb-16soic/dp/2340545?st=Flash%20Memory%20NOR
// http://nl.farnell.com/cypress-semiconductor/s25fl512sagmfi011/memory-flash-512mbit-16soic/dp/2136298?st=Flash%20Memory%20NOR%20512mbit
// http://nl.farnell.com/cypress-semiconductor/s25fl128lagmfm010/flash-memory-aec-q100-128mbit/dp/2771145 € 5,54
// https://os.mbed.com/users/Decimus/code/FRAMSPI/
// http://www.ftdicommunity.com/index.php?board=3.0
// https://github.com/nopnop2002/STM32_GD2/blob/master/STM32_GD2.cpp
// http://www.ftdichip.com/Support/Documents/AppNotes/AN_269_FT_App_Signature.pdf
// http://forum.arduino.cc/index.php?topic=296126.0
// https://www.youtube.com/watch?v=2FKN5UdqCKg
// https://os.mbed.com/users/Sissors/code/BurstSPI/


//#define BAUD_RATE 9600
//// NUCLEO-F746ZG
//#define USB_TX          SERIAL_TX   // PD_8  USART3 TX
//#define USB_RX          SERIAL_RX   // PD_9  USART3 RX
//
//#define BUFFER_SIZE 8192
//
//#define BUTTON_ACCEPT_ALARM_TAG 1
//#define BUTTON_ACCEPT_HORN_TAG 2
//#define BUTTON_SET_TAG 3
//#define BUTTON_DIM_TAG 4
//
//#define TFT_MOSI PA_7
//#define TFT_MISO PA_6
//#define TFT_SCLK PA_5
//#define TFT_CS   PC_7
//#define TFT_INT  PB_4
//#define TFT_PD   PA_4
//
//// Pinout on Nucleo-F746ZG
//#define SD_MOSI  PE_14
//#define SD_MISO  PE_13
//#define SD_SCLK  PE_12
//#define SD_CS    PE_11
//
//#define SF_MOSI  PB_15
//#define SF_MISO  PC_2
//#define SF_SCLK  PB_13
//#define SF_CS    PB_12
//
//#define EE_SDA PB_9
//#define EE_SCL PB_8
//#define EE_ADDR 0xa0
//#define EE_SIZE 32*1024
//#define EE_BLOCK_SIZE 16
//
//#define MBED_CONF_SD_SPI_TRANSFER_FREQ 40000000
//
//#define INDICATOR_RUN_STATUS_OFF 0
//#define INDICATOR_RUN_STATUS_RUNNING 1
//#define INDICATOR_RUN_STATUS_WARNING 2
//#define INDICATOR_RUN_STATUS_OFF_RED 3
//
//#define INDICATOR_ALARM_STATUS_OFF 0
//#define INDICATOR_ALARM_STATUS_WARNING 1
//#define INDICATOR_ALARM_STATUS_FAILURE 2
//
Serial pc(USBTX, USBRX);

DigitalOut myled(LED1);

// Setup the watchdog timer
WDT wdt;

FT813 TFT(TFT_MOSI, TFT_MISO, TFT_SCLK, TFT_CS, TFT_INT, TFT_PD);  // mosi, miso, sck, ss, int, pd     // the FT813 is connected to SPI 11-13

// PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, PinName ssel=NC, int mode=0
//QSPI qspi(PF_8, PF_9, PF_7, PF_6, PF_10, PB_10);
DigitalOut myledPF8(PF_8);

//HeapBlockDevice bd(128 * 512, 512);

// Instantiate the SDBlockDevice by specifying the SPI pins connected to the SDCard socket.
SDBlockDevice sd(MBED_CONF_SD_SPI_MOSI, MBED_CONF_SD_SPI_MISO, MBED_CONF_SD_SPI_CLK, MBED_CONF_SD_SPI_CS, MBED_CONF_SD_SPI_TRANSFER_FREQ);

// Create flash device on SPI bus with PTE5 as chip select
SPIFBlockDevice spif(SF_MOSI, SF_MISO, SF_SCLK, SF_CS, 100000); // mosi, miso, sclk, cs, freq

// Create EEPROM device on I2C bus with 32kbytes of memory
//I2CEEBlockDevice ee(EE_SDA, EE_SCL, EE_ADDR, EE_SIZE, EE_BLOCK_SIZE); // sda, scl, addr, size, block, freq

//I2C i2c(EE_SDA, EE_SCL); // sda, scl
//
//I2CList I2C_List(EE_SDA, EE_SCL); // sda, scl

//SPI spi(SF_MOSI, SF_MOSI, SF_SCLK); // mosi, miso, sclk
//FRAMSPI fram(spi, SF_CS);

BurstSPI bspi(SF_MOSI, SF_MISO, SF_SCLK); // PinName mosi, PinName miso, PinName sclk
SPI      rspi(SF_MOSI, SF_MISO, SF_SCLK); // PinName mosi, PinName miso, PinName sclk

FATFileSystem fs("fs");

//AP3000 ap3000(&TFT);

Timer timer;

NMEA0183 nmea0183;

MCP79412 rtc(EE_SDA, EE_SCL); // sda, scl

uint8_t setting_block_size;

struct t_setting {
    uint8_t version;
    char name[32];
    double value;
} setting = {
    1,
    "Hello World!",
    3.1415926536
};

//struct button {
//    uint8_t accept_alarm_pressed;
//    uint8_t accept_horn_pressed;
//    uint8_t set_pressed;
//    uint8_t dim_pressed;
//};
//
//struct indicator {
//    uint8_t md_main_running;
//    uint8_t rb_main_phase_fail;
//    uint8_t rb_main_main_power;
//    uint8_t rb_main_ctrl_power;
//    uint8_t rb_main_oil_press;
//    uint8_t rb_main_hydr_lock;
//    uint8_t rb_main_overload;
//    uint8_t rb_main_oil_level;
//    uint8_t rb_main_oil_filter;
//    uint8_t rb_main_oil_temp;
//    
//    uint8_t md_aux_running;
//    uint8_t rb_aux_phase_fail;
//    uint8_t rb_aux_main_power;
//    uint8_t rb_aux_ctrl_power;
//    uint8_t rb_aux_oil_press;
//    uint8_t rb_aux_hydr_lock;
//    uint8_t rb_aux_overload;
//    uint8_t rb_aux_oil_level;
//    uint8_t rb_aux_oil_filter;
//    uint8_t rb_aux_oil_temp;
//    
//    uint8_t rb_fu_failure;
//    uint8_t rb_used;
//    uint8_t rb_main_most_used;
//    uint8_t rb_aux_most_used;    
//};
//
//struct button my_button;
    
typedef struct {
    char name[64];
    uint16_t fmt;
    uint16_t w;
    uint16_t h;
} image;

//image images[128];

uint16_t imageCount = 0;

    ft_int16_t x_size,y_size;
    int err;

void return_error(int ret_val){
  if (ret_val)
    printf("\033[1;31mFailure. %d\033[0m\n", ret_val);
  else
    printf("\033[1;32mdone.\033[0m\n");
}

void errno_error(void* ret_val){
  if (ret_val == NULL)
    printf(" \033[1;31mFailure. %d\033[0m\n", errno);
  else
    printf(" \033[1;32mdone.\033[0m\n");
}

// global Vars
unsigned int r,b,g;


//int getImageIndexFromName(char *name) {
//    for (int i = 0; i < imageCount; i++) {
//        if(strstr(images[i].name, name) != NULL) {
//            return i;
//        }
//    }
//    return -1;
//}


// function to convert hue , saturation and  value to RGB
// see http://en.wikipedia.org/wiki/HSL_and_HSV
void hsv2rgb(float H, float S, float V)
{
    float f, h, p, q, t;
    int i;
    if( S == 0.0) {
        r = V * 255;  
        g = V * 255;
        b = V * 255;
        return;
    }
    if(H > 360.0) H = 0.0;   // check values
    if(S > 1.0) S = 1.0; 
    if(S < 0.0) S = 0.0;
    if(V > 1.0) V = 1.0;
    if(V < 0.0) V = 0.0;
    
    h = H / 60.0;
    i = (int) h;
    f = h - i;
    p = V * (1.0 - S);
    q = V * (1.0 - (S * f));
    t = V * (1.0 - (S * (1.0 - f)));
 
    switch(i) {
        case 0:
            r = V * 255;  
            g = t * 255;
            b = p * 255;
            break;
        case 1:
            r = q * 255;
            g = V * 255;
            b = p * 255;
            break;
        case 2:
            r = p * 255;
            g = V * 255;
            b = t * 255;
            break;
        case 3:
            r = p * 255;
            g = q * 255;
            b = V * 255;
            break;
        case 4:
            r = t * 255;
            g = p * 255;
            b = V * 255;
            break;
        case 5:
        default:
            r = V * 255;
            g = p * 255;
            b = q * 255;
            break;
    }  
}


/***************************************************************************/
/* Show a Screen with Text for 5 seconds                                   */
/* A spinner shows the delay                                               */
/***************************************************************************/

ft_void_t Start_Screen(ft_char8_t *str)
{
    TFT.DLstart();                              // start a new display command list
    TFT.DL(CLEAR_COLOR_RGB(0xff, 0xff, 0xff));       // set the clear color to white
    TFT.DL(CLEAR(1, 1, 1));                       // clear buffers -> color buffer,stencil buffer, tag buffer
    
    TFT.DL(COLOR_RGB(0x80, 0x80, 0x00));          // set current color
    TFT.Text((TFT.DispWidth/2), TFT.DispHeight/2, 31, OPT_CENTERX, str); // draw Text with font 31
    TFT.DL(COLOR_RGB(0xFF, 0x00, 0x00));          // change current color
    TFT.Spinner((TFT.DispWidth/2), TFT.DispHeight/4, 0, 0);  // draw a animated spinner

    TFT.DL(DISPLAY());                          // Display the image
    TFT.Swap();                                 // Swap the current display list
    TFT.Flush_Co_Buffer();                      // Download the command list into fifo

    TFT.WaitCmdfifo_empty();                    // Wait till coprocessor completes the operation
    TFT.Sleep(1000);                            // Wait 5 s to show
}

void screen_cm3000(void)
{
    TFT.DLstart();                              // start a new display command list
    TFT.DL(CLEAR_COLOR_RGB(0x21, 0x21, 0x21));        // set current color to white
    TFT.DL(CLEAR(1, 1, 1));                     // clear buffers -> color buffer,stencil buffer, tag buffer
    TFT.DL(COLOR_RGB(0xff, 0xff, 0xff));        // set current color to white

    // Bitmap
    // BACKGROUND-01.png
    TFT.DL(TAG(1));                             // assign TAG
    //  Narrow On button, 100x132, Address 0-26400
    TFT.DL(BEGIN(BITMAPS));                  
    TFT.DL(BITMAP_SOURCE(TFT.GetBitmapAddress(0)));
    TFT.DL(BITMAP_LAYOUT(ARGB4, 100*2, 132));    // <------- this distorts the colors
    TFT.DL(BITMAP_SIZE(NEAREST, BORDER, BORDER, 100, 132));
    TFT.DL(COLOR_RGB(0xff, 0xff, 0xff)); // all colors in bitmap at 100%
    TFT.DL(VERTEX2II(20, 290, 0, 0));    

//    TFT.SetRotate(0); // Standard landscape
//    TFT.SetRotate(1); // Rotate 180 to landscape (upside down)
//    TFT.SetRotate(2); // Rotate 90 CCW to portrait
//    TFT.SetRotate(3); // Rotate 90 CW to portrait
//    TFT.SetRotate(4); // Mirror over landscape X
//    TFT.SetRotate(5); // Mirror over landscape Y
//    TFT.SetRotate(6); // Rotate 90 CCW to portrait and mirror over portrait X
//    TFT.SetRotate(7); // Rotate 90 CW to portrait and mirror over portrait X
    
    TFT.DL(DISPLAY());                          // Display the image
    TFT.Swap();                                 // Swap the current display list
    TFT.Flush_Co_Buffer();                      // Download the command list into fifo
    TFT.WaitCmdfifo_empty();                    // Wait till coprocessor completes the operation
}

// construct the screen and downloasd it to the LCD
void screen_1(unsigned int color, unsigned int bright, unsigned int tagoption1, unsigned int tagoption2, unsigned int tagoption3, unsigned int tagoption4)
{
    TFT.DLstart();                              // start a new display command list
    TFT.DL(CLEAR_COLOR_RGB(0x21, 0x21, 0x21));        // set current color to white
    TFT.DL(CLEAR(1, 1, 1));                     // clear buffers -> color buffer,stencil buffer, tag buffer
    TFT.DL(COLOR_RGB(0xff, 0xff, 0xff));        // set current color to white
    
    // Default widget colors
    TFT.SetThemeDefaultColor();
//    TFT.GradColor(COLOR_RGB(0xff, 0xff, 0xff)); // Default 0xffffff
//    TFT.FgColor(COLOR_RGB(0x00, 0x38, 0x70));   // Default 0x003870    0 56 112
//    TFT.BgColor(COLOR_RGB(0x00, 0x20, 0x40));   // Default 0x002040    0 32 64

    TFT.DL(TAG(1));                             // assign TAG value 1
//    TFT.FgColor(COLOR_RGB(0x00, 0x00, 0xff));   // forground color red
//    TFT.BgColor(COLOR_RGB(0x00, 0x00, 0x80));
    TFT.Dial(249, 86, 55, 0, color);            // dial for color 
    
    TFT.DL(TAG(2));                             // assign TAG value 2
//    TFT.FgColor(COLOR_RGB(0x00, 0x00, 0xff));   // forground color red
//    TFT.BgColor(COLOR_RGB(0x00, 0x00, 0x80));
    TFT.Slider(196, 215, 236, 21, 0, bright , 255); // slider for brightness 
    TFT.DL(COLOR_RGB(0xff, 0xff, 0xff));        // set current color to white
    TFT.Text(22, 84, 30, 0, "Color");           // text Color
    TFT.Text(22, 208, 30, 0, "Brightness");     // text Brightness

    // TFT.Button(ft_int16_t x, ft_int16_t y, ft_int16_t w, ft_int16_t h, ft_int16_t font, ft_uint16_t options, const ft_char8_t* s);
    TFT.DL(TAG(3)); // This is tag value for button
    // 0 = 3D, OPT_FLAT
    TFT.SetThemeColor(COLOR_RGB(0xff, 0x00, 0x00));
//    TFT.GradColor(COLOR_RGB(0xff, 0xff, 0xff));
//    TFT.FgColor(COLOR_RGB(0x70, 0x00, 0x00));
//    TFT.BgColor(COLOR_RGB(0x38, 0x00, 0x00));
    TFT.Button(500, 20, 200, 50, 31, tagoption1, "25%");

    TFT.DL(TAG(4)); // This is tag value for button
    TFT.SetThemeColor(COLOR_RGB(0x00, 0xff, 0x00));
//    TFT.GradColor(COLOR_RGB(0xff, 0xff, 0xff));
//    TFT.FgColor(COLOR_RGB(0x00, 0x70, 0x00));
//    TFT.BgColor(COLOR_RGB(0x00, 0x40, 0x00));
    TFT.Button(500, 80, 200, 50, 31, tagoption2, "50%");
    
    TFT.DL(TAG(5)); // This is tag value for button
    TFT.SetThemeColor(COLOR_RGB(0x00, 0x7f, 0xff));
//    TFT.GradColor(COLOR_RGB(0xff, 0xff, 0xff));
//    TFT.FgColor(COLOR_RGB(0x00, 0x38, 0x70));
//    TFT.BgColor(COLOR_RGB(0x00, 0x20, 0x40));
    TFT.Button(500, 140, 200, 50, 31, tagoption3, "75%");

//    // Default
//    TFT.SetThemeDefaultColor();
////    TFT.GradColor(COLOR_RGB(0xff, 0xff, 0xff)); // Default 0xffffff
////    TFT.FgColor(COLOR_RGB(0x00, 0x38, 0x70));   // Default 0x003870
////    TFT.BgColor(COLOR_RGB(0x00, 0x20, 0x40));   // Default 0x002040
//
//
    TFT.DL(POINT_SIZE(100));                    // color point around the dial 
    TFT.DL(BEGIN(POINTS));                  
    TFT.DL(COLOR_RGB(0x00, 0x0, 0xff));          // color of next point 
    TFT.DL(VERTEX2II(183, 47, 0, 0));           // set point x,y 
    TFT.DL(COLOR_RGB(0xff, 0x00, 0x00)); 
    TFT.DL(VERTEX2II(249, 162, 0, 0));
    TFT.DL(COLOR_RGB(0xff, 0x00, 0xff)); 
    TFT.DL(VERTEX2II(183, 123, 0, 0));
    TFT.DL(COLOR_RGB(0xff, 0xff, 0x00)); 
    TFT.DL(VERTEX2II(317, 123, 0, 0));
    TFT.DL(COLOR_RGB(0x00, 0xff, 0xff)); 
    TFT.DL(VERTEX2II(249, 11, 0, 0));
    TFT.DL(COLOR_RGB(0x00, 0xff, 0x00)); 
    TFT.DL(VERTEX2II(317, 50, 0, 0));
    TFT.DL(SCISSOR_XY(10, 10));                 // define sub area starting at 10,10
    TFT.DL(SCISSOR_SIZE(50, 50));               // size 50, 50
    hsv2rgb(color / 65536.0 * 360, 1.0, bright / 255.0);  // calculate rgb color from settings 
    TFT.DL(CLEAR_COLOR_RGB(r, b, g));           // set filling color to r,g,b
    TFT.DL(CLEAR(1, 1, 1));                     // fill the area  
    
    // Clipping area
    TFT.DL(SCISSOR_XY(0, 0));                 // define area starting at 380,220
    TFT.DL(SCISSOR_SIZE(480, 800));             // size 480, 800
    TFT.DL(COLOR_RGB(0xff, 0xff, 0xff)); 
    
    // Rectangle
    TFT.DL(TAG(6));                             // assign TAG
    TFT.DL(COLOR_RGB(0x80, 0x00, 0xff));                 // set current color to red
    TFT.Rect(60, 270, 260, 340, 5);

    // Circle
    TFT.DL(TAG(7));                             // assign TAG
    TFT.DL(COLOR_RGB(0x00, 0xff, 0x00));        // set current color to green
    TFT.Point(400, 340, 60);

    // Rectangle
    TFT.DL(TAG(8));                             // assign TAG
    TFT.DL(COLOR_RGB(r, b, g));                 // set current color to red
    TFT.Rect(160, 305, 360, 440, 20);
    TFT.DL(COLOR_RGB(0x00, 0x00, 0x00));        // set current color to black
    TFT.Rect(165, 310, 355, 435, 10);

    // Line
    TFT.DL(TAG(9));                             // assign TAG
    TFT.DL(COLOR_RGB(0x00, 0x00, 0xff));        // set current color to blue
    TFT.Line(440, 310, 680, 230 + r, 20);
    
    // Circle
    TFT.DL(TAG(10));                             // assign TAG
    TFT.DL(COLOR_RGB(0xff, 0x00, 0xff));        // set current color to green
    TFT.Point(600, 340, 80);
//    TFT.DL(TAG(10));                             // assign TAG
    TFT.DL(COLOR_RGB(0x00, 0x00, 0x00));        // set current color to green
    TFT.Point(600, 340, 70);
    
    // Bitmap
    TFT.DL(TAG(11));                             // assign TAG
    //  Narrow On button, 100x132, Address 0-26400
    TFT.DL(COLOR_RGB(0xff, 0xff, 0xff));  // set the clear color to white
    TFT.DL(BEGIN(BITMAPS));                  
//    TFT.DL(BITMAP_SOURCE(TFT.GetBitmapAddress(1)));
//    TFT.DL(BITMAP_LAYOUT(ARGB4, 100*2, 132));    // <------- this distorts the colors
//    TFT.DL(BITMAP_SIZE(NEAREST, BORDER, BORDER, 100, 132));
//    TFT.DL(COLOR_RGB(0xff, 0xff, 0xff)); // all colors in bitmap at 100%
//    TFT.DL(VERTEX2II(20, 290, 0, 0));    

//    int index = 0;
    if (tagoption4 == 0) {
//        index = getImageIndexFromName("SwitchOn_100x132");
        TFT.ShowBitmapByName("SwitchOn_100x132", 20, 290);
    }
    else {
//        index = getImageIndexFromName("SwitchOff_100x132");
        TFT.ShowBitmapByName("SwitchOff_100x132", 20, 290);
    }
//    TFT.ShowBitmapAtAddress(images[index].addr, images[index].fmt, 20, 290, images[index].w, images[index].h);


//    TFT.SetRotate(0); // Standard landscape
//    TFT.SetRotate(1); // Rotate 180 to landscape (upside down)
//    TFT.SetRotate(2); // Rotate 90 CCW to portrait
//    TFT.SetRotate(3); // Rotate 90 CW to portrait
//    TFT.SetRotate(4); // Mirror over landscape X
//    TFT.SetRotate(5); // Mirror over landscape Y
//    TFT.SetRotate(6); // Rotate 90 CCW to portrait and mirror over portrait X
//    TFT.SetRotate(7); // Rotate 90 CW to portrait and mirror over portrait X
    
    TFT.DL(DISPLAY());                          // Display the image
    TFT.Swap();                                 // Swap the current display list
    TFT.Flush_Co_Buffer();                      // Download the command list into fifo
    TFT.WaitCmdfifo_empty();                    // Wait till coprocessor completes the operation
}

// construct the screen and downloasd it to the LCD
void screen_2(unsigned int r, unsigned int g, unsigned int b)
{
    TFT.DLstart();                              // start a new display command list
    TFT.DL(CLEAR(1, 1, 1));                     // clear buffers -> color buffer,stencil buffer, tag buffer
    TFT.DL(COLOR_RGB(0xff, 0xff, 0xff));        // set current color to white
    TFT.DL(TAG(1));                             // assign TAG value 1
    TFT.FgColor(COLOR_RGB(0xff, 0x00, 0x00));   // forground color red
    TFT.Slider(140, 81, 310, 14, 0, r, 255);    // slider for red
    TFT.DL(TAG(2));                             // assign TAG value 2
    TFT.FgColor(COLOR_RGB(0x00, 0xff, 0x00));   // forground color green
    TFT.Slider(140, 133, 310, 14, 0, g, 255);   // slider for green
    TFT.DL(TAG(3));                             // assign TAG value 3
    TFT.FgColor(COLOR_RGB(0x00, 0x00, 0xff));   // forground color blue
    TFT.Slider(139, 185, 310, 14, 0, b, 255);   // slider for blue
    TFT.DL(COLOR_RGB(0xff, 0x00, 0x00));        // set current color to red
    TFT.Text(82, 69, 30, 0, "R");               // text R
    TFT.DL(COLOR_RGB(0x00, 0xff, 0x00));        // set current color to green
    TFT.Text(82, 120, 30, 0, "G");              // text G
    TFT.DL(COLOR_RGB(0x00, 0x00, 0xff));        // set current color to blue
    TFT.Text(82, 174, 30, 0, "B");              // text B
    TFT.DL(SCISSOR_XY(10, 10));                 // define area starting at 10,10
    TFT.DL(SCISSOR_SIZE(50, 50));               // size 50,50
    TFT.DL(CLEAR_COLOR_RGB(r, g, b));             // set clear color to r,g,b
    TFT.DL(CLEAR(1, 1, 1));                     // fill the area
    
    // Clipping area
    TFT.DL(SCISSOR_XY(0, 220));                 // define area starting at 380,220
    TFT.DL(SCISSOR_SIZE(799, 259));             // size 50,50
    // Rectangle
    TFT.DL(COLOR_RGB(0xff, 0x00, 0x00));        // set current color to red
    TFT.Rect(160, 290, 360, 440, 20);
    TFT.DL(COLOR_RGB(0x00, 0x00, 0x00));        // set current color to black
    TFT.Rect(165, 295, 355, 435, 10);
    // Circle
    TFT.DL(COLOR_RGB(0x00, 0xff, 0x00));        // set current color to green
    TFT.Point(400, 260, 40);
    // Line
    TFT.DL(COLOR_RGB(0x00, 0x00, 0xff));        // set current color to blue
    TFT.Line(440, 270, 680, 400, 20);
    
    TFT.DL(DISPLAY());                          // Display the image
    TFT.Swap();                                 // Swap the current display list
    TFT.Flush_Co_Buffer();                      // Download the command list into fifo
    TFT.WaitCmdfifo_empty();                    // Wait till coprocessor completes the operation
}

void substring(char *s, char *d, int pos, int len) //usage: substring(Src, Dst, Pos, Len);
{
//usage: substring(Source, Destination, pos, len);
    char *t;
 
    s=s+pos;
    t=s+len;
    while (s!=t) {
        *d=*s;
        s++;
        d++;
    }
    *d='\0';
}

int main() {
    pc.baud(BAUD_RATE);
    printf("\n\n\n");
    printf("----------------------------------\n");
    printf("20180621_FT800_RGB_demo2\n");
    printf("" __DATE__ " " __TIME__ "\n");
#if defined(MBED_MAJOR_VERSION)
    printf("Using \033[1;37mMbed OS %d.%d.%d\033[0m\n", MBED_MAJOR_VERSION, MBED_MINOR_VERSION, MBED_PATCH_VERSION);
#else
    printf("Using Mbed OS from master.\n");
#endif
    printf("CPU SystemCoreClock: \033[1;37m%d MHz\033[0m\n", SystemCoreClock/1000000);
    printf("----------------------------------\n");

    // https://www.unixtimestamp.com/
    set_time(1531525845);  // Set RTC time to Wed, 28 Oct 2009 11:35:37

    uint8_t second     = 0;
    uint8_t minute     = 0;
    uint8_t hour       = 0;
    uint8_t dayOfWeek  = 1;      // Will be determined
    uint8_t dayOfMonth = 16;
    uint8_t month      = 7;
    uint8_t year       = 18;
    printf("%02d-%02d-%02d %02d:%02d:%02d\n", dayOfMonth, month, year, hour, minute, second);
    
//    struct tm *t;
//    *t = rtc.setSystemDateTime(second, minute, hour, dayOfMonth, month, year);
//    printf("-> Debug %d %02d-%02d-%03d %02d:%02d:%02d\n", t->tm_wday, t->tm_mday, t->tm_mon, t->tm_year, t->tm_hour, t->tm_min, t->tm_sec);

    struct tm t;
    t = rtc.setSystemDateTime(second, minute, hour, dayOfMonth, month, year);
    printf("-> Debug %d %02d-%02d-%03d %02d:%02d:%02d\n", t.tm_wday, t.tm_mday, t.tm_mon, t.tm_year, t.tm_hour, t.tm_min, t.tm_sec);

    time_t secondsEpoch = time(NULL);
    
    printf("Time as seconds since January 1, 1970 = %d\n", secondsEpoch);
    
    printf("Time as a basic string = %s", ctime(&secondsEpoch));
    
    char buffer[32];
    strftime(buffer, 32, "%a %d-%m-%Y %H:%M:%S\n", localtime(&secondsEpoch));
    printf("Time: %s", buffer);
//    wait(5);
    secondsEpoch = time(NULL);
    strftime(buffer, 32, "%a %d-%m-%Y %H:%M:%S\n", localtime(&secondsEpoch));
    printf("Time: %s", buffer);

    printf("year %d\n", year);
    time_t seconds2 = rtc.convertDateTimeToTimestamp(second, minute, hour, dayOfMonth, month, year);
    printf("seconds2 %d\n", seconds2);

    uint8_t Weekday = rtc.getWeekdayFromDate(dayOfMonth, month, year);
    printf("Weekday %d\n", Weekday);
    
    rtc.setRtcFromTm(&t);

//    uint8_t second = 0;
//    uint8_t minute = 18;
//    uint8_t hour = 1;
//    uint8_t dayOfWeek = 6;
//    uint8_t dayOfMonth = 14;
//    uint8_t month = 7;
//    uint8_t year = 18;
//    printf("%02d-%02d-%02d %02d:%02d:%02d\n", dayOfMonth, month, year, hour, minute, second);
//    rtc.setSystemDateTime(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
//    wait(5);
    rtc.getSystemDateTime(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
    printf("%d %02d-%02d-%02d %02d:%02d:%02d\n", dayOfWeek, dayOfMonth, month, year, hour, minute, second);
//    wait(5);
    rtc.getSystemDateTime(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
    printf("%d %02d-%02d-%02d %02d:%02d:%02d\n", dayOfWeek, dayOfMonth, month, year, hour, minute, second);
    

// https://os.mbed.com/questions/77039/Use-external-clock-signal-HSE-in-Nucleo-/



    switch (__HAL_RCC_GET_SYSCLK_SOURCE())
    {
//    case RCC_SYSCLKSOURCE_STATUS_MSI:
//        printf("MSI used as system clock.\r\n");
//        break;
    case RCC_SYSCLKSOURCE_STATUS_HSI:
        printf("HSI used as system clock.\r\n");
        break;
    case RCC_SYSCLKSOURCE_STATUS_HSE:
        printf("HSE used as system clock.\r\n");
        break;
    case RCC_SYSCLKSOURCE_STATUS_PLLCLK:
        printf("PLL used as system clock.\r\n");
//        if ((RCC->CFGR & RCC_CFGR_PLLSRC) == RCC_CFGR_PLLSRC_HSE) {
//            printf("HSE oscillator clock selected as PLL input clock.\r\n");
//        }
//        else {
//            printf("HSI16 oscillator clock selected as PLL input clock.\r\n");
//        }
        break;
    }
 
     printf("HCE Information: \r\n");
 
    if (READ_BIT(RCC->CR, RCC_CR_HSEON)){
        printf("RCC_CR_HSEON = 1 \r\n");
    }
    else{
        printf("RCC_CR_HSEON = 0 \r\n");
    }
 
    if (READ_BIT(RCC->CR, RCC_CR_HSEBYP)){
        printf("RCC_CR_HSEBYP = 1 \r\n");
    }
    else{
        printf("RCC_CR_HSEBYP = 0 \r\n");
    }
 
    if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) {
        printf("RCC_FLAG_HSERDY = 1 \r\n");
    }
    else {
        printf("RCC_FLAG_HSERDY = 0 \r\n");
    }
 
 
    printf("\n");
//    I2C_List.List();

//    printf("Searching for I2C devices...\n");
//    int count = 0;
//    for (int address=0; address<256; address+=2) {
//        if (!i2c.write(address, NULL, 0)) { // 0 returned is ok
//            count++;
//            printf("%2d: 0x%02X\n", count, address);
//        }
//    }
//    printf("%d I2C devices found\n", count);    

    wdt.Configure(WDT_TIMEOUT);  

    timer.start();
    double my_time = timer.read();

    int error = 0;
    printf("Welcome to the FAT32 filesystem example.\n");
    
//    printf("Formatting a FAT, SD-Card filesystem... "); // "Formatting a FAT, RAM-backed filesystem... "
//    fflush(stdout);
//    error = FATFileSystem::format(&sd);
//    return_error(error);
    
    printf("Mounting the filesystem on \"/fs\"... ");
    fflush(stdout);
    // Initialize the SD card device and print the memory layout
    sd.init();
    error = fs.mount(&sd);
    return_error(error);
    printf("sd size: %llu Bytes.\n",         sd.size());
//    printf("sd read size: %llu\n",    sd.get_read_size());
//    printf("sd program size: %llu\n", sd.get_program_size());
//    printf("sd erase size: %llu\n",   sd.get_erase_size());

//    // Initialize the SPI flash device and print the memory layout
//    spif.init();
//    printf("spif size: %llu\n",         spif.size());
//    printf("spif read size: %llu\n",    spif.get_read_size());
//    printf("spif program size: %llu\n", spif.get_program_size());
//    printf("spif erase size: %llu\n",   spif.get_erase_size());

//    printf("Mounting the filesystem on \"/eefs\"... ");
    fflush(stdout);

//    // Initialize the EEPROM and print the memory layout
//    ee.init();
////    error = eefs.mount(&i2cee);
////    return_error(error);
//    printf("ee size: %llu Bytes.\n",         ee.size());
//    printf("ee read size: %llu\n",    ee.get_read_size());
//    printf("ee program size: %llu\n", ee.get_program_size());
//    printf("ee erase size: %llu\n",   ee.get_erase_size());

//    printf("Send 1000 SPI packets as fast as possible...\n");
//    uint8_t data[1000];
//    for (int i = 0; i<1000; i++)
//        data[i] = (uint8_t) (i & 0xff);
//     //Send 1000 SPI packets as fast as possible
//    bspi.setFormat();
//    timer.reset();
//    for (int i = 0; i<1000; i++)
//        bspi.fastWrite(data[i]);
//    my_time = timer.read();
//    bspi.clearRX();
//    printf("Time: %f.\n", my_time);
//
//    rspi.format(8, 0);                  // 8 bit spi mode 0
//    rspi.frequency(54000000);
//    timer.reset();
//    for (int i = 0; i<1000; i++)
//        rspi.write(data[i]);
//    my_time = timer.read();
//    printf("Time: %f.\n", my_time);

//    printf("----------\n");
//    printf("EEPROM string...\n");
//    timer.reset();
//    // --- Save a string into EEPROM and read it back ---
//    uint8_t block_size = 32;
//    ee.erase(0, block_size);
//    // Write "Hello World!" to the first block
//    char hello[] = "Hello World!";
//    printf("Save \"%s\"\n", hello);
//    char *buffer = (char*)malloc(block_size);
//    sprintf(buffer, "%s", hello);
//    // Program EEPROM
//    ee.program(buffer, 0, block_size);
//    sprintf(buffer, "empty\n"); // empty buffer, not nessesary but helps when debugging
//    // Read back what was stored
//    ee.read(buffer, 0, block_size);
//    printf("Read \"%s\"\n", buffer);
//    my_time = timer.read();
//    printf("Time: %f.\n", my_time);
//
//
//    printf("----------\n");
//    printf("EEPROM struct...\n");
//    timer.reset();
//    // --- Save a structure into EEPROM and read it back ---
//    // No. of bytes to be stored, but topped up to be multiplied by block size
//    unsigned int setting_block_size = ceil(sizeof(setting)/(double)EE_BLOCK_SIZE)*EE_BLOCK_SIZE;
//    printf("No. of bytes to be stored: %d\n", setting_block_size);
//    // Temporary buffer
//    char *buffer2 = (char*)malloc(setting_block_size);
//    // Save the struct to EEPROM
//    setting.version = 56;
//    printf("Save struct version: %u, name: %s, value: %3.10lf\n", setting.version, setting.name, setting.value);
//    memcpy(buffer2, &setting, sizeof(setting));
//    // Program EEPROM
//    ee.program(buffer2, 0, setting_block_size);
//    // Read back what was stored
//    t_setting tmp; // Re-make the struct
//    memset(buffer2, 0, sizeof(buffer2)); // empty buffer, not nessesary but helps when debugging
//    // Read the struct from the EEPROM
//    if (ee.read(buffer2, 0, setting_block_size ) == 0) { // get data into buffer
//        // Convert what we read into struct
//        memcpy(&tmp, buffer2, sizeof(tmp)); // copy only size of struct not setting_block_size
//        printf("Read struct version: %u, name: %s, value: %3.10lf\n", tmp.version, tmp.name, tmp.value);
//    } else {
//        printf("Error when reading\n");
//    }
//    my_time = timer.read();
//    printf("Time: %f.\n", my_time);

//    
//    char filename[] = "/fs/my_text_file.txt";
//    
//    printf("Opening a new file, \"/%s\"...", filename);
//    fflush(stdout);
//    FILE* fd = fopen(filename, "w");
//    errno_error(fd);
//    
//    printf("Writing text to a file:\n");
//    char text[] = "Hello world!\nThis is just some text...\n";
//    printf("\033[1;37m%s\033[0m", text);
//    fprintf(fd, "%s", text);
//
////    for (int i = 0; i < 10; i++) {
////        printf("%d/20\n", i);
////        fprintf(fd, "%d\n", i);
////    }
////    printf("Writing decimal numbers to a file (10/10) done.\n");
//    printf("Writing text to a file done.\n");
//    
//    printf("Closing file...");
////    fflush(stdout);
//    fclose(fd);
//    printf(" done.\r\n");
//    
//    printf("Re-opening file read-only...");
////    fflush(stdout);
//    fd = fopen(filename, "r");
//    errno_error(fd);
//
//    printf("Dumping file to screen:\n");
//    printf("\033[1;37m");
//    char buff[16] = {0};
//    while (!feof(fd)) {
//        int size = fread(&buff[0], 1, 15, fd);
//        fwrite(&buff[0], 1, size, stdout);
//    }
//    printf("\033[0m");
//    printf("Closing file...");
////    fflush(stdout);
//    fclose(fd);
//    printf(" done.\r\n");
//    
//    printf("Opening root directory...");
//    fflush(stdout);
//    DIR* dir = opendir("/fs/");
//    errno_error(fd);
//    
//    struct dirent* de;
//    printf("Printing all filenames:\n");
//    printf("\033[1;37m");
//    while((de = readdir(dir)) != NULL) {
//        printf("  %s\r\n", &(de->d_name)[0]);
//    }
//    printf("\033[0m");
//    
//    printf("Closing root directory... ");
//    fflush(stdout);
//    error = closedir(dir);
//    return_error(error);
//    printf("Filesystem Demo complete.\n");


//    printf("Start FRAM Demo.\n");
//    char wdata[] = "Hello world!";
//    char rdata[14];
//    fram.write(0, wdata, 13); // 12 symbols + zero terminator
//    fram.read(0, rdata, 13);
//    pc.printf("data: %s", rdata);
//    printf("Done.\n");


// Set screen rotation
//    TFT.SetRotate(2); // Rotate 90 CCW to portrait
//    TFT.SetRotate(3); // Rotate 90 CW to portrait

//    TFT.SetOrientation(FT8_DISPLAY_LANDSCAPE_0);
    TFT.SetOrientation(FT8_DISPLAY_PORTRAIT_90CW);   // CM3000
//    TFT.SetOrientation(FT8_DISPLAY_PORTRAIT_90CCW);   // CM3000

//    ap3000.SetBacklight((uint16_t)255);

//    TFT.Calibrate();                                    // calibrate the touch screen
//    // Read calibrate registers
//    printf("// Calibration values:\n");
//    printf("    ft_uint32_t canned_calibration_data[] = {\n");
//    for(int i = 0; i < 24; i+=4) {
//        printf("        ");
//        printf("0x%08x", TFT.read_calibrate_reg32(i));
//        if (i < 20)
//            printf(",");
//        printf("\n");
//    }
//    printf("    };\n");
//    printf("    TFT.write_calibrate32(canned_calibration_data);\n");

    // Default
//    ft_uint32_t canned_calibration_data[] = {
//        0x00000000,
//        0x00010000,
//        0x00000000,
//        0xffff0000,
//        0x00000000,
//        0x031f0000
//    };
//    TFT.write_calibrate32(canned_calibration_data);


    // Landscape 0
//    ft_uint32_t canned_calibration_data[] = {
//        0x000109b0,   // 68016
//        0x0000023d,   // 573
//        0x0000fa64,   // 64100
//        0xffffffcf,   // -49
//        0xfffefc9a,   // -66406
//        0x01ee8754    // 32409428
//    };
//    TFT.write_calibrate32(canned_calibration_data);

    // Calibration rotate 90 CCW to portrait 
//    ft_uint32_t canned_calibration_data[] = {
//        0x00000491,
//        0x0000fd0b,
//        0xfff6f84b,
//        0x00010503,
//        0x000006b7,
//        0xffeeb0b7
//    };
//    TFT.write_calibrate32(canned_calibration_data);

//    // Calibration rotate 90 CW to portrait 
//    ft_uint32_t canned_calibration_data[] = {
//        0xfffff994,
//        0xffff07d3,
//        0x01e4b85c,
//        0xfffef6f5,
//        0x000002ad,
//        0x032eb4d4
//    };
//    TFT.write_calibrate32(canned_calibration_data);

//    // Read calibrate registers
//    printf("// Calibration values:\n");
//    printf("    ft_uint32_t canned_calibration_data[] = {\n");
//    for(int i = 0; i < 24; i+=4) {
//        printf("        ");
//        printf("0x%08x", TFT.read_calibrate_reg32(i));
//        if (i < 20)
//            printf(",");
//        printf("\n");
//    }
//    printf("    };\n");
//    printf("    TFT.write_calibrate32(canned_calibration_data);\n");






//
//    TFT.DL(CLEAR(1, 1, 1));                     // clear buffers -> color buffer,stencil buffer, tag buffer
//    TFT.DL(COLOR_RGB(0xff, 0xff, 0xff));  // set the clear color to white
//    TFT.DL(SAVE_CONTEXT());

//    TFT.DL(BEGIN(BITMAPS));
//
//    TFT.DL(BLEND_FUNC(ONE,ZERO));
//    TFT.DL(COLOR_A(0x55));
//    TFT.DL(VERTEX2II(0, 0, 0, 0));
//    TFT.DL(BLEND_FUNC(ONE,ONE));
//    TFT.DL(COLOR_A(0xAA));
//    TFT.DL(VERTEX2II(0, 0, 0, 1));
//    TFT.DL(COLOR_MASK(1,1,1,0));
//    TFT.Scale(4*65536,4*65536);
//    TFT.SetMatrix();
//    TFT.DL(BLEND_FUNC(DST_ALPHA,ZERO));
//    TFT.DL(VERTEX2II(0, 0, 2, 1));
//    TFT.DL(BLEND_FUNC(ONE_MINUS_DST_ALPHA,ONE));
//    TFT.DL(VERTEX2II(0, 0, 2, 0));
//    
//    TFT.DL(RESTORE_CONTEXT());


//    // NMEA0183 Test

    int status = nmea0183.CheckParity("$PVMAL,A,R1,F3A8,C000,0030*34");
    printf("nmea0183.CheckParity %d\n", status);


//image images2[] = {
//    {"/fs/BACKGROUND_01_C_20x20_BL.bin", L8, 20, 20},
//    {"/fs/BACKGROUND_01_C_20x20_BR.bin", L8, 20, 20},
//    {"/fs/BACKGROUND_01_C_20x20_TL.bin", L8, 20, 20},
//    {"/fs/BACKGROUND_01_C_20x20_TR.bin", L8, 20, 20},
//    
//    {"/fs/BACKGROUND_01_H_5x4.bin", L8, 5, 4},
//    {"/fs/BACKGROUND_01_H_10x4.bin", L8, 10, 4},
//    {"/fs/BACKGROUND_01_H_25x4.bin", L8, 25, 4},
//    {"/fs/BACKGROUND_01_H_190x4.bin", L8, 190, 4},
//    {"/fs/BACKGROUND_01_V_4x535.bin", L8, 4, 535},
//    {"/fs/BACKGROUND_01_V_4x21.bin", L8, 4, 21},
//    
//    {"/fs/RegularButtonRed_220x51r.bin", ARGB4, 220, 51},
//    {"/fs/RegularButtonBlk_220x51r4t.bin", ARGB4, 220, 51},
//    {"/fs/RegularButtonGray_220x51r0r10t.bin", ARGB4, 220, 51},
//    {"/fs/RegularButtonRed_220x51r0r10t.bin", ARGB4, 220, 51},
//    {"/fs/RegularButtonYel_220x51r0r10t.bin", ARGB4, 220, 51},
//
//    {"/fs/RegulaButtonrBlk_220x51r0t.bin", ARGB4, 220, 51},
//    {"/fs/RegularButtonGray_220x51r0t.bin", ARGB4, 220, 51},
//    {"/fs/RegularButtonRed_220x51r0t.bin", ARGB4, 220, 51},
//    {"/fs/RegularButtonYel_220x51r0t.bin", ARGB4, 220, 51},
//
//    {"/fs/SwitchOn_234x132_blk.bin", L8, 234, 132},
//    {"/fs/SwitchOff_234x132_blk.bin", L8, 234, 132},
//    {"/fs/SwitchOn_100x132_blk.bin", L8, 100, 132},
//    {"/fs/SwitchOff_100x132_blk.bin", L8, 234, 132},
//    {"/fs/SwitchOn_115x66_t.bin", L8, 115, 66},
//    {"/fs/SwitchOff_115x66_t.bin", L8, 115, 66},
//    
//    {"/fs/MD_DISABLED_230x70.bin", ARGB4, 230, 70},
//    {"/fs/MD_OFF_230x70.bin", ARGB4, 230, 70},
//    {"/fs/MD_OFF_GREY_230x70.bin", ARGB4, 230, 70},
//    {"/fs/MD_RUNNING_230x70.bin", ARGB4, 230, 70},
//    {"/fs/MD_WARNING_230x70.bin", ARGB4, 230, 70},
//    
//    {"/fs/RUN_TIME_C_ON_21_X_21.bin", ARGB4, 21, 21},
//    {"/fs/RUN_TIME_C_OFF_21_X_21.bin", ARGB4, 21, 21},
//    {"/fs/RUN_TIME_L_ON_21_X_21.bin", ARGB4, 21, 21},
//    {"/fs/RUN_TIME_L_OFF_21_X_21.bin", ARGB4, 21, 21},
//    {"/fs/RUN_TIME_R_ON_21_X_21.bin", ARGB4, 21, 21},
//    {"/fs/RUN_TIME_R_OFF_21_X_21.bin", ARGB4, 21, 21}
//};
//    uint16_t entries = sizeof(images2) / sizeof(images2[0]);
//    printf("--- images2[] %d\n", entries);
//    for (int i = 0; i < entries; i++) {
//        printf("%3d - %s, %d, %d, %d\n", i, images2[i].name, images2[i].fmt, images2[i].w, images2[i].h);
//    }

//    TFT.SetLoadAddress(0);
//    TFT.SetBitmapCount(0);









    // ---------------------------------------- Load and show bitmaps ----------------------------------------
    

    // Splash Screen
//    printf("--------------\n");
//    printf("loadSplashScreen...\n");
//    timer.reset();
//    loadSplashScreen();
//    my_time = timer.read();
//    printf("Time: %f Sec.\n", my_time);
  
    printf("--------------\n");
    printf("showSplashScreen...\n");
    timer.reset();
    showSplashScreen();
    my_time = timer.read();
    printf("Time: %f Sec.\n", my_time);

//    wait(3);

    printf("--------------\n");
    printf("loadBitmaps...\n");
    timer.reset();

    loadBitmaps();

    my_time = timer.read();
    printf("Time: %f Sec.\n", my_time);

    uint32_t RamUsage = TFT.GetRamUsage();
    uint16_t GetRamNoOfBitmaps = TFT.GetRamNoOfBitmaps();
    printf("RAM usage: %d Bytes.\n", RamUsage);
    printf("RAM no of bitmaps: %d.\n", GetRamNoOfBitmaps);

    printf("--------------\n");
    printf("showMainPage...\n");
    timer.reset();

    InitAP3000();

//    button my_button;
//    my_button.accept_alarm_pressed = 0;
//    my_button.accept_horn_pressed = 0;
//    my_button.set_pressed = 0;
//    my_button.dim_pressed = 0;
//
//    indicator my_indicator;
//    my_indicator.rb_used = 1;
//    my_indicator.rb_main_most_used = 1;
//    my_indicator.rb_aux_most_used = 0;
//    
//    // INDICATOR_RUN_STATUS_OFF
//    // INDICATOR_RUN_STATUS_RUNNING
//    // INDICATOR_RUN_STATUS_WARNING
//    // INDICATOR_RUN_STATUS_OFF_RED
//    my_indicator.md_main_running    = INDICATOR_RUN_STATUS_RUNNING;
//    my_indicator.md_aux_running     = INDICATOR_RUN_STATUS_WARNING;
//    
//    // INDICATOR_ALARM_STATUS_OFF
//    // INDICATOR_ALARM_STATUS_WARNING
//    // INDICATOR_ALARM_STATUS_FAILURE
//    my_indicator.rb_main_phase_fail = INDICATOR_ALARM_STATUS_FAILURE;
//    my_indicator.rb_main_main_power = INDICATOR_ALARM_STATUS_FAILURE;
//    my_indicator.rb_main_ctrl_power = INDICATOR_ALARM_STATUS_FAILURE;
//    my_indicator.rb_main_oil_press  = INDICATOR_ALARM_STATUS_FAILURE;
//    my_indicator.rb_main_hydr_lock  = INDICATOR_ALARM_STATUS_OFF;
//    my_indicator.rb_main_overload   = INDICATOR_ALARM_STATUS_WARNING;
//    my_indicator.rb_main_oil_level  = INDICATOR_ALARM_STATUS_WARNING;
//    my_indicator.rb_main_oil_filter = INDICATOR_ALARM_STATUS_WARNING;
//    my_indicator.rb_main_oil_temp   = INDICATOR_ALARM_STATUS_WARNING;
//
//    my_indicator.rb_aux_phase_fail  = INDICATOR_ALARM_STATUS_FAILURE;
//    my_indicator.rb_aux_main_power  = INDICATOR_ALARM_STATUS_FAILURE;
//    my_indicator.rb_aux_ctrl_power  = INDICATOR_ALARM_STATUS_FAILURE;
//    my_indicator.rb_aux_oil_press   = INDICATOR_ALARM_STATUS_FAILURE;
//    my_indicator.rb_aux_hydr_lock   = INDICATOR_ALARM_STATUS_OFF;
//    my_indicator.rb_aux_overload    = INDICATOR_ALARM_STATUS_WARNING;
//    my_indicator.rb_aux_oil_level   = INDICATOR_ALARM_STATUS_WARNING;
//    my_indicator.rb_aux_oil_filter  = INDICATOR_ALARM_STATUS_WARNING;
//    my_indicator.rb_aux_oil_temp    = INDICATOR_ALARM_STATUS_WARNING;
//
//    my_indicator.rb_fu_failure      = INDICATOR_ALARM_STATUS_FAILURE;

    showMainPage();
//    wait(1); 

//    wait(1); 

    my_time = timer.read();
    printf("Time: %f Sec.\n", my_time);

    TFT.Track(  3, 623, 234, 132, BUTTON_ACCEPT_ALARM_TAG);
    TFT.Track(243, 623, 234, 132, BUTTON_ACCEPT_HORN_TAG);
    TFT.Track(  5, 553, 115,  66, BUTTON_SET_TAG);
    TFT.Track(360, 553, 115,  66, BUTTON_DIM_TAG);
    TFT.Track( 10, 360, 220, 51, 100);
    TFT.Track(250, 360, 220, 51, 101);

    Timer touchTimer;
    touchTimer.reset();
    touchTimer.start();
    
//    setPumpRunningBlinkStatus(MAIN_SYSTEM, STEADY_RUNNING_ON);
//    setPumpRunningBlinkStatus(AUX_SYSTEM, BLINK_WARNING_ON);
//    
//    setAlarmBlinkStatus(MAIN_SYSTEM, OIL_PRESS, BLINK_FAILURE_ON);
//    setAlarmBlinkStatus(AUX_SYSTEM, HYDR_LOCK, BLINK_WARNING_ON);
//    setAlarmBlinkStatus(GLOBAL_SYSTEM, FU_FAILURE, BLINK_FAILURE_ON);
    
    Timer minutes;
    minutes.reset();
    minutes.start();
    uint32_t noOfMinutes = 0;
    
    uint32_t secondCount = 0;
    Timer seconds;
    seconds.reset();
    seconds.start();
    Timer timerWdt;
    timerWdt.reset();
    timerWdt.start();
    uint16_t tagvalOld = TAGVAL_NONE;
    while(1) {
        // Watch Dog Timer
        if (timerWdt.read() >= 1.0f) {
            timerWdt.reset();
            wdt.Service();
            TFT.SetTouchConfig(VAL_TOUCH_CONFIG);
        }
        
        // Print time (check stability)
        if (minutes.read() >= 60.0f) {
            minutes.reset();
            noOfMinutes++;
            secondsEpoch = time(NULL);
            strftime(buffer, 32, "%a %d-%m-%Y %H:%M\n", localtime(&secondsEpoch));
            printf("Time: %s", buffer);
        }
        
//        uint16_t tagval = TFT.GetTouchedTag();
        uint16_t tagval = TFT.GetTouchTag();
        
        if(tagval != 0) {                               // touch -> get new values
            uint16_t tagX = TFT.GetTouchTagX();
            uint16_t tagY = TFT.GetTouchTagY();
            uint16_t TouchConfig = TFT.GetTouchConfig();
//            printf("GetTouchTagXY %d %d\n", tagX, tagY);
//            uint16_t tagval1 = TFT.GetTouchedTag(1);
            printf("GetTouchTagXY %d %d %04x\n", tagX, tagY, TouchConfig);
            // The touch screen is touched, the tag value (touch-id) greater than 0
            // However, we can ocasionally get random (invalid) touch id's
            // Therfore we validate the touch duration times
            // Valid touch events take about 0.15 Sec.
            // Invalid touch events take very short, not longer than about 0.025 Sec.
            // Now, we can also detect long press
            my_time = touchTimer.read();
//            printf("d: %f\n", time);
            if ((tagval != tagvalOld) && (my_time >= 0.035)) {
                // Execute below only once, if the touched tag (touch-id) changed
                printf("t %d\n", tagval);
                processButtonPressed(tagval);
                touchTimer.reset();
                showMainPage();
                tagvalOld = tagval;
                wait(0.01);
            }
        }
        else
        {
            // The touch screen is released, the tag value (touch-id) is 0
            if (tagvalOld != TAGVAL_NONE) {
                my_time = touchTimer.read();
                printf("r: %f\n", my_time);
                processButtonReleased();
                showMainPage();
                tagvalOld = TAGVAL_NONE;
                wait(0.01);
            }
        }
        updateAlarmLights();
        
        // Create alarms at time intervals to test it
        if (seconds.read() >= 1.0f) {
            seconds.reset();
            secondCount++;
            
            if (secondCount == 2) {
                setPumpRunningBlinkStatus(MAIN_SYSTEM, STEADY_RUNNING_ON);
            }
            if (secondCount == 4) {
                setAlarmBlinkStatus(MAIN_SYSTEM, OIL_PRESS, BLINK_FAILURE_ON);
            }
            if (secondCount == 6) {
                setAlarmBlinkStatus(AUX_SYSTEM, HYDR_LOCK, BLINK_WARNING_ON);
            }
            if (secondCount == 8) {
                setAlarmBlinkStatus(GLOBAL_SYSTEM, FU_FAILURE, BLINK_FAILURE_ON);
            }
            if (secondCount == 10) {
                setPumpRunningBlinkStatus(AUX_SYSTEM, STEADY_WARNING_ON);
            }
            if (secondCount == 12) {
                setAlarmBlinkStatus(MAIN_SYSTEM, OIL_PRESS, STEADY_FAILURE_ON);
            }
            if (secondCount == 14) {
                setAlarmBlinkStatus(AUX_SYSTEM, HYDR_LOCK, STEADY_WARNING_ON);
            }
            if (secondCount == 16) {
                setAlarmBlinkStatus(GLOBAL_SYSTEM, FU_FAILURE, STEADY_FAILURE_ON);
            }
            if (secondCount == 18) {
                setPumpInUse(PUMP_IN_USE_MAIN);
            }
            if (secondCount == 20) {
                setAlarmBlinkStatus(GLOBAL_SYSTEM, FU_FAILURE, BLINK_FAILURE_ON);
            }
        }
        wait(0.01);
    }
    
//    wait (500);
//}






//    printf("----------\n");
//    for (int i = 0; i < 4; i++)
//    {
//        printf("Show Bitmap from memory...\n");
//        timer.reset();
//        TFT.DLstart();                              // start a new display command list
//    
//        TFT.DL(CLEAR_COLOR_RGB(0x21, 0x21, 0x21));  // set the clear color to white
//        TFT.DL(CLEAR(1, 1, 1));                     // clear buffers -> color buffer,stencil buffer, tag buffer
//        TFT.DL(COLOR_RGB(0xff, 0xff, 0xff));  // set the clear color to white
//        
////    TFT.DL(SAVE_CONTEXT());             
////    TFT.DL(BITMAP_HANDLE(0));
//
////    TFT.Png("/fs/BACKGROUND-01.png", 0, 0);
//
//    //    TFT.LoadIdentity();
//        TFT.DL(BEGIN(BITMAPS));                  
//
//
//        //  Narrow On button, 100x132, Address 0-26400
//        TFT.ShowBitmap(1, ARGB4, 125, 20, 100, 132); // bitmap, x, y, w, h
//        // Narrow Off button, 100x132, Address 26400-52800
//        TFT.ShowBitmap(2, ARGB4, 20, 20, 100, 132); // bitmap, x, y, w, h
//        // Wide On button, 182x132, Address 52800-100848
//        TFT.ShowBitmap(3, ARGB4, 416, 20, 182, 132); // bitmap, x, y, w, h
//        // Wide Off button, 182x132, Address 100848-148896
//        TFT.ShowBitmap(4, ARGB4, 230, 20, 182, 132); // bitmap, x, y, w, h
//
////        TFT.DL(END());                  
//        TFT.DL(DISPLAY());                          // Display the image (erases the other images!)
//        TFT.Swap();                                 // Swap the current display list
//        TFT.Flush_Co_Buffer();                      // Download the command list into fifo
//        TFT.WaitCmdfifo_empty();                    // Wait till coprocessor completes the operation
//        time = timer.read();
//        printf("Time: %f.\n", time);
//        wait(0.5);
//    
//    
//    
//        printf("Show Bitmap from memory...\n");
//        timer.reset();
//        TFT.DLstart();                              // start a new display command list
//    
//        TFT.DL(CLEAR_COLOR_RGB(0x21, 0x21, 0x21));  // set the clear color to white
//        TFT.DL(CLEAR(1, 1, 1));                     // clear buffers -> color buffer,stencil buffer, tag buffer
//        TFT.DL(COLOR_RGB(0xff, 0xff, 0xff));  // set the clear color to white
//        
//    TFT.DL(SAVE_CONTEXT());             
//    TFT.DL(BITMAP_HANDLE(0));
//
//    //    TFT.LoadIdentity();
//        TFT.DL(BEGIN(BITMAPS));                  
//
//        //  Narrow On button, 100x132, Address 0-26400
//        TFT.ShowBitmap(1, ARGB4, 20, 20, 100, 132); // bitmap, x, y, w, h    
//        // Narrow Off button, 100x132, Address 26400-52800
//        TFT.ShowBitmap(2, ARGB4, 125, 20, 100, 132); // bitmap, x, y, w, h
//        // Wide On button, 182x132, Address 52800-100848
//        TFT.ShowBitmap(3, ARGB4, 230, 20, 182, 132); // bitmap, x, y, w, h
//        // Wide Off button, 182x132, Address 100848-148896
//        TFT.ShowBitmap(4, ARGB4, 416, 20, 182, 132); // bitmap, x, y, w, h
//    
////        TFT.DL(END());                  
//        TFT.DL(DISPLAY());                          // Display the image (erases the other images!)
//        TFT.Swap();                                 // Swap the current display list
//        TFT.Flush_Co_Buffer();                      // Download the command list into fifo
//        TFT.WaitCmdfifo_empty();                    // Wait till coprocessor completes the operation
//        time = timer.read();
//        printf("Time: %f.\n", time);
//        wait(0.5);
//    }



//    printf("----------\n");
//    printf("Erase screen\n");
//    TFT.DLstart();                              // start a new display command list
//    TFT.DL(CLEAR_COLOR_RGB(0x00, 0x00, 0x00));  // set the clear color to black
//    TFT.DL(CLEAR(1, 1, 1));                     // clear buffers -> color buffer,stencil buffer, tag buffer
//    TFT.DL(COLOR_RGB(0xff, 0xff, 0xff));        // set the color to white
//    TFT.DL(DISPLAY());                          // Display the image
//    TFT.Swap();                                 // Swap the current display list
//    TFT.Flush_Co_Buffer();                      // Download the command list into fifo
//    TFT.WaitCmdfifo_empty();                    // Wait till coprocessor completes the operation

//    printf("----------\n");
//    printf("JpgSplash...\n");
//    timer.reset();
//    TFT.JpgSplash("/fs/Damen-shipyards-logo_760x157.jpg", 0xff, 0xff, 0xff);
//    time = timer.read();
//    printf("Time: %f.\n", time);
//    wait(1);
    
//    printf("RGB DEMO START\n");
//    Start_Screen("RGB DEMO START");                 // Show start screen
//    TFT.Calibrate();                                // calibrate the touch screen
//    /* Set the tracker for the 3 sliders -  define the Area for touching */
//    TFT.Track(131,  63, 330, 48, 1);                // slider r
//    TFT.Track(131, 116, 330, 48, 2);                // slider g
//    TFT.Track(131, 168, 330, 48, 3);                // slider b
//    TFT.Flush_Co_Buffer();                          // Download the commands into fifo
//    TFT.WaitCmdfifo_empty();                        // Wait till coprocessor completes the operation
//    screen_2(r,g,b);                                // paint screen
//    /* the demo is updating the screen in a endless loop                                    */
//    while(1) {
//        ft_uint8_t tagval = 0;
//        TrackRegisterVal = TFT.Rd32(REG_TRACKER);   // check if one of the tree Slider is touched
//        tagval = TrackRegisterVal & 0xff;
//        if(0 != tagval) {                           // touch -> get new rgb value
//            if(1 == tagval) {                       // the red slider is touched
//                r = TrackRegisterVal>>16;           // get the new value
//                r = r *255/65536;                   // scale it down to 255
//            } else if(2 == tagval) {                // the green slider is touched
//                g = TrackRegisterVal>>16;           // get new slider value
//                g = g * 255/65536;                  // scale it down to 255
//            } else if(3 == tagval) {                // the blue slider is touched
//                b = TrackRegisterVal>>16;           // get new slider value
//                b = b * 255/65536;                  // scale it down to 255
//            }
//            screen_2(r, g, b);                        // paint new screen
//            TFT.Sleep(10);                          // wait 10ms for next check
//        }
//    }  // end of display loop



//    unsigned int color = 0;
//    unsigned int bright = 255;
////    ft_uint32_t TrackRegisterVal = 0;           // touch track
//    uint16_t TrackRegisterVal = 0;           // touch track
//
////    printf("RGB DEMO2 START\n");
////    Start_Screen("RGB DEMO2 START");                    // Show start screen
//
//    
//    /* Set the tracker for the dial -  define the Area for touching */
//    printf("Set the tracker for the dial -  define the Area for touching\n");
//  
//  
//    TFT.DL(TAG(2));                             // assign TAG value 2
//    //TFT.FgColor(COLOR_RGB(0x00 ,0xff, 0x00));   // forground color green
//
//    //  TFT.Dial(249, 86, 55, 0, color);            // dial for color 
//    TFT.Track(249, 86, 1, 1, 1);                        // Dial  - dimension 1,1 means rotary
//    // TFT.Slider(196, 215, 236, 21, 0, bright , 255); // slider for brightness 
//    TFT.Track(179, 199, 277, 48, 2);                    // Slider
//    // TFT.Button(500, 63, 200, 50, 31, 0, "Test 1");
//    TFT.Track(500, 20, 200, 50, 3);                     // Button
//    TFT.Track(500, 80, 200, 50, 4);                     // Button
//    TFT.Track(500, 140, 200, 50, 5);                    // Button
//    TFT.Track(20, 290, 100, 132, 11);                   // Bitmap
//    
//    TFT.Flush_Co_Buffer();                              // Download the commands into fifo
//    TFT.WaitCmdfifo_empty();                            // Wait till coprocessor completes the operation
//    int tagoption1 = 0;
//    int tagoption2 = 0;
//    int tagoption3 = 0;
//    int tagoption4 = 0;
//    screen_1(color, bright, tagoption1, tagoption2, tagoption3, tagoption4);                            // paint screen
//    /* the demo is updating the screen in a endless loop */
//    
//    Timer t1;
//    t1.start();
//    t1.reset();
//    
//    tagoption1 = 0;
//    tagoption2 = 0;
//    tagoption3 = 0;
//    tagoption4 = 0;
////    int tagvalOld = -1;
//     tagvalOld = -1;
//    while(1) {
//        ft_uint8_t tagval = 0;
//        TrackRegisterVal = TFT.Rd32(REG_TRACKER);       // check if one of the tracking fields is touched
//        tagval = TrackRegisterVal & 0xff;
//        if(tagval != 0) {                               // touch -> get new values
//            if (tagval != tagvalOld) {
//                printf("t %d\n", tagval);
//                tagvalOld = tagval;
//            }
//            if(tagval == 1) {                           // the dial touched
//                color = TrackRegisterVal>>16;           // get the new value
//            }
//            else if(tagval == 2) {                    // the slider is touched
//                bright = TrackRegisterVal>>16;          // get new slider value
//                bright = bright * 255/65536;            // scale it down to 255
//                TFT.SetBacklight(bright); // Brightness
//            }
//            else if(tagval == 3) {                    // the button is touched
////                TFT.SetBacklight(63); // Brightness
//                tagoption1 = OPT_FLAT;
//                bright = 64;
//                TFT.SetBacklight(bright); // Brightness
//            }
//            else if(tagval == 4) {                    // the button is touched
////                TFT.SetBacklight(63); // Brightness
//                tagoption2 = OPT_FLAT;
//                bright = 128;
//                TFT.SetBacklight(bright); // Brightness
//            }
//            else if(tagval == 5) {                    // the button is touched
////                TFT.SetBacklight(63); // Brightness
//                tagoption3 = OPT_FLAT;
//                bright = 192;
//                TFT.SetBacklight(bright); // Brightness
//            }
//            else if(tagval == 8) {                    // the button is touched
////                TFT.SetBacklight(63); // Brightness
////                tagoption2 = OPT_FLAT;
//                bright = 171;
//                TFT.SetBacklight(bright); // Brightness
//            }
//            else if(tagval == 10) {                    // the button is touched
////                TFT.SetBacklight(63); // Brightness
////                tagoption3 = OPT_FLAT;
//                bright = 212;
//                TFT.SetBacklight(bright); // Brightness
//            }
//            else if(tagval == 11) {                    // the button is touched
////                TFT.SetBacklight(63); // Brightness
////                tagoption3 = OPT_FLAT;
//                tagoption4 = OPT_FLAT;
//                bright = 230;
//                TFT.SetBacklight(bright); // Brightness
//            }
//            screen_1(color, bright, tagoption1, tagoption2, tagoption3, tagoption4);                    // paint new screen
//            TFT.Sleep(10);                              // wait 10ms for next check
//        }
//        else
//        {
//            tagvalOld = -1;
////            printf("Tagval %d, tagoption %d\n", tagval, tagoption);
//            if (tagoption1 != 0)
//            {
//                tagoption1 = 0;
//                screen_1(color, bright, tagoption1, tagoption2, tagoption3, tagoption4);                    // paint new screen
//                TFT.Sleep(10);                              // wait 10ms for next check
//            }
//            if (tagoption2 != 0)
//            {
//                tagoption2 = 0;
//                screen_1(color, bright, tagoption1, tagoption2, tagoption3, tagoption4);                    // paint new screen
//                TFT.Sleep(10);                              // wait 10ms for next check
//            }
//            if (tagoption3 != 0)
//            {
//                tagoption3 = 0;
//                screen_1(color, bright, tagoption1, tagoption2, tagoption3, tagoption4);                    // paint new screen
//                TFT.Sleep(10);                              // wait 10ms for next check
//            }
//            if (tagoption4 != 0)
//            {
//                tagoption4 = 0;
//                screen_1(color, bright, tagoption1, tagoption2, tagoption3, tagoption4);                    // paint new screen
//                TFT.Sleep(10);                              // wait 10ms for next check
//            }
//        }
//    }  // end of display loop
//
//    while(1) {
//        myled = !myled; // LED is ON
//        wait(0.5); // 500 ms
//    }
//
//    fs.unmount();
//
//    // Deinitialize the device
//    sd.deinit();

    // Deinitialize the device
//    spif.deinit();

    // Deinitialize the device
//    ee.deinit();

}