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

📄 intr.c

📁 qnx powerpc MPC8245的 BSP源文件
💻 C
字号:
/* * $QNXLicenseC:  * Copyright 2007, QNX Software Systems.   *   * Licensed under the Apache License, Version 2.0 (the "License"). You   * may not reproduce, modify or distribute this software except in   * compliance with the License. You may obtain a copy of the License   * at: http://www.apache.org/licenses/LICENSE-2.0   *   * Unless required by applicable law or agreed to in writing, software   * distributed under the License is distributed on an "AS IS" basis,   * WITHOUT WARRANTIES OF ANY KIND, either express or implied.  *  * This file may contain contributions from others, either as   * contributors under the License or as licensors under other terms.    * Please review this entire file for other proprietary rights or license   * notices, as well as the QNX Development Suite License Guide at   * http://licensing.qnx.com/license-guide/ for other information.  * $  */#include "externs.h"/* * Process data in a line status register */static intprocess_lsr(DEV_8250 *dev, unsigned char lsr) {	unsigned key = 0, eventflag = 0;	// Return immediately if no errors.	if((lsr & (LSR_BI|LSR_OE|LSR_FE|LSR_PE)) == 0) {		/* No break, can re-enable the LSR interrupt. */  		write_8250(dev->port[REG_IE], 0x0f); 		return(0);	}		// Save the error as out-of-band data which can be retrieved via devctl().	dev->tty.oband_data |= (lsr >> 1) & 0x0f;	atomic_set(&dev->tty.flags, OBAND_DATA);// Uncomment for post 1.0 since there was no time to test sufficiently//	if(dev->tty.notify[2].cnt) {//		dev->tty.notify[2].cnt = 0;	// Disarm//		dev->tty.notify[2].event.sigev_value.sival_int |= _NOTIFY_COND_OBAND;//		atomic_set(&dev->tty.flags, EVENT_NOTIFY_OBAND);//		eventflag = 1;//		}	// Read whatever input data happens to be in the buffer to "eat" the	// spurious data associated with break, parity error, etc.	key = read_8250(dev->port[REG_RX]);	if(lsr & LSR_BI) {		key |= TTI_BREAK;		/* On the MPC8540 chip, when a break occurs, the lsr interrupt stays 		asserted until a character is input.  We therefore need to disable the 		lsr interrupt to prevent an interrupt overflow condition. */ 		write_8250(dev->port[REG_IE], 0x0b); 	} else {		/* No break, can re-enable the LSR interrupt. */ 		write_8250(dev->port[REG_IE], 0x0f); 		if(lsr & LSR_OE)			key |= TTI_OVERRUN;		else if(lsr & LSR_FE)			key |= TTI_FRAME;		else if(lsr & LSR_PE)			key |= TTI_PARITY;	}	return(tti(&dev->tty, key) | eventflag);}/* * Serial interrupt handler */const struct sigevent *ser_intr(void *area, int id) {	struct dev_list	*list = area;	int				status = 0;	int				something_happened;	unsigned char	msr, lsr;	DEV_8250		*dev;	struct sigevent *event = NULL;	unsigned char   fifo_counter;	do {		something_happened = 0;		for(dev = list->device; dev != NULL; dev = dev->next) {			unsigned	iir;			uintptr_t	*port = dev->port;			status = 0;			iir = read_8250(port[REG_II]) & 0x07;			switch(iir) {			case II_RX:		// Receive data				do {					status |= tti(&dev->tty, read_8250(port[REG_RX]));					lsr = read_8250(port[REG_LS]);					status |= process_lsr(dev, lsr);				} while(lsr & LSR_RXRDY);				break;			case II_TX:		// Transmit buffer empty				fifo_counter = 0;				do {					dev->tty.un.s.tx_tmr = 0;					// The override causes tto to ignore the check on tx buffer empty 					// since we know that the entire fifo is empty when the interrupt fires					//status |= tto(&dev->tty, TTO_DATA, dev->fifo_override);					status |= tto(&dev->tty, TTO_DATA, FIFO_XMIT_OVERRIDE);				} while( (++fifo_counter < dev->tx_fifo) && (dev->tty.obuf.cnt > 0) );				break;			case II_MS:		// Modem change				msr = read_8250(port[REG_MS]);				if(msr & MSR_DDCD)					status |= tti(&dev->tty, (msr & MSR_DCD) ? TTI_CARRIER : TTI_HANGUP);									if((msr & MSR_DCTS)  &&  (dev->tty.c_cflag & OHFLOW))					status |= tti(&dev->tty, (msr & MSR_CTS) ? TTI_OHW_CONT : TTI_OHW_STOP);				break;			case II_LS:		// Line status change				lsr = read_8250(port[REG_LS]);				status |= process_lsr(dev, lsr);				break;			default:				continue;				}			something_happened = 1;			if(status) {				if((dev->tty.flags & EVENT_QUEUED) == 0) {					event = &ttyctrl.event;					dev_lock(&ttyctrl);					ttyctrl.event_queue[ttyctrl.num_events++] = &dev->tty;					atomic_set(&dev->tty.flags, EVENT_QUEUED);					dev_unlock(&ttyctrl);					}				}			}		} while(something_happened);	return(event);	}

⌨️ 快捷键说明

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