iic.cpp

来自「S3C24A0的完整BSP包,对开发此芯片的开发者很有用.」· C++ 代码 · 共 1,063 行 · 第 1/2 页

CPP
1,063
字号
	{0x0a,0x9d},   
	{0x0b,0x02},   
	{0x0c,0x04},   
	{0x0d,0x00},   
	{0x0e,0x20},   
	{0x0f,0x02},   
	{0x1b,0x40},   
	{0x1c,0x40},   

	                 
	//page5             
	{0xec,0x05},   
	{0x1f,0x00},   
	{0x08,0x59},   
	{0x0a,0x71},   
	{0x1e,0x00}, // 23 at 20frame  
	           


	//page6             
	{0xec,0x06},   
	{0x00,0x3e},   
	{0x01,0xa6}, 
	{0x02,0x40}, 
	{0x03,0xcb}, 
	{0x04,0x09}, 
	{0x05,0xdb}, 
	{0x06,0x40},   
	{0x07,0xf2}, 

	{0x08,0x09},           
	{0x09,0xdb},   
	{0x0a,0x40},   
	{0x0b,0xf2}, 
	                 

	//page7          
	{0xec,0x07},   
	{0x11,0xfe},   
	{0x23,0x07},   
	{0x08,0xff},   
	{0x09,0x6c},   
	{0x87,0x00},   
	{0x21,0xff},   
	{0x22,0x70}, 
	{0x31,0x05},   
	{0x38,0x01},   
	{0x39,0x01},   

	{0x3a,0xf0},   

	{0x26,0x04}, 
	{0x27,0x10}, 
	{0x2a,0x10},   
	{0x2b,0x10},   

	{0x49,0x02},   
	{0x59,0x80},   
	{0x5A,0x04}, 
	{0x5B,0x06}, 
	{0x5C,0x06}, 
	{0x5D,0x06}, 
	{0x5E,0x04}, 
	{0x5F,0x04}, 



	//page0          
	{0xec,0x00},   
	{0x0a,0x01},   
	{0x13,0x20}, 
	{0x14,0x20},   
	{0x15,0x20},   
	{0x16,0x20},   
	{0x17,0x30},   
	{0x18,0x30},   
	{0x19,0x20},   
	{0x1a,0x20}, 
	{0x1b,0x20},   
	{0x1c,0x20},   
	{0x1d,0x20},   
	{0x1e,0x30},   
	{0x1f,0x30},   
	{0x20,0x20}, 
	{0x71,0x11}, 	
	{0x72,0xaa}, //aa at 20.0Mhz  // a2  at 19.2Mhz 
	{0x61,0xb0},   
	{0x66,0x01},   
	{0x6c,0x50},   
	{0x7c,0x00},   
	{0x0D,0x24},   

	{0x7e,0x04},   
	{0x64,0xf0},   

	{0x86,0x01},   
	{0x87,0x00},   


	   
	{0x76,0x80},   
	{0x77,0x90},   
	{0x78,0x6c},   

	{0x34,0x0d},   
	{0x35,0x0a},   
	{0x36,0x05},   
	{0x37,0x05},   
	{0x38,0x06},   
	{0x39,0x08},   
	{0x3A,0x0a},   
	{0x3B,0x0a},   
	{0x3C,0x18},   
	{0x3D,0xE0},   
	{0x3E,0x10},   

	{0x40,0x1d}, 	
	{0x41,0x4f}, 	
	{0x42,0x24}, 	
	{0x43,0x3c}, 	
	{0x44,0x34}, 	
	{0x45,0x2e}, 	

	{0x48,0xb0}, 
	{0x49,0xc0}, 
	{0x4A,0x58}, 
	{0x4B,0x50}, 
	{0x4C,0xe0},   
	{0x4D,0xc0}, 
	{0x4E,0x30}, 
	{0x4F,0x20}, 
	                  
	{0x50,0xb0}, 
	{0x51,0xc0}, 
	{0x52,0x50}, 
	{0x53,0x60}, 
	{0x54,0xe0},   
	{0x55,0xc0}, 
	{0x56,0x20}, 
	{0x57,0x10}, 
	                  
	{0x58,0xa0},   
	{0x59,0xc0}, 
	{0x5A,0x60},   
	{0x5B,0x58}, 
	{0x5C,0xe0},   
	{0x5D,0xc0}, 
	{0x5E,0x45},   
	{0x5F,0x10}, 

	{0x79,0x00},   
	{0x7a,0xfe},   


	{0xe0,0x0f},   
	{0xe5,0x48},   
	{0xe3,0x58},   
	                 
	{0x73,0x11},   
	               
	{0xa4,0x30},   
	{0xa5,0x30},   
	{0x7f,0x30},   
	{0xbb,0x01},   

	//  TotalH : 0858(035a) = 0656(0290) + 0202(00ca)
	//  TotalV : 0559(022f) = 0508(01fc) + 0051(0033) + [04(04)]

	{0xec,0x00},             
	{0x02,0x00},             
	{0x03,0x6b},     

	// gamma : dc8

	{0xec,0x01}, 
	{0x24,0x08}, 
	{0x25,0x10}, 
	{0x26,0x40}, 
	{0x27,0x80}, 
	{0x28,0x2C}, 
	{0x29,0xD6}, 
	{0x2A,0x0C}, 
	{0x2B,0xFF}, 
	{0x2C,0x00}, 
	{0x2D,0x5F}, 

	{0xB0,0x08}, 
	{0xB1,0x10}, 
	{0xB2,0x40}, 
	{0xB3,0x80}, 
	{0xB4,0x2C}, 
	{0xB5,0xD6}, 
	{0xB6,0x0C}, 
	{0xB7,0xFF}, 
	{0xB8,0x00}, 
	{0xB9,0x5F}, 
	{0xec,0x00},
	{0x77,0xc0},    // color gain
	{0x6c,0x30},    // ae target
	{0x76,0x7a},    // brightness
	{0x78,0x78},    // agc max
	{0x73,0x00},    // frame 

	{0x42,0x26},    
	{0x43,0x3a},
	{0x4a,0x30},

	{0xec,0x01},
	{0x15,0xfa},     // color matrix
	{0x16,0xfd}, 
	{0x20,0xd0},     //high-light color suppress reference
	{0x22,0x2f},     //high-light color suppress gain
	{0x6d,0x0e},     //yc group delay

	{0xec,0x02},
	{0x2c,0x82},     // adlc
	{0x27,0x37},

	{0xec,0x02},
	{0x14,0x01},
	{0x15,0xcf},
	{0xec,0x03},
	{0x08,0x01},
	{0x09,0xcf},
	{0xec,0x00},

	{0xec,0x00},
	{0x0c,0x6a},
	{0x73,0x41},

	// added by junon
	{0xec,0x01}, 
	{0x10,0x26}, // 0x21-ITU-R656(CbYCrY), 0x25-ITU-R601(CbYCrY), 0x26-ITU-R601(YCrYCb)
