root/platform/generic/wrappers.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. isdigit
  2. isspace
  3. isalpha
  4. isupper
  5. islower
  6. ispunct
  7. isxdigit
  8. tolower
  9. toupper
  10. submenu_sort_arm
  11. msleep
  12. task_lock
  13. task_unlock
  14. task_name
  15. task_id_list_get
  16. get_property_case
  17. set_property_case
  18. get_parameter_size
  19. get_parameter_data
  20. set_parameter_data
  21. get_uiprop_value
  22. mark_filesystem_bootable
  23. vid_bitmap_refresh
  24. lens_get_zoom_pos
  25. lens_get_zoom_point
  26. lens_set_zoom_point
  27. lens_set_zoom_speed
  28. lens_set_zoom_point
  29. lens_set_zoom_speed
  30. lens_set_focus_pos
  31. play_sound
  32. stat_get_vbatt
  33. GetAdChValue
  34. get_battery_temp
  35. get_ccd_temp
  36. get_optical_temp
  37. get_tick_count
  38. PutInNdFilter
  39. PutOutNdFilter
  40. shooting_get_nd_value_ev96
  41. shooting_get_nd_current_ev96
  42. shooting_get_current_tv96
  43. shooting_get_current_av96
  44. IsStrobeChargeCompleted
  45. SetCurrentCaptureModeType
  46. GetUsableMinAv
  47. GetUsableMaxAv
  48. UnsetZoomForMovie
  49. MoveIrisWithAv
  50. ExpCtrlTool_StartContiAE
  51. ExpCtrlTool_StopContiAE
  52. SetAE_ShutterSpeed
  53. takeFileIOSemaphore
  54. open
  55. close
  56. write
  57. read
  58. lseek
  59. mkdir
  60. mkdir_if_not_exist
  61. remove
  62. fw_closedir
  63. get_fstype
  64. fw_opendir
  65. fw_readdir
  66. fw_opendir
  67. fw_readdir
  68. stat
  69. fopen
  70. fclose
  71. fread
  72. fwrite
  73. fseek
  74. feof
  75. fflush
  76. fgets
  77. rename
  78. GetFreeCardSpaceKb
  79. GetTotalCardSpaceKb
  80. errnoOfTaskGet
  81. strlen
  82. strcmp
  83. strncmp
  84. strchr
  85. strcpy
  86. strncpy
  87. strcat
  88. strrchr
  89. strtol
  90. strtoul
  91. strpbrk
  92. sprintf
  93. strerror
  94. time
  95. utime
  96. localtime
  97. strftime
  98. mktime
  99. set_clock
  100. log
  101. log10
  102. pow
  103. sqrt
  104. log2
  105. exmem_alloc_cached
  106. exmem_alloc_uncached
  107. exmem_free_uncached
  108. canon_malloc
  109. canon_free
  110. umalloc
  111. ufree
  112. memcpy
  113. memset
  114. memcmp
  115. memchr
  116. GetMemInfo
  117. rand
  118. srand
  119. qsort
  120. disable_shutdown
  121. enable_shutdown
  122. camera_shutdown_in_a_second
  123. EnterToCompensationEVF
  124. ExitFromCompensationEVF
  125. TurnOnBackLight
  126. TurnOffBackLight
  127. TurnOnDisplay
  128. TurnOffDisplay
  129. DoAELock
  130. UnlockAE
  131. DoAFLock
  132. UnlockAF
  133. EngDrvRead
  134. is_mbr_loaded
  135. mbr_read
  136. mbr_read_dryos
  137. get_part_count
  138. get_part_type
  139. is_partition_changed
  140. swap_partitions
  141. get_active_partition
  142. create_partitions
  143. swap_partitions
  144. get_part_count
  145. get_part_type
  146. get_active_partition
  147. is_partition_changed
  148. mute_on_zoom
  149. MakeAFScan
  150. get_jogdial_direction
  151. JogDial_CW
  152. JogDial_CCW
  153. my_some_f
  154. save_ext_for_dng
  155. change_ext_to_dng
  156. change_ext_to_default
  157. dh_err
  158. drv_self_hide
  159. drv_self_unhide
  160. apex2us
  161. PostLogicalEventForNotPowerType
  162. PostLogicalEventToUI
  163. SetLogicalEventActive
  164. SetScriptMode
  165. vid_get_viewport_width
  166. vid_get_viewport_byte_width
  167. vid_get_viewport_yscale
  168. vid_get_viewport_xoffset
  169. vid_get_viewport_yoffset
  170. vid_get_viewport_display_xoffset
  171. vid_get_viewport_display_yoffset
  172. vid_get_viewport_type
  173. hook_alt_raw_image_addr
  174. vid_turn_off_updates
  175. vid_turn_on_updates
  176. _GetCurrentTargetDistance
  177. add_ptp_handler
  178. get_ptp_file_buf_size
  179. get_ptp_file_buf
  180. CreateTask
  181. ExitTask
  182. _reboot_fw_update
  183. switch_mode_usb
  184. switch_mode_usb
  185. SetFileAttributes
  186. vid_get_viewport_display_xoffset_proper
  187. vid_get_viewport_display_yoffset_proper
  188. vid_get_viewport_buffer_width_proper
  189. vid_get_viewport_width_proper
  190. vid_get_viewport_height_proper
  191. vid_get_viewport_width_proper
  192. vid_get_viewport_height_proper
  193. vid_get_viewport_fullscreen_height
  194. vid_get_viewport_fullscreen_width
  195. vid_get_palette_type
  196. vid_get_palette_size
  197. vid_get_aspect_ratio
  198. vid_get_bitmap_active_buffer
  199. vid_get_bitmap_active_palette
  200. vid_get_viewport_active_buffer
  201. dbg_printf
  202. _srand
  203. _rand
  204. ARM_usb_HPtimer_good
  205. ARM_usb_HPtimer_bad
  206. start_usb_HPtimer
  207. stop_usb_HPtimer
  208. SetHPTimerAfterNow
  209. CancelHPTimer
  210. update_hdmi_power_override
  211. DisableCamError
  212. DebugAssert
  213. CreateBinarySemaphore
  214. TakeSemaphore
  215. GiveSemaphore
  216. SetVideoOutType
  217. GetVideoOutType

   1 #include "camera.h"
   2 #include "lolevel.h"
   3 #include "platform.h"
   4 #include "raw_buffer.h"
   5 #include "conf.h"
   6 #include "math.h"
   7 #include "levent.h"
   8 #include "ptp_chdk.h"
   9 #include "live_view.h"
  10 #include "usb_remote.h"
  11 #include "exmem.h"
  12 #include "stdio.h"
  13 
  14 // arbitrary timeout for canon heap semaphore
  15 #if !CAM_DRYOS
  16 #define CANON_HEAP_SEM_TIMEOUT 1000
  17 extern int canon_heap_sem;
  18 #endif
  19 
  20 //----------------------------------------------------------------------------
  21 // Char Wrappers (VxWorks - ARM stubs)
  22 
  23 #if !CAM_DRYOS
  24 
  25 int isdigit(int c) { return _isdigit(c); }
  26 int isspace(int c) { return _isspace(c); }
  27 int isalpha(int c) { return _isalpha(c); }
  28 int isupper(int c) { return _isupper(c); }
  29 int islower(int c) { return _islower(c); }
  30 int ispunct(int c) { return _ispunct(c); }
  31 int isxdigit(int c) { return _isxdigit(c); }
  32 
  33 int tolower(int c) { return _tolower(c); }
  34 int toupper(int c) { return _toupper(c); }
  35 
  36 #endif
  37 
  38 //----------------------------------------------------------------------------
  39 
  40 int submenu_sort_arm(const void* v1, const void* v2)
  41 {
  42     extern int submenu_sort(const void* v1, const void* v2);
  43     return submenu_sort(v1, v2);
  44 }
  45 
  46 //----------------------------------------------------------------------------
  47 
  48 void msleep(long msec)
  49 {
  50     _SleepTask(msec);
  51 }
  52 
  53 #ifndef CAM_DRYOS
  54 long task_lock()
  55 {
  56     return _taskLock();
  57 }
  58 
  59 long task_unlock()
  60 {
  61     return _taskUnlock();
  62 }
  63 
  64 const char *task_name(int id)
  65 {
  66     return _taskName(id);
  67 }
  68 
  69 int task_id_list_get(int *idlist,int size)
  70 {
  71     return _taskIdListGet(idlist,size);
  72 }
  73 #endif
  74 
  75 long get_property_case(long id, void *buf, long bufsize)
  76 {
  77 // workaround for missing PROPCASE_SHOOTING
  78 #if CAM_PROPSET == 7 || CAM_PROPSET == 9 || CAM_PROPSET == 10 || CAM_PROPSET == 11 || CAM_PROPSET == 12 || CAM_PROPSET == 13
  79     if(id==PROPCASE_SHOOTING) {
  80         int r=_GetPropertyCase(PROPCASE_SHOOTING_STATE, buf, bufsize);
  81         // 1 50ms after half press, 2 after exp hook, 3 while shooting
  82         // propset 6 has similar procase id 351, goes 3->0 when get_shooting goes false
  83         // propset 4 and 5 id 352 is similar but only goes to 2
  84         // (4 per https://chdk.setepontos.com/index.php?topic=11604.msg113712#msg113712)
  85         if(*(char *)buf > 1) {
  86             *(char *)buf = 1;
  87         } else {
  88             *(char *)buf = 0;
  89         }
  90         return r;
  91     }
  92 #endif
  93     return _GetPropertyCase(id, buf, bufsize);
  94 }
  95 
  96 long set_property_case(long id, void *buf, long bufsize)
  97 {
  98     // ignore set on fake prop
  99 #if CAM_PROPSET == 7 || CAM_PROPSET == 9 || CAM_PROPSET == 10 || CAM_PROPSET == 11 || CAM_PROPSET == 12 || CAM_PROPSET == 13
 100     if(id==PROPCASE_SHOOTING) {
 101         return 0;
 102     }
 103 #endif
 104 
 105     return _SetPropertyCase(id, buf, bufsize);
 106 }
 107 
 108 // FlashParamsTable entries point to this structure
 109 #if CAM_FLASHPARAMS_VERSION == 2
 110 // ixus30_sd200, ixus40_sd300
 111 typedef struct
 112 {
 113     short   unk1;
 114     short   unk2;
 115     void*   data;   // Pointer to param data
 116     short   size;   // param size
 117     short   unk3;
 118     int     unk4;
 119     short   unk5;
 120     short   unk6;
 121 } flashParam;
 122 #else
 123 // version 3 (every camera from 2005 on)
 124 typedef struct
 125 {
 126     void*   data;   // Pointer to param data
 127     short   unk1;
 128     short   size;   // param size
 129     short   unk2;
 130     short   unk3;
 131     short   unk4;
 132     char    unk5;
 133     char    unk6;
 134 } flashParam;
 135 #endif // CAM_FLASHPARAMS_VERSION
 136 
 137 short get_parameter_size(long id)
 138 {
 139     extern flashParam* FlashParamsTable[];
 140 
 141     if ((id >= 0) && (id < get_flash_params_count()))
 142         return FlashParamsTable[id]->size;
 143 
 144     return 0;
 145 }
 146 
 147 long get_parameter_data(long id, void *buf, long bufsize)
 148 {
 149     return _GetParameterData(id|PARAMETER_DATA_FLAG, buf, bufsize);
 150 }
 151 
 152 long set_parameter_data(long id, void *buf, long bufsize)
 153 {
 154     return _SetParameterData(id|PARAMETER_DATA_FLAG, buf, bufsize);
 155 }
 156 
 157 short __attribute__((weak)) get_uiprop_value(unsigned long id)
 158 {
 159     // avoid asserts: return 0 if id is above limit
 160     if (id >= (unsigned long)uiprop_count)
 161         return 0;
 162     return _PTM_GetCurrentItem(id|0x8000);
 163 }
 164 
 165 void mark_filesystem_bootable()
 166 {
 167 #ifdef  CAM_DRYOS_2_3_R47
 168     // DryOS release 47 (2011) no longer has the UpdateMBROnFlash function to write the master boot record on
 169     // the SD card. Instead it has seperate functions for writing the 'BOOTDISK' and 'SCRIPT' signatures to
 170     // the MBR. The firmware function also takes care of writing the bootdisk signature to the correct location
 171     // for FAT32 formatted cards.
 172     _MakeSDCardBootable(0);
 173 #else
 174     _UpdateMBROnFlash(0, 0x40, "BOOTDISK");
 175 #endif
 176 }
 177 
 178 // d6 cams must define, don't have usable _RefreshPhysicalScreen
 179 #ifndef THUMB_FW
 180 void __attribute__((weak)) vid_bitmap_refresh()
 181 {
 182     _RefreshPhysicalScreen(1);
 183 }
 184 #endif
 185 
 186 long lens_get_zoom_pos()
 187 {
 188     return _GetZoomLensCurrentPosition();
 189 }
 190 
 191 long lens_get_zoom_point()
 192 {
 193     return _GetZoomLensCurrentPoint();
 194 }
 195 
 196 #ifdef CAM_ILC
 197 void lens_set_zoom_point(__attribute__ ((unused))long newpt) {}
 198 void lens_set_zoom_speed(__attribute__ ((unused))long newspd) {}
 199 #else // !CAM_ILC
 200 
 201 #if defined(CAM_USE_ALT_SET_ZOOM_POINT)
 202 static int mz_speed = 3; // max speed on cameras with multi-speed zoom, ignored on others
 203 #endif
 204 
 205 void lens_set_zoom_point(long newpt)
 206 {
 207     if (newpt < 0) {
 208         newpt = 0;
 209     } else if (newpt >= zoom_points) {
 210         newpt = zoom_points-1;
 211     }
 212 
 213 #if defined(CAM_USE_ALT_SET_ZOOM_POINT)
 214 
 215         if (lens_get_zoom_point() != newpt)
 216         {
 217                 int digizoom_pos;
 218                 get_property_case(PROPCASE_DIGITAL_ZOOM_POSITION,&digizoom_pos,sizeof(digizoom_pos));
 219                 // check current digital zoom mode & state
 220                 // state == 1 && mode == 0 --> Digital Zoom Standard
 221                 if ((shooting_get_digital_zoom_state() == 1) && (shooting_get_digital_zoom_mode() == 0) && (digizoom_pos != 0))
 222                 {
 223                         // reset digital zoom in case camera is in this zoom range
 224                         extern void _PT_MoveDigitalZoomToWide();
 225                         _PT_MoveDigitalZoomToWide();
 226                 }
 227 
 228                 // starting around digic 4 - _MoveZoomLensWithPoint crashes many cameras
 229                 // _PT_MoveOpticalZoomAt works, and updates PROPCASE_OPTICAL_ZOOM_POSITION; but doesn't wait for zoom to finish
 230         // _MoveOpticalZoom at is underlying function that accepts speed
 231         // updates jpeg engine distortion correction setting, maintains focus position
 232                 extern void _MoveOpticalZoomAt(long pt,int speed);
 233                 _MoveOpticalZoomAt(newpt,mz_speed);
 234 
 235                 // have to sleep here, zoom_busy set in another task, without sleep this will hang
 236                 while (zoom_busy) msleep(10);
 237 
 238                 // g10,g12 & sx30 only use this value for optical zoom
 239                 zoom_status=ZOOM_OPTICAL_MAX;
 240         }
 241 #else   // !(CAM_USE_ALT_SET_ZOOM_POINT)
 242     _MoveZoomLensWithPoint((short*)&newpt);
 243 
 244     // tight loop here hangs some cameras (the task that clears zoom_busy
 245     // is starved; seen at least on S95 and IXUS 220), so stick in a sleep
 246     while (zoom_busy) msleep(10);
 247 
 248     if (newpt==0) zoom_status=ZOOM_OPTICAL_MIN;
 249     else if (newpt >= zoom_points) zoom_status=ZOOM_OPTICAL_MAX;
 250     else zoom_status=ZOOM_OPTICAL_MEDIUM;
 251     _SetPropertyCase(PROPCASE_OPTICAL_ZOOM_POSITION, &newpt, sizeof(newpt));
 252 #endif  // !(CAM_USE_ALT_SET_ZOOM_POINT)
 253 }
 254 
 255 void lens_set_zoom_speed(long newspd)
 256 {
 257 // translate % to speed values for _MoveOpticalZoomAt
 258 // which correspond to different speeds varies by camera
 259 #if defined(CAM_USE_ALT_SET_ZOOM_POINT)
 260     if (newspd < 25) {
 261         mz_speed = 0;
 262     } else if (newspd < 50) {
 263         mz_speed = 1;
 264     } else if (newspd < 75) {
 265         mz_speed = 2;
 266     } else {
 267         mz_speed = 3;
 268     }
 269 #else  // !CAM_USE_ALT_SET_ZOOM_POINT
 270     // a few old cameras support setting by %
 271     if (newspd < 5) {
 272         newspd = 5;
 273     } else if (newspd > 100) {
 274         newspd = 100;
 275     }
 276     _SetZoomActuatorSpeedPercent((short*)&newspd);
 277 #endif // !CAM_USE_ALT_SET_ZOOM_POINT
 278 }
 279 #endif // !CAM_ILC
 280 
 281 void lens_set_focus_pos(long newpos)
 282 {
 283     if (newpos >= CAMERA_MAX_DIST) newpos = INFINITY_DIST; // Set to infinity value that will work on all cameras
 284     _MoveFocusLensToDistance((short*)&newpos);
 285     while ((shooting_is_flash_ready()!=1) || (focus_busy)) msleep(10);
 286     newpos = _GetFocusLensSubjectDistance();
 287     _SetPropertyCase(PROPCASE_SUBJECT_DIST1, &newpos, sizeof(newpos));
 288     _SetPropertyCase(PROPCASE_SUBJECT_DIST2, &newpos, sizeof(newpos));
 289 }
 290 
 291 void play_sound(unsigned sound)
 292 {
 293         static const int sounds[]={ 0x2001, //startup sound
 294                                 0x2002, //shutter sound
 295                                 0x2003, //button press sound
 296                                 0x2004, //self-timer sound
 297                                 0xC211, //short beep
 298                                 50000,  // AF confirmation
 299                                 0xC507, // error beep imo
 300                                 0x400D, // LONG ERROR BEEP CONTINIUOUS- warning, cannot be stopped (yet)
 301                             };
 302     if(sound >= sizeof(sounds)/sizeof(sounds[0]))
 303         return;
 304 
 305     _PT_PlaySound(sounds[sound], 0, 0);
 306 }
 307 
 308 long stat_get_vbatt()
 309 {
 310     return _VbattGet();
 311 }
 312 
 313 //========================================================================
 314 // NOTE : some early DryOS cameras need a pointer rather than a value and the 
 315 //        xus30 & 40 want a char * string here. Override this funcion in camera's
 316 //        lib.c file if impelementing remote via battery 3rd terminal functionality.
 317 //        see http://chdk.setepontos.com/index.php?topic=10385.msg109353#msg109353
 318 //
 319 int __attribute__((weak)) GetAdChValue(int channel)        
 320 {
 321 #ifdef CAM_DRYOS
 322     return _GetAdChValue(channel);
 323 #else
 324     return _GetAdChValue(&channel);
 325 #endif
 326 }
 327 
 328 int get_battery_temp()
 329 {
 330     return _GetBatteryTemperature();
 331 }
 332 
 333 int get_ccd_temp()
 334 {
 335     return _GetCCDTemperature();
 336 }
 337 
 338 int get_optical_temp()
 339 {
 340     return _GetOpticalTemperature();
 341 }
 342 
 343 long get_tick_count()
 344 {
 345 long t;
 346 #if !CAM_DRYOS
 347     _GetSystemTime(&t);
 348     return t;
 349 #else
 350     return (int)_GetSystemTime(&t);
 351 #endif
 352 }
 353 
 354 #if CAM_HAS_ND_FILTER
 355 void PutInNdFilter()                { _PutInNdFilter(); }
 356 void PutOutNdFilter()               { _PutOutNdFilter(); }
 357 #endif
 358 
 359 short shooting_get_nd_value_ev96(void)
 360 {
 361 #if CAM_HAS_ND_FILTER
 362     return _get_nd_value();
 363 #else
 364     return 0;
 365 #endif
 366 }
 367 
 368 short shooting_get_nd_current_ev96(void)
 369 {
 370 #if CAM_HAS_ND_FILTER
 371     return _get_current_nd_value();
 372 #else
 373     return 0;
 374 #endif
 375 }
 376 
 377 long shooting_get_current_tv96()
 378 {
 379     // old cameras crash if _GetCurrentShutterSpeed called when inactive
 380     if(!shooting_get_imager_active()) {
 381         return SHOOTING_TV96_INVALID;
 382     }
 383     return _GetCurrentShutterSpeed();
 384 }
 385 long shooting_get_current_av96()    { return _GetCurrentAvValue(); }
 386 
 387 long IsStrobeChargeCompleted()      { return _IsStrobeChargeCompleted(); }
 388 void SetCurrentCaptureModeType()    { _SetCurrentCaptureModeType(); }
 389 
 390 #if CAM_HAS_IRIS_DIAPHRAGM
 391 // returns available Av range in AV96 on cameras with iris.
 392 // Function exists on a few later cameras without iris, behavior unknown.
 393 // Appears to be the full range, including smaller (higher F/ number) than available in Canon UI.
 394 // Note Min = smallest physical aperture = largest Av96 value
 395 short GetUsableMinAv(void) { return _GetUsableMinAv(); }
 396 short GetUsableMaxAv(void) { return _GetUsableMaxAv(); }
 397 #endif
 398 
 399 #if CAM_CAN_UNLOCK_OPTICAL_ZOOM_IN_VIDEO
 400 void UnsetZoomForMovie()            { _UnsetZoomForMovie(); }
 401 #endif
 402 
 403 #ifdef CAM_AV_OVERRIDE_IRIS_FIX
 404 int MoveIrisWithAv(short *v)        { return _MoveIrisWithAv(v); }
 405 #endif
 406 
 407 #if CAM_EV_IN_VIDEO
 408 void ExpCtrlTool_StartContiAE(int v1, int v2)   { _ExpCtrlTool_StartContiAE(v1,v2); }
 409 void ExpCtrlTool_StopContiAE(int v1, int v2)    { _ExpCtrlTool_StopContiAE(v1, v2); }
 410 short SetAE_ShutterSpeed(short *tv)             { return _SetAE_ShutterSpeed(tv); }
 411 #endif
 412 
 413 //----------------------------------------------------------------------------
 414 // I/O wrappers
 415 
 416 extern int fileio_semaphore;
 417 
 418 int takeFileIOSemaphore()
 419 {
 420     int timeout = CAM_FILEIO_SEM_TIMEOUT;
 421 #if defined(CAM_IS_VID_REC_WORKS)
 422     if (is_video_recording())
 423         timeout = CAM_FILEIO_SEM_TIMEOUT_VID;
 424 #endif
 425 #if defined(OPT_FILEIO_STATS)
 426     int t = get_tick_count();
 427 #endif
 428     // Check fileio semaphore with timeout, if not available we are probably recording video
 429     if (_TakeSemaphore(fileio_semaphore,timeout) & 1)
 430     {
 431 #if defined(OPT_FILEIO_STATS)
 432         camera_info.fileio_stats.fileio_semaphore_errors++;
 433 #endif
 434         return 0;
 435     }
 436 #if defined(OPT_FILEIO_STATS)
 437     t = get_tick_count() - t;
 438     if (t > camera_info.fileio_stats.max_semaphore_timeout)
 439         camera_info.fileio_stats.max_semaphore_timeout = t;
 440 #endif
 441     return 1;
 442 }
 443 
 444 int open (const char *name, int flags, int mode )
 445 {
 446 #if defined(OPT_FILEIO_STATS)
 447     camera_info.fileio_stats.open_count++;
 448 #endif
 449 #if !CAM_DRYOS
 450     // Adjust O_TRUNC and O_CREAT flags for VxWorks
 451     // Remove O_APPEND flag if present (not in VxWorks)
 452     flags = (flags & ~(O_TRUNC|O_CREAT|O_APPEND)) | ((flags & (O_TRUNC|O_CREAT)) << 1);
 453 #else
 454     if(!name || name[0]!='A')
 455         return -1;
 456 #endif
 457     int haveSemaphore = takeFileIOSemaphore();
 458     if (!haveSemaphore)
 459 #if defined(CAM_IS_VID_REC_WORKS)
 460         if (!conf.allow_unsafe_io)
 461 #endif
 462             return -1;
 463     int fd = _Open(name, flags, mode);
 464     if (haveSemaphore)
 465         _GiveSemaphore(fileio_semaphore);
 466 #if defined(OPT_FILEIO_STATS)
 467     if (fd == -1)
 468         camera_info.fileio_stats.open_fail_count++;
 469 #endif
 470     return fd;
 471 }
 472 
 473 int close (int fd)
 474 {
 475 #if defined(OPT_FILEIO_STATS)
 476     camera_info.fileio_stats.close_count++;
 477 #endif
 478     if (fd == -1)
 479     {
 480 #if defined(OPT_FILEIO_STATS)
 481         camera_info.fileio_stats.close_badfile_count++;
 482 #endif
 483         return -1;
 484     }
 485     int haveSemaphore = takeFileIOSemaphore();
 486     if (!haveSemaphore)
 487 #if defined(CAM_IS_VID_REC_WORKS)
 488         if (!conf.allow_unsafe_io)
 489 #endif
 490             return -1;
 491     int r = _Close(fd);
 492     if (haveSemaphore)
 493         _GiveSemaphore(fileio_semaphore);
 494 #if defined(OPT_FILEIO_STATS)
 495     if (r == -1)
 496         camera_info.fileio_stats.close_fail_count++;
 497 #endif
 498     return r;
 499 }
 500 
 501 int write (int fd, const void *buffer, long nbytes)
 502 {
 503     if (fd == -1)
 504     {
 505 #if defined(OPT_FILEIO_STATS)
 506         camera_info.fileio_stats.write_badfile_count++;
 507 #endif
 508         return -1;
 509     }
 510     int haveSemaphore = takeFileIOSemaphore();
 511     if (!haveSemaphore)
 512 #if defined(CAM_IS_VID_REC_WORKS)
 513         if (!conf.allow_unsafe_io)
 514 #endif
 515             return -1;
 516     int r = _Write(fd, buffer, nbytes);
 517     if (haveSemaphore)
 518         _GiveSemaphore(fileio_semaphore);
 519     return r;
 520 }
 521 
 522 int read (int fd, void *buffer, long nbytes)
 523 {
 524     return _Read(fd, buffer, nbytes);
 525 }
 526 
 527 int lseek (int fd, long offset, int whence)
 528 {
 529     return _lseek(fd, offset, whence); /* yes, it's lower-case lseek here since Lseek calls just lseek (A610) */
 530 }
 531 
 532 long mkdir(const char *dirname)
 533 {
 534 #ifdef MKDIR_RETURN_ONE_ON_SUCCESS
 535     // mkdir returns 1 on success, 0 on fail. So, values are inverted, to be compatible with previous versions
 536     if(_MakeDirectory_Fut(dirname,1)) return 0;
 537     else                              return 1;
 538 #else
 539     return _MakeDirectory_Fut(dirname,-1); // meaning of second arg is not clear, firmware seems to use -1
 540 #endif
 541 }
 542 
 543 long mkdir_if_not_exist(const char *dirname)
 544 {
 545     // Check if directory exists and create it if it does not.
 546     if (stat(dirname,0) != 0) return mkdir(dirname);
 547     return 0;   // Success
 548 }
 549 
 550 int remove(const char *name)
 551 {
 552 #ifdef CAM_DRYOS_2_3_R39
 553     // For DryOS R39 and later need to check if 'name' is a file or directory
 554     // and call appropriate delete function.
 555     struct stat st;
 556     if (stat(name,&st) == 0)
 557     {
 558         if (st.st_attrib & DOS_ATTR_DIRECTORY)
 559                 return _DeleteDirectory_Fut(name);
 560         else
 561                 return _DeleteFile_Fut(name);
 562     }
 563     return -1;  // return fail - file / directory does not exist
 564 #else
 565     return _DeleteFile_Fut(name);
 566 #endif
 567 }
 568 
 569 //----------------------------------------------------------------------------
 570 // minimal directory wrappers, rest of implementation is in core/lib_thumb.c
 571 
 572 int fw_closedir(void *d)
 573 {
 574     int have_semaphore = takeFileIOSemaphore();
 575     if (!have_semaphore)
 576 #if defined(CAM_IS_VID_REC_WORKS)
 577         if (!conf.allow_unsafe_io)
 578 #endif
 579             return -1;
 580 
 581     extern int _closedir(void *d);
 582     int ret = _closedir(d);
 583 
 584     if (have_semaphore)
 585         _GiveSemaphore(fileio_semaphore);
 586 
 587     return ret;
 588 }
 589 
 590 #if defined(CAM_DRYOS)
 591     int get_fstype(void)
 592     {
 593 #ifdef CAM_DRYOS_2_3_R39
 594         // fw function returns 1..3 for FAT 12-16-32, 4 for exFAT
 595         // TODO: fix this if any supported camera gets more than 1 drive OR the returned values change
 596         extern int _get_fstype(int);
 597         return _get_fstype(0);
 598 #else
 599         return 0;
 600 #endif
 601     }
 602 
 603     void *fw_opendir(const char* name)
 604     {
 605         void *ret;
 606         int have_semaphore = takeFileIOSemaphore();
 607         if (!have_semaphore)
 608 #if defined(CAM_IS_VID_REC_WORKS)
 609             if (!conf.allow_unsafe_io)
 610 #endif
 611                 return NULL;
 612 
 613         extern void *_OpenFastDir(const char* name);
 614         ret = _OpenFastDir(name);
 615 
 616         if (have_semaphore)
 617             _GiveSemaphore(fileio_semaphore);
 618 
 619         return ret;
 620     }
 621 
 622     int fw_readdir(void *d, void* dd)
 623     {
 624         extern int _ReadFastDir(void *d, void* dd);
 625         return _ReadFastDir(d, dd);
 626     }
 627 
 628 #else // Vx
 629 
 630     void *fw_opendir(const char* name)
 631     {
 632         void *ret;
 633         int have_semaphore = takeFileIOSemaphore();
 634         if (!have_semaphore)
 635 #if defined(CAM_IS_VID_REC_WORKS)
 636             if (!conf.allow_unsafe_io)
 637 #endif
 638                 return NULL;
 639 
 640         extern void *_opendir(const char* name);
 641         ret = _opendir(name);
 642 
 643         if (have_semaphore)
 644             _GiveSemaphore(fileio_semaphore);
 645 
 646         return ret;
 647     }
 648 
 649     void *fw_readdir(void *d)
 650     {
 651         extern void *_readdir(void *d);
 652         return _readdir(d);
 653     }
 654 
 655 #endif // CAM_DRYOS
 656 
 657 //-----------------------------------------------------------------------------------
 658 
 659 // Internal camera firmare 'stat' structures
 660 
 661 #if !CAM_DRYOS
 662 
 663 struct  __stat  // VxWorks
 664 {
 665     unsigned long       st_dev;         /* device ID number */
 666     unsigned long       st_ino;         /* file serial number */
 667     unsigned short      st_mode;        /* file mode (see below) */
 668     short               st_nlink;       /* number of links to file */
 669     short               st_uid;         /* user ID of file's owner */
 670     short               st_gid;         /* group ID of file's group */
 671     unsigned long       st_rdev;        /* device ID, only if special file */
 672     unsigned long       st_size;        /* size of file, in bytes */
 673     unsigned long       st_atime;       /* time of last access */
 674     unsigned long       st_mtime;       /* time of last modification */
 675     unsigned long       st_ctime;       /* time of last change of file status */
 676     long                st_blksize;
 677     long                st_blocks;
 678     unsigned char       st_attrib;      /* file attribute byte (dosFs only) */
 679     int                 reserved1;      /* reserved for future use */
 680     int                 reserved2;      /* reserved for future use */
 681     int                 reserved3;      /* reserved for future use */
 682     int                 reserved4;      /* reserved for future use */
 683     int                 reserved5;      /* reserved for future use */
 684     int                 reserved6;      /* reserved for future use */
 685 };
 686 
 687 #else
 688 
 689 #ifndef CAM_DRYOS_2_3_R39
 690 
 691 struct  __stat  // DryOS pre R39
 692     {
 693     unsigned long       st_dev;         //?
 694     unsigned long       st_ino;         //?
 695     unsigned short      st_mode;        //?
 696     short               st_nlink;       //?
 697     short               st_uid;         //?
 698     short               st_gid;         //?
 699     unsigned long       st_atime;       //?
 700     unsigned long       st_mtime;       //?
 701     unsigned long       st_ctime;       //?
 702     unsigned long       st_size;
 703     long                st_blksize;     //?
 704     long                st_blocks;      //?
 705     unsigned char       st_attrib;
 706     int                 reserved1;      //
 707     int                 reserved2;      //
 708     int                 reserved3;      //
 709     int                 reserved4;      //
 710     int                 reserved5;      //
 711     int                 reserved6;      //
 712 };
 713 
 714 #else
 715 
 716 #ifndef CAM_DRYOS_2_3_R59
 717 
 718 struct __stat   // DryOS R39...R58
 719 {
 720     unsigned long       st_unknown_1;
 721     unsigned long       st_attrib;
 722     unsigned long       st_size;
 723     unsigned long       st_ctime;
 724     unsigned long       st_mtime;
 725     unsigned long       st_unknown_2;
 726 };
 727 
 728 #else
 729 
 730 struct __stat   // DryOS >= R59
 731 {
 732     unsigned long       st_unknown_1;
 733     unsigned long       st_attrib;
 734     unsigned long       st_size;        // fixme: very likely 64bit, upper 32 bit is st_unknown_2
 735     unsigned long       st_unknown_2;
 736     unsigned long       st_ctime;
 737     unsigned long       st_mtime;
 738     unsigned long       st_unknown_3;
 739 };
 740 
 741 #endif//CAM_DRYOS_2_3_R59
 742 
 743 #endif//CAM_DRYOS_2_3_R39
 744 
 745 #endif//CAM_DRYOS
 746 
 747 int stat(const char *name, struct stat *pStat)
 748 {
 749     // sanity check. canon firmware hangup if start not from 'A/'
 750     if ( !name || (name[0] | 0x20)!='a' || name[1]!='/' ) return 1;
 751 
 752     // use temp __stat stucture to match camera firmware
 753     // and copy values across to output
 754     struct __stat lStat;
 755     int rv = _stat(name, &lStat);
 756     if (pStat)
 757     {
 758         if (rv == 0)
 759         {
 760             pStat->st_attrib = lStat.st_attrib;
 761             pStat->st_size = lStat.st_size;
 762             pStat->st_ctime = lStat.st_ctime;
 763             pStat->st_mtime = lStat.st_mtime;
 764         }
 765         else
 766         {
 767             memset( pStat, 0, sizeof(struct stat));
 768         }
 769     }
 770     return rv;
 771 }
 772 
 773 FILE *fopen(const char *filename, const char *mode) {
 774 #ifdef CAM_DRYOS
 775     if(!filename || filename[0]!='A') {
 776         return NULL;
 777     }
 778 #endif
 779 
 780     // Check fileio semaphore, if not available we are probably recording video
 781     if (!takeFileIOSemaphore())
 782         return NULL;
 783     _GiveSemaphore(fileio_semaphore);
 784 
 785     return (FILE *)_Fopen_Fut(filename,mode);
 786 }
 787 
 788 long fclose(FILE *f) {
 789     return _Fclose_Fut((long)f);
 790 }
 791 
 792 long fread(void *buf, long elsize, long count, FILE *f) {
 793     return _Fread_Fut(buf,elsize,count,(long)f);
 794 }
 795 
 796 long fwrite(const void *buf, long elsize, long count, FILE *f) {
 797     return _Fwrite_Fut(buf,elsize,count,(long)f);
 798 }
 799 
 800 long fseek(FILE *file, long offset, long whence) {
 801     return _Fseek_Fut((long)file,offset,whence);
 802 }
 803 
 804 long feof(FILE * file) {
 805     return _Feof_Fut((long)file);
 806 }
 807 
 808 long fflush(FILE * file) {
 809     return _Fflush_Fut((long)file);
 810 }
 811 
 812 char *fgets(char *buf, int n, FILE *f) {
 813     return _Fgets_Fut(buf,n,(int)f);
 814 }
 815 
 816 int rename(const char *oldname, const char *newname) {
 817  return _RenameFile_Fut(oldname, newname);
 818 }
 819 
 820 unsigned int GetFreeCardSpaceKb(void){
 821 // get free clusters directly for digic >= 6, updates during video recording
 822 #ifdef THUMB_FW
 823     extern unsigned long live_free_cluster_count;
 824     unsigned long free_clusters = live_free_cluster_count;
 825 #else
 826     unsigned long free_clusters = _GetDrive_FreeClusters(0);
 827 #endif
 828         return (free_clusters*(_GetDrive_ClusterSize(0)>>9))>>1;
 829 }
 830 
 831 unsigned int GetTotalCardSpaceKb(void){
 832         return (_GetDrive_TotalClusters(0)*(_GetDrive_ClusterSize(0)>>9))>>1;
 833 }
 834 
 835 //----------------------------------------------------------------------------
 836 
 837 int errnoOfTaskGet(int tid) {
 838 #if !CAM_DRYOS
 839     return _errnoOfTaskGet(tid);
 840 #else
 841     (void)tid;
 842     return 0;
 843 #endif
 844 }
 845 
 846 //----------------------------------------------------------------------------
 847 // String wrappers
 848 
 849 long strlen(const char *s) {
 850     return _strlen(s);
 851 }
 852 
 853 int strcmp(const char *s1, const char *s2) {
 854     return _strcmp(s1, s2);
 855 }
 856 
 857 int strncmp(const char *s1, const char *s2, long n) {
 858     return _strncmp(s1, s2, n);
 859 }
 860 
 861 char *strchr(const char *s, int c) {
 862     return _strchr(s, c);
 863 }
 864 
 865 char *strcpy(char *dest, const char *src) {
 866     return _strcpy(dest, src);
 867 }
 868 
 869 char *strncpy(char *dest, const char *src, long n) {
 870     return _strncpy(dest, src, n);
 871 }
 872 
 873 char *strcat(char *dest, const char *app) {
 874     return _strcat(dest, app);
 875 }
 876 
 877 char *strrchr(const char *s, int c) {
 878     return _strrchr(s, c);
 879 }
 880 
 881 long strtol(const char *nptr, char **endptr, int base) {
 882     return _strtol(nptr, endptr, base);
 883 }
 884 
 885 unsigned long strtoul(const char *nptr, char **endptr, int base) {
 886 #if CAM_DRYOS
 887     return (unsigned long)_strtolx(nptr, endptr, base, 0);
 888 #else
 889     return _strtoul(nptr, endptr, base);
 890 #endif
 891 }
 892 
 893 #if !CAM_DRYOS
 894 char *strpbrk(const char *s, const char *accept)
 895 {
 896     return _strpbrk(s, accept);
 897 }
 898 #endif
 899 
 900 //----------------------------------------------------------------------------
 901 
 902 long sprintf(char *s, const char *st, ...)
 903 {
 904     long res;
 905     __builtin_va_list va;
 906     __builtin_va_start(va, st);
 907     res = _vsprintf(s, st, va);
 908     __builtin_va_end(va);
 909     return res;
 910 }
 911 
 912 // strerror exists on vxworks cams,
 913 // but it does about the same thing as this
 914 const char *strerror(int en) {
 915 #if !CAM_DRYOS
 916     static char msg[20];
 917     sprintf(msg,"errno 0x%X",en);
 918     return msg;
 919 #else
 920     (void)en;
 921     return "error";
 922 #endif
 923 }
 924 
 925 //----------------------------------------------------------------------------
 926 // Time wrappers
 927 
 928 unsigned long time(unsigned long *timer) {
 929     return _time(timer);
 930 }
 931 
 932 int utime(const char *file, struct utimbuf *newTimes) {
 933 #if !CAM_DRYOS
 934     return _utime(file, newTimes);
 935 #else
 936     int res=0;
 937     int fd;
 938     fd = _open(file, 0, 0);
 939 
 940 #ifdef CAM_DRYOS_2_3_R39
 941     if (fd>=0) {
 942         _close(fd);
 943         res=_SetFileTimeStamp(file, newTimes->modtime, newTimes->actime);
 944     }
 945 #else
 946     if (fd>=0) {
 947         res=_SetFileTimeStamp(fd, newTimes->modtime, newTimes->actime);
 948         _close(fd);
 949     }
 950     // return value compatibe with utime: ok=0 fail=-1
 951 #endif
 952     return (res)?0:-1;
 953 #endif
 954 }
 955 
 956 struct tm *localtime(const time_t *_tod) {
 957 #if !CAM_DRYOS
 958     return _localtime(_tod);
 959 #else
 960     // for DRYOS cameras do something with this!  - sizeof(x[]) must be >= sizeof(struct tm) :  'static int x[9];'
 961     static int x[10];
 962     return _LocalTime(_tod, &x);
 963 #endif
 964 }
 965 
 966 long strftime(char *s, unsigned long maxsize, const char *format, const struct tm *timp) {
 967         return _strftime(s,maxsize,format,timp);
 968 }
 969 
 970 time_t mktime(struct tm *timp) {
 971 #if !CAM_DRYOS
 972         return _mktime(timp);
 973 #else
 974         int timp_ext[10]; // struct tm + a ptr
 975         _memcpy(timp_ext,timp,9*sizeof(int));
 976         timp_ext[9]=0;
 977         long retval = _mktime_ext(&timp_ext);
 978         _memcpy(timp,timp_ext,9*sizeof(int));
 979         return retval;
 980 #endif
 981 }
 982 
 983 void set_clock(int year, int month, int day, int hour, int minute, int second)
 984 {
 985     int buf[6];
 986     buf[0] = year;
 987     buf[1] = month;
 988     buf[2] = day;
 989     buf[3] = hour;
 990     buf[4] = minute;
 991     buf[5] = second;
 992     _SetDate(buf);
 993     // SetDate sets second, so adjust subsec offset
 994     camera_info.tick_count_offset = get_tick_count() % 1000; 
 995 }
 996 
 997 //----------------------------------------------------------------------------
 998 // Math wrappers
 999 
