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

Revision 1213, 33.6 KB checked in by reyalp, 2 years ago (diff)

G12 & SX30 + misc cleanup from philmoz in http://chdk.setepontos.com/index.php?topic=650.msg69328#msg69328

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