#endif
};


extern void Camera_Initialize(void);

extern volatile S3C24A0_IOPORT_REG 	*s24A0IOP;
extern volatile S3C24A0_IICBUS_REG 	*s24A0IIC;
extern volatile S3C24A0_INTR_REG 		*s24A0INT;
extern volatile S3C24A0_CLKPWR_REG 	*s24A0PWR;

void Camera_Initialize(void);
void Delay(int time);
void SetCAMClockDivider(int divn);

void CAM_WriteBlock(void);
void Wr_CamIIC(U32 slvAddr, U32 addr, U8 data);
void Rd_CamIIC(U32 slvAddr, U32 addr, U8 *data);
void Run_IicPoll(void);
void IicPoll(void);

static HANDLE IIC_InterruptEvent = NULL;

void Camera_Initialize(void)
{
	UINT Irq = 0;
	if (IIC_InterruptEvent == NULL)
	{
		// allocate the interrupt event for IIC
		IIC_InterruptEvent = CreateEvent(NULL, FALSE, FALSE,NULL);
		
		if (NULL == IIC_InterruptEvent) 
		{
			RETAILMSG(RETAIL_ON,(TEXT("IIC interrupt event Error1\r\n")));
		}
		
		// Obtain sysintr values from the OAL for the camera interrupt.
		//
		Irq = IRQ_IIC;
		if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &Irq, sizeof(UINT32), &gIntrIIC, sizeof(UINT32), NULL))
		{
			RETAILMSG(RETAIL_ON, (TEXT("ERROR: Failed to request the iic sysintr.\r\n")));
			gIntrIIC = SYSINTR_UNDEFINED;			
		}
		
		// initialize the interrupt to the event
		if (!InterruptInitialize (gIntrIIC, IIC_InterruptEvent, NULL, 0)) 
		{
		RETAILMSG(RETAIL_ON,(TEXT("IIC interrupt event Error2\r\n")));
		}
		
	}
	RETAILMSG(RETAIL_ON,(TEXT("Use IIC for initialization\r\n")));

	// Use IIC for initialization
	CAM_WriteBlock();
}

void SetCAMClockDivider(int divn) // divn is even number 0~15
{	
	s24A0PWR->CLKDIVN = (s24A0PWR->CLKDIVN & ~(0xf00)) | ((divn & 0xf)<<8); // CAMCLK is divided..
}

void CamIIC_open(void)
{	
	//Enable ACK, Prescaler IICCLK=PCLK/512, Enable interrupt, Transmit clock value Tx clock=IICCLK/16
	s24A0IIC->IICCON  = (1<<7) | (1<<6) | (1<<5) | ~(1<<4) | (0x3);

	RETAILMSG(RETAIL_ON, (TEXT("----------------------  s24A0IIC->IICSTAT 0x%x\r\n"), s24A0IIC->IICSTAT));

	s24A0IIC->IICSTAT &= ~(1<<4);		//disable serial output before setting IICADD
	s24A0IIC->IICADD  = 0x10;                   //24A0 slave address = [7:1]
	s24A0IIC->IICSTAT = 0x10;                   //IIC bus data output enable(Rx/Tx)
	s24A0IIC->SDADLY  = (1<<2)|(3); 		// SDAOUT has 5clock cycle delay

	RETAILMSG(RETAIL_ON, (TEXT("IICCON = 0x%x IICSTAT = 0x%x IICADD = 0x%x IICDS = 0x%x\r\n"), s24A0IIC->IICCON, s24A0IIC->IICSTAT, s24A0IIC->IICADD, s24A0IIC->IICDS));
}

void CAM_WriteBlock(void)
{
	static U8 rdata[256]; 
	int err = 0;
	int i;
	  	
	CamIIC_open();
	
//	RETAILMSG(RETAIL_ON, (TEXT("IICCON = 0x%x IICSTAT = 0x%x IICADD = 0x%x IICDS = 0x%x\r\n"), s24A0IIC->IICCON, s24A0IIC->IICSTAT, s24A0IIC->IICADD, s24A0IIC->IICDS));
//	RETAILMSG(RETAIL_ON,(_T("Inside CAM_WriteBlock(), size = %d\r\n"), sizeof(S5X532_YCbCr8bit_TV)/2));

//	for(i=0; i<(sizeof(S5X532_YCbCr8bit_TV)/2); i++)
//	{
		//RETAILMSG(RETAIL_ON,(TEXT("num:%d\r\n"),i));	
//		Wr_CamIIC(SlaveID, S5X532_YCbCr8bit_TV[i][0], S5X532_YCbCr8bit_TV[i][1]);
//		Sleep(1);
//	}

        
    
	
	
	
	
	      for(i=0; i<(sizeof(_OV9650_Init)/2); i=i+2)
			{
				Wr_CamIIC(SlaveID, _OV9650_Init[i], _OV9650_Init[i+1]);
			    Sleep(1);
			}
			for(i=0; i<(sizeof(_OV9650_Init_CIF)/2); i=i+2)
			{
				Wr_CamIIC(SlaveID, _OV9650_Init_CIF[i], _OV9650_Init_CIF[i+1]);
			    Sleep(1);
			}


#if 0
	//-------------------------------------------------------------------
	// Routines for IIC Read/Write test start

    for(i=1; i<10; i++)
    {
    	//RETAILMSG(RETAIL_ON,(TEXT("num:%d "),i));
		if (S5X532_YCbCr8bit_TV[i][0] != 0xec)
			Wr_CamIIC(SlaveID, S5X532_YCbCr8bit_TV[i][0], S5X532_YCbCr8bit_TV[i][1]);
		else 
			Rd_CamIIC(SlaveID, S5X532_YCbCr8bit_TV[i][0], &rdata[i]);
		Sleep(1);
	}
    for(i=1; i<10; i++)
    {
		if (S5X532_YCbCr8bit_TV[i][0] != 0xec)
			RETAILMSG(RETAIL_ON,(_T("Page : 0x%x\r\n"), S5X532_YCbCr8bit_TV[i][1]));
		else 
		{			
			RETAILMSG(RETAIL_ON,(_T("Addr: 0x%x, W: 0x%x, R: 0x%x\r\n"), S5X532_YCbCr8bit_TV[i][0], S5X532_YCbCr8bit_TV[i][1], rdata[i]));
			
			if (S5X532_YCbCr8bit_TV[i][1] != rdata[i]) err++;
		}
	}
	if (err) RETAILMSG(RETAIL_ON,(_T("IIC Wr/Rd Error !!!! %d\r\n"), i));
	else RETAILMSG(RETAIL_ON,(_T("IIC Wr/Rd Success !!!!\r\n")));
	
	// Routines for IIC Read/Write test end
	//-------------------------------------------------------------------
#endif

    RETAILMSG(RETAIL_ON,(TEXT("Block TX Ended...\r\n")));	
}

void Wr_CamIIC(U32 slvAddr, U32 addr, U8 data)
{
	_iicMode      	= WRDATA;
	_iicPt        	= 0;
	_iicData[0]   = (U8)addr;
	_iicData[1]   = data;
	_iicDataCount = 2;

	// write slave address
	s24A0IIC->IICDS	= slvAddr;  	//0x5a

	// After this time, timing is critical, because IIC start.
	s24A0IIC->IICSTAT	= 0xf0; 		//Start Master TX Condition    

	s24A0IIC->IICCON	= 0xef;   	//Clearing the pending bit isn't needed because the pending bit has been cleared.

//	RETAILMSG(RETAIL_ON,(_T("Inside Wr_CamIIC(), before while,  _iicDataCount = %d\r\n"), _iicDataCount));
	
	while(_iicDataCount!=-1)
	   	Run_IicPoll();
    
}

void Rd_CamIIC(U32 slvAddr,U32 addr,U8 *data)
{
	/*IIC Slave Addr Write + IIC Reg Addr Write */	
	_iicMode      = SETRDADDR;
	_iicPt        = 0;
	_iicData[0]   = (U8)addr;
	_iicDataCount = 1;
       
    // write slave address
    s24A0IIC->IICDS	= slvAddr;  //0x42: OV7620 Slave ID 

    // After this time, timing is critical, because IIC start.
    s24A0IIC->IICSTAT	= 0xf0; 	//Start Master TX Condition    
    s24A0IIC->IICCON	= 0xef;   	//Clearing the pending bit isn't needed because the pending bit has been cleared.

    while(_iicDataCount!=-1)
       Run_IicPoll();

    _iicMode      = RDDATA;
    _iicPt        = 0;
    _iicDataCount = 1;
    
    s24A0IIC->IICDS   = slvAddr;
    s24A0IIC->IICSTAT = 0xb0;                    //Master Rx,Start
    s24A0IIC->IICCON  = 0xef;                    //Resumes IIC operation. 

    while(_iicDataCount!=-1)
       Run_IicPoll();

	*data = _iicData[1];
}

