1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - library - camera
3   File:     camera_api.c
4 
5   Copyright 2007-2008 Nintendo. All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law. They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Date:: 2009-02-23#$
14   $Rev: 10064 $
15   $Author: kitase_hirotake $
16  *---------------------------------------------------------------------------*/
17 #include <twl.h>
18 #include <twl/camera.h>
19 
20 #include "camera_intr.h"
21 
22 /*---------------------------------------------------------------------------*
23     Constant Definitions
24  *---------------------------------------------------------------------------*/
25 // Pack and copy
26 #define CAMERA_PACK_U16(d, s)                   \
27     ((d)[0] = (u8)((*((u16*)s) >>  0) & 0xFF),  \
28      (d)[1] = (u8)((*((u16*)s) >>  8) & 0xFF))
29 
30 #define CAMERA_PACK_U32(d, s)                   \
31     ((d)[0] = (u8)((*((u32*)s) >>  0) & 0xFF),  \
32      (d)[1] = (u8)((*((u32*)s) >>  8) & 0xFF),  \
33      (d)[2] = (u8)((*((u32*)s) >> 16) & 0xFF),  \
34      (d)[3] = (u8)((*((u32*)s) >> 24) & 0xFF))
35 
36 
37 #define CAMERA_VSYNC_TIMEOUT    OS_SecondsToTicks( 1 )  // 1 second
38 #define CAMERA_RETRY_COUNT 2
39 
40 typedef enum
41 {
42     I2C_Init,
43     I2C_PhotoMode_IN,
44     I2C_PhotoMode_OUT,
45     I2C_SizeA_IN,
46     I2C_SizeB_IN,
47     I2C_SizeA_OUT,
48     I2C_SizeB_OUT,
49     I2C_FrameRate_IN,
50     I2C_FrameRate_OUT,
51     I2C_EffectA_IN,
52     I2C_EffectB_IN,
53     I2C_EffectA_OUT,
54     I2C_EffectB_OUT,
55     I2C_FlipA_IN,
56     I2C_FlipB_IN,
57     I2C_FlipA_OUT,
58     I2C_FlipB_OUT,
59     I2C_WhiteBalance_IN,
60     I2C_WhiteBalance_OUT,
61     I2C_Exposure_IN,
62     I2C_Exposure_OUT,
63     I2C_Sharpness_IN,
64     I2C_Sharpness_OUT,
65     I2C_AutoExposure_IN,
66     I2C_AutoExposure_OUT,
67     I2C_AutoWhiteBalance_IN,
68     I2C_AutoWhiteBalance_OUT,
69     I2C_Context_IN,
70     I2C_Context_OUT,
71     I2C_Activate,
72     Set_LED,
73     I2C_MAX
74 }
75 CAMERAI2CList;
76 
77 /*---------------------------------------------------------------------------*
78     Type Definitions
79  *---------------------------------------------------------------------------*/
80 typedef struct CAMERAState
81 {
82     CAMERASize size_A;
83     CAMERASize size_B;
84     CAMERAEffect effect_A;
85     CAMERAEffect effect_B;
86     CAMERAFlip flip_A;
87     CAMERAFlip flip_B;
88     CAMERAPhotoMode photo;
89     CAMERAWhiteBalance wb;
90     CAMERAFrameRate rate;
91     int exposure;
92     int sharpness;
93     BOOL ae;
94     BOOL awb;
95     CAMERAContext context;
96     BOOL blink;
97 }
98 CAMERAState;
99 
100 typedef struct CAMERAStateTmp
101 {
102     CAMERASelect set_camera; // For which camera is this temporary setting information?
103     CAMERAContext set_context; // For which context is this temporary setting information?
104     union
105     {
106         CAMERASize size;
107         CAMERAEffect effect;
108         CAMERAFlip flip;
109         CAMERAPhotoMode photo;
110         CAMERAWhiteBalance wb;
111         CAMERAFrameRate rate;
112         int exposure;
113         int sharpness;
114         BOOL ae;
115         BOOL awb;
116         CAMERAContext context;
117         BOOL blink;
118     };
119 }
120 CAMERAStateTmp;
121 
122 typedef struct CAMERAWork
123 {
124     BOOL            lock;
125     CAMERACallback  callback;
126     CAMERAResult    result;             // Only the leading data is in a different caregory
127     void            *callbackArg;
128     CAMERAPxiCommand    command;        // Command type
129     CAMERAPxiResult     pxiResult;      // Only the leading data is in a different caregory
130     u8      current;                    // Quantity of received data (in bytes) (excluding the leading data!!)
131     u8      total;                      // Number of final data (1 + subsequent commands *3)
132     u8 padding[2];
133     u8      *data;                      // Save API arg if any
134     size_t  size;                       // Save API arg if any
135 
136     BOOL    last_state;                 // Last state before pxi
137     BOOL    force_activate;             // Keep clock request
138     BOOL    force_deactivate;           // Stop clock request
139 
140     PMSleepCallbackInfo sleepCbInfo;    // Callback information when recovering from sleep
141     PMExitCallbackInfo  exitCbInfo;     // Callback information when reset/power off
142 
143     OSTick CAMERAiLastCameraVSync;      // Time for detecting a camera malfunction
144     CAMERAIntrCallback CAMERAiVsyncCallback;       // Callback called by the camera VSYNC
145     CAMERAIntrCallback CAMERAiBufferErrorCallback; // Callback called by the camera buffer error
146     CAMERAIntrCallback CAMERAiRebootCallback;      // Callback called after camera reboot is completed
147     OSThread  CAMERAiMonitorThread[1];                 // Thread structure for detecting a camera malfunction
148     u32 CAMERAiMonitorThreadStack[1024];               // Stack of thread for detecting a camera malfunction
149 
150     CAMERASelect CAMERAiCurrentCamera;  // Current camera set just before by user
151 
152     CAMERAState CAMERAiStateIn;         // Setting value of inner camera
153     CAMERAState CAMERAiStateOut;        // Setting value of outer camera
154     CAMERAStateTmp CAMERAiStateTmp;     // Maintain the setting until I2C command succeeds
155 
156     u32 CAMERAiRetryCount;              // Camera reboot retry count
157 
158     int             CAMERAiMonitorCounter;
159     OSMessageQueue  CAMERAiMonitorMessageQueue[1];  // To MonitorThread
160     OSMessage       CAMERAiMonitorMessage[1];       // Only one type, and duplication is meaningless, so only one
161 }
162 CAMERAWork;
163 
164 /*---------------------------------------------------------------------------*
165     Static Variable Definitions
166  *---------------------------------------------------------------------------*/
167 static BOOL cameraInitialized;
168 static CAMERAWork cameraWork;
169 
170 /*---------------------------------------------------------------------------*
171     Internal Function Definitions
172  *---------------------------------------------------------------------------*/
173 static BOOL CameraSendPxiCommand(CAMERAPxiCommand command, u8 size, u8 data);
174 static void CameraSendPxiData(u8 *pData);
175 static void CameraPxiCallback(PXIFifoTag tag, u32 data, BOOL err);
176 static void CameraSyncCallback(CAMERAResult result, void *arg);
177 static void CameraCallCallbackAndUnlock(CAMERAResult result);
178 static void CameraWaitBusy(void);
179 static void CameraStandbyCallback(void* args);
180 
181 
182 //--------------------------------------------------------------------------------
183 //    Camera interrupt process (Generated when there is an error and for VSYNC)
184 //
185 /*---------------------------------------------------------------------------*
186   Name:         CAMERA_CameraIntr
187 
188   Description:  Camera interrupt process.
189                 Called during buffer errors and at VSYNC.
190 
191   Arguments:    None.
192 
193   Returns:      None.
194  *---------------------------------------------------------------------------*/
CAMERA_CameraIntr(void)195 static void CAMERA_CameraIntr(void)
196 {
197     OS_SetIrqCheckFlag(OS_IE_CAMERA);
198 
199     if (CAMERA_GetErrorStatus())
200     {
201         // Call a buffer error interrupt callback specified by user
202         if(cameraWork.CAMERAiBufferErrorCallback != 0)
203             cameraWork.CAMERAiBufferErrorCallback(CAMERA_RESULT_SUCCESS);
204     }
205     else
206     {
207         cameraWork.CAMERAiLastCameraVSync = OS_GetTick();
208         // Call a VSYNC interrupt callback specified by user
209         if(cameraWork.CAMERAiVsyncCallback != 0)
210             cameraWork.CAMERAiVsyncCallback(CAMERA_RESULT_SUCCESS);
211     }
212 }
213 
214 /*---------------------------------------------------------------------------*
215   Name:         CAMERA_SetVsynCallback
216 
217   Description:  Sets the callback function invoked when there is a camera VSYNC interrupt.
218 
219   Arguments:    callback: The callback function to set
220 
221   Returns:      None.
222  *---------------------------------------------------------------------------*/
CAMERA_SetVsyncCallbackCore(CAMERAIntrCallback callback)223 void CAMERA_SetVsyncCallbackCore(CAMERAIntrCallback callback)
224 {
225     cameraWork.CAMERAiVsyncCallback = callback;
226 }
227 
228 /*---------------------------------------------------------------------------*
229   Name:         CAMERA_SetBufferErrorCallback
230 
231   Description:  Sets the callback function invoked when there is a camera buffer error interrupt.
232 
233   Arguments:    callback: The callback function to set
234 
235   Returns:      None.
236  *---------------------------------------------------------------------------*/
CAMERA_SetBufferErrorCallbackCore(CAMERAIntrCallback callback)237 void CAMERA_SetBufferErrorCallbackCore(CAMERAIntrCallback callback)
238 {
239     cameraWork.CAMERAiBufferErrorCallback = callback;
240 }
241 
242 /*---------------------------------------------------------------------------*
243   Name:         CAMERA_SetRebootCallback
244 
245   Description:  Sets the callback function called when the recovery process is completed after a camera malfunction.
246 
247   Arguments:    callback: The callback function to set
248 
249   Returns:      None.
250  *---------------------------------------------------------------------------*/
CAMERA_SetRebootCallbackCore(CAMERAIntrCallback callback)251 void CAMERA_SetRebootCallbackCore(CAMERAIntrCallback callback)
252 {
253     cameraWork.CAMERAiRebootCallback = callback;
254 }
255 
256 
CAMERA_GetWhiteBalanceFromPhotoMode(CAMERAPhotoMode photo)257 static CAMERAWhiteBalance CAMERA_GetWhiteBalanceFromPhotoMode(CAMERAPhotoMode photo)
258 {
259     switch (photo)
260     {
261     case CAMERA_PHOTO_MODE_NORMAL:
262     case CAMERA_PHOTO_MODE_PORTRAIT:
263         return CAMERA_WHITE_BALANCE_NORMAL;
264     case CAMERA_PHOTO_MODE_LANDSCAPE:
265         return CAMERA_WHITE_BALANCE_DAYLIGHT;
266     case CAMERA_PHOTO_MODE_NIGHTVIEW:
267     case CAMERA_PHOTO_MODE_LETTER:
268         return CAMERA_WHITE_BALANCE_NORMAL;
269     }
270     return CAMERA_WHITE_BALANCE_NORMAL; // It should not come here
271 }
272 
CAMERA_GetSharpnessFromPhotoMode(CAMERAPhotoMode photo)273 static int CAMERA_GetSharpnessFromPhotoMode(CAMERAPhotoMode photo)
274 {
275     switch (photo)
276     {
277     case CAMERA_PHOTO_MODE_NORMAL:
278         return 0;
279     case CAMERA_PHOTO_MODE_PORTRAIT:
280         return -2;
281     case CAMERA_PHOTO_MODE_LANDSCAPE:
282         return 1;
283     case CAMERA_PHOTO_MODE_NIGHTVIEW:
284         return -1;
285     case CAMERA_PHOTO_MODE_LETTER:
286         return 2;
287     }
288     return 0; // It should not come here
289 }
290 
CAMERA_GetExposureFromPhotoMode(CAMERAPhotoMode photo)291 static int CAMERA_GetExposureFromPhotoMode(CAMERAPhotoMode photo)
292 {
293     switch (photo)
294     {
295     case CAMERA_PHOTO_MODE_NORMAL:
296     case CAMERA_PHOTO_MODE_PORTRAIT:
297     case CAMERA_PHOTO_MODE_LANDSCAPE:
298         return 0;
299     case CAMERA_PHOTO_MODE_NIGHTVIEW:
300     case CAMERA_PHOTO_MODE_LETTER:
301         return 2;
302     }
303     return 0; // It should not come here
304 }
305 
CAMERA_GoReboot(void)306 static void CAMERA_GoReboot(void)
307 {
308     cameraWork.lock = TRUE;
309     cameraWork.CAMERAiRetryCount++;
310     /*
311         Specify to start rebooting process to CAMERA_MonitorThread.
312             This is not called multiple times in sequence.
313             If this is called multiple times, only the first one is notified, so there is no problem.
314     */
315     (void)OS_SendMessage(cameraWork.CAMERAiMonitorMessageQueue, NULL, OS_MESSAGE_NOBLOCK);    // Call while locked.
316 }
317 
318 /*---------------------------------------------------------------------------*
319   Name:         CAMERA_Reboot
320 
321   Description:  Camera reboot routine.
322 
323   Arguments:    result: Result of previous I2C process
324                 arg: Type of I2C to be invoked next
325 
326   Returns:      None.
327  *---------------------------------------------------------------------------*/
CAMERA_Reboot(CAMERAResult result,void * arg)328 static void CAMERA_Reboot(CAMERAResult result, void* arg)
329 {
330     CAMERAI2CList state = (CAMERAI2CList)arg;
331 
332 //OS_TPrintf("callback was called (%d).\n", state);
333     if(result != CAMERA_RESULT_SUCCESS) // Redo if failed
334     {
335 //OS_TPrintf("Failed to reboot (%d).\n", result);
336         return;
337     }
338 
339     switch(state)
340     {
341     case I2C_Init:
342 //OS_TPrintf("CAMERA_I2CInitAsyncCore(CAMERA_SELECT_BOTH)\n");
343         (void)CAMERA_I2CInitAsyncCore(CAMERA_SELECT_BOTH, CAMERA_Reboot, (void*)I2C_PhotoMode_IN);
344         return;
345     case I2C_PhotoMode_IN:
346         if(cameraWork.CAMERAiStateIn.photo != CAMERA_PHOTO_MODE_PORTRAIT)
347         {
348 //OS_TPrintf("CAMERA_I2CPhotoModeAsyncCore(CAMERA_SELECT_IN, cameraWork.CAMERAiStateIn.photo)\n");
349             (void)CAMERA_I2CPhotoModeAsyncCore(CAMERA_SELECT_IN, cameraWork.CAMERAiStateIn.photo, CAMERA_Reboot, (void*)I2C_PhotoMode_OUT);
350             return;
351         }
352     case I2C_PhotoMode_OUT:
353         if(cameraWork.CAMERAiStateOut.photo != CAMERA_PHOTO_MODE_NORMAL)
354         {
355 //OS_TPrintf("CAMERA_I2CPhotoModeAsyncCore(CAMERA_SELECT_OUT, cameraWork.CAMERAiStateOut.photo)\n");
356             (void)CAMERA_I2CPhotoModeAsyncCore(CAMERA_SELECT_OUT, cameraWork.CAMERAiStateOut.photo, CAMERA_Reboot, (void*)I2C_SizeA_IN);
357             return;
358         }
359     case I2C_SizeA_IN:
360         if(cameraWork.CAMERAiStateIn.size_A != CAMERA_SIZE_DS_LCD)
361         {
362 //OS_TPrintf("CAMERA_I2CSizeExAsyncCore(CAMERA_SELECT_IN, CAMERA_CONTEXT_A, cameraWork.CAMERAiStateIn.size_A)\n");
363             (void)CAMERA_I2CSizeExAsyncCore(CAMERA_SELECT_IN, CAMERA_CONTEXT_A, cameraWork.CAMERAiStateIn.size_A, CAMERA_Reboot, (void*)I2C_SizeB_IN);
364             return;
365         }
366     case I2C_SizeB_IN:
367         if(cameraWork.CAMERAiStateIn.size_B != CAMERA_SIZE_VGA)
368         {
369 //OS_TPrintf("CAMERA_I2CSizeExAsyncCore(CAMERA_SELECT_IN, CAMERA_CONTEXT_B, cameraWork.CAMERAiStateIn.size_B)\n");
370             (void)CAMERA_I2CSizeExAsyncCore(CAMERA_SELECT_IN, CAMERA_CONTEXT_B, cameraWork.CAMERAiStateIn.size_B, CAMERA_Reboot, (void*)I2C_SizeA_OUT);
371             return;
372         }
373     case I2C_SizeA_OUT:
374         if(cameraWork.CAMERAiStateOut.size_A != CAMERA_SIZE_DS_LCD)
375         {
376 //OS_TPrintf("CAMERA_I2CSizeExAsyncCore(CAMERA_SELECT_OUT, CAMERA_CONTEXT_A, cameraWork.CAMERAiStateOut.size_A)\n");
377             (void)CAMERA_I2CSizeExAsyncCore(CAMERA_SELECT_OUT, CAMERA_CONTEXT_A, cameraWork.CAMERAiStateOut.size_A, CAMERA_Reboot, (void*)I2C_SizeB_OUT);
378             return;
379         }
380     case I2C_SizeB_OUT:
381         if(cameraWork.CAMERAiStateOut.size_B != CAMERA_SIZE_VGA)
382         {
383 //OS_TPrintf("CAMERA_I2CSizeExAsyncCore(CAMERA_SELECT_OUT, CAMERA_CONTEXT_B, cameraWork.CAMERAiStateOut.size_B)\n");
384             (void)CAMERA_I2CSizeExAsyncCore(CAMERA_SELECT_OUT, CAMERA_CONTEXT_B, cameraWork.CAMERAiStateOut.size_B, CAMERA_Reboot, (void*)I2C_FrameRate_IN);
385             return;
386         }
387     case I2C_FrameRate_IN:
388         if(cameraWork.CAMERAiStateIn.rate != CAMERA_FRAME_RATE_15)
389         {
390 //OS_TPrintf("CAMERA_I2CFrameRateAsyncCore(CAMERA_SELECT_IN, cameraWork.CAMERAiStateIn.rate)\n");
391             (void)CAMERA_I2CFrameRateAsyncCore(CAMERA_SELECT_IN, cameraWork.CAMERAiStateIn.rate, CAMERA_Reboot, (void*)I2C_FrameRate_OUT);
392             return;
393         }
394     case I2C_FrameRate_OUT:
395         if(cameraWork.CAMERAiStateOut.rate != CAMERA_FRAME_RATE_15)
396         {
397 //OS_TPrintf("CAMERA_I2CFrameRateAsyncCore(CAMERA_SELECT_OUT, cameraWork.CAMERAiStateOut.rate)\n");
398             (void)CAMERA_I2CFrameRateAsyncCore(CAMERA_SELECT_OUT, cameraWork.CAMERAiStateOut.rate, CAMERA_Reboot, (void*)I2C_EffectA_IN);
399             return;
400         }
401     case I2C_EffectA_IN:
402         if(cameraWork.CAMERAiStateIn.effect_A != CAMERA_EFFECT_NONE)
403         {
404 //OS_TPrintf("CAMERA_I2CEffectExAsyncCore(CAMERA_SELECT_IN, CAMERA_CONTEXT_A, cameraWork.CAMERAiStateIn.effect_A)\n");
405             (void)CAMERA_I2CEffectExAsyncCore(CAMERA_SELECT_IN, CAMERA_CONTEXT_A, cameraWork.CAMERAiStateIn.effect_A, CAMERA_Reboot, (void*)I2C_EffectB_IN);
406             return;
407         }
408     case I2C_EffectB_IN:
409         if(cameraWork.CAMERAiStateIn.effect_B != CAMERA_EFFECT_NONE)
410         {
411 //OS_TPrintf("CAMERA_I2CEffectExAsyncCore(CAMERA_SELECT_IN, CAMERA_CONTEXT_B, cameraWork.CAMERAiStateIn.effect_B)\n");
412             (void)CAMERA_I2CEffectExAsyncCore(CAMERA_SELECT_IN, CAMERA_CONTEXT_B, cameraWork.CAMERAiStateIn.effect_B, CAMERA_Reboot, (void*)I2C_EffectA_OUT);
413             return;
414         }
415     case I2C_EffectA_OUT:
416         if(cameraWork.CAMERAiStateOut.effect_A != CAMERA_EFFECT_NONE)
417         {
418 //OS_TPrintf("CAMERA_I2CEffectExAsyncCore(CAMERA_SELECT_OUT, CAMERA_CONTEXT_A, cameraWork.CAMERAiStateOut.effect_A)\n");
419             (void)CAMERA_I2CEffectExAsyncCore(CAMERA_SELECT_OUT, CAMERA_CONTEXT_A, cameraWork.CAMERAiStateOut.effect_A, CAMERA_Reboot, (void*)I2C_EffectB_OUT);
420             return;
421         }
422     case I2C_EffectB_OUT:
423         if(cameraWork.CAMERAiStateOut.effect_B != CAMERA_EFFECT_NONE)
424         {
425 //OS_TPrintf("CAMERA_I2CEffectExAsyncCore(CAMERA_SELECT_OUT, CAMERA_CONTEXT_B, cameraWork.CAMERAiStateOut.effect_B)\n");
426             (void)CAMERA_I2CEffectExAsyncCore(CAMERA_SELECT_OUT, CAMERA_CONTEXT_B, cameraWork.CAMERAiStateOut.effect_B, CAMERA_Reboot, (void*)I2C_FlipA_IN);
427             return;
428         }
429     case I2C_FlipA_IN:
430         if(cameraWork.CAMERAiStateIn.flip_A != CAMERA_FLIP_HORIZONTAL)
431         {
432 //OS_TPrintf("CAMERA_I2CFlipExAsyncCore(CAMERA_SELECT_IN, CAMERA_CONTEXT_A, cameraWork.CAMERAiStateIn.flip_A)\n");
433             (void)CAMERA_I2CFlipExAsyncCore(CAMERA_SELECT_IN, CAMERA_CONTEXT_A, cameraWork.CAMERAiStateIn.flip_A, CAMERA_Reboot, (void*)I2C_FlipB_IN);
434             return;
435         }
436     case I2C_FlipB_IN:
437         if(cameraWork.CAMERAiStateIn.flip_B != CAMERA_FLIP_HORIZONTAL)
438         {
439 //OS_TPrintf("CAMERA_I2CFlipExAsyncCore(CAMERA_SELECT_IN, CAMERA_CONTEXT_B, cameraWork.CAMERAiStateIn.flip_B)\n");
440             (void)CAMERA_I2CFlipExAsyncCore(CAMERA_SELECT_IN, CAMERA_CONTEXT_B, cameraWork.CAMERAiStateIn.flip_B, CAMERA_Reboot, (void*)I2C_FlipA_OUT);
441             return;
442         }
443     case I2C_FlipA_OUT:
444         if(cameraWork.CAMERAiStateOut.flip_A != CAMERA_FLIP_NONE)
445         {
446 //OS_TPrintf("CAMERA_I2CFlipExAsyncCore(CAMERA_SELECT_OUT, CAMERA_CONTEXT_A, cameraWork.CAMERAiStateOut.flip_A)\n");
447             (void)CAMERA_I2CFlipExAsyncCore(CAMERA_SELECT_OUT, CAMERA_CONTEXT_A, cameraWork.CAMERAiStateOut.flip_A, CAMERA_Reboot, (void*)I2C_FlipB_OUT);
448             return;
449         }
450     case I2C_FlipB_OUT:
451         if(cameraWork.CAMERAiStateOut.flip_B != CAMERA_FLIP_NONE)
452         {
453 //OS_TPrintf("CAMERA_I2CFlipExAsyncCore(CAMERA_SELECT_OUT, CAMERA_CONTEXT_B, cameraWork.CAMERAiStateOut.flip_B)\n");
454             (void)CAMERA_I2CFlipExAsyncCore(CAMERA_SELECT_OUT, CAMERA_CONTEXT_B, cameraWork.CAMERAiStateOut.flip_B, CAMERA_Reboot, (void*)I2C_WhiteBalance_IN);
455             return;
456         }
457     case I2C_WhiteBalance_IN:
458         if(cameraWork.CAMERAiStateIn.wb != CAMERA_GetWhiteBalanceFromPhotoMode(cameraWork.CAMERAiStateIn.photo))
459         {
460 //OS_TPrintf("CAMERA_I2CWhiteBalanceAsyncCore(CAMERA_SELECT_IN, cameraWork.CAMERAiStateIn.wb)\n");
461             (void)CAMERA_I2CWhiteBalanceAsyncCore(CAMERA_SELECT_IN, cameraWork.CAMERAiStateIn.wb, CAMERA_Reboot, (void*)I2C_WhiteBalance_OUT);
462             return;
463         }
464     case I2C_WhiteBalance_OUT:
465         if(cameraWork.CAMERAiStateOut.wb != CAMERA_GetWhiteBalanceFromPhotoMode(cameraWork.CAMERAiStateOut.photo))
466         {
467 //OS_TPrintf("CAMERA_I2CWhiteBalanceAsyncCore(CAMERA_SELECT_OUT, cameraWork.CAMERAiStateOut.wb)\n");
468             (void)CAMERA_I2CWhiteBalanceAsyncCore(CAMERA_SELECT_OUT, cameraWork.CAMERAiStateOut.wb, CAMERA_Reboot, (void*)I2C_Exposure_IN);
469             return;
470         }
471     case I2C_Exposure_IN:
472         if (cameraWork.CAMERAiStateIn.exposure != CAMERA_GetExposureFromPhotoMode(cameraWork.CAMERAiStateIn.photo))
473         {
474 //OS_TPrintf("CAMERA_I2CExposureAsyncCore(CAMERA_SELECT_IN, cameraWork.CAMERAiStateIn.exposure)\n");
475             (void)CAMERA_I2CExposureAsyncCore(CAMERA_SELECT_IN, cameraWork.CAMERAiStateIn.exposure, CAMERA_Reboot, (void*)I2C_Exposure_OUT);
476             return;
477         }
478     case I2C_Exposure_OUT:
479         if (cameraWork.CAMERAiStateOut.exposure != CAMERA_GetExposureFromPhotoMode(cameraWork.CAMERAiStateOut.photo))
480         {
481 //OS_TPrintf("CAMERA_I2CExposureAsyncCore(CAMERA_SELECT_OUT, cameraWork.CAMERAiStateOut.exposure)\n");
482             (void)CAMERA_I2CExposureAsyncCore(CAMERA_SELECT_OUT, cameraWork.CAMERAiStateOut.exposure, CAMERA_Reboot, (void*)I2C_Sharpness_IN);
483             return;
484         }
485     case I2C_Sharpness_IN:
486         if (cameraWork.CAMERAiStateIn.sharpness != CAMERA_GetSharpnessFromPhotoMode(cameraWork.CAMERAiStateIn.photo))
487         {
488 //OS_TPrintf("CAMERA_I2CSharpnessAsyncCore(CAMERA_SELECT_IN, cameraWork.CAMERAiStateIn.sharpness)\n");
489             (void)CAMERA_I2CSharpnessAsyncCore(CAMERA_SELECT_IN, cameraWork.CAMERAiStateIn.sharpness, CAMERA_Reboot, (void*)I2C_Sharpness_OUT);
490             return;
491         }
492     case I2C_Sharpness_OUT:
493         if (cameraWork.CAMERAiStateOut.sharpness != CAMERA_GetSharpnessFromPhotoMode(cameraWork.CAMERAiStateOut.photo))
494         {
495 //OS_TPrintf("CAMERA_I2CSharpnessAsyncCore(CAMERA_SELECT_OUT, cameraWork.CAMERAiStateOut.sharpness)\n");
496             (void)CAMERA_I2CSharpnessAsyncCore(CAMERA_SELECT_OUT, cameraWork.CAMERAiStateOut.sharpness, CAMERA_Reboot, (void*)I2C_AutoExposure_IN);
497             return;
498         }
499     case I2C_AutoExposure_IN:
500         if (cameraWork.CAMERAiStateIn.ae != TRUE)
501         {
502 //OS_TPrintf("CAMERA_I2CAutoExposureAsyncCore(CAMERA_SELECT_IN, cameraWork.CAMERAiStateIn.ae)\n");
503             (void)CAMERA_I2CAutoExposureAsyncCore(CAMERA_SELECT_IN, cameraWork.CAMERAiStateIn.ae, CAMERA_Reboot, (void*)I2C_AutoExposure_OUT);
504             return;
505         }
506     case I2C_AutoExposure_OUT:
507         if (cameraWork.CAMERAiStateOut.ae != TRUE)
508         {
509 //OS_TPrintf("CAMERA_I2CAutoExposureAsyncCore(CAMERA_SELECT_OUT, cameraWork.CAMERAiStateOut.ae)\n");
510             (void)CAMERA_I2CAutoExposureAsyncCore(CAMERA_SELECT_OUT, cameraWork.CAMERAiStateOut.ae, CAMERA_Reboot, (void*)I2C_AutoWhiteBalance_IN);
511             return;
512         }
513     case I2C_AutoWhiteBalance_IN:
514         if (cameraWork.CAMERAiStateIn.awb != TRUE)
515         {
516 //OS_TPrintf("CAMERA_I2CAutoWhiteBalanceAsyncCore(CAMERA_SELECT_IN, cameraWork.CAMERAiStateIn.awb)\n");
517             (void)CAMERA_I2CAutoWhiteBalanceAsyncCore(CAMERA_SELECT_IN, cameraWork.CAMERAiStateIn.awb, CAMERA_Reboot, (void*)I2C_AutoWhiteBalance_OUT);
518             return;
519         }
520     case I2C_AutoWhiteBalance_OUT:
521         if (cameraWork.CAMERAiStateOut.awb != TRUE)
522         {
523 //OS_TPrintf("CAMERA_I2CAutoWhiteBalanceAsyncCore(CAMERA_SELECT_OUT, cameraWork.CAMERAiStateOut.awb)\n");
524             (void)CAMERA_I2CAutoWhiteBalanceAsyncCore(CAMERA_SELECT_OUT, cameraWork.CAMERAiStateOut.awb, CAMERA_Reboot, (void*)I2C_Context_IN);
525             return;
526         }
527     case I2C_Context_IN:
528         if (cameraWork.CAMERAiStateIn.context != CAMERA_CONTEXT_A)
529         {
530 //OS_TPrintf("CAMERA_I2CContextSwitchAsync(CAMERA_SELECT_IN, cameraWork.CAMERAiStateIn.context)\n");
531             (void)CAMERA_I2CContextSwitchAsync(CAMERA_SELECT_IN, cameraWork.CAMERAiStateIn.context, CAMERA_Reboot, (void*)I2C_Context_OUT);
532             return;
533         }
534     case I2C_Context_OUT:
535         if (cameraWork.CAMERAiStateOut.context != CAMERA_CONTEXT_A)
536         {
537 //OS_TPrintf("CAMERA_I2CContextSwitchAsync(CAMERA_SELECT_OUT, cameraWork.CAMERAiStateOut.context)\n");
538             (void)CAMERA_I2CContextSwitchAsync(CAMERA_SELECT_OUT, cameraWork.CAMERAiStateOut.context, CAMERA_Reboot, (void*)I2C_Activate);
539             return;
540         }
541     case I2C_Activate:
542         // Started on original camera side
543         if (cameraWork.CAMERAiCurrentCamera != CAMERA_SELECT_NONE)
544         {
545 //OS_TPrintf("CAMERA_I2CActivateAsyncCore(cameraWork.CAMERAiCurrentCamera)\n");
546             (void)CAMERA_I2CActivateAsyncCore(cameraWork.CAMERAiCurrentCamera, CAMERA_Reboot, (void*)Set_LED);
547             return;
548         }
549     case Set_LED:
550         // Only when the outer camera is enabled; change the LED as necessary
551         if ((cameraWork.CAMERAiCurrentCamera == CAMERA_SELECT_OUT)&&(cameraWork.CAMERAiStateOut.blink == TRUE))
552         {
553             (void)CAMERA_SetLEDAsync(TRUE, CAMERA_Reboot, (void*)I2C_MAX);
554             return;
555         }
556     }
557 //OS_TPrintf("Reboot was done.\n");
558     cameraWork.CAMERAiRetryCount = 0; // Initialize retry counter
559     if(cameraWork.CAMERAiRebootCallback != 0)    // Notify the application that the reboot process is completed
560     {
561         cameraWork.CAMERAiRebootCallback(CAMERA_RESULT_SUCCESS);
562     }
563 }
564 
CAMERA_CheckRetryCount(void)565 static CAMERAResult CAMERA_CheckRetryCount(void)
566 {
567     // Consider FATAL if the I2C function fails more than a fixed number of times
568     if(cameraWork.CAMERAiRetryCount > CAMERA_RETRY_COUNT)
569     {
570         // When camera is not disabled, disable camera before returning an error.
571         if(cameraWork.CAMERAiCurrentCamera != CAMERA_SELECT_NONE)
572         {
573             // Specify master clock
574             cameraWork.force_deactivate = TRUE;
575 
576             cameraWork.CAMERAiCurrentCamera = CAMERA_SELECT_NONE;
577 
578             (void)CameraSendPxiCommand(CAMERA_PXI_COMMAND_ACTIVATE, CAMERA_PXI_SIZE_ACTIVATE, (u8)CAMERA_SELECT_NONE);
579         }
580         return CAMERA_RESULT_FATAL_ERROR;
581     }
582     // Consider ILLEGAL_STATUS if rebooting
583     if(cameraWork.CAMERAiRetryCount > 0)
584     {
585         return CAMERA_RESULT_ILLEGAL_STATUS;
586     }
587     return CAMERA_RESULT_SUCCESS;
588 }
589 
590 /*---------------------------------------------------------------------------*
591   Name:         CAMERA_MonitorThread
592 
593   Description:  Camera monitoring thread that is also for initiating rebooting.
594 
595   Arguments:    arg: Unused
596 
597   Returns:      None.
598  *---------------------------------------------------------------------------*/
599 #define CAMERA_MONITOR_INTERVAL 100
600 #define CAMERA_MONITOR_COUNT    (1000/CAMERA_MONITOR_INTERVAL)
CAMERA_MonitorThread(void * arg)601 static void CAMERA_MonitorThread(void* arg)
602 {
603 #pragma unused(arg)
604     (void)OS_DisableInterrupts();
605     while (1)
606     {
607         OSMessage msg;
608         OS_Sleep(CAMERA_MONITOR_INTERVAL);
609         if ( !OS_ReceiveMessage(cameraWork.CAMERAiMonitorMessageQueue, &msg, OS_MESSAGE_NOBLOCK) )
610         {   // Periodic call process
611             if (cameraWork.CAMERAiRetryCount != 0                               // Do nothing if already running
612                 || cameraWork.CAMERAiCurrentCamera == CAMERA_SELECT_NONE        // Do nothing if in standby
613                 || cameraWork.lock                                              // Do nothing if calling another I2C
614                 || ++cameraWork.CAMERAiMonitorCounter < CAMERA_MONITOR_COUNT)   // Do nothing if an adequate amount of time has not passed
615             {
616                 continue;
617             }
618             cameraWork.CAMERAiMonitorCounter = 0;
619             if ( (int)(OS_GetTick() - cameraWork.CAMERAiLastCameraVSync) < CAMERA_VSYNC_TIMEOUT )
620             {
621                 continue;
622             }
623             // Reboot confirmed (GoReboot();return; is also ok)
624             cameraWork.lock = TRUE;
625             cameraWork.CAMERAiRetryCount++;
626         }
627 //OS_TPrintf("Reboot....\n");
628         // Reboot starting process
629         if ( CAMERA_CheckRetryCount() == CAMERA_RESULT_FATAL_ERROR )    // FATAL error if failure occurs more than a fixed number of times
630         {
631             cameraWork.lock = FALSE; // Unlock because failed
632             if(cameraWork.CAMERAiRebootCallback != 0)    // Notify the application that the reboot process failed
633             {
634                 cameraWork.CAMERAiRebootCallback(CAMERA_RESULT_FATAL_ERROR);
635             }
636             return;
637         }
638         (void)OS_EnableInterrupts();    // Because it takes a long time...
639         CAMERA_ResetCore(); // Hardware reset
640         (void)OS_DisableInterrupts();
641         cameraWork.lock = FALSE;
642         CAMERA_Reboot(CAMERA_RESULT_SUCCESS, (void*)I2C_Init); // The reboot routine is called when lock == FALSE, and interrupts are prohibited
643     }
644 }
645 
646 /*---------------------------------------------------------------------------*
647   Name:         CAMERA_Init
648 
649   Description:  Initializes the camera library.
650 
651   Arguments:    None.
652 
653   Returns:      CAMERAResult
654  *---------------------------------------------------------------------------*/
CAMERA_InitCore(void)655 CAMERAResult CAMERA_InitCore(void)
656 {
657     //---- Check if tick system is available
658     SDK_ASSERTMSG(OS_IsTickAvailable(), "CAMERA_Init: camera system needs of tick system.");
659 
660     // Check if initialized
661     if (cameraInitialized)
662     {
663         return CAMERA_RESULT_BUSY;
664     }
665     cameraInitialized = 1;
666 
667     // Clear the various callback functions
668     cameraWork.CAMERAiVsyncCallback = 0;
669     cameraWork.CAMERAiBufferErrorCallback = 0;
670     cameraWork.CAMERAiRebootCallback = 0;
671 
672     // Variable initialization
673     cameraWork.lock = FALSE;
674     cameraWork.callback = NULL;
675     cameraWork.force_deactivate = cameraWork.force_activate = FALSE;
676 
677     cameraWork.CAMERAiCurrentCamera = CAMERA_SELECT_NONE;
678     cameraWork.CAMERAiRetryCount = 0; // Initialize retry counter
679     cameraWork.CAMERAiMonitorCounter = 0;
680 
681     // Initialize PXI
682     PXI_Init();
683     if (!PXI_IsCallbackReady(PXI_FIFO_TAG_CAMERA, PXI_PROC_ARM7))
684     {
685         return CAMERA_RESULT_FATAL_ERROR;
686     }
687     PXI_SetFifoRecvCallback(PXI_FIFO_TAG_CAMERA, CameraPxiCallback);
688 #if 0
689     if (0 > PXI_SendWordByFifo(PXI_FIFO_TAG_CAMERA, 0, 0))
690     {
691         OS_TPrintf("===failed PXI_Send...ARM7 Start\n");
692         return CAMERA_RESULT_SEND_ERROR;
693     }
694 #endif
695     // Hardware reset
696     CAMERA_ResetCore();
697     // Guarantee stopping of capture and no errors
698     CAMERA_StopCaptureCore();
699     CAMERA_ClearBufferCore();
700 
701     // Register sleep recovery callbacks
702     PM_SetSleepCallbackInfo(&cameraWork.sleepCbInfo, CameraStandbyCallback, NULL);
703     PMi_InsertPreSleepCallbackEx(&cameraWork.sleepCbInfo, PM_CALLBACK_PRIORITY_CAMERA);
704     // Register the callback when reset/power is off
705     PM_SetExitCallbackInfo(&cameraWork.exitCbInfo, CameraStandbyCallback, NULL);
706     PMi_InsertPostExitCallbackEx(&cameraWork.exitCbInfo, PM_CALLBACK_PRIORITY_CAMERA);
707 
708     // Set camera interrupt
709     CAMERA_SetVsyncInterruptCore(CAMERA_INTR_VSYNC_NEGATIVE_EDGE);
710     CAMERA_SetBufferErrorInterruptCore(TRUE);
711     CAMERA_SetMasterInterruptCore(TRUE);
712     OS_SetIrqFunction(OS_IE_CAMERA, CAMERA_CameraIntr);
713     (void)OS_EnableIrqMask(OS_IE_CAMERA);
714 
715     // Initialize the camera in/out setting value
716     {
717         cameraWork.CAMERAiStateIn.size_A = CAMERA_SIZE_DS_LCD;
718         cameraWork.CAMERAiStateIn.size_B = CAMERA_SIZE_VGA;
719         cameraWork.CAMERAiStateIn.effect_A = CAMERA_EFFECT_NONE;
720         cameraWork.CAMERAiStateIn.effect_B = CAMERA_EFFECT_NONE;
721         cameraWork.CAMERAiStateIn.flip_A = CAMERA_FLIP_HORIZONTAL;
722         cameraWork.CAMERAiStateIn.flip_B = CAMERA_FLIP_HORIZONTAL;
723         cameraWork.CAMERAiStateIn.photo = CAMERA_PHOTO_MODE_PORTRAIT;
724         cameraWork.CAMERAiStateIn.wb = CAMERA_WHITE_BALANCE_NORMAL;
725         cameraWork.CAMERAiStateIn.rate = CAMERA_FRAME_RATE_15;
726         cameraWork.CAMERAiStateIn.exposure = 0;
727         cameraWork.CAMERAiStateIn.sharpness = -2;
728         cameraWork.CAMERAiStateIn.ae = TRUE;
729         cameraWork.CAMERAiStateIn.awb = TRUE;
730         cameraWork.CAMERAiStateIn.context = CAMERA_CONTEXT_A;
731         cameraWork.CAMERAiStateIn.blink = FALSE; // There is no option on the inner camera for LED lighting/flashing, but initialize anyway
732 
733         cameraWork.CAMERAiStateOut.size_A = CAMERA_SIZE_DS_LCD;
734         cameraWork.CAMERAiStateOut.size_B = CAMERA_SIZE_VGA;
735         cameraWork.CAMERAiStateOut.effect_A = CAMERA_EFFECT_NONE;
736         cameraWork.CAMERAiStateOut.effect_B = CAMERA_EFFECT_NONE;
737         cameraWork.CAMERAiStateOut.flip_A = CAMERA_FLIP_NONE;
738         cameraWork.CAMERAiStateOut.flip_B = CAMERA_FLIP_NONE;
739         cameraWork.CAMERAiStateOut.photo = CAMERA_PHOTO_MODE_NORMAL;
740         cameraWork.CAMERAiStateOut.wb = CAMERA_WHITE_BALANCE_NORMAL;
741         cameraWork.CAMERAiStateOut.rate = CAMERA_FRAME_RATE_15;
742         cameraWork.CAMERAiStateOut.exposure = 0;
743         cameraWork.CAMERAiStateOut.sharpness = 0;
744         cameraWork.CAMERAiStateOut.ae = TRUE;
745         cameraWork.CAMERAiStateOut.awb = TRUE;
746         cameraWork.CAMERAiStateOut.context = CAMERA_CONTEXT_A;
747         cameraWork.CAMERAiStateOut.blink = FALSE;
748     }
749 
750     // Create message queue for rebooting
751     OS_InitMessageQueue(cameraWork.CAMERAiMonitorMessageQueue, cameraWork.CAMERAiMonitorMessage, sizeof(cameraWork.CAMERAiMonitorMessage)/sizeof(OSMessage));
752     // Create a thread for detecting malfunction
753     OS_CreateThread(cameraWork.CAMERAiMonitorThread, CAMERA_MonitorThread, 0, &cameraWork.CAMERAiMonitorThreadStack[1024], 4096, 4);
754     OS_WakeupThreadDirect(cameraWork.CAMERAiMonitorThread);
755     return CAMERA_RESULT_SUCCESS;
756 }
757 
758 /*---------------------------------------------------------------------------*
759   Name:         CAMERA_End
760 
761   Description:  Quit the camera library.
762 
763   Arguments:    None.
764 
765   Returns:      None.
766  *---------------------------------------------------------------------------*/
CAMERA_EndCore(void)767 void CAMERA_EndCore(void)
768 {
769     // Check if initialized
770     if (cameraInitialized == 0)
771     {
772         return;
773     }
774     cameraInitialized = 0;
775 
776     // Delete the callback when recovering from sleep
777     PM_DeletePreSleepCallback(&cameraWork.sleepCbInfo);
778     // Delete the callback when reset or when powering off
779     PM_DeletePostExitCallback(&cameraWork.exitCbInfo);
780 
781     // Stop camera module
782     (void)CAMERA_I2CActivateCore(CAMERA_SELECT_NONE);
783 
784     // Hardware reset
785     CAMERA_ResetCore();
786     // Guarantee stopping of capture and no errors
787     CAMERA_StopCaptureCore();
788     CAMERA_ClearBufferCore();
789 
790     // Stop PXI
791     PXI_SetFifoRecvCallback(PXI_FIFO_TAG_CAMERA, NULL);
792 
793     // Free camera interrupt setting
794     CAMERA_SetVsyncInterruptCore(CAMERA_INTR_VSYNC_NONE);
795     CAMERA_SetBufferErrorInterruptCore(FALSE);
796     CAMERA_SetMasterInterruptCore(FALSE);
797     OS_SetIrqFunction(OS_IE_CAMERA, 0);
798     (void)OS_DisableIrqMask(OS_IE_CAMERA);
799 
800     // Delete a thread for detecting malfunction
801     OS_KillThread(cameraWork.CAMERAiMonitorThread, 0);
802 }
803 
804 /*---------------------------------------------------------------------------*
805   Name:         CAMERA_Start
806 
807   Description:  Host API that starts capturing. Can also be used for switching.
808                 SYNC version only.
809 
810   Arguments:    camera: One of CAMERASelect values
811 
812   Returns:      CAMERAResult.
813  *---------------------------------------------------------------------------*/
CAMERA_StartCore(CAMERASelect camera)814 CAMERAResult CAMERA_StartCore(CAMERASelect camera)
815 {
816     CAMERAResult result;
817 
818     switch (camera)
819     {
820     // case CAMERA_SELECT_NONE:
821     case CAMERA_SELECT_IN:
822     case CAMERA_SELECT_OUT:
823     // case CAMERA_SELECT_BOTH:
824         break;
825     default:
826         return CAMERA_RESULT_ILLEGAL_PARAMETER;
827     }
828     result = CAMERA_I2CActivateCore(camera);
829     if (result != CAMERA_RESULT_SUCCESS_TRUE)
830     {
831         return result;
832     }
833     CAMERA_StopCaptureCore();
834     while ( CAMERA_IsBusyCore() != FALSE)
835     {
836     }
837     CAMERA_ClearBufferCore();
838     CAMERA_StartCaptureCore();
839     return CAMERA_RESULT_SUCCESS_TRUE;
840 }
841 
842 /*---------------------------------------------------------------------------*
843   Name:         CAMERA_Stop
844 
845   Description:  Host API that stops capturing.
846                 SYNC version only.
847 
848   Arguments:    None.
849 
850   Returns:      CAMERAResult.
851  *---------------------------------------------------------------------------*/
CAMERA_StopCore(void)852 CAMERAResult CAMERA_StopCore(void)
853 {
854     int limit = OS_MilliSecondsToTicks( 200 ) * 64 / 4;
855     CAMERA_StopCaptureCore();
856     while ( limit-- > 0 && CAMERA_IsBusyCore() != FALSE) // With timeout
857     {
858         OS_SpinWaitSysCycles( 4 );
859     }
860     CAMERA_ClearBufferCore();
861     return CAMERA_I2CActivateCore(CAMERA_SELECT_NONE);
862 }
863 
864 /*---------------------------------------------------------------------------*
865   Name:         CAMERA_I2CInitAsync
866 
867   Description:  Initialize camera registers via I2C.
868                 ASYNC version.
869 
870   Arguments:    camera: One of the CAMERASelect values
871                 callback: Specifies the function to be called when the asynchronous process is completed
872                 arg: Specifies the argument used when calling the callback function
873 
874   Returns:      CAMERAResult.
875  *---------------------------------------------------------------------------*/
CAMERA_I2CInitAsyncCore(CAMERASelect camera,CAMERACallback callback,void * arg)876 CAMERAResult CAMERA_I2CInitAsyncCore(CAMERASelect camera, CAMERACallback callback, void *arg)
877 {
878     const CAMERAPxiCommand  command = CAMERA_PXI_COMMAND_INIT;
879     const u8                _size   = CAMERA_PXI_SIZE_INIT;
880     OSIntrMode enabled;
881     CAMERAResult result;
882 
883     SDK_NULL_ASSERT(callback);
884 
885     // Status check based on the retry count and whether rebooting
886     result = CAMERA_CheckRetryCount();
887     if(result == CAMERA_RESULT_FATAL_ERROR)
888         return result;
889 
890     switch (camera)
891     {
892     // case CAMERA_SELECT_NONE:
893     case CAMERA_SELECT_IN:
894     case CAMERA_SELECT_OUT:
895     case CAMERA_SELECT_BOTH:
896         break;
897     default:
898         return CAMERA_RESULT_ILLEGAL_PARAMETER;
899     }
900 
901     enabled = OS_DisableInterrupts();
902     if (cameraWork.lock)
903     {
904         (void)OS_RestoreInterrupts(enabled);
905         return result == CAMERA_RESULT_ILLEGAL_STATUS ? CAMERA_RESULT_ILLEGAL_STATUS : CAMERA_RESULT_BUSY;
906     }
907     cameraWork.lock = TRUE;
908     (void)OS_RestoreInterrupts(enabled);
909     // Callback settings
910     cameraWork.callback = callback;
911     cameraWork.callbackArg = arg;
912     // Specify master clock
913     cameraWork.force_deactivate = TRUE;
914     return CameraSendPxiCommand(command, _size, (u8)camera) ? CAMERA_RESULT_SUCCESS : CAMERA_RESULT_SEND_ERROR;
915 }
916 
917 /*---------------------------------------------------------------------------*
918   Name:         CAMERA_I2CInit
919 
920   Description:  Initialize camera registers via I2C.
921                 SYNC version.
922 
923   Arguments:    camera: One of the CAMERASelect values
924 
925   Returns:      CAMERAResult.
926  *---------------------------------------------------------------------------*/
CAMERA_I2CInitCore(CAMERASelect camera)927 CAMERAResult CAMERA_I2CInitCore(CAMERASelect camera)
928 {
929     cameraWork.result = CAMERA_I2CInitAsyncCore(camera, CameraSyncCallback, 0);
930     if (cameraWork.result == CAMERA_RESULT_SUCCESS)
931     {
932         CameraWaitBusy();
933     }
934     return cameraWork.result;
935 }
936 
937 /*---------------------------------------------------------------------------*
938   Name:         CAMERA_I2CActivateAsync
939 
940   Description:  Activate specified camera (goto standby if NONE is specified).
941                 ASYNC version.
942 
943   Arguments:    camera: One of the CAMERASelect values (BOTH is not valid)
944                 callback: Specifies the function to be called when the asynchronous process is completed
945                 arg: Specifies the argument used when calling the callback function
946 
947   Returns:      CAMERAResult.
948  *---------------------------------------------------------------------------*/
CAMERA_I2CActivateAsyncCore(CAMERASelect camera,CAMERACallback callback,void * arg)949 CAMERAResult CAMERA_I2CActivateAsyncCore(CAMERASelect camera, CAMERACallback callback, void *arg)
950 {
951     const CAMERAPxiCommand  command = CAMERA_PXI_COMMAND_ACTIVATE;
952     const u8                _size   = CAMERA_PXI_SIZE_ACTIVATE;
953     OSIntrMode enabled;
954     CAMERAResult result;
955 
956     SDK_NULL_ASSERT(callback);
957 
958     // Status check based on the retry count and whether rebooting
959     result = CAMERA_CheckRetryCount();
960     if(result == CAMERA_RESULT_FATAL_ERROR)
961         return result;
962 
963     switch (camera)
964     {
965     case CAMERA_SELECT_NONE:
966     case CAMERA_SELECT_IN:
967     case CAMERA_SELECT_OUT:
968     //case CAMERA_SELECT_BOTH:
969         break;
970     default:
971         return CAMERA_RESULT_ILLEGAL_PARAMETER;
972     }
973 
974     enabled = OS_DisableInterrupts();
975     if (cameraWork.lock)
976     {
977         (void)OS_RestoreInterrupts(enabled);
978         return result == CAMERA_RESULT_ILLEGAL_STATUS ? CAMERA_RESULT_ILLEGAL_STATUS : CAMERA_RESULT_BUSY;
979     }
980     cameraWork.lock = TRUE;
981     (void)OS_RestoreInterrupts(enabled);
982     // Callback settings
983     cameraWork.callback = callback;
984     cameraWork.callbackArg = arg;
985     // Specify master clock
986     if (camera == CAMERA_SELECT_NONE)
987     {
988         cameraWork.force_deactivate = TRUE;
989     }
990     else
991     {
992         cameraWork.force_activate = TRUE;
993     }
994 
995     cameraWork.CAMERAiCurrentCamera = camera;
996     if(cameraWork.CAMERAiRetryCount == 0)
997     {
998         cameraWork.CAMERAiStateTmp.blink = FALSE;
999     }
1000 
1001     cameraWork.CAMERAiLastCameraVSync = OS_GetTick();
1002 
1003     return CameraSendPxiCommand(command, _size, (u8)camera) ? CAMERA_RESULT_SUCCESS : CAMERA_RESULT_SEND_ERROR;
1004 }
1005 
1006 /*---------------------------------------------------------------------------*
1007   Name:         CAMERA_I2CActivate
1008 
1009   Description:  Activate specified camera (goto standby if NONE is specified).
1010                 SYNC version.
1011 
1012   Arguments:    camera: One of the CAMERASelect values (BOTH is not valid)
1013 
1014   Returns:      CAMERAResult.
1015  *---------------------------------------------------------------------------*/
CAMERA_I2CActivateCore(CAMERASelect camera)1016 CAMERAResult CAMERA_I2CActivateCore(CAMERASelect camera)
1017 {
1018     cameraWork.result = CAMERA_I2CActivateAsyncCore(camera, CameraSyncCallback, 0);
1019     if (cameraWork.result == CAMERA_RESULT_SUCCESS)
1020     {
1021         CameraWaitBusy();
1022     }
1023     return cameraWork.result;
1024 }
1025 
1026 /*---------------------------------------------------------------------------*
1027   Name:         CAMERA_I2CContextSwitchAsync
1028 
1029   Description:  Resize camera output image.
1030                 ASYNC version.
1031 
1032   Arguments:    camera: One of the CAMERASelect values
1033                 context: One of the CAMERAContext values (A or B)
1034                 callback: Specifies the function to be called when the asynchronous process is completed
1035                 arg: Specifies the argument used when calling the callback function
1036 
1037   Returns:      CAMERAResult.
1038  *---------------------------------------------------------------------------*/
CAMERA_I2CContextSwitchAsyncCore(CAMERASelect camera,CAMERAContext context,CAMERACallback callback,void * arg)1039 CAMERAResult CAMERA_I2CContextSwitchAsyncCore(CAMERASelect camera, CAMERAContext context, CAMERACallback callback, void *arg)
1040 {
1041     const CAMERAPxiCommand  command = CAMERA_PXI_COMMAND_CONTEXT_SWITCH;
1042     const u8                _size   = CAMERA_PXI_SIZE_CONTEXT_SWITCH;
1043     OSIntrMode enabled;
1044     u8  data[_size+2];
1045     int i;
1046     CAMERAResult result;
1047 
1048     SDK_NULL_ASSERT(callback);
1049 
1050     // Status check based on the retry count and whether rebooting
1051     result = CAMERA_CheckRetryCount();
1052     if(result == CAMERA_RESULT_FATAL_ERROR)
1053         return result;
1054 
1055     switch (camera)
1056     {
1057     // case CAMERA_SELECT_NONE:
1058     case CAMERA_SELECT_IN:
1059     case CAMERA_SELECT_OUT:
1060     // case CAMERA_SELECT_BOTH:
1061         break;
1062     default:
1063         return CAMERA_RESULT_ILLEGAL_PARAMETER;
1064     }
1065     switch (context)
1066     {
1067     case CAMERA_CONTEXT_A:
1068     case CAMERA_CONTEXT_B:
1069     // case CAMERA_CONTEXT_BOTH:
1070         break;
1071     default:
1072         return CAMERA_RESULT_ILLEGAL_PARAMETER;
1073     }
1074 
1075     enabled = OS_DisableInterrupts();
1076     if (cameraWork.lock)
1077     {
1078         (void)OS_RestoreInterrupts(enabled);
1079         return result == CAMERA_RESULT_ILLEGAL_STATUS ? CAMERA_RESULT_ILLEGAL_STATUS : CAMERA_RESULT_BUSY;
1080     }
1081     cameraWork.lock = TRUE;
1082     (void)OS_RestoreInterrupts(enabled);
1083     // Callback settings
1084     cameraWork.callback = callback;
1085     cameraWork.callbackArg = arg;
1086 
1087     // Create data
1088     data[0] = (u8)camera;
1089     data[1] = (u8)context;
1090 
1091     // Set the setting value to the I2C command saving structure for the rebooting routine
1092     cameraWork.CAMERAiStateTmp.set_camera = camera;
1093     cameraWork.CAMERAiStateTmp.context = context;
1094 
1095     // Send command
1096     if (CameraSendPxiCommand(command, _size, data[0]) == FALSE)
1097     {
1098         return CAMERA_RESULT_SEND_ERROR;
1099     }
1100     for (i = 1; i < _size; i+=3) {
1101         CameraSendPxiData(&data[i]);
1102     }
1103 
1104     return CAMERA_RESULT_SUCCESS;
1105 }
1106 
1107 /*---------------------------------------------------------------------------*
1108   Name:         CAMERA_I2CContextSwitch
1109 
1110   Description:  Resize camera output image.
1111                 SYNC version.
1112 
1113   Arguments:    camera: One of the CAMERASelect values
1114                 context: One of CAMERAContext values (A or B)
1115 
1116   Returns:      CAMERAResult.
1117  *---------------------------------------------------------------------------*/
CAMERA_I2CContextSwitchCore(CAMERASelect camera,CAMERAContext context)1118 CAMERAResult CAMERA_I2CContextSwitchCore(CAMERASelect camera, CAMERAContext context)
1119 {
1120     cameraWork.result = CAMERA_I2CContextSwitchAsyncCore(camera, context, CameraSyncCallback, 0);
1121     if (cameraWork.result == CAMERA_RESULT_SUCCESS)
1122     {
1123         CameraWaitBusy();
1124     }
1125     return cameraWork.result;
1126 }
1127 /*---------------------------------------------------------------------------*
1128   Name:         CAMERAi_I2CSizeExAsync
1129 
1130   Description:  Set camera frame size.
1131                 ASYNC version.
1132 
1133   Arguments:    camera: One of the CAMERASelect values
1134                 context: One of the CAMERAContext values (A or B or BOTH)
1135                 size: One of the CAMERASize values
1136                 callback: Specifies the function to be called when the asynchronous process is completed
1137                 arg: Specifies the argument used when calling the callback function
1138 
1139   Returns:      CAMERAResult.
1140  *---------------------------------------------------------------------------*/
CAMERA_I2CSizeExAsyncCore(CAMERASelect camera,CAMERAContext context,CAMERASize size,CAMERACallback callback,void * arg)1141 CAMERAResult CAMERA_I2CSizeExAsyncCore(CAMERASelect camera, CAMERAContext context, CAMERASize size, CAMERACallback callback, void *arg)
1142 {
1143     const CAMERAPxiCommand  command = CAMERA_PXI_COMMAND_SIZE;
1144     const u8                _size   = CAMERA_PXI_SIZE_SIZE;
1145     OSIntrMode enabled;
1146     u8  data[_size+2];
1147     int i;
1148     CAMERAResult result;
1149 
1150     SDK_NULL_ASSERT(callback);
1151 
1152     // Status check based on the retry count and whether rebooting
1153     result = CAMERA_CheckRetryCount();
1154     if(result == CAMERA_RESULT_FATAL_ERROR)
1155         return result;
1156 
1157     switch (camera)
1158     {
1159     // case CAMERA_SELECT_NONE:
1160     case CAMERA_SELECT_IN:
1161     case CAMERA_SELECT_OUT:
1162     case CAMERA_SELECT_BOTH:
1163         break;
1164     default:
1165         return CAMERA_RESULT_ILLEGAL_PARAMETER;
1166     }
1167     switch (context)
1168     {
1169     case CAMERA_CONTEXT_A:
1170     case CAMERA_CONTEXT_B:
1171     case CAMERA_CONTEXT_BOTH:
1172         break;
1173     default:
1174         return CAMERA_RESULT_ILLEGAL_PARAMETER;
1175     }
1176     switch (size)
1177     {
1178     case CAMERA_SIZE_VGA:
1179     case CAMERA_SIZE_QVGA:
1180     case CAMERA_SIZE_QQVGA:
1181     case CAMERA_SIZE_CIF:
1182     case CAMERA_SIZE_QCIF:
1183     case CAMERA_SIZE_DS_LCD:
1184     case CAMERA_SIZE_DS_LCDx4:
1185         break;
1186     default:
1187         return CAMERA_RESULT_ILLEGAL_PARAMETER;
1188     }
1189 
1190     enabled = OS_DisableInterrupts();
1191     if (cameraWork.lock)
1192     {
1193         (void)OS_RestoreInterrupts(enabled);
1194         return result == CAMERA_RESULT_ILLEGAL_STATUS ? CAMERA_RESULT_ILLEGAL_STATUS : CAMERA_RESULT_BUSY;
1195     }
1196     cameraWork.lock = TRUE;
1197     (void)OS_RestoreInterrupts(enabled);
1198     // Callback settings
1199     cameraWork.callback = callback;
1200     cameraWork.callbackArg = arg;
1201 
1202     // Create data
1203     data[0] = (u8)camera;
1204     data[1] = (u8)context;
1205     data[2] = (u8)size;
1206 
1207     // Set the setting value to the I2C command saving structure for the rebooting routine
1208     cameraWork.CAMERAiStateTmp.set_camera = camera;
1209     cameraWork.CAMERAiStateTmp.set_context = context;
1210     cameraWork.CAMERAiStateTmp.size = size;
1211 
1212     // Send command
1213     if (CameraSendPxiCommand(command, _size, data[0]) == FALSE)
1214     {
1215         return CAMERA_RESULT_SEND_ERROR;
1216     }
1217     for (i = 1; i < _size; i+=3) {
1218         CameraSendPxiData(&data[i]);
1219     }
1220 
1221     return CAMERA_RESULT_SUCCESS;
1222 }
1223 
1224 /*---------------------------------------------------------------------------*
1225   Name:         CAMERAi_I2CSizeEx
1226 
1227   Description:  Set camera frame size.
1228                 SYNC version.
1229 
1230   Arguments:    camera: One of the CAMERASelect values
1231                 context: One of the CAMERAContext values (A or B)
1232                 size: One of the CAMERASize values
1233 
1234   Returns:      CAMERAResult.
1235  *---------------------------------------------------------------------------*/
CAMERA_I2CSizeExCore(CAMERASelect camera,CAMERAContext context,CAMERASize size)1236 CAMERAResult CAMERA_I2CSizeExCore(CAMERASelect camera, CAMERAContext context, CAMERASize size)
1237 {
1238     cameraWork.result = CAMERA_I2CSizeExAsyncCore(camera, context, size, CameraSyncCallback, 0);
1239     if (cameraWork.result == CAMERA_RESULT_SUCCESS)
1240     {
1241         CameraWaitBusy();
1242     }
1243     return cameraWork.result;
1244 }
1245 
1246 /*---------------------------------------------------------------------------*
1247   Name:         CAMERA_I2CFrameRateAsync
1248 
1249   Description:  Set camera frame rate.
1250                 ASYNC version.
1251 
1252   Arguments:    camera: One of the CAMERASelect values
1253                 rate: One of the CAMERAFrameRate values
1254                 callback: Specifies the function to be called when the asynchronous process is completed
1255                 arg: Specifies the argument used when calling the callback function
1256 
1257   Returns:      CAMERAResult
1258  *---------------------------------------------------------------------------*/
CAMERA_I2CFrameRateAsyncCore(CAMERASelect camera,CAMERAFrameRate rate,CAMERACallback callback,void * arg)1259 CAMERAResult CAMERA_I2CFrameRateAsyncCore(CAMERASelect camera, CAMERAFrameRate rate, CAMERACallback callback, void *arg)
1260 {
1261     const CAMERAPxiCommand  command = CAMERA_PXI_COMMAND_FRAME_RATE;
1262     const u8                _size   = CAMERA_PXI_SIZE_FRAME_RATE;
1263     OSIntrMode enabled;
1264     u8  data[_size+2];
1265     int i;
1266     CAMERAResult result;
1267 
1268     SDK_NULL_ASSERT(callback);
1269 
1270     // Status check based on the retry count and whether rebooting
1271     result = CAMERA_CheckRetryCount();
1272     if(result == CAMERA_RESULT_FATAL_ERROR)
1273         return result;
1274 
1275     switch (camera)
1276     {
1277     // case CAMERA_SELECT_NONE:
1278     case CAMERA_SELECT_IN:
1279     case CAMERA_SELECT_OUT:
1280     case CAMERA_SELECT_BOTH:
1281         break;
1282     default:
1283         return CAMERA_RESULT_ILLEGAL_PARAMETER;
1284     }
1285     switch (rate)
1286     {
1287     case CAMERA_FRAME_RATE_15:
1288     case CAMERA_FRAME_RATE_15_TO_5:
1289     case CAMERA_FRAME_RATE_15_TO_2:
1290     case CAMERA_FRAME_RATE_8_5:
1291     case CAMERA_FRAME_RATE_5:
1292     case CAMERA_FRAME_RATE_20:
1293     case CAMERA_FRAME_RATE_20_TO_5:
1294     case CAMERA_FRAME_RATE_30:
1295     case CAMERA_FRAME_RATE_30_TO_5:
1296         break;
1297     default:
1298         return CAMERA_RESULT_ILLEGAL_PARAMETER;
1299     }
1300 
1301     enabled = OS_DisableInterrupts();
1302     if (cameraWork.lock)
1303     {
1304         (void)OS_RestoreInterrupts(enabled);
1305         return result == CAMERA_RESULT_ILLEGAL_STATUS ? CAMERA_RESULT_ILLEGAL_STATUS : CAMERA_RESULT_BUSY;
1306     }
1307     cameraWork.lock = TRUE;
1308     (void)OS_RestoreInterrupts(enabled);
1309     // Callback settings
1310     cameraWork.callback = callback;
1311     cameraWork.callbackArg = arg;
1312 
1313     // Create data
1314     data[0] = (u8)camera;
1315     data[1] = (u8)rate;
1316 
1317     // Set the setting value to the I2C command saving structure for the rebooting routine
1318     cameraWork.CAMERAiStateTmp.set_camera = camera;
1319     cameraWork.CAMERAiStateTmp.rate = rate;
1320 
1321     // Send command
1322     if (CameraSendPxiCommand(command, _size, data[0]) == FALSE)
1323     {
1324         return CAMERA_RESULT_SEND_ERROR;
1325     }
1326     for (i = 1; i < _size; i+=3) {
1327         CameraSendPxiData(&data[i]);
1328     }
1329 
1330     return CAMERA_RESULT_SUCCESS;
1331 }
1332 
1333 /*---------------------------------------------------------------------------*
1334   Name:         CAMERA_I2CFrameRate
1335 
1336   Description:  Set camera frame rate.
1337                 SYNC version.
1338 
1339   Arguments:    camera: One of the CAMERASelect values
1340                 rate: One of the CAMERAFrameRate values
1341 
1342   Returns:      CAMERAResult.
1343  *---------------------------------------------------------------------------*/
CAMERA_I2CFrameRateCore(CAMERASelect camera,CAMERAFrameRate rate)1344 CAMERAResult CAMERA_I2CFrameRateCore(CAMERASelect camera, CAMERAFrameRate rate)
1345 {
1346     cameraWork.result = CAMERA_I2CFrameRateAsyncCore(camera, rate, CameraSyncCallback, 0);
1347     if (cameraWork.result == CAMERA_RESULT_SUCCESS)
1348     {
1349         CameraWaitBusy();
1350     }
1351     return cameraWork.result;
1352 }
1353 
1354 /*---------------------------------------------------------------------------*
1355   Name:         CAMERA_I2CEffectExAsync
1356 
1357   Description:  Set camera effect.
1358                 ASYNC version.
1359 
1360   Arguments:    camera: One of the CAMERASelect values
1361                 context: One of the CAMERAContext values (A or B)
1362                 effect: One of the CAMERAEffect values
1363                 callback: Specifies the function to be called when the asynchronous process is completed
1364                 arg: Specifies the argument used when calling the callback function
1365 
1366   Returns:      CAMERAResult.
1367  *---------------------------------------------------------------------------*/
CAMERA_I2CEffectExAsyncCore(CAMERASelect camera,CAMERAContext context,CAMERAEffect effect,CAMERACallback callback,void * arg)1368 CAMERAResult CAMERA_I2CEffectExAsyncCore(CAMERASelect camera, CAMERAContext context, CAMERAEffect effect, CAMERACallback callback, void *arg)
1369 {
1370     const CAMERAPxiCommand  command = CAMERA_PXI_COMMAND_EFFECT;
1371     const u8                _size   = CAMERA_PXI_SIZE_EFFECT;
1372     OSIntrMode enabled;
1373     u8  data[_size+2];
1374     int i;
1375     CAMERAResult result;
1376 
1377     SDK_NULL_ASSERT(callback);
1378 
1379     // Status check based on the retry count and whether rebooting
1380     result = CAMERA_CheckRetryCount();
1381     if(result == CAMERA_RESULT_FATAL_ERROR)
1382         return result;
1383 
1384     switch (camera)
1385     {
1386     // case CAMERA_SELECT_NONE:
1387     case CAMERA_SELECT_IN:
1388     case CAMERA_SELECT_OUT:
1389     case CAMERA_SELECT_BOTH:
1390         break;
1391     default:
1392         return CAMERA_RESULT_ILLEGAL_PARAMETER;
1393     }
1394     switch (context)
1395     {
1396     case CAMERA_CONTEXT_A:
1397     case CAMERA_CONTEXT_B:
1398     case CAMERA_CONTEXT_BOTH:
1399         break;
1400     default:
1401         return CAMERA_RESULT_ILLEGAL_PARAMETER;
1402     }
1403     switch (effect)
1404     {
1405     case CAMERA_EFFECT_NONE:
1406     case CAMERA_EFFECT_MONO:
1407     case CAMERA_EFFECT_SEPIA:
1408     case CAMERA_EFFECT_NEGATIVE:
1409     case CAMERA_EFFECT_NEGAFILM:
1410     case CAMERA_EFFECT_SEPIA01:
1411         break;
1412     default:
1413         return CAMERA_RESULT_ILLEGAL_PARAMETER;
1414     }
1415 
1416     enabled = OS_DisableInterrupts();
1417     if (cameraWork.lock)
1418     {
1419         (void)OS_RestoreInterrupts(enabled);
1420         return result == CAMERA_RESULT_ILLEGAL_STATUS ? CAMERA_RESULT_ILLEGAL_STATUS : CAMERA_RESULT_BUSY;
1421     }
1422     cameraWork.lock = TRUE;
1423     (void)OS_RestoreInterrupts(enabled);
1424     // Callback settings
1425     cameraWork.callback = callback;
1426     cameraWork.callbackArg = arg;
1427 
1428     // Create data
1429     data[0] = (u8)camera;
1430     data[1] = (u8)context;
1431     data[2] = (u8)effect;
1432 
1433     // Set the setting value to the I2C command saving structure for the rebooting routine
1434     cameraWork.CAMERAiStateTmp.set_camera = camera;
1435     cameraWork.CAMERAiStateTmp.set_context = context;
1436     cameraWork.CAMERAiStateTmp.effect = effect;
1437 
1438     // Send command
1439     if (CameraSendPxiCommand(command, _size, data[0]) == FALSE)
1440     {
1441         return CAMERA_RESULT_SEND_ERROR;
1442     }
1443     for (i = 1; i < _size; i+=3) {
1444         CameraSendPxiData(&data[i]);
1445     }
1446 
1447     return CAMERA_RESULT_SUCCESS;
1448 }
1449 
1450 /*---------------------------------------------------------------------------*
1451   Name:         CAMERA_I2CEffectEx
1452 
1453   Description:  Set camera effect.
1454                 SYNC version.
1455 
1456   Arguments:    camera: One of the CAMERASelect values
1457                 context: One of the CAMERAContext values (A or B)
1458                 effect: One of the CAMERAEffect values
1459 
1460   Returns:      CAMERAResult.
1461  *---------------------------------------------------------------------------*/
CAMERA_I2CEffectExCore(CAMERASelect camera,CAMERAContext context,CAMERAEffect effect)1462 CAMERAResult CAMERA_I2CEffectExCore(CAMERASelect camera, CAMERAContext context, CAMERAEffect effect)
1463 {
1464     cameraWork.result = CAMERA_I2CEffectExAsyncCore(camera, context, effect, CameraSyncCallback, 0);
1465     if (cameraWork.result == CAMERA_RESULT_SUCCESS)
1466     {
1467         CameraWaitBusy();
1468     }
1469     return cameraWork.result;
1470 }
1471 
1472 /*---------------------------------------------------------------------------*
1473   Name:         CAMERA_I2CFlipExAsync
1474 
1475   Description:  Set camera flip/mirror.
1476                 ASYNC version.
1477 
1478   Arguments:    camera: One of the CAMERASelect values
1479                 context: One of CAMERAContext values (A or B)
1480                 flip: One of the CAMERAFlip values
1481                 callback: Specifies the function to be called when the asynchronous process is completed
1482                 arg: Specifies the argument used when calling the callback function
1483 
1484   Returns:      CAMERAResult.
1485  *---------------------------------------------------------------------------*/
CAMERA_I2CFlipExAsyncCore(CAMERASelect camera,CAMERAContext context,CAMERAFlip flip,CAMERACallback callback,void * arg)1486 CAMERAResult CAMERA_I2CFlipExAsyncCore(CAMERASelect camera, CAMERAContext context, CAMERAFlip flip, CAMERACallback callback, void *arg)
1487 {
1488     const CAMERAPxiCommand  command = CAMERA_PXI_COMMAND_FLIP;
1489     const u8                _size   = CAMERA_PXI_SIZE_FLIP;
1490     OSIntrMode enabled;
1491     u8  data[_size+2];
1492     int i;
1493     CAMERAResult result;
1494 
1495     SDK_NULL_ASSERT(callback);
1496 
1497     // Status check based on the retry count and whether rebooting
1498     result = CAMERA_CheckRetryCount();
1499     if(result == CAMERA_RESULT_FATAL_ERROR)
1500         return result;
1501 
1502     switch (camera)
1503     {
1504     // case CAMERA_SELECT_NONE:
1505     case CAMERA_SELECT_IN:
1506     case CAMERA_SELECT_OUT:
1507     case CAMERA_SELECT_BOTH:
1508         break;
1509     default:
1510         return CAMERA_RESULT_ILLEGAL_PARAMETER;
1511     }
1512     switch (context)
1513     {
1514     case CAMERA_CONTEXT_A:
1515     case CAMERA_CONTEXT_B:
1516     case CAMERA_CONTEXT_BOTH:
1517         break;
1518     default:
1519         return CAMERA_RESULT_ILLEGAL_PARAMETER;
1520     }
1521     switch (flip)
1522     {
1523     case CAMERA_FLIP_NONE:
1524     case CAMERA_FLIP_VERTICAL:
1525     case CAMERA_FLIP_HORIZONTAL:
1526     case CAMERA_FLIP_REVERSE:
1527         break;
1528     default:
1529         return CAMERA_RESULT_ILLEGAL_PARAMETER;
1530     }
1531 
1532     enabled = OS_DisableInterrupts();
1533     if (cameraWork.lock)
1534     {
1535         (void)OS_RestoreInterrupts(enabled);
1536         return result == CAMERA_RESULT_ILLEGAL_STATUS ? CAMERA_RESULT_ILLEGAL_STATUS : CAMERA_RESULT_BUSY;
1537     }
1538     cameraWork.lock = TRUE;
1539     (void)OS_RestoreInterrupts(enabled);
1540     // Callback settings
1541     cameraWork.callback = callback;
1542     cameraWork.callbackArg = arg;
1543 
1544     // Create data
1545     data[0] = (u8)camera;
1546     data[1] = (u8)context;
1547     data[2] = (u8)flip;
1548 
1549     // Set the setting value to the I2C command saving structure for the rebooting routine
1550     cameraWork.CAMERAiStateTmp.set_camera = camera;
1551     cameraWork.CAMERAiStateTmp.set_context = context;
1552     cameraWork.CAMERAiStateTmp.flip = flip;
1553 
1554     // Send command
1555     if (CameraSendPxiCommand(command, _size, data[0]) == FALSE)
1556     {
1557         return CAMERA_RESULT_SEND_ERROR;
1558     }
1559     for (i = 1; i < _size; i+=3) {
1560         CameraSendPxiData(&data[i]);
1561     }
1562 
1563     return CAMERA_RESULT_SUCCESS;
1564 }
1565 
1566 /*---------------------------------------------------------------------------*
1567   Name:         CAMERA_I2CFlipEx
1568 
1569   Description:  Set camera flip/mirror.
1570                 SYNC version.
1571 
1572   Arguments:    camera: One of the CAMERASelect values
1573                 context: One of the CAMERAContext values (A or B)
1574                 flip: One of the CAMERAFlip values
1575 
1576   Returns:      CAMERAResult.
1577  *---------------------------------------------------------------------------*/
CAMERA_I2CFlipExCore(CAMERASelect camera,CAMERAContext context,CAMERAFlip flip)1578 CAMERAResult CAMERA_I2CFlipExCore(CAMERASelect camera, CAMERAContext context, CAMERAFlip flip)
1579 {
1580     cameraWork.result = CAMERA_I2CFlipExAsyncCore(camera, context, flip, CameraSyncCallback, 0);
1581     if (cameraWork.result == CAMERA_RESULT_SUCCESS)
1582     {
1583         CameraWaitBusy();
1584     }
1585     return cameraWork.result;
1586 }
1587 
1588 /*---------------------------------------------------------------------------*
1589   Name:         CAMERA_I2CPhotoModeAsync
1590 
1591   Description:  Set camera photo mode.
1592                 ASYNC version.
1593 
1594   Arguments:    camera: One of the CAMERASelect values
1595                 mode: One of the CAMERAPhotoMode values
1596                 callback: Specifies the function to be called when the asynchronous process is completed
1597                 arg: Specifies the argument used when calling the callback function
1598 
1599   Returns:      CAMERAResult.
1600  *---------------------------------------------------------------------------*/
CAMERA_I2CPhotoModeAsyncCore(CAMERASelect camera,CAMERAPhotoMode mode,CAMERACallback callback,void * arg)1601 CAMERAResult CAMERA_I2CPhotoModeAsyncCore(CAMERASelect camera, CAMERAPhotoMode mode, CAMERACallback callback, void *arg)
1602 {
1603     const CAMERAPxiCommand  command = CAMERA_PXI_COMMAND_PHOTO_MODE;
1604     const u8                _size   = CAMERA_PXI_SIZE_PHOTO_MODE;
1605     OSIntrMode enabled;
1606     u8  data[_size+2];
1607     int i;
1608     CAMERAResult result;
1609 
1610     SDK_NULL_ASSERT(callback);
1611 
1612     // Status check based on the retry count and whether rebooting
1613     result = CAMERA_CheckRetryCount();
1614     if(result == CAMERA_RESULT_FATAL_ERROR)
1615         return result;
1616 
1617     switch (camera)
1618     {
1619     // case CAMERA_SELECT_NONE:
1620     case CAMERA_SELECT_IN:
1621     case CAMERA_SELECT_OUT:
1622     case CAMERA_SELECT_BOTH:
1623         break;
1624     default:
1625         return CAMERA_RESULT_ILLEGAL_PARAMETER;
1626     }
1627     switch (mode)
1628     {
1629     case CAMERA_PHOTO_MODE_NORMAL:
1630     case CAMERA_PHOTO_MODE_PORTRAIT:
1631     case CAMERA_PHOTO_MODE_LANDSCAPE:
1632     case CAMERA_PHOTO_MODE_NIGHTVIEW:
1633     case CAMERA_PHOTO_MODE_LETTER:
1634         break;
1635     default:
1636         return CAMERA_RESULT_ILLEGAL_PARAMETER;
1637     }
1638 
1639     enabled = OS_DisableInterrupts();
1640     if (cameraWork.lock)
1641     {
1642         (void)OS_RestoreInterrupts(enabled);
1643         return result == CAMERA_RESULT_ILLEGAL_STATUS ? CAMERA_RESULT_ILLEGAL_STATUS : CAMERA_RESULT_BUSY;
1644     }
1645     cameraWork.lock = TRUE;
1646     (void)OS_RestoreInterrupts(enabled);
1647     // Callback settings
1648     cameraWork.callback = callback;
1649     cameraWork.callbackArg = arg;
1650 
1651     // Create data
1652     data[0] = (u8)camera;
1653     data[1] = (u8)mode;
1654 
1655     // Set the setting value to the I2C command saving structure for the rebooting routine
1656     // It is necessary to remember three parameters changed simultaneously for PhotoMode
1657     cameraWork.CAMERAiStateTmp.set_camera = camera;
1658     cameraWork.CAMERAiStateTmp.photo = mode;
1659 
1660     // Send command
1661     if (CameraSendPxiCommand(command, _size, data[0]) == FALSE)
1662     {
1663         return CAMERA_RESULT_SEND_ERROR;
1664     }
1665     for (i = 1; i < _size; i+=3) {
1666         CameraSendPxiData(&data[i]);
1667     }
1668 
1669     return CAMERA_RESULT_SUCCESS;
1670 }
1671 
1672 /*---------------------------------------------------------------------------*
1673   Name:         CAMERA_I2CPhotoMode
1674 
1675   Description:  Set camera photo mode.
1676                 SYNC version.
1677 
1678   Arguments:    camera: One of the CAMERASelect values
1679                 mode: One of the CAMERAPhotoMode values
1680 
1681   Returns:      CAMERAResult.
1682  *---------------------------------------------------------------------------*/
CAMERA_I2CPhotoModeCore(CAMERASelect camera,CAMERAPhotoMode mode)1683 CAMERAResult CAMERA_I2CPhotoModeCore(CAMERASelect camera, CAMERAPhotoMode mode)
1684 {
1685     cameraWork.result = CAMERA_I2CPhotoModeAsyncCore(camera, mode, CameraSyncCallback, 0);
1686     if (cameraWork.result == CAMERA_RESULT_SUCCESS)
1687     {
1688         CameraWaitBusy();
1689     }
1690     return cameraWork.result;
1691 }
1692 
1693 /*---------------------------------------------------------------------------*
1694   Name:         CAMERA_I2CWhiteBalanceAsync
1695 
1696   Description:  Set camera white balance.
1697                 ASYNC version.
1698 
1699   Arguments:    camera: One of the CAMERASelect values
1700                 wb: One of the CAMERAWhiteBalance values
1701                 callback: Specifies the function to be called when the asynchronous process is completed
1702                 arg: Specifies the argument used when calling the callback function
1703 
1704   Returns:      CAMERAResult.
1705  *---------------------------------------------------------------------------*/
CAMERA_I2CWhiteBalanceAsyncCore(CAMERASelect camera,CAMERAWhiteBalance wb,CAMERACallback callback,void * arg)1706 CAMERAResult CAMERA_I2CWhiteBalanceAsyncCore(CAMERASelect camera, CAMERAWhiteBalance wb, CAMERACallback callback, void *arg)
1707 {
1708     const CAMERAPxiCommand  command = CAMERA_PXI_COMMAND_WHITE_BALANCE;
1709     const u8                _size   = CAMERA_PXI_SIZE_WHITE_BALANCE;
1710     OSIntrMode enabled;
1711     u8  data[_size+2];
1712     int i;
1713     CAMERAResult result;
1714 
1715     SDK_NULL_ASSERT(callback);
1716 
1717     // Status check based on the retry count and whether rebooting or not
1718     result = CAMERA_CheckRetryCount();
1719     if(result == CAMERA_RESULT_FATAL_ERROR)
1720         return result;
1721 
1722     switch (camera)
1723     {
1724     // case CAMERA_SELECT_NONE:
1725     case CAMERA_SELECT_IN:
1726     case CAMERA_SELECT_OUT:
1727     case CAMERA_SELECT_BOTH:
1728         break;
1729     default:
1730         return CAMERA_RESULT_ILLEGAL_PARAMETER;
1731     }
1732     switch (wb)
1733     {
1734     case CAMERA_WHITE_BALANCE_AUTO:
1735     case CAMERA_WHITE_BALANCE_3200K:
1736     case CAMERA_WHITE_BALANCE_4150K:
1737     case CAMERA_WHITE_BALANCE_5200K:
1738     case CAMERA_WHITE_BALANCE_6000K:
1739     case CAMERA_WHITE_BALANCE_7000K:
1740         break;
1741     default:
1742         return CAMERA_RESULT_ILLEGAL_PARAMETER;
1743     }
1744 
1745     enabled = OS_DisableInterrupts();
1746     if (cameraWork.lock)
1747     {
1748         (void)OS_RestoreInterrupts(enabled);
1749         return result == CAMERA_RESULT_ILLEGAL_STATUS ? CAMERA_RESULT_ILLEGAL_STATUS : CAMERA_RESULT_BUSY;
1750     }
1751     cameraWork.lock = TRUE;
1752     (void)OS_RestoreInterrupts(enabled);
1753     // Callback settings
1754     cameraWork.callback = callback;
1755     cameraWork.callbackArg = arg;
1756 
1757     // Create data
1758     data[0] = (u8)camera;
1759     data[1] = (u8)wb;
1760 
1761     // Set the setting value to the I2C command saving structure for the rebooting routine
1762     cameraWork.CAMERAiStateTmp.set_camera = camera;
1763     cameraWork.CAMERAiStateTmp.wb = wb;
1764 
1765     // Send command
1766     if (CameraSendPxiCommand(command, _size, data[0]) == FALSE)
1767     {
1768         return CAMERA_RESULT_SEND_ERROR;
1769     }
1770     for (i = 1; i < _size; i+=3) {
1771         CameraSendPxiData(&data[i]);
1772     }
1773 
1774     return CAMERA_RESULT_SUCCESS;
1775 }
1776 
1777 /*---------------------------------------------------------------------------*
1778   Name:         CAMERA_I2CWhiteBalance
1779 
1780   Description:  Set camera white balance.
1781                 SYNC version.
1782 
1783   Arguments:    camera: One of the CAMERASelect values
1784                 wb: One of the CAMERAWhiteBalance values
1785 
1786   Returns:      CAMERAResult.
1787  *---------------------------------------------------------------------------*/
CAMERA_I2CWhiteBalanceCore(CAMERASelect camera,CAMERAWhiteBalance wb)1788 CAMERAResult CAMERA_I2CWhiteBalanceCore(CAMERASelect camera, CAMERAWhiteBalance wb)
1789 {
1790     cameraWork.result = CAMERA_I2CWhiteBalanceAsyncCore(camera, wb, CameraSyncCallback, 0);
1791     if (cameraWork.result == CAMERA_RESULT_SUCCESS)
1792     {
1793         CameraWaitBusy();
1794     }
1795     return cameraWork.result;
1796 }
1797 
1798 /*---------------------------------------------------------------------------*
1799   Name:         CAMERA_I2CExposureAsync
1800 
1801   Description:  Set camera exposure.
1802                 ASYNC version.
1803 
1804   Arguments:    camera: One of the CAMERASelect values
1805                 exposure: -5 to +5
1806                 callback: Specifies the function to be called when the asynchronous process is completed
1807                 arg: Specifies the argument used when calling the callback function
1808 
1809   Returns:      CAMERAResult.
1810  *---------------------------------------------------------------------------*/
CAMERA_I2CExposureAsyncCore(CAMERASelect camera,int exposure,CAMERACallback callback,void * arg)1811 CAMERAResult CAMERA_I2CExposureAsyncCore(CAMERASelect camera, int exposure, CAMERACallback callback, void *arg)
1812 {
1813     const CAMERAPxiCommand  command = CAMERA_PXI_COMMAND_EXPOSURE;
1814     const u8                _size   = CAMERA_PXI_SIZE_EXPOSURE;
1815     OSIntrMode enabled;
1816     u8  data[_size+2];
1817     int i;
1818     CAMERAResult result;
1819 
1820     SDK_NULL_ASSERT(callback);
1821 
1822     // Status check based on the retry count and whether rebooting
1823     result = CAMERA_CheckRetryCount();
1824     if(result == CAMERA_RESULT_FATAL_ERROR)
1825         return result;
1826 
1827     switch (camera)
1828     {
1829     // case CAMERA_SELECT_NONE:
1830     case CAMERA_SELECT_IN:
1831     case CAMERA_SELECT_OUT:
1832     case CAMERA_SELECT_BOTH:
1833         break;
1834     default:
1835         return CAMERA_RESULT_ILLEGAL_PARAMETER;
1836     }
1837     if (exposure < -5 || exposure > 5)
1838     {
1839         return CAMERA_RESULT_ILLEGAL_PARAMETER;
1840     }
1841 
1842     enabled = OS_DisableInterrupts();
1843     if (cameraWork.lock)
1844     {
1845         (void)OS_RestoreInterrupts(enabled);
1846         return result == CAMERA_RESULT_ILLEGAL_STATUS ? CAMERA_RESULT_ILLEGAL_STATUS : CAMERA_RESULT_BUSY;
1847     }
1848     cameraWork.lock = TRUE;
1849     (void)OS_RestoreInterrupts(enabled);
1850     // Callback settings
1851     cameraWork.callback = callback;
1852     cameraWork.callbackArg = arg;
1853 
1854     // Create data
1855     data[0] = (u8)camera;
1856     data[1] = (u8)exposure;
1857 
1858     // Set the setting value to the I2C command saving structure for the rebooting routine
1859     cameraWork.CAMERAiStateTmp.set_camera = camera;
1860     cameraWork.CAMERAiStateTmp.exposure = exposure;
1861 
1862     // Send command
1863     if (CameraSendPxiCommand(command, _size, data[0]) == FALSE)
1864     {
1865         return CAMERA_RESULT_SEND_ERROR;
1866     }
1867     for (i = 1; i < _size; i+=3) {
1868         CameraSendPxiData(&data[i]);
1869     }
1870 
1871     return CAMERA_RESULT_SUCCESS;
1872 }
1873 
1874 /*---------------------------------------------------------------------------*
1875   Name:         CAMERA_I2CExposure
1876 
1877   Description:  Set camera exposure.
1878                 SYNC version.
1879 
1880   Arguments:    camera: One of the CAMERASelect values
1881                 exposure: -5 to +5
1882   Returns:      CAMERAResult.
1883  *---------------------------------------------------------------------------*/
CAMERA_I2CExposureCore(CAMERASelect camera,int exposure)1884 CAMERAResult CAMERA_I2CExposureCore(CAMERASelect camera, int exposure)
1885 {
1886     cameraWork.result = CAMERA_I2CExposureAsyncCore(camera, exposure, CameraSyncCallback, 0);
1887     if (cameraWork.result == CAMERA_RESULT_SUCCESS)
1888     {
1889         CameraWaitBusy();
1890     }
1891     return cameraWork.result;
1892 }
1893 
1894 /*---------------------------------------------------------------------------*
1895   Name:         CAMERA_I2CSharpnessAsync
1896 
1897   Description:  Set camera sharpness.
1898                 ASYNC version.
1899 
1900   Arguments:    camera: One of the CAMERASelect values
1901                 sharpness: -3 to +5
1902                 callback: Specifies the function to be called when the asynchronous process is completed
1903                 arg: Specifies the argument used when calling the callback function
1904 
1905   Returns:      CAMERAResult
1906  *---------------------------------------------------------------------------*/
CAMERA_I2CSharpnessAsyncCore(CAMERASelect camera,int sharpness,CAMERACallback callback,void * arg)1907 CAMERAResult CAMERA_I2CSharpnessAsyncCore(CAMERASelect camera, int sharpness, CAMERACallback callback, void *arg)
1908 {
1909     const CAMERAPxiCommand  command = CAMERA_PXI_COMMAND_SHARPNESS;
1910     const u8                _size   = CAMERA_PXI_SIZE_SHARPNESS;
1911     OSIntrMode enabled;
1912     u8  data[_size+2];
1913     int i;
1914     CAMERAResult result;
1915 
1916     SDK_NULL_ASSERT(callback);
1917 
1918     // Status check based on the retry count and whether rebooting
1919     result = CAMERA_CheckRetryCount();
1920     if(result == CAMERA_RESULT_FATAL_ERROR)
1921         return result;
1922 
1923     switch (camera)
1924     {
1925     // case CAMERA_SELECT_NONE:
1926     case CAMERA_SELECT_IN:
1927     case CAMERA_SELECT_OUT:
1928     case CAMERA_SELECT_BOTH:
1929         break;
1930     default:
1931         return CAMERA_RESULT_ILLEGAL_PARAMETER;
1932     }
1933     if (sharpness < -3 || sharpness > 5)
1934     {
1935         return CAMERA_RESULT_ILLEGAL_PARAMETER;
1936     }
1937 
1938     enabled = OS_DisableInterrupts();
1939     if (cameraWork.lock)
1940     {
1941         (void)OS_RestoreInterrupts(enabled);
1942         return result == CAMERA_RESULT_ILLEGAL_STATUS ? CAMERA_RESULT_ILLEGAL_STATUS : CAMERA_RESULT_BUSY;
1943     }
1944     cameraWork.lock = TRUE;
1945     (void)OS_RestoreInterrupts(enabled);
1946     // Callback settings
1947     cameraWork.callback = callback;
1948     cameraWork.callbackArg = arg;
1949 
1950     // Create data
1951     data[0] = (u8)camera;
1952     data[1] = (u8)sharpness;
1953 
1954     // Set the setting value to the I2C command saving structure for the rebooting routine
1955     cameraWork.CAMERAiStateTmp.set_camera = camera;
1956     cameraWork.CAMERAiStateTmp.sharpness = sharpness;
1957 
1958     // Send command
1959     if (CameraSendPxiCommand(command, _size, data[0]) == FALSE)
1960     {
1961         return CAMERA_RESULT_SEND_ERROR;
1962     }
1963     for (i = 1; i < _size; i+=3) {
1964         CameraSendPxiData(&data[i]);
1965     }
1966 
1967     return CAMERA_RESULT_SUCCESS;
1968 }
1969 
1970 /*---------------------------------------------------------------------------*
1971   Name:         CAMERA_I2CSharpness
1972 
1973   Description:  Set camera sharpness.
1974                 SYNC version.
1975 
1976   Arguments:    camera: One of the CAMERASelect values
1977                 sharpness: -3 to +5
1978   Returns:      CAMERAResult.
1979  *---------------------------------------------------------------------------*/
CAMERA_I2CSharpnessCore(CAMERASelect camera,int sharpness)1980 CAMERAResult CAMERA_I2CSharpnessCore(CAMERASelect camera, int sharpness)
1981 {
1982     cameraWork.result = CAMERA_I2CSharpnessAsyncCore(camera, sharpness, CameraSyncCallback, 0);
1983     if (cameraWork.result == CAMERA_RESULT_SUCCESS)
1984     {
1985         CameraWaitBusy();
1986     }
1987     return cameraWork.result;
1988 }
1989 
1990 /*---------------------------------------------------------------------------*
1991   Name:         CAMERAi_I2CTestPatternAsync
1992 
1993   Description:  Set camera test pattern.
1994                 ASYNC version.
1995 
1996   Arguments:    camera: One of the CAMERASelect values
1997                 pattern: One of the CAMERATestPattern values
1998                 callback: Specifies the function to be called when the asynchronous process is completed.
1999                 arg: Specifies the argument used when calling the callback function
2000 
2001   Returns:      CAMERAResult.
2002  *---------------------------------------------------------------------------*/
CAMERAi_I2CTestPatternAsyncCore(CAMERASelect camera,CAMERATestPattern pattern,CAMERACallback callback,void * arg)2003 CAMERAResult CAMERAi_I2CTestPatternAsyncCore(CAMERASelect camera, CAMERATestPattern pattern, CAMERACallback callback, void *arg)
2004 {
2005     const CAMERAPxiCommand  command = CAMERA_PXI_COMMAND_TEST_PATTERN;
2006     const u8                _size   = CAMERA_PXI_SIZE_TEST_PATTERN;
2007     OSIntrMode enabled;
2008     u8  data[_size+2];
2009     int i;
2010     CAMERAResult result;
2011 
2012     SDK_NULL_ASSERT(callback);
2013 
2014     // Status check based on the retry count and whether rebooting or not
2015     result = CAMERA_CheckRetryCount();
2016     if(result == CAMERA_RESULT_FATAL_ERROR)
2017         return result;
2018 
2019     switch (camera)
2020     {
2021     // case CAMERA_SELECT_NONE:
2022     case CAMERA_SELECT_IN:
2023     case CAMERA_SELECT_OUT:
2024     case CAMERA_SELECT_BOTH:
2025         break;
2026     default:
2027         return CAMERA_RESULT_ILLEGAL_PARAMETER;
2028     }
2029     switch (pattern)
2030     {
2031     case CAMERA_TEST_PATTERN_DISABLED:
2032     case CAMERA_TEST_PATTERN_COLOR_BAR:
2033     case CAMERA_TEST_PATTERN_NOISE:
2034         break;
2035     default:
2036         return CAMERA_RESULT_ILLEGAL_PARAMETER;
2037     }
2038 
2039     enabled = OS_DisableInterrupts();
2040     if (cameraWork.lock)
2041     {
2042         (void)OS_RestoreInterrupts(enabled);
2043         return result == CAMERA_RESULT_ILLEGAL_STATUS ? CAMERA_RESULT_ILLEGAL_STATUS : CAMERA_RESULT_BUSY;
2044     }
2045     cameraWork.lock = TRUE;
2046     (void)OS_RestoreInterrupts(enabled);
2047     // Callback settings
2048     cameraWork.callback = callback;
2049     cameraWork.callbackArg = arg;
2050 
2051     // Create data
2052     data[0] = (u8)camera;
2053     data[1] = (u8)pattern;
2054 
2055     // Send command
2056     if (CameraSendPxiCommand(command, _size, data[0]) == FALSE)
2057     {
2058         return CAMERA_RESULT_SEND_ERROR;
2059     }
2060     for (i = 1; i < _size; i+=3) {
2061         CameraSendPxiData(&data[i]);
2062     }
2063 
2064     return CAMERA_RESULT_SUCCESS;
2065 }
2066 
2067 /*---------------------------------------------------------------------------*
2068   Name:         CAMERAi_I2CTestPattern
2069 
2070   Description:  Set camera test pattern.
2071                 SYNC version.
2072 
2073   Arguments:    camera: One of the CAMERASelect values
2074                 pattern: One of the CAMERATestPattern values
2075 
2076   Returns:      CAMERAResult.
2077  *---------------------------------------------------------------------------*/
CAMERAi_I2CTestPatternCore(CAMERASelect camera,CAMERATestPattern pattern)2078 CAMERAResult CAMERAi_I2CTestPatternCore(CAMERASelect camera, CAMERATestPattern pattern)
2079 {
2080     cameraWork.result = CAMERAi_I2CTestPatternAsyncCore(camera, pattern, CameraSyncCallback, 0);
2081     if (cameraWork.result == CAMERA_RESULT_SUCCESS)
2082     {
2083         CameraWaitBusy();
2084     }
2085     return cameraWork.result;
2086 }
2087 
2088 /*---------------------------------------------------------------------------*
2089   Name:         CAMERA_I2CAutoExposureAsync
2090 
2091   Description:  Enable/disable camera auto-exposure.
2092                 ASYNC version.
2093 
2094   Arguments:    camera: One of the CAMERASelect values
2095                 on: TRUE if AE will enable
2096                 callback: Specifies the function to be called when the asynchronous process is completed
2097                 arg: Specifies the argument used when calling the callback function
2098 
2099   Returns:      CAMERAResult.
2100  *---------------------------------------------------------------------------*/
CAMERA_I2CAutoExposureAsyncCore(CAMERASelect camera,BOOL on,CAMERACallback callback,void * arg)2101 CAMERAResult CAMERA_I2CAutoExposureAsyncCore(CAMERASelect camera, BOOL on, CAMERACallback callback, void *arg)
2102 {
2103     const CAMERAPxiCommand  command = CAMERA_PXI_COMMAND_AUTO_EXPOSURE;
2104     const u8                _size   = CAMERA_PXI_SIZE_AUTO_EXPOSURE;
2105     OSIntrMode enabled;
2106     u8  data[_size+2];
2107     int i;
2108     CAMERAResult result;
2109 
2110     SDK_NULL_ASSERT(callback);
2111 
2112     // Status check based on the retry count and whether rebooting
2113     result = CAMERA_CheckRetryCount();
2114     if(result == CAMERA_RESULT_FATAL_ERROR)
2115         return result;
2116 
2117     switch (camera)
2118     {
2119     // case CAMERA_SELECT_NONE:
2120     case CAMERA_SELECT_IN:
2121     case CAMERA_SELECT_OUT:
2122     case CAMERA_SELECT_BOTH:
2123         break;
2124     default:
2125         return CAMERA_RESULT_ILLEGAL_PARAMETER;
2126     }
2127 
2128     enabled = OS_DisableInterrupts();
2129     if (cameraWork.lock)
2130     {
2131         (void)OS_RestoreInterrupts(enabled);
2132         return result == CAMERA_RESULT_ILLEGAL_STATUS ? CAMERA_RESULT_ILLEGAL_STATUS : CAMERA_RESULT_BUSY;
2133     }
2134     cameraWork.lock = TRUE;
2135     (void)OS_RestoreInterrupts(enabled);
2136     // Callback settings
2137     cameraWork.callback = callback;
2138     cameraWork.callbackArg = arg;
2139 
2140     // Create data
2141     data[0] = (u8)camera;
2142     data[1] = (u8)(on ? TRUE : FALSE);
2143 
2144     // Set the setting value to the I2C command saving structure for the rebooting routine
2145     cameraWork.CAMERAiStateTmp.set_camera = camera;
2146     cameraWork.CAMERAiStateTmp.ae = on;
2147 
2148     // Send command
2149     if (CameraSendPxiCommand(command, _size, data[0]) == FALSE)
2150     {
2151         return CAMERA_RESULT_SEND_ERROR;
2152     }
2153     for (i = 1; i < _size; i+=3) {
2154         CameraSendPxiData(&data[i]);
2155     }
2156 
2157     return CAMERA_RESULT_SUCCESS;
2158 }
2159 
2160 /*---------------------------------------------------------------------------*
2161   Name:         CAMERA_I2CAutoExposure
2162 
2163   Description:  Enable/disable camera auto-exposure.
2164                 SYNC version.
2165 
2166   Arguments:    camera: One of the CAMERASelect values
2167                 on: TRUE if AE will enable
2168   Returns:      CAMERAResult.
2169  *---------------------------------------------------------------------------*/
CAMERA_I2CAutoExposureCore(CAMERASelect camera,BOOL on)2170 CAMERAResult CAMERA_I2CAutoExposureCore(CAMERASelect camera, BOOL on)
2171 {
2172     cameraWork.result = CAMERA_I2CAutoExposureAsyncCore(camera, on, CameraSyncCallback, 0);
2173     if (cameraWork.result == CAMERA_RESULT_SUCCESS)
2174     {
2175         CameraWaitBusy();
2176     }
2177     return cameraWork.result;
2178 }
2179 
2180 /*---------------------------------------------------------------------------*
2181   Name:         CAMERA_I2CAutoWhiteBalanceAsync
2182 
2183   Description:  Enable/disable camera auto-white-balance.
2184                 ASYNC version.
2185 
2186   Arguments:    camera: One of the CAMERASelect values
2187                 on: TRUE if AWB will enable
2188                 callback: Specifies the function to be called when the asynchronous process is completed
2189                 arg: Specifies the argument used when calling the callback function
2190 
2191   Returns:      CAMERAResult.
2192  *---------------------------------------------------------------------------*/
CAMERA_I2CAutoWhiteBalanceAsyncCore(CAMERASelect camera,BOOL on,CAMERACallback callback,void * arg)2193 CAMERAResult CAMERA_I2CAutoWhiteBalanceAsyncCore(CAMERASelect camera, BOOL on, CAMERACallback callback, void *arg)
2194 {
2195     const CAMERAPxiCommand  command = CAMERA_PXI_COMMAND_AUTO_WHITE_BALANCE;
2196     const u8                _size   = CAMERA_PXI_SIZE_AUTO_WHITE_BALANCE;
2197     OSIntrMode enabled;
2198     u8  data[_size+2];
2199     int i;
2200     CAMERAResult result;
2201 
2202     SDK_NULL_ASSERT(callback);
2203 
2204     // Status check based on the retry count and whether rebooting
2205     result = CAMERA_CheckRetryCount();
2206     if(result == CAMERA_RESULT_FATAL_ERROR)
2207         return result;
2208 
2209     switch (camera)
2210     {
2211     // case CAMERA_SELECT_NONE:
2212     case CAMERA_SELECT_IN:
2213     case CAMERA_SELECT_OUT:
2214     case CAMERA_SELECT_BOTH:
2215         break;
2216     default:
2217         return CAMERA_RESULT_ILLEGAL_PARAMETER;
2218     }
2219 
2220     if ((camera & CAMERA_SELECT_IN) && cameraWork.CAMERAiStateIn.wb != CAMERA_WHITE_BALANCE_NORMAL)
2221     {
2222         return CAMERA_RESULT_INVALID_COMMAND;
2223     }
2224     if ((camera & CAMERA_SELECT_OUT) && cameraWork.CAMERAiStateOut.wb != CAMERA_WHITE_BALANCE_NORMAL)
2225     {
2226         return CAMERA_RESULT_INVALID_COMMAND;
2227     }
2228 
2229     enabled = OS_DisableInterrupts();
2230     if (cameraWork.lock)
2231     {
2232         (void)OS_RestoreInterrupts(enabled);
2233         return result == CAMERA_RESULT_ILLEGAL_STATUS ? CAMERA_RESULT_ILLEGAL_STATUS : CAMERA_RESULT_BUSY;
2234     }
2235     cameraWork.lock = TRUE;
2236     (void)OS_RestoreInterrupts(enabled);
2237     // Callback settings
2238     cameraWork.callback = callback;
2239     cameraWork.callbackArg = arg;
2240 
2241     // Create data
2242     data[0] = (u8)camera;
2243     data[1] = (u8)(on ? TRUE : FALSE);
2244 
2245     // Set the setting value to the I2C command saving structure for the rebooting routine
2246     cameraWork.CAMERAiStateTmp.set_camera = camera;
2247     cameraWork.CAMERAiStateTmp.awb = on;
2248 
2249     // Send command
2250     if (CameraSendPxiCommand(command, _size, data[0]) == FALSE)
2251     {
2252         return CAMERA_RESULT_SEND_ERROR;
2253     }
2254     for (i = 1; i < _size; i+=3) {
2255         CameraSendPxiData(&data[i]);
2256     }
2257 
2258     return CAMERA_RESULT_SUCCESS;
2259 }
2260 
2261 /*---------------------------------------------------------------------------*
2262   Name:         CAMERA_I2CAutoWhiteBalance
2263 
2264   Description:  Enable/disable camera auto-white-balance.
2265                 SYNC version.
2266 
2267   Arguments:    camera: One of the CAMERASelect values
2268                 on: TRUE if AE will enable
2269   Returns:      CAMERAResult.
2270  *---------------------------------------------------------------------------*/
CAMERA_I2CAutoWhiteBalanceCore(CAMERASelect camera,BOOL on)2271 CAMERAResult CAMERA_I2CAutoWhiteBalanceCore(CAMERASelect camera, BOOL on)
2272 {
2273     cameraWork.result = CAMERA_I2CAutoWhiteBalanceAsyncCore(camera, on, CameraSyncCallback, 0);
2274     if (cameraWork.result == CAMERA_RESULT_SUCCESS)
2275     {
2276         CameraWaitBusy();
2277     }
2278     return cameraWork.result;
2279 }
2280 
2281 /*---------------------------------------------------------------------------*
2282   Name:         CAMERA_SetLEDAsync
2283 
2284   Description:  Set camera LED (outside) to blink or not.
2285                 It works only when the OUT camera is active.
2286                 The default state when calling I2CActivate(OUT/BOTH) does not blink.
2287                 ASYNC version.
2288 
2289   Arguments:    isBlink: TRUE to flash; FALSE to light
2290                 callback: Specifies the function to be called when the asynchronous process is completed
2291                 arg: Specifies the argument used when calling the callback function
2292 
2293   Returns:      CAMERAResult.
2294  *---------------------------------------------------------------------------*/
CAMERA_SetLEDAsyncCore(BOOL isBlink,CAMERACallback callback,void * arg)2295 CAMERAResult CAMERA_SetLEDAsyncCore(BOOL isBlink, CAMERACallback callback, void *arg)
2296 {
2297     const CAMERAPxiCommand  command = CAMERA_PXI_COMMAND_SET_LED;
2298     const u8                _size   = CAMERA_PXI_SIZE_SET_LED;
2299     OSIntrMode enabled;
2300 
2301     SDK_NULL_ASSERT(callback);
2302 
2303     enabled = OS_DisableInterrupts();
2304     if (cameraWork.lock)
2305     {
2306         (void)OS_RestoreInterrupts(enabled);
2307         return CAMERA_RESULT_BUSY;
2308     }
2309     cameraWork.lock = TRUE;
2310     (void)OS_RestoreInterrupts(enabled);
2311     // Callback settings
2312     cameraWork.callback = callback;
2313     cameraWork.callbackArg = arg;
2314 
2315     // Set the setting value to the structure for the rebooting routine
2316     cameraWork.CAMERAiStateTmp.blink = isBlink;
2317 
2318     return CameraSendPxiCommand(command, _size, (u8)isBlink) ? CAMERA_RESULT_SUCCESS : CAMERA_RESULT_SEND_ERROR;
2319 }
2320 
2321 /*---------------------------------------------------------------------------*
2322   Name:         CAMERA_SetLED
2323 
2324   Description:  Set camera LED (outside) to blink or not.
2325                 It works only when the OUT camera is active.
2326                 The default state when calling I2CActivate(OUT/BOTH) does not blink.
2327                 SYNC version.
2328 
2329   Arguments:    isBlink: TRUE to flash; FALSE to light
2330 
2331   Returns:      CAMERAResult.
2332  *---------------------------------------------------------------------------*/
CAMERA_SetLEDCore(BOOL isBlink)2333 CAMERAResult CAMERA_SetLEDCore(BOOL isBlink)
2334 {
2335     cameraWork.result = CAMERA_SetLEDAsyncCore(isBlink, CameraSyncCallback, 0);
2336     if (cameraWork.result == CAMERA_RESULT_SUCCESS)
2337     {
2338         CameraWaitBusy();
2339     }
2340     return cameraWork.result;
2341 }
2342 
2343 static CAMERACallback cameraSwitchOffLEDCallback;
2344 
CAMERAi_SwitchOffLEDAsyncCallback(CAMERAResult result,void * arg)2345 static void CAMERAi_SwitchOffLEDAsyncCallback(CAMERAResult result, void* arg)
2346 {
2347 
2348     if(result != CAMERA_RESULT_SUCCESS)
2349         cameraSwitchOffLEDCallback(result, arg);
2350 
2351     (void)CAMERA_SetLEDAsyncCore(FALSE, cameraSwitchOffLEDCallback, arg);
2352 }
2353 
2354 /*---------------------------------------------------------------------------*
2355   Name:         CAMERA_SwitchOffLEDAsync
2356 
2357   Description:  Turn off the camera LED only one time.
2358                 The operation is the same as when continuously calling CAMERA_SetLED(TRUE), CAMERA_SetLED(FALSE).
2359 
2360 
2361   Arguments:    callback: Specifies the function to be called when the asynchronous process is completed
2362                 arg: Specifies the argument used when calling the callback function
2363 
2364   Returns:      CAMERAResult.
2365  *---------------------------------------------------------------------------*/
CAMERA_SwitchOffLEDAsyncCore(CAMERACallback callback,void * arg)2366 CAMERAResult CAMERA_SwitchOffLEDAsyncCore(CAMERACallback callback, void *arg)
2367 {
2368     cameraSwitchOffLEDCallback = callback;
2369 
2370     return CAMERA_SetLEDAsyncCore(TRUE, CAMERAi_SwitchOffLEDAsyncCallback, arg);
2371 }
2372 
2373 /*---------------------------------------------------------------------------*
2374   Name:         CAMERA_SwitchOffLED
2375 
2376   Description:  Turn off the camera LED only one time.
2377                 The operation is the same as when continuously calling CAMERA_SetLED(TRUE), CAMERA_SetLED(FALSE).
2378 
2379 
2380   Arguments:    None.
2381 
2382   Returns:      CAMERAResult.
2383  *---------------------------------------------------------------------------*/
CAMERA_SwitchOffLEDCore(void)2384 CAMERAResult CAMERA_SwitchOffLEDCore(void)
2385 {
2386     CAMERAResult result;
2387 
2388     result = CAMERA_SetLEDCore(TRUE);
2389     if(result != CAMERA_RESULT_SUCCESS)
2390         return result;
2391     return CAMERA_SetLEDCore(FALSE);
2392 }
2393 
CAMERAi_Wait(u32 clocks)2394 static inline void CAMERAi_Wait(u32 clocks)
2395 {
2396     OS_SpinWaitSysCycles(clocks << 1);
2397 }
CAMERAi_StopMasterClock(void)2398 static inline BOOL CAMERAi_StopMasterClock(void)
2399 {
2400     OSIntrMode enabled = OS_DisableInterrupts();
2401     u16  reg = reg_SCFG_CLK;
2402     reg_SCFG_CLK = (u16)(reg & ~REG_SCFG_CLK_CAMCKI_MASK);
2403     (void)OS_RestoreInterrupts(enabled);
2404     return (BOOL)((reg & REG_SCFG_CLK_CAMCKI_MASK) >> REG_SCFG_CLK_CAMCKI_SHIFT);
2405 }
CAMERAi_StartMasterClock(void)2406 static inline BOOL CAMERAi_StartMasterClock(void)
2407 {
2408     OSIntrMode enabled = OS_DisableInterrupts();
2409     u16  reg = reg_SCFG_CLK;
2410     reg_SCFG_CLK = (u16)(reg | REG_SCFG_CLK_CAMCKI_MASK);
2411     (void)OS_RestoreInterrupts(enabled);
2412     if ( (reg & REG_SCFG_CLK_CAMCKI_MASK) == 0 )
2413     {
2414         CAMERAi_Wait( 10 );
2415     }
2416     return (BOOL)((reg & REG_SCFG_CLK_CAMCKI_MASK) >> REG_SCFG_CLK_CAMCKI_SHIFT);
2417 }
2418 
2419 /*---------------------------------------------------------------------------*
2420   Name:         CameraSendPxiCommand
2421 
2422   Description:  Send specified leading command to ARM7 via PXI.
2423 
2424   Arguments:    command: Targeted command
2425                 size: Send data size (in bytes)
2426                 data: Leading data (only 1 byte)
2427 
2428   Returns:      BOOL: Returns TRUE if a send for PXI completed, and FALSE if send by PXI failed.
2429 
2430  *---------------------------------------------------------------------------*/
CameraSendPxiCommand(CAMERAPxiCommand command,u8 size,u8 data)2431 static BOOL CameraSendPxiCommand(CAMERAPxiCommand command, u8 size, u8 data)
2432 {
2433     u32 pxiData = (u32)(CAMERA_PXI_START_BIT |
2434             ((command << CAMERA_PXI_COMMAND_SHIFT) & CAMERA_PXI_COMMAND_MASK) |
2435             ((size << CAMERA_PXI_DATA_NUMS_SHIFT) & CAMERA_PXI_DATA_NUMS_MASK) |
2436             ((data << CAMERA_PXI_1ST_DATA_SHIFT) & CAMERA_PXI_1ST_DATA_MASK));
2437     cameraWork.last_state = CAMERAi_StartMasterClock();
2438     if (0 > PXI_SendWordByFifo(PXI_FIFO_TAG_CAMERA, pxiData, 0))
2439     {
2440         if ( cameraWork.last_state == FALSE )
2441         {
2442             (void)CAMERAi_StopMasterClock();
2443         }
2444         return FALSE;
2445     }
2446     return TRUE;
2447 }
2448 
2449 /*---------------------------------------------------------------------------*
2450   Name:         CameraSendPxiData
2451 
2452   Description:  Send specified subsequent data to ARM7 via PXI.
2453 
2454   Arguments:    pData: Pointer to top of 3-byte data
2455 
2456   Returns:      None.
2457  *---------------------------------------------------------------------------*/
CameraSendPxiData(u8 * pData)2458 static void CameraSendPxiData(u8 *pData)
2459 {
2460     u32 pxiData = (u32)((pData[0] << 16) | (pData[1] << 8) | pData[2]);
2461     while (0 > PXI_SendWordByFifo(PXI_FIFO_TAG_CAMERA, pxiData, 0))
2462     {
2463     }
2464 }
2465 
2466 /*---------------------------------------------------------------------------*
2467   Name:         CameraPxiCallback
2468 
2469   Description:  Common callback function for asynchronous RTC functions.
2470 
2471   Arguments:    tag: PXI tag that shows the message type
2472                 data: Message from ARM7
2473                 err: PXI transfer error flag
2474 
2475   Returns:      None.
2476  *---------------------------------------------------------------------------*/
CameraPxiCallback(PXIFifoTag tag,u32 data,BOOL err)2477 static void CameraPxiCallback(PXIFifoTag tag, u32 data, BOOL err)
2478 {
2479 #pragma unused( tag )
2480     CAMERAResult   result;
2481 
2482     // Verify PXI communication error
2483     if (err)
2484     {
2485         // Forcibly end sequence
2486         CameraCallCallbackAndUnlock(CAMERA_RESULT_FATAL_ERROR);
2487         return;
2488     }
2489     // Leading data
2490     if (data & CAMERA_PXI_START_BIT)
2491     {
2492         // Analyze received data
2493         SDK_ASSERT((data & CAMERA_PXI_RESULT_BIT) == CAMERA_PXI_RESULT_BIT);
2494         cameraWork.total = (u8)((data & CAMERA_PXI_DATA_NUMS_MASK) >> CAMERA_PXI_DATA_NUMS_SHIFT);
2495         cameraWork.current = 0;
2496         cameraWork.command = (CAMERAPxiCommand)((data & CAMERA_PXI_COMMAND_MASK) >> CAMERA_PXI_COMMAND_SHIFT);
2497         cameraWork.pxiResult = (CAMERAPxiResult)((data & CAMERA_PXI_1ST_DATA_MASK) >> CAMERA_PXI_1ST_DATA_SHIFT);
2498     }
2499     // Subsequent data
2500     else
2501     {
2502         if (cameraWork.data == NULL)
2503         {
2504             // Forcibly end sequence
2505             CameraCallCallbackAndUnlock(CAMERA_RESULT_FATAL_ERROR);
2506             return;
2507         }
2508         if (cameraWork.current < cameraWork.size)
2509         {
2510             cameraWork.data[cameraWork.current++] = (u8)((data & 0xFF0000) >> 16);
2511         }
2512         if (cameraWork.current < cameraWork.size)
2513         {
2514             cameraWork.data[cameraWork.current++] = (u8)((data & 0x00FF00) >> 8);
2515         }
2516         if (cameraWork.current < cameraWork.size)
2517         {
2518             cameraWork.data[cameraWork.current++] = (u8)((data & 0x0000FF) >> 0);
2519         }
2520     }
2521 
2522     if (cameraWork.current >= cameraWork.total-1)   // There should be no >
2523     {
2524         if (cameraWork.force_deactivate != FALSE || (cameraWork.force_activate == FALSE && cameraWork.last_state == FALSE))
2525         {
2526             (void)CAMERAi_StopMasterClock();
2527         }
2528         cameraWork.force_deactivate = cameraWork.force_activate = FALSE;
2529 
2530         // Check the result of processing
2531         switch (cameraWork.pxiResult)
2532         {
2533         case CAMERA_PXI_RESULT_SUCCESS:     // alias CAMERA_PXI_RESULT_SUCCESS_TRUE
2534             result = CAMERA_RESULT_SUCCESS; // alias CAMERA_RESULT_SUCCESS_TRUE
2535             // Processing was successful, so apply the changes to the structure for rebooting
2536             switch (cameraWork.command)
2537             {
2538             case CAMERA_PXI_COMMAND_ACTIVATE:
2539                 cameraWork.CAMERAiStateOut.blink = cameraWork.CAMERAiStateTmp.blink;
2540                 break;
2541             case CAMERA_PXI_COMMAND_CONTEXT_SWITCH:
2542                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_IN)
2543                     cameraWork.CAMERAiStateIn.context = cameraWork.CAMERAiStateTmp.context;
2544                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_OUT)
2545                     cameraWork.CAMERAiStateOut.context = cameraWork.CAMERAiStateTmp.context;
2546                 break;
2547             case CAMERA_PXI_COMMAND_SIZE:
2548                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_IN)
2549                     if(cameraWork.CAMERAiStateTmp.set_context & CAMERA_CONTEXT_A)
2550                         cameraWork.CAMERAiStateIn.size_A = cameraWork.CAMERAiStateTmp.size;
2551                     if(cameraWork.CAMERAiStateTmp.set_context & CAMERA_CONTEXT_B)
2552                         cameraWork.CAMERAiStateIn.size_B = cameraWork.CAMERAiStateTmp.size;
2553                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_OUT)
2554                     if(cameraWork.CAMERAiStateTmp.set_context & CAMERA_CONTEXT_A)
2555                         cameraWork.CAMERAiStateOut.size_A = cameraWork.CAMERAiStateTmp.size;
2556                     if(cameraWork.CAMERAiStateTmp.set_context & CAMERA_CONTEXT_B)
2557                         cameraWork.CAMERAiStateOut.size_B = cameraWork.CAMERAiStateTmp.size;
2558                 break;
2559             case CAMERA_PXI_COMMAND_FRAME_RATE:
2560                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_IN)
2561                     cameraWork.CAMERAiStateIn.rate = cameraWork.CAMERAiStateTmp.rate;
2562                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_OUT)
2563                     cameraWork.CAMERAiStateOut.rate = cameraWork.CAMERAiStateTmp.rate;
2564                 break;
2565             case CAMERA_PXI_COMMAND_EFFECT:
2566                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_IN)
2567                     if(cameraWork.CAMERAiStateTmp.set_context & CAMERA_CONTEXT_A)
2568                         cameraWork.CAMERAiStateIn.effect_A = cameraWork.CAMERAiStateTmp.effect;
2569                     if(cameraWork.CAMERAiStateTmp.set_context & CAMERA_CONTEXT_B)
2570                         cameraWork.CAMERAiStateIn.effect_B = cameraWork.CAMERAiStateTmp.effect;
2571                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_OUT)
2572                     if(cameraWork.CAMERAiStateTmp.set_context & CAMERA_CONTEXT_A)
2573                         cameraWork.CAMERAiStateOut.effect_A = cameraWork.CAMERAiStateTmp.effect;
2574                     if(cameraWork.CAMERAiStateTmp.set_context & CAMERA_CONTEXT_B)
2575                         cameraWork.CAMERAiStateOut.effect_B = cameraWork.CAMERAiStateTmp.effect;
2576                 break;
2577             case CAMERA_PXI_COMMAND_FLIP:
2578                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_IN)
2579                     if(cameraWork.CAMERAiStateTmp.set_context & CAMERA_CONTEXT_A)
2580                         cameraWork.CAMERAiStateIn.flip_A = cameraWork.CAMERAiStateTmp.flip;
2581                     if(cameraWork.CAMERAiStateTmp.set_context & CAMERA_CONTEXT_B)
2582                         cameraWork.CAMERAiStateIn.flip_B = cameraWork.CAMERAiStateTmp.flip;
2583                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_OUT)
2584                     if(cameraWork.CAMERAiStateTmp.set_context & CAMERA_CONTEXT_A)
2585                         cameraWork.CAMERAiStateOut.flip_A = cameraWork.CAMERAiStateTmp.flip;
2586                     if(cameraWork.CAMERAiStateTmp.set_context & CAMERA_CONTEXT_B)
2587                         cameraWork.CAMERAiStateOut.flip_B = cameraWork.CAMERAiStateTmp.flip;
2588                 break;
2589             case CAMERA_PXI_COMMAND_PHOTO_MODE:
2590                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_IN)
2591                 {
2592                     cameraWork.CAMERAiStateIn.photo = cameraWork.CAMERAiStateTmp.photo;
2593                     switch (cameraWork.CAMERAiStateIn.photo)
2594                     {
2595                     case CAMERA_PHOTO_MODE_NORMAL:
2596                         cameraWork.CAMERAiStateIn.sharpness = 0;
2597                         cameraWork.CAMERAiStateIn.exposure = 0;
2598                         cameraWork.CAMERAiStateIn.wb = CAMERA_WHITE_BALANCE_NORMAL;
2599                         break;
2600                     case CAMERA_PHOTO_MODE_PORTRAIT:
2601                         cameraWork.CAMERAiStateIn.sharpness = -2;
2602                         cameraWork.CAMERAiStateIn.exposure = 0;
2603                         cameraWork.CAMERAiStateIn.wb = CAMERA_WHITE_BALANCE_NORMAL;
2604                         break;
2605                     case CAMERA_PHOTO_MODE_LANDSCAPE:
2606                         cameraWork.CAMERAiStateIn.sharpness = 1;
2607                         cameraWork.CAMERAiStateIn.exposure = 0;
2608                         cameraWork.CAMERAiStateIn.wb = CAMERA_WHITE_BALANCE_DAYLIGHT;
2609                         break;
2610                     case CAMERA_PHOTO_MODE_NIGHTVIEW:
2611                         cameraWork.CAMERAiStateIn.sharpness = -1;
2612                         cameraWork.CAMERAiStateIn.exposure = 2;
2613                         cameraWork.CAMERAiStateIn.wb = CAMERA_WHITE_BALANCE_NORMAL;
2614                         break;
2615                     case CAMERA_PHOTO_MODE_LETTER:
2616                         cameraWork.CAMERAiStateIn.sharpness = 2;
2617                         cameraWork.CAMERAiStateIn.exposure = 2;
2618                         cameraWork.CAMERAiStateIn.wb = CAMERA_WHITE_BALANCE_NORMAL;
2619                         break;
2620                     }
2621                 }
2622                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_OUT)
2623                 {
2624                     cameraWork.CAMERAiStateOut.photo = cameraWork.CAMERAiStateTmp.photo;
2625                     switch (cameraWork.CAMERAiStateOut.photo)
2626                     {
2627                     case CAMERA_PHOTO_MODE_NORMAL:
2628                         cameraWork.CAMERAiStateOut.sharpness = 0;
2629                         cameraWork.CAMERAiStateOut.exposure = 0;
2630                         cameraWork.CAMERAiStateOut.wb = CAMERA_WHITE_BALANCE_NORMAL;
2631                         break;
2632                     case CAMERA_PHOTO_MODE_PORTRAIT:
2633                         cameraWork.CAMERAiStateOut.sharpness = -2;
2634                         cameraWork.CAMERAiStateOut.exposure = 0;
2635                         cameraWork.CAMERAiStateOut.wb = CAMERA_WHITE_BALANCE_NORMAL;
2636                         break;
2637                     case CAMERA_PHOTO_MODE_LANDSCAPE:
2638                         cameraWork.CAMERAiStateOut.sharpness = 1;
2639                         cameraWork.CAMERAiStateOut.exposure = 0;
2640                         cameraWork.CAMERAiStateOut.wb = CAMERA_WHITE_BALANCE_DAYLIGHT;
2641                         break;
2642                     case CAMERA_PHOTO_MODE_NIGHTVIEW:
2643                         cameraWork.CAMERAiStateOut.sharpness = -1;
2644                         cameraWork.CAMERAiStateOut.exposure = 2;
2645                         cameraWork.CAMERAiStateOut.wb = CAMERA_WHITE_BALANCE_NORMAL;
2646                         break;
2647                     case CAMERA_PHOTO_MODE_LETTER:
2648                         cameraWork.CAMERAiStateOut.sharpness = 2;
2649                         cameraWork.CAMERAiStateOut.exposure = 2;
2650                         cameraWork.CAMERAiStateOut.wb = CAMERA_WHITE_BALANCE_NORMAL;
2651                         break;
2652                     }
2653                 }
2654                 break;
2655             case CAMERA_PXI_COMMAND_WHITE_BALANCE:
2656                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_IN)
2657                 {
2658                     cameraWork.CAMERAiStateIn.wb = cameraWork.CAMERAiStateTmp.wb;
2659                     cameraWork.CAMERAiStateIn.awb = TRUE;
2660                 }
2661                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_OUT)
2662                 {
2663                     cameraWork.CAMERAiStateOut.wb = cameraWork.CAMERAiStateTmp.wb;
2664                     cameraWork.CAMERAiStateOut.awb = TRUE;
2665                 }
2666                 break;
2667             case CAMERA_PXI_COMMAND_EXPOSURE:
2668                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_IN)
2669                     cameraWork.CAMERAiStateIn.exposure = cameraWork.CAMERAiStateTmp.exposure;
2670                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_OUT)
2671                     cameraWork.CAMERAiStateOut.exposure = cameraWork.CAMERAiStateTmp.exposure;
2672                 break;
2673             case CAMERA_PXI_COMMAND_SHARPNESS:
2674                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_IN)
2675                     cameraWork.CAMERAiStateIn.sharpness = cameraWork.CAMERAiStateTmp.sharpness;
2676                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_OUT)
2677                     cameraWork.CAMERAiStateOut.sharpness = cameraWork.CAMERAiStateTmp.sharpness;
2678                 break;
2679             case CAMERA_PXI_COMMAND_AUTO_EXPOSURE:
2680                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_IN)
2681                     cameraWork.CAMERAiStateIn.ae = cameraWork.CAMERAiStateTmp.ae;
2682                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_OUT)
2683                     cameraWork.CAMERAiStateOut.ae = cameraWork.CAMERAiStateTmp.ae;
2684                 break;
2685             case CAMERA_PXI_COMMAND_AUTO_WHITE_BALANCE:
2686                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_IN)
2687                     cameraWork.CAMERAiStateIn.awb = cameraWork.CAMERAiStateTmp.awb;
2688                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_OUT)
2689                     cameraWork.CAMERAiStateOut.awb = cameraWork.CAMERAiStateTmp.awb;
2690                 break;
2691             case CAMERA_PXI_COMMAND_SET_LED:
2692                 cameraWork.CAMERAiStateOut.blink = cameraWork.CAMERAiStateTmp.blink;
2693                 break;
2694             default:
2695                 break;
2696             }
2697             break;
2698         case CAMERA_PXI_RESULT_SUCCESS_FALSE:
2699             result = CAMERA_RESULT_SUCCESS_FALSE;
2700             break;
2701         case CAMERA_PXI_RESULT_ILLEGAL_STATUS:
2702             result = CAMERA_RESULT_ILLEGAL_STATUS;
2703             break;
2704         case CAMERA_PXI_RESULT_INVALID_COMMAND:
2705         case CAMERA_PXI_RESULT_INVALID_PARAMETER:
2706         case CAMERA_PXI_RESULT_BUSY:
2707         default:
2708             result = CAMERA_RESULT_FATAL_ERROR;
2709         }
2710 
2711         // Call the callback
2712         CameraCallCallbackAndUnlock(result);
2713 
2714         // Start the reboot routine after CAMERA_RESULT_ILLEGAL_STATUS
2715         if(result == CAMERA_RESULT_ILLEGAL_STATUS)
2716         {
2717 //OS_TPrintf("Send message to reboot from PXI.\n");
2718             CAMERA_GoReboot();
2719         }
2720     }
2721 }
2722 
2723 /*---------------------------------------------------------------------------*
2724   Name:         CameraSyncCallback
2725 
2726   Description:  Callback for synchronous API.
2727 
2728   Arguments:    result: Result sent from ARM7
2729                 arg: Unused
2730 
2731   Returns:      None.
2732  *---------------------------------------------------------------------------*/
CameraSyncCallback(CAMERAResult result,void * arg)2733 static void CameraSyncCallback(CAMERAResult result, void *arg)
2734 {
2735 #pragma unused(arg)
2736     cameraWork.result = result;
2737 }
2738 
2739 /*---------------------------------------------------------------------------*
2740   Name:         CameraCallCallbackAndUnlock
2741 
2742   Description:  Calls the callback and unlocks the camera processing.
2743 
2744   Arguments:    result: Result sent from ARM7
2745 
2746   Returns:      None.
2747  *---------------------------------------------------------------------------*/
CameraCallCallbackAndUnlock(CAMERAResult result)2748 static void CameraCallCallbackAndUnlock(CAMERAResult result)
2749 {
2750     CAMERACallback cb;
2751 
2752     if (cameraWork.lock)
2753     {
2754         cameraWork.lock = FALSE;
2755     }
2756     if (cameraWork.callback)
2757     {
2758         cb = cameraWork.callback;
2759         cameraWork.callback = NULL;
2760         cb(result, cameraWork.callbackArg);
2761     }
2762 }
2763 
2764 /*---------------------------------------------------------------------------*
2765   Name:         CameraWaitBusy
2766 
2767   Description:  Wait while asynchronous processing for camera is locked.
2768 
2769   Arguments:    None.
2770 
2771   Returns:      None.
2772  *---------------------------------------------------------------------------*/
2773 #if 0
2774 #include    <nitro/code32.h>
2775 static asm void CameraWaitBusy(void)
2776 {
2777     ldr     r12,    =cameraWork.lock
2778 loop:
2779     ldr     r0,     [ r12,  #0 ]
2780     cmp     r0,     #TRUE
2781     beq     loop
2782     bx      lr
2783 }
2784 #include    <nitro/codereset.h>
2785 #else
2786 extern void PXIi_HandlerRecvFifoNotEmpty(void);
CameraWaitBusy(void)2787 static void CameraWaitBusy(void)
2788 {
2789     volatile BOOL *p = &cameraWork.lock;
2790 
2791     while (*p)
2792     {
2793         if (OS_GetCpsrIrq() == OS_INTRMODE_IRQ_DISABLE || OS_GetIrq() == OS_IME_DISABLE)
2794         {
2795             PXIi_HandlerRecvFifoNotEmpty();
2796         }
2797     }
2798 }
2799 #endif
2800 
2801 /*---------------------------------------------------------------------------*
2802   Name:         CameraStandbyCallback
2803 
2804   Description:  Set camera to standby.
2805 
2806   Arguments:    arg: Unused
2807 
2808   Returns:      None.
2809  *---------------------------------------------------------------------------*/
CameraStandbyCallback(void * args)2810 static void CameraStandbyCallback(void* args)
2811 {
2812 #pragma unused(args)
2813     (void)CAMERA_I2CActivateCore(CAMERA_SELECT_NONE);
2814 }
2815