LMS 2012
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
c_ui.c
Go to the documentation of this file.
1 /*
2  * LEGO® MINDSTORMS EV3
3  *
4  * Copyright (C) 2010-2013 The LEGO Group
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  */
20 
21 
153 #include "lms2012.h"
154 #include "c_ui.h"
155 #include "d_terminal.h"
156 #include "../../c_memory/source/c_memory.h"
157 #include "../../c_com/source/c_com.h"
158 #include "../../c_input/source/c_input.h"
159 #include <string.h>
160 #include <time.h>
161 extern char *strptime(const char *s, const char *format, struct tm *tm);
162 
163 
164 #ifdef DEBUG_C_UI
165 #define DEBUG
166 #endif
167 
168 
169 #if (HARDWARE != SIMULATION)
170 
171 #include <sys/stat.h>
172 #include <sys/statvfs.h>
173 #include <sys/types.h>
174 #include <sys/sysinfo.h>
175 
176 #include <stdio.h>
177 #include <stdlib.h>
178 #include <fcntl.h>
179 #include <unistd.h>
180 #include <dirent.h>
181 #include "d_lcd.h"
182 
183 #include <sys/mman.h>
184 #include <sys/ioctl.h>
185 #include <math.h>
186 #include <sys/utsname.h>
187 
188 #include <sys/socket.h>
189 #include <netinet/in.h>
190 #include <net/if.h>
191 #include <arpa/inet.h>
192 
193 
195 
196 
197 #else
198 
199 #define snprintf _snprintf
200 #include <stdio.h>
201 #include <stdlib.h>
203 
204  void setUiInstance(UI_GLOBALS * _Instance)
205  {
206  gUiInstance= _Instance;
207  }
208 
210  {
211  return gUiInstance;
212  }
213 
214 #endif
215 
216 
217 #ifndef DISABLE_VIRTUAL_BATT_TEMP
218 
219  //Defines der kan tænde for debug beskeder
220  //#define __dbg1
221  //#define __dbg2
222 
223  /*************************** Model parameters *******************************/
224  //Approx. initial internal resistance of 6 Energizer industrial batteries :
225  float R_bat_init = 0.63468;
226  //Bjarke's proposal for spring resistance :
227  //float spring_resistance = 0.42;
228  //Batteries' heat capacity :
229  float heat_cap_bat = 136.6598;
230  //Newtonian cooling constant for electronics :
231  float K_bat_loss_to_elec = -0.0003; //-0.000789767;
232  //Newtonian heating constant for electronics :
233  float K_bat_gain_from_elec = 0.001242896; //0.001035746;
234  //Newtonian cooling constant for environment :
235  float K_bat_to_room = -0.00012;
236  //Battery power Boost
237  float battery_power_boost = 1.7;
238  //Battery R_bat negative gain
239  float R_bat_neg_gain = 1.00;
240 
241  //Slope of electronics lossless heating curve (linear!!!) [Deg.C / s] :
242  float K_elec_heat_slope = 0.0123175;
243  //Newtonian cooling constant for battery packs :
244  float K_elec_loss_to_bat = -0.004137487;
245  //Newtonian heating constant for battery packs :
246  float K_elec_gain_from_bat = 0.002027574; //0.00152068;
247  //Newtonian cooling constant for environment :
248  float K_elec_to_room = -0.001931431; //-0.001843639;
249 
250  // Function for estimating new battery temperature based on measurements
251  // of battery voltage and battery power.
252  float new_bat_temp (float V_bat, float I_bat)
253  {
254 
255  static int index = 0; //Keeps track of sample index since power-on
256  static float I_bat_mean = 0; //Running mean current
257  const float sample_period = 0.4; //Algorithm update period in seconds
258  static float T_bat = 0; //Battery temperature
259  static float T_elec = 0; //EV3 electronics temperature
260 
261  static float R_bat_model_old = 0;//Old internal resistance of the battery model
262  float R_bat_model; //Internal resistance of the battery model
263  static float R_bat = 0; //Internal resistance of the batteries
264  float slope_A; //Slope obtained by linear interpolation
265  float intercept_b; //Offset obtained by linear interpolation
266  const float I_1A = 0.05; //Current carrying capacity at bottom of the curve
267  const float I_2A = 2.0; //Current carrying capacity at the top of the curve
268 
269  float R_1A = 0.0; //Internal resistance of the batteries at 1A and V_bat
270  float R_2A = 0.0; //Internal resistance of the batteries at 2A and V_bat
271 
272  //Flag that prevents initialization of R_bat when the battery is charging
273  static unsigned char has_passed_7v5_flag = 'N';
274 
275  float dT_bat_own = 0.0; //Batteries' own heat
276  float dT_bat_loss_to_elec = 0.0; // Batteries' heat loss to electronics
277  float dT_bat_gain_from_elec = 0.0; //Batteries' heat gain from electronics
278  float dT_bat_loss_to_room = 0.0; //Batteries' cooling from environment
279 
280  float dT_elec_own = 0.0; //Electronics' own heat
281  float dT_elec_loss_to_bat = 0.0;//Electronics' heat loss to the battery pack
282  float dT_elec_gain_from_bat = 0.0;//Electronics' heat gain from battery packs
283  float dT_elec_loss_to_room = 0.0; //Electronics' heat loss to the environment
284 
285  /***************************************************************************/
286 
287  //Update the average current: I_bat_mean
288  if (index > 0)
289  {
290  I_bat_mean = ((index) * I_bat_mean + I_bat) / (index + 1) ;
291  }
292  else
293  {
294  I_bat_mean = I_bat;
295  }
296 
297  index = index + 1;
298 
299 
300  //Calculate R_1A as a function of V_bat (internal resistance at 1A continuous)
301  R_1A = 0.014071 * (V_bat * V_bat * V_bat * V_bat)
302  - 0.335324 * (V_bat * V_bat * V_bat)
303  + 2.933404 * (V_bat * V_bat)
304  - 11.243047 * V_bat
305  + 16.897461;
306 
307  //Calculate R_2A as a function of V_bat (internal resistance at 2A continuous)
308  R_2A = 0.014420 * (V_bat * V_bat * V_bat * V_bat)
309  - 0.316728 * (V_bat * V_bat * V_bat)
310  + 2.559347 * (V_bat * V_bat)
311  - 9.084076 * V_bat
312  + 12.794176;
313 
314  //Calculate the slope by linear interpolation between R_1A and R_2A
315  slope_A = (R_1A - R_2A) / (I_1A - I_2A);
316 
317  //Calculate intercept by linear interpolation between R1_A and R2_A
318  intercept_b = R_1A - slope_A * R_1A;
319 
320  //Reload R_bat_model:
321  R_bat_model = slope_A * I_bat_mean + intercept_b;
322 
323  //Calculate batteries' internal resistance: R_bat
324  if ((V_bat > 7.5) && (has_passed_7v5_flag == 'N'))
325  {
326  R_bat = R_bat_init; //7.5 V not passed a first time
327  }
328  else
329  {
330  //Only update R_bat with positive outcomes: R_bat_model - R_bat_model_old
331  //R_bat updated with the change in model R_bat is not equal value in the model!
332  if ((R_bat_model - R_bat_model_old) > 0)
333  {
334  R_bat = R_bat + R_bat_model - R_bat_model_old;
335  }
336  else // The negative outcome of R_bat_model added to only part of R_bat
337  {
338  R_bat = R_bat + ( R_bat_neg_gain * (R_bat_model - R_bat_model_old));
339  }
340  //Make sure we initialize R_bat later
341  has_passed_7v5_flag = 'Y';
342  }
343 
344  //Save R_bat_model for use in the next function call
345  R_bat_model_old = R_bat_model;
346 
347  //Debug code:
348  #ifdef __dbg1
349  if (index < 500)
350  {
351  printf("%c %f %f %f %f %f %f\n", has_passed_7v5_flag, R_1A, R_2A,
352  slope_A, intercept_b, R_bat_model - R_bat_model_old, R_bat);
353  }
354  #endif
355 
356  /*****Calculate the 4 types of temperature change for the batteries******/
357 
358  //Calculate the batteries' own temperature change
359  dT_bat_own = R_bat * I_bat * I_bat * sample_period * battery_power_boost
360  / heat_cap_bat;
361 
362  //Calculate the batteries' heat loss to the electronics
363  if (T_bat > T_elec)
364  {
365  dT_bat_loss_to_elec = K_bat_loss_to_elec * (T_bat - T_elec)
366  * sample_period;
367  }
368  else
369  {
370  dT_bat_loss_to_elec = 0.0;
371  }
372 
373  //Calculate the batteries' heat gain from the electronics
374  if (T_bat < T_elec)
375  {
376  dT_bat_gain_from_elec = K_bat_gain_from_elec * (T_elec - T_bat)
377  * sample_period;
378  }
379  else
380  {
381  dT_bat_gain_from_elec = 0.0;
382  }
383 
384  //Calculate the batteries' heat loss to environment
385  dT_bat_loss_to_room = K_bat_to_room * T_bat * sample_period;
386  /************************************************************************/
387 
388 
389 
390  /*****Calculate the 4 types of temperature change for the electronics****/
391 
392  //Calculate the electronics' own temperature change
393  dT_elec_own = K_elec_heat_slope * sample_period;
394 
395  //Calculate the electronics' heat loss to the batteries
396  if (T_elec > T_bat)
397  {
398  dT_elec_loss_to_bat = K_elec_loss_to_bat * (T_elec - T_bat)
399  * sample_period;
400  }
401  else
402  {
403  dT_elec_loss_to_bat = 0.0;
404  }
405 
406  //Calculate the electronics' heat gain from the batteries
407  if (T_elec < T_bat)
408  {
409  dT_elec_gain_from_bat = K_elec_gain_from_bat * (T_bat - T_elec)
410  * sample_period;
411  }
412  else
413  {
414  dT_elec_gain_from_bat = 0.0;
415  }
416 
417  //Calculate the electronics' heat loss to the environment
418  dT_elec_loss_to_room = K_elec_to_room * T_elec * sample_period;
419 
420  /*****************************************************************************/
421  //Debug code:
422  #ifdef __dbg2
423  if (index < 500)
424  {
425  printf("%f %f %f %f %f <> %f %f %f %f %f\n",dT_bat_own, dT_bat_loss_to_elec,
426  dT_bat_gain_from_elec, dT_bat_loss_to_room, T_bat,
427  dT_elec_own, dT_elec_loss_to_bat, dT_elec_gain_from_bat,
428  dT_elec_loss_to_room, T_elec);
429  }
430  #endif
431 
432 
433 
434  //Refresh battery temperature
435  T_bat = T_bat + dT_bat_own + dT_bat_loss_to_elec
436  + dT_bat_gain_from_elec + dT_bat_loss_to_room;
437 
438  //Refresh electronics temperature
439  T_elec = T_elec + dT_elec_own + dT_elec_loss_to_bat
440  + dT_elec_gain_from_bat + dT_elec_loss_to_room;
441 
442  return T_bat;
443 
444  }
445 #endif
446 
447 
448 #ifdef DEBUG_VIRTUAL_BATT_TEMP
449 static int TempFile = -1;
450 #endif
451 
452 
453 #ifndef DISABLE_VIRTUAL_BATT_TEMP
454 
455 void cUiCheckTemp(void);
456 
457 #define CALL_INTERVAL 400 // [mS]
458 
459 #ifdef DEBUG_VIRTUAL_BATT_TEMP
460 
461 void cUiInitTemp(void)
462 {
463  char Buffer[250];
464  int BufferSize;
465  float Const[11];
466  int Tmp;
467  char *Str;
468  LFILE *pFile;
469 
470  mkdir("../prjs/TempTest",DIRPERMISSIONS);
471  chmod("../prjs/TempTest",DIRPERMISSIONS);
472  sync();
473 
474  Tmp = 0;
475  pFile = fopen ("../prjs/Const/TempConst.rtf","r");
476  if (pFile != NULL)
477  {
478  do
479  {
480  Str = fgets(Buffer,250,pFile);
481  Buffer[249] = 0;
482  if (Str != NULL)
483  {
484  if ((Buffer[0] != '/') && (Buffer[0] != '*') && (Buffer[0] != ' '))
485  {
486  Const[Tmp] = DATAF_NAN;
487  if (sscanf(Buffer,"%f",&Const[Tmp]) != 1)
488  {
489  Const[Tmp] = DATAF_NAN;
490  }
491  Tmp++;
492  }
493  }
494  }
495  while (Str != NULL);
496  fclose (pFile);
497 
498  R_bat_init = Const[0];
499  heat_cap_bat = Const[1];
500  K_bat_loss_to_elec = Const[2];
501  K_bat_gain_from_elec = Const[3];
502  K_bat_to_room = Const[4];
503  battery_power_boost = Const[5];
504  R_bat_neg_gain = Const[6];
505  K_elec_heat_slope = Const[7];
506  K_elec_loss_to_bat = Const[8];
507  K_elec_gain_from_bat = Const[9];
508  K_elec_to_room = Const[10];
509 
510  }
511 
512  TempFile = open("../prjs/TempTest/TempFile.rtf",O_CREAT | O_WRONLY | O_APPEND | O_SYNC,FILEPERMISSIONS);
513  chmod("../prjs/TempTest/TempFile.rtf",FILEPERMISSIONS);
514  if (TempFile >= MIN_HANDLE)
515  {
516  if (Tmp)
517  {
518  BufferSize = snprintf(Buffer,250,"* TempConst.rtf ************************\r\n");
519  }
520  else
521  {
522  BufferSize = snprintf(Buffer,250,"* Build in *****************************\r\n");
523  }
524  write(TempFile,Buffer,BufferSize);
525  BufferSize = snprintf(Buffer,250," R_bat_init = %13.9f\r\n",R_bat_init);
526  write(TempFile,Buffer,BufferSize);
527  BufferSize = snprintf(Buffer,250," heat_cap_bat = %13.9f\r\n",heat_cap_bat);
528  write(TempFile,Buffer,BufferSize);
529  BufferSize = snprintf(Buffer,250," K_bat_loss_to_elec = %13.9f\r\n",K_bat_loss_to_elec);
530  write(TempFile,Buffer,BufferSize);
531  BufferSize = snprintf(Buffer,250," K_bat_gain_from_elec = %13.9f\r\n",K_bat_gain_from_elec);
532  write(TempFile,Buffer,BufferSize);
533  BufferSize = snprintf(Buffer,250," K_bat_to_room = %13.9f\r\n",K_bat_to_room);
534  write(TempFile,Buffer,BufferSize);
535  BufferSize = snprintf(Buffer,250," battery_power_boost = %13.9f\r\n",battery_power_boost);
536  write(TempFile,Buffer,BufferSize);
537  BufferSize = snprintf(Buffer,250," R_bat_neg_gain = %13.9f\r\n",R_bat_neg_gain);
538  write(TempFile,Buffer,BufferSize);
539  BufferSize = snprintf(Buffer,250," K_elec_heat_slope = %13.9f\r\n",K_elec_heat_slope);
540  write(TempFile,Buffer,BufferSize);
541  BufferSize = snprintf(Buffer,250," K_elec_loss_to_bat = %13.9f\r\n",K_elec_loss_to_bat);
542  write(TempFile,Buffer,BufferSize);
543  BufferSize = snprintf(Buffer,250," K_elec_gain_from_bat = %13.9f\r\n",K_elec_gain_from_bat);
544  write(TempFile,Buffer,BufferSize);
545  BufferSize = snprintf(Buffer,250," K_elec_to_room = %13.9f\r\n",K_elec_to_room);
546  write(TempFile,Buffer,BufferSize);
547  BufferSize = snprintf(Buffer,250,"****************************************\r\n");
548  write(TempFile,Buffer,BufferSize);
549  }
550  UiInstance.TempTimer = (UiInstance.MilliSeconds - CALL_INTERVAL);
551  cUiCheckTemp();
552 }
553 
554 
555 void cUiExitTemp(void)
556 {
557  if (TempFile >= MIN_HANDLE)
558  {
559  close(TempFile);
560  TempFile = -1;
561  }
562 }
563 #endif
564 
565 #endif
566 
567 
568 IMGDATA DownloadSuccesSound[] = { opINFO,LC0(GET_VOLUME),LV0(0),opSOUND,LC0(PLAY),LV0(0),LCS,'u','i','/','D','o','w','n','l','o','a','d','S','u','c','c','e','s',0,opSOUND_READY,opOBJECT_END };
569 
571 {
572  VARDATA Locals[1];
573 
574  ExecuteByteCode(DownloadSuccesSound,NULL,Locals);
575 }
576 
577 
578 void cUiButtonClr(void)
579 {
580  DATA8 Button;
581 
582  for (Button = 0;Button < BUTTONS;Button++)
583  {
584  UiInstance.ButtonState[Button] &= ~BUTTON_CLR;
585  }
586 }
587 
588 
589 void cUiButtonFlush(void)
590 {
591  DATA8 Button;
592 
593  for (Button = 0;Button < BUTTONS;Button++)
594  {
595  UiInstance.ButtonState[Button] &= ~BUTTON_FLUSH;
596  }
597 }
598 
599 
600 void cUiSetLed(DATA8 State)
601 {
602  DATA8 Buffer[2];
603 
604  UiInstance.LedState = State;
605 
606  if (UiInstance.UiFile >= MIN_HANDLE)
607  {
608  if (UiInstance.Warnlight)
609  {
610  if ((State == LED_GREEN_FLASH) || (State == LED_RED_FLASH) || (State == LED_ORANGE_FLASH))
611  {
612  Buffer[0] = LED_ORANGE_FLASH + '0';
613  }
614  else
615  {
616  if ((State == LED_GREEN_PULSE) || (State == LED_RED_PULSE) || (State == LED_ORANGE_PULSE))
617  {
618  Buffer[0] = LED_ORANGE_PULSE + '0';
619  }
620  else
621  {
622  Buffer[0] = LED_ORANGE + '0';
623  }
624  }
625  }
626  else
627  {
628  Buffer[0] = UiInstance.LedState + '0';
629  }
630  Buffer[1] = 0;
631  write(UiInstance.UiFile,Buffer,2);
632  }
633 }
634 
635 
636 void cUiAlive(void)
637 {
638  UiInstance.SleepTimer = 0;
639 }
640 
641 
642 RESULT cUiInit(void)
643 {
644  RESULT Result = OK;
645  UI *pUiTmp;
646  ANALOG *pAdcTmp;
647  UBYTE Tmp;
648  DATAF Hw;
649  char Buffer[32];
650  char OsBuf[2000];
651  int Lng;
652  int Start;
653  int Sid;
654  struct ifreq Sifr;
655  struct utsname *pOs;
656  struct tm tm;
657 
658  cUiAlive();
659 
660  UiInstance.ReadyForWarnings = 0;
661  UiInstance.UpdateState = 0;
662  UiInstance.RunLedEnabled = 0;
663  UiInstance.RunScreenEnabled = 0;
664  UiInstance.TopLineEnabled = 0;
665  UiInstance.BackButtonBlocked = 0;
666  UiInstance.Escape = 0;
667  UiInstance.KeyBufIn = 0;
668  UiInstance.Keys = 0;
669  UiInstance.UiWrBufferSize = 0;
670 
671  UiInstance.ScreenBusy = 0;
672  UiInstance.ScreenBlocked = 0;
673  UiInstance.ScreenPrgId = -1;
674  UiInstance.ScreenObjId = -1;
675 
676  UiInstance.PowerInitialized = 0;
677  UiInstance.ShutDown = 0;
678 
679  UiInstance.PowerShutdown = 0;
680  UiInstance.PowerState = 0;
681  UiInstance.VoltShutdown = 0;
682  UiInstance.Warnlight = 0;
683  UiInstance.Warning = 0;
684  UiInstance.WarningShowed = 0;
685  UiInstance.WarningConfirmed = 0;
686  UiInstance.VoltageState = 0;
687 
688  UiInstance.pLcd = &UiInstance.LcdSafe;
689  UiInstance.pUi = &UiInstance.UiSafe;
690  UiInstance.pAnalog = &UiInstance.Analog;
691 
692  UiInstance.Browser.PrgId = 0;
693  UiInstance.Browser.ObjId = 0;
694 
695  UiInstance.Tbatt = 0.0;
696  UiInstance.Vbatt = 9.0;
697  UiInstance.Ibatt = 0.0;
698  UiInstance.Imotor = 0.0;
699  UiInstance.Iintegrated = 0.0;
700 #ifdef Linux_X86
701  UiInstance.Ibatt = 0.1;
702  UiInstance.Imotor = 0.0;
703 #endif
704 
705  Result = dTerminalInit();
706 
707  UiInstance.PowerFile = open(POWER_DEVICE_NAME,O_RDWR);
708  UiInstance.UiFile = open(UI_DEVICE_NAME,O_RDWR | O_SYNC);
709  UiInstance.AdcFile = open(ANALOG_DEVICE_NAME,O_RDWR | O_SYNC);
710 
711  dLcdInit((*UiInstance.pLcd).Lcd);
712 
713  Hw = 0;
714  if (UiInstance.UiFile >= MIN_HANDLE)
715  {
716  pUiTmp = (UI*)mmap(0, sizeof(UI), PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, UiInstance.UiFile, 0);
717 
718  if (pUiTmp == MAP_FAILED)
719  {
720 #ifndef Linux_X86
722  Result = FAIL;
723 #endif
724  }
725  else
726  {
727  UiInstance.pUi = pUiTmp;
728  }
729 
730  read(UiInstance.UiFile,UiInstance.HwVers,HWVERS_SIZE);
731  sscanf(&UiInstance.HwVers[1],"%f",&Hw);
732  }
733  else
734  {
735 #ifndef Linux_X86
737  Result = FAIL;
738 #else
739  snprintf(UiInstance.HwVers,HWVERS_SIZE,"X86");
740 #endif
741  }
742  Hw *= (DATAF)10;
743  UiInstance.Hw = (DATA8)Hw;
744 
745  if (UiInstance.AdcFile >= MIN_HANDLE)
746  {
747  pAdcTmp = (ANALOG*)mmap(0, sizeof(ANALOG), PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, UiInstance.AdcFile, 0);
748 
749  if (pAdcTmp == MAP_FAILED)
750  {
751 #ifndef Linux_X86
753  Result = FAIL;
754 #endif
755  }
756  else
757  {
758  UiInstance.pAnalog = pAdcTmp;
759  }
760  }
761  else
762  {
763 #ifndef Linux_X86
765  Result = FAIL;
766 #endif
767  }
768 
769  if (SPECIALVERS < '0')
770  {
771  snprintf(UiInstance.FwVers,FWVERS_SIZE,"V%4.2f",VERS);
772  }
773  else
774  {
775  snprintf(UiInstance.FwVers,FWVERS_SIZE,"V%4.2f%c",VERS,SPECIALVERS);
776  }
777 
778 
779  snprintf(Buffer,32,"%s %s",__DATE__,__TIME__);
780  strptime((const char*)Buffer,(const char*)"%B %d %Y %H:%M:%S",(struct tm*)&tm);
781  strftime(UiInstance.FwBuild,FWBUILD_SIZE,"%y%m%d%H%M",&tm);
782 
783  pOs = (struct utsname*)OsBuf;
784  uname(pOs);
785 
786  snprintf(UiInstance.OsVers,OSVERS_SIZE,"%s %s",(*pOs).sysname,(*pOs).release);
787 
788  sprintf((char*)UiInstance.OsBuild,"?");
789 
790  Lng = strlen((*pOs).version) - 9;
791  if (Lng > 0)
792  {
793  (*pOs).version[Lng++] = ' ';
794  (*pOs).version[Lng++] = ' ';
795  (*pOs).version[Lng++] = ' ';
796  (*pOs).version[Lng++] = ' ';
797 
798  Lng = strlen((*pOs).version);
799  Tmp = 0;
800  Start = 0;
801 
802  while ((Start < Lng) && (Tmp == 0))
803  {
804  if (strptime((const char*)&(*pOs).version[Start],(const char*)"%B %d %H:%M:%S %Y",(struct tm*)&tm) != NULL)
805  {
806  Tmp = 1;
807  }
808  Start++;
809  }
810  if (Tmp)
811  {
812  strftime((char*)UiInstance.OsBuild,OSBUILD_SIZE,"%y%m%d%H%M",&tm);
813  }
814  }
815 
816  UiInstance.IpAddr[0] = 0;
817  Sid = socket(AF_INET,SOCK_DGRAM,0);
818  Sifr.ifr_addr.sa_family = AF_INET;
819  strncpy(Sifr.ifr_name,"eth0",IFNAMSIZ - 1);
820  if (ioctl(Sid,SIOCGIFADDR,&Sifr) >= 0)
821  {
822  snprintf(UiInstance.IpAddr,IPADDR_SIZE,"%s",inet_ntoa(((struct sockaddr_in *)&Sifr.ifr_addr)->sin_addr));
823  }
824  close(Sid);
825 
826  cUiButtonClr();
827 
828  UiInstance.BattIndicatorHigh = BATT_INDICATOR_HIGH;
829  UiInstance.BattIndicatorLow = BATT_INDICATOR_LOW;
830  UiInstance.BattWarningHigh = BATT_WARNING_HIGH;
831  UiInstance.BattWarningLow = BATT_WARNING_LOW;
832  UiInstance.BattShutdownHigh = BATT_SHUTDOWN_HIGH;
833  UiInstance.BattShutdownLow = BATT_SHUTDOWN_LOW;
834 
835  UiInstance.Accu = 0;
836  if (UiInstance.PowerFile >= MIN_HANDLE)
837  {
838  read(UiInstance.PowerFile,Buffer,2);
839  if (Buffer[0] == '1')
840  {
841  UiInstance.Accu = 1;
842  UiInstance.BattIndicatorHigh = ACCU_INDICATOR_HIGH;
843  UiInstance.BattIndicatorLow = ACCU_INDICATOR_LOW;
844  UiInstance.BattWarningHigh = ACCU_WARNING_HIGH;
845  UiInstance.BattWarningLow = ACCU_WARNING_LOW;
846  UiInstance.BattShutdownHigh = ACCU_SHUTDOWN_HIGH;
847  UiInstance.BattShutdownLow = ACCU_SHUTDOWN_LOW;
848  }
849  }
850 
851 #ifdef DEBUG_VIRTUAL_BATT_TEMP
852  cUiInitTemp();
853 #endif
854 
855  return (Result);
856 }
857 
858 
859 RESULT cUiOpen(void)
860 {
861  RESULT Result = FAIL;
862 
863  // Save screen before run
864  LCDCopy(&UiInstance.LcdSafe,&UiInstance.LcdPool[0],sizeof(LCD));
865 
866  cUiButtonClr();
867  cUiSetLed(LED_GREEN_PULSE);
868  UiInstance.RunScreenEnabled = 3;
869  UiInstance.RunLedEnabled = 1;
870  UiInstance.TopLineEnabled = 0;
871 
872  Result = OK;
873 
874  return (Result);
875 }
876 
877 
878 RESULT cUiClose(void)
879 {
880  RESULT Result = FAIL;
881 
882  UiInstance.Warning &= ~WARNING_BUSY;
883  UiInstance.RunLedEnabled = 0;
884  UiInstance.RunScreenEnabled = 0;
885  UiInstance.TopLineEnabled = 1;
886  UiInstance.BackButtonBlocked = 0;
887  UiInstance.Browser.NeedUpdate = 1;
888  cUiSetLed(LED_GREEN);
889 
890  cUiButtonClr();
891 
892  Result = OK;
893 
894  return (Result);
895 }
896 
897 
898 RESULT cUiExit(void)
899 {
900  RESULT Result = FAIL;
901 
902 #ifdef DEBUG_VIRTUAL_BATT_TEMP
903  cUiExitTemp();
904 #endif
905 
906  Result = dTerminalExit();
907 
908  if (UiInstance.AdcFile >= MIN_HANDLE)
909  {
910  munmap(UiInstance.pAnalog,sizeof(ANALOG));
911  close(UiInstance.AdcFile);
912  }
913 
914  if (UiInstance.UiFile >= MIN_HANDLE)
915  {
916  munmap(UiInstance.pUi,sizeof(UI));
917  close(UiInstance.UiFile);
918  }
919 
920  if (UiInstance.PowerFile >= MIN_HANDLE)
921  {
922  close(UiInstance.PowerFile);
923  }
924 
925  Result = OK;
926 
927  return (Result);
928 }
929 
930 
932 {
933  DATA8 Button;
934 
935  for (Button = 0;Button < BUTTONS;Button++)
936  {
937 
938  // Check real hardware buttons
939 
940  if ((*UiInstance.pUi).Pressed[Button])
941  { // Button pressed
942 
943  if (UiInstance.ButtonDebounceTimer[Button] == 0)
944  { // Button activated
945 
946  UiInstance.ButtonState[Button] |= BUTTON_ACTIVE;
947  }
948 
949  UiInstance.ButtonDebounceTimer[Button] = BUTTON_DEBOUNCE_TIME;
950  }
951  else
952  { // Button not pressed
953 
954  if (UiInstance.ButtonDebounceTimer[Button] > 0)
955  { // Debounce delay
956 
957  UiInstance.ButtonDebounceTimer[Button] -= Time;
958 
959  if (UiInstance.ButtonDebounceTimer[Button] <= 0)
960  { // Button released
961 
962  UiInstance.ButtonState[Button] &= ~BUTTON_ACTIVE;
963  UiInstance.ButtonDebounceTimer[Button] = 0;
964  }
965  }
966  }
967 
968  // Check virtual buttons (hardware, direct command, PC)
969 
970  if (UiInstance.ButtonState[Button] & BUTTON_ACTIVE)
971  {
972  if (!(UiInstance.ButtonState[Button] & BUTTON_PRESSED))
973  { // Button activated
974 
975  UiInstance.Activated = BUTTON_SET;
976  UiInstance.ButtonState[Button] |= BUTTON_PRESSED;
977  UiInstance.ButtonState[Button] |= BUTTON_ACTIVATED;
978  UiInstance.ButtonTimer[Button] = 0;
979  UiInstance.ButtonRepeatTimer[Button] = BUTTON_START_REPEAT_TIME;
980  }
981 
982  // Control auto repeat
983 
984  if (UiInstance.ButtonRepeatTimer[Button] > Time)
985  {
986  UiInstance.ButtonRepeatTimer[Button] -= Time;
987  }
988  else
989  {
990  if ((Button != 1) && (Button != 5))
991  { // No repeat on ENTER and BACK
992 
993  UiInstance.Activated |= BUTTON_SET;
994  UiInstance.ButtonState[Button] |= BUTTON_ACTIVATED;
995  UiInstance.ButtonRepeatTimer[Button] = BUTTON_REPEAT_TIME;
996  }
997  }
998 
999  // Control long press
1000 
1001  UiInstance.ButtonTimer[Button] += Time;
1002 
1003  if (UiInstance.ButtonTimer[Button] >= LONG_PRESS_TIME)
1004  {
1005  if (!(UiInstance.ButtonState[Button] & BUTTON_LONG_LATCH))
1006  { // Only once
1007 
1008  UiInstance.ButtonState[Button] |= BUTTON_LONG_LATCH;
1009 
1010 #ifdef BUFPRINTSIZE
1011  if (Button == 2)
1012  {
1013  UiInstance.Activated |= BUTTON_BUFPRINT;
1014  }
1015 #endif
1016  }
1017  UiInstance.ButtonState[Button] |= BUTTON_LONGPRESS;
1018  }
1019 
1020  }
1021  else
1022  {
1023  if ((UiInstance.ButtonState[Button] & BUTTON_PRESSED))
1024  { // Button released
1025 
1026  UiInstance.ButtonState[Button] &= ~BUTTON_PRESSED;
1027  UiInstance.ButtonState[Button] &= ~BUTTON_LONG_LATCH;
1028  UiInstance.ButtonState[Button] |= BUTTON_BUMBED;
1029  }
1030  }
1031  }
1032 }
1033 
1034 
1035 #ifndef LEGO_SIMULATION
1036 RESULT cUiUpdateInput(void)
1037 {
1038  UBYTE Key;
1039 
1040  if (GetTerminalEnable())
1041  {
1042 
1043  if (dTerminalRead(&Key) == OK)
1044  {
1045  switch (Key)
1046  {
1047  case ' ' :
1048  {
1049  UiInstance.Escape = Key;
1050  }
1051  break;
1052 
1053  case '<' :
1054  {
1055  UiInstance.Escape = Key;
1056  }
1057  break;
1058 
1059  case '\r' :
1060  case '\n' :
1061  {
1062  if (UiInstance.KeyBufIn)
1063  {
1064  UiInstance.Keys = UiInstance.KeyBufIn;
1065  UiInstance.KeyBufIn = 0;
1066  }
1067  }
1068  break;
1069 
1070  default :
1071  {
1072  UiInstance.KeyBuffer[UiInstance.KeyBufIn] = Key;
1073  if (++UiInstance.KeyBufIn >= KEYBUF_SIZE)
1074  {
1075  UiInstance.KeyBufIn--;
1076  }
1077  UiInstance.KeyBuffer[UiInstance.KeyBufIn] = 0;
1078  }
1079  break;
1080 
1081  }
1082  }
1083  }
1084  dLcdRead();
1085 
1086  return (OK);
1087 }
1088 #endif
1089 
1090 
1092 {
1093  DATA8 Result;
1094 
1095  Result = UiInstance.Escape;
1096  UiInstance.Escape = 0;
1097 
1098  return (Result);
1099 }
1100 
1101 
1102 void cUiTestpin(DATA8 State)
1103 {
1104  DATA8 Data8;
1105 
1106  Data8 = State;
1107  if (UiInstance.PowerFile >= MIN_HANDLE)
1108  {
1109  write(UiInstance.PowerFile,&Data8,1);
1110  }
1111 }
1112 
1113 
1115 {
1116  UBYTE Tmp = 0;
1117 
1118  if ((Char >= '0') && (Char <= '9'))
1119  {
1120  Tmp = (UBYTE)(Char - '0');
1121  }
1122  else
1123  {
1124  Char |= 0x20;
1125 
1126  if ((Char >= 'a') && (Char <= 'f'))
1127  {
1128  Tmp = (UBYTE)(Char - 'a') + 10;
1129  }
1130  }
1131 
1132  return (Tmp);
1133 }
1134 
1135 
1136 void cUiFlushBuffer(void)
1137 {
1138  if (UiInstance.UiWrBufferSize)
1139  {
1140  if (GetTerminalEnable())
1141  {
1142  dTerminalWrite((UBYTE*)UiInstance.UiWrBuffer,UiInstance.UiWrBufferSize);
1143  }
1144  UiInstance.UiWrBufferSize = 0;
1145  }
1146 }
1147 
1148 
1149 void cUiWriteString(DATA8 *pString)
1150 {
1151  while (*pString)
1152  {
1153  UiInstance.UiWrBuffer[UiInstance.UiWrBufferSize] = *pString;
1154  if (++UiInstance.UiWrBufferSize >= UI_WR_BUFFER_SIZE)
1155  {
1156  cUiFlushBuffer();
1157  }
1158  pString++;
1159  }
1160 }
1161 
1162 
1163 #define REAL_ANY_BUTTON 6
1164 #define REAL_NO_BUTTON 7
1165 
1166 
1167 DATA8 MappedToReal[BUTTONTYPES] =
1168 {
1169 // Mapped Real
1170  [UP_BUTTON] = 0,
1171  [ENTER_BUTTON] = 1,
1172  [DOWN_BUTTON] = 2,
1173  [RIGHT_BUTTON] = 3,
1174  [LEFT_BUTTON] = 4,
1175  [BACK_BUTTON] = 5,
1176  [ANY_BUTTON] = REAL_ANY_BUTTON,
1177  [NO_BUTTON] = REAL_NO_BUTTON
1178 };
1179 
1180 
1182 {
1183  DATA8 Real;
1184 
1185  if ((Mapped >= 0) && (Mapped < BUTTONTYPES))
1186  {
1187  Real = MappedToReal[Mapped];
1188  }
1189  else
1190  {
1191  Real = REAL_ANY_BUTTON;
1192  }
1193 
1194  return (Real);
1195 }
1196 
1197 
1198 void cUiSetPress(DATA8 Button,DATA8 Press)
1199 {
1200  Button = cUiButtonRemap(Button);
1201 
1202  if (Button < BUTTONS)
1203  {
1204  if (Press)
1205  {
1206  UiInstance.ButtonState[Button] |= BUTTON_ACTIVE;
1207  }
1208  else
1209  {
1210  UiInstance.ButtonState[Button] &= ~BUTTON_ACTIVE;
1211  }
1212  }
1213  else
1214  {
1215  if (Button == REAL_ANY_BUTTON)
1216  {
1217  if (Press)
1218  {
1219  for (Button = 0;Button < BUTTONS;Button++)
1220  {
1221  UiInstance.ButtonState[Button] |= BUTTON_ACTIVE;
1222  }
1223  }
1224  else
1225  {
1226  for (Button = 0;Button < BUTTONS;Button++)
1227  {
1228  UiInstance.ButtonState[Button] &= ~BUTTON_ACTIVE;
1229  }
1230  }
1231  }
1232  }
1233 }
1234 
1235 
1237 {
1238  DATA8 Result = 0;
1239 
1240  Button = cUiButtonRemap(Button);
1241 
1242  if (Button < BUTTONS)
1243  {
1244  if (UiInstance.ButtonState[Button] & BUTTON_PRESSED)
1245  {
1246  Result = 1;
1247  }
1248  }
1249  else
1250  {
1251  if (Button == REAL_ANY_BUTTON)
1252  {
1253  for (Button = 0;Button < BUTTONS;Button++)
1254  {
1255  if (UiInstance.ButtonState[Button] & BUTTON_PRESSED)
1256  {
1257  Result = 1;
1258  }
1259  }
1260  }
1261  }
1262 
1263  return (Result);
1264 }
1265 
1266 
1268 {
1269  DATA8 Result = 0;
1270 
1271  Button = cUiButtonRemap(Button);
1272 
1273  if (Button < BUTTONS)
1274  {
1275  if (UiInstance.ButtonState[Button] & BUTTON_ACTIVATED)
1276  {
1277  Result = 1;
1278  }
1279  }
1280  else
1281  {
1282  if (Button == REAL_ANY_BUTTON)
1283  {
1284  for (Button = 0;Button < BUTTONS;Button++)
1285  {
1286  if (UiInstance.ButtonState[Button] & BUTTON_ACTIVATED)
1287  {
1288  Result = 1;
1289  }
1290  }
1291  }
1292  else
1293  {
1294  if (Button == REAL_NO_BUTTON)
1295  {
1296  Result = 1;
1297  for (Button = 0;Button < BUTTONS;Button++)
1298  {
1299  if (UiInstance.ButtonState[Button] & BUTTON_ACTIVATED)
1300  {
1301  Result = 0;
1302  }
1303  }
1304  }
1305  }
1306  }
1307 
1308  return (Result);
1309 }
1310 
1311 
1313 {
1314  DATA8 Result = 0;
1315 
1316  Button = cUiButtonRemap(Button);
1317 
1318  if (Button < BUTTONS)
1319  {
1320  if (UiInstance.ButtonState[Button] & BUTTON_ACTIVATED)
1321  {
1322  UiInstance.ButtonState[Button] &= ~BUTTON_ACTIVATED;
1323  Result = 1;
1324  }
1325  }
1326  else
1327  {
1328  if (Button == REAL_ANY_BUTTON)
1329  {
1330  for (Button = 0;Button < BUTTONS;Button++)
1331  {
1332  if (UiInstance.ButtonState[Button] & BUTTON_ACTIVATED)
1333  {
1334  UiInstance.ButtonState[Button] &= ~BUTTON_ACTIVATED;
1335  Result = 1;
1336  }
1337  }
1338  }
1339  else
1340  {
1341  if (Button == REAL_NO_BUTTON)
1342  {
1343  Result = 1;
1344  for (Button = 0;Button < BUTTONS;Button++)
1345  {
1346  if (UiInstance.ButtonState[Button] & BUTTON_ACTIVATED)
1347  {
1348  UiInstance.ButtonState[Button] &= ~BUTTON_ACTIVATED;
1349  Result = 0;
1350  }
1351  }
1352  }
1353  }
1354  }
1355  if (Result)
1356  {
1357  UiInstance.Click = 1;
1358  }
1359 
1360  return (Result);
1361 }
1362 
1363 
1365 {
1366  DATA8 Result = 0;
1367 
1368  Button = cUiButtonRemap(Button);
1369 
1370  if (Button < BUTTONS)
1371  {
1372  if (UiInstance.ButtonState[Button] & BUTTON_BUMBED)
1373  {
1374  UiInstance.ButtonState[Button] &= ~BUTTON_BUMBED;
1375  Result = 1;
1376  }
1377  }
1378  else
1379  {
1380  if (Button == REAL_ANY_BUTTON)
1381  {
1382  for (Button = 0;Button < BUTTONS;Button++)
1383  {
1384  if (UiInstance.ButtonState[Button] & BUTTON_BUMBED)
1385  {
1386  UiInstance.ButtonState[Button] &= ~BUTTON_BUMBED;
1387  Result = 1;
1388  }
1389  }
1390  }
1391  else
1392  {
1393  if (Button == REAL_NO_BUTTON)
1394  {
1395  Result = 1;
1396  for (Button = 0;Button < BUTTONS;Button++)
1397  {
1398  if (UiInstance.ButtonState[Button] & BUTTON_BUMBED)
1399  {
1400  UiInstance.ButtonState[Button] &= ~BUTTON_BUMBED;
1401  Result = 0;
1402  }
1403  }
1404  }
1405  }
1406  }
1407 
1408  return (Result);
1409 }
1410 
1411 
1413 {
1414  DATA8 Result = 0;
1415 
1416  Button = cUiButtonRemap(Button);
1417 
1418  if (Button < BUTTONS)
1419  {
1420  if (UiInstance.ButtonState[Button] & BUTTON_LONGPRESS)
1421  {
1422  Result = 1;
1423  }
1424  }
1425  else
1426  {
1427  if (Button == REAL_ANY_BUTTON)
1428  {
1429  for (Button = 0;Button < BUTTONS;Button++)
1430  {
1431  if (UiInstance.ButtonState[Button] & BUTTON_LONGPRESS)
1432  {
1433  Result = 1;
1434  }
1435  }
1436  }
1437  else
1438  {
1439  if (Button == REAL_NO_BUTTON)
1440  {
1441  Result = 1;
1442  for (Button = 0;Button < BUTTONS;Button++)
1443  {
1444  if (UiInstance.ButtonState[Button] & BUTTON_LONGPRESS)
1445  {
1446  Result = 0;
1447  }
1448  }
1449  }
1450  }
1451  }
1452 
1453  return (Result);
1454 }
1455 
1456 
1458 {
1459  DATA8 Result = 0;
1460 
1461  Button = cUiButtonRemap(Button);
1462 
1463  if (Button < BUTTONS)
1464  {
1465  if (UiInstance.ButtonState[Button] & BUTTON_LONGPRESS)
1466  {
1467  UiInstance.ButtonState[Button] &= ~BUTTON_LONGPRESS;
1468  Result = 1;
1469  }
1470  }
1471  else
1472  {
1473  if (Button == REAL_ANY_BUTTON)
1474  {
1475  for (Button = 0;Button < BUTTONS;Button++)
1476  {
1477  if (UiInstance.ButtonState[Button] & BUTTON_LONGPRESS)
1478  {
1479  UiInstance.ButtonState[Button] &= ~BUTTON_LONGPRESS;
1480  Result = 1;
1481  }
1482  }
1483  }
1484  else
1485  {
1486  if (Button == REAL_NO_BUTTON)
1487  {
1488  Result = 1;
1489  for (Button = 0;Button < BUTTONS;Button++)
1490  {
1491  if (UiInstance.ButtonState[Button] & BUTTON_LONGPRESS)
1492  {
1493  UiInstance.ButtonState[Button] &= ~BUTTON_LONGPRESS;
1494  Result = 0;
1495  }
1496  }
1497  }
1498  }
1499  }
1500  if (Result)
1501  {
1502  UiInstance.Click = 1;
1503  }
1504 
1505  return (Result);
1506 }
1507 
1508 
1510 {
1511  DATA16 Result = 0;
1512 
1513  if (cUiTestShortPress(LEFT_BUTTON))
1514  {
1515  Result = -1;
1516  }
1517  if (cUiTestShortPress(RIGHT_BUTTON))
1518  {
1519  Result = 1;
1520  }
1521 
1522  return (Result);
1523 }
1524 
1525 
1527 {
1528  DATA16 Result = 0;
1529 
1530  if (cUiGetShortPress(LEFT_BUTTON))
1531  {
1532  Result = -1;
1533  }
1534  if (cUiGetShortPress(RIGHT_BUTTON))
1535  {
1536  Result = 1;
1537  }
1538 
1539  return (Result);
1540 }
1541 
1542 
1544 {
1545  DATA16 Result = 0;
1546 
1547  if (cUiGetShortPress(UP_BUTTON))
1548  {
1549  Result = -1;
1550  }
1551  if (cUiGetShortPress(DOWN_BUTTON))
1552  {
1553  Result = 1;
1554  }
1555 
1556  return (Result);
1557 }
1558 
1559 
1561 {
1562  DATA8 Result = 0;
1563 
1564  Result = cUiTestShortPress(ANY_BUTTON);
1565 
1566  return (Result);
1567 }
1568 
1569 
1571 {
1572  return ((X + 7) & ~7);
1573 }
1574 
1575 
1576 #define SHUNT_IN 0.11 // [Ohm]
1577 #define AMP_CIN 22.0 // [Times]
1578 
1579 #define EP2_SHUNT_IN 0.05 // [Ohm]
1580 #define EP2_AMP_CIN 15.0 // [Times]
1581 
1582 #define SHUNT_OUT 0.055 // [Ohm]
1583 #define AMP_COUT 19.0 // [Times]
1584 
1585 #define VCE 0.05 // [V]
1586 #define AMP_VIN 0.5 // [Times]
1587 
1588 #define AVR_CIN 300
1589 #define AVR_COUT 30
1590 #define AVR_VIN 30
1591 
1592 #define CNT_V(C) (((DATAF)C * (DATAF)ADC_REF) / ((DATAF)ADC_RES * (DATAF)1000.0))
1593 
1594 
1595 void cUiUpdateCnt(void)
1596 {
1597  if (UiInstance.PowerInitialized)
1598  {
1599  UiInstance.CinCnt *= (DATAF)(AVR_CIN - 1);
1600  UiInstance.CoutCnt *= (DATAF)(AVR_COUT - 1);
1601  UiInstance.VinCnt *= (DATAF)(AVR_VIN - 1);
1602 
1603  UiInstance.CinCnt += (DATAF)(*UiInstance.pAnalog).BatteryCurrent;
1604  UiInstance.CoutCnt += (DATAF)(*UiInstance.pAnalog).MotorCurrent;
1605  UiInstance.VinCnt += (DATAF)(*UiInstance.pAnalog).Cell123456;
1606 
1607  UiInstance.CinCnt /= (DATAF)(AVR_CIN);
1608  UiInstance.CoutCnt /= (DATAF)(AVR_COUT);
1609  UiInstance.VinCnt /= (DATAF)(AVR_VIN);
1610  }
1611  else
1612  {
1613  UiInstance.CinCnt = (DATAF)(*UiInstance.pAnalog).BatteryCurrent;
1614  UiInstance.CoutCnt = (DATAF)(*UiInstance.pAnalog).MotorCurrent;
1615  UiInstance.VinCnt = (DATAF)(*UiInstance.pAnalog).Cell123456;
1616  UiInstance.PowerInitialized = 1;
1617  }
1618 }
1619 
1620 
1621 void cUiUpdatePower(void)
1622 {
1623 #ifndef Linux_X86
1624  DATAF CinV;
1625  DATAF CoutV;
1626 
1627  if ((UiInstance.Hw == FINAL) || (UiInstance.Hw == FINALB))
1628  {
1629  CinV = CNT_V(UiInstance.CinCnt) / AMP_CIN;
1630  UiInstance.Vbatt = (CNT_V(UiInstance.VinCnt) / AMP_VIN) + CinV + VCE;
1631 
1632  UiInstance.Ibatt = CinV / SHUNT_IN;
1633  CoutV = CNT_V(UiInstance.CoutCnt) / AMP_COUT;
1634  UiInstance.Imotor = CoutV / SHUNT_OUT;
1635 
1636  }
1637  else
1638  {
1639  CinV = CNT_V(UiInstance.CinCnt) / EP2_AMP_CIN;
1640  UiInstance.Vbatt = (CNT_V(UiInstance.VinCnt) / AMP_VIN) + CinV + VCE;
1641 
1642  UiInstance.Ibatt = CinV / EP2_SHUNT_IN;
1643  UiInstance.Imotor = 0;
1644 
1645  }
1646 
1647 #endif
1648 #ifdef DEBUG_TEMP_SHUTDOWN
1649 
1650  UiInstance.Vbatt = 7.0;
1651  UiInstance.Ibatt = 5.0;
1652 
1653 #endif
1654 }
1655 
1656 
1657 //#define TRACK_UPDATE
1658 
1659 
1702 #define TOP_BATT_ICONS 5
1704 {
1705  SICON_BATT_0, // 0
1706  SICON_BATT_1, // 1
1707  SICON_BATT_2, // 2
1708  SICON_BATT_3, // 3
1709  SICON_BATT_4 // 4
1710 };
1711 
1712 
1713 #define TOP_BT_ICONS 4
1715 {
1716  SICON_BT_ON, // 001
1717  SICON_BT_VISIBLE, // 011
1718  SICON_BT_CONNECTED, // 101
1719  SICON_BT_CONNVISIB, // 111
1720 };
1721 
1722 
1723 #define TOP_WIFI_ICONS 4
1725 {
1726  SICON_WIFI_3, // 001
1727  SICON_WIFI_3, // 011
1728  SICON_WIFI_CONNECTED, // 101
1729  SICON_WIFI_CONNECTED, // 111
1730 };
1731 
1732 
1734 {
1735  DATA16 X1,X2;
1736  DATA16 V;
1737  DATA8 BtStatus;
1738  DATA8 WifiStatus;
1739  DATA8 TmpStatus;
1740  DATA8 Name[NAME_LENGTH + 1];
1741 
1742 #ifdef TRACK_UPDATE
1743  static DATA16 Counter = 0;
1744  static char Buffer[10];
1745 #endif
1746 #ifdef DEBUG_VIRTUAL_BATT_TEMP
1747  char TempBuf[10];
1748 #endif
1749 #ifdef ENABLE_MEMORY_TEST
1750  DATA32 Total;
1751  DATA32 Free;
1752 #endif
1753 
1754  if (UiInstance.TopLineEnabled)
1755  {
1756  // Clear top line
1757  LCDClearTopline(UiInstance.pLcd);
1758 
1759 #ifdef TRACK_UPDATE
1760  Counter++;
1761  sprintf(Buffer,"%d",Counter);
1762  dLcdDrawText((*UiInstance.pLcd).Lcd,FG_COLOR,16,1,SMALL_FONT,(DATA8*)Buffer);
1763 #endif
1764  // Show BT status
1765  TmpStatus = 0;
1766  BtStatus = cComGetBtStatus();
1767  if (BtStatus > 0)
1768  {
1769  TmpStatus = 1;
1770  BtStatus >>= 1;
1771  if ((BtStatus >= 0 ) && (BtStatus < TOP_BT_ICONS))
1772  {
1773  dLcdDrawIcon((*UiInstance.pLcd).Lcd,FG_COLOR,0,1,SMALL_ICON,TopLineBtIconMap[BtStatus]);
1774  }
1775  }
1776  if (UiInstance.BtOn != TmpStatus)
1777  {
1778  UiInstance.BtOn = TmpStatus;
1779  UiInstance.UiUpdate = 1;
1780  }
1781 
1782  // Show WIFI status
1783  TmpStatus = 0;
1784  WifiStatus = cComGetWifiStatus();
1785  if (WifiStatus > 0)
1786  {
1787  TmpStatus = 1;
1788  WifiStatus >>= 1;
1789  if ((WifiStatus >= 0 ) && (WifiStatus < TOP_WIFI_ICONS))
1790  {
1791  dLcdDrawIcon((*UiInstance.pLcd).Lcd,FG_COLOR,16,1,SMALL_ICON,TopLineWifiIconMap[WifiStatus]);
1792  }
1793  }
1794  if (UiInstance.WiFiOn != TmpStatus)
1795  {
1796  UiInstance.WiFiOn = TmpStatus;
1797  UiInstance.UiUpdate = 1;
1798  }
1799 #ifdef DEBUG_VIRTUAL_BATT_TEMP
1800  snprintf(TempBuf,10,"%4.1f",UiInstance.Tbatt);
1801  dLcdDrawText((*UiInstance.pLcd).Lcd,FG_COLOR,32,1,SMALL_FONT,(DATA8*)TempBuf);
1802 #endif
1803 
1804  // Show brick name
1805  cComGetBrickName(NAME_LENGTH + 1,Name);
1806 
1807  X1 = dLcdGetFontWidth(SMALL_FONT);
1808  X2 = LCD_WIDTH / X1;
1809  X2 -= strlen((char*)Name);
1810  X2 /= 2;
1811  X2 *= X1;
1812  dLcdDrawText((*UiInstance.pLcd).Lcd,FG_COLOR,X2,1,SMALL_FONT,Name);
1813 
1814 #ifdef ENABLE_PERFORMANCE_TEST
1815  X1 = 100;
1816  X2 = (DATA16)VMInstance.PerformTime;
1817  X2 = (X2 * 40) / 1000;
1818  if (X2 > 40)
1819  {
1820  X2 = 40;
1821  }
1822  dLcdRect((*UiInstance.pLcd).Lcd,FG_COLOR,X1,3,40,5);
1823  dLcdFillRect((*UiInstance.pLcd).Lcd,FG_COLOR,X1,3,X2,5);
1824 #endif
1825 #ifdef ENABLE_LOAD_TEST
1826  X1 = 100;
1827  X2 = (DATA16)(UiInstance.Iintegrated * 1000.0);
1828  X2 = (X2 * 40) / (DATA16)(LOAD_SHUTDOWN_HIGH * 1000.0);
1829  if (X2 > 40)
1830  {
1831  X2 = 40;
1832  }
1833  dLcdRect((*UiInstance.pLcd).Lcd,FG_COLOR,X1,3,40,5);
1834  dLcdFillRect((*UiInstance.pLcd).Lcd,FG_COLOR,X1,3,X2,5);
1835 #endif
1836 #ifdef ENABLE_MEMORY_TEST
1837  cMemoryGetUsage(&Total,&Free,0);
1838 
1839  X1 = 100;
1840  X2 = (DATA16)((((Total - (DATA32)LOW_MEMORY) - Free) * (DATA32)40) / (Total - (DATA32)LOW_MEMORY));
1841  if (X2 > 40)
1842  {
1843  X2 = 40;
1844  }
1845  dLcdRect((*UiInstance.pLcd).Lcd,FG_COLOR,X1,3,40,5);
1846  dLcdFillRect((*UiInstance.pLcd).Lcd,FG_COLOR,X1,3,X2,5);
1847 #endif
1848 
1849 // 112,118,124,130,136,142,148
1850 #ifdef ENABLE_STATUS_TEST
1851  X1 = 100;
1852  X2 = 102;
1853  for (V = 0;V < 7;V++)
1854  {
1855  dLcdDrawPixel((*UiInstance.pLcd).Lcd,FG_COLOR,X2 + (V * 6),5);
1856  dLcdDrawPixel((*UiInstance.pLcd).Lcd,FG_COLOR,X2 + (V * 6),4);
1857 
1858  if ((VMInstance.Status & (0x40 >> V)))
1859  {
1860  dLcdFillRect((*UiInstance.pLcd).Lcd,FG_COLOR,X1 + (V * 6),2,5,6);
1861  }
1862  }
1863 #endif
1864 
1865  // Calculate number of icons
1866  X1 = dLcdGetIconWidth(SMALL_ICON);
1867  X2 = (LCD_WIDTH - X1) / X1;
1868 
1869 #ifndef Linux_X86
1870  // Show USB status
1871  if (cComGetUsbStatus())
1872  {
1873  dLcdDrawIcon((*UiInstance.pLcd).Lcd,FG_COLOR,(X2 - 1) * X1,1,SMALL_ICON,SICON_USB);
1874  }
1875 #endif
1876 
1877 #ifdef DEBUG_BACK_BLOCKED
1878  if (UiInstance.BackButtonBlocked)
1879  {
1880  dLcdFillRect((*UiInstance.pLcd).Lcd,FG_COLOR,100,2,5,6);
1881  }
1882 #endif
1883 
1884  // Show battery
1885  V = (DATA16)(UiInstance.Vbatt * 1000.0);
1886  V -= UiInstance.BattIndicatorLow;
1887  V = (V * (TOP_BATT_ICONS - 1)) / (UiInstance.BattIndicatorHigh - UiInstance.BattIndicatorLow);
1888  if (V > (TOP_BATT_ICONS - 1))
1889  {
1890  V = (TOP_BATT_ICONS - 1);
1891  }
1892  if (V < 0)
1893  {
1894  V = 0;
1895  }
1896  dLcdDrawIcon((*UiInstance.pLcd).Lcd,FG_COLOR,X2 * X1,1,SMALL_ICON,TopLineBattIconMap[V]);
1897 
1898 #ifdef DEBUG_RECHARGEABLE
1899  if (UiInstance.Accu == 0)
1900  {
1901  dLcdDrawPixel((*UiInstance.pLcd).Lcd,FG_COLOR,176,4);
1902  dLcdDrawPixel((*UiInstance.pLcd).Lcd,FG_COLOR,176,5);
1903  }
1904 #endif
1905 
1906  // Show bottom line
1908  }
1909 }
1910 
1911 
1912 void cUiUpdateLcd(void)
1913 {
1914  UiInstance.Font = NORMAL_FONT;
1915  cUiUpdateTopline();
1916  dLcdUpdate(UiInstance.pLcd);
1917 }
1918 
1919 
1920 #include "mindstorms.xbm"
1921 #include "Ani1x.xbm"
1922 #include "Ani2x.xbm"
1923 #include "Ani3x.xbm"
1924 #include "Ani4x.xbm"
1925 #include "Ani5x.xbm"
1926 #include "Ani6x.xbm"
1927 #include "POP2.xbm"
1928 #include "POP3.xbm"
1929 #include "PCApp.xbm"
1930 
1931 
1932 void cUiRunScreen(void)
1933 { // 100mS
1934 
1935  if (UiInstance.ScreenBlocked == 0)
1936  {
1937  switch (UiInstance.RunScreenEnabled)
1938  {
1939  case 0 :
1940  {
1941  }
1942  break;
1943 
1944  case 1 :
1945  { // 100mS
1946 
1947  UiInstance.RunScreenEnabled++;
1948  }
1949  break;
1950 
1951  case 2 :
1952  { // 200mS
1953 
1954  UiInstance.RunScreenEnabled++;
1955  }
1956  break;
1957 
1958  case 3 :
1959  {
1960  // Init animation number
1961  UiInstance.RunScreenNumber = 1;
1962 
1963  // Clear screen
1964  LCDClear((*UiInstance.pLcd).Lcd);
1965  cUiUpdateLcd();
1966 
1967 
1968  // Enable top line
1969 
1970  // Draw fixed image
1971  dLcdDrawPicture((*UiInstance.pLcd).Lcd,FG_COLOR,8,39,mindstorms_width,mindstorms_height,(UBYTE*)mindstorms_bits);
1972  cUiUpdateLcd();
1973 
1974  // Draw user program name
1975  dLcdDrawText((*UiInstance.pLcd).Lcd,FG_COLOR,8,79,1,(DATA8*)VMInstance.Program[USER_SLOT].Name);
1976  cUiUpdateLcd();
1977 
1978  UiInstance.RunScreenTimer = 0;
1979  UiInstance.RunScreenCounter = 0;
1980 
1981  UiInstance.RunScreenEnabled++;
1982  }
1983  // FALL THROUGH
1984 
1985  case 4 :
1986  { // 0mS -> Ani1
1987 
1988  if (UiInstance.RunLedEnabled)
1989  {
1990  cUiSetLed(LED_GREEN_PULSE);
1991  }
1992 
1993  dLcdDrawPicture((*UiInstance.pLcd).Lcd,FG_COLOR,8,67,Ani1x_width,Ani1x_height,(UBYTE*)Ani1x_bits);
1994  cUiUpdateLcd();
1995 
1996  UiInstance.RunScreenTimer = UiInstance.MilliSeconds;
1997  UiInstance.RunScreenEnabled++;
1998  }
1999  break;
2000 
2001  case 5 :
2002  { // 100mS
2003 
2004  UiInstance.RunScreenEnabled++;
2005  }
2006  break;
2007 
2008  case 6 :
2009  { // 200mS
2010 
2011  UiInstance.RunScreenEnabled++;
2012  }
2013  break;
2014 
2015  case 7 :
2016  { // 300mS
2017 
2018  UiInstance.RunScreenEnabled++;
2019  }
2020  break;
2021 
2022  case 8 :
2023  { // 400mS
2024 
2025  UiInstance.RunScreenEnabled++;
2026  }
2027  break;
2028 
2029  case 9 :
2030  { // 500mS -> Ani2
2031 
2032  dLcdDrawPicture((*UiInstance.pLcd).Lcd,FG_COLOR,8,67,Ani2x_width,Ani2x_height,(UBYTE*)Ani2x_bits);
2033  cUiUpdateLcd();
2034 
2035  UiInstance.RunScreenEnabled++;
2036  }
2037  break;
2038 
2039  case 10 :
2040  { // 600mS -> Ani3
2041 
2042  dLcdDrawPicture((*UiInstance.pLcd).Lcd,FG_COLOR,8,67,Ani3x_width,Ani3x_height,(UBYTE*)Ani3x_bits);
2043  cUiUpdateLcd();
2044 
2045  UiInstance.RunScreenEnabled++;
2046  }
2047  break;
2048 
2049  case 11 :
2050  { // 700ms -> Ani4
2051 
2052  dLcdDrawPicture((*UiInstance.pLcd).Lcd,FG_COLOR,8,67,Ani4x_width,Ani4x_height,(UBYTE*)Ani4x_bits);
2053  cUiUpdateLcd();
2054 
2055  UiInstance.RunScreenEnabled++;
2056  }
2057  break;
2058 
2059  case 12 :
2060  { // 800ms -> Ani5
2061 
2062  dLcdDrawPicture((*UiInstance.pLcd).Lcd,FG_COLOR,8,67,Ani5x_width,Ani5x_height,(UBYTE*)Ani5x_bits);
2063  cUiUpdateLcd();
2064 
2065  UiInstance.RunScreenEnabled++;
2066  }
2067  break;
2068 
2069  default :
2070  { // 900ms -> Ani6
2071 
2072  dLcdDrawPicture((*UiInstance.pLcd).Lcd,FG_COLOR,8,67,Ani6x_width,Ani6x_height,(UBYTE*)Ani6x_bits);
2073  cUiUpdateLcd();
2074 
2075  UiInstance.RunScreenEnabled = 4;
2076  }
2077  break;
2078 
2079  }
2080  }
2081 }
2082 
2083 #ifndef DISABLE_LOW_VOLTAGE
2084 
2129 { // 400mS
2130 
2131  cUiUpdatePower();
2132 
2133  if (UiInstance.Vbatt >= UiInstance.BattWarningHigh)
2134  {
2135  UiInstance.Warning &= ~WARNING_BATTLOW;
2136  }
2137 
2138  if (UiInstance.Vbatt <= UiInstance.BattWarningLow)
2139  {
2140  UiInstance.Warning |= WARNING_BATTLOW;
2141  }
2142 
2143  if (UiInstance.Vbatt >= UiInstance.BattShutdownHigh)
2144  { // Good
2145 
2146  UiInstance.Warning &= ~WARNING_VOLTAGE;
2147  }
2148 
2149  if (UiInstance.Vbatt < UiInstance.BattShutdownLow)
2150  { // Bad
2151 
2152  UiInstance.Warning |= WARNING_VOLTAGE;
2153 
2154  ProgramEnd(USER_SLOT);
2155 
2156  if ((UiInstance.MilliSeconds - UiInstance.VoltageTimer) >= LOW_VOLTAGE_SHUTDOWN_TIME)
2157  { // Realy bad
2158 
2159  UiInstance.ShutDown = 1;
2160  }
2161  }
2162  else
2163  {
2164  UiInstance.VoltageTimer = UiInstance.MilliSeconds;
2165  }
2166 }
2167 
2168 #endif
2169 
2170 #ifdef ENABLE_HIGH_CURRENT
2171 
2224 void cUiCheckPower(UWORD Time)
2225 { // 400mS
2226 
2227  DATA16 X,Y;
2228  DATAF I;
2229  DATAF Slope;
2230 
2231  I = UiInstance.Ibatt + UiInstance.Imotor;
2232 
2233  if (I > LOAD_BREAK_EVEN)
2234  {
2235  Slope = LOAD_SLOPE_UP;
2236  }
2237  else
2238  {
2239  Slope = LOAD_SLOPE_DOWN;
2240  }
2241 
2242  UiInstance.Iintegrated += (I - LOAD_BREAK_EVEN) * (Slope * (DATAF)Time / 1000.0);
2243 
2244  if (UiInstance.Iintegrated < 0.0)
2245  {
2246  UiInstance.Iintegrated = 0.0;
2247  }
2248  if (UiInstance.Iintegrated > LOAD_SHUTDOWN_FAIL)
2249  {
2250  UiInstance.Iintegrated = LOAD_SHUTDOWN_FAIL;
2251  }
2252 
2253  if ((UiInstance.Iintegrated >= LOAD_SHUTDOWN_HIGH) || (I >= LOAD_SHUTDOWN_FAIL))
2254  {
2255  UiInstance.Warning |= WARNING_CURRENT;
2256  UiInstance.PowerShutdown = 1;
2257  }
2258  if (UiInstance.Iintegrated <= LOAD_BREAK_EVEN)
2259  {
2260  UiInstance.Warning &= ~WARNING_CURRENT;
2261  UiInstance.PowerShutdown = 0;
2262  }
2263 
2264  if (UiInstance.PowerShutdown)
2265  {
2266  if (UiInstance.ScreenBlocked == 0)
2267  {
2268  if (ProgramStatus(USER_SLOT) != STOPPED)
2269  {
2270  UiInstance.PowerState = 1;
2271  }
2272  }
2273  ProgramEnd(USER_SLOT);
2274  }
2275 
2276  switch (UiInstance.PowerState)
2277  {
2278  case 0 :
2279  {
2280  if (UiInstance.PowerShutdown)
2281  {
2282  UiInstance.PowerState++;
2283  }
2284  }
2285  break;
2286 
2287  case 1 :
2288  {
2289  if (!UiInstance.ScreenBusy)
2290  {
2291  if ((!UiInstance.VoltShutdown))
2292  {
2293  UiInstance.ScreenBlocked = 1;
2294  UiInstance.PowerState++;
2295  }
2296  }
2297  }
2298  break;
2299 
2300  case 2 :
2301  {
2302  LCDCopy(&UiInstance.LcdSafe,&UiInstance.LcdSave,sizeof(UiInstance.LcdSave));
2303  UiInstance.PowerState++;
2304  }
2305  break;
2306 
2307  case 3 :
2308  {
2309  X = 16;
2310  Y = 52;
2311 
2312  dLcdDrawPicture((*UiInstance.pLcd).Lcd,FG_COLOR,X,Y,POP3_width,POP3_height,(UBYTE*)POP3_bits);
2313 
2314  dLcdDrawIcon((*UiInstance.pLcd).Lcd,FG_COLOR,X + 48,Y + 10,LARGE_ICON,WARNSIGN);
2315  dLcdDrawIcon((*UiInstance.pLcd).Lcd,FG_COLOR,X + 72,Y + 10,LARGE_ICON,WARN_POWER);
2316  dLcdDrawLine((*UiInstance.pLcd).Lcd,FG_COLOR,X + 5,Y + 39,X + 138,Y + 39);
2317  dLcdDrawIcon((*UiInstance.pLcd).Lcd,FG_COLOR,X + 56,Y + 40,LARGE_ICON,YES_SEL);
2318  dLcdUpdate(UiInstance.pLcd);
2319  cUiButtonFlush();
2320  UiInstance.PowerState++;
2321  }
2322  break;
2323 
2324  case 4 :
2325  {
2326  if (cUiGetShortPress(ENTER_BUTTON))
2327  {
2328  if (UiInstance.ScreenBlocked)
2329  {
2330  UiInstance.ScreenBlocked = 0;
2331  }
2332  LCDCopy(&UiInstance.LcdSave,&UiInstance.LcdSafe,sizeof(UiInstance.LcdSafe));
2333  dLcdUpdate(UiInstance.pLcd);
2334  UiInstance.PowerState++;
2335  }
2336  if ((!UiInstance.PowerShutdown))
2337  {
2338  UiInstance.PowerState = 0;
2339  }
2340  }
2341  break;
2342 
2343  case 5 :
2344  {
2345  if ((!UiInstance.PowerShutdown))
2346  {
2347  UiInstance.PowerState = 0;
2348  }
2349  }
2350  break;
2351 
2352  }
2353 }
2354 #endif
2355 
2356 
2357 #ifndef DISABLE_VIRTUAL_BATT_TEMP
2358 
2376 void cUiCheckTemp(void)
2377 {
2378  if ((UiInstance.MilliSeconds - UiInstance.TempTimer) >= CALL_INTERVAL)
2379  {
2380  UiInstance.TempTimer += CALL_INTERVAL;
2381  UiInstance.Tbatt = new_bat_temp(UiInstance.Vbatt,(UiInstance.Ibatt * (DATAF)1.1));
2382 #ifdef DEBUG_TEMP_SHUTDOWN
2383  UiInstance.Tbatt += 35.0;
2384 #endif
2385 #ifdef DEBUG_VIRTUAL_BATT_TEMP
2386  char Buffer[250];
2387  int BufferSize;
2388 
2389  if (TempFile >= MIN_HANDLE)
2390  {
2391  BufferSize = snprintf(Buffer,250,"%8.1f,%9.6f,%9.6f,%11.6f\r\n",(float)UiInstance.MilliSeconds / (float)1000,UiInstance.Vbatt,UiInstance.Ibatt,UiInstance.Tbatt);
2392  write(TempFile,Buffer,BufferSize);
2393  }
2394 #endif
2395  }
2396 
2397  if (UiInstance.Tbatt >= TEMP_SHUTDOWN_WARNING)
2398  {
2399  UiInstance.Warning |= WARNING_TEMP;
2400  }
2401  else
2402  {
2403  UiInstance.Warning &= ~WARNING_TEMP;
2404  }
2405 
2406 
2407  if (UiInstance.Tbatt >= TEMP_SHUTDOWN_FAIL)
2408  {
2409  ProgramEnd(USER_SLOT);
2410  UiInstance.ShutDown = 1;
2411  }
2412 }
2413 #endif
2414 
2415 #ifndef DISABLE_LOW_MEMORY
2416 
2417 void cUiCheckMemory(void)
2418 { // 400mS
2419 
2420  DATA32 Total;
2421  DATA32 Free;
2422 
2423  cMemoryGetUsage(&Total,&Free,0);
2424 
2425  if (Free > LOW_MEMORY)
2426  { // Good
2427 
2428  UiInstance.Warning &= ~WARNING_MEMORY;
2429  }
2430  else
2431  { // Bad
2432 
2433  UiInstance.Warning |= WARNING_MEMORY;
2434  }
2435 
2436 }
2437 
2438 #endif
2439 
2440 
2442 {
2443  ULONG Timeout;
2444 
2445  UiInstance.SleepTimer += Time;
2446 
2447  if (UiInstance.Activated & BUTTON_ALIVE)
2448  {
2449  UiInstance.Activated &= ~BUTTON_ALIVE;
2450  cUiAlive();
2451  }
2452  Timeout = (ULONG)GetSleepMinutes();
2453 
2454  if (Timeout)
2455  {
2456  if (UiInstance.SleepTimer >= (Timeout * 60000L))
2457  {
2458  UiInstance.ShutDown = 1;
2459  }
2460  }
2461 }
2462 
2463 
2464 void cUiUpdate(UWORD Time)
2465 {
2466  DATA8 Warning;
2467  DATA8 Tmp;
2468 
2469  UiInstance.MilliSeconds += (ULONG)Time;
2470 
2471  cUiUpdateButtons(Time);
2472  cUiUpdateInput();
2473  cUiUpdateCnt();
2474 
2475 #ifdef MAX_FRAMES_PER_SEC
2476  UiInstance.DisplayTimer += (ULONG)Time;
2477  if (UiInstance.DisplayTimer >= (1000 / MAX_FRAMES_PER_SEC))
2478  {
2479  UiInstance.AllowUpdate = 1;
2480  if (UiInstance.ScreenBusy == 0)
2481  {
2482  dLcdAutoUpdate();
2483  }
2484  }
2485 #endif
2486 
2487 
2488  if ((UiInstance.MilliSeconds - UiInstance.UpdateStateTimer) >= 50)
2489  {
2490  UiInstance.UpdateStateTimer = UiInstance.MilliSeconds;
2491 
2492  if (!UiInstance.Event)
2493  {
2494  UiInstance.Event = cComGetEvent();
2495  }
2496 
2497  switch (UiInstance.UpdateState++)
2498  {
2499  case 0 :
2500  { // 50 mS
2501 
2502 #ifdef ENABLE_HIGH_CURRENT
2503  if (UiInstance.ReadyForWarnings)
2504  {
2505  cUiCheckPower(400);
2506  }
2507 #endif
2508 #ifndef DISABLE_VIRTUAL_BATT_TEMP
2509  if (UiInstance.ReadyForWarnings)
2510  {
2511  if (!UiInstance.Accu)
2512  {
2513  cUiCheckTemp();
2514  }
2515  }
2516 #endif
2517  }
2518  break;
2519 
2520  case 1 :
2521  { // 100 mS
2522 
2523  cUiRunScreen();
2524  }
2525  break;
2526 
2527  case 2 :
2528  { // 150 mS
2529 
2530  cUiCheckAlive(400);
2531 #ifndef DISABLE_LOW_MEMORY
2532  if (UiInstance.ReadyForWarnings)
2533  {
2534  cUiCheckMemory();
2535  }
2536 #endif
2537  }
2538  break;
2539 
2540  case 3 :
2541  { // 200 mS
2542 
2543  cUiRunScreen();
2544  }
2545  break;
2546 
2547  case 4 :
2548  { // 250 mS
2549 
2550 #ifndef DISABLE_LOW_VOLTAGE
2551  if (UiInstance.ReadyForWarnings)
2552  {
2553  cUiCheckVoltage();
2554  }
2555 #endif
2556  }
2557  break;
2558 
2559  case 5 :
2560  { // 300 mS
2561 
2562  cUiRunScreen();
2563  }
2564  break;
2565 
2566  case 6 :
2567  { // 350 mS
2568 
2569  if (UiInstance.ScreenBusy == 0)
2570  {
2571  cUiUpdateTopline();
2572  dLcdUpdate(UiInstance.pLcd);
2573  }
2574 #ifdef BUFPRINTSIZE
2575  if ((*UiInstance.pUi).Activated & BUTTON_BUFPRINT)
2576  {
2577  (*UiInstance.pUi).Activated &= ~BUTTON_BUFPRINT;
2578  BufPrint('w',"");
2579  }
2580 #endif
2581  }
2582  break;
2583 
2584  default :
2585  { // 400 mS
2586 
2587  cUiRunScreen();
2588  UiInstance.UpdateState = 0;
2589  UiInstance.ReadyForWarnings = 1;
2590  }
2591  break;
2592 
2593  }
2594 
2595  if (UiInstance.Warning)
2596  { // Some warning present
2597 
2598  if (!UiInstance.Warnlight)
2599  { // If not on - turn orange light on
2600 
2601  UiInstance.Warnlight = 1;
2602  cUiSetLed(UiInstance.LedState);
2603  }
2604  }
2605  else
2606  { // No warning
2607 
2608  if (UiInstance.Warnlight)
2609  { // If orange light on - turn it off
2610 
2611  UiInstance.Warnlight = 0;
2612  cUiSetLed(UiInstance.LedState);
2613  }
2614  }
2615 
2616  // Get valid popup warnings
2617  Warning = UiInstance.Warning & WARNINGS;
2618 
2619  // Find warnings that has not been showed
2620  Tmp = Warning & ~UiInstance.WarningShowed;
2621 
2622  if (Tmp)
2623  { // Show popup
2624 
2625  if (!UiInstance.ScreenBusy)
2626  { // Wait on screen
2627 
2628  if (UiInstance.ScreenBlocked == 0)
2629  {
2630  LCDCopy(&UiInstance.LcdSafe,&UiInstance.LcdSave,sizeof(UiInstance.LcdSave));
2631  dLcdDrawPicture((*UiInstance.pLcd).Lcd,FG_COLOR,vmPOP3_ABS_X,vmPOP3_ABS_Y,POP3_width,POP3_height,(UBYTE*)POP3_bits);
2632 
2633  if (Tmp & WARNING_TEMP)
2634  {
2635  dLcdDrawIcon((*UiInstance.pLcd).Lcd,FG_COLOR,vmPOP3_ABS_WARN_ICON_X1,vmPOP3_ABS_WARN_ICON_Y,LARGE_ICON,WARNSIGN);
2636  dLcdDrawIcon((*UiInstance.pLcd).Lcd,FG_COLOR,vmPOP3_ABS_WARN_ICON_X2,vmPOP3_ABS_WARN_SPEC_ICON_Y,LARGE_ICON,WARN_POWER);
2637  dLcdDrawIcon((*UiInstance.pLcd).Lcd,FG_COLOR,vmPOP3_ABS_WARN_ICON_X3,vmPOP3_ABS_WARN_SPEC_ICON_Y,LARGE_ICON,TO_MANUAL);
2638  UiInstance.WarningShowed |= WARNING_TEMP;
2639  }
2640  else
2641  {
2642  if (Tmp & WARNING_CURRENT)
2643  {
2644  dLcdDrawIcon((*UiInstance.pLcd).Lcd,FG_COLOR,vmPOP3_ABS_WARN_ICON_X1,vmPOP3_ABS_WARN_ICON_Y,LARGE_ICON,WARNSIGN);
2645  dLcdDrawIcon((*UiInstance.pLcd).Lcd,FG_COLOR,vmPOP3_ABS_WARN_ICON_X2,vmPOP3_ABS_WARN_SPEC_ICON_Y,LARGE_ICON,WARN_POWER);
2646  dLcdDrawIcon((*UiInstance.pLcd).Lcd,FG_COLOR,vmPOP3_ABS_WARN_ICON_X3,vmPOP3_ABS_WARN_SPEC_ICON_Y,LARGE_ICON,TO_MANUAL);
2647  UiInstance.WarningShowed |= WARNING_CURRENT;
2648  }
2649  else
2650  {
2651  if (Tmp & WARNING_VOLTAGE)
2652  {
2653  dLcdDrawIcon((*UiInstance.pLcd).Lcd,FG_COLOR,vmPOP3_ABS_WARN_ICON_X,vmPOP3_ABS_WARN_ICON_Y,LARGE_ICON,WARNSIGN);
2654  dLcdDrawIcon((*UiInstance.pLcd).Lcd,FG_COLOR,vmPOP3_ABS_WARN_SPEC_ICON_X,vmPOP3_ABS_WARN_SPEC_ICON_Y,LARGE_ICON,WARN_BATT);
2655  UiInstance.WarningShowed |= WARNING_VOLTAGE;
2656  }
2657  else
2658  {
2659  if (Tmp & WARNING_MEMORY)
2660  {
2661  dLcdDrawIcon((*UiInstance.pLcd).Lcd,FG_COLOR,vmPOP3_ABS_WARN_ICON_X,vmPOP3_ABS_WARN_ICON_Y,LARGE_ICON,WARNSIGN);
2662  dLcdDrawIcon((*UiInstance.pLcd).Lcd,FG_COLOR,vmPOP3_ABS_WARN_SPEC_ICON_X,vmPOP3_ABS_WARN_SPEC_ICON_Y,LARGE_ICON,WARN_MEMORY);
2663  UiInstance.WarningShowed |= WARNING_MEMORY;
2664  }
2665  else
2666  {
2667  if (Tmp & WARNING_DSPSTAT)
2668  {
2669  dLcdDrawIcon((*UiInstance.pLcd).Lcd,FG_COLOR,vmPOP3_ABS_WARN_ICON_X,vmPOP3_ABS_WARN_ICON_Y,LARGE_ICON,WARNSIGN);
2670  dLcdDrawIcon((*UiInstance.pLcd).Lcd,FG_COLOR,vmPOP3_ABS_WARN_SPEC_ICON_X,vmPOP3_ABS_WARN_SPEC_ICON_Y,LARGE_ICON,PROGRAM_ERROR);
2671  UiInstance.WarningShowed |= WARNING_DSPSTAT;
2672  }
2673  else
2674  {
2675  }
2676  }
2677  }
2678  }
2679  }
2681  dLcdDrawIcon((*UiInstance.pLcd).Lcd,FG_COLOR,vmPOP3_ABS_WARN_YES_X,vmPOP3_ABS_WARN_YES_Y,LARGE_ICON,YES_SEL);
2682  dLcdUpdate(UiInstance.pLcd);
2683  cUiButtonFlush();
2684  UiInstance.ScreenBlocked = 1;
2685  }
2686  }
2687  }
2688 
2689  // Find warnings that have been showed but not confirmed
2690  Tmp = UiInstance.WarningShowed;
2691  Tmp &= ~UiInstance.WarningConfirmed;
2692 
2693  if (Tmp)
2694  {
2695  if (cUiGetShortPress(ENTER_BUTTON))
2696  {
2697  UiInstance.ScreenBlocked = 0;
2698  LCDCopy(&UiInstance.LcdSave,&UiInstance.LcdSafe,sizeof(UiInstance.LcdSafe));
2699  dLcdUpdate(UiInstance.pLcd);
2700  if (Tmp & WARNING_TEMP)
2701  {
2702  UiInstance.WarningConfirmed |= WARNING_TEMP;
2703  }
2704  else
2705  {
2706  if (Tmp & WARNING_CURRENT)
2707  {
2708  UiInstance.WarningConfirmed |= WARNING_CURRENT;
2709  }
2710  else
2711  {
2712  if (Tmp & WARNING_VOLTAGE)
2713  {
2714  UiInstance.WarningConfirmed |= WARNING_VOLTAGE;
2715  }
2716  else
2717  {
2718  if (Tmp & WARNING_MEMORY)
2719  {
2720  UiInstance.WarningConfirmed |= WARNING_MEMORY;
2721  }
2722  else
2723  {
2724  if (Tmp & WARNING_DSPSTAT)
2725  {
2726  UiInstance.WarningConfirmed |= WARNING_DSPSTAT;
2727  UiInstance.Warning &= ~WARNING_DSPSTAT;
2728  }
2729  else
2730  {
2731  }
2732  }
2733  }
2734  }
2735  }
2736  }
2737  }
2738 
2739  // Find warnings that have been showed, confirmed and removed
2740  Tmp = ~Warning;
2741  Tmp &= WARNINGS;
2742  Tmp &= UiInstance.WarningShowed;
2743  Tmp &= UiInstance.WarningConfirmed;
2744 
2745  UiInstance.WarningShowed &= ~Tmp;
2746  UiInstance.WarningConfirmed &= ~Tmp;
2747  }
2748 }
2749 
2750 
2751 const DATA8 FiletypeToNormalIcon[FILETYPES] =
2752 {
2753  [FILETYPE_UNKNOWN] = ICON_FOLDER,
2754  [TYPE_FOLDER] = ICON_FOLDER,
2755  [TYPE_SOUND] = ICON_SOUND,
2756  [TYPE_BYTECODE] = ICON_RUN,
2757  [TYPE_GRAPHICS] = ICON_IMAGE,
2758  [TYPE_DATALOG] = ICON_OBD,
2759  [TYPE_PROGRAM] = ICON_OBP,
2760  [TYPE_TEXT] = ICON_TEXT
2761 };
2762 
2763 DATA8 cUiNotification(DATA8 Color,DATA16 X,DATA16 Y,DATA8 Icon1,DATA8 Icon2,DATA8 Icon3,DATA8 *pText,DATA8 *pState)
2764 {
2765  RESULT Result = BUSY;
2766  NOTIFY *pQ;
2767  DATA16 AvailableX;
2768  DATA16 UsedX;
2769  DATA16 Line;
2770  DATA16 CharIn;
2771  DATA16 CharOut;
2772  DATA8 Character;
2773  DATA16 X2;
2774  DATA16 Y2;
2775  DATA16 AvailableY;
2776  DATA16 UsedY;
2777 
2778  pQ = &UiInstance.Notify;
2779 
2780  if (*pState == 0)
2781  {
2782  *pState = 1;
2783  (*pQ).ScreenStartX = X;
2784  (*pQ).ScreenStartY = Y;
2785  (*pQ).ScreenWidth = POP3_width;
2786  (*pQ).ScreenHeight = POP3_height;
2787  (*pQ).IconStartY = (*pQ).ScreenStartY + 10;
2788  (*pQ).IconWidth = dLcdGetIconWidth(LARGE_ICON);
2789  (*pQ).IconHeight = dLcdGetIconHeight(LARGE_ICON);
2790  (*pQ).IconSpaceX = (*pQ).IconWidth;
2791 
2792  (*pQ).YesNoStartX = (*pQ).ScreenStartX + ((*pQ).ScreenWidth / 2);
2793  (*pQ).YesNoStartX -= ((*pQ).IconWidth + 8) / 2;
2794  (*pQ).YesNoStartX = cUiAlignX((*pQ).YesNoStartX);
2795  (*pQ).YesNoStartY = (*pQ).ScreenStartY + 40;
2796 
2797  (*pQ).LineStartX = (*pQ).ScreenStartX + 5;
2798  (*pQ).LineStartY = (*pQ).ScreenStartY + 39;
2799  (*pQ).LineEndX = (*pQ).LineStartX + 134;
2800 
2801  // Find no of icons
2802  (*pQ).NoOfIcons = 0;
2803  if (Icon1 > ICON_NONE)
2804  {
2805  (*pQ).NoOfIcons++;
2806  }
2807  if (Icon2 > ICON_NONE)
2808  {
2809  (*pQ).NoOfIcons++;
2810  }
2811  if (Icon3 > ICON_NONE)
2812  {
2813  (*pQ).NoOfIcons++;
2814  }
2815 
2816  // Find no of text lines
2817  (*pQ).TextLines = 0;
2818  if (pText[0])
2819  {
2820  (*pQ).IconStartX = (*pQ).ScreenStartX + 8;
2821  (*pQ).IconStartX = cUiAlignX((*pQ).IconStartX);
2822 
2823  AvailableX = (*pQ).ScreenWidth;
2824  AvailableX -= (((*pQ).IconStartX - (*pQ).ScreenStartX)) * 2;
2825 
2826  AvailableX -= (*pQ).NoOfIcons * (*pQ).IconSpaceX;
2827 
2828 
2829  (*pQ).NoOfChars = strlen((char*)pText);
2830 
2831 
2832  (*pQ).Font = SMALL_FONT;
2833  (*pQ).FontWidth = dLcdGetFontWidth((*pQ).Font);
2834  UsedX = (*pQ).FontWidth * (*pQ).NoOfChars;
2835 
2836  Line = 0;
2837 
2838  if (UsedX <= AvailableX)
2839  { // One line - small font
2840 
2841  if ((AvailableX - UsedX) >= 32)
2842  {
2843  (*pQ).IconStartX += 32;
2844  }
2845 
2846  snprintf((char*)(*pQ).TextLine[Line],MAX_NOTIFY_LINE_CHARS,"%s",pText);
2847  Line++;
2848  (*pQ).TextLines++;
2849 
2850  (*pQ).TextStartX = (*pQ).IconStartX + ((*pQ).NoOfIcons * (*pQ).IconSpaceX) ;
2851  (*pQ).TextStartY = (*pQ).ScreenStartY + 18;
2852  (*pQ).TextSpaceY = dLcdGetFontHeight((*pQ).Font) + 1;
2853  }
2854  else
2855  { // one or more lines - tiny font
2856 
2857  (*pQ).Font = TINY_FONT;
2858  (*pQ).FontWidth = dLcdGetFontWidth((*pQ).Font);
2859  UsedX = (*pQ).FontWidth * (*pQ).NoOfChars;
2860  AvailableX -= (*pQ).FontWidth;
2861 
2862  CharIn = 0;
2863 
2864  while ((pText[CharIn]) && (Line < MAX_NOTIFY_LINES))
2865  {
2866  CharOut = 0;
2867  UsedX = 0;
2868  while ((pText[CharIn]) && (CharOut < MAX_NOTIFY_LINE_CHARS) && (UsedX < (AvailableX - (*pQ).FontWidth)))
2869  {
2870  Character = pText[CharIn];
2871  if (Character == '_')
2872  {
2873  Character = ' ';
2874  }
2875  (*pQ).TextLine[Line][CharOut] = Character;
2876  CharIn++;
2877  CharOut++;
2878  UsedX += (*pQ).FontWidth;
2879  }
2880  while ((CharOut > 8) && (pText[CharIn] != ' ') && (pText[CharIn] != '_') && (pText[CharIn] != 0))
2881  {
2882  CharIn--;
2883  CharOut--;
2884  }
2885  if (pText[CharIn] != 0)
2886  {
2887  CharIn++;
2888  }
2889  (*pQ).TextLine[Line][CharOut] = 0;
2890  Line++;
2891  }
2892 
2893  (*pQ).TextLines = Line;
2894 
2895  (*pQ).TextStartX = (*pQ).IconStartX + ((*pQ).NoOfIcons * (*pQ).IconSpaceX) + (*pQ).FontWidth ;
2896  (*pQ).TextSpaceY = dLcdGetFontHeight((*pQ).Font) + 1;
2897 
2898 
2899  AvailableY = (*pQ).LineStartY - ((*pQ).ScreenStartY + 5);
2900  UsedY = (*pQ).TextLines * (*pQ).TextSpaceY;
2901 
2902  while (UsedY > AvailableY)
2903  {
2904  (*pQ).TextLines--;
2905  UsedY = (*pQ).TextLines * (*pQ).TextSpaceY;
2906  }
2907  Y2 = (AvailableY - UsedY) / 2;
2908 
2909  (*pQ).TextStartY = (*pQ).ScreenStartY + Y2 + 5;
2910  }
2911 
2912  }
2913  else
2914  {
2915  (*pQ).IconStartX = (*pQ).ScreenStartX + ((*pQ).ScreenWidth / 2);
2916  (*pQ).IconStartX -= ((*pQ).IconWidth + 8) / 2;
2917  (*pQ).IconStartX -= ((*pQ).NoOfIcons / 2) * (*pQ).IconWidth;
2918  (*pQ).IconStartX = cUiAlignX((*pQ).IconStartX);
2919  (*pQ).TextStartY = (*pQ).ScreenStartY + 8;
2920  }
2921 
2922  (*pQ).NeedUpdate = 1;
2923  }
2924 
2925 
2926  if ((*pQ).NeedUpdate)
2927  {
2928 //* UPDATE ***************************************************************************************************
2929  (*pQ).NeedUpdate = 0;
2930 
2931  dLcdDrawPicture((*UiInstance.pLcd).Lcd,Color,(*pQ).ScreenStartX,(*pQ).ScreenStartY,POP3_width,POP3_height,(UBYTE*)POP3_bits);
2932 
2933  X2 = (*pQ).IconStartX;
2934 
2935  if (Icon1 > ICON_NONE)
2936  {
2937  dLcdDrawIcon((*UiInstance.pLcd).Lcd,Color,X2,(*pQ).IconStartY,LARGE_ICON,Icon1);
2938  X2 += (*pQ).IconSpaceX;
2939  }
2940  if (Icon2 > ICON_NONE)
2941  {
2942  dLcdDrawIcon((*UiInstance.pLcd).Lcd,Color,X2,(*pQ).IconStartY,LARGE_ICON,Icon2);
2943  X2 += (*pQ).IconSpaceX;
2944  }
2945  if (Icon3 > ICON_NONE)
2946  {
2947  dLcdDrawIcon((*UiInstance.pLcd).Lcd,Color,X2,(*pQ).IconStartY,LARGE_ICON,Icon3);
2948  X2 += (*pQ).IconSpaceX;
2949  }
2950 
2951  Line = 0;
2952  Y2 = (*pQ).TextStartY;
2953  while (Line < (*pQ).TextLines)
2954  {
2955  dLcdDrawText((*UiInstance.pLcd).Lcd,Color,(*pQ).TextStartX,Y2,(*pQ).Font,(*pQ).TextLine[Line]);
2956  Y2 += (*pQ).TextSpaceY;
2957  Line++;
2958  }
2959 
2960  dLcdDrawLine((*UiInstance.pLcd).Lcd,Color,(*pQ).LineStartX,(*pQ).LineStartY,(*pQ).LineEndX,(*pQ).LineStartY);
2961 
2962  dLcdDrawIcon((*UiInstance.pLcd).Lcd,Color,(*pQ).YesNoStartX,(*pQ).YesNoStartY,LARGE_ICON,YES_SEL);
2963 
2964  cUiUpdateLcd();
2965  UiInstance.ScreenBusy = 0;
2966  }
2967 
2968  if (cUiGetShortPress(ENTER_BUTTON))
2969  {
2970  cUiButtonFlush();
2971  Result = OK;
2972  *pState = 0;
2973  }
2974 
2975  return (Result);
2976 }
2977 
2978 
2979 DATA8 cUiQuestion(DATA8 Color, DATA16 X,DATA16 Y,DATA8 Icon1,DATA8 Icon2,DATA8 *pText,DATA8 *pState,DATA8 *pAnswer)
2980 {
2981  RESULT Result = BUSY;
2982  TQUESTION *pQ;
2983  DATA16 Inc;
2984 
2985  pQ = &UiInstance.Question;
2986 
2987  Inc = cUiGetHorz();
2988  if (Inc != 0)
2989  {
2990  (*pQ).NeedUpdate = 1;
2991 
2992  *pAnswer += Inc;
2993 
2994  if (*pAnswer > 1)
2995  {
2996  *pAnswer = 1;
2997  (*pQ).NeedUpdate = 0;
2998  }
2999  if (*pAnswer < 0)
3000  {
3001  *pAnswer = 0;
3002  (*pQ).NeedUpdate = 0;
3003  }
3004  }
3005 
3006  if (*pState == 0)
3007  {
3008  *pState = 1;
3009  (*pQ).ScreenStartX = X;
3010  (*pQ).ScreenStartY = Y;
3011  (*pQ).IconWidth = dLcdGetIconWidth(LARGE_ICON);
3012  (*pQ).IconHeight = dLcdGetIconHeight(LARGE_ICON);
3013 
3014  (*pQ).NoOfIcons = 0;
3015  if (Icon1 > ICON_NONE)
3016  {
3017  (*pQ).NoOfIcons++;
3018  }
3019  if (Icon2 > ICON_NONE)
3020  {
3021  (*pQ).NoOfIcons++;
3022  }
3023  (*pQ).Default = *pAnswer;
3024 
3025  (*pQ).NeedUpdate = 1;
3026  }
3027 
3028 
3029  if ((*pQ).NeedUpdate)
3030  {
3031 //* UPDATE ***************************************************************************************************
3032  (*pQ).NeedUpdate = 0;
3033 
3034  dLcdDrawPicture((*UiInstance.pLcd).Lcd,Color,(*pQ).ScreenStartX,(*pQ).ScreenStartY,POP3_width,POP3_height,(UBYTE*)POP3_bits);
3035  (*pQ).ScreenWidth = POP3_width;
3036  (*pQ).ScreenHeight = POP3_height;
3037 
3038  (*pQ).IconStartX = (*pQ).ScreenStartX + ((*pQ).ScreenWidth / 2);
3039  if ((*pQ).NoOfIcons > 1)
3040  {
3041  (*pQ).IconStartX -= (*pQ).IconWidth;
3042  }
3043  else
3044  {
3045  (*pQ).IconStartX -= (*pQ).IconWidth / 2;
3046  }
3047  (*pQ).IconStartX = cUiAlignX((*pQ).IconStartX);
3048  (*pQ).IconSpaceX = (*pQ).IconWidth;
3049  (*pQ).IconStartY = (*pQ).ScreenStartY + 10;
3050 
3051  (*pQ).YesNoStartX = (*pQ).ScreenStartX + ((*pQ).ScreenWidth / 2);
3052  (*pQ).YesNoStartX -= 8;
3053  (*pQ).YesNoStartX -= (*pQ).IconWidth;
3054  (*pQ).YesNoStartX = cUiAlignX((*pQ).YesNoStartX);
3055  (*pQ).YesNoSpaceX = (*pQ).IconWidth + 16;
3056  (*pQ).YesNoStartY = (*pQ).ScreenStartY + 40;
3057 
3058  (*pQ).LineStartX = (*pQ).ScreenStartX + 5;
3059  (*pQ).LineStartY = (*pQ).ScreenStartY + 39;
3060  (*pQ).LineEndX = (*pQ).LineStartX + 134;
3061 
3062  switch ((*pQ).NoOfIcons)
3063  {
3064  case 1 :
3065  {
3066  dLcdDrawIcon((*UiInstance.pLcd).Lcd,Color,(*pQ).IconStartX,(*pQ).IconStartY,LARGE_ICON,Icon1);
3067  }
3068  break;
3069 
3070  case 2 :
3071  {
3072  dLcdDrawIcon((*UiInstance.pLcd).Lcd,Color,(*pQ).IconStartX,(*pQ).IconStartY,LARGE_ICON,Icon1);
3073  dLcdDrawIcon((*UiInstance.pLcd).Lcd,Color,(*pQ).IconStartX + (*pQ).IconSpaceX,(*pQ).IconStartY,LARGE_ICON,Icon2);
3074  }
3075  break;
3076 
3077  }
3078 
3079  if (*pAnswer == 0)
3080  {
3081  dLcdDrawIcon((*UiInstance.pLcd).Lcd,Color,(*pQ).YesNoStartX,(*pQ).YesNoStartY,LARGE_ICON,NO_SEL);
3082  dLcdDrawIcon((*UiInstance.pLcd).Lcd,Color,(*pQ).YesNoStartX + (*pQ).YesNoSpaceX,(*pQ).YesNoStartY,LARGE_ICON,YES_NOTSEL);
3083  }
3084  else
3085  {
3086  dLcdDrawIcon((*UiInstance.pLcd).Lcd,Color,(*pQ).YesNoStartX,(*pQ).YesNoStartY,LARGE_ICON,NO_NOTSEL);
3087  dLcdDrawIcon((*UiInstance.pLcd).Lcd,Color,(*pQ).YesNoStartX + (*pQ).YesNoSpaceX,(*pQ).YesNoStartY,LARGE_ICON,YES_SEL);
3088  }
3089 
3090  dLcdDrawLine((*UiInstance.pLcd).Lcd,Color,(*pQ).LineStartX,(*pQ).LineStartY,(*pQ).LineEndX,(*pQ).LineStartY);
3091 
3092  cUiUpdateLcd();
3093  UiInstance.ScreenBusy = 0;
3094  }
3095  if (cUiGetShortPress(ENTER_BUTTON))
3096  {
3097  cUiButtonFlush();
3098  Result = OK;
3099  *pState = 0;
3100  }
3101  if (cUiGetShortPress(BACK_BUTTON))
3102  {
3103  cUiButtonFlush();
3104  Result = OK;
3105  *pState = 0;
3106  *pAnswer = -1;
3107  }
3108 
3109  return (Result);
3110 }
3111 
3112 
3113 RESULT cUiIconQuestion(DATA8 Color,DATA16 X,DATA16 Y,DATA8 *pState,DATA32 *pIcons)
3114 {
3115  RESULT Result = BUSY;
3116  IQUESTION *pQ;
3117  DATA32 Mask;
3118  DATA32 TmpIcons;
3119  DATA16 Tmp;
3120  DATA16 Loop;
3121  DATA8 Icon;
3122 
3123  pQ = &UiInstance.IconQuestion;
3124 
3125  if (*pState == 0)
3126  {
3127  *pState = 1;
3128  (*pQ).ScreenStartX = X;
3129  (*pQ).ScreenStartY = Y;
3130  (*pQ).ScreenWidth = POP2_width;
3131  (*pQ).ScreenHeight = POP2_height;
3132  (*pQ).IconWidth = dLcdGetIconWidth(LARGE_ICON);
3133  (*pQ).IconHeight = dLcdGetIconHeight(LARGE_ICON);
3134  (*pQ).Frame = 2;
3135  (*pQ).Icons = *pIcons;
3136  (*pQ).NoOfIcons = 0;
3137  (*pQ).PointerX = 0;
3138 
3139  TmpIcons = (*pQ).Icons;
3140  while (TmpIcons)
3141  {
3142  if (TmpIcons & 1)
3143  {
3144  (*pQ).NoOfIcons++;
3145  }
3146  TmpIcons >>= 1;
3147  }
3148 
3149  if ((*pQ).NoOfIcons)
3150  {
3151  (*pQ).IconStartY = (*pQ).ScreenStartY + (((*pQ).ScreenHeight - (*pQ).IconHeight) / 2);
3152 
3153  (*pQ).IconSpaceX = (((*pQ).ScreenWidth - ((*pQ).IconWidth * (*pQ).NoOfIcons)) / (*pQ).NoOfIcons) + (*pQ).IconWidth;
3154  (*pQ).IconSpaceX = (*pQ).IconSpaceX & ~7;
3155 
3156  Tmp = (*pQ).IconSpaceX * (*pQ).NoOfIcons - ((*pQ).IconSpaceX - (*pQ).IconWidth);
3157 
3158  (*pQ).IconStartX = (*pQ).ScreenStartX + (((*pQ).ScreenWidth - Tmp) / 2);
3159  (*pQ).IconStartX = ((*pQ).IconStartX + 7) & ~7;
3160 
3161  (*pQ).SelectStartX = (*pQ).IconStartX - 1;
3162  (*pQ).SelectStartY = (*pQ).IconStartY - 1;
3163  (*pQ).SelectWidth = (*pQ).IconWidth + 2;
3164  (*pQ).SelectHeight = (*pQ).IconHeight + 2;
3165  (*pQ).SelectSpaceX = (*pQ).IconSpaceX;
3166  }
3167 #ifdef DEBUG
3168  printf("Shown icons %d -> 0x%08X\r\n",(*pQ).NoOfIcons,(*pQ).Icons);
3169 #endif
3170 
3171  (*pQ).NeedUpdate = 1;
3172  }
3173 
3174  if ((*pQ).NoOfIcons)
3175  {
3176  // Check for move pointer
3177  Tmp = cUiGetHorz();
3178  if (Tmp)
3179  {
3180  (*pQ).PointerX += Tmp;
3181 
3182  (*pQ).NeedUpdate = 1;
3183 
3184  if ((*pQ).PointerX < 0)
3185  {
3186  (*pQ).PointerX = 0;
3187  (*pQ).NeedUpdate = 0;
3188  }
3189  if ((*pQ).PointerX >= (*pQ).NoOfIcons)
3190  {
3191  (*pQ).PointerX = (*pQ).NoOfIcons - 1;
3192  (*pQ).NeedUpdate = 0;
3193  }
3194  }
3195  }
3196 
3197  if ((*pQ).NeedUpdate)
3198  {
3199 //* UPDATE ***************************************************************************************************
3200  (*pQ).NeedUpdate = 0;
3201 
3202  dLcdDrawPicture((*UiInstance.pLcd).Lcd,Color,(*pQ).ScreenStartX,(*pQ).ScreenStartY,POP2_width,POP2_height,(UBYTE*)POP2_bits);
3203  (*pQ).ScreenWidth = POP2_width;
3204  (*pQ).ScreenHeight = POP2_height;
3205 
3206  // Show icons
3207  Loop = 0;
3208  Icon = 0;
3209  TmpIcons = (*pQ).Icons;
3210  while (Loop < (*pQ).NoOfIcons)
3211  {
3212  while (!(TmpIcons & 1))
3213  {
3214  Icon++;
3215  TmpIcons >>= 1;
3216  }
3217  dLcdDrawIcon((*UiInstance.pLcd).Lcd,Color,(*pQ).IconStartX + (*pQ).IconSpaceX * Loop,(*pQ).IconStartY,LARGE_ICON,Icon);
3218  Loop++;
3219  Icon++;
3220  TmpIcons >>= 1;
3221  }
3222 
3223  // Show selection
3224  dLcdInverseRect((*UiInstance.pLcd).Lcd,(*pQ).SelectStartX + (*pQ).SelectSpaceX * (*pQ).PointerX,(*pQ).SelectStartY,(*pQ).SelectWidth,(*pQ).SelectHeight);
3225 
3226  // Update screen
3227  cUiUpdateLcd();
3228  UiInstance.ScreenBusy = 0;
3229  }
3230  if (cUiGetShortPress(ENTER_BUTTON))
3231  {
3232  if ((*pQ).NoOfIcons)
3233  {
3234  Mask = 0x00000001;
3235  TmpIcons = (*pQ).Icons;
3236  Loop = (*pQ).PointerX + 1;
3237 
3238  do
3239  {
3240  if (TmpIcons & Mask)
3241  {
3242  Loop--;
3243  }
3244  Mask <<= 1;
3245  }
3246  while (Loop && Mask);
3247  Mask >>= 1;
3248  *pIcons = Mask;
3249  }
3250  else
3251  {
3252  *pIcons = 0;
3253  }
3254  cUiButtonFlush();
3255  Result = OK;
3256  *pState = 0;
3257 #ifdef DEBUG
3258  printf("Selecting icon %d -> 0x%08X\r\n",(*pQ).PointerX,*pIcons);
3259 #endif
3260  }
3261  if (cUiGetShortPress(BACK_BUTTON))
3262  {
3263  *pIcons = 0;
3264  cUiButtonFlush();
3265  Result = OK;
3266  *pState = 0;
3267  }
3268 
3269  return (Result);
3270 }
3271 
3272 
3273 #include "keyboardc.xbm"
3274 #include "keyboards.xbm"
3275 #include "keyboardn.xbm"
3276 
3277 #define MAX_KEYB_DEEPT 3
3278 #define MAX_KEYB_WIDTH 12
3279 #define MAX_KEYB_HEIGHT 4
3280 
3281 DATA8 cUiKeyboard(DATA8 Color,DATA16 X,DATA16 Y,DATA8 Icon,DATA8 Lng,DATA8 *pText,DATA8 *pCharSet,DATA8 *pAnswer)
3282 {
3283  KEYB *pK;
3284  DATA16 Width;
3285  DATA16 Height;
3286  DATA16 Inc;
3287  DATA16 SX;
3288  DATA16 SY;
3289  DATA16 X3;
3290  DATA16 X4;
3291  DATA16 Tmp;
3292  DATA8 TmpChar;
3293  DATA8 SelectedChar = 0;
3294 
3295  // Value Marking
3296  // table > 0x20 -> normal rect
3297  // table = 0x20 -> spacebar
3298  // table = 0 -> end
3299  // table = 0x01 -> num
3300  // table = 0x02 -> cap
3301  // table = 0x03 -> non cap
3302  // table = 0x04 -> big cap
3303  // table = 0x08 -> backspace
3304  // table = 0x0D -> enter
3305  //
3306 
3307 
3309  {
3310  {
3311  { 'Q','W','E','R','T','Y','U','I','O','P', 0x08,0x00 },
3312  { 0x03,'A','S','D','F','G','H','J','K','L', 0x0D,0x00 },
3313  { 0x01,'Z','X','C','V','B','N','M',0x0D,0x0D,0x0D,0x00 },
3314  { ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', 0x0D,0x00 }
3315  },
3316  {
3317  { 'q','w','e','r','t','y','u','i','o','p', 0x08,0x00 },
3318  { 0x02,'a','s','d','f','g','h','j','k','l', 0x0D,0x00 },
3319  { 0x01,'z','x','c','v','b','n','m',0x0D,0x0D,0x0D,0x00 },
3320  { ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', 0x0D,0x00 }
3321  },
3322  {
3323  { '1','2','3','4','5','6','7','8','9','0', 0x08,0x00 },
3324  { 0x04,'+','-','=','<','>','/','\\','*',':', 0x0D,0x00 },
3325  { 0x04,'(',')','_','.','@','!','?',0x0D,0x0D,0x0D,0x00 },
3326  { ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', 0x0D,0x00 }
3327  }
3328  };
3329 
3330  pK = &UiInstance.Keyboard;
3331 
3332  if (*pCharSet != 0)
3333  {
3334  (*pK).CharSet = *pCharSet;
3335  *pCharSet = 0;
3336  (*pK).ScreenStartX = X;
3337  (*pK).ScreenStartY = Y;
3338 
3339  if ((Icon >= 0) && (Icon < N_ICON_NOS))
3340  {
3341  (*pK).IconStartX = cUiAlignX((*pK).ScreenStartX + 7);
3342  (*pK).IconStartY = (*pK).ScreenStartY + 4;
3343  (*pK).TextStartX = (*pK).IconStartX + dLcdGetIconWidth(NORMAL_ICON);
3344  }
3345  else
3346  {
3347  (*pK).TextStartX = cUiAlignX((*pK).ScreenStartX + 9);
3348  }
3349  (*pK).TextStartY = (*pK).ScreenStartY + 7;
3350  (*pK).StringStartX = (*pK).ScreenStartX + 8;
3351  (*pK).StringStartY = (*pK).ScreenStartY + 22;
3352  (*pK).KeybStartX = (*pK).ScreenStartX + 13;
3353  (*pK).KeybStartY = (*pK).ScreenStartY + 40;
3354  (*pK).KeybSpaceX = 11;
3355  (*pK).KeybSpaceY = 14;
3356  (*pK).KeybHeight = 13;
3357  (*pK).KeybWidth = 9;
3358  (*pK).Layout = 0;
3359  (*pK).PointerX = 10;
3360  (*pK).PointerY = 1;
3361  (*pK).NeedUpdate = 1;
3362  }
3363 
3364  Width = strlen((char*)KeyboardLayout[(*pK).Layout][(*pK).PointerY]) - 1;
3365  Height = MAX_KEYB_HEIGHT - 1;
3366 
3367  Inc = cUiGetHorz();
3368  (*pK).PointerX += Inc;
3369  if ((*pK).PointerX < 0)
3370  {
3371  (*pK).PointerX = 0;
3372  }
3373  if ((*pK).PointerX > Width)
3374  {
3375  (*pK).PointerX = Width;
3376  }
3377  Inc = cUiGetVert();
3378  (*pK).PointerY += Inc;
3379  if ((*pK).PointerY < 0)
3380  {
3381  (*pK).PointerY = 0;
3382  }
3383  if ((*pK).PointerY > Height)
3384  {
3385  (*pK).PointerY = Height;
3386  }
3387 
3388 
3389  TmpChar = KeyboardLayout[(*pK).Layout][(*pK).PointerY][(*pK).PointerX];
3390 
3391  if (cUiGetShortPress(BACK_BUTTON))
3392  {
3393  SelectedChar = 0x0D;
3394  pAnswer[0] = 0;
3395  }
3396  if (cUiGetShortPress(ENTER_BUTTON))
3397  {
3398  SelectedChar = TmpChar;
3399 
3400  switch (SelectedChar)
3401  {
3402  case 0x01 :
3403  {
3404  (*pK).Layout = 2;
3405  }
3406  break;
3407 
3408  case 0x02 :
3409  {
3410  (*pK).Layout = 0;
3411  }
3412  break;
3413 
3414  case 0x03 :
3415  {
3416  (*pK).Layout = 1;
3417  }
3418  break;
3419 
3420  case 0x04 :
3421  {
3422  (*pK).Layout = 0;
3423  }
3424  break;
3425 
3426  case 0x08 :
3427  {
3428  Tmp = (DATA16)strlen((char*)pAnswer);
3429  if (Tmp)
3430  {
3431  Tmp--;
3432  pAnswer[Tmp] = 0;
3433  }
3434  }
3435  break;
3436 
3437  case '\r' :
3438  {
3439  }
3440  break;
3441 
3442  default :
3443  {
3444  if (ValidateChar(&SelectedChar,(*pK).CharSet) == OK)
3445  {
3446  Tmp = (DATA16)strlen((char*)pAnswer);
3447  pAnswer[Tmp] = SelectedChar;
3448  if (++Tmp >= Lng)
3449  {
3450  Tmp--;
3451  }
3452  pAnswer[Tmp] = 0;
3453  }
3454  }
3455  break;
3456 
3457 
3458  }
3459 
3460  TmpChar = KeyboardLayout[(*pK).Layout][(*pK).PointerY][(*pK).PointerX];
3461 
3462  (*pK).NeedUpdate = 1;
3463  }
3464 
3465  if (((*pK).OldX != (*pK).PointerX) || ((*pK).OldY != (*pK).PointerY))
3466  {
3467  (*pK).OldX = (*pK).PointerX;
3468  (*pK).OldY = (*pK).PointerY;
3469  (*pK).NeedUpdate = 1;
3470  }
3471 
3472  if ((*pK).NeedUpdate)
3473  {
3474 //* UPDATE ***************************************************************************************************
3475  (*pK).NeedUpdate = 0;
3476 
3477  switch ((*pK).Layout)
3478  {
3479  case 0 :
3480  {
3481  dLcdDrawPicture((*UiInstance.pLcd).Lcd,Color,(*pK).ScreenStartX,(*pK).ScreenStartY,keyboardc_width,keyboardc_height,(UBYTE*)keyboardc_bits);
3482  }
3483  break;
3484 
3485  case 1 :
3486  {
3487  dLcdDrawPicture((*UiInstance.pLcd).Lcd,Color,(*pK).ScreenStartX,(*pK).ScreenStartY,keyboards_width,keyboards_height,(UBYTE*)keyboards_bits);
3488  }
3489  break;
3490 
3491  case 2 :
3492  {
3493  dLcdDrawPicture((*UiInstance.pLcd).Lcd,Color,(*pK).ScreenStartX,(*pK).ScreenStartY,keyboardn_width,keyboardn_height,(UBYTE*)keyboardn_bits);
3494  }
3495  break;
3496 
3497  }
3498  if ((Icon >= 0) && (Icon < N_ICON_NOS))
3499  {
3500  dLcdDrawIcon((*UiInstance.pLcd).Lcd,Color,(*pK).IconStartX,(*pK).IconStartY,NORMAL_ICON,Icon);
3501  }
3502  if (pText[0])
3503  {
3504  dLcdDrawText((*UiInstance.pLcd).Lcd,Color,(*pK).TextStartX,(*pK).TextStartY,SMALL_FONT,pText);
3505  }
3506 
3507 
3508  X4 = 0;
3509  X3 = strlen((char*)pAnswer);
3510  if (X3 > 15)
3511  {
3512  X4 = X3 - 15;
3513  }
3514 
3515  dLcdDrawText((*UiInstance.pLcd).Lcd,Color,(*pK).StringStartX,(*pK).StringStartY,NORMAL_FONT,&pAnswer[X4]);
3516  dLcdDrawChar((*UiInstance.pLcd).Lcd,Color,(*pK).StringStartX + (X3 - X4) * 8,(*pK).StringStartY,NORMAL_FONT,'_');
3517 
3518 
3519 
3520  SX = (*pK).KeybStartX + (*pK).PointerX * (*pK).KeybSpaceX;
3521  SY = (*pK).KeybStartY + (*pK).PointerY * (*pK).KeybSpaceY;
3522 
3523  switch (TmpChar)
3524  {
3525  case 0x01 :
3526  case 0x02 :
3527  case 0x03 :
3528  {
3529  dLcdInverseRect((*UiInstance.pLcd).Lcd,SX - 8,SY,(*pK).KeybWidth + 8,(*pK).KeybHeight);
3530  }
3531  break;
3532 
3533  case 0x04 :
3534  {
3535  dLcdInverseRect((*UiInstance.pLcd).Lcd,SX - 8,(*pK).KeybStartY + 1 * (*pK).KeybSpaceY,(*pK).KeybWidth + 8,(*pK).KeybHeight * 2 + 1);
3536  }
3537  break;
3538 
3539  case 0x08 :
3540  {
3541  dLcdInverseRect((*UiInstance.pLcd).Lcd,SX + 2,SY,(*pK).KeybWidth + 5,(*pK).KeybHeight);
3542  }
3543  break;
3544 
3545  case 0x0D :
3546  {
3547  SX = (*pK).KeybStartX + 112;
3548  SY = (*pK).KeybStartY + 1 * (*pK).KeybSpaceY;
3549  dLcdInverseRect((*UiInstance.pLcd).Lcd,SX,SY,(*pK).KeybWidth + 5,(*pK).KeybSpaceY + 1);
3550  SX = (*pK).KeybStartX + 103;
3551  SY = (*pK).KeybStartY + 1 + 2 * (*pK).KeybSpaceY;
3552  dLcdInverseRect((*UiInstance.pLcd).Lcd,SX,SY,(*pK).KeybWidth + 14,(*pK).KeybSpaceY * 2 - 4);
3553  }
3554  break;
3555 
3556  case 0x20 :
3557  {
3558  dLcdInverseRect((*UiInstance.pLcd).Lcd,(*pK).KeybStartX + 11,SY + 1,(*pK).KeybWidth + 68,(*pK).KeybHeight - 3);
3559  }
3560  break;
3561 
3562  default :
3563  {
3564  dLcdInverseRect((*UiInstance.pLcd).Lcd,SX + 1,SY,(*pK).KeybWidth,(*pK).KeybHeight);
3565  }
3566  break;
3567 
3568  }
3569  cUiUpdateLcd();
3570  UiInstance.ScreenBusy = 0;
3571  }
3572 
3573  return (SelectedChar);
3574 }
3575 
3576 
3577 void cUiDrawBar(DATA8 Color,DATA16 X,DATA16 Y,DATA16 X1,DATA16 Y1,DATA16 Min,DATA16 Max,DATA16 Act)
3578 {
3579  DATA16 Tmp;
3580  DATA16 Items;
3581  DATA16 KnobHeight = 7;
3582 
3583  Items = Max - Min;
3584 
3585  switch (X1)
3586  {
3587  case 5 :
3588  {
3589  KnobHeight = 7;
3590  }
3591  break;
3592 
3593  case 6 :
3594  {
3595  KnobHeight = 9;
3596  }
3597  break;
3598 
3599  default :
3600  {
3601  if (Items > 0)
3602  {
3603  KnobHeight = Y1 / Items;
3604  }
3605  }
3606  break;
3607 
3608  }
3609 
3610  if (Act < Min)
3611  {
3612  Act = Min;
3613  }
3614  if (Act > Max)
3615  {
3616  Act = Max;
3617  }
3618 
3619  // Draw scroll bar
3620  dLcdRect((*UiInstance.pLcd).Lcd,Color,X,Y,X1,Y1);
3621 
3622  // Draw nob
3623  Tmp = Y;
3624  if ((Items > 1) && (Act > 0))
3625  {
3626  Tmp += ((Y1 - KnobHeight) * (Act - 1)) / (Items - 1);
3627  }
3628 
3629  switch (X1)
3630  {
3631  case 5 :
3632  {
3633  dLcdDrawPixel((*UiInstance.pLcd).Lcd,Color,X + 1,Tmp);
3634  dLcdDrawPixel((*UiInstance.pLcd).Lcd,Color,X + 2,Tmp);
3635  dLcdDrawPixel((*UiInstance.pLcd).Lcd,Color,X + 3,Tmp);
3636  Tmp++;
3637  dLcdDrawPixel((*UiInstance.pLcd).Lcd,Color,X + 1,Tmp);
3638  dLcdDrawPixel((*UiInstance.pLcd).Lcd,Color,X + 3,Tmp);
3639  Tmp++;
3640  dLcdDrawPixel((*UiInstance.pLcd).Lcd,Color,X + 2,Tmp);
3641  Tmp++;
3642  dLcdDrawPixel((*UiInstance.pLcd).Lcd,Color,X + 1,Tmp);
3643  dLcdDrawPixel((*UiInstance.pLcd).Lcd,Color,X + 3,Tmp);
3644  Tmp++;
3645  dLcdDrawPixel((*UiInstance.pLcd).Lcd,Color,X + 2,Tmp);
3646  Tmp++;
3647  dLcdDrawPixel((*UiInstance.pLcd).Lcd,Color,X + 1,Tmp);
3648  dLcdDrawPixel((*UiInstance.pLcd).Lcd,Color,X + 3,Tmp);
3649  Tmp++;
3650  dLcdDrawPixel((*UiInstance.pLcd).Lcd,Color,X + 1,Tmp);
3651  dLcdDrawPixel((*UiInstance.pLcd).Lcd,Color,X + 2,Tmp);
3652  dLcdDrawPixel((*UiInstance.pLcd).Lcd,Color,X + 3,Tmp);
3653  }
3654  break;
3655 
3656  case 6 :
3657  {
3658  dLcdDrawPixel((*UiInstance.pLcd).Lcd,Color,X + 2,Tmp);
3659  dLcdDrawPixel((*UiInstance.pLcd).Lcd,Color,X + 3,Tmp);
3660  Tmp++;
3661  dLcdDrawPixel((*UiInstance.pLcd).Lcd,Color,X + 1,Tmp);
3662  dLcdDrawPixel((*UiInstance.pLcd).Lcd,Color,X + 4,Tmp);
3663  Tmp++;
3664  Tmp++;
3665  dLcdDrawPixel((*UiInstance.pLcd).Lcd,Color,X + 2,Tmp);
3666  dLcdDrawPixel((*UiInstance.pLcd).Lcd,Color,X + 3,Tmp);
3667  Tmp++;
3668  Tmp++;
3669  dLcdDrawPixel((*UiInstance.pLcd).Lcd,Color,X + 2,Tmp);
3670  dLcdDrawPixel((*UiInstance.pLcd).Lcd,Color,X + 3,Tmp);
3671  Tmp++;
3672  Tmp++;
3673  dLcdDrawPixel((*UiInstance.pLcd).Lcd,Color,X + 1,Tmp);
3674  dLcdDrawPixel((*UiInstance.pLcd).Lcd,Color,X + 4,Tmp);
3675  Tmp++;
3676  dLcdDrawPixel((*UiInstance.pLcd).Lcd,Color,X + 2,Tmp);
3677  dLcdDrawPixel((*UiInstance.pLcd).Lcd,Color,X + 3,Tmp);
3678  }
3679  break;
3680 
3681  default :
3682  {
3683  dLcdFillRect((*UiInstance.pLcd).Lcd,Color,X,Tmp,X1,KnobHeight);
3684  }
3685  break;
3686 
3687  }
3688 
3689 }
3690 
3691 
3692 RESULT cUiBrowser(DATA8 Type,DATA16 X,DATA16 Y,DATA16 X1,DATA16 Y1,DATA8 Lng,DATA8 *pType,DATA8 *pAnswer)
3693 {
3694  RESULT Result = BUSY;
3695  DATA32 Image;
3696  BROWSER *pB;
3697  PRGID PrgId;
3698  OBJID ObjId;
3699  DATA16 Tmp;
3700  DATA16 Indent;
3701  DATA16 Item;
3702  DATA16 TotalItems;
3703  DATA8 TmpType;
3704  DATA8 Folder;
3705  DATA8 OldPriority;
3706  DATA8 Priority;
3707  DATA8 Color;
3708  DATA16 Ignore;
3709  DATA8 Data8;
3710  DATA32 Total;
3711  DATA32 Free;
3712  RESULT TmpResult;
3713  HANDLER TmpHandle;
3714 
3715  PrgId = CurrentProgramId();
3716  ObjId = CallingObjectId();
3717  pB = &UiInstance.Browser;
3718 
3719  Color = FG_COLOR;
3720 
3721  // Test ignore horizontal update
3722  if ((Type & 0x20))
3723  {
3724  Ignore = -1;
3725  }
3726  else
3727  {
3728  if ((Type & 0x10))
3729  {
3730  Ignore = 1;
3731  }
3732  else
3733  {
3734  Ignore = 0;
3735  }
3736  }
3737 
3738  // Isolate browser type
3739  Type &= 0x0F;
3740 
3741  CheckUsbstick(&Data8,&Total,&Free,0);
3742  if (Data8)
3743  {
3744  UiInstance.UiUpdate = 1;
3745  }
3746  CheckSdcard(&Data8,&Total,&Free,0);
3747  if (Data8)
3748  {
3749  UiInstance.UiUpdate = 1;
3750  }
3751 
3752  if (ProgramStatusChange(USER_SLOT) == STOPPED)
3753  {
3754  if (Type != BROWSE_FILES)
3755  {
3756  Result = OK;
3757  *pType = 0;
3758 #ifdef DEBUG
3759  printf("Browser interrupted\r\n");
3760 #endif
3761  }
3762  }
3763 
3764  if ((*pType == TYPE_REFRESH_BROWSER))
3765  {
3766  UiInstance.UiUpdate = 1;
3767  }
3768 
3769  if ((*pType == TYPE_RESTART_BROWSER))
3770  {
3771  if ((*pB).hFiles)
3772  {
3773  cMemoryCloseFolder((*pB).PrgId,&(*pB).hFiles);
3774  }
3775  if ((*pB).hFolders)
3776  {
3777  cMemoryCloseFolder((*pB).PrgId,&(*pB).hFolders);
3778  }
3779  (*pB).PrgId = 0;
3780  (*pB).ObjId = 0;
3781 // pAnswer[0] = 0;
3782  *pType = 0;
3783 #ifdef DEBUG
3784  printf("Restarting browser\r\n");
3785 #endif
3786  }
3787 
3788  if (((*pB).PrgId == 0) && ((*pB).ObjId == 0))
3789  {
3790 //* INIT *****************************************************************************************************
3791 
3792  // Define screen
3793  (*pB).ScreenStartX = X;
3794  (*pB).ScreenStartY = Y;
3795  (*pB).ScreenWidth = X1;
3796  (*pB).ScreenHeight = Y1;
3797 
3798  // calculate lines on screen
3799  (*pB).LineSpace = 5;
3800  (*pB).IconHeight = dLcdGetIconHeight(NORMAL_ICON);
3801  (*pB).LineHeight = (*pB).IconHeight + (*pB).LineSpace;
3802  (*pB).Lines = ((*pB).ScreenHeight / (*pB).LineHeight);
3803 
3804  // calculate chars and lines on screen
3805  (*pB).CharWidth = dLcdGetFontWidth(NORMAL_FONT);
3806  (*pB).CharHeight = dLcdGetFontHeight(NORMAL_FONT);
3807  (*pB).IconWidth = dLcdGetIconWidth(NORMAL_ICON);
3808  (*pB).Chars = (((*pB).ScreenWidth - (*pB).IconWidth) / (*pB).CharWidth);
3809 
3810  // calculate start of icon
3811  (*pB).IconStartX = cUiAlignX((*pB).ScreenStartX);
3812  (*pB).IconStartY = (*pB).ScreenStartY + (*pB).LineSpace / 2;
3813 
3814  // calculate start of text
3815  (*pB).TextStartX = cUiAlignX((*pB).ScreenStartX + (*pB).IconWidth);
3816  (*pB).TextStartY = (*pB).ScreenStartY + ((*pB).LineHeight - (*pB).CharHeight) / 2;
3817 
3818  // Calculate selection barBrowser
3819  (*pB).SelectStartX = (*pB).ScreenStartX + 1;
3820  (*pB).SelectWidth = (*pB).ScreenWidth - ((*pB).CharWidth + 5);
3821  (*pB).SelectStartY = (*pB).IconStartY - 1;
3822  (*pB).SelectHeight = (*pB).IconHeight + 2;
3823 
3824  // Calculate scroll bar
3825  (*pB).ScrollWidth = 6;
3826  (*pB).NobHeight = 9;
3827  (*pB).ScrollStartX = (*pB).ScreenStartX + (*pB).ScreenWidth - (*pB).ScrollWidth;
3828  (*pB).ScrollStartY = (*pB).ScreenStartY + 1;
3829  (*pB).ScrollHeight = (*pB).ScreenHeight - 2;
3830  (*pB).ScrollSpan = (*pB).ScrollHeight - (*pB).NobHeight;
3831 
3832  strncpy((char*)(*pB).TopFolder,(char*)pAnswer,MAX_FILENAME_SIZE);
3833 
3834  (*pB).PrgId = PrgId;
3835  (*pB).ObjId = ObjId;
3836 
3837  (*pB).OldFiles = 0;
3838  (*pB).Folders = 0;
3839  (*pB).OpenFolder = 0;
3840  (*pB).Files = 0;
3841  (*pB).ItemStart = 1;
3842  (*pB).ItemPointer = 1;
3843  (*pB).NeedUpdate = 1;
3844  UiInstance.UiUpdate = 1;
3845  }
3846 
3847  if (((*pB).PrgId == PrgId) && ((*pB).ObjId == ObjId))
3848  {
3849 //* CTRL *****************************************************************************************************
3850 
3851 
3852  if (UiInstance.UiUpdate)
3853  {
3854  UiInstance.UiUpdate = 0;
3855 #ifdef DEBUG
3856  printf("Refreshing browser\r\n");
3857 #endif
3858 
3859  if ((*pB).hFiles)
3860  {
3861  cMemoryCloseFolder((*pB).PrgId,&(*pB).hFiles);
3862  }
3863  if ((*pB).hFolders)
3864  {
3865  cMemoryCloseFolder((*pB).PrgId,&(*pB).hFolders);
3866  }
3867 
3868  (*pB).OpenFolder = 0;
3869  (*pB).Files = 0;
3870  *pType = 0;
3871 
3872  switch (Type)
3873  {
3874  case BROWSE_FOLDERS :
3875  case BROWSE_FOLDS_FILES :
3876  {
3877  if (cMemoryOpenFolder(PrgId,TYPE_FOLDER,(*pB).TopFolder,&(*pB).hFolders) == OK)
3878  {
3879  #ifdef DEBUG
3880  printf("\r\n%d %d Opening browser in %s\r\n",PrgId,ObjId,(char*)(*pB).TopFolder);
3881  #endif
3882 //******************************************************************************************************
3883  if ((*pB).OpenFolder)
3884  {
3885  cMemoryGetItem((*pB).PrgId,(*pB).hFolders,(*pB).OpenFolder,FOLDERNAME_SIZE + SUBFOLDERNAME_SIZE,(*pB).SubFolder,&TmpType);
3886  #ifdef DEBUG
3887  printf("Open folder %3d (%s)\r\n",(*pB).OpenFolder,(*pB).SubFolder);
3888  #endif
3889  if (strcmp((char*)(*pB).SubFolder,SDCARD_FOLDER) == 0)
3890  {
3891  Item = (*pB).ItemPointer;
3892  cMemoryGetItemName((*pB).PrgId,(*pB).hFolders,Item,MAX_FILENAME_SIZE,(*pB).Filename,pType,&Priority);
3893  Result = cMemoryGetItem((*pB).PrgId,(*pB).hFolders,Item,FOLDERNAME_SIZE + SUBFOLDERNAME_SIZE,(*pB).FullPath,pType);
3894  *pType = TYPE_SDCARD;
3895 
3896  snprintf((char*)pAnswer,Lng,"%s",(char*)(*pB).FullPath);
3897  }
3898  else
3899  {
3900  if (strcmp((char*)(*pB).SubFolder,USBSTICK_FOLDER) == 0)
3901  {
3902  Item = (*pB).ItemPointer;
3903  cMemoryGetItemName((*pB).PrgId,(*pB).hFolders,Item,MAX_FILENAME_SIZE,(*pB).Filename,pType,&Priority);
3904  Result = cMemoryGetItem((*pB).PrgId,(*pB).hFolders,Item,FOLDERNAME_SIZE + SUBFOLDERNAME_SIZE,(*pB).FullPath,pType);
3905  *pType = TYPE_USBSTICK;
3906 
3907  snprintf((char*)pAnswer,Lng,"%s",(char*)(*pB).FullPath);
3908  }
3909  else
3910  {
3911  Result = cMemoryOpenFolder(PrgId,FILETYPE_UNKNOWN,(*pB).SubFolder,&(*pB).hFiles);
3912  Result = BUSY;
3913  }
3914  }
3915  }
3916 //******************************************************************************************************
3917  }
3918  else
3919  {
3920  #ifdef DEBUG
3921  printf("\r\n%d %d Open error\r\n",PrgId,ObjId);
3922  #endif
3923  (*pB).PrgId = 0;
3924  (*pB).ObjId = 0;
3925  }
3926  }
3927  break;
3928 
3929  case BROWSE_CACHE:
3930  {
3931  }
3932  break;
3933 
3934  case BROWSE_FILES :
3935  {
3936  if (cMemoryOpenFolder(PrgId,FILETYPE_UNKNOWN,(*pB).TopFolder,&(*pB).hFiles) == OK)
3937  {
3938  #ifdef DEBUG
3939  printf("\r\n%d %d Opening browser in %s\r\n",PrgId,ObjId,(char*)(*pB).TopFolder);
3940  #endif
3941 
3942  }
3943  else
3944  {
3945  #ifdef DEBUG
3946  printf("\r\n%d %d Open error\r\n",PrgId,ObjId);
3947  #endif
3948  (*pB).PrgId = 0;
3949  (*pB).ObjId = 0;
3950  }
3951  }
3952  break;
3953 
3954  }
3955  }
3956 
3957 #ifndef DISABLE_SDCARD_SUPPORT
3958  if (strstr((char*)(*pB).SubFolder,SDCARD_FOLDER) != NULL)
3959  {
3960  (*pB).Sdcard = 1;
3961  }
3962  else
3963  {
3964  (*pB).Sdcard = 0;
3965  }
3966 #endif
3967 
3968 #ifndef DISABLE_USBSTICK_SUPPORT
3969  if (strstr((char*)(*pB).SubFolder,USBSTICK_FOLDER) != NULL)
3970  {
3971  (*pB).Usbstick = 1;
3972  }
3973  else
3974  {
3975  (*pB).Usbstick = 0;
3976  }
3977 #endif
3978 
3979  TmpResult = OK;
3980  switch (Type)
3981  {
3982  case BROWSE_FOLDERS :
3983  case BROWSE_FOLDS_FILES :
3984  {
3985  // Collect folders in directory
3986  TmpResult = cMemoryGetFolderItems((*pB).PrgId,(*pB).hFolders,&(*pB).Folders);
3987 
3988  // Collect files in folder
3989  if (((*pB).OpenFolder) && (TmpResult == OK))
3990  {
3991  TmpResult = cMemoryGetFolderItems((*pB).PrgId,(*pB).hFiles,&(*pB).Files);
3992  }
3993  }
3994  break;
3995 
3996  case BROWSE_CACHE :
3997  {
3998  (*pB).Folders = (DATA16)cMemoryGetCacheFiles();
3999  }
4000  break;
4001 
4002  case BROWSE_FILES :
4003  {
4004  TmpResult = cMemoryGetFolderItems((*pB).PrgId,(*pB).hFiles,&(*pB).Files);
4005  }
4006  break;
4007 
4008  }
4009 
4010  if (((*pB).OpenFolder != 0) && ((*pB).OpenFolder == (*pB).ItemPointer))
4011  {
4012  if (cUiGetShortPress(BACK_BUTTON))
4013  {
4014  // Close folder
4015  #ifdef DEBUG
4016  printf("Close folder %3d\r\n",(*pB).OpenFolder);
4017  #endif
4018 
4019  cMemoryCloseFolder((*pB).PrgId,&(*pB).hFiles);
4020  if ((*pB).ItemPointer > (*pB).OpenFolder)
4021  {
4022  (*pB).ItemPointer -= (*pB).Files;
4023  }
4024  (*pB).OpenFolder = 0;
4025  (*pB).Files = 0;
4026  }
4027  }
4028 
4029 #ifndef DISABLE_SDCARD_SUPPORT
4030  if ((*pB).Sdcard == 1)
4031  {
4032  if ((*pB).OpenFolder == 0)
4033  {
4034  if (cUiGetShortPress(BACK_BUTTON))
4035  {
4036  // Collapse sdcard
4037  #ifdef DEBUG
4038  printf("Collapse sdcard\r\n");
4039  #endif
4040  if ((*pB).hFiles)
4041  {
4042  cMemoryCloseFolder((*pB).PrgId,&(*pB).hFiles);
4043  }
4044  if ((*pB).hFolders)
4045  {
4046  cMemoryCloseFolder((*pB).PrgId,&(*pB).hFolders);
4047  }
4048  (*pB).PrgId = 0;
4049  (*pB).ObjId = 0;
4050  strcpy((char*)pAnswer,vmPRJS_DIR);
4051  *pType = 0;
4052  (*pB).SubFolder[0] = 0;
4053  }
4054  }
4055  }
4056 #endif
4057 #ifndef DISABLE_USBSTICK_SUPPORT
4058  if ((*pB).Usbstick == 1)
4059  {
4060  if ((*pB).OpenFolder == 0)
4061  {
4062  if (cUiGetShortPress(BACK_BUTTON))
4063  {
4064  // Collapse usbstick
4065  #ifdef DEBUG
4066  printf("Collapse usbstick\r\n");
4067  #endif
4068  if ((*pB).hFiles)
4069  {
4070  cMemoryCloseFolder((*pB).PrgId,&(*pB).hFiles);
4071  }
4072  if ((*pB).hFolders)
4073  {
4074  cMemoryCloseFolder((*pB).PrgId,&(*pB).hFolders);
4075  }
4076  (*pB).PrgId = 0;
4077  (*pB).ObjId = 0;
4078  strcpy((char*)pAnswer,vmPRJS_DIR);
4079  *pType = 0;
4080  (*pB).SubFolder[0] = 0;
4081  }
4082  }
4083  }
4084 #endif
4085  if ((*pB).OldFiles != ((*pB).Files + (*pB).Folders))
4086  {
4087  (*pB).OldFiles = ((*pB).Files + (*pB).Folders);
4088  (*pB).NeedUpdate = 1;
4089  }
4090 
4091  if (cUiGetShortPress(ENTER_BUTTON))
4092  {
4093  (*pB).OldFiles = 0;
4094  if ((*pB).OpenFolder)
4095  {
4096  if (((*pB).ItemPointer > (*pB).OpenFolder) && ((*pB).ItemPointer <= ((*pB).OpenFolder + (*pB).Files)))
4097  { // File selected
4098 
4099  Item = (*pB).ItemPointer - (*pB).OpenFolder;
4100  Result = cMemoryGetItem((*pB).PrgId,(*pB).hFiles,Item,Lng,(*pB).FullPath,pType);
4101 
4102  snprintf((char*)pAnswer,Lng,"%s",(char*)(*pB).FullPath);
4103 
4104 
4105 #ifdef DEBUG
4106  printf("Select file %3d\r\n",Item);
4107 #endif
4108  }
4109  else
4110  { // Folder selected
4111 
4112  if ((*pB).OpenFolder == (*pB).ItemPointer)
4113  { // Enter on open folder
4114 
4115  Item = (*pB).OpenFolder;
4116  Result = cMemoryGetItem((*pB).PrgId,(*pB).hFolders,Item,Lng,pAnswer,pType);
4117 #ifdef DEBUG
4118  printf("Select folder %3d\r\n",Item);
4119 #endif
4120  }
4121  else
4122  { // Close folder
4123 
4124 #ifdef DEBUG
4125  printf("Close folder %3d\r\n",(*pB).OpenFolder);
4126 #endif
4127 
4128  cMemoryCloseFolder((*pB).PrgId,&(*pB).hFiles);
4129  if ((*pB).ItemPointer > (*pB).OpenFolder)
4130  {
4131  (*pB).ItemPointer -= (*pB).Files;
4132  }
4133  (*pB).OpenFolder = 0;
4134  (*pB).Files = 0;
4135  }
4136  }
4137  }
4138  if ((*pB).OpenFolder == 0)
4139  { // Open folder
4140 
4141  switch (Type)
4142  {
4143  case BROWSE_FOLDERS :
4144  { // Folder
4145 
4146  Item = (*pB).ItemPointer;
4147  cMemoryGetItemName((*pB).PrgId,(*pB).hFolders,Item,MAX_FILENAME_SIZE,(*pB).Filename,pType,&Priority);
4148  Result = cMemoryGetItem((*pB).PrgId,(*pB).hFolders,Item,FOLDERNAME_SIZE + SUBFOLDERNAME_SIZE,(*pB).FullPath,pType);
4149 
4150  snprintf((char*)pAnswer,Lng,"%s/%s",(char*)(*pB).FullPath,(char*)(*pB).Filename);
4151  *pType = TYPE_BYTECODE;
4152 #ifdef DEBUG
4153  printf("Select folder %3d\r\n",Item);
4154 #endif
4155  }
4156  break;
4157 
4158  case BROWSE_FOLDS_FILES :
4159  { // Folder & File
4160 
4161  (*pB).OpenFolder = (*pB).ItemPointer;
4162  cMemoryGetItem((*pB).PrgId,(*pB).hFolders,(*pB).OpenFolder,FOLDERNAME_SIZE + SUBFOLDERNAME_SIZE,(*pB).SubFolder,&TmpType);
4163 #ifdef DEBUG
4164  printf("Open folder %3d (%s)\r\n",(*pB).OpenFolder,(*pB).SubFolder);
4165 #endif
4166  if (strcmp((char*)(*pB).SubFolder,SDCARD_FOLDER) == 0)
4167  {
4168  Item = (*pB).ItemPointer;
4169  cMemoryGetItemName((*pB).PrgId,(*pB).hFolders,Item,MAX_FILENAME_SIZE,(*pB).Filename,pType,&Priority);
4170  Result = cMemoryGetItem((*pB).PrgId,(*pB).hFolders,Item,FOLDERNAME_SIZE + SUBFOLDERNAME_SIZE,(*pB).FullPath,pType);
4171  *pType = TYPE_SDCARD;
4172 
4173  snprintf((char*)pAnswer,Lng,"%s",(char*)(*pB).FullPath);
4174  }
4175  else
4176  {
4177  if (strcmp((char*)(*pB).SubFolder,USBSTICK_FOLDER) == 0)
4178  {
4179  Item = (*pB).ItemPointer;
4180  cMemoryGetItemName((*pB).PrgId,(*pB).hFolders,Item,MAX_FILENAME_SIZE,(*pB).Filename,pType,&Priority);
4181  Result = cMemoryGetItem((*pB).PrgId,(*pB).hFolders,Item,FOLDERNAME_SIZE + SUBFOLDERNAME_SIZE,(*pB).FullPath,pType);
4182  *pType = TYPE_USBSTICK;
4183 
4184  snprintf((char*)pAnswer,Lng,"%s",(char*)(*pB).FullPath);
4185  }
4186  else
4187  {
4188  (*pB).ItemStart = (*pB).ItemPointer;
4189  Result = cMemoryOpenFolder(PrgId,FILETYPE_UNKNOWN,(*pB).SubFolder,&(*pB).hFiles);
4190 
4191  Result = BUSY;
4192  }
4193  }
4194  }
4195  break;
4196 
4197  case BROWSE_CACHE :
4198  { // Cache
4199 
4200  Item = (*pB).ItemPointer;
4201 
4202  *pType = cMemoryGetCacheName(Item,FOLDERNAME_SIZE + SUBFOLDERNAME_SIZE,(char*)(*pB).FullPath,(char*)(*pB).Filename);
4203  snprintf((char*)pAnswer,Lng,"%s",(char*)(*pB).FullPath);
4204  Result = OK;
4205 #ifdef DEBUG
4206  printf("Select folder %3d\r\n",Item);
4207 #endif
4208  }
4209  break;
4210 
4211  case BROWSE_FILES :
4212  { // File
4213 
4214  if (((*pB).ItemPointer > (*pB).OpenFolder) && ((*pB).ItemPointer <= ((*pB).OpenFolder + (*pB).Files)))
4215  { // File selected
4216 
4217  Item = (*pB).ItemPointer - (*pB).OpenFolder;
4218 
4219  Result = cMemoryGetItem((*pB).PrgId,(*pB).hFiles,Item,Lng,(*pB).FullPath,pType);
4220 
4221  snprintf((char*)pAnswer,Lng,"%s",(char*)(*pB).FullPath);
4222  Result = OK;
4223  #ifdef DEBUG
4224  printf("Select file %3d\r\n",Item);
4225  #endif
4226  }
4227  }
4228  break;
4229 
4230  }
4231  }
4232  (*pB).NeedUpdate = 1;
4233  }
4234 
4235  TotalItems = (*pB).Folders + (*pB).Files;
4236  if (TmpResult == OK)
4237  {
4238  if (TotalItems)
4239  {
4240  if ((*pB).ItemPointer > TotalItems)
4241  {
4242 
4243  (*pB).ItemPointer = TotalItems;
4244  (*pB).NeedUpdate = 1;
4245  }
4246  if ((*pB).ItemStart > (*pB).ItemPointer)
4247  {
4248  (*pB).ItemStart = (*pB).ItemPointer;
4249  (*pB).NeedUpdate = 1;
4250  }
4251  }
4252  else
4253  {
4254  (*pB).ItemStart = 1;
4255  (*pB).ItemPointer = 1;
4256  }
4257  }
4258 
4259  Tmp = cUiGetVert();
4260  if (Tmp != 0)
4261  { // up/down arrow pressed
4262 
4263  (*pB).NeedUpdate = 1;
4264 
4265  // Calculate item pointer
4266  (*pB).ItemPointer += Tmp;
4267  if ((*pB).ItemPointer < 1)
4268  {
4269  (*pB).ItemPointer = 1;
4270  (*pB).NeedUpdate = 0;
4271  }
4272  if ((*pB).ItemPointer > TotalItems)
4273  {
4274  (*pB).ItemPointer = TotalItems;
4275  (*pB).NeedUpdate = 0;
4276  }
4277  }
4278 
4279  // Calculate item start
4280  if ((*pB).ItemPointer < (*pB).ItemStart)
4281  {
4282  if ((*pB).ItemPointer > 0)
4283  {
4284  (*pB).ItemStart = (*pB).ItemPointer;
4285  }
4286  }
4287  if ((*pB).ItemPointer >= ((*pB).ItemStart + (*pB).Lines))
4288  {
4289  (*pB).ItemStart = (*pB).ItemPointer - (*pB).Lines;
4290  (*pB).ItemStart++;
4291  }
4292 
4293  if ((*pB).NeedUpdate)
4294  {
4295 //* UPDATE ***************************************************************************************************
4296  (*pB).NeedUpdate = 0;
4297 
4298 #ifdef DEBUG
4299 #ifndef DISABLE_SDCARD_SUPPORT
4300  if ((*pB).Sdcard)
4301  {
4302  printf("SDCARD\r\n");
4303  }
4304 #endif
4305 #ifndef DISABLE_USBSTICK_SUPPORT
4306  if ((*pB).Usbstick)
4307  {
4308  printf("USBSTICK\r\n");
4309  }
4310 #endif
4311  printf("Folders = %3d, OpenFolder = %3d, Files = %3d, ItemStart = %3d, ItemPointer = %3d, TotalItems = %3d\r\n\n",(*pB).Folders,(*pB).OpenFolder,(*pB).Files,(*pB).ItemStart,(*pB).ItemPointer,TotalItems);
4312 #endif
4313 
4314  // clear screen
4315  dLcdFillRect((*UiInstance.pLcd).Lcd,BG_COLOR,(*pB).ScreenStartX,(*pB).ScreenStartY,(*pB).ScreenWidth,(*pB).ScreenHeight);
4316 
4317  OldPriority = 0;
4318  for (Tmp = 0;Tmp < (*pB).Lines;Tmp++)
4319  {
4320  Item = Tmp + (*pB).ItemStart;
4321  Folder = 1;
4322  Priority = OldPriority;
4323 
4324  if (Item <= TotalItems)
4325  {
4326  if ((*pB).OpenFolder)
4327  {
4328  if ((Item > (*pB).OpenFolder) && (Item <= ((*pB).OpenFolder + (*pB).Files)))
4329  {
4330  Item -= (*pB).OpenFolder;
4331  Folder = 0;
4332  }
4333  else
4334  {
4335  if (Item > (*pB).OpenFolder)
4336  {
4337  Item -= (*pB).Files;
4338  }
4339  }
4340  }
4341 #ifdef DEBUG
4342  if ((*pB).ItemPointer == (Tmp + (*pB).ItemStart))
4343  {
4344  printf("> ");
4345  }
4346  else
4347  {
4348  printf(" ");
4349  }
4350 #endif
4351 
4352 //*** Graphics ***********************************************************************************************
4353 
4354  if (Folder)
4355  { // Show folder
4356 
4357  switch (Type)
4358  {
4359  case BROWSE_FOLDERS :
4360  {
4361  cMemoryGetItemName((*pB).PrgId,(*pB).hFolders,Item,(*pB).Chars,(*pB).Filename,&TmpType,&Priority);
4362  if (cMemoryGetItemIcon((*pB).PrgId,(*pB).hFolders,Item,&TmpHandle,&Image) == OK)
4363  {
4364  dLcdDrawBitmap((*UiInstance.pLcd).Lcd,Color,(*pB).IconStartX,(*pB).IconStartY + (Tmp * (*pB).LineHeight),(IP)Image);
4365  cMemoryCloseFile((*pB).PrgId,TmpHandle);
4366  }
4367  else
4368  {
4369  dLcdDrawPicture((*UiInstance.pLcd).Lcd,Color,(*pB).IconStartX,(*pB).IconStartY + (Tmp * (*pB).LineHeight),PCApp_width,PCApp_height,(UBYTE*)PCApp_bits);
4370  }
4371 
4372  (*pB).Text[0] = 0;
4373  if (strcmp((char*)(*pB).Filename,"Bluetooth") == 0)
4374  {
4375  if (UiInstance.BtOn)
4376  {
4377  (*pB).Text[0] = '+';
4378  }
4379  else
4380  {
4381  (*pB).Text[0] = '-';
4382  }
4383  }
4384  else
4385  {
4386  if (strcmp((char*)(*pB).Filename,"WiFi") == 0)
4387  {
4388  if (UiInstance.WiFiOn)
4389  {
4390  (*pB).Text[0] = '+';
4391  }
4392  else
4393  {
4394  (*pB).Text[0] = '-';
4395  }
4396  }
4397  else
4398  {
4399  if (cMemoryGetItemText((*pB).PrgId,(*pB).hFolders,Item,(*pB).Chars,(*pB).Text) != OK)
4400  {
4401  (*pB).Text[0] = 0;
4402  }
4403  }
4404  }
4405  switch ((*pB).Text[0])
4406  {
4407  case 0 :
4408  {
4409  }
4410  break;
4411 
4412  case '+' :
4413  {
4414  Indent = ((*pB).Chars - 1) * (*pB).CharWidth - dLcdGetIconWidth(MENU_ICON);
4415  dLcdDrawIcon((*UiInstance.pLcd).Lcd,Color,(*pB).TextStartX + Indent,((*pB).TextStartY - 2) + (Tmp * (*pB).LineHeight),MENU_ICON,ICON_CHECKED);
4416  }
4417  break;
4418 
4419  case '-' :
4420  {
4421  Indent = ((*pB).Chars - 1) * (*pB).CharWidth - dLcdGetIconWidth(MENU_ICON);
4422  dLcdDrawIcon((*UiInstance.pLcd).Lcd,Color,(*pB).TextStartX + Indent,((*pB).TextStartY - 2) + (Tmp * (*pB).LineHeight),MENU_ICON,ICON_CHECKBOX);
4423  }
4424  break;
4425 
4426  default :
4427  {
4428  Indent = (((*pB).Chars - 1) - (DATA16)strlen((char*)(*pB).Text)) * (*pB).CharWidth;
4429  dLcdDrawText((*UiInstance.pLcd).Lcd,Color,(*pB).TextStartX + Indent,(*pB).TextStartY + (Tmp * (*pB).LineHeight),NORMAL_FONT,(*pB).Text);
4430  }
4431  break;
4432 
4433  }
4434 
4435  }
4436  break;
4437 
4438  case BROWSE_FOLDS_FILES :
4439  {
4440  cMemoryGetItemName((*pB).PrgId,(*pB).hFolders,Item,(*pB).Chars,(*pB).Filename,&TmpType,&Priority);
4441  dLcdDrawIcon((*UiInstance.pLcd).Lcd,Color,(*pB).IconStartX,(*pB).IconStartY + (Tmp * (*pB).LineHeight),NORMAL_ICON,FiletypeToNormalIcon[TmpType]);
4442 
4443  if ((Priority == 1) || (Priority == 2))
4444  {
4445  dLcdDrawIcon((*UiInstance.pLcd).Lcd,Color,(*pB).IconStartX,(*pB).IconStartY + (Tmp * (*pB).LineHeight),NORMAL_ICON,ICON_FOLDER2);
4446  }
4447  else
4448  {
4449  if (Priority == 3)
4450  {
4451  dLcdDrawIcon((*UiInstance.pLcd).Lcd,Color,(*pB).IconStartX,(*pB).IconStartY + (Tmp * (*pB).LineHeight),NORMAL_ICON,ICON_SD);
4452  }
4453  else
4454  {
4455  if (Priority == 4)
4456  {
4457  dLcdDrawIcon((*UiInstance.pLcd).Lcd,Color,(*pB).IconStartX,(*pB).IconStartY + (Tmp * (*pB).LineHeight),NORMAL_ICON,ICON_USB);
4458  }
4459  else
4460  {
4461  dLcdDrawIcon((*UiInstance.pLcd).Lcd,Color,(*pB).IconStartX,(*pB).IconStartY + (Tmp * (*pB).LineHeight),NORMAL_ICON,FiletypeToNormalIcon[TmpType]);
4462  }
4463  }
4464  }
4465  if (Priority != OldPriority)
4466  {
4467  if ((Priority == 1) || (Priority >= 3))
4468  {
4469  if (Tmp)
4470  {
4471  dLcdDrawDotLine((*UiInstance.pLcd).Lcd,Color,(*pB).SelectStartX,(*pB).SelectStartY + ((Tmp - 1) * (*pB).LineHeight) + (*pB).LineHeight - 2,(*pB).SelectStartX + (*pB).SelectWidth,(*pB).SelectStartY + ((Tmp - 1) * (*pB).LineHeight) + (*pB).LineHeight - 2,1,2);
4472  }
4473  }
4474  }
4475  }
4476  break;
4477 
4478  case BROWSE_CACHE :
4479  {
4480  TmpType = cMemoryGetCacheName(Item,(*pB).Chars,(char*)(*pB).FullPath,(char*)(*pB).Filename);
4481  dLcdDrawIcon((*UiInstance.pLcd).Lcd,Color,(*pB).IconStartX,(*pB).IconStartY + (Tmp * (*pB).LineHeight),NORMAL_ICON,FiletypeToNormalIcon[TmpType]);
4482  }
4483  break;
4484 
4485  case BROWSE_FILES :
4486  {
4487  cMemoryGetItemName((*pB).PrgId,(*pB).hFiles,Item,(*pB).Chars,(*pB).Filename,&TmpType,&Priority);
4488  dLcdDrawIcon((*UiInstance.pLcd).Lcd,Color,(*pB).IconStartX,(*pB).IconStartY + (Tmp * (*pB).LineHeight),NORMAL_ICON,FiletypeToNormalIcon[TmpType]);
4489  }
4490  break;
4491 
4492  }
4493  // Draw folder name
4494  dLcdDrawText((*UiInstance.pLcd).Lcd,Color,(*pB).TextStartX,(*pB).TextStartY + (Tmp * (*pB).LineHeight),NORMAL_FONT,(*pB).Filename);
4495 
4496  // Draw open folder
4497  if (Item == (*pB).OpenFolder)
4498  {
4499  dLcdDrawIcon((*UiInstance.pLcd).Lcd,Color,144,(*pB).IconStartY + (Tmp * (*pB).LineHeight),NORMAL_ICON,ICON_OPENFOLDER);
4500  }
4501 
4502  // Draw selection
4503  if ((*pB).ItemPointer == (Tmp + (*pB).ItemStart))
4504  {
4505  dLcdInverseRect((*UiInstance.pLcd).Lcd,(*pB).SelectStartX,(*pB).SelectStartY + (Tmp * (*pB).LineHeight),(*pB).SelectWidth + 1,(*pB).SelectHeight);
4506  }
4507 
4508  // Draw end line
4509  switch (Type)
4510  {
4511  case BROWSE_FOLDERS :
4512  case BROWSE_FOLDS_FILES :
4513  case BROWSE_FILES :
4514  {
4515  if (((Tmp + (*pB).ItemStart) == TotalItems) && (Tmp < ((*pB).Lines - 1)))
4516  {
4517  dLcdDrawDotLine((*UiInstance.pLcd).Lcd,Color,(*pB).SelectStartX,(*pB).SelectStartY + (Tmp * (*pB).LineHeight) + (*pB).LineHeight - 2,(*pB).SelectStartX + (*pB).SelectWidth,(*pB).SelectStartY + (Tmp * (*pB).LineHeight) + (*pB).LineHeight - 2,1,2);
4518  }
4519  }
4520  break;
4521 
4522  case BROWSE_CACHE :
4523  {
4524  if (((Tmp + (*pB).ItemStart) == 1) && (Tmp < ((*pB).Lines - 1)))
4525  {
4526  dLcdDrawDotLine((*UiInstance.pLcd).Lcd,Color,(*pB).SelectStartX,(*pB).SelectStartY + (Tmp * (*pB).LineHeight) + (*pB).LineHeight - 2,(*pB).SelectStartX + (*pB).SelectWidth,(*pB).SelectStartY + (Tmp * (*pB).LineHeight) + (*pB).LineHeight - 2,1,2);
4527  }
4528  if (((Tmp + (*pB).ItemStart) == TotalItems) && (Tmp < ((*pB).Lines - 1)))
4529  {
4530  dLcdDrawDotLine((*UiInstance.pLcd).Lcd,Color,(*pB).SelectStartX,(*pB).SelectStartY + (Tmp * (*pB).LineHeight) + (*pB).LineHeight - 2,(*pB).SelectStartX + (*pB).SelectWidth,(*pB).SelectStartY + (Tmp * (*pB).LineHeight) + (*pB).LineHeight - 2,1,2);
4531  }
4532  }
4533  break;
4534 
4535  }
4536 
4537 #ifdef DEBUG
4538  printf("%s %d %d %d\r\n",(char*)(*pB).Filename,Item,(*pB).OpenFolder,Priority);
4539 #endif
4540  }
4541  else
4542  { // Show file
4543 
4544  // Get file name and type
4545  cMemoryGetItemName((*pB).PrgId,(*pB).hFiles,Item,(*pB).Chars - 1,(*pB).Filename,&TmpType,&Priority);
4546 
4547  // show File icons
4548  dLcdDrawIcon((*UiInstance.pLcd).Lcd,Color,(*pB).IconStartX + (*pB).CharWidth,(*pB).IconStartY + (Tmp * (*pB).LineHeight),NORMAL_ICON,FiletypeToNormalIcon[TmpType]);
4549 
4550  // Draw file name
4551  dLcdDrawText((*UiInstance.pLcd).Lcd,Color,(*pB).TextStartX + (*pB).CharWidth,(*pB).TextStartY + (Tmp * (*pB).LineHeight),NORMAL_FONT,(*pB).Filename);
4552 
4553  // Draw folder line
4554  if ((Tmp == ((*pB).Lines - 1)) || (Item == (*pB).Files))
4555  {
4556  dLcdDrawLine((*UiInstance.pLcd).Lcd,Color,(*pB).IconStartX + (*pB).CharWidth - 3,(*pB).SelectStartY + (Tmp * (*pB).LineHeight),(*pB).IconStartX + (*pB).CharWidth - 3,(*pB).SelectStartY + (Tmp * (*pB).LineHeight) + (*pB).SelectHeight - 1);
4557  }
4558  else
4559  {
4560  dLcdDrawLine((*UiInstance.pLcd).Lcd,Color,(*pB).IconStartX + (*pB).CharWidth - 3,(*pB).SelectStartY + (Tmp * (*pB).LineHeight),(*pB).IconStartX + (*pB).CharWidth - 3,(*pB).SelectStartY + (Tmp * (*pB).LineHeight) + (*pB).LineHeight - 1);
4561  }
4562 
4563  // Draw selection
4564  if ((*pB).ItemPointer == (Tmp + (*pB).ItemStart))
4565  {
4566  dLcdInverseRect((*UiInstance.pLcd).Lcd,(*pB).SelectStartX + (*pB).CharWidth,(*pB).SelectStartY + (Tmp * (*pB).LineHeight),(*pB).SelectWidth + 1 - (*pB).CharWidth,(*pB).SelectHeight);
4567  }
4568 
4569 #ifdef DEBUG
4570  printf(" | %s\r\n",(char*)(*pB).Filename);
4571 #endif
4572 
4573  }
4574 
4575 //************************************************************************************************************
4576  }
4577 #ifdef DEBUG
4578  else
4579  {
4580  printf("\r\n");
4581  }
4582 #endif
4583  OldPriority = Priority;
4584  }
4585 #ifdef DEBUG
4586  printf("\r\n");
4587 #endif
4588 
4589  cUiDrawBar(1,(*pB).ScrollStartX,(*pB).ScrollStartY,(*pB).ScrollWidth,(*pB).ScrollHeight,0,TotalItems,(*pB).ItemPointer);
4590 
4591  // Update
4592  cUiUpdateLcd();
4593  UiInstance.ScreenBusy = 0;
4594  }
4595 
4596  if (Result != OK)
4597  {
4598  Tmp = cUiTestHorz();
4599  if (Ignore == Tmp)
4600  {
4601  Tmp = cUiGetHorz();
4602  Tmp = 0;
4603  }
4604 
4605  if ((Tmp != 0) || (cUiTestShortPress(BACK_BUTTON)) || (cUiTestLongPress(BACK_BUTTON)))
4606  {
4607  if (Type != BROWSE_CACHE)
4608  {
4609  if ((*pB).OpenFolder)
4610  {
4611  if ((*pB).hFiles)
4612  {
4613  cMemoryCloseFolder((*pB).PrgId,&(*pB).hFiles);
4614  }
4615  }
4616  if ((*pB).hFolders)
4617  {
4618  cMemoryCloseFolder((*pB).PrgId,&(*pB).hFolders);
4619  }
4620  }
4621  (*pB).PrgId = 0;
4622  (*pB).ObjId = 0;
4623  (*pB).SubFolder[0] = 0;
4624  pAnswer[0] = 0;
4625  *pType = 0;
4626 
4627  #ifdef DEBUG
4628  printf("%d %d Closing browser with [%s] type [%d]\r\n",PrgId,ObjId,(char*)pAnswer,*pType);
4629  #endif
4630  Result = OK;
4631  }
4632  }
4633  else
4634  {
4635  (*pB).NeedUpdate = 1;
4636  }
4637  }
4638  else
4639  {
4640  pAnswer[0] = 0;
4641  *pType = TYPE_RESTART_BROWSER;
4642  Result = FAIL;
4643  }
4644 
4645  if (*pType > 0)
4646  {
4647 #ifndef DISABLE_SDCARD_SUPPORT
4648  if ((*pB).Sdcard)
4649  {
4650  *pType |= TYPE_SDCARD;
4651  }
4652 #endif
4653 #ifndef DISABLE_USBSTICK_SUPPORT
4654  if ((*pB).Usbstick)
4655  {
4656  *pType |= TYPE_USBSTICK;
4657  }
4658 #endif
4659  }
4660 
4661  if (Result != BUSY)
4662  {
4663 //* EXIT *****************************************************************************************************
4664 
4665 #ifdef DEBUG
4666  printf("%d %d Return from browser with [%s] type [0x%02X]\r\n\n",PrgId,ObjId,(char*)pAnswer,*pType);
4667 #endif
4668  }
4669 
4670  return (Result);
4671 }
4672 
4673 
4674 static char Delimiter[][3] =
4675 {
4676  [DEL_NONE] = "",
4677  [DEL_TAB] = "\t",
4678  [DEL_SPACE] = " ",
4679  [DEL_RETURN] = "\r",
4680  [DEL_COLON] = ":",
4681  [DEL_COMMA] = ",",
4682  [DEL_LINEFEED] = "\n",
4683  [DEL_CRLF] = "\r\n",
4684 };
4685 
4686 
4688 {
4689  DATA32 Point = 0;
4690  DATA16 Lines = 0;
4691  DATA8 DelPoi;
4692 
4693  if (Del < DELS)
4694  {
4695  while (pText[Point] && (Point < Size))
4696  {
4697  DelPoi = 0;
4698  while ((pText[Point]) && (Point < Size) && (Delimiter[Del][DelPoi]) && (pText[Point] == Delimiter[Del][DelPoi]))
4699  {
4700  DelPoi++;
4701  Point++;
4702  }
4703  if (Delimiter[Del][DelPoi] == 0)
4704  {
4705  Lines++;
4706  }
4707  else
4708  {
4709  if ((pText[Point]) && (Point < Size))
4710  {
4711  Point++;
4712  }
4713  }
4714  }
4715  }
4716 
4717  return (Lines);
4718 }
4719 
4720 
4721 void cUiTextboxAppendLine(DATA8 *pText,DATA32 Size,DATA8 Del,DATA8 *pLine,DATA8 Font)
4722 {
4723  DATA32 Point = 0;
4724  DATA8 DelPoi = 0;
4725 
4726  if (Del < DELS)
4727  {
4728  while ((pText[Point]) && (Point < Size))
4729  {
4730  Point++;
4731  }
4732  if ((Point < Size) && (Font))
4733  {
4734  pText[Point] = Font;
4735  Point++;
4736  }
4737 
4738  while ((Point < Size) && (*pLine))
4739  {
4740  pText[Point] = *pLine;
4741  Point++;
4742  pLine++;
4743  }
4744  while ((Point < Size) && (Delimiter[Del][DelPoi]))
4745  {
4746  pText[Point] = Delimiter[Del][DelPoi];
4747  Point++;
4748  DelPoi++;
4749  }
4750  }
4751 }
4752 
4753 
4755 {
4756  DATA32 Result = -1;
4757  DATA32 Point = 0;
4758  DATA8 DelPoi = 0;
4759 
4760  *pFont = 0;
4761  if (Del < DELS)
4762  {
4763  Result = Point;
4764  while ((Line) && (pText[Point]) && (Point < Size))
4765  {
4766 
4767  DelPoi = 0;
4768  while ((pText[Point]) && (Point < Size) && (Delimiter[Del][DelPoi]) && (pText[Point] == Delimiter[Del][DelPoi]))
4769  {
4770  DelPoi++;
4771  Point++;
4772  }
4773  if (Delimiter[Del][DelPoi] == 0)
4774  {
4775  Line--;
4776  if (Line)
4777  {
4778  Result = Point;
4779  }
4780  }
4781  else
4782  {
4783  if ((pText[Point]) && (Point < Size))
4784  {
4785  Point++;
4786  }
4787  }
4788  }
4789  if (Line != 0)
4790  {
4791  Result = -1;
4792  }
4793  if (Result >= 0)
4794  {
4795  if ((pText[Result] > 0) && (pText[Result] < FONTTYPES))
4796  {
4797  *pFont = pText[Result];
4798  Result++;
4799  }
4800  }
4801  }
4802 
4803  return (Result);
4804 }
4805 
4806 void cUiTextboxReadLine(DATA8 *pText,DATA32 Size,DATA8 Del,DATA8 Lng,DATA16 Line,DATA8 *pLine,DATA8 *pFont)
4807 {
4808  DATA32 Start;
4809  DATA32 Point = 0;
4810  DATA8 DelPoi = 0;
4811  DATA8 Run = 1;
4812 
4813  Start = cUiTextboxFindLine(pText,Size,Del,Line,pFont);
4814  Point = Start;
4815 
4816  pLine[0] = 0;
4817 
4818  if (Point >= 0)
4819  {
4820  while ((Run) && (pText[Point]) && (Point < Size))
4821  {
4822  DelPoi = 0;
4823  while ((pText[Point]) && (Point < Size) && (Delimiter[Del][DelPoi]) && (pText[Point] == Delimiter[Del][DelPoi]))
4824  {
4825  DelPoi++;
4826  Point++;
4827  }
4828  if (Delimiter[Del][DelPoi] == 0)
4829  {
4830  Run = 0;
4831  }
4832  else
4833  {
4834  if ((pText[Point]) && (Point < Size))
4835  {
4836  Point++;
4837  }
4838  }
4839  }
4840  Point -= (DATA32)DelPoi;
4841 
4842  if (((Point - Start) + 1) < (DATA32)Lng)
4843  {
4844  Lng = (DATA8)(Point - Start) + 1;
4845  }
4846  snprintf((char*)pLine,Lng,"%s",(char*)&pText[Start]);
4847  }
4848 }
4849 
4850 
4851 RESULT cUiTextbox(DATA16 X,DATA16 Y,DATA16 X1,DATA16 Y1,DATA8 *pText,DATA32 Size,DATA8 Del,DATA16 *pLine)
4852 {
4853  RESULT Result = BUSY;
4854  TXTBOX *pB;
4855  DATA16 Item;
4856  DATA16 TotalItems;
4857  DATA16 Tmp;
4858  DATA16 Ypos;
4859  DATA8 Color;
4860 
4861  pB = &UiInstance.Txtbox;
4862  Color = FG_COLOR;
4863 
4864  if (*pLine < 0)
4865  {
4866 //* INIT *****************************************************************************************************
4867  // Define screen
4868  (*pB).ScreenStartX = X;
4869  (*pB).ScreenStartY = Y;
4870  (*pB).ScreenWidth = X1;
4871  (*pB).ScreenHeight = Y1;
4872 
4873  (*pB).Font = UiInstance.Font;
4874 
4875  // calculate chars and lines on screen
4876  (*pB).CharWidth = dLcdGetFontWidth((*pB).Font);
4877  (*pB).CharHeight = dLcdGetFontHeight((*pB).Font);
4878  (*pB).Chars = ((*pB).ScreenWidth / (*pB).CharWidth);
4879 
4880  // calculate lines on screen
4881  (*pB).LineSpace = 5;
4882  (*pB).LineHeight = (*pB).CharHeight + (*pB).LineSpace;
4883  (*pB).Lines = ((*pB).ScreenHeight / (*pB).LineHeight);
4884 
4885  // calculate start of text
4886  (*pB).TextStartX = cUiAlignX((*pB).ScreenStartX);
4887  (*pB).TextStartY = (*pB).ScreenStartY + ((*pB).LineHeight - (*pB).CharHeight) / 2;
4888 
4889  // Calculate selection barBrowser
4890  (*pB).SelectStartX = (*pB).ScreenStartX;
4891  (*pB).SelectWidth = (*pB).ScreenWidth - ((*pB).CharWidth + 5);
4892  (*pB).SelectStartY = (*pB).TextStartY - 1;
4893  (*pB).SelectHeight = (*pB).CharHeight + 1;
4894 
4895  // Calculate scroll bar
4896  (*pB).ScrollWidth = 5;
4897  (*pB).NobHeight = 7;
4898  (*pB).ScrollStartX = (*pB).ScreenStartX + (*pB).ScreenWidth - (*pB).ScrollWidth;
4899  (*pB).ScrollStartY = (*pB).ScreenStartY + 1;
4900  (*pB).ScrollHeight = (*pB).ScreenHeight - 2;
4901  (*pB).ScrollSpan = (*pB).ScrollHeight - (*pB).NobHeight;
4902 
4903  (*pB).Items = cUiTextboxGetLines(pText,Size,Del);
4904  (*pB).ItemStart = 1;
4905  (*pB).ItemPointer = 1;
4906 
4907  (*pB).NeedUpdate = 1;
4908 
4909  *pLine = 0;
4910  }
4911 
4912  TotalItems = (*pB).Items;
4913 
4914  Tmp = cUiGetVert();
4915  if (Tmp != 0)
4916  { // up/down arrow pressed
4917 
4918  (*pB).NeedUpdate = 1;
4919 
4920  // Calculate item pointer
4921  (*pB).ItemPointer += Tmp;
4922  if ((*pB).ItemPointer < 1)
4923  {
4924  (*pB).ItemPointer = 1;
4925  (*pB).NeedUpdate = 0;
4926  }
4927  if ((*pB).ItemPointer > TotalItems)
4928  {
4929  (*pB).ItemPointer = TotalItems;
4930  (*pB).NeedUpdate = 0;
4931  }
4932  }
4933 
4934  // Calculate item start
4935  if ((*pB).ItemPointer < (*pB).ItemStart)
4936  {
4937  if ((*pB).ItemPointer > 0)
4938  {
4939  (*pB).ItemStart = (*pB).ItemPointer;
4940  }
4941  }
4942  if ((*pB).ItemPointer >= ((*pB).ItemStart + (*pB).Lines))
4943  {
4944  (*pB).ItemStart = (*pB).ItemPointer - (*pB).Lines;
4945  (*pB).ItemStart++;
4946  }
4947 
4948  if (cUiGetShortPress(ENTER_BUTTON))
4949  {
4950  *pLine = (*pB).ItemPointer;
4951 
4952  Result = OK;
4953  }
4954  if (cUiGetShortPress(BACK_BUTTON))
4955  {
4956  *pLine = -1;
4957 
4958  Result = OK;
4959  }
4960 
4961 
4962  if ((*pB).NeedUpdate)
4963  {
4964 //* UPDATE ***************************************************************************************************
4965  (*pB).NeedUpdate = 0;
4966 
4967  // clear screen
4968  dLcdFillRect((*UiInstance.pLcd).Lcd,BG_COLOR,(*pB).ScreenStartX,(*pB).ScreenStartY,(*pB).ScreenWidth,(*pB).ScreenHeight);
4969 
4970  Ypos = (*pB).TextStartY + 2;
4971 
4972  for (Tmp = 0;Tmp < (*pB).Lines;Tmp++)
4973  {
4974  Item = Tmp + (*pB).ItemStart;
4975 
4976  if (Item <= TotalItems)
4977  {
4978  cUiTextboxReadLine(pText,Size,Del,TEXTSIZE,Item,(*pB).Text,&(*pB).Font);
4979 
4980  // calculate chars and lines on screen
4981  (*pB).CharWidth = dLcdGetFontWidth((*pB).Font);
4982  (*pB).CharHeight = dLcdGetFontHeight((*pB).Font);
4983 
4984  // calculate lines on screen
4985  (*pB).LineSpace = 2;
4986  (*pB).LineHeight = (*pB).CharHeight + (*pB).LineSpace;
4987  (*pB).Lines = ((*pB).ScreenHeight / (*pB).LineHeight);
4988 
4989  // Calculate selection barBrowser
4990  (*pB).SelectStartX = (*pB).ScreenStartX;
4991  (*pB).SelectWidth = (*pB).ScreenWidth - ((*pB).ScrollWidth + 2);
4992  (*pB).SelectStartY = (*pB).TextStartY - 1;
4993  (*pB).SelectHeight = (*pB).CharHeight + 1;
4994 
4995  (*pB).Chars = ((*pB).SelectWidth / (*pB).CharWidth);
4996 
4997  (*pB).Text[(*pB).Chars] = 0;
4998 
4999  if ((Ypos + (*pB).LineHeight) <= ((*pB).ScreenStartY + (*pB).ScreenHeight))
5000  {
5001  dLcdDrawText((*UiInstance.pLcd).Lcd,Color,(*pB).TextStartX,Ypos,(*pB).Font,(*pB).Text);
5002  }
5003  else
5004  {
5005  Tmp = (*pB).Lines;
5006  }
5007  }
5008 
5009  cUiDrawBar(1,(*pB).ScrollStartX,(*pB).ScrollStartY,(*pB).ScrollWidth,(*pB).ScrollHeight,0,TotalItems,(*pB).ItemPointer);
5010 
5011  if ((Ypos + (*pB).LineHeight) <= ((*pB).ScreenStartY + (*pB).ScreenHeight))
5012  {
5013  // Draw selection
5014  if ((*pB).ItemPointer == (Tmp + (*pB).ItemStart))
5015  {
5016  dLcdInverseRect((*UiInstance.pLcd).Lcd,(*pB).SelectStartX,Ypos - 1,(*pB).SelectWidth,(*pB).LineHeight);
5017  }
5018  }
5019  Ypos += (*pB).LineHeight;
5020  }
5021 
5022  // Update
5023  cUiUpdateLcd();
5024  UiInstance.ScreenBusy = 0;
5025  }
5026 
5027  return(Result);
5028 }
5029 
5030 
5031 void cUiGraphSetup(DATA16 StartX,DATA16 SizeX,DATA8 Items,DATA16 *pOffset,DATA16 *pSpan,DATAF *pMin,DATAF *pMax,DATAF *pVal)
5032 {
5033  DATA16 Item;
5034  DATA16 Pointer;
5035 
5036  UiInstance.Graph.Initialized = 0;
5037 
5038  UiInstance.Graph.pOffset = pOffset;
5039  UiInstance.Graph.pSpan = pSpan;
5040  UiInstance.Graph.pMin = pMin;
5041  UiInstance.Graph.pMax = pMax;
5042  UiInstance.Graph.pVal = pVal;
5043 
5044  if (Items < 0)
5045  {
5046  Items = 0;
5047  }
5048  if (Items > GRAPH_BUFFERS)
5049  {
5050  Items = GRAPH_BUFFERS;
5051  }
5052 
5053 
5054  UiInstance.Graph.GraphStartX = StartX;
5055  UiInstance.Graph.GraphSizeX = SizeX;
5056  UiInstance.Graph.Items = Items;
5057  UiInstance.Graph.Pointer = 0;
5058 
5059  for (Item = 0;Item < UiInstance.Graph.Items;Item++)
5060  {
5061  for (Pointer = 0;Pointer < UiInstance.Graph.GraphSizeX;Pointer++)
5062  {
5063  UiInstance.Graph.Buffer[Item][Pointer] = DATAF_NAN;
5064  }
5065  }
5066 
5067  UiInstance.Graph.Initialized = 1;
5068 
5069  // Simulate graph
5070  UiInstance.Graph.Value = UiInstance.Graph.pMin[0];
5071  UiInstance.Graph.Down = 0;
5072  UiInstance.Graph.Inc = (UiInstance.Graph.pMax[0] - UiInstance.Graph.pMin[0]) / (DATAF)20;
5073 }
5074 
5075 
5076 void cUiGraphSample(void)
5077 {
5078  DATAF Sample;
5079  DATA16 Item;
5080  DATA16 Pointer;
5081 
5082  if (UiInstance.Graph.Initialized)
5083  { // Only if initialized
5084 
5085  if (UiInstance.Graph.Pointer < UiInstance.Graph.GraphSizeX)
5086  {
5087  for (Item = 0;Item < (UiInstance.Graph.Items);Item++)
5088  {
5089  // Insert sample
5090  Sample = UiInstance.Graph.pVal[Item];
5091 
5092  if (!(isnan(Sample)))
5093  {
5094  UiInstance.Graph.Buffer[Item][UiInstance.Graph.Pointer] = Sample;
5095  }
5096  else
5097  {
5098  UiInstance.Graph.Buffer[Item][UiInstance.Graph.Pointer] = DATAF_NAN;
5099  }
5100  }
5101  UiInstance.Graph.Pointer++;
5102  }
5103  else
5104  {
5105  // Scroll buffers
5106  for (Item = 0;Item < (UiInstance.Graph.Items);Item++)
5107  {
5108  for (Pointer = 0;Pointer < (UiInstance.Graph.GraphSizeX - 1);Pointer++)
5109  {
5110  UiInstance.Graph.Buffer[Item][Pointer] = UiInstance.Graph.Buffer[Item][Pointer + 1];
5111  }
5112 
5113  // Insert sample
5114  Sample = UiInstance.Graph.pVal[Item];
5115 
5116  if (!(isnan(Sample)))
5117  {
5118  UiInstance.Graph.Buffer[Item][Pointer] = Sample;
5119  }
5120  else
5121  {
5122  UiInstance.Graph.Buffer[Item][Pointer] = DATAF_NAN;
5123  }
5124  }
5125  }
5126  }
5127 }
5128 
5129 
5130 void cUiGraphDraw(DATA8 View,DATAF *pActual,DATAF *pLowest,DATAF *pHighest,DATAF *pAverage)
5131 {
5132  DATAF Sample;
5133  DATA8 Samples;
5134  DATA16 Value;
5135  DATA16 Item;
5136  DATA16 Pointer;
5137  DATA16 X;
5138  DATA16 Y1;
5139  DATA16 Y2;
5140  DATA8 Color = 1;
5141 
5142  *pActual = DATAF_NAN;
5143  *pLowest = DATAF_NAN;
5144  *pHighest = DATAF_NAN;
5145  *pAverage = DATAF_NAN;
5146  Samples = 0;
5147 
5148  if (UiInstance.Graph.Initialized)
5149  { // Only if initialized
5150 
5151  if (UiInstance.ScreenBlocked == 0)
5152  {
5153 
5154  // View or all
5155  if ((View >= 0) && (View < UiInstance.Graph.Items))
5156  {
5157  Item = View;
5158 
5159  Y1 = (UiInstance.Graph.pOffset[Item] + UiInstance.Graph.pSpan[Item]);
5160 
5161  // Draw buffers
5162  X = UiInstance.Graph.GraphStartX;
5163  for (Pointer = 0;Pointer < UiInstance.Graph.Pointer;Pointer++)
5164  {
5165  Sample = UiInstance.Graph.Buffer[Item][Pointer];
5166  if (!(isnan(Sample)))
5167  {
5168  *pActual = Sample;
5169  if (isnan(*pAverage))
5170  {
5171  *pAverage = (DATAF)0;
5172  *pLowest = *pActual;
5173  *pHighest = *pActual;
5174  }
5175  else
5176  {
5177  if (*pActual < *pLowest)
5178  {
5179  *pLowest = *pActual;
5180  }
5181  if (*pActual > *pHighest)
5182  {
5183  *pHighest = *pActual;
5184  }
5185  }
5186  *pAverage += *pActual;
5187  Samples++;
5188 
5189  // Scale Y axis
5190  Value = (DATA16)((((Sample - UiInstance.Graph.pMin[Item]) * (DATAF)UiInstance.Graph.pSpan[Item]) / (UiInstance.Graph.pMax[Item] - UiInstance.Graph.pMin[Item])));
5191 
5192  // Limit Y axis
5193  if (Value > UiInstance.Graph.pSpan[Item])
5194  {
5195  Value = UiInstance.Graph.pSpan[Item];
5196  }
5197  if (Value < 0)
5198  {
5199  Value = 0;
5200  }
5201 /*
5202  printf("S=%-3d V=%3.0f L=%3.0f H=%3.0f A=%3.0f v=%3.0f ^=%3.0f O=%3d S=%3d Y=%d\r\n",Samples,*pActual,*pLowest,*pHighest,*pAverage,UiInstance.Graph.pMin[Item],UiInstance.Graph.pMax[Item],UiInstance.Graph.pOffset[Item],UiInstance.Graph.pSpan[Item],Value);
5203 */
5204  Y2 = (UiInstance.Graph.pOffset[Item] + UiInstance.Graph.pSpan[Item]) - Value;
5205  if (Pointer > 1)
5206  {
5207  if (Y2 > Y1)
5208  {
5209  dLcdDrawLine((*UiInstance.pLcd).Lcd,Color,X - 2,Y1 - 1,X - 1,Y2 - 1);
5210  dLcdDrawLine((*UiInstance.pLcd).Lcd,Color,X,Y1 + 1,X + 1,Y2 + 1);
5211  }
5212  else
5213  {
5214  if (Y2 < Y1)
5215  {
5216  dLcdDrawLine((*UiInstance.pLcd).Lcd,Color,X,Y1 - 1,X + 1,Y2 - 1);
5217  dLcdDrawLine((*UiInstance.pLcd).Lcd,Color,X - 2,Y1 + 1,X - 1,Y2 + 1);
5218  }
5219  else
5220  {
5221  dLcdDrawLine((*UiInstance.pLcd).Lcd,Color,X - 1,Y1 - 1,X,Y2 - 1);
5222  dLcdDrawLine((*UiInstance.pLcd).Lcd,Color,X - 1,Y1 + 1,X,Y2 + 1);
5223  }
5224  }
5225  dLcdDrawLine((*UiInstance.pLcd).Lcd,Color,X - 1,Y1,X,Y2);
5226  }
5227  else
5228  {
5229  dLcdDrawPixel((*UiInstance.pLcd).Lcd,Color,X,Y2);
5230  }
5231 
5232  Y1 = Y2;
5233  }
5234  X++;
5235  }
5236  if (Samples != 0)
5237  {
5238  *pAverage = *pAverage / (DATAF)Samples;
5239  }
5240 
5241  }
5242  else
5243  {
5244  // Draw buffers
5245  for (Item = 0;Item < UiInstance.Graph.Items;Item++)
5246  {
5247  Y1 = (UiInstance.Graph.pOffset[Item] + UiInstance.Graph.pSpan[Item]);
5248 
5249  X = UiInstance.Graph.GraphStartX + 1;
5250  for (Pointer = 0;Pointer < UiInstance.Graph.Pointer;Pointer++)
5251  {
5252  Sample = UiInstance.Graph.Buffer[Item][Pointer];
5253 
5254  // Scale Y axis
5255  Value = (DATA16)((((Sample - UiInstance.Graph.pMin[Item]) * (DATAF)UiInstance.Graph.pSpan[Item]) / (UiInstance.Graph.pMax[Item] - UiInstance.Graph.pMin[Item])));
5256 
5257  // Limit Y axis
5258  if (Value > UiInstance.Graph.pSpan[Item])
5259  {
5260  Value = UiInstance.Graph.pSpan[Item];
5261  }
5262  if (Value < 0)
5263  {
5264  Value = 0;
5265  }
5266  Y2 = (UiInstance.Graph.pOffset[Item] + UiInstance.Graph.pSpan[Item]) - Value;
5267  if (Pointer > 1)
5268  {
5269 
5270  if (Y2 > Y1)
5271  {
5272  dLcdDrawLine((*UiInstance.pLcd).Lcd,Color,X - 2,Y1 - 1,X - 1,Y2 - 1);
5273  dLcdDrawLine((*UiInstance.pLcd).Lcd,Color,X,Y1 + 1,X + 1,Y2 + 1);
5274  }
5275  else
5276  {
5277  if (Y2 < Y1)
5278  {
5279  dLcdDrawLine((*UiInstance.pLcd).Lcd,Color,X,Y1 - 1,X + 1,Y2 - 1);
5280  dLcdDrawLine((*UiInstance.pLcd).Lcd,Color,X - 2,Y1 + 1,X - 1,Y2 + 1);
5281  }
5282  else
5283  {
5284  dLcdDrawLine((*UiInstance.pLcd).Lcd,Color,X - 1,Y1 - 1,X,Y2 - 1);
5285  dLcdDrawLine((*UiInstance.pLcd).Lcd,Color,X - 1,Y1 + 1,X,Y2 + 1);
5286  }
5287  }
5288  dLcdDrawLine((*UiInstance.pLcd).Lcd,Color,X - 1,Y1,X,Y2);
5289 
5290  }
5291  else
5292  {
5293  dLcdDrawPixel((*UiInstance.pLcd).Lcd,Color,X,Y2);
5294  }
5295 
5296  Y1 = Y2;
5297  X++;
5298  }
5299  }
5300  }
5301  UiInstance.ScreenBusy = 1;
5302  }
5303  }
5304 }
5305 
5306 
5307 //******* BYTE CODE SNIPPETS **************************************************
5308 
5309 
5545 void cUiDraw(void)
5546 {
5547  PRGID TmpPrgId;
5548  OBJID TmpObjId;
5549  IP TmpIp;
5550  DATA8 GBuffer[25];
5551  UBYTE pBmp[LCD_BUFFER_SIZE];
5552  DATA8 Cmd;
5553  DATA8 Color;
5554  DATA16 X;
5555  DATA16 Y;
5556  DATA16 X1;
5557  DATA16 Y1;
5558  DATA16 Y2;
5559  DATA16 Y3;
5560  DATA32 Size;
5561  DATA16 R;
5562  DATA8 *pText;
5563  DATA8 No;
5564  DATAF DataF;
5565  DATA8 Figures;
5566  DATA8 Decimals;
5567  IP pI;
5568  DATA8 *pState;
5569  DATA8 *pAnswer;
5570  DATA8 Lng;
5571  DATA8 SelectedChar;
5572  DATA8 *pType;
5573  DATA8 Type;
5574  DATA16 On;
5575  DATA16 Off;
5576  DATA16 CharWidth;
5577  DATA16 CharHeight;
5578  DATA8 TmpColor;
5579  DATA16 Tmp;
5580  DATA8 Length;
5581  DATA8 *pUnit;
5582  DATA32 *pIcons;
5583  DATA8 Items;
5584  DATA8 View;
5585  DATA16 *pOffset;
5586  DATA16 *pSpan;
5587  DATAF *pMin;
5588  DATAF *pMax;
5589  DATAF *pVal;
5590  DATA16 Min;
5591  DATA16 Max;
5592  DATA16 Act;
5593  DATAF Actual;
5594  DATAF Lowest;
5595  DATAF Highest;
5596  DATAF Average;
5597  DATA8 Icon1;
5598  DATA8 Icon2;
5599  DATA8 Icon3;
5600  DATA8 Blocked;
5601  DATA8 Open;
5602  DATA8 Del;
5603  DATA8 *pCharSet;
5604  DATA16 *pLine;
5605 
5606 
5607  TmpPrgId = CurrentProgramId();
5608 
5609  if ((TmpPrgId != GUI_SLOT) && (TmpPrgId != DEBUG_SLOT))
5610  {
5611  UiInstance.RunScreenEnabled = 0;
5612  }
5613  if (UiInstance.ScreenBlocked == 0)
5614  {
5615  Blocked = 0;
5616  }
5617  else
5618  {
5619  TmpObjId = CallingObjectId();
5620  if ((TmpPrgId == UiInstance.ScreenPrgId) && (TmpObjId == UiInstance.ScreenObjId))
5621  {
5622  Blocked = 0;
5623  }
5624  else
5625  {
5626  Blocked = 1;
5627  }
5628  }
5629 
5630  TmpIp = GetObjectIp();
5631  Cmd = *(DATA8*)PrimParPointer();
5632 
5633  switch (Cmd)
5634  { // Function
5635 
5636  case UPDATE :
5637  {
5638  if (Blocked == 0)
5639  {
5640  cUiUpdateLcd();
5641  UiInstance.ScreenBusy = 0;
5642  }
5643  }
5644  break;
5645 
5646  case CLEAN :
5647  {
5648  if (Blocked == 0)
5649  {
5650  UiInstance.Font = NORMAL_FONT;
5651 
5652  Color = BG_COLOR;
5653  if (Color)
5654  {
5655  Color = -1;
5656  }
5657  memset(&((*UiInstance.pLcd).Lcd[0]),Color,LCD_BUFFER_SIZE);
5658 
5659  UiInstance.ScreenBusy = 1;
5660  }
5661  }
5662  break;
5663 
5664  case TEXTBOX :
5665  {
5666  X = *(DATA16*)PrimParPointer(); // start x
5667  Y = *(DATA16*)PrimParPointer(); // start y
5668  X1 = *(DATA16*)PrimParPointer(); // size x
5669  Y1 = *(DATA16*)PrimParPointer(); // size y
5670  pText = (DATA8*)PrimParPointer(); // textbox
5671  Size = *(DATA32*)PrimParPointer(); // textbox size
5672  Del = *(DATA8*)PrimParPointer(); // delimitter
5673  pLine = (DATA16*)PrimParPointer(); // line
5674 
5675  if (Blocked == 0)
5676  {
5677  if (cUiTextbox(X,Y,X1,Y1,pText,Size,Del,pLine) == BUSY)
5678  {
5679  SetObjectIp(TmpIp - 1);
5681  }
5682  }
5683  else
5684  {
5685  SetObjectIp(TmpIp - 1);
5687  }
5688  }
5689  break;
5690 
5691  case FILLRECT :
5692  {
5693  Color = *(DATA8*)PrimParPointer();
5694  X = *(DATA16*)PrimParPointer();
5695  Y = *(DATA16*)PrimParPointer();
5696  X1 = *(DATA16*)PrimParPointer();
5697  Y1 = *(DATA16*)PrimParPointer();
5698  if (Blocked == 0)
5699  {
5700  dLcdFillRect((*UiInstance.pLcd).Lcd,Color,X,Y,X1,Y1);
5701  UiInstance.ScreenBusy = 1;
5702  }
5703  }
5704  break;
5705 
5706  case INVERSERECT :
5707  {
5708  X = *(DATA16*)PrimParPointer();
5709  Y = *(DATA16*)PrimParPointer();
5710  X1 = *(DATA16*)PrimParPointer();
5711  Y1 = *(DATA16*)PrimParPointer();
5712  if (Blocked == 0)
5713  {
5714  dLcdInverseRect((*UiInstance.pLcd).Lcd,X,Y,X1,Y1);
5715  UiInstance.ScreenBusy = 1;
5716  }
5717  }
5718  break;
5719 
5720  case RECT :
5721  {
5722  Color = *(DATA8*)PrimParPointer();
5723  X = *(DATA16*)PrimParPointer();
5724  Y = *(DATA16*)PrimParPointer();
5725  X1 = *(DATA16*)PrimParPointer();
5726  Y1 = *(DATA16*)PrimParPointer();
5727  if (Blocked == 0)
5728  {
5729  dLcdRect((*UiInstance.pLcd).Lcd,Color,X,Y,X1,Y1);
5730  UiInstance.ScreenBusy = 1;
5731  }
5732  }
5733  break;
5734 
5735  case PIXEL :
5736  {
5737  Color = *(DATA8*)PrimParPointer();
5738  X = *(DATA16*)PrimParPointer();
5739  Y = *(DATA16*)PrimParPointer();
5740  if (Blocked == 0)
5741  {
5742  dLcdDrawPixel((*UiInstance.pLcd).Lcd,Color,X,Y);
5743  UiInstance.ScreenBusy = 1;
5744  }
5745  }
5746  break;
5747 
5748  case LINE :
5749  {
5750  Color = *(DATA8*)PrimParPointer();
5751  X = *(DATA16*)PrimParPointer();
5752  Y = *(DATA16*)PrimParPointer();
5753  X1 = *(DATA16*)PrimParPointer();
5754  Y1 = *(DATA16*)PrimParPointer();
5755  if (Blocked == 0)
5756  {
5757  dLcdDrawLine((*UiInstance.pLcd).Lcd,Color,X,Y,X1,Y1);
5758  UiInstance.ScreenBusy = 1;
5759  }
5760  }
5761  break;
5762 
5763  case DOTLINE :
5764  {
5765  Color = *(DATA8*)PrimParPointer();
5766  X = *(DATA16*)PrimParPointer();
5767  Y = *(DATA16*)PrimParPointer();
5768  X1 = *(DATA16*)PrimParPointer();
5769  Y1 = *(DATA16*)PrimParPointer();
5770  On = *(DATA16*)PrimParPointer();
5771  Off = *(DATA16*)PrimParPointer();
5772  if (Blocked == 0)
5773  {
5774  dLcdDrawDotLine((*UiInstance.pLcd).Lcd,Color,X,Y,X1,Y1,On,Off);
5775  UiInstance.ScreenBusy = 1;
5776  }
5777  }
5778  break;
5779 
5780  case CIRCLE :
5781  {
5782  Color = *(DATA8*)PrimParPointer();
5783  X = *(DATA16*)PrimParPointer();
5784  Y = *(DATA16*)PrimParPointer();
5785  R = *(DATA16*)PrimParPointer();
5786  if (R)
5787  {
5788  if (Blocked == 0)
5789  {
5790  dLcdDrawCircle((*UiInstance.pLcd).Lcd,Color,X,Y,R);
5791  UiInstance.ScreenBusy = 1;
5792  }
5793  }
5794  }
5795  break;
5796 
5797  case FILLCIRCLE :
5798  {
5799  Color = *(DATA8*)PrimParPointer();
5800  X = *(DATA16*)PrimParPointer();
5801  Y = *(DATA16*)PrimParPointer();
5802  R = *(DATA16*)PrimParPointer();
5803  if (R)
5804  {
5805  if (Blocked == 0)
5806  {
5807  dLcdDrawFilledCircle((*UiInstance.pLcd).Lcd,Color,X,Y,R);
5808  UiInstance.ScreenBusy = 1;
5809  }
5810  }
5811  }
5812  break;
5813 
5814  case TEXT :
5815  {
5816  Color = *(DATA8*)PrimParPointer();
5817  X = *(DATA16*)PrimParPointer();
5818  Y = *(DATA16*)PrimParPointer();
5819  pText = (DATA8*)PrimParPointer();
5820  if (Blocked == 0)
5821  {
5822  dLcdDrawText((*UiInstance.pLcd).Lcd,Color,X,Y,UiInstance.Font,pText);
5823  UiInstance.ScreenBusy = 1;
5824  }
5825  }
5826  break;
5827 
5828  case ICON :
5829  {
5830  Color = *(DATA8*)PrimParPointer();
5831  X = *(DATA16*)PrimParPointer();
5832  Y = *(DATA16*)PrimParPointer();
5833  Type = *(DATA8*)PrimParPointer();
5834  No = *(DATA8*)PrimParPointer();
5835  if (Blocked == 0)
5836  {
5837  dLcdDrawIcon((*UiInstance.pLcd).Lcd,Color,X,Y,Type,No);
5838  UiInstance.ScreenBusy = 1;
5839  }
5840  }
5841  break;
5842 
5843  case BMPFILE :
5844  {
5845  Color = *(DATA8*)PrimParPointer();
5846  X = *(DATA16*)PrimParPointer();
5847  Y = *(DATA16*)PrimParPointer();
5848  pText = (DATA8*)PrimParPointer();
5849 
5850  if (Blocked == 0)
5851  {
5852  if (cMemoryGetImage(pText,LCD_BUFFER_SIZE,pBmp) == OK)
5853  {
5854  dLcdDrawBitmap((*UiInstance.pLcd).Lcd,Color,X,Y,pBmp);
5855  UiInstance.ScreenBusy = 1;
5856  }
5857  }
5858  }
5859  break;
5860 
5861  case PICTURE :
5862  {
5863  Color = *(DATA8*)PrimParPointer();
5864  X = *(DATA16*)PrimParPointer();
5865  Y = *(DATA16*)PrimParPointer();
5866  pI = *(IP*)PrimParPointer();
5867  if (pI != NULL)
5868  {
5869  if (Blocked == 0)
5870  {
5871  dLcdDrawBitmap((*UiInstance.pLcd).Lcd,Color,X,Y,pI);
5872  UiInstance.ScreenBusy = 1;
5873  }
5874  }
5875  }
5876  break;
5877 
5878  case VALUE :
5879  {
5880  Color = *(DATA8*)PrimParPointer();
5881  X = *(DATA16*)PrimParPointer();
5882  Y = *(DATA16*)PrimParPointer();
5883  DataF = *(DATAF*)PrimParPointer();
5884  Figures = *(DATA8*)PrimParPointer();
5885  Decimals = *(DATA8*)PrimParPointer();
5886 
5887  if (isnan(DataF))
5888  {
5889  for (Lng = 0;Lng < Figures;Lng++)
5890  {
5891  GBuffer[Lng] = '-';
5892  }
5893  }
5894  else
5895  {
5896  if (Figures < 0)
5897  {
5898  Figures = 0 - Figures;
5899  snprintf((char*)GBuffer,24,"%.*f",Decimals,DataF);
5900  }
5901  else
5902  {
5903  snprintf((char*)GBuffer,24,"%*.*f",Figures,Decimals,DataF);
5904  }
5905  if (GBuffer[0] == '-')
5906  { // Negative
5907 
5908  Figures++;
5909  }
5910  }
5911  GBuffer[Figures] = 0;
5912  pText = GBuffer;
5913  if (Blocked == 0)
5914  {
5915  dLcdDrawText((*UiInstance.pLcd).Lcd,Color,X,Y,UiInstance.Font,pText);
5916  UiInstance.ScreenBusy = 1;
5917  }
5918  }
5919  break;
5920 
5921  case VIEW_VALUE :
5922  {
5923  Color = *(DATA8*)PrimParPointer();
5924  X = *(DATA16*)PrimParPointer();
5925  Y = *(DATA16*)PrimParPointer();
5926  DataF = *(DATAF*)PrimParPointer();
5927  Figures = *(DATA8*)PrimParPointer();
5928  Decimals = *(DATA8*)PrimParPointer();
5929  if (Blocked == 0)
5930  {
5931 
5932  TmpColor = Color;
5933  CharWidth = dLcdGetFontWidth(UiInstance.Font);
5934  CharHeight = dLcdGetFontHeight(UiInstance.Font);
5935  X1 = ((CharWidth + 2) / 3) - 1;
5936  Y1 = (CharHeight / 2);
5937 
5938  Lng = (DATA8)snprintf((char*)GBuffer,24,"%.*f",Decimals,DataF);
5939 
5940  if (Lng)
5941  {
5942  if (GBuffer[0] == '-')
5943  { // Negative
5944 
5945  TmpColor = Color;
5946  Lng--;
5947  pText = &GBuffer[1];
5948  }
5949  else
5950  { // Positive
5951 
5952  TmpColor = 1 - Color;
5953  pText = GBuffer;
5954  }
5955 
5956  // Make sure negative sign is deleted from last time
5957  dLcdDrawLine((*UiInstance.pLcd).Lcd,1 - Color,X - X1,Y + Y1,X + (Figures * CharWidth),Y + Y1);
5958  if (CharHeight > 12)
5959  {
5960  dLcdDrawLine((*UiInstance.pLcd).Lcd,1 - Color,X - X1,Y + Y1 - 1,X + (Figures * CharWidth),Y + Y1 - 1);
5961  }
5962 
5963  // Check for "not a number"
5964  Tmp = 0;
5965  while((pText[Tmp] != 0) && (pText[Tmp] != 'n'))
5966  {
5967  Tmp++;
5968  }
5969  if (pText[Tmp] == 'n')
5970  { // "nan"
5971 
5972  for (Tmp = 0;Tmp < (DATA16)Figures;Tmp++)
5973  {
5974  GBuffer[Tmp] = '-';
5975  }
5976  GBuffer[Tmp] = 0;
5977 
5978  // Draw figures
5979  dLcdDrawText((*UiInstance.pLcd).Lcd,Color,X,Y,UiInstance.Font,GBuffer);
5980  }
5981  else
5982  { // Normal number
5983 
5984  // Check number of figures
5985  if (Lng > Figures)
5986  { // Limit figures
5987 
5988  for (Tmp = 0;Tmp < (DATA16)Figures;Tmp++)
5989  {
5990  GBuffer[Tmp] = '>';
5991  }
5992  GBuffer[Tmp] = 0;
5993  Lng = (DATA16)Figures;
5994  pText = GBuffer;
5995  TmpColor = 1 - Color;
5996 
5997  // Find X indent
5998  Tmp = ((DATA16)Figures - Lng) * CharWidth;
5999  }
6000  else
6001  { // Centre figures
6002 
6003  // Find X indent
6004  Tmp = ((((DATA16)Figures - Lng) + 1) / 2) * CharWidth;
6005  }
6006 
6007  // Draw figures
6008  dLcdDrawText((*UiInstance.pLcd).Lcd,Color,X + Tmp,Y,UiInstance.Font,pText);
6009 
6010  // Draw negative sign
6011  dLcdDrawLine((*UiInstance.pLcd).Lcd,TmpColor,X - X1 + Tmp,Y + Y1,X + Tmp,Y + Y1);
6012  if (CharHeight > 12)
6013  {
6014  dLcdDrawLine((*UiInstance.pLcd).Lcd,TmpColor,X - X1 + Tmp,Y + Y1 - 1,X + Tmp,Y + Y1 - 1);
6015  }
6016  }
6017  }
6018  UiInstance.ScreenBusy = 1;
6019  }
6020  }
6021  break;
6022 
6023  case VIEW_UNIT :
6024  {
6025  Color = *(DATA8*)PrimParPointer();
6026  X = *(DATA16*)PrimParPointer();
6027  Y = *(DATA16*)PrimParPointer();
6028  DataF = *(DATAF*)PrimParPointer();
6029  Figures = *(DATA8*)PrimParPointer();
6030  Decimals = *(DATA8*)PrimParPointer();
6031  Length = *(DATA8*)PrimParPointer();
6032  pUnit = (DATA8*)PrimParPointer();
6033 
6034  if (Blocked == 0)
6035  {
6036  TmpColor = Color;
6037  CharWidth = dLcdGetFontWidth(LARGE_FONT);
6038  CharHeight = dLcdGetFontHeight(LARGE_FONT);
6039  X1 = ((CharWidth + 2) / 3) - 1;
6040  Y1 = (CharHeight / 2);
6041 
6042  Lng = (DATA8)snprintf((char*)GBuffer,24,"%.*f",Decimals,DataF);
6043 
6044  if (Lng)
6045  {
6046  if (GBuffer[0] == '-')
6047  { // Negative
6048 
6049  TmpColor = Color;
6050  Lng--;
6051  pText = &GBuffer[1];
6052  }
6053  else
6054  { // Positive
6055 
6056  TmpColor = 1 - Color;
6057  pText = GBuffer;
6058  }
6059 
6060  // Make sure negative sign is deleted from last time
6061  dLcdDrawLine((*UiInstance.pLcd).Lcd,1 - Color,X - X1,Y + Y1,X + (Figures * CharWidth),Y + Y1);
6062  if (CharHeight > 12)
6063  {
6064  dLcdDrawLine((*UiInstance.pLcd).Lcd,1 - Color,X - X1,Y + Y1 - 1,X + (Figures * CharWidth),Y + Y1 - 1);
6065  }
6066 
6067  // Check for "not a number"
6068  Tmp = 0;
6069  while((pText[Tmp] != 0) && (pText[Tmp] != 'n'))
6070  {
6071  Tmp++;
6072  }
6073  if (pText[Tmp] == 'n')
6074  { // "nan"
6075 
6076  for (Tmp = 0;Tmp < (DATA16)Figures;Tmp++)
6077  {
6078  GBuffer[Tmp] = '-';
6079  }
6080  GBuffer[Tmp] = 0;
6081 
6082  // Draw figures
6083  dLcdDrawText((*UiInstance.pLcd).Lcd,Color,X,Y,LARGE_FONT,GBuffer);
6084  }
6085  else
6086  { // Normal number
6087 
6088  // Check number of figures
6089  if (Lng > Figures)
6090  { // Limit figures
6091 
6092  for (Tmp = 0;Tmp < (DATA16)Figures;Tmp++)
6093  {
6094  GBuffer[Tmp] = '>';
6095  }
6096  GBuffer[Tmp] = 0;
6097  Lng = (DATA16)Figures;
6098  pText = GBuffer;
6099  TmpColor = 1 - Color;
6100 
6101  // Find X indent
6102  Tmp = ((DATA16)Figures - Lng) * CharWidth;
6103  }
6104  else
6105  { // Centre figures
6106 
6107  // Find X indent
6108  Tmp = ((((DATA16)Figures - Lng) + 1) / 2) * CharWidth;
6109  }
6110  Tmp = 0;
6111 
6112  // Draw figures
6113  dLcdDrawText((*UiInstance.pLcd).Lcd,Color,X + Tmp,Y,LARGE_FONT,pText);
6114 
6115  // Draw negative sign
6116  dLcdDrawLine((*UiInstance.pLcd).Lcd,TmpColor,X - X1 + Tmp,Y + Y1,X + Tmp,Y + Y1);
6117  if (CharHeight > 12)
6118  {
6119  dLcdDrawLine((*UiInstance.pLcd).Lcd,TmpColor,X - X1 + Tmp,Y + Y1 - 1,X + Tmp,Y + Y1 - 1);
6120  }
6121 
6122  Tmp = ((((DATA16)Lng))) * CharWidth;
6123  snprintf((char*)GBuffer,Length,"%s",pUnit);
6124  dLcdDrawText((*UiInstance.pLcd).Lcd,Color,X + Tmp,Y,SMALL_FONT,GBuffer);
6125 
6126  }
6127  }
6128  UiInstance.ScreenBusy = 1;
6129  }
6130  }
6131  break;
6132 
6133  case NOTIFICATION :
6134  {
6135  Color = *(DATA8*)PrimParPointer();
6136  X = *(DATA16*)PrimParPointer(); // start x
6137  Y = *(DATA16*)PrimParPointer(); // start y
6138  Icon1 = *(DATA8*)PrimParPointer();
6139  Icon2 = *(DATA8*)PrimParPointer();
6140  Icon3 = *(DATA8*)PrimParPointer();
6141  pText = (DATA8*)PrimParPointer();
6142  pState = (DATA8*)PrimParPointer();
6143 
6144  if (Blocked == 0)
6145  {
6146  if (cUiNotification(Color,X,Y,Icon1,Icon2,Icon3,pText,pState) == BUSY)
6147  {
6148  SetObjectIp(TmpIp - 1);
6150  }
6151  }
6152  else
6153  {
6154  SetObjectIp(TmpIp - 1);
6156  }
6157  }
6158  break;
6159 
6160  case QUESTION :
6161  {
6162  Color = *(DATA8*)PrimParPointer();
6163  X = *(DATA16*)PrimParPointer(); // start x
6164  Y = *(DATA16*)PrimParPointer(); // start y
6165  Icon1 = *(DATA8*)PrimParPointer();
6166  Icon2 = *(DATA8*)PrimParPointer();
6167  pText = (DATA8*)PrimParPointer();
6168  pState = (DATA8*)PrimParPointer();
6169  pAnswer = (DATA8*)PrimParPointer();
6170 
6171  if (Blocked == 0)
6172  {
6173  if (cUiQuestion(Color,X,Y,Icon1,Icon2,pText,pState,pAnswer) == BUSY)
6174  {
6175  SetObjectIp(TmpIp - 1);
6177  }
6178  }
6179  else
6180  {
6181  SetObjectIp(TmpIp - 1);
6183  }
6184  }
6185  break;
6186 
6187 
6188  case ICON_QUESTION :
6189  {
6190  Color = *(DATA8*)PrimParPointer();
6191  X = *(DATA16*)PrimParPointer(); // start x
6192  Y = *(DATA16*)PrimParPointer(); // start y
6193  pState = (DATA8*)PrimParPointer();
6194  pIcons = (DATA32*)PrimParPointer();
6195 
6196  if (Blocked == 0)
6197  {
6198  if (cUiIconQuestion(Color,X,Y,pState,pIcons) == BUSY)
6199  {
6200  SetObjectIp(TmpIp - 1);
6202  }
6203  }
6204  else
6205  {
6206  SetObjectIp(TmpIp - 1);
6208  }
6209  }
6210  break;
6211 
6212 
6213  case KEYBOARD :
6214  {
6215  Color = *(DATA8*)PrimParPointer();
6216  X = *(DATA16*)PrimParPointer(); // start x
6217  Y = *(DATA16*)PrimParPointer(); // start y
6218  No = *(DATA8*)PrimParPointer(); // Icon
6219  Lng = *(DATA8*)PrimParPointer(); // length
6220  pText = (DATA8*)PrimParPointer(); // default
6221  pCharSet = (DATA8*)PrimParPointer(); // valid char set
6222  pAnswer = (DATA8*)PrimParPointer(); // string
6223 
6224  if (VMInstance.Handle >= 0)
6225  {
6226  pAnswer = (DATA8*)VmMemoryResize(VMInstance.Handle,(DATA32)Lng);
6227  }
6228 
6229  if (Blocked == 0)
6230  {
6231  SelectedChar = cUiKeyboard(Color,X,Y,No,Lng,pText,pCharSet,pAnswer);
6232 
6233  // Wait for "ENTER"
6234  if (SelectedChar != 0x0D)
6235  {
6236  SetObjectIp(TmpIp - 1);
6238  }
6239  }
6240  else
6241  {
6242  SetObjectIp(TmpIp - 1);
6244  }
6245  }
6246  break;
6247 
6248  case BROWSE :
6249  {
6250  Type = *(DATA8*)PrimParPointer(); // Browser type
6251  X = *(DATA16*)PrimParPointer(); // start x
6252  Y = *(DATA16*)PrimParPointer(); // start y
6253  X1 = *(DATA16*)PrimParPointer(); // size x
6254  Y1 = *(DATA16*)PrimParPointer(); // size y
6255  Lng = *(DATA8*)PrimParPointer(); // length
6256  pType = (DATA8*)PrimParPointer(); // item type
6257  pAnswer = (DATA8*)PrimParPointer(); // item name
6258 
6259  if (VMInstance.Handle >= 0)
6260  {
6261  pAnswer = (DATA8*)VmMemoryResize(VMInstance.Handle,(DATA32)Lng);
6262  }
6263 
6264  if (Blocked == 0)
6265  {
6266  if (cUiBrowser(Type,X,Y,X1,Y1,Lng,pType,pAnswer) == BUSY)
6267  {
6268  SetObjectIp(TmpIp - 1);
6270  }
6271  }
6272  else
6273  {
6274  SetObjectIp(TmpIp - 1);
6276  }
6277  }
6278  break;
6279 
6280  case VERTBAR :
6281  {
6282  Color = *(DATA8*)PrimParPointer();
6283  X = *(DATA16*)PrimParPointer(); // start x
6284  Y = *(DATA16*)PrimParPointer(); // start y
6285  X1 = *(DATA16*)PrimParPointer(); // size x
6286  Y1 = *(DATA16*)PrimParPointer(); // size y
6287  Min = *(DATA16*)PrimParPointer(); // min
6288  Max = *(DATA16*)PrimParPointer(); // max
6289  Act = *(DATA16*)PrimParPointer(); // actual
6290 
6291  if (Blocked == 0)
6292  {
6293  cUiDrawBar(Color,X,Y,X1,Y1,Min,Max,Act);
6294  }
6295  }
6296  break;
6297 
6298  case SELECT_FONT :
6299  {
6300  UiInstance.Font = *(DATA8*)PrimParPointer();
6301  if (Blocked == 0)
6302  {
6303  if (UiInstance.Font >= FONTTYPES)
6304  {
6305  UiInstance.Font = (FONTTYPES - 1);
6306  }
6307  if (UiInstance.Font < 0)
6308  {
6309  UiInstance.Font = 0;
6310  }
6311  }
6312  }
6313  break;
6314 
6315  case TOPLINE :
6316  {
6317  UiInstance.TopLineEnabled = *(DATA8*)PrimParPointer();
6318  }
6319  break;
6320 
6321  case FILLWINDOW :
6322  {
6323  Color = *(DATA8*)PrimParPointer();
6324  Y = *(DATA16*)PrimParPointer(); // start y
6325  Y1 = *(DATA16*)PrimParPointer(); // size y
6326  if (Blocked == 0)
6327  {
6328  UiInstance.Font = NORMAL_FONT;
6329 
6330  if ((Y + Y1) < LCD_HEIGHT)
6331  {
6332  if ((Color == 0) || (Color == 1))
6333  {
6334  Y *= ((LCD_WIDTH + 7) / 8);
6335 
6336  if (Y1)
6337  {
6338  Y1 *= ((LCD_WIDTH + 7) / 8);
6339  }
6340  else
6341  {
6342  Y1 = LCD_BUFFER_SIZE - Y;
6343  }
6344 
6345  if (Color)
6346  {
6347  Color = -1;
6348  }
6349  memset(&((*UiInstance.pLcd).Lcd[Y]),Color,Y1);
6350  }
6351  else
6352  {
6353  if (Y1 == 0)
6354  {
6355  Y1 = LCD_HEIGHT;
6356  }
6357  Y2 = ((LCD_WIDTH + 7) / 8);
6358  for (Tmp = Y;Tmp < Y1;Tmp++)
6359  {
6360  Y3 = Tmp * ((LCD_WIDTH + 7) / 8);
6361  memset(&((*UiInstance.pLcd).Lcd[Y3]),Color,Y2);
6362  Color = ~Color;
6363  }
6364  }
6365  }
6366 
6367  UiInstance.ScreenBusy = 1;
6368  }
6369  }
6370  break;
6371 
6372  case STORE :
6373  {
6374  No = *(DATA8*)PrimParPointer();
6375  if (Blocked == 0)
6376  {
6377  if (No < LCD_STORE_LEVELS)
6378  {
6379  LCDCopy(&UiInstance.LcdSafe,&UiInstance.LcdPool[No],sizeof(LCD));
6380  }
6381  }
6382  }
6383  break;
6384 
6385  case RESTORE :
6386  {
6387  No = *(DATA8*)PrimParPointer();
6388  if (Blocked == 0)
6389  {
6390  if (No < LCD_STORE_LEVELS)
6391  {
6392  LCDCopy(&UiInstance.LcdPool[No],&UiInstance.LcdSafe,sizeof(LCD));
6393  UiInstance.ScreenBusy = 1;
6394  }
6395  }
6396  }
6397  break;
6398 
6399  case GRAPH_SETUP :
6400  {
6401  X = *(DATA16*)PrimParPointer(); // start x
6402  X1 = *(DATA16*)PrimParPointer(); // size y
6403  Items = *(DATA8*)PrimParPointer(); // items
6404  pOffset = (DATA16*)PrimParPointer(); // handle to offset Y
6405  pSpan = (DATA16*)PrimParPointer(); // handle to span y
6406  pMin = (DATAF*)PrimParPointer(); // handle to min
6407  pMax = (DATAF*)PrimParPointer(); // handle to max
6408  pVal = (DATAF*)PrimParPointer(); // handle to val
6409 
6410  if (Blocked == 0)
6411  {
6412  cUiGraphSetup(X,X1,Items,pOffset,pSpan,pMin,pMax,pVal);
6413  }
6414  }
6415  break;
6416 
6417  case GRAPH_DRAW :
6418  {
6419  View = *(DATA8*)PrimParPointer(); // view
6420 
6421  cUiGraphDraw(View,&Actual,&Lowest,&Highest,&Average);
6422 
6423  *(DATAF*)PrimParPointer() = Actual;
6424  *(DATAF*)PrimParPointer() = Lowest;
6425  *(DATAF*)PrimParPointer() = Highest;
6426  *(DATAF*)PrimParPointer() = Average;
6427  }
6428  break;
6429 
6430  case SCROLL :
6431  {
6432  Y = *(DATA16*)PrimParPointer();
6433  if ((Y > 0) && (Y < LCD_HEIGHT))
6434  {
6435  dLcdScroll((*UiInstance.pLcd).Lcd,Y);
6436  }
6437  }
6438  break;
6439 
6440  case POPUP :
6441  {
6442  Open = *(DATA8*)PrimParPointer();
6443  if (Blocked == 0)
6444  {
6445  if (Open)
6446  {
6447  if (!UiInstance.ScreenBusy)
6448  {
6449  TmpObjId = CallingObjectId();
6450 
6451  LCDCopy(&UiInstance.LcdSafe,&UiInstance.LcdSave,sizeof(UiInstance.LcdSave));
6452  UiInstance.ScreenPrgId = TmpPrgId;
6453  UiInstance.ScreenObjId = TmpObjId;
6454  UiInstance.ScreenBlocked = 1;
6455  }
6456  else
6457  { // Wait on scrreen
6458 
6459  SetObjectIp(TmpIp - 1);
6461  }
6462  }
6463  else
6464  {
6465  LCDCopy(&UiInstance.LcdSave,&UiInstance.LcdSafe,sizeof(UiInstance.LcdSafe));
6466  dLcdUpdate(UiInstance.pLcd);
6467 
6468  UiInstance.ScreenPrgId = -1;
6469  UiInstance.ScreenObjId = -1;
6470  UiInstance.ScreenBlocked = 0;
6471  }
6472  }
6473  else
6474  { // Wait on not blocked
6475 
6476  SetObjectIp(TmpIp - 1);
6478  }
6479  }
6480  break;
6481 
6482  }
6483 }
6484 
6485 
6497 void cUiFlush(void)
6498 {
6499  cUiFlushBuffer();
6500 }
6501 
6502 
6614 void cUiRead(void)
6615 {
6616  IP TmpIp;
6617  DATA8 Cmd;
6618  DATA8 Lng;
6619  DATA8 Data8;
6620  DATA8 *pSource;
6621  DATA8 *pDestination;
6622  DATA16 Data16;
6623  IMGDATA Tmp;
6624  DATA32 pImage;
6625  DATA32 Length;
6626  DATA32 Total;
6627  DATA32 Size;
6628  IMGHEAD *pImgHead;
6629  OBJHEAD *pObjHead;
6630 
6631 
6632  TmpIp = GetObjectIp();
6633  Cmd = *(DATA8*)PrimParPointer();
6634 
6635  switch (Cmd)
6636  { // Function
6637 
6638  case GET_STRING :
6639  {
6640  if (UiInstance.Keys)
6641  {
6642  Lng = *(DATA8*)PrimParPointer();
6643  pDestination = (DATA8*)PrimParPointer();
6644  pSource = (DATA8*)UiInstance.KeyBuffer;
6645 
6646  while ((UiInstance.Keys) && (Lng))
6647  {
6648  *pDestination = *pSource;
6649  pDestination++;
6650  pSource++;
6651  UiInstance.Keys--;
6652  Lng--;
6653  }
6654  *pDestination = 0;
6655  UiInstance.KeyBufIn = 0;
6656  }
6657  else
6658  {
6659  SetObjectIp(TmpIp - 1);
6661  }
6662  }
6663  break;
6664 
6665  case KEY :
6666  {
6667  if (UiInstance.KeyBufIn)
6668  {
6669  *(DATA8*)PrimParPointer() = (DATA8)UiInstance.KeyBuffer[0];
6670  UiInstance.KeyBufIn--;
6671 
6672  for (Lng = 0;Lng < UiInstance.KeyBufIn;Lng++)
6673  {
6674  UiInstance.KeyBuffer[Lng] = UiInstance.KeyBuffer[Lng + 1];
6675  }
6676 #ifdef DEBUG_TRACE_KEY
6677  printf("%s",(char*)UiInstance.KeyBuffer);
6678 #endif
6679  }
6680  else
6681  {
6682  *(DATA8*)PrimParPointer() = (DATA8)0;
6683  }
6684  }
6685  break;
6686 
6687  case GET_SHUTDOWN :
6688  {
6689  *(DATA8*)PrimParPointer() = UiInstance.ShutDown;
6690  UiInstance.ShutDown = 0;
6691  }
6692  break;
6693 
6694  case GET_WARNING :
6695  {
6696  *(DATA8*)PrimParPointer() = UiInstance.Warning;
6697  }
6698  break;
6699 
6700  case GET_LBATT :
6701  {
6702  Data16 = (DATA16)(UiInstance.Vbatt * 1000.0);
6703  Data16 -= UiInstance.BattIndicatorLow;
6704  Data16 = (Data16 * 100) / (UiInstance.BattIndicatorHigh - UiInstance.BattIndicatorLow);
6705  if (Data16 > 100)
6706  {
6707  Data16 = 100;
6708  }
6709  if (Data16 < 0)
6710  {
6711  Data16 = 0;
6712  }
6713  *(DATA8*)PrimParPointer() = (DATA8)Data16;
6714  }
6715  break;
6716 
6717  case ADDRESS :
6718  {
6719  if (UiInstance.Keys)
6720  {
6721  *(DATA32*)PrimParPointer() = (DATA32)atol((const char*)UiInstance.KeyBuffer);
6722  UiInstance.Keys = 0;
6723  }
6724  else
6725  {
6726  SetObjectIp(TmpIp - 1);
6728  }
6729  }
6730  break;
6731 
6732  case CODE :
6733  {
6734  if (UiInstance.Keys)
6735  {
6736  Length = *(DATA32*)PrimParPointer();
6737  pImage = *(DATA32*)PrimParPointer();
6738 
6739  pImgHead = (IMGHEAD*)pImage;
6740  pObjHead = (OBJHEAD*)(pImage + sizeof(IMGHEAD));
6741  pDestination = (DATA8*)(pImage + sizeof(IMGHEAD) + sizeof(OBJHEAD));
6742 
6743  if (Length > (sizeof(IMGHEAD) + sizeof(OBJHEAD)))
6744  {
6745 
6746  (*pImgHead).Sign[0] = 'l';
6747  (*pImgHead).Sign[1] = 'e';
6748  (*pImgHead).Sign[2] = 'g';
6749  (*pImgHead).Sign[3] = 'o';
6750  (*pImgHead).ImageSize = 0;
6751  (*pImgHead).VersionInfo = (UWORD)(VERS * 100.0);
6752  (*pImgHead).NumberOfObjects = 1;
6753  (*pImgHead).GlobalBytes = 0;
6754 
6755  (*pObjHead).OffsetToInstructions = (IP)(sizeof(IMGHEAD) + sizeof(OBJHEAD));
6756  (*pObjHead).OwnerObjectId = 0;
6757  (*pObjHead).TriggerCount = 0;
6758  (*pObjHead).LocalBytes = MAX_COMMAND_LOCALS;
6759 
6760  pSource = (DATA8*)UiInstance.KeyBuffer;
6761  Size = sizeof(IMGHEAD) + sizeof(OBJHEAD);
6762 
6763  Length -= sizeof(IMGHEAD) + sizeof(OBJHEAD);
6764  Length--;
6765  while ((UiInstance.Keys) && (Length))
6766  {
6767  Tmp = (IMGDATA)(AtoN(*pSource) << 4);
6768  pSource++;
6769  UiInstance.Keys--;
6770  if (UiInstance.Keys)
6771  {
6772  Tmp += (IMGDATA)(AtoN(*pSource));
6773  pSource++;
6774  UiInstance.Keys--;
6775  }
6776  else
6777  {
6778  Tmp = 0;
6779  }
6780  *pDestination = Tmp;
6781  pDestination++;
6782  Length--;
6783  Size++;
6784  }
6785  *pDestination = opOBJECT_END;
6786  Size++;
6787  (*pImgHead).ImageSize = Size;
6788  memset(UiInstance.Globals,0,sizeof(UiInstance.Globals));
6789 
6790  *(DATA32*)PrimParPointer() = (DATA32)UiInstance.Globals;
6791  *(DATA8*)PrimParPointer() = 1;
6792  }
6793  }
6794  else
6795  {
6796  SetObjectIp(TmpIp - 1);
6798  }
6799  }
6800  break;
6801 
6802  case GET_HW_VERS :
6803  {
6804  Lng = *(DATA8*)PrimParPointer();
6805  pDestination = (DATA8*)PrimParPointer();
6806 
6807  if (VMInstance.Handle >= 0)
6808  {
6809  Data8 = (DATA8)strlen((char*)UiInstance.HwVers) + 1;
6810  if ((Lng > Data8) || (Lng == -1))
6811  {
6812  Lng = Data8;
6813  }
6814  pDestination = (DATA8*)VmMemoryResize(VMInstance.Handle,(DATA32)Lng);
6815  }
6816  if (pDestination != NULL)
6817  {
6818  snprintf((char*)pDestination,Lng,"%s",UiInstance.HwVers);
6819  }
6820  }
6821  break;
6822 
6823  case GET_FW_VERS :
6824  {
6825  Lng = *(DATA8*)PrimParPointer();
6826  pDestination = (DATA8*)PrimParPointer();
6827 
6828  if (VMInstance.Handle >= 0)
6829  {
6830  Data8 = (DATA8)strlen((char*)UiInstance.FwVers) + 1;
6831  if ((Lng > Data8) || (Lng == -1))
6832  {
6833  Lng = Data8;
6834  }
6835  pDestination = (DATA8*)VmMemoryResize(VMInstance.Handle,(DATA32)Lng);
6836  }
6837  if (pDestination != NULL)
6838  {
6839  snprintf((char*)pDestination,Lng,"%s",UiInstance.FwVers);
6840  }
6841  }
6842  break;
6843 
6844  case GET_FW_BUILD :
6845  {
6846  Lng = *(DATA8*)PrimParPointer();
6847  pDestination = (DATA8*)PrimParPointer();
6848 
6849  if (VMInstance.Handle >= 0)
6850  {
6851  Data8 = (DATA8)strlen((char*)UiInstance.FwBuild) + 1;
6852  if ((Lng > Data8) || (Lng == -1))
6853  {
6854  Lng = Data8;
6855  }
6856  pDestination = (DATA8*)VmMemoryResize(VMInstance.Handle,(DATA32)Lng);
6857  }
6858  if (pDestination != NULL)
6859  {
6860  snprintf((char*)pDestination,Lng,"%s",UiInstance.FwBuild);
6861  }
6862  }
6863  break;
6864 
6865  case GET_OS_VERS :
6866  {
6867  Lng = *(DATA8*)PrimParPointer();
6868  pDestination = (DATA8*)PrimParPointer();
6869 
6870  if (VMInstance.Handle >= 0)
6871  {
6872  Data8 = (DATA8)strlen((char*)UiInstance.OsVers) + 1;
6873  if ((Lng > Data8) || (Lng == -1))
6874  {
6875  Lng = Data8;
6876  }
6877  pDestination = (DATA8*)VmMemoryResize(VMInstance.Handle,(DATA32)Lng);
6878  }
6879  if (pDestination != NULL)
6880  {
6881  snprintf((char*)pDestination,Lng,"%s",UiInstance.OsVers);
6882  }
6883  }
6884  break;
6885 
6886  case GET_OS_BUILD :
6887  {
6888  Lng = *(DATA8*)PrimParPointer();
6889  pDestination = (DATA8*)PrimParPointer();
6890 
6891  if (VMInstance.Handle >= 0)
6892  {
6893  Data8 = (DATA8)strlen((char*)UiInstance.OsBuild) + 1;
6894  if ((Lng > Data8) || (Lng == -1))
6895  {
6896  Lng = Data8;
6897  }
6898  pDestination = (DATA8*)VmMemoryResize(VMInstance.Handle,(DATA32)Lng);
6899  }
6900  if (pDestination != NULL)
6901  {
6902  snprintf((char*)pDestination,Lng,"%s",UiInstance.OsBuild);
6903  }
6904  }
6905  break;
6906 
6907  case GET_VERSION :
6908  {
6909  snprintf((char*)UiInstance.ImageBuffer,IMAGEBUFFER_SIZE,"%s V%4.2f%c(%s %s)",PROJECT,VERS,SPECIALVERS,__DATE__,__TIME__);
6910  Lng = *(DATA8*)PrimParPointer();
6911  pDestination = (DATA8*)PrimParPointer();
6912  pSource = (DATA8*)UiInstance.ImageBuffer;
6913 
6914  if (VMInstance.Handle >= 0)
6915  {
6916  Data8 = (DATA8)strlen((char*)UiInstance.ImageBuffer) + 1;
6917  if ((Lng > Data8) || (Lng == -1))
6918  {
6919  Lng = Data8;
6920  }
6921  pDestination = (DATA8*)VmMemoryResize(VMInstance.Handle,(DATA32)Lng);
6922  }
6923  if (pDestination != NULL)
6924  {
6925  snprintf((char*)pDestination,Lng,"%s",UiInstance.ImageBuffer);
6926  }
6927  }
6928  break;
6929 
6930  case GET_IP :
6931  {
6932  Lng = *(DATA8*)PrimParPointer();
6933  pDestination = (DATA8*)PrimParPointer();
6934 
6935  if (VMInstance.Handle >= 0)
6936  {
6937  Data8 = IPADDR_SIZE;
6938  if ((Lng > Data8) || (Lng == -1))
6939  {
6940  Lng = Data8;
6941  }
6942  pDestination = (DATA8*)VmMemoryResize(VMInstance.Handle,(DATA32)Lng);
6943  }
6944  if (pDestination != NULL)
6945  {
6946  snprintf((char*)pDestination,Lng,"%s",UiInstance.IpAddr);
6947  }
6948 
6949  }
6950  break;
6951 
6952  case GET_POWER :
6953  {
6954  *(DATAF*)PrimParPointer() = UiInstance.Vbatt;
6955  *(DATAF*)PrimParPointer() = UiInstance.Ibatt;
6956  *(DATAF*)PrimParPointer() = UiInstance.Iintegrated;
6957  *(DATAF*)PrimParPointer() = UiInstance.Imotor;
6958  }
6959  break;
6960 
6961  case GET_VBATT :
6962  {
6963  *(DATAF*)PrimParPointer() = UiInstance.Vbatt;
6964  }
6965  break;
6966 
6967  case GET_IBATT :
6968  {
6969  *(DATAF*)PrimParPointer() = UiInstance.Ibatt;
6970  }
6971  break;
6972 
6973  case GET_IINT :
6974  {
6975  *(DATAF*)PrimParPointer() = UiInstance.Iintegrated;
6976  }
6977  break;
6978 
6979  case GET_IMOTOR :
6980  {
6981  *(DATAF*)PrimParPointer() = UiInstance.Imotor;
6982  }
6983  break;
6984 
6985  case GET_EVENT :
6986  {
6987  *(DATA8*)PrimParPointer() = UiInstance.Event;
6988  UiInstance.Event = 0;
6989  }
6990  break;
6991 
6992  case GET_TBATT :
6993  {
6994  *(DATAF*)PrimParPointer() = UiInstance.Tbatt;
6995  }
6996  break;
6997 
6998  case TEXTBOX_READ :
6999  {
7000  pSource = (DATA8*)PrimParPointer();
7001  Size = *(DATA32*)PrimParPointer();
7002  Data8 = *(DATA8*)PrimParPointer();
7003  Lng = *(DATA8*)PrimParPointer();
7004  Data16 = *(DATA16*)PrimParPointer();
7005  pDestination = (DATA8*)PrimParPointer();
7006 
7007  cUiTextboxReadLine(pSource,Size,Data8,Lng,Data16,pDestination,&Data8);
7008  }
7009  break;
7010 
7011  case GET_SDCARD :
7012  {
7013  *(DATA8*)PrimParPointer() = CheckSdcard(&Data8,&Total,&Size,0);
7014  *(DATA32*)PrimParPointer() = Total;
7015  *(DATA32*)PrimParPointer() = Size;
7016  }
7017  break;
7018 
7019  case GET_USBSTICK :
7020  {
7021  *(DATA8*)PrimParPointer() = CheckUsbstick(&Data8,&Total,&Size,0);
7022  *(DATA32*)PrimParPointer() = Total;
7023  *(DATA32*)PrimParPointer() = Size;
7024  }
7025  break;
7026 
7027  }
7028 }
7029 
7030 
7115 void cUiWrite(void)
7116 {
7117  IP TmpIp;
7118  DATA8 Cmd;
7119  DATA8 *pSource;
7120  DSPSTAT DspStat = BUSYBREAK;
7121  DATA8 Buffer[50];
7122  DATA8 Data8;
7123  DATA16 Data16;
7124  DATA32 Data32;
7125  DATA32 pGlobal;
7126  DATA32 Tmp;
7127  DATAF DataF;
7128  DATA8 Figures;
7129  DATA8 Decimals;
7130  DATA8 No;
7131  DATA8 *pText;
7132 
7133 
7134  TmpIp = GetObjectIp();
7135  Cmd = *(DATA8*)PrimParPointer();
7136 
7137  switch (Cmd)
7138  { // Function
7139 
7140  case WRITE_FLUSH :
7141  {
7142  cUiFlush();
7143  DspStat = NOBREAK;
7144  }
7145  break;
7146 
7147  case FLOATVALUE :
7148  {
7149  DataF = *(DATAF*)PrimParPointer();
7150  Figures = *(DATA8*)PrimParPointer();
7151  Decimals = *(DATA8*)PrimParPointer();
7152 
7153  snprintf((char*)Buffer,32,"%*.*f",Figures,Decimals,DataF);
7154  cUiWriteString(Buffer);
7155 
7156  DspStat = NOBREAK;
7157  }
7158  break;
7159 
7160  case STAMP :
7161  { // write time, prgid, objid, ip
7162 
7163  pSource = (DATA8*)PrimParPointer();
7164  snprintf((char*)Buffer,50,"####[ %09u %01u %03u %06u %s]####\r\n",GetTime(),CurrentProgramId(),CallingObjectId(),CurrentObjectIp(),pSource);
7165  cUiWriteString(Buffer);
7166  cUiFlush();
7167  DspStat = NOBREAK;
7168  }
7169  break;
7170 
7171  case PUT_STRING :
7172  {
7173  pSource = (DATA8*)PrimParPointer();
7174  cUiWriteString(pSource);
7175  DspStat = NOBREAK;
7176  }
7177  break;
7178 
7179  case CODE :
7180  {
7181  pGlobal = *(DATA32*)PrimParPointer();
7182  Data32 = *(DATA32*)PrimParPointer();
7183 
7184  pSource = (DATA8*)pGlobal;
7185 
7186  cUiWriteString((DATA8*)"\r\n ");
7187  for (Tmp = 0;Tmp < Data32;Tmp++)
7188  {
7189  snprintf((char*)Buffer,7,"%02X ",pSource[Tmp] & 0xFF);
7190  cUiWriteString(Buffer);
7191  if (((Tmp & 0x3) == 0x3) && ((Tmp & 0xF) != 0xF))
7192  {
7193  cUiWriteString((DATA8*)" ");
7194  }
7195  if (((Tmp & 0xF) == 0xF) && (Tmp < (Data32 - 1)))
7196  {
7197  cUiWriteString((DATA8*)"\r\n ");
7198  }
7199  }
7200  cUiWriteString((DATA8*)"\r\n");
7201  DspStat = NOBREAK;
7202  }
7203  break;
7204 
7205  case TEXTBOX_APPEND :
7206  {
7207  pText = (DATA8*)PrimParPointer();
7208  Data32 = *(DATA32*)PrimParPointer();
7209  Data8 = *(DATA8*)PrimParPointer();
7210  pSource = (DATA8*)PrimParPointer();
7211 
7212  cUiTextboxAppendLine(pText,Data32,Data8,pSource,UiInstance.Font);
7213 
7214  DspStat = NOBREAK;
7215  }
7216  break;
7217 
7218  case SET_BUSY :
7219  {
7220  Data8 = *(DATA8*)PrimParPointer();
7221 
7222  if (Data8)
7223  {
7224  UiInstance.Warning |= WARNING_BUSY;
7225  }
7226  else
7227  {
7228  UiInstance.Warning &= ~WARNING_BUSY;
7229  }
7230 
7231  DspStat = NOBREAK;
7232  }
7233  break;
7234 
7235  case VALUE8 :
7236  {
7237  Data8 = *(DATA8*)PrimParPointer();
7238  if (Data8 != DATA8_NAN)
7239  {
7240  snprintf((char*)Buffer,7,"%d",(int)Data8);
7241  }
7242  else
7243  {
7244  snprintf((char*)Buffer,7,"nan");
7245  }
7246  cUiWriteString(Buffer);
7247 
7248  DspStat = NOBREAK;
7249  }
7250  break;
7251 
7252  case VALUE16 :
7253  {
7254  Data16 = *(DATA16*)PrimParPointer();
7255  if (Data16 != DATA16_NAN)
7256  {
7257  snprintf((char*)Buffer,9,"%d",Data16 & 0xFFFF);
7258  }
7259  else
7260  {
7261  snprintf((char*)Buffer,7,"nan");
7262  }
7263  cUiWriteString(Buffer);
7264 
7265  DspStat = NOBREAK;
7266  }
7267  break;
7268 
7269  case VALUE32 :
7270  {
7271  Data32 = *(DATA32*)PrimParPointer();
7272  if (Data32 != DATA32_NAN)
7273  {
7274  snprintf((char*)Buffer,14,"%ld",(long unsigned int)(Data32 & 0xFFFFFFFF));
7275  }
7276  else
7277  {
7278  snprintf((char*)Buffer,7,"nan");
7279  }
7280 
7281  cUiWriteString(Buffer);
7282 
7283  DspStat = NOBREAK;
7284  }
7285  break;
7286 
7287  case VALUEF :
7288  {
7289  DataF = *(DATAF*)PrimParPointer();
7290  snprintf((char*)Buffer,24,"%f",DataF);
7291  cUiWriteString(Buffer);
7292 
7293  DspStat = NOBREAK;
7294  }
7295  break;
7296 
7297  case LED :
7298  {
7299  Data8 = *(DATA8*)PrimParPointer();
7300  if (Data8 < 0)
7301  {
7302  Data8 = 0;
7303  }
7304  if (Data8 >= LEDPATTERNS)
7305  {
7306  Data8 = LEDPATTERNS - 1;
7307  }
7308  cUiSetLed(Data8);
7309  UiInstance.RunLedEnabled = 0;
7310 
7311  DspStat = NOBREAK;
7312  }
7313  break;
7314 
7315  case POWER :
7316  {
7317  Data8 = *(DATA8*)PrimParPointer();
7318 
7319  if (UiInstance.PowerFile >= 0)
7320  {
7321  ioctl(UiInstance.PowerFile,0,(size_t)&Data8);
7322  }
7323 
7324  DspStat = NOBREAK;
7325  }
7326  break;
7327 
7328  case TERMINAL :
7329  {
7330  No = *(DATA8*)PrimParPointer();
7331 
7332  if (No)
7333  {
7334  SetTerminalEnable(1);
7335  }
7336  else
7337  {
7338  SetTerminalEnable(0);
7339  }
7340 
7341  DspStat = NOBREAK;
7342  }
7343  break;
7344 
7345  case SET_TESTPIN :
7346  {
7347  Data8 = *(DATA8*)PrimParPointer();
7348  cUiTestpin(Data8);
7349  DspStat = NOBREAK;
7350  }
7351  break;
7352 
7353  case INIT_RUN :
7354  {
7355  UiInstance.RunScreenEnabled = 3;
7356 
7357  DspStat = NOBREAK;
7358  }
7359  break;
7360 
7361  case UPDATE_RUN :
7362  {
7363  DspStat = NOBREAK;
7364  }
7365  break;
7366 
7367  case GRAPH_SAMPLE :
7368  {
7369  cUiGraphSample();
7370  DspStat = NOBREAK;
7371  }
7372  break;
7373 
7374  case DOWNLOAD_END :
7375  {
7376  UiInstance.UiUpdate = 1;
7378  DspStat = NOBREAK;
7379  }
7380  break;
7381 
7382  case SCREEN_BLOCK :
7383  {
7384  UiInstance.ScreenBlocked = *(DATA8*)PrimParPointer();
7385  DspStat = NOBREAK;
7386  }
7387  break;
7388 
7389  default :
7390  {
7391  DspStat = FAILBREAK;
7392  }
7393  break;
7394 
7395  }
7396 
7397  if (DspStat == BUSYBREAK)
7398  { // Rewind IP
7399 
7400  SetObjectIp(TmpIp - 1);
7401  }
7402  SetDispatchStatus(DspStat);
7403 }
7404 
7405 
7487 void cUiButton(void)
7488 {
7489  PRGID TmpPrgId;
7490  OBJID TmpObjId;
7491  IP TmpIp;
7492  DATA8 Cmd;
7493  DATA8 Button;
7494  DATA8 State;
7495  DATA16 Inc;
7496  DATA8 Blocked;
7497 
7498  TmpIp = GetObjectIp();
7499  TmpPrgId = CurrentProgramId();
7500 
7501  if (UiInstance.ScreenBlocked == 0)
7502  {
7503  Blocked = 0;
7504  }
7505  else
7506  {
7507  TmpObjId = CallingObjectId();
7508  if ((TmpPrgId == UiInstance.ScreenPrgId) && (TmpObjId == UiInstance.ScreenObjId))
7509  {
7510  Blocked = 0;
7511  }
7512  else
7513  {
7514  Blocked = 1;
7515  }
7516  }
7517 
7518  Cmd = *(DATA8*)PrimParPointer();
7519 
7520  State = 0;
7521  Inc = 0;
7522 
7523  switch (Cmd)
7524  { // Function
7525 
7526  case PRESS :
7527  {
7528  Button = *(DATA8*)PrimParPointer();
7529  cUiSetPress(Button,1);
7530  }
7531  break;
7532 
7533  case RELEASE :
7534  {
7535  Button = *(DATA8*)PrimParPointer();
7536  cUiSetPress(Button,0);
7537  }
7538  break;
7539 
7540  case SHORTPRESS :
7541  {
7542  Button = *(DATA8*)PrimParPointer();
7543 
7544  if (Blocked == 0)
7545  {
7546  State = cUiGetShortPress(Button);
7547  }
7548  *(DATA8*)PrimParPointer() = State;
7549  }
7550  break;
7551 
7552  case GET_BUMBED :
7553  {
7554  Button = *(DATA8*)PrimParPointer();
7555 
7556  if (Blocked == 0)
7557  {
7558  State = cUiGetBumbed(Button);
7559  }
7560  *(DATA8*)PrimParPointer() = State;
7561  }
7562  break;
7563 
7564  case PRESSED :
7565  {
7566  Button = *(DATA8*)PrimParPointer();
7567 
7568  if (Blocked == 0)
7569  {
7570  State = cUiGetPress(Button);
7571  }
7572  *(DATA8*)PrimParPointer() = State;
7573  }
7574  break;
7575 
7576  case LONGPRESS :
7577  {
7578  Button = *(DATA8*)PrimParPointer();
7579 
7580  if (Blocked == 0)
7581  {
7582  State = cUiGetLongPress(Button);
7583  }
7584  *(DATA8*)PrimParPointer() = State;
7585  }
7586  break;
7587 
7588  case FLUSH :
7589  {
7590  if (Blocked == 0)
7591  {
7592  cUiButtonFlush();
7593  }
7594  }
7595  break;
7596 
7597  case WAIT_FOR_PRESS :
7598  {
7599  if (Blocked == 0)
7600  {
7601  if (cUiWaitForPress() == 0)
7602  {
7603  SetObjectIp(TmpIp - 1);
7605  }
7606  }
7607  else
7608  {
7609  SetObjectIp(TmpIp - 1);
7611  }
7612  }
7613  break;
7614 
7615  case GET_HORZ :
7616  {
7617  if (Blocked == 0)
7618  {
7619  Inc = cUiGetHorz();
7620  }
7621  *(DATA16*)PrimParPointer() = Inc;
7622  }
7623  break;
7624 
7625  case GET_VERT :
7626  {
7627  if (Blocked == 0)
7628  {
7629  Inc = cUiGetVert();
7630  }
7631  *(DATA16*)PrimParPointer() = Inc;
7632  }
7633  break;
7634 
7635  case SET_BACK_BLOCK :
7636  {
7637  UiInstance.BackButtonBlocked = *(DATA8*)PrimParPointer();
7638  }
7639  break;
7640 
7641  case GET_BACK_BLOCK :
7642  {
7643  *(DATA8*)PrimParPointer() = UiInstance.BackButtonBlocked;
7644  }
7645  break;
7646 
7647  case TESTSHORTPRESS :
7648  {
7649  Button = *(DATA8*)PrimParPointer();
7650 
7651  if (Blocked == 0)
7652  {
7653  State = cUiTestShortPress(Button);
7654  }
7655  *(DATA8*)PrimParPointer() = State;
7656  }
7657  break;
7658 
7659  case TESTLONGPRESS :
7660  {
7661  Button = *(DATA8*)PrimParPointer();
7662 
7663  if (Blocked == 0)
7664  {
7665  State = cUiTestLongPress(Button);
7666  }
7667  *(DATA8*)PrimParPointer() = State;
7668  }
7669  break;
7670 
7671  case GET_CLICK :
7672  {
7673  *(DATA8*)PrimParPointer() = UiInstance.Click;
7674  UiInstance.Click = 0;
7675  }
7676  break;
7677 
7678  }
7679 }
7680 
7681 
7697 void cUiKeepAlive(void)
7698 {
7699  cUiAlive();
7701 }
7702 
7703 
7704 //*****************************************************************************
ULONG SleepTimer
Definition: c_ui.h:351
DATA16 * pSpan
Definition: c_ui.h:72
#define BUTTON_BUMBED
button has been pressed and released
Definition: c_ui.h:305
DATA16 ScreenStartX
Definition: c_ui.h:120
DATA8 Event
Definition: c_ui.h:426
DATA8 cUiWaitForPress(void)
Definition: c_ui.c:1560
#define DATA32_NAN
Definition: bytecodes.h:1494
DSPSTAT ExecuteByteCode(IP pByteCode, GP pGlobals, LP pLocals)
Execute byte code stream (C-call)
Definition: lms2012.c:535
OBJID ObjId
Definition: c_ui.h:228
#define FWVERS_SIZE
Definition: c_ui.h:294
void SetDispatchStatus(DSPSTAT DspStat)
Set object (dispatch) status.
Definition: lms2012.c:256
DATA8 cUiKeyboard(DATA8 Color, DATA16 X, DATA16 Y, DATA8 Icon, DATA8 Lng, DATA8 *pText, DATA8 *pCharSet, DATA8 *pAnswer)
Definition: c_ui.c:3281
RESULT cUiUpdateInput(void)
Definition: c_ui.c:1036
#define GRAPH_BUFFERS
Definition: c_ui.h:31
#define vmPOP3_ABS_WARN_YES_X
Definition: bytecodes.h:1559
void cUiTextboxReadLine(DATA8 *pText, DATA32 Size, DATA8 Del, DATA8 Lng, DATA16 Line, DATA8 *pLine, DATA8 *pFont)
Definition: c_ui.c:4806
DATAF CinCnt
Definition: c_ui.h:363
#define BUTTON_PRESSED
button is pressed at the moment
Definition: c_ui.h:302
UI_GLOBALS * gUiInstance
Definition: c_ui.c:202
char Char
Definition: tistdtypes.h:54
#define LCD_STORE_LEVELS
Store levels.
Definition: lms2012.h:199
#define BUTTON_SET
Definition: c_ui.h:317
const DATA8 FiletypeToNormalIcon[FILETYPES]
Definition: c_ui.c:2751
#define BUTTON_FLUSH
Definition: c_ui.h:309
#define vmPOP3_ABS_WARN_ICON_X2
Definition: bytecodes.h:1552
#define Run
IMGDATA DownloadSuccesSound[]
Definition: c_ui.c:568
void cUiButtonFlush(void)
Definition: c_ui.c:589
float K_elec_to_room
Definition: c_ui.c:248
RESULT cMemoryGetImage(DATA8 *pFileName, DATA16 Size, UBYTE *pBmp)
Definition: c_memory.c:1480
DATA8 VoltShutdown
Definition: c_ui.h:408
IMGDATA Globals[MAX_COMMAND_GLOBALS]
Definition: c_ui.h:453
DATAF * pMax
Definition: c_ui.h:69
void cUiUpdatePower(void)
Definition: c_ui.c:1621
IQUESTION IconQuestion
Definition: c_ui.h:340
DATA8 BtOn
Definition: c_ui.h:416
UBYTE PowerInitialized
Definition: c_ui.h:377
void dLcdScroll(UBYTE *pImage, DATA16 Y0)
Definition: d_lcd.c:522
DATA8 Font
Definition: c_ui.h:430
UBYTE VARDATA
Variable base type.
Definition: lmstypes.h:68
#define BG_COLOR
Background color.
Definition: lms2012.h:204
DATA8 WiFiOn
Definition: c_ui.h:417
void cUiWriteString(DATA8 *pString)
Definition: c_ui.c:1149
DATA8 GetTerminalEnable(void)
Definition: lms2012.c:354
int UiFile
Definition: c_ui.h:347
DATA16 BattIndicatorLow
Definition: c_ui.h:420
Break because of fail.
Definition: lms2012.h:674
void cUiButton(void)
opUI_BUTTON byte code
Definition: c_ui.c:7487
DATA8 CheckUsbstick(DATA8 *pChanged, DATA32 *pTotal, DATA32 *pFree, DATA8 Force)
Definition: lms2012.c:1959
SWORD DATA16
VM Type for 2 byte signed value.
Definition: lmstypes.h:62
#define vmPOP3_ABS_WARN_YES_Y
Definition: bytecodes.h:1560
DATA16 dLcdGetFontWidth(DATA8 Font)
Definition: d_lcd.c:790
void LogErrorNumber(ERR Err)
Definition: lms2012.c:445
#define TOP_BATT_ICONS
Definition: c_ui.c:1702
char FwVers[FWVERS_SIZE]
Definition: c_ui.h:445
SLONG DATA32
VM Type for 4 byte signed value.
Definition: lmstypes.h:63
DATAF BattShutdownHigh
Definition: c_ui.h:423
DATAF * pVal
Definition: c_ui.h:70
BROWSER Browser
Definition: c_ui.h:341
#define VCE
Definition: c_ui.c:1585
DATA8 Name[FILENAME_SIZE]
Definition: lms2012.h:762
#define MAX_NOTIFY_LINE_CHARS
Definition: c_ui.h:35
UBYTE dLcdRead(void)
Definition: d_lcd.c:199
void cMemoryCloseFolder(PRGID PrgId, HANDLER *pHandle)
Definition: c_memory.c:2064
DATA8 BackButtonBlocked
Definition: c_ui.h:386
UBYTE TopLineBattIconMap[TOP_BATT_ICONS]
Definition: c_ui.c:1703
#define MAX_KEYB_WIDTH
Definition: c_ui.c:3278
UWORD OBJID
Object id type.
Definition: lmstypes.h:73
void cUiSetPress(DATA8 Button, DATA8 Press)
Definition: c_ui.c:1198
#define LCDCopy(S, D, L)
Definition: d_lcd.h:82
#define OSBUILD_SIZE
Definition: c_ui.h:297
#define vmPOP3_ABS_WARN_SPEC_ICON_Y
Definition: bytecodes.h:1556
Definition: c_ui.h:195
void SetObjectIp(IP Ip)
Set current instruction pointer.
Definition: lms2012.c:309
PRGID ScreenPrgId
Definition: c_ui.h:401
RESULT ValidateChar(DATA8 *pChar, DATA8 Set)
Definition: lms2012.c:5680
UBYTE cComGetBtStatus(void)
Definition: c_com.c:5557
void cUiDownloadSuccesSound(void)
Definition: c_ui.c:570
#define AVR_VIN
Definition: c_ui.c:1590
char * strptime(const char *s, const char *format, struct tm *tm)
void dLcdInit(UBYTE *pImage)
Definition: d_lcd.c:179
void cUiUpdateCnt(void)
Definition: c_ui.c:1595
DATA8 cUiEscape(void)
Definition: c_ui.c:1091
char FwBuild[FWBUILD_SIZE]
Definition: c_ui.h:446
#define FINAL
Final prototype.
Definition: lms2012.h:101
DATA8 cUiGetBumbed(DATA8 Button)
Definition: c_ui.c:1364
DATA8 cUiTestShortPress(DATA8 Button)
Definition: c_ui.c:1267
NOTIFY Notify
Definition: c_ui.h:338
ANALOG * pAnalog
Definition: c_ui.h:336
void cUiRead(void)
opUI_READ byte code
Definition: c_ui.c:6614
ULONG UpdateStateTimer
Definition: c_ui.h:380
void cUiUpdateLcd(void)
Definition: c_ui.c:1912
char IpAddr[IPADDR_SIZE]
Definition: c_ui.h:449
DATA16 HANDLER
Memory list index.
Definition: lmstypes.h:85
DATA16 GraphStartX
Definition: c_ui.h:75
#define AVR_COUT
Definition: c_ui.c:1589
void cUiFlush(void)
opUI_FLUSH byte code
Definition: c_ui.c:6497
RESULT cUiTextbox(DATA16 X, DATA16 Y, DATA16 X1, DATA16 Y1, DATA8 *pText, DATA32 Size, DATA8 Del, DATA16 *pLine)
Definition: c_ui.c:4851
void dLcdDrawText(UBYTE *pImage, DATA8 Color, DATA16 X0, DATA16 Y0, DATA8 Font, DATA8 *pText)
Definition: d_lcd.c:936
void * PrimParPointer(void)
Get next encoded parameter from byte code stream.
Definition: lms2012.c:694
void cUiGraphSetup(DATA16 StartX, DATA16 SizeX, DATA8 Items, DATA16 *pOffset, DATA16 *pSpan, DATAF *pMin, DATAF *pMax, DATAF *pVal)
Definition: c_ui.c:5031
#define DATA8_NAN
Definition: bytecodes.h:1492
GRAPH Graph
Definition: c_ui.h:343
DATA8 KeyBuffer[KEYBUF_SIZE+1]
Definition: c_ui.h:434
DATAF * pMin
Definition: c_ui.h:68
float battery_power_boost
Definition: c_ui.c:237
void dLcdDrawIcon(UBYTE *pImage, DATA8 Color, DATA16 X0, DATA16 Y0, DATA8 Type, DATA8 No)
Definition: d_lcd.c:1072
#define BUTTON_BUFPRINT
Definition: c_ui.h:315
DATAF BattWarningHigh
Definition: c_ui.h:421
IP GetObjectIp(void)
Get current instruction pointer.
Definition: lms2012.c:298
DATA8 cMemoryGetCacheName(DATA8 Item, DATA8 MaxLength, char *pFileName, char *pName)
Definition: c_memory.c:986
DATA8 ShutDown
Definition: c_ui.h:404
DATAF Vbatt
Definition: c_ui.h:372
DATA8 cUiNotification(DATA8 Color, DATA16 X, DATA16 Y, DATA8 Icon1, DATA8 Icon2, DATA8 Icon3, DATA8 *pText, DATA8 *pState)
Definition: c_ui.c:2763
DATA8 cUiQuestion(DATA8 Color, DATA16 X, DATA16 Y, DATA8 Icon1, DATA8 Icon2, DATA8 *pText, DATA8 *pState, DATA8 *pAnswer)
Definition: c_ui.c:2979
DATA8 Escape
Definition: c_ui.h:389
UI_GLOBALS * getUiInstance()
Definition: c_ui.c:209
KEYB Keyboard
Definition: c_ui.h:342
RESULT dTerminalExit(void)
Definition: d_terminal.c:155
UI UiSafe
Definition: c_ui.h:332
void cUiCheckTemp(void)
Definition: c_ui.c:2376
ULONG RunScreenTimer
Definition: c_ui.h:354
DATA8 LedState
Definition: c_ui.h:391
DATA8 RunLedEnabled
Definition: c_ui.h:385
#define FWBUILD_SIZE
Definition: c_ui.h:295
OBJID CallingObjectId(void)
Get calling object id.
Definition: lms2012.c:196
#define LCD_WIDTH
LCD horizontal pixels.
Definition: lms2012.h:196
DATA8 PowerState
Definition: c_ui.h:407
void dLcdDrawLine(UBYTE *pImage, DATA8 Color, DATA16 X0, DATA16 Y0, DATA16 X1, DATA16 Y1)
Definition: d_lcd.c:571
#define REAL_ANY_BUTTON
Definition: c_ui.c:1163
DATA16 Pointer
Definition: c_ui.h:74
OBJSTAT ProgramStatus(PRGID PrgId)
Get program status.
Definition: lms2012.c:218
DATA16 cUiGetVert(void)
Definition: c_ui.c:1543
OBJID ScreenObjId
Definition: c_ui.h:402
#define snprintf
Definition: c_ui.c:199
void cUiWrite(void)
opUI_WRITE byte code
Definition: c_ui.c:7115
IMGDATA ImageBuffer[IMAGEBUFFER_SIZE]
Definition: c_ui.h:432
DATA8 TopLineEnabled
Definition: c_ui.h:383
#define vmPOP3_ABS_WARN_ICON_X1
Definition: bytecodes.h:1551
IMGDATA * IP
Instruction pointer type.
Definition: lmstypes.h:74
RESULT dTerminalWrite(UBYTE *pData, UWORD Cnt)
Definition: d_terminal.c:149
#define KEYBUF_SIZE
Definition: c_ui.h:28
#define BUTTON_CLR
Definition: c_ui.h:308
DATAF Buffer[GRAPH_BUFFERS][GRAPH_BUFFER_SIZE]
Definition: c_ui.h:73
DATA8 RunScreenNumber
Definition: c_ui.h:387
ULONG CurrentObjectIp(void)
Definition: lms2012.c:333
void dLcdDrawChar(UBYTE *pImage, DATA8 Color, DATA16 X0, DATA16 Y0, DATA8 Font, DATA8 Char)
Definition: d_lcd.c:802
DATA8 GetSleepMinutes(void)
Definition: lms2012.c:390
void cUiTextboxAppendLine(DATA8 *pText, DATA32 Size, DATA8 Del, DATA8 *pLine, DATA8 Font)
Definition: c_ui.c:4721
void cUiGraphSample(void)
Definition: c_ui.c:5076
#define CALL_INTERVAL
Definition: c_ui.c:457
unsigned int ULONG
Basic Type used to symbolise 32 bit unsigned values.
Definition: lmstypes.h:31
UBYTE TopLineWifiIconMap[TOP_WIFI_ICONS]
Definition: c_ui.c:1724
#define MAX_NOTIFY_LINES
Definition: c_ui.h:34
DATA8 cUiButtonRemap(DATA8 Mapped)
Definition: c_ui.c:1181
void cUiKeepAlive(void)
opKEEP_ALIVE byte code
Definition: c_ui.c:7697
DATA16 dLcdGetFontHeight(DATA8 Font)
Definition: d_lcd.c:796
ULONG MilliSeconds
Definition: c_ui.h:353
PRGID PrgId
Definition: c_ui.h:227
void cUiTestpin(DATA8 State)
Definition: c_ui.c:1102
#define UI_WR_BUFFER_SIZE
Definition: c_ui.h:29
#define IMAGEBUFFER_SIZE
Definition: c_ui.h:27
DATA16 cUiAlignX(DATA16 X)
Definition: c_ui.c:1570
DATA8 VoltageState
Definition: c_ui.h:409
float K_bat_loss_to_elec
Definition: c_ui.c:231
DATA8 RunScreenEnabled
Definition: c_ui.h:384
#define vmPOP3_ABS_WARN_LINE_ENDX
Definition: bytecodes.h:1563
DATA8 cComGetUsbStatus(void)
Definition: c_com.c:2831
DATA32 cUiTextboxFindLine(DATA8 *pText, DATA32 Size, DATA8 Del, DATA16 Line, DATA8 *pFont)
Definition: c_ui.c:4754
#define OSVERS_SIZE
Definition: c_ui.h:296
DATA16 ButtonDebounceTimer[BUTTONS]
Definition: c_ui.h:395
void dLcdUpdate(LCD *pDisp)
Definition: d_lcd.c:167
DATA8 Click
Definition: c_ui.h:428
DATAF CoutCnt
Definition: c_ui.h:364
DATAF BattWarningLow
Definition: c_ui.h:422
DATA16 GraphSizeX
Definition: c_ui.h:76
DATA16 ButtonTimer[BUTTONS]
Definition: c_ui.h:394
#define vmPOP3_ABS_WARN_ICON_X
Definition: bytecodes.h:1550
DSPSTAT cMemoryCloseFile(PRGID PrgId, HANDLER Handle)
Definition: c_memory.c:1421
#define UiInstance
Definition: c_ui.h:460
#define TEXTSIZE
Definition: c_ui.h:193
void cUiUpdateButtons(DATA16 Time)
Definition: c_ui.c:931
#define BUTTON_LONG_LATCH
Definition: c_ui.h:306
#define CNT_V(C)
Definition: c_ui.c:1592
LCD LcdSafe
Definition: c_ui.h:326
DATA8 Accu
Definition: c_ui.h:405
float K_elec_loss_to_bat
Definition: c_ui.c:244
void cUiRunScreen(void)
Definition: c_ui.c:1932
DATA8 ScreenBusy
Definition: c_ui.h:399
#define IPADDR_SIZE
Definition: c_ui.h:298
RESULT cUiExit(void)
Definition: c_ui.c:898
#define BUTTON_LONGPRESS
button long press detected
Definition: c_ui.h:304
DATA8 KeyBufIn
Definition: c_ui.h:435
#define FINALB
Schematics revision B and C.
Definition: lms2012.h:100
LCD LcdPool[LCD_STORE_LEVELS]
Definition: c_ui.h:328
DATA8 UiUpdate
Definition: c_ui.h:414
#define DATAF_NAN
Definition: bytecodes.h:1495
UI * pUi
Definition: c_ui.h:333
void cUiUpdateTopline(void)
Definition: c_ui.c:1733
#define vmPOP3_ABS_WARN_ICON_Y
Definition: bytecodes.h:1554
DATA8 cUiTestLongPress(DATA8 Button)
Definition: c_ui.c:1412
RESULT cMemoryGetItemName(PRGID PrgId, HANDLER Handle, DATA16 Item, DATA8 Length, DATA8 *pName, DATA8 *pType, DATA8 *pPriority)
Definition: c_memory.c:1815
void cMemoryGetUsage(DATA32 *pTotal, DATA32 *pFree, DATA8 Force)
Definition: c_memory.c:104
RESULT dTerminalRead(UBYTE *pData)
Definition: d_terminal.c:143
#define BUTTON_ACTIVE
Definition: c_ui.h:301
DATA8 WarningConfirmed
Definition: c_ui.h:413
DATA16 dLcdGetIconHeight(DATA8 Type)
Definition: d_lcd.c:1017
DATA16 dLcdGetIconWidth(DATA8 Type)
Definition: d_lcd.c:1011
RESULT cMemoryGetItemText(PRGID PrgId, HANDLER Handle, DATA16 Item, DATA8 Length, DATA8 *pText)
Definition: c_memory.c:1921
#define vmPOP3_ABS_WARN_SPEC_ICON_X
Definition: bytecodes.h:1555
#define LCS
Definition: bytecodes.h:1611
RESULT cUiOpen(void)
Definition: c_ui.c:859
#define LC0(v)
Definition: bytecodes.h:1615
#define AVR_CIN
Definition: c_ui.c:1588
DATA8 WarningShowed
Definition: c_ui.h:412
#define AMP_COUT
Definition: c_ui.c:1583
void cUiSetLed(DATA8 State)
Definition: c_ui.c:600
RESULT cUiBrowser(DATA8 Type, DATA16 X, DATA16 Y, DATA16 X1, DATA16 Y1, DATA8 Lng, DATA8 *pType, DATA8 *pAnswer)
Definition: c_ui.c:3692
void dLcdInverseRect(UBYTE *pImage, DATA16 X0, DATA16 Y0, DATA16 X1, DATA16 Y1)
Definition: d_lcd.c:1274
DATA8 cUiGetPress(DATA8 Button)
Definition: c_ui.c:1236
#define BUTTON_ALIVE
Definition: c_ui.h:313
DATA8 MappedToReal[BUTTONTYPES]
Definition: c_ui.c:1167
void cUiCheckAlive(UWORD Time)
Definition: c_ui.c:2441
DATA8 CharSet
Definition: c_ui.h:188
DATA16 ButtonRepeatTimer[BUTTONS]
Definition: c_ui.h:396
#define IFNAMSIZ
Definition: common.h:318
LCD * pLcd
Definition: c_ui.h:330
#define LV0(i)
Definition: bytecodes.h:1621
ULONG VoltageTimer
Definition: c_ui.h:356
#define TOP_BT_ICONS
Definition: c_ui.c:1713
#define LCDClearTopline(I)
Definition: d_lcd.h:78
void ProgramEnd(PRGID PrgId)
Exit program nicely (freeing up memory)
Definition: lms2012.c:1555
float K_bat_to_room
Definition: c_ui.c:235
unsigned char UBYTE
Basic Type used to symbolise 8 bit unsigned values.
Definition: lmstypes.h:29
float R_bat_init
Definition: c_ui.c:225
void SetTerminalEnable(DATA8 Value)
Definition: lms2012.c:348
PRG Program[MAX_PROGRAMS]
Program[0] is the UI byte codes running.
Definition: lms2012.h:1431
DATA8 NeedUpdate
Definition: c_ui.h:237
Definition: c_ui.h:167
DATA8 cMemoryGetCacheFiles(void)
Definition: c_memory.c:1021
#define BUTTONS
Number of buttons in the system.
Definition: lms2012.h:193
void dLcdRect(UBYTE *pImage, DATA8 Color, DATA16 X0, DATA16 Y0, DATA16 X1, DATA16 Y1)
Definition: d_lcd.c:1243
void setUiInstance(UI_GLOBALS *_Instance)
Definition: c_ui.c:204
RESULT cMemoryGetItemIcon(PRGID PrgId, HANDLER Handle, DATA16 Item, HANDLER *pHandle, DATA32 *pImagePointer)
Definition: c_memory.c:1869
HANDLER Handle
Definition: lms2012.h:1474
#define EP2_SHUNT_IN
Definition: c_ui.c:1579
FLOAT DATAF
VM Type for 4 byte floating point value.
Definition: lmstypes.h:64
UBYTE cComGetWifiStatus(void)
Definition: c_com.c:5563
UBYTE TopLineBtIconMap[TOP_BT_ICONS]
Definition: c_ui.c:1714
void cUiButtonClr(void)
Definition: c_ui.c:578
#define LCDClear(I)
Definition: d_lcd.h:76
float R_bat_neg_gain
Definition: c_ui.c:239
unsigned short UWORD
Basic Type used to symbolise 16 bit unsigned values.
Definition: lmstypes.h:30
#define LFILE
Definition: lmstypes.h:39
UBYTE IMGDATA
Image base type.
Definition: lmstypes.h:69
char Buffer[1024]
Definition: c_wifi.c:102
void dLcdDrawDotLine(UBYTE *pImage, DATA8 Color, DATA16 X0, DATA16 Y0, DATA16 X1, DATA16 Y1, DATA16 On, DATA16 Off)
Definition: d_lcd.c:622
void dLcdAutoUpdate(void)
DATA8 Warnlight
Definition: c_ui.h:410
void cComGetBrickName(DATA8 Length, DATA8 *pBrickName)
Definition: c_com.c:5583
#define DataF
#define DATA16_NAN
Definition: bytecodes.h:1493
void cUiGraphDraw(DATA8 View, DATAF *pActual, DATAF *pLowest, DATAF *pHighest, DATAF *pAverage)
Definition: c_ui.c:5130
#define HWVERS_SIZE
Definition: c_ui.h:293
float new_bat_temp(float V_bat, float I_bat)
Definition: c_ui.c:252
#define vmPOP3_ABS_WARN_LINE_X
Definition: bytecodes.h:1561
DATAF Imotor
Definition: c_ui.h:374
DATA8 ButtonState[BUTTONS]
Definition: c_ui.h:393
#define vmPOP3_ABS_WARN_ICON_X3
Definition: bytecodes.h:1553
TXTBOX Txtbox
Definition: c_ui.h:344
DATA8 CheckSdcard(DATA8 *pChanged, DATA32 *pTotal, DATA32 *pFree, DATA8 Force)
Definition: lms2012.c:1855
PRGID CurrentProgramId(void)
Get current program id.
Definition: lms2012.c:207
DATA8 Keys
Definition: c_ui.h:436
DATA32 TempTimer
Definition: c_ui.h:368
RESULT cMemoryGetItem(PRGID PrgId, HANDLER Handle, DATA16 Item, DATA8 Length, DATA8 *pName, DATA8 *pType)
Definition: c_memory.c:2023
DATAF Value
Definition: c_ui.h:81
#define MAX_KEYB_DEEPT
Definition: c_ui.c:3277
#define LCD_BUFFER_SIZE
Definition: lms2012.h:1237
RESULT cUiClose(void)
Definition: c_ui.c:878
#define SHUNT_IN
Definition: c_ui.c:1576
UBYTE AtoN(DATA8 Char)
Definition: c_ui.c:1114
void * VmMemoryResize(HANDLER Handle, DATA32 Elements)
Definition: lms2012.c:366
void dLcdDrawCircle(UBYTE *pImage, DATA8 Color, DATA16 X0, DATA16 Y0, DATA16 R)
Definition: d_lcd.c:710
UWORD PRGID
Program id type.
Definition: lmstypes.h:71
DATAF Tbatt
Definition: c_ui.h:371
#define FG_COLOR
Foreground color.
Definition: lms2012.h:203
TQUESTION Question
Definition: c_ui.h:339
DATA16 * pOffset
Definition: c_ui.h:71
#define SHUNT_OUT
Definition: c_ui.c:1582
LCD LcdSave
Definition: c_ui.h:327
DATAF Ibatt
Definition: c_ui.h:373
DATAF VinCnt
Definition: c_ui.h:365
DATA8 cUiGetLongPress(DATA8 Button)
Definition: c_ui.c:1457
char OsVers[OSVERS_SIZE]
Definition: c_ui.h:447
RESULT cMemoryOpenFolder(PRGID PrgId, DATA8 Type, DATA8 *pFolderName, HANDLER *pHandle)
Definition: c_memory.c:1690
SBYTE DATA8
VM Type for 1 byte signed value.
Definition: lmstypes.h:61
DATA8 Items
Definition: c_ui.h:78
ULONG GetTime(void)
Definition: lms2012.c:315
void dLcdDrawBitmap(UBYTE *pImage, DATA8 Color, DATA16 X0, DATA16 Y0, IP pBitmap)
Definition: d_lcd.c:1105
DATAF Inc
Definition: c_ui.h:82
#define MAX_KEYB_HEIGHT
Definition: c_ui.c:3279
Definition: c_ui.h:256
#define TOPLINE_HEIGHT
Top line vertical pixels.
Definition: lms2012.h:198
int AdcFile
Definition: c_ui.h:348
DATA8 cUiGetShortPress(DATA8 Button)
Definition: c_ui.c:1312
DATA16 cUiTestHorz(void)
Definition: c_ui.c:1509
void cUiCheckMemory(void)
Definition: c_ui.c:2417
RESULT cMemoryGetFolderItems(PRGID PrgId, HANDLER Handle, DATA16 *pItems)
Definition: c_memory.c:1742
#define vmPOP3_ABS_X
Definition: bytecodes.h:1547
void cUiDrawBar(DATA8 Color, DATA16 X, DATA16 Y, DATA16 X1, DATA16 Y1, DATA16 Min, DATA16 Max, DATA16 Act)
Definition: c_ui.c:3577
#define AMP_CIN
Definition: c_ui.c:1577
DATA16 cUiGetHorz(void)
Definition: c_ui.c:1526
#define BUTTON_ACTIVATED
button has been activated since last read
Definition: c_ui.h:303
void dLcdFillRect(UBYTE *pImage, DATA8 Color, DATA16 X0, DATA16 Y0, DATA16 X1, DATA16 Y1)
Definition: d_lcd.c:1254
#define USBSTICK_FOLDER
Definition: lms2012.h:216
void dLcdDrawFilledCircle(UBYTE *pImage, DATA8 Color, DATA16 X0, DATA16 Y0, DATA16 R)
Definition: d_lcd.c:1303
DATA8 Hw
Definition: c_ui.h:451
ANALOG Analog
Definition: c_ui.h:335
void dLcdDrawPicture(UBYTE *pImage, DATA8 Color, DATA16 X0, DATA16 Y0, DATA16 IconWidth, DATA16 IconHeight, UBYTE *pIconBits)
Definition: d_lcd.c:1029
Definition: c_ui.h:87
DSPSTAT
Definition: lms2012.h:665
void cUiCheckVoltage(void)
Definition: c_ui.c:2128
DATAF BattShutdownLow
Definition: c_ui.h:424
#define vmPOP3_ABS_Y
Definition: bytecodes.h:1548
RESULT cUiIconQuestion(DATA8 Color, DATA16 X, DATA16 Y, DATA8 *pState, DATA32 *pIcons)
Definition: c_ui.c:3113
DATA16 BattIndicatorHigh
Definition: c_ui.h:419
Object is stopped or not triggered yet.
Definition: bytecodes.h:1517
float heat_cap_bat
Definition: c_ui.c:229
#define EP2_AMP_CIN
Definition: c_ui.c:1580
DATA8 cComGetEvent(void)
Definition: c_com.c:5589
RESULT dTerminalInit(void)
Definition: d_terminal.c:137
GLOBALS VMInstance
Definition: lms2012.c:131
#define REAL_NO_BUTTON
Definition: c_ui.c:1164
DATA8 UpdateState
Definition: c_ui.h:379
DATAF Iintegrated
Definition: c_ui.h:375
Break because of waiting for completion.
Definition: lms2012.h:671
DATA8 Warning
Definition: c_ui.h:411
DATA8 Down
Definition: c_ui.h:83
void dLcdDrawPixel(UBYTE *pImage, DATA8 Color, DATA16 X0, DATA16 Y0)
Definition: d_lcd.c:530
OBJSTAT ProgramStatusChange(PRGID PrgId)
Get program status change.
Definition: lms2012.c:229
UBYTE ReadyForWarnings
Definition: c_ui.h:381
#define SDCARD_FOLDER
Definition: lms2012.h:215
#define LCD_HEIGHT
LCD vertical pixels.
Definition: lms2012.h:197
Dispatcher running (looping)
Definition: lms2012.h:667
DATA8 Activated
Definition: c_ui.h:397
void cUiAlive(void)
Definition: c_ui.c:636
int PowerFile
Definition: c_ui.h:346
void cUiDraw(void)
opUI_DRAW byte code
Definition: c_ui.c:5545
float K_bat_gain_from_elec
Definition: c_ui.c:233
#define vmPOP3_ABS_WARN_LINE_Y
Definition: bytecodes.h:1562
char OsBuild[OSBUILD_SIZE]
Definition: c_ui.h:448
DATA8 Initialized
Definition: c_ui.h:79
DATA16 cUiTextboxGetLines(DATA8 *pText, DATA32 Size, DATA8 Del)
Definition: c_ui.c:4687
void cUiUpdate(UWORD Time)
Definition: c_ui.c:2464
DATA16 UiWrBufferSize
Definition: c_ui.h:439
#define TOP_WIFI_ICONS
Definition: c_ui.c:1723
float K_elec_heat_slope
Definition: c_ui.c:242
DATA16 ScreenStartX
Definition: c_ui.h:89
DATA8 UiWrBuffer[UI_WR_BUFFER_SIZE]
Definition: c_ui.h:438
float K_elec_gain_from_bat
Definition: c_ui.c:246
DATA8 PowerShutdown
Definition: c_ui.h:406
IP OffsetToInstructions
Offset to instructions from image start.
Definition: lmstypes.h:169
void cUiFlushBuffer(void)
Definition: c_ui.c:1136
RESULT cUiInit(void)
Definition: c_ui.c:642
char HwVers[HWVERS_SIZE]
Definition: c_ui.h:444
DATA8 ScreenBlocked
Definition: c_ui.h:400
DATA8 RunScreenCounter
Definition: c_ui.h:388
int Hw
Definition: d_analog.c:317
#define AMP_VIN
Definition: c_ui.c:1586
#define NULL