1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - library - camera
3   File:     camera.c
4 
5   Copyright 2007-2008 Nintendo. All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law. They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Date:: 2008-09-26#$
14   $Rev: 8691 $
15   $Author: yutaka $
16  *---------------------------------------------------------------------------*/
17 #include <twl.h>
18 #include <twl/camera.h>
19 
20 #include "camera_intr.h"
21 
22 /*---------------------------------------------------------------------------*
23     Constant Definitions
24  *---------------------------------------------------------------------------*/
25 #define SYNC_TYPE   (0 << REG_CAM_MCNT_SYNC_SHIFT)  // 1 if low active
26 #define RCLK_TYPE   (0 << REG_CAM_MCNT_IRCLK_SHIFT) // 1 if negative edge
27 
28 #define RESET_ON    ( SYNC_TYPE | RCLK_TYPE )
29 #define RESET_OFF   ( REG_CAM_MCNT_VIO_MASK | REG_CAM_MCNT_RST_MASK | SYNC_TYPE | RCLK_TYPE ) // RST is only for TS-X2
30 
31 /*---------------------------------------------------------------------------*
32     Type Definitions
33  *---------------------------------------------------------------------------*/
34 
35 /*---------------------------------------------------------------------------*
36     Static Variable Definitions
37  *---------------------------------------------------------------------------*/
38 
39 /*---------------------------------------------------------------------------*
40     Internal Function Definitions
41  *---------------------------------------------------------------------------*/
CAMERAi_Wait(u32 clocks)42 static inline void CAMERAi_Wait(u32 clocks)
43 {
44     OS_SpinWaitSysCycles(clocks << 1);
45 }
46 
47 /*---------------------------------------------------------------------------*
48   Name:         CAMERA_Reset
49 
50   Description:  Hardware reset before I2C access.
51 
52   Arguments:    None.
53 
54   Returns:      None.
55  *---------------------------------------------------------------------------*/
CAMERA_ResetCore(void)56 void CAMERA_ResetCore( void )
57 {
58     reg_SCFG_CLK |= REG_SCFG_CLK_CAMHCLK_MASK;  // ensure powered on
59 
60     reg_CAM_MCNT = RESET_ON;                    // hardware reset
61     CAMERAi_Wait( 15 );
62     reg_SCFG_CLK |= REG_SCFG_CLK_CAMCKI_MASK;   // clock out to read internal ROM code
63     CAMERAi_Wait( 15 );
64     reg_CAM_MCNT = RESET_OFF;                   // reset off
65     CAMERAi_Wait( 4100 );                       // wait to done to read internal ROM code
66 
67     reg_SCFG_CLK &= ~REG_SCFG_CLK_CAMCKI_MASK;  // stop to clock
68 }
69 
70 /*---------------------------------------------------------------------------*
71   Name:         CAMERA_IsBusy
72 
73   Description:  Determine availability of camera.
74 
75   Arguments:    None.
76 
77   Returns:      TRUE if camera is busy.
78  *---------------------------------------------------------------------------*/
CAMERA_IsBusyCore(void)79 BOOL CAMERA_IsBusyCore( void )
80 {
81     return (reg_CAM_CNT & REG_CAM_CNT_E_MASK) >> REG_CAM_CNT_E_SHIFT;
82 }
83 
84 /*---------------------------------------------------------------------------*
85   Name:         CAMERA_StartCapture
86 
87   Description:  Start receiving camera data.
88 
89   Arguments:    None.
90 
91   Returns:      None.
92  *---------------------------------------------------------------------------*/
CAMERA_StartCaptureCore(void)93 void CAMERA_StartCaptureCore( void )
94 {
95     reg_CAM_CNT |= REG_CAM_CNT_E_MASK;
96 }
97 
98 /*---------------------------------------------------------------------------*
99   Name:         CAMERA_StopCapture
100 
101   Description:  Stop receiving camera data.
102 
103   Arguments:    None.
104 
105   Returns:      None.
106  *---------------------------------------------------------------------------*/
CAMERA_StopCaptureCore(void)107 void CAMERA_StopCaptureCore( void )
108 {
109     reg_CAM_CNT &= ~REG_CAM_CNT_E_MASK;
110 }
111 
112 /*---------------------------------------------------------------------------*
113   Name:         CAMERA_SetTrimmingParamsCenter
114 
115   Description:  Set camera trimming parameters by centering.
116                 NOTE: Call CAMERA_SetTrimming to enable trimming.
117 
118   Arguments:    destWidth: Width of image to output
119                 destHeight: Height of image to output
120                 srcWidth: Original width of image
121                 srcHeight: Original height of image
122 
123   Returns:      None.
124  *---------------------------------------------------------------------------*/
CAMERA_SetTrimmingParamsCenterCore(u16 destWidth,u16 destHeight,u16 srcWidth,u16 srcHeight)125 void CAMERA_SetTrimmingParamsCenterCore(u16 destWidth, u16 destHeight, u16 srcWidth, u16 srcHeight)
126 {
127     if( (destWidth > srcWidth)||(destHeight > srcHeight) ) //Trimming range is outside of original image
128     {
129         return;
130     }
131 
132     destWidth -= 2;
133     destHeight -= 1;
134     reg_CAM_SOFS = REG_CAM_SOFS_FIELD( (srcHeight-destHeight) >> 1, (srcWidth-destWidth) >> 1);
135     reg_CAM_EOFS = REG_CAM_EOFS_FIELD( (srcHeight+destHeight) >> 1, (srcWidth+destWidth) >> 1);
136 }
137 
138 /*---------------------------------------------------------------------------*
139   Name:         CAMERA_SetTrimmingParams
140 
141   Description:  Set camera trimming parameters.
142                 NOTE: Width = x2 - x1;  Height = y2 - y1.
143                 NOTE: Call CAMERA_SetTrimming to enable trimming
144 
145   Arguments:    x1: X-coordinate of top-left trimming point (multiple of 2)
146                 y1: Y-coordinate of top-left trimming point
147                 x2: X-coordinate of bottom-right trimming point (multiple of 2)
148                 y2: Y-coordinate of bottom-right trimming point
149 
150   Returns:      None.
151  *---------------------------------------------------------------------------*/
CAMERA_SetTrimmingParamsCore(u16 x1,u16 y1,u16 x2,u16 y2)152 void CAMERA_SetTrimmingParamsCore(u16 x1, u16 y1, u16 x2, u16 y2)
153 {
154     if( (x1 > x2)||(y1 > y2) ) // The ending position offset is smaller than the starting position offset
155     {
156         return;
157     }
158     // Behavior when the ending position is out of the range of the original image is described in the function reference.
159     // Behavior when the starting position is out of the range of the original image is described in the function reference.
160 
161     reg_CAM_SOFS = REG_CAM_SOFS_FIELD( y1, x1 );
162     reg_CAM_EOFS = REG_CAM_EOFS_FIELD( y2 - 1, x2 -2 );
163 }
164 
165 /*---------------------------------------------------------------------------*
166   Name:         CAMERA_GetTrimmingParams
167 
168   Description:  Get camera trimming parameters.
169                 NOTE: Width = x2 - x1;  Height = y2 - y1.
170                 NOTE: Call CAMERA_SetTrimming to enable trimming.
171 
172   Arguments:    x1: X-coordinate of top-left trimming point (multiple of 2)
173                 y1: Y-coordinate of top-left trimming point
174                 x2: X-coordinate of bottom-right trimming point (multiple of 2)
175                 y2: Y-coordinate of bottom-right trimming point
176 
177   Returns:      None.
178  *---------------------------------------------------------------------------*/
CAMERA_GetTrimmingParamsCore(u16 * x1,u16 * y1,u16 * x2,u16 * y2)179 void CAMERA_GetTrimmingParamsCore(u16* x1, u16* y1, u16* x2, u16* y2)
180 {
181     *x1 = (u16)((reg_CAM_SOFS & REG_CAM_SOFS_HOFS_MASK) >> REG_CAM_SOFS_HOFS_SHIFT);
182     *y1 = (u16)((reg_CAM_SOFS & REG_CAM_SOFS_VOFS_MASK) >> REG_CAM_SOFS_VOFS_SHIFT);
183     *x2 = (u16)(((reg_CAM_EOFS & REG_CAM_EOFS_HOFS_MASK) >> REG_CAM_EOFS_HOFS_SHIFT) + 2);
184     *y2 = (u16)(((reg_CAM_EOFS & REG_CAM_EOFS_VOFS_MASK) >> REG_CAM_EOFS_VOFS_SHIFT) + 1);
185 }
186 
187 /*---------------------------------------------------------------------------*
188   Name:         CAMERA_SetTrimming
189 
190   Description:  Set trimming to be enabled/disabled.
191 
192   Arguments:    enabled: TRUE if set trimming will be enabled
193 
194   Returns:      None.
195  *---------------------------------------------------------------------------*/
CAMERA_SetTrimmingCore(BOOL enabled)196 void CAMERA_SetTrimmingCore( BOOL enabled )
197 {
198     u16 value = reg_CAM_CNT;
199     reg_CAM_CNT = (u16)(enabled ? (value | REG_CAM_CNT_T_MASK)
200                                 : (value & ~REG_CAM_CNT_T_MASK));
201 }
202 
203 /*---------------------------------------------------------------------------*
204   Name:         CAMERA_IsTrimming
205 
206   Description:  Get whether trimming will be enabled/disabled
207 
208   Arguments:    None.
209 
210   Returns:      TRUE if set trimming will be enabled
211  *---------------------------------------------------------------------------*/
CAMERA_IsTrimmingCore(void)212 BOOL CAMERA_IsTrimmingCore( void )
213 {
214     return ((reg_CAM_CNT & REG_CAM_CNT_T_MASK) >> REG_CAM_CNT_T_SHIFT);
215 }
216 
217 /*---------------------------------------------------------------------------*
218   Name:         CAMERA_SetOutputFormat
219 
220   Description:  Set camera output format.
221 
222   Arguments:    output: One of the CAMERAOutput values
223 
224   Returns:      None.
225  *---------------------------------------------------------------------------*/
CAMERA_SetOutputFormatCore(CAMERAOutput output)226 void CAMERA_SetOutputFormatCore( CAMERAOutput output )
227 {
228     u16 value = reg_CAM_CNT;
229     switch (output)
230     {
231     case CAMERA_OUTPUT_YUV:
232         reg_CAM_CNT = (u16)(value & ~REG_CAM_CNT_F_MASK);
233         break;
234     case CAMERA_OUTPUT_RGB:
235         reg_CAM_CNT = (u16)(value | REG_CAM_CNT_F_MASK);
236         break;
237     }
238 }
239 
240 /*---------------------------------------------------------------------------*
241   Name:         CAMERA_GetOutputFormat
242 
243   Description:  Get camera output format.
244 
245   Arguments:    None.
246 
247   Returns:      One of the CAMERAOutput values.
248  *---------------------------------------------------------------------------*/
CAMERA_GetOutputFormatCore(void)249 CAMERAOutput CAMERA_GetOutputFormatCore( void )
250 {
251     return (reg_CAM_CNT & REG_CAM_CNT_F_MASK) ? CAMERA_OUTPUT_RGB : CAMERA_OUTPUT_YUV;
252 }
253 
254 /*---------------------------------------------------------------------------*
255   Name:         CAMERA_GetErrorStatus
256 
257   Description:  Determines whether a line-buffer error has occurred
258 
259   Arguments:    None.
260 
261   Returns:      TRUE if an error has occurred
262  *---------------------------------------------------------------------------*/
CAMERA_GetErrorStatusCore(void)263 BOOL CAMERA_GetErrorStatusCore( void )
264 {
265     return (reg_CAM_CNT & REG_CAM_CNT_ERR_MASK) >> REG_CAM_CNT_ERR_SHIFT;
266 }
267 
268 /*---------------------------------------------------------------------------*
269   Name:         CAMERA_ClearBuffer
270 
271   Description:  Clear line buffer and error status.
272 
273   Arguments:    None.
274 
275   Returns:      None.
276  *---------------------------------------------------------------------------*/
CAMERA_ClearBufferCore(void)277 void CAMERA_ClearBufferCore( void )
278 {
279     reg_CAM_CNT |= REG_CAM_CNT_CL_MASK;
280 }
281 
282 /*---------------------------------------------------------------------------*
283   Name:         CAMERA_SetMasterInterrupt
284 
285   Description:  Set interrupt mode.
286 
287   Arguments:    enabled: TRUE if set master interrupt will be enabled
288 
289   Returns:      None.
290  *---------------------------------------------------------------------------*/
CAMERA_SetMasterInterruptCore(BOOL enabled)291 void CAMERA_SetMasterInterruptCore( BOOL enabled )
292 {
293     u16 value = reg_CAM_CNT;
294     reg_CAM_CNT = (u16)(enabled ? (value | REG_CAM_CNT_IREQI_MASK)
295                                 : (value & ~REG_CAM_CNT_IREQI_MASK));
296 }
297 
298 /*---------------------------------------------------------------------------*
299   Name:         CAMERA_GetMasterInterrupt
300 
301   Description:  Get interrupt mode.
302 
303   Arguments:    None.
304 
305   Returns:      TRUE if set master interrupt will be enabled.
306  *---------------------------------------------------------------------------*/
CAMERA_GetMasterInterruptCore(void)307 BOOL CAMERA_GetMasterInterruptCore( void )
308 {
309     return ((reg_CAM_CNT & REG_CAM_CNT_IREQI_MASK) >> REG_CAM_CNT_IREQI_SHIFT);
310 }
311 
312 /*---------------------------------------------------------------------------*
313   Name:         CAMERA_SetVsyncInterrupt
314 
315   Description:  Set vsync interrupt mode.
316 
317   Arguments:    type: One of the CAMERAIntrVsync values
318 
319   Returns:      None.
320  *---------------------------------------------------------------------------*/
CAMERA_SetVsyncInterruptCore(CAMERAIntrVsync type)321 void CAMERA_SetVsyncInterruptCore( CAMERAIntrVsync type )
322 {
323     reg_CAM_CNT = (u16)((reg_CAM_CNT & ~REG_CAM_CNT_IREQVS_MASK) | type);
324 }
325 
326 /*---------------------------------------------------------------------------*
327   Name:         CAMERA_GetVsyncInterrupt
328 
329   Description:  Get vsync interrupt mode.
330 
331   Arguments:    None.
332 
333   Returns:      One of the CAMERAIntrVsync values.
334  *---------------------------------------------------------------------------*/
CAMERA_GetVsyncInterruptCore(void)335 CAMERAIntrVsync CAMERA_GetVsyncInterruptCore( void )
336 {
337     return (CAMERAIntrVsync)(reg_CAM_CNT & REG_CAM_CNT_IREQVS_MASK);
338 }
339 
340 /*---------------------------------------------------------------------------*
341   Name:         CAMERA_SetBufferErrorInterrupt
342 
343   Description:  Set buffer error interrupt mode.
344 
345   Arguments:    enabled: TRUE if set buffer error interrupt will be enabled
346 
347   Returns:      None.
348  *---------------------------------------------------------------------------*/
CAMERA_SetBufferErrorInterruptCore(BOOL enabled)349 void CAMERA_SetBufferErrorInterruptCore( BOOL enabled )
350 {
351     u16 value = reg_CAM_CNT;
352     reg_CAM_CNT = (u16)(enabled ? (value | REG_CAM_CNT_IREQBE_MASK)
353                                 : (value & ~REG_CAM_CNT_IREQBE_MASK));
354 }
355 
356 /*---------------------------------------------------------------------------*
357   Name:         CAMERA_GetBufferErrorInterrupt
358 
359   Description:  Get buffer error interrupt mode.
360 
361   Arguments:    None.
362 
363   Returns:      TRUE if set buffer error interrupt will be enabled.
364  *---------------------------------------------------------------------------*/
CAMERA_GetBufferErrorInterruptCore(void)365 BOOL CAMERA_GetBufferErrorInterruptCore( void )
366 {
367     return ((reg_CAM_CNT & REG_CAM_CNT_IREQBE_MASK) >> REG_CAM_CNT_IREQBE_SHIFT);
368 }
369 
370 /*---------------------------------------------------------------------------*
371   Name:         CAMERA_SetTransferLines
372 
373   Description:  Set the number of lines to store in the buffer.
374 
375   Arguments:    lines: Number of lines
376 
377   Returns:      None.
378  *---------------------------------------------------------------------------*/
CAMERA_SetTransferLinesCore(int lines)379 void CAMERA_SetTransferLinesCore( int lines )
380 {
381     if (lines >= 1 && lines <= 16)
382     {
383         u16 bits = (u16)((lines - 1) << REG_CAM_CNT_TL_SHIFT);
384         reg_CAM_CNT = (u16)((reg_CAM_CNT & ~REG_CAM_CNT_TL_MASK) | bits);
385     }
386 }
387 
388 /*---------------------------------------------------------------------------*
389   Name:         CAMERA_GetTransferLines
390 
391   Description:  Get number of lines to load from the buffer.
392 
393   Arguments:    None.
394 
395   Returns:      Number of lines.
396  *---------------------------------------------------------------------------*/
CAMERA_GetTransferLinesCore(void)397 int CAMERA_GetTransferLinesCore( void )
398 {
399     return ( ((reg_CAM_CNT & REG_CAM_CNT_TL_MASK) >> REG_CAM_CNT_TL_SHIFT) + 1);
400 }
401 
402 /*---------------------------------------------------------------------------*
403   Name:         CAMERA_GetMaxLinesRound
404 
405   Description:  Rounding CAMERA_GET_MAX_LINES.
406 
407   Arguments:    Width: Width of image
408                 Height: Height of image
409 
410   Returns:      Max lines.
411  *---------------------------------------------------------------------------*/
CAMERA_GetMaxLinesRoundCore(u16 width,u16 height)412 int CAMERA_GetMaxLinesRoundCore(u16 width, u16 height)
413 {
414     int lines;
415 
416     for(lines = CAMERA_GET_MAX_LINES(width) ;lines > 1; lines--)
417     {
418         if( height % lines == 0 )
419         {
420             return lines;
421         }
422     }
423     return 1;
424 }
425 
426 /*---------------------------------------------------------------------------*
427   Name:         CAMERA_GetBytesAtOnce
428 
429   Description:  Find the single transfer size when receiving frame data from the camera buffer.
430 
431   Arguments:    width: Width of image
432 
433   Returns:      Unit.
434  *---------------------------------------------------------------------------*/
CAMERA_GetBytesAtOnceCore(u16 width)435 u32 CAMERA_GetBytesAtOnceCore(u16 width)
436 {
437     return (u32)( CAMERA_GET_LINE_BYTES(width) * CAMERA_GetTransferLinesCore() );
438 }
439