interrupt가 복병.. interrupt에서 중요한일은 다 하기때문에
I2C도 잘 모르는 상황에서 시간을 좀 잡아먹을듯 싶다
I2C를 잘 모른다면 먼저 S3C2240 Datasheet에서 I2C부분 읽어볼것을 추천
CamReset();
rCIGCTRL |= (1<<31); //camera interface software reset Delay(10); rCIGCTRL &= ~(1<<31); |
rCLKCON |= (1<<19); //Control HCLK into Camera enable
CamPortSet();
void CamPortSet(void) { save_GPJCON = rGPJCON; save_GPJDAT = rGPJDAT; save_GPJUP = rGPJUP; rGPJCON = 0x2aaaaaa; // 0010 1010 1010 1010 1010 1010 1010 // GPJ를 CAM으로 set rGPJDAT = 0; // Data register를 0으로 초기화 rGPJUP = 0; // GPJ pull-up } |
ChangeUPllValue(60, 4, 1); // UPLL clock = 96MHz, PLL input 16.9344MHz
void ChangeUPllValue(int mdiv,int pdiv,int sdiv) { rUPLLCON = (mdiv<<12) | (pdiv<<4) | sdiv; } |
rCLKDIVN|=(1<<3); // UCLK 48MHz setting for UPLL 96MHz
// 0:48MHz, 1:24MHz, 2:16MHz, 3:12MHz...
// Camera clock = UPLL/[(CAMCLK_DIV+1)X2]
Uart_Printf("1...\n");
switch(USED_CAM_TYPE) // USED_CAM_TYPE = 5
{
case CAM_AU70H :
if (AU70H_VIDEO_SIZE==1152)
SetCAMClockDivider(CAMCLK24000000); //Set Camera Clock for SXGA
if (AU70H_VIDEO_SIZE==640)
SetCAMClockDivider(CAMCLK16000000); //Set Camera Clock for VGA
break;
case CAM_S5X3A1 :
SetCAMClockDivider(CAMCLK24000000); //Set Camera Clock for SXGA
break;
default : // 24MHz
SetCAMClockDivider(CAMCLK24000000); //Set Camera Clock 24MHz s5x532, ov7620
void SetCAMClockDivider(int divn) // CAMCLK24000000 = 5 { rCAMDIVN = (rCAMDIVN & ~(0xf))|(1<<4)|(divn); // CAMCLK is divided.. } |
//Uart_Printf("rCAMDIVN : 0x%x\n", rCAMDIVN); //0x11
break;
}
Uart_Printf("2...\n");
// Initializing camera module
CamModuleReset(); // s5x532 must do this..
void CamModuleReset(void) { switch(USED_CAM_TYPE) //USED_CAM_TYPE = 5 { case CAM_OV7620 : // reset - active high case CAM_S5X532 : // reset - active low, but H/W inverted.. so, in this case active high case CAM_S5X433 : // reset - active low, but H/W inverted.. so, in this case active high case CAM_S5X3A1 : // reset - active low, but H/W inverted.. so, in this case active high rCIGCTRL |= (1<<30); //external camera reset high Delay(30); rCIGCTRL &= ~(1<<30); //external camera reset low break; case CAM_AU70H : // reset - active low #if REBIS case CAM_MICRON: // reset - active low CAM_MICRON = 5 #endif default : //CIGCTRL [30] : External camera processor reset or power down rCIGCTRL &= ~(1<<30); //external camera reset low Delay(10); rCIGCTRL |= (1<<30); //external camera reset high break; } } |
Delay(500); // ready time of s5x433, s5x532 IIC interface. needed...
CameraModuleSetting();
int CameraModuleSetting(void) { unsigned int i, j, save_E, save_PE, RegAddr, RegData; static U8 rdata[256]; int donestatus; IicPortSet(); //void IicPortSet(void) //{ // save_GPECON = rGPECON; // rGPECON = rGPECON & ~(0xf<<28) | (0xa<<28); // //GPE15:IICSDA , GPE14:IICSCL //} //IIICSDA : IIC-bus data //IICSCL : IIC-bus clock // for camera init, added by junon pISR_IIC = (unsigned)Cam_IICInt; //explain two rows 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; #if REBIS #else Camera_WriteBlock(); // Camera_ReadBlock(); #endif return donestatus; } |
void __irq Cam_IICInt(void) { #if REBIS //REBIS = 1 U32 iicSt, i; ClearPending(BIT_IIC); //#define ClearPending(bit) {\ //BIT_IIC = 0x1 << 27 // rSRCPND = bit;\ //INT_IIC Requested(Source pending register) // rINTPND = bit;\ //INT_IIC Requested(Interrupt pending register) // rINTPND;\ // } 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 ) // case by I2C_Read16 or Rd_CamIIC { _CAMiicData[_CAMiicPt++] = rIICDS; rIICSTAT = 0x90; // Stop MasRx condition // Rx/Tx Enable & Master receive mode rIICCON = 0xEF; // Resuems IIC operation. //prescaler? Tx clock = IICLK/(15 + 1) // No interrupt pending // IIC-Bus Tx/Rx interrupt enable // IICCLK = fPCLK/512 // IIC-bus acknowledge enable 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. //IICDS : Multi-master IIC-bus transmit/receive data shift register if( (_CAMiicDataCount) == 0 ) { rIICCON = 0x6F; // Resumes IIC operation with NOACK //in case of S5X532 Camera. //prescaler? Tx clock = IICLK/(15 + 1) // No interrupt pending // IIC-Bus Tx/Rx interrupt enable // IICCLK = fPCLK/512 // IIC-bus acknowledge disable } else { rIICCON = 0xEF; // Resumes IIC operaton with ACK. } break; case CAMWRDATA: //case by I2C_Write16 or Wr_CamIIC if( (_CAMiicDataCount--) == 0 ) { rIICSTAT = 0xD0; // stop MasTx condition rIICCON = 0xEF; // 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 = 0xEF; //resumes IIC operation. break; case CAMSETRDADDR: // case by I2C_Read16 or Rd_CamIIC // Uart_Printf("[S%d]",_iicDataCount); if( (_CAMiicDataCount--) == 0 ) { rIICSTAT = 0xD0; //stop MasTx condition rIICCON = 0xEF; //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 = 0xEF; //resumes IIC operation. break; default: break; } rINTMSK &= ~BIT_IIC; #else // #if REBIS 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 // No interrupt pending 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; #endif // #if REBIS #else } void Camera_WriteByte(void) { #if REBIS U32 RegAddr; U16 RegData; Uart_Printf("Input Write Register Address of %s\n=>", CAM_NAME); RegAddr = (U32)Uart_GetIntNum(); Uart_Printf("Input Write Transfer Data into %s\n=>", CAM_NAME); RegData = (U16)Uart_GetIntNum(); I2C_Write16( CAM_ID, RegAddr, RegData ); #else 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 #endif // #if REBIS #else } |
Camera_WriteBlock();
void SetCAMClockDivider(int divn) // CAMCLK24000000 == 5 { rCAMDIVN = (rCAMDIVN & ~(0xf))|(1<<4)|(divn); // CAMCLK is divided.. } |
Uart_Printf("Initializing end...\n");
'Programming > 그밖에...' 카테고리의 다른 글
섹시한 라이브러리?? libsexy.so (0) | 2010.09.14 |
---|---|
Android SDK 설치시 error (0) | 2009.11.20 |
Touch screen Calibration (0) | 2009.09.10 |
CIE L*a*b* (0) | 2009.06.01 |
단위환산표 (0) | 2008.05.21 |