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

📄 serial.c

📁 这是一个uC/OS-II For cs8900的移植项目源代码.可以在uCOSV252.exe上运行
💻 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 + -