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