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

📄 m68681sio.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 2 页
字号:
LOCAL int m68681TxStartup    (    M68681_CHAN * pChan    )    {    char   outChar;    int    lvl;    if ((*pChan->getTxChar) (pChan->getTxArg, &outChar) != ERROR)	{	lvl = intLock ();	M68681_WRITE (pChan->cr, M68681_CR_TX_ENABLE);	M68681_WRITE (pChan->tb, outChar);	intUnlock (lvl);	}    return (OK);    }/******************************************************************************** m68681CallbackInstall - install ISR callbacks to get/put chars.** This driver allows interrupt callbacks, for transmitting characters* and receiving characters. In general, drivers may support other types* of callbacks too.** RETURNS:* Returns OK on success, or ENOSYS for an unsupported callback type.*/LOCAL int m68681CallbackInstall    (    M68681_CHAN *	pChan,    int		callbackType,    STATUS	(*callback)(),    void *      callbackArg    )    {    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);	}    }/******************************************************************************** m68681PollOutput - output a character in polled mode.** This routine polls the status register to see if the TxRDY bit has been set.* This signals that the transmit holding register is empty and that the* specified DUART channel is ready for transmission.** RETURNS:* Returns OK if a character sent, EIO on device error, EAGAIN* if the output buffer is full.*/LOCAL int m68681PollOutput    (    M68681_CHAN *	pChan,    char	outChar    )    {    char statusReg;    statusReg = M68681_READ (pChan->sr);    /* is the transitter ready to accept a character? */    if ((statusReg & M68681_SR_TXRDY) == 0x00)	return (EAGAIN);    /* write out the character */    M68681_WRITE (pChan->tb, outChar);    return (OK);    }/******************************************************************************** m68681PollInput - poll the device for input.** This routine polls the status register to see if the RxRDY bit is set.* This gets set when the DUART receives a character and signals the* pressence of a character in the channels receive buffer.** RETURNS:* Returns OK if a character arrived, EIO on device error, EAGAIN* if the input buffer if empty.*/LOCAL int m68681PollInput    (    M68681_CHAN *	pChan,    char *	thisChar    )    {    char statusReg;    statusReg = M68681_READ (pChan->sr);    if ((statusReg & M68681_SR_RXRDY) == 0x00)	return (EAGAIN);    M68681_WRITE (thisChar, *pChan->rb);    return (OK);    }/******************************************************************************** m68681ModeSet - 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, transmitter interrupt and the* received break condition interrupt. If polled mode is desired the xmitrs for* the specified channel is enabled.** RETURNS:* Returns a status of OK if the mode was set else ERROR.*/LOCAL STATUS m68681ModeSet    (    M68681_CHAN * pChan,    UINT	newMode    )    {    int oldlevel;    if ((newMode != SIO_MODE_POLL) && (newMode != SIO_MODE_INT))	return (ERROR);    oldlevel = intLock ();    if (newMode == SIO_MODE_INT     && pChan->pDuart->intEnable)        {	/* Enable the interrupts for receiver/transmitter conditions */	m68681ImrSetClr (pChan->pDuart, (pChan->rcvrEnb | pChan->xmitEnb), 0);        }    else        {	/* Disable interrupts and enable the transmitter for the channel */	m68681ImrSetClr (pChan->pDuart, 0, (pChan->rcvrEnb | pChan->xmitEnb));	M68681_WRITE (pChan->cr, M68681_CR_TX_ENABLE);        }    intUnlock (oldlevel);    pChan->mode = newMode;    return (OK);    }/******************************************************************************** m68681BaudSet - change baud rate for channel** This routine sets the baud rate for the DUART. The interrupts are disabled* during chip access.** RETURNS:* Returns a status of OK if the baud rate was set else ERROR.*/LOCAL STATUS  m68681BaudSet    (    M68681_CHAN * pChan,    UINT	baud    )    {    int ix, oldlevel = intLock ();    STATUS status = ERROR;    for (ix = 0; ix < NELEMENTS (baudTable); ix ++)        {	if (baudTable [ix].rate == baud)	    {	    m68681AcrSetClr (pChan->pDuart, baudTable[ix].baudBit,			    M68681_ACR_BRG_SELECT);	    M68681_WRITE (pChan->csr, baudTable [ix].csrVal);	    pChan->baudRate = baud;	    status = OK;	    break;	    }        }    intUnlock (oldlevel);    return (status);    }/********************************************************************************* m68681InitStruct - initializes the channel structure** This routine initializes the specified channels driver functions.** RETURNS: N/A.*/LOCAL void m68681InitStruct    (    M68681_CHAN * pChan    )    {    pChan->sio.pDrvFuncs= &m68681SioDrvFuncs;    pChan->getTxChar	= m68681DummyCallback;    pChan->putRcvChar	= m68681DummyCallback;    pChan->mode		= 0; /* undefined */    if (pChan->options == 0 || pChan->options > MAX_OPTIONS)	pChan->options = M68681_DEFAULT_OPTIONS;    if (pChan->baudRate == 0 || pChan->baudRate > MAX_BAUD)	pChan->baudRate = M68681_DEFAULT_BAUD;    }/********************************************************************************* m68681InitChannel - initialize a single channel** This routine initializes the specified channel.  It is required* that the transmitters and receivers have been issued s/w reset commands* before the mode registers, clock select registers, auxillary clock* registers & output port configuration registers are changed.** This routine only sets the initial state as part of m68681DevInit.  The* user can change this state through ioct clommands as desired.** RETURNS: N/A.*/LOCAL void m68681InitChannel    (    M68681_CHAN * pChan,    M68681_DUART * pDuart    )    {    /* Reset the transmitters  & receivers  */    M68681_WRITE (pChan->cr, M68681_CR_RST_BRK_INT_CMD);    M68681_WRITE (pChan->cr, M68681_CR_RST_ERR_STS_CMD);    m68681OptsSet (pChan, pChan->options); /* TX is disabled */    m68681BaudSet (pChan, pChan->baudRate);    }/********************************************************************************* m68681OptsSet - set the serial options** Set the channel operating mode to that specified.  All sioLib options* are supported: CLOCAL, CREAD, CSIZE, PARENB, and PARODD.** Note, this routine disables the transmitter.  The calling routine* may have to re-enable it.** RETURNS:* Returns OK to indicate success, otherwise ERROR is returned*/LOCAL STATUS m68681OptsSet    (    M68681_CHAN * pChan, /* ptr to channel */    UINT options	/* new hardware options */    )    {    int mr1Value = 0;    int mr2Value = 0;    int lvl;    if (pChan == NULL || options & 0xffffff00)	return ERROR;    /* Reset the transmitters  & receivers  */    switch (options & CSIZE)	{	case CS5:	    mr1Value = M68681_MR1_BITS_CHAR_5; break;	case CS6:	    mr1Value = M68681_MR1_BITS_CHAR_6; break;	case CS7:	    mr1Value = M68681_MR1_BITS_CHAR_7; break;	default:	case CS8:	    mr1Value = M68681_MR1_BITS_CHAR_8; break;	}    if (options & STOPB)	mr2Value = M68681_MR2_STOP_BITS_2;    else	mr2Value = M68681_MR2_STOP_BITS_1;    switch (options & (PARENB|PARODD))	{	case PARENB|PARODD:	    mr1Value |= M68681_MR1_ODD_PARITY; break;	case PARENB:	    mr1Value |= M68681_MR1_EVEN_PARITY; break;	case PARODD:	    mr1Value |= M68681_MR1_PAR_MODE_MULTI; break;	default:	case 0:	    mr1Value |= M68681_MR1_NO_PARITY; break;	}    if (!(options & CLOCAL))	{	/* clocal disables hardware flow control */	mr1Value |= M68681_MR1_RX_RTS;	mr2Value |= M68681_MR2_TX_CTS;	}    lvl = intLock ();    /* now reset the channel mode registers */    M68681_WRITE (pChan->cr, M68681_CR_RST_MR_PTR_CMD | M68681_CR_RX_DISABLE |                      M68681_CR_TX_DISABLE);    M68681_WRITE (pChan->cr, M68681_CR_RST_TX_CMD);    M68681_WRITE (pChan->cr, M68681_CR_RST_RX_CMD);    M68681_WRITE (pChan->mr, mr1Value);  /* mode register 1  */    M68681_WRITE (pChan->mr, mr2Value);  /* mode register 2  */    if (options & CREAD)	M68681_WRITE (pChan->cr, M68681_CR_RX_ENABLE);    intUnlock (lvl);    pChan->options = options;    return OK;    }/********************************************************************************* m68681Ioctl - special device control** RETURNS:* Returns OK on success, EIO on device error, ENOSYS on unsupported* request.*/LOCAL int m68681Ioctl    (    M68681_CHAN *	pChan,		/* device to control */    int		request,		/* request code */    void *	someArg			/* some argument */    )    {    STATUS result;    int     arg = (int)someArg;    switch (request)	{	case SIO_BAUD_SET:	    return (m68681BaudSet (pChan, arg) == OK ? OK : EIO);	case SIO_BAUD_GET:	    *(int *)arg = pChan->baudRate;	    return (OK);	case SIO_MODE_SET:	    return (m68681ModeSet (pChan, arg) == OK ? OK : EIO);	case SIO_MODE_GET:	    *(int *)arg = pChan->mode;	    return (OK);	case SIO_AVAIL_MODES_GET:	    *(int *)arg = SIO_MODE_INT | SIO_MODE_POLL;	    return (OK);	case SIO_HW_OPTS_SET:	    /* change options, then set mode to restart chip correctly */	    result = m68681OptsSet (pChan, arg);	    m68681ModeSet (pChan, pChan->mode);	    return result;	case SIO_HW_OPTS_GET:	    *(int *)arg = pChan->options;	    return (OK);	default:	    return (ENOSYS);	}    }/********************************************************************************* m68681IntWr - handle a transmitter interrupt** This routine handles write interrupts from the DUART. This isr is invoked* when the TxRDY bit in the interrupt status register has been set. If there* is no character to transmit the transmitter for the channel is disabled.** RETURNS: N/A*/LOCAL void m68681IntWr    (    M68681_CHAN * pChan    )    {    char            outChar;    volatile UCHAR  *tb = pChan->tb;    if ((*pChan->getTxChar) (pChan->getTxArg, &outChar) != ERROR)	{	M68681_WRITE (tb, outChar);	   /* if char available, tx it */	}    else        {	M68681_WRITE (pChan->cr, M68681_CR_TX_DISABLE);        }    }/******************************************************************************* m68681IntRd - handle a reciever interrupt** This routine handles read interrupts from the DUART.* The DUART has been programmed to generate read interrupts when the RXRDY* status bit has been set in the interrupt status register. When a character* has been  received it is removed from the channels receive buffer.** RETURNS: N/A*/LOCAL void m68681IntRd    (    M68681_CHAN * pChan    )    {    volatile UCHAR  *rb = pChan->rb;    UCHAR            inchar;    char             statusReg;    statusReg = M68681_READ (pChan->sr);    while ((statusReg & M68681_SR_RXRDY) != 0x00)        {	inchar = M68681_READ (rb);	(*pChan->putRcvChar) (pChan->putRcvArg, inchar);	if (pChan->mode != SIO_MODE_INT)	    break;	statusReg = M68681_READ (pChan->sr);        }    }/********************************************************************************* m68681Int - handle all DUART interrupts in one vector** This routine handles all interrupts in a single interrupt vector.* It identifies and services each interrupting source in turn, using* edge-sensitive interrupt controllers.** RETURNS: N/A*/void m68681Int    (    M68681_DUART * pDuart    )    {    UCHAR        	intStatus;    volatile UCHAR      resetTimer;    /* loop until all sources have been handled */    while ((intStatus = (M68681_READ(pDuart->isr) & pDuart->imrCopy)) != 0)	{	if ((intStatus & M68681_ISR_TX_RDY_A_INT) != 0)	    m68681IntWr (&pDuart->portA);	if ((intStatus & M68681_ISR_RX_RDY_A_INT) != 0)	    m68681IntRd (&pDuart->portA);	if ((intStatus & M68681_ISR_TX_RDY_B_INT) != 0)	    m68681IntWr (&pDuart->portB);     	if ((intStatus & M68681_ISR_RX_RDY_B_INT) != 0)	    m68681IntRd (&pDuart->portB);	if (intStatus & M68681_ISR_CTR_RDY_INT)	    {	    if (pDuart->tickRtn != NULL)		(*pDuart->tickRtn) (pDuart->tickArg);	    else		/* Clear the timer int */		resetTimer = M68681_READ (pDuart->ctroff);	    }	}    }

⌨️ 快捷键说明

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