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. get_ptp_file_buf_size
  173. get_ptp_file_buf
  174. CreateTask
  175. ExitTask
  176. _reboot_fw_update
  177. switch_mode_usb
  178. switch_mode_usb
  179. SetFileAttributes
  180. vid_get_viewport_display_xoffset_proper
  181. vid_get_viewport_display_yoffset_proper
  182. vid_get_viewport_buffer_width_proper
  183. vid_get_viewport_width_proper
  184. vid_get_viewport_height_proper
  185. vid_get_viewport_width_proper
  186. vid_get_viewport_height_proper
  187. vid_get_viewport_fullscreen_height
  188. vid_get_viewport_fullscreen_width
  189. vid_get_palette_type
  190. vid_get_palette_size
  191. vid_get_aspect_ratio
  192. vid_get_bitmap_active_buffer
  193. vid_get_bitmap_active_palette
  194. vid_get_viewport_active_buffer
  195. dbg_printf
  196. _srand
  197. _rand
  198. ARM_usb_HPtimer_good
  199. ARM_usb_HPtimer_bad
  200. start_usb_HPtimer
  201. stop_usb_HPtimer
  202. SetHPTimerAfterNow
  203. CancelHPTimer
  204. update_hdmi_power_override
  205. DisableCamError
  206. DebugAssert
  207. CreateBinarySemaphore
  208. TakeSemaphore
  209. 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 #ifndef CAM_DRYOS_2_3_R59
 701 
 702 struct __stat   // DryOS R39...R58
 703 {
 704     unsigned long       st_unknown_1;
 705     unsigned long       st_attrib;
 706     unsigned long       st_size;
 707     unsigned long       st_ctime;
 708     unsigned long       st_mtime;
 709     unsigned long       st_unknown_2;
 710 };
 711 
 712 #else
 713 
 714 struct __stat   // DryOS >= R59
 715 {
 716     unsigned long       st_unknown_1;
 717     unsigned long       st_attrib;
 718     unsigned long       st_size;        // fixme: very likely 64bit, upper 32 bit is st_unknown_2
 719     unsigned long       st_unknown_2;
 720     unsigned long       st_ctime;
 721     unsigned long       st_mtime;
 722     unsigned long       st_unknown_3;
 723 };
 724 
 725 #endif//CAM_DRYOS_2_3_R59
 726 
 727 #endif//CAM_DRYOS_2_3_R39
 728 
 729 #endif//CAM_DRYOS
 730 
 731 int stat(const char *name, struct stat *pStat)
 732 {
 733     // sanity check. canon firmware hangup if start not from 'A/'
 734     if ( !name || (name[0] | 0x20)!='a' || name[1]!='/' ) return 1;
 735 
 736     // use temp __stat stucture to match camera firmware
 737     // and copy values across to output
 738     struct __stat lStat;
 739     int rv = _stat(name, &lStat);
 740     if (pStat)
 741     {
 742         if (rv == 0)
 743         {
 744             pStat->st_attrib = lStat.st_attrib;
 745             pStat->st_size = lStat.st_size;
 746             pStat->st_ctime = lStat.st_ctime;
 747             pStat->st_mtime = lStat.st_mtime;
 748         }
 749         else
 750         {
 751             memset( pStat, 0, sizeof(struct stat));
 752         }
 753     }
 754     return rv;
 755 }
 756 
 757 FILE *fopen(const char *filename, const char *mode) {
 758 #ifdef CAM_DRYOS
 759     if(!filename || filename[0]!='A') {
 760         return NULL;
 761     }
 762 #endif
 763 
 764     // Check fileio semaphore, if not available we are probably recording video
 765     if (!takeFileIOSemaphore())
 766         return NULL;
 767     _GiveSemaphore(fileio_semaphore);
 768 
 769     return (FILE *)_Fopen_Fut(filename,mode);
 770 }
 771 
 772 long fclose(FILE *f) {
 773     return _Fclose_Fut((long)f);
 774 }
 775 
 776 long fread(void *buf, long elsize, long count, FILE *f) {
 777     return _Fread_Fut(buf,elsize,count,(long)f);
 778 }
 779 
 780 long fwrite(const void *buf, long elsize, long count, FILE *f) {
 781     return _Fwrite_Fut(buf,elsize,count,(long)f);
 782 }
 783 
 784 long fseek(FILE *file, long offset, long whence) {
 785     return _Fseek_Fut((long)file,offset,whence);
 786 }
 787 
 788 long feof(FILE * file) {
 789     return _Feof_Fut((long)file);
 790 }
 791 
 792 long fflush(FILE * file) {
 793     return _Fflush_Fut((long)file);
 794 }
 795 
 796 char *fgets(char *buf, int n, FILE *f) {
 797     return _Fgets_Fut(buf,n,(int)f);
 798 }
 799 
 800 int rename(const char *oldname, const char *newname) {
 801  return _RenameFile_Fut(oldname, newname);
 802 }
 803 
 804 unsigned int GetFreeCardSpaceKb(void){
 805         return (_GetDrive_FreeClusters(0)*(_GetDrive_ClusterSize(0)>>9))>>1;
 806 }
 807 
 808 unsigned int GetTotalCardSpaceKb(void){
 809         return (_GetDrive_TotalClusters(0)*(_GetDrive_ClusterSize(0)>>9))>>1;
 810 }
 811 
 812 //----------------------------------------------------------------------------
 813 
 814 int errnoOfTaskGet(int tid) {
 815 #if !CAM_DRYOS
 816     return _errnoOfTaskGet(tid);
 817 #else
 818     return 0;
 819 #endif
 820 }
 821 
 822 //----------------------------------------------------------------------------
 823 // String wrappers
 824 
 825 long strlen(const char *s) {
 826     return _strlen(s);
 827 }
 828 
 829 int strcmp(const char *s1, const char *s2) {
 830     return _strcmp(s1, s2);
 831 }
 832 
 833 int strncmp(const char *s1, const char *s2, long n) {
 834     return _strncmp(s1, s2, n);
 835 }
 836 
 837 char *strchr(const char *s, int c) {
 838     return _strchr(s, c);
 839 }
 840 
 841 char *strcpy(char *dest, const char *src) {
 842     return _strcpy(dest, src);
 843 }
 844 
 845 char *strncpy(char *dest, const char *src, long n) {
 846     return _strncpy(dest, src, n);
 847 }
 848 
 849 char *strcat(char *dest, const char *app) {
 850     return _strcat(dest, app);
 851 }
 852 
 853 char *strrchr(const char *s, int c) {
 854     return _strrchr(s, c);
 855 }
 856 
 857 long strtol(const char *nptr, char **endptr, int base) {
 858     return _strtol(nptr, endptr, base);
 859 }
 860 
 861 unsigned long strtoul(const char *nptr, char **endptr, int base) {
 862 #if CAM_DRYOS
 863     return (unsigned long)_strtolx(nptr, endptr, base, 0);
 864 #else
 865     return _strtoul(nptr, endptr, base);
 866 #endif
 867 }
 868 
 869 #if !CAM_DRYOS
 870 char *strpbrk(const char *s, const char *accept)
 871 {
 872     return _strpbrk(s, accept);
 873 }
 874 #endif
 875 
 876 //----------------------------------------------------------------------------
 877 
 878 long sprintf(char *s, const char *st, ...)
 879 {
 880     long res;
 881     __builtin_va_list va;
 882     __builtin_va_start(va, st);
 883     res = _vsprintf(s, st, va);
 884     __builtin_va_end(va);
 885     return res;
 886 }
 887 
 888 // strerror exists on vxworks cams,
 889 // but it does about the same thing as this
 890 const char *strerror(int en) {
 891 #if !CAM_DRYOS
 892     static char msg[20];
 893     sprintf(msg,"errno 0x%X",en);
 894     return msg;
 895 #else
 896     return "error";
 897 #endif
 898 }
 899 
 900 //----------------------------------------------------------------------------
 901 // Time wrappers
 902 
 903 unsigned long time(unsigned long *timer) {
 904     return _time(timer);
 905 }
 906 
 907 int utime(const char *file, struct utimbuf *newTimes) {
 908 #if !CAM_DRYOS
 909     return _utime(file, newTimes);
 910 #else
 911     int res=0;
 912     int fd;
 913     fd = _open(file, 0, 0);
 914 
 915 #ifdef CAM_DRYOS_2_3_R39
 916     if (fd>=0) {
 917         _close(fd);
 918         res=_SetFileTimeStamp(file, newTimes->modtime, newTimes->actime);
 919     }
 920 #else
 921     if (fd>=0) {
 922         res=_SetFileTimeStamp(fd, newTimes->modtime, newTimes->actime);
 923         _close(fd);
 924     }
 925     // return value compatibe with utime: ok=0 fail=-1
 926 #endif
 927     return (res)?0:-1;
 928 #endif
 929 }
 930 
 931 struct tm *localtime(const time_t *_tod) {
 932 #if !CAM_DRYOS
 933     return _localtime(_tod);
 934 #else
 935     // for DRYOS cameras do something with this!  - sizeof(x[]) must be >= sizeof(struct tm) :  'static int x[9];'
 936     static int x[10];
 937     return _LocalTime(_tod, &x);
 938 #endif
 939 }
 940 
 941 long strftime(char *s, unsigned long maxsize, const char *format, const struct tm *timp) {
 942         return _strftime(s,maxsize,format,timp);
 943 }
 944 
 945 time_t mktime(struct tm *timp) {
 946 #if !CAM_DRYOS
 947         return _mktime(timp);
 948 #else
 949         int timp_ext[10]; // struct tm + a ptr
 950         _memcpy(timp_ext,timp,9*sizeof(int));
 951         timp_ext[9]=0;
 952         long retval = _mktime_ext(&timp_ext);
 953         _memcpy(timp,timp_ext,9*sizeof(int));
 954         return retval;
 955 #endif
 956 }
 957 
 958 //----------------------------------------------------------------------------
 959 // Math wrappers
 960 
 961 double _log(double x) {
 962     return __log(x);
 963 }
 964 
 965 double _log10(double x) {
 966     return __log10(x);
 967 }
 968 
 969 double _pow(double x, double y) {
 970     return __pow(x, y);
 971 }
 972 
 973 double _sqrt(double x) {
 974     return __sqrt(x);
 975 }
 976 
 977 //----------------------------------------------------------------------------
 978 
 979 #ifdef OPT_EXMEM_MALLOC
 980 void *exmem_alloc(int pool_id,int size,int unk,int unk2)
 981 {
 982     return _exmem_alloc(pool_id,size,unk,unk2);
 983 }
 984 #endif
 985 
 986 void *canon_malloc(long size)
 987 {
 988 #if CAM_DRYOS
 989     return _malloc(size);
 990 #else
 991     if (_TakeSemaphore(canon_heap_sem,CANON_HEAP_SEM_TIMEOUT)) {
 992         return 0;
 993     } else {
 994         void *r=_malloc(size);
 995         _GiveSemaphore(canon_heap_sem);
 996         return r;
 997     }
 998 #endif
 999 }
1000 
1001 void canon_free(void *p)
1002 {
1003 #if CAM_DRYOS
1004     _free(p);
1005 #else
1006     if (!_TakeSemaphore(canon_heap_sem,CANON_HEAP_SEM_TIMEOUT)) {
1007        _free(p);
1008        _GiveSemaphore(canon_heap_sem);
1009     }
1010 #endif
1011 }
1012 
1013 void *umalloc(long size) {
1014 #if CAM_DRYOS
1015     return _AllocateUncacheableMemory(size);
1016 #else
1017     if (_TakeSemaphore(canon_heap_sem,CANON_HEAP_SEM_TIMEOUT)) {
1018         return 0;
1019     } else {
1020         void *r=_AllocateUncacheableMemory(size);
1021         _GiveSemaphore(canon_heap_sem);
1022         return r;
1023     }
1024 #endif
1025 }
1026 
1027 void ufree(void *p) {
1028 #if CAM_DRYOS
1029     _FreeUncacheableMemory(p);
1030 #else
1031     if (!_TakeSemaphore(canon_heap_sem,CANON_HEAP_SEM_TIMEOUT)) {
1032         _FreeUncacheableMemory(p);
1033        _GiveSemaphore(canon_heap_sem);
1034     }
1035 #endif
1036 }
1037 
1038 void *memcpy(void *dest, const void *src, long n) {
1039     return _memcpy(dest, src, n);
1040 }
1041 
1042 void *memset(void *s, int c, int n) {
1043     return _memset(s, c, n);
1044 }
1045 
1046 int memcmp(const void *s1, const void *s2, long n) {
1047     return _memcmp(s1, s2, n);
1048 }
1049 
1050 #if !CAM_DRYOS
1051 void *memchr(const void *s, int c, int n) {
1052         return _memchr(s,c,n);
1053 }
1054 #endif
1055 
1056 //----------------------------------------------------------------------------
1057 
1058 void GetMemInfo(cam_meminfo *camera_meminfo)
1059 {
1060 // Use firmware GetMemInfo function to retrieve info about Canon heap memory allocation
1061 
1062 #if defined(CAM_DRYOS)
1063     // Prior to dryos R39 GetMemInfo returns 9 values, after R39 it returns 10 (all but 1 are used in each case)
1064     int fw_info[10];
1065     extern void _GetMemInfo(int*);
1066     _GetMemInfo(fw_info);
1067 
1068 #if defined(CAM_DRYOS_2_3_R39)
1069     // For newer dryos version copy all 9 used values to CHDK structure
1070     camera_meminfo->start_address        = fw_info[0];
1071     camera_meminfo->end_address          = fw_info[1];
1072     camera_meminfo->total_size           = fw_info[2];
1073     camera_meminfo->allocated_size       = fw_info[3];
1074     camera_meminfo->allocated_peak       = fw_info[4];
1075     camera_meminfo->allocated_count      = fw_info[5];
1076     camera_meminfo->free_size            = fw_info[6];
1077     camera_meminfo->free_block_max_size  = fw_info[7];
1078     camera_meminfo->free_block_count     = fw_info[8];
1079 #else
1080     // For older dryos version copy 8 used values to CHDK structure and calculate missing value
1081     camera_meminfo->start_address        = fw_info[0];
1082     camera_meminfo->end_address          = fw_info[0] + fw_info[1];
1083     camera_meminfo->total_size           = fw_info[1];
1084     camera_meminfo->allocated_size       = fw_info[2];
1085     camera_meminfo->allocated_peak       = fw_info[3];
1086     camera_meminfo->allocated_count      = fw_info[4];
1087     camera_meminfo->free_size            = fw_info[5];
1088     camera_meminfo->free_block_max_size  = fw_info[6];
1089     camera_meminfo->free_block_count     = fw_info[7];
1090 #endif
1091 #else // vxworks
1092 extern int sys_mempart_id;
1093     int fw_info[5];
1094     // -1 for invalid
1095     memset(camera_meminfo,0xFF,sizeof(cam_meminfo));
1096     if(!_TakeSemaphore(canon_heap_sem,CANON_HEAP_SEM_TIMEOUT)) {
1097 #ifdef CAM_NO_MEMPARTINFO
1098         camera_meminfo->free_block_max_size = _memPartFindMax(sys_mempart_id);
1099 #else
1100         _memPartInfoGet(sys_mempart_id,fw_info);
1101         // TODO we could fill in start address from _start + MEMISOSIZE, if chdk not in exmem
1102         // these are guessed, look reasonable on a540
1103         camera_meminfo->free_size = fw_info[0];
1104         camera_meminfo->free_block_count = fw_info[1];
1105         camera_meminfo->free_block_max_size = fw_info[2];
1106         camera_meminfo->allocated_size = fw_info[3];
1107         camera_meminfo->allocated_count = fw_info[4];
1108 #endif
1109         _GiveSemaphore(canon_heap_sem);
1110     }
1111 #endif
1112 }
1113 
1114 //----------------------------------------------------------------------------
1115 
1116 int rand(void) {
1117     return _rand();
1118 }
1119 
1120 void *srand(unsigned int seed) {
1121     return _srand(seed);
1122 }
1123 
1124 void qsort(void *__base, int __nelem, int __size, int (*__cmp)(const void *__e1, const void *__e2)) {
1125     _qsort(__base, __nelem, __size, __cmp);
1126 }
1127 
1128 static int shutdown_disabled = 0;
1129 void disable_shutdown() {
1130     if (!shutdown_disabled) {
1131         _LockMainPower();
1132         shutdown_disabled = 1;
1133     }
1134 }
1135 
1136 void enable_shutdown() {
1137     if (shutdown_disabled) {
1138         _UnlockMainPower();
1139         shutdown_disabled = 0;
1140     }
1141 }
1142 
1143 void camera_shutdown_in_a_second(void) {
1144     int i;
1145     _SetAutoShutdownTime(1); // 1 sec
1146     for (i=0;i<200;i++)
1147         _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").
1148 }
1149 
1150 void EnterToCompensationEVF(void)
1151 {
1152   _EnterToCompensationEVF();
1153 }
1154 
1155 void ExitFromCompensationEVF()
1156 {
1157   _ExitFromCompensationEVF();
1158 }
1159 
1160 void TurnOnBackLight(void)
1161 {
1162   _TurnOnBackLight();
1163 }
1164 
1165 void TurnOffBackLight(void)
1166 {
1167   _TurnOffBackLight();
1168 }
1169 
1170 extern void gui_set_need_restore();
1171 
1172 void TurnOnDisplay(void)
1173 {
1174   _TurnOnDisplay();
1175   // required to re-draw the canon and CHDK UI after re-enabling display
1176   gui_set_need_restore() ;
1177 }
1178 
1179 void TurnOffDisplay(void)
1180 {
1181   _TurnOffDisplay();
1182 }
1183 
1184 void DoAELock(void)
1185 {
1186   if (!camera_info.state.mode_play)
1187   {
1188      _DoAELock();
1189   }
1190 }
1191 
1192 void UnlockAE(void)
1193 {
1194   if (!camera_info.state.mode_play)
1195   {
1196      _UnlockAE();
1197   }
1198 }
1199 
1200 void DoAFLock(void)
1201 {
1202   if (!camera_info.state.mode_play)
1203   {
1204      int af_lock=1;
1205      _DoAFLock();
1206      set_property_case(PROPCASE_AF_LOCK,&af_lock,sizeof(af_lock));
1207   }
1208 }
1209 
1210 void UnlockAF(void)
1211 {
1212   if (!camera_info.state.mode_play)
1213   {
1214      int af_lock=0;
1215      _UnlockAF();
1216      set_property_case(PROPCASE_AF_LOCK,&af_lock,sizeof(af_lock));
1217   }
1218 }
1219 
1220 int EngDrvRead(int gpio_reg)
1221 {
1222   return _EngDrvRead(gpio_reg);
1223 }
1224 
1225 #if CAM_MULTIPART
1226 
1227 #define SECTOR_SIZE 512
1228 static char *mbr_buf=(void*)0;
1229 static unsigned long drive_sectors;
1230 
1231 int is_mbr_loaded()
1232 {
1233         return (mbr_buf == (void*)0) ? 0 : 1;
1234 }
1235 
1236 #ifndef CAM_DRYOS
1237 
1238 int mbr_read(char* mbr_sector, unsigned long drive_total_sectors, unsigned long *part_start_sector,  unsigned long *part_length){
1239 // return value: 1 - success, 0 - fail
1240 // called only in VxWorks
1241 
1242  int offset=0x10; // points to partition #2
1243  int valid;
1244 
1245  if ((mbr_sector[0x1FE]!=0x55) || (mbr_sector[0x1FF]!=0xAA)) return 0; // signature check
1246 
1247  mbr_buf=_AllocateUncacheableMemory(SECTOR_SIZE);
1248  _memcpy(mbr_buf,mbr_sector,SECTOR_SIZE);
1249  drive_sectors=drive_total_sectors;
1250 
1251  while(offset>=0) {
1252 
1253   *part_start_sector=(*(unsigned short*)(mbr_sector+offset+0x1C8)<<16) | *(unsigned short*)(mbr_sector+offset+0x1C6);
1254   *part_length=(*(unsigned short*)(mbr_sector+offset+0x1CC)<<16) | *(unsigned short*)(mbr_sector+offset+0x1CA);
1255 
1256   valid= (*part_start_sector) && (*part_length) &&
1257          (*part_start_sector<=drive_total_sectors) &&
1258          (*part_start_sector+*part_length<=drive_total_sectors) &&
1259          ((mbr_sector[offset+0x1BE]==0) || (mbr_sector[offset+0x1BE]==0x80)); // status: 0x80 (active) or 0 (non-active)
1260 
1261   if (valid && ((mbr_sector[0x1C2+offset]==0x0B) || (mbr_sector[0x1C2+offset]==0x0C))) break;   // FAT32 secondary partition
1262 
1263   offset-=0x10;
1264 
1265  }
1266 
1267  return valid;
1268 }
1269 
1270 #else
1271 
1272 int mbr_read_dryos(unsigned long drive_total_sectors, char* mbr_sector ){
1273 // Called only in DRYOS
1274  mbr_buf=_AllocateUncacheableMemory(SECTOR_SIZE);
1275  _memcpy(mbr_buf,mbr_sector,SECTOR_SIZE);
1276  drive_sectors=drive_total_sectors;
1277  return drive_total_sectors;
1278 }
1279 
1280 #endif
1281 
1282 int get_part_count(void)
1283 {
1284   unsigned long part_start_sector, part_length;
1285   char part_status, part_type;
1286   int i;
1287   int count=0;
1288   if (is_mbr_loaded())
1289   {
1290     for (i=0; i<=3;i++)
1291     {
1292       part_start_sector=(*(unsigned short*)(mbr_buf+i*16+0x1C8)<<16) | *(unsigned short*)(mbr_buf+i*16+0x1C6);
1293       part_length=(*(unsigned short*)(mbr_buf+i*16+0x1CC)<<16) | *(unsigned short*)(mbr_buf+i*16+0x1CA);
1294       part_status=mbr_buf[i*16+0x1BE];
1295       part_type=mbr_buf[0x1C2+i*16];
1296       if ( part_start_sector && part_length && part_type && ((part_status==0) || (part_status==0x80)) ) count++;
1297     }
1298   }
1299   return count;
1300 }
1301 int get_part_type()
1302 {
1303   int partType = 0x00;
1304   if (is_mbr_loaded())
1305   {
1306     partType=mbr_buf[0x1C2+(get_active_partition()-1)*16];
1307   }
1308   return partType;
1309 } 
1310 
1311 static int boot_partition = 0;
1312 static int partition_changed = 0;
1313 int is_partition_changed()
1314 {
1315   return partition_changed;
1316 }
1317 
1318 int swap_partitions(int new_partition)
1319 {
1320   if (is_mbr_loaded())
1321   {
1322     int i,j,p;
1323     char c;
1324     
1325     int partition_count = get_part_count();
1326     int active_partition = get_active_partition();
1327     
1328     if(!boot_partition)
1329     {
1330       boot_partition = active_partition;
1331     }
1332 
1333     // wrong input
1334     if( new_partition > partition_count || new_partition <= 0 )
1335     {
1336       return 0;
1337     }
1338     partition_changed = (new_partition==boot_partition)?0:1;
1339     
1340     // rotate partitions till new_partition is found
1341     for(j=0;j<partition_count;++j)
1342     {
1343       if(new_partition == get_active_partition())
1344       {
1345         break;
1346       }
1347       for(i=0;i<16;i++)
1348       {
1349         c=mbr_buf[i+0x1BE];
1350         for(p=1; p<partition_count; ++p)
1351         {
1352           mbr_buf[i+(p-1)*16+0x1BE]=mbr_buf[i+p*16+0x1BE];
1353         }
1354         mbr_buf[i+(partition_count-1)*16+0x1BE]=c;
1355       }
1356     }
1357     _WriteSDCard(0,0,1,mbr_buf);
1358   }
1359   return 1;
1360 }
1361 
1362 unsigned char get_active_partition(void)
1363 {
1364   unsigned int  partition_start[4];
1365   unsigned char partition_number = 1;
1366   int partition_count = get_part_count();
1367   int i;
1368 
1369   for( i=0; i<partition_count; ++i )
1370   {
1371     int a = mbr_buf[0x01C6+(i)*16];
1372     int b = mbr_buf[0x01C7+(i)*16];
1373     int c = mbr_buf[0x01C8+(i)*16];
1374     int d = mbr_buf[0x01C9+(i)*16];
1375     partition_start[i] = (((((d<<8) +c)<<8) +b)<<8) +a;
1376   }
1377   for( i=1; i<partition_count; ++i )
1378   {
1379     if(partition_start[i]<partition_start[0])
1380     {
1381       ++partition_number;
1382     }
1383   }
1384   return partition_number;
1385 }
1386 
1387 void create_partitions(void){
1388         if (is_mbr_loaded())
1389         {
1390          unsigned long start, length;
1391          char type;
1392 
1393          _memset(mbr_buf,0,SECTOR_SIZE);
1394 
1395          start=1; length=2*1024*1024/SECTOR_SIZE; //2 Mb
1396          type=1; // FAT primary
1397          mbr_buf[0x1BE + 4]=type;
1398          mbr_buf[0x1BE + 8]=start;   mbr_buf[0x1BE + 9]=start>>8;   mbr_buf[0x1BE + 10]=start>>16;  mbr_buf[0x1BE + 11]=start>>24;
1399          mbr_buf[0x1BE + 12]=length; mbr_buf[0x1BE + 13]=length>>8; mbr_buf[0x1BE + 14]=length>>16; mbr_buf[0x1BE + 15]=length>>24;
1400 
1401          start=start+length; length=drive_sectors-start-1;
1402          type=0x0B;  //FAT32 primary;
1403          mbr_buf[0x1CE + 4]=type;
1404          mbr_buf[0x1CE + 8]=start;   mbr_buf[0x1CE + 9]=start>>8;   mbr_buf[0x1CE + 10]=start>>16;  mbr_buf[0x1CE + 11]=start>>24;
1405          mbr_buf[0x1CE + 12]=length; mbr_buf[0x1CE + 13]=length>>8; mbr_buf[0x1CE + 14]=length>>16; mbr_buf[0x1CE + 15]=length>>24;
1406 
1407          mbr_buf[0x1FE]=0x55; mbr_buf[0x1FF]=0xAA; // signature;
1408 
1409          _WriteSDCard(0,0,1,mbr_buf);
1410         }
1411 }
1412 
1413 #else
1414 
1415 // Dummy for scripts if not implemented in camera
1416 int swap_partitions(int new_partition) { return 0; }
1417 int get_part_count(void) { return 1; }
1418 int get_part_type() { return 0; }
1419 unsigned char get_active_partition(void) { return 1; }
1420 int is_partition_changed() { return 0; }
1421 
1422 #endif
1423 
1424 int mute_on_zoom(int x){
1425  static int old_busy=0;
1426  int busy=zoom_busy||focus_busy;
1427  if (old_busy!=busy) {
1428   if (busy) {
1429 #if CAM_CAN_MUTE_MICROPHONE
1430    if (conf.mute_on_zoom) _TurnOffMic();
1431 #endif
1432    }
1433    else {
1434 #if CAM_CAN_MUTE_MICROPHONE
1435   if (conf.mute_on_zoom) _TurnOnMic();
1436 #endif
1437 #if CAM_EV_IN_VIDEO
1438   if (get_ev_video_avail()) set_ev_video_avail(0);
1439 #endif
1440   }
1441   old_busy=busy;
1442  }
1443  return x; // preserve R0 if called from assembler
1444 }
1445 
1446 
1447 #if CAM_AF_SCAN_DURING_VIDEO_RECORD
1448 void MakeAFScan(void){
1449  int a=0, save;
1450  if (zoom_busy || focus_busy) return;
1451  save=some_flag_for_af_scan;
1452  some_flag_for_af_scan=0;
1453 #if CAM_AF_SCAN_DURING_VIDEO_RECORD == 2
1454  parameter_for_af_scan=3;
1455 #endif
1456  _MakeAFScan(&a, 3);
1457  some_flag_for_af_scan=save;
1458 #if CAM_RESET_AEL_AFTER_VIDEO_AF
1459  int ae_lock;
1460  get_property_case(PROPCASE_AE_LOCK,&ae_lock,sizeof(ae_lock));
1461  if (ae_lock == 0)                                              // AE not locked so ensure it is unlocked after re-focus
1462          _ExpCtrlTool_StartContiAE(0,0);
1463  else                                                                   // AE locked before so re-lock after
1464          _ExpCtrlTool_StopContiAE(0,0);
1465 #else
1466  _ExpCtrlTool_StartContiAE(0,0);
1467 #endif
1468 }
1469 #endif
1470 
1471 long __attribute__((weak)) get_jogdial_direction(void)  { return 0; }
1472 void __attribute__((weak)) JogDial_CW(void)     {}
1473 void __attribute__((weak)) JogDial_CCW(void)    {}
1474 
1475 #if defined (DNG_EXT_FROM)
1476 
1477 #define DNG_EXT_TO ".DNG"
1478 
1479 typedef int(*p_some_f)(char*, int);
1480 
1481 extern p_some_f some_f_for_dng;  // camera variable!
1482 extern char* second_ext_for_dng; // camera variable!
1483 
1484 p_some_f default_some_f;
1485 char *   default_second_ext;
1486 
1487 int my_some_f(char *s, int x){
1488   char *f;
1489   f=strstr(s, DNG_EXT_FROM);
1490   if (f) _memcpy(f, DNG_EXT_TO, sizeof(DNG_EXT_TO)-1);
1491   return default_some_f(s, x);
1492 }
1493 
1494 void save_ext_for_dng(void){
1495  default_some_f=some_f_for_dng;
1496  default_second_ext=second_ext_for_dng;
1497 }
1498 
1499 void change_ext_to_dng(void){
1500  some_f_for_dng=my_some_f;
1501  second_ext_for_dng=DNG_EXT_TO;
1502 }
1503 
1504 void change_ext_to_default(void){
1505  some_f_for_dng=default_some_f;
1506  second_ext_for_dng=default_second_ext;
1507 }
1508 
1509 #endif
1510 
1511 #if !CAM_DRYOS
1512 static long drv_struct[16];
1513 #endif
1514 
1515 long dh_err()
1516 {
1517     return -1;
1518 }
1519 
1520 #if !CAM_DRYOS
1521 void drv_self_hide()
1522 {
1523     long drvnum;
1524 
1525     drvnum = _iosDrvInstall(dh_err,dh_err,dh_err,dh_err,dh_err,dh_err,dh_err);
1526     if (drvnum >= 0)
1527         _iosDevAdd(drv_struct, "A/DISKBOOT.BIN", drvnum);
1528 }
1529 
1530 void drv_self_unhide()
1531 {
1532  _iosDevDelete(drv_struct);
1533 }
1534 #endif
1535 
1536 int  apex2us(int apex_tv){
1537 #if CAM_EXT_TV_RANGE
1538 /*
1539  Extended Tv, by barberofcivil, http://chdk.setepontos.com/index.php/topic,4392.0.html
1540  Explanation by reyalP:
1541  In every port, the original shutter overrides (as opposed to super long exposure) worked by
1542  setting the propcase values at some point after auto-exposure has happened (except in manual
1543  modes, where the manual control propcases may be used instead). The Canon code previously took
1544  these values unchanged for short exposures. In newer cameras, like on the SX10 / SD980, the value
1545  is changed, apparently some time after it has been retrieved from the propcase. We know this is
1546  the case, because the propcase value itself doesn't get clamped to the allowed range (if it did,
1547  barberofcivil's code wouldn't work).
1548 */
1549         short tv;
1550         tv = shooting_get_tv96();
1551         if (tv<-576 || tv!=apex_tv) return 1000000.0*pow(2.0, -tv/96.0);
1552         else return _apex2us(apex_tv);
1553 #else
1554         return 0;
1555 #endif
1556 }
1557 
1558 void PostLogicalEventForNotPowerType(unsigned id, unsigned x) {
1559         _PostLogicalEventForNotPowerType(id,x);
1560 }
1561 
1562 void PostLogicalEventToUI(unsigned id, unsigned x) {
1563         _PostLogicalEventToUI(id,x);
1564 }
1565 
1566 void SetLogicalEventActive(unsigned id, unsigned state) {
1567         _SetLogicalEventActive(id, state);
1568 }
1569 
1570 void SetScriptMode(unsigned mode) {
1571         _SetScriptMode(mode);
1572 }
1573 
1574 // TODO this belongs lib.c, but not all cameras include it
1575 // same as bitmap width for most cameras, override in platform/sub/lib.c as needed
1576 int __attribute__((weak)) vid_get_viewport_width() {
1577         return camera_screen.width;
1578 }
1579 
1580 // Physical width of viewport row in bytes
1581 int __attribute__((weak)) vid_get_viewport_byte_width() {
1582         return 720 * 6 / 4;     // For most cameras viewport is 720 pixels wide, each group of 4 pixels uses 6 bytes (UYVYYY)
1583 }
1584 
1585 // Y multiplier for cameras with 480 pixel high viewports (CHDK code assumes 240)
1586 int __attribute__((weak)) vid_get_viewport_yscale() {
1587         return 1;               // For most cameras viewport is 240 pixels high
1588 }
1589 
1590 // viewport x offset - used when image size != viewport size (zebra, histogram, motion detect & edge overlay)
1591 int __attribute__((weak)) vid_get_viewport_xoffset() {
1592         return 0;
1593 }
1594 
1595 // viewport y offset - used when image size != viewport size (zebra, histogram, motion detect & edge overlay)
1596 int __attribute__((weak)) vid_get_viewport_yoffset() {
1597         return 0;
1598 }
1599 
1600 // viewport display x offset - used when image size != viewport size (zebra, histogram, motion detect & edge overlay)
1601 int __attribute__((weak)) vid_get_viewport_display_xoffset() {
1602         return vid_get_viewport_xoffset();
1603 }
1604 
1605 // viewport display y offset - used when image size != viewport size (zebra, histogram, motion detect & edge overlay)
1606 int __attribute__((weak)) vid_get_viewport_display_yoffset() {
1607         return vid_get_viewport_yoffset();
1608 }
1609 
1610 // format of live view viewport
1611 #ifndef THUMB_FW
1612 int vid_get_viewport_type() {
1613         return LV_FB_YUV8;
1614 }
1615 // D6 cameras must define
1616 #endif
1617 
1618 // for cameras with two (or more?) RAW buffers this can be used to speed up DNG creation by
1619 // calling reverse_bytes_order only once. Override in platform/sub/lib.c
1620 char __attribute__((weak)) *hook_alt_raw_image_addr() {
1621         return hook_raw_image_addr();
1622 }
1623 
1624 void __attribute__((weak)) vid_turn_off_updates()
1625 {
1626 }
1627 
1628 void __attribute__((weak)) vid_turn_on_updates()
1629 {
1630 }
1631 
1632 // use _GetFocusLensSubjectDistance for this on dryos, vx functions are basically equivlent
1633 // not used in CHDK currently for either OS
1634 #ifdef CAM_DRYOS
1635 long __attribute__((weak)) _GetCurrentTargetDistance()
1636 {
1637         return _GetFocusLensSubjectDistance();
1638 }
1639 #endif
1640 
1641 int add_ptp_handler(int opcode, ptp_handler handler, int unknown)
1642 {
1643 #ifdef CAM_CHDK_PTP
1644     return _add_ptp_handler(opcode,handler,unknown);
1645 #else
1646     return 0;
1647 #endif
1648 }
1649 
1650 #ifdef CAM_PTP_USE_NATIVE_BUFFER
1651 int get_ptp_file_buf_size(void)
1652 {
1653     return _get_ptp_buf_size(CAM_PTP_FILE_BUFFER_ID);
1654 }
1655 
1656 char *get_ptp_file_buf(void)
1657 {
1658     return _get_ptp_file_buf();
1659 }
1660 #endif
1661 
1662 int CreateTask (const char *name, int prio, int stack_size, void *entry)
1663 {
1664     return _CreateTask(name, prio, stack_size, entry, 0);
1665 }
1666 
1667 void ExitTask()
1668 {
1669     _ExitTask();
1670 }
1671 
1672 // TODO not in sigs for vx yet
1673 #ifndef CAM_DRYOS
1674 void __attribute__((weak)) _reboot_fw_update(const char *fw_update)
1675 {
1676         return;
1677 }
1678 #endif
1679 
1680 #ifdef CAM_DRYOS
1681 int __attribute__((weak)) switch_mode_usb(int mode)
1682 {
1683 #ifdef CAM_CHDK_PTP
1684     if ( mode == 0 ) {
1685         _Rec2PB();
1686         _set_control_event(0x80000000|CAM_USB_EVENTID);
1687     } else if ( mode == 1 ) {
1688         _set_control_event(CAM_USB_EVENTID);
1689         _PB2Rec();
1690     } else return 0;
1691     return 1;
1692 #else
1693   return 0;
1694 #endif // CAM_CHDK_PTP
1695 }
1696 
1697 #else // vxworks
1698 // this doesn't need any special functions so it's defined even without CHDK_CAM_PTP
1699 int __attribute__((weak)) switch_mode_usb(int mode)
1700 {
1701     if ( mode == 0 ) {
1702         // TODO should we revert scriptmode and/or levent? seems to work without
1703         levent_set_play();
1704     } else if ( mode == 1 ) {
1705 #ifdef CAM_USB_EVENTID_VXWORKS
1706         _SetScriptMode(1); // needed to override event
1707         _SetLogicalEventActive(CAM_USB_EVENTID_VXWORKS,0); // set levent "ConnectUSBCable" inactive
1708 #endif
1709         levent_set_record();
1710     } else return 0;
1711     return 1;
1712 }
1713 #endif // vxworks
1714 
1715 /*
1716 // this wrapper isn't currently needed
1717 // 7 calls functions and sets some MMIOs, but doesn't disable caches and actually restart
1718 // 3 skips one function call on some cameras, but does restart
1719 void Restart(unsigned option) {
1720         _Restart(option);
1721 }
1722 */
1723 
1724 unsigned char SetFileAttributes(const char* fn, unsigned char attr)
1725 {
1726 #ifdef CAM_DRYOS_2_3_R39
1727     return _SetFileAttributes(fn, attr);
1728 #else
1729     int fd;
1730     unsigned char ret = -1;
1731     
1732     fd = open(fn, 0, 0);
1733     if( fd ) {
1734         _SetFileAttributes(fd, attr);
1735         close(fd);
1736         ret = attr;
1737     }
1738     return ret;
1739 #endif
1740 }
1741 
1742 // Default implementation of PTP live view functions.
1743 // Override as needed for camera specific variations (see G12/SX30/IXUS310/SX130IS for working examples)
1744 
1745 int __attribute__((weak)) vid_get_viewport_display_xoffset_proper() { return vid_get_viewport_display_xoffset()*2; }
1746 int __attribute__((weak)) vid_get_viewport_display_yoffset_proper() { return vid_get_viewport_display_yoffset(); }
1747 int __attribute__((weak)) vid_get_viewport_buffer_width_proper()    { return 720; }
1748 #ifdef THUMB_FW
1749 int __attribute__((weak)) vid_get_viewport_width_proper()           { return vid_get_viewport_width(); }
1750 int __attribute__((weak)) vid_get_viewport_height_proper()          { return vid_get_viewport_height(); }
1751 #else
1752 int __attribute__((weak)) vid_get_viewport_width_proper()           { return vid_get_viewport_width()*2; }
1753 int __attribute__((weak)) vid_get_viewport_height_proper()          { return 240; }
1754 #endif
1755 int __attribute__((weak)) vid_get_viewport_fullscreen_height()      { return 240; }
1756 int __attribute__((weak)) vid_get_viewport_fullscreen_width()       { return vid_get_viewport_buffer_width_proper(); }
1757 
1758 int __attribute__((weak)) vid_get_palette_type()                    { return 0; }       // 0 = no palette into, 1 = 16 x 4 byte AYUV values, 
1759                                                                                         // 2 = 16 x 4 byte AYUV (A = 0..3), 3 = 256 x 4 byte AYUV (A = 0..3)
1760 int __attribute__((weak)) vid_get_palette_size()                    { return 0; }
1761 int __attribute__((weak)) vid_get_aspect_ratio()                    { return 0; }       // 0 = 4:3, 1 = 16:9 LCD Aspect Ratio, 2 = 3:2
1762 
1763 void __attribute__((weak)) *vid_get_bitmap_active_buffer()
1764 {
1765   return vid_get_bitmap_fb();   // *** does not get the active buffer! (override if active buffer can be determined)
1766 }
1767 
1768 void __attribute__((weak)) *vid_get_bitmap_active_palette()
1769 {
1770   return 0; // return no palette info unless overridden
1771 }
1772 
1773 // Get active viewport buffer address based on PLAY/REC mode.
1774 // Try to use 'live' buffer in REC mode if vid_get_viewport_live_fb is implemented
1775 // can return NULL in plaback mode, if a video is selected
1776 void *vid_get_viewport_active_buffer()
1777 {
1778   void *p;
1779 
1780   if (camera_info.state.mode_play)
1781   {
1782     p = vid_get_viewport_fb_d();
1783   } else {
1784     p = vid_get_viewport_live_fb();
1785     if ( !p )
1786     {
1787       p = vid_get_viewport_fb();
1788     }
1789   }
1790   
1791   return p;
1792 }
1793 
1794 /*
1795  debug logging function that can be sent to various places
1796  body is ifdef'd inside the body to allow exporting to modules
1797  eventproc version may require System.Create()/SystemEventInit first
1798 */
1799 void dbg_printf(char *fmt,...) {
1800 #ifdef DEBUG_LOGGING
1801     char s[256];
1802     __builtin_va_list va;
1803     __builtin_va_start(va, fmt);
1804     _vsprintf(s, fmt, va);
1805     __builtin_va_end(va);
1806 
1807     // stdout - for use with uart redirection
1808     _ExecuteEventProcedure("Printf",s);
1809     // camera log - will show up in crash dumps, or in stdout on ShowCameraLog
1810     // length limited, asserts if too long
1811     //s[59]=0;
1812     //_LogCameraEvent(0x20,s);
1813 
1814     // file
1815     /*
1816     FILE *f=fopen("A/DBGPRINT.LOG","ab");
1817     if(!f) {
1818         return;
1819     }
1820     fwrite(s,strlen(s),1,f);
1821     fclose(f);
1822     */
1823 #endif
1824 }
1825 
1826 #ifdef CAM_MISSING_RAND
1827 /* Some cameras does not have srand()/rand() functions in firmware, and should be aded here.
1828 E.G. a810/a2300
1829 */
1830 static unsigned int random_variable;
1831 void *_srand(unsigned int seed) {
1832     random_variable = seed;
1833     return (void *) &random_variable;
1834 }
1835 
1836 int _rand(void) {
1837     int value;
1838     value = random_variable*0x41C64E6D+0x3039;
1839     random_variable = value;
1840     value = (0x7FFF & (value>>0x10));
1841     return value;
1842 };
1843 #endif
1844 
1845 //  USB remote high speed timer for pulse width measurement and pulse counting
1846 
1847 extern int _SetHPTimerAfterNow(int delay, int(*good_cb)(int, int), int(*bad_cb)(int, int), int );
1848 extern int _CancelHPTimer(int);
1849 extern int usb_HPtimer_bad(int, int);
1850 extern int usb_HPtimer_good(int, int);
1851 
1852 int usb_HPtimer_handle=0;
1853 int usb_HPtimer_error_count=0;
1854 
1855 static int ARM_usb_HPtimer_good(int time, int interval) { return usb_HPtimer_good(time, interval); }
1856 static int ARM_usb_HPtimer_bad(int time, int interval) { return usb_HPtimer_bad(time, interval); }
1857 
1858 int start_usb_HPtimer(int interval)            // return 0 if timer already running or error,  1 if successful
1859 {
1860 #ifdef CAM_REMOTE_USB_HIGHSPEED
1861 
1862     if ( usb_HPtimer_handle == 0 )
1863     {
1864         if(interval < CAM_REMOTE_HIGHSPEED_LIMIT) interval=CAM_REMOTE_HIGHSPEED_LIMIT;
1865         usb_HPtimer_handle = _SetHPTimerAfterNow(interval,ARM_usb_HPtimer_good,ARM_usb_HPtimer_bad,interval);
1866         if (!(usb_HPtimer_handle & 0x01)) return 1 ;
1867         usb_HPtimer_handle = 0 ;
1868     }
1869 #endif
1870     return 0;
1871 }
1872 
1873 int stop_usb_HPtimer() 
1874 {
1875 #ifdef CAM_REMOTE_USB_HIGHSPEED
1876     if( usb_HPtimer_handle ) 
1877     {
1878         _CancelHPTimer(usb_HPtimer_handle);
1879         usb_HPtimer_handle = 0 ;
1880         return 1 ;
1881     }
1882 #endif
1883     return 0;
1884 }
1885 
1886 // HP timer functions, callbacks need to be ARM on VxWorks
1887 int SetHPTimerAfterNow(int delay, int(*good_cb)(int, int), int(*bad_cb)(int, int), int param)
1888 {
1889     return _SetHPTimerAfterNow(delay,good_cb,bad_cb,param);
1890 }
1891 
1892 int CancelHPTimer(int handle)
1893 {
1894     return _CancelHPTimer(handle);
1895 }
1896 
1897 // Override HDMI power on in rec mode for using HDMI Hotplug detect as remote
1898 // note does not disable power if remote turned off or channel changed
1899 // May want to add support for controlling independent of remote as output signal
1900 #ifdef CAM_REMOTE_HDMI_POWER_OVERRIDE
1901 extern void _EnableHDMIPower();
1902 void update_hdmi_power_override()
1903 {
1904     static int oldhdmistate = -1;
1905     if ((camera_info.state.mode_rec == 1) && conf.remote_enable && (conf.remote_input_channel == REMOTE_INPUT_HDMI_HPD))
1906     {
1907         /* if switched to shooting mode and remote using HDMI hotplug is enabled, switch on HDMI Power */
1908         /* just do it once on every change because it needs i2c communication depending on HDMI tranceiver */
1909         if (oldhdmistate != 1)
1910         {
1911             _EnableHDMIPower();
1912         }
1913         oldhdmistate = 1;
1914     }
1915     else
1916     {
1917         oldhdmistate = 0;
1918     }
1919 }
1920 #endif
1921 
1922 // disable camera error(s), E32 is the only error that can be handled at the moment (on newer 'IS' cameras)
1923 #if (OPT_DISABLE_CAM_ERROR)
1924 #warning OPT_DISABLE_CAM_ERROR enabled
1925 void DisableCamError(void)
1926 {
1927     extern void _DisableISDriveError(void);
1928     _DisableISDriveError();
1929 }
1930 #endif
1931 
1932 //---------------------------------------------------------------
1933 // Semaphore & Assert
1934 
1935 void DebugAssert(char *err, int line)
1936 {
1937 #if CAM_3ARG_DebugAssert
1938     extern void _DebugAssert(int, char*, int);
1939     _DebugAssert(0, err, line);
1940 #else
1941     extern void _DebugAssert(char*, int);
1942     _DebugAssert(err, line);
1943 #endif
1944 }
1945 
1946 int CreateBinarySemaphore(char *name, int init)
1947 {
1948     extern int _CreateBinarySemaphore(char*, int);
1949     return _CreateBinarySemaphore(name, init);
1950 }
1951 
1952 int TakeSemaphore(int sem, int timeout)
1953 {
1954     return _TakeSemaphore(sem, timeout);
1955 }
1956 
1957 void GiveSemaphore(int sem)
1958 {
1959     _GiveSemaphore(sem);
1960 }
1961 
1962 //---------------------------------------------------------------

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