Sample GUI for LPC4088. Base code to begin dev

Dependencies:   DMBasicGUI DMSupport

Fork of lpc4088_displaymodule_shipped_demo by Embedded Artists

Revision:
0:b94e330c98ac
Child:
3:57de4d043115
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Fri Mar 20 13:36:44 2015 +0000
@@ -0,0 +1,587 @@
+/******************************************************************************
+ * Includes
+ *****************************************************************************/
+ 
+#include "mbed.h"
+#include "mbed_interface.h"
+#include "rtos.h"
+#include "EthernetInterface.h"
+#include "HTTPServer.h"
+#include "mbed_rpc.h"
+#include "USBHostMSD.h"
+#include "USBHostMouse.h"
+#include "USBHostKeyboard.h"
+
+#include "DMBoard.h"
+
+#include "AppLauncherSpecial.h"
+#include "meas.h"
+
+#include "AppNetworkSettings.h"
+#include "AppStatus.h"
+#include "AppTouchCalibration.h"
+#include "AppColorPicker.h"
+#include "AppImageViewer.h"
+#include "AppSlideShow.h"
+#include "AppRTCSettings.h"
+#include "AppUSBStatus.h"
+#include "AppDraw.h"
+#include "image_data.h"
+#include "Resource.h"
+
+#include "lpc_swim.h"
+#include "lpc_helvr10.h"
+#include "lpc_winfreesystem14x16.h"
+
+/******************************************************************************
+ * Typedefs and defines
+ *****************************************************************************/
+
+typedef enum {
+    Res_ok,
+    Res_cancel,
+    Res_arrow_up,
+    Res_arrow_down,
+    Res_arrow_left,
+    Res_arrow_right,
+    Res_repeat,
+    Res_digits,
+    Res_background,
+    Res_about,
+    Res_ColorPickerApp,
+    Res_ImageViewerApp,
+    Res_SlideshowApp,
+    Res_SettingsApp, 
+    Res_StatusApp, 
+    //Res_TouchTestApp,
+    Res_RtcApp,
+    Res_USBStatusApp,
+    Res_DrawingApp,
+    //Res_CalibrationApp,
+    NumResources,
+} resorces_t;
+
+/******************************************************************************
+ * Local variables
+ *****************************************************************************/
+
+static Resource* RESOURCES[NumResources] = {0};
+
+static void prepareResources()
+{
+  Display* disp = DMBoard::instance().display();
+  
+  // select which images to use based on display size
+  if (disp->width() == 480) {
+    RESOURCES[Res_ok         ] = new Resource(img_480x272_ok,          img_size_480x272_ok, 40, 40);
+    RESOURCES[Res_cancel     ] = new Resource(img_480x272_cancel,      img_size_480x272_cancel, 40, 40);
+    RESOURCES[Res_arrow_up   ] = new Resource(img_480x272_arrow_up,    img_size_480x272_arrow_up,    52, 52);
+    RESOURCES[Res_arrow_down ] = new Resource(img_480x272_arrow_down,  img_size_480x272_arrow_down,  52, 52);
+    RESOURCES[Res_arrow_left ] = new Resource(img_480x272_arrow_left,  img_size_480x272_arrow_left,  52, 52);
+    RESOURCES[Res_arrow_right] = new Resource(img_480x272_arrow_right, img_size_480x272_arrow_right, 52, 52);
+    RESOURCES[Res_repeat     ] = new Resource(img_480x272_repeat,      img_size_480x272_repeat, 40, 40);
+    RESOURCES[Res_digits     ] = new Resource(img_numbers_16b,         img_size_numbers_16b, 13, 242);
+      
+    RESOURCES[Res_ColorPickerApp] = new Resource(img_480x272_super_mono_3d_part2_19, img_size_480x272_super_mono_3d_part2_19, 64, 64);
+    RESOURCES[Res_ImageViewerApp] = new Resource(img_480x272_super_mono_3d_48,       img_size_480x272_super_mono_3d_48,       64, 64);
+    RESOURCES[Res_SlideshowApp  ] = new Resource(img_480x272_super_mono_3d_87,       img_size_480x272_super_mono_3d_87,       64, 64);
+    RESOURCES[Res_SettingsApp   ] = new Resource(img_480x272_super_mono_3d_93,       img_size_480x272_super_mono_3d_93,       64, 64);
+    RESOURCES[Res_StatusApp     ] = new Resource(img_480x272_super_mono_3d_part2_68, img_size_480x272_super_mono_3d_part2_68, 64, 64);
+    RESOURCES[Res_RtcApp        ] = new Resource(img_480x272_super_mono_3d_02,       img_size_480x272_super_mono_3d_02,       64, 64);
+    RESOURCES[Res_USBStatusApp  ] = new Resource(img_480x272_super_mono_3d_57,       img_size_480x272_super_mono_3d_57,       64, 64);
+    RESOURCES[Res_DrawingApp    ] = new Resource(img_480x272_super_mono_3d_22,       img_size_480x272_super_mono_3d_22,       64, 64);
+    RESOURCES[Res_background    ] = new Resource(img_480x272_background,             img_size_480x272_background, 364, 57);
+    RESOURCES[Res_about         ] = new Resource(img_480x272_about,                  img_size_480x272_about, 240, 245);
+    
+    swim_set_default_font(&font_helvr10);
+  } else {
+    RESOURCES[Res_ok         ] = new Resource(img_800x480_ok,          img_size_800x480_ok,       64, 64);
+    RESOURCES[Res_cancel     ] = new Resource(img_800x480_cancel,      img_size_800x480_cancel,   64, 64);
+    RESOURCES[Res_arrow_up   ] = new Resource("/qspi/800x480_arrow_up.raw",                     128, 128);
+    RESOURCES[Res_arrow_down ] = new Resource("/qspi/800x480_arrow_down.raw",                   128, 128);
+    RESOURCES[Res_arrow_left ] = new Resource("/qspi/800x480_arrow_left.raw",                   128, 128);
+    RESOURCES[Res_arrow_right] = new Resource("/qspi/800x480_arrow_right.raw",                  128, 128);
+    RESOURCES[Res_repeat     ] = new Resource(img_800x480_repeat,      img_size_800x480_repeat,  64,  64);
+    RESOURCES[Res_digits     ] = new Resource(img_numbers_20b,         img_size_numbers_20b,     16, 322);
+      
+    RESOURCES[Res_ColorPickerApp] = new Resource("/qspi/800x480_super-mono-3d-part2-19.raw",  64,  64);
+    RESOURCES[Res_ImageViewerApp] = new Resource("/qspi/800x480_super-mono-3d-48.raw",        64,  64);
+    RESOURCES[Res_SlideshowApp  ] = new Resource("/qspi/800x480_super-mono-3d-87.raw",        64,  64);
+    RESOURCES[Res_SettingsApp   ] = new Resource("/qspi/800x480_super-mono-3d-93.raw",        64,  64);
+    RESOURCES[Res_StatusApp     ] = new Resource("/qspi/800x480_super-mono-3d-part2-68.raw",  64,  64);
+    RESOURCES[Res_RtcApp        ] = new Resource("/qspi/800x480_super-mono-3d-02.raw",        64,  64);
+    RESOURCES[Res_USBStatusApp  ] = new Resource("/qspi/800x480_super-mono-3d-57.raw",        64,  64);
+    RESOURCES[Res_DrawingApp    ] = new Resource("/qspi/800x480_super-mono-3d-22.raw",        64,  64);
+    RESOURCES[Res_background    ] = new Resource("/qspi/800x480_background.raw",             548,  80);
+    RESOURCES[Res_about         ] = new Resource("/qspi/800x480_about.raw",                  420, 429);
+      
+    swim_set_default_font(&font_winfreesys14x16);
+  }
+}
+
+/******************************************************************************
+ * Global variables
+ *****************************************************************************/
+
+EthernetInterface eth;
+bool ethInitialized = false;
+bool ethUsingDHCP = true;
+bool haveUSBMSD = false;
+
+/******************************************************************************
+ * Local functions
+ *****************************************************************************/
+
+void aliveTask(void const* args)
+{
+  DMBoard* board = &DMBoard::instance();
+    
+  while(true)
+  {
+    board->setLED(DMBoard::Led4, false);
+    board->setLED(DMBoard::Led1, true);
+    Thread::wait(300);
+    board->setLED(DMBoard::Led1, false);
+    board->setLED(DMBoard::Led2, true);
+    Thread::wait(300);
+    board->setLED(DMBoard::Led2, false);
+    board->setLED(DMBoard::Led3, true);
+    Thread::wait(300);
+    board->setLED(DMBoard::Led3, false);
+    board->setLED(DMBoard::Led4, true);
+    Thread::wait(300);
+  }
+}
+
+#if defined(DM_BOARD_USE_DISPLAY)
+
+typedef enum {
+    ColorPickerApp,
+    ImageViewerApp,
+    SlideshowApp,
+    SettingsApp, 
+    StatusApp, 
+    TouchTestApp,
+    RtcApp,
+    USBStatusApp,
+    DrawingApp,
+    CalibrationApp =  AppLauncherSpecial::CalibrationApp,
+    Placeholder,
+} myapps_t;
+
+static App* launchApp(uint32_t id)
+{
+  App* a = NULL;
+  switch ((myapps_t)id) {
+      case CalibrationApp:
+          a = new AppTouchCalibration();
+         ((AppTouchCalibration*)a)->addResource(AppTouchCalibration::Resource_Ok_button, RESOURCES[Res_ok]);
+          break;
+      case SettingsApp:
+          a = new AppNetworkSettings();
+         ((AppNetworkSettings*)a)->addResource(AppNetworkSettings::Resource_Ok_button, RESOURCES[Res_ok]);
+         ((AppNetworkSettings*)a)->addResource(AppNetworkSettings::Resource_Cancel_button, RESOURCES[Res_cancel]);
+         ((AppNetworkSettings*)a)->addResource(AppNetworkSettings::Resource_ArrowUp_button, RESOURCES[Res_arrow_up]);
+         ((AppNetworkSettings*)a)->addResource(AppNetworkSettings::Resource_ArrowDown_button, RESOURCES[Res_arrow_down]);
+         ((AppNetworkSettings*)a)->addResource(AppNetworkSettings::Resource_ArrowLeft_button, RESOURCES[Res_arrow_left]);
+         ((AppNetworkSettings*)a)->addResource(AppNetworkSettings::Resource_ArrowRight_button, RESOURCES[Res_arrow_right]);
+         ((AppNetworkSettings*)a)->addResource(AppNetworkSettings::Resource_Digits, RESOURCES[Res_digits]);
+          break;
+      case ColorPickerApp:
+          a = new AppColorPicker();
+         ((AppColorPicker*)a)->addResource(AppColorPicker::Resource_Ok_button, RESOURCES[Res_ok]);
+          break;
+      case ImageViewerApp:
+          a = new AppImageViewer();
+         ((AppImageViewer*)a)->addResource(AppImageViewer::Resource_Ok_button, RESOURCES[Res_ok]);
+          break;
+      case SlideshowApp:
+          {
+              // Select folder for the slideshow based on display size
+              Display* d = DMBoard::instance().display();
+              if (d->width() == 480) {
+                  a = new AppSlideShow("/qspi/slides.txt", "/qspi/480x272", 0, 0);
+              } else {
+                  a = new AppSlideShow("/qspi/slides.txt", "/qspi/800x480", 0, 0);
+              }
+              
+             ((AppSlideShow*)a)->addResource(AppSlideShow::Resource_Ok_button, RESOURCES[Res_ok]);
+             ((AppSlideShow*)a)->addResource(AppSlideShow::Resource_Repeat_button, RESOURCES[Res_repeat]);
+          }
+          break;
+      case StatusApp:
+          a = new AppStatus();
+         ((AppStatus*)a)->addResource(AppStatus::Resource_Ok_button, RESOURCES[Res_ok]);
+         ((AppStatus*)a)->addResource(AppStatus::Resource_About_image, RESOURCES[Res_about]);
+          break;
+      case RtcApp:
+          a = new AppRTCSettings();
+         ((AppRTCSettings*)a)->addResource(AppRTCSettings::Resource_Ok_button, RESOURCES[Res_ok]);
+         ((AppRTCSettings*)a)->addResource(AppRTCSettings::Resource_Cancel_button, RESOURCES[Res_cancel]);
+         ((AppRTCSettings*)a)->addResource(AppRTCSettings::Resource_ArrowUp_button, RESOURCES[Res_arrow_up]);
+         ((AppRTCSettings*)a)->addResource(AppRTCSettings::Resource_ArrowDown_button, RESOURCES[Res_arrow_down]);
+         ((AppRTCSettings*)a)->addResource(AppRTCSettings::Resource_ArrowLeft_button, RESOURCES[Res_arrow_left]);
+         ((AppRTCSettings*)a)->addResource(AppRTCSettings::Resource_ArrowRight_button, RESOURCES[Res_arrow_right]);
+         ((AppRTCSettings*)a)->addResource(AppRTCSettings::Resource_Digits, RESOURCES[Res_digits]);
+          break;
+      case USBStatusApp:
+          a = new AppUSBStatus();
+         ((AppUSBStatus*)a)->addResource(AppUSBStatus::Resource_Ok_button, RESOURCES[Res_ok]);
+          break;
+      case DrawingApp:
+          a = new AppDraw();
+         ((AppDraw*)a)->addResource(AppDraw::Resource_Ok_button, RESOURCES[Res_ok]);
+          break;
+      default:
+          break;
+  }
+  return a;
+}
+
+#define SWIM_TASK_PREFIX  "[SWIM] "
+void swimTask(void const* args)
+{
+  RtosLog* log = DMBoard::instance().logger();
+  Display* disp = DMBoard::instance().display();
+    
+  log->printf(SWIM_TASK_PREFIX"swimTask started\n");
+  
+  int iconsize = (disp->width()==480) ? 64 : 128;
+  AppLauncherSpecial launcher(iconsize, iconsize);
+  launcher.addResource(AppLauncherSpecial::Resource_Background, RESOURCES[Res_background]);
+    
+  if (launcher.setup()) {
+    launcher.addImageButton(SettingsApp,    "Network",      0x2d5c, RESOURCES[Res_SettingsApp   ]);
+    launcher.addImageButton(DrawingApp,     "Drawing",      0x2d5c, RESOURCES[Res_DrawingApp    ]);
+    launcher.addImageButton(SlideshowApp,   "Slideshow",    0x2d5c, RESOURCES[Res_SlideshowApp  ]);
+    launcher.addImageButton(ColorPickerApp, "Color Picker", 0x2d5c, RESOURCES[Res_ColorPickerApp]);
+    launcher.addImageButton(ImageViewerApp, "Image Viewer", 0x2d5c, RESOURCES[Res_ImageViewerApp]);
+    launcher.addImageButton(StatusApp,      "About",        0x2d5c, RESOURCES[Res_StatusApp     ]);
+    launcher.addImageButton(USBStatusApp,   "USB Status",   0x2d5c, RESOURCES[Res_USBStatusApp  ]);
+    launcher.addImageButton(RtcApp,         "Clock",        0x2d5c, RESOURCES[Res_RtcApp        ]);
+      
+    launcher.setAppCreatorFunc(launchApp);
+    log->printf(SWIM_TASK_PREFIX"Starting menu system\n");
+    launcher.runToCompletion();
+    launcher.teardown();
+  } else {
+    log->printf(SWIM_TASK_PREFIX"Failed to prepare menu system\n");
+  }
+  
+  // Should never end up here  
+  mbed_die();
+}
+
+#endif //DM_BOARD_USE_DISPLAY
+
+
+#define NET_TASK_PREFIX  "[NET] "
+
+void netTask(void const* args)
+{
+  RtosLog* log = DMBoard::instance().logger();
+  log->printf(NET_TASK_PREFIX"EthernetInterface Setting up...\r\n");
+  if(eth.init()!=0) {                             //for DHCP Server
+     //if(eth.init(IPAddress,NetMasks,Gateway)!=0) { //for Static IP Address
+     log->printf(NET_TASK_PREFIX"EthernetInterface Initialize Error \r\n");
+     mbed_die();
+  }
+  while (eth.connect() != 0) {
+     Thread::wait(1000);
+  }
+  
+  ethInitialized = true;
+  ethUsingDHCP = true;
+  
+  log->printf(NET_TASK_PREFIX"IP Address is %s\r\n", eth.getIPAddress());
+  log->printf(NET_TASK_PREFIX"NetMask is %s\r\n", eth.getNetworkMask());
+  log->printf(NET_TASK_PREFIX"Gateway Address is %s\r\n", eth.getGateway());
+  log->printf(NET_TASK_PREFIX"Ethernet Setup OK\r\n");
+
+  HTTPServerAddHandler<SimpleHandler>("/hello"); //Default handler
+  FSHandler::mount("/usb", "/");
+  HTTPServerAddHandler<FSHandler>("/");
+  //HTTPServerAddHandler<RPCHandler>("/rpc");
+  //lcd.locate(0,0);
+  //lcd.printf("%s",eth.getIPAddress());
+  HTTPServerStart(80);
+}
+
+static volatile int8_t mouse_button, mouse_x, mouse_y, mouse_z;
+static uint16_t cursor_x=0, cursor_y=0, mouse_max_x = 0, mouse_max_y = 0;
+void mouseEvent(uint8_t buttons, int8_t x, int8_t y, int8_t z)
+{
+    mouse_button = buttons;
+    mouse_x = x;
+    mouse_y = y;
+    mouse_z = z;
+    
+    if (mouse_max_x == 0) {
+        mouse_max_x = DMBoard::instance().display()->width() - 1;
+    }
+    if (mouse_max_y == 0) {
+        mouse_max_y = DMBoard::instance().display()->height() - 1;
+    }
+    
+    if (x < 0) {
+        if (cursor_x > -x) {
+            cursor_x += x;
+        } else {
+            cursor_x = 0;
+        }
+    } else {
+        if ((cursor_x + x) > mouse_max_x) {
+            cursor_x = mouse_max_x;
+        } else {
+            cursor_x += x;
+        }
+    }
+    y = y/8;
+    if (y < 0) {
+        if (cursor_y > -y) {
+            cursor_y += y;
+        } else {
+            cursor_y = 0;
+        }
+    } else {
+        if ((cursor_y + y) > mouse_max_y) {
+            cursor_y = mouse_max_y;
+        } else {
+            cursor_y += y;
+        }
+    }
+    
+    //Chip_LCD_Cursor_SetPos(LPC_LCD, cursor_x, cursor_y);
+    LPC_LCD->CRSR_XY = (cursor_x & 0x3FF) | ((cursor_y & 0x3FF) << 16);
+}
+
+#define LCD_CURSOR_32x32 0
+#define LCD_CURSOR_64x64 1
+#define CURSOR_SIZE  LCD_CURSOR_32x32
+#define CURSOR_H_SIZE 32
+#define CURSOR_V_SIZE 32
+#define CURSOR_NUM   0    
+#define CURSOR_H_OFS (10)
+#define CURSOR_V_OFS (6)
+
+const unsigned char __attribute__ ((aligned(4))) Cursor[(CURSOR_H_SIZE / 4) * CURSOR_V_SIZE] =
+{
+	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAA, 0xFA, 0xAA, 0xAA, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAB, 0xFE, 0xAA, 0xAA, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAB, 0xFE, 0xAA, 0xAA, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAB, 0xFE, 0xAA, 0xAA, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAB, 0xFE, 0xAA, 0xAA, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAB, 0xFF, 0xEA, 0xAA, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAB, 0xFF, 0xFF, 0xAA, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAB, 0xFF, 0xFF, 0xFA, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAB, 0xFF, 0xFF, 0xFE, 0xAA, 0xAA,
+	0xAA, 0xAB, 0xFB, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA,
+	0xAA, 0xAB, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA,
+	0xAA, 0xAB, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xBF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xBF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAF, 0xFF, 0xFF, 0xFE, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAB, 0xFF, 0xFF, 0xFE, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAB, 0xFF, 0xFF, 0xFE, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFA, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFA, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFA, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA
+};
+
+void prepareCursor(bool enable) {
+	//Chip_LCD_Cursor_Disable(LPC_LCD, 0);
+    LPC_LCD->CRSR_CTRL = (CURSOR_NUM << 4);
+    
+    if (enable) {
+        //Chip_LCD_Cursor_Config(LPC_LCD, LCD_CURSOR_32x32, true);
+        LPC_LCD->CRSR_CFG = ((true ? 1 : 0) << 1) | CURSOR_SIZE;
+        
+        //Chip_LCD_Cursor_WriteImage(LPC_LCD, 0, (void *) Cursor);
+        {
+            int i, j;
+            uint32_t *fifoptr, *crsr_ptr = (uint32_t *) Cursor;
+
+            /* Check if Cursor Size was configured as 32x32 or 64x64*/
+            if (CURSOR_SIZE == LCD_CURSOR_32x32) {
+                i = CURSOR_NUM * 64;
+                j = i + 64;
+            }
+            else {
+                i = 0;
+                j = 256;
+            }
+            fifoptr = (uint32_t *) &(LPC_LCD->CRSR_IMG[0]);
+
+            /* Copy Cursor Image content to FIFO */
+            for (; i < j; i++) {
+
+                *fifoptr = *crsr_ptr;
+                crsr_ptr++;
+                fifoptr++;
+            }
+        }
+        
+        //Chip_LCD_Cursor_SetClip(LPC_LCD, CURSOR_H_OFS, CURSOR_V_OFS);
+        LPC_LCD->CRSR_CLIP = (CURSOR_H_OFS & 0x3F) | ((CURSOR_V_OFS & 0x3F) << 8);
+        
+        //Chip_LCD_Cursor_SetPos(LPC_LCD, cursor_x, cursor_y);
+        
+        //Chip_LCD_Cursor_Enable(LPC_LCD, 0);
+        LPC_LCD->CRSR_CTRL = (CURSOR_NUM << 4) | 1;
+    }
+}
+
+
+#define CIRCBUFF_SIZE 256
+static volatile uint8_t circbuff[CIRCBUFF_SIZE];
+static volatile uint32_t circbuff_read = 0;
+static uint32_t circbuff_write = 0;
+void keyEvent(uint8_t key)
+{
+    circbuff[circbuff_write%CIRCBUFF_SIZE] = key;
+    circbuff_write++;
+}
+
+bool msdConnected = false;
+bool keyboardConnected = false;
+bool mouseConnected = false;
+
+#define USB_TASK_PREFIX  "[USB] "
+#define USB_CONNECTION_EVENT   (1<<4)
+void usbTask(void const* args)
+{
+  USBHostMSD* msd = new USBHostMSD("usb");
+  USBHostKeyboard* keyboard = new USBHostKeyboard();
+  USBHostMouse* mouse = new USBHostMouse();
+  USBHost* host = USBHost::getHostInst();
+  host->signalOnConnections(Thread::gettid(), USB_CONNECTION_EVENT);
+
+  RtosLog* log = DMBoard::instance().logger();
+    
+  log->printf(USB_TASK_PREFIX"usbTask started\n");
+    
+  prepareCursor(false);
+
+  while (true) {
+    // wait for connect/disconnect message from USBHost
+    Thread::signal_wait(USB_CONNECTION_EVENT);
+    log->printf(USB_TASK_PREFIX"got USB event\n");
+      
+    if (msd->connected()) {
+      if (!msdConnected) {
+        msdConnected = true;
+        haveUSBMSD = true;
+        log->printf(USB_TASK_PREFIX"USB MassStorage Device - Connected\n");
+      }
+    } else {
+      if (msdConnected) {
+        msdConnected = false;
+        haveUSBMSD = false;
+        log->printf(USB_TASK_PREFIX"USB MassStorage Device - Ejected\n");
+      }
+      
+      if (msd->connect()) {
+        msdConnected = true;
+        haveUSBMSD = true;
+        log->printf(USB_TASK_PREFIX"USB MassStorage Device - Connected\n");
+      }      
+    }
+    
+    if (keyboard->connected()) {
+      if (!keyboardConnected) {
+        keyboardConnected = true;
+        log->printf(USB_TASK_PREFIX"USB Keyboard - Connected\n");
+        keyboard->attach(keyEvent);
+      }
+    } else {
+      if (keyboardConnected) {
+        keyboardConnected = false;
+        log->printf(USB_TASK_PREFIX"USB Keyboard - Ejected\n");
+      }
+      if (keyboard->connect()) {
+        keyboardConnected = true;
+        log->printf(USB_TASK_PREFIX"USB Keyboard - Connected\n");
+        keyboard->attach(keyEvent);
+      }
+    }
+    
+    if (mouse->connected()) {
+      if (!mouseConnected) {
+        mouseConnected = true;
+        log->printf(USB_TASK_PREFIX"USB Mouse - Connected\n");
+        mouse->attachEvent(mouseEvent);
+        prepareCursor(true);
+      }
+    } else {
+      if (mouseConnected) {
+        prepareCursor(false);
+        mouseConnected = false;
+        log->printf(USB_TASK_PREFIX"USB Mouse - Ejected\n");
+      }
+      if (mouse->connect()) {
+        mouseConnected = true;
+        log->printf(USB_TASK_PREFIX"USB Mouse - Connected\n");
+        mouse->attachEvent(mouseEvent);
+        prepareCursor(true);
+      }
+    }
+  }
+}
+
+
+
+/******************************************************************************
+ * Main function
+ *****************************************************************************/
+int main()
+{
+  DMBoard::BoardError err;
+  DMBoard* board = &DMBoard::instance();
+  RtosLog* log = board->logger();
+  err = board->init();
+  if (err != DMBoard::Ok) {
+    log->printf("Failed to initialize the board, got error %d\r\n", err);
+    log->printf("\nTERMINATING\n");
+    wait_ms(2000); // allow RtosLog to flush messages
+    mbed_die();
+  }
+  
+  // select which images to use based on display size
+  prepareResources();
+  
+  board->buzzer(440,50);
+  wait_ms(30);
+  board->buzzer(660,50);
+  wait_ms(30);
+  board->buzzer(440,50);
+  
+  log->printf("\n\n---\nDemo for Embedded World 2015\nBuilt: " __DATE__ " at " __TIME__ "\n\n");
+  
+ 
+  Thread tAlive(aliveTask);
+#if defined(DM_BOARD_USE_DISPLAY)
+  Thread tSwim(swimTask, NULL, osPriorityNormal, 8192);
+#endif  
+  Thread tNetwork(netTask, NULL, osPriorityNormal, 8192);
+  Thread tUSBHandler(usbTask, NULL, osPriorityNormal, 8192);
+  
+  while(1) { 
+    // Wait forever (in 1h increments) to prevent the tAlive, tSwim,
+    // tNetwork and tUSBHandler thread from being garbage collected.
+    Thread::wait(3600*1000);
+  }
+}
+
+