📄 s3c2510sio.c
字号:
default:
cnt = 1;
break;
}
for (i=0; i<cnt; i++)
{
/* Read character from Receive Data Register. */
inChar = (char)*S3C2510_URXBUF(ch);
/* Call callback routine. */
(*pChan->putRcvChar)(pChan->putRcvArg, inChar);
}
}
else if (stat & S3C2510_HUSTAT_ERXTO) /* Receive Event Timeout */
{
/* Clear bit. */
*S3C2510_USTAT(ch) |= S3C2510_HUSTAT_ERXTO;
while (1)
{
/* Read character from Receive Data Register. */
inChar = (char)*S3C2510_URXBUF(ch);
/* Call callback routine. */
(*pChan->putRcvChar)(pChan->putRcvArg, inChar);
stat = *S3C2510_USTAT(ch);
/* Terminate if FIFO is empty. */
if (stat & S3C2510_HUSTAT_RFEMT) /* Receive FIFO Empty */
{
break;
}
}
}
#ifdef INCLUDE_LED
else
{
LED_ON(LED6_MASK);
}
#endif /* INCLUDE_LED */
}
}
/*******************************************************************************
*
* s3c2510SioIntTx - handle a transmit interrupt
*
* This routine handles write interrupts from the UART.
*
* RETURNS: NA
*/
void s3c2510SioIntTx(
S3C2510_SIO_CHAN *pChan /* device caused Tx interrupt */
)
{
int ch = pChan->ch;
UINT32 stat;
char outChar;
stat = *S3C2510_USTAT(ch);
if (ch == 0) /* console UART */
{
if (stat & S3C2510_USTAT_THE) /* Transmit Holding Register Empty */
{
/* Call callback routine. */
if ((*pChan->getTxChar)(pChan->getTxArg, &outChar) != ERROR)
{
/* Write char to Transmit Data Register. */
*S3C2510_UTXBUF(ch) = (VUINT8)outChar;
}
else
{
/* Disable Transmit Holding Register Empty Interrupt. */
*S3C2510_UINT(ch) &= ~S3C2510_UINT_THEIE;
}
}
#ifdef INCLUDE_LED
else
{
LED_ON(LED7_MASK);
}
#endif /* INCLUDE_LED */
}
else /* high-speed UART */
{
if (stat & S3C2510_USTAT_THE) /* Transmit Holding Register Empty */
{
UINT32 cnt, i;
switch (*S3C2510_UCON(ch) & S3C2510_HUCON_TFTL_MASK)
{
case S3C2510_HUCON_TFTL_24:
cnt = 24;
break;
case S3C2510_HUCON_TFTL_16:
cnt = 16;
break;
case S3C2510_HUCON_TFTL_8:
cnt = 8;
break;
default:
cnt = 30;
break;
}
for (i=0; i<cnt; i++)
{
/* Call callback routine. */
if ((*pChan->getTxChar)(pChan->getTxArg, &outChar) != ERROR)
{
/* Write char to Transmit Data Register. */
*S3C2510_UTXBUF(ch) = (VUINT8)outChar;
}
else
{
/* Disable Transmit Holding Register Empty Interrupt. */
*S3C2510_UINT(ch) &= ~S3C2510_UINT_THEIE;
break;
}
}
}
#ifdef INCLUDE_LED
else
{
LED_ON(LED7_MASK);
}
#endif /* INCLUDE_LED */
}
}
/*******************************************************************************
*
* s3c2510SioDummyCallback - dummy callback routine.
*
* RETURNS: ERROR, always.
*/
LOCAL STATUS s3c2510SioDummyCallback(void)
{
return ERROR;
}
/******************************************************************************
*
* s3c2510SioBaudSet - set the baud rates
*
* RETURNS: OK on success, ENOSYS on unsupported request, EIO on failed request.
*/
LOCAL int s3c2510SioBaudSet(
S3C2510_SIO_CHAN *pChan, /* device to control */
int baudRate /* baud rate */
)
{
int cnt;
if (pChan->ch != 0) /* high-speed UART */
{
if (baudRate == 0) /* hangup request */
{
return (s3c2510SioHup(pChan));
}
}
/* Calculate the baud rate. */
cnt = (UART_BRGCLK_FREQ / (baudRate * 16 * (1 << (UART_BRGCLK_DIV_FACTOR * 4)))) - 1;
/* Baudrate divisor must fit in a 12-bit register. */
if ((cnt < 0) || (cnt > 0xFFF))
{
return EIO;
}
/* Write to the Baud Rate Divisor Register. */
*S3C2510_UBRD(pChan->ch) = (UINT16)((cnt << S3C2510_UBRD_CNT_SHIFT) | UART_BRGCLK_DIV_FACTOR);
pChan->baudRate = baudRate;
return OK;
}
/******************************************************************************
*
* s3c2510SioOptsSet - 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: OK on success, ENOSYS on unsupported request, EIO on failed request.
*/
LOCAL int s3c2510SioOptsSet(
S3C2510_SIO_CHAN *pChan, /* device to control */
int options /* options */
)
{
UINT32 ucon;
/* Set default bits for UART Control Register. */
ucon = S3C2510_UCON_RMODE_CPU | /* CPU Request */
S3C2510_UCON_TMODE_CPU | /* CPU Request */
#ifdef UARTCLK_EXTERNAL
S3C2510_UCON_SCSEL_UCLK; /* External */
#else /* UARTCLK_EXTERNAL */
S3C2510_UCON_SCSEL_PCLK2; /* Internal (PCLK2 = PCLK / 2) */
#endif /* UARTCLK_EXTERNAL */
/* Set character size. */
switch (options & CSIZE)
{
case CS5:
ucon |= S3C2510_UCON_WL_5; /* 5 Bits */
break;
case CS6:
ucon |= S3C2510_UCON_WL_6; /* 6 Bits */
break;
case CS7:
ucon |= S3C2510_UCON_WL_7; /* 7 Bits */
break;
case CS8:
ucon |= S3C2510_UCON_WL_8; /* 8 Bits */
break;
}
/* Set stop bits. */
if (!(options & STOPB)) /* send two stop bits (else one) */
{
ucon |= S3C2510_UCON_STB_1; /* One Stop Bit per Frame */
}
else
{
ucon |= S3C2510_UCON_STB_2; /* Two Stop Bit per Frame */
}
/* Set parity. */
if (!(options & PARENB)) /* parity detection enabled (else disabled) */
{
ucon |= S3C2510_UCON_PMD_NO; /* No Parity */
}
else
{
if (options & PARODD) /* odd parity (else even) */
{
ucon |= S3C2510_UCON_PMD_ODD; /* Odd Parity */
}
else
{
ucon |= S3C2510_UCON_PMD_EVEN; /* Even Parity */
}
}
if (pChan->ch != 0) /* high-speed UART. */
{
ucon |= S3C2510_HUCON_RFTL_28 | /* Receive FIFO Trigger Level */
S3C2510_HUCON_TFTL_16 | /* Transmit FIFO Trigger Level */
S3C2510_HUCON_RFEN | /* Receive FIFO Enable */
S3C2510_HUCON_TFEN; /* Transmit FIFO Enable */
if (!(options & CLOCAL)) /* ignore modem status lines */
{
ucon |= S3C2510_HUCON_HFEN | /* Hardware Flow Control Enable */
S3C2510_HUCON_RTSRTR_RTS | /* RTS/RTR Selection */
S3C2510_HUCON_DTR; /* Data Terminal Ready to Pin */
}
}
/* Write UART Control Register. */
*S3C2510_UCON(pChan->ch) = ucon;
pChan->options = options;
return OK;
}
/******************************************************************************
*
* s3c2510SioModeSet - set the channel's SIO mode
*
* RETURNS: OK on success, ENOSYS on unsupported request, EIO on failed request.
*/
LOCAL int s3c2510SioModeSet(
S3C2510_SIO_CHAN *pChan, /* device to control */
int sioMode /* SIO mode */
)
{
int ch = pChan->ch;
if ((sioMode != SIO_MODE_POLL) && (sioMode != SIO_MODE_INT))
{
return EIO;
}
if (sioMode == SIO_MODE_INT) /* interrupt mode */
{
if (ch == 0) /* console UART */
{
*S3C2510_UINT(ch) = S3C2510_UINT_OERIE | /* Overrun Error Interrupt Enable */
S3C2510_UINT_PERIE | /* Parity Error Interrupt Enable */
S3C2510_UINT_FERIE | /* Frame Error Interrupt Enable */
S3C2510_UINT_RDVIE | /* Receive Data Valid Interrupt Enable */
S3C2510_UINT_THEIE; /* Transmit Holding Register Empty Interrupt Enable */
}
else /* high-speed UART */
{
*S3C2510_UINT(ch) = S3C2510_UINT_OERIE | /* Overrun Error Interrupt Enable */
S3C2510_UINT_PERIE | /* Parity Error Interrupt Enable */
S3C2510_UINT_FERIE | /* Frame Error Interrupt Enable */
S3C2510_HUINT_ERXTOIE | /* Receive Event Timeout Interrupt Enable */
S3C2510_HUINT_RFREAIE | /* Receive FIFO Trigger Level Reached Interrupt Enable */
S3C2510_UINT_THEIE; /* Transmit Holding Register Empty Interrupt Enable */
}
}
else /* polling mode */
{
*S3C2510_UINT(ch) = S3C2510_UINT_OERIE | /* Overrun Error Interrupt Enable */
S3C2510_UINT_PERIE | /* Parity Error Interrupt Enable */
S3C2510_UINT_FERIE; /* Frame Error Interrupt Enable */
}
pChan->sioMode = sioMode;
return OK;
}
/******************************************************************************
*
* s3c2510SioOpen - set the modem control lines
*
* Set the modem control lines(RTS, DTR) TRUE if not already set.
*
* RETURNS: OK on success, ENOSYS on unsupported request, EIO on failed request.
*/
LOCAL int s3c2510SioOpen(
S3C2510_SIO_CHAN *pChan /* device to control */
)
{
if (pChan->ch == 0) /* console UART */
{
return ENOSYS;
}
if (!(pChan->options & HUPCL)) /* hang up on last close */
{
return ENOSYS;
}
if (pChan->options & CLOCAL) /* ignore modem status lines */
{
return ENOSYS;
}
/* Asserts DTR. */
*S3C2510_UCON(pChan->ch) |= S3C2510_HUCON_DTR; /* Data Terminal Ready to Pin */
return OK;
}
/******************************************************************************
*
* s3c2510SioHup - hang up the modem control lines
*
* Resets the RTS and DTR signals.
*
* RETURNS: OK on success, ENOSYS on unsupported request, EIO on failed request.
*/
LOCAL int s3c2510SioHup(
S3C2510_SIO_CHAN *pChan /* device to control */
)
{
if (pChan->ch == 0) /* console UART */
{
return ENOSYS;
}
if (!(pChan->options & HUPCL)) /* hang up on last close */
{
return ENOSYS;
}
if (pChan->options & CLOCAL) /* ignore modem status lines */
{
return ENOSYS;
}
/* Deasserts DTR. */
*S3C2510_UCON(pChan->ch) &= ~S3C2510_HUCON_DTR; /* Data Terminal Ready to Pin */
return OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -