📄 sci.c
字号:
* channel. The function will wait for the buffer to empty out if the buffer is full.
* The function returns to your application if the buffer doesn't empty within the specified
* timeout. A timeout value of 0 means that the calling function will wait forever for the
* buffer to empty out. The character to send is first inserted into the Tx buffer and will
* be sent by the Tx ISR. If this is the first character placed into the buffer, the Tx ISR
* will be enabled.
* Arguments : 'c' is the character to send.
* 'to' is the timeout (in clock ticks) to wait in case the buffer is full. If you
* specify a timeout of 0, the function will wait forever for the buffer to empty.
* Returns : COMM_NO_ERR if the character was placed in the Tx buffer
* COMM_TX_TIMEOUT if the buffer didn't empty within the specified timeout period
*********************************************************************************************************
*/
INT8U CommPutChar ( INT8U c, INT16U to)
{
INT8U oserr;
COMM_RING_BUF *pbuf;
pbuf = &CommBuf;
OSSemPend(pbuf->RingBufTxSem, to, &oserr); /* Wait for space in Tx buffer */
if (oserr == OS_TIMEOUT) {
return (COMM_TX_TIMEOUT); /* Timed out, return error code */
}
OS_ENTER_CRITICAL();
pbuf->RingBufTxCtr++; /* No, increment character count */
*pbuf->RingBufTxInPtr++ = c; /* Put character into buffer */
if (pbuf->RingBufTxInPtr == &pbuf->RingBufTx[COMM_TX_BUF_SIZE]) { /* Wrap IN pointer */
pbuf->RingBufTxInPtr = &pbuf->RingBufTx[0];
}
if (pbuf->RingBufTxCtr == 1) { /* See if this is the first character */
CommTxIntEn();
CommTxIntTrigger(); /* Yes, Enable and trigger Tx interrupts */
}
OS_EXIT_CRITICAL();
return (COMM_NO_ERR);
}
#else /* In Singletasking mode */
/*
*********************************************************************************************************
* OUTPUT CHARACTER
* ( In Singletasking mode )
*
* Description : This function is called by your application to send a character on the communications
* channel. The character to send is first inserted into the Tx buffer and will be sent by
* the Tx ISR. If this is the first character placed into the buffer, the Tx ISR will be
* enabled. If the Tx buffer is full, the character will not be sent (i.e. it will be lost)
* Arguments : 'c' is the character to send.
* Returns : COMM_NO_ERR if the function was successful (the buffer was not full)
* COMM_TX_FULL if the buffer was full
*********************************************************************************************************
*/
INT8U CommPutChar ( INT8U c)
{
COMM_RING_BUF *pbuf;
pbuf = &CommBuf;
OS_ENTER_CRITICAL();
if (pbuf->RingBufTxCtr < COMM_TX_BUF_SIZE) { /* See if buffer is full */
pbuf->RingBufTxCtr++; /* No, increment character count */
*pbuf->RingBufTxInPtr++ = c; /* Put character into buffer */
if (pbuf->RingBufTxInPtr == &pbuf->RingBufTx[COMM_TX_BUF_SIZE]) { /* Wrap IN pointer */
pbuf->RingBufTxInPtr = &pbuf->RingBufTx[0];
}
if (pbuf->RingBufTxCtr == 1) { /* See if this is the first character */
CommTxIntEn();
CommTxIntTrigger(); /* Yes, Enable and trigger Tx interrupts */
OS_EXIT_CRITICAL();
} else {
OS_EXIT_CRITICAL();
}
return (COMM_NO_ERR);
} else {
OS_EXIT_CRITICAL();
return (COMM_TX_FULL);
}
}
#endif
/*
*********************************************************************************************************
* INSERT CHARACTER INTO RING BUFFER
*
*
* Description : This function is called by the Rx ISR to insert a character into the receive ring buffer.
* Arguments : 'c' is the character to insert into the ring buffer. If the buffer is full, the
* character will not be inserted, it will be lost.
*********************************************************************************************************
*/
void CommPutRxChar (INT8U c)
{
COMM_RING_BUF *pbuf;
pbuf = &CommBuf;
if (pbuf->RingBufRxCtr < COMM_RX_BUF_SIZE) { /* See if buffer is full */
pbuf->RingBufRxCtr++; /* No, increment character count */
*pbuf->RingBufRxInPtr++ = c; /* Put character into buffer */
if (pbuf->RingBufRxInPtr == &pbuf->RingBufRx[COMM_RX_BUF_SIZE]) { /* Wrap IN pointer */
pbuf->RingBufRxInPtr = &pbuf->RingBufRx[0];
}
#if MULTITASK == 1
OSSemPost(pbuf->RingBufRxSem); /* Indicate that character was received */
#endif
}
}
/*
*********************************************************************************************************
* CONFIGURE PORT
*
* Description : This function is used to configure a serial I/O port. This code is for IBM-PCs and
* compatibles and assumes a National Semiconductor NS16450.
*
* Arguments : 'baud' is the desired baud rate (anything, standard rates or not)
* 'bits' defines the number of bits used and can be either 5, 6, 7 or 8.
* 'parity' specifies the 'parity' to use:
* COMM_PARITY_NONE
* COMM_PARITY_ODD
* COMM_PARITY_EVEN
* 'stops' defines the number of stop bits used and can be either 1 or 2.
* 'rx_priority' is the priority of rx interrupt:
* HIGH_PRIORITY (INT1)
* LOW_PRIORITY (INT5)
* 'tx_priority' is the priority of rx interrupt:
* HIGH_PRIORITY (INT1)
* LOW_PRIORITY (INT5)
*
* Returns : COMM_NO_ERR if the channel has been configured.
*********************************************************************************************************
*/
INT8U CommCfgPort ( INT16U baud, INT8U bits, INT8U parity, INT8U stops,INT8U rx_priority,INT8U tx_priority)
{
INT16U div; /* Baud rate divisor */
INT8U divlo;
INT8U divhi;
INT8U ccr; /* Communication Control Register */
div = (INT16U)(5000000L / (INT32U)baud-1); /* Compute divisor for desired baud rate */
divlo = div & 0x00FF; /* Split divisor into LOW and HIGH bytes */
divhi = (div >> 8) & 0x00FF;
ccr = ((stops - 1) << 7) + (bits - 1);
switch (parity)
{
case COMM_PARITY_ODD:
ccr |= 0x20; /* Odd parity */
break;
case COMM_PARITY_EVEN:
ccr |= 0x60; /* Even parity */
break;
case COMM_PARITY_NONE: /* Even none-parity */
break;
}
*sciccr=ccr;
*scilbaud=divlo;
*scihbaud=divhi;
switch (rx_priority)
{
case HIGH_PRIORITY: *scipri &=~(0x20);break;
case LOW_PRIORITY: *scipri |=(0x20);break;
}
switch (tx_priority)
{
case HIGH_PRIORITY: *scipri &=~(0x40);break;
case LOW_PRIORITY: *scipri |=(0x40);break;
}
*scictl1=0x03;
*scictl2= 0x00; /* Disable both Rx and Tx interrupts */
return (COMM_NO_ERR);
}
/*
*********************************************************************************************************
* DISABLE RX INTERRUPTS
*
* Description : This function disables the Rx interrupt.
* Arguments : void
* Returns: void
*********************************************************************************************************
*/
void CommRxIntDis (void)
{
*scictl2 &=~(0x02); /* Disable Rx interrupts */
}
/*
*********************************************************************************************************
* ENABLE RX INTERRUPTS
*
* Description : This function enables the Rx interrupt.
* Arguments : void
* Returns: void
*********************************************************************************************************
*/
void CommRxIntEn (void)
{
*scictl2 |=(0x02);
}
/*
*********************************************************************************************************
* ENABLE TX INTERRUPTS
*
* Description : This function enables transmission of characters. Transmission of characters is
* interrupt driven.
* Arguments : void
* Returns: void
*********************************************************************************************************
*/
void CommTxIntEn(void)
{
*scictl2 |=(0x01);
}
/*
*********************************************************************************************************
* DISABLE TX INTERRUPTS
*
* Description : This function disables the character transmission.
* Arguments : void
* Returns: void
*********************************************************************************************************
*/
void CommTxIntDis (void)
{
*scictl2 &=~(0x01);
}
/*
*********************************************************************************************************
* TRIGGER TX INTERRUPTS
*
* Description : This function is used to trigger a Tx interrupt.
* Arguments : void
* Returns: void
*********************************************************************************************************
*/
static void CommTxIntTrigger(void)
{
*scitxbuf='';
}
/*
*********************************************************************************************************
* RX INTERRUPT SERVICE ROUTINE
*
* Description : This function is the Rx interrupt service routine. The function gets the character from the Rx Buffer register and
* inserts it into Rx ring buffer.
* Arguments : void
* Returns: void
*********************************************************************************************************
*/
void CommRxISR(void)
{
INT8U c;
c = (INT8U)(*scirxbuf); /* Process received character */
CommPutRxChar(c); /* Insert received character into buffer */
}
/*
*********************************************************************************************************
* TX INTERRUPT SERVICE ROUTINE
*
* Description : This function is the Tx interrupt service routine. The function gets the character from the Tx ring buffer and puts
* it into Tx buffer register.
* Arguments : void
* Returns: void
*********************************************************************************************************
*/
void CommTxISR(void)
{
INT8U c;
INT8U err;
c = CommGetTxChar(&err); /* Get next character to send. */
if (err == COMM_TX_EMPTY) /* Do we have anymore characters to send ? */
{
CommTxIntDis(); /* No, Disable Tx interrupts */
}
else
{
*scitxbuf= c; /* Yes, Send character */
}
}
/*
************************************************************************************
END OF SCI.C
************************************************************************************
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -