📄 serial_saa9730.c
字号:
/************************************************************************ * * SERIAL_SAA9730.c * * The 'SERIAL_SAA9730' module implements the SERIAL-SAA9730 * 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_saa9730_api.h>#include <excep_api.h>#include <string.h>/************************************************************************ * Constants*************************************************************************//* Offset addresses for the SAA9730 EVM (Event monitor) */#define EVM_SAA9730_BASE_OFS 0x2000#define EVM_SAA9730_ISR_OFS (0x00>>2)#define EVM_SAA9730_IER_OFS (0x04>>2)#define EVM_SAA9730_IMR_OFS (0x08>>2)#define EVM_SAA9730_IER_MASTER 0x00000001#define EVM_SAA9730_IER_ALL 0xF7FFFFFF#define EVM_SAA9730_GPIO0 0x00000010 /* ~RI */#define EVM_SAA9730_GPIO1 0x00000020 /* ~DSR */#define EVM_SAA9730_SECISR_OFS (0x1C>>2)#define EVM_SAA9730_SECIER_OFS (0x20>>2)#define EVM_SAA9730_SECIMR_OFS (0x24>>2)#define EVM_SAA9730_SECIER_UART1 0x00000008#define EVM_SAA9730_SECIER_ALL 0xFFFFFFFF#define EVM_SAA9730_IERSW_OFS (0x2C>>2)#define EVM_SAA9730_SECIERSW_OFS (0x30>>2)/* Offset addresses for the SAA9730 UART mapped as 8-bit device on PCI */#define SERIAL_SAA9730_UART_OFS 0x21800 /* UART-device offset */#define SERIAL_SAA9730_RBR_OFS 0x00 /* Receiver Buffer */#define SERIAL_SAA9730_THR_OFS 0x00 /* Transmitter Holding */#define SERIAL_SAA9730_IER_OFS 0x01 /* Interrupt enable */#define SERIAL_SAA9730_IIR_OFS 0x02 /* Interrupt identification */#define SERIAL_SAA9730_FCR_OFS 0x02 /* FIFO control */#define SERIAL_SAA9730_LCR_OFS 0x03 /* Line control */#define SERIAL_SAA9730_MCR_OFS 0x04 /* Modem control */#define SERIAL_SAA9730_LSR_OFS 0x05 /* Line status */#define SERIAL_SAA9730_MSR_OFS 0x06 /* Modem status */#define SERIAL_SAA9730_SCR_OFS 0x07 /* Scratch */#define SERIAL_SAA9730_DLL_OFS 0x00 /* Divisor latch LSB */#define SERIAL_SAA9730_DLM_OFS 0x01 /* Divisor latch MSB */#define SERIAL_SAA9730_CFG_OFS 0x0c /* Configuration register *//* FCR control */#define SERIAL_FCR_ENABLE 0x01 /* enable FIFO's */#define SERIAL_FCR_RCVR_RESET 0x02 /* reset receiver FIFO */#define SERIAL_FCR_TXMT_RESET 0x04 /* reset transmit FIFO */#define SERIAL_FCR_RCVFIFO_1 0x00 /* receive FIFO threshold 1 */#define SERIAL_FCR_RCVFIFO_4 0x40 /* receive FIFO threshold 4 */#define SERIAL_FCR_RCVFIFO_8 0x80 /* receive FIFO threshold 8 */#define SERIAL_FCR_RCVFIFO_14 0xc0 /* receive FIFO threshold 14 *//* IER mask */#define SERIAL_IER_RCVEN 0x01 /* receive interrupt enable *//* LCR control */#define SERIAL_LCR_DATA5 0x00 /* 5-bit character */#define SERIAL_LCR_DATA6 0x01 /* 6-bit character */#define SERIAL_LCR_DATA7 0x02 /* 7-bit character */#define SERIAL_LCR_DATA8 0x03 /* 8-bit character */#define SERIAL_LCR_DATA_MSK 0x03 /* MASK for data field */#define SERIAL_LCR_STOP1 0x00 /* 1 stop bit */#define SERIAL_LCR_STOP15 0x04 /* 1.5 stop bit, if data is 5-bit */#define SERIAL_LCR_STOP2 0x04 /* 2 stop bit */#define SERIAL_LCR_STOP_MSK 0x04 /* MASK for stop bit field */#define SERIAL_LCR_PARITYNONE 0x00 /* No parity */#define SERIAL_LCR_PARITYODD 0x08 /* Odd parity */#define SERIAL_LCR_PARITYEVEN 0x18 /* Even parity */#define SERIAL_LCR_PARITYMARK 0x28 /* Mark parity */#define SERIAL_LCR_PARITYSPACE 0x38 /* Space parity */#define SERIAL_LCR_PARITY_MASK 0x38 /* MASK for parity field */#define SERIAL_LCR_BREAK 0x40 /* request to send a 'break' */#define SERIAL_LCR_DLAB 0x80 /* enable divisor latch registers *//* MCR control */#define SERIAL_MCR_DTR 0x01 /* Data Terminal Ready */#define SERIAL_MCR_RTS 0x02 /* Request To Send */#define SERIAL_MCR_OUT1 0x04 /* General purpose output */#define SERIAL_MCR_OUT2 0x08 /* Interrupt enable */#define SERIAL_MCR_LOOP 0x10 /* Local loop back */#define SERIAL_MCR_AFE 0x20 /* Auto-flow control enable *//* LSR status */#define SERIAL_LSR_DR 0x01 /* Character ready */#define SERIAL_LSR_OE 0x02 /* RX-ERROR: Overrun */#define SERIAL_LSR_PE 0x04 /* RX-ERROR: Parity */#define SERIAL_LSR_FE 0x08 /* RX-ERROR: Framing (stop bit)*/#define SERIAL_LSR_BI 0x10 /* 'BREAK' detected */#define SERIAL_LSR_THRE 0x20 /* Transmit Holding empty */#define SERIAL_LSR_TEMT 0x40 /* Transmitter empty (IDLE) */#define SERIAL_LSR_FIFOERR 0x80 /* RX-ERROR: FIFO *//* MSR status */#define SERIAL_MSR_DCTS 0x01 /* Delta clear to send */#define SERIAL_MSR_DDSR 0x02 /* Delta data set ready */#define SERIAL_MSR_TERI 0x04 /* Trailing edge ring ind. */#define SERIAL_MSR_DDCD 0x08 /* Delta data carrier detect */#define SERIAL_MSR_CTS 0x10 /* Clear to send */#define SERIAL_MSR_DSR 0x20 /* Data Set Ready */#define SERIAL_MSR_RI 0x40 /* Ring Indicator */#define SERIAL_MSR_DCD 0x80 /* Data carrier detect *//* CFR control */#define SERIAL_CFG_BREAK 0x02 /* Sends a break */#define SERIAL_CFG_RTSEN 0x10 /* Enable RTS auto flow control*/#define SERIAL_CFG_CTSEN 0x20 /* Enable CTS auto tx inhibit *//************************************************************************ * Macro Definitions*************************************************************************//************************************************************************ * Type Definitions*************************************************************************//************************************************************************ * Public variables ************************************************************************//************************************************************************ * Static variables ************************************************************************//* All physical register addresses are initialized here to increase speed. The SAA9730 is sitting on the PCI bus with 8-bit device access */static volatile UINT8 *phy_rbr ; /* '0', RO, receive buffer, */static volatile UINT8 *phy_thr ; /* '0', WO, trans. holding, */static volatile UINT8 *phy_ier ; /* '1', RW, int. enable, */static volatile UINT8 *phy_iir ; /* '2', RO, int. ident, */static volatile UINT8 *phy_fcr ; /* '2', WO, FIFO control, */static volatile UINT8 *phy_lcr ; /* '3', RW, line control, */static volatile UINT8 *phy_mcr ; /* '4', RW, modem control, */static volatile UINT8 *phy_lsr ; /* '5', RW, line status, */static volatile UINT8 *phy_msr ; /* '6', RW, modem status, */static volatile UINT8 *phy_scr ; /* '7', RW, scratch */static volatile UINT8 *phy_dll ; /* '0', RW, divisor latch LSB */static volatile UINT8 *phy_dlm ; /* '1', RW, divisor latch MSB */static volatile UINT8 *phy_cfg ; /* 'c', RW, configuration coltrol */static volatile UINT32 *evm_base ; /* Event monitor base address *//* Baudrate conversion table for UART divisor latch. EEPROM-encoding to divisor values at 3.6923 MHz crystal */static const UINT16 serial_baudrate[SERIAL_BAUDRATE_MAX] = { SERIAL_ILLEGAL, /* 0: not defined */ 0x0c04, /* 1: 75 baud */ 0x0831, /* 2: 110 baud */ 0x0601, /* 3: 150 baud */ 0x0300, /* 4: 300 baud */ 0x017f, /* 5: 600 baud */ 191, /* 6: 1.200 baud */ 127, /* 7: 1.800 baud */ 95, /* 8: 2.400 baud */ 47, /* 9: 4.800 baud */ 31, /* 10: 7.200 baud */ 23, /* 11: 9.600 baud */ 15, /* 12: 14.400 baud */ 11, /* 13: 19.200 baud */ 5, /* 14: 38.400 baud */ 3, /* 15: 57.600 baud */ 1, /* 16: 115.200 baud */ 0, /* 17: 230.400 baud */ SERIAL_ILLEGAL, /* 18: 460.800 baud */ SERIAL_ILLEGAL /* 19: 921.600 baud */} ;/* 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 ;static UINT32 poll_retcode ;static UINT32 shadow_ier ;static UINT32 shadow_mcr = (SERIAL_MCR_DTR | SERIAL_MCR_OUT2) ;static UINT32 shadow_flow ;/************************************************************************** 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 ;static UINT16 *recv_getptr ;static UINT16 *recv_flushptr ;static UINT16 recv_buffer[POLLSIZE] ;/* Boolean indicating whether interrupt handler is registered or not */static bool registered = FALSE;/************************************************************************ * Static function prototypes ************************************************************************/static INT32 SERIAL_SAA9730_init( UINT32 major, /* IN: major device number */ UINT32 minor, /* IN: minor device number */ UINT32 *port ); /* IN: port mapping */staticINT32 SERIAL_SAA9730_read( UINT32 major, /* IN: major device number */ UINT32 minor, /* IN: minor device number */ UINT8 *p_param ) ; /* OUT: character been read */staticUINT32 SERIAL_SAA9730_irqpoll( void ) ;staticUINT32 SERIAL_SAA9730_irq( UINT32 in_intrpt ) ;staticINT32 SERIAL_SAA9730_write(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -