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

📄 m8260sio.c

📁 motorola 8260 CPU上面
💻 C
📖 第 1 页 / 共 2 页
字号:
/* m8260Sio.c - Motorola MPC8260 SCC UART serial driver *//* Copyright 1984-1999 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01k,03oct99,ms_  roll back to circa 01g to fix hang01j,16sep99,ms_  some include files come from drv/sio01i,16sep99,ms_  rename m8260Int.h to m8260IntrCtl.h01h,15jul99,ms_  make compliant with our coding standards		 use macros to access hardware registers01g,21may99,ms_  set a number of "not used" fields as indicated by user's                 manual01f,19apr99,ms_  add documentation to functions with none01e,17apr99,ms_  final EAR cleanup01d,14apr99,ms_  interrupt numbers are defined, not vectors01c,08apr99,ms_  upgrade to multiple channels01b,06apr99,ms_  try using claudios buffer scheme01a,08mar99,ms_	 adapted from src/drv/m8260Sio.c version 01b*//*DESCRIPTIONThis is the driver for the SCCs in the internal Communications Processor (CP)of the Motorola MPC8260. This driver only supports the SCCs in asynchronous UART mode.USAGEAn M8260_SIO_CHAN structure is used to describe the chip.The BSP's sysHwInit() routine typically calls sysSerialHwInit(),which initializes all the values in the M8260_11/2/1 3:39PM=_CHAN structure (exceptthe SIO_DRV_FUNCS) before calling m8260SioDevInit().The BSP's sysHwInit2() routine typically calls sysSerialHwInit2() whichconnects the chip's interrupts via intConnect().INCLUDE FILES: drv/sio/m8260Sio.h drv/sio/m8260Cp.h drv/intrCtl/m8260IntrCtl.h*//* includes */#include "vxWorks.h"#include "intLib.h"#include "errno.h"#include "sioLib.h"#include "drv/sio/m8260Sio.h"#include "drv/sio/m8260Cp.h"#include "drv/intrCtl/m8260IntrCtl.h"/* defines */#define DEFAULT_BAUD 9600/* 8260pc */#define WITH_SCC2	0/* local forward declarations */static STATUS m8260SioIoctl (M8260_SCC_CHAN *pSccChan,int request,int arg);static int    m8260SioPollOutput (SIO_CHAN *pSioChan,char);static int    m8260SioPollInput (SIO_CHAN *pSioChan,char *);static void   m8260SioStartup (M8260_SCC_CHAN *pSccChan);static int    m8260SioCallbackInstall (SIO_CHAN *pSioChan, int, STATUS (*)(), void *);/* global forward declarations */void   m8260SioResetChannel (M8260_SCC_CHAN *pSccChan);/* local driver function table */static SIO_DRV_FUNCS m8260SioDrvFuncs =    {    (int (*)())			m8260SioIoctl,    (int (*)())			m8260SioStartup,    				m8260SioCallbackInstall,    (int (*)())			m8260SioPollInput,    (int (*)(SIO_CHAN *,char))	m8260SioPollOutput    };/********************************************************************************* m8260SioDevInit - initialize the SCC** This routine is called to initialize the chip to a quiescent state.* Note that the `sccNum' field of M8260_SCC_CHAN must be less than * or equal to the* maximum number of SCC channels to configure as SIOs, as defined in * ads8260.h*/void m8260SioDevInit    (    M8260_SCC_CHAN *pSccChan    )    {    UINT32  immrVal = pSccChan->immrVal;    /* holder for the immr value */    UINT8   sccNum = pSccChan->sccNum;      /* holder for the fcc number */    UINT8   scc = sccNum - 1;            	/* a convenience */    VINT16 *pSCCM = (VINT16 *) (immrVal + M8260_SCC_BASE + M8260_SCCM_OFFSET +	                       (scc * M8260_SCC_OFFSET_NEXT_SCC));    if (sccNum > N_SIO_CHANNELS)		return;    /*     * Disable receive and transmit interrupts.     * Always flush cache pipe before first read     */    CACHE_PIPE_FLUSH ();	    *pSCCM &= ~(M8260_SCC_UART_SCCX_RX | M8260_SCC_UART_SCCX_TX);    pSccChan->baudRate  = DEFAULT_BAUD;    pSccChan->pDrvFuncs = &m8260SioDrvFuncs;    }/********************************************************************************* m8260SioResetChannel - initialize an SCC channel** This routines initializes an SCC channel. Initialized are:* * .CS*        CPCR*        BRGC*        Baud rate*        Buffer Descriptors*        RBASE field in SCC Parameter RAM*        TBASE field in SCC Parameter RAM*        RFCR field in SCC Parameter RAM*        TFCR field in SCC Parameter RAM*        MRBLR field in SCC Parameter RAM*        *        SCC mode registers: GSMR_L, GSMR_H, AND PSMR*        transmit and receive interrupts are enabled in SCCM ** RETURNS: NA** .CE*/void m8260SioResetChannel     (    M8260_SCC_CHAN *pSccChan    )    {    UINT32  immrVal = pSccChan->immrVal;    /* holder for the immr value */    UINT8   sccNum = pSccChan->sccNum;      /* holder for the fcc number */    UINT8   scc = sccNum - 1;            	/* a convenience */    VINT32  cpcrVal = 0;         		/* a convenience */    VINT32 *pBRGC = (VINT32 *) (immrVal + M8260_BRGC_BASE + 			        (scc * M8260_BRGC_OFFSET_NEXT_BRGC));    VINT32 *pGSMR_L = (VINT32 *) (immrVal + M8260_SCC_BASE +                                   M8260_GSMR_L_OFFSET +				  (scc * M8260_SCC_OFFSET_NEXT_SCC));    VINT32 *pGSMR_H = (VINT32 *) (immrVal + M8260_SCC_BASE +                                   M8260_GSMR_H_OFFSET +				  (scc * M8260_SCC_OFFSET_NEXT_SCC));    VINT16 *pPSMR = (VINT16 *) (immrVal + M8260_SCC_BASE + 		      	        (scc * M8260_SCC_OFFSET_NEXT_SCC) +			        M8260_PSMR_OFFSET);    VINT16 *pSCCM = (VINT16 *) (immrVal + M8260_SCC_BASE + M8260_SCCM_OFFSET +		      	        (scc * M8260_SCC_OFFSET_NEXT_SCC));    VINT16 *pRBASE = (VINT16 *) (immrVal + M8260_SCC_PRAM_BASE +			 	 M8260_SCC_PRAM_RBASE +				 (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM));			     VINT16 *pTBASE = (VINT16 *) (immrVal + M8260_SCC_PRAM_BASE +				 M8260_SCC_PRAM_TBASE +				 (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM));    VINT8 * pRFCR = (VINT8 *) (immrVal + M8260_SCC_PRAM_BASE +                               M8260_SCC_PRAM_RFCR +                               (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM));    VINT8 * pTFCR = (VINT8 *) (immrVal + M8260_SCC_PRAM_BASE +                               M8260_SCC_PRAM_TFCR +                               (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM));    VINT16 *pMRBLR = (VINT16 *) (immrVal + M8260_SCC_PRAM_BASE +                                 M8260_SCC_PRAM_MRBLR +                                 (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM));    VINT16 *pMAX_IDL = (VINT16 *) (immrVal + M8260_SCC_PRAM_BASE +                                 0x38 +                                 (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM));    VINT16 *pBRKCR = (VINT16 *) (immrVal + M8260_SCC_PRAM_BASE +                                 0x3C +                                 (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM));    VINT16 *pPAREC = (VINT16 *) (immrVal + M8260_SCC_PRAM_BASE +                                 M8260_SCC_UART_PRAM_PAREC +                                 (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM));    VINT16 *pFRMEC = (VINT16 *) (immrVal + M8260_SCC_PRAM_BASE +                                 M8260_SCC_UART_PRAM_FRMEC +                                 (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM));    VINT16 *pNOSEC = (VINT16 *) (immrVal + M8260_SCC_PRAM_BASE +                                 M8260_SCC_UART_PRAM_NOSEC +                                 (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM));    VINT16 *pBRKEC = (VINT16 *) (immrVal + M8260_SCC_PRAM_BASE +                                 M8260_SCC_UART_PRAM_BRKEC +                                 (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM));    VINT16 *pUADDR1 = (VINT16 *) (immrVal + M8260_SCC_PRAM_BASE +                                 0x48 +                                 (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM));    VINT16 *pUADDR2 = (VINT16 *) (immrVal + M8260_SCC_PRAM_BASE +                                 0x4A +                                 (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM));    VINT16 *pTOSEQ = (VINT16 *) (immrVal + M8260_SCC_PRAM_BASE +                                 0x4E +                                 (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM));    VINT16 *pCHARACTER1 = (VINT16 *) (immrVal + M8260_SCC_PRAM_BASE +                                 0x50 +                                 (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM));    VINT16 *pCHARACTER2 = (VINT16 *) (immrVal + M8260_SCC_PRAM_BASE +                                 0x52 +                                 (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM));    VINT16 *pCHARACTER3 = (VINT16 *) (immrVal + M8260_SCC_PRAM_BASE +                                 0x54 +                                 (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM));    VINT16 *pCHARACTER4 = (VINT16 *) (immrVal + M8260_SCC_PRAM_BASE +                                 0x56 +                                 (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM));    VINT16 *pCHARACTER5 = (VINT16 *) (immrVal + M8260_SCC_PRAM_BASE +                                 0x58 +                                 (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM));    VINT16 *pCHARACTER6 = (VINT16 *) (immrVal + M8260_SCC_PRAM_BASE +                                 0x5A +                                 (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM));    VINT16 *pCHARACTER7 = (VINT16 *) (immrVal + M8260_SCC_PRAM_BASE +                                 0x5C +                                 (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM));    VINT16 *pCHARACTER8 = (VINT16 *) (immrVal + M8260_SCC_PRAM_BASE +                                 0x5E +                                 (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM));    VINT16 *pRCCM = (VINT16 *) (immrVal + M8260_SCC_PRAM_BASE +                                 0x60 +                                 (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM));    int ix = 0;        int oldlevel = intLock ();	/* lock interrupts */     CACHE_PIPE_FLUSH ();    /* wait until the CP is clear */    do        {	M8260_SCC_32_RD((M8260_CPCR (immrVal)), cpcrVal);        if (ix++ == M8260_CPCR_LATENCY)            break;        } while (cpcrVal & M8260_CPCR_FLG) 	    ;    if (ix >= M8260_CPCR_LATENCY)        {        /* what to do, other than log an error? */        }    /* Stop transmitting on SCC, if doing so */    cpcrVal = (M8260_CPCR_OP (M8260_CPCR_TX_STOP)               | M8260_CPCR_SBC (M8260_CPCR_SBC_SCC1 | (scc * 0x1))               | M8260_CPCR_PAGE (M8260_CPCR_PAGE_SCC1 | (scc * 0x1))               | M8260_CPCR_FLG);    M8260_SCC_32_WR (M8260_CPCR (immrVal), cpcrVal);    /* flush cache pipe when switching from write to read */    CACHE_PIPE_FLUSH ();   /* wait until the CP is clear */    ix = 0;    do        {        M8260_SCC_32_RD((M8260_CPCR (immrVal)), cpcrVal);        if (ix++ == M8260_CPCR_LATENCY)            break;        } while (cpcrVal & M8260_CPCR_FLG) ;    if (ix >= M8260_CPCR_LATENCY)        {        /* what to do, other than log an error? */        }    /* set up SCC as NMSI, select Baud Rate Generator */    /* reset baud rate generator, wait for reset to clear... */     * pBRGC |= M8260_BRGC_RST;    /* flush cache pipe when switching from write to read */    CACHE_PIPE_FLUSH ();    while ((*pBRGC) & M8260_BRGC_RST);    m8260SioIoctl (pSccChan, SIO_BAUD_SET, pSccChan->baudRate);    /* set up the RECEIVE buffer descriptors */    /* buffer status/control */    M8260_SCC_16_WR((pSccChan->pBdBase +                      M8260_SCC_RCV_BD_OFF +                      M8260_SCC_BD_STAT_OFF), 0xB000);    CACHE_PIPE_FLUSH ();    /* buffer length */    M8260_SCC_16_WR((pSccChan->pBdBase +                      M8260_SCC_RCV_BD_OFF +                      M8260_SCC_BD_LEN_OFF), 0x0001);    CACHE_PIPE_FLUSH ();    /* buffer address */    M8260_SCC_32_WR((pSccChan->pBdBase +                      M8260_SCC_RCV_BD_OFF +                      M8260_SCC_BD_ADDR_OFF), pSccChan->rcvBufferAddr);    /* set the SCC parameter ram field RBASE */    * pRBASE = 0x00 + (0x100 * scc);    /* set up the TRANSMIT buffer descriptors */    /*      * buffer status/control;     * not ready, Wrap, Bit Clear-to-send_report, Interrupt      */    M8260_SCC_16_WR((pSccChan->pBdBase +                      M8260_SCC_TX_BD_OFF +                      M8260_SCC_BD_STAT_OFF), 0x3800);    /* buffer length */    M8260_SCC_16_WR((pSccChan->pBdBase +                      M8260_SCC_TX_BD_OFF +                      M8260_SCC_BD_LEN_OFF), 0x0001);    /* buffer address */    M8260_SCC_32_WR((pSccChan->pBdBase +                      M8260_SCC_TX_BD_OFF +                      M8260_SCC_BD_ADDR_OFF), pSccChan->txBufferAddr);    /* set the SCC parameter ram field TBASE */    * pTBASE = 0x08 + (0x100 * scc);    /* disable transmit and receive interrupts */    * pSCCM &= ~(M8260_SCC_UART_SCCX_RX | M8260_SCC_UART_SCCX_TX);    /* program the three SCC mode registers: gsmrl, gsmrh, and psmr */    /*      * Protocol Specific Mode Register for SCC     * Normal CTS, 1 stop bit, 8 data bits      */    * pPSMR   = M8260_SCC_UART_PSMR_FLC  | M8260_SCC_UART_PSMR_CL_8BIT;    /*      * General Serial Mode Register for SCC, high word     * xmit fifo is 1 byte, receive fifo 8 bits      */    * pGSMR_H = M8260_SCC_GSMRH_RFW      | M8260_SCC_GSMRH_TFL;    /*      * General Serial Mode Register for SCC, low word     * set SCC attributes to standard UART mode, disable xmit and rcv     */    * pGSMR_L = (M8260_SCC_GSMRL_RDCR_X16 | 		 M8260_SCC_GSMRL_TDCR_X16 | 		 M8260_SCC_GSMRL_UART) 		 & ~		 (M8260_SCC_GSMRL_ENT | M8260_SCC_GSMRL_ENR);    /* initialize parameter RAM area for this SCC */    * pRFCR = 0x18;	/* supervisor data access */    * pTFCR = 0x18;	/* supervisor data access */    * pMRBLR = 1;    /* initialize some unused parameters in SCC parameter RAM */    * pMAX_IDL = 0x0;    * pBRKCR = 0x0001;    * pPAREC = 0x0;    * pFRMEC = 0x0;    * pNOSEC = 0x0;    * pBRKEC = 0x0;    * pUADDR1 = 0x0;    * pUADDR2 = 0x0;    * pTOSEQ = 0x0;    * pCHARACTER1 = 0x8000;    * pCHARACTER2 = 0x8000;    * pCHARACTER3 = 0x8000;    * pCHARACTER4 = 0x8000;    * pCHARACTER5 = 0x8000;    * pCHARACTER6 = 0x8000;    * pCHARACTER7 = 0x8000;    * pCHARACTER8 = 0x8000;    * pRCCM = 0x0C0FF;    CACHE_PIPE_FLUSH ();   /* wait until the CP is clear */    ix = 0;    do        {        M8260_SCC_32_RD((M8260_CPCR (immrVal)), cpcrVal);        if (ix++ == M8260_CPCR_LATENCY)            break;        } while (cpcrVal & M8260_CPCR_FLG) ;    if (ix >= M8260_CPCR_LATENCY)        {        /* what to do, other than log an error? */        }    /* Tell CP to initialize tx and rx parameters for SCC */    cpcrVal = (M8260_CPCR_OP (M8260_CPCR_RT_INIT)               | M8260_CPCR_SBC (M8260_CPCR_SBC_SCC1 | (scc * 0x1))               | M8260_CPCR_PAGE (M8260_CPCR_PAGE_SCC1 | (scc * 0x1))               | M8260_CPCR_MCN (M8260_CPCR_MCN_ETH)               | M8260_CPCR_FLG);    M8260_SCC_32_WR (M8260_CPCR (immrVal), cpcrVal);    CACHE_PIPE_FLUSH ();    /* wait until the CP is clear */    ix = 0;    do        {        M8260_SCC_32_RD((M8260_CPCR (immrVal)), cpcrVal);        if (ix++ == M8260_CPCR_LATENCY)            break;        } while (cpcrVal & M8260_CPCR_FLG) ;    if (ix >= M8260_CPCR_LATENCY)        {        /* what to do, other than log an error? */        }    CACHE_PIPE_FLUSH ();    /* lastly, enable the transmitter and receiver  */    * pGSMR_L |= (M8260_SCC_GSMRL_ENT | M8260_SCC_GSMRL_ENR);    CACHE_PIPE_FLUSH ();    intUnlock (oldlevel);			/* UNLOCK INTERRUPTS */    }/********************************************************************************* m8260SioIoctl - special device control** Allows the caller to get and set the buad rate; to get and set the mode;* and to get the allowable modes.** RETURNS: OK on success, EIO on device error, ENOSYS on unsupported*          request.**/LOCAL STATUS m8260SioIoctl    (    M8260_SCC_CHAN *	pSccChan,	/* device to control */    int			request,	/* request code */

⌨️ 快捷键说明

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