root/platform/generic/wrappers.c

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

DEFINITIONS

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

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

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