?? camproset.c
字號:
/******************************************************************************
Filename: camproset.c
Descriptions
- Camera Processor Initialization code using SCCB.
- SCCB(Serial Camera Contol Bus) H/W dependent code.
- Camera Processor Initialization code using IIC.
History
- July 23, 2003. Draft Version 0.0 by purnnamu
- Janualy 15, 2004. Modifed by Boaz
- Feb. 10, 2004. Modified by junon for S3C2440A
Copyright (c) 2003 SAMSUNG Electronics.
# However, Anybody can use this code without our permission.
******************************************************************************/
#include "def.h"
#include "2440addr.h"
#include "2440lib.h"
#include "camproset.h"
#include "camdef.h"
#include "camdata.h"
#define CAMWRDATA (1)
#define CAMRDDATA (3)
#define CAMSETRDADDR (4)
#define CAMIICBUFSIZE 0x20
#if USED_CAM_TYPE==CAM_OV7620
#define CAM_ID (0x42)
#define CAM_NAME "OV7620"
#elif USED_CAM_TYPE==CAM_S5X433
#define CAM_ID (0x42)
#define CAM_NAME "S5X433"
#elif USED_CAM_TYPE==CAM_S5X532
#define CAM_ID (0x5a)
#define CAM_NAME "S5X532"
#elif USED_CAM_TYPE==CAM_S5X3A1
#define CAM_ID (0x5a)
#define CAM_NAME "S5X3A1"
#elif USED_CAM_TYPE==CAM_AU70H
#define CAM_ID (0x22)
#define CAM_NAME "AU70H"
#elif USED_CAM_TYPE==CAM_SAA7113H //modufied by GongJun
#define CAM_ID (0x33)
#define CAM_NAME "SAA7113H"
#endif
static U8 _CAMiicData[CAMIICBUFSIZE];
static volatile int _CAMiicDataCount;
static volatile int _CAMiicStatus;
static volatile int _CAMiicMode;
static int _CAMiicPt;
volatile U32 save_GPECON;
void* func_cammodule_test[][2] =
{
//IIC
( void* ) Camera_WriteByte, "Write 1 byte data into Camera module register", ( void* ) Camera_ReadByte,
"Read 1 byte data from Camera module register", ( void* ) Camera_WriteBlock,
"Write a block of byte data into Camera module register", ( void* ) Camera_ReadBlock,
"Read a block of byte data from Camera module register", 0, 0
};
void Camera_Iic_Test( void )
{
int i, camclk;
CameraModuleSetting();
Uart_Printf( "\n***** IIC Master Tx/Rx Test Program with %s Camera Module *****\n" , CAM_NAME );
while ( 1 )
{
i = 0;
Uart_Printf( "\n\n" );
while ( 1 )
{
//display menu
Uart_Printf( "%2d:%s\n" , i , func_cammodule_test[i][1] );
i++;
if ( ( int ) ( func_cammodule_test[i][0] ) == 0 )
{
Uart_Printf( "\n" );
break;
}
if ( ( i % 4 ) == 0 )
Uart_Printf( "\n" );
}
Uart_Printf( "\nPress Enter key to exit : " );
i = Uart_GetIntNum();
if ( i == -1 )
break; // return.
if ( i >= 0 && ( i < ( ( sizeof( func_cammodule_test ) - 1 ) / 8 ) ) ) // select and execute...
( ( void ( * ) ( void ) ) ( func_cammodule_test[i][0] ) ) ();
}
Uart_Printf( "\n" );
rINTMSK |= BIT_IIC;
}
void IicPortSet( void )
{
save_GPECON = rGPECON;
rGPECON = rGPECON & ~( 0xf << 28 ) | ( 0xa << 28 ); //GPE15:IICSDA , GPE14:IICSCL
}
void IicPortReturn( void )
{
rGPECON = save_GPECON;
}
void Wr_CamIIC( U32 slvAddr , U32 addr , U8 data )
{
_CAMiicMode = CAMWRDATA;
_CAMiicPt = 0;
_CAMiicData[0] = ( U8 ) addr;
_CAMiicData[1] = data;
_CAMiicDataCount = 2;
rIICDS = slvAddr; //0x5a: S5X532 Slave ID
rIICSTAT = 0xf0; //Start Master TX Condition
rIICCON &= ~( 1 << 4 ); //Clearing the pending bit isn't needed because the pending bit has been cleared.
while ( _CAMiicDataCount != -1 );
}
void Rd_CamIIC( U32 slvAddr , U32 addr , U8* data )
{
/*IIC Slave Addr Write + IIC Reg Addr Write */
_CAMiicMode = CAMSETRDADDR;
_CAMiicPt = 0;
_CAMiicData[0] = ( U8 ) addr;
_CAMiicDataCount = 1;
rIICDS = slvAddr;
rIICSTAT = 0xf0; //Master Tx, Start
rIICCON &= ~( 1 << 4 ); //Resumes IIC operation.
//Clearing the pending bit isn't needed because the pending bit has been cleared.
while ( _CAMiicDataCount != -1 );
_CAMiicMode = CAMRDDATA;
_CAMiicPt = 0;
_CAMiicDataCount = 1;
rIICDS = slvAddr;
rIICSTAT = 0xb0; //Master Rx,Start
rIICCON &= ~( 1 << 4 ); //Resumes IIC operation.
while ( _CAMiicDataCount != -1 );
*data = _CAMiicData[1];
}
void __irq Cam_IICInt( void )
{
U32 iicSt, i;
ClearPending( BIT_IIC );
iicSt = rIICSTAT;
rINTMSK |= BIT_IIC;
if ( iicSt & 0x8 )
{
} //When bus arbitration is failed.
if ( iicSt & 0x4 )
{
} //When a slave address is matched with IICADD
if ( iicSt & 0x2 )
{
} //When a slave address is 0000000b
if ( iicSt & 0x1 )
{
} //When ACK isn't received
switch ( _CAMiicMode )
{
case CAMRDDATA:
if ( ( _CAMiicDataCount-- ) == 0 )
{
_CAMiicData[_CAMiicPt++] = rIICDS;
rIICSTAT = 0x90; //Stop MasRx condition
rIICCON &= ~( 1 << 4 ); //Resumes IIC operation.
Delay( 1 ); //Wait until stop condtion is in effect., Too long time... # need the time 2440:Delay(1), 24A0: Delay(2)
//The pending bit will not be set after issuing stop condition.
break;
}
_CAMiicData[_CAMiicPt++] = rIICDS; //The last data has to be read with no ack.
if ( ( _CAMiicDataCount ) == 0 )
rIICCON &= ~( ( 1 << 7 ) | ( 1 << 4 ) ); //Resumes IIC operation with NOACK in case of S5X532 Cameara
// rIICCON = 0x6f; //Resumes IIC operation with NOACK in case of S5X532 Cameara
else
rIICCON &= ~( 1 << 4 ); //Resumes IIC operation with ACK
break;
case CAMWRDATA:
if ( ( _CAMiicDataCount-- ) == 0 )
{
rIICSTAT = 0xd0; //stop MasTx condition
rIICCON &= ~( 1 << 4 ); //resumes IIC operation.
Delay( 1 ); //wait until stop condtion is in effect. # need the time 2440:Delay(1), 24A0: Delay(2)
//The pending bit will not be set after issuing stop condition.
break;
}
rIICDS = _CAMiicData[_CAMiicPt++]; //_iicData[0] has dummy.
for ( i = 0; i < 10; i++ )
; //for setup time until rising edge of IICSCL
rIICCON &= ~( 1 << 4 ); //resumes IIC operation.
break;
case CAMSETRDADDR:
//Uart_Printf("[S%d]",_iicDataCount);
if ( ( _CAMiicDataCount-- ) == 0 )
{
rIICSTAT = 0xd0; //stop MasTx condition
rIICCON &= ~( 1 << 4 ); //resumes IIC operation.
Delay( 1 ); //wait until stop condtion is in effect.
break; //IIC operation is stopped because of IICCON[4]
}
rIICDS = _CAMiicData[_CAMiicPt++];
for ( i = 0; i < 10; i++ )
; //for setup time until rising edge of IICSCL
rIICCON &= ~( 1 << 4 ); //resumes IIC operation.
break;
default:
break;
}
rINTMSK &= ~BIT_IIC;
}
void Camera_WriteByte( void )
{
unsigned int i, j, save_E, save_PE, RegAddr, RegData, pageNo;
#if (USED_CAM_TYPE==CAM_S5X532)||(USED_CAM_TYPE==CAM_S5X3A1)
Uart_Printf( "Input Write Page No of %s\n=>" , CAM_NAME );
pageNo = ( U8 ) Uart_GetIntNum();
#endif
Uart_Printf( "Input Write Register Address of %s\n=>" , CAM_NAME );
RegAddr = ( U8 ) Uart_GetIntNum();
Uart_Printf( "Input Write Transfer Data into %s\n=>" , CAM_NAME );
RegData = ( U8 ) Uart_GetIntNum();
#if (USED_CAM_TYPE==CAM_S5X532)||(USED_CAM_TYPE==CAM_S5X3A1)
Wr_CamIIC( CAM_ID , ( U8 ) 0xec , pageNo ); // set Page no
#endif
Wr_CamIIC( CAM_ID , ( U8 ) RegAddr , RegData ); // set register after setting page number
}
void Camera_ReadByte( void )
{
unsigned int i, j, save_E, save_PE, RegAddr, RegData, pageNo;
static U8 rdata[8];
#if (USED_CAM_TYPE==CAM_S5X532)||(USED_CAM_TYPE==CAM_S5X3A1)
Uart_Printf( "Input Write Page No of %s\n=>" , CAM_NAME );
pageNo = ( U8 ) Uart_GetIntNum();
Wr_CamIIC( CAM_ID , ( U8 ) 0xec , pageNo ); // set Page no
#endif
Uart_Printf( "Input Read Register Address of %s\n=>" , CAM_NAME );
RegAddr = ( U8 ) Uart_GetIntNum();
Rd_CamIIC( CAM_ID , RegAddr , &rdata[0] );
Uart_Printf( "Register Addr: 0x%2x, data: 0x%2x\n" , RegAddr , rdata[0] );
}
void Camera_WriteBlock( void )
{
unsigned int i, j, save_E, save_PE, RegAddr, RegData;
static U8 rdata[256];
#if USED_CAM_TYPE==CAM_OV7620
for ( i = 0; i < ( sizeof( Ov7620_YCbCr8bit ) / 2 ); i++ )
Wr_CamIIC( CAM_ID , Ov7620_YCbCr8bit[i][0] , Ov7620_YCbCr8bit[i][1] );
#elif USED_CAM_TYPE==CAM_S5X532
for ( i = 0; i < ( sizeof( S5X532_YCbCr8bit ) / 2 ); i++ )
Wr_CamIIC( CAM_ID , S5X532_YCbCr8bit[i][0] , S5X532_YCbCr8bit[i][1] );
#elif USED_CAM_TYPE==CAM_S5X3A1
for ( i = 0; i < ( sizeof( S5X3A1_YCbCr8bit ) / 2 ); i++ )
Wr_CamIIC( CAM_ID , S5X3A1_YCbCr8bit[i][0] , S5X3A1_YCbCr8bit[i][1] );
#elif USED_CAM_TYPE==CAM_AU70H
for ( i = 0; i < ( sizeof( Au70h ) / 2 ); i++ )
Wr_CamIIC( CAM_ID , Au70h[i][0] , Au70h[i][1] );
#endif
Uart_Printf( "\nBlock TX Ended...\n" );
}
void Camera_ReadBlock( void )
{
unsigned int i, j, save_E, save_PE, RegAddr, RegData;
static U8 rdata[256];
#if USED_CAM_TYPE==CAM_OV7620
for ( i = 0; i < ( sizeof( Ov7620_YCbCr8bit ) / 2 ); i++ )
Rd_CamIIC( CAM_ID , Ov7620_YCbCr8bit[i][0] , &rdata[i] );
for ( i = 0; i < ( sizeof( Ov7620_YCbCr8bit ) / 2 ); i++ )
Uart_Printf( "Addr: 0x%2x, W: 0x%2x, R: 0x%2x\n" , Ov7620_YCbCr8bit[i][0] , Ov7620_YCbCr8bit[i][1] , rdata[i] );
#elif USED_CAM_TYPE==CAM_S5X532
for ( i = 0; i < ( sizeof( S5X532_YCbCr8bit ) / 2 ); i++ )
{
if ( S5X532_YCbCr8bit[i][0] == 0xec )
Wr_CamIIC( CAM_ID , S5X532_YCbCr8bit[i][0] , S5X532_YCbCr8bit[i][1] );
else
Rd_CamIIC( CAM_ID , S5X532_YCbCr8bit[i][0] , &rdata[i] );
}
for ( i = 0; i < ( sizeof( S5X532_YCbCr8bit ) / 2 ); i++ )
{
if ( S5X532_YCbCr8bit[i][0] == 0xec )
Uart_Printf( "Page: 0x%2x\n" , S5X532_YCbCr8bit[i][1] );
else
Uart_Printf( "Addr: 0x%2x, W: 0x%2x, R: 0x%2x\n" , S5X532_YCbCr8bit[i][0] , S5X532_YCbCr8bit[i][1] ,
rdata[i] );
}
#elif USED_CAM_TYPE==CAM_S5X3A1
for ( i = 0; i < ( sizeof( S5X3A1_YCbCr8bit ) / 2 ); i++ )
{
if ( S5X3A1_YCbCr8bit[i][0] == 0xec )
Wr_CamIIC( CAM_ID , S5X3A1_YCbCr8bit[i][0] , S5X3A1_YCbCr8bit[i][1] );
else
Rd_CamIIC( CAM_ID , S5X3A1_YCbCr8bit[i][0] , &rdata[i] );
}
for ( i = 0; i < ( sizeof( S5X3A1_YCbCr8bit ) / 2 ); i++ )
{
if ( S5X3A1_YCbCr8bit[i][0] == 0xec )
Uart_Printf( "Page: 0x%2x\n" , S5X3A1_YCbCr8bit[i][1] );
else
Uart_Printf( "Addr: 0x%2x, W: 0x%2x, R: 0x%2x\n" , S5X3A1_YCbCr8bit[i][0] , S5X3A1_YCbCr8bit[i][1] ,
rdata[i] );
}
#elif USED_CAM_TYPE==CAM_AU70H
for ( i = 0; i < ( sizeof( Au70h ) / 2 ); i++ )
Rd_CamIIC( CAM_ID , Au70h[i][0] , &rdata[i] );
for ( i = 0; i < ( sizeof( Au70h ) / 2 ); i++ )
Uart_Printf( "Addr: 0x%2x, W: 0x%2x, R: 0x%2x\n" , Au70h[i][0] , Au70h[i][1] , rdata[i] );
#endif
}
int CameraModuleSetting( void )
{
unsigned int i, j, save_E, save_PE, RegAddr, RegData;
static U8 rdata[256];
int donestatus;
IicPortSet();
// for camera init, added by junon
pISR_IIC = ( unsigned ) Cam_IICInt;
rINTMSK &= ~( BIT_IIC );
//Enable ACK, Prescaler IICCLK=PCLK/512, Enable interrupt, Transmit clock value Tx clock=IICCLK/16
rIICCON = ( 1 << 7 ) | ( 1 << 6 ) | ( 1 << 5 ) | ( 0x3 );
rIICADD = 0x10; //24A0 slave address = [7:1]
rIICSTAT = 0x10; //IIC bus data output enable(Rx/Tx)
rIICLC = ( 1 << 2 ) | ( 3 ); // SDAOUT has 5clock cycle delay
donestatus = 1;
Camera_WriteBlock();
// Camera_ReadBlock();
return donestatus;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -