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

📄 lwmon.c

📁 AT91RM9200的完整启动代码:包括loader, boot及U-boot三部分均已编译通过!欢迎下载使用!
💻 C
📖 第 1 页 / 共 2 页
字号:
	}	/* Reset error code and verify */	val = KEYBD_CMD_RESET_ERRORS;	i2c_write (kbd_addr, 0, 0, &val, 1);	udelay(1000);	/* delay NEEDED by keyboard PIC !!! */	val = KEYBD_CMD_READ_STATUS;	i2c_write (kbd_addr, 0, 0, &val, 1);	i2c_read (kbd_addr, 0, 0, &val, 1);	val &= KEYBD_STATUS_MASK;	/* clear unused bits */	if (val) {			/* permanent error, report it */		gd->kbd_status |= val;		return;	}	/*	 * Read current keyboard state.	 *         * After the error reset it may take some time before the         * keyboard PIC picks up a valid keyboard scan - the total         * scan time is approx. 1.6 ms (information by Martin Rajek,         * 28 Sep 2002). We read a couple of times for the keyboard         * to stabilize, using a big enough delay.         * 10 times should be enough. If the data is still changing,         * we use what we get :-(	 */	memset (tmp_data, 0xFF, KEYBD_DATALEN);	/* impossible value */	for (i=0; i<10; ++i) {		val = KEYBD_CMD_READ_KEYS;		i2c_write (kbd_addr, 0, 0, &val, 1);		i2c_read (kbd_addr, 0, 0, kbd_data, KEYBD_DATALEN);		if (memcmp(kbd_data, tmp_data, KEYBD_DATALEN) == 0) {			/* consistent state, done */			break;		}		/* remeber last state, delay, and retry */		memcpy (tmp_data, kbd_data, KEYBD_DATALEN);		udelay (5000);	}}/***********************************************************************F* Function:     int misc_init_r (void) P*A*Z* *P* Parameters:   noneP*P* Returnvalue:  intP*                - 0 is always returned, even in the case of a keyboardP*                    error. *Z* Intention:    This function is the misc_init_r() method implementationZ*               for the lwmon board.Z*               The keyboard controller is initialized and the resultZ*               of a read copied to the environment variable "keybd".Z*               If KEYBD_SET_DEBUGMODE is defined, a check is made forZ*               this key, and if found display to the LCD will be enabled.Z*               The keys in "keybd" are checked against the magicZ*               keycommands defined in the environment.Z*               See also key_match(). *D* Design:       wd@denx.deC* Coding:       wd@denx.deV* Verification: dzu@denx.de ***********************************************************************/int misc_init_r (void){	DECLARE_GLOBAL_DATA_PTR;	uchar kbd_data[KEYBD_DATALEN];	uchar keybd_env[2 * KEYBD_DATALEN + 1];	uchar kbd_init_status = gd->kbd_status >> 8;	uchar kbd_status = gd->kbd_status;	uchar val;	uchar *str;	int i;	if (kbd_init_status) {		printf ("KEYBD: Error %02X\n", kbd_init_status);	}	if (kbd_status) {		/* permanent error, report it */		printf ("*** Keyboard error code %02X ***\n", kbd_status);		sprintf (keybd_env, "%02X", kbd_status);		setenv ("keybd", keybd_env);		return 0;	}	/*	 * Now we know that we have a working  keyboard,  so  disable	 * all output to the LCD except when a key press is detected.	 */	if ((console_assign (stdout, "serial") < 0) ||		(console_assign (stderr, "serial") < 0)) {		printf ("Can't assign serial port as output device\n");	}	/* Read Version */	val = KEYBD_CMD_READ_VERSION;	i2c_write (kbd_addr, 0, 0, &val, 1);	i2c_read (kbd_addr, 0, 0, kbd_data, KEYBD_VERSIONLEN);	printf ("KEYBD: Version %d.%d\n", kbd_data[0], kbd_data[1]);	/* Read current keyboard state */	val = KEYBD_CMD_READ_KEYS;	i2c_write (kbd_addr, 0, 0, &val, 1);	i2c_read (kbd_addr, 0, 0, kbd_data, KEYBD_DATALEN);	for (i = 0; i < KEYBD_DATALEN; ++i) {		sprintf (keybd_env + i + i, "%02X", kbd_data[i]);	}	setenv ("keybd", keybd_env);	str = strdup (key_match (kbd_data));	/* decode keys */#ifdef KEYBD_SET_DEBUGMODE	if (kbd_data[0] == KEYBD_SET_DEBUGMODE) {	/* set debug mode */		if ((console_assign (stdout, "lcd") < 0) ||			(console_assign (stderr, "lcd") < 0)) {			printf ("Can't assign LCD display as output device\n");		}	}#endif /* KEYBD_SET_DEBUGMODE */#ifdef CONFIG_PREBOOT	/* automatically configure "preboot" command on key match */	setenv ("preboot", str);	/* set or delete definition */#endif /* CONFIG_PREBOOT */	if (str != NULL) {		free (str);	}	return (0);}#ifdef CONFIG_PREBOOTstatic uchar kbd_magic_prefix[] = "key_magic";static uchar kbd_command_prefix[] = "key_cmd";static int compare_magic (uchar *kbd_data, uchar *str){	uchar compare[KEYBD_DATALEN-1];	uchar *nxt;	int i;	/* Don't include modifier byte */	memcpy (compare, kbd_data+1, KEYBD_DATALEN-1);	for (; str != NULL; str = (*nxt) ? nxt+1 : nxt) {		uchar c;		int k;		c = (uchar) simple_strtoul (str, (char **) (&nxt), 16);		if (str == nxt) {	/* invalid character */			break;		}		/*		 * Check if this key matches the input.		 * Set matches to zero, so they match only once		 * and we can find duplicates or extra keys		 */		for (k = 0; k < sizeof(compare); ++k) {			if (compare[k] == '\0')	/* only non-zero entries */				continue;			if (c == compare[k]) {	/* found matching key */				compare[k] = '\0';				break;			}		}		if (k == sizeof(compare)) {			return -1;		/* unmatched key */		}	}	/*	 * A full match leaves no keys in the `compare' array,	 */	for (i = 0; i < sizeof(compare); ++i) {		if (compare[i])		{			return -1;		}	}	return 0;}/***********************************************************************F* Function:     static uchar *key_match (uchar *kbd_data) P*A*Z* *P* Parameters:   uchar *kbd_dataP*                - The keys to match against our magic definitionsP*P* Returnvalue:  uchar *P*                - != NULL: Pointer to the corresponding command(s)P*                     NULL: No magic is about to happen *Z* Intention:    Check if pressed key(s) match magic sequence,Z*               and return the command string associated with that key(s).Z*Z*               If no key press was decoded, NULL is returned.Z*Z*               Note: the first character of the argument will beZ*                     overwritten with the "magic charcter code" of theZ*                     decoded key(s), or '\0'.Z*Z*               Note: the string points to static environment dataZ*                     and must be saved before you call any function thatZ*                     modifies the environment. *D* Design:       wd@denx.deC* Coding:       wd@denx.deV* Verification: dzu@denx.de ***********************************************************************/static uchar *key_match (uchar *kbd_data){	uchar magic[sizeof (kbd_magic_prefix) + 1];	uchar *suffix;	uchar *kbd_magic_keys;	/*	 * The following string defines the characters that can pe appended	 * to "key_magic" to form the names of environment variables that	 * hold "magic" key codes, i. e. such key codes that can cause	 * pre-boot actions. If the string is empty (""), then only	 * "key_magic" is checked (old behaviour); the string "125" causes	 * checks for "key_magic1", "key_magic2" and "key_magic5", etc.	 */	if ((kbd_magic_keys = getenv ("magic_keys")) == NULL)		kbd_magic_keys = "";	/* loop over all magic keys;	 * use '\0' suffix in case of empty string	 */	for (suffix=kbd_magic_keys; *suffix || suffix==kbd_magic_keys; ++suffix) {		sprintf (magic, "%s%c", kbd_magic_prefix, *suffix);#if 0		printf ("### Check magic \"%s\"\n", magic);#endif		if (compare_magic(kbd_data, getenv(magic)) == 0) {			uchar cmd_name[sizeof (kbd_command_prefix) + 1];			char *cmd;			sprintf (cmd_name, "%s%c", kbd_command_prefix, *suffix);			cmd = getenv (cmd_name);#if 0			printf ("### Set PREBOOT to $(%s): \"%s\"\n",					cmd_name, cmd ? cmd : "<<NULL>>");#endif			*kbd_data = *suffix;			return (cmd);		}	}#if 0	printf ("### Delete PREBOOT\n");#endif	*kbd_data = '\0';	return (NULL);}#endif /* CONFIG_PREBOOT *//*---------------Board Special Commands: PIC read/write ---------------*/#if (CONFIG_COMMANDS & CFG_CMD_BSP)/***********************************************************************F* Function:     int do_pic (cmd_tbl_t *cmdtp, int flag,F*                           int argc, char *argv[]) P*A*Z* *P* Parameters:   cmd_tbl_t *cmdtpP*                - Pointer to our command table entryP*               int flagP*                - If the CMD_FLAG_REPEAT bit is set, then this call isP*                  a repetitionP*               int argcP*                - Argument countP*               char *argv[]P*                - Array of the actual argumentsP*P* Returnvalue:  intP*                - 0  The command was handled successfullyP*                  1  An error occurred *Z* Intention:    Implement the "pic [read|write]" commands.Z*               The read subcommand takes one argument, the register,Z*               whereas the write command takes two, the register andZ*               the new value. *D* Design:       wd@denx.deC* Coding:       wd@denx.deV* Verification: dzu@denx.de ***********************************************************************/int do_pic (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){	uchar reg, val;	switch (argc) {	case 3:					/* PIC read reg */		if (strcmp (argv[1], "read") != 0)			break;		reg = simple_strtoul (argv[2], NULL, 16);		printf ("PIC read: reg %02x: %02x\n\n", reg, pic_read (reg));		return 0;	case 4:					/* PIC write reg val */		if (strcmp (argv[1], "write") != 0)			break;		reg = simple_strtoul (argv[2], NULL, 16);		val = simple_strtoul (argv[3], NULL, 16);		printf ("PIC write: reg %02x val 0x%02x: %02x => ",				reg, val, pic_read (reg));		pic_write (reg, val);		printf ("%02x\n\n", pic_read (reg));		return 0;	default:		break;	}	printf ("Usage:\n%s\n", cmdtp->usage);	return 1;}/***********************************************************************F* Function:     int do_kbd (cmd_tbl_t *cmdtp, int flag,F*                           int argc, char *argv[]) P*A*Z* *P* Parameters:   cmd_tbl_t *cmdtpP*                - Pointer to our command table entryP*               int flagP*                - If the CMD_FLAG_REPEAT bit is set, then this call isP*                  a repetitionP*               int argcP*                - Argument countP*               char *argv[]P*                - Array of the actual argumentsP*P* Returnvalue:  intP*                - 0 is always returned. *Z* Intention:    Implement the "kbd" command.Z*               The keyboard status is read.  The result is printed onZ*               the console and written into the "keybd" environmentZ*               variable. *D* Design:       wd@denx.deC* Coding:       wd@denx.deV* Verification: dzu@denx.de ***********************************************************************/int do_kbd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){	uchar kbd_data[KEYBD_DATALEN];	uchar keybd_env[2 * KEYBD_DATALEN + 1];	uchar val;	int i;#if 0 /* Done in kbd_init */	i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);#endif	/* Read keys */	val = KEYBD_CMD_READ_KEYS;	i2c_write (kbd_addr, 0, 0, &val, 1);	i2c_read (kbd_addr, 0, 0, kbd_data, KEYBD_DATALEN);	puts ("Keys:");	for (i = 0; i < KEYBD_DATALEN; ++i) {		sprintf (keybd_env + i + i, "%02X", kbd_data[i]);		printf (" %02x", kbd_data[i]);	}	putc ('\n');	setenv ("keybd", keybd_env);	return 0;}/* Read and set LSB switch */#define CFG_PC_TXD1_ENA		0x0008		/* PC.12 *//***********************************************************************F* Function:     int do_lsb (cmd_tbl_t *cmdtp, int flag,F*                           int argc, char *argv[]) P*A*Z* *P* Parameters:   cmd_tbl_t *cmdtpP*                - Pointer to our command table entryP*               int flagP*                - If the CMD_FLAG_REPEAT bit is set, then this call isP*                  a repetitionP*               int argcP*                - Argument countP*               char *argv[]P*                - Array of the actual argumentsP*P* Returnvalue:  intP*                - 0  The command was handled successfullyP*                  1  An error occurred *Z* Intention:    Implement the "lsb [on|off]" commands.Z*               The lsb is switched according to the first parameter byZ*               by signaling the PIC I/O expander.Z*               Called with no arguments, the current setting isZ*               printed. *D* Design:       wd@denx.deC* Coding:       wd@denx.deV* Verification: dzu@denx.de ***********************************************************************/int do_lsb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){	uchar val;	immap_t *immr = (immap_t *) CFG_IMMR;	switch (argc) {	case 1:					/* lsb - print setting */		val = pic_read (0x60);		printf ("LSB is o%s\n", (val & 0x20) ? "n" : "ff");		return 0;	case 2:					/* lsb on or lsb off - set switch */		val = pic_read (0x60);		if (strcmp (argv[1], "on") == 0) {			val |= 0x20;			immr->im_ioport.iop_pcpar &= ~(CFG_PC_TXD1_ENA);			immr->im_ioport.iop_pcdat |= CFG_PC_TXD1_ENA;			immr->im_ioport.iop_pcdir |= CFG_PC_TXD1_ENA;		} else if (strcmp (argv[1], "off") == 0) {			val &= ~0x20;			immr->im_ioport.iop_pcpar &= ~(CFG_PC_TXD1_ENA);			immr->im_ioport.iop_pcdat &= ~(CFG_PC_TXD1_ENA);			immr->im_ioport.iop_pcdir |= CFG_PC_TXD1_ENA;		} else {			break;		}		pic_write (0x60, val);		return 0;	default:		break;	}	printf ("Usage:\n%s\n", cmdtp->usage);	return 1;}#endif /* CFG_CMD_BSP *//*----------------------------- Utilities -----------------------------*//***********************************************************************F* Function:     uchar pic_read (uchar reg) P*A*Z* *P* Parameters:   uchar regP*                - Register to readP*P* Returnvalue:  ucharP*                - Value read from register *Z* Intention:    Read a register from the PIC I/O expander. *D* Design:       wd@denx.deC* Coding:       wd@denx.deV* Verification: dzu@denx.de ***********************************************************************/uchar pic_read (uchar reg){	return (i2c_reg_read (CFG_I2C_PICIO_ADDR, reg));}/***********************************************************************F* Function:     void pic_write (uchar reg, uchar val) P*A*Z* *P* Parameters:   uchar regP*                - Register to readP*               uchar valP*                - Value to writeP*P* Returnvalue:  none *Z* Intention:    Write to a register on the PIC I/O expander. *D* Design:       wd@denx.deC* Coding:       wd@denx.deV* Verification: dzu@denx.de ***********************************************************************/void pic_write (uchar reg, uchar val){	i2c_reg_write (CFG_I2C_PICIO_ADDR, reg, val);}/*---------------------- Board Control Functions ----------------------*//***********************************************************************F* Function:     void board_poweroff (void) P*A*Z* *P* Parameters:   noneP*P* Returnvalue:  none *Z* Intention:    Turn off the battery power and loop endless, so thisZ*               should better be the last function you call... *D* Design:       wd@denx.deC* Coding:       wd@denx.deV* Verification: dzu@denx.de ***********************************************************************/void board_poweroff (void){    /* Turn battery off */    ((volatile immap_t *)CFG_IMMR)->im_ioport.iop_pcdat &= ~(1 << (31 - 13));    while (1);}#ifdef CONFIG_MODEM_SUPPORTstatic int key_pressed(void){	uchar kbd_data[KEYBD_DATALEN];	uchar val;	/* Read keys */	val = KEYBD_CMD_READ_KEYS;	i2c_write (kbd_addr, 0, 0, &val, 1);	i2c_read (kbd_addr, 0, 0, kbd_data, KEYBD_DATALEN);	return (compare_magic(kbd_data, CONFIG_MODEM_KEY_MAGIC) == 0);}#endif	/* CONFIG_MODEM_SUPPORT */

⌨️ 快捷键说明

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