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_focus_pos
  29. play_sound
  30. stat_get_vbatt
  31. GetAdChValue
  32. get_battery_temp
  33. get_ccd_temp
  34. get_optical_temp
  35. get_tick_count
  36. PutInNdFilter
  37. PutOutNdFilter
  38. shooting_get_nd_value_ev96
  39. shooting_get_nd_current_ev96
  40. shooting_get_current_tv96
  41. shooting_get_current_av96
  42. IsStrobeChargeCompleted
  43. SetCurrentCaptureModeType
  44. GetUsableMinAv
  45. GetUsableMaxAv
  46. UnsetZoomForMovie
  47. MoveIrisWithAv
  48. ExpCtrlTool_StartContiAE
  49. ExpCtrlTool_StopContiAE
  50. SetAE_ShutterSpeed
  51. takeFileIOSemaphore
  52. open
  53. close
  54. write
  55. read
  56. lseek
  57. mkdir
  58. mkdir_if_not_exist
  59. remove
  60. fw_closedir
  61. get_fstype
  62. fw_opendir
  63. fw_readdir
  64. fw_opendir
  65. fw_readdir
  66. stat
  67. fopen
  68. fclose
  69. fread
  70. fwrite
  71. fseek
  72. feof
  73. fflush
  74. fgets
  75. rename
  76. GetFreeCardSpaceKb
  77. GetTotalCardSpaceKb
  78. errnoOfTaskGet
  79. strlen
  80. strcmp
  81. strncmp
  82. strchr
  83. strcpy
  84. strncpy
  85. strcat
  86. strrchr
  87. strtol
  88. strtoul
  89. strpbrk
  90. sprintf
  91. strerror
  92. time
  93. utime
  94. localtime
  95. strftime
  96. mktime
  97. _log
  98. _log10
  99. _pow
  100. _sqrt
  101. exmem_alloc
  102. canon_malloc
  103. canon_free
  104. umalloc
  105. ufree
  106. memcpy
  107. memset
  108. memcmp
  109. memchr
  110. GetMemInfo
  111. rand
  112. srand
  113. qsort
  114. disable_shutdown
  115. enable_shutdown
  116. camera_shutdown_in_a_second
  117. EnterToCompensationEVF
  118. ExitFromCompensationEVF
  119. TurnOnBackLight
  120. TurnOffBackLight
  121. TurnOnDisplay
  122. TurnOffDisplay
  123. DoAELock
  124. UnlockAE
  125. DoAFLock
  126. UnlockAF
  127. EngDrvRead
  128. is_mbr_loaded
  129. mbr_read
  130. mbr_read_dryos
  131. get_part_count
  132. get_part_type
  133. is_partition_changed
  134. swap_partitions
  135. get_active_partition
  136. create_partitions
  137. swap_partitions
  138. get_part_count
  139. get_part_type
  140. get_active_partition
  141. is_partition_changed
  142. mute_on_zoom
  143. MakeAFScan
  144. get_jogdial_direction
  145. JogDial_CW
  146. JogDial_CCW
  147. my_some_f
  148. save_ext_for_dng
  149. change_ext_to_dng
  150. change_ext_to_default
  151. dh_err
  152. drv_self_hide
  153. drv_self_unhide
  154. apex2us
  155. PostLogicalEventForNotPowerType
  156. PostLogicalEventToUI
  157. SetLogicalEventActive
  158. SetScriptMode
  159. vid_get_viewport_width
  160. vid_get_viewport_byte_width
  161. vid_get_viewport_yscale
  162. vid_get_viewport_xoffset
  163. vid_get_viewport_yoffset
  164. vid_get_viewport_display_xoffset
  165. vid_get_viewport_display_yoffset
  166. vid_get_viewport_type
  167. hook_alt_raw_image_addr
  168. vid_turn_off_updates
  169. vid_turn_on_updates
  170. _GetCurrentTargetDistance
  171. add_ptp_handler
  172. CreateTask
  173. ExitTask
  174. _reboot_fw_update
  175. switch_mode_usb
  176. switch_mode_usb
  177. SetFileAttributes
  178. vid_get_viewport_display_xoffset_proper
  179. vid_get_viewport_display_yoffset_proper
  180. vid_get_viewport_buffer_width_proper
  181. vid_get_viewport_width_proper
  182. vid_get_viewport_height_proper
  183. vid_get_viewport_width_proper
  184. vid_get_viewport_height_proper
  185. vid_get_viewport_fullscreen_height
  186. vid_get_viewport_fullscreen_width
  187. vid_get_palette_type
  188. vid_get_palette_size
  189. vid_get_aspect_ratio
  190. vid_get_bitmap_active_buffer
  191. vid_get_bitmap_active_palette
  192. vid_get_viewport_active_buffer
  193. dbg_printf
  194. _srand
  195. _rand
  196. ARM_usb_HPtimer_good
  197. ARM_usb_HPtimer_bad
  198. start_usb_HPtimer
  199. stop_usb_HPtimer
  200. SetHPTimerAfterNow
  201. CancelHPTimer
  202. update_hdmi_power_override
  203. DisableCamError
  204. DebugAssert
  205. CreateBinarySemaphore
  206. TakeSemaphore
  207. GiveSemaphore

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

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