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

📄 iic.c

📁 samsung 最新芯片2450 的测试程序.
💻 C
字号:
;/*********************************************************************
;* Project Name : S3C2443X
;*
;* Copyright 2005 by Samsung Electronics, Inc.
;* All rights reserved.
;*
;* Project Description :
;* This software is only for verifying functions of the mDirac III
;* Anybody can use this code without our permission.
;**********************************************************************
;*
;*	Description	:	Code for the basic function for IIC.
;*					It can support write and read mode with 7-bit addresses
;*					Can make the 10-bit address write and read mode
;*					with assemble these functions.
;*	
;*	History
;*			R0.0 (2005.9.30) : Y.C.Kwon draft
;*
;**********************************************************************/

#include "System.h"
#include "iic.h"
#include "iic1.h"


#define	SlaveRX			(0)
#define	SlaveTX			(1)
#define	MasterRX		(2)
#define	MasterTX		(3)


static volatile char *IIC_BUFFER;
//static volatile char IIC_BUFFER[3];
static volatile unsigned int IIC_PT;
static unsigned int IIC_DATALEN;
static volatile unsigned char IIC_STAT;


void * iic_func[][2]=
{
	(void *) Test_IIC_Int,				(char *)"IIC Test(Int)         ",
	(void *) Test_IIC_Pol,			(char *)"IIC Test(Poll)        ", 						//	"123456789012345678901"
	(void *) Test_IIC1_Int,				(char *)"IIC1 Test(Int)        ",
	(void *) Test_IIC1_Pol,			(char *)"IIC1 Test(Poll)       ",
	0,0
};

void Test_IIC(void)
{
	int i=0;

	while(1)
	{
		i=0;
		printf("\n\n");
		while(1)
		{   //display menu
			printf("%2d:%s",i,iic_func[i][1]);
			i++;
			if((int)(iic_func[i][0])==0)
			{
				printf("\n");
				break;
			}
			printf("\n");
		}

		printf("\nPress Enter key to exit : ");
		i = GetIntNum();
		if(i==-1) break;		// return.
		if(i>=0 && (i<((sizeof(iic_func)-1)/8)) )	// select and execute...
			( (void (*)(void)) (iic_func[i][0]) )();
	}

}



void __irq IIC_Int( void)
{
	IIC_STAT = rIICSTAT;

	switch( (IIC_STAT>>6)&0x3) {

	case SlaveRX	:	break;

	case SlaveTX	:	break;

	case MasterRX	:	if (IIC_PT>0)
							IIC_BUFFER[IIC_PT-1] = rIICDS;
						
						IIC_PT++;

						if (IIC_PT==IIC_DATALEN)
							rIICCON 	&=  ~(1<<7);
						else if (IIC_PT>IIC_DATALEN)
							rIICSTAT	=	0x90;			//	Stop Master Rx condition

						rIICCON &= ~(1<<4);					//	Clear pending bit to resume
						break;

	case MasterTX	:	if (IIC_PT<IIC_DATALEN)
							rIICDS	=	IIC_BUFFER[IIC_PT];
						else	
							rIICSTAT= 	0xd0;				//	Stop Master Tx condition, ACK flag clear

						IIC_PT++;

						rIICCON &= ~(1<<4);					//	Clear pending bit to resume
						break;
	}

	IIC_STAT&=0xf;
	ClearPending(BIT_IIC);
}

void IIC_open( unsigned int freq)		//	Hz order.
{
	unsigned int	clk_prescaler, clk_divider;

      rGPECON = rGPECON & ~(0xf<<28) | (0xa<<28); // IIC setting
      rGPEUDP = rGPEUDP & ~(0xf<<28) | (0x0<<28);	
    
     if (((PCLK>>4)/freq)>0xf) {
		clk_prescaler	=	1;
		clk_divider		=	(PCLK>>9)/freq;		//	PCLK/512/freq
	} else {
		clk_prescaler	=	0;
		clk_divider		=	(PCLK>>4)/freq;		//	PCLK/16/freq
	}

   	//	Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16
	rIICCON		=	(clk_prescaler<<6) | (1<<5) | (clk_divider&0xf);


	rIICADD		=	0x10;							//	Slave address = [7:1]
	rIICSTAT	=	0x10;                  			//	IIC bus data output enable(Rx/Tx)
	rIICLC		=	0;		 						//	SDA Filter disable
}

