📄 au1500sio.c
字号:
oldlevel = intLock ();
if (newMode == SIO_MODE_INT)
{
/* Enable appropriate interrupts */
if (pChan->options & CLOCAL)
{
regs->uart_inten = pChan->ier | UART_INTEN_TIE | UART_INTEN_RIE;
}
else
{
mask = regs->uart_mdmctrl & UART_MDMSTAT_CT;
/* if the CTS is asserted enable Tx interrupt */
if (mask & UART_MDMSTAT_CT)
pChan->ier |= UART_INTEN_TIE; /* enable Tx interrupt */
else
pChan->ier &= ~UART_INTEN_TIE; /* disable Tx interrupt */
regs->uart_inten = pChan->ier;
}
}
else
{
/* disable all interrupts */
regs->uart_inten = 0;
}
pChan->channelMode = newMode;
intUnlock (oldlevel);
return (OK);
}
/*******************************************************************************
*
* auSioIoctl - 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 command SIO_HUP is sent by ttyDrv when the last close() function
* call is made. Likewise SIO_OPEN is sent when the first open() function call
* is made.
*
* RETURNS: OK on success, EIO on device error, ENOSYS on unsupported
* request.
*/
LOCAL STATUS auSioIoctl
(
AUSIO_CHAN * pChan, /* pointer to channel */
int request, /* request code */
int arg /* some argument */
)
{
FAST STATUS status;
status = OK;
switch (request)
{
case SIO_BAUD_SET:
if (arg < AU_UART_MIN_RATE || arg > AU_UART_MAX_RATE)
status = EIO; /* baud rate out of range */
else
status = auSioBaudSet (pChan, arg);
break;
case SIO_BAUD_GET:
*(int *)arg = pChan->baudRate;
break;
case SIO_MODE_SET:
status = (auSioModeSet (pChan, arg) == OK) ? OK : EIO;
break;
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:
status = (auSioOptsSet (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 = auSioHup (pChan);
break;
case SIO_OPEN:
/* check if hupcl option is enabled */
if (pChan->options & HUPCL)
status = auSioOpen (pChan);
break;
default:
status = ENOSYS;
}
return (status);
}
/*******************************************************************************
*
* auSioIntWr - handle a transmitter interrupt
*
* This routine handles write interrupts from the UART. It reads a character
* and puts it in the transmit holding register of the device for transfer.
*
* If there are no more characters to transmit, transmission is disabled by
* clearing the transmit interrupt enable bit in the IER(int enable register).
*
* RETURNS: N/A
*
*/
void auSioIntWr
(
AUSIO_CHAN * pChan /* pointer to channel */
)
{
char outChar;
AU1000_UART *regs = (AU1000_UART *)pChan->regs;
/* send as many characters as possible */
while (regs->uart_linestat & (UART_LINESTAT_TE | UART_LINESTAT_TT))
{
if ((*pChan->getTxChar) (pChan->getTxArg, &outChar) != ERROR)
{
/* Write Buffer errata */
__asm("sync");
regs->uart_txdata = outChar;
}
else
{
/* FIX!!! could disable int even if some chars sent! */
pChan->ier &= ~UART_INTEN_TIE; /* disable Tx Int */
regs->uart_inten = pChan->ier;
break;
}
}
}
/*******************************************************************************
*
* auSioIntRd - handle a receiver interrupt
*
* This routine handles read interrupts from the UART.
*
* RETURNS: N/A
*
*/
LOCAL void auSioIntRd
(
AUSIO_CHAN * pChan /* pointer to channel */
)
{
char inchar;
AU1000_UART *regs = (AU1000_UART *)pChan->regs;
/* read all characters from fifo */
while (regs->uart_linestat & UART_LINESTAT_DR)
{
inchar = regs->uart_rxdata;
(*pChan->putRcvChar) (pChan->putRcvArg, inchar);
}
}
/********************************************************************************
*
* auSioInt - interrupt level processing
*
* This routine handles four sources of interrupts from the UART. They are
* prioritized in the following order by the Interrupt Identification Register:
* Receiver Line Status, Received Data Ready, Transmit Holding Register Empty
* and Modem Status.
*
* When a modem status interrupt occurs, the transmit interrupt is enabled if
* the CTS signal is TRUE.
*
* RETURNS: N/A
*
*/
void auSioInt
(
AUSIO_CHAN * pChan /* pointer to channel */
)
{
volatile char intStatus;
AU1000_UART *regs = (AU1000_UART *)pChan->regs;
/* read the Interrrupt Status Register (Int. Ident.) */
intStatus = regs->uart_intcause & UART_INTCAUSE_IID;
switch (intStatus)
{
case UART_INTCAUSE_IID_RLS:
/* overrun,parity error and break interrupt */
/* must read to clear condition else rx stops */
intStatus = regs->uart_linestat;
break;
case UART_INTCAUSE_IID_RDA: /* received data available */
case UART_INTCAUSE_IID_CTO:
auSioIntRd (pChan);
break;
case UART_INTCAUSE_IID_TBA: /* transmitter holding register ready */
auSioIntWr (pChan);
break;
case UART_INTCAUSE_IID_MS: /* modem status register */
{
char msr;
msr = regs->uart_mdmstat;
/* if CTS is asserted by modem, enable tx interrupt */
if ((msr & UART_MDMSTAT_CT) && (msr & UART_MDMSTAT_DC))
pChan->ier |= UART_INTEN_TIE;
else
pChan->ier &= ~UART_INTEN_TIE;
}
break;
default:
break;
}
regs->uart_inten = pChan->ier;
}
/*******************************************************************************
*
* auSioTxStartup - transmitter startup routine
*
* Call interrupt level character output routine and enable interrupt if it is
* in interrupt mode with no hardware flow control.
* If the option for hardware flow control is enabled and CTS is set TRUE,
* then the Tx interrupt is enabled.
*
* RETURNS: N/A
*/
LOCAL void auSioTxStartup
(
AUSIO_CHAN * pChan /* pointer to channel */
)
{
char mask;
AU1000_UART *regs = (AU1000_UART *)pChan->regs;
if (pChan->channelMode == SIO_MODE_INT)
{
if (pChan->options & CLOCAL)
{
/* No modem control */
pChan->ier |= UART_INTEN_TIE;
regs->uart_inten = pChan->ier;
}
else
{
mask = regs->uart_mdmstat & UART_MDMSTAT_CT;
/* if the CTS is asserted enable Tx interrupt */
if (mask & UART_MDMSTAT_CT)
pChan->ier |= UART_INTEN_TIE; /* enable Tx interrupt */
else
pChan->ier &= ~UART_INTEN_TIE; /* disable Tx interrupt */
regs->uart_inten = pChan->ier;
}
}
}
/******************************************************************************
*
* auSioPollOutput - output a character in polled mode.
*
* RETURNS: OK if a character arrived, EIO on device error, EAGAIN
* if the output buffer if full.
*/
LOCAL int auSioPollOutput
(
AUSIO_CHAN * pChan, /* pointer to channel */
char outChar /* char to send */
)
{
char pollStatus;
char msr;
AU1000_UART *regs = (AU1000_UART *)pChan->regs;
pollStatus = regs->uart_linestat;
msr = regs->uart_mdmstat;
/* is the transmitter ready to accept a character? */
if ((pollStatus & UART_LINESTAT_TE) == 0x00)
return (EAGAIN);
if (!(pChan->options & CLOCAL)) /* modem flow control ? */
{
if (msr & UART_MDMSTAT_CT)
{
/* Write Buffer errata */
__asm("sync");
regs->uart_txdata = outChar;
}
else
return (EAGAIN);
}
else
regs->uart_txdata = outChar;
return (OK);
}
/******************************************************************************
*
* auSioPollInput - poll the device for input.
*
* RETURNS: OK if a character arrived, EIO on device error, EAGAIN
* if the input buffer if empty.
*/
LOCAL int auSioPollInput
(
AUSIO_CHAN * pChan, /* pointer to channel */
char * pChar /* pointer to char */
)
{
char pollStatus;
AU1000_UART *regs = (AU1000_UART *)pChan->regs;
pollStatus = regs->uart_linestat;
if ((pollStatus & UART_LINESTAT_DR) == 0x00)
return (EAGAIN);
/* got a character */
*pChar = regs->uart_rxdata;
return (OK);
}
/******************************************************************************
*
* auSioCallbackInstall - 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.
*/
LOCAL int auSioCallbackInstall
(
SIO_CHAN * pSioChan, /* pointer to device to control */
int callbackType, /* callback type(tx or receive) */
STATUS (*callback)(), /* pointer to callback function */
void * callbackArg /* callback function argument */
)
{
AUSIO_CHAN * pChan = (AUSIO_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 + -