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

📄 cd2400sio.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* cd2400Sio.c - CL-CD2400 MPCC serial driver *//* Copyright 1984-1995 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01h,20nov96,dds  SPR 5438: Added interrupt locking to cd2400Startup () routine.01g,01dec95,myz  removed waiting for transmitter done loop in ioctl SIO_MODE_SET01f,16nov95,myz  reworked SPR #4678 about the baud rate problem with WDB agent01e,08sep95,myz  fixed the SPR #467801d,03aug95,myz  fixed the warning messages01c,20jun95,ms	 fixed comments for mangen01b,15jun95,ms   updated for new driver structure01a,05mar95,myz  written (using cd2400Serial.c + the VxMon polled driver).*//*DESCRIPTIONThis is the driver for the Cirus Logic CD2400 MPCC.  It uses the SCC's inasynchronous mode.USAGEA CD2400_QUSART structure is used to describe the chip. This data structurecontains four CD2400_CHAN structure which describe the chip's four serialchannels.The BSP's sysHwInit() routine typically calls sysSerialHwInit()which initializes all the values in the CD2400_QUSART structure (exceptthe SIO_DRV_FUNCS) before calling cd2400HrdInit().The BSP's sysHwInit2() routine typically calls sysSerialHwInit2() whichconnects the chips interrupts (cd2400Int, cd2400IntRx, andcd2400IntTx) via intConnect().IOCTL FUNCTIONSThis driver responds to the same ioctl() codes as a normal serial driver; formore information, see the comments in sioLib.h.  The available baud ratesare:  50, 110, 150, 300, 600, 1200, 2400, 3600, 4800, 7200, 9600,19200, and 38400.INCLUDE FILES: drv/sio/cd2400Sio.h*/#include "vxWorks.h"#include "sioLib.h"#include "intLib.h"#include "errno.h"#include "drv/sio/cd2400Sio.h"#define DEFAULT_BAUD	9600/* forward declarations */static int      cd2400Ioctl    (SIO_CHAN *, int, void *);static int      cd2400Startup  (SIO_CHAN * );static int      cd2400PRxChar  (SIO_CHAN *, char *);static int      cd2400PTxChar  (SIO_CHAN *, char);static void     cd2400ChanIntEnDisable (CD2400_CHAN *, int);static void     cd2400SetMode  (CD2400_CHAN *, int);static int      cd2400CallbackInstall (SIO_CHAN *, int, STATUS (*)(), void *);static void     cd2400InitChannel(CD2400_CHAN *);/* channel descriptors */typedef struct			/* BAUD */    {    USHORT rate;		/* baud rate */    USHORT timeConstant;	/* time constant */    char tcor;			/* transmit clock option register value */    char rcor;			/* receive clock option register value */    } BAUD;static BAUD baudTable [] =    {     {    50, 2048, (unsigned char)TCOR_CLK4, RCOR_CLK4 },     {   110, 2048, (unsigned char)TCOR_CLK4, RCOR_CLK4 },     {   150, 2048, (unsigned char)TCOR_CLK4, RCOR_CLK4 },     {   300, 512,                 TCOR_CLK3, RCOR_CLK3 },     {   600, 512,                 TCOR_CLK3, RCOR_CLK3 },     {  1200, 128,                 TCOR_CLK2, RCOR_CLK2 },     {  2400, 128,                 TCOR_CLK2, RCOR_CLK2 },     {  3600, 32,                  TCOR_CLK1, RCOR_CLK1 },     {  4800, 32,                  TCOR_CLK1, RCOR_CLK1 },     {  7200, 32,                  TCOR_CLK1, RCOR_CLK1 },     {  9600, 32,                  TCOR_CLK1, RCOR_CLK1 },     { 19200, 8,                   TCOR_CLK0, RCOR_CLK0 },     { 38400, 8,                   TCOR_CLK0, RCOR_CLK0 }    };/* local driver function table */static SIO_DRV_FUNCS cd2400SioDrvFuncs =    {    (int (*)())cd2400Ioctl,    (int (*)())cd2400Startup,    cd2400CallbackInstall,    (int (*)())cd2400PRxChar,    (int (*)(SIO_CHAN *,char))cd2400PTxChar    };/********************************************************************************* cd2400HrdInit - initialize the chip** This routine initializes the chip and the four channels.*/void cd2400HrdInit    (    CD2400_QUSART * pQusart		/* chip to reset */    )    {    FAST int   oldlevel;	/* current interrupt level mask */    int	ix;    oldlevel = intLock ();      /* disable interrupts during init */    /* make sure the driver function pointers are installed */    for (ix = 0; ix < N_CHANNELS; ix++)	pQusart->channel[ix].pDrvFuncs      = &cd2400SioDrvFuncs;    while (*MPCC_CCR)	;			/* make sure no outstanding commands */    *MPCC_CCR = CCR_RESET_ALL;	/* reset chip */    while (*MPCC_CCR)	;			/* make sure we are done */    while (*MPCC_GFRCR == 0)	;			/* wait for it to be non-zero */    *MPCC_TPR = 0x0a;		/* Timer Peroid Register */    *MPCC_PILR1 = 0x00;		/* Priority Interrupt Level Register */    *MPCC_PILR2 = 0x02;		/* Priority Interrupt Level Register */    *MPCC_PILR3 = 0x03;		/* Priority Interrupt Level Register */    for (ix = 0; ix < N_CHANNELS; ix++)	cd2400InitChannel (&pQusart->channel[ix]);    intUnlock (oldlevel);    }/********************************************************************************* cd2400InitChannel - initialize a single channel*/static void cd2400InitChannel    (    CD2400_CHAN *	pChan		/* channel to reset */    )    {    int        oldlevel;		/* current interrupt level mask */    CD2400_QUSART * pQusart = pChan->pQusart;    oldlevel = intLock ();		/* disable interrupts during init */    /* initialize registers */    *MPCC_CAR  = pChan->chan_num;    *MPCC_LIVR = pChan->int_vec;    *MPCC_COR1 = COR1_NO_PARITY	|		 COR1_8BITS;    *MPCC_COR2 = 0x00;    *MPCC_COR3 = COR3_1STOP_BIT;    *MPCC_COR4 = 0x00;	/* no modem control for now */    *MPCC_COR5 = 0x00;	/* no modem control for now */    *MPCC_COR6 = COR6_NORMAL_CR_NL	|		 COR6_BRK_EXCEPTION	|		 COR6_PARITY_EXCEPTION;    *MPCC_COR7 = COR7_NORMAL_CR_NL;    *MPCC_CMR = CMR_RX_INTERRUPT	|		CMR_TX_INTERRUPT	|		CMR_ASYNC_MODE;    *MPCC_TBPR = BPR_9600;    *MPCC_TCOR = TCOR_CLK1;    *MPCC_RBPR = BPR_9600;    *MPCC_RCOR = RCOR_CLK1;    *MPCC_CPSR = CPSR_CRC_V41;    *MPCC_SCHR1 = 0x00;    *MPCC_SCHR2 = 0x00;    *MPCC_SCHR3 = 0x00;		/* Special Char Reg 3 */    *MPCC_SCHR4 = 0x00;		/* Special Char Reg 4 */    *MPCC_SCRL = 0x00;		/* Special Char Range Low */    *MPCC_SCRH = 0x00;		/* Special Char Range High */    *MPCC_RTPRL = 0x01;		/* set timeout high - ONLY DMA mode */    *MPCC_RTPRH = 0x00;		/* so this should not be used for now */    while (*MPCC_CCR)	;			/* make sure no outstanding commands */    *MPCC_CCR = CCR_INIT_CHANNEL;    while (*MPCC_CCR)	;			/* make sure we are done */    *MPCC_CCR = CCR_ENABLE_TRANS	|		CCR_ENABLE_REC;	/* enable Tx and Rx */    while (*MPCC_CCR)	;    *MPCC_IER = 0;       /* disable interrupt */    *MPCC_MSVRDTR = MSVR_DTR;    *MPCC_MSVRRTS = MSVR_RTS;    pChan->created = TRUE;    intUnlock (oldlevel);    }/********************************************************************************* cd2400Ioctl - special device control** This routine handles SIO_BAUD_SET and SIO_RESET requests.** RETURNS: OK on success, EIO on device error, ENOSYS on unsupported*          request.*/static int cd2400Ioctl    (    SIO_CHAN * 	pSioChan,	/* device to control */    int		request,	/* request code      */    void *	arg		/* some argument     */    )    {    int		oldlevel;		/* current interrupt level mask */    FAST int	ix;    STATUS	status;    USHORT        rcvBaud;    char        rcvFreq;    CD2400_QUSART * pQusart = ((CD2400_CHAN *)pSioChan)->pQusart;    switch (request)	{	case SIO_BAUD_SET:	    status = EIO;		/* baud rate out of range */	    /* disable interrupts during chip access */	    oldlevel = intLock ();	    *MPCC_CAR = ((CD2400_CHAN *)pSioChan)->chan_num; /*  channel */	    for (ix = 0; ix < NELEMENTS (baudTable); ix++)		{		if (baudTable [ix].rate == (int)arg)		    {		    *MPCC_TBPR = ( (pQusart->baudClkFreq /				   baudTable [ix].timeConstant) /				  (int)arg ) - 1;		    *MPCC_TCOR = baudTable [ix].tcor;		    *MPCC_RBPR = ( (pQusart->baudClkFreq /                                   baudTable [ix].timeConstant) /                                  (int)arg ) - 1;		    *MPCC_RCOR = baudTable [ix].rcor;		    status = OK;		    break;		    }		}	    intUnlock (oldlevel);	    break;        case SIO_BAUD_GET:            status = EIO;               /* baud rate out of range */            /* disable interrupts during chip access */            oldlevel = intLock ();            *MPCC_CAR = ((CD2400_CHAN *)pSioChan)->chan_num; /*  channel */            rcvBaud = (unsigned char)(*MPCC_RBPR);	    rcvFreq = (*MPCC_RCOR) & 0x7;  /* masked off unwanted bits */             for (ix = 0; ix < NELEMENTS (baudTable); ix++)                {                if ( (rcvBaud == ( (pQusart->baudClkFreq /                    baudTable [ix].timeConstant) / baudTable [ix].rate) - 1) &&		    (rcvFreq == baudTable [ix].rcor) )                    {                    *(int *)arg = baudTable [ix].rate;                    status = OK;                    }                }             intUnlock (oldlevel);            break;        case SIO_MODE_SET:            if (!((int)arg == SIO_MODE_POLL || (int)arg == SIO_MODE_INT))                {                status = EIO;                break;                }            /* lock interrupt  */            oldlevel = intLock();	    cd2400SetMode ((CD2400_CHAN *)pSioChan, (int)arg);            ((CD2400_CHAN *)pSioChan)->channelMode = (int)arg;

⌨️ 快捷键说明

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