Loads bitmaps into QSPI memory for GC500_2_5inch to use.

Dependencies:   DMBasicGUI DMSupport

main.cpp

Committer:
jmitc91516
Date:
2017-07-31
Revision:
0:a5c253316af6

File content as of revision 0:a5c253316af6:

#include "mbed.h"
#include "DMBoard.h"
#include "lpc_swim.h"
#include "lpc_swim_font.h"

#include "GuiLib.h"
#include "GuiDisplay.h"

#include <fstream>

/*
    This application loads bitmaps into QSPI memory for use by the GC500_2_5inch application,
    since memory limits do not allow these bitmaps to be included in the application
    in the normal way.

    The associated easyGUI project is C:/easyGUI Projects/GC500_2_5inch_BitmapLoader.gui
   
    It is intended for use with the Embedded Artists LPC4088 board, 5 inch display.
*/

// Use QSPI - uncomment '#define DM_BOARD_USE_QSPI' in dm_board_config.h, and:
#include "QSPIFileSystem.h"
QSPIFileSystem qspifs("qspi");
// Can now use QSPI memory as file device '/qspi/'
//

/*
    Bodge so GuiDisplay.c ('easyGUIFixed' file) can call Thread::wait 
    (giving it an accurate millisecond timer)
*/
extern "C" {
    void EasyGUIWaitMs(GuiConst_INT32U msec)
    {
        Thread::wait(msec);
    }
}


void Save_easyGUI_bitmap(int bitmapIndex, char* bitmapName, int bitmapSize, SWIM_WINDOW_T* winPtr, int winX, int winY)
{
    char bitmapSizeFilename[200];
//    sprintf(bitmapSizeFilename, "/mci/%s_BMP.size", bitmapName);
    sprintf(bitmapSizeFilename, "/qspi/%s_BMP.size", bitmapName);

    char buff[100];
    
    ofstream bitmapSizeStream;
    bitmapSizeStream.open(bitmapSizeFilename);
    if(bitmapSizeStream) {
        bitmapSizeStream << bitmapSize << "\n";
        bitmapSizeStream.close();
        sprintf(buff, "Wrote %d to bitmap size file: %s", bitmapSize, bitmapSizeFilename);
        swim_put_text_xy(winPtr, buff, winX, winY);
    } else {
        sprintf(buff, "Failed to open bitmap size file for writing: %s", bitmapSizeFilename);
        swim_put_text_xy(winPtr, buff, winX, winY);
    }
    
    winY += 12;  

    char bitmapDataFilename[200];
//    sprintf(bitmapDataFilename, "/mci/%s_BMP.data", bitmapName);
    sprintf(bitmapDataFilename, "/qspi/%s_BMP.data", bitmapName);

    ofstream bitmapDataStream;
    bitmapDataStream.open(bitmapDataFilename, (ios::out | ios::binary));
    if(bitmapDataStream) {
        bitmapDataStream.write((char*) GuiStruct_BitmapPtrList[bitmapIndex], bitmapSize);
        bitmapDataStream.close();
        sprintf(buff, "Wrote %d bytes to bitmap data file: %s", bitmapSize, bitmapDataFilename);
        swim_put_text_xy(winPtr, buff, winX, winY);
    } else {
        sprintf(buff, "Failed to open bitmap data file for writing: %s", bitmapDataFilename);
        swim_put_text_xy(winPtr, buff, winX, winY);
    }
}

/*
    Displays the directory of files in QSPI memory.
    
    Used for debugging/testing - not appropriate or required in the 'real' system.
    
    Args: pointer to a 'swim window', and the X and Y coordinates at which to display the directory on the screen
*/
void DisplayQSPIDirectory(SWIM_WINDOW_T* winPtr, int winX, int winY)
{
    DIR *dp;
    dp = opendir("/qspi/");

    if(dp != NULL) {
        struct dirent *dirp;
        
        swim_put_text_xy(winPtr, "Start of QSPI directory", winX, winY);
        winY += 12;
    
        // Indent file names
        while((dirp = readdir(dp)) != NULL) {
            swim_put_text_xy(winPtr, dirp->d_name, winX + 30, winY);
            winY += 12;
        }
        closedir(dp);
    
        swim_put_text_xy(winPtr, "End of QSPI directory", winX, winY);
    } else {
        swim_put_text_xy(winPtr, "Failed to open QSPI directory", winX, winY);
    }
}

/*
    Deletes all existing files in the QSPI directory.
    
    So that we know there is only the bitmap files there, nothing else
*/
void ClearQSPIDirectory(void)
{
    DIR *dp;
    dp = opendir("/qspi/");

    if(dp != NULL) {
        struct dirent *dirp;
        
        while((dirp = readdir(dp)) != NULL) {
            char buff[200];
            sprintf(buff, "/qspi/%s", dirp->d_name);
            remove(buff);
        }
        closedir(dp);
    }
}


