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

📄 st16954sio.c

📁 vxworks下串口驱动如何开发 主要针对16c954的非智能串口的初始化和 收发数据
💻 C
📖 第 1 页 / 共 2 页
字号:
	case SIO_MODE_GET:
	    *(int *)arg = pChan->channelMode;
	    break;


	case SIO_AVAIL_MODES_GET:
	    *(int *)arg = SIO_MODE_INT | SIO_MODE_POLL;
	    break;


	case SIO_HW_OPTS_SET:
	case SIO_HW_OPTS_GET:
	default:
	    status = ENOSYS;
	}

    return status;

    }

/*******************************************************************************
*
* st16954IntWr - handle a transmitter interrupt
*
* This routine handles write interrupts from the UART.
*
* RETURNS: N/A
*/

void st16954IntWr
    (
    ST16954_CHAN *	pChan	/* ptr to struct describing channel */
    )
    {
    char outChar;

    if ((*pChan->getTxChar) (pChan->getTxArg, &outChar) != ERROR)
	{
	/* write char. to Transmit Holding Reg. */

	ST16954_REG_WRITE(pChan, THR, outChar);
	}
    else
	{
	pChan->ier |= RxFIFO_BIT;
	pChan->ier &= (~TxFIFO_BIT); /* indicates to disable Tx Int */
	ST16954_REG_WRITE(pChan, IER, pChan->ier);
	}
/*    ST16954_REG_READ(pChan, LSR, outChar);*/
    }

/*****************************************************************************
*
* st16954IntRd - handle a receiver interrupt
*
* This routine handles read interrupts from the UART.
*
* RETURNS: N/A
*/

void st16954IntRd
    (
    ST16954_CHAN *	pChan	/* ptr to struct describing channel */
    )
    {
    char inchar;

    /* read character from Receive Holding Reg. */

    ST16954_REG_READ(pChan, RHR, inchar);

    (*pChan->putRcvChar) (pChan->putRcvArg, inchar);
    }

/**********************************************************************
*
* st16954IntEx - miscellaneous interrupt processing
*
* This routine handles miscellaneous interrupts on the UART.
*
* RETURNS: N/A
*/

void st16954IntEx
    (
    ST16954_CHAN *	pChan	/* ptr to struct describing channel */
    )
    {

    /* Nothing for now... */
    }

/******************************************************************************
*
* st16954Int - interrupt level processing
*
* This routine handles interrupts from the UART.
*
* RETURNS: N/A
*/

void st16954Int
    (
    ST16954_CHAN *	pChan	/* ptr to struct describing channel */
    )
    {
    FAST volatile char        intStatus;
    FAST volatile char        lsr;
    char outChar;	/* Possible char to be output */

    /*
     * If this routine has been called from the multiplexed interrupt
     * handler, then we have already read the Interrupt Status Register,
     * and must not read it again, else this routine has been installled
     * directly using intConnect() and we must now read the Interrupt
     * Status Register (or Interrupt Identification Register).
     */
     if (!multiplexed)
	 {
	 ST16954_REG_READ(pChan, ISR, intStatus);
	 intStatus &= 0x0F;
	}
	
    ST16954_REG_READ(pChan, LSR, lsr);
    
    /*
     * This UART chip always produces level active interrupts, and the ISR
     * only indicates the highest priority interrupt.
     * In the case that receive and transmit interrupts happened at
     * the same time, we must clear both interrupt pending to prevent
     * edge-triggered interrupt(output from interrupt controller) from locking
     * up. One way doing it is to disable all the interrupts at the beginning
     * of the ISR and enable at the end.
     */
    
    ST16954_REG_WRITE(pChan, IER, 0);
    
    switch (intStatus)
	{
	case ISR_RLS:
	    /*
	     * overrun, parity error and break interrupt:
	     *
	     * read LSR to reset interrupt
	     */

	    break;


	case ISR_RDA:
	    /* received data available: FALL THROUGH to timeout */

	case ISR_TIMEOUT:
	    /*
	     * receiver FIFO interrupt. In some cases, ISR_RDA
	     * will not be indicated in ISR register when there
	     * is more than one char. in FIFO.
	     */
	    st16954IntRd (pChan);  /* RxChar Avail */
	    break;


	case ISR_THRE:
	    /* transmitter holding register ready */
	    if ((*pChan->getTxChar) (pChan->getTxArg, &outChar) != ERROR)
		{
		/*  char. to Transmit Holding Reg. */

		ST16954_REG_WRITE(pChan, THR, outChar);
		
		}
	    else
		pChan->ier &= (~TxFIFO_BIT); /* indicates to disable Tx Int */
	    break;


	default:
	    break;
	}
    
    ST16954_REG_WRITE(pChan, IER, pChan->ier);
    
    }

/******************************************************************************
*
* st16954MuxInt - multiplexed interrupt level processing
*
* This routine handles multiplexed interrupts from the DUART. It assumes that
* channels 0 and 1 are connected so that they produce the same interrupt.
*
* RETURNS: N/A
*/

