📄 uart.c
字号:
/***************************************** Copyright (c) 2001-2002 Sigma Designs, Inc. All Rights Reserved Proprietary and Confidential *****************************************//* This file is part of the Jasper DVD boot loader *//** Uart functions (for debug only)*/#include "config.h"#include "uart.h"#include "util.h"#ifdef ENABLE_UART#define READ_PLL 1// some hardware specific information#define QUASAR_MAP_AREA 0x00600000#define DRAM_pllcontrol 0xC04// global variablesstatic unsigned int g_uartbase = (DEFAULT_UART_PORT == 0) ? UART1_BASE : UART2_BASE;//// UART initialization//static int UartGetClkDiv(int baudrate){#ifdef SERIAL_CLOCK_EXT return 0x01;#else // programs the UART to specified baud // calculates the correct divisors based on the current system clock value int temp, div, mult, divsel; int clkdiv; unsigned long speed; // calculate speed // read pll ctrl value temp = CPU_RD_32BIT_REG (QUASAR_MAP_AREA, ((0x1000 + DRAM_pllcontrol) << 2)); div = ( (temp & 0x0f00) >> 8) ; // calculate divider parameter mult = ( (temp & 0x00fc) >> 2) ; // calculate multiplier parameter divsel = (temp & 0x0002); // isolate divsel bit // speed = 13500000 * (mult+2) / (div+2); // calculate system clock speed // no divide instruction. if (div == 2) speed = 3375000 * (mult+2); // 13500000 / (2+2) = 3375000 else if (div == 3) speed = 2700000 * (mult+2); // 13500000 / (2+3) = 2700000 else if (div == 1) speed = 4500000 * (mult+2); // 13500000 / (2+1) else { speed = 0; temp = 0; while (temp < 13500000) { temp += (div + 2); speed++; } speed = speed * (mult + 2); } if (divsel) speed = speed >> 1; // factor divsel bit in // clkdiv = speed / (baudrate * 16) // no divide instruction for (clkdiv = 0; (long) speed > 0; speed -= (baudrate << 4)) ++clkdiv;#endif return clkdiv;}void InitUartPort (int port, int baudrate){ unsigned int base = (port == 0) ? UART1_BASE : UART2_BASE; int lcr, clkdiv = UartGetClkDiv(baudrate); lcr = (DEFAULT_DATABITS - 5); if (DEFAULT_STOPBITS == 2) lcr |= UART_LCR_STOP; lcr |= DEFAULT_PARITY; CPU_WR_32BIT_REG (base, UART_IER, 0x00); // IRQ ENABL: all disabled CPU_WR_32BIT_REG (base, UART_FCR, 0x1f); // FIFO CTRL: depth=16, clear rec & transm. FIFO, Tx.Trig = 4bytes CPU_WR_32BIT_REG (base, UART_LCR, lcr); // LINE CTRL: 0x18 = 0001 1111: 8 bit, 2 stop, parity EVEN; // 0x03 = 0000 0011: 8 bit, 1 stop, NO parity;#ifdef SERIAL_CLOCK_EXT CPU_WR_32BIT_REG (base, UART_CLKSEL, 0x01); // select EXTERNAL UART Clock CPU_WR_32BIT_REG (base, UART_CLKDIV, 0x01); // CLK DIV : DIVIDED BY 1*16#else CPU_WR_32BIT_REG (base, UART_CLKSEL, 0x00); // CLK SEL : SELECT INTERNAL CLOCK CPU_WR_32BIT_REG (base, UART_CLKDIV, clkdiv); // CLK DIV : DEVIDED according to PLL Speed#endif }void InitUart (void){ InitUartPort(0, DEFAULT_BAUDRATE); InitUartPort(1, DEFAULT_BAUDRATE);// XXXXXXX the below code assumes a system clock of 74.25 mHz/*// PROGRAM UARTS TO FIFO MODE, 8 BITS, 2 STOP, EVEN PAR, CLK_Devider // 38400 bauds with 74.25 mhz sys clock CPU_WR_32BIT_REG ( UART1_BASE,UART_IER,0x00 ); // IRQ ENABL: all disabled CPU_WR_32BIT_REG ( UART1_BASE,UART_FCR,0x7 ); // FIFO CTRL: depth=16, clear rec & transm. FIFO CPU_WR_32BIT_REG ( UART1_BASE,UART_LCR,0x3 ); // LINE CTRL: 0000 0011: 8 bit, 1 stop, NO parity;#ifndef SERIAL_CLOCK_EXT// CPU_WR_32BIT_REG ( UART1_BASE,UART_CLKDIV,0x02 ); // CLK DIV : DEVIDED BY 2*16 CPU_WR_32BIT_REG ( UART1_BASE,UART_CLKDIV,120 ); // CLK DIV : DEVIDED BY 485*16#else CPU_WR_32BIT_REG ( UART1_BASE,UART_CLKDIV,1 ); // CLK DIV : DEVIDED BY 485*16 CPU_WR_32BIT_REG ( UART1_BASE,UART_CLKSEL,0x01 ); // select EXTERNAL UART Clock#endif*/}//// UART output//void PrintChar (int ch){ while ((CPU_RD_32BIT_REG(g_uartbase,UART_LSR)&0x20) == 0); CPU_WR_32BIT_REG (g_uartbase,UART_TBR, ch);}void PrintString (char *t, int maxlen){ while (maxlen-- && *t) { while((CPU_RD_32BIT_REG(g_uartbase,UART_LSR)&0x20) == 0); CPU_WR_32BIT_REG (g_uartbase,UART_TBR, *t++); }}static char hextab[16]="0123456789ABCDEF";void PrintByte(unsigned char b){ char str[2]; str[0]=hextab[(b>>4) & 0xF]; str[1]=hextab[(b) & 0xF]; PrintString(str,2);}void PrintShort(unsigned short s){ char str[4]; str[0]=hextab[(s>>12) & 0xF]; str[1]=hextab[(s>>8) & 0xF]; str[2]=hextab[(s>>4) & 0xF]; str[3]=hextab[(s) & 0xF]; PrintString(str,4);}void PrintLong(unsigned long l){ char str[8]; str[0]=hextab[(l>>28) & 0xF]; str[1]=hextab[(l>>24) & 0xF]; str[2]=hextab[(l>>20) & 0xF]; str[3]=hextab[(l>>16) & 0xF]; str[4]=hextab[(l>>12) & 0xF]; str[5]=hextab[(l>>8) & 0xF]; str[6]=hextab[(l>>4) & 0xF]; str[7]=hextab[(l) & 0xF]; PrintString(str,8);}//// UART input//int PeekChar (void){ if (CPU_RD_32BIT_REG(g_uartbase, UART_LSR) & 0x01) return CPU_RD_32BIT_REG(g_uartbase, UART_RBR); else return -1;}int GetChar (void){ while ((CPU_RD_32BIT_REG(g_uartbase, UART_LSR) & 0x01) == 0); return CPU_RD_32BIT_REG(g_uartbase, UART_RBR);}char *GetString (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) PrintChar(str[pos]); ++pos; } } for (;;) { ch = GetChar (); // escape sequence (0x1b, 0x5b, 0xxx) if (ch == 0x1b && (flag & GETSTR_ESCAPE)) { str[pos] = 0; return NULL; } if (ch != '\b') PrintChar(ch); if (ch == '\r') PrintChar('\n'); else if (ch == '\n') PrintChar('\r'); if (ch == '\r' || ch == '\n') break; else if (ch == '\b') { if (pos > 0) { --pos; PrintChar(ch); PrintChar(' '); PrintChar(ch); } } else { if (pos < maxlen - 2) str[pos++] = ch; } } str[pos] = 0; return str;}#define GETCMD_MAXBUF 16#define GETCMD_MAXLEN 32char *GetCommand (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 (GetString(str, GETCMD_MAXLEN, flag) == NULL) { // get the escape sequence GetChar(); ch = GetChar(); if (ch != 0x41 && ch != 0x42) continue; if (ch == 0x41) { // up if (cmdpos == 0) continue; --cmdpos; } else if (ch == 0x42) { if (cmdpos == s_cmdnum) continue; ++cmdpos; } // clear line for (len = strlen(str); len > 0; --len) { PrintChar('\b'); PrintChar(' '); PrintChar('\b'); } // redisplay line if (cmdpos == s_cmdnum) str[0] = 0; else { strcpy(str, s_cmdbuf[cmdpos]); PrintString(str, -1); } } if (str[0] != 0) { // append new command 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 0;}char *GetRawString(char *str, int maxlen){ int pos = 0; int ch; if (maxlen < 0) maxlen = 256; for (;;) { ch = GetChar(); if (pos < maxlen - 2) str[pos++] = ch; if (ch == '\r' || ch == '\n') break; } str[pos] = 0; return str;}#endif // ENABLE_UART
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -