cmd_i2c.c

来自「uboot详细解读可用启动引导LINUX2.6内核」· C语言 代码 · 共 1,330 行 · 第 1/3 页

C
1,330
字号
		/*		 * Chip is always specified.		 */		chip = simple_strtoul(argv[1], NULL, 16);		/*		 * Address is always specified.		 */		addr = simple_strtoul(argv[2], NULL, 16);		alen = 1;		for (j = 0; j < 8; j++) {			if (argv[2][j] == '.') {				alen = argv[2][j+1] - '0';				if (alen > 4) {					printf ("Usage:\n%s\n", cmdtp->usage);					return 1;				}				break;			} else if (argv[2][j] == '\0')				break;		}	}	/*	 * Print the address, followed by value.  Then accept input for	 * the next value.  A non-converted value exits.	 */	do {		printf("%08lx:", addr);		if (i2c_read(chip, addr, alen, (uchar *)&data, size) != 0)			puts ("\nError reading the chip,\n");		else {			data = cpu_to_be32(data);			if (size == 1)				printf(" %02lx", (data >> 24) & 0x000000FF);			else if (size == 2)				printf(" %04lx", (data >> 16) & 0x0000FFFF);			else				printf(" %08lx", data);		}		nbytes = readline (" ? ");		if (nbytes == 0) {			/*			 * <CR> pressed as only input, don't modify current			 * location and move to next.			 */			if (incrflag)				addr += size;			nbytes = size;#ifdef CONFIG_BOOT_RETRY_TIME			reset_cmd_timeout(); /* good enough to not time out */#endif		}#ifdef CONFIG_BOOT_RETRY_TIME		else if (nbytes == -2)			break;	/* timed out, exit the command	*/#endif		else {			char *endp;			data = simple_strtoul(console_buffer, &endp, 16);			if (size == 1)				data = data << 24;			else if (size == 2)				data = data << 16;			data = be32_to_cpu(data);			nbytes = endp - console_buffer;			if (nbytes) {#ifdef CONFIG_BOOT_RETRY_TIME				/*				 * good enough to not time out				 */				reset_cmd_timeout();#endif				if (i2c_write(chip, addr, alen, (uchar *)&data, size) != 0)					puts ("Error writing the chip.\n");#ifdef CFG_EEPROM_PAGE_WRITE_DELAY_MS				udelay(CFG_EEPROM_PAGE_WRITE_DELAY_MS * 1000);#endif				if (incrflag)					addr += size;			}		}	} while (nbytes);	chip = i2c_mm_last_chip;	addr = i2c_mm_last_addr;	alen = i2c_mm_last_alen;	return 0;}/* * Syntax: *	iprobe {addr}{.0, .1, .2} */int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){	int j;#if defined(CFG_I2C_NOPROBES)	int k, skip;	uchar bus = GET_BUS_NUM;#endif	/* NOPROBES */	puts ("Valid chip addresses:");	for (j = 0; j < 128; j++) {#if defined(CFG_I2C_NOPROBES)		skip = 0;		for (k=0; k < NUM_ELEMENTS_NOPROBE; k++) {			if (COMPARE_BUS(bus, k) && COMPARE_ADDR(j, k)) {				skip = 1;				break;			}		}		if (skip)			continue;#endif		if (i2c_probe(j) == 0)			printf(" %02X", j);	}	putc ('\n');#if defined(CFG_I2C_NOPROBES)	puts ("Excluded chip addresses:");	for (k=0; k < NUM_ELEMENTS_NOPROBE; k++) {		if (COMPARE_BUS(bus,k))			printf(" %02X", NO_PROBE_ADDR(k));	}	putc ('\n');#endif	return 0;}/* * Syntax: *	iloop {i2c_chip} {addr}{.0, .1, .2} [{length}] [{delay}] *	{length} - Number of bytes to read *	{delay}  - A DECIMAL number and defaults to 1000 uSec */int do_i2c_loop(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){	u_char	chip;	ulong	alen;	uint	addr;	uint	length;	u_char	bytes[16];	int	delay;	int	j;	if (argc < 3) {		printf ("Usage:\n%s\n", cmdtp->usage);		return 1;	}	/*	 * Chip is always specified.	 */	chip = simple_strtoul(argv[1], NULL, 16);	/*	 * Address is always specified.	 */	addr = simple_strtoul(argv[2], NULL, 16);	alen = 1;	for (j = 0; j < 8; j++) {		if (argv[2][j] == '.') {			alen = argv[2][j+1] - '0';			if (alen > 4) {				printf ("Usage:\n%s\n", cmdtp->usage);				return 1;			}			break;		} else if (argv[2][j] == '\0')			break;	}	/*	 * Length is the number of objects, not number of bytes.	 */	length = 1;	length = simple_strtoul(argv[3], NULL, 16);	if (length > sizeof(bytes))		length = sizeof(bytes);	/*	 * The delay time (uSec) is optional.	 */	delay = 1000;	if (argc > 3)		delay = simple_strtoul(argv[4], NULL, 10);	/*	 * Run the loop...	 */	while (1) {		if (i2c_read(chip, addr, alen, bytes, length) != 0)			puts ("Error reading the chip.\n");		udelay(delay);	}	/* NOTREACHED */	return 0;}/* * The SDRAM command is separately configured because many * (most?) embedded boards don't use SDRAM DIMMs. */#if defined(CONFIG_CMD_SDRAM)static void print_ddr2_tcyc (u_char const b){	printf ("%d.", (b >> 4) & 0x0F);	switch (b & 0x0F) {	case 0x0:	case 0x1:	case 0x2:	case 0x3:	case 0x4:	case 0x5:	case 0x6:	case 0x7:	case 0x8:	case 0x9:		printf ("%d ns\n", b & 0x0F);		break;	case 0xA:		puts ("25 ns\n");		break;	case 0xB:		puts ("33 ns\n");		break;	case 0xC:		puts ("66 ns\n");		break;	case 0xD:		puts ("75 ns\n");		break;	default:		puts ("?? ns\n");		break;	}}static void decode_bits (u_char const b, char const *str[], int const do_once){	u_char mask;	for (mask = 0x80; mask != 0x00; mask >>= 1, ++str) {		if (b & mask) {			puts (*str);			if (do_once)				return;		}	}}/* * Syntax: *	sdram {i2c_chip} */int do_sdram (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){	enum { unknown, EDO, SDRAM, DDR2 } type;	u_char	chip;	u_char	data[128];	u_char	cksum;	int	j;	static const char *decode_CAS_DDR2[] = {		" TBD", " 6", " 5", " 4", " 3", " 2", " TBD", " TBD"	};	static const char *decode_CAS_default[] = {		" TBD", " 7", " 6", " 5", " 4", " 3", " 2", " 1"	};	static const char *decode_CS_WE_default[] = {		" TBD", " 6", " 5", " 4", " 3", " 2", " 1", " 0"	};	static const char *decode_byte21_default[] = {		"  TBD (bit 7)\n",		"  Redundant row address\n",		"  Differential clock input\n",		"  Registerd DQMB inputs\n",		"  Buffered DQMB inputs\n",		"  On-card PLL\n",		"  Registered address/control lines\n",		"  Buffered address/control lines\n"	};	static const char *decode_byte22_DDR2[] = {		"  TBD (bit 7)\n",		"  TBD (bit 6)\n",		"  TBD (bit 5)\n",		"  TBD (bit 4)\n",		"  TBD (bit 3)\n",		"  Supports partial array self refresh\n",		"  Supports 50 ohm ODT\n",		"  Supports weak driver\n"	};	static const char *decode_row_density_DDR2[] = {		"512 MiB", "256 MiB", "128 MiB", "16 GiB",		"8 GiB", "4 GiB", "2 GiB", "1 GiB"	};	static const char *decode_row_density_default[] = {		"512 MiB", "256 MiB", "128 MiB", "64 MiB",		"32 MiB", "16 MiB", "8 MiB", "4 MiB"	};	if (argc < 2) {		printf ("Usage:\n%s\n", cmdtp->usage);		return 1;	}	/*	 * Chip is always specified.	 */	chip = simple_strtoul (argv[1], NULL, 16);	if (i2c_read (chip, 0, 1, data, sizeof (data)) != 0) {		puts ("No SDRAM Serial Presence Detect found.\n");		return 1;	}	cksum = 0;	for (j = 0; j < 63; j++) {		cksum += data[j];	}	if (cksum != data[63]) {		printf ("WARNING: Configuration data checksum failure:\n"			"  is 0x%02x, calculated 0x%02x\n", data[63], cksum);	}	printf ("SPD data revision            %d.%d\n",		(data[62] >> 4) & 0x0F, data[62] & 0x0F);	printf ("Bytes used                   0x%02X\n", data[0]);	printf ("Serial memory size           0x%02X\n", 1 << data[1]);	puts ("Memory type                  ");	switch (data[2]) {	case 2:		type = EDO;		puts ("EDO\n");		break;	case 4:		type = SDRAM;		puts ("SDRAM\n");		break;	case 8:		type = DDR2;		puts ("DDR2\n");		break;	default:		type = unknown;		puts ("unknown\n");		break;	}	puts ("Row address bits             ");	if ((data[3] & 0x00F0) == 0)		printf ("%d\n", data[3] & 0x0F);	else		printf ("%d/%d\n", data[3] & 0x0F, (data[3] >> 4) & 0x0F);	puts ("Column address bits          ");	if ((data[4] & 0x00F0) == 0)		printf ("%d\n", data[4] & 0x0F);	else		printf ("%d/%d\n", data[4] & 0x0F, (data[4] >> 4) & 0x0F);	switch (type) {	case DDR2:		printf ("Number of ranks              %d\n",			(data[5] & 0x07) + 1);		break;	default:		printf ("Module rows                  %d\n", data[5]);		break;	}	switch (type) {	case DDR2:		printf ("Module data width            %d bits\n", data[6]);		break;	default:		printf ("Module data width            %d bits\n",			(data[7] << 8) | data[6]);		break;	}	puts ("Interface signal levels      ");	switch(data[8]) {		case 0:  puts ("TTL 5.0 V\n");	break;		case 1:  puts ("LVTTL\n");	break;		case 2:  puts ("HSTL 1.5 V\n");	break;		case 3:  puts ("SSTL 3.3 V\n");	break;		case 4:  puts ("SSTL 2.5 V\n");	break;		case 5:  puts ("SSTL 1.8 V\n");	break;		default: puts ("unknown\n");	break;	}	switch (type) {	case DDR2:		printf ("SDRAM cycle time             ");		print_ddr2_tcyc (data[9]);		break;	default:		printf ("SDRAM cycle time             %d.%d ns\n",			(data[9] >> 4) & 0x0F, data[9] & 0x0F);		break;	}	switch (type) {	case DDR2:		printf ("SDRAM access time            0.%d%d ns\n",			(data[10] >> 4) & 0x0F, data[10] & 0x0F);		break;	default:		printf ("SDRAM access time            %d.%d ns\n",			(data[10] >> 4) & 0x0F, data[10] & 0x0F);		break;	}	puts ("EDC configuration            ");	switch (data[11]) {		case 0:  puts ("None\n");	break;		case 1:  puts ("Parity\n");	break;		case 2:  puts ("ECC\n");	break;		default: puts ("unknown\n");	break;	}	if ((data[12] & 0x80) == 0)		puts ("No self refresh, rate        ");	else		puts ("Self refresh, rate           ");	switch(data[12] & 0x7F) {		case 0:  puts ("15.625 us\n");	break;

⌨️ 快捷键说明

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