void IIC_open_Cam( unsigned int freq)		//	Hz order.
{
	unsigned int	clk_prescaler, clk_divider;

      rGPECON = rGPECON & ~(0xf<<28) | (0xa<<28); // IIC setting
      rGPEUDP = rGPEUDP & ~(0xf<<28) | (0x0<<28);	
    
       pISR_IIC = (unsigned)IIC_Int;
	rINTMSK &= ~(BIT_IIC);

	if (((PCLK>>4)/freq)>0xf) {
		clk_prescaler	=	1;
		clk_divider		=	(PCLK>>9)/freq;		//	PCLK/512/freq
	} else {
		clk_prescaler	=	0;
		clk_divider		=	(PCLK>>4)/freq;		//	PCLK/16/freq
	}

   	//	Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16
	rIICCON		=	(clk_prescaler<<6) | (1<<5) | (clk_divider&0xf);

	rIICADD		=	0x10;							//	Slave address = [7:1]
	rIICSTAT	=	0x10;                  			//	IIC bus data output enable(Rx/Tx)
	rIICLC		=	0;		 						//	SDA Filter disable
}


void IIC_close( void)
{
	rINTMSK |= BIT_IIC;

	rIICSTAT = 0x0;                    		//	IIC bus data output disable(Rx/Tx)
}

//	Write Mode Format with 7-bit addresses
void IIC_Write( unsigned char SlaveAddr, char *Data, unsigned int n)
{
	while(rIICSTAT&(1<<5));					//	Wait until IIC bus is free.

//	IIC_BUFFER[1]	=	*Data;
	IIC_BUFFER	=	Data;
	IIC_PT		=	0;
	IIC_DATALEN	=	n;

	rIICCON 	|=  (1<<7);
	rIICDS		=	SlaveAddr;
	rIICSTAT	=	0xF0;					//	Master Tx Start.
}

void IIC_Write_Pol( unsigned char SlaveAddr, char *Data, unsigned int n)
{

	while(rIICSTAT&(1<<5));					//	Wait until IIC bus is free.

 //	IIC_BUFFER[1]	=	*Data;
	IIC_BUFFER	=	Data;
	IIC_PT		=	0;
	IIC_DATALEN	=	n;

	rIICCON 	|=  (1<<7); // acknowledge enable bit
	rIICDS		=	SlaveAddr;
	rIICSTAT	=	0xF0;					//	Master Tx Start.
	
	while(IIC_DATALEN >= IIC_PT)
	{

		while(!(rIICCON&(1<<4))); // check the interrupt pending bit
	
		IIC_STAT = rIICSTAT;

		switch( (IIC_STAT>>6)&0x3) {

		case SlaveRX	:	break;

		case SlaveTX	:	break;

		case MasterRX	:	if (IIC_PT>0)
								IIC_BUFFER[IIC_PT-1] = rIICDS;

							IIC_PT++;

							if (IIC_PT==IIC_DATALEN)
								rIICCON 	&=  ~(1<<7);
							else if (IIC_PT>IIC_DATALEN)
								rIICSTAT	=	0x90;			//	Stop Master Rx condition

							rIICCON &= ~(1<<4);					//	Clear pending bit to resume
							break;

		case MasterTX	:	if (IIC_PT<IIC_DATALEN)
								rIICDS	=	IIC_BUFFER[IIC_PT];
		                                          
							else	
								rIICSTAT= 	0xd0;				//	Stop Master Tx condition, ACK flag clear

							IIC_PT++;

							rIICCON &= ~(1<<4);					//	Clear pending bit to resume
							break;
		}

		IIC_STAT&=0xf;  // check status flag
	}
	
}

//	Read Mode Format with 7-bit addresses
void IIC_Read( unsigned char SlaveAddr, char *Data, unsigned int n)
{
	while(rIICSTAT&(1<<5));					//	Wait until IIC bus is free.

//	IIC_BUFFER[1]	=	*Data;
	IIC_BUFFER	=	Data;
	IIC_PT		=	0;
	IIC_DATALEN	=	n;

	rIICCON 	|=  (1<<7);
	rIICDS		=	SlaveAddr;
	rIICSTAT	=	0xB0;					//	Master Rx Start
}

void IIC_Read_Pol( unsigned char SlaveAddr, char *Data, unsigned int n)
{
	while(rIICSTAT&(1<<5));					//	Wait until IIC bus is free.

//	IIC_BUFFER[1]	=	*Data;
	IIC_BUFFER	=	Data;
	IIC_PT		=	0;
	IIC_DATALEN	=	n;

	rIICCON 	|=  (1<<7);
	rIICDS		=	SlaveAddr;
	rIICSTAT	=	0xB0;					//	Master Rx Start
	
	while(IIC_DATALEN >= IIC_PT)
	{
		
		while(!(rIICCON&(1<<4)));
		
		IIC_STAT = rIICSTAT;

		switch( (IIC_STAT>>6)&0x3) {

		case SlaveRX	:	break;

		case SlaveTX	:	break;

		case MasterRX	:	if (IIC_PT>0)
								IIC_BUFFER[IIC_PT-1] = rIICDS;
		                                    
							IIC_PT++;

							if (IIC_PT==IIC_DATALEN)
								rIICCON 	&=  ~(1<<7);
						
							else if (IIC_PT>IIC_DATALEN)
								rIICSTAT	=	0x90;			//	Stop Master Rx condition

							rIICCON &= ~(1<<4);					//	Clear pending bit to resume
							break;

		case MasterTX	:	if (IIC_PT<IIC_DATALEN)
								rIICDS	=	IIC_BUFFER[IIC_PT];
							else	
								rIICSTAT= 	0xd0;				//	Stop Master Tx condition, ACK flag clear

							IIC_PT++;

							rIICCON &= ~(1<<4);					//	Clear pending bit to resume
							break;
		}

		IIC_STAT&=0xf;  // check status flag
	}
}



