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

📄 st16c2550sio.c

📁 sbc7410的vxworksbsp
💻 C
📖 第 1 页 / 共 2 页
字号:
/* st16c2550Sio.c - st16c2550 UART tty driver */#include "copyright_wrs.h"/*modification history--------------------01j,01i,01h,01g,01f,01e,01d,01c,01b,01a,02-mar-2005,fzz   derived from st16c2550Serial.c.*//*DESCRIPTIONThis is the driver for the st16c2550 DUART. This device includes two universalasynchronous receiver/transmitters, a baud rate generator, and a completemodem control capability.A ST16C2550_CHAN structure is used to describe the serial channel. This datastructure is defined in st16c2550Sio.h.Only asynchronous serial operation is supported by this driver.The default serial settings are 8 data bits, 1 stop bit, no parity, 9600baud, and software flow control.USAGEThe BSP's sysHwInit() routine typically calls sysSerialHwInit(),which creates the ST16C2550_CHAN structure and initializes all the values in thestructure (except the SIO_DRV_FUNCS) before calling st16c2550DevInit().The BSP's sysHwInit2() routine typically calls sysSerialHwInit2(), whichconnects the chips interrupts via intConnect() (either the singleinterrupt `st16c2550Int' or the three interrupts `st16c2550IntWr', `st16c2550IntRd',and `st16c2550IntEx').This driver handles setting of hardware options such as parity(odd, even) andnumber of data bits(5, 6, 7, 8). Hardware flow control is provided with thehandshakes RTS/CTS. The function HUPCL(hang up on last close) is available.When hardware flow control is enabled, the signals RTS and DTR are set TRUEand remain set until a HUPCL is performed.INCLUDE FILES: drv/sio/ns16552Sio.h*//* includes */#include "vxWorks.h"#include "intLib.h"#include "errnoLib.h"#include "errno.h"#include "sioLib.h"#include "drv/sio/st16c2550Sio.h"/* local defines       */#ifndef SIO_HUP#   define SIO_OPEN 0x100A#   define SIO_HUP  0x100B#endif/* min/max baud rate */#define ST16C2550_MIN_RATE 50#define ST16C2550_MAX_RATE 115200#define REG(reg, pchan) \ (*(volatile UINT8 *)((UINT32)pchan->regs + (reg * pchan->regDelta)))#define REGPTR(reg, pchan) \ ((volatile UINT8 *)((UINT32)pchan->regs + (reg * pchan->regDelta)))/* static forward declarations */LOCAL   int     st16c2550CallbackInstall (SIO_CHAN *, int, STATUS (*)(), void *);LOCAL   STATUS  st16c2550DummyCallback ();LOCAL   void    st16c2550InitChannel (ST16C2550_CHAN *);LOCAL   STATUS  st16c2550BaudSet (ST16C2550_CHAN *, UINT);LOCAL   STATUS  st16c2550ModeSet (ST16C2550_CHAN *, UINT);LOCAL   STATUS  st16c2550Ioctl (ST16C2550_CHAN *, int, int);LOCAL   void    st16c2550TxStartup (ST16C2550_CHAN *);LOCAL   int     st16c2550PollOutput (ST16C2550_CHAN *, char);LOCAL   int     st16c2550PollInput (ST16C2550_CHAN *, char *);LOCAL   STATUS  st16c2550OptsSet (ST16C2550_CHAN *, UINT);LOCAL   STATUS  st16c2550Open (ST16C2550_CHAN * pChan );LOCAL   STATUS  st16c2550Hup (ST16C2550_CHAN * pChan );/* driver functions */static SIO_DRV_FUNCS st16c2550SioDrvFuncs ={    (int (*)())st16c2550Ioctl,    (int (*)())st16c2550TxStartup,    st16c2550CallbackInstall,    (int (*)())st16c2550PollInput,    (int (*)(SIO_CHAN *,char))st16c2550PollOutput};/****************************************************************************** * * st16c2550DummyCallback - dummy callback routine. */LOCAL STATUS st16c2550DummyCallback (void){    return (ERROR);}/****************************************************************************** * * st16c2550DevInit - intialize an ST16C2550 channel * * This routine initializes some SIO_CHAN function pointers and then resets * the chip in a quiescent state.  Before this routine is called, the BSP * must already have initialized all the device addresses, etc. in the * ST16C2550_CHAN structure. * * RETURNS: N/A */void st16c2550DevInit    (    ST16C2550_CHAN * pChan  /* pointer to channel */    ){    int oldlevel = intLock ();    /* initialize the driver function pointers in the SIO_CHAN's */    pChan->pDrvFuncs    = &st16c2550SioDrvFuncs;    /* set the non BSP-specific constants */    pChan->getTxChar    = st16c2550DummyCallback;    pChan->putRcvChar   = st16c2550DummyCallback;    pChan->channelMode  = 0;    /* undefined */    pChan->options      = (CLOCAL | CREAD | CS8);    pChan->mcr      = MCR_OUT2;    pChan->baudRate = 9600;    /* reset the chip */    st16c2550InitChannel (pChan);    intUnlock (oldlevel);}/********************************************************************************* st16c2550InitChannel - initialize UART** Initialize the number of data bits, parity and set the selected* baud rate.* Set the modem control signals if the option is selected.** RETURNS: N/A*/LOCAL void st16c2550InitChannel    (    ST16C2550_CHAN * pChan  /* pointer to channel */    ){    /* set the requested baud rate */        st16c2550BaudSet(pChan, pChan->baudRate);    /* set the options */    st16c2550OptsSet(pChan, pChan->options);}/********************************************************************************* st16c2550OptsSet - set the serial options** Set the channel operating mode to that specified.  All sioLib options* are supported: CLOCAL, HUPCL, CREAD, CSIZE, PARENB, and PARODD.* When the HUPCL option is enabled, a connection is closed on the last* close() call and opened on each open() call.** Note, this routine disables the transmitter.  The calling routine* may have to re-enable it.** RETURNS:* Returns OK to indicate success, otherwise ERROR is returned*/LOCAL STATUS st16c2550OptsSet    (    ST16C2550_CHAN * pChan, /* pointer to channel */    UINT options        /* new hardware options */    ){    FAST int     oldlevel;      /* current interrupt level mask */    pChan->lcr = 0;    pChan->mcr &= (~(MCR_RTS | MCR_DTR)); /* clear RTS and DTR bits */    if ((pChan->chan == 3) || (pChan->chan == 4) )    {        pChan->mcr |= (MCR_DTR | MCR_RTS); /*Tissa  st16c2550 is used as RS422  */        REG(MCR, pChan) = pChan->mcr;    }    if (pChan == NULL || options & 0xffffff00)        return ERROR;    switch (options & CSIZE)    {        case CS5:            pChan->lcr = CHAR_LEN_5; break;        case CS6:            pChan->lcr = CHAR_LEN_6; break;        case CS7:            pChan->lcr = CHAR_LEN_7; break;                default:        case CS8:            pChan->lcr = CHAR_LEN_8; break;    }    if (options & STOPB)        pChan->lcr |= LCR_STB;    else        pChan->lcr |= ONE_STOP;    switch (options & (PARENB | PARODD))    {        case PARENB|PARODD:            pChan->lcr |= LCR_PEN; break;        case PARENB:            pChan->lcr |= (LCR_PEN | LCR_EPS); break;        default:        case 0:            pChan->lcr |= PARITY_NONE; break;    }    REG(IER, pChan) = 0;    if (!(options & CLOCAL))    {    /* !clocal enables hardware flow control(DTR/DSR) */        pChan->mcr |= (MCR_DTR | MCR_RTS);        pChan->ier &= (~TxFIFO_BIT);        pChan->ier |= IER_EMSI;    /* enable modem status interrupt */    }    else        pChan->ier &= ~IER_EMSI; /* disable modem status interrupt */    oldlevel = intLock ();    REG(LCR, pChan) = pChan->lcr;    REG(MCR, pChan) = pChan->mcr;    /* now reset the channel mode registers */    REG(FCR, pChan) = (RxCLEAR | TxCLEAR | FIFO_ENABLE);    if (options & CREAD)        pChan->ier |= RxFIFO_BIT;    if (pChan->channelMode == SIO_MODE_INT)    {        REG(IER, pChan) = pChan->ier;    }    intUnlock (oldlevel);    pChan->options = options;    return OK;}/********************************************************************************* st16c2550Hup - hang up the modem control lines** Resets the RTS and DTR signals and clears both the receiver and* transmitter sections.** RETURNS: OK*/LOCAL STATUS st16c2550Hup    (    ST16C2550_CHAN * pChan  /* pointer to channel */    ){    FAST int     oldlevel;  /* current interrupt level mask */    oldlevel = intLock ();    pChan->mcr &= (~(MCR_RTS | MCR_DTR));    REG(MCR, pChan) = pChan->mcr;    REG(FCR, pChan) = (RxCLEAR | TxCLEAR);    intUnlock (oldlevel);    return (OK);}/********************************************************************************* st16c2550Open - Set the modem control lines** Set the modem control lines(RTS, DTR) TRUE if not already set.* It also clears the receiver, transmitter and enables the fifo.** RETURNS: OK*/LOCAL STATUS st16c2550Open    (    ST16C2550_CHAN * pChan  /* pointer to channel */    ){    FAST int     oldlevel;  /* current interrupt level mask */    char mask;    mask = REG(MCR, pChan) & (MCR_RTS | MCR_DTR);    if (mask != (MCR_RTS | MCR_DTR))    {        /* RTS and DTR not set yet */        oldlevel = intLock ();        /* set RTS and DTR TRUE */        pChan->mcr |= (MCR_DTR | MCR_RTS);        REG(MCR, pChan) = pChan->mcr;        /* clear Tx and receive and enable FIFO */        REG(FCR, pChan) = (RxCLEAR | TxCLEAR | FIFO_ENABLE);        intUnlock (oldlevel);    }    return (OK);}/******************************************************************************** st16c2550BaudSet - change baud rate for channel** This routine sets the baud rate for the UART. The interrupts are disabled* during chip access.** RETURNS: OK*/LOCAL STATUS  st16c2550BaudSet    (    ST16C2550_CHAN * pChan, /* pointer to channel */    UINT       baud     /* requested baud rate */    ){    int   oldlevel;    /* disable interrupts during chip access */    oldlevel = intLock ();    /* Enable access to the divisor latches by setting DLAB in LCR. */    REG(LCR, pChan) = LCR_DLAB | pChan->lcr;    /* Set divisor latches. */    REG(DLL, pChan) = pChan->xtal/(16 * baud);    REG(DLM, pChan) = (pChan->xtal/(16 * baud)) >> 8;    /* Restore line control register */    REG(LCR, pChan) = pChan->lcr;    pChan->baudRate = baud;    intUnlock (oldlevel);    return (OK);}/********************************************************************************* st16c2550ModeSet - change channel mode setting** This driver supports both polled and interrupt modes and is capable of* switching between modes dynamically.** If interrupt mode is desired this routine enables the channels receiver and* transmitter interrupts. If the modem control option is TRUE, the Tx interrupt* is disabled if the CTS signal is FALSE. It is enabled otherwise.** If polled mode is desired the device interrupts are disabled.** RETURNS:* Returns a status of OK if the mode was set else ERROR.*/LOCAL STATUS st16c2550ModeSet    (    ST16C2550_CHAN * pChan, /* pointer to channel */    UINT    newMode     /* mode requested */    ){    FAST int     oldlevel;  /* current interrupt level mask */    char mask;    if ((newMode != SIO_MODE_POLL) && (newMode != SIO_MODE_INT))    return (ERROR);

⌨️ 快捷键说明

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