📄 serial.c
字号:
/*------------------------------------------------------------------------- * Filename: serial.c * Version: $Id: serial.c,v 1.2 2001/08/06 22:44:52 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 *-----------------------------------------------------------------------*//* * serial.c: Serial utilities for blob * * Copyright (C) 1999 2000 2001 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 * */#ident "$Id: serial.c,v 1.2 2001/08/06 22:44:52 erikm Exp $"#ifdef HAVE_CONFIG_H# include "config.h"#endif#include "led.h"#include "sa1100.h"#include "serial.h"#include "time.h"/* * Initialise the serial port with the given baudrate. The settings * are always 8 data bits, no parity, 1 stop bit, no start bits. * */void SerialInit(eBauds baudrate){ /* Theory of operations: * - Flush the output buffer * - switch receiver and transmitter off * - clear all sticky bits in control register 3 * - set the port to sensible defaults (no break, no interrupts, * no parity, 8 databits, 1 stopbit, transmitter and receiver * enabled * - set the baudrate to the requested value * - turn the receiver and transmitter back on */#if defined USE_SERIAL1 while(Ser1UTSR1 & UTSR1_TBY) { } Ser1UTCR3 = 0x00; Ser1UTSR0 = 0xff; Ser1UTCR0 = ( UTCR0_1StpBit | UTCR0_8BitData ); Ser1UTCR1 = 0; Ser1UTCR2 = (u32)baudrate; Ser1UTCR3 = ( UTCR3_RXE | UTCR3_TXE );#elif defined USE_SERIAL3 while(Ser3UTSR1 & UTSR1_TBY) { } Ser3UTCR3 = 0x00; Ser3UTSR0 = 0xff; Ser3UTCR0 = ( UTCR0_1StpBit | UTCR0_8BitData ); Ser3UTCR1 = 0; Ser3UTCR2 = (u32)baudrate; Ser3UTCR3 = ( UTCR3_RXE | UTCR3_TXE );#else#error "Configuration error: No serial port used at all!"#endif}/* * Output a single byte to the serial port. */void SerialOutputByte(const char c){#if defined USE_SERIAL1 /* wait for room in the tx FIFO */ while((Ser1UTSR0 & UTSR0_TFS) == 0) ; Ser1UTDR = c;#elif defined USE_SERIAL3 /* wait for room in the tx FIFO */ while((Ser3UTSR0 & UTSR0_TFS) == 0) ; Ser3UTDR = c;#else#error "Configuration error: No serial port used at all!"#endif /* If \n, also do \r */ if(c == '\n') SerialOutputByte('\r');}/* * Write a null terminated string to the serial port. */void SerialOutputString(const char *s) { while(*s != 0) SerialOutputByte(*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'; SerialOutputByte(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) SerialOutputByte((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--) SerialOutputByte(*buf++);}/* * 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 defined USE_SERIAL1 if(Ser1UTSR1 & UTSR1_RNE) { int err = Ser1UTSR1 & (UTSR1_PRE | UTSR1_FRE | UTSR1_ROR); *c = (char)Ser1UTDR;#elif defined USE_SERIAL3 if(Ser3UTSR1 & UTSR1_RNE) { int err = Ser3UTSR1 & (UTSR1_PRE | UTSR1_FRE | UTSR1_ROR); *c = (char)Ser3UTDR;#else#error "Configuration error: No serial port at all"#endif /* If you're lucky, you should be able to use this as * debug information ;-) -- Erik */ 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 { led_toggle(); 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){ u32 startTime, currentTime; char c; int i; int numRead; int skipNewline = 1; int maxRead = len - 1; startTime = TimerGetTime(); for(numRead = 0, i = 0; numRead < maxRead;) { /* try to get a byte from the serial port */ while(!SerialInputByte(&c)) { currentTime = TimerGetTime(); /* check timeout value */ if((currentTime - startTime) > (timeout * TICKS_PER_SECOND)) { /* timeout */ s[i++] = '\0'; return(numRead); } } /* eat newline characters at start of string */ if((skipNewline == 1) && (c != '\r') && (c != '\n')) skipNewline = 0; if(skipNewline == 0) { if((c == '\r') || (c == '\n')) { s[i++] = '\0'; return(numRead); } else { s[i++] = c; numRead++; } } } return(numRead);}/* * 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; char 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(!SerialInputByte(&c)) { currentTime = TimerGetTime(); /* check timeout value */ if((currentTime - startTime) > (timeout * TICKS_PER_SECOND)) { /* timeout! */ return(numRead); } } buf[i++] = c; numRead ++; } return(numRead);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -