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

📄 p3544sio.c

📁 vxworks practise_3544.rar 的驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
/* p3544Sio.c - p3544 serial driver *//* Copyright 1984-2000 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01k,05dec00,dat  merge from sustaining branch to tor2_0_x01j,20nov00,pai  enabled receiver buffer full interrupt from UART in                 p3544Startup() (SPR 32443).01i,06oct99,pai  account for PC87307 hardware anomaly in p3544Int() (SPR 26117).01h,26oct98,dbt  call p3544InitChannel() in p3544HrdInit() rather than in                 p3544ModeSet(). (SPR #22349).01g,23may97,db   added hardware options and modem control(SPR #7542).                 fixed bugs reported in SPRs 9404, 9223.01f,12oct95,dgf  added bauds > 38k01e,03aug95,myz  fixed the warning messages01d,12jul95,myz  fixed the baud rate problem.01c,20jun95,ms   fixed comments for mangen.01b,15jun95,ms   updated for new driver structure01a,15mar95,myz  written (using p3544Serial.c + the VxMon polled driver).*//*DESCRIPTIONThis is the driver for the cPCI 3544 UART Chip used on the PC 386.It uses the SCCs in asynchronous mode only.USAGEAn p3544_CHAN structure is used to describe the chip.The BSP's sysHwInit() routine typically calls sysSerialHwInit()which initializes all the register values in the p3544_CHAN structure(except the SIO_DRV_FUNCS) before calling p3544HrdInit().The BSP's sysHwInit2() routine typically calls sysSerialHwInit2() whichconnects the chips interrupt handler (p3544Int) via intConnect().IOCTL FUNCTIONSThis driver responds to all the same ioctl() codes as a normal serial driver;for more information, see the comments in sioLib.h.  As initialized, theavailable baud rates are 110, 300, 600, 1200, 2400, 4800, 9600, 19200, and38400.This driver handles setting of hardware options such as parity(odd, even) andnumber of data bits(5, 6, 7, 8). Hardware flow control is provided with thehandshakes RTS/CTS. The function HUPCL(hang up on last close) is available.INCLUDE FILES: drv/sio/p3544Sio.h*/#include "vxWorks.h"#include "iv.h"#include "intLib.h"#include "errnoLib.h"#include "p3544Sio.h"#include "logLib.h"#include <ioLib.h>#include <stdio.h>#include <string.h>#include <vxWorks.h>#include <taskLib.h>/* defines *//* This value is used to specify the maximum number of times p3544Int() * routine will read the 3544 Interrupt Identification Register before * returning.  This value should optimally be derived from the BRDR. */LOCAL char *Hwa_PCI3544_Rec_Data_Buffer_char[8*4];LOCAL void Hwa_CPCI_3544_Rec_Task_Func(UINT8 Inser_Para_Fd );LOCAL int Hwa_Cpci_3544_Task_Id[4];#define ASTD_COM_FLAGS (ASYNC_BOOT_AUTOCONF |ASYNC_AUTO_IRQ )#define p3544_IIR_READ_MAX          40#ifndef p3544_DEFAULT_BAUD#   define  p3544_DEFAULT_BAUD     9600#endif#ifndef SIO_HUP#   define SIO_OPEN     0x100A#   define SIO_HUP      0x100B#endif/* locals *//* baudTable is a table of the available baud rates, and the values to write * to the UART's baud rate divisor {high, low} register. the formula is * 1843200(source) / (16 * baudrate) */static p3544_BAUD p3544baudTable [] =    {    {50, 2304}, {75, 1536}, {110, 1047}, {134, 857}, {150, 768},    {300, 384}, {600, 192}, {1200, 96}, {2000, 58}, {2400, 48},    {3600,32}, {4800, 24}, {7200,16}, {9600, 12}, {19200, 6}, {38400, 3},    {57600, 2}, {115200, 1}    };static SIO_DRV_FUNCS p3544SioDrvFuncs;static struct serial_uart_config p3544_uart_config[] = {	{ "unknown", 1, 0 },	{ "8250", 1, 0 },	{ "16450", 1, 0 },	{ "16550", 1, 0 },	{ "16550A", 16, UART_CLEAR_FIFO | UART_USE_FIFO },	{ "cirrus", 1, 0 },	{ "ST16650", 1, UART_CLEAR_FIFO | UART_STARTECH },	{ "ST16650V2", 32, UART_CLEAR_FIFO | UART_USE_FIFO |			UART_STARTECH },	{ "TI16750", 64, UART_CLEAR_FIFO | UART_USE_FIFO},	{ 0, 0}};/* forward declarations */LOCAL   void    p3544InitChannel (p3544_CHAN *);LOCAL   int     p3544Ioctl(p3544_CHAN *, int, int);LOCAL   int     p3544Startup(p3544_CHAN *pChan);LOCAL   int     p3544PRxChar (p3544_CHAN *pChan, char *ch);LOCAL   int     p3544PTxChar(p3544_CHAN *pChan, char ch);LOCAL   STATUS  p3544OptsSet (p3544_CHAN *, UINT);LOCAL   STATUS  p3544ModeSet (p3544_CHAN *, UINT);LOCAL   STATUS  p3544BaudSet (p3544_CHAN *, UINT);LOCAL   void    p3544_check_modem_status(p3544_CHAN * pChan);LOCAL   void    p3544_autoconfig( p3544_CHAN *  pChan);/*************Add Dengtao 2005-09-27*****************/LOCAL    BOOL   Hwa_Cpci_3544_Inst=FALSE;/******************************************************************************** p3544CallbackInstall  (  ) - install ISR callbacks to get put chars.** This routine installs the callback functions for the driver** RETURNS: OK on success or ENOSYS on unsupported callback type.*/ static int p3544CallbackInstall    (    SIO_CHAN *  pSioChan,    int         callbackType,    STATUS      (*callback)(),    void *      callbackArg    )    {    p3544_CHAN * pChan = (p3544_CHAN *)pSioChan;    switch (callbackType)        {        case SIO_CALLBACK_GET_TX_CHAR:            pChan->getTxChar    = callback;            pChan->getTxArg     = callbackArg;            return (OK);        case SIO_CALLBACK_PUT_RCV_CHAR:            pChan->putRcvChar   = callback;            pChan->putRcvArg    = callbackArg;            return (OK);        default:            return (ENOSYS);        }    }/******************************************************************************** p3544HrdInit () - initialize the chip** This routine is called to reset the chip in a quiescent state.* RETURNS: N/A*/void p3544HrdInit    (    p3544_CHAN *  pChan         /* pointer to device */    )    {    if (p3544SioDrvFuncs.ioctl == NULL)        {        p3544SioDrvFuncs.ioctl          = (int (*)())p3544Ioctl;        p3544SioDrvFuncs.txStartup      = (int (*)())p3544Startup;       // p3544SioDrvFuncs.callbackInstall = (int (*)())p3544CallbackInstall;	p3544SioDrvFuncs.callbackInstall = p3544CallbackInstall;        p3544SioDrvFuncs.pollInput      = (int (*)())p3544PRxChar;        p3544SioDrvFuncs.pollOutput     = (int (*)(SIO_CHAN *,char))p3544PTxChar;        }    pChan->pDrvFuncs = &p3544SioDrvFuncs; 	p3544_autoconfig(pChan);    /*detect port type */    p3544InitChannel(pChan);    /* reset the channel *///printf("sucongna p3544initchannel\t");       }/********************************************************************************* p3544InitChannel ()  - initialize a single channel*/static void p3544InitChannel    (    p3544_CHAN *  pChan         /* pointer to device */    )    {    int intLevel;        pChan->options = (CS8 | CREAD | CLOCAL);	intLevel = intLock ();	if (p3544_uart_config[pChan->port_type].flags & UART_STARTECH) 	{		/* Wake up UART */		PCI_OUT_BYTE(pChan->lcr, 0xBF);		PCI_OUT_BYTE(pChan->efr, UART_EFR_ECB);		PCI_OUT_BYTE(pChan->ier, 0);		PCI_OUT_BYTE(pChan->efr, 0);		PCI_OUT_BYTE(pChan->lcr, 0);	}	if (pChan->port_type == PORT_16750)	{		/* Wake up UART */		PCI_OUT_BYTE(pChan->ier, 0);	}	/*	 * Clear the FIFO buffers and disable them	 * (they will be reenabled in p220_change_speed())	 */	if (p3544_uart_config[pChan->port_type].flags & UART_CLEAR_FIFO)	{		PCI_OUT_BYTE(pChan->fcr, ((UART_FCR_CLEAR_RCVR |	UART_FCR_CLEAR_XMIT)));////su	}	 /* set channel baud rate */    p3544OptsSet(pChan, pChan->options  );//su    (void) p3544BaudSet(pChan, p3544_DEFAULT_BAUD);	/*	 * At this point there's no way the LSR could still be 0xFF;	 * if it is, then bail out, because there's likely no UART	 * here.	 */	if (PCI_IN_BYTE(pChan->lsr) == 0xff) 	{		intUnlock (intLevel);		return ;	}	/*	 * Clear the interrupt registers.	 */	(void) PCI_IN_BYTE(pChan->data);	(void) PCI_IN_BYTE(pChan->iir);	(void) PCI_IN_BYTE(pChan->msr);	/*	 * Now, initialize the UART	 */	PCI_OUT_BYTE(pChan->lcr, UART_LCR_WLEN8);	/* reset DLAB *///su	PCI_OUT_BYTE(pChan->mcr, UART_MCR_OUT2);	//su	/*	 * Finally, enable interrupts	 */	PCI_OUT_BYTE(pChan->ier, UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI);	/* enable interrupts *///su	/*	 * And clear the interrupt registers again for luck.	 */	(void)PCI_IN_BYTE(pChan->lsr);	(void)PCI_IN_BYTE(pChan->data);	(void)PCI_IN_BYTE(pChan->iir);	(void)PCI_IN_BYTE(pChan->msr);	intUnlock (intLevel);           return ;    }/********************************************************************************* p3544Hu () - hang up the modem control lines ** Resets the RTS and DTR signals.** RETURNS: OK*/LOCAL STATUS p3544Hup    (    p3544_CHAN * pChan          /* pointer to channel */    )    {    FAST int     oldlevel;      /* current interrupt level mask */    oldlevel = intLock ();    PCI_OUT_BYTE (pChan->mcr, UART_MCR_OUT2);    intUnlock (oldlevel);    return (OK);    }    /********************************************************************************* p3544Open () - Set the modem control lines ** Set the modem control lines(RTS, DTR) TRUE if not already set.  * It also clears the receiver. ** RETURNS: OK*/LOCAL STATUS p3544Open    (    p3544_CHAN * pChan          /* pointer to channel */    )    {    FAST int     oldlevel;      /* current interrupt level mask */    char mask;    /* read modem control register */           mask = (PCI_IN_BYTE (pChan->mcr)) & (UART_MCR_RTS | UART_MCR_DTR);    if (mask != (UART_MCR_RTS | UART_MCR_DTR))         {        /* RTS and DTR not set yet */        oldlevel = intLock ();        /* set RTS and DTR TRUE */        PCI_OUT_BYTE (pChan->mcr, (UART_MCR_RTS | UART_MCR_DTR | \                                        UART_MCR_OUT2));        intUnlock (oldlevel);        }    return (OK);    }/******************************************************************************** p3544BaudSet () - change baud rate for channel** This routine sets the baud rate for the UART. The interrupts are disabled* during chip access.** RETURNS: OK to indicate success, otherwise ERROR is returned*/LOCAL STATUS  p3544BaudSet    (    p3544_CHAN *   pChan,       /* pointer to channel */    UINT           baud         /* requested baud rate */    )    {    int         oldlevel;    STATUS      status;    FAST        int     ix;    UINT8       lcr,fcr = 0;     /* disable interrupts during chip access */       oldlevel = intLock ();	    status = ERROR;    for (ix = 0; ix < NELEMENTS (p3544baudTable); ix++)        {        if (p3544baudTable [ix].rate == baud)        /* lookup baud rate value */            {            lcr = PCI_IN_BYTE (pChan->lcr);               /*PCI_OUT_BYTE (pChan->lcr, (char)(UART_LCR_DLAB | lcr));            PCI_OUT_BYTE (pChan->dlm, ((p3544baudTable[ix].preset)>> 8));            PCI_OUT_BYTE (pChan->dll, (p3544baudTable[ix].preset)&0xff);            PCI_OUT_BYTE (pChan->lcr, lcr);*/            status = OK;            break;            }        }       /* Set up FIFO's */	if (p3544_uart_config[pChan->port_type].flags & UART_USE_FIFO) {		if (p3544baudTable[ix].rate < 2400)			fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;		else			fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_8;	}    intUnlock(oldlevel);    return (status);    }/********************************************************************************* p3544ModeSet () - change channel mode setting** This driver supports both polled and interrupt modes and is capable of* switching between modes dynamically. ** If interrupt mode is desired this routine enables the channels receiver and * transmitter interrupts. If the modem control option is TRUE, the Tx interrupt* is disabled if the CTS signal is FALSE. It is enabled otherwise. *

⌨️ 快捷键说明

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