📄 serial.c
字号:
/*-------------------------------------------------------------------------
* Filename: serial.c
* Version: $Id: serial.c,v 1.18 2000/07/10 14:20:17 erikm Exp $
* Copyright: Copyright (C) 1999, Erik Mouw
* Author: Erik Mouw <J.A.K.Mouw@its.tudelft.nl>
* Description: Serial utilities for blob
* Created at: Tue Aug 24 20:25:00 1999
* Modified by: Erik Mouw <J.A.K.Mouw@its.tudelft.nl>
* Modified at: Mon Oct 4 20:11:14 1999
* Modified by: Young-Su, Ahn. <nurie@dreamwiz.com>
* Modified at: Wed Mar 13 20:11:14 2001
*-----------------------------------------------------------------------*/
/*
* serial.c: Serial utilities for blob
*
* Copyright (C) 1999 Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
*
* 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 "serial.h"
#include "time.h"
#include "errno.h"
// number of nibbles in a word */
#define NIBBLES_PER_LONG (8)
#define NIBBLES_PER_SHORT (4)
#define NIBBLES_PER_CHAR (2)
#define SerialUTSR0 Ser3UTSR0
#define SerialUTSR1 Ser3UTSR1
#define SerialUTDR Ser3UTDR
#define SerialUTCR0 Ser3UTCR0
#define SerialUTCR1 Ser3UTCR1
#define SerialUTCR2 Ser3UTCR2
#define SerialUTCR3 Ser3UTCR3
//serial_driver_t *serial_driver;
//******************************************************************************
//
// 堡开 函荐 沥狼
//
//******************************************************************************
static int SerialErrorFlag = 0;
// 开且 : serial阑 林绢柳 baudrate肺 促矫 檬扁拳.
// 概俺 : SCR : SCR俊 瘤沥且 蔼. Baudrate甫 BaudToSCR(A)阑 烹秦 SCR狼 蔼栏肺 官曹 荐 乐促.
// 馆券 :
// 林狼 :
void SerialInit(SCR scr){
#ifdef USE_SERIAL1
// Serial Port 1阑 荤侩窍搁, UART肺 荤侩窍档废 汲沥.
Ser1SDCR0 = 0x00000001;
#endif
// 1. Flush the output buffer. serial捞 悼累吝牢 悼救 扁促覆.
while (UTSR1 & UTSR1_TBY);
// 2. Rx, Tx off.
UTCR3 = 0x00;
UTSR0 = 0xff; // 了价钦聪促. 恐 0xff牢瘤 捞蜡甫 葛福摆嚼聪促.
// 3. Serial阑 荤侩窍绊磊 窍绰 规侥栏肺 set.
#ifdef SERIAL_CONFIG
UTCR0 = (SERIAL_STOP_BIT | SERIAL_DATA_BIT | SERIAL_PARITY_ENABLE | SERIAL_PARITY);
#else
UTCR0 = (UTCR0_1StpBit | UTCR0_8BitData);
#endif
// 4. Set Baudrate.
UTCR1 = 0;
UTCR2 = (ulong)scr;
// 5. Rx, Tx on.
UTCR3 = (UTCR3_RXE | UTCR3_TXE);
return;
}
// Output a single byte to the serial port.
void SerialOutputByte(const char c){
// wait for room in the tx FIFO.
while (!(UTSR0 & UTSR0_TFS));
UTDR = c;
// c=='\n'捞搁, 角力肺绰 "\n\r"阑 免仿.
if (c=='\n') SerialOutputByte('\r');
}
// Read a single byte from the serial port. Returns 1 on success, 0
// otherwise. When the function is succesfull, the character read is
// written into its argument c.
int SerialInputByte(char *c){
if(UTSR1 & UTSR1_RNE){
int err = UTSR1 & (UTSR1_PRE | UTSR1_FRE | UTSR1_ROR);
(volatile char)*c = UTDR;
// If you're lucky, you should be able to use this as
// debug information.
if(err & UTSR1_PRE)
SerialOutputByte('@');
else if(err & UTSR1_FRE)
SerialOutputByte('#');
else if(err & UTSR1_ROR)
SerialOutputByte('$');
// We currently only care about framing and parity errors.
if((err & (UTSR1_PRE | UTSR1_FRE)) != 0){
return SerialInputByte(c);
}
else return 1;
}
else {
// no bit ready.
return(0);
}
} // SerialInputByte.
// read a string with maximum length len from the serial port
// using a timeout of timeout seconds.
// len is the length of array s _including_ the trailing zero,
// the function returns the number of bytes read _excluding_
// the trailing zero.
int SerialInputString(char *s, const int len, const int timeout){
ulong endTime;
char c;
int i, numRead;
endTime = GetTime() + HZ * timeout;
for (numRead=0, i=0; numRead<len-1;){
// try to get a byte from the serial port.
while (!SerialInputByte(&c)) {
// check timeout value.
if (GetTime() > endTime){
// timeout.
s[i++] = '\0';
return numRead;
}
}
// eat newline characters at start of string.
if (numRead!=0 || (c!='\r' && c!='\n')){
if ((c=='\r') || (c=='\n')){
s[i++] = '\0';
return(numRead);
} else {
s[i++] = c;
numRead++;
}
}
}
return(numRead);
} // SerialInputString.
//------------------------------------------------------------------------------
// 汲疙 : 矫府倔 叼官捞胶俊 茄 巩磊甫 焊辰促.
// 概拌 : 绝澜
// 馆券 : 绝澜
// 林狼 : 绝澜
//------------------------------------------------------------------------------
void SerialOutChar( const char c )
{
// 傈价 啊瓷且锭鳖瘤 扁促赴促.
while((Ser3UTSR0 & UTSR0_TFS) == 0); // WatchDoc();
// 矫府倔俊 单捞鸥甫 免仿茄促.
Ser3UTDR = c;
}
//------------------------------------------------------------------------------
// 汲疙 : 矫府倔 叼官捞胶俊 茄 巩磊甫 焊辰促.
// 概拌 : 绝澜
// 馆券 : 绝澜
// 林狼 : CR 狼 LR CR 肺 函版窍咯 免仿茄促.
//------------------------------------------------------------------------------
void SerialOutChar_CheckCR( const char c )
{
SerialOutChar( c );
if(c == '\n') SerialOutChar('\r');
}
//------------------------------------------------------------------------------
// 汲疙 : 矫府倔 叼官捞胶俊 巩磊凯阑 焊辰促.
// 概拌 : 绝澜
// 馆券 : 绝澜
// 林狼 : 绝澜
//------------------------------------------------------------------------------
int SerialOutStr( char *str, int size )
{
int lp ;
for (lp=0;lp<size;lp++) SerialOutChar(str[lp]) ;
return lp;
}
//------------------------------------------------------------------------------
// 汲疙 : 矫府倔 叼官捞胶俊 巩磊凯阑 焊辰促.
// 概拌 : 绝澜
// 馆券 : 绝澜
// 林狼 : 绝澜
//------------------------------------------------------------------------------
int SerialOutStr_CheckCR( char *str, int size )
{
int lp ;
for (lp=0;lp<size;lp++) SerialOutChar_CheckCR(str[lp]) ;
return lp;
}
//------------------------------------------------------------------------------
// 汲疙 : 矫府倔 叼官捞胶俊辑 茄 巩磊甫 罐绰促.
// 概拌 : 绝澜
// 馆券 : 荐脚等 单捞鸥啊 乐栏搁 1 / 绝栏搁 0
// 林狼 : 绝澜
//------------------------------------------------------------------------------
int SerialIsReadyChar( void )
{
// 荐脚等 单捞鸥啊 乐绰啊甫 犬牢茄促.
if(Ser3UTSR1 & UTSR1_RNE) return 1;
return 0;
}
//------------------------------------------------------------------------------
// 汲疙 : 矫府倔 叼官捞胶俊辑 茄 巩磊甫 罐绰促.
// 概拌 : 绝澜
// 馆券 : 荐脚等 巩磊
// 林狼 : 绝澜
//------------------------------------------------------------------------------
char SerialIsGetChar( void )
{
// 俊矾甫 啊廉 柯促.
SerialErrorFlag = Ser3UTSR1 & (UTSR1_PRE | UTSR1_FRE | UTSR1_ROR);
// 荐脚等 单捞鸥甫 啊廉 柯促.
return (char)Ser3UTDR;
}
//------------------------------------------------------------------------------
// 汲疙 : 矫府倔 叼官捞胶狼 荐脚 俊矾 敲扼弊甫 努府绢 茄促.
// 概拌 : 绝澜
// 馆券 : 荐脚等 巩磊
// 林狼 : 绝澜
//------------------------------------------------------------------------------
char SerialIsClearError( void )
{
SerialErrorFlag = 0;
return (char)SerialErrorFlag;
}
//------------------------------------------------------------------------------
// 汲疙 : 矫府倔 叼官捞胶狼 荐脚 俊矾 敲扼弊 蔼阑 掘绰促.
// 概拌 : 绝澜
// 馆券 : 荐脚等 巩磊
// 林狼 : 绝澜
//------------------------------------------------------------------------------
int SerialIsGetError( void )
{
return SerialErrorFlag;
}
/*
* SerialInputBlock(): almost the same as SerialInputString(), but
* this one just reads a block of characters without looking at
* special characters.
*/
int SerialInputBlock(char *buf, int bufsize, const int timeout)
{
u32 startTime, currentTime;
int c;
int i;
int numRead;
int maxRead = bufsize;
startTime = TimerGetTime();
for(numRead = 0, i = 0; numRead < maxRead;) {
/* try to get a byte from the serial port */
while(serial_poll() == 0) {
currentTime = TimerGetTime();
/* check timeout value */
if((currentTime - startTime) >
(timeout * TICKS_PER_SECOND)) {
/* timeout! */
return(numRead);
}
}
c = serial_read();
/* check for errors */
if(c < 0)
return c;
buf[i++] = c;
numRead ++;
}
return(numRead);
}
/* initialise serial port at the request baudrate. returns 0 on
* success, or a negative error number on failure
*/
/*int serial_init(SCR baudrate)
{
return serial_driver->init(baudrate);
}
*/
/* read one character from the serial port. return character (between
* 0 and 255) on success, or negative error number on failure. this
* function is blocking */
int serial_read(void)
{
// return serial_driver->read();
return sa11x0_serial_read();
}
/* read one character from the serial port. return character (between
* 0 and 255) on success, or negative error number on failure. this
* function is blocking */
static int sa11x0_serial_read(void)
{
int rv;
for(;;) {
rv = sa11x0_serial_poll();
if(rv < 0)
return rv;
if(rv > 0)
return SerialUTDR & 0xff;
}
}
/* write character to serial port and replace all \n characters by a
* \n\r sequence. return 0 on success, or negative error number on
* failure. this function is blocking
*/
int serial_write(int c)
{
int rv;
//rv = serial_driver->write(c);
rv = sa11x0_serial_write(c);
/* if \n, also do \r */
if(c == '\n')
//rv = serial_driver->write('\r');
rv = sa11x0_serial_write('\r');
return rv;
}
/* write character to serial port. return 0 on success, or negative
* error number on failure. this function is blocking
*/
static int sa11x0_serial_write(int c)
{
/* wait for room in the transmit FIFO */
while((SerialUTSR0 & UTSR0_TFS) == 0) {
}
SerialUTDR = c & 0xff;
return 0;
}
/* write character to serial port and do not replace any
* characters. return 0 on success, or negative error number on
* failure. this function is blocking
*/
int serial_write_raw(int c)
{
//return serial_driver->write(c);
return sa11x0_serial_write(c);
}
/* check if there is a character available to read. returns 1 if there
* is a character available, 0 if not, and negative error number on
* failure */
int serial_poll(void)
{
//return serial_driver->poll();
return sa11x0_serial_poll();
}
/* check if there is a character available to read. returns 1 if there
* is a character available, 0 if not, and negative error number on
* failure */
static int sa11x0_serial_poll(void)
{
/* check for errors */
if(SerialUTSR1 & (UTSR1_PRE | UTSR1_FRE | UTSR1_ROR))
return -ESERIAL;
if(SerialUTSR1 & UTSR1_RNE)
return 1;
else
return 0;
}
/* flush serial input queue. returns 0 on success or negative error
* number otherwise
*/
int serial_flush_input(void)
{
printf("serial_flush_input\n"); //ssenja 030611
// return serial_driver->flush_input();
return sa11x0_serial_flush_input();
}
/* flush serial input queue. returns 0 on success or negative error
* number otherwise
*/
static int sa11x0_serial_flush_input(void)
{
volatile u32 tmp;
printf("in_flush_input\n");
/* keep on reading as long as the receiver is not empty */
while(SerialUTSR1 & UTSR1_RNE) {
if(SerialUTSR1 & (UTSR1_PRE | UTSR1_FRE | UTSR1_ROR))
return -ESERIAL;
tmp = SerialUTDR;
}
printf("in_flush_input\n");
return 0;
}
/* flush output queue. returns 0 on success or negative error number
* otherwise
*/
int serial_flush_output(void)
{
//return serial_driver->flush_output();
return sa11x0_serial_flush_output();
}
/* flush output queue. returns 0 on success or negative error number
* otherwise
*/
static int sa11x0_serial_flush_output(void)
{
/* wait until the transmitter is no longer busy */
while(SerialUTSR1 & UTSR1_TBY) {
}
return 0;
}
/*
* Write a null terminated string to the serial port.
*/
void SerialOutputString(const char *s)
{
while(*s != 0)
serial_write(*s++);
} /* SerialOutputString */
/*
* Write the argument of the function in hexadecimal to the serial
* port. If you want "0x" in front of it, you'll have to add it
* yourself.
*/
void SerialOutputHex(const u32 h)
{
char c;
int i;
for(i = NIBBLES_PER_WORD - 1; i >= 0; i--) {
c = (char)((h >> (i * 4)) & 0x0f);
if(c > 9)
c += ('a' - 10);
else
c += '0';
serial_write(c);
}
}
/*
* Write the argument of the function in decimal to the serial port.
* We just assume that each argument is positive (i.e. unsigned).
*/
void SerialOutputDec(const u32 d)
{
int leading_zero = 1;
u32 divisor, result, remainder;
remainder = d;
for(divisor = 1000000000;
divisor > 0;
divisor /= 10) {
result = remainder / divisor;
remainder %= divisor;
if(result != 0 || divisor == 1)
leading_zero = 0;
if(leading_zero == 0)
serial_write((char)(result) + '0');
}
}
/*
* Write a block of data to the serial port. Similar to
* SerialOutputString(), but this function just writes the number of
* characters indicated by bufsize and doesn't look at termination
* characters.
*/
void SerialOutputBlock(const char *buf, int bufsize)
{
while(bufsize--)
serial_write(*buf++);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -