Demo for Embedded World 2015.
Dependencies: DMBasicGUI DMSupport
AppStatus.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 "AppStatus.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_WIDTH 40 00039 #define BTN_HEIGHT 40 00040 #define BTN_OFF 20 00041 00042 #define DEMO_VERSION "v0.9" 00043 #define DEMO_BUILD_INFO __DATE__ " " __TIME__ 00044 00045 #define DESCR(__res, __disp) \ 00046 (((__res) == ((__disp)->currentResolution())) ? ("Active") : (((__disp)->isSupported(__res)) ? ("Supported") : ("N/A"))) 00047 00048 00049 /****************************************************************************** 00050 * Global variables 00051 *****************************************************************************/ 00052 00053 extern EthernetInterface eth; 00054 extern bool ethInitialized; 00055 extern bool ethUsingDHCP; 00056 00057 /****************************************************************************** 00058 * Private functions 00059 *****************************************************************************/ 00060 00061 static void buttonClicked(uint32_t x) 00062 { 00063 bool* done = (bool*)x; 00064 *done = true; 00065 } 00066 00067 void AppStatus::draw() 00068 { 00069 // Prepare fullscreen 00070 swim_window_open(_win, 00071 _disp->width(), _disp->height(), // full size 00072 (COLOR_T*)_fb, 00073 0,0,_disp->width()-1, _disp->height()-1, // window position and size 00074 1, // border 00075 BLACK, WHITE, BLACK); // colors: pen, backgr, forgr 00076 //swim_set_title(_win, "Application Status", BLACK); 00077 00078 swim_put_image_xy(_win, _bgImg.pixels, _bgImg.width, _bgImg.height, (_disp->width()-_bgImg.width)/2, 5+(_disp->height()-_bgImg.height)/2); 00079 00080 00081 char buff[120]; 00082 00083 // Column 1 00084 swim_put_text_xy(_win, "Demo:", HEADER_X_OFF, HEADER_Y_SPACING); 00085 swim_put_text_xy(_win, "Version:", ITEM_CAPTION_X_OFF, HEADER_Y_SPACING + ITEM_CAPTION_Y_SPACING * 1); 00086 swim_put_text_xy(_win, "Build:", ITEM_CAPTION_X_OFF, HEADER_Y_SPACING + ITEM_CAPTION_Y_SPACING * 2); 00087 00088 swim_put_text_xy(_win, "Network:", HEADER_X_OFF, HEADER_Y_SPACING + ITEM_CAPTION_Y_SPACING * 4); 00089 swim_put_text_xy(_win, "DHCP/Static:", ITEM_CAPTION_X_OFF, HEADER_Y_SPACING + ITEM_CAPTION_Y_SPACING * 5); 00090 swim_put_text_xy(_win, "IP Address:", ITEM_CAPTION_X_OFF, HEADER_Y_SPACING + ITEM_CAPTION_Y_SPACING * 6); 00091 swim_put_text_xy(_win, "NetMask:", ITEM_CAPTION_X_OFF, HEADER_Y_SPACING + ITEM_CAPTION_Y_SPACING * 7); 00092 swim_put_text_xy(_win, "Gateway:", ITEM_CAPTION_X_OFF, HEADER_Y_SPACING + ITEM_CAPTION_Y_SPACING * 8); 00093 swim_put_text_xy(_win, "MAC Address:", ITEM_CAPTION_X_OFF, HEADER_Y_SPACING + ITEM_CAPTION_Y_SPACING * 9); 00094 00095 char mac[6]; 00096 mbed_mac_address(mac); 00097 snprintf(buff, 19, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); 00098 swim_put_text_xy(_win, buff, ITEM_CAPTION_X_OFF+10, HEADER_Y_SPACING + ITEM_CAPTION_Y_SPACING * 10); 00099 00100 // Column 2 00101 swim_put_text_xy(_win, DEMO_VERSION, ITEM_VALUE_X_OFF-20, HEADER_Y_SPACING + ITEM_CAPTION_Y_SPACING * 1); 00102 swim_put_text_xy(_win, DEMO_BUILD_INFO, ITEM_VALUE_X_OFF-20, HEADER_Y_SPACING + ITEM_CAPTION_Y_SPACING * 2); 00103 00104 swim_put_text_xy(_win, ethUsingDHCP?"DHCP":"Static IP", ITEM_VALUE_X_OFF-20, HEADER_Y_SPACING + ITEM_CAPTION_Y_SPACING * 5); 00105 if (ethInitialized) { 00106 swim_put_text_xy(_win, eth.get_ip_address(), ITEM_VALUE_X_OFF-20, HEADER_Y_SPACING + ITEM_CAPTION_Y_SPACING * 6); 00107 swim_put_text_xy(_win, eth.get_netmask(), ITEM_VALUE_X_OFF-20, HEADER_Y_SPACING + ITEM_CAPTION_Y_SPACING * 7); 00108 swim_put_text_xy(_win, eth.get_gateway(), ITEM_VALUE_X_OFF-20, HEADER_Y_SPACING + ITEM_CAPTION_Y_SPACING * 8); 00109 //swim_put_text_xy(_win, eth.getMACAddress(), ITEM_VALUE_X_OFF, HEADER_Y_SPACING + ITEM_CAPTION_Y_SPACING * 4); 00110 } else { 00111 swim_put_text_xy(_win, "Not Initialized", ITEM_VALUE_X_OFF-20, HEADER_Y_SPACING + ITEM_CAPTION_Y_SPACING * 6); 00112 swim_put_text_xy(_win, "Not Initialized", ITEM_VALUE_X_OFF-20, HEADER_Y_SPACING + ITEM_CAPTION_Y_SPACING * 7); 00113 swim_put_text_xy(_win, "Not Initialized", ITEM_VALUE_X_OFF-20, HEADER_Y_SPACING + ITEM_CAPTION_Y_SPACING * 8); 00114 } 00115 00116 // Column 3 00117 swim_put_text_xy(_win, "Display:", COL3_OFF+HEADER_X_OFF, HEADER_Y_SPACING); 00118 swim_put_text_xy(_win, "Size:", COL3_OFF+ITEM_CAPTION_X_OFF, HEADER_Y_SPACING + ITEM_CAPTION_Y_SPACING * 1); 00119 swim_put_text_xy(_win, "Landscape:", COL3_OFF+ITEM_CAPTION_X_OFF, HEADER_Y_SPACING + ITEM_CAPTION_Y_SPACING * 2); 00120 swim_put_text_xy(_win, "Resolutions:", COL3_OFF+ITEM_CAPTION_X_OFF, HEADER_Y_SPACING + ITEM_CAPTION_Y_SPACING * 3); 00121 swim_put_text_xy(_win, "16bit rgb565:", COL3_OFF+ITEM_CAPTION_X_OFF+10, HEADER_Y_SPACING + ITEM_CAPTION_Y_SPACING * 4); 00122 swim_put_text_xy(_win, "18bit rgb666:", COL3_OFF+ITEM_CAPTION_X_OFF+10, HEADER_Y_SPACING + ITEM_CAPTION_Y_SPACING * 5); 00123 swim_put_text_xy(_win, "24bit rgb888:", COL3_OFF+ITEM_CAPTION_X_OFF+10, HEADER_Y_SPACING + ITEM_CAPTION_Y_SPACING * 6); 00124 00125 swim_put_text_xy(_win, "BIOS:", COL3_OFF+HEADER_X_OFF, HEADER_Y_SPACING + ITEM_CAPTION_Y_SPACING * 8); 00126 //swim_put_text_xy(_win, "Info:", COL3_OFF+ITEM_CAPTION_X_OFF, HEADER_Y_SPACING + ITEM_CAPTION_Y_SPACING * 8); 00127 //swim_put_text_xy(_win, "Board Type:", COL3_OFF+ITEM_CAPTION_X_OFF, HEADER_Y_SPACING + ITEM_CAPTION_Y_SPACING * 9); 00128 { 00129 uint8_t type, maj, min, rev; 00130 BiosLoader::instance().getBiosStats(type, maj, min, rev); 00131 //snprintf(buff, 19, "v%u.%u.%u", maj, min, rev); 00132 //swim_put_text_xy(_win, buff, COL4 -20, HEADER_Y_SPACING + ITEM_CAPTION_Y_SPACING * 8); 00133 //snprintf(buff, 19, "%u", type); 00134 //swim_put_text_xy(_win, buff, COL4 -20, HEADER_Y_SPACING + ITEM_CAPTION_Y_SPACING * 9); 00135 snprintf(buff, 25, "v%u.%u.%u (board type %u)", maj, min, rev, type); 00136 swim_put_text_xy(_win, buff, COL3_OFF+ITEM_CAPTION_X_OFF, HEADER_Y_SPACING + ITEM_CAPTION_Y_SPACING * 9); 00137 } 00138 00139 // Column 4 00140 sprintf(buff, "%d x %d pixels", _disp->width(), _disp->height()); 00141 swim_put_text_xy(_win, buff, COL4 -20, HEADER_Y_SPACING + ITEM_CAPTION_Y_SPACING * 1); 00142 00143 sprintf(buff, "%s", _disp->landscape()?"YES":"NO"); 00144 swim_put_text_xy(_win, buff, COL4 -20, HEADER_Y_SPACING + ITEM_CAPTION_Y_SPACING * 2); 00145 00146 //sprintf(buff, "%s %s", _disp->isSupported(Display::Resolution_16bit_rgb565)?"Supported":"N/A", _disp->currentResolution()==Display::Resolution_16bit_rgb565?" (Active)":""); 00147 sprintf(buff, "%s", DESCR(Display::Resolution_16bit_rgb565, _disp)); 00148 swim_put_text_xy(_win, buff, COL4, HEADER_Y_SPACING + ITEM_CAPTION_Y_SPACING * 4); 00149 00150 //sprintf(buff, "%s %s", _disp->isSupported(Display::Resolution_18bit_rgb666)?"Supported":"N/A", _disp->currentResolution()==Display::Resolution_18bit_rgb666?" (Active)":""); 00151 sprintf(buff, "%s", DESCR(Display::Resolution_18bit_rgb666, _disp)); 00152 swim_put_text_xy(_win, buff, COL4, HEADER_Y_SPACING + ITEM_CAPTION_Y_SPACING * 5); 00153 00154 //sprintf(buff, "%s %s", _disp->isSupported(Display::Resolution_24bit_rgb888)?"Supported":"N/A", _disp->currentResolution()==Display::Resolution_24bit_rgb888?" (Active)":""); 00155 sprintf(buff, "%s", DESCR(Display::Resolution_24bit_rgb888, _disp)); 00156 swim_put_text_xy(_win, buff, COL4, HEADER_Y_SPACING + ITEM_CAPTION_Y_SPACING * 6); 00157 00158 _btn = new ImageButton(_win->fb, _win->xpmax - BTN_OFF - BTN_WIDTH, _win->ypmax - BTN_OFF - BTN_HEIGHT, BTN_WIDTH, BTN_HEIGHT); 00159 _btn->loadImages(img_ok, img_size_ok); 00160 _btn->draw(); 00161 } 00162 00163 /****************************************************************************** 00164 * Public functions 00165 *****************************************************************************/ 00166 00167 AppStatus::AppStatus() : _disp(NULL), _win(NULL), _fb(NULL), _btn(NULL) 00168 { 00169 _bgImg.pointerToFree = NULL; 00170 _bgImg.pixels = NULL; 00171 } 00172 00173 AppStatus::~AppStatus() 00174 { 00175 teardown(); 00176 } 00177 00178 bool AppStatus::setup() 00179 { 00180 RtosLog* log = DMBoard::instance().logger(); 00181 00182 _disp = DMBoard::instance().display(); 00183 _win = (SWIM_WINDOW_T*)malloc(sizeof(SWIM_WINDOW_T)); 00184 _fb = _disp->allocateFramebuffer(); 00185 00186 if (_win == NULL || _fb == NULL) { 00187 log->printf("Failed to allocate memory for framebuffer\r\n"); 00188 return false; 00189 } 00190 00191 if (Image::decode(img_about, img_size_about, Image::RES_16BIT, &_bgImg) != 0) { 00192 log->printf("Failed to load background image\n"); 00193 return false; 00194 } 00195 00196 return true; 00197 } 00198 00199 void AppStatus::runToCompletion() 00200 { 00201 // Alternative 1: use the calling thread's context to run in 00202 bool done = false; 00203 draw(); 00204 _btn->setAction(buttonClicked, (uint32_t)&done); 00205 void* oldFB = _disp->swapFramebuffer(_fb); 00206 00207 // Wait for touches, but the AppLauncher is already listening 00208 // for new touch event and sends a signal to its thread which 00209 // is the same as runs this function so it is enough to wait 00210 // for that signal. 00211 TouchPanel* touch = DMBoard::instance().touchPanel(); 00212 touch_coordinate_t coord; 00213 while(!done) { 00214 Thread::signal_wait(0x1); 00215 if (touch->read(coord) == TouchPanel::TouchError_Ok) { 00216 if (_btn->handle(coord.x, coord.y, coord.z > 0)) { 00217 _btn->draw(); 00218 } 00219 } 00220 } 00221 00222 // User has clicked the button, restore the original FB 00223 _disp->swapFramebuffer(oldFB); 00224 swim_window_close(_win); 00225 } 00226 00227 bool AppStatus::teardown() 00228 { 00229 if (_win != NULL) { 00230 free(_win); 00231 _win = NULL; 00232 } 00233 if (_fb != NULL) { 00234 free(_fb); 00235 _fb = NULL; 00236 } 00237 if (_btn != NULL) { 00238 delete _btn; 00239 _btn = NULL; 00240 } 00241 if (_bgImg.pointerToFree != NULL) { 00242 free(_bgImg.pointerToFree); 00243 _bgImg.pointerToFree = NULL; 00244 } 00245 return true; 00246 } 00247 00248 00249
Generated on Wed Jul 13 2022 18:24:58 by 1.7.2