📄 serial-pxa.c
字号:
/* * serial-pxa.c: Intel PXA serial port driver * * Copyright (c) 2003, Intel Corporation * * 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 * */#ifdef HAVE_CONFIG_H# include <blob/config.h>#endif#include <blob/pxa.h>#include <blob/errno.h>#include <blob/serial.h>#include <blob/types.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 14745600static int 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 */static 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 */static 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. */static int pxa_serial_init(serial_baud_t baud){ CKEN |= CKEN6_FFUART; /* set the port to sensible defaults (no break, no interrupts, * no parity, 8 databits, 1 stopbit, transmitter and receiver * enabled) */ UART_LCR = 0x3; /* assert DTR & RTS to avoid problems of hardware handshake * with serial terminals */ UART_MCR = MCR_DTR | MCR_RTS ; /* disenable FIFO */ UART_FCR = FCR_TRFIFOE; /* enable UART */ UART_IER = IER_UUE; pxa_serial_change_speed(baud); 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. */static 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 */static 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 */static int pxa_serial_write(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;}/* export serial driver */serial_driver_t pxa_serial_driver = { init: pxa_serial_init, read: pxa_serial_read, write: pxa_serial_write, poll: pxa_serial_poll, flush_input: pxa_serial_flush_input, flush_output: pxa_serial_flush_output};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -