1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - library - camera
3   File:     camera_api.c
4 
5   Copyright 2007-2009 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-06-19#$
14   $Rev: 10786 $
15   $Author: okajima_manabu $
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_TASSERTMSG(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     case CAMERA_FRAME_RATE_15_TO_10:
1297     case CAMERA_FRAME_RATE_20_TO_10:
1298     case CAMERA_FRAME_RATE_30_TO_10:
1299         break;
1300     default:
1301         return CAMERA_RESULT_ILLEGAL_PARAMETER;
1302     }
1303 
1304     enabled = OS_DisableInterrupts();
1305     if (cameraWork.lock)
1306     {
1307         (void)OS_RestoreInterrupts(enabled);
1308         return result == CAMERA_RESULT_ILLEGAL_STATUS ? CAMERA_RESULT_ILLEGAL_STATUS : CAMERA_RESULT_BUSY;
1309     }
1310     cameraWork.lock = TRUE;
1311     (void)OS_RestoreInterrupts(enabled);
1312     // Callback settings
1313     cameraWork.callback = callback;
1314     cameraWork.callbackArg = arg;
1315 
1316     // Create data
1317     data[0] = (u8)camera;
1318     data[1] = (u8)rate;
1319 
1320     // Set the setting value to the I2C command saving structure for the rebooting routine
1321     cameraWork.CAMERAiStateTmp.set_camera = camera;
1322     cameraWork.CAMERAiStateTmp.rate = rate;
1323 
1324     // Send command
1325     if (CameraSendPxiCommand(command, _size, data[0]) == FALSE)
1326     {
1327         return CAMERA_RESULT_SEND_ERROR;
1328     }
1329     for (i = 1; i < _size; i+=3) {
1330         CameraSendPxiData(&data[i]);
1331     }
1332 
1333     return CAMERA_RESULT_SUCCESS;
1334 }
1335 
1336 /*---------------------------------------------------------------------------*
1337   Name:         CAMERA_I2CFrameRate
1338 
1339   Description:  Set camera frame rate.
1340                 SYNC version.
1341 
1342   Arguments:    camera: One of the CAMERASelect values
1343                 rate: One of the CAMERAFrameRate values
1344 
1345   Returns:      CAMERAResult.
1346  *---------------------------------------------------------------------------*/
CAMERA_I2CFrameRateCore(CAMERASelect camera,CAMERAFrameRate rate)1347 CAMERAResult CAMERA_I2CFrameRateCore(CAMERASelect camera, CAMERAFrameRate rate)
1348 {
1349     cameraWork.result = CAMERA_I2CFrameRateAsyncCore(camera, rate, CameraSyncCallback, 0);
1350     if (cameraWork.result == CAMERA_RESULT_SUCCESS)
1351     {
1352         CameraWaitBusy();
1353     }
1354     return cameraWork.result;
1355 }
1356 
1357 /*---------------------------------------------------------------------------*
1358   Name:         CAMERA_I2CEffectExAsync
1359 
1360   Description:  Set camera effect.
1361                 ASYNC version.
1362 
1363   Arguments:    camera: One of the CAMERASelect values
1364                 context: One of the CAMERAContext values (A or B)
1365                 effect: One of the CAMERAEffect values
1366                 callback: Specifies the function to be called when the asynchronous process is completed
1367                 arg: Specifies the argument used when calling the callback function
1368 
1369   Returns:      CAMERAResult.
1370  *---------------------------------------------------------------------------*/
CAMERA_I2CEffectExAsyncCore(CAMERASelect camera,CAMERAContext context,CAMERAEffect effect,CAMERACallback callback,void * arg)1371 CAMERAResult CAMERA_I2CEffectExAsyncCore(CAMERASelect camera, CAMERAContext context, CAMERAEffect effect, CAMERACallback callback, void *arg)
1372 {
1373     const CAMERAPxiCommand  command = CAMERA_PXI_COMMAND_EFFECT;
1374     const u8                _size   = CAMERA_PXI_SIZE_EFFECT;
1375     OSIntrMode enabled;
1376     u8  data[_size+2];
1377     int i;
1378     CAMERAResult result;
1379 
1380     SDK_NULL_ASSERT(callback);
1381 
1382     // Status check based on the retry count and whether rebooting
1383     result = CAMERA_CheckRetryCount();
1384     if(result == CAMERA_RESULT_FATAL_ERROR)
1385         return result;
1386 
1387     switch (camera)
1388     {
1389     // case CAMERA_SELECT_NONE:
1390     case CAMERA_SELECT_IN:
1391     case CAMERA_SELECT_OUT:
1392     case CAMERA_SELECT_BOTH:
1393         break;
1394     default:
1395         return CAMERA_RESULT_ILLEGAL_PARAMETER;
1396     }
1397     switch (context)
1398     {
1399     case CAMERA_CONTEXT_A:
1400     case CAMERA_CONTEXT_B:
1401     case CAMERA_CONTEXT_BOTH:
1402         break;
1403     default:
1404         return CAMERA_RESULT_ILLEGAL_PARAMETER;
1405     }
1406     switch (effect)
1407     {
1408     case CAMERA_EFFECT_NONE:
1409     case CAMERA_EFFECT_MONO:
1410     case CAMERA_EFFECT_SEPIA:
1411     case CAMERA_EFFECT_NEGATIVE:
1412     case CAMERA_EFFECT_NEGAFILM:
1413     case CAMERA_EFFECT_SEPIA01:
1414         break;
1415     default:
1416         return CAMERA_RESULT_ILLEGAL_PARAMETER;
1417     }
1418 
1419     enabled = OS_DisableInterrupts();
1420     if (cameraWork.lock)
1421     {
1422         (void)OS_RestoreInterrupts(enabled);
1423         return result == CAMERA_RESULT_ILLEGAL_STATUS ? CAMERA_RESULT_ILLEGAL_STATUS : CAMERA_RESULT_BUSY;
1424     }
1425     cameraWork.lock = TRUE;
1426     (void)OS_RestoreInterrupts(enabled);
1427     // Callback settings
1428     cameraWork.callback = callback;
1429     cameraWork.callbackArg = arg;
1430 
1431     // Create data
1432     data[0] = (u8)camera;
1433     data[1] = (u8)context;
1434     data[2] = (u8)effect;
1435 
1436     // Set the setting value to the I2C command saving structure for the rebooting routine
1437     cameraWork.CAMERAiStateTmp.set_camera = camera;
1438     cameraWork.CAMERAiStateTmp.set_context = context;
1439     cameraWork.CAMERAiStateTmp.effect = effect;
1440 
1441     // Send command
1442     if (CameraSendPxiCommand(command, _size, data[0]) == FALSE)
1443     {
1444         return CAMERA_RESULT_SEND_ERROR;
1445     }
1446     for (i = 1; i < _size; i+=3) {
1447         CameraSendPxiData(&data[i]);
1448     }
1449 
1450     return CAMERA_RESULT_SUCCESS;
1451 }
1452 
1453 /*---------------------------------------------------------------------------*
1454   Name:         CAMERA_I2CEffectEx
1455 
1456   Description:  Set camera effect.
1457                 SYNC version.
1458 
1459   Arguments:    camera: One of the CAMERASelect values
1460                 context: One of the CAMERAContext values (A or B)
1461                 effect: One of the CAMERAEffect values
1462 
1463   Returns:      CAMERAResult.
1464  *---------------------------------------------------------------------------*/
CAMERA_I2CEffectExCore(CAMERASelect camera,CAMERAContext context,CAMERAEffect effect)1465 CAMERAResult CAMERA_I2CEffectExCore(CAMERASelect camera, CAMERAContext context, CAMERAEffect effect)
1466 {
1467     cameraWork.result = CAMERA_I2CEffectExAsyncCore(camera, context, effect, CameraSyncCallback, 0);
1468     if (cameraWork.result == CAMERA_RESULT_SUCCESS)
1469     {
1470         CameraWaitBusy();
1471     }
1472     return cameraWork.result;
1473 }
1474 
1475 /*---------------------------------------------------------------------------*
1476   Name:         CAMERA_I2CFlipExAsync
1477 
1478   Description:  Set camera flip/mirror.
1479                 ASYNC version.
1480 
1481   Arguments:    camera: One of the CAMERASelect values
1482                 context: One of CAMERAContext values (A or B)
1483                 flip: One of the CAMERAFlip values
1484                 callback: Specifies the function to be called when the asynchronous process is completed
1485                 arg: Specifies the argument used when calling the callback function
1486 
1487   Returns:      CAMERAResult.
1488  *---------------------------------------------------------------------------*/
CAMERA_I2CFlipExAsyncCore(CAMERASelect camera,CAMERAContext context,CAMERAFlip flip,CAMERACallback callback,void * arg)1489 CAMERAResult CAMERA_I2CFlipExAsyncCore(CAMERASelect camera, CAMERAContext context, CAMERAFlip flip, CAMERACallback callback, void *arg)
1490 {
1491     const CAMERAPxiCommand  command = CAMERA_PXI_COMMAND_FLIP;
1492     const u8                _size   = CAMERA_PXI_SIZE_FLIP;
1493     OSIntrMode enabled;
1494     u8  data[_size+2];
1495     int i;
1496     CAMERAResult result;
1497 
1498     SDK_NULL_ASSERT(callback);
1499 
1500     // Status check based on the retry count and whether rebooting
1501     result = CAMERA_CheckRetryCount();
1502     if(result == CAMERA_RESULT_FATAL_ERROR)
1503         return result;
1504 
1505     switch (camera)
1506     {
1507     // case CAMERA_SELECT_NONE:
1508     case CAMERA_SELECT_IN:
1509     case CAMERA_SELECT_OUT:
1510     case CAMERA_SELECT_BOTH:
1511         break;
1512     default:
1513         return CAMERA_RESULT_ILLEGAL_PARAMETER;
1514     }
1515     switch (context)
1516     {
1517     case CAMERA_CONTEXT_A:
1518     case CAMERA_CONTEXT_B:
1519     case CAMERA_CONTEXT_BOTH:
1520         break;
1521     default:
1522         return CAMERA_RESULT_ILLEGAL_PARAMETER;
1523     }
1524     switch (flip)
1525     {
1526     case CAMERA_FLIP_NONE:
1527     case CAMERA_FLIP_VERTICAL:
1528     case CAMERA_FLIP_HORIZONTAL:
1529     case CAMERA_FLIP_REVERSE:
1530         break;
1531     default:
1532         return CAMERA_RESULT_ILLEGAL_PARAMETER;
1533     }
1534 
1535     enabled = OS_DisableInterrupts();
1536     if (cameraWork.lock)
1537     {
1538         (void)OS_RestoreInterrupts(enabled);
1539         return result == CAMERA_RESULT_ILLEGAL_STATUS ? CAMERA_RESULT_ILLEGAL_STATUS : CAMERA_RESULT_BUSY;
1540     }
1541     cameraWork.lock = TRUE;
1542     (void)OS_RestoreInterrupts(enabled);
1543     // Callback settings
1544     cameraWork.callback = callback;
1545     cameraWork.callbackArg = arg;
1546 
1547     // Create data
1548     data[0] = (u8)camera;
1549     data[1] = (u8)context;
1550     data[2] = (u8)flip;
1551 
1552     // Set the setting value to the I2C command saving structure for the rebooting routine
1553     cameraWork.CAMERAiStateTmp.set_camera = camera;
1554     cameraWork.CAMERAiStateTmp.set_context = context;
1555     cameraWork.CAMERAiStateTmp.flip = flip;
1556 
1557     // Send command
1558     if (CameraSendPxiCommand(command, _size, data[0]) == FALSE)
1559     {
1560         return CAMERA_RESULT_SEND_ERROR;
1561     }
1562     for (i = 1; i < _size; i+=3) {
1563         CameraSendPxiData(&data[i]);
1564     }
1565 
1566     return CAMERA_RESULT_SUCCESS;
1567 }
1568 
1569 /*---------------------------------------------------------------------------*
1570   Name:         CAMERA_I2CFlipEx
1571 
1572   Description:  Set camera flip/mirror.
1573                 SYNC version.
1574 
1575   Arguments:    camera: One of the CAMERASelect values
1576                 context: One of the CAMERAContext values (A or B)
1577                 flip: One of the CAMERAFlip values
1578 
1579   Returns:      CAMERAResult.
1580  *---------------------------------------------------------------------------*/
CAMERA_I2CFlipExCore(CAMERASelect camera,CAMERAContext context,CAMERAFlip flip)1581 CAMERAResult CAMERA_I2CFlipExCore(CAMERASelect camera, CAMERAContext context, CAMERAFlip flip)
1582 {
1583     cameraWork.result = CAMERA_I2CFlipExAsyncCore(camera, context, flip, CameraSyncCallback, 0);
1584     if (cameraWork.result == CAMERA_RESULT_SUCCESS)
1585     {
1586         CameraWaitBusy();
1587     }
1588     return cameraWork.result;
1589 }
1590 
1591 /*---------------------------------------------------------------------------*
1592   Name:         CAMERA_I2CPhotoModeAsync
1593 
1594   Description:  Set camera photo mode.
1595                 ASYNC version.
1596 
1597   Arguments:    camera: One of the CAMERASelect values
1598                 mode: One of the CAMERAPhotoMode values
1599                 callback: Specifies the function to be called when the asynchronous process is completed
1600                 arg: Specifies the argument used when calling the callback function
1601 
1602   Returns:      CAMERAResult.
1603  *---------------------------------------------------------------------------*/
CAMERA_I2CPhotoModeAsyncCore(CAMERASelect camera,CAMERAPhotoMode mode,CAMERACallback callback,void * arg)1604 CAMERAResult CAMERA_I2CPhotoModeAsyncCore(CAMERASelect camera, CAMERAPhotoMode mode, CAMERACallback callback, void *arg)
1605 {
1606     const CAMERAPxiCommand  command = CAMERA_PXI_COMMAND_PHOTO_MODE;
1607     const u8                _size   = CAMERA_PXI_SIZE_PHOTO_MODE;
1608     OSIntrMode enabled;
1609     u8  data[_size+2];
1610     int i;
1611     CAMERAResult result;
1612 
1613     SDK_NULL_ASSERT(callback);
1614 
1615     // Status check based on the retry count and whether rebooting
1616     result = CAMERA_CheckRetryCount();
1617     if(result == CAMERA_RESULT_FATAL_ERROR)
1618         return result;
1619 
1620     switch (camera)
1621     {
1622     // case CAMERA_SELECT_NONE:
1623     case CAMERA_SELECT_IN:
1624     case CAMERA_SELECT_OUT:
1625     case CAMERA_SELECT_BOTH:
1626         break;
1627     default:
1628         return CAMERA_RESULT_ILLEGAL_PARAMETER;
1629     }
1630     switch (mode)
1631     {
1632     case CAMERA_PHOTO_MODE_NORMAL:
1633     case CAMERA_PHOTO_MODE_PORTRAIT:
1634     case CAMERA_PHOTO_MODE_LANDSCAPE:
1635     case CAMERA_PHOTO_MODE_NIGHTVIEW:
1636     case CAMERA_PHOTO_MODE_LETTER:
1637         break;
1638     default:
1639         return CAMERA_RESULT_ILLEGAL_PARAMETER;
1640     }
1641 
1642     enabled = OS_DisableInterrupts();
1643     if (cameraWork.lock)
1644     {
1645         (void)OS_RestoreInterrupts(enabled);
1646         return result == CAMERA_RESULT_ILLEGAL_STATUS ? CAMERA_RESULT_ILLEGAL_STATUS : CAMERA_RESULT_BUSY;
1647     }
1648     cameraWork.lock = TRUE;
1649     (void)OS_RestoreInterrupts(enabled);
1650     // Callback settings
1651     cameraWork.callback = callback;
1652     cameraWork.callbackArg = arg;
1653 
1654     // Create data
1655     data[0] = (u8)camera;
1656     data[1] = (u8)mode;
1657 
1658     // Set the setting value to the I2C command saving structure for the rebooting routine
1659     // It is necessary to remember three parameters changed simultaneously for PhotoMode
1660     cameraWork.CAMERAiStateTmp.set_camera = camera;
1661     cameraWork.CAMERAiStateTmp.photo = mode;
1662 
1663     // Send command
1664     if (CameraSendPxiCommand(command, _size, data[0]) == FALSE)
1665     {
1666         return CAMERA_RESULT_SEND_ERROR;
1667     }
1668     for (i = 1; i < _size; i+=3) {
1669         CameraSendPxiData(&data[i]);
1670     }
1671 
1672     return CAMERA_RESULT_SUCCESS;
1673 }
1674 
1675 /*---------------------------------------------------------------------------*
1676   Name:         CAMERA_I2CPhotoMode
1677 
1678   Description:  Set camera photo mode.
1679                 SYNC version.
1680 
1681   Arguments:    camera: One of the CAMERASelect values
1682                 mode: One of the CAMERAPhotoMode values
1683 
1684   Returns:      CAMERAResult.
1685  *---------------------------------------------------------------------------*/
CAMERA_I2CPhotoModeCore(CAMERASelect camera,CAMERAPhotoMode mode)1686 CAMERAResult CAMERA_I2CPhotoModeCore(CAMERASelect camera, CAMERAPhotoMode mode)
1687 {
1688     cameraWork.result = CAMERA_I2CPhotoModeAsyncCore(camera, mode, CameraSyncCallback, 0);
1689     if (cameraWork.result == CAMERA_RESULT_SUCCESS)
1690     {
1691         CameraWaitBusy();
1692     }
1693     return cameraWork.result;
1694 }
1695 
1696 /*---------------------------------------------------------------------------*
1697   Name:         CAMERA_I2CWhiteBalanceAsync
1698 
1699   Description:  Set camera white balance.
1700                 ASYNC version.
1701 
1702   Arguments:    camera: One of the CAMERASelect values
1703                 wb: One of the CAMERAWhiteBalance values
1704                 callback: Specifies the function to be called when the asynchronous process is completed
1705                 arg: Specifies the argument used when calling the callback function
1706 
1707   Returns:      CAMERAResult.
1708  *---------------------------------------------------------------------------*/
CAMERA_I2CWhiteBalanceAsyncCore(CAMERASelect camera,CAMERAWhiteBalance wb,CAMERACallback callback,void * arg)1709 CAMERAResult CAMERA_I2CWhiteBalanceAsyncCore(CAMERASelect camera, CAMERAWhiteBalance wb, CAMERACallback callback, void *arg)
1710 {
1711     const CAMERAPxiCommand  command = CAMERA_PXI_COMMAND_WHITE_BALANCE;
1712     const u8                _size   = CAMERA_PXI_SIZE_WHITE_BALANCE;
1713     OSIntrMode enabled;
1714     u8  data[_size+2];
1715     int i;
1716     CAMERAResult result;
1717 
1718     SDK_NULL_ASSERT(callback);
1719 
1720     // Status check based on the retry count and whether rebooting or not
1721     result = CAMERA_CheckRetryCount();
1722     if(result == CAMERA_RESULT_FATAL_ERROR)
1723         return result;
1724 
1725     switch (camera)
1726     {
1727     // case CAMERA_SELECT_NONE:
1728     case CAMERA_SELECT_IN:
1729     case CAMERA_SELECT_OUT:
1730     case CAMERA_SELECT_BOTH:
1731         break;
1732     default:
1733         return CAMERA_RESULT_ILLEGAL_PARAMETER;
1734     }
1735     switch (wb)
1736     {
1737     case CAMERA_WHITE_BALANCE_AUTO:
1738     case CAMERA_WHITE_BALANCE_3200K:
1739     case CAMERA_WHITE_BALANCE_4150K:
1740     case CAMERA_WHITE_BALANCE_5200K:
1741     case CAMERA_WHITE_BALANCE_6000K:
1742     case CAMERA_WHITE_BALANCE_7000K:
1743         break;
1744     default:
1745         return CAMERA_RESULT_ILLEGAL_PARAMETER;
1746     }
1747 
1748     enabled = OS_DisableInterrupts();
1749     if (cameraWork.lock)
1750     {
1751         (void)OS_RestoreInterrupts(enabled);
1752         return result == CAMERA_RESULT_ILLEGAL_STATUS ? CAMERA_RESULT_ILLEGAL_STATUS : CAMERA_RESULT_BUSY;
1753     }
1754     cameraWork.lock = TRUE;
1755     (void)OS_RestoreInterrupts(enabled);
1756     // Callback settings
1757     cameraWork.callback = callback;
1758     cameraWork.callbackArg = arg;
1759 
1760     // Create data
1761     data[0] = (u8)camera;
1762     data[1] = (u8)wb;
1763 
1764     // Set the setting value to the I2C command saving structure for the rebooting routine
1765     cameraWork.CAMERAiStateTmp.set_camera = camera;
1766     cameraWork.CAMERAiStateTmp.wb = wb;
1767 
1768     // Send command
1769     if (CameraSendPxiCommand(command, _size, data[0]) == FALSE)
1770     {
1771         return CAMERA_RESULT_SEND_ERROR;
1772     }
1773     for (i = 1; i < _size; i+=3) {
1774         CameraSendPxiData(&data[i]);
1775     }
1776 
1777     return CAMERA_RESULT_SUCCESS;
1778 }
1779 
1780 /*---------------------------------------------------------------------------*
1781   Name:         CAMERA_I2CWhiteBalance
1782 
1783   Description:  Set camera white balance.
1784                 SYNC version.
1785 
1786   Arguments:    camera: One of the CAMERASelect values
1787                 wb: One of the CAMERAWhiteBalance values
1788 
1789   Returns:      CAMERAResult.
1790  *---------------------------------------------------------------------------*/
CAMERA_I2CWhiteBalanceCore(CAMERASelect camera,CAMERAWhiteBalance wb)1791 CAMERAResult CAMERA_I2CWhiteBalanceCore(CAMERASelect camera, CAMERAWhiteBalance wb)
1792 {
1793     cameraWork.result = CAMERA_I2CWhiteBalanceAsyncCore(camera, wb, CameraSyncCallback, 0);
1794     if (cameraWork.result == CAMERA_RESULT_SUCCESS)
1795     {
1796         CameraWaitBusy();
1797     }
1798     return cameraWork.result;
1799 }
1800 
1801 /*---------------------------------------------------------------------------*
1802   Name:         CAMERA_I2CExposureAsync
1803 
1804   Description:  Set camera exposure.
1805                 ASYNC version.
1806 
1807   Arguments:    camera: One of the CAMERASelect values
1808                 exposure: -5 to +5
1809                 callback: Specifies the function to be called when the asynchronous process is completed
1810                 arg: Specifies the argument used when calling the callback function
1811 
1812   Returns:      CAMERAResult.
1813  *---------------------------------------------------------------------------*/
CAMERA_I2CExposureAsyncCore(CAMERASelect camera,int exposure,CAMERACallback callback,void * arg)1814 CAMERAResult CAMERA_I2CExposureAsyncCore(CAMERASelect camera, int exposure, CAMERACallback callback, void *arg)
1815 {
1816     const CAMERAPxiCommand  command = CAMERA_PXI_COMMAND_EXPOSURE;
1817     const u8                _size   = CAMERA_PXI_SIZE_EXPOSURE;
1818     OSIntrMode enabled;
1819     u8  data[_size+2];
1820     int i;
1821     CAMERAResult result;
1822 
1823     SDK_NULL_ASSERT(callback);
1824 
1825     // Status check based on the retry count and whether rebooting
1826     result = CAMERA_CheckRetryCount();
1827     if(result == CAMERA_RESULT_FATAL_ERROR)
1828         return result;
1829 
1830     switch (camera)
1831     {
1832     // case CAMERA_SELECT_NONE:
1833     case CAMERA_SELECT_IN:
1834     case CAMERA_SELECT_OUT:
1835     case CAMERA_SELECT_BOTH:
1836         break;
1837     default:
1838         return CAMERA_RESULT_ILLEGAL_PARAMETER;
1839     }
1840     if (exposure < -5 || exposure > 5)
1841     {
1842         return CAMERA_RESULT_ILLEGAL_PARAMETER;
1843     }
1844 
1845     enabled = OS_DisableInterrupts();
1846     if (cameraWork.lock)
1847     {
1848         (void)OS_RestoreInterrupts(enabled);
1849         return result == CAMERA_RESULT_ILLEGAL_STATUS ? CAMERA_RESULT_ILLEGAL_STATUS : CAMERA_RESULT_BUSY;
1850     }
1851     cameraWork.lock = TRUE;
1852     (void)OS_RestoreInterrupts(enabled);
1853     // Callback settings
1854     cameraWork.callback = callback;
1855     cameraWork.callbackArg = arg;
1856 
1857     // Create data
1858     data[0] = (u8)camera;
1859     data[1] = (u8)exposure;
1860 
1861     // Set the setting value to the I2C command saving structure for the rebooting routine
1862     cameraWork.CAMERAiStateTmp.set_camera = camera;
1863     cameraWork.CAMERAiStateTmp.exposure = exposure;
1864 
1865     // Send command
1866     if (CameraSendPxiCommand(command, _size, data[0]) == FALSE)
1867     {
1868         return CAMERA_RESULT_SEND_ERROR;
1869     }
1870     for (i = 1; i < _size; i+=3) {
1871         CameraSendPxiData(&data[i]);
1872     }
1873 
1874     return CAMERA_RESULT_SUCCESS;
1875 }
1876 
1877 /*---------------------------------------------------------------------------*
1878   Name:         CAMERA_I2CExposure
1879 
1880   Description:  Set camera exposure.
1881                 SYNC version.
1882 
1883   Arguments:    camera: One of the CAMERASelect values
1884                 exposure: -5 to +5
1885   Returns:      CAMERAResult.
1886  *---------------------------------------------------------------------------*/
CAMERA_I2CExposureCore(CAMERASelect camera,int exposure)1887 CAMERAResult CAMERA_I2CExposureCore(CAMERASelect camera, int exposure)
1888 {
1889     cameraWork.result = CAMERA_I2CExposureAsyncCore(camera, exposure, CameraSyncCallback, 0);
1890     if (cameraWork.result == CAMERA_RESULT_SUCCESS)
1891     {
1892         CameraWaitBusy();
1893     }
1894     return cameraWork.result;
1895 }
1896 
1897 /*---------------------------------------------------------------------------*
1898   Name:         CAMERA_I2CSharpnessAsync
1899 
1900   Description:  Set camera sharpness.
1901                 ASYNC version.
1902 
1903   Arguments:    camera: One of the CAMERASelect values
1904                 sharpness: -3 to +5
1905                 callback: Specifies the function to be called when the asynchronous process is completed
1906                 arg: Specifies the argument used when calling the callback function
1907 
1908   Returns:      CAMERAResult
1909  *---------------------------------------------------------------------------*/
CAMERA_I2CSharpnessAsyncCore(CAMERASelect camera,int sharpness,CAMERACallback callback,void * arg)1910 CAMERAResult CAMERA_I2CSharpnessAsyncCore(CAMERASelect camera, int sharpness, CAMERACallback callback, void *arg)
1911 {
1912     const CAMERAPxiCommand  command = CAMERA_PXI_COMMAND_SHARPNESS;
1913     const u8                _size   = CAMERA_PXI_SIZE_SHARPNESS;
1914     OSIntrMode enabled;
1915     u8  data[_size+2];
1916     int i;
1917     CAMERAResult result;
1918 
1919     SDK_NULL_ASSERT(callback);
1920 
1921     // Status check based on the retry count and whether rebooting
1922     result = CAMERA_CheckRetryCount();
1923     if(result == CAMERA_RESULT_FATAL_ERROR)
1924         return result;
1925 
1926     switch (camera)
1927     {
1928     // case CAMERA_SELECT_NONE:
1929     case CAMERA_SELECT_IN:
1930     case CAMERA_SELECT_OUT:
1931     case CAMERA_SELECT_BOTH:
1932         break;
1933     default:
1934         return CAMERA_RESULT_ILLEGAL_PARAMETER;
1935     }
1936     if (sharpness < -3 || sharpness > 5)
1937     {
1938         return CAMERA_RESULT_ILLEGAL_PARAMETER;
1939     }
1940 
1941     enabled = OS_DisableInterrupts();
1942     if (cameraWork.lock)
1943     {
1944         (void)OS_RestoreInterrupts(enabled);
1945         return result == CAMERA_RESULT_ILLEGAL_STATUS ? CAMERA_RESULT_ILLEGAL_STATUS : CAMERA_RESULT_BUSY;
1946     }
1947     cameraWork.lock = TRUE;
1948     (void)OS_RestoreInterrupts(enabled);
1949     // Callback settings
1950     cameraWork.callback = callback;
1951     cameraWork.callbackArg = arg;
1952 
1953     // Create data
1954     data[0] = (u8)camera;
1955     data[1] = (u8)sharpness;
1956 
1957     // Set the setting value to the I2C command saving structure for the rebooting routine
1958     cameraWork.CAMERAiStateTmp.set_camera = camera;
1959     cameraWork.CAMERAiStateTmp.sharpness = sharpness;
1960 
1961     // Send command
1962     if (CameraSendPxiCommand(command, _size, data[0]) == FALSE)
1963     {
1964         return CAMERA_RESULT_SEND_ERROR;
1965     }
1966     for (i = 1; i < _size; i+=3) {
1967         CameraSendPxiData(&data[i]);
1968     }
1969 
1970     return CAMERA_RESULT_SUCCESS;
1971 }
1972 
1973 /*---------------------------------------------------------------------------*
1974   Name:         CAMERA_I2CSharpness
1975 
1976   Description:  Set camera sharpness.
1977                 SYNC version.
1978 
1979   Arguments:    camera: One of the CAMERASelect values
1980                 sharpness: -3 to +5
1981   Returns:      CAMERAResult.
1982  *---------------------------------------------------------------------------*/
CAMERA_I2CSharpnessCore(CAMERASelect camera,int sharpness)1983 CAMERAResult CAMERA_I2CSharpnessCore(CAMERASelect camera, int sharpness)
1984 {
1985     cameraWork.result = CAMERA_I2CSharpnessAsyncCore(camera, sharpness, CameraSyncCallback, 0);
1986     if (cameraWork.result == CAMERA_RESULT_SUCCESS)
1987     {
1988         CameraWaitBusy();
1989     }
1990     return cameraWork.result;
1991 }
1992 
1993 /*---------------------------------------------------------------------------*
1994   Name:         CAMERAi_I2CTestPatternAsync
1995 
1996   Description:  Set camera test pattern.
1997                 ASYNC version.
1998 
1999   Arguments:    camera: One of the CAMERASelect values
2000                 pattern: One of the CAMERATestPattern values
2001                 callback: Specifies the function to be called when the asynchronous process is completed.
2002                 arg: Specifies the argument used when calling the callback function
2003 
2004   Returns:      CAMERAResult.
2005  *---------------------------------------------------------------------------*/
CAMERAi_I2CTestPatternAsyncCore(CAMERASelect camera,CAMERATestPattern pattern,CAMERACallback callback,void * arg)2006 CAMERAResult CAMERAi_I2CTestPatternAsyncCore(CAMERASelect camera, CAMERATestPattern pattern, CAMERACallback callback, void *arg)
2007 {
2008     const CAMERAPxiCommand  command = CAMERA_PXI_COMMAND_TEST_PATTERN;
2009     const u8                _size   = CAMERA_PXI_SIZE_TEST_PATTERN;
2010     OSIntrMode enabled;
2011     u8  data[_size+2];
2012     int i;
2013     CAMERAResult result;
2014 
2015     SDK_NULL_ASSERT(callback);
2016 
2017     // Status check based on the retry count and whether rebooting or not
2018     result = CAMERA_CheckRetryCount();
2019     if(result == CAMERA_RESULT_FATAL_ERROR)
2020         return result;
2021 
2022     switch (camera)
2023     {
2024     // case CAMERA_SELECT_NONE:
2025     case CAMERA_SELECT_IN:
2026     case CAMERA_SELECT_OUT:
2027     case CAMERA_SELECT_BOTH:
2028         break;
2029     default:
2030         return CAMERA_RESULT_ILLEGAL_PARAMETER;
2031     }
2032     switch (pattern)
2033     {
2034     case CAMERA_TEST_PATTERN_DISABLED:
2035     case CAMERA_TEST_PATTERN_COLOR_BAR:
2036     case CAMERA_TEST_PATTERN_NOISE:
2037         break;
2038     default:
2039         return CAMERA_RESULT_ILLEGAL_PARAMETER;
2040     }
2041 
2042     enabled = OS_DisableInterrupts();
2043     if (cameraWork.lock)
2044     {
2045         (void)OS_RestoreInterrupts(enabled);
2046         return result == CAMERA_RESULT_ILLEGAL_STATUS ? CAMERA_RESULT_ILLEGAL_STATUS : CAMERA_RESULT_BUSY;
2047     }
2048     cameraWork.lock = TRUE;
2049     (void)OS_RestoreInterrupts(enabled);
2050     // Callback settings
2051     cameraWork.callback = callback;
2052     cameraWork.callbackArg = arg;
2053 
2054     // Create data
2055     data[0] = (u8)camera;
2056     data[1] = (u8)pattern;
2057 
2058     // Send command
2059     if (CameraSendPxiCommand(command, _size, data[0]) == FALSE)
2060     {
2061         return CAMERA_RESULT_SEND_ERROR;
2062     }
2063     for (i = 1; i < _size; i+=3) {
2064         CameraSendPxiData(&data[i]);
2065     }
2066 
2067     return CAMERA_RESULT_SUCCESS;
2068 }
2069 
2070 /*---------------------------------------------------------------------------*
2071   Name:         CAMERAi_I2CTestPattern
2072 
2073   Description:  Set camera test pattern.
2074                 SYNC version.
2075 
2076   Arguments:    camera: One of the CAMERASelect values
2077                 pattern: One of the CAMERATestPattern values
2078 
2079   Returns:      CAMERAResult.
2080  *---------------------------------------------------------------------------*/
CAMERAi_I2CTestPatternCore(CAMERASelect camera,CAMERATestPattern pattern)2081 CAMERAResult CAMERAi_I2CTestPatternCore(CAMERASelect camera, CAMERATestPattern pattern)
2082 {
2083     cameraWork.result = CAMERAi_I2CTestPatternAsyncCore(camera, pattern, CameraSyncCallback, 0);
2084     if (cameraWork.result == CAMERA_RESULT_SUCCESS)
2085     {
2086         CameraWaitBusy();
2087     }
2088     return cameraWork.result;
2089 }
2090 
2091 /*---------------------------------------------------------------------------*
2092   Name:         CAMERA_I2CAutoExposureAsync
2093 
2094   Description:  Enable/disable camera auto-exposure.
2095                 ASYNC version.
2096 
2097   Arguments:    camera: One of the CAMERASelect values
2098                 on: TRUE if AE will enable
2099                 callback: Specifies the function to be called when the asynchronous process is completed
2100                 arg: Specifies the argument used when calling the callback function
2101 
2102   Returns:      CAMERAResult.
2103  *---------------------------------------------------------------------------*/
CAMERA_I2CAutoExposureAsyncCore(CAMERASelect camera,BOOL on,CAMERACallback callback,void * arg)2104 CAMERAResult CAMERA_I2CAutoExposureAsyncCore(CAMERASelect camera, BOOL on, CAMERACallback callback, void *arg)
2105 {
2106     const CAMERAPxiCommand  command = CAMERA_PXI_COMMAND_AUTO_EXPOSURE;
2107     const u8                _size   = CAMERA_PXI_SIZE_AUTO_EXPOSURE;
2108     OSIntrMode enabled;
2109     u8  data[_size+2];
2110     int i;
2111     CAMERAResult result;
2112 
2113     SDK_NULL_ASSERT(callback);
2114 
2115     // Status check based on the retry count and whether rebooting
2116     result = CAMERA_CheckRetryCount();
2117     if(result == CAMERA_RESULT_FATAL_ERROR)
2118         return result;
2119 
2120     switch (camera)
2121     {
2122     // case CAMERA_SELECT_NONE:
2123     case CAMERA_SELECT_IN:
2124     case CAMERA_SELECT_OUT:
2125     case CAMERA_SELECT_BOTH:
2126         break;
2127     default:
2128         return CAMERA_RESULT_ILLEGAL_PARAMETER;
2129     }
2130 
2131     enabled = OS_DisableInterrupts();
2132     if (cameraWork.lock)
2133     {
2134         (void)OS_RestoreInterrupts(enabled);
2135         return result == CAMERA_RESULT_ILLEGAL_STATUS ? CAMERA_RESULT_ILLEGAL_STATUS : CAMERA_RESULT_BUSY;
2136     }
2137     cameraWork.lock = TRUE;
2138     (void)OS_RestoreInterrupts(enabled);
2139     // Callback settings
2140     cameraWork.callback = callback;
2141     cameraWork.callbackArg = arg;
2142 
2143     // Create data
2144     data[0] = (u8)camera;
2145     data[1] = (u8)(on ? TRUE : FALSE);
2146 
2147     // Set the setting value to the I2C command saving structure for the rebooting routine
2148     cameraWork.CAMERAiStateTmp.set_camera = camera;
2149     cameraWork.CAMERAiStateTmp.ae = on;
2150 
2151     // Send command
2152     if (CameraSendPxiCommand(command, _size, data[0]) == FALSE)
2153     {
2154         return CAMERA_RESULT_SEND_ERROR;
2155     }
2156     for (i = 1; i < _size; i+=3) {
2157         CameraSendPxiData(&data[i]);
2158     }
2159 
2160     return CAMERA_RESULT_SUCCESS;
2161 }
2162 
2163 /*---------------------------------------------------------------------------*
2164   Name:         CAMERA_I2CAutoExposure
2165 
2166   Description:  Enable/disable camera auto-exposure.
2167                 SYNC version.
2168 
2169   Arguments:    camera: One of the CAMERASelect values
2170                 on: TRUE if AE will enable
2171   Returns:      CAMERAResult.
2172  *---------------------------------------------------------------------------*/
CAMERA_I2CAutoExposureCore(CAMERASelect camera,BOOL on)2173 CAMERAResult CAMERA_I2CAutoExposureCore(CAMERASelect camera, BOOL on)
2174 {
2175     cameraWork.result = CAMERA_I2CAutoExposureAsyncCore(camera, on, CameraSyncCallback, 0);
2176     if (cameraWork.result == CAMERA_RESULT_SUCCESS)
2177     {
2178         CameraWaitBusy();
2179     }
2180     return cameraWork.result;
2181 }
2182 
2183 /*---------------------------------------------------------------------------*
2184   Name:         CAMERA_I2CAutoWhiteBalanceAsync
2185 
2186   Description:  Enable/disable camera auto-white-balance.
2187                 ASYNC version.
2188 
2189   Arguments:    camera: One of the CAMERASelect values
2190                 on: TRUE if AWB will enable
2191                 callback: Specifies the function to be called when the asynchronous process is completed
2192                 arg: Specifies the argument used when calling the callback function
2193 
2194   Returns:      CAMERAResult.
2195  *---------------------------------------------------------------------------*/
CAMERA_I2CAutoWhiteBalanceAsyncCore(CAMERASelect camera,BOOL on,CAMERACallback callback,void * arg)2196 CAMERAResult CAMERA_I2CAutoWhiteBalanceAsyncCore(CAMERASelect camera, BOOL on, CAMERACallback callback, void *arg)
2197 {
2198     const CAMERAPxiCommand  command = CAMERA_PXI_COMMAND_AUTO_WHITE_BALANCE;
2199     const u8                _size   = CAMERA_PXI_SIZE_AUTO_WHITE_BALANCE;
2200     OSIntrMode enabled;
2201     u8  data[_size+2];
2202     int i;
2203     CAMERAResult result;
2204 
2205     SDK_NULL_ASSERT(callback);
2206 
2207     // Status check based on the retry count and whether rebooting
2208     result = CAMERA_CheckRetryCount();
2209     if(result == CAMERA_RESULT_FATAL_ERROR)
2210         return result;
2211 
2212     switch (camera)
2213     {
2214     // case CAMERA_SELECT_NONE:
2215     case CAMERA_SELECT_IN:
2216     case CAMERA_SELECT_OUT:
2217     case CAMERA_SELECT_BOTH:
2218         break;
2219     default:
2220         return CAMERA_RESULT_ILLEGAL_PARAMETER;
2221     }
2222 
2223     if ((camera & CAMERA_SELECT_IN) && cameraWork.CAMERAiStateIn.wb != CAMERA_WHITE_BALANCE_NORMAL)
2224     {
2225         return CAMERA_RESULT_INVALID_COMMAND;
2226     }
2227     if ((camera & CAMERA_SELECT_OUT) && cameraWork.CAMERAiStateOut.wb != CAMERA_WHITE_BALANCE_NORMAL)
2228     {
2229         return CAMERA_RESULT_INVALID_COMMAND;
2230     }
2231 
2232     enabled = OS_DisableInterrupts();
2233     if (cameraWork.lock)
2234     {
2235         (void)OS_RestoreInterrupts(enabled);
2236         return result == CAMERA_RESULT_ILLEGAL_STATUS ? CAMERA_RESULT_ILLEGAL_STATUS : CAMERA_RESULT_BUSY;
2237     }
2238     cameraWork.lock = TRUE;
2239     (void)OS_RestoreInterrupts(enabled);
2240     // Callback settings
2241     cameraWork.callback = callback;
2242     cameraWork.callbackArg = arg;
2243 
2244     // Create data
2245     data[0] = (u8)camera;
2246     data[1] = (u8)(on ? TRUE : FALSE);
2247 
2248     // Set the setting value to the I2C command saving structure for the rebooting routine
2249     cameraWork.CAMERAiStateTmp.set_camera = camera;
2250     cameraWork.CAMERAiStateTmp.awb = on;
2251 
2252     // Send command
2253     if (CameraSendPxiCommand(command, _size, data[0]) == FALSE)
2254     {
2255         return CAMERA_RESULT_SEND_ERROR;
2256     }
2257     for (i = 1; i < _size; i+=3) {
2258         CameraSendPxiData(&data[i]);
2259     }
2260 
2261     return CAMERA_RESULT_SUCCESS;
2262 }
2263 
2264 /*---------------------------------------------------------------------------*
2265   Name:         CAMERA_I2CAutoWhiteBalance
2266 
2267   Description:  Enable/disable camera auto-white-balance.
2268                 SYNC version.
2269 
2270   Arguments:    camera: One of the CAMERASelect values
2271                 on: TRUE if AE will enable
2272   Returns:      CAMERAResult.
2273  *---------------------------------------------------------------------------*/
CAMERA_I2CAutoWhiteBalanceCore(CAMERASelect camera,BOOL on)2274 CAMERAResult CAMERA_I2CAutoWhiteBalanceCore(CAMERASelect camera, BOOL on)
2275 {
2276     cameraWork.result = CAMERA_I2CAutoWhiteBalanceAsyncCore(camera, on, CameraSyncCallback, 0);
2277     if (cameraWork.result == CAMERA_RESULT_SUCCESS)
2278     {
2279         CameraWaitBusy();
2280     }
2281     return cameraWork.result;
2282 }
2283 
2284 /*---------------------------------------------------------------------------*
2285   Name:         CAMERA_SetLEDAsync
2286 
2287   Description:  Set camera LED (outside) to blink or not.
2288                 It works only when the OUT camera is active.
2289                 The default state when calling I2CActivate(OUT/BOTH) does not blink.
2290                 ASYNC version.
2291 
2292   Arguments:    isBlink: TRUE to flash; FALSE to light
2293                 callback: Specifies the function to be called when the asynchronous process is completed
2294                 arg: Specifies the argument used when calling the callback function
2295 
2296   Returns:      CAMERAResult.
2297  *---------------------------------------------------------------------------*/
CAMERA_SetLEDAsyncCore(BOOL isBlink,CAMERACallback callback,void * arg)2298 CAMERAResult CAMERA_SetLEDAsyncCore(BOOL isBlink, CAMERACallback callback, void *arg)
2299 {
2300     const CAMERAPxiCommand  command = CAMERA_PXI_COMMAND_SET_LED;
2301     const u8                _size   = CAMERA_PXI_SIZE_SET_LED;
2302     OSIntrMode enabled;
2303 
2304     SDK_NULL_ASSERT(callback);
2305 
2306     enabled = OS_DisableInterrupts();
2307     if (cameraWork.lock)
2308     {
2309         (void)OS_RestoreInterrupts(enabled);
2310         return CAMERA_RESULT_BUSY;
2311     }
2312     cameraWork.lock = TRUE;
2313     (void)OS_RestoreInterrupts(enabled);
2314     // Callback settings
2315     cameraWork.callback = callback;
2316     cameraWork.callbackArg = arg;
2317 
2318     // Set the setting value to the structure for the rebooting routine
2319     cameraWork.CAMERAiStateTmp.blink = isBlink;
2320 
2321     return CameraSendPxiCommand(command, _size, (u8)isBlink) ? CAMERA_RESULT_SUCCESS : CAMERA_RESULT_SEND_ERROR;
2322 }
2323 
2324 /*---------------------------------------------------------------------------*
2325   Name:         CAMERA_SetLED
2326 
2327   Description:  Set camera LED (outside) to blink or not.
2328                 It works only when the OUT camera is active.
2329                 The default state when calling I2CActivate(OUT/BOTH) does not blink.
2330                 SYNC version.
2331 
2332   Arguments:    isBlink: TRUE to flash; FALSE to light
2333 
2334   Returns:      CAMERAResult.
2335  *---------------------------------------------------------------------------*/
CAMERA_SetLEDCore(BOOL isBlink)2336 CAMERAResult CAMERA_SetLEDCore(BOOL isBlink)
2337 {
2338     cameraWork.result = CAMERA_SetLEDAsyncCore(isBlink, CameraSyncCallback, 0);
2339     if (cameraWork.result == CAMERA_RESULT_SUCCESS)
2340     {
2341         CameraWaitBusy();
2342     }
2343     return cameraWork.result;
2344 }
2345 
2346 static CAMERACallback cameraSwitchOffLEDCallback;
2347 
CAMERAi_SwitchOffLEDAsyncCallback(CAMERAResult result,void * arg)2348 static void CAMERAi_SwitchOffLEDAsyncCallback(CAMERAResult result, void* arg)
2349 {
2350 
2351     if(result != CAMERA_RESULT_SUCCESS)
2352         cameraSwitchOffLEDCallback(result, arg);
2353 
2354     (void)CAMERA_SetLEDAsyncCore(FALSE, cameraSwitchOffLEDCallback, arg);
2355 }
2356 
2357 /*---------------------------------------------------------------------------*
2358   Name:         CAMERA_SwitchOffLEDAsync
2359 
2360   Description:  Turn off the camera LED only one time.
2361                 The operation is the same as when continuously calling CAMERA_SetLED(TRUE), CAMERA_SetLED(FALSE).
2362 
2363 
2364   Arguments:    callback: Specifies the function to be called when the asynchronous process is completed
2365                 arg: Specifies the argument used when calling the callback function
2366 
2367   Returns:      CAMERAResult.
2368  *---------------------------------------------------------------------------*/
CAMERA_SwitchOffLEDAsyncCore(CAMERACallback callback,void * arg)2369 CAMERAResult CAMERA_SwitchOffLEDAsyncCore(CAMERACallback callback, void *arg)
2370 {
2371     cameraSwitchOffLEDCallback = callback;
2372 
2373     return CAMERA_SetLEDAsyncCore(TRUE, CAMERAi_SwitchOffLEDAsyncCallback, arg);
2374 }
2375 
2376 /*---------------------------------------------------------------------------*
2377   Name:         CAMERA_SwitchOffLED
2378 
2379   Description:  Turn off the camera LED only one time.
2380                 The operation is the same as when continuously calling CAMERA_SetLED(TRUE), CAMERA_SetLED(FALSE).
2381 
2382 
2383   Arguments:    None.
2384 
2385   Returns:      CAMERAResult.
2386  *---------------------------------------------------------------------------*/
CAMERA_SwitchOffLEDCore(void)2387 CAMERAResult CAMERA_SwitchOffLEDCore(void)
2388 {
2389     CAMERAResult result;
2390 
2391     result = CAMERA_SetLEDCore(TRUE);
2392     if(result != CAMERA_RESULT_SUCCESS)
2393         return result;
2394     return CAMERA_SetLEDCore(FALSE);
2395 }
2396 
CAMERAi_Wait(u32 clocks)2397 static inline void CAMERAi_Wait(u32 clocks)
2398 {
2399     OS_SpinWaitSysCycles(clocks << 1);
2400 }
CAMERAi_StopMasterClock(void)2401 static inline BOOL CAMERAi_StopMasterClock(void)
2402 {
2403     OSIntrMode enabled = OS_DisableInterrupts();
2404     u16  reg = reg_SCFG_CLK;
2405     reg_SCFG_CLK = (u16)(reg & ~REG_SCFG_CLK_CAMCKI_MASK);
2406     (void)OS_RestoreInterrupts(enabled);
2407     return (BOOL)((reg & REG_SCFG_CLK_CAMCKI_MASK) >> REG_SCFG_CLK_CAMCKI_SHIFT);
2408 }
CAMERAi_StartMasterClock(void)2409 static inline BOOL CAMERAi_StartMasterClock(void)
2410 {
2411     OSIntrMode enabled = OS_DisableInterrupts();
2412     u16  reg = reg_SCFG_CLK;
2413     reg_SCFG_CLK = (u16)(reg | REG_SCFG_CLK_CAMCKI_MASK);
2414     (void)OS_RestoreInterrupts(enabled);
2415     if ( (reg & REG_SCFG_CLK_CAMCKI_MASK) == 0 )
2416     {
2417         CAMERAi_Wait( 10 );
2418     }
2419     return (BOOL)((reg & REG_SCFG_CLK_CAMCKI_MASK) >> REG_SCFG_CLK_CAMCKI_SHIFT);
2420 }
2421 
2422 /*---------------------------------------------------------------------------*
2423   Name:         CameraSendPxiCommand
2424 
2425   Description:  Send specified leading command to ARM7 via PXI.
2426 
2427   Arguments:    command: Targeted command
2428                 size: Send data size (in bytes)
2429                 data: Leading data (only 1 byte)
2430 
2431   Returns:      BOOL: Returns TRUE if a send for PXI completed, and FALSE if send by PXI failed.
2432 
2433  *---------------------------------------------------------------------------*/
CameraSendPxiCommand(CAMERAPxiCommand command,u8 size,u8 data)2434 static BOOL CameraSendPxiCommand(CAMERAPxiCommand command, u8 size, u8 data)
2435 {
2436     u32 pxiData = (u32)(CAMERA_PXI_START_BIT |
2437             ((command << CAMERA_PXI_COMMAND_SHIFT) & CAMERA_PXI_COMMAND_MASK) |
2438             ((size << CAMERA_PXI_DATA_NUMS_SHIFT) & CAMERA_PXI_DATA_NUMS_MASK) |
2439             ((data << CAMERA_PXI_1ST_DATA_SHIFT) & CAMERA_PXI_1ST_DATA_MASK));
2440     cameraWork.last_state = CAMERAi_StartMasterClock();
2441     if (0 > PXI_SendWordByFifo(PXI_FIFO_TAG_CAMERA, pxiData, 0))
2442     {
2443         if ( cameraWork.last_state == FALSE )
2444         {
2445             (void)CAMERAi_StopMasterClock();
2446         }
2447         return FALSE;
2448     }
2449     return TRUE;
2450 }
2451 
2452 /*---------------------------------------------------------------------------*
2453   Name:         CameraSendPxiData
2454 
2455   Description:  Send specified subsequent data to ARM7 via PXI.
2456 
2457   Arguments:    pData: Pointer to top of 3-byte data
2458 
2459   Returns:      None.
2460  *---------------------------------------------------------------------------*/
CameraSendPxiData(u8 * pData)2461 static void CameraSendPxiData(u8 *pData)
2462 {
2463     u32 pxiData = (u32)((pData[0] << 16) | (pData[1] << 8) | pData[2]);
2464     while (0 > PXI_SendWordByFifo(PXI_FIFO_TAG_CAMERA, pxiData, 0))
2465     {
2466     }
2467 }
2468 
2469 /*---------------------------------------------------------------------------*
2470   Name:         CameraPxiCallback
2471 
2472   Description:  Common callback function for asynchronous RTC functions.
2473 
2474   Arguments:    tag: PXI tag that shows the message type
2475                 data: Message from ARM7
2476                 err: PXI transfer error flag
2477 
2478   Returns:      None.
2479  *---------------------------------------------------------------------------*/
CameraPxiCallback(PXIFifoTag tag,u32 data,BOOL err)2480 static void CameraPxiCallback(PXIFifoTag tag, u32 data, BOOL err)
2481 {
2482 #pragma unused( tag )
2483     CAMERAResult   result;
2484 
2485     // Verify PXI communication error
2486     if (err)
2487     {
2488         // Forcibly end sequence
2489         CameraCallCallbackAndUnlock(CAMERA_RESULT_FATAL_ERROR);
2490         return;
2491     }
2492     // Leading data
2493     if (data & CAMERA_PXI_START_BIT)
2494     {
2495         // Analyze received data
2496         SDK_ASSERT((data & CAMERA_PXI_RESULT_BIT) == CAMERA_PXI_RESULT_BIT);
2497         cameraWork.total = (u8)((data & CAMERA_PXI_DATA_NUMS_MASK) >> CAMERA_PXI_DATA_NUMS_SHIFT);
2498         cameraWork.current = 0;
2499         cameraWork.command = (CAMERAPxiCommand)((data & CAMERA_PXI_COMMAND_MASK) >> CAMERA_PXI_COMMAND_SHIFT);
2500         cameraWork.pxiResult = (CAMERAPxiResult)((data & CAMERA_PXI_1ST_DATA_MASK) >> CAMERA_PXI_1ST_DATA_SHIFT);
2501     }
2502     // Subsequent data
2503     else
2504     {
2505         if (cameraWork.data == NULL)
2506         {
2507             // Forcibly end sequence
2508             CameraCallCallbackAndUnlock(CAMERA_RESULT_FATAL_ERROR);
2509             return;
2510         }
2511         if (cameraWork.current < cameraWork.size)
2512         {
2513             cameraWork.data[cameraWork.current++] = (u8)((data & 0xFF0000) >> 16);
2514         }
2515         if (cameraWork.current < cameraWork.size)
2516         {
2517             cameraWork.data[cameraWork.current++] = (u8)((data & 0x00FF00) >> 8);
2518         }
2519         if (cameraWork.current < cameraWork.size)
2520         {
2521             cameraWork.data[cameraWork.current++] = (u8)((data & 0x0000FF) >> 0);
2522         }
2523     }
2524 
2525     if (cameraWork.current >= cameraWork.total-1)   // There should be no >
2526     {
2527         if (cameraWork.force_deactivate != FALSE || (cameraWork.force_activate == FALSE && cameraWork.last_state == FALSE))
2528         {
2529             (void)CAMERAi_StopMasterClock();
2530         }
2531         cameraWork.force_deactivate = cameraWork.force_activate = FALSE;
2532 
2533         // Check the result of processing
2534         switch (cameraWork.pxiResult)
2535         {
2536         case CAMERA_PXI_RESULT_SUCCESS:     // alias CAMERA_PXI_RESULT_SUCCESS_TRUE
2537             result = CAMERA_RESULT_SUCCESS; // alias CAMERA_RESULT_SUCCESS_TRUE
2538             // Processing was successful, so apply the changes to the structure for rebooting
2539             switch (cameraWork.command)
2540             {
2541             case CAMERA_PXI_COMMAND_ACTIVATE:
2542                 cameraWork.CAMERAiStateOut.blink = cameraWork.CAMERAiStateTmp.blink;
2543                 break;
2544             case CAMERA_PXI_COMMAND_CONTEXT_SWITCH:
2545                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_IN)
2546                     cameraWork.CAMERAiStateIn.context = cameraWork.CAMERAiStateTmp.context;
2547                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_OUT)
2548                     cameraWork.CAMERAiStateOut.context = cameraWork.CAMERAiStateTmp.context;
2549                 break;
2550             case CAMERA_PXI_COMMAND_SIZE:
2551                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_IN)
2552                     if(cameraWork.CAMERAiStateTmp.set_context & CAMERA_CONTEXT_A)
2553                         cameraWork.CAMERAiStateIn.size_A = cameraWork.CAMERAiStateTmp.size;
2554                     if(cameraWork.CAMERAiStateTmp.set_context & CAMERA_CONTEXT_B)
2555                         cameraWork.CAMERAiStateIn.size_B = cameraWork.CAMERAiStateTmp.size;
2556                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_OUT)
2557                     if(cameraWork.CAMERAiStateTmp.set_context & CAMERA_CONTEXT_A)
2558                         cameraWork.CAMERAiStateOut.size_A = cameraWork.CAMERAiStateTmp.size;
2559                     if(cameraWork.CAMERAiStateTmp.set_context & CAMERA_CONTEXT_B)
2560                         cameraWork.CAMERAiStateOut.size_B = cameraWork.CAMERAiStateTmp.size;
2561                 break;
2562             case CAMERA_PXI_COMMAND_FRAME_RATE:
2563                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_IN)
2564                     cameraWork.CAMERAiStateIn.rate = cameraWork.CAMERAiStateTmp.rate;
2565                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_OUT)
2566                     cameraWork.CAMERAiStateOut.rate = cameraWork.CAMERAiStateTmp.rate;
2567                 break;
2568             case CAMERA_PXI_COMMAND_EFFECT:
2569                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_IN)
2570                     if(cameraWork.CAMERAiStateTmp.set_context & CAMERA_CONTEXT_A)
2571                         cameraWork.CAMERAiStateIn.effect_A = cameraWork.CAMERAiStateTmp.effect;
2572                     if(cameraWork.CAMERAiStateTmp.set_context & CAMERA_CONTEXT_B)
2573                         cameraWork.CAMERAiStateIn.effect_B = cameraWork.CAMERAiStateTmp.effect;
2574                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_OUT)
2575                     if(cameraWork.CAMERAiStateTmp.set_context & CAMERA_CONTEXT_A)
2576                         cameraWork.CAMERAiStateOut.effect_A = cameraWork.CAMERAiStateTmp.effect;
2577                     if(cameraWork.CAMERAiStateTmp.set_context & CAMERA_CONTEXT_B)
2578                         cameraWork.CAMERAiStateOut.effect_B = cameraWork.CAMERAiStateTmp.effect;
2579                 break;
2580             case CAMERA_PXI_COMMAND_FLIP:
2581                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_IN)
2582                     if(cameraWork.CAMERAiStateTmp.set_context & CAMERA_CONTEXT_A)
2583                         cameraWork.CAMERAiStateIn.flip_A = cameraWork.CAMERAiStateTmp.flip;
2584                     if(cameraWork.CAMERAiStateTmp.set_context & CAMERA_CONTEXT_B)
2585                         cameraWork.CAMERAiStateIn.flip_B = cameraWork.CAMERAiStateTmp.flip;
2586                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_OUT)
2587                     if(cameraWork.CAMERAiStateTmp.set_context & CAMERA_CONTEXT_A)
2588                         cameraWork.CAMERAiStateOut.flip_A = cameraWork.CAMERAiStateTmp.flip;
2589                     if(cameraWork.CAMERAiStateTmp.set_context & CAMERA_CONTEXT_B)
2590                         cameraWork.CAMERAiStateOut.flip_B = cameraWork.CAMERAiStateTmp.flip;
2591                 break;
2592             case CAMERA_PXI_COMMAND_PHOTO_MODE:
2593                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_IN)
2594                 {
2595                     cameraWork.CAMERAiStateIn.photo = cameraWork.CAMERAiStateTmp.photo;
2596                     switch (cameraWork.CAMERAiStateIn.photo)
2597                     {
2598                     case CAMERA_PHOTO_MODE_NORMAL:
2599                         cameraWork.CAMERAiStateIn.sharpness = 0;
2600                         cameraWork.CAMERAiStateIn.exposure = 0;
2601                         cameraWork.CAMERAiStateIn.wb = CAMERA_WHITE_BALANCE_NORMAL;
2602                         break;
2603                     case CAMERA_PHOTO_MODE_PORTRAIT:
2604                         cameraWork.CAMERAiStateIn.sharpness = -2;
2605                         cameraWork.CAMERAiStateIn.exposure = 0;
2606                         cameraWork.CAMERAiStateIn.wb = CAMERA_WHITE_BALANCE_NORMAL;
2607                         break;
2608                     case CAMERA_PHOTO_MODE_LANDSCAPE:
2609                         cameraWork.CAMERAiStateIn.sharpness = 1;
2610                         cameraWork.CAMERAiStateIn.exposure = 0;
2611                         cameraWork.CAMERAiStateIn.wb = CAMERA_WHITE_BALANCE_DAYLIGHT;
2612                         break;
2613                     case CAMERA_PHOTO_MODE_NIGHTVIEW:
2614                         cameraWork.CAMERAiStateIn.sharpness = -1;
2615                         cameraWork.CAMERAiStateIn.exposure = 2;
2616                         cameraWork.CAMERAiStateIn.wb = CAMERA_WHITE_BALANCE_NORMAL;
2617                         break;
2618                     case CAMERA_PHOTO_MODE_LETTER:
2619                         cameraWork.CAMERAiStateIn.sharpness = 2;
2620                         cameraWork.CAMERAiStateIn.exposure = 2;
2621                         cameraWork.CAMERAiStateIn.wb = CAMERA_WHITE_BALANCE_NORMAL;
2622                         break;
2623                     }
2624                 }
2625                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_OUT)
2626                 {
2627                     cameraWork.CAMERAiStateOut.photo = cameraWork.CAMERAiStateTmp.photo;
2628                     switch (cameraWork.CAMERAiStateOut.photo)
2629                     {
2630                     case CAMERA_PHOTO_MODE_NORMAL:
2631                         cameraWork.CAMERAiStateOut.sharpness = 0;
2632                         cameraWork.CAMERAiStateOut.exposure = 0;
2633                         cameraWork.CAMERAiStateOut.wb = CAMERA_WHITE_BALANCE_NORMAL;
2634                         break;
2635                     case CAMERA_PHOTO_MODE_PORTRAIT:
2636                         cameraWork.CAMERAiStateOut.sharpness = -2;
2637                         cameraWork.CAMERAiStateOut.exposure = 0;
2638                         cameraWork.CAMERAiStateOut.wb = CAMERA_WHITE_BALANCE_NORMAL;
2639                         break;
2640                     case CAMERA_PHOTO_MODE_LANDSCAPE:
2641                         cameraWork.CAMERAiStateOut.sharpness = 1;
2642                         cameraWork.CAMERAiStateOut.exposure = 0;
2643                         cameraWork.CAMERAiStateOut.wb = CAMERA_WHITE_BALANCE_DAYLIGHT;
2644                         break;
2645                     case CAMERA_PHOTO_MODE_NIGHTVIEW:
2646                         cameraWork.CAMERAiStateOut.sharpness = -1;
2647                         cameraWork.CAMERAiStateOut.exposure = 2;
2648                         cameraWork.CAMERAiStateOut.wb = CAMERA_WHITE_BALANCE_NORMAL;
2649                         break;
2650                     case CAMERA_PHOTO_MODE_LETTER:
2651                         cameraWork.CAMERAiStateOut.sharpness = 2;
2652                         cameraWork.CAMERAiStateOut.exposure = 2;
2653                         cameraWork.CAMERAiStateOut.wb = CAMERA_WHITE_BALANCE_NORMAL;
2654                         break;
2655                     }
2656                 }
2657                 break;
2658             case CAMERA_PXI_COMMAND_WHITE_BALANCE:
2659                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_IN)
2660                 {
2661                     cameraWork.CAMERAiStateIn.wb = cameraWork.CAMERAiStateTmp.wb;
2662                     cameraWork.CAMERAiStateIn.awb = TRUE;
2663                 }
2664                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_OUT)
2665                 {
2666                     cameraWork.CAMERAiStateOut.wb = cameraWork.CAMERAiStateTmp.wb;
2667                     cameraWork.CAMERAiStateOut.awb = TRUE;
2668                 }
2669                 break;
2670             case CAMERA_PXI_COMMAND_EXPOSURE:
2671                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_IN)
2672                     cameraWork.CAMERAiStateIn.exposure = cameraWork.CAMERAiStateTmp.exposure;
2673                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_OUT)
2674                     cameraWork.CAMERAiStateOut.exposure = cameraWork.CAMERAiStateTmp.exposure;
2675                 break;
2676             case CAMERA_PXI_COMMAND_SHARPNESS:
2677                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_IN)
2678                     cameraWork.CAMERAiStateIn.sharpness = cameraWork.CAMERAiStateTmp.sharpness;
2679                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_OUT)
2680                     cameraWork.CAMERAiStateOut.sharpness = cameraWork.CAMERAiStateTmp.sharpness;
2681                 break;
2682             case CAMERA_PXI_COMMAND_AUTO_EXPOSURE:
2683                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_IN)
2684                     cameraWork.CAMERAiStateIn.ae = cameraWork.CAMERAiStateTmp.ae;
2685                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_OUT)
2686                     cameraWork.CAMERAiStateOut.ae = cameraWork.CAMERAiStateTmp.ae;
2687                 break;
2688             case CAMERA_PXI_COMMAND_AUTO_WHITE_BALANCE:
2689                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_IN)
2690                     cameraWork.CAMERAiStateIn.awb = cameraWork.CAMERAiStateTmp.awb;
2691                 if(cameraWork.CAMERAiStateTmp.set_camera & CAMERA_SELECT_OUT)
2692                     cameraWork.CAMERAiStateOut.awb = cameraWork.CAMERAiStateTmp.awb;
2693                 break;
2694             case CAMERA_PXI_COMMAND_SET_LED:
2695                 cameraWork.CAMERAiStateOut.blink = cameraWork.CAMERAiStateTmp.blink;
2696                 break;
2697             default:
2698                 break;
2699             }
2700             break;
2701         case CAMERA_PXI_RESULT_SUCCESS_FALSE:
2702             result = CAMERA_RESULT_SUCCESS_FALSE;
2703             break;
2704         case CAMERA_PXI_RESULT_ILLEGAL_STATUS:
2705             result = CAMERA_RESULT_ILLEGAL_STATUS;
2706             break;
2707         case CAMERA_PXI_RESULT_INVALID_COMMAND:
2708         case CAMERA_PXI_RESULT_INVALID_PARAMETER:
2709         case CAMERA_PXI_RESULT_BUSY:
2710         default:
2711             result = CAMERA_RESULT_FATAL_ERROR;
2712         }
2713 
2714         // Call the callback
2715         CameraCallCallbackAndUnlock(result);
2716 
2717         // Start the reboot routine after CAMERA_RESULT_ILLEGAL_STATUS
2718         if(result == CAMERA_RESULT_ILLEGAL_STATUS)
2719         {
2720 //OS_TPrintf("Send message to reboot from PXI.\n");
2721             CAMERA_GoReboot();
2722         }
2723     }
2724 }
2725 
2726 /*---------------------------------------------------------------------------*
2727   Name:         CameraSyncCallback
2728 
2729   Description:  Callback for synchronous API.
2730 
2731   Arguments:    result: Result sent from ARM7
2732                 arg: Unused
2733 
2734   Returns:      None.
2735  *---------------------------------------------------------------------------*/
CameraSyncCallback(CAMERAResult result,void * arg)2736 static void CameraSyncCallback(CAMERAResult result, void *arg)
2737 {
2738 #pragma unused(arg)
2739     cameraWork.result = result;
2740 }
2741 
2742 /*---------------------------------------------------------------------------*
2743   Name:         CameraCallCallbackAndUnlock
2744 
2745   Description:  Calls the callback and unlocks the camera processing.
2746 
2747   Arguments:    result: Result sent from ARM7
2748 
2749   Returns:      None.
2750  *---------------------------------------------------------------------------*/
CameraCallCallbackAndUnlock(CAMERAResult result)2751 static void CameraCallCallbackAndUnlock(CAMERAResult result)
2752 {
2753     CAMERACallback cb;
2754 
2755     if (cameraWork.lock)
2756     {
2757         cameraWork.lock = FALSE;
2758     }
2759     if (cameraWork.callback)
2760     {
2761         cb = cameraWork.callback;
2762         cameraWork.callback = NULL;
2763         cb(result, cameraWork.callbackArg);
2764     }
2765 }
2766 
2767 /*---------------------------------------------------------------------------*
2768   Name:         CameraWaitBusy
2769 
2770   Description:  Wait while asynchronous processing for camera is locked.
2771 
2772   Arguments:    None.
2773 
2774   Returns:      None.
2775  *---------------------------------------------------------------------------*/
2776 #if 0
2777 #include    <nitro/code32.h>
2778 static asm void CameraWaitBusy(void)
2779 {
2780     ldr     r12,    =cameraWork.lock
2781 loop:
2782     ldr     r0,     [ r12,  #0 ]
2783     cmp     r0,     #TRUE
2784     beq     loop
2785     bx      lr
2786 }
2787 #include    <nitro/codereset.h>
2788 #else
2789 extern void PXIi_HandlerRecvFifoNotEmpty(void);
CameraWaitBusy(void)2790 static void CameraWaitBusy(void)
2791 {
2792     volatile BOOL *p = &cameraWork.lock;
2793 
2794     while (*p)
2795     {
2796         if (OS_GetCpsrIrq() == OS_INTRMODE_IRQ_DISABLE || OS_GetIrq() == OS_IME_DISABLE)
2797         {
2798             PXIi_HandlerRecvFifoNotEmpty();
2799         }
2800     }
2801 }
2802 #endif
2803 
2804 /*---------------------------------------------------------------------------*
2805   Name:         CameraStandbyCallback
2806 
2807   Description:  Set camera to standby.
2808 
2809   Arguments:    arg: Unused
2810 
2811   Returns:      None.
2812  *---------------------------------------------------------------------------*/
CameraStandbyCallback(void * args)2813 static void CameraStandbyCallback(void* args)
2814 {
2815 #pragma unused(args)
2816     (void)CAMERA_I2CActivateCore(CAMERA_SELECT_NONE);
2817 }
2818