📄 sci.c
字号:
/*
*********************************************************************************************************
* Shanghai Maritime University
* Pudong Avenue 1550#
*
* (c)Copyright 2005,SMSC,Shanghai,China
* All Rights Reserved
*
*
*
*
* Filename : SCI.C
* Programmer : Chen Jutao (Modified from Jean J. Labrosse's COMMRTOS.c and COMMBGND.c
* Description : This file provides the serial communication functions.
*
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* INCLUDES
*********************************************************************************************************
*/
#include "C2407_REG_C.h"
#include "includes.h"
#include "SCI_CFG.H"
/*
*********************************************************************************************************
* LOCAL FUNCTION DECLARATION
*********************************************************************************************************
*/
static void CommTxIntTrigger(void);
/*
*********************************************************************************************************
* DATA TYPES
*********************************************************************************************************
*/
typedef struct {
INT16U RingBufRxCtr; /* Number of characters in the Rx ring buffer */
#if MULTITASK == 1
OS_EVENT *RingBufRxSem; /* Pointer to Rx semaphore */
#endif
INT8U *RingBufRxInPtr; /* Pointer to where next character will be inserted */
INT8U *RingBufRxOutPtr; /* Pointer from where next character will be extracted */
INT8U RingBufRx[COMM_RX_BUF_SIZE]; /* Ring buffer character storage (Rx) */
INT16U RingBufTxCtr; /* Number of characters in the Tx ring buffer */
#if MULTITASK == 1
OS_EVENT *RingBufTxSem; /* Pointer to Tx semaphore */
#endif
INT8U *RingBufTxInPtr; /* Pointer to where next character will be inserted */
INT8U *RingBufTxOutPtr; /* Pointer from where next character will be extracted */
INT8U RingBufTx[COMM_TX_BUF_SIZE]; /* Ring buffer character storage (Tx) */
} COMM_RING_BUF;
/*
*********************************************************************************************************
* GLOBAL VARIABLES
*********************************************************************************************************
*/
COMM_RING_BUF CommBuf;
static volatile INT16U *sciccr = SCICCR;
static volatile INT16U *scictl1 = SCICTL1;
static volatile INT16U *scictl2 = SCICTL2;
static volatile INT16U *scihbaud = SCIHBAUD;
static volatile INT16U *scilbaud = SCILBAUD;
static volatile INT16U *scipri = SCIPRI;
static volatile INT16U *scirxbuf = SCIRXBUF;
static volatile INT16U *scitxbuf = SCITXBUF;
/*
************************************************************************************************************
*/
#if MULTITASK == 1 /* In Multitasking mode */
/*
*********************************************************************************************************
* REMOVE CHARACTER FROM RING BUFFER
* ( In Singletasking mode )
*
* Description : This function is called by your application to obtain a character from the communications
* channel. The function will wait for a character to be received on the serial channel or
* until the function times out.
* Arguments : 'to' is the amount of time (in clock ticks) that the calling function is willing to
* wait for a character to arrive. If you specify a timeout of 0, the function will
* wait forever for a character to arrive.
* 'err' is a pointer to where an error code will be placed:
* *err is set to COMM_NO_ERR if a character has been received
* *err is set to COMM_RX_TIMEOUT if a timeout occurred
* Returns : The character in the buffer (or NUL if a timeout occurred)
*********************************************************************************************************
*/
INT8U CommGetChar (INT16U to, INT8U *err)
{
INT8U c;
INT8U oserr;
COMM_RING_BUF *pbuf;
pbuf = & CommBuf;
OSSemPend(pbuf->RingBufRxSem, to, &oserr); /* Wait for character to arrive */
if (oserr == OS_TIMEOUT) { /* See if characters received within timeout*/
*err = COMM_RX_TIMEOUT; /* No, return error code */
return (NUL);
} else {
OS_ENTER_CRITICAL();
pbuf->RingBufRxCtr--; /* Yes, decrement character count */
c = *pbuf->RingBufRxOutPtr++; /* Get character from buffer */
if (pbuf->RingBufRxOutPtr == &pbuf->RingBufRx[COMM_RX_BUF_SIZE]) { /* Wrap OUT pointer */
pbuf->RingBufRxOutPtr = &pbuf->RingBufRx[0];
}
OS_EXIT_CRITICAL();
*err = COMM_NO_ERR;
return (c);
}
}
#else /* In Singletasking mode */
/*
*********************************************************************************************************
* REMOVE CHARACTER FROM RING BUFFER
* (In Singletasking mode )
*
* Description : This function is called by your application to obtain a character from the communications
* channel.
* Arguments : 'err' is a pointer to where an error code will be placed:
* *err is set to COMM_NO_ERR if a character is available
* *err is set to COMM_RX_EMPTY if the Rx buffer is empty
* Returns : The character in the buffer (or NUL if the buffer is empty)
*********************************************************************************************************
*/
INT8U CommGetChar (INT8U *err)
{
INT8U c;
COMM_RING_BUF *pbuf;
pbuf = & CommBuf;
OS_ENTER_CRITICAL();
if (pbuf->RingBufRxCtr > 0) { /* See if buffer is empty */
pbuf->RingBufRxCtr--; /* No, decrement character count */
c = *pbuf->RingBufRxOutPtr++; /* Get character from buffer */
if (pbuf->RingBufRxOutPtr == &pbuf->RingBufRx[COMM_RX_BUF_SIZE]) { /* Wrap OUT pointer */
pbuf->RingBufRxOutPtr = &pbuf->RingBufRx[0];
}
OS_EXIT_CRITICAL();
*err = COMM_NO_ERR;
return (c);
} else {
OS_EXIT_CRITICAL();
*err = COMM_RX_EMPTY;
c = NUL; /* Buffer is empty, return NUL */
return (c);
}
}
#endif
/*
*********************************************************************************************************
* GET TX CHARACTER FROM RING BUFFER
*
*
* Description : This function is called by the Tx ISR to extract the next character from the Tx buffer.
* The function returns FALSE if the buffer is empty after the character is extracted from
* the buffer. This is done to signal the Tx ISR to disable interrupts because this is the
* last character to send.
* Arguments : 'err' is a pointer to where an error code will be deposited:
* *err is set to COMM_NO_ERR if at least one character was available
* from the buffer.
* *err is set to COMM_TX_EMPTY if the Tx buffer is empty.
* Returns : The next character in the Tx buffer or NUL if the buffer is empty.
*********************************************************************************************************
*/
INT8U CommGetTxChar (INT8U *err)
{
INT8U c;
COMM_RING_BUF *pbuf;
pbuf = &CommBuf;
if (pbuf->RingBufTxCtr > 0) { /* See if buffer is empty */
pbuf->RingBufTxCtr--; /* No, decrement character count */
c = *pbuf->RingBufTxOutPtr++; /* Get character from buffer */
if (pbuf->RingBufTxOutPtr == &pbuf->RingBufTx[COMM_TX_BUF_SIZE]) { /* Wrap OUT pointer */
pbuf->RingBufTxOutPtr = &pbuf->RingBufTx[0];
}
#if MULTITASK == 1
OSSemPost(pbuf->RingBufTxSem); /* Indicate that character will be sent */
#endif
*err = COMM_NO_ERR;
return (c); /* Characters are still available */
} else {
*err = COMM_TX_EMPTY;
return (NUL); /* Buffer is empty */
}
}
/*
*********************************************************************************************************
* INITIALIZE COMMUNICATIONS MODULE
*
*
* Description : This function is called by your application to initialize the communications module. You
* must call this function before calling any other functions.
* Arguments : none
*********************************************************************************************************
*/
void CommInit (void)
{
COMM_RING_BUF *pbuf;
pbuf = &CommBuf; /* Initialize the ring buffer */
pbuf->RingBufRxCtr = 0;
pbuf->RingBufRxInPtr = &pbuf->RingBufRx[0];
pbuf->RingBufRxOutPtr = &pbuf->RingBufRx[0];
#if MULTITASK == 1
pbuf->RingBufRxSem = OSSemCreate(0);
#endif
pbuf->RingBufTxCtr = 0;
pbuf->RingBufTxInPtr = &pbuf->RingBufTx[0];
pbuf->RingBufTxOutPtr = &pbuf->RingBufTx[0];
#if MULTITASK == 1
pbuf->RingBufTxSem = OSSemCreate(COMM_TX_BUF_SIZE);
#endif
}
/*
*********************************************************************************************************
* SEE IF RX CHARACTER BUFFER IS EMPTY
*
*
* Description : This function is called by your application to see if any character is available from the
* communications channel. If at least one character is available, the function returns
* FALSE otherwise, the function returns TRUE.
* Arguments : viod
* Returns : TRUE if the buffer IS empty.
* FALSE if the buffer IS NOT empty or you have specified an incorrect channel.
*********************************************************************************************************
*/
BOOLEAN CommIsEmpty (void)
{
BOOLEAN empty;
COMM_RING_BUF *pbuf;
pbuf = &CommBuf;
OS_ENTER_CRITICAL();
if (pbuf->RingBufRxCtr > 0) { /* See if buffer is empty */
empty = FALSE; /* Buffer is NOT empty */
} else {
empty = TRUE; /* Buffer is empty */
}
OS_EXIT_CRITICAL();
return (empty);
}
/*
*********************************************************************************************************
* SEE IF TX CHARACTER BUFFER IS FULL
*
*
* Description : This function is called by your application to see if any more characters can be placed
* in the Tx buffer. In other words, this function check to see if the Tx buffer is full.
* If the buffer is full, the function returns TRUE otherwise, the function returns FALSE.
* Arguments : NULL
* Returns : TRUE if the buffer IS full.
* FALSE if the buffer IS NOT full or you have specified an incorrect channel.
*********************************************************************************************************
*/
BOOLEAN CommIsFull (void)
{
BOOLEAN full;
COMM_RING_BUF *pbuf;
pbuf = &CommBuf;
OS_ENTER_CRITICAL();
if (pbuf->RingBufTxCtr < COMM_TX_BUF_SIZE) { /* See if buffer is full */
full = FALSE; /* Buffer is NOT full */
} else {
full = TRUE; /* Buffer is full */
}
OS_EXIT_CRITICAL();
return (full);
}
#if MULTITASK == 1 /* In Multitasking mode */
/*
*********************************************************************************************************
* OUTPUT CHARACTER
* ( In Multitasking mode )
*
* Description : This function is called by your application to send a character on the communications
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -