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

📄 serial_ti16550.c

📁 MIPS YAMON, a famous monitor inc. source, make file and PDF manuals.
💻 C
📖 第 1 页 / 共 3 页
字号:
/************************************************************************ * *      SERIAL_TI16550.c * *      The 'SERIAL_TI16550' module implements the SERIAL-TI16550C *      device driver as an IO device with following services: * *        1) init  device:  configure and initialize serial driver *        2) open  device:  not used *        3) close device:  not used *        4) read  device:  read character from serial device *        5) write device:  write character to serial device *        6) ctrl  device:  statistics and poll for ctrl/c * * * ###################################################################### * * mips_start_of_legal_notice *  * Copyright (c) 2004 MIPS Technologies, Inc. All rights reserved. * * * Unpublished rights (if any) reserved under the copyright laws of the * United States of America and other countries. * * This code is proprietary to MIPS Technologies, Inc. ("MIPS * Technologies"). Any copying, reproducing, modifying or use of this code * (in whole or in part) that is not expressly permitted in writing by MIPS * Technologies or an authorized third party is strictly prohibited. At a * minimum, this code is protected under unfair competition and copyright * laws. Violations thereof may result in criminal penalties and fines. * * MIPS Technologies reserves the right to change this code to improve * function, design or otherwise. MIPS Technologies does not assume any * liability arising out of the application or use of this code, or of any * error or omission in such code. Any warranties, whether express, * statutory, implied or otherwise, including but not limited to the implied * warranties of merchantability or fitness for a particular purpose, are * excluded. Except as expressly provided in any written license agreement * from MIPS Technologies or an authorized third party, the furnishing of * this code does not give recipient any license to any intellectual * property rights, including any patent rights, that cover this code. * * This code shall not be exported, reexported, transferred, or released, * directly or indirectly, in violation of the law of any country or * international law, regulation, treaty, Executive Order, statute, * amendments or supplements thereto. Should a conflict arise regarding the * export, reexport, transfer, or release of this code, the laws of the * United States of America shall be the governing law. * * This code constitutes one or more of the following: commercial computer * software, commercial computer software documentation or other commercial * items. If the user of this code, or any related documentation of any * kind, including related technical data or manuals, is an agency, * department, or other entity of the United States government * ("Government"), the use, duplication, reproduction, release, * modification, disclosure, or transfer of this code, or any related * documentation of any kind, is restricted in accordance with Federal * Acquisition Regulation 12.212 for civilian agencies and Defense Federal * Acquisition Regulation Supplement 227.7202 for military agencies. The use * of this code by the Government is further restricted in accordance with * the terms of the license agreement(s) and/or applicable contract terms * and conditions covering this code from MIPS Technologies or an authorized * third party. * * * *  * mips_end_of_legal_notice *  * ************************************************************************//************************************************************************ *      Include files ************************************************************************/#include <sysdefs.h>#include <syserror.h>#include <sysdev.h>#include <io_api.h>#include <syscon_api.h>#include <sys_api.h>#include <serial_api.h>#include <serial_ti16550_api.h>#include <excep_api.h>#include <string.h>/************************************************************************ *  Definitions*************************************************************************/#define SET_ADDR( offset ) \	sys_reg_addr( bigend, spacing, ti16550base, offset )/* Register access *//* #define PHY_RBR_W(minor, data)  SETREG(minor, data, rbr) */#define PHY_THR_W(minor, data)  if (size[minor] == sizeof(UINT8))	\				  REG8(phy_thr[minor]) = (data);	\				else *(phy_thr[minor]) = (data);#define PHY_IER_W(minor, data)  if (size[minor] == sizeof(UINT8))	\				  REG8(phy_ier[minor]) = (data);	\				else *(phy_ier[minor]) = (data);#define PHY_FCR_W(minor, data)  if (size[minor] == sizeof(UINT8))	\				  REG8(phy_fcr[minor]) = (data);	\				else *(phy_fcr[minor]) = (data);#define PHY_LCR_W(minor, data)  if (size[minor] == sizeof(UINT8))	\				  REG8(phy_lcr[minor]) = (data);	\				else *(phy_lcr[minor]) = (data);#define PHY_MCR_W(minor, data)  if (size[minor] == sizeof(UINT8))	\				  REG8(phy_mcr[minor]) = (data);	\				else *(phy_mcr[minor]) = (data);#define PHY_DLL_W(minor, data)  if (size[minor] == sizeof(UINT8))	\				  REG8(phy_dll[minor]) = (data);	\				else *(phy_dll[minor]) = (data);#define PHY_DLM_W(minor, data)  if (size[minor] == sizeof(UINT8))	\				  REG8(phy_dlm[minor]) = (data);	\				else *(phy_dlm[minor]) = (data);#define PHY_RBR_R(minor)	( size[minor] == sizeof(UINT8) ? \	                        REG8(phy_rbr[minor]) :		 \	                           *(phy_rbr[minor]) )#define PHY_LSR_R(minor)	( size[minor] == sizeof(UINT8) ? \	                        REG8(phy_lsr[minor]) :		 \	                           *(phy_lsr[minor]) )#define PHY_MSR_R(minor)	( size[minor] == sizeof(UINT8) ? \	                        REG8(phy_msr[minor]) :		 \	                           *(phy_msr[minor]) )/************************************************************************ *      Public variables ************************************************************************//************************************************************************ *      Static variables ************************************************************************//* Is UART Big endian device or not */static bool  bigend;/* Base address of controller */static void  *ti16550base;/* Spacing of register */static UINT8 spacing;/* Size of registers (number of bytes) */static UINT8 size[SERIAL_MAX_16550_DEVICES];static volatile UINT32 *phy_rbr[SERIAL_MAX_16550_DEVICES];  /* '0', RO, receive buffer,       */static volatile UINT32 *phy_thr[SERIAL_MAX_16550_DEVICES];  /* '0', WO, trans. holding,       */static volatile UINT32 *phy_ier[SERIAL_MAX_16550_DEVICES];  /* '1', RW, int. enable,          */static volatile UINT32 *phy_iir[SERIAL_MAX_16550_DEVICES];  /* '2', RO, int. ident,           */static volatile UINT32 *phy_fcr[SERIAL_MAX_16550_DEVICES];  /* '2', WO, FIFO control,         */static volatile UINT32 *phy_lcr[SERIAL_MAX_16550_DEVICES];  /* '3', RW, line control,         */static volatile UINT32 *phy_mcr[SERIAL_MAX_16550_DEVICES];  /* '4', RW, modem control,        */static volatile UINT32 *phy_lsr[SERIAL_MAX_16550_DEVICES];  /* '5', RW, line status,          */static volatile UINT32 *phy_msr[SERIAL_MAX_16550_DEVICES];  /* '6', RW, modem status,         */static volatile UINT32 *phy_scr[SERIAL_MAX_16550_DEVICES];  /* '7', RW, scratch               */static volatile UINT32 *phy_dll[SERIAL_MAX_16550_DEVICES];  /* '0', RW, divisor latch LSB     */static volatile UINT32 *phy_dlm[SERIAL_MAX_16550_DEVICES];  /* '1', RW, divisor latch MSB     *//*  Databit conversion table. *  EEPROM-encoding to device control */static const UINT8 serial_databits[SERIAL_DATABITS_MAX] = {    SERIAL_ILLEGAL,   /* 0, undefined  */    SERIAL_LCR_DATA7, /* 1, 7 databits */    SERIAL_LCR_DATA8  /* 2, 8 databits */};/*  Parity conversion table. *  EEPROM-encoding to device control */static const UINT8 serial_parity[SERIAL_PARITY_MAX] = {    SERIAL_ILLEGAL,        /* 0, undefined  */    SERIAL_LCR_PARITYNONE, /* 1, none       */    SERIAL_LCR_PARITYODD,  /* 2, odd        */    SERIAL_LCR_PARITYEVEN  /* 3, even       */};/*  Stopbits conversion table. *  EEPROM-encoding to device control */static const UINT8 serial_stopbits[SERIAL_STOPBITS_MAX] = {    SERIAL_ILLEGAL,     /* 0, undefined   */    SERIAL_LCR_STOP1,   /* 1, 1 stopbit   */    SERIAL_LCR_STOP15,  /* 2, 1.5 stopbit */    SERIAL_LCR_STOP2    /* 3, 2 stopbit   */};static t_UART_statistics  uart_statistics[SERIAL_MAX_16550_DEVICES];static UINT32		  poll_retcode[SERIAL_MAX_16550_DEVICES];static UINT32		  shadow_ier[SERIAL_MAX_16550_DEVICES];static UINT32		  shadow_mcr[SERIAL_MAX_16550_DEVICES];static UINT32		  shadow_flow[SERIAL_MAX_16550_DEVICES];/*  Receive buffer operation: * *  putptr points to the next free location *  When a byte is polled from the uart, it is stored by putptr, *  which is then cyclic incremented UNLESS it gets equal to getptr. * *  That way, getptr == putptr means buffer empty, and *            the buffer can hold POLLSIZE-1 bytes. */ #define POLLSIZE	0x800   /* Must be power of 2 and at least 128 */#define HW_LIMIT_STOP	(POLLSIZE-64)  /* RTS OFF when 64 chars in buf */#define HW_LIMIT_START	(POLLSIZE-32)  /* RTS  ON when 32 chars in buf */static UINT16 *recv_putptr[SERIAL_MAX_16550_DEVICES];static UINT16 *recv_getptr[SERIAL_MAX_16550_DEVICES];static UINT16 *recv_flushptr[SERIAL_MAX_16550_DEVICES];static UINT16  recv_buffer[SERIAL_MAX_16550_DEVICES][POLLSIZE];static UINT32 minor_numbers[SERIAL_MAX_16550_DEVICES];/* Available baudrates */static t_SERIAL_baudrate_div *serial_baudrate;/*  Boolean indicating whether interrupt handlers are registered or not. *  Initial value is 0 (FALSE) since data is in BSS. */static bool  registered[SERIAL_MAX_16550_DEVICES];/************************************************************************ *      Static function prototypes ************************************************************************/static INT32 SERIAL_TI16550_init(    UINT32 major,          /* IN: major device number             */    UINT32 minor,          /* IN: minor device number             */    UINT32 *port );        /* IN: port mapping			  */static INT32 SERIAL_TI16550_read(    UINT32 major,          /* IN: major device number             */    UINT32 minor,          /* IN: minor device number             */    UINT8  *p_param );     /* OUT: character been read            */static UINT32 SERIAL_TI16550_irqpoll(     UINT32 minor );static UINT32 SERIAL_TI16550_irq(     UINT32 minor,    UINT32 in_intrpt );static INT32 SERIAL_TI16550_write(    UINT32 major,          /* IN: major device number             */    UINT32 minor,          /* IN: minor device number             */    UINT8  *p_param );     /* IN: character to write              */static INT32 SERIAL_TI16550_ctrl(    UINT32 major,          /* IN: major device number             */    UINT32 minor,          /* IN: minor device number             */    t_SERIAL_ctrl_descriptor *p_param );/* INOUT: IOCTL structure */static voidserial_int_handler(    void *data );	/* Holds the minor device number		*//************************************************************************ *      Implementation : Public functions ************************************************************************//************************************************************************ * *                          SERIAL_TI16550_install *  Description : *  ------------- * *  Installs the serial TI16550 serial device drivers services in  *  the IO system at the reserved device slot, found in the *  'sysdev.h' file, which defines all major device numbers. * *  Note: *  This service is the only public declared interface function; all *  provided device driver services are static declared, but this *  function installs the function pointers in the io-system to *  enable the provided public driver services. * *  Parameters : *  ------------ * *  None * *  Return values : *  --------------- * *  'OK'(=0) *  'ERROR_IO_ILLEGAL_MAJOR':  Illegal major device number *  'ERROR_IO_NO_SPACE':       Device slot already allocated * ************************************************************************/INT32 SERIAL_TI16550_install( void ){        UINT32 i;    UINT32 tty;    UINT32 major, minor;    /* Initialise variables */    for( i=0; i<SERIAL_MAX_16550_DEVICES; i++ )    {        minor_numbers[i] = i;        shadow_mcr[i] = SERIAL_MCR_DTR | SERIAL_MCR_OUT2;    }    /* pre-initialize local variables and install device services */    IO_install( SYS_MAJOR_SERIAL_TI16550,         /* major device number */         (t_io_service) SERIAL_TI16550_init,      /* 'init'  service     */                        NULL,                     /* 'open'  service  na */                        NULL,                     /* 'close' service  na */         (t_io_service) SERIAL_TI16550_read,      /* 'read'  service     */         (t_io_service) SERIAL_TI16550_write,     /* 'write' service     */         (t_io_service) SERIAL_TI16550_ctrl );    /* 'ctrl' service      */    /* call our own 'init' service */    /* TTY0 */    tty = PORT_TTY0;    SYSCON_read( SYSCON_COM_TTY0_MAJOR, (void *)(&major), sizeof(UINT32) );        if (major == SYS_MAJOR_SERIAL_TI16550)    {        SYSCON_read(SYSCON_COM_TTY0_MINOR, (void *)(&minor), sizeof(UINT32));	IO_init( SYS_MAJOR_SERIAL_TI16550, minor, &tty );

⌨️ 快捷键说明

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