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

📄 ppc860sccsio.c

📁 其中包括88796网卡驱动、mbmflash驱动、i2c接口的eeprom驱动、oki的ml9620can网卡驱动、扩展的串口驱动源代码。适用于moto的ppc8××系列在vxworks环境下。
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "vxWorks.h"
#include "intLib.h"
#include "errno.h"
#include "sioLib.h"
#include "drv/multi/ppc860Siu.h"
#include "drv/multi/ppc860Cpm.h"
#include "drv/sio/ppc860Sio.h"

#define DEFAULT_BAUD 9600	/* default baudrate */

SCC_UART_PROTO *scc1Param;	/* the uart protocal parameter ram of scc1 */
SCC_UART_PROTO *scc2Param;	/* the uart protocal parameter ram of scc2 */
SCC_UART_PROTO *scc3Param;	/* the uart protocal parameter ram of scc3 */
SCC_UART_PROTO *scc4Param;	/* the uart protocal parameter ram of scc4 */

static STATUS ppc860SccIoctl (PPC860SCC_CHAN *pChan,int request,int arg);
static void   ppc860SccResetChannel (PPC860SCC_CHAN *pChan);
static int    ppc860SccPollOutput (SIO_CHAN *,char);
static int    ppc860SccPollInput (SIO_CHAN *,char *);
static void   ppc860SccStartup (PPC860SCC_CHAN *);
static int    ppc860SccCallbackInstall (SIO_CHAN *, int, STATUS (*)(), void *);

static SIO_DRV_FUNCS ppc860SccSioDrvFuncs =
    {
    (int (*)())			ppc860SccIoctl,
    (int (*)())			ppc860SccStartup,
    (int (*)())			ppc860SccCallbackInstall,
    (int (*)())			ppc860SccPollInput,
    (int (*)(SIO_CHAN *,char))	ppc860SccPollOutput
};

/*******************************************************************************
*
* ppc860SccDevInit - initialize the SCC
*
* This routine is called to initialize the chip to a quiescent state.
* Note that the `sccNum' field of PPC860SCC_CHAN must be either 1 or 2.
*/
void ppc860SccDevInit(PPC860SCC_CHAN *pChan)
{
    int	scc;
    
    scc=pChan->uart.sccNum-1;
    
    /* masks off this SCC's interrupt. */
	
    * CIMR(pChan->regBase) &= ~(CIMR_SCC1>>scc);

    pChan->baudRate  = DEFAULT_BAUD;
    pChan->pDrvFuncs = &ppc860SccSioDrvFuncs;
}

/*******************************************************************************
*
* ppc860SccResetChannel - initialize the SCC
*/

