diff options
Diffstat (limited to 'cpu/arm720t/serial_netarm.c')
| -rw-r--r-- | cpu/arm720t/serial_netarm.c | 185 | 
1 files changed, 185 insertions, 0 deletions
| diff --git a/cpu/arm720t/serial_netarm.c b/cpu/arm720t/serial_netarm.c new file mode 100644 index 000000000..8cfe049b0 --- /dev/null +++ b/cpu/arm720t/serial_netarm.c @@ -0,0 +1,185 @@ +/* + * Serial Port stuff - taken from Linux + * + * (C) Copyright 2002 + * MAZeT GmbH <www.mazet.de> + * Stephan Linz <linz@mazet.de>, <linz@li-pro.net> + * + * (c) 2004 + * IMMS gGmbH <www.imms.de> + * Thomas Elste <info@elste.org> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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 <common.h> +#include <asm/arch/netarm_registers.h> + +#ifdef CONFIG_NETARM + +#define PORTA	(*(volatile unsigned int *)(NETARM_GEN_MODULE_BASE + NETARM_GEN_PORTA)) +#define PORTB	(*(volatile unsigned int *)(NETARM_GEN_MODULE_BASE + NETARM_GEN_PORTB)) + +/* wait until transmitter is ready for another character */ +#define TXWAITRDY(registers) 							\ +{										\ +	ulong tmo = get_timer(0) + 1 * CFG_HZ;					\ +	while (((registers)->status_a & NETARM_SER_STATA_TX_RDY) == 0 )	{	\ +		if (get_timer(0) > tmo)						\ +			break;							\ +	}									\ +} + + +volatile netarm_serial_channel_t *serial_reg_ch1 = get_serial_channel(0); +volatile netarm_serial_channel_t *serial_reg_ch2 = get_serial_channel(1); + +extern void _netarm_led_FAIL1(void); + +/* + * Setup both serial i/f with given baudrate + */ +void serial_setbrg (void) +{ +	/* get the gd pointer */ +	DECLARE_GLOBAL_DATA_PTR; + +	/* set 0 ... make sure pins are configured for serial */ +	PORTA = PORTB = +		NETARM_GEN_PORT_MODE (0xef) | NETARM_GEN_PORT_DIR (0xe0); + +	/* first turn em off */ +	serial_reg_ch1->ctrl_a = serial_reg_ch2->ctrl_a = 0; + +	/* clear match register, we don't need it */ +	serial_reg_ch1->rx_match = serial_reg_ch2->rx_match = 0; + +	/* setup bit rate generator and rx buffer gap timer (1 byte only) */ +	if ((gd->baudrate >= MIN_BAUD_RATE) +	    && (gd->baudrate <= MAX_BAUD_RATE)) { +		serial_reg_ch1->bitrate = serial_reg_ch2->bitrate = +			NETARM_SER_BR_X16 (gd->baudrate); +		serial_reg_ch1->rx_buf_timer = serial_reg_ch2->rx_buf_timer = +			0; +		serial_reg_ch1->rx_char_timer = serial_reg_ch2->rx_char_timer = +			NETARM_SER_RXGAP (gd->baudrate); +	} else { +		hang (); +	} + +	/* setup port mode */ +	serial_reg_ch1->ctrl_b = serial_reg_ch2->ctrl_b = +		( NETARM_SER_CTLB_RCGT_EN | +		  NETARM_SER_CTLB_UART_MODE); +	serial_reg_ch1->ctrl_a = serial_reg_ch2->ctrl_a = +		( NETARM_SER_CTLA_ENABLE | +		  NETARM_SER_CTLA_P_NONE | +		  /* see errata */ +		  NETARM_SER_CTLA_2STOP | +		  NETARM_SER_CTLA_8BITS | +		  NETARM_SER_CTLA_DTR_EN | +		  NETARM_SER_CTLA_RTS_EN); +} + + +/* + * Initialise the serial port with the given baudrate. The settings + * are always 8 data bits, no parity, 1 stop bit, no start bits. + */ +int serial_init (void) +{ +	serial_setbrg (); +	return 0; +} + + +/* + * Output a single byte to the serial port. + */ +void serial_putc (const char c) +{ +	volatile unsigned char *fifo; + +	/* If \n, also do \r */ +	if (c == '\n') +		serial_putc ('\r'); + +	fifo = (volatile unsigned char *) &(serial_reg_ch1->fifo); +	TXWAITRDY (serial_reg_ch1); +	*fifo = c; +} + +/* + * Test of a single byte from the serial port. Returns 1 on success, 0 + * otherwise. + */ +int serial_tstc(void) +{ +	return serial_reg_ch1->status_a & NETARM_SER_STATA_RX_RDY; +} + +/* + * Read a single byte from the serial port. Returns 1 on success, 0 + * otherwise. + */ +int serial_getc (void) +{ +	unsigned int ch_uint; +	volatile unsigned int *fifo; +	volatile unsigned char *fifo_char = NULL; +	int buf_count = 0; + +	while (!(serial_reg_ch1->status_a & NETARM_SER_STATA_RX_RDY)) +		/* NOP */ ; + +	fifo = (volatile unsigned int *) &(serial_reg_ch1->fifo); +	fifo_char = (unsigned char *) &ch_uint; +	ch_uint = *fifo; + +	buf_count = NETARM_SER_STATA_RXFDB (serial_reg_ch1->status_a); +	switch (buf_count) { +	case NETARM_SER_STATA_RXFDB_4BYTES: +		buf_count = 4; +		break; +	case NETARM_SER_STATA_RXFDB_3BYTES: +		buf_count = 3; +		break; +	case NETARM_SER_STATA_RXFDB_2BYTES: +		buf_count = 2; +		break; +	case NETARM_SER_STATA_RXFDB_1BYTES: +		buf_count = 1; +		break; +	default: +		/* panic, be never here */ +	} + +	serial_reg_ch1->status_a |= NETARM_SER_STATA_RX_CLOSED; + +	return ch_uint & 0xff; +} + +void serial_puts (const char *s) +{ +	while (*s) { +		serial_putc (*s++); +	} +} + +#endif /* CONFIG_NETARM */ |