CircleOS  1
Util.c
Go to the documentation of this file.
1 /****************** COPYRIGHT (C) 2007-2013 KEOLABS S.A.S. ********************/
14 /******************************************************************************/
15 
16 /* Includes ------------------------------------------------------------------*/
17 #include "circle.h"
18 # if DMA2D_AVAIL
19 # include "DMA2D_Graphic.h"
20 #endif
21 
23 
24 /* Private defines -----------------------------------------------------------*/
25 
26 /* Private typedef -----------------------------------------------------------*/
27 enum eSpeed CurrentSpeed;
28 
29 /* Private variables ---------------------------------------------------------*/
30 bool fTemperatureInFahrenheit = 0;
32 /* External variables --------------------------------------------------------*/
33 #if SDCARD_AVAIL
34 extern VOLINFO volume_info;
35 extern DIRINFO directory_info;
36 #endif
37 
38 /* Private function prototypes -----------------------------------------------*/
39 static void _int2str( u8* ptr, int_t X, len_t digit, bool flagunsigned, bool fillwithzero );
40 
41 /* Private functions ---------------------------------------------------------*/
42 /*******************************************************************************
43 *
44 * vbattoa
45 *
46 *******************************************************************************/
57 /******************************************************************************/
58 NODEBUG void vbattoa( u8* ptr, u16 X )
59 {
60  u8 c;
61  u16 r = 0;
62 
63  /* 1 000 digit*/
64  c = ( ( X - r ) / 1000 );
65  r = r + ( c * 1000 );
66  *ptr++ = c + 0x30;
67 
68  /* Dot*/
69  *ptr++ = '.';
70 
71  /* 100 digit*/
72  c = ( ( X - r ) / 100 );
73  r = r + ( c * 100 );
74  *ptr++ = c + 0x30;
75 
76  /* 10 digit*/
77  c = ( ( X - r ) / 10 );
78  r = r + ( c * 10 );
79  *ptr++ = c + 0x30;
80 
81  /* Volt*/
82  *ptr++ = 'V';
83  *ptr++ = 0;
84 }
85 
86 /*******************************************************************************
87 *
88 * _int2str
89 *
90 *******************************************************************************/
103 /******************************************************************************/
104 NODEBUG static void _int2str( u8* ptr, int_t X, len_t digit, bool flagunsigned, bool fillwithzero )
105 {
106  u8 c;
107  bool fFirst = 0;
108  bool fNeg = 0;
109  uint_t DIG = 1;
110  len_t i;
111  int_t r;
112 
113  for ( i = 1; i < digit; i++ )
114  {
115  DIG *= 10;
116  }
117 
118  if ( !flagunsigned && ( X < 0 ) )
119  {
120  fNeg = 1;
121  r = -X;
122  }
123  else
124  {
125  r = X;
126  }
127 
128  for ( i = 0; i < digit; i++, DIG /= 10 )
129  {
130  c = ( r / DIG );
131  r -= ( c * DIG );
132 
133  if ( fillwithzero || fFirst || c || ( i == ( digit - 1 ) ) )
134  {
135  if ( ( fFirst == 0 ) && !flagunsigned )
136  {
137  *ptr++ = fNeg ? '-' : ' ';
138  }
139 
140  *ptr++ = ( c % 10 ) + '0';
141  fFirst = 1;
142  }
143  else
144  {
145  *ptr++ = ' ';
146  }
147  }
148 
149  *ptr++ = '\0';
150 }
151 
152 /* Public functions for CircleOS ---------------------------------------------*/
153 
154 
156 
157 /* Public functions ----------------------------------------------------------*/
158 
159 /*******************************************************************************
160 *
161 * UTIL_SetTempMode
162 *
163 *******************************************************************************/
171 /******************************************************************************/
172 void UTIL_SetTempMode( bool mode )
173 {
174  fTemperatureInFahrenheit = mode;
175 
176  return;
177 }
178 
179 /*******************************************************************************
180 *
181 * UTIL_uint2str
182 *
183 *******************************************************************************/
197 /********************************************************************************/
198 void UTIL_uint2str( u8* ptr, uint_t X, len_t digit, bool fillwithzero )
199 {
200  _int2str( ptr, X, digit, 1, fillwithzero );
201 }
202 
203 /*******************************************************************************
204 *
205 * UTIL_int2str
206 *
207 *******************************************************************************/
221 /******************************************************************************/
222 void UTIL_int2str( u8* ptr, int_t X, len_t digit, bool fillwithzero )
223 {
224  _int2str( ptr, X, digit, 0, fillwithzero );
225 }
226 
227 /*******************************************************************************
228 *
229 * UTIL_GetPll
230 *
231 *******************************************************************************/
239 /******************************************************************************/
240 enum eSpeed UTIL_GetPll( void )
241 {
242  return CurrentSpeed;
243 }
244 
245 /*******************************************************************************
246 *
247 * UTIL_GetVersion
248 *
249 *******************************************************************************/
257 /******************************************************************************/
258 char* UTIL_GetVersion( void )
259 {
260  return STR_OSVERSION;
261 }
262 
263 
264 /*******************************************************************************
265 *
266 * UTIL_SetSchHandler
267 *
268 *******************************************************************************/
283 /********************************************************************************/
284 void UTIL_SetSchHandler( enum eSchHandler Ix, tHandler pHDL )
285 {
286 #if ( MEMS_POINTER && MEMS_SPEC_MNGT ) // Not necessary if no MEMS menu handling
287  if ( !Ix )
288  pMEMS_Handler = pHDL;
289  else
290 #endif
291  {
292  if ( Ix < COUNTOF( SchHandler ) )
293  SchHandler[Ix] = pHDL;
294  }
295 }
296 
297 /*******************************************************************************
298 *
299 * UTIL_GetSchHandler
300 *
301 *******************************************************************************/
315 /********************************************************************************/
316 tHandler UTIL_GetSchHandler( enum eSchHandler Ix )
317 {
318 #if (MEMS_POINTER && MEMS_SPEC_MNGT) // Not necessary if no MEMS menu handling
319  if ( !Ix )
320  return pMEMS_Handler;
321  else
322 #endif
323  {
324  if ( Ix < COUNTOF( SchHandler ) )
325  return SchHandler[Ix];
326  else
327  return 0;
328  }
329 }
330 
331 /*******************************************************************************
332 *
333 * UTIL_IsStandAloneMode
334 *
335 *******************************************************************************/
344 /********************************************************************************/
346 {
347  return fIsStandAlone;
348 }
349 
350 
351 /*******************************************************************************
352 *
353 * UTIL_GetBatStatus
354 *
355 *******************************************************************************/
365 /******************************************************************************/
366 u16 UTIL_GetBatStatus( void )
367 {
368  return POWER_ReadStatus( );
369 }
370 
371 /*******************************************************************************
372 * Function Name : UTIL_SaveScreenBMP
373 * Description : Utility to capture/save the current screen on the SD card
374 * The format is the standard Windows 24-bit BMP (no compression).
375 * Input : filename: path of the BMP file on the SD card
376 * Return : (!=0) if error (SD file access...)
377 * 0 if OK
378 * IMPORTANT NOTE : The BMP format requires 32 bit alignment between lines.
379 * This alignment is made automatically as long as width
380 * is a multiple of 4. If NOT, padding with 0 should be added
381 * to the functions (not done in this first version).
382 *******************************************************************************/
383 NODEBUG2 uint_t UTIL_SaveScreenBMP( char* filename )
384 {
385  uint_t retval = 0;
386 
387 #if SDCARD_AVAIL
388 
389 #define WRITE_VALUE(type,val) {value = (val); *(type*)(localbuf+ofs) = value;ofs+=sizeof(type);}
390 
391  FILEINFO file_capture; //current file handler
392  char localbuf[ 2 + 12 + 40 + 1];
393  unsigned size, ofs, value;
394  s16 x, y;
395  u32 successcount;
396  unsigned width = PHYS_SCREEN_WIDTH; //240 for OP4
397  unsigned height = PHYS_SCREEN_HEIGHT; //320 for OP4
398 
399  //FL130829 Crash with STM32F429 because of the inversion of height/width in horizontal mode
400  if ( ( LCD_GetScreenOrientation() % 2 ) == 1 )
401  {
402  width = PHYS_SCREEN_HEIGHT;
403  height = PHYS_SCREEN_WIDTH;
404  }
405 
406 #if DMA2D_AVAIL
408 #endif
409 
410  if ( !filename || !*filename )
411  {
412  DRAW_DisplayStringWithMode( 0, 0, "Filename is missing for UTIL_SaveScreenBMP.", ALL_SCREEN, NORMAL_TEXT, CENTER );
413  return -1;
414  }
415 
416  SD_DeInit();
417 
418  int StartMBR = FS_Mount( MMCSD_SDIO );
419  if ( StartMBR != FR_OK )
420  {
421  DRAW_DisplayStringWithMode( 0, 0, "No SD Card.", ALL_SCREEN, NORMAL_TEXT, CENTER );
422  return -1;
423  }
424 
425  // Open volume on first partition (0)
426  if ( FS_GetVolumeInfo( 0, StartMBR, &volume_info ) )
427  {
428  DRAW_DisplayStringWithMode( 0, 0, "Invalid SD Card format.", ALL_SCREEN, NORMAL_TEXT, CENTER );
429  return -1;
430  }
431 
432  if ( FS_OpenFile( &volume_info, filename, FS_WRITE | FS_CREATE_ALWAYS, &file_capture ) )
433  {
434  DRAW_DisplayStringWithMode( 0, 0, "Unable to open file.", ALL_SCREEN, NORMAL_TEXT, CENTER );
435  return -1;
436  }
437 
438  //file information
439  localbuf[0] = 'B'; // "BM" stands for a Windows bitmap
440  localbuf[1] = 'M';
441  ofs = 2;
442 
443  size = 2 + 12 + 40 + width * height * 3; //size of the file: type+file_header+image_header+data
444 
445  //file header
446  WRITE_VALUE( unsigned, size ); //total file size
447  WRITE_VALUE( unsigned, 0 ); //useless information coding on 4 bytes
448  WRITE_VALUE( unsigned, 2 + 12 + 40 ); //offset for the position of the image
449 
450  //image header
451  WRITE_VALUE( unsigned, 40 ); //header size
452  WRITE_VALUE( unsigned, width ); //width in pixel
453  WRITE_VALUE( unsigned, height ); //height in pixel
454  WRITE_VALUE( short unsigned, 1 ); //plane=1
455  WRITE_VALUE( short unsigned, 24 ); //24 bits per pixel
456  WRITE_VALUE( unsigned, 0 ); //compression method (none).
457  WRITE_VALUE( unsigned, ( 3 * width * height ) ); //image size
458  WRITE_VALUE( unsigned, 0 ); //
459  WRITE_VALUE( unsigned, 0 ); //
460  WRITE_VALUE( unsigned, 0 ); //number of colors in the palette
461  WRITE_VALUE( unsigned, 0 ); //number of important colors in the palette
462 
463  retval = FS_WriteFile( &file_capture, localbuf, &successcount, 2 + 12 + 40 );
464  size = successcount;
465 
466  //then we save the image itself...
467  int index_wr = 0;
468  for ( y = 0 ; ( y < height ) && ( retval == 0 ) ; y++ )
469  {
470  for ( x = 0 ; ( x < width ) && ( retval == 0 ) ; x++ )
471  {
472  u16 pix;
473  u8 blue, red, green;
474 
475  pix = LCD_GetPixel( x, y );
476 
477  /* RGB is 16-bit coded in CircleOS as G2G1G0B4 B3B2B1B0 R4R3R2R1 R0G5G4G3*/
478  red = ( pix & 0xf8 ); // 5 bits (to be aligned on the left side of a byte)
479  green = ( ( pix << 5 ) & 0xE0 ) | ( ( pix >> 11 ) & 0x1C );
480  blue = ( ( pix >> 5 ) & 0xF8 );
481 
482  localbuf[0 + index_wr * 3] = blue;
483  localbuf[1 + index_wr * 3] = green;
484  localbuf[2 + index_wr * 3] = red;
485  if ( ++index_wr == 4 ) //write data every 4 pixels
486  {
487  retval = FS_WriteFile( &file_capture, localbuf, &successcount, 3 * 4 );
488  size += successcount;
489  index_wr = 0;
490  }
491  }
492  }
493  FS_Close( &file_capture );
494 
495  if ( retval )
496  DRAW_DisplayStringWithMode( 0, 0, "Write access error.", ALL_SCREEN, NORMAL_TEXT, CENTER );
497 
498  FS_Unmount( MMCSD_SDIO );
499 
500 #endif // if SDCARD_AVAIL
501 
502  return retval;
503 }
504 
505 /*******************************************************************************
506 *
507 * UTIL_SetDividerHandler
508 *
509 *******************************************************************************/
521 /********************************************************************************/
522 void UTIL_SetDividerHandler( enum eSchHandler IDx, u16 divider )
523 {
524  SchHandlerDivider[IDx] = divider;
525 }
526 
527 /*******************************************************************************
528 *
529 * UTIL_GetDividerHandler
530 *
531 *******************************************************************************/
543 /********************************************************************************/
545 {
546  return SchHandlerDivider[IDx];
547 }
548