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

📄 tto.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"inttto(TTYDEV *ttydev, int action, int arg1) {	TTYBUF 			*bup = &ttydev->obuf;	DEV_8250		*dev = (DEV_8250 *)ttydev;	const uintptr_t	*port = dev->port;	int 			status = 0;	unsigned char 	c;	switch(action) {	case TTO_STTY:		ser_stty(dev);		return(0);	case TTO_CTRL:		if(arg1 & _SERCTL_BRK_CHG)			set_port(port[REG_LC], LCR_BREAK, arg1 &_SERCTL_BRK ? LCR_BREAK : 0);		if(arg1 & _SERCTL_DTR_CHG)			set_port(port[REG_MC], MCR_DTR, arg1 & _SERCTL_DTR ? MCR_DTR : 0);		if(arg1 & _SERCTL_RTS_CHG)			set_port(port[REG_MC], MCR_RTS, arg1 & _SERCTL_RTS ? MCR_RTS : 0);		return(0);	case TTO_LINESTATUS:		return(((read_8250(port[REG_MS]) << 8) | read_8250(port[REG_MC])) & 0xf003);	case TTO_DATA:		break;	default:		return(0);	}   /*    * If the OSW_PAGED_OVERRIDE flag is set then allow    * transmit of character even if output is suspended via    * the OSW_PAGED flag. This flag implies that the next    * character in the obuf is a software flow control    * charater (STOP/START).    * Note: tx_inject sets it up so that the contol    *       character is at the start (tail) of the buffer.    *   */   if(dev->tty.flags & (OHW_PAGED|OSW_PAGED) && !(dev->tty.xflags & OSW_PAGED_OVERRIDE))		return(0);	dev_lock(&dev->tty);	if(bup->cnt > 0) {		if( (read_8250(port[REG_LS]) & LSR_TXRDY) || ( dev->tx_fifo > 0 && arg1 == FIFO_XMIT_OVERRIDE) ) {			// Get the next character to print from the output buffer			c = *bup->tail;			if(c == '\n'  &&  ((dev->tty.c_oflag & (OPOST | ONLCR)) == (OPOST | ONLCR)) && 					((dev->tty.flags & NL_INSERT) == 0)) {				c = '\r';				atomic_set(&dev->tty.flags, NL_INSERT);			} else {				atomic_clr(&dev->tty.flags, NL_INSERT);				if(++bup->tail >= &bup->buff[bup->size])					bup->tail = &bup->buff[0];				--bup->cnt;			}				// Print the character			dev->tty.un.s.tx_tmr = 3;  /* Timeout */			write_8250(port[REG_TX], c);         /* Clear the OSW_PAGED_OVERRIDE flag as we only want          * one character to be transmitted in this case.          */         if (dev->tty.xflags & OSW_PAGED_OVERRIDE)            atomic_clr(&dev->tty.xflags, OSW_PAGED_OVERRIDE);		}		dev_unlock(&dev->tty);	} else {		dev_unlock(&dev->tty);		// Check for notify conditions		if(dev->tty.notify[1].cnt < bup->size - bup->cnt) {			dev->tty.notify[1].cnt = (~0u) >> 1;	// Disarm			atomic_set(&dev->tty.flags, EVENT_NOTIFY_OUTPUT);			status = 1;		}		// Is anyone waiting for the output buffer to drain?		if(dev->tty.waiting_drain && bup->cnt == 0) {			atomic_set(&dev->tty.flags, EVENT_DRAIN);			status = 1;		}	}	// If anyone is waiting to write, kick them when buffer drains to 1/4 full.	if(dev->tty.waiting_write && bup->cnt < bup->size/4) {		atomic_set(&dev->tty.flags, EVENT_WRITE);		return(1);	}	return(status);}voidser_stty(DEV_8250 *dev) {	unsigned 		lcr = 0;	const uintptr_t *port = dev->port;	unsigned		value;	// Set Baud rate	value = (dev->tty.baud == 0) ? 0 : (dev->clk/(dev->tty.baud * dev->div));	dev_lock(&dev->tty);	set_port(port[REG_LC], LCR_DLAB, LCR_DLAB);	set_port(port[REG_DL0], 0xff, value & 0xff);	set_port(port[REG_DL1], 0xff, value >> 8);	set_port(port[REG_LC], LCR_DLAB, 0);	dev_unlock(&dev->tty);	// Set data bits	switch(dev->tty.c_cflag & CSIZE) {	case CS8: ++lcr;	case CS7: ++lcr;	case CS6: ++lcr;	}	// Set stop bits	if(dev->tty.c_cflag & CSTOPB)		lcr |= LCR_STB2;	// Set parity bits	if(dev->tty.c_cflag & PARENB)		lcr |= LCR_PEN;	if((dev->tty.c_cflag & PARODD) == 0)		lcr |= LCR_EPS;	set_port(port[REG_LC], 0xFF, lcr);	// turn on DTR, RTS	set_port(port[REG_MC], MCR_DTR|MCR_RTS, MCR_DTR|MCR_RTS);	// Extract the rx and tx fifo sizes	dev->rx_fifo = dev->tty.fifo & 0xf;	dev->tx_fifo = (dev->tty.fifo >> 4) & 0xf;	// Set RX fifo trigger level	switch(dev->rx_fifo) {	case 1:  value = 0x01; break;	case 4:  value = 0x41; break;	case 8:  value = 0x81; break;	case 14: value = 0xC1; break;	default: value = 0x00; break;	}	// If only the TX fifo is set, enable the fifo and set RX trigger = 1 	if(dev->tx_fifo && !value) {		value = 0x01;	}	if(value) {		//		// Try to enable 1/4/8/14-deep FIFO mode if a 16550		// NOTE: That this is NOT always desirable since it significantly		//       affects received character timing, and does NOT		//       significantly increase receive performance.		//       (Keep in mind that the 16550 with FIFO disabled		//       is still very useful, since it SHOULD buffer		//       up to 16 received characters even when FIFO is off)		//		write_8250(port[REG_FC], value);		if((read_8250(port[REG_II]) & II_FIFO) == 0) {		  // No FIFO, not an 16550 so reset FIFO		  write_8250(port[REG_FC], 0x00);		}	}	else {		write_8250(port[REG_FC], 0x00);	//If no threshold specified, reset the fifo		}}#if 0voidser_ctrl(DEV_8250 *dev, unsigned flags) {	if(flags & _SERCTL_BRK_CHG)		set_port(dev->port[REG_LC], LCR_BREAK, flags &_SERCTL_BRK ? LCR_BREAK : 0);	if(flags & _SERCTL_DTR_CHG)		set_port(dev->port[REG_MC], MCR_DTR, flags & _SERCTL_DTR ? MCR_DTR : 0);	if(flags & _SERCTL_RTS_CHG)		set_port(dev->port[REG_MC], MCR_RTS, flags & _SERCTL_RTS ? MCR_RTS : 0);}#endifint drain_check(TTYDEV *ttydev, uintptr_t *count) {	TTYBUF 			*bup = &ttydev->obuf;	DEV_8250		*dev = (DEV_8250 *)ttydev;	const uintptr_t	*port = dev->port;	// if the device has DRAINED, return 1	if (dev->tty.waiting_drain && (bup->cnt == 0) &&		(read_8250(port[REG_LS]) & LSR_TSRE)) return 1;	// if the device has not DRAINED, set a timer based on 50ms counts	// wait for the time it takes for one character to be transmitted	// out the shift register.  We do this dynamically since the	// baud rate can change.			*count = ((IO_CHAR_DEFAULT_BITSIZE * 20) / ttydev->baud) + 1;		return 0;}

⌨️ 快捷键说明

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