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

📄 serial-pxa.c

📁 LUBBOCK板的BLOB
💻 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	14745600

static 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 + -