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

📄 smc8260sio.c

📁 wind river提供的MPC8260的BSP典型代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* smc8260Sio.c - Motorola MPC8260 SMC UART serial driver *//* Copyright 1984-2001 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01e,22oct01,g_h  Clean warning.01d,12oct01,g_h  Clean for T2.201c,07may01,g_h  rename to smc8260Sio.c01b,26apr99,elk  added SMC2.01a,10mar99,elk	 adapted from ppc860Sio.c (ver 01b).*//*DESCRIPTIONThis is the driver for the SMCs in the internal Communications Processor (CP)of the Motorola MPC8260.  This driver only supports the SMCs in asynchronous UART mode.USAGEA PPC8260SMC_CHAN structure is used to describe the chip.The BSP's sysHwInit() routine typically calls sysSerialHwInit(),which initializes all the values in the PPC8260SMC_CHAN structure (exceptthe SIO_DRV_FUNCS) before calling smc8260DevInit().The BSP's sysHwInit2() routine typically calls sysSerialHwInit2() whichconnects the chip's interrupts via intConnect().INCLUDE FILES: smc8260Sio.h*//* includes */#include "vxWorks.h"#include "intLib.h"#include "errno.h"#include "sioLib.h"#include "drv/mem/m8260Siu.h"#include "drv/sio/m8260Brg.h"#include "drv/sio/m8260Cp.h"#include "drv/sio/m8260CpmMux.h"#include "smc8260Sio.h"void bcopyLongs(char *source, char *destination, int nlongs);/* defines */#define DEFAULT_BAUD 9600/* forward declarations */LOCAL STATUS smc8260Ioctl (PPC8260SMC_CHAN *pChan,int request,int arg);LOCAL void   smc8260ResetChannel (PPC8260SMC_CHAN *pChan);LOCAL int    smc8260PollOutput (SIO_CHAN *,char);LOCAL int    smc8260PollInput (SIO_CHAN *,char *);LOCAL void   smc8260Startup (PPC8260SMC_CHAN *);LOCAL int    smc8260CallbackInstall (SIO_CHAN *, int, STATUS (*)(), void *);/* local driver function table */LOCAL SIO_DRV_FUNCS smc8260SioDrvFuncs =    {    (int (*)())                smc8260Ioctl,    (int (*)())                smc8260Startup,    (int (*)())                smc8260CallbackInstall,    (int (*)())                smc8260PollInput,    (int (*)(SIO_CHAN *,char)) smc8260PollOutput    };/********************************************************************************* smc8260DevInit - initialize the SMC** This routine is called to initialize the chip to a quiescent state.* Note that the `smcNum' field of PPC8260SMC_CHAN must be either 1 or 2.** RETURNS: N/A.*/void smc8260DevInit    (    PPC8260SMC_CHAN *pChan    )    {    /* masks off this SMC's interrupt. */	    *M8260_SIMR_L(pChan->regBase) &= (~(0x00001000 >> (pChan->uart.smcNum - 1)));    pChan->baudRate  = DEFAULT_BAUD;    pChan->pDrvFuncs = &smc8260SioDrvFuncs;    }/********************************************************************************* smc8260ResetChannel - reset the SMC channel** This routine reset the SMC channel** RETURNS: N/A.*/LOCAL void smc8260ResetChannel     (    PPC8260SMC_CHAN *pChan    )    {    int smc;			/* the SMC number being initialized */    int baud;			/* the baud rate generator being used */    int frame;    int oldlevel = intLock ();	/* lock interrupts */     smc  = pChan->uart.smcNum - 1;		/* get SMC number */    baud = pChan->bgrNum - 1;			/* get BRG number */    pChan->uart.intMask = 0x00001000 >> smc;    /* set up SMC as NMSI, select Baud Rate Generator */    switch( baud ) 	{	default:        /* default to BRG1 */	case 0:         /* Select BRG1 */ 	    * CMXSMR(pChan->regBase) |= (0x00 >> (4 * smc));	    break;	case 1:         /* Select BRG2 */ 	    * CMXSMR(pChan->regBase) |= (0x00 >> (4 * smc));	    break;	case 6:         /* select BRG7 */	    * CMXSMR(pChan->regBase) |= (0x10 >> (4 * smc));	    break;	case 7:         /* select BRG8 */	    * CMXSMR(pChan->regBase) |= (0x10 >> (4 * smc));	    break;        }     /* reset baud rate generator, wait for reset to clear... */     *pChan->pBaud |= M8260_BRGC_RST;    while (*pChan->pBaud & M8260_BRGC_RST);    smc8260Ioctl (pChan, SIO_BAUD_SET, pChan->baudRate);    /* set up transmit buffer descriptors */    pChan->uart.txBdBase = (SMC_BUF *) (pChan->regBase +			 ((UINT32) pChan->uart.txBdBase ));    pChan->uart.pSmc->param.tbase = (UINT16) ((UINT32) pChan->uart.txBdBase);    pChan->uart.pSmc->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 = (SMC_BUF *) (pChan->regBase +		         ((UINT32) pChan->uart.rxBdBase ));    pChan->uart.pSmc->param.rbase = (UINT16) ((UINT32) pChan->uart.rxBdBase);    pChan->uart.pSmc->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 = 1; /* 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;    /* set SMC attributes to standard UART mode */    pChan->uart.pSmcReg->smcmr = SMCMR_STD_MODE;    /* initialize parameter RAM area for this SMC */    pChan->uart.pSmc->param.rfcr   = 0x18;	/* supervisor data access */    pChan->uart.pSmc->param.tfcr   = 0x18;	/* supervisor data access */    pChan->uart.pSmc->param.mrblr  = 0x1;	/* one character rx buffers */    pChan->uart.pSmc->param.maxidl = 0x0;	/* no idle features */    pChan->uart.pSmc->param.brkln  = 0x0;	/* no breaks received yet */    pChan->uart.pSmc->param.brkec  = 0x0;	/* zero break condition ctr */    pChan->uart.pSmc->param.brkcr  = 0x1;	/* xmit 1 BRK on stop */    /* clear all events */    pChan->uart.pSmcReg->smce = SMCE_ALL_EVENTS;    /* enables the transmitter and receiver  */    pChan->uart.pSmcReg->smcmr |= SMCMR_TEN | SMCMR_REN;    /* unmask interrupt (Tx, Rx only) */    pChan->uart.pSmcReg->smcm  = SMCM_TX_MSK | SMCM_RX_MSK;    *M8260_SIMR_L(pChan->regBase) |= pChan->uart.intMask;                         intUnlock (oldlevel);			/* UNLOCK INTERRUPTS */    }/********************************************************************************* smc8260Ioctl - special device control** This routine is the special device control.** RETURNS: OK on success, EIO on device error, ENOSYS on unsupported*          request.*/LOCAL STATUS smc8260Ioctl    (    PPC8260SMC_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 >=  SMC_MIN_BAUD && arg <= SMC_MAX_BAUD)		{		/* 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) << M8260_BRGC_CD_SHIFT)) | M8260_BRGC_EN |		    M8260_BRGC_DIV16;                else                    *pChan->pBaud = (BRGC_CD_MSK & 			(baudRate << 1)) | M8260_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)                smc8260ResetChannel(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                           [(pChan->uart.txBdNext + i) % pChan->uart.txBdNum].                           statusMode & BD_TX_READY_BIT);                }            if (arg == SIO_MODE_INT)		{                * M8260_SIPNR_L(pChan->regBase) = pChan->uart.intMask;				/* reset the SMC's interrupt status bit */		* M8260_SIMR_L(pChan->regBase) |= pChan->uart.intMask;				/* enable this SMC's interrupt  */		pChan->uart.pSmcReg->smce = SMCE_RX;					/* reset the receiver status bit */                 pChan->uart.pSmcReg->smcm = SMCM_RX_MSK | SMCM_TX_MSK;				/* enables receive and transmit interrupts */

⌨️ 快捷键说明

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