source: trunk/platform/generic/wrappers.c @ 934

Revision 934, 32.3 KB checked in by rudi_de, 16 months ago (diff)

Aktualisierung auf Rev. 1622 internationaler Branch: Release-1.0
http://trac.assembla.com/chdk/changeset/1622/branches/release-1_0

Betrifft alle DryOS Kameras

  • Korrektur der Reihenfolge von Änderungs- und Zugriffszeit in DryOS utime()
  • Testskript llibtst.lua aktualisiert
  • Property svn:eol-style set to native
Line 
1#include "camera.h"
2#include "lolevel.h"
3#include "platform.h"
4#include "conf.h"
5#include "math.h"
6#include "levent.h"
7#include "stdlib.h"
8
9//----------------------------------------------------------------------------
10// Char Wrappers
11
12#if CAM_DRYOS
13#define _U      0x01    /* upper */
14#define _L      0x02    /* lower */
15#define _D      0x04    /* digit */
16#define _C      0x20    /* cntrl */
17#define _P      0x10    /* punct */
18#define _S      0x40    /* white space (space/lf/tab) */
19#define _X      0x80    /* hex digit */
20#define _SP     0x08    /* hard space (0x20) */
21static int _ctype(int c,int t) {
22    extern unsigned char ctypes[];  // Firmware ctypes table (in stubs_entry.S)
23    return ctypes[c&0xFF] & t;
24}
25
26int isdigit(int c) { return _ctype(c,_D); }
27int isspace(int c) { return _ctype(c,_S); }
28int isalpha(int c) { return _ctype(c,(_U|_L)); }
29int isupper(int c) { return _ctype(c,_U); }
30int islower(int c) { return _ctype(c,_L); }
31int ispunct(int c) { return _ctype(c,_P); }
32int isxdigit(int c) { return _ctype(c,(_X|_D)); }
33int iscntrl(int c) { return _ctype(c,_C); }
34
35int tolower(int c) { return isupper(c) ? c | 0x20 : c; }
36int toupper(int c) { return islower(c) ? c & ~0x20 : c; }
37
38#else   //!CAM_DRYOS
39
40int isdigit(int c) { return _isdigit(c); }
41int isspace(int c) { return _isspace(c); }
42int isalpha(int c) { return _isalpha(c); }
43int isupper(int c) { return _isupper(c); }
44int islower(int c) { return _islower(c); }
45int ispunct(int c) { return _ispunct(c); }
46int isxdigit(int c) { return _isxdigit(c); }
47
48// don't want to require the whole ctype table on vxworks just for this one
49int iscntrl(int c) { return ((c >=0 && c <32) || c == 127); }
50
51int tolower(int c) { return _tolower(c); }
52int toupper(int c) { return _toupper(c); }
53
54#endif
55
56int isalnum(int c) { return (isdigit(c) || isalpha(c)); }
57
58//----------------------------------------------------------------------------
59
60void msleep(long msec)
61{
62    _SleepTask(msec);
63}
64
65#ifndef CAM_DRYOS
66long task_lock()
67{
68    return _taskLock();
69}
70
71long task_unlock()
72{
73    return _taskUnlock();
74}
75
76const char *task_name(int id)
77{
78    return _taskName(id);
79}
80
81int task_id_list_get(int *idlist,int size)
82{
83    return _taskIdListGet(idlist,size);
84}
85
86void remount_filesystem()
87{
88    _Unmount_FileSystem();
89    _Mount_FileSystem();
90}
91#endif
92
93long get_property_case(long id, void *buf, long bufsize)
94{
95    return _GetPropertyCase(id, buf, bufsize);
96}
97
98long set_property_case(long id, void *buf, long bufsize)
99{
100    return _SetPropertyCase(id, buf, bufsize);
101}
102
103long get_parameter_data(long id, void *buf, long bufsize)
104{
105    return _GetParameterData(id|0x4000, buf, bufsize);
106}
107
108long set_parameter_data(long id, void *buf, long bufsize)
109{
110    return _SetParameterData(id|0x4000, buf, bufsize);
111}
112
113void mark_filesystem_bootable()
114{
115#ifdef  CAM_DRYOS_2_3_R47
116    // DryOS release 47 (2011) no longer has the UpdateMBROnFlash function to write the master boot record on
117    // the SD card. Instead it has seperate functions for writing the 'BOOTDISK' and 'SCRIPT' signatures to
118    // the MBR. The firmware function also takes care of writing the bootdisk signature to the correct location
119    // for FAT32 formatted cards.
120    _MakeSDCardBootable(0);
121#else
122    _UpdateMBROnFlash(0, 0x40, "BOOTDISK");
123#endif
124}
125
126void __attribute__((weak)) vid_bitmap_refresh()
127{
128    _RefreshPhysicalScreen(1);
129}
130
131long lens_get_zoom_pos()
132{
133    return _GetZoomLensCurrentPosition();
134}
135
136void lens_set_zoom_pos(long newpos)
137{
138}
139
140long lens_get_zoom_point()
141{
142    return _GetZoomLensCurrentPoint();
143}
144
145void lens_set_zoom_point(long newpt)
146{
147    if (newpt < 0) {
148        newpt = 0;
149    } else if (newpt >= zoom_points) {
150        newpt = zoom_points-1;
151    }
152
153#if defined(CAMERA_sx30) || \
154    defined(CAMERA_g12) || \
155    defined(CAMERA_sx130is)|| \
156    defined(CAMERA_g10) || \
157    defined(CAMERA_sx220hs) || \
158    defined(CAMERA_sx230hs) || \
159    defined(CAMERA_ixus220_elph300hs)
160        if (lens_get_zoom_point() != newpt)
161        {
162                // Get current digital zoom mode & state
163                // state == 1 && mode == 0 --> Digital Zoom Standard
164                int digizoom_mode, digizoom_state, digizoom_pos;
165                get_property_case(PROPCASE_DIGITAL_ZOOM_MODE,&digizoom_mode,sizeof(digizoom_mode));
166                get_property_case(PROPCASE_DIGITAL_ZOOM_STATE,&digizoom_state,sizeof(digizoom_state));
167                get_property_case(PROPCASE_DIGITAL_ZOOM_POSITION,&digizoom_pos,sizeof(digizoom_pos));
168                if ((digizoom_state == 1) && (digizoom_mode == 0) && (digizoom_pos != 0))
169                {
170                        // reset digital zoom in case camera is in this zoom range
171                        extern void _PT_MoveDigitalZoomToWide();
172                        _PT_MoveDigitalZoomToWide();
173                }
174
175  #if defined(CAMERA_sx30) || \
176    defined(CAMERA_sx130is) || \
177    defined(CAMERA_sx220hs) || \
178    defined(CAMERA_sx230hs) || \
179    defined(CAMERA_ixus220_elph300hs)
180                // SX30 - _MoveZoomLensWithPoint crashes camera
181                // _PT_MoveOpticalZoomAt works, and updates PROPCASE_OPTICAL_ZOOM_POSITION; but doesn't wait for zoom to finish
182        // IXUS220, SX220/230 - _MoveZoomLensWithPoint does not notify the JPEG engine of the new focal length,
183        //                      causing incorrect lens distortion fixes to be applied; _PT_MoveOpticalZoomAt works
184                extern void _PT_MoveOpticalZoomAt(long*);
185                _PT_MoveOpticalZoomAt(&newpt);
186  #else
187            _MoveZoomLensWithPoint((short*)&newpt);
188  #endif
189
190                // have to sleep here, zoom_busy set in another task, without sleep this will hang
191                while (zoom_busy) msleep(10);
192
193                // g10,g12 & sx30 only use this value for optical zoom
194                zoom_status=ZOOM_OPTICAL_MAX;
195
196  #if defined(CAMERA_g12)|| defined(CAMERA_g10)
197            _SetPropertyCase(PROPCASE_OPTICAL_ZOOM_POSITION, &newpt, sizeof(newpt));
198  #endif
199        }
200#else   // !(CAMERA_g10 || CAMERA_g12 || CAMERA_sx30)
201    _MoveZoomLensWithPoint((short*)&newpt);
202
203    // tight loop here hangs some cameras (the task that clears zoom_busy
204    // is starved; seen at least on S95 and IXUS 220), so stick in a sleep
205    while (zoom_busy) msleep(10);
206
207    if (newpt==0) zoom_status=ZOOM_OPTICAL_MIN;
208    else if (newpt >= zoom_points) zoom_status=ZOOM_OPTICAL_MAX;
209    else zoom_status=ZOOM_OPTICAL_MEDIUM;
210    _SetPropertyCase(PROPCASE_OPTICAL_ZOOM_POSITION, &newpt, sizeof(newpt));
211#endif  // !(CAMERA_g10 || CAMERA_g12 || CAMERA_sx30)
212}
213
214void lens_set_zoom_speed(long newspd)
215{
216    if (newspd < 5) {
217        newspd = 5;
218    } else if (newspd > 100) {
219        newspd = 100;
220    }
221    _SetZoomActuatorSpeedPercent((short*)&newspd);
222}
223
224void lens_set_focus_pos(long newpos)
225{
226    if (newpos >= MAX_DIST) newpos = INFINITY_DIST; // Set to infinity value that will work on all cameras
227    _MoveFocusLensToDistance((short*)&newpos);
228    while ((shooting_is_flash_ready()!=1) || (focus_busy)) msleep(10);
229    newpos = _GetFocusLensSubjectDistance();
230    _SetPropertyCase(PROPCASE_SUBJECT_DIST1, &newpos, sizeof(newpos));
231    _SetPropertyCase(PROPCASE_SUBJECT_DIST2, &newpos, sizeof(newpos));
232}
233
234void play_sound(unsigned sound)
235{
236        static const int sounds[]={ 0x2001, //startup sound
237                                0x2002, //shutter sound
238                                0x2003, //button press sound
239                                0x2004, //self-timer sound
240                                0xC211, //short beep
241                                50000,  // AF confirmation
242                                0xC507, // error beep imo
243                                0x400D, // LONG ERROR BEEP CONTINIUOUS- warning, cannot be stopped (yet)
244                            };
245    if(sound >= sizeof(sounds)/sizeof(sounds[0]))
246        return;
247
248    _PT_PlaySound(sounds[sound], 0);
249}
250
251long stat_get_vbatt()
252{
253    return _VbattGet();
254}
255
256int get_battery_temp()
257{
258    return _GetBatteryTemperature();
259}
260
261int get_ccd_temp()
262{
263    return _GetCCDTemperature();
264}
265
266int get_optical_temp()
267{
268    return _GetOpticalTemperature();
269}
270
271long get_tick_count()
272{
273long t;
274#if !CAM_DRYOS
275    _GetSystemTime(&t);
276    return t;
277#else
278    return (int)_GetSystemTime(&t);
279#endif
280}
281
282//----------------------------------------------------------------------------
283// I/O wrappers
284
285/*int creat (const char *name, int flags)
286{
287    return _creat(name, flags);
288}*/
289
290int open (const char *name, int flags, int mode )
291{
292#ifdef CAM_DRYOS
293    if(!name || name[0]!='A')
294        return -1;
295#endif
296#if defined(CAM_STARTUP_CRASH_FILE_OPEN_FIX)    // enable fix for camera crash at startup when opening the conf / font files
297                                                                                                // see http://chdk.setepontos.com/index.php?topic=6179.0
298        if (flags == O_RDONLY)                                          // At startup opening the conf / font files conflicts with Canon task if use _Open. Camera can randomly crash.
299                return _open(name, flags, mode);
300#endif
301    return _Open(name, flags, mode);
302}
303
304int close (int fd)
305{
306    return _Close(fd);
307}
308
309int write (int fd, const void *buffer, long nbytes)
310{
311    return _Write(fd, buffer, nbytes);
312}
313
314int read (int fd, void *buffer, long nbytes)
315{
316    return _Read(fd, buffer, nbytes);
317}
318
319int lseek (int fd, long offset, int whence)
320{
321    return _lseek(fd, offset, whence); /* yes, it's lower-case lseek here since Lseek calls just lseek (A610) */
322}
323
324long mkdir(const char *dirname)
325{
326        return _MakeDirectory_Fut(dirname,-1); // meaning of second arg is not clear, firmware seems to use -1
327}
328
329long mkdir_if_not_exist(const char *dirname)
330{
331    // Check if directory exists and create it if it does not.
332    struct stat st;
333    if (stat(dirname,&st) != 0) return mkdir(dirname);
334    return 0;   // Success
335}
336
337int remove(const char *name)
338{
339#ifdef CAM_DRYOS_2_3_R39
340    // For DryOS R39 and later need to check if 'name' is a file or directory
341    // and call appropriate delete function.
342    struct stat st;
343    if (stat(name,&st) == 0)
344    {
345        if (st.st_attrib & DOS_ATTR_DIRECTORY)
346                return _DeleteDirectory_Fut(name);
347        else
348                return _DeleteFile_Fut(name);
349    }
350    return -1;  // return fail - file / directory does not exist
351#else
352    return _DeleteFile_Fut(name);
353#endif
354}
355
356//----------------------------------------------------------------------------
357// directory wrappers
358#ifndef CAM_DRYOS
359DIR *opendir(const char* name) {
360    return _opendir(name);
361}
362struct dirent* readdir(DIR *d) {
363    return _readdir(d);
364}
365int closedir(DIR *d) {
366    return _closedir(d);
367}
368
369void rewinddir(DIR *d) {
370    return _rewinddir(d);
371}
372#else // dryos
373DIR *opendir(const char* name) {
374    DIR *d;
375    DIR_dryos *dh = _opendir(name);
376    if(!dh) {
377        return (void *)0;
378    }
379    d = _malloc(sizeof(DIR));
380    if(!d) {
381        _closedir(dh);
382        return NULL;
383    }
384    d->dh = dh;
385    return d;
386}
387
388struct dirent * readdir(DIR *d) {
389  _ReadFastDir(d->dh, d->de_buf);
390  return d->de_buf[0]? &d->de : NULL;
391}
392
393int closedir(DIR *d) {
394    int r;
395    if(!d) {
396        return -1;
397    }
398    r = _closedir(d->dh);
399    _free(d);   
400    return r;
401}
402
403/* not used
404void rewinddir(DIR *d) {
405    if(!d) {
406        return;
407    }
408    _rewinddir(d->dh);
409}
410*/
411
412#endif // dryos dir functions
413
414int stat(const char *name, struct stat *pStat) {
415    return _stat(name, pStat);
416}
417
418FILE *fopen(const char *filename, const char *mode) {
419#ifdef CAM_DRYOS
420    if(!filename || filename[0]!='A') {
421        return NULL;
422    }
423#endif
424    return (FILE *)_Fopen_Fut(filename,mode);
425}
426
427long fclose(FILE *f) {
428    return _Fclose_Fut((long)f);
429}
430
431long fread(void *buf, long elsize, long count, FILE *f) {
432    return _Fread_Fut(buf,elsize,count,(long)f);
433}
434
435long fwrite(const void *buf, long elsize, long count, FILE *f) {
436    return _Fwrite_Fut(buf,elsize,count,(long)f);
437}
438
439long fseek(FILE *file, long offset, long whence) {
440    return _Fseek_Fut((long)file,offset,whence);
441}
442
443long feof(FILE * file) {
444    return _Feof_Fut((long)file);
445}
446
447long fflush(FILE * file) {
448    return _Fflush_Fut((long)file);
449}
450
451char *fgets(char *buf, int n, FILE *f) {
452    return _Fgets_Fut(buf,n,(int)f);
453}
454
455int rename(const char *oldname, const char *newname) {
456 return _RenameFile_Fut(oldname, newname);
457}
458
459unsigned int GetFreeCardSpaceKb(void){
460        return (_GetDrive_FreeClusters(0)*(_GetDrive_ClusterSize(0)>>9))>>1;
461}
462
463unsigned int GetTotalCardSpaceKb(void){
464        return (_GetDrive_TotalClusters(0)*(_GetDrive_ClusterSize(0)>>9))>>1;
465}
466
467//----------------------------------------------------------------------------
468
469int errnoOfTaskGet(int tid) {
470#if !CAM_DRYOS
471    return _errnoOfTaskGet(tid);
472#else
473    return 0;
474#endif
475}
476
477//----------------------------------------------------------------------------
478// String wrappers
479
480long strlen(const char *s) {
481    return _strlen(s);
482}
483
484int strcmp(const char *s1, const char *s2) {
485    return _strcmp(s1, s2);
486}
487
488int strncmp(const char *s1, const char *s2, long n) {
489    return _strncmp(s1, s2, n);
490}
491
492char *strchr(const char *s, int c) {
493    return _strchr(s, c);
494}
495
496char *strcpy(char *dest, const char *src) {
497    return _strcpy(dest, src);
498}
499
500char *strncpy(char *dest, const char *src, long n) {
501    return _strncpy(dest, src, n);
502}
503
504char *strcat(char *dest, const char *app) {
505    return _strcat(dest, app);
506}
507
508char *strrchr(const char *s, int c) {
509    return _strrchr(s, c);
510}
511
512long strtol(const char *nptr, char **endptr, int base) {
513    return _strtol(nptr, endptr, base);
514}
515
516unsigned long strtoul(const char *nptr, char **endptr, int base) {
517#if CAM_DRYOS
518    return (unsigned long)_strtolx(nptr, endptr, base, 0);
519#else
520    return _strtoul(nptr, endptr, base);
521#endif
522}
523
524char *strpbrk(const char *s, const char *accept) {
525#if !CAM_DRYOS
526    return _strpbrk(s, accept);
527#else
528    const char *sc1,*sc2;
529
530    for( sc1 = s; *sc1 != '\0'; ++sc1) {
531     for( sc2 = accept; *sc2 != '\0'; ++sc2) {
532      if (*sc1 == *sc2) return (char *) sc1;
533     }
534    }
535return (void*)0;
536#endif
537}
538
539//----------------------------------------------------------------------------
540
541long sprintf(char *s, const char *st, ...)
542{
543    long res;
544    __builtin_va_list va;
545    __builtin_va_start(va, st);
546    res = _vsprintf(s, st, va);
547    __builtin_va_end(va);
548    return res;
549}
550
551// strerror exists on vxworks cams,
552// but it does about the same thing as this
553const char *strerror(int en) {
554#if !CAM_DRYOS
555    static char msg[20];
556    sprintf(msg,"errno 0x%X",en);
557    return msg;
558#else
559    return "error";
560#endif
561}
562
563//----------------------------------------------------------------------------
564// Time wrappers
565
566unsigned long time(unsigned long *timer) {
567    return _time(timer);
568}
569
570int utime(const char *file, struct utimbuf *newTimes) {
571#if !CAM_DRYOS
572  return _utime(file, newTimes);
573#else
574 int res=0;
575 int fd;
576 fd = _open(file, 0, 0);
577
578#ifdef CAM_DRYOS_2_3_R39
579    if (fd>=0) {
580        _close(fd);
581        res=_SetFileTimeStamp(file, newTimes->modtime, newTimes->actime);
582    }
583#else
584    if (fd>=0) {
585        res=_SetFileTimeStamp(fd, newTimes->modtime, newTimes->actime);
586        _close(fd);
587    }
588    // return value compatibe with utime: ok=0 fail=-1
589#endif
590  return (res)?0:-1;
591#endif
592}
593
594struct tm *localtime(const unsigned long *_tod) {
595#if !CAM_DRYOS
596    return _localtime(_tod);
597#else
598// for DRYOS cameras do something with this!  - sizeof(x[]) must be >= sizeof(struct tm) :  'static int x[9];'
599  static int x[9];
600  return _LocalTime(_tod, &x);
601#endif
602}
603
604long strftime(char *s, unsigned long maxsize, const char *format, const struct tm *timp) {
605        return _strftime(s,maxsize,format,timp);
606}
607
608time_t mktime(struct tm *timp) {
609#if !CAM_DRYOS
610        return _mktime(timp);
611#else
612        int timp_ext[10]; // struct tm + a ptr
613        _memcpy(timp_ext,timp,9*sizeof(int));
614        timp_ext[9]=0;
615        long retval = _mktime_ext(&timp_ext);
616        _memcpy(timp,timp_ext,9*sizeof(int));
617        return retval;
618#endif
619}
620
621//----------------------------------------------------------------------------
622// Math wrappers
623
624double _log(double x) {
625    return __log(x);
626}
627
628double _log10(double x) {
629    return __log10(x);
630}
631
632double _pow(double x, double y) {
633    return __pow(x, y);
634}
635
636double _sqrt(double x) {
637    return __sqrt(x);
638}
639
640//----------------------------------------------------------------------------
641// Memory wrappers
642
643#ifdef OPT_EXMEM_MALLOC
644// I set this up to 16 mb and it still booted...
645#ifndef EXMEM_HEAP_SKIP
646#define EXMEM_HEAP_SKIP 0
647#endif
648#ifndef EXMEM_BUFFER_SIZE
649#define EXMEM_BUFFER_SIZE (1024*1024*2) // default size if not specified by camera
650#endif
651#define EXMEM_HEAP_SIZE (EXMEM_BUFFER_SIZE+EXMEM_HEAP_SKIP)     // desired space + amount to skip for the movie buffers (if needed)
652// these aren't currently needed elsewhere
653/*
654void * exmem_alloc(unsigned pool_id, unsigned size)
655{
656        return _exmem_alloc(pool_id,size,0);
657}
658
659void exmem_free(unsigned pool_id)
660{
661        _exmem_free(pool_id);
662}
663*/
664
665static void *exmem_heap;
666void *exmem_start = 0, *exmem_end = 0;
667int exmem_size = 0;
668
669void *suba_init(void *heap, unsigned size, unsigned rst, unsigned mincell);
670void *suba_alloc(void *heap, unsigned size, unsigned zero);
671int suba_free(void *heap, void *p);
672
673void exmem_malloc_init() {
674        // pool zero is EXMEM_RAMDISK on d10
675        void *mem = _exmem_alloc(0,EXMEM_HEAP_SIZE,0);
676        if(mem) {
677#if defined(OPT_CHDK_IN_EXMEM)
678                // If loading CHDK into exmem then move heap start past the end of CHDK
679                // and reduce available space by CHDK size (MEMISOSIZE)
680                // round MEMISOSIZE up to next 4 byte boundary if needed (just in case)
681                exmem_start = mem + ((MEMISOSIZE+3)&0xFFFFFFFC);
682                exmem_size = EXMEM_HEAP_SIZE - EXMEM_HEAP_SKIP - ((MEMISOSIZE+3)&0xFFFFFFFC);
683#else
684                // Set start & size based on requested values
685                exmem_start = mem;
686                exmem_size = EXMEM_HEAP_SIZE - EXMEM_HEAP_SKIP;
687#endif
688                exmem_end = exmem_start + exmem_size;
689#if defined(OPT_EXMEM_TESTING)
690                // For testing exmem allocated memory for corruption from normal camera operations
691                // set the above #define. This will allocate the memory; but won't use it (exmem_heap is set to 0)
692                // Instead all the memory is filled with the guard value below.
693                // In gui_draw_debug_vals_osd (gui.c) the memory is tested for the guard value and if any
694                // corruption has occurred then info about the memory locations that were altered is displayed
695                // If OPT_EXMEM_TESTING is defined then OPT_CHDK_IN_EXMEM should not be set.
696                unsigned long *p;
697                for (p=(unsigned long*)exmem_start; p<(unsigned long*)exmem_end; p++) *p = 0xDEADBEEF;
698                exmem_heap = 0;
699#else
700                // Normal operation, use the suba allocation system to manage the memory block
701                exmem_heap = suba_init(exmem_start,exmem_size,1,8);
702#endif
703        }
704}
705
706void *malloc(long size) {
707        if(exmem_heap)
708                return suba_alloc(exmem_heap,size,0);
709        else
710                return _malloc(size);
711}
712void free(void *p) {
713        if(exmem_heap && (p >= exmem_heap))
714                suba_free(exmem_heap,p);
715        else
716                _free(p);
717}
718
719int exmem_largest_block()
720{
721        extern int suba_largest_block(void*);
722        return suba_largest_block(exmem_heap);
723}
724// regular malloc
725#else
726void *malloc(long size) {
727    return _malloc(size);
728}
729
730void free(void *p) {
731    return _free(p);
732}
733#endif
734
735void *umalloc(long size) {
736    return _AllocateUncacheableMemory(size);
737}
738
739void ufree(void *p) {
740    return _FreeUncacheableMemory(p);
741}
742
743void *memcpy(void *dest, const void *src, long n) {
744    return _memcpy(dest, src, n);
745}
746
747void *memset(void *s, int c, int n) {
748    return _memset(s, c, n);
749}
750
751int memcmp(const void *s1, const void *s2, long n) {
752    return _memcmp(s1, s2, n);
753}
754
755void *memchr(const void *s, int c, int n) {
756#if !CAM_DRYOS
757        return _memchr(s,c,n);
758#else
759        while (n-- > 0) {
760                if (*(char *)s == c)
761                        return (void *)s;
762                s++;
763        }
764        return (void *)0;
765#endif
766}
767
768//----------------------------------------------------------------------------
769
770int rand(void) {
771    return _rand();
772}
773
774void *srand(unsigned int seed) {
775    return _srand(seed);
776}
777
778void qsort(void *__base, int __nelem, int __size, int (*__cmp)(const void *__e1, const void *__e2)) {
779    _qsort(__base, __nelem, __size, __cmp);
780}
781
782static int shutdown_disabled = 0;
783void disable_shutdown() {
784    if (!shutdown_disabled) {
785        _LockMainPower();
786        shutdown_disabled = 1;
787    }
788}
789
790void enable_shutdown() {
791    if (shutdown_disabled) {
792        _UnlockMainPower();
793        shutdown_disabled = 0;
794    }
795}
796void camera_shutdown_in_a_second(void){
797int i;
798//#if CAM_DRYOS
799//#else
800_SetAutoShutdownTime(1); // 1 sec
801for (i=0;i<200;i++) _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").
802//#endif
803}
804
805unsigned int GetJpgCount(void){
806 return strtol(camera_jpeg_count_str(),((void*)0),0);
807}
808
809unsigned int GetRawCount(void){
810 return GetFreeCardSpaceKb()/((hook_raw_size() / 1024)+GetFreeCardSpaceKb()/GetJpgCount());
811}
812
813void EnterToCompensationEVF(void)
814{
815  _EnterToCompensationEVF();
816}
817
818void ExitFromCompensationEVF()
819{
820  _ExitFromCompensationEVF();
821}
822
823void TurnOnBackLight(void)
824{
825  _TurnOnBackLight();
826}
827
828void TurnOffBackLight(void)
829{
830  _TurnOffBackLight();
831}
832
833void DoAFLock(void)
834{
835  _DoAFLock();
836}
837
838void UnlockAF(void)
839{
840  _UnlockAF();
841}
842
843#if CAM_MULTIPART
844
845#define SECTOR_SIZE 512
846static char *mbr_buf=(void*)0;
847static unsigned long drive_sectors;
848
849int is_mbr_loaded()
850{
851        return (mbr_buf == (void*)0) ? 0 : 1;
852}
853
854#ifndef CAM_DRYOS
855
856int mbr_read(char* mbr_sector, unsigned long drive_total_sectors, unsigned long *part_start_sector,  unsigned long *part_length){
857// return value: 1 - success, 0 - fail
858// called only in VxWorks
859
860 int offset=0x10; // points to partition #2
861 int valid;
862
863 if ((mbr_sector[0x1FE]!=0x55) || (mbr_sector[0x1FF]!=0xAA)) return 0; // signature check
864
865 mbr_buf=_AllocateUncacheableMemory(SECTOR_SIZE);
866 _memcpy(mbr_buf,mbr_sector,SECTOR_SIZE);
867 drive_sectors=drive_total_sectors;
868
869 while(offset>=0) {
870
871  *part_start_sector=(*(unsigned short*)(mbr_sector+offset+0x1C8)<<16) | *(unsigned short*)(mbr_sector+offset+0x1C6);
872  *part_length=(*(unsigned short*)(mbr_sector+offset+0x1CC)<<16) | *(unsigned short*)(mbr_sector+offset+0x1CA);
873
874  valid= (*part_start_sector) && (*part_length) &&
875         (*part_start_sector<=drive_total_sectors) &&
876         (*part_start_sector+*part_length<=drive_total_sectors) &&
877         ((mbr_sector[offset+0x1BE]==0) || (mbr_sector[offset+0x1BE]==0x80)); // status: 0x80 (active) or 0 (non-active)
878
879  if (valid && ((mbr_sector[0x1C2+offset]==0x0B) || (mbr_sector[0x1C2+offset]==0x0C))) break;   // FAT32 secondary partition
880
881  offset-=0x10;
882
883 }
884
885 return valid;
886}
887
888#else
889
890int mbr_read_dryos(unsigned long drive_total_sectors, char* mbr_sector ){
891// Called only in DRYOS
892 mbr_buf=_AllocateUncacheableMemory(SECTOR_SIZE);
893 _memcpy(mbr_buf,mbr_sector,SECTOR_SIZE);
894 drive_sectors=drive_total_sectors;
895 return drive_total_sectors;
896}
897
898#endif
899
900int get_part_count(void)
901{
902  unsigned long part_start_sector, part_length;
903  char part_status, part_type;
904  int i;
905  int count=0;
906  if (is_mbr_loaded())
907  {
908    for (i=0; i<=3;i++)
909    {
910      part_start_sector=(*(unsigned short*)(mbr_buf+i*16+0x1C8)<<16) | *(unsigned short*)(mbr_buf+i*16+0x1C6);
911      part_length=(*(unsigned short*)(mbr_buf+i*16+0x1CC)<<16) | *(unsigned short*)(mbr_buf+i*16+0x1CA);
912      part_status=mbr_buf[i*16+0x1BE];
913      part_type=mbr_buf[0x1C2+i*16];
914      if ( part_start_sector && part_length && part_type && ((part_status==0) || (part_status==0x80)) ) count++;
915    }
916  }
917  return count;
918}
919int get_part_type()
920{
921  int partType = 0x00;
922  if (is_mbr_loaded())
923  {
924    partType=mbr_buf[0x1C2+(get_active_partition()-1)*16];
925  }
926  return partType;
927}
928
929static int boot_partition = 0;
930static int partition_changed = 0;
931int is_partition_changed()
932{
933  return partition_changed;
934}
935
936int swap_partitions(int new_partition)
937{
938  if (is_mbr_loaded())
939  {
940    int i,j,p;
941    char c;
942   
943    int partition_count = get_part_count();
944    int active_partition = get_active_partition();
945   
946    if(!boot_partition)
947    {
948      boot_partition = active_partition;
949    }
950
951    // wrong input
952    if( new_partition > partition_count || new_partition <= 0 )
953    {
954      return 0;
955    }
956    partition_changed = (new_partition==boot_partition)?0:1;
957   
958    // rotate partitions till new_partition is found
959    for(j=0;j<partition_count;++j)
960    {
961      if(new_partition == get_active_partition())
962      {
963        break;
964      }
965      for(i=0;i<16;i++)
966      {
967        c=mbr_buf[i+0x1BE];
968        for(p=1; p<partition_count; ++p)
969        {
970          mbr_buf[i+(p-1)*16+0x1BE]=mbr_buf[i+p*16+0x1BE];
971        }
972        mbr_buf[i+(partition_count-1)*16+0x1BE]=c;
973      }
974    }
975    _WriteSDCard(0,0,1,mbr_buf);
976  }
977  return 1;
978}
979
980unsigned char get_active_partition(void)
981{
982  unsigned int  partition_start[4];
983  unsigned char partition_number = 1;
984  int partition_count = get_part_count();
985  int i;
986
987  for( i=0; i<partition_count; ++i )
988  {
989    int a = mbr_buf[0x01C6+(i)*16];
990    int b = mbr_buf[0x01C7+(i)*16];
991    int c = mbr_buf[0x01C8+(i)*16];
992    int d = mbr_buf[0x01C9+(i)*16];
993    partition_start[i] = (((((d<<8) +c)<<8) +b)<<8) +a;
994  }
995  for( i=1; i<partition_count; ++i )
996  {
997    if(partition_start[i]<partition_start[0])
998    {
999      ++partition_number;
1000    }
1001  }
1002  return partition_number;
1003}
1004
1005void create_partitions(void){
1006        if (is_mbr_loaded())
1007        {
1008         unsigned long start, length;
1009         char type;
1010
1011         _memset(mbr_buf,0,SECTOR_SIZE);
1012
1013         start=1; length=2*1024*1024/SECTOR_SIZE; //2 Mb
1014         type=1; // FAT primary
1015         mbr_buf[0x1BE + 4]=type;
1016         mbr_buf[0x1BE + 8]=start;   mbr_buf[0x1BE + 9]=start>>8;   mbr_buf[0x1BE + 10]=start>>16;  mbr_buf[0x1BE + 11]=start>>24;
1017         mbr_buf[0x1BE + 12]=length; mbr_buf[0x1BE + 13]=length>>8; mbr_buf[0x1BE + 14]=length>>16; mbr_buf[0x1BE + 15]=length>>24;
1018
1019         start=start+length; length=drive_sectors-start-1;
1020         type=0x0B;  //FAT32 primary;
1021         mbr_buf[0x1CE + 4]=type;
1022         mbr_buf[0x1CE + 8]=start;   mbr_buf[0x1CE + 9]=start>>8;   mbr_buf[0x1CE + 10]=start>>16;  mbr_buf[0x1CE + 11]=start>>24;
1023         mbr_buf[0x1CE + 12]=length; mbr_buf[0x1CE + 13]=length>>8; mbr_buf[0x1CE + 14]=length>>16; mbr_buf[0x1CE + 15]=length>>24;
1024
1025         mbr_buf[0x1FE]=0x55; mbr_buf[0x1FF]=0xAA; // signature;
1026
1027         _WriteSDCard(0,0,1,mbr_buf);
1028        }
1029}
1030
1031#endif
1032
1033int mute_on_zoom(int x){
1034 static int old_busy=0;
1035 int busy=zoom_busy||focus_busy;
1036 if (old_busy!=busy) {
1037  if (busy) {
1038#if CAM_CAN_MUTE_MICROPHONE
1039   if (conf.mute_on_zoom) _TurnOffMic();
1040#endif
1041   }
1042   else {
1043#if CAM_CAN_MUTE_MICROPHONE
1044  if (conf.mute_on_zoom) _TurnOnMic();
1045#endif
1046#if CAM_EV_IN_VIDEO
1047  if (get_ev_video_avail()) set_ev_video_avail(0);
1048#endif
1049  }
1050  old_busy=busy;
1051 }
1052 return x; // preserve R0 if called from assembler
1053}
1054
1055
1056#if CAM_AF_SCAN_DURING_VIDEO_RECORD
1057void MakeAFScan(void){
1058 int a=0, save;
1059 if (zoom_busy || focus_busy) return;
1060 save=some_flag_for_af_scan;
1061 some_flag_for_af_scan=0;
1062#if CAM_AF_SCAN_DURING_VIDEO_RECORD == 2
1063 parameter_for_af_scan=3;
1064#endif
1065 _MakeAFScan(&a, 3);
1066 some_flag_for_af_scan=save;
1067#if defined(CAMERA_g12) || defined(CAMERA_g10)
1068 int ae_lock;
1069 get_property_case(PROPCASE_AE_LOCK,&ae_lock,sizeof(ae_lock));
1070 if (ae_lock == 0)                                              // AE not locked so ensure it is unlocked after re-focus
1071         _ExpCtrlTool_StartContiAE(0,0);
1072 else                                                                   // AE locked before so re-lock after
1073         _ExpCtrlTool_StopContiAE(0,0);
1074#else
1075 _ExpCtrlTool_StartContiAE(0,0);
1076#endif
1077}
1078#endif
1079
1080long __attribute__((weak)) get_jogdial_direction(void){
1081 return 0;
1082}
1083
1084#if defined (DNG_EXT_FROM)
1085
1086#define DNG_EXT_TO ".DNG"
1087
1088typedef int(*p_some_f)(char*, int);
1089
1090extern p_some_f some_f_for_dng;  // camera variable!
1091extern char* second_ext_for_dng; // camera variable!
1092
1093p_some_f default_some_f;
1094char *   default_second_ext;
1095
1096char *_strstr (const char *s1, const char *s2)
1097{
1098  const char *p = s1;
1099  const int len = _strlen (s2);
1100
1101  for (; (p = _strchr (p, *s2)) != 0; p++)
1102    {
1103      if (_strncmp (p, s2, len) == 0)
1104        return (char *)p;
1105    }
1106  return (0);
1107}
1108
1109
1110int my_some_f(char *s, int x){
1111  char *f;
1112  f=_strstr(s, DNG_EXT_FROM);
1113  if (f) _memcpy(f, DNG_EXT_TO, sizeof(DNG_EXT_TO)-1);
1114  return default_some_f(s, x);
1115}
1116
1117void save_ext_for_dng(void){
1118 default_some_f=some_f_for_dng;
1119 default_second_ext=second_ext_for_dng;
1120}
1121
1122void change_ext_to_dng(void){
1123 some_f_for_dng=my_some_f;
1124 second_ext_for_dng=DNG_EXT_TO;
1125}
1126
1127void change_ext_to_default(void){
1128 some_f_for_dng=default_some_f;
1129 second_ext_for_dng=default_second_ext;
1130}
1131
1132#endif
1133
1134
1135static long drv_struct[16];
1136
1137long dh_err()
1138{
1139    return -1;
1140}
1141
1142void drv_self_hide()
1143{
1144#if !CAM_DRYOS
1145    long drvnum;
1146
1147    drvnum = _iosDrvInstall(dh_err,dh_err,dh_err,dh_err,dh_err,dh_err,dh_err);
1148    if (drvnum >= 0)
1149        _iosDevAdd(drv_struct, "A/DISKBOOT.BIN", drvnum);
1150#endif
1151}
1152
1153void drv_self_unhide(){
1154#if !CAM_DRYOS
1155 _iosDevDelete(drv_struct);
1156#endif
1157}
1158
1159int  apex2us(int apex_tv){
1160#if CAM_EXT_TV_RANGE
1161/*
1162 Extended Tv, by barberofcivil, http://chdk.setepontos.com/index.php/topic,4392.0.html
1163 Explanation by reyalP:
1164 In every port, the original shutter overrides (as opposed to super long exposure) worked by
1165 setting the propcase values at some point after auto-exposure has happened (except in manual
1166 modes, where the manual control propcases may be used instead). The Canon code previously took
1167 these values unchanged for short exposures. In newer cameras, like on the SX10 / SD980, the value
1168 is changed, apparently some time after it has been retrieved from the propcase. We know this is
1169 the case, because the propcase value itself doesn't get clamped to the allowed range (if it did,
1170 barberofcivil's code wouldn't work).
1171*/
1172        short tv;
1173        tv = shooting_get_tv96();
1174        if (tv<-576 || tv!=apex_tv) return 1000000.0*pow(2.0, -tv/96.0);
1175        else return _apex2us(apex_tv);
1176#else
1177        return 0;
1178#endif
1179}
1180
1181void PostLogicalEventForNotPowerType(unsigned id, unsigned x) {
1182        _PostLogicalEventForNotPowerType(id,x);
1183}
1184
1185void PostLogicalEventToUI(unsigned id, unsigned x) {
1186        _PostLogicalEventToUI(id,x);
1187}
1188
1189void SetLogicalEventActive(unsigned id, unsigned state) {
1190        _SetLogicalEventActive(id, state);
1191}
1192
1193void SetScriptMode(unsigned mode) {
1194        _SetScriptMode(mode);
1195}
1196
1197// TODO this belongs lib.c, but not all cameras include it
1198// same as bitmap width for most cameras, override in platform/sub/lib.c as needed
1199int __attribute__((weak)) vid_get_viewport_width() {
1200        return vid_get_bitmap_screen_width();
1201}
1202
1203// Physical width of viewport row in bytes
1204int __attribute__((weak)) vid_get_viewport_byte_width() {
1205        return 720 * 6 / 4;     // For most cameras viewport is 720 pixels wide, each group of 4 pixels uses 6 bytes (UYVYYY)
1206}
1207
1208// Y multiplier for cameras with 480 pixel high viewports (CHDK code assumes 240)
1209int __attribute__((weak)) vid_get_viewport_yscale() {
1210        return 1;               // For most cameras viewport is 240 pixels high
1211}
1212
1213// viewport x offset - used when image size != viewport size (zebra, histogram, motion detect & edge overlay)
1214int __attribute__((weak)) vid_get_viewport_xoffset() {
1215        return 0;
1216}
1217
1218// viewport y offset - used when image size != viewport size (zebra, histogram, motion detect & edge overlay)
1219int __attribute__((weak)) vid_get_viewport_yoffset() {
1220        return 0;
1221}
1222
1223// viewport image offset - used when image size != viewport size (zebra, histogram, motion detect & edge overlay)
1224// returns the byte offset into the viewport buffer where the image pixels start (to skip any black borders)
1225// see G12 port for sample implementation
1226int vid_get_viewport_image_offset() {
1227        return (vid_get_viewport_yoffset() * vid_get_viewport_byte_width() * vid_get_viewport_yscale()) + (vid_get_viewport_xoffset() * 3);
1228}
1229
1230// viewport image offset - used when image size != viewport size (zebra, histogram, motion detect & edge overlay)
1231// returns the byte offset to skip at the end of a viewport buffer row to get to the next row.
1232// see G12 port for sample implementation
1233int vid_get_viewport_row_offset() {
1234        return (vid_get_viewport_byte_width() * vid_get_viewport_yscale()) - (vid_get_viewport_width() * 3);
1235}
1236
1237// for cameras with two (or more?) RAW buffers this can be used to speed up DNG creation by
1238// calling reverse_bytes_order only once. Override in platform/sub/lib.c
1239char __attribute__((weak)) *hook_alt_raw_image_addr() {
1240        return hook_raw_image_addr();
1241}
1242
1243void __attribute__((weak)) vid_turn_off_updates()
1244{
1245}
1246
1247void __attribute__((weak)) vid_turn_on_updates()
1248{
1249}
1250
1251// use _GetFocusLensSubjectDistance for this on dryos, vx functions are basically equivlent
1252// not used in CHDK currently for either OS
1253#ifdef CAM_DRYOS
1254long __attribute__((weak)) _GetCurrentTargetDistance()
1255{
1256        return _GetFocusLensSubjectDistance();
1257}
1258#endif
1259
1260#ifdef CAM_CHDK_PTP
1261int add_ptp_handler(int opcode, ptp_handler handler, int unknown)
1262{
1263  return _add_ptp_handler(opcode,handler,unknown);
1264}
1265
1266// this would make more sense in generic/main.c but not all a cameras use it
1267void init_chdk_ptp_task() {
1268  _CreateTask("InitCHDKPTP", 0x19, 0x200, init_chdk_ptp, 0);
1269};
1270
1271#endif
1272
1273void ExitTask()
1274{
1275  _ExitTask();
1276}
1277
1278// TODO not in sigs for vx yet
1279#ifndef CAM_DRYOS
1280void __attribute__((weak)) _reboot_fw_update(const char *fw_update)
1281{
1282        return;
1283}
1284#endif
1285
1286
1287int __attribute__((weak)) switch_mode_usb(int mode)
1288{
1289
1290    return 0;
1291}
1292
1293/*
1294// this wrapper isn't currently needed
1295// 7 calls functions and sets some MMIOs, but doesn't disable caches and actually restart
1296// 3 skips one function call on some cameras, but does restart
1297void Restart(unsigned option) {
1298        _Restart(option);
1299}
1300*/
1301
1302unsigned char SetFileAttributes(const char* fn, unsigned char attr)
1303{
1304    int fd;
1305    unsigned char ret = -1;
1306   
1307    fd = open(fn, 0, 0);
1308    if( fd ) {
1309        _SetFileAttributes(fd, attr);
1310        close(fd);
1311        ret = attr;
1312    }
1313    return ret;
1314}
Note: See TracBrowser for help on using the repository browser.