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

📄 sc28l198serial.c

📁 Embedded Planet公司的ep8260单板计算机的BSP包(VxWorks)
💻 C
📖 第 1 页 / 共 4 页
字号:
{   150, B150},
{   200, B200},   
{   300, B300},   
{   450, B450},   
{   600, B600},   
{   900, B900},   
{  1200, B1200},
{  1800, B1800},  
{  2400, B2400},  
{  3600, B3600},  
{  4800, B4800},  
{  7200, B7200}, 
{  9600, B9600},
{ 14400, B14400}, 
{ 19200, B19200}, 
{ 28800, B28800}, 
{ 38400, B38400},
{ 57600, B57600}, 
{115200, B115200}, 
{230400, B230400} 
};


/* This is the value of the IMMR register.
 * It is initialized in sc28l198Drv().
 * It is used in sc28l198Interrupt().
 */
static int immrVal;


LOCAL SC28L198_DEV_CHAN* sc28l198Open(SC28L198_DEV_CHAN *pChannel,
                                      char *extension, int mode);
LOCAL int sc28l198Close(SC28L198_DEV_CHAN *pChannel);
LOCAL int sc28l198Read (SC28L198_DEV_CHAN *pChannel, char *buffer,
                        int maxBytes);
LOCAL int sc28l198Write(SC28L198_DEV_CHAN *pChannel, char *buffer, int nBytes);
LOCAL int sc28l198Ioctl(SC28L198_DEV_CHAN *pChannel, int ioctlCode, int *arg);

LOCAL int sc28l198BufRead(FAST SC28L198_DEV_CHAN *pChannel, char *buffer,
                          int maxBytes);
LOCAL int sc28l198BufWrite (FAST SC28L198_DEV_CHAN *pChannel, char *buffer,
                            int nBytes);
LOCAL void sc28l198Flush (FAST SC28L198_DEV_CHAN *pChannel);
LOCAL void sc28l198FlushWrt(FAST SC28L198_DEV_CHAN *pChannel);
LOCAL void sc28l198FlushRd (FAST SC28L198_DEV_CHAN *pChannel);

LOCAL STATUS sc28l198HrdInit(int uart);
LOCAL void sc28l198ResetChan(int uart, int chan);

LOCAL void sc28l198Error(int errorNum, char *errorMsg);

LOCAL int sc28l198BaudRate(int baudRate);
LOCAL int sc28l198Parity(char *parity);
LOCAL int sc28l198StopBits(int stopBits);
LOCAL int sc28l198DataBits(int dataBits); 

void sc28l198SetBaudRate(int uart, int chan, int baudRate);
void sc28l198ConfigChan(int uart, int chan, int dataBits, int stopBits,
                        int parity);

void sc28l198InitInterrupts(int uart);

/* Driver debug control */
#define SC28L198_DEBUG
#ifdef  SC28L198_DEBUG
#define DRV_DEBUG_OFF       0x0000
#define DRV_DEBUG_INIT      0x0001
#define DRV_DEBUG_OPEN      0x0002
#define DRV_DEBUG_READ      0x0004
#define DRV_DEBUG_WRITE     0x0008
#define DRV_DEBUG_IOCTRL    0x0010
#define DRV_DEBUG_INTR      0x0020
#define DRV_DEBUG_CMDS      0x0040
#define DRV_DEBUG_ALL       0xffff

/* Sets driver diagnostic output level    */
int sc28l198Debug=DRV_DEBUG_OFF;            

#define DRV_LOG(FLG, X0, X1, X2, X3, X4, X5, X6)		\
    do {						        \
    if (sc28l198Debug & FLG)  				        \
	    logMsg (X0, (int)X1, (int)X2, (int)X3, (int)X4,     \
			(int)X5, (int)X6);			\
    } while (0)

#define DRV_PRINT(FLG, X)			\
    do {					\
    if (sc28l198Debug & FLG)			\
	printf X;				\
    } while (0)
#else
#define DRV_LOG(FLG, X0, X1, X2, X3, X4, X5, X6)
#define DRV_PRINT(FLG, X)
#endif


/******************************************************************************
 * Error message handler for the SC28L198.
 * 
 * Note that the current implementation does not use the error number.
 ******************************************************************************/
LOCAL void
sc28l198Error(int errorNum, char *errorMsg)
{
    logMsg("SC28L198: %s\n",(int)errorMsg,0,0,0,0,0);
    /* errnoSet(errorNum); */
} /* sc28l198Error() */

/******************************************************************************
 * Note that we need some way to disable the transmitter interrupts when the
 * TxFIFO is empty.  One way would be to use the "Enable TX" bit in the
 * Command Register (CR).  This is the method used by most of the other
 * serial drivers. However, if you look at the design of this chip we can
 * only write to it which means it get very messy to preserve the state of
 * "Enable RX" bit.
 * 
 * To get around this "feature" we will use the mask bit in the Interrupt
 * Mask Register (IMR) to function in this role.  We will enable and disable
 * TxRDY in the IMR just prior to and then end of a block transmission.
 ******************************************************************************/

/******************************************************************************
 * Enable the generation of interrupts for TxFIFO.
 ******************************************************************************/
void 
sc28l198EnableTxInt(SC28L198_DEV_CHAN *pChannel)
{
    DRV_LOG(DRV_DEBUG_CMDS, "enabling tx int, uart=%d, chan=%d.\n",
            pChannel->uart,pChannel->chan,0,0,0,0);

    pChannel->lastIMR |= TXRDY_INT;
    *SC28L198_IMR(pChannel->uart,pChannel->chan) = pChannel->lastIMR;
} /* sc28l198EnableTxInt() */

/******************************************************************************
 * Disable the generation of interrupts for TxFIFO.
 ******************************************************************************/
void 
sc28l198DisableTxInt(SC28L198_DEV_CHAN *pChannel)
{
    DRV_LOG(DRV_DEBUG_CMDS, "disabling tx int, uart=%d, chan=%d.\n",
            pChannel->uart,pChannel->chan,0,0,0,0);

    pChannel->lastIMR &= ~TXRDY_INT;
    *SC28L198_IMR(pChannel->uart,pChannel->chan) = pChannel->lastIMR;
} /* sc28l198DisableTxInt() */

/******************************************************************************
 * Enable the generation of interrupts for RxFIFO.
 ******************************************************************************/
void 
sc28l198EnableRxInt(SC28L198_DEV_CHAN *pChannel)
{
    SC28L198_DEV_CHAN *pRxChan = SAME_PCHANNEL_IN_OTHER_OCTART(pChannel);

    DRV_LOG(DRV_DEBUG_CMDS, "enabling rx int, uart=%d, chan=%d.\n",
            pRxChan->uart,pRxChan->chan,0,0,0,0);

    pRxChan->lastIMR |= RXRDY_INT;
    *SC28L198_IMR(pRxChan->uart,pRxChan->chan) = pRxChan->lastIMR;
} /* sc28l198EnableRxInt() */

/******************************************************************************
 * Disable the generation of interrupts for RxFIFO.
 ******************************************************************************/
void 
sc28l198DisableRxInt(SC28L198_DEV_CHAN *pChannel)
{
    SC28L198_DEV_CHAN *pRxChan = SAME_PCHANNEL_IN_OTHER_OCTART(pChannel);

    DRV_LOG(DRV_DEBUG_CMDS, "disabling rx int, uart=%d, chan=%d.\n",
            pRxChan->uart,pRxChan->chan,0,0,0,0);

    pRxChan->lastIMR &= ~RXRDY_INT;
    *SC28L198_IMR(pRxChan->uart,pRxChan->chan) = pRxChan->lastIMR;
} /* sc28l198DisableRxInt() */

/******************************************************************************
 * Enable transmitter and receiver.
 ******************************************************************************/
void 
sc28l198EnableRxTx(SC28L198_DEV_CHAN *pChannel)
{
    SC28L198_DEV_CHAN *pRxChan = SAME_PCHANNEL_IN_OTHER_OCTART(pChannel);

    DRV_LOG(DRV_DEBUG_CMDS,
            "enabling rx (uart=%d, chan=%d) and tx (uart=%d, chan=%d)...\n",
            pRxChan->uart,pRxChan->chan, pChannel->uart,pChannel->chan,0,0);

    pRxChan->lastCR |= RX_ENABLE;
    *pRxChan->uartCommandReg = pRxChan->lastCR;

    pChannel->lastCR |= TX_ENABLE;
    *pChannel->uartCommandReg = pChannel->lastCR;

    DRV_LOG(DRV_DEBUG_CMDS,
            "...sent 0x%02x to rx cmd reg, 0x%02x to tx cmd reg.\n",
            pRxChan->lastCR, pChannel->lastCR,0,0,0,0);

} /* sc28l198EnableRxTx() */

/******************************************************************************
 * Disable transmitter and receiver.
 ******************************************************************************/
void 
sc28l198DisableRxTx(SC28L198_DEV_CHAN *pChannel)
{
    SC28L198_DEV_CHAN *pRxChan = SAME_PCHANNEL_IN_OTHER_OCTART(pChannel);

    DRV_LOG(DRV_DEBUG_CMDS,
            "disabling rx (uart=%d, chan=%d) and tx (uart=%d, chan=%d)...\n",
            pRxChan->uart,pRxChan->chan, pChannel->uart,pChannel->chan,0,0);

    pRxChan->lastCR &= ~(RX_ENABLE);
    *pRxChan->uartCommandReg = pRxChan->lastCR;

    pChannel->lastCR &= ~(TX_ENABLE);
    *pChannel->uartCommandReg = pChannel->lastCR;

    DRV_LOG(DRV_DEBUG_CMDS,
            "...sent 0x%02x to rx cmd reg, 0x%02x to tx cmd reg.\n",
            pRxChan->lastCR, pChannel->lastCR,0,0,0,0);

} /* sc28l198DisableRxTx() */


/******************************************************************************
 * Open a channel.
 ******************************************************************************/
LOCAL SC28L198_DEV_CHAN* 
sc28l198Open(SC28L198_DEV_CHAN *pChannel, char *extension, int mode)
{
    DRV_LOG(DRV_DEBUG_OPEN,
            "Open request uart=%d channel=%d extension='%s' mode=%d\n",
            pChannel->uart, pChannel->chan, extension,mode,0,0);

    if( pChannel->chanOpen==TRUE )
    {
        sc28l198Error(0, "Requested device already open\n");
        return((SC28L198_DEV_CHAN*) ERROR);
    }

    /* Indicate that the channel is now open */
    pChannel->chanOpen=TRUE;

    /* Flush input and output buffers         */
    sc28l198Flush(pChannel);     

    /* Reset the channel to a known good state */
    sc28l198ResetChan(pChannel->uart, pChannel->chan);     

    /* Set baud rate and line format options  */
    sc28l198SetBaudRate(pChannel->uart, pChannel->chan, pChannel->baudRate);
    sc28l198ConfigChan(pChannel->uart, pChannel->chan, pChannel->dataBits,
                       pChannel->stopBits, pChannel->parity);

    /* Enable the transmitter and receiver */
    sc28l198EnableRxTx(pChannel);  

    /* Enable the RxFIFO interrupt only */
    sc28l198EnableRxInt(pChannel);

    return(pChannel);

}  /* sc28l198Open() */

/******************************************************************************

*******************************************************************************/
LOCAL int 
sc28l198Close(SC28L198_DEV_CHAN *pChannel)
{
    /* Disable Receiver and Transmitter      */
    sc28l198DisableRxTx(pChannel);

    /* Clear the channel open flag so we can reopen this channel later */
    pChannel->chanOpen = FALSE;

    return(OK);
} /* sc28l198Close() */

/******************************************************************************

*******************************************************************************/
LOCAL int 
sc28l198Read (SC28L198_DEV_CHAN *pChannel, char *buffer, int maxBytes)
{
    DRV_LOG(DRV_DEBUG_READ, "Read request uart=%d channel=%d size=%d\n",
            pChannel->uart, pChannel->chan, maxBytes,0,0,0);

    return(sc28l198BufRead (pChannel, buffer, maxBytes));
} /* sc28l198Read() */

/******************************************************************************

*******************************************************************************/
LOCAL int 
sc28l198Write(SC28L198_DEV_CHAN *pChannel, char *buffer, int nBytes)
{
    DRV_LOG(DRV_DEBUG_WRITE, "Write request uart=%d channel=%d size=%d\n",
            pChannel->uart, pChannel->chan, nBytes,0,0,0);

    return(sc28l198BufWrite(pChannel, buffer, nBytes));
} /* sc28l198Write() */

/******************************************************************************

*******************************************************************************/
LOCAL int 
sc28l198Ioctl(SC28L198_DEV_CHAN *pChannel, int ioctlCode, int *arg)
{
    SC28L198_DEV_CHAN *pRxChan;

    DRV_LOG(DRV_DEBUG_IOCTRL, "IOCTL request uart=%d channel=%d code=%d\n",
            pChannel->uart, pChannel->chan, ioctlCode,0,0,0);

    /* Decide which request is being made     */
    switch(ioctlCode)
    {
        case FIONREAD:
            pRxChan = SAME_PCHANNEL_IN_OTHER_OCTART(pChannel);
            *arg = rngNBytes(pRxChan->rdBuf);
            break;

        case FIONWRITE:
            *arg = rngNBytes(pChannel->wrtBuf);
            break;

        case FIOFLUSH:
            sc28l198Flush(pChannel);
            break;

        case FIORFLUSH:
            sc28l198FlushRd(pChannel);
            break;

        case FIOWFLUSH:
            sc28l198FlushWrt(pChannel);
            break;

        case FIOISATTY:
            return(TRUE);
            break;

        case FIOBAUDRATE:           
            /* Set a channel's baud rate              */
            pChannel->baudRate = sc28l198BaudRate((int) *arg);

            /* Set baud rate to user specified value  */
            sc28l198SetBaudRate(pChannel->uart, pChannel->chan,
                                pChannel->baudRate);
            break;

        default:
            errnoSet (S_ioLib_UNKNOWN_REQUEST);
            return(ERROR);
            break;

    } /* switch */

⌨️ 快捷键说明

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