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

📄 serial.c

📁 一款类linux的操作系统源码
💻 C
字号:
/* *  Roadrunner/pk *    Copyright (C) 1989-2001  Cornfed Systems, Inc. * *  The Roadrunner/pk operating system is free software; you can *  redistribute and/or modify it under the terms of the GNU General *  Public License, version 2, as published by the Free Software *  Foundation. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT 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 * *  More information about the Roadrunner/pk operating system of *  which this file is a part is available on the World-Wide Web *  at: http://www.cornfed.com. * *//* * This driver is based on the Linux serial driver: * *  linux/drivers/char/serial.c * *  Copyright (C) 1991, 1992  Linus Torvalds *    (and a host of others, including Theodore Ts'o) * * Port of the serial driver to the Roadrunner/pk operating system. *      -- Joel Vallier <joel.vallier@wanadoo.fr>, May 2000 */ #include <errno.h> #include <m68328.h>#include <dev/serial.h>#include <sys/intr.h>#include <event.h>#include <stdlib.h>#include <sys/mem.h>#include <sys/config.h>#include <string.h>#include <sys/ioctl.h>#include <stdio.h>#define MASTER_CLOCK	CLOCK_16_58MHZ#define RXQ_LENGTH	PAGE_SIZEstatic int s0_initialized = 0;typedef struct {	unsigned char	id;	volatile unsigned short	*UART_CTL;	volatile unsigned short	*BAUD_CTL;	volatile unsigned short	*MISC_REG;	volatile unsigned short	*RX;	volatile unsigned short	*TX;	volatile unsigned char	*TX_REG;	volatile unsigned char	*TX_DATA;	    int intr;			               /* Interrupt number */    int eoi;			               /* End-of-interrupt mask */    int event;			               /* Asynchronous event number */    char *name;                                    /* UART name */    int dfl_xmit_fifo_size;                        /* fifo size */    int flags;                                     /* flag      */    int speed;			               /* Baud rate */    int databits;		                        /* Number of data bits */    int parity;			               /* Parity type */    int stopbits;		                        /* Number of stop bits */    char *q;			               /* Receive queue */    int h, t;			               /* Receive queue head and tail */    char last;			               /* Last character received */	} m68328_port;m68328_port port0 = {	0,	(unsigned short *)M328_USTCNT,	(unsigned short *)M328_UBAUD,	(unsigned short *)M328_UARTMISC,	(unsigned short *)M328_UARTRX,	(unsigned short *)M328_UARTTX,	(unsigned char *)M328_UARTTX,	(unsigned char *)(M328_UARTTX + 1),    INTR_UTXD0,			               /* Interrupt number */    0,     			               /* End-of-interrupt mask */    EVENT_UTXD0,			               /* Asynchronous event number */    "MC68EZ328_S0",                                /* UART name */    8,                                             /* fifo size */    0,                                             /* flag      */    115200, 			               /* Baud rate */    8,  		                                 /* Number of data bits */    0,			                        /* Parity type */    1,		                                 /* Number of stop bits */    NULL,			               /* Receive queue */    0,                                             /* Receive queue head  */    0,			                        /* Receive queue tail */    0,			                        /* Last character received */	};m68328_port *s0 = &port0;/* Enable bits in the UART Control Register */#define UART_ENABLE	0x1 << 15#define RX_ENABLE		0x1 << 14#define TX_ENABLE		0x1 << 13#define PARITY_ENABLE	0x1 << 11#define ODD_PARITY	0x1 << 10#define STOP_BITS		0x1 <<  9#define EIGHT_BIT_TRX	0x1 <<  8#define TX_AVAIL_EN	0x1 <<  0/* Define masks to disable certain bits in UART Control Register */#define TX_DISABLE	0xDFFF#define RX_DISABLE	0xBFFF/* Enumerate supported clock speeds */#define CLOCK_16_58MHZ	1#define CLOCK_32_16MHZ	2/* Here are just some different values to configure the baudrate */#if MASTER_CLOCK == CLOCK_16_58MHZ	#define B230400			0x001c	#define B115200			0x0038	#define B57600			0x0138	#define B38400			0x0026	#define B19200			0x0126	#define B9600			0x0226	#define B4800			0x0326	#define B2400			0x0426	#define B1200			0x0526	#define B600			0x0626	#define B300			0x0726#elif MASTER_CLOCK == CLOCK_32_16MHZ	#define B230400			0x0038	#define B115200			0x0138	#define B57600			0x0238	#define B38400			0x0126	#define B19200			0x0226	#define B9600			0x0326	#define B4800			0x0426	#define B2400			0x0526	#define B1200			0x0626	#define B600			0x0726	#define B300			0x070B#else	#error "MASTER_CLOCK is not defined correctly"#endif/* local data */static unsigned char	PESEL		;//: M328_PESEL;static unsigned char	PEPUEN		;//: M328_PEPUEN;static unsigned char	PGSEL		;//: M328_PGSEL;static unsigned char	PGPUEN		;//: M328_PGPUEN;static unsigned char	PJSEL		;//: M328_PJSEL;static unsigned char	PJPUEN		;//: M328_PJPUEN;static unsigned short	PLL_CTL		;//: M328_PLLCR;static voids0_isr(void *params){    u_char ch;    unsigned short	receive_reg;        disable;    /* XXX Only handling the receive chars interrupt for now */    do {        receive_reg = *(s0->RX);	/* Word-read the receiver regs */	if (receive_reg & 0x2000)	{	/* a character is already in the FIFO */		if (receive_reg & 0x0F00)		{	/* a data read error occured, we don't differentiate */		    break;		}		else		{	/* the data */			ch = (char)receive_reg;			            /* Place character in receive queue */	        if (((s0->t + 1) % RXQ_LENGTH) != s0->h) {	           s0->q[s0->t] = ch;	           s0->t = (s0->t + 1) % RXQ_LENGTH;	                       #if _DEBUG_ECHO	            s0_put(ch);            #endif					    }	     }	}    } while (1);    enable;}ints0_init(){    /* Allocate and initialize receive queue */    //2002年10月09日修改    //s0->q = (char *) kmalloc(RXQ_LENGTH);    s0->q = (char *) malloc(RXQ_LENGTH);    bzero(s0->q, RXQ_LENGTH);	PESEL &= 0x0F;			/* configure the E port */	PEPUEN |= 0x10;			/* receive pull-up must be enabled */	   //SCM: PLL config should be part of board initialization, not here   //PLL_CTL = 0x2400;			/* configure the PLL control */	*(s0->UART_CTL) = 0x0000;			/* disable UART for re-configuration */	*(s0->MISC_REG) = 0x0000;			/* Set the MISC register to defaults */	*(s0->BAUD_CTL) = B115200;		/* Set the baudrate */	*(s0->TX_REG) = 0x08;				/* Set TX register to ignore CTS */	/* set UART control to enabled (Tx and Rx), 1 stop bits, 8 data bits, no parity */	*(s0->UART_CTL) = UART_ENABLE | RX_ENABLE | TX_ENABLE | STOP_BITS | EIGHT_BIT_TRX;	    isr_inst(s0->intr, s0_isr, s0);    intr_unmask(s0->intr);			return 0;}ints0_shut(){  return ENOSYS;}ints0_ioctl(int cmd, void *args){    if (cmd == GET_BUFFER_SIZE) {	if (args == NULL)	    return EINVAL;	*((u_long *) args) = 1;	return 0;    }    return ENOTTY;}ints0_get(int *c){    int   len;    char  * addr;        addr = (char *)0x00710000;        //kprintf("%x  %2x\n",addr);        len = 0;        do {        u_char ch;    unsigned short	receive_reg;        receive_reg = *(s0->RX);	/* Word-read the receiver regs */    	if (receive_reg & 0x2000)	{	/* a character is already in the FIFO */		if (receive_reg & 0x0F00)		{	/* a data read error occured, we don't differentiate */		    continue;		}		else		{	/* the data */			ch = (char)receive_reg;						*addr = ch;						*addr++;			//len ++;						//if(len == 0x100)			// {			//    len = 0;			    //kprintf("%x  %2x\n",addr,ch);			    s0_put(ch);			//  }  						//if(addr == (char *)0x00716000)kprintf("copy end!");		}	}	        } while (1);    disable;    while (s0->h == s0->t) {	enable;	event_wait(s0->event);	disable;    }    *c = s0->q[s0->h];    s0->h = (s0->h + 1) % RXQ_LENGTH;    if (*c == '\r')	*c = '\n';    enable;    return 0;}ints0_put(int c){    disable;	while (1)	{		if (*(s0->TX_REG) & 0x20)		{	/* The FIFO has a slot available*/			*(s0->TX_DATA) = (unsigned char) c;			break;		}	}	    if (c == '\r') {	while (1)	{		if (*(s0->TX_REG) & 0x20)		{	/* The FIFO has a slot available*/			*(s0->TX_DATA) = (unsigned char) '\n';			break;		}	}    }        if (c == '\n' && s0->last != '\r') {	while (1)	{		if (*(s0->TX_REG) & 0x20)		{	/* The FIFO has a slot available*/			*(s0->TX_DATA) = (unsigned char) '\r';			break;		}	}    }        s0->last = c;    enable;    return 0;}

⌨️ 快捷键说明

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