void Run_IicPoll(void)
{
	DWORD waitStatus;

//	RETAILMSG(RETAIL_ON, (TEXT("In Run_IicPoll, waiting for IIC_InterruptEvent\r\n")));

	// When using Interrupt mode
	waitStatus = WaitForSingleObject(IIC_InterruptEvent, INFINITE);

	// When using polling mode
//    if(s24A0IIC->IICCON & 0x10)                  //Tx/Rx Interrupt Enable
//	RETAILMSG(RETAIL_ON, (TEXT("In Run_IicPoll, IIC_InterruptEvent wait over\r\n")));
       IicPoll();
}       

void IicPoll(void)
{
//	RETAILMSG(RETAIL_ON,(TEXT("IicPoll --> IIC Interrupt occur\r\n")));

    	switch(_iicMode)
    	{
        case RDDATA:
            if((_iicDataCount--)==0)
            {
                _iicData[_iicPt++] = s24A0IIC->IICDS;
            
                s24A0IIC->IICSTAT = 0x90;      //Stop MasRx condition 
                s24A0IIC->IICCON  = 0xef;      //Resumes IIC operation.
                Delay(10);                 //Wait until stop condtion is in effect., Too long time... 
                                                //The pending bit will not be set after issuing stop condition.
                break;    
            }      
            _iicData[_iicPt++] = s24A0IIC->IICDS;     //The last data has to be read with no ack.

            if((_iicDataCount)==0)
                s24A0IIC->IICCON = 0x6f;                 //Resumes IIC operation with NOACK in case of OV7620 Cameara  
            else 
                s24A0IIC->IICCON = 0xef;                 //Resumes IIC operation with ACK
            break;

        case WRDATA:
            if((_iicDataCount--)==0)
            {
                s24A0IIC->IICSTAT = 0xd0;                //stop MasTx condition 
                s24A0IIC->IICCON  = 0xef;                //resumes IIC operation.
                Delay(10);                       		// we should adjust this time.
                
                //The pending bit will not be set after issuing stop condition.
                break;
            }
          
            s24A0IIC->IICDS = _iicData[_iicPt++];        	//_iicData[0] has dummy.
            //for setup time until rising edge of IICSCL. we have to adjust this time.
			Delay(10);
            //for(i=0;i<1000;i++);
			// IICDS has to be written before clearing the IIC interrupt pending bit
			//RETAILMSG(RETAIL_ON,(TEXT("BB")));						// we should adjust this time.
            
            s24A0IIC->IICCON = 0xef;                    	 //resumes IIC operation.
            
            break;

        case SETRDADDR:
            if((_iicDataCount--)==0)
            {
                  s24A0IIC->IICSTAT = 0xd0;                //stop MasTx condition 
    		    s24A0IIC->IICCON  = 0xef;                //resumes IIC operation.
                  Delay(1);      //wait until stop condtion is in effect.
                  
                  
                  break;                  //IIC operation is stopped because of IICCON[4]    
            }

            s24A0IIC->IICDS = _iicData[_iicPt++];
			Delay(10); 
			//for(i=0;i<1000;i++);          //for setup time until rising edge of IICSCL
            //RETAILMSG(RETAIL_ON,(TEXT("RD")));				// we should adjust this time.
            s24A0IIC->IICCON = 0xef;             //resumes IIC operation.
            break;

        default:
            break;      
    }
    
    InterruptDone(gIntrIIC);
}

void Delay(int time)
{
    volatile int i;
    
    for(;time>0;time--)
        for(i=0;i<100;i++);
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?