void IIC_Wait( void)						//	Waiting for the command takes effect.
{											//	But not for IIS bus free.
	while(IIC_PT<=IIC_DATALEN);
}

unsigned char IIC_Status( void)						//	Return IIC Status Register value at last interrupt occur.
{
	return	IIC_STAT;
}


//****************************************************************//
//*	Basic test code for Serial EEPROM with the basic functions.
//****************************************************************//

#define	EEPROMSlaveAddr		0xa0

void WrSerialEEPROM( char Addr, char Data)
{
	char D[2];
	

	D[0]=Addr;
	D[1]=Data;
	IIC_Write( EEPROMSlaveAddr, D, 2);

     
	do	{									//	Polling for an ACK signal from SerialEEPROM.
		IIC_Write( EEPROMSlaveAddr, NULL, 0);
		IIC_Wait();
	} while(IIC_Status()&0x1);
	
}

void WrSerialEEPROM_Pol( char Addr, char Data)
{
	char D[2];
	

	D[0]=Addr;
	D[1]=Data;
	IIC_Write_Pol( EEPROMSlaveAddr, D, 2);

	
	do	{												//	Polling for an ACK signal from SerialEEPROM.
		IIC_Write_Pol( EEPROMSlaveAddr, NULL, 0);
		IIC_Wait();
		} while(IIC_Status()&0x1); // ACK was not received

}


void RdSerialEEPROM( char Addr, char *Data)
{
	IIC_Write( EEPROMSlaveAddr, &Addr, 1);
	IIC_Read( EEPROMSlaveAddr, Data, 1);
	IIC_Wait();								//	Waiting for read complete.
}

void RdSerialEEPROM_Pol( char Addr, char *Data)
{
	IIC_Write_Pol( EEPROMSlaveAddr, &Addr, 1);
	IIC_Read_Pol( EEPROMSlaveAddr, Data, 1);
	IIC_Wait();								//	Waiting for read complete.
}

void Test_IIC_Int( void)
{
    unsigned int i;
    char D;

    printf("[ IIC Test using Serial EEPROM ]\n");

	IIC_open(200000);	//	Serial EEPROM IIC clk = 200KHz

	pISR_IIC = (unsigned)IIC_Int;
	rINTMSK &= ~(BIT_IIC);
	
    printf("\nWrite (0xff) and read back from EEPROM\n");
    
    for(i=0;i<256;i++) {
       D=0;
        WrSerialEEPROM(i,0xff);
        RdSerialEEPROM(i,&D);
 	printf("%02x ",D);
        if ((i&0xf)==0xf) printf("\n");
    }

    printf("\nWrite (0~255) and read back from EEPROM\n");
    
    for(i=0;i<256;i++) {
        D=0;
        WrSerialEEPROM(i,i);
        RdSerialEEPROM(i,&D);
        printf("%02x ",D);
        if ((i&0xf)==0xf) printf("\n");
    }

    IIC_close();
}

void Test_IIC_Pol( void)
{
    unsigned int i;
    char D;

    printf("[ IIC Test using Serial EEPROM [polling mode] ]\n");

    
 	IIC_open(200000);	//	Serial EEPROM IIC clk = 200KHz
	
    printf("\nWrite (0xff) and read back from EEPROM\n");
    
    for(i=0;i<256;i++) {
        D=0;
        WrSerialEEPROM_Pol(i,0xff);
        RdSerialEEPROM_Pol(i,&D);
        printf("%02x ",D);
        if ((i&0xf)==0xf) printf("\n");
    }

    printf("\nWrite (0~255) and read back from EEPROM\n");
    
    for(i=0;i<256;i++) {
        D=0;
        WrSerialEEPROM_Pol(i,i);
        RdSerialEEPROM_Pol(i,&D);
        printf("%02x ",D);
        if ((i&0xf)==0xf) printf("\n");
    }

    IIC1_close();
}

⌨️ 快捷键说明

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