The out-of-the-box demo application flashed on all display modules before they are shipped.

Dependencies:   DMBasicGUI DMSupport

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers <title>AppUSBStatus.cpp Source File</title>

AppUSBStatus.cpp

00001 /*
00002  *  Copyright 2014 Embedded Artists AB
00003  *
00004  *  Licensed under the Apache License, Version 2.0 (the "License");
00005  *  you may not use this file except in compliance with the License.
00006  *  You may obtain a copy of the License at
00007  *
00008  *    http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  *  Unless required by applicable law or agreed to in writing, software
00011  *  distributed under the License is distributed on an "AS IS" BASIS,
00012  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  *  See the License for the specific language governing permissions and
00014  *  limitations under the License.
00015  */
00016 
00017 
00018 #include "mbed.h"
00019 #include "EthernetInterface.h"
00020 #include "AppUSBStatus.h"
00021 #include "lpc_swim_image.h"
00022 #include "lpc_swim_font.h"
00023 #include "image_data.h"
00024 #include "BiosLoader.h"
00025 
00026 /******************************************************************************
00027  * Defines and typedefs
00028  *****************************************************************************/
00029  
00030 #define HEADER_X_OFF            (20-5)
00031 #define HEADER_Y_SPACING        (20-5)
00032 #define ITEM_CAPTION_X_OFF      (40-15)
00033 #define ITEM_CAPTION_Y_SPACING  (swim_get_font_height(_win) + 5)
00034 #define ITEM_VALUE_X_OFF        (140-25)
00035 #define COL3_OFF                (230+70)
00036 #define COL4                    (COL3_OFF + ITEM_VALUE_X_OFF - 5)
00037 
00038 #define BTN_OFF    20
00039  
00040 #define DEMO_VERSION     "v0.9"
00041 #define DEMO_BUILD_INFO  __DATE__ " " __TIME__
00042 
00043 #define DESCR(__res, __disp) \
00044   (((__res) == ((__disp)->currentResolution())) ? ("Active") : (((__disp)->isSupported(__res)) ? ("Supported") : ("N/A")))
00045 
00046 
00047 static const unsigned char* IMAGES[] = {
00048   img_usb_masstorage,
00049   img_usb_masstorage_ejected,
00050   img_usb_mouse,
00051   img_usb_mouse_ejected,
00052   img_usb_keyboard,
00053   img_usb_keyboard_ejected,
00054 };
00055 static const unsigned int IMAGE_SIZES[] = {
00056   img_size_usb_masstorage,
00057   img_size_usb_masstorage_ejected,
00058   img_size_usb_mouse,
00059   img_size_usb_mouse_ejected,
00060   img_size_usb_keyboard,
00061   img_size_usb_keyboard_ejected,
00062 };
00063 static const char* CAPTIONS[] = {
00064   "Memory Stick",
00065   "No Memory Stick",
00066   "Mouse",
00067   "No Mouse",
00068   "Keyboard",
00069   "No Keyboard",
00070 };
00071 
00072 /******************************************************************************
00073  * Global variables
00074  *****************************************************************************/
00075 
00076 extern bool msdConnected;
00077 extern bool keyboardConnected;
00078 extern bool mouseConnected;
00079 
00080 /******************************************************************************
00081  * Private functions
00082  *****************************************************************************/
00083 
00084 static void buttonClicked(uint32_t x)
00085 {
00086   bool* done = (bool*)x;
00087   *done = true;
00088 }
00089 
00090 void AppUSBStatus::draw()
00091 {
00092     // Prepare fullscreen
00093     swim_window_open(_win, 
00094                    _disp->width(), _disp->height(),         // full size
00095                    (COLOR_T*)_fb,
00096                    0,0,_disp->width()-1, _disp->height()-1, // window position and size
00097                    0,                                       // border
00098                    BLACK, WHITE, BLACK);                     // colors: pen, backgr, forgr
00099     //swim_set_title(_win, "USB Status", BLACK);
00100     
00101     // Start by drawing all USB Devices disconnected. Each device is drawn in
00102     // its own window so that the positioning information can be kept here
00103     int images = NumImages/2;
00104     int xspace = (_disp->width() - (_images[0].width * images)) / 4;
00105     int yoff = (_disp->height() - _images[0].height)/3;
00106     int xoff = xspace;
00107     for (int i = 1; i < NumImages; i+=2) {
00108       swim_window_open(&_imageWindows[i/2], 
00109                        _disp->width(), _disp->height(),         // full size
00110                        (COLOR_T*)_fb,
00111                        xoff,yoff,xoff+_images[0].width-1, yoff+_images[0].height+20-1, // window position and size
00112                        0,                                       // border
00113                        BLACK, WHITE, BLACK);                     // colors: pen, backgr, forgr
00114       swim_put_image(&_imageWindows[i/2], _images[i].pixels, _images[i].width, _images[i].height);
00115         
00116       swim_put_text_centered_win(&_imageWindows[i/2], CAPTIONS[i], _images[i].height);
00117       xoff += _images[i].width + xspace;
00118     }
00119 
00120     _btn = new ImageButton(_win->fb, _win->xpmax - BTN_OFF - _resOk->width(), _win->ypmax - BTN_OFF - _resOk->height(), _resOk->width(), _resOk->height());
00121     _btn->loadImages(_resOk);
00122     _btn->draw();
00123 }
00124 
00125 void AppUSBStatus::updateStatus(Ids id)    
00126 {
00127     SWIM_WINDOW_T* pWin = &_imageWindows[id/2];
00128     swim_clear_screen(pWin, WHITE);
00129     swim_put_image(pWin, _images[id].pixels, _images[id].width, _images[id].height);    
00130     swim_put_text_centered_win(pWin, CAPTIONS[id], _images[id].height);
00131 }
00132 
00133 /******************************************************************************
00134  * Public functions
00135  *****************************************************************************/
00136 
00137 AppUSBStatus::AppUSBStatus() : _disp(NULL), _win(NULL), _fb(NULL), 
00138   _btn(NULL), _resOk(NULL)
00139 {
00140   for (int i = 0; i < NumImages; i++) {
00141     _images[i].pointerToFree = NULL;
00142     _images[i].pixels = NULL;
00143   }
00144 }
00145 
00146 AppUSBStatus::~AppUSBStatus()
00147 {
00148     teardown();
00149 }
00150 
00151 bool AppUSBStatus::setup()
00152 {
00153     RtosLog* log = DMBoard::instance().logger();
00154 
00155     _disp = DMBoard::instance().display();
00156     _win = (SWIM_WINDOW_T*)malloc(sizeof(SWIM_WINDOW_T));
00157     _fb = _disp->allocateFramebuffer();
00158 
00159     if (_win == NULL || _fb == NULL) {
00160         log->printf("Failed to allocate memory for framebuffer\r\n");
00161         return false;
00162     }
00163     
00164     for (int i = 0; i < NumImages; i++) {
00165         if (Image::decode(IMAGES[i], IMAGE_SIZES[i], Image::RES_16BIT, &_images[i]) != 0) {
00166             log->printf("Failed to load image %d of %d\n", i+1, NumImages);
00167             return false;
00168         }
00169     }
00170     
00171     return true;
00172 }
00173 
00174 void AppUSBStatus::runToCompletion()
00175 {
00176     // Alternative 1: use the calling thread's context to run in
00177     bool done = false;
00178     draw();
00179     _btn->setAction(buttonClicked, (uint32_t)&done);
00180     void* oldFB = _disp->swapFramebuffer(_fb);
00181     
00182     // Wait for touches, but the AppLauncher is already listening
00183     // for new touch event and sends a signal to its thread which
00184     // is the same as runs this function so it is enough to wait
00185     // for that signal.
00186     TouchPanel* touch = DMBoard::instance().touchPanel();
00187     touch_coordinate_t coord;
00188     bool lastMassStorage = false;
00189     bool lastMouse = false;
00190     bool lastKeyboard = false;
00191     while(!done) {
00192       ThisThread::flags_wait_all_for(0x1, 500);
00193       if (touch->read(coord) == TouchPanel::TouchError_Ok) {
00194         if (_btn->handle(coord.x, coord.y, coord.z > 0)) {
00195             _btn->draw();
00196         }
00197       }
00198       if (lastMassStorage != msdConnected) {
00199         lastMassStorage = msdConnected;
00200         updateStatus(lastMassStorage ? USBHost_MassStorage_Inserted : USBHost_MassStorage_Ejected);
00201       }
00202       if (lastKeyboard != keyboardConnected) {
00203         lastKeyboard = keyboardConnected;
00204         updateStatus(lastKeyboard ? USBHost_Keyboard_Inserted : USBHost_Keyboard_Ejected);
00205       }
00206       if (lastMouse != mouseConnected) {
00207         lastMouse = mouseConnected;
00208         updateStatus(lastMouse ? USBHost_Mouse_Inserted : USBHost_Mouse_Ejected);
00209       }
00210     }
00211     
00212     // User has clicked the button, restore the original FB
00213     _disp->swapFramebuffer(oldFB);
00214     swim_window_close(_win);
00215 }
00216 
00217 bool AppUSBStatus::teardown()
00218 {
00219     if (_win != NULL) {
00220         free(_win);
00221         _win = NULL;
00222     }
00223     if (_fb != NULL) {
00224         free(_fb);
00225         _fb = NULL;
00226     }
00227     if (_btn != NULL) {
00228         delete _btn;
00229         _btn = NULL;
00230     }
00231     for (int i = 0; i < NumImages; i++) {
00232         if (_images[i].pointerToFree != NULL) {
00233             free(_images[i].pointerToFree);
00234             _images[i].pointerToFree = NULL;
00235         }    
00236     }
00237     return true;
00238 }
00239 
00240 
00241 void AppUSBStatus::addResource(Resources id, Resource* res)
00242 {
00243     _resOk = res;
00244 }
00245