📄 serial-pxa.c
字号:
/* * serial-pxa.c: Intel PXA serial port driver * * Copyright (c) 2003, Intel Corporation (yu.tang@intel.com) * * 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 "pxa.h"#include "errno.h"#include "serial-pxa.h"#include "types.h"#include "time.h"#define UART_RBR FFRBR#define UART_THR FFTHR#define UART_LCR FFLCR#define UART_LSR FFLSR#define UART_IER FFIER#define UART_FCR FFFCR#define UART_DLL FFDLL#define UART_DLH FFDLH#define UART_MCR FFMCR#define XTAL 14745600int pxa_serial_change_speed(int baud){ int divisor = XTAL / (baud<<4); UART_LCR |= LCR_DLAB; UART_DLL = (divisor & 0xFF); UART_DLH = (divisor >> 8); UART_LCR &= ~LCR_DLAB; return 0;}/* Flush serial input queue. * Returns 0 on success or negative error number otherwise */int pxa_serial_flush_input(void){ volatile u32 tmp; /* keep on reading as long as the receiver is not empty */ while( UART_LSR & LSR_DR ) { if( UART_LSR & ( LSR_PE | LSR_FE | LSR_BI) ) return -ESERIAL; tmp = UART_RBR; } return 0;}/* Flush output queue. * Returns 0 on success or negative error number otherwise */int pxa_serial_flush_output(void){ /* wait until the transmitter is ready to transmit*/ while( !(UART_LSR & LSR_TDRQ) ); return 0;}/* Initialise serial port at the request baudrate. * Returns 0 on success, or a negative error number otherwise. * * 147.7456 MHZ * BaudRate = ---------------- * 16 x Divisor * * thus, if divisor is 24, the baud rate is 38400 bps. */int pxa_serial_init(serial_baud_t baud)//zkj. This function is fully modified.{ CKEN |= CKEN6_FFUART; UART_IER = 0; //disenable ffuart UART_FCR = 0; //disenable fifo /* set the port to sensible defaults (no break, no interrupts, * no parity, 8 databits, 1 stopbit, transmitter and receiver * enabled) */ UART_LCR = LCR_WLS0 | LCR_WLS1; pxa_serial_change_speed(baud); /* assert DTR & RTS to avoid problems of hardware handshake * with serial terminals */ UART_MCR = MCR_DTR | MCR_RTS ; /* enable UART */ UART_IER = IER_UUE; pxa_serial_flush_output(); return 0;}/* 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 pxa_serial_poll(void){ /* check for errors */ if( UART_LSR & ( LSR_PE | LSR_FE | LSR_BI) ) return -ESERIAL; if ( UART_LSR & LSR_DR ) return 1; else return 0;}/* 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 pxa_serial_read(void){ int rv; for(;;) { rv = pxa_serial_poll(); if(rv < 0) return rv; if(rv > 0) return UART_RBR & 0xff; }}/* write character to serial port. return 0 on success, or negative * error number on failure. this function is blocking */int pxa_serial_write(char c)//zkj. blob is: (int c){ int count=0; /* wait for room in the transmit FIFO */ while( (UART_LSR & LSR_TDRQ) == 0 ) { count ++; if(count > 1000) return 0; } UART_THR = c & 0xff; return 0;}/* * Write a null terminated string to the serial port. */void SerialOutputString(const char *s){ while(*s != 0) pxa_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'; pxa_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) pxa_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--) pxa_serial_write(*buf++);}/* * 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; int 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(pxa_serial_poll() == 0) { currentTime = TimerGetTime(); /* check timeout value */ if((currentTime - startTime) > (timeout * TICKS_PER_SECOND)) { /* timeout */ s[i++] = '\0'; return(numRead); } } c = pxa_serial_read(); /* check for errors */ if(c < 0) { s[i++] = '\0'; return c; } /* 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++] = (char)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; 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(pxa_serial_poll() == 0) { currentTime = TimerGetTime(); /* check timeout value */ if((currentTime - startTime) > (timeout * TICKS_PER_SECOND)) { /* timeout! */ return(numRead); } } c = pxa_serial_read(); /* check for errors */ if(c < 0) return c; buf[i++] = c; numRead ++; } return(numRead);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -