source: branches/release-1_0/platform/generic/wrappers.c @ 1622

Revision 1622, 35.5 KB checked in by reyalp, 16 months ago (diff)

correct order of mtime and atime in dryos utime(), update llibtst.lua to check stat values

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