⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iic.cpp

📁 wince底层驱动开发代码 ARM作为一种嵌入式系统处理器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	{0x2D,0x1B},
	{0xB0,0x28},
	{0xB1,0x3F},
	{0xB2,0x65},
	{0xB3,0xA1},
	{0xB4,0xFF},
	{0xB5,0x96},
	{0xB6,0x85},
	{0xB7,0xFF},
	{0xB8,0x00},
	{0xB9,0x1B},
	{0x15,0x15},
	{0x18,0x85},
	{0x1f,0x05},
	{0x87,0x40},
	{0x37,0x60},
	{0x38,0xd5},
	{0x48,0xa0},
	{0x61,0x54},
	{0x62,0x54},
	{0x63,0x14},
	{0x64,0x14},
	{0x6d,0x12},
	{0x78,0x09},
	{0x79,0xD7},
	{0x7A,0x14},
	{0x7B,0xEE},
	                 
	//=============== page2 ===============//
	{0xec,0x02},
	{0x2c,0x76},
	{0x25,0x25},
	{0x27,0x27},
	{0x30,0x29},
	{0x36,0x08},
	{0x38,0x04},

	//=============== page3 ===============//
	{0xec,0x03},
	{0x08,0x00},
	{0x09,0x33},

	//=============== page4 ===============//
	{0xec,0x04},
	{0x00,0x21},
	{0x01,0x00},            
	{0x02,0x9d},            
	{0x03,0x02},            
	{0x04,0x04},         
	{0x05,0x00},            
	{0x06,0x1f},          
	{0x07,0x02},            
	{0x08,0x21},            
	{0x09,0x00},            
	{0x0a,0x9d},           
	{0x0b,0x02},            
	{0x0c,0x04},             
	{0x0d,0x00},            
	{0x0e,0x20},            
	{0x0f,0x02},            
	{0x1b,0x3c},            
	{0x1c,0x3c},            

	//=============== page5 ===============//
	{0xec,0x05},                               
	{0x1f,0x00},                               
	{0x08,0x59},            
	{0x0a,0x71},            
	{0x1e,0x23},            
	{0x0e,0x3c},            

	//=============== page7 ===============//
	{0xec,0x07},
	{0x11,0xfe},

	// 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 IOPreg *s2440IOP;
extern volatile IICreg *s2440IIC;

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)
{
	if (IIC_InterruptEvent == NULL)
	{
	    // allocate the interrupt event for IIC
	    IIC_InterruptEvent = CreateEvent(NULL, FALSE, FALSE,NULL);
	    
	    if (NULL == IIC_InterruptEvent) {
			RETAILMSG(1,(TEXT("IIC interrupt event Error1\r\n")));
	    }
	    // initialize the card insertion interrupt event
	    if (!InterruptInitialize (SYSINTR_IIC, IIC_InterruptEvent, NULL, 0)) {
			RETAILMSG(1,(TEXT("IIC interrupt event Error2\r\n")));
	    }
	}
	RETAILMSG(1,(TEXT("Use IIC for initialization\r\n")));
	// Use IIC for initialization
	CAM_WriteBlock();
}

void SetCAMClockDivider(int divn) // divn is even number 0~15
{
	volatile CLKPWRreg	*s2440PWR = (CLKPWRreg *)CLKPWR_BASE;
	
	s2440PWR->rCAMDIVN = (s2440PWR->rCAMDIVN & ~(0xf))|(0x10)|(divn); // CAMCLK is divided..
//	RETAILMSG(1,(TEXT("s2440PWR->rCLKCON:0x%x\r\n"),s2440PWR->rCLKCON));
}

