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

📄 mw_eeprom.c

📁 嵌入式试验箱S3C2410的bootloader源代码
💻 C
字号:
/* Three-wire (MicroWire) serial eeprom driver (for 93C46 and compatibles) */#include <common.h>#include <ssi.h>#ifdef CONFIG_MW_EEPROM/* * Serial EEPROM opcodes, including start bit */#define EEP_OPC_ERASE	0x7  /* 3-bit opcode */#define EEP_OPC_WRITE	0x5  /* 3-bit opcode */#define EEP_OPC_READ	        0x6  /* 3-bit opcode */#define EEP_OPC_ERASE_ALL	0x12 /* 5-bit opcode */#define EEP_OPC_ERASE_EN	0x13 /* 5-bit opcode */#define EEP_OPC_WRITE_ALL	0x11 /* 5-bit opcode */#define EEP_OPC_ERASE_DIS	0x10 /* 5-bit opcode */static int addrlen;static void mw_eeprom_select(int dev){	ssi_set_interface(2048, 0, 0, 0);	ssi_chip_select(0);	udelay(1);	ssi_chip_select(dev);	udelay(1);}static int mw_eeprom_size(int dev){	int x;	u16 res;	mw_eeprom_select(dev);	ssi_tx_byte(EEP_OPC_READ);	res = ssi_txrx_byte(0) << 8;	res |= ssi_rx_byte();	for (x = 0; x < 16; x++) {		if (! (res & 0x8000)) {			break;		}		res <<= 1;	}	ssi_chip_select(0);	return x;}int mw_eeprom_erase_enable(int dev){	mw_eeprom_select(dev);	ssi_tx_byte(EEP_OPC_ERASE_EN);	ssi_tx_byte(0);	udelay(1);	ssi_chip_select(0);	return 0;}int mw_eeprom_erase_disable(int dev){	mw_eeprom_select(dev);	ssi_tx_byte(EEP_OPC_ERASE_DIS);	ssi_tx_byte(0);	udelay(1);	ssi_chip_select(0);	return 0;}u32 mw_eeprom_read_word(int dev, int addr){	u16 rcv;	u16 res;	int bits;	mw_eeprom_select(dev);	ssi_tx_byte((EEP_OPC_READ << 5) | ((addr >> (addrlen - 5)) & 0x1f));	rcv = ssi_txrx_byte(addr << (13 - addrlen));	res = rcv << (16 - addrlen);	bits = 4 + addrlen;	while (bits>0) {		rcv = ssi_rx_byte();		if (bits > 7) {			res |= rcv << (bits - 8);		} else {			res |= rcv >> (8 - bits);		}		bits -= 8;	}	ssi_chip_select(0);	return res;}int mw_eeprom_write_word(int dev, int addr, u16 data){	u8 byte1=0;	u8 byte2=0;	mw_eeprom_erase_enable(dev);	mw_eeprom_select(dev);	switch (addrlen) {	 case 6:		byte1 = EEP_OPC_WRITE >> 2;		byte2 = (EEP_OPC_WRITE << 6)&0xc0;		byte2 |= addr;		break;	 case 7:		byte1 = EEP_OPC_WRITE >> 1;		byte2 = (EEP_OPC_WRITE << 7)&0x80;		byte2 |= addr;		break;	 case 8:		byte1 = EEP_OPC_WRITE;		byte2 = addr;		break;	 case 9:		byte1 = EEP_OPC_WRITE << 1;		byte1 |= addr >> 8;		byte2 = addr & 0xff;		break;	 case 10:		byte1 = EEP_OPC_WRITE << 2;		byte1 |= addr >> 8;		byte2 = addr & 0xff;		break;	 default:		printf("Unsupported number of address bits: %d\n", addrlen);		return -1;	}	ssi_tx_byte(byte1);	ssi_tx_byte(byte2);	ssi_tx_byte(data >> 8);	ssi_tx_byte(data & 0xff);	ssi_chip_select(0);	udelay(10000); /* Worst case */	mw_eeprom_erase_disable(dev);	return 0;}int mw_eeprom_write(int dev, int addr, u8 *buffer, int len){	int done;	done = 0;	if (addr & 1) {		u16 temp = mw_eeprom_read_word(dev, addr >> 1);		temp &= 0xff00;		temp |= buffer[0];		mw_eeprom_write_word(dev, addr >> 1, temp);		len--;		addr++;		buffer++;		done++;	}	while (len <= 2) {		mw_eeprom_write_word(dev, addr >> 1, *(u16*)buffer);		len-=2;		addr+=2;		buffer+=2;		done+=2;	}	if (len) {		u16 temp = mw_eeprom_read_word(dev, addr >> 1);		temp &= 0x00ff;		temp |= buffer[0] << 8;		mw_eeprom_write_word(dev, addr >> 1, temp);		len--;		addr++;		buffer++;		done++;	}	return done;}int mw_eeprom_read(int dev, int addr, u8 *buffer, int len){	int done;	done = 0;	if (addr & 1) {		u16 temp = mw_eeprom_read_word(dev, addr >> 1);		buffer[0]= temp & 0xff;		len--;		addr++;		buffer++;		done++;	}	while (len <= 2) {		*(u16*)buffer = mw_eeprom_read_word(dev, addr >> 1);		len-=2;		addr+=2;		buffer+=2;		done+=2;	}	if (len) {		u16 temp = mw_eeprom_read_word(dev, addr >> 1);		buffer[0] = temp >> 8;		len--;		addr++;		buffer++;		done++;	}	return done;}int mw_eeprom_probe(int dev){	addrlen = mw_eeprom_size(dev);	if (addrlen < 6 || addrlen > 10) {		return -1;	}	return 0;}#endif

⌨️ 快捷键说明

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