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

📄 avr.c

📁 uboot详细解读可用启动引导LINUX2.6内核
💻 C
字号:
/* * avr.c * * AVR functions * * Copyright (C) 2006 Mihai Georgian <u-boot@linuxnotincluded.org.uk> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */#include <common.h>#include <ns16550.h>#include <console.h>/* Button codes from the AVR */#define PWRR			0x20		/* Power button release	*/#define PWRP			0x21		/* Power button push	*/#define RESR			0x22		/* Reset button release	*/#define RESP			0x23		/* Reset button push	*/#define AVRINIT			0x33		/* Init complete	*/#define AVRRESET		0x31		/* Reset request	*//* LED commands */#define PWRBLINKSTRT		'['		/* Blink power LED	*/#define PWRBLINKSTOP		'Z'		/* Solid power LED	*/#define HDDLEDON		'W'		/* HDD LED on		*/#define HDDLEDOFF		'V'		/* HDD LED off		*/#define HDDBLINKSTRT		'Y'		/* HDD LED start blink	*/#define HDDBLINKSTOP		'X'		/* HDD LED stop blink	*//* Timings for LEDs blinking to show choice */#define PULSETIME		250		/* msecs		*/#define LONGPAUSE		(5 * PULSETIME)/* Button press times */#define PUSHHOLD		1000		/* msecs		*/#define NOBUTTON		(6 * (LONGPAUSE+PULSETIME))/* Boot and console choices */#define MAX_BOOT_CHOICE		3static char *consoles[] = {	"serial",#if defined(CONFIG_NETCONSOLE)	"nc",#endif};#define MAX_CONS_CHOICE		(sizeof(consoles)/sizeof(char *))#if !defined(CONFIG_NETCONSOLE)#define DEF_CONS_CHOICE		0#else#define DEF_CONS_CHOICE		1#endif#define perror(fmt, args...) printf("%s: " fmt, __FUNCTION__ , ##args)extern void miconCntl_SendCmd(unsigned char dat);extern void miconCntl_DisWDT(void);static int boot_stop;static int boot_choice = 1;static int cons_choice = DEF_CONS_CHOICE;static char envbuffer[16];void init_AVR_DUART (void){	NS16550_t AVR_port = (NS16550_t) CFG_NS16550_COM2;	int clock_divisor = CFG_NS16550_CLK / 16 / 9600;	/*	 * AVR port init sequence taken from	 * the original Linkstation init code	 * Normal U-Boot serial reinit doesn't	 * work because the AVR uses even parity	 */	AVR_port->lcr = 0x00;	AVR_port->ier = 0x00;	AVR_port->lcr = LCR_BKSE;	AVR_port->dll = clock_divisor & 0xff;	AVR_port->dlm = (clock_divisor >> 8) & 0xff;	AVR_port->lcr = LCR_WLS_8 | LCR_PEN | LCR_EPS;	AVR_port->mcr = 0x00;	AVR_port->fcr = FCR_FIFO_EN | FCR_RXSR | FCR_TXSR;	miconCntl_DisWDT();	boot_stop = 0;	miconCntl_SendCmd(PWRBLINKSTRT);}static inline int avr_tstc(void){	return (NS16550_tstc((NS16550_t)CFG_NS16550_COM2));}static inline char avr_getc(void){	return (NS16550_getc((NS16550_t)CFG_NS16550_COM2));}static int push_timeout(char button_code){	ulong push_start = get_timer(0);	while (get_timer(push_start) <= PUSHHOLD)		if (avr_tstc() && avr_getc() == button_code)			return 0;	return 1;}static void next_boot_choice(void){	ulong return_start;	ulong pulse_start;	int on_times;	int button_on;	int led_state;	char c;	button_on = 0;	return_start = get_timer(0);	on_times = boot_choice;	led_state = 0;	miconCntl_SendCmd(HDDLEDOFF);	pulse_start = get_timer(0);	while (get_timer(return_start) <= NOBUTTON || button_on) {		if (avr_tstc()) {			c = avr_getc();			if (c == PWRP)				button_on = 1;			else if (c == PWRR) {				button_on = 0;				return_start = get_timer(0);				if (++boot_choice > MAX_BOOT_CHOICE)					boot_choice = 1;				sprintf(envbuffer, "bootcmd%d", boot_choice);				if (getenv(envbuffer)) {					sprintf(envbuffer, "run bootcmd%d", boot_choice);					setenv("bootcmd", envbuffer);				}				on_times = boot_choice;				led_state = 1;				miconCntl_SendCmd(HDDLEDON);				pulse_start = get_timer(0);			} else {				perror("Unexpected code: 0x%02X\n", c);			}		}		if (on_times && get_timer(pulse_start) > PULSETIME) {			if (led_state == 1) {				--on_times;				led_state = 0;				miconCntl_SendCmd(HDDLEDOFF);			} else {				led_state = 1;				miconCntl_SendCmd(HDDLEDON);			}			pulse_start = get_timer(0);		}		if (!on_times && get_timer(pulse_start) > LONGPAUSE) {			on_times = boot_choice;			led_state = 1;			miconCntl_SendCmd(HDDLEDON);			pulse_start = get_timer(0);		}	}	if (led_state)		miconCntl_SendCmd(HDDLEDOFF);}void next_cons_choice(int console){	ulong return_start;	ulong pulse_start;	int on_times;	int button_on;	int led_state;	char c;	button_on = 0;	cons_choice = console;	return_start = get_timer(0);	on_times = cons_choice+1;	led_state = 1;	miconCntl_SendCmd(HDDLEDON);	pulse_start = get_timer(0);	while (get_timer(return_start) <= NOBUTTON || button_on) {		if (avr_tstc()) {			c = avr_getc();			if (c == RESP)				button_on = 1;			else if (c == RESR) {				button_on = 0;				return_start = get_timer(0);				cons_choice = (cons_choice + 1) % MAX_CONS_CHOICE;				console_assign(stdin, consoles[cons_choice]);				console_assign(stdout, consoles[cons_choice]);				console_assign(stderr, consoles[cons_choice]);				on_times = cons_choice+1;				led_state = 0;				miconCntl_SendCmd(HDDLEDOFF);				pulse_start = get_timer(0);			} else {				perror("Unexpected code: 0x%02X\n", c);			}		}		if (on_times && get_timer(pulse_start) > PULSETIME) {			if (led_state == 0) {				--on_times;				led_state = 1;				miconCntl_SendCmd(HDDLEDON);			} else {				led_state = 0;				miconCntl_SendCmd(HDDLEDOFF);			}			pulse_start = get_timer(0);		}		if (!on_times && get_timer(pulse_start) > LONGPAUSE) {			on_times = cons_choice+1;			led_state = 0;			miconCntl_SendCmd(HDDLEDOFF);			pulse_start = get_timer(0);		}	}	if (led_state);	miconCntl_SendCmd(HDDLEDOFF);}int avr_input(void){	char avr_button;	if (!avr_tstc())		return 0;	avr_button = avr_getc();	switch (avr_button) {	case PWRP:		if (push_timeout(PWRR)) {			/* Timeout before power button release */			boot_stop = ~boot_stop;			if (boot_stop)				miconCntl_SendCmd(PWRBLINKSTOP);			else				miconCntl_SendCmd(PWRBLINKSTRT);			/* Wait for power button release */			while (avr_getc() != PWRR)				;		} else			/* Power button released */			next_boot_choice();		break;	case RESP:		/* Wait for Reset button release */		while (avr_getc() != RESR)			;		next_cons_choice(cons_choice);		break;	case AVRINIT:		return 0;	default:		perror("Unexpected code: 0x%02X\n", avr_button);		return 0;	}	if (boot_stop)		return (-3);	else		return (-2);}void avr_StopBoot(void){	boot_stop = ~0;	miconCntl_SendCmd(PWRBLINKSTOP);}

⌨️ 快捷键说明

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