1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - library - camera
3   File:     camera.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-04#$
14   $Rev: 10698 $
15   $Author: okubata_ryoma $
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;  // Reliably turn on the power
59 
60     reg_CAM_MCNT = RESET_ON;                    // Hardware reset
61     CAMERAi_Wait( 15 );
62     reg_SCFG_CLK |= REG_SCFG_CLK_CAMCKI_MASK;   // Provide a clock to the camera module for reading internal ROM code
63     CAMERAi_Wait( 15 );
64     reg_CAM_MCNT = RESET_OFF;                   // Cancel the reset state
65     CAMERAi_Wait( 4100 );                       // Wait for internal ROM code to be read
66 
67     reg_SCFG_CLK &= ~REG_SCFG_CLK_CAMCKI_MASK;  // Disable CAM_CKI
68 }
69 
70 /*---------------------------------------------------------------------------*
71   Name:         CAMERA_IsBusy
72 
73   Description:  Determines 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:  Starts receiving camera data.
88 
89   Arguments:    None.
90 
91   Returns:      None.
92  *---------------------------------------------------------------------------*/
CAMERA_StartCaptureCore(void)93 void CAMERA_StartCaptureCore( void )
94 {
95     OSIntrMode old = OS_DisableInterrupts();
96     reg_CAM_CNT |= REG_CAM_CNT_E_MASK;
97     (void)OS_RestoreInterrupts(old);
98 }
99 
100 /*---------------------------------------------------------------------------*
101   Name:         CAMERA_StopCapture
102 
103   Description:  Stops receiving camera data.
104 
105   Arguments:    None.
106 
107   Returns:      None.
108  *---------------------------------------------------------------------------*/
CAMERA_StopCaptureCore(void)109 void CAMERA_StopCaptureCore( void )
110 {
111     OSIntrMode old = OS_DisableInterrupts();
112     reg_CAM_CNT &= ~REG_CAM_CNT_E_MASK;
113     (void)OS_RestoreInterrupts(old);
114 }
115 
116 /*---------------------------------------------------------------------------*
117   Name:         CAMERA_SetTrimmingParamsCenter
118 
119   Description:  Sets camera trimming parameters by centering.
120                 Note: Call CAMERA_SetTrimming to enable trimming.
121 
122   Arguments:    destWidth: Width of image to output
123                 destHeight: Height of image to output
124                 srcWidth: Original width of image
125                 srcHeight: Original height of image
126 
127   Returns:      None.
128  *---------------------------------------------------------------------------*/
CAMERA_SetTrimmingParamsCenterCore(u16 destWidth,u16 destHeight,u16 srcWidth,u16 srcHeight)129 void CAMERA_SetTrimmingParamsCenterCore(u16 destWidth, u16 destHeight, u16 srcWidth, u16 srcHeight)
130 {
131     if( (destWidth > srcWidth)||(destHeight > srcHeight) ) //Trimming range is outside original image
132     {
133         return;
134     }
135 
136     destWidth -= 2;
137     destHeight -= 1;
138     reg_CAM_SOFS = REG_CAM_SOFS_FIELD( (srcHeight-destHeight) >> 1, (srcWidth-destWidth) >> 1);
139     reg_CAM_EOFS = REG_CAM_EOFS_FIELD( (srcHeight+destHeight) >> 1, (srcWidth+destWidth) >> 1);
140 }
141 
142 /*---------------------------------------------------------------------------*
143   Name:         CAMERA_SetTrimmingParams
144 
145   Description:  Sets camera trimming parameters.
146                 Note: width = x2 - x1;  height = y2 - y1;
147                 Note: Call CAMERA_SetTrimming to enable trimming.
148 
149   Arguments:    x1: X-coordinate of top-left trimming point (multiple of 2)
150                 y1: Y-coordinate of top-left trimming point
151                 x2: X-coordinate of bottom-right trimming point (multiple of 2)
152                 y2: Y-coordinate of bottom-right trimming point
153 
154   Returns:      None.
155  *---------------------------------------------------------------------------*/
CAMERA_SetTrimmingParamsCore(u16 x1,u16 y1,u16 x2,u16 y2)156 void CAMERA_SetTrimmingParamsCore(u16 x1, u16 y1, u16 x2, u16 y2)
157 {
158     if( (x1 > x2)||(y1 > y2) ) // The ending position offset is smaller than the starting position offset
159     {
160         return;
161     }
162     // Behavior when the ending position is out of the range of the original image is described in the function reference.
163     // Behavior when the starting position is out of the range of the original image is described in the function reference.
164 
165     reg_CAM_SOFS = REG_CAM_SOFS_FIELD( y1, x1 );
166     reg_CAM_EOFS = REG_CAM_EOFS_FIELD( y2 - 1, x2 -2 );
167 }
168 
169 /*---------------------------------------------------------------------------*
170   Name:         CAMERA_GetTrimmingParams
171 
172   Description:  Gets camera trimming parameters.
173                 Note: width = x2 - x1;  height = y2 - y1;
174                 Note: Call CAMERA_SetTrimming to enable trimming.
175 
176   Arguments:    x1: X-coordinate of top-left trimming point (multiple of 2)
177                 y1: Y-coordinate of top-left trimming point
178                 x2: X-coordinate of bottom-right trimming point (multiple of 2)
179                 y2: Y-coordinate of bottom-right trimming point
180 
181   Returns:      None.
182  *---------------------------------------------------------------------------*/
CAMERA_GetTrimmingParamsCore(u16 * x1,u16 * y1,u16 * x2,u16 * y2)183 void CAMERA_GetTrimmingParamsCore(u16* x1, u16* y1, u16* x2, u16* y2)
184 {
185     *x1 = (u16)((reg_CAM_SOFS & REG_CAM_SOFS_HOFS_MASK) >> REG_CAM_SOFS_HOFS_SHIFT);
186     *y1 = (u16)((reg_CAM_SOFS & REG_CAM_SOFS_VOFS_MASK) >> REG_CAM_SOFS_VOFS_SHIFT);
187     *x2 = (u16)(((reg_CAM_EOFS & REG_CAM_EOFS_HOFS_MASK) >> REG_CAM_EOFS_HOFS_SHIFT) + 2);
188     *y2 = (u16)(((reg_CAM_EOFS & REG_CAM_EOFS_VOFS_MASK) >> REG_CAM_EOFS_VOFS_SHIFT) + 1);
189 }
190 
191 /*---------------------------------------------------------------------------*
192   Name:         CAMERA_SetTrimming
193 
194   Description:  Sets trimming to be enabled/disabled.
195 
196   Arguments:    enabled: TRUE if set trimming will be enabled
197 
198   Returns:      None.
199  *---------------------------------------------------------------------------*/
CAMERA_SetTrimmingCore(BOOL enabled)200 void CAMERA_SetTrimmingCore( BOOL enabled )
201 {
202     OSIntrMode old = OS_DisableInterrupts();
203     u16 value = reg_CAM_CNT;
204     reg_CAM_CNT = (u16)(enabled ? (value | REG_CAM_CNT_T_MASK)
205                                 : (value & ~REG_CAM_CNT_T_MASK));
206     (void)OS_RestoreInterrupts(old);
207 }
208 
209 /*---------------------------------------------------------------------------*
210   Name:         CAMERA_IsTrimming
211 
212   Description:  Gets whether trimming will be enabled/disabled.
213 
214   Arguments:    None.
215 
216   Returns:      TRUE if set trimming will be enabled.
217  *---------------------------------------------------------------------------*/
CAMERA_IsTrimmingCore(void)218 BOOL CAMERA_IsTrimmingCore( void )
219 {
220     return ((reg_CAM_CNT & REG_CAM_CNT_T_MASK) >> REG_CAM_CNT_T_SHIFT);
221 }
222 
223 /*---------------------------------------------------------------------------*
224   Name:         CAMERA_SetOutputFormat
225 
226   Description:  Sets camera output format.
227 
228   Arguments:    output: One of the CAMERAOutput values
229 
230   Returns:      None.
231  *---------------------------------------------------------------------------*/
CAMERA_SetOutputFormatCore(CAMERAOutput output)232 void CAMERA_SetOutputFormatCore( CAMERAOutput output )
233 {
234     OSIntrMode old = OS_DisableInterrupts();
235     u16 value = reg_CAM_CNT;
236     switch (output)
237     {
238     case CAMERA_OUTPUT_YUV:
239         reg_CAM_CNT = (u16)(value & ~REG_CAM_CNT_F_MASK);
240         break;
241     case CAMERA_OUTPUT_RGB:
242         reg_CAM_CNT = (u16)(value | REG_CAM_CNT_F_MASK);
243         break;
244     }
245     (void)OS_RestoreInterrupts(old);
246 }
247 
248 /*---------------------------------------------------------------------------*
249   Name:         CAMERA_GetOutputFormat
250 
251   Description:  Gets CAMERA output format.
252 
253   Arguments:    None.
254 
255   Returns:      One of the CAMERAOutput values.
256  *---------------------------------------------------------------------------*/
CAMERA_GetOutputFormatCore(void)257 CAMERAOutput CAMERA_GetOutputFormatCore( void )
258 {
259     return (reg_CAM_CNT & REG_CAM_CNT_F_MASK) ? CAMERA_OUTPUT_RGB : CAMERA_OUTPUT_YUV;
260 }
261 
262 /*---------------------------------------------------------------------------*
263   Name:         CAMERA_GetErrorStatus
264 
265   Description:  Determines whether a line-buffer error has occurred.
266 
267   Arguments:    None.
268 
269   Returns:      TRUE if an error has occurred.
270  *---------------------------------------------------------------------------*/
CAMERA_GetErrorStatusCore(void)271 BOOL CAMERA_GetErrorStatusCore( void )
272 {
273     return (reg_CAM_CNT & REG_CAM_CNT_ERR_MASK) >> REG_CAM_CNT_ERR_SHIFT;
274 }
275 
276 /*---------------------------------------------------------------------------*
277   Name:         CAMERA_ClearBuffer
278 
279   Description:  Clears line buffer and error status.
280 
281   Arguments:    None.
282 
283   Returns:      None.
284  *---------------------------------------------------------------------------*/
CAMERA_ClearBufferCore(void)285 void CAMERA_ClearBufferCore( void )
286 {
287     OSIntrMode old = OS_DisableInterrupts();
288     reg_CAM_CNT |= REG_CAM_CNT_CL_MASK;
289     (void)OS_RestoreInterrupts(old);
290 }
291 
292 /*---------------------------------------------------------------------------*
293   Name:         CAMERA_SetMasterInterrupt
294 
295   Description:  Sets interrupt mode.
296 
297   Arguments:    enabled: TRUE if set master interrupt will be enabled
298 
299   Returns:      None.
300  *---------------------------------------------------------------------------*/
CAMERA_SetMasterInterruptCore(BOOL enabled)301 void CAMERA_SetMasterInterruptCore( BOOL enabled )
302 {
303     OSIntrMode old = OS_DisableInterrupts();
304     u16 value = reg_CAM_CNT;
305     reg_CAM_CNT = (u16)(enabled ? (value | REG_CAM_CNT_IREQI_MASK)
306                                 : (value & ~REG_CAM_CNT_IREQI_MASK));
307     (void)OS_RestoreInterrupts(old);
308 }
309 
310 /*---------------------------------------------------------------------------*
311   Name:         CAMERA_GetMasterInterrupt
312 
313   Description:  Gets interrupt mode.
314 
315   Arguments:    None.
316 
317   Returns:      TRUE if set master interrupt will be enabled.
318  *---------------------------------------------------------------------------*/
CAMERA_GetMasterInterruptCore(void)319 BOOL CAMERA_GetMasterInterruptCore( void )
320 {
321     return ((reg_CAM_CNT & REG_CAM_CNT_IREQI_MASK) >> REG_CAM_CNT_IREQI_SHIFT);
322 }
323 
324 /*---------------------------------------------------------------------------*
325   Name:         CAMERA_SetVsyncInterrupt
326 
327   Description:  Sets vsync interrupt mode.
328 
329   Arguments:    type: One of the CAMERAIntrVsync values
330 
331   Returns:      None.
332  *---------------------------------------------------------------------------*/
CAMERA_SetVsyncInterruptCore(CAMERAIntrVsync type)333 void CAMERA_SetVsyncInterruptCore( CAMERAIntrVsync type )
334 {
335     OSIntrMode old = OS_DisableInterrupts();
336     reg_CAM_CNT = (u16)((reg_CAM_CNT & ~REG_CAM_CNT_IREQVS_MASK) | type);
337     (void)OS_RestoreInterrupts(old);
338 }
339 
340 /*---------------------------------------------------------------------------*
341   Name:         CAMERA_GetVsyncInterrupt
342 
343   Description:  Gets vsync interrupt mode.
344 
345   Arguments:    None.
346 
347   Returns:      One of the CAMERAIntrVsync values.
348  *---------------------------------------------------------------------------*/
CAMERA_GetVsyncInterruptCore(void)349 CAMERAIntrVsync CAMERA_GetVsyncInterruptCore( void )
350 {
351     return (CAMERAIntrVsync)(reg_CAM_CNT & REG_CAM_CNT_IREQVS_MASK);
352 }
353 
354 /*---------------------------------------------------------------------------*
355   Name:         CAMERA_SetBufferErrorInterrupt
356 
357   Description:  Sets buffer error interrupt mode.
358 
359   Arguments:    enabled: TRUE if set buffer error interrupt will be enabled
360 
361   Returns:      None.
362  *---------------------------------------------------------------------------*/
CAMERA_SetBufferErrorInterruptCore(BOOL enabled)363 void CAMERA_SetBufferErrorInterruptCore( BOOL enabled )
364 {
365     OSIntrMode old = OS_DisableInterrupts();
366     u16 value = reg_CAM_CNT;
367     reg_CAM_CNT = (u16)(enabled ? (value | REG_CAM_CNT_IREQBE_MASK)
368                                 : (value & ~REG_CAM_CNT_IREQBE_MASK));
369     (void)OS_RestoreInterrupts(old);
370 }
371 
372 /*---------------------------------------------------------------------------*
373   Name:         CAMERA_GetBufferErrorInterrupt
374 
375   Description:  Gets buffer error interrupt mode.
376 
377   Arguments:    None.
378 
379   Returns:      TRUE if set buffer error interrupt will be enabled.
380  *---------------------------------------------------------------------------*/
CAMERA_GetBufferErrorInterruptCore(void)381 BOOL CAMERA_GetBufferErrorInterruptCore( void )
382 {
383     return ((reg_CAM_CNT & REG_CAM_CNT_IREQBE_MASK) >> REG_CAM_CNT_IREQBE_SHIFT);
384 }
385 
386 /*---------------------------------------------------------------------------*
387   Name:         CAMERA_SetTransferLines
388 
389   Description:  Sets the number of lines to store in the buffer.
390 
391   Arguments:    lines: Number of lines
392 
393   Returns:      None.
394  *---------------------------------------------------------------------------*/
CAMERA_SetTransferLinesCore(int lines)395 void CAMERA_SetTransferLinesCore( int lines )
396 {
397     if (lines >= 1 && lines <= 16)
398     {
399         OSIntrMode old = OS_DisableInterrupts();
400         u16 bits = (u16)((lines - 1) << REG_CAM_CNT_TL_SHIFT);
401         reg_CAM_CNT = (u16)((reg_CAM_CNT & ~REG_CAM_CNT_TL_MASK) | bits);
402     (void)OS_RestoreInterrupts(old);
403     }
404 }
405 
406 /*---------------------------------------------------------------------------*
407   Name:         CAMERA_GetTransferLines
408 
409   Description:  Gets number of lines to load from the buffer.
410 
411   Arguments:    None.
412 
413   Returns:      Number of lines.
414  *---------------------------------------------------------------------------*/
CAMERA_GetTransferLinesCore(void)415 int CAMERA_GetTransferLinesCore( void )
416 {
417     return ( ((reg_CAM_CNT & REG_CAM_CNT_TL_MASK) >> REG_CAM_CNT_TL_SHIFT) + 1);
418 }
419 
420 /*---------------------------------------------------------------------------*
421   Name:         CAMERA_GetMaxLinesRound
422 
423   Description:  Rounds the value of CAMERA_GET_MAX_LINES to the value passed to CAMERA_SetTransferLines.
424 
425   Arguments:    width: Width of image
426                 height: Height of image
427 
428   Returns:      Max lines.
429  *---------------------------------------------------------------------------*/
CAMERA_GetMaxLinesRoundCore(u16 width,u16 height)430 int CAMERA_GetMaxLinesRoundCore(u16 width, u16 height)
431 {
432     int lines;
433 
434     for(lines = CAMERA_GET_MAX_LINES(width) ;lines > 1; lines--)
435     {
436         if( height % lines == 0 )
437         {
438             return lines;
439         }
440     }
441     return 1;
442 }
443 
444 /*---------------------------------------------------------------------------*
445   Name:         CAMERA_GetBytesAtOnce
446 
447   Description:  Finds the single transfer size when receiving frame data from the camera buffer.
448 
449   Arguments:    width: Width of image
450 
451   Returns:      The size of a single transfer.
452  *---------------------------------------------------------------------------*/
CAMERA_GetBytesAtOnceCore(u16 width)453 u32 CAMERA_GetBytesAtOnceCore(u16 width)
454 {
455     return (u32)( CAMERA_GET_LINE_BYTES(width) * CAMERA_GetTransferLinesCore() );
456 }
457