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

📄 m68302sio.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* m68302Sio.c - Motorola MC68302 bimodal tty driver *//* Copyright 1984-1996 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01g,11jul97,dgp  doc: correct ttyDrv and tyLib in SEE ALSO01f,20jun97,map  fixed RX event clear [SPR# 8803]01e,12dec96,map  handle non-DPRAM buffers [SPR# 7479]01d,06nov96,dgp  doc: final formatting01c,30may96,dat  More ISR work, work on ModeSet().01b,24may96,dat  fixed ISR and modeSet rtn, new baud rate setup		 added polled mode operation.01a,01mar96,dat  written (from m68302Serial.c).*//*DESCRIPTIONThis is the driver for the internal communications processor (CP)of the Motorola MC68302.USER-CALLABLE ROUTINESMost of the routines in this driver are accessible only through the I/Osystem.  Before the driver can be used, it must be initialized by calling theroutines m68302SioInit() and m68302SioInit2().Normally, they are called by sysSerialHwInit() and sysSerialHwInit2()in sysSerial.cThis driver uses 408 bytes of buffer space as follows:  128 bytes for portA tx buffer  128 bytes for portB tx buffer  128 bytes for portC tx buffer    8 bytes for portA rx buffers (8 buffers, 1 byte each)    8 bytes for portB rx buffers (8 buffers, 1 byte each)    8 bytes for portC rx buffers (8 buffers, 1 byte each)The buffer pointer in the `m68302cp' structure points to the buffer area,which is usually specified as IMP_BASE_ADDR.INTERNALThere is only one Tx buffer for each SCC device.  This is probably becauseSCC1 and SCC2 can have 8 buffers each, but SCC3 can only have 4.Hardware abstraction isn't used in this driver.  These SCCs are internalto the CPU.  It doesn't seem to make sense to abstract it under thatcondition - i.e. it can't be used with any other CPU.IOCTL FUNCTIONSThis driver responds to the same ioctl() codes as a normal tty driver; formore information, see the manual entry for tyLib.  The available baudrates are 300, 600, 1200, 2400, 4800, 9600 and 19200.SEE ALSOttyDrv, tyLibINCLUDE FILES: drv/sio/m68302Sio.h sioLib.h*/#include "vxWorks.h"#include "sioLib.h"#include "intLib.h"#include "errno.h"#include "drv/sio/m68302Sio.h"#define MIN_BRG_DIV 	3#define MAX_BRG_DIV 	2047#define RX_BD_NUM 	8	/* number of receiver BDs */#define DPRAM_START	(char *)((*IMP_BAR & 0x0fff) << 12)#define DPRAM_END	(DPRAM_START + 0x0fff)/* forward LOCAL declarations */LOCAL	int	m68302SioTxStartup (SIO_CHAN * pSioChan);LOCAL	int	m68302SioCallbackInstall (SIO_CHAN *pSioChan, int callbackType,				STATUS (*callback)(), void *callbackArg);LOCAL	int	m68302SioPollOutput (SIO_CHAN *pSioChan, char	outChar);LOCAL	int	m68302SioPollInput (SIO_CHAN *pSioChan, char *thisChar);LOCAL	int	m68302SioIoctl (SIO_CHAN *pSioChan, int request, void *arg);LOCAL	void	m68302SioChanInit (M68302_CHAN *pChan, M68302_CP *pCp);LOCAL	STATUS	dummyCallback (void);LOCAL	int	m68302ModeSet (M68302_CHAN *, uint_t);LOCAL	int	m68302BaudSet (M68302_CHAN *, int);/* local variables */#ifndef DEFAULT_BAUD#   define DEFAULT_BAUD 9600#endifLOCAL SIO_DRV_FUNCS m68302SioDrvFuncs =    {    m68302SioIoctl,    m68302SioTxStartup,    m68302SioCallbackInstall,    m68302SioPollInput,    m68302SioPollOutput    };/******************************************************************************** m68302SioInit - initialize a M68302_CP** This routine initializes the driver* function pointers and then resets the chip to a quiescent state.* The BSP must already have initialized all the device addresses and the* `baudFreq' fields in the M68302_CP structure before passing it to this* routine. The routine resets the device and initializes everything to support * polled mode (if possible), but does not enable interrupts.** RETURNS: N/A*/void m68302SioInit    (    M68302_CP * pCp    )    {    int oldlevel = intLock ();			/* LOCK INTERRUPTS */    /* reset the chip */    *pCp->pCr =  (char) (CR_RST | CR_FLG);    while (*pCp->pCr != 0) 		/* Wait for reset to finish */	/* do nothing */ ;    *pCp->pImr 	  = 0;    *pCp->pSiMask = 0xffff;    *pCp->pSiMode = 0x0000;		/* NMSI for all channels */    pCp->intEnable= FALSE;		/* disable int mode for now */    m68302SioChanInit (&pCp->portA, pCp);    m68302SioChanInit (&pCp->portB, pCp);    m68302SioChanInit (&pCp->portC, pCp);    intUnlock (oldlevel);			/* UNLOCK INTERRUPTS */    }/******************************************************************************** m68302SioInit2 - initialize a M68302_CP (part 2)** Enables interrupt mode of operation.** RETURNS: N/A*/void m68302SioInit2    (    M68302_CP * pCp    )    {    pCp->intEnable = TRUE;    /* reset mode, since it may have changed */    m68302ModeSet (&pCp->portA, pCp->portA.mode);    m68302ModeSet (&pCp->portB, pCp->portB.mode);    m68302ModeSet (&pCp->portC, pCp->portC.mode);    *pCp->pImr |= pCp->imrMask;/* unmask int */    }/*********************************************************************** m68302SioChanInit - initialize a single channel** Initialize a single channel of the Communications Processor.  The* default initialization places the channel in UART protocol.** If the pScc pointer is null, then this channel will not be initialized.* This is used to prevent initialization of a non-existant SCC channel* on some CPU variants.** RETURNS: N/A*/LOCAL void m68302SioChanInit    (    M68302_CHAN *pChan,    M68302_CP *pCp    )    {    int		frame;    int		baud;    int		bdLocFlag=0;    if (pChan == NULL     || pChan->pScc == NULL)	return;    if ((pCp->buffer < DPRAM_START) || (pCp->buffer > DPRAM_END))        bdLocFlag = UART_RX_BD_EXT;    pChan->sio.pDrvFuncs= &m68302SioDrvFuncs;    pChan->getTxChar    = dummyCallback;    pChan->putRcvChar	= dummyCallback;    pChan->pCp		= pCp;    pChan->pSccReg->scon= 0x0;    baud = (pChan->baud <= 0 ? DEFAULT_BAUD : pChan->baud);    m68302SioIoctl (&pChan->sio, SIO_BAUD_SET, (void *)baud);    pChan->mode = SIO_MODE_POLL;    /* 8 data bits, 1 stop bit, no parity, Rcvr enabled */    pChan->options = (CREAD | CS8);    pChan->pSccReg->scm = UART_SCM_ASYNC | UART_SCM_MANUAL |			  UART_SCM_8BIT | UART_SCM_RTSM;    pChan->pSccReg->dsr		= 0x7e7e;	/* no fractional stop bits */    pChan->pParam->rfcr		= 0x50;		/* sup. data access */    pChan->pParam->tfcr		= 0x50;		/* sup. data access */    pChan->pParam->mrblr	= 0x1;		/* one character rx buffers */    /* next receive buffer */    pChan->rxBdNext	= 0;    for (frame = 0; frame < 8; frame ++)	{	pChan->pScc->rxBd[frame].statusMode	= bdLocFlag | UART_RX_BD_EMPTY						    | UART_RX_BD_INT;	pChan->pScc->rxBd[frame].dataLength	= 1;	pChan->pScc->rxBd[frame].dataPointer	=			(char *)((pChan->channel << 3) + frame + 0x180				+ (int)pCp->buffer);	}    pChan->pScc->rxBd[RX_BD_NUM-1].statusMode	|= UART_RX_BD_WRAP;    pChan->pScc->txBd[0].statusMode	= bdLocFlag | UART_TX_BD_INT        				  | UART_TX_BD_WRAP;    pChan->pScc->txBd[0].dataLength	= 0x80;    pChan->pScc->txBd[0].dataPointer	= (char *)(pChan->channel * 0x80 +					  (int)pCp->buffer);    pChan->pProt->maxIdl	= 0x0;    pChan->pProt->idlc		= 0x0;    pChan->pProt->brkcr		= 0x0;    pChan->pProt->parec		= 0x0;    pChan->pProt->frmec		= 0x0;    pChan->pProt->nosec		= 0x0;    pChan->pProt->brkec		= 0x0;    pChan->pProt->uaddr1	= 0x0;    pChan->pProt->uaddr2	= 0x0;    pChan->pProt->cntChar1	= 0x8000;    pChan->pSccReg->scce = 0xff;		/* clr all events */    pChan->pSccReg->sccm = 0; 		/* mask all events for now */    pChan->pSccReg->scm |= UART_SCM_ENR | UART_SCM_ENT; /* enable RX,TX */    }/********************************************************************************* m68302SioInt - handle an SCC interrupt** This routine gets called to handle SCC interrupts.** RETURNS: N/A.** NOMANUAL*/void m68302SioInt    (    M68302_CHAN *pChan    )    {    char outChar;    FAST UINT16   dataLen = 0;    FAST UINT8    event = pChan->pSccReg->scce;    /* acknowledge interrupt */    pChan->pSccReg->scce= event;		/* clear events */    /* restrict ourselves to interrupt events, not polled events */    event &= pChan->pSccReg->sccm;    *pChan->pCp->pIsr = pChan->intAck;	/* ack. interrupt */    /* a negative channel # indicates an inactive channel */    if (pChan->channel < 0)	return;    if (event & UART_SCCE_TX)	{	/* fill buffer with data */	while (dataLen <= 0x80	    && pChan->mode != SIO_MODE_POLL	    && (pChan->getTxChar)(pChan->getTxArg, &outChar) == OK)	    {	    pChan->pScc->txBd[0].dataPointer[dataLen++] = outChar;	    }	/* handoff buffer to device */	if (dataLen > 0)	    {	    pChan->pScc->txBd[0].dataLength  = dataLen;	    pChan->pScc->txBd[0].statusMode |= UART_TX_BD_READY;	    }	}    /* Rx buffers are 1 chara in length, get all available */    if (event & UART_SCCE_RX)	{	int nextBd = pChan->rxBdNext;	while (!(pChan->pScc->rxBd[nextBd].statusMode & UART_RX_BD_EMPTY)	    && pChan->mode != SIO_MODE_POLL )	    {	    char data;	    data = pChan->pScc->rxBd[nextBd].dataPointer[0];	    pChan->pScc->rxBd[nextBd].statusMode |= UART_RX_BD_EMPTY;	    nextBd = (nextBd + 1) % RX_BD_NUM;	    pChan->rxBdNext = nextBd;	    (*pChan->putRcvChar) (pChan->putRcvArg, data);	    }	}    /* all other events ignored */    }/******************************************************************************** m68302SioTxStartup - start the interrupt transmitter** This routine is called from ttyDrv to start the transmitter when data* is ready to go out.  TtyDrv keeps track of the transmitter status and only* calls this routine when needed to startup character output.** RETURNS:* Returns OK on success, ENOSYS if the device is polled-only, or* EIO on hardware error.*/LOCAL int m68302SioTxStartup    (    SIO_CHAN * pSioChan		/* channel to start */    )    {    char outChar;    FAST int dataLen = 0;    M68302_CHAN *pChan = (M68302_CHAN *)pSioChan;    if (!(pChan->pScc->txBd[0].statusMode & UART_TX_BD_READY))

⌨️ 快捷键说明

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