Loads bitmaps into QSPI memory for GC500_2_5inch to use.
Dependencies: DMBasicGUI DMSupport
Diff: main.cpp
- Revision:
- 0:a5c253316af6
diff -r 000000000000 -r a5c253316af6 main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Mon Jul 31 15:44:39 2017 +0000 @@ -0,0 +1,246 @@ +#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) { + } +}