static void ppc860SccResetChannel(PPC860SCC_CHAN *pChan)
{
	int scc;
	int baud;
	int frame;
	
	int oldLevel=intLock();
	
	scc=pChan->uart.sccNum-1;
	baud=pChan->bgrNum-1;
	pChan->uart.intMask=CIMR_SCC1>>scc;
	
	switch(baud)
	{
		case 0:		
			*SICR(pChan->regBase)|=((SICR_R1CS_BRG1<<(scc*8))|(SICR_T1CS_BRG1<<(scc*8)));
			break;
		case 1:		
			*SICR(pChan->regBase)|=((SICR_R1CS_BRG2<<(scc*8))|(SICR_T1CS_BRG2<<(scc*8)));
			break;
		case 2:		
			*SICR(pChan->regBase)|=((SICR_R1CS_BRG3<<(scc*8))|(SICR_T1CS_BRG3<<(scc*8)));
			break;
		case 3:
			*SICR(pChan->regBase)|=((SICR_R1CS_BRG4<<(scc*8))|(SICR_T1CS_BRG4<<(scc*8)));
			break;
	}
	
	  /* reset baud rate generator, wait for reset to clear... */
 
    	*pChan->pBaud |= BRGC_RST;
   	 while (*pChan->pBaud & BRGC_RST);
   	 
   	 ppc860SccIoctl (pChan, SIO_BAUD_SET, pChan->baudRate);
   	 
   	 /* set up transmit buffer descriptors */

    	pChan->uart.txBdBase = (SCC_BUF *) (pChan->regBase +
    				((UINT32) pChan->uart.txBdBase ));
   		pChan->uart.pScc->param.tbase = (UINT16) ((UINT32) pChan->uart.txBdBase);
   		pChan->uart.pScc->param.tbptr = (UINT16) ((UINT32) pChan->uart.txBdBase);
    	pChan->uart.txBdNext = 0;
    	 /* initialize each transmit buffer descriptor */

    	for (frame = 0; frame < pChan->uart.txBdNum; frame++)
        {
        	pChan->uart.txBdBase[frame].statusMode = BD_TX_INTERRUPT_BIT;

        	pChan->uart.txBdBase[frame].dataPointer = pChan->uart.txBufBase +
                                                (frame * pChan->uart.txBufSize);
        }
          /* set the last BD to wrap to the first */

    	pChan->uart.txBdBase[(frame - 1)].statusMode |= BD_TX_WRAP_BIT;

    	/* set up receive buffer descriptors */

   	 	pChan->uart.rxBdBase = (SCC_BUF *) (pChan->regBase +
		         	((UINT32) pChan->uart.rxBdBase ));

    	pChan->uart.pScc->param.rbase = (UINT16) ((UINT32) pChan->uart.rxBdBase);
    	pChan->uart.pScc->param.rbptr = (UINT16) ((UINT32) pChan->uart.rxBdBase);
    	pChan->uart.rxBdNext = 0;

   	 /* initialize each receive buffer descriptor */
	
   	 for (frame = 0; frame < pChan->uart.rxBdNum; frame++)
        {
        	pChan->uart.rxBdBase[frame].statusMode = BD_RX_EMPTY_BIT |
						 BD_RX_INTERRUPT_BIT;
        	pChan->uart.rxBdBase[frame].dataLength = 0; /* char oriented */
        	pChan->uart.rxBdBase[frame].dataPointer = pChan->uart.rxBufBase +frame;
        }
	/* set the last BD to wrap to the first */

    	pChan->uart.rxBdBase[(frame - 1)].statusMode |= BD_RX_WRAP_BIT;	
    	
    	/* initialize the SCC parameter ram */
    	pChan->uart.pScc->param.rfcr   = 0x18;	/* supervisor data access */
    	pChan->uart.pScc->param.tfcr   = 0x18;	/* supervisor data access */
    	pChan->uart.pScc->param.mrblr  = 0x01;	/* 64 character rx buffers */
    	
    	switch(scc)
    	{
    		case 0:
    			scc1Param=(SCC_UART_PROTO *)pChan->uart.pScc->prot;
    			scc1Param->maxIdl=0x10;
    			scc1Param->brkcr=0x0001;
    			scc1Param->parec=0x00;
    			scc1Param->frmer=0x00;
    			scc1Param->nosec=0x00;
    			scc1Param->brkec=0x00;
    			scc1Param->uaddr1=0x00;
    			scc1Param->uaddr2=0x00;
    			scc1Param->toseq=0x00;
    			scc1Param->character1=0x8000;
    			scc1Param->character2=0x8000;
    			scc1Param->character3=0x8000;
    			scc1Param->character4=0x8000;
    			scc1Param->character5=0x8000;
    			scc1Param->character6=0x8000;
    			scc1Param->character7=0x8000;
    			scc1Param->character8=0x8000;
    			scc1Param->rccm=0xc0ff;
    			break;
    			
    		case 1:
    			scc2Param=(SCC_UART_PROTO *)pChan->uart.pScc->prot;
    			scc2Param->maxIdl=0x10;
    			scc2Param->brkcr=0x0001;
    			scc2Param->parec=0x00;
    			scc2Param->frmer=0x00;
    			scc2Param->nosec=0x00;
    			scc2Param->brkec=0x00;
    			scc2Param->uaddr1=0x00;
    			scc2Param->uaddr2=0x00;
    			scc2Param->toseq=0x00;
    			scc2Param->character1=0x8000;
    			scc2Param->character2=0x8000;
    			scc2Param->character3=0x8000;
    			scc2Param->character4=0x8000;
    			scc2Param->character5=0x8000;
    			scc2Param->character6=0x8000;
    			scc2Param->character7=0x8000;
    			scc2Param->character8=0x8000;
    			scc2Param->rccm=0xc0ff;
    			break;
    			
    		case 2:
    			scc3Param=(SCC_UART_PROTO *)pChan->uart.pScc->prot;
    			scc3Param->maxIdl=0x10;
    			scc3Param->brkcr=0x0001;
    			scc3Param->parec=0x00;
    			scc3Param->frmer=0x00;
    			scc3Param->nosec=0x00;
    			scc3Param->brkec=0x00;
    			scc3Param->uaddr1=0x00;
    			scc3Param->uaddr2=0x00;
    			scc3Param->toseq=0x00;
    			scc3Param->character1=0x8000;
    			scc3Param->character2=0x8000;
    			scc3Param->character3=0x8000;
    			scc3Param->character4=0x8000;
    			scc3Param->character5=0x8000;
    			scc3Param->character6=0x8000;
    			scc3Param->character7=0x8000;
    			scc3Param->character8=0x8000;
    			scc3Param->rccm=0xc0ff;
    			break;
    			
    		case 3:
    			scc4Param=(SCC_UART_PROTO *)pChan->uart.pScc->prot;
    			scc4Param->maxIdl=0x10;
    			scc4Param->brkcr=0x0001;
    			scc4Param->parec=0x00;
    			scc4Param->frmer=0x00;
    			scc4Param->nosec=0x00;
    			scc4Param->brkec=0x00;
    			scc4Param->uaddr1=0x00;
    			scc4Param->uaddr2=0x00;
    			scc4Param->toseq=0x00;
    			scc4Param->character1=0x8000;
    			scc4Param->character2=0x8000;
    			scc4Param->character3=0x8000;
    			scc4Param->character4=0x8000;
    			scc4Param->character5=0x8000;
    			scc4Param->character6=0x8000;
    			scc4Param->character7=0x8000;
    			scc4Param->character8=0x8000;
    			scc4Param->rccm=0xc0ff;
    			break;
    		
    	}
    	/* clear all events */

    	pChan->uart.pSccReg->scce = 0xffff;
    	
    	/* enables the transmitter and receiver  */

    	pChan->uart.pSccReg->sccm=0x03;
    	
    	pChan->uart.pSccReg->gsmrh=0x20;
    	pChan->uart.pSccReg->gsmrl=0x28004;
    	pChan->uart.pSccReg->psmr=0x3000;
    	pChan->uart.pSccReg->gsmrl|=0x30;
    	
    	*CIMR(pChan->regBase) |= pChan->uart.intMask;
    	 intUnlock (oldLevel);			/* UNLOCK INTERRUPTS */
}

/*******************************************************************************
*
* ppc860SccIoctl - special device control
*
* RETURNS: OK on success, EIO on device error, ENOSYS on unsupported
*          request.
*
*/

LOCAL STATUS ppc860SccIoctl
    (
    PPC860SCC_CHAN *	pChan,		/* device to control */
    int			request,	/* request code */
    int			arg		/* some argument */
    )
    {
    int		baudRate;
    int 	oldlevel;
    STATUS 	status = OK;

    switch (request)
	{
	case SIO_BAUD_SET:
            if (arg >=  50 && arg <= 38400)	/* could go higher... */
		{
		/* calculate proper counter value, then enable BRG */

		baudRate = (pChan->clockRate + (8 * arg)) / (16 * arg);

		if (--baudRate > 0xfff)
		    *pChan->pBaud = (BRGC_CD_MSK &
		    (((baudRate + 8) / 16) << BRGC_CD_SHIFT)) | BRGC_EN |
		    BRGC_DIV16;
                else
                    *pChan->pBaud = (BRGC_CD_MSK & 
			(baudRate << 1)) | BRGC_EN;

                pChan->baudRate = arg;
		}
            else
	        status = EIO;
	    break;
    
	case SIO_BAUD_GET:
	    * (int *) arg = pChan->baudRate;
	    break;

	case SIO_MODE_SET:
            if (!((int) arg == SIO_MODE_POLL || (int) arg == SIO_MODE_INT))
                {
                status = EIO;
                break;
                }

            /* lock interrupt  */

            oldlevel = intLock();

            /* initialize channel on first MODE_SET */

            if (!pChan->channelMode)
                ppc860SccResetChannel(pChan);

            /*
             * if switching from POLL to INT mode, wait for all characters to
             * clear the output pins
             */

            if ((pChan->channelMode == SIO_MODE_POLL) && (arg == SIO_MODE_INT))
                {
		int i;

                for (i=0; i < pChan->uart.txBdNum; i++)
                    while (pChan->uart.txBdBase

⌨️ 快捷键说明

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