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

📄 uart.c

📁 em86xx 完整启动程序,支持网络下载与串通下载
💻 C
字号:
/***************************************** Copyright (c) 2002-2004 Sigma Designs, Inc. All Rights Reserved Proprietary and Confidential *****************************************//* This file is part of the EM86XX boot loader *//* * uart.c * * UART Input/Output * * modified from jasper boot loader by Ho Lee 12/10/2002 */#include "config.h"#include "uart.h"#include "io.h"#include "em86xxapi.h"#include "util.h"#include "vsprintf.h"#ifdef CONFIG_ENABLE_FIP#include "ide.h"#include "fip.h"#endif// global variablesstatic unsigned int g_uartbase = (DEFAULT_UART_PORT == 0) ? UART0_BASE : UART1_BASE;static int g_baudrate = DEFAULT_UART_BAUDRATE;// function prototypesvoid uart_init(void);void uart_init_port(int port, int baudrate, int fifo);static int uart_getclkdiv(int baudrate);void uart_putc(int ch);void uart_puts(const char *t);void uart_putns(const char *t, int maxlen);int uart_printf(const char *fmt, ...);void uart_printbyte(unsigned int data);void uart_printshort(unsigned int data);void uart_printlong(unsigned int data);int uart_peekc(void);int uart_getc(void);char *uart_gets_raw(char *str, int maxlen);char *uart_gets(char *str, int maxlen, int flag);char *uart_getcmd(char *str);//// UART initialization//void uart_init(void){    uart_init_port(0, DEFAULT_UART_BAUDRATE, 1);    uart_init_port(1, DEFAULT_UART_BAUDRATE, 1);}void uart_init_port(int port, int baudrate, int fifo){    unsigned int base = (port == 0) ? UART0_BASE : UART1_BASE;    int lcr, clkdiv = uart_getclkdiv(baudrate);    unsigned int dummy;    g_baudrate = baudrate;    dummy = __raw_readl(base + UART_MSR); /* Clear Modem interrupt */    lcr = (DEFAULT_UART_DATABITS - 5);    if (DEFAULT_UART_STOPBITS == 2)        lcr |= UART_LCR_STOP;    lcr |= DEFAULT_UART_PARITY;    __raw_writel(0x00, base + UART_IER);            // IRQ ENABL: all disabled    if (fifo)        __raw_writel(0x1f, base + UART_FCR);        // FIFO CTRL: depth=16, clear rec & transm. FIFO, Tx.Trig = 4bytes    else        __raw_writel(0x00, base + UART_FCR);        // FIFO CTRL: diable FIFO    __raw_writel(lcr, base + UART_LCR);             // LINE CTRL: #ifdef CONFIG_USE_SYSCLK    __raw_writel(0x00, base + UART_CLKSEL);         // CLK  SEL : SELECT INTERNAL CLOCK#else    __raw_writel(0x01, base + UART_CLKSEL);         // CLK  SEL : SELECT EXTERNAL CLOCK#endif    __raw_writel(clkdiv, base + UART_CLKDIV);       // CLK  DIV : DEVIDED according to PLL Speed}void uart_reset(void){    uart_init_port(0, g_baudrate, 1);    uart_init_port(1, g_baudrate, 1);}int uart_getclkdiv(int baudrate){    int clkdiv;    unsigned long speed;#ifdef CONFIG_USE_SYSCLK    speed = em86xx_getclock() >> 1;#else    speed = EM86XX_EXT_CLOCK;#endif    // clkdiv = speed / (baudrate * 16)    // no divide instruction    for (clkdiv = 0; (long) speed > 0; speed -= (baudrate << 4))        ++clkdiv;    return clkdiv;}//// UART output//void uart_putc(int ch){    while ((__raw_readl(g_uartbase + UART_LSR) & 0x20) == 0)        ;    __raw_writel(ch, g_uartbase + UART_TBR);    while ((__raw_readl(g_uartbase + UART_LSR) & 0x20) == 0)        ;}void uart_puts(const char *t){    while (*t) {        if (*t == '\n')            uart_putc('\r');        uart_putc(*t++);    }}void uart_putns(const char *t, int maxlen){           while (maxlen-- && *t) {        if (*t == '\n')            uart_putc('\r');        uart_putc(*t++);    }}int uart_printf(const char *fmt, ...){    char buf[256];    va_list args;    int i;    va_start(args, fmt);    i = vsprintf(buf, fmt, args); /* hopefully i < sizeof(buf) */    va_end(args);    uart_puts(buf);        return i;}static char g_hextab[] = "0123456789ABCDEF";void uart_printbyte(unsigned int data){    char str[2];    str[0] = g_hextab[(data >> 4) & 0xF];    str[1] = g_hextab[(data)      & 0xF];        uart_putns(str, 2);}void uart_printshort(unsigned int data){    char str[4];    str[0] = g_hextab[(data >> 12) & 0xF];    str[1] = g_hextab[(data >> 8)  & 0xF];    str[2] = g_hextab[(data >> 4)  & 0xF];    str[3] = g_hextab[(data)       & 0xF];        uart_putns(str, 4);}void uart_printlong(unsigned int data){    char str[8];    str[0] = g_hextab[(data >> 28) & 0xF];    str[1] = g_hextab[(data >> 24) & 0xF];    str[2] = g_hextab[(data >> 20) & 0xF];    str[3] = g_hextab[(data >> 16) & 0xF];    str[4] = g_hextab[(data >> 12) & 0xF];    str[5] = g_hextab[(data >> 8)  & 0xF];    str[6] = g_hextab[(data >> 4)  & 0xF];    str[7] = g_hextab[(data)       & 0xF];        uart_putns(str,8);}void uart_printint(int data){    char str[32], *cp = str + sizeof str - 1;    *cp = 0;    do {        *--cp = (data % 10) + '0';        data /= 10;    } while (data != 0);    uart_puts(cp);}//// UART input//static int s_ungetc = 0;int uart_peekc(void){    if (__raw_readl(g_uartbase + UART_LSR) & 0x01)        return __raw_readl(g_uartbase + UART_RBR);    else        return -1;}int uart_getc(void){#if defined(CONFIG_ENABLE_FIP) && defined(CONFIG_ENABLE_IDE)    extern int downloading;    unsigned long key = 0;#endif            if (s_ungetc > 0) {        int ch = s_ungetc;        s_ungetc = 0;        return ch;    }    while ((__raw_readl(g_uartbase + UART_LSR) & 0x01) == 0) {#if defined(CONFIG_ENABLE_FIP) && defined(CONFIG_ENABLE_IDE)	if (downloading == 0) {    	    key = fip_readkey(); /* See if any buttons is pressed */            if (key == FIP_KEY_W1)  /* Ejecting the CD *///by lai 20080619	        ide_cdrom_eject(0, key);	}#endif        ;    }    return __raw_readl(g_uartbase + UART_RBR);}void uart_ungetc(int ch){    s_ungetc = ch;}char *uart_gets_raw(char *str, int maxlen){    int pos = 0;    int ch;            if (maxlen < 0)        maxlen = 256;    for (;;) {        ch = uart_getc();        if (pos < maxlen - 2)            str[pos++] = ch;        if (ch == '\r' || ch == '\n')             break;    }    str[pos] = 0;        return str;}char *uart_gets(char *str, int maxlen, int flag){    int pos = 0;    int ch;    if (maxlen < 0)        maxlen = 256;    if (flag & GETSTR_APPEND) {        while (str[pos] != 0) {            if (flag & GETSTR_APPENDDISP)                uart_putc(str[pos]);            ++pos;        }    }    for (;;) {        ch = uart_getc();        // escape sequence (0x1b, ...)        if (ch == 0x1b) {            if (flag & GETSTR_ESCAPE) {                str[pos] = 0;                return NULL;            }         }        if (ch == 0x7f) // DEL            ch = '\b';        else if (ch == '\n')            ch = '\r';        if (ch != '\b')            uart_putc(ch);        if (ch == '\r') {            uart_putc('\n');            break;        } else if (ch == '\b') {            if (pos > 0) {                --pos;                uart_putc(ch);                uart_putc(' ');                uart_putc(ch);            }        } else {            if (pos < maxlen - 2)                str[pos++] = ch;        }    }    str[pos] = 0;        return str;}#define GETCMD_MAXBUF       32#define GETCMD_MAXLEN       512char *uart_getcmd(char *str){    static char s_cmdbuf[GETCMD_MAXBUF][GETCMD_MAXLEN];    static int s_cmdnum = 0;    int i, ch, len, cmdpos = s_cmdnum;    int flag = GETSTR_ESCAPE | GETSTR_APPEND;    str[0] = 0;        while (uart_gets(str, GETCMD_MAXLEN, flag) == NULL) {        // get the escape sequence        ch = uart_getc();        if (ch != 0x5b)            continue;        ch = uart_getc();        if (ch == 0x33) {            ch = uart_getc();            if (ch == 0x7e)         // DEL                uart_ungetc('\b');            continue;        } else if (ch == 0x41) {    // up            if (cmdpos == 0)                 continue;            --cmdpos;        } else if (ch == 0x42) {    // down            if (cmdpos == s_cmdnum)                continue;            ++cmdpos;        } else            continue;        // clear line        for (len = strlen(str); len > 0; --len) {            uart_putc('\b');            uart_putc(' ');            uart_putc('\b');        }        // redisplay line        if (cmdpos == s_cmdnum)            str[0] = 0;        else {            strcpy(str, s_cmdbuf[cmdpos]);            uart_puts(str);        }    }    if (str[0] != 0) {        // process '!' history        if (str[0] == '!') {            for (i = s_cmdnum - 1; i >= 0; --i)                 if (strncmp(s_cmdbuf[i], str + 1, strlen(str) - 1) == 0) {                    strcpy(str, s_cmdbuf[i]);                    break;                }        }        // append new command        if (s_cmdnum > 0 && strcmp(s_cmdbuf[s_cmdnum - 1], str) == 0)             ;        else if (s_cmdnum == GETCMD_MAXBUF) {            for (i = 0; i < GETCMD_MAXBUF - 1; ++i)                strcpy(s_cmdbuf[i], s_cmdbuf[i + 1]);        } else            ++s_cmdnum;        strcpy(s_cmdbuf[s_cmdnum - 1], str);    }    return str;}

⌨️ 快捷键说明

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