1000 double log(double x) {
1001     return __log(x);
1002 }
1003 
1004 double log10(double x) {
1005     return __log10(x);
1006 }
1007 
1008 double pow(double x, double y) {
1009     return __pow(x, y);
1010 }
1011 
1012 double sqrt(double x) {
1013     return __sqrt(x);
1014 }
1015 
1016 // log2(x) = log(x) * (1 / log(2))
1017 double log2(double x) { return (log(x) * ((double)1.44269504088906)); }
1018 
1019 //----------------------------------------------------------------------------
1020 
1021 #ifdef OPT_EXMEM_MALLOC
1022 void *exmem_alloc_cached(unsigned int pool_id,unsigned int size,int unk,int unk2)
1023 {
1024     return _exmem_alloc(pool_id,size,unk,unk2);
1025 }
1026 #endif
1027 
1028 void *exmem_alloc_uncached(unsigned int type, unsigned int size, exmem_alloc_info *allocinf)
1029 {
1030     return _exmem_ualloc(type, size, allocinf);
1031 }
1032 void exmem_free_uncached(unsigned int type)
1033 {
1034     _exmem_ufree(type);
1035 }
1036 
1037 void *canon_malloc(long size)
1038 {
1039 #if CAM_DRYOS
1040     return _malloc(size);
1041 #else
1042     if (_TakeSemaphore(canon_heap_sem,CANON_HEAP_SEM_TIMEOUT)) {
1043         return 0;
1044     } else {
1045         void *r=_malloc(size);
1046         _GiveSemaphore(canon_heap_sem);
1047         return r;
1048     }
1049 #endif
1050 }
1051 
1052 void canon_free(void *p)
1053 {
1054 #if CAM_DRYOS
1055     _free(p);
1056 #else
1057     if (!_TakeSemaphore(canon_heap_sem,CANON_HEAP_SEM_TIMEOUT)) {
1058        _free(p);
1059        _GiveSemaphore(canon_heap_sem);
1060     }
1061 #endif
1062 }
1063 
1064 void *umalloc(long size) {
1065 #if CAM_DRYOS
1066     return _AllocateUncacheableMemory(size);
1067 #else
1068     if (_TakeSemaphore(canon_heap_sem,CANON_HEAP_SEM_TIMEOUT)) {
1069         return 0;
1070     } else {
1071         void *r=_AllocateUncacheableMemory(size);
1072         _GiveSemaphore(canon_heap_sem);
1073         return r;
1074     }
1075 #endif
1076 }
1077 
1078 void ufree(void *p) {
1079 #if CAM_DRYOS
1080     _FreeUncacheableMemory(p);
1081 #else
1082     if (!_TakeSemaphore(canon_heap_sem,CANON_HEAP_SEM_TIMEOUT)) {
1083         _FreeUncacheableMemory(p);
1084        _GiveSemaphore(canon_heap_sem);
1085     }
1086 #endif
1087 }
1088 
1089 void *memcpy(void *dest, const void *src, long n) {
1090     return _memcpy(dest, src, n);
1091 }
1092 
1093 void *memset(void *s, int c, int n) {
1094     return _memset(s, c, n);
1095 }
1096 
1097 int memcmp(const void *s1, const void *s2, long n) {
1098     return _memcmp(s1, s2, n);
1099 }
1100 
1101 #if !CAM_DRYOS
1102 void *memchr(const void *s, int c, int n) {
1103         return _memchr(s,c,n);
1104 }
1105 #endif
1106 
1107 //----------------------------------------------------------------------------
1108 
1109 void GetMemInfo(cam_meminfo *camera_meminfo)
1110 {
1111 // Use firmware GetMemInfo function to retrieve info about Canon heap memory allocation
1112 
1113 #if defined(CAM_DRYOS)
1114     // Prior to dryos R39 GetMemInfo returns 9 values, after R39 it returns 10 (all but 1 are used in each case)
1115     int fw_info[10];
1116     extern void _GetMemInfo(int*);
1117     _GetMemInfo(fw_info);
1118 
1119 #if defined(CAM_DRYOS_2_3_R39)
1120     // For newer dryos version copy all 9 used values to CHDK structure
1121     camera_meminfo->start_address        = fw_info[0];
1122     camera_meminfo->end_address          = fw_info[1];
1123     camera_meminfo->total_size           = fw_info[2];
1124     camera_meminfo->allocated_size       = fw_info[3];
1125     camera_meminfo->allocated_peak       = fw_info[4];
1126     camera_meminfo->allocated_count      = fw_info[5];
1127     camera_meminfo->free_size            = fw_info[6];
1128     camera_meminfo->free_block_max_size  = fw_info[7];
1129     camera_meminfo->free_block_count     = fw_info[8];
1130 #else
1131     // For older dryos version copy 8 used values to CHDK structure and calculate missing value
1132     camera_meminfo->start_address        = fw_info[0];
1133     camera_meminfo->end_address          = fw_info[0] + fw_info[1];
1134     camera_meminfo->total_size           = fw_info[1];
1135     camera_meminfo->allocated_size       = fw_info[2];
1136     camera_meminfo->allocated_peak       = fw_info[3];
1137     camera_meminfo->allocated_count      = fw_info[4];
1138     camera_meminfo->free_size            = fw_info[5];
1139     camera_meminfo->free_block_max_size  = fw_info[6];
1140     camera_meminfo->free_block_count     = fw_info[7];
1141 #endif
1142 #else // vxworks
1143     extern int sys_mempart_id;
1144     // -1 for invalid
1145     memset(camera_meminfo,0xFF,sizeof(cam_meminfo));
1146     if(!_TakeSemaphore(canon_heap_sem,CANON_HEAP_SEM_TIMEOUT)) {
1147 #ifdef CAM_NO_MEMPARTINFO
1148         camera_meminfo->free_block_max_size = _memPartFindMax(sys_mempart_id);
1149 #else
1150         int fw_info[5];
1151         _memPartInfoGet(sys_mempart_id,fw_info);
1152         // TODO we could fill in start address from _start + MEMISOSIZE, if chdk not in exmem
1153         // these are guessed, look reasonable on a540
1154         camera_meminfo->free_size = fw_info[0];
1155         camera_meminfo->free_block_count = fw_info[1];
1156         camera_meminfo->free_block_max_size = fw_info[2];
1157         camera_meminfo->allocated_size = fw_info[3];
1158         camera_meminfo->allocated_count = fw_info[4];
1159 #endif
1160         _GiveSemaphore(canon_heap_sem);
1161     }
1162 #endif
1163 }
1164 
1165 //----------------------------------------------------------------------------
1166 
1167 int rand(void) {
1168     return _rand();
1169 }
1170 
1171 void *srand(unsigned int seed) {
1172     return _srand(seed);
1173 }
1174 
1175 void qsort(void *__base, int __nelem, int __size, int (*__cmp)(const void *__e1, const void *__e2)) {
1176     _qsort(__base, __nelem, __size, __cmp);
1177 }
1178 
1179 static int shutdown_disabled = 0;
1180 void disable_shutdown() {
1181     if (!shutdown_disabled) {
1182         _LockMainPower();
1183         shutdown_disabled = 1;
1184     }
1185 }
1186 
1187 void enable_shutdown() {
1188     if (shutdown_disabled) {
1189         _UnlockMainPower();
1190         shutdown_disabled = 0;
1191     }
1192 }
1193 
1194 void camera_shutdown_in_a_second(void) {
1195     int i;
1196     _SetAutoShutdownTime(1); // 1 sec
1197     for (i=0;i<200;i++)
1198         _UnlockMainPower(); // set power unlock counter to 200 or more, because every keyboard function call try to lock power again ( if "Disable LCD off" menu is "alt" or "script").
1199 }
1200 
1201 void EnterToCompensationEVF(void)
1202 {
1203   _EnterToCompensationEVF();
1204 }
1205 
1206 void ExitFromCompensationEVF()
1207 {
1208   _ExitFromCompensationEVF();
1209 }
1210 
1211 void TurnOnBackLight(void)
1212 {
1213   _TurnOnBackLight();
1214 }
1215 
1216 void TurnOffBackLight(void)
1217 {
1218   _TurnOffBackLight();
1219 }
1220 
1221 extern void gui_set_need_restore();
1222 
1223 void TurnOnDisplay(void)
1224 {
1225   _TurnOnDisplay();
1226   // required to re-draw the canon and CHDK UI after re-enabling display
1227   gui_set_need_restore() ;
1228 }
1229 
1230 void TurnOffDisplay(void)
1231 {
1232   _TurnOffDisplay();
1233 }
1234 
1235 void DoAELock(void)
1236 {
1237   if (!camera_info.state.mode_play)
1238   {
1239      _DoAELock();
1240   }
1241 }
1242 
1243 void UnlockAE(void)
1244 {
1245   if (!camera_info.state.mode_play)
1246   {
1247      _UnlockAE();
1248   }
1249 }
1250 
1251 void DoAFLock(void)
1252 {
1253   if (!camera_info.state.mode_play)
1254   {
1255      int af_lock=1;
1256      _DoAFLock();
1257      set_property_case(PROPCASE_AF_LOCK,&af_lock,sizeof(af_lock));
1258   }
1259 }
1260 
1261 void UnlockAF(void)
1262 {
1263   if (!camera_info.state.mode_play)
1264   {
1265      int af_lock=0;
1266      _UnlockAF();
1267      set_property_case(PROPCASE_AF_LOCK,&af_lock,sizeof(af_lock));
1268   }
1269 }
1270 
1271 int EngDrvRead(int gpio_reg)
1272 {
1273   return _EngDrvRead(gpio_reg);
1274 }
1275 
1276 #if CAM_MULTIPART
1277 
1278 #define SECTOR_SIZE 512
1279 static char *mbr_buf=(void*)0;
1280 static unsigned long drive_sectors;
1281 
1282 int is_mbr_loaded()
1283 {
1284         return (mbr_buf == (void*)0) ? 0 : 1;
1285 }
1286 
1287 #ifndef CAM_DRYOS
1288 
1289 int mbr_read(char* mbr_sector, unsigned long drive_total_sectors, unsigned long *part_start_sector,  unsigned long *part_length){
1290 // return value: 1 - success, 0 - fail
1291 // called only in VxWorks
1292 
1293  int offset=0x10; // points to partition #2
1294  int valid;
1295 
1296  if ((mbr_sector[0x1FE]!=0x55) || (mbr_sector[0x1FF]!=0xAA)) return 0; // signature check
1297 
1298  mbr_buf=_AllocateUncacheableMemory(SECTOR_SIZE);
1299  _memcpy(mbr_buf,mbr_sector,SECTOR_SIZE);
1300  drive_sectors=drive_total_sectors;
1301 
1302  while(offset>=0) {
1303 
1304   *part_start_sector=(*(unsigned short*)(mbr_sector+offset+0x1C8)<<16) | *(unsigned short*)(mbr_sector+offset+0x1C6);
1305   *part_length=(*(unsigned short*)(mbr_sector+offset+0x1CC)<<16) | *(unsigned short*)(mbr_sector+offset+0x1CA);
1306 
1307   valid= (*part_start_sector) && (*part_length) &&
1308          (*part_start_sector<=drive_total_sectors) &&
1309          (*part_start_sector+*part_length<=drive_total_sectors) &&
1310          ((mbr_sector[offset+0x1BE]==0) || (mbr_sector[offset+0x1BE]==0x80)); // status: 0x80 (active) or 0 (non-active)
1311 
1312   if (valid && ((mbr_sector[0x1C2+offset]==0x0B) || (mbr_sector[0x1C2+offset]==0x0C))) break;   // FAT32 secondary partition
1313 
1314   offset-=0x10;
1315 
1316  }
1317 
1318  return valid;
1319 }
1320 
1321 #else
1322 
1323 int mbr_read_dryos(unsigned long drive_total_sectors, char* mbr_sector ){
1324 // Called only in DRYOS
1325  mbr_buf=_AllocateUncacheableMemory(SECTOR_SIZE);
1326  _memcpy(mbr_buf,mbr_sector,SECTOR_SIZE);
1327  drive_sectors=drive_total_sectors;
1328  return drive_total_sectors;
1329 }
1330 
1331 #endif
1332 
1333 int get_part_count(void)
1334 {
1335   unsigned long part_start_sector, part_length;
1336   char part_status, part_type;
1337   int i;
1338   int count=0;
1339   if (is_mbr_loaded())
1340   {
1341     for (i=0; i<=3;i++)
1342     {
1343       part_start_sector=(*(unsigned short*)(mbr_buf+i*16+0x1C8)<<16) | *(unsigned short*)(mbr_buf+i*16+0x1C6);
1344       part_length=(*(unsigned short*)(mbr_buf+i*16+0x1CC)<<16) | *(unsigned short*)(mbr_buf+i*16+0x1CA);
1345       part_status=mbr_buf[i*16+0x1BE];
1346       part_type=mbr_buf[0x1C2+i*16];
1347       if ( part_start_sector && part_length && part_type && ((part_status==0) || (part_status==0x80)) ) count++;
1348     }
1349   }
1350   return count;
1351 }
1352 int get_part_type()
1353 {
1354   int partType = 0x00;
1355   if (is_mbr_loaded())
1356   {
1357     partType=mbr_buf[0x1C2+(get_active_partition()-1)*16];
1358   }
1359   return partType;
1360 } 
1361 
1362 static int boot_partition = 0;
1363 static int partition_changed = 0;
1364 int is_partition_changed()
1365 {
1366   return partition_changed;
1367 }
1368 
1369 int swap_partitions(int new_partition)
1370 {
1371   if (is_mbr_loaded())
1372   {
1373     int i,j,p;
1374     char c;
1375     
1376     int partition_count = get_part_count();
1377     int active_partition = get_active_partition();
1378     
1379     if(!boot_partition)
1380     {
1381       boot_partition = active_partition;
1382     }
1383 
1384     // wrong input
1385     if( new_partition > partition_count || new_partition <= 0 )
1386     {
1387       return 0;
1388     }
1389     partition_changed = (new_partition==boot_partition)?0:1;
1390     
1391     // rotate partitions till new_partition is found
1392     for(j=0;j<partition_count;++j)
1393     {
1394       if(new_partition == get_active_partition())
1395       {
1396         break;
1397       }
1398       for(i=0;i<16;i++)
1399       {
1400         c=mbr_buf[i+0x1BE];
1401         for(p=1; p<partition_count; ++p)
1402         {
1403           mbr_buf[i+(p-1)*16+0x1BE]=mbr_buf[i+p*16+0x1BE];
1404         }
1405         mbr_buf[i+(partition_count-1)*16+0x1BE]=c;
1406       }
1407     }
1408     _WriteSDCard(0,0,1,mbr_buf);
1409   }
1410   return 1;
1411 }
1412 
1413 unsigned char get_active_partition(void)
1414 {
1415   unsigned int  partition_start[4];
1416   unsigned char partition_number = 1;
1417   int partition_count = get_part_count();
1418   int i;
1419 
1420   for( i=0; i<partition_count; ++i )
1421   {
1422     int a = mbr_buf[0x01C6+(i)*16];
1423     int b = mbr_buf[0x01C7+(i)*16];
1424     int c = mbr_buf[0x01C8+(i)*16];
1425     int d = mbr_buf[0x01C9+(i)*16];
1426     partition_start[i] = (((((d<<8) +c)<<8) +b)<<8) +a;
1427   }
1428   for( i=1; i<partition_count; ++i )
1429   {
1430     if(partition_start[i]<partition_start[0])
1431     {
1432       ++partition_number;
1433     }
1434   }
1435   return partition_number;
1436 }
1437 
1438 void create_partitions(void){
1439         if (is_mbr_loaded())
1440         {
1441          unsigned long start, length;
1442          char type;
1443 
1444          _memset(mbr_buf,0,SECTOR_SIZE);
1445 
1446          start=1; length=2*1024*1024/SECTOR_SIZE; //2 Mb
1447          type=1; // FAT primary
1448          mbr_buf[0x1BE + 4]=type;
1449          mbr_buf[0x1BE + 8]=start;   mbr_buf[0x1BE + 9]=start>>8;   mbr_buf[0x1BE + 10]=start>>16;  mbr_buf[0x1BE + 11]=start>>24;
1450          mbr_buf[0x1BE + 12]=length; mbr_buf[0x1BE + 13]=length>>8; mbr_buf[0x1BE + 14]=length>>16; mbr_buf[0x1BE + 15]=length>>24;
1451 
1452          start=start+length; length=drive_sectors-start-1;
1453          type=0x0B;  //FAT32 primary;
1454          mbr_buf[0x1CE + 4]=type;
1455          mbr_buf[0x1CE + 8]=start;   mbr_buf[0x1CE + 9]=start>>8;   mbr_buf[0x1CE + 10]=start>>16;  mbr_buf[0x1CE + 11]=start>>24;
1456          mbr_buf[0x1CE + 12]=length; mbr_buf[0x1CE + 13]=length>>8; mbr_buf[0x1CE + 14]=length>>16; mbr_buf[0x1CE + 15]=length>>24;
1457 
1458          mbr_buf[0x1FE]=0x55; mbr_buf[0x1FF]=0xAA; // signature;
1459 
1460          _WriteSDCard(0,0,1,mbr_buf);
1461         }
1462 }
1463 
1464 #else
1465 
1466 // Dummy for scripts if not implemented in camera
1467 int swap_partitions(__attribute__ ((unused))int new_partition) { return 0; }
1468 int get_part_count(void) { return 1; }
1469 int get_part_type() { return 0; }
1470 unsigned char get_active_partition(void) { return 1; }
1471 int is_partition_changed() { return 0; }
1472 
1473 #endif
1474 
1475 int mute_on_zoom(int x){
1476  static int old_busy=0;
1477  int busy=zoom_busy||focus_busy;
1478  if (old_busy!=busy) {
1479   if (busy) {
1480 #if CAM_CAN_MUTE_MICROPHONE
1481    if (conf.mute_on_zoom) _TurnOffMic();
1482 #endif
1483    }
1484    else {
1485 #if CAM_CAN_MUTE_MICROPHONE
1486   if (conf.mute_on_zoom) _TurnOnMic();
1487 #endif
1488 #if CAM_EV_IN_VIDEO
1489   if (get_ev_video_avail()) set_ev_video_avail(0);
1490 #endif
1491   }
1492   old_busy=busy;
1493  }
1494  return x; // preserve R0 if called from assembler
1495 }
1496 
1497 
1498 #if CAM_AF_SCAN_DURING_VIDEO_RECORD
1499 void MakeAFScan(void){
1500  int a=0, save;
1501  if (zoom_busy || focus_busy) return;
1502  save=some_flag_for_af_scan;
1503  some_flag_for_af_scan=0;
1504 #if CAM_AF_SCAN_DURING_VIDEO_RECORD == 2
1505  parameter_for_af_scan=3;
1506 #endif
1507  _MakeAFScan(&a, 3);
1508  some_flag_for_af_scan=save;
1509 #if CAM_RESET_AEL_AFTER_VIDEO_AF
1510  int ae_lock;
1511  get_property_case(PROPCASE_AE_LOCK,&ae_lock,sizeof(ae_lock));
1512  if (ae_lock == 0)                                              // AE not locked so ensure it is unlocked after re-focus
1513          _ExpCtrlTool_StartContiAE(0,0);
1514  else                                                                   // AE locked before so re-lock after
1515          _ExpCtrlTool_StopContiAE(0,0);
1516 #else
1517  _ExpCtrlTool_StartContiAE(0,0);
1518 #endif
1519 }
1520 #endif
1521 
1522 long __attribute__((weak)) get_jogdial_direction(void)  { return 0; }
1523 void __attribute__((weak)) JogDial_CW(void)     {}
1524 void __attribute__((weak)) JogDial_CCW(void)    {}
1525 
1526 #if defined (DNG_EXT_FROM)
1527 
1528 #define DNG_EXT_TO ".DNG"
1529 
1530 typedef int(*p_some_f)(char*, int);
1531 
1532 extern p_some_f some_f_for_dng;  // camera variable!
1533 extern char* second_ext_for_dng; // camera variable!
1534 
1535 p_some_f default_some_f;
1536 char *   default_second_ext;
1537 
1538 int my_some_f(char *s, int x){
1539   char *f;
1540   f=strstr(s, DNG_EXT_FROM);
1541   if (f) _memcpy(f, DNG_EXT_TO, sizeof(DNG_EXT_TO)-1);
1542   return default_some_f(s, x);
1543 }
1544 
1545 void save_ext_for_dng(void){
1546  default_some_f=some_f_for_dng;
1547  default_second_ext=second_ext_for_dng;
1548 }
1549 
1550 void change_ext_to_dng(void){
1551  some_f_for_dng=my_some_f;
1552  second_ext_for_dng=DNG_EXT_TO;
1553 }
1554 
1555 void change_ext_to_default(void){
1556  some_f_for_dng=default_some_f;
1557  second_ext_for_dng=default_second_ext;
1558 }
1559 
1560 #endif
1561 
1562 #if !CAM_DRYOS
1563 static long drv_struct[16];
1564 #endif
1565 
1566 long dh_err()
1567 {
1568     return -1;
1569 }
1570 
1571 #if !CAM_DRYOS
1572 void drv_self_hide()
1573 {
1574     long drvnum;
1575 
1576     drvnum = _iosDrvInstall(dh_err,dh_err,dh_err,dh_err,dh_err,dh_err,dh_err);
1577     if (drvnum >= 0)
1578         _iosDevAdd(drv_struct, "A/DISKBOOT.BIN", drvnum);
1579 }
1580 
1581 void drv_self_unhide()
1582 {
1583  _iosDevDelete(drv_struct);
1584 }
1585 #endif
1586 
1587 int  apex2us(int apex_tv){
1588 #if CAM_EXT_TV_RANGE
1589 /*
1590  Extended Tv, by barberofcivil, http://chdk.setepontos.com/index.php/topic,4392.0.html
1591  Explanation by reyalP:
1592  In every port, the original shutter overrides (as opposed to super long exposure) worked by
1593  setting the propcase values at some point after auto-exposure has happened (except in manual
1594  modes, where the manual control propcases may be used instead). The Canon code previously took
1595  these values unchanged for short exposures. In newer cameras, like on the SX10 / SD980, the value
1596  is changed, apparently some time after it has been retrieved from the propcase. We know this is
1597  the case, because the propcase value itself doesn't get clamped to the allowed range (if it did,
1598  barberofcivil's code wouldn't work).
1599 */
1600         short tv;
1601         tv = shooting_get_tv96();
1602         if (tv<-576 || tv!=apex_tv) return 1000000.0*pow(2.0, -tv/96.0);
1603         else return _apex2us(apex_tv);
1604 #else
1605         return 0;
1606 #endif
1607 }
1608 
1609 void PostLogicalEventForNotPowerType(unsigned id, unsigned x) {
1610         _PostLogicalEventForNotPowerType(id,x);
1611 }
1612 
1613 void PostLogicalEventToUI(unsigned id, unsigned x) {
1614         _PostLogicalEventToUI(id,x);
1615 }
1616 
1617 void SetLogicalEventActive(unsigned id, unsigned state) {
1618         _SetLogicalEventActive(id, state);
1619 }
1620 
1621 void SetScriptMode(unsigned mode) {
1622         _SetScriptMode(mode);
1623 }
1624 
1625 // TODO this belongs lib.c, but not all cameras include it
1626 // same as bitmap width for most cameras, override in platform/sub/lib.c as needed
1627 int __attribute__((weak)) vid_get_viewport_width() {
1628         return camera_screen.width;
1629 }
1630 
1631 // Physical width of viewport row in bytes
1632 int __attribute__((weak)) vid_get_viewport_byte_width() {
1633         return 720 * 6 / 4;     // For most cameras viewport is 720 pixels wide, each group of 4 pixels uses 6 bytes (UYVYYY)
1634 }
1635 
1636 // Y multiplier for cameras with 480 pixel high viewports (CHDK code assumes 240)
1637 int __attribute__((weak)) vid_get_viewport_yscale() {
1638         return 1;               // For most cameras viewport is 240 pixels high
1639 }
1640 
1641 // viewport x offset - used when image size != viewport size (zebra, histogram, motion detect & edge overlay)
1642 int __attribute__((weak)) vid_get_viewport_xoffset() {
1643         return 0;
1644 }
1645 
1646 // viewport y offset - used when image size != viewport size (zebra, histogram, motion detect & edge overlay)
1647 int __attribute__((weak)) vid_get_viewport_yoffset() {
1648         return 0;
1649 }
1650 
1651 // viewport display x offset - used when image size != viewport size (zebra, histogram, motion detect & edge overlay)
1652 int __attribute__((weak)) vid_get_viewport_display_xoffset() {
1653         return vid_get_viewport_xoffset();
1654 }
1655 
1656 // viewport display y offset - used when image size != viewport size (zebra, histogram, motion detect & edge overlay)
1657 int __attribute__((weak)) vid_get_viewport_display_yoffset() {
1658         return vid_get_viewport_yoffset();
1659 }
1660 
1661 // format of live view viewport
1662 #ifndef THUMB_FW
1663 int vid_get_viewport_type() {
1664         return LV_FB_YUV8;
1665 }
1666 // D6 cameras must define
1667 #endif
1668 
1669 // for cameras with two (or more?) RAW buffers this can be used to speed up DNG creation by
1670 // calling reverse_bytes_order only once. Override in platform/sub/lib.c
1671 char __attribute__((weak)) *hook_alt_raw_image_addr() {
1672         return hook_raw_image_addr();
1673 }
1674 
1675 void __attribute__((weak)) vid_turn_off_updates()
1676 {
1677 }
1678 
1679 void __attribute__((weak)) vid_turn_on_updates()
1680 {
1681 }
1682 
1683 // use _GetFocusLensSubjectDistance for this on dryos, vx functions are basically equivlent
1684 // not used in CHDK currently for either OS
1685 #ifdef CAM_DRYOS
1686 long __attribute__((weak)) _GetCurrentTargetDistance()
1687 {
1688         return _GetFocusLensSubjectDistance();
1689 }
1690 #endif
1691 
1692 int add_ptp_handler(int opcode, ptp_handler handler, int unknown)
1693 {
1694 #ifdef CAM_CHDK_PTP
1695     return _add_ptp_handler(opcode,handler,unknown);
1696 #else
1697     return 0;
1698 #endif
1699 }
1700 
1701 #ifdef CAM_PTP_USE_NATIVE_BUFFER
1702 int get_ptp_file_buf_size(void)
1703 {
1704     return _get_ptp_buf_size(CAM_PTP_FILE_BUFFER_ID);
1705 }
1706 
1707 char *get_ptp_file_buf(void)
1708 {
1709     return _get_ptp_file_buf();
1710 }
1711 #endif
1712 
1713 int CreateTask (const char *name, int prio, int stack_size, void *entry)
1714 {
1715     return _CreateTask(name, prio, stack_size, entry, 0);
1716 }
1717 
1718 void ExitTask()
1719 {
1720     _ExitTask();
1721 }
1722 
1723 // TODO not in sigs for vx yet
1724 #ifndef CAM_DRYOS
1725 void __attribute__((weak)) _reboot_fw_update(__attribute__ ((unused))const char *fw_update)
1726 {
1727         return;
1728 }
1729 #endif
1730 
1731 #ifdef CAM_DRYOS
1732 int __attribute__((weak)) switch_mode_usb(int mode)
1733 {
1734 #ifdef CAM_CHDK_PTP
1735     if ( mode == 0 ) {
1736         _Rec2PB();
1737         _set_control_event(0x80000000|CAM_USB_EVENTID);
1738     } else if ( mode == 1 ) {
1739         _set_control_event(CAM_USB_EVENTID);
1740         _PB2Rec();
1741     } else return 0;
1742     return 1;
1743 #else
1744   return 0;
1745 #endif // CAM_CHDK_PTP
1746 }
1747 
1748 #else // vxworks
1749 // this doesn't need any special functions so it's defined even without CHDK_CAM_PTP
1750 int __attribute__((weak)) switch_mode_usb(int mode)
1751 {
1752     if ( mode == 0 ) {
1753         // TODO should we revert scriptmode and/or levent? seems to work without
1754         levent_set_play();
1755     } else if ( mode == 1 ) {
1756 #ifdef CAM_USB_EVENTID_VXWORKS
1757         _SetScriptMode(1); // needed to override event
1758         _SetLogicalEventActive(CAM_USB_EVENTID_VXWORKS,0); // set levent "ConnectUSBCable" inactive
1759 #endif
1760         levent_set_record();
1761     } else return 0;
1762     return 1;
1763 }
1764 #endif // vxworks
1765 
1766 /*
1767 // this wrapper isn't currently needed
1768 // 7 calls functions and sets some MMIOs, but doesn't disable caches and actually restart
1769 // 3 skips one function call on some cameras, but does restart
1770 void Restart(unsigned option) {
1771         _Restart(option);
1772 }
1773 */
1774 
1775 unsigned char SetFileAttributes(const char* fn, unsigned char attr)
1776 {
1777 #ifdef CAM_DRYOS_2_3_R39
1778     return _SetFileAttributes(fn, attr);
1779 #else
1780     int fd;
1781     unsigned char ret = -1;
1782     
1783     fd = open(fn, 0, 0);
1784     if( fd ) {
1785         _SetFileAttributes(fd, attr);
1786         close(fd);
1787         ret = attr;
1788     }
1789     return ret;
1790 #endif
1791 }
1792 
1793 // Default implementation of PTP live view functions.
1794 // Override as needed for camera specific variations (see G12/SX30/IXUS310/SX130IS for working examples)
1795 
1796 int __attribute__((weak)) vid_get_viewport_display_xoffset_proper() { return vid_get_viewport_display_xoffset()*2; }
1797 int __attribute__((weak)) vid_get_viewport_display_yoffset_proper() { return vid_get_viewport_display_yoffset(); }
1798 int __attribute__((weak)) vid_get_viewport_buffer_width_proper()    { return 720; }
1799 #ifdef THUMB_FW
1800 int __attribute__((weak)) vid_get_viewport_width_proper()           { return vid_get_viewport_width(); }
1801 int __attribute__((weak)) vid_get_viewport_height_proper()          { return vid_get_viewport_height(); }
1802 #else
1803 int __attribute__((weak)) vid_get_viewport_width_proper()           { return vid_get_viewport_width()*2; }
1804 int __attribute__((weak)) vid_get_viewport_height_proper()          { return 240; }
1805 #endif
1806 int __attribute__((weak)) vid_get_viewport_fullscreen_height()      { return 240; }
1807 int __attribute__((weak)) vid_get_viewport_fullscreen_width()       { return vid_get_viewport_buffer_width_proper(); }
1808 
1809 int __attribute__((weak)) vid_get_palette_type()                    { return 0; }       // 0 = no palette into, 1 = 16 x 4 byte AYUV values, 
1810                                                                                         // 2 = 16 x 4 byte AYUV (A = 0..3), 3 = 256 x 4 byte AYUV (A = 0..3)
1811 int __attribute__((weak)) vid_get_palette_size()                    { return 0; }
1812 int __attribute__((weak)) vid_get_aspect_ratio()                    { return 0; }       // 0 = 4:3, 1 = 16:9 LCD Aspect Ratio, 2 = 3:2
1813 
1814 void __attribute__((weak)) *vid_get_bitmap_active_buffer()
1815 {
1816   return vid_get_bitmap_fb();   // *** does not get the active buffer! (override if active buffer can be determined)
1817 }
1818 
1819 void __attribute__((weak)) *vid_get_bitmap_active_palette()
1820 {
1821   return 0; // return no palette info unless overridden
1822 }
1823 
1824 // Get active viewport buffer address based on PLAY/REC mode.
1825 // Try to use 'live' buffer in REC mode if vid_get_viewport_live_fb is implemented
1826 // can return NULL in plaback mode, if a video is selected
1827 void *vid_get_viewport_active_buffer()
1828 {
1829   void *p;
1830 
1831   if (camera_info.state.mode_play)
1832   {
1833     p = vid_get_viewport_fb_d();
1834   } else {
1835     p = vid_get_viewport_live_fb();
1836     if ( !p )
1837     {
1838       p = vid_get_viewport_fb();
1839     }
1840   }
1841   
1842   return p;
1843 }
1844 
1845 /*
1846  debug logging function that can be sent to various places
1847  body is ifdef'd inside the body to allow exporting to modules
1848  eventproc version may require System.Create()/SystemEventInit first
1849 */
1850 #ifdef DEBUG_LOGGING
1851 void dbg_printf(char *fmt,...) {
1852     char s[256];
1853     __builtin_va_list va;
1854     __builtin_va_start(va, fmt);
1855     _vsprintf(s, fmt, va);
1856     __builtin_va_end(va);
1857 
1858     // stdout - for use with uart redirection
1859     _ExecuteEventProcedure("Printf",s);
1860     // camera log - will show up in crash dumps, or in stdout on ShowCameraLog
1861     // length limited, asserts if too long
1862     //s[59]=0;
1863     //_LogCameraEvent(0x20,s);
1864 
1865     // file
1866     /*
1867     FILE *f=fopen("A/DBGPRINT.LOG","ab");
1868     if(!f) {
1869         return;
1870     }
1871     fwrite(s,strlen(s),1,f);
1872     fclose(f);
1873     */
1874 }
1875 #endif
1876 
1877 #ifdef CAM_MISSING_RAND
1878 /* Some cameras does not have srand()/rand() functions in firmware, and should be aded here.
1879 E.G. a810/a2300
1880 */
1881 static unsigned int random_variable;
1882 void *_srand(unsigned int seed) {
1883     random_variable = seed;
1884     return (void *) &random_variable;
1885 }
1886 
1887 int _rand(void) {
1888     int value;
1889     value = random_variable*0x41C64E6D+0x3039;
1890     random_variable = value;
1891     value = (0x7FFF & (value>>0x10));
1892     return value;
1893 };
1894 #endif
1895 
1896 //  USB remote high speed timer for pulse width measurement and pulse counting
1897 
1898 extern int _SetHPTimerAfterNow(int delay, int(*good_cb)(int, int), int(*bad_cb)(int, int), int );
1899 extern int _CancelHPTimer(int);
1900 extern int usb_HPtimer_bad(int, int);
1901 extern int usb_HPtimer_good(int, int);
1902 
1903 int usb_HPtimer_handle=0;
1904 
1905 static int ARM_usb_HPtimer_good(int time, int interval) { return usb_HPtimer_good(time, interval); }
1906 static int ARM_usb_HPtimer_bad(int time, int interval) { return usb_HPtimer_bad(time, interval); }
1907 
1908 int start_usb_HPtimer(int interval)            // return 0 if timer already running or error,  1 if successful
1909 {
1910 #ifdef CAM_REMOTE_USB_HIGHSPEED
1911 
1912     if ( usb_HPtimer_handle == 0 )
1913     {
1914         if(interval < CAM_REMOTE_HIGHSPEED_LIMIT) interval=CAM_REMOTE_HIGHSPEED_LIMIT;
1915         usb_HPtimer_handle = _SetHPTimerAfterNow(interval,ARM_usb_HPtimer_good,ARM_usb_HPtimer_bad,interval);
1916         if (!(usb_HPtimer_handle & 0x01)) return 1 ;
1917         usb_HPtimer_handle = 0 ;
1918     }
1919 #endif
1920     return 0;
1921 }
1922 
1923 int stop_usb_HPtimer() 
1924 {
1925 #ifdef CAM_REMOTE_USB_HIGHSPEED
1926     if( usb_HPtimer_handle ) 
1927     {
1928         _CancelHPTimer(usb_HPtimer_handle);
1929         usb_HPtimer_handle = 0 ;
1930         return 1 ;
1931     }
1932 #endif
1933     return 0;
1934 }
1935 
1936 // HP timer functions, callbacks need to be ARM on VxWorks
1937 int SetHPTimerAfterNow(int delay, int(*good_cb)(int, int), int(*bad_cb)(int, int), int param)
1938 {
1939     return _SetHPTimerAfterNow(delay,good_cb,bad_cb,param);
1940 }
1941 
1942 int CancelHPTimer(int handle)
1943 {
1944     return _CancelHPTimer(handle);
1945 }
1946 
1947 // Override HDMI power on in rec mode for using HDMI Hotplug detect as remote
1948 // note does not disable power if remote turned off or channel changed
1949 // May want to add support for controlling independent of remote as output signal
1950 #ifdef CAM_REMOTE_HDMI_POWER_OVERRIDE
1951 extern void _EnableHDMIPower();
1952 void update_hdmi_power_override()
1953 {
1954     static int oldhdmistate = -1;
1955     if ((camera_info.state.mode_rec == 1) && conf.remote_enable && (conf.remote_input_channel == REMOTE_INPUT_HDMI_HPD))
1956     {
1957         /* if switched to shooting mode and remote using HDMI hotplug is enabled, switch on HDMI Power */
1958         /* just do it once on every change because it needs i2c communication depending on HDMI tranceiver */
1959         if (oldhdmistate != 1)
1960         {
1961             _EnableHDMIPower();
1962         }
1963         oldhdmistate = 1;
1964     }
1965     else
1966     {
1967         oldhdmistate = 0;
1968     }
1969 }
1970 #endif
1971 
1972 // disable camera error(s), E32 is the only error that can be handled at the moment (on newer 'IS' cameras)
1973 #if (OPT_DISABLE_CAM_ERROR)
1974 #warning OPT_DISABLE_CAM_ERROR enabled
1975 void DisableCamError(void)
1976 {
1977     extern void _DisableISDriveError(void);
1978     _DisableISDriveError();
1979 }
1980 #endif
1981 
1982 //---------------------------------------------------------------
1983 // Semaphore & Assert
1984 
1985 void DebugAssert(char *err, int line)
1986 {
1987 #if CAM_3ARG_DebugAssert
1988     extern void _DebugAssert(int, char*, int);
1989     _DebugAssert(0, err, line);
1990 #else
1991     extern void _DebugAssert(char*, int);
1992     _DebugAssert(err, line);
1993 #endif
1994 }
1995 
1996 int CreateBinarySemaphore(char *name, int init)
1997 {
1998     extern int _CreateBinarySemaphore(char*, int);
1999     return _CreateBinarySemaphore(name, init);
2000 }
2001 
2002 int TakeSemaphore(int sem, int timeout)
2003 {
2004     return _TakeSemaphore(sem, timeout);
2005 }
2006 
2007 void GiveSemaphore(int sem)
2008 {
2009     _GiveSemaphore(sem);
2010 }
2011 
2012 //---------------------------------------------------------------
2013 // Video out
2014 #ifdef CAM_UNLOCK_ANALOG_AV_IN_REC
2015 void SetVideoOutType(int x) {
2016     extern void _SetVideoOutType(int);
2017     _TurnOffDisplay();
2018     _SetVideoOutType(x);
2019     _TurnOnDisplay();
2020 }
2021 int GetVideoOutType(void) {
2022     extern int _GetVideoOutType(void);
2023     return _GetVideoOutType();
2024 }
2025 #endif
2026 //---------------------------------------------------------------

/* [<][>][^][v][top][bottom][index][help] */