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

Revision 1570, 36.1 KB checked in by philmoz, 16 months ago (diff)

Add support for cameras that allow subject distance overrides greater than the current max value of 65535.

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