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

📄 p3544sio.c

📁 vxworks practise_3544.rar 的驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
* If polled mode is desired the device interrupts are disabled. ** RETURNS:* Returns a status of OK if the mode was set else ERROR.*/LOCAL STATUS p3544ModeSet    (    p3544_CHAN * pChan,         /* pointer to channel */    UINT        newMode         /* mode requested */    )       {    FAST int     oldlevel;      /* current interrupt level mask */    char ier, mask;    if ((newMode != SIO_MODE_POLL) && (newMode != SIO_MODE_INT))        return (ERROR);    oldlevel = intLock();               if (newMode == SIO_MODE_POLL)        ier = 0x00;    else      {		if (pChan->options & CLOCAL) 		{	    	            ier = UART_IER_RDI;		}    	else          {	               mask = (PCI_IN_BYTE (pChan->msr)) & UART_MSR_CTS;            /* if the CTS is asserted enable Tx interrupt */            if (mask & UART_MSR_CTS)	    	{				                ier = (UART_IER_THRI | UART_IER_MSI);	    	}            else	    	{        		                ier = (UART_IER_MSI); 	    	}       	    }       }    PCI_OUT_BYTE (pChan->ier, ier);	    pChan->channelMode = newMode;                intUnlock(oldlevel);    return (OK);    }/********************************************************************************* p3544OptsSet ()- set the serial options** Set the channel operating mode to that specified.  All sioLib options* are supported: CLOCAL, HUPCL, CREAD, CSIZE, PARENB, and PARODD.** RETURNS:* Returns OK to indicate success, otherwise ERROR is returned*/LOCAL STATUS p3544OptsSet    (    p3544_CHAN * pChan,         /* pointer to channel */    UINT options                /* new hardware options */    )    {    FAST int     oldlevel;              /* current interrupt level mask */    char lcr = 0;     char mcr = UART_MCR_OUT2;    char ier;    char mask;    ier = PCI_IN_BYTE (pChan->ier);    if (pChan == NULL || options & 0xffffff00)        return ERROR;    switch (options & CSIZE)        {        case CS5:            lcr = UART_LCR_WLEN5; break;        case CS6:            lcr = UART_LCR_WLEN6; break;        case CS7:            lcr = UART_LCR_WLEN7; break;        default:        case CS8:            lcr = UART_LCR_WLEN8; break;        }    if (options & STOPB)        lcr |= UART_LCR_STOP;    else        lcr |= 0;        switch (options & (PARENB | PARODD))        {        case PARENB|PARODD:            lcr |= UART_LCR_PARITY; break;        case PARENB:            lcr |= (UART_LCR_PARITY | UART_LCR_EPAR); break;        default:        case 0:            lcr |= 0; break;        }    PCI_OUT_BYTE (pChan->ier, 0x00);    if (!(options & CLOCAL))        {        /* !clocal enables hardware flow control(DTR/DSR) */        mcr |= (UART_MCR_DTR | UART_MCR_RTS);        ier |= UART_IER_MSI;    /* enable modem status interrupt */        mask = (PCI_IN_BYTE (pChan->msr)) & UART_MSR_CTS;        /* if the CTS is asserted enable Tx interrupt */        if (mask & UART_MSR_CTS)                ier |= UART_IER_THRI;        else                ier &= (~UART_IER_THRI);         }    else         ier &= ~UART_IER_MSI; /* disable modem status interrupt */     oldlevel = intLock ();    PCI_OUT_BYTE (pChan->lcr, lcr| UART_LCR_DLAB);    PCI_OUT_BYTE (pChan->mcr, mcr);    /* now clear the port */    PCI_IN_BYTE (pChan->data);    if (options & CREAD)          ier |= UART_IER_RDI;    if (pChan->channelMode == SIO_MODE_INT)        {        PCI_OUT_BYTE (pChan->ier, ier);        }    intUnlock (oldlevel);    pChan->options = options;    return OK;    }/********************************************************************************* p3544Ioctl ( ) - special device control** Includes commands to get/set baud rate, mode(INT, POLL), hardware options(* parity, number of data bits), and modem control(RTS/CTS and DTR/DSR).* The ioctl commands SIO_HUP and SIO_OPEN are implemented to provide the * HUPCL( hang up on last close) function.** RETURNS: OK on success, EIO on device error, ENOSYS on unsupported*          request.*/static int p3544Ioctl    (    p3544_CHAN *  pChan,        /* device to control */    int request,                /* request code */    int arg                     /* some argument */    )    {    int ix;    int baudH;    int baudL;    int oldlevel;    UINT8 lcr;    int status = OK;    switch (request)        {        case SIO_BAUD_SET:            status = (p3544BaudSet(pChan, arg) == OK) ? OK : EIO;            break;        case SIO_BAUD_GET:                        oldlevel = intLock();            status = EIO;            lcr = PCI_IN_BYTE (pChan->lcr);            PCI_OUT_BYTE (pChan->lcr, (char)(UART_LCR_DLAB | lcr));            baudH = PCI_IN_BYTE(pChan->dlm);            baudL = PCI_IN_BYTE(pChan->dll);            PCI_OUT_BYTE (pChan->lcr, lcr);            for (ix = 0; ix < NELEMENTS (p3544baudTable); ix++)                {                if ( baudH  == MSB (p3544baudTable[ix].preset) &&                     baudL  == LSB (p3544baudTable[ix].preset) )                    {                    *(int *)arg = p3544baudTable[ix].rate;                    status = OK;                    }                }            intUnlock(oldlevel);            break;        case SIO_MODE_SET:            status = (p3544ModeSet (pChan, arg) == OK) ? OK : EIO;            break;        case SIO_MODE_GET:            *(int *)arg = pChan->channelMode;            return (OK);        case SIO_AVAIL_MODES_GET:            *(int *)arg = SIO_MODE_INT | SIO_MODE_POLL;            return (OK);        case SIO_HW_OPTS_SET:            status = (p3544OptsSet (pChan, arg) == OK) ? OK : EIO;            break;        case SIO_HW_OPTS_GET:            *(int *)arg = pChan->options;            break;        case SIO_HUP:            /* check if hupcl option is enabled */            if (pChan->options & HUPCL)                 status = p3544Hup (pChan);            break;                case SIO_OPEN:            /* check if hupcl option is enabled */            if (pChan->options & HUPCL)                 status = p3544Open (pChan);            break;        default:            status = ENOSYS;            break;        }    return (status);    }/********************************************************************************/void st1655xIntRd    (    p3544_CHAN *	pChan	/* ptr to struct describing channel */    )    {    char inchar;    UINT32 status=0;    do {	if (pChan->putRcvChar != NULL)	{		unsigned char temp =  PCI_IN_BYTE (pChan->data);		(*pChan->putRcvChar)(pChan->putRcvArg, temp);	}	else		PCI_IN_BYTE (pChan->data);	status = PCI_IN_BYTE ( pChan->lsr  );    } while (status & 0x01) ;    return;    }/********************************************************************************* p3544Int () - handle a receiver/transmitter interrupt** This routine handles four sources of interrupts from the UART.  If there is* another character to be transmitted, the character is sent.  When a modem* status interrupt occurs, the transmit interrupt is enabled if the CTS signal* is TRUE.** INTERNAL* The UART interrupts are prioritized in the following order by the Interrupt* Identification Register:**     Bit 2    bit 1    bit 0    Priority        Interrupt ID*     -------------------------------------------------------*     0        0        1        none            none*     1        1        0        0               serialization error or BREAK*     1        0        0        1               received data*     0        1        0        2               transmitter buffer empty*     0        0        0        3               RS-232 input** In the table, priority level 0 is the highest priority.  These priorities* are not typically configurable via software.  The interrupt is expressed as* a two-bit integer.  Bit 0, the pending bit, is negative logic - a value 0* means that an interrupt is pending.** When nested interrupts occur, the second interrupt is identified in the* Interrupt Identification Register(IIR) as soon as the first interrupt is* cleared. Therefore, the interrupt service routine must continue to read IIR* until bit-0 is 1.** When the 3544 generates an interrupt, all interrupts with an equal or* lower priority are locked out until the current interrupt has been cleared.* The operation required to clear an interrupt varies according to the source.* The actions typically required to clear an interrupt are as follows:**    Source of interrupt                Response required to reset*    ---------------------------------------------------------------------*    receiver error or BREAK            read serialization status register*    received data                      read data from receiver register*    transmit buffer empty              write to the transmitter or read*                                       the interrupt ID register*    RS-232 input                       read the RS-232 status register** In response to an empty transmit buffer (TBE), the interrupt can be* cleared by writing a byte to the transmitter buffer register.  It can* also be cleared by reading the interrupt identification register.** Failure to clear all interrupts before returning will leave an interrupt* pending and prevent the UART from generating further interrupt requests* to the CPU.** RETURNS: N/A*/void p3544Int    (    p3544_CHAN  *  pChan    )   {    char outChar;       /* store a byte for transmission */    char interruptID;   /* store contents of interrupt ID register */    char lineStatus;    /* store contents of line status register */    char ier;           /* store contents of interrupt enable register */    int  ix = 0;        /* allows us to return just in case IP never clears */    int  i; 	  for (i = 0; i < 4; i++)  {    ier = PCI_IN_BYTE(pChan->ier);    /* service UART interrupts until IP bit set or read counter expires */    FOREVER        { 		interruptID = PCI_IN_BYTE(pChan->iir);        if ((interruptID == UART_IIR_NO_INT) || (++ix > p3544_IIR_READ_MAX))            {            break;  /* interrupt cleared or loop counter expired */             }         /* filter possible anomalous interrupt ID from PC87307VUL (SPR 26117) */        interruptID &= UART_IIR_ID;  /* clear odd-bit to find interrupt ID */        if (interruptID == UART_IIR_RLSI)            {	            	            lineStatus = PCI_IN_BYTE (pChan->lsr);            }        else if (interruptID == UART_IIR_RDI)            {    	    st1655xIntRd (pChan);	/* at least one RxChar available */#if 0                        if (pChan->putRcvChar != NULL)                (*pChan->putRcvChar)(pChan->putRcvArg,                               PCI_IN_BYTE (pChan->data));            else                PCI_IN_BYTE (pChan->data);#endif                        }        else if (interruptID == UART_IIR_THRI)            {            	            if ((pChan->getTxChar != NULL) &&                (*pChan->getTxChar) (pChan->getTxArg, &outChar) == OK               )                {                 PCI_OUT_BYTE(pChan->data, outChar);                }            /* There are no bytes available for transmission.  Reading             * the IIR at the top of this loop will clear the interrupt.             */

⌨️ 快捷键说明

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