/*---------------------------------------------------------------------------* Project: TwlSDK - library - camera File: camera.c Copyright 2007-2008 Nintendo. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Date:: 2008-09-26#$ $Rev: 8691 $ $Author: yutaka $ *---------------------------------------------------------------------------*/ #include #include #include "camera_intr.h" /*---------------------------------------------------------------------------* Constant Definitions *---------------------------------------------------------------------------*/ #define SYNC_TYPE (0 << REG_CAM_MCNT_SYNC_SHIFT) // 1 if low active #define RCLK_TYPE (0 << REG_CAM_MCNT_IRCLK_SHIFT) // 1 if negative edge #define RESET_ON ( SYNC_TYPE | RCLK_TYPE ) #define RESET_OFF ( REG_CAM_MCNT_VIO_MASK | REG_CAM_MCNT_RST_MASK | SYNC_TYPE | RCLK_TYPE ) // RST is only for TS-X2 /*---------------------------------------------------------------------------* Type Definitions *---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------* Static Variable Definitions *---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------* Internal Function Definitions *---------------------------------------------------------------------------*/ static inline void CAMERAi_Wait(u32 clocks) { OS_SpinWaitSysCycles(clocks << 1); } /*---------------------------------------------------------------------------* Name: CAMERA_Reset Description: Hardware reset before I2C access. Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ void CAMERA_ResetCore( void ) { reg_SCFG_CLK |= REG_SCFG_CLK_CAMHCLK_MASK; // ensure powered on reg_CAM_MCNT = RESET_ON; // hardware reset CAMERAi_Wait( 15 ); reg_SCFG_CLK |= REG_SCFG_CLK_CAMCKI_MASK; // clock out to read internal ROM code CAMERAi_Wait( 15 ); reg_CAM_MCNT = RESET_OFF; // reset off CAMERAi_Wait( 4100 ); // wait to done to read internal ROM code reg_SCFG_CLK &= ~REG_SCFG_CLK_CAMCKI_MASK; // stop to clock } /*---------------------------------------------------------------------------* Name: CAMERA_IsBusy Description: Determine availability of camera. Arguments: None. Returns: TRUE if camera is busy. *---------------------------------------------------------------------------*/ BOOL CAMERA_IsBusyCore( void ) { return (reg_CAM_CNT & REG_CAM_CNT_E_MASK) >> REG_CAM_CNT_E_SHIFT; } /*---------------------------------------------------------------------------* Name: CAMERA_StartCapture Description: Start receiving camera data. Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ void CAMERA_StartCaptureCore( void ) { reg_CAM_CNT |= REG_CAM_CNT_E_MASK; } /*---------------------------------------------------------------------------* Name: CAMERA_StopCapture Description: Stop receiving camera data. Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ void CAMERA_StopCaptureCore( void ) { reg_CAM_CNT &= ~REG_CAM_CNT_E_MASK; } /*---------------------------------------------------------------------------* Name: CAMERA_SetTrimmingParamsCenter Description: Set camera trimming parameters by centering. NOTE: Call CAMERA_SetTrimming to enable trimming. Arguments: destWidth: Width of image to output destHeight: Height of image to output srcWidth: Original width of image srcHeight: Original height of image Returns: None. *---------------------------------------------------------------------------*/ void CAMERA_SetTrimmingParamsCenterCore(u16 destWidth, u16 destHeight, u16 srcWidth, u16 srcHeight) { if( (destWidth > srcWidth)||(destHeight > srcHeight) ) //Trimming range is outside of original image { return; } destWidth -= 2; destHeight -= 1; reg_CAM_SOFS = REG_CAM_SOFS_FIELD( (srcHeight-destHeight) >> 1, (srcWidth-destWidth) >> 1); reg_CAM_EOFS = REG_CAM_EOFS_FIELD( (srcHeight+destHeight) >> 1, (srcWidth+destWidth) >> 1); } /*---------------------------------------------------------------------------* Name: CAMERA_SetTrimmingParams Description: Set camera trimming parameters. NOTE: Width = x2 - x1; Height = y2 - y1. NOTE: Call CAMERA_SetTrimming to enable trimming Arguments: x1: X-coordinate of top-left trimming point (multiple of 2) y1: Y-coordinate of top-left trimming point x2: X-coordinate of bottom-right trimming point (multiple of 2) y2: Y-coordinate of bottom-right trimming point Returns: None. *---------------------------------------------------------------------------*/ void CAMERA_SetTrimmingParamsCore(u16 x1, u16 y1, u16 x2, u16 y2) { if( (x1 > x2)||(y1 > y2) ) // The ending position offset is smaller than the starting position offset { return; } // Behavior when the ending position is out of the range of the original image is described in the function reference. // Behavior when the starting position is out of the range of the original image is described in the function reference. reg_CAM_SOFS = REG_CAM_SOFS_FIELD( y1, x1 ); reg_CAM_EOFS = REG_CAM_EOFS_FIELD( y2 - 1, x2 -2 ); } /*---------------------------------------------------------------------------* Name: CAMERA_GetTrimmingParams Description: Get camera trimming parameters. NOTE: Width = x2 - x1; Height = y2 - y1. NOTE: Call CAMERA_SetTrimming to enable trimming. Arguments: x1: X-coordinate of top-left trimming point (multiple of 2) y1: Y-coordinate of top-left trimming point x2: X-coordinate of bottom-right trimming point (multiple of 2) y2: Y-coordinate of bottom-right trimming point Returns: None. *---------------------------------------------------------------------------*/ void CAMERA_GetTrimmingParamsCore(u16* x1, u16* y1, u16* x2, u16* y2) { *x1 = (u16)((reg_CAM_SOFS & REG_CAM_SOFS_HOFS_MASK) >> REG_CAM_SOFS_HOFS_SHIFT); *y1 = (u16)((reg_CAM_SOFS & REG_CAM_SOFS_VOFS_MASK) >> REG_CAM_SOFS_VOFS_SHIFT); *x2 = (u16)(((reg_CAM_EOFS & REG_CAM_EOFS_HOFS_MASK) >> REG_CAM_EOFS_HOFS_SHIFT) + 2); *y2 = (u16)(((reg_CAM_EOFS & REG_CAM_EOFS_VOFS_MASK) >> REG_CAM_EOFS_VOFS_SHIFT) + 1); } /*---------------------------------------------------------------------------* Name: CAMERA_SetTrimming Description: Set trimming to be enabled/disabled. Arguments: enabled: TRUE if set trimming will be enabled Returns: None. *---------------------------------------------------------------------------*/ void CAMERA_SetTrimmingCore( BOOL enabled ) { u16 value = reg_CAM_CNT; reg_CAM_CNT = (u16)(enabled ? (value | REG_CAM_CNT_T_MASK) : (value & ~REG_CAM_CNT_T_MASK)); } /*---------------------------------------------------------------------------* Name: CAMERA_IsTrimming Description: Get whether trimming will be enabled/disabled Arguments: None. Returns: TRUE if set trimming will be enabled *---------------------------------------------------------------------------*/ BOOL CAMERA_IsTrimmingCore( void ) { return ((reg_CAM_CNT & REG_CAM_CNT_T_MASK) >> REG_CAM_CNT_T_SHIFT); } /*---------------------------------------------------------------------------* Name: CAMERA_SetOutputFormat Description: Set camera output format. Arguments: output: One of the CAMERAOutput values Returns: None. *---------------------------------------------------------------------------*/ void CAMERA_SetOutputFormatCore( CAMERAOutput output ) { u16 value = reg_CAM_CNT; switch (output) { case CAMERA_OUTPUT_YUV: reg_CAM_CNT = (u16)(value & ~REG_CAM_CNT_F_MASK); break; case CAMERA_OUTPUT_RGB: reg_CAM_CNT = (u16)(value | REG_CAM_CNT_F_MASK); break; } } /*---------------------------------------------------------------------------* Name: CAMERA_GetOutputFormat Description: Get camera output format. Arguments: None. Returns: One of the CAMERAOutput values. *---------------------------------------------------------------------------*/ CAMERAOutput CAMERA_GetOutputFormatCore( void ) { return (reg_CAM_CNT & REG_CAM_CNT_F_MASK) ? CAMERA_OUTPUT_RGB : CAMERA_OUTPUT_YUV; } /*---------------------------------------------------------------------------* Name: CAMERA_GetErrorStatus Description: Determines whether a line-buffer error has occurred Arguments: None. Returns: TRUE if an error has occurred *---------------------------------------------------------------------------*/ BOOL CAMERA_GetErrorStatusCore( void ) { return (reg_CAM_CNT & REG_CAM_CNT_ERR_MASK) >> REG_CAM_CNT_ERR_SHIFT; } /*---------------------------------------------------------------------------* Name: CAMERA_ClearBuffer Description: Clear line buffer and error status. Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ void CAMERA_ClearBufferCore( void ) { reg_CAM_CNT |= REG_CAM_CNT_CL_MASK; } /*---------------------------------------------------------------------------* Name: CAMERA_SetMasterInterrupt Description: Set interrupt mode. Arguments: enabled: TRUE if set master interrupt will be enabled Returns: None. *---------------------------------------------------------------------------*/ void CAMERA_SetMasterInterruptCore( BOOL enabled ) { u16 value = reg_CAM_CNT; reg_CAM_CNT = (u16)(enabled ? (value | REG_CAM_CNT_IREQI_MASK) : (value & ~REG_CAM_CNT_IREQI_MASK)); } /*---------------------------------------------------------------------------* Name: CAMERA_GetMasterInterrupt Description: Get interrupt mode. Arguments: None. Returns: TRUE if set master interrupt will be enabled. *---------------------------------------------------------------------------*/ BOOL CAMERA_GetMasterInterruptCore( void ) { return ((reg_CAM_CNT & REG_CAM_CNT_IREQI_MASK) >> REG_CAM_CNT_IREQI_SHIFT); } /*---------------------------------------------------------------------------* Name: CAMERA_SetVsyncInterrupt Description: Set vsync interrupt mode. Arguments: type: One of the CAMERAIntrVsync values Returns: None. *---------------------------------------------------------------------------*/ void CAMERA_SetVsyncInterruptCore( CAMERAIntrVsync type ) { reg_CAM_CNT = (u16)((reg_CAM_CNT & ~REG_CAM_CNT_IREQVS_MASK) | type); } /*---------------------------------------------------------------------------* Name: CAMERA_GetVsyncInterrupt Description: Get vsync interrupt mode. Arguments: None. Returns: One of the CAMERAIntrVsync values. *---------------------------------------------------------------------------*/ CAMERAIntrVsync CAMERA_GetVsyncInterruptCore( void ) { return (CAMERAIntrVsync)(reg_CAM_CNT & REG_CAM_CNT_IREQVS_MASK); } /*---------------------------------------------------------------------------* Name: CAMERA_SetBufferErrorInterrupt Description: Set buffer error interrupt mode. Arguments: enabled: TRUE if set buffer error interrupt will be enabled Returns: None. *---------------------------------------------------------------------------*/ void CAMERA_SetBufferErrorInterruptCore( BOOL enabled ) { u16 value = reg_CAM_CNT; reg_CAM_CNT = (u16)(enabled ? (value | REG_CAM_CNT_IREQBE_MASK) : (value & ~REG_CAM_CNT_IREQBE_MASK)); } /*---------------------------------------------------------------------------* Name: CAMERA_GetBufferErrorInterrupt Description: Get buffer error interrupt mode. Arguments: None. Returns: TRUE if set buffer error interrupt will be enabled. *---------------------------------------------------------------------------*/ BOOL CAMERA_GetBufferErrorInterruptCore( void ) { return ((reg_CAM_CNT & REG_CAM_CNT_IREQBE_MASK) >> REG_CAM_CNT_IREQBE_SHIFT); } /*---------------------------------------------------------------------------* Name: CAMERA_SetTransferLines Description: Set the number of lines to store in the buffer. Arguments: lines: Number of lines Returns: None. *---------------------------------------------------------------------------*/ void CAMERA_SetTransferLinesCore( int lines ) { if (lines >= 1 && lines <= 16) { u16 bits = (u16)((lines - 1) << REG_CAM_CNT_TL_SHIFT); reg_CAM_CNT = (u16)((reg_CAM_CNT & ~REG_CAM_CNT_TL_MASK) | bits); } } /*---------------------------------------------------------------------------* Name: CAMERA_GetTransferLines Description: Get number of lines to load from the buffer. Arguments: None. Returns: Number of lines. *---------------------------------------------------------------------------*/ int CAMERA_GetTransferLinesCore( void ) { return ( ((reg_CAM_CNT & REG_CAM_CNT_TL_MASK) >> REG_CAM_CNT_TL_SHIFT) + 1); } /*---------------------------------------------------------------------------* Name: CAMERA_GetMaxLinesRound Description: Rounding CAMERA_GET_MAX_LINES. Arguments: Width: Width of image Height: Height of image Returns: Max lines. *---------------------------------------------------------------------------*/ int CAMERA_GetMaxLinesRoundCore(u16 width, u16 height) { int lines; for(lines = CAMERA_GET_MAX_LINES(width) ;lines > 1; lines--) { if( height % lines == 0 ) { return lines; } } return 1; } /*---------------------------------------------------------------------------* Name: CAMERA_GetBytesAtOnce Description: Find the single transfer size when receiving frame data from the camera buffer. Arguments: width: Width of image Returns: Unit. *---------------------------------------------------------------------------*/ u32 CAMERA_GetBytesAtOnceCore(u16 width) { return (u32)( CAMERA_GET_LINE_BYTES(width) * CAMERA_GetTransferLinesCore() ); }