void st16954MuxInt
    (
    ST16954_MUX *	pMux	/* ptr to struct describing multiplexed chans */
    )
    {
    FAST volatile char        intStatus;
    ST16954_CHAN *	pChan;

    /* get pointer to structure for channel to examine first */

    pChan = &(pMux->pChan[pMux->nextChan]);


    /*
     * Step on the next channel to examine: use round-robin for which to
     * examine first.
     */

    if (pMux->nextChan == 0)
	pMux->nextChan = 1;
    else
	pMux->nextChan = 0;


    /*
     * Let the st16954Int() routine know it is called from here, not direct
     * from intConnect().
     */

    multiplexed = TRUE;


    /* check Interrupt Status Register for this channel */

    ST16954_REG_READ(pChan, ISR, intStatus);
    intStatus &= 0x0F;


    if ((intStatus & 0x01) == 0)
	{
	/* Call int handler if int active */

	st16954Int (pChan);
	}
    else
	{
	/* step on again */

	pChan = &pMux->pChan[pMux->nextChan];

	if (pMux->nextChan == 0)
	    pMux->nextChan = 1;
	else
	    pMux->nextChan = 0;


	/* get interrupt status for next channel */

	ST16954_REG_READ(pChan, ISR, intStatus);
	intStatus &= 0x0F;


	/* and call interrupt handler if active */

	if ((intStatus & 0x01) == 0)
	    st16954Int (pChan);
	}

    multiplexed = FALSE;

    return;
    }

/*******************************************************************************
*
* st16954TxStartup - transmitter startup routine
*
* Call interrupt level character output routine and enable interrupt!
*
* RETURNS: OK on success, ENOSYS if the device is polled-only, or
* EIO on hardware error.
*/

LOCAL int st16954TxStartup
    (
    ST16954_CHAN *		pChan  /* ptr to SIO_CHAN describing this channel */
    )
    {
/*    ST16954_CHAN *	pChan = (ST16954_CHAN *)pSioChan;*/

    if (pChan->channelMode == SIO_MODE_INT)
	{
        pChan->ier = IER_ERDAI;

	pChan->ier |= TxFIFO_BIT;

	ST16954_REG_WRITE(pChan, IER, pChan->ier);
	return OK;
	}
    else
	return ENOSYS;
    }

/******************************************************************************
*
* st16954PollOutput - output a character in polled mode.
*
* RETURNS: OK if a character arrived, EIO on device error, EAGAIN
* if the output buffer is full, ENOSYS if the device is interrupt-only.
*/

int st16954PollOutput
    (
    ST16954_CHAN *		pChan, /* ptr to SIO_CHAN describing this channel */
    char		*outChar,	  /* char to be output */
    int  count
    )
    {
    char pollStatus;
    int i;
    unsigned int time_out=0;

    ST16954_REG_WRITE(pChan, SPR, SPR_ACR); /* SPR = 0, PT ACR */

    ST16954_REG_READ(pChan, ACR, pollStatus);/* Get ACR to char inchar */

    ST16954_REG_WRITE(pChan, ACR, pollStatus | ACR_ADDEN | ACR_ICREN);/* Set ACR[7], to enable access to RFL, ect */

    while((++time_out)<10000)
    {
        ST16954_REG_READ(pChan, TFL, pollStatus);

        if ((pollStatus & 0xFF) == 0x00)
	    break;
    }
	
    ST16954_REG_WRITE(pChan, SPR, SPR_ACR);			            /* SPR = 0, PT ACR */

    ST16954_REG_WRITE(pChan, ACR, pollStatus & (~ACR_ADDEN));
	
    if(pollStatus > 0) 
	return EAGAIN;

    for (i = 0; i < count; i++)
    {
	ST16954_REG_WRITE(pChan, THR, outChar[i]);
    }
    return OK;
    }

/******************************************************************************
*
* st16954PollInput - poll the device for input.
*
* RETURNS: OK if a character arrived, EIO on device error, EAGAIN
* if the input buffer is empty, ENOSYS if the device is interrupt-only.
*/

int st16954PollInput
    (
    ST16954_CHAN *		pChan, /* ptr to SIO_CHAN describing this channel */
    char *		thisChar  /* ptr to where to return character */
    )
    {
    char pollStatus;
    int i, nLen;

    ST16954_REG_WRITE(pChan, SPR, SPR_ACR); /* SPR = 0, PT ACR */

    ST16954_REG_READ(pChan, ACR, pollStatus);/* Get ACR to char inchar */

    ST16954_REG_WRITE(pChan, ACR, pollStatus | ACR_ADDEN | ACR_ICREN);/* Set ACR[7], to enable access to RFL, ect */

    ST16954_REG_READ(pChan, RFL, nLen);   /* Read RFL to get the number of characters in the receiver FIFO */
    nLen=nLen & 0xFF;
	
    ST16954_REG_WRITE(pChan, SPR, SPR_ACR);			            /* SPR = 0, PT ACR */

    ST16954_REG_WRITE(pChan, ACR, pollStatus & (~ACR_ADDEN));

    for (i = 0; i < nLen; i++)
    {
        ST16954_REG_READ(pChan, RHR, thisChar[i]);				            
    }

   return nLen;
   
    }

/******************************************************************************
*
* st16954CallbackInstall - install ISR callbacks to get/put chars.
*
* This routine installs interrupt callbacks for transmitting characters
* and receiving characters.
*
* RETURNS: OK on success, or ENOSYS for an unsupported callback type.
*/

int st16954CallbackInstall
    (
    ST16954_CHAN *	pChan,	/* ptr to SIO_CHAN describing this channel */
    int		callbackType,	/* type of callback */
    STATUS	(*callback)(),	/* callback */
    void *	callbackArg	/* parameter to callback */

    )
    {
/*    ST16954_CHAN * pChan = (ST16954_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;
	}
    }




⌨️ 快捷键说明

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