void CAM_WriteBlock(void)
{
    unsigned int i, save_E, save_PE;
    static U8 rdata[256]; 
    int err = 0;
      	
    save_E   = s2440IOP->rGPECON;
    save_PE  = s2440IOP->rGPEUP;

    s2440IOP->rGPEUP  &= ~0xc000;                  	//Pull-up disable
    s2440IOP->rGPEUP  |=  0xc000;                  	//Pull-up disable
    s2440IOP->rGPECON &= ~(0xF<<28);                //GPE15:IICSDA , GPE14:IICSCL    
    s2440IOP->rGPECON |=  (0xa<<28);                //GPE15:IICSDA , GPE14:IICSCL    

    //Enable ACK, Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16
    s2440IIC->rIICCON  = (1<<7) | (1<<6) | (1<<5) | (0xf);

    s2440IIC->rIICADD  = 0x10;                    	//2440 slave address = [7:1]. this is avialable when 240 is slave.
    s2440IIC->rIICSTAT = 0x10;                    	//IIC bus data output enable(Rx/Tx)
    s2440IIC->rIICLC = (1<<2)|(3);  				// Filter enable, 15 clocks SDA output delay     added into 2440
  
    for(i=0; i<(sizeof(S5X532_YCbCr8bit_TV)/2); i++){
    	//RETAILMSG(1,(TEXT("num:%d\r\n"),i));	
		Wr_CamIIC(SlaveID, S5X532_YCbCr8bit_TV[i][0], S5X532_YCbCr8bit_TV[i][1]);
		Sleep(1);
	}
	
    RETAILMSG(1,(TEXT("Block TX Ended...\r\n")));	

    s2440IOP->rGPEUP  = save_PE;
    s2440IOP->rGPECON = save_E;
}

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
    s2440IIC->rIICDS	= slvAddr;  //0x42: OV7620 Slave ID 
    // After this time, timing is critical, because IIC start.
    s2440IIC->rIICSTAT	= 0xf0; 	//Start Master TX Condition    
    s2440IIC->rIICCON	= 0xef;   	//Clearing the pending bit isn't needed because the pending bit has been cleared.

    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
    s2440IIC->rIICDS	= slvAddr;  //0x42: OV7620 Slave ID 
    // After this time, timing is critical, because IIC start.
    s2440IIC->rIICSTAT	= 0xf0; 	//Start Master TX Condition    
    s2440IIC->rIICCON	= 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;
    
    s2440IIC->rIICDS   = slvAddr;
    s2440IIC->rIICSTAT = 0xb0;                    //Master Rx,Start
    s2440IIC->rIICCON  = 0xef;                    //Resumes IIC operation. 

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

	*data = _iicData[1];    
	//RETAILMSG(1,(TEXT("Data:0x%x\r\n"),_iicData[1]));
}

void Run_IicPoll(void)
{
	DWORD waitStatus;
	
	// When using Interrupt mode
	waitStatus = WaitForSingleObject(IIC_InterruptEvent, INFINITE);
	// When using polling mode
//    if(s2440IIC->rIICCON & 0x10)                  //Tx/Rx Interrupt Enable
       	IicPoll();
}       

void IicPoll(void)
{
    volatile U32 i;

	//RETAILMSG(1,(TEXT("IIC Interrupt occur\r\n")));

    switch(_iicMode)
    {
        case RDDATA:
            if((_iicDataCount--)==0)
            {
                _iicData[_iicPt++] = s2440IIC->rIICDS;
            
                s2440IIC->rIICSTAT = 0x90;      //Stop MasRx condition 
                s2440IIC->rIICCON  = 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++] = s2440IIC->rIICDS;     //The last data has to be read with no ack.

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

        case WRDATA:
            if((_iicDataCount--)==0)
            {
                s2440IIC->rIICSTAT = 0xd0;                //stop MasTx condition 
                s2440IIC->rIICCON  = 0xef;                //resumes IIC operation.
                Delay(10);                       		// we should adjust this time.
                
                //The pending bit will not be set after issuing stop condition.
                break;    
            }
          
            s2440IIC->rIICDS = _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(1,(TEXT("BB")));						// we should adjust this time.
            
            s2440IIC->rIICCON = 0xef;                    	 //resumes IIC operation.
            
            break;

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

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

        default:
            break;      
    }
    
    InterruptDone(SYSINTR_IIC);
}

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

⌨️ 快捷键说明

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