Example using the support package for LPC4088 DisplayModule

Dependencies:   DMBasicGUI DMSupport

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /******************************************************************************
00002  * Includes
00003  *****************************************************************************/
00004  
00005 #include "mbed.h"
00006 #include "mbed_interface.h"
00007 #include "rtos.h"
00008 
00009 #include "dm_board_config.h"
00010 
00011 #if defined(DM_BOARD_USE_ETHERNET)
00012   #include "EthernetInterface.h"
00013   #include "HTTPServer.h"
00014 #endif
00015 #if defined(DM_BOARD_USE_USB_DEVICE)
00016   #include "USBMSD_RAMFS.h"
00017   #include "USBSerial.h"
00018   #include "USBKeyboard.h"
00019   #include "AppUSBMouse.h"
00020 #endif
00021 #if defined(DM_BOARD_USE_USB_HOST)
00022   #include "USBHostMSD.h"
00023   #include "USBHostMouse.h"
00024   #include "USBHostKeyboard.h"
00025 #endif
00026 #include "DMBoard.h"
00027 
00028 #include "AppLauncher.h"
00029 #include "meas.h"
00030 
00031 #include "AppNetworkSettings.h"
00032 #include "AppStatus.h"
00033 #include "AppTouchCalibration.h"
00034 #include "AppColorPicker.h"
00035 #include "AppImageViewer.h"
00036 #include "AppSlideShow.h"
00037 #include "AppRTCSettings.h"
00038 //#include "AppUSBStatus.h"
00039 #include "AppDraw.h"
00040 #include "image_data.h"
00041 #include "Resource.h"
00042 
00043 
00044 /******************************************************************************
00045  * Typedefs and defines
00046  *****************************************************************************/
00047 
00048 /* Size of RAM file system exposed to PC as USB MassStorage */
00049 #define RAM_FS_SIZE (20*1024*1024)
00050 
00051 /******************************************************************************
00052  * Local variables
00053  *****************************************************************************/
00054 
00055 static Resource resOkButton(img_ok, img_size_ok, 40, 40);
00056 static Resource resRepeatButton(img_repeat, img_size_repeat, 40, 40);
00057 
00058 /******************************************************************************
00059  * Global variables
00060  *****************************************************************************/
00061 
00062 #if defined(DM_BOARD_USE_ETHERNET)
00063   EthernetInterface eth;
00064   bool ethInitialized = false;
00065   bool ethUsingDHCP = true;
00066 #endif
00067 #if defined(DM_BOARD_USE_USB_HOST)
00068   bool haveUSBMSD = false;
00069 #endif
00070 
00071 #if defined(DM_BOARD_USE_USB_DEVICE)
00072   //#define DEMO_USB_DEVICE_MOUSE
00073   //#define DEMO_USB_DEVICE_SERIAL
00074   #define DEMO_USB_DEVICE_MSD
00075 #endif
00076 
00077 /******************************************************************************
00078  * Local functions
00079  *****************************************************************************/
00080 
00081 void aliveTask(void)
00082 {
00083   DMBoard* board = &DMBoard::instance();
00084     
00085   while(true)
00086   {
00087     board->setLED(DMBoard::Led4, false);
00088     board->setLED(DMBoard::Led1, true);
00089     ThisThread::sleep_for(300);
00090     board->setLED(DMBoard::Led1, false);
00091     board->setLED(DMBoard::Led2, true);
00092     ThisThread::sleep_for(300);
00093     board->setLED(DMBoard::Led2, false);
00094     board->setLED(DMBoard::Led3, true);
00095     ThisThread::sleep_for(300);
00096     board->setLED(DMBoard::Led3, false);
00097     board->setLED(DMBoard::Led4, true);
00098     ThisThread::sleep_for(300);
00099   }
00100 }
00101 
00102 #if defined(DM_BOARD_USE_DISPLAY)
00103 
00104 typedef enum {
00105     ColorPickerApp,
00106     ImageViewerApp,
00107     SlideshowApp,
00108     SettingsApp, 
00109     StatusApp, 
00110     TouchTestApp,
00111     RtcApp,
00112     USBStatusApp,
00113     DrawingApp,
00114     USBMouseApp,
00115     CalibrationApp =  AppLauncher::CalibrationApp,
00116     Placeholder,
00117 } myapps_t;
00118 
00119 static App* launchApp(uint32_t id)
00120 {
00121   App* a = NULL;
00122   switch ((myapps_t)id) {
00123       case CalibrationApp:
00124           a = new AppTouchCalibration();
00125          ((AppTouchCalibration*)a)->addResource(AppTouchCalibration::Resource_Ok_button, &resOkButton);
00126           break;
00127       case SettingsApp:
00128           a = new AppNetworkSettings();
00129           break;
00130       case ColorPickerApp:
00131           a = new AppColorPicker();
00132          ((AppColorPicker*)a)->addResource(AppColorPicker::Resource_Ok_button, &resOkButton);
00133           break;
00134       case ImageViewerApp:
00135           a = new AppImageViewer();
00136           break;
00137       case SlideshowApp:
00138           a = new AppSlideShow("/mci/elec14/ea_logo.txt", "/mci/elec14", 0, 0);
00139          ((AppSlideShow*)a)->addResource(AppSlideShow::Resource_Ok_button, &resOkButton);
00140          ((AppSlideShow*)a)->addResource(AppSlideShow::Resource_Repeat_button, &resRepeatButton);
00141           break;
00142       case StatusApp:
00143           a = new AppStatus();
00144           break;
00145       case RtcApp:
00146           a = new AppRTCSettings();
00147           break;
00148       case USBStatusApp:
00149           //a = new AppUSBStatus();
00150           break;
00151       case DrawingApp:
00152           a = new AppDraw();
00153           break;
00154 #if defined(DM_BOARD_USE_USB_DEVICE) && defined(DEMO_USB_DEVICE_MOUSE)
00155       case USBMouseApp:
00156           a = new AppUSBMouse();
00157           break;
00158 #endif
00159       default:
00160           break;
00161   }
00162   return a;
00163 }
00164 
00165 #define SWIM_TASK_PREFIX  "[SWIM] "
00166 void swimTask(void)
00167 {
00168   RtosLog* log = DMBoard::instance().logger();
00169     
00170   log->printf(SWIM_TASK_PREFIX"swimTask started\n");
00171   
00172   AppLauncher launcher;
00173     
00174     
00175   if (launcher.setup()) {
00176     launcher.addImageButton(SettingsApp, "Network", WHITE,  img_preferences_system_network, img_size_preferences_system_network);
00177     launcher.addImageButton(DrawingApp, "Drawing", WHITE, img_bijiben, img_size_bijiben);
00178     launcher.addImageButton(SlideshowApp, "Slideshow", WHITE, img_multimedia_photo_manager, img_size_multimedia_photo_manager);
00179     //launcher.addImageButton(TouchGFXApp,  "TouchGFX");
00180     //launcher.addImageButton(EmWinApp,     "emWin");
00181     launcher.addImageButton(ColorPickerApp, "Color Picker", WHITE,  img_preferences_color, img_size_preferences_color);
00182     launcher.addImageButton(ImageViewerApp, "Image Viewer", WHITE,  img_multimedia_photo_manager, img_size_multimedia_photo_manager);
00183     launcher.addImageButton(StatusApp, "About", WHITE,  img_utilities_system_monitor, img_size_utilities_system_monitor);
00184 #if defined(DM_BOARD_USE_USB_DEVICE) && defined(DEMO_USB_DEVICE_MOUSE)
00185     launcher.addImageButton(USBMouseApp, "USB Mouse", WHITE,  img_unetbootin, img_size_unetbootin);
00186 #else
00187     launcher.addImageButton(Placeholder, "USB Status", WHITE,  img_unetbootin, img_size_unetbootin);
00188 #endif
00189     launcher.addImageButton(RtcApp, "Clock", WHITE,  img_preferences_system_time, img_size_preferences_system_time);
00190       
00191     launcher.setAppCreatorFunc(launchApp);
00192     log->printf(SWIM_TASK_PREFIX"Starting menu system\n");
00193     launcher.runToCompletion();
00194     launcher.teardown();
00195   } else {
00196     log->printf(SWIM_TASK_PREFIX"Failed to prepare menu system\n");
00197   }
00198   
00199   // Should never end up here  
00200   mbed_die();
00201 }
00202 
00203 #endif //DM_BOARD_USE_DISPLAY
00204 
00205 #if defined(DM_BOARD_USE_ETHERNET)
00206 
00207   #define NET_TASK_PREFIX  "[NET] "  
00208   void netTask(void)
00209   {
00210     RtosLog* log = DMBoard::instance().logger();
00211     log->printf(NET_TASK_PREFIX"EthernetInterface Setting up...\r\n"); 
00212 
00213     nsapi_error_t net_err = eth.connect();
00214 
00215     if (net_err != NSAPI_ERROR_OK) {
00216         log->printf(NET_TASK_PREFIX"EthernetInterface connect Error %d\r\n", net_err);
00217     }
00218     else {
00219 
00220         ethInitialized = true;
00221         ethUsingDHCP = true;
00222     
00223         log->printf(NET_TASK_PREFIX"IP Address is %s\r\n", eth.get_ip_address());
00224         log->printf(NET_TASK_PREFIX"NetMask is %s\r\n", eth.get_netmask());
00225         log->printf(NET_TASK_PREFIX"Gateway Address is %s\r\n", eth.get_gateway());
00226         log->printf(NET_TASK_PREFIX"Ethernet Setup OK\r\n");
00227   
00228         HTTPServerAddHandler<SimpleHandler>("/hello"); //Default handler
00229         FSHandler::mount("/mci", "/");
00230         HTTPServerAddHandler<FSHandler>("/");
00231         //lcd.locate(0,0);
00232         //lcd.printf("%s",eth.getIPAddress());
00233         HTTPServerStart(80);
00234 
00235     }    
00236     
00237 
00238   }
00239 #endif //DM_BOARD_USE_ETHERNET
00240 
00241 #if defined(DM_BOARD_USE_USB_HOST)
00242 static volatile int mouse_button, mouse_x, mouse_y, mouse_z;
00243 static uint16_t cursor_x=0, cursor_y=0;
00244 void mouseEvent(uint8_t buttons, int8_t x, int8_t y, int8_t z)
00245 {
00246     mouse_button = buttons;
00247     mouse_x = x;
00248     mouse_y = y;
00249     mouse_z = z;
00250     
00251     if (x < 0) {
00252         if (cursor_x > -x) {
00253             cursor_x += x;
00254         } else {
00255             cursor_x = 0;
00256         }
00257     } else {
00258         if ((cursor_x + x) >= 480) {
00259             cursor_x = 479;
00260         } else {
00261             cursor_x += x;
00262         }
00263     }
00264 
00265     if (y < 0) {
00266         if (cursor_y > -y) {
00267             cursor_y += y;
00268         } else {
00269             cursor_y = 0;
00270         }
00271     } else {
00272         if ((cursor_y + y) >= 272) {
00273             cursor_y = 271;
00274         } else {
00275             cursor_y += y;
00276         }
00277     }
00278     
00279     //Chip_LCD_Cursor_SetPos(LPC_LCD, cursor_x, cursor_y);
00280     LPC_LCD->CRSR_XY = (cursor_x & 0x3FF) | ((cursor_y & 0x3FF) << 16);
00281 }
00282 
00283 #define LCD_CURSOR_32x32 0
00284 #define LCD_CURSOR_64x64 1
00285 #define CURSOR_SIZE  LCD_CURSOR_32x32
00286 #define CURSOR_H_SIZE 32
00287 #define CURSOR_V_SIZE 32
00288 #define CURSOR_NUM   0    
00289 #define CURSOR_H_OFS (10)
00290 #define CURSOR_V_OFS (6)
00291 
00292 const unsigned char __attribute__ ((aligned(4))) Cursor[(CURSOR_H_SIZE / 4) * CURSOR_V_SIZE] =
00293 {
00294     0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
00295     0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
00296     0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
00297     0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
00298     0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
00299     0xAA, 0xAA, 0xAA, 0xFA, 0xAA, 0xAA, 0xAA, 0xAA,
00300     0xAA, 0xAA, 0xAB, 0xFE, 0xAA, 0xAA, 0xAA, 0xAA,
00301     0xAA, 0xAA, 0xAB, 0xFE, 0xAA, 0xAA, 0xAA, 0xAA,
00302     0xAA, 0xAA, 0xAB, 0xFE, 0xAA, 0xAA, 0xAA, 0xAA,
00303     0xAA, 0xAA, 0xAB, 0xFE, 0xAA, 0xAA, 0xAA, 0xAA,
00304     0xAA, 0xAA, 0xAB, 0xFF, 0xEA, 0xAA, 0xAA, 0xAA,
00305     0xAA, 0xAA, 0xAB, 0xFF, 0xFF, 0xAA, 0xAA, 0xAA,
00306     0xAA, 0xAA, 0xAB, 0xFF, 0xFF, 0xFA, 0xAA, 0xAA,
00307     0xAA, 0xAA, 0xAB, 0xFF, 0xFF, 0xFE, 0xAA, 0xAA,
00308     0xAA, 0xAB, 0xFB, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA,
00309     0xAA, 0xAB, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA,
00310     0xAA, 0xAB, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA,
00311     0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA,
00312     0xAA, 0xAA, 0xBF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA,
00313     0xAA, 0xAA, 0xBF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA,
00314     0xAA, 0xAA, 0xAF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA,
00315     0xAA, 0xAA, 0xAF, 0xFF, 0xFF, 0xFE, 0xAA, 0xAA,
00316     0xAA, 0xAA, 0xAB, 0xFF, 0xFF, 0xFE, 0xAA, 0xAA,
00317     0xAA, 0xAA, 0xAB, 0xFF, 0xFF, 0xFE, 0xAA, 0xAA,
00318     0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFA, 0xAA, 0xAA,
00319     0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFA, 0xAA, 0xAA,
00320     0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFA, 0xAA, 0xAA,
00321     0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
00322     0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
00323     0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
00324     0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
00325     0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA
00326 };
00327 
00328 void prepareCursor(bool enable) {
00329     //Chip_LCD_Cursor_Disable(LPC_LCD, 0);
00330     LPC_LCD->CRSR_CTRL = (CURSOR_NUM << 4);
00331     
00332     if (enable) {
00333         //Chip_LCD_Cursor_Config(LPC_LCD, LCD_CURSOR_32x32, true);
00334         LPC_LCD->CRSR_CFG = ((true ? 1 : 0) << 1) | CURSOR_SIZE;
00335         
00336         //Chip_LCD_Cursor_WriteImage(LPC_LCD, 0, (void *) Cursor);
00337         {
00338             int i, j;
00339             uint32_t *fifoptr, *crsr_ptr = (uint32_t *) Cursor;
00340 
00341             /* Check if Cursor Size was configured as 32x32 or 64x64*/
00342             if (CURSOR_SIZE == LCD_CURSOR_32x32) {
00343                 i = CURSOR_NUM * 64;
00344                 j = i + 64;
00345             }
00346             else {
00347                 i = 0;
00348                 j = 256;
00349             }
00350             fifoptr = (uint32_t *) &(LPC_LCD->CRSR_IMG[0]);
00351 
00352             /* Copy Cursor Image content to FIFO */
00353             for (; i < j; i++) {
00354 
00355                 *fifoptr = *crsr_ptr;
00356                 crsr_ptr++;
00357                 fifoptr++;
00358             }
00359         }
00360         
00361         //Chip_LCD_Cursor_SetClip(LPC_LCD, CURSOR_H_OFS, CURSOR_V_OFS);
00362         LPC_LCD->CRSR_CLIP = (CURSOR_H_OFS & 0x3F) | ((CURSOR_V_OFS & 0x3F) << 8);
00363         
00364         //Chip_LCD_Cursor_SetPos(LPC_LCD, cursor_x, cursor_y);
00365         
00366         //Chip_LCD_Cursor_Enable(LPC_LCD, 0);
00367         LPC_LCD->CRSR_CTRL = (CURSOR_NUM << 4) | 1;
00368     }
00369 }
00370 
00371 
00372 #define CIRCBUFF_SIZE 256
00373 static volatile uint8_t circbuff[CIRCBUFF_SIZE];
00374 static volatile uint32_t circbuff_read = 0;
00375 static uint32_t circbuff_write = 0;
00376 void keyEvent(uint8_t key)
00377 {
00378     circbuff[circbuff_write%CIRCBUFF_SIZE] = key;
00379     circbuff_write++;
00380 }
00381 
00382 
00383 #define USBH_TASK_PREFIX  "[USBH] "
00384 #define USBH_CONNECTION_EVENT   (1<<4)
00385 void usbHostTask(void)
00386 {
00387   bool msdConnected = false;
00388   bool keyboardConnected = false;
00389   bool mouseConnected = false;
00390 
00391   USBHostMSD* msd = new USBHostMSD("usb");
00392   USBHostKeyboard* keyboard = new USBHostKeyboard();
00393   USBHostMouse* mouse = new USBHostMouse();
00394   USBHost* host = USBHost::getHostInst();
00395   EventFlags connectionEvent;
00396   host->signalOnConnections(&connectionEvent, USBH_CONNECTION_EVENT);
00397 
00398   RtosLog* log = DMBoard::instance().logger();
00399     
00400   log->printf(USBH_TASK_PREFIX"Started\n");
00401     
00402   prepareCursor(false);
00403 
00404   while (true) {
00405 
00406     // wait for connect/disconnect message from USBHost
00407     connectionEvent.wait_any(USBH_CONNECTION_EVENT);
00408     log->printf(USBH_TASK_PREFIX"got USB event\n");
00409 
00410     if (msd->connected()) {
00411       if (!msdConnected) {
00412         msdConnected = true;
00413         haveUSBMSD = true;
00414         log->printf(USBH_TASK_PREFIX"USB MassStorage Device - Connected\n");
00415       }
00416     } else {
00417       if (msdConnected) {
00418         msdConnected = false;
00419         haveUSBMSD = false;
00420         log->printf(USBH_TASK_PREFIX"USB MassStorage Device - Ejected\n");
00421       }
00422       
00423       if (msd->connect()) {
00424         msdConnected = true;
00425         haveUSBMSD = true;
00426         log->printf(USBH_TASK_PREFIX"USB MassStorage Device - Connected\n");
00427       }      
00428     }
00429     
00430     if (keyboard->connected()) {
00431       if (!keyboardConnected) {
00432         keyboardConnected = true;
00433         log->printf(USBH_TASK_PREFIX"USB Keyboard - Connected\n");
00434         keyboard->attach(keyEvent);
00435       }
00436     } else {
00437       if (keyboardConnected) {
00438         keyboardConnected = false;
00439         log->printf(USBH_TASK_PREFIX"USB Keyboard - Ejected\n");
00440       }
00441       if (keyboard->connect()) {
00442         keyboardConnected = true;
00443         log->printf(USBH_TASK_PREFIX"USB Keyboard - Connected\n");
00444         keyboard->attach(keyEvent);
00445       }
00446     }
00447     
00448     if (mouse->connected()) {
00449       if (!mouseConnected) {
00450         mouseConnected = true;
00451         log->printf(USBH_TASK_PREFIX"USB Mouse - Connected\n");
00452         mouse->attachEvent(mouseEvent);
00453         prepareCursor(true);
00454       }
00455     } else {
00456       if (mouseConnected) {
00457         prepareCursor(false);
00458         mouseConnected = false;
00459         log->printf(USBH_TASK_PREFIX"USB Mouse - Ejected\n");
00460       }
00461       if (mouse->connect()) {
00462         mouseConnected = true;
00463         log->printf(USBH_TASK_PREFIX"USB Mouse - Connected\n");
00464         mouse->attachEvent(mouseEvent);
00465         prepareCursor(true);
00466       }
00467     }
00468 
00469   }
00470 }
00471 
00472 #endif //DM_BOARD_USE_USB_HOST
00473 
00474 #if defined(DM_BOARD_USE_USB_DEVICE)
00475 
00476   #define USBD_TASK_PREFIX  "[USBD] "
00477   //#define USBD_CONNECTION_EVENT   (1<<4)
00478   void usbDeviceTask(void)
00479   {
00480     DMBoard* board = &DMBoard::instance();
00481     RtosLog* log = board->logger();
00482       
00483     log->printf(USBD_TASK_PREFIX"Started\n");
00484   
00485     // Possibilities:
00486     // - MassStorage
00487     //    * RAM file system
00488     //        a) For editing of settings or registry
00489     //        b) To give user an html file with information
00490     //        c) For BIOS updating
00491     //    * Expose MCI file system
00492     // - Serial
00493     //    * Let RtosLogger use the USBDevice serial port instead to 
00494     //      allow prints during debugging
00495     // - Mouse
00496     //    * Use the display as a "trackpad"
00497     // - Keyboard
00498     //    * Could be used by the RtosLogger (for fun)
00499     //    * Write our logo in ASCII art (for fun)
00500     // - Audio?
00501     // - CDC?
00502       
00503 #if defined(DEMO_USB_DEVICE_MSD)
00504     // USBDevice: MassStorage - Expose a 5MB RAM file system
00505     //
00506     // Notes: 
00507     //    * Copying the large file to the PC at ca 512Kbyte per second
00508     //    * Copying a large file to the board at ca 800Kbyte per second
00509     void* fsmem = malloc(RAM_FS_SIZE);
00510     if (fsmem == NULL) {
00511       log->printf("Failed to allocate memory for RAM file system\n");
00512       mbed_die();
00513     }
00514     RAMFileSystem ramfs((uint32_t)fsmem, RAM_FS_SIZE, "ram");
00515     USBMSD_RAMFS usbmsd(&ramfs);  
00516     ramfs.format();
00517     
00518     // Create test file that user can modify
00519     FILE* f = fopen("/ram/message.txt", "w");
00520     if (f != NULL) {
00521       fwrite("Hello World!\n", 1, 13, f);
00522       fclose(f);
00523     }
00524     
00525     // Create benchmark file
00526     uint32_t benchSize = RAM_FS_SIZE - 1*1024*1024;
00527     log->printf(USBD_TASK_PREFIX"Generating %dMB benchmarking file...\n", benchSize/(1024*1024));
00528     char buff[512+1] = {0};
00529     for (int i = 0; i < 512; i++) {
00530       buff[i] = i;
00531     }
00532     f = fopen("/ram/bench.bin", "w");
00533     if (f != NULL) {
00534       for (int i = 0; i < (benchSize/512); i++) {
00535         fwrite(buff, 1, 512, f);
00536       }
00537       fclose(f);
00538     }
00539     log->printf(USBD_TASK_PREFIX"Finished generating /ram/bench.bin\n");
00540     
00541     while (true) {
00542       if (usbmsd.connect()) {
00543         log->printf(USBD_TASK_PREFIX"USB MassStorage - Connected\n");
00544         log->printf(USBD_TASK_PREFIX"Press USER button to disconnect USB MassStorage!\n");
00545         while (!board->buttonPressed()) {
00546           Thread::wait(50);
00547         }
00548         log->printf(USBD_TASK_PREFIX"User requested USB disconnect\n");
00549         usbmsd.disconnect();
00550         while (board->buttonPressed()) {
00551           Thread::wait(50);
00552         }
00553         log->printf(USBD_TASK_PREFIX"USB disconnected\n");
00554         
00555         {
00556           log->printf("Reading /ram/message.txt:\n");
00557           f = fopen("/ram/message.txt", "r");
00558           if (f != NULL) {
00559             while (true) {
00560               size_t num = fread(buff, 1, 512, f);
00561               if (num > 0) {
00562                 buff[num] = '\0';
00563                 log->printf(buff);
00564               } else {
00565                 break;
00566               }
00567             }
00568             fclose(f);
00569             log->printf("\nEOF\n");
00570           } else {
00571             log->printf("Failed to read /ram/message.txt\n");
00572           }
00573         }
00574         
00575         log->printf("\n"USBD_TASK_PREFIX"Press USER button to connect USB MassStorage again!\n");
00576         while (!board->buttonPressed()) {
00577           Thread::wait(50);
00578         }
00579         while (board->buttonPressed()) {
00580           Thread::wait(50);
00581         }
00582         log->printf(USBD_TASK_PREFIX"User requested to connect USB again\n");
00583       } 
00584     }
00585 #endif // #if defined(DEMO_USB_DEVICE_MSD)
00586     
00587 #if defined(DEMO_USB_DEVICE_SERIAL)
00588     // USBDevice: Serial  (see http://developer.mbed.org/handbook/USBSerial)
00589     // http://developer.mbed.org/questions/5872/User-Friendly-Installation-of-USBSerial-/
00590     //
00591     // Notes: 
00592     //    * Works, but a reset (e.g. Alt-B) requires the USB cable to be ejected+inserted 
00593     //      for the PC to see the COM port again. It does not help to restart the Terminal
00594     //      program
00595     //    * Unplugging the USB cable after the terminal program on the PC has connected
00596     //      and then plugging it in again does not work. The terminal program will not see
00597     //      the port until after a bord reset. 
00598     //      Update: This seems to be the Terminal Program's fault. Restarting the terminal
00599     //      program will make the port appear again.
00600     //    * It is possible to have the cable connected before powering up as well as connecting
00601     //      the cable after powering up.
00602   #if defined(DM_BOARD_USE_USBSERIAL_IN_RTOSLOG)
00603     int counter = 0;
00604     while(true) {
00605         Thread::wait(1000);
00606         log->printf(USBD_TASK_PREFIX"Counter %3d\n", counter++);
00607     }
00608   #else
00609     USBSerial s;
00610     int counter = 0;
00611     while(true) {
00612         Thread::wait(1000);
00613         s.printf(USBD_TASK_PREFIX"Counter %3d\n", counter++);
00614     }
00615   #endif
00616 #endif // #if defined(DEMO_USB_DEVICE_SERIAL)
00617     
00618 #if defined(DEMO_USB_DEVICE_MOUSE)
00619     // Notes: 
00620     //    * If the USBMouse class is used after this then the USBKeyboard stops working.
00621     //      if both are to be used then the USBMouseKeyboard class must be used instead.
00622     USBKeyboard keyb;
00623     while(true) {
00624       while (!board->buttonPressed()) {
00625         Thread::wait(50);
00626       }
00627       keyb.printf("Hello World!\n");
00628       while (board->buttonPressed()) {
00629         Thread::wait(50);
00630       }
00631     }
00632 #endif // #if defined(DEMO_USB_DEVICE_MOUSE)    
00633   }
00634 #endif
00635 
00636 
00637 #define REGTEST "[REG] "
00638 static void testRegistry()
00639 {
00640   Registry* reg = DMBoard::instance().registry();
00641   RtosLog* log = DMBoard::instance().logger();
00642   char* key;
00643   char* val;
00644   Registry::RegistryError err;
00645     
00646   log->printf(REGTEST"Before:\n");
00647   for (int i = 0; i < reg->numEntries(); i++) {
00648     err = reg->entryAt(i, &key, &val);
00649     if (err == Registry::Ok) {
00650       log->printf(REGTEST"   [%2d] '%s' = '%s'\n", i, key, val);
00651       free(key);
00652       free(val);
00653     } else {
00654       log->printf(REGTEST"   [%2d] got error %d\n", i, err);
00655     }
00656   }
00657   
00658   log->printf(REGTEST"Getting existing value:\n");
00659   err = reg->getValue("IP Address", &val);
00660   if (err == Registry::Ok) {
00661     log->printf(REGTEST"   Existing 'IP Address' = '%s'\n", val);
00662     free(val);
00663   } else {
00664     log->printf(REGTEST"   Existing 'IP Address' got error %d\n", err);
00665   }
00666   
00667   log->printf(REGTEST"Getting missing value:\n");
00668   err = reg->getValue("X78g4dfwx", &val);
00669   if (err == Registry::Ok) {
00670     log->printf(REGTEST"   Missing 'X78g4dfwx' = '%s'\n", val);
00671     free(val);
00672   } else if (err == Registry::NoSuchKeyError) {
00673     log->printf(REGTEST"   Missing 'X78g4dfwx' was missing.\n", err);
00674   } else {
00675     log->printf(REGTEST"   Existing 'X78g4dfwx' got error %d\n", err);
00676   }
00677 
00678   log->printf(REGTEST"Updating value:\n");
00679   err = reg->getValue("EATest", &val);
00680   if (err == Registry::Ok) {
00681     log->printf(REGTEST"   Old value for 'EATest' = '%s'\n", val);
00682     char buf[32];
00683     sprintf(buf, "%d", atoi(val)+1);
00684     free(val);
00685     err = reg->setValue("EATest", buf);
00686     if (err == Registry::Ok) {
00687       log->printf(REGTEST"   Updated 'EATest' to '%s'\n", buf);
00688     } else {
00689       log->printf(REGTEST"   Failed to update 'EATest', got error %d\n", err);
00690     }
00691   } else if (err == Registry::NoSuchKeyError) {
00692     log->printf(REGTEST"   No value for 'EATest', adding one\n", err);
00693     err = reg->setValue("EATest", "-3");
00694     if (err == Registry::Ok) {
00695       log->printf(REGTEST"   Set 'EATest' to '0'\n");
00696     } else {
00697       log->printf(REGTEST"   Failed to set 'EATest', got error %d\n", err);
00698     }
00699   } else {
00700     log->printf(REGTEST"   Failed to read 'EATest' got error %d\n", err);
00701   }
00702   
00703   log->printf(REGTEST"Storing values persistently\n");
00704   err = reg->store();
00705   if (err != Registry::Ok) {
00706     log->printf(REGTEST"   Failed to store values, got error %d\n", err);
00707   }
00708 
00709   log->printf(REGTEST"After:\n");
00710   for (int i = 0; i < reg->numEntries(); i++) {
00711     err = reg->entryAt(i, &key, &val);
00712     if (err == Registry::Ok) {
00713       log->printf(REGTEST"   [%2d] '%s' = '%s'\n", i, key, val);
00714       free(key);
00715       free(val);
00716     } else {
00717       log->printf(REGTEST"   [%2d] got error %d\n", i, err);
00718     }
00719   }  
00720 }
00721 
00722 /******************************************************************************
00723  * Main function
00724  *****************************************************************************/
00725 int main()
00726 {
00727   DMBoard::BoardError err;
00728   DMBoard* board = &DMBoard::instance();
00729   RtosLog* log = board->logger();
00730   err = board->init();
00731   if (err != DMBoard::Ok) {
00732     log->printf("Failed to initialize the board, got error %d\r\n", err);
00733     log->printf("\nTERMINATING\n");
00734     ThisThread::sleep_for(2000); // allow RtosLog to flush messages
00735     mbed_die();
00736   }
00737 
00738   board->buzzer(440,50);
00739   wait_ms(30);
00740   board->buzzer(660,50);
00741   wait_ms(30);
00742   board->buzzer(440,50);
00743   
00744   log->printf("\n\n---\nMulti-threaded demo\nBuilt: " __DATE__ " at " __TIME__ "\n\n");
00745   
00746   //testRegistry();
00747   
00748   
00749   Thread tAlive;
00750   tAlive.start(aliveTask);
00751 #if defined(DM_BOARD_USE_DISPLAY)
00752   Thread tSwim(osPriorityNormal, 8192);
00753   tSwim.start(swimTask);
00754 #endif
00755 
00756 
00757 
00758 #if defined(DM_BOARD_USE_ETHERNET)  
00759   Thread tNetwork(osPriorityNormal, 8192);
00760   tNetwork.start(netTask);
00761 #endif
00762 
00763 #if defined(DM_BOARD_USE_USB_HOST)
00764   Thread tUSBHandler(osPriorityNormal, 8192);
00765   tUSBHandler.start(usbHostTask);
00766 #elif defined(DM_BOARD_USE_USB_DEVICE)
00767   Thread tUSBDev(osPriorityNormal, 8192);
00768   tUSBDev.start(usbDeviceTask);
00769 #endif
00770 
00771   while(1) { 
00772     ThisThread::sleep_for(5000);
00773     time_t seconds = time(NULL);
00774 
00775     log->printf("Time: %s\n", ctime(&seconds));
00776   }
00777 }