int main()
{
  DMBoard::BoardError err;
  DMBoard* board = &DMBoard::instance();
  RtosLog* log = board->logger();
  Display* disp = board->display();
  
  do {
    err = board->init();
    if (err != DMBoard::Ok) {
      log->printf("Failed to initialize the board, got error %d\r\n", err);
      break;
    }
    
    log->printf("\n\nHello World!\n\n");
    
    SWIM_WINDOW_T win;
    void* fb = disp->allocateFramebuffer();
    if (fb == NULL) {
      log->printf("Failed to allocate memory for a frame buffer\r\n");
      err = DMBoard::MemoryError;
      break;
    }
    
    // Prepare fullscreen
    swim_window_open(&win, 
                     disp->width(), disp->height(),         // full size
                     (COLOR_T*)fb,
                     0,0,disp->width()-1, disp->height()-1, // window position and size
                     1,                                     // border
                     WHITE, BLUE, BLACK);                   // colors: pen, backgr, forgr
    swim_set_title(&win, "GC500_2_5inch Bitmap Loader", BLACK);
  
    // Message    
//    swim_put_text_xy(&win, "Checking for SD/MMC card", 100, 0);
//    if(mcifs.cardInserted()) {
//        swim_put_text_xy(&win, "Found SD/MMC card", 100, 10);

    // Make sure QSPI filesystem is formatted before we try to use it
    if (!qspifs.isformatted()) {
        qspifs.format();
    }
        
#define START_DISPLAY_FIRST
#ifdef  START_DISPLAY_FIRST
    // Start display in default mode (16-bit)
    Display::DisplayError disperr = disp->powerUp(fb);
    if (disperr != Display::DisplayError_Ok) {
      log->printf("Failed to initialize the display, got error %d\r\n", disperr);
      break;
    }
#endif //  START_DISPLAY_FIRST

//#define CLEAR_DIRECTORY_FIRST // *** Need to consider whether to reinstate this in production version - or have a separate "ClearQSPI" application ***
#ifdef CLEAR_DIRECTORY_FIRST
        ClearQSPIDirectory(); // Appears to cause LPC4088 error
#endif

#define LOAD_THE_BITMAPS // May want to not load them (e.g. for testing purposes)
#ifdef LOAD_THE_BITMAPS 

        // Values passed to Save_easyGUI_bitmap are manually copied
        // from GuiStruct.c and GuiStruct.h, and hard-coded here
        
        // Component bitmaps
        Save_easyGUI_bitmap(GuiStruct_Bitmap_Column, "GuiStruct_Bitmap_Column", 17674, &win, 10, 10);
        Save_easyGUI_bitmap(GuiStruct_Bitmap_Detector, "GuiStruct_Bitmap_Detector", 19493, &win, 10, 40);
        Save_easyGUI_bitmap(GuiStruct_Bitmap_Injector, "GuiStruct_Bitmap_Injector", 18789, &win, 10, 70);
        Save_easyGUI_bitmap(GuiStruct_Bitmap_Gas, "GuiStruct_Bitmap_Gas", 21169, &win, 10, 100);
        
        // Home page bitmaps
        Save_easyGUI_bitmap(GuiStruct_Bitmap_ColumnButton, "GuiStruct_Bitmap_ColumnButton", 19682, &win, 10, 140);
        Save_easyGUI_bitmap(GuiStruct_Bitmap_DetectorButton, "GuiStruct_Bitmap_DetectorButton", 21526, &win, 10, 170);
        Save_easyGUI_bitmap(GuiStruct_Bitmap_InjectorButton, "GuiStruct_Bitmap_InjectorButton", 20853, &win, 10, 200);
        Save_easyGUI_bitmap(GuiStruct_Bitmap_GasButton, "GuiStruct_Bitmap_GasButton", 23258, &win, 10, 230);
        
        // Background bitmaps
        Save_easyGUI_bitmap(GuiStruct_Bitmap_BootScreen, "GuiStruct_Bitmap_BootScreen", 123419, &win, 10, 270);
        Save_easyGUI_bitmap(GuiStruct_Bitmap_BlankBackground, "GuiStruct_Bitmap_BlankBackground", 1157, &win, 10, 300);
        
        // Scroll arrow bitmaps
        Save_easyGUI_bitmap(GuiStruct_Bitmap_UpArrowDoubled, "GuiStruct_Bitmap_UpArrowDoubled", 218, &win, 10, 340);
        Save_easyGUI_bitmap(GuiStruct_Bitmap_DownArrowDoubled, "GuiStruct_Bitmap_DownArrowDoubled", 218, &win, 10, 370);
        Save_easyGUI_bitmap(GuiStruct_Bitmap_UpArrow, "GuiStruct_Bitmap_UpArrow", 176, &win, 10, 400);
        Save_easyGUI_bitmap(GuiStruct_Bitmap_DownArrow, "GuiStruct_Bitmap_DownArrow", 176, &win, 10, 430);
        Save_easyGUI_bitmap(GuiStruct_Bitmap_UpArrow1point5, "GuiStruct_Bitmap_UpArrow1point5", 196, &win, 10, 470);
        Save_easyGUI_bitmap(GuiStruct_Bitmap_DownArrow1point5, "GuiStruct_Bitmap_DownArrow1point5", 196, &win, 10, 500);

#endif // LOAD_THE_BITMAPS 

        DisplayQSPIDirectory(&win, 450, 30);
//    } else {
//        swim_put_text_xy(&win, "SD/MMC card not found", 100, 30);
//    }

    
#ifndef  START_DISPLAY_FIRST
    // Start display in default mode (16-bit)
    Display::DisplayError disperr = disp->powerUp(fb);
    if (disperr != Display::DisplayError_Ok) {
      log->printf("Failed to initialize the display, got error %d\r\n", disperr);
      break;
    }
#endif //  START_DISPLAY_FIRST
  } while(false);

  if (err != DMBoard::Ok) {
    log->printf("\nTERMINATING\n");
    wait_ms(2000); // allow RtosLog to flush messages
    mbed_die();
  }  

  while(true) {
  }   
}