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

📄 eeprom.c

📁 这是飞凌TE2410开发板的Bootloader源程序。
💻 C
字号:
/*
to support wr/rd parameters to/from eeprom
*/
#include "def.h"
#include "2440addr.h"
#include "2440lib.h"

#define	SLV_ADDR_24C02	0xa0
#define	SLV_ADDR_CAMERA	0x42//0x5a

void mdelay(int ms);

static volatile int iic_ints;
static void __irq IicInt(void)
{
	ClearPending(BIT_IIC);
	iic_ints++;
}

static int iic_wr(U8 data, U8 cnt)
{
	int i, c;

	for(i=0; i<20; i++);
	
	if(cnt)
		rIICDS = data;
		
	rIICCON &= ~0x10;		//Resume IIC operation to send

	i = 3;	//3ms
	//while(!(rIICCON&0x10)&&i--) mdelay(1);
	c = iic_ints;
	while(iic_ints==c&&i--) mdelay(1);
	//rIICCON &= ~0x10;
	
	if(!i)
		return -1;

	return (rIICSTAT&1)?-1:0;
}

static int iic_rd(U8 *pBuf)
{
	int i, c;
	
	for(i=0; i<20; i++);
	
	rIICCON &= ~0x10;		//Resumes IIC operation to receive
	i = 3;	//3ms
	//while(!(rIICCON&0x10)&&i--) mdelay(1);
	c = iic_ints;
	while(iic_ints==c&i--) mdelay(1);
	
	if(i) {
		*pBuf = rIICDS;
		return 0;
	}
	
	return -1;
}

static int seek_iic_device(U8 slvAddr)
{
	int i;
	U8 d;
	
	i = 200;				//200ms
	while(i--) {
		rIICDS   = slvAddr;
		rIICSTAT = 0xb0;	//read mode
		if(!iic_wr(0, 0)) {
			iic_rd(&d);
			break;
		}
		mdelay(1);
	}
	rIICSTAT = 0x90;
	rIICCON &= ~0x10;		//Resume IIC operation to send stop
	mdelay(1);

	return (i>=0)?0:-1;
}

//8 bits register address only
static int write_eeprom(U8 slvAddr, U8 addr, U8 data)
{
	int i;
	U8 ch[3];
	
	ch[1] = addr;
	ch[2] = data;
	
	rIICDS   = slvAddr;
	rIICSTAT = 0xf0;		//MasTx,Start
	for(i=0; i<3; i++)
		if(iic_wr(ch[i], i))
			break;
	rIICSTAT = 0xd0;		//Stop MasTx condition
	rIICCON &= ~0x10;		//Resume IIC operation to send stop
	mdelay(1);
	if(i<3)
		return -1;
		
	return seek_iic_device(slvAddr);
}

//8 bits register address only
static int read_eeprom(U8 slvAddr, U8 addr, U8 *pBuf)
{
	int i;
	U8 ch[2];
	
	ch[1] = addr;
	
	rIICDS   = slvAddr;
	rIICSTAT = 0xf0;		//MasTx,Start
	for(i=0; i<2; i++)
		if(iic_wr(ch[i], i))
			break;
	if(i<2) {
		rIICSTAT = 0xd0;	//Stop MasTx condition
		rIICCON &= ~0x10;	//Resume IIC operation to send stop
		mdelay(1);
		return -1;
	}

	rIICDS   = slvAddr;
	rIICSTAT = 0xb0;		//Master Rx,Start
	if(!iic_wr(0, 0))		//wait ack
		i = iic_rd(pBuf);
	rIICSTAT = 0x90;		//Stop MaxRx condition
	rIICCON &= ~0x10;		//Resume IIC operation to send stop
	mdelay(1);
	
	return i;
}

static void init_iic_op(void)
{
	rCLKCON |= 1<<16;
	
	rGPEUP  |= 0xc000;                  //Pull-up disable
	rGPECON &= ~0xf0000000;
	rGPECON |= 0xa0000000;              //GPE15:IICSDA , GPE14:IICSCL 
	
	//Enable ACK, Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16
	// If PCLK 50.7MHz, IICCLK = 3.17MHz, Tx Clock = 0.198MHz
	//rIICCON = (1<<7) | (1<<6) | (1<<5) | (0);	//IICCLK=PCLK/512=97K
	//just read one byte, don't enable ack!
	rIICCON = (0<<7) | (1<<6) | (1<<5) | (0);	//IICCLK=PCLK/512=97K
	
	rIICSTAT = 0x10;                    //IIC bus data output enable(Rx/Tx)
	rIICADD  = 0x10;                    //2410 slave address = [7:1]
	
	pISR_IIC = (unsigned)IicInt;
	EnableIrq(BIT_IIC);
}

static void end_iic_op(void)
{
//	rCLKCON &= ~(1<<16);
	DisableIrq(BIT_IIC);
}

int write_24c02(U8 *pBuf)
{
	int i;
	
	init_iic_op();
	
	for(i=0; i<256; i++) {
		//if(seek_iic_device(SLV_ADDR_24C02))
		//	break;
		if(write_eeprom(SLV_ADDR_24C02, i, pBuf[i]))
			break;
	}
	
	end_iic_op();
	
	Uart_Printf("Write EEPROM %s!\n", (i<256)?"Fail":"Success");
	
	return i<256;
}

int read_24c02(U8 *pBuf)
{
	int i;
	
	init_iic_op();
	
	for(i=0; i<256; i++) {
		if(read_eeprom(SLV_ADDR_24C02, i, pBuf+i))
			break;
	}
	
	end_iic_op();
	
	Uart_Printf("Read EEPROM %s!\n", (i<256)?"Fail":"Success");

	return i<256;
}

int find_camera(void)
{
	int ret = -2;
	U8 d[256];
	
	rGPGCON &= ~(3<<24);
	rGPGCON |= 1<<24;
	rGPGUP  &= ~(1<<12);
	rGPGDAT |= 1<<12;
	
	rGPJCON = 0x1aaaaaa;
	rGPJUP  = 0;
	rGPJDAT = 0;
	mdelay(10);
	rGPJDAT = 1<<12;
	mdelay(10);
	
	init_iic_op();
	
	if(!write_eeprom(SLV_ADDR_CAMERA, 0xec, 0)) {
		int i, a;
		
		ret = -1;
		a = 0xb0;
		for(i=0; i<4; i++)
			if(read_eeprom(SLV_ADDR_CAMERA, a+i, d+i))
				break;
		if(i>=4)
			ret = 0;
		
	//	Uart_Printf("i = %d\n", i);
	//	for(i=0; i<256; i++)
	//		Uart_Printf("%c%02x", (i%16)?' ':'\n', d[i]);
	}
	
	end_iic_op();

	switch(ret)	{
	case -2:
		Uart_Printf("Fail to write camera IIC!\n");
		break;
	case -1:
		Uart_Printf("Fail to read camera IIC!\n");
		break;
	case 0:
		Uart_Printf("Read camera ID is 0x%04x, ", (d[0]<<8)|d[1]);
		Uart_Printf("chip version is 0x%04x\n", (d[2]<<8)|d[3]);
		break;
	default:
		break;
	}
		
	return ret;
}

⌨️ 快捷键说明

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