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

📄 serial_max3100.c

📁 嵌入式试验箱S3C2410的bootloader源代码
💻 C
字号:
/* * (C) Copyright 2003 * * Pantelis Antoniou <panto@intracom.gr> * Intracom S.A. * * 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 <watchdog.h>#ifdef CONFIG_MAX3100_SERIALDECLARE_GLOBAL_DATA_PTR;/**************************************************************//* convienient macros */#define MAX3100_SPI_RXD() (MAX3100_SPI_RXD_PORT & MAX3100_SPI_RXD_BIT)#define MAX3100_SPI_TXD(x) \	do { \		if (x) \			MAX3100_SPI_TXD_PORT |=  MAX3100_SPI_TXD_BIT; \		else \			MAX3100_SPI_TXD_PORT &= ~MAX3100_SPI_TXD_BIT; \	} while(0)#define MAX3100_SPI_CLK(x) \	do { \		if (x) \			MAX3100_SPI_CLK_PORT |=  MAX3100_SPI_CLK_BIT; \		else \			MAX3100_SPI_CLK_PORT &= ~MAX3100_SPI_CLK_BIT; \	} while(0)#define MAX3100_SPI_CLK_TOGGLE() (MAX3100_SPI_CLK_PORT ^= MAX3100_SPI_CLK_BIT)#define MAX3100_CS(x) \	do { \		if (x) \			MAX3100_CS_PORT |=  MAX3100_CS_BIT; \		else \			MAX3100_CS_PORT &= ~MAX3100_CS_BIT; \	} while(0)/**************************************************************//* MAX3100 definitions */#define MAX3100_WC	(3 << 14)		/* write configuration */#define MAX3100_RC	(1 << 14)		/* read  configuration */#define MAX3100_WD	(2 << 14)		/* write data          */#define MAX3100_RD	(0 << 14)		/* read  data          *//* configuration register bits */#define MAX3100_FEN	(1 << 13)		/* FIFO enable           */#define MAX3100_SHDN    (1 << 12)		/* shutdown bit          */#define MAX3100_TM	(1 << 11)		/* T bit irq mask        */#define MAX3100_RM	(1 << 10)		/* R bit irq mask        */#define MAX3100_PM	(1 <<  9)		/* P bit irq mask        */#define MAX3100_RAM	(1 <<  8)		/* mask for RA/FE bit    */#define MAX3100_IR	(1 <<  7)		/* IRDA timing mode      */#define MAX3100_ST	(1 <<  6)		/* transmit stop bit     */#define MAX3100_PE	(1 <<  5)		/* parity enable bit     */#define MAX3100_L	(1 <<  4)		/* Length bit            */#define MAX3100_B_MASK	(0x000F)		/* baud rate bits mask   */#define MAX3100_B(x)	((x) & 0x000F)	/* baud rate select bits *//* data register bits (write) */#define MAX3100_TE	(1 << 10)		/* transmit enable bit (active low)        */#define MAX3100_RTS	(1 <<  9)		/* request-to-send bit (inverted ~RTS pin) *//* data register bits (read) */#define MAX3100_RA	(1 << 10)		/* receiver activity when in shutdown mode */#define MAX3100_FE	(1 << 10)		/* framing error when in normal mode       */#define MAX3100_CTS	(1 <<  9)		/* clear-to-send bit (inverted ~CTS pin)   *//* data register bits (both directions) */#define MAX3100_R 	(1 << 15)		/* receive bit    */#define MAX3100_T	(1 << 14)		/* transmit bit   */#define MAX3100_P	(1 <<  8)		/* parity bit     */#define MAX3100_D_MASK	0x00FF                  /* data bits mask */#define MAX3100_D(x)	((x) & 0x00FF)		/* data bits      *//* these definitions are valid only for fOSC = 3.6864MHz */#define MAX3100_B_230400        MAX3100_B(0)#define MAX3100_B_115200        MAX3100_B(1)#define MAX3100_B_57600         MAX3100_B(2)#define MAX3100_B_38400         MAX3100_B(9)#define MAX3100_B_19200         MAX3100_B(10)#define MAX3100_B_9600          MAX3100_B(11)#define MAX3100_B_4800          MAX3100_B(12)#define MAX3100_B_2400          MAX3100_B(13)#define MAX3100_B_1200          MAX3100_B(14)#define MAX3100_B_600           MAX3100_B(15)/**************************************************************/static inline unsigned int max3100_transfer(unsigned int val){	unsigned int rx;	int b;	MAX3100_SPI_CLK(0);	MAX3100_CS(0);	rx = 0; b = 16;	while (--b >= 0) {		MAX3100_SPI_TXD(val & 0x8000);		val <<= 1;		MAX3100_SPI_CLK_TOGGLE();		udelay(1);		rx <<= 1;		if (MAX3100_SPI_RXD())			rx |= 1;		MAX3100_SPI_CLK_TOGGLE();		udelay(1);	}	MAX3100_SPI_CLK(1);	MAX3100_CS(1);	return rx;}/**************************************************************//* must be power of 2 */#define RXFIFO_SZ	16static int rxfifo_cnt;static int rxfifo_in;static int rxfifo_out;static unsigned char rxfifo_buf[16];static void max3100_putc(int c){	unsigned int rx;	while (((rx = max3100_transfer(MAX3100_RC)) & MAX3100_T) == 0)		WATCHDOG_RESET();	rx = max3100_transfer(MAX3100_WD | (c & 0xff));	if ((rx & MAX3100_RD) != 0 && rxfifo_cnt < RXFIFO_SZ) {		rxfifo_cnt++;		rxfifo_buf[rxfifo_in++] = rx & 0xff;		rxfifo_in &= RXFIFO_SZ - 1;	}}static int max3100_getc(void){	int c;	unsigned int rx;	while (rxfifo_cnt == 0) {		rx = max3100_transfer(MAX3100_RD);		if ((rx & MAX3100_R) != 0) {			do {				rxfifo_cnt++;				rxfifo_buf[rxfifo_in++] = rx & 0xff;				rxfifo_in &= RXFIFO_SZ - 1;				if (rxfifo_cnt >= RXFIFO_SZ)					break;			} while (((rx = max3100_transfer(MAX3100_RD)) & MAX3100_R) != 0);		}		WATCHDOG_RESET();	}	rxfifo_cnt--;	c = rxfifo_buf[rxfifo_out++];	rxfifo_out &= RXFIFO_SZ - 1;	return c;}static int max3100_tstc(void){	unsigned int rx;	if (rxfifo_cnt > 0)		return 1;	rx = max3100_transfer(MAX3100_RD);	if ((rx & MAX3100_R) == 0)		return 0;	do {		rxfifo_cnt++;		rxfifo_buf[rxfifo_in++] = rx & 0xff;		rxfifo_in &= RXFIFO_SZ - 1;		if (rxfifo_cnt >= RXFIFO_SZ)			break;	} while (((rx = max3100_transfer(MAX3100_RD)) & MAX3100_R) != 0);	return 1;}int serial_init(void){	unsigned int wconf, rconf;	int i;	wconf = 0;	/* Set baud rate */	switch (gd->baudrate) {		case 1200:			wconf = MAX3100_B_1200;			break;		case 2400:			wconf = MAX3100_B_2400;			break;		case 4800:			wconf = MAX3100_B_4800;			break;		case 9600:			wconf = MAX3100_B_9600;			break;		case 19200:			wconf = MAX3100_B_19200;			break;		case 38400:			wconf = MAX3100_B_38400;			break;		case 57600:			wconf = MAX3100_B_57600;			break;		default:		case 115200:			wconf = MAX3100_B_115200;			break;		case 230400:			wconf = MAX3100_B_230400;			break;	}	/* try for 10ms, with a 100us gap */	for (i = 0; i < 10000; i += 100) {		max3100_transfer(MAX3100_WC | wconf);		rconf = max3100_transfer(MAX3100_RC) & 0x3fff;		if (rconf == wconf)			break;		udelay(100);	}	rxfifo_in = rxfifo_out = rxfifo_cnt = 0;	return (0);}void serial_putc(const char c){	if (c == '\n')		max3100_putc('\r');	max3100_putc(c);}void serial_puts(const char *s){	while (*s)		serial_putc (*s++);}int serial_getc(void){	return max3100_getc();}int serial_tstc(void){	return max3100_tstc();}/* XXX WTF? */void serial_setbrg(void){}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -