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

📄 m8260sccsio.c

📁 au1500开发的应用程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/* m8260Sio.c - Motorola MPC8260 SCC UART serial driver */

/* Copyright 1984-2002 Wind River Systems, Inc. */
#include "copyright_wrs.h"

/*
modification history
--------------------
01a,21feb05,fhchen  adopted from src/drv/m8260Sio.c (ver 01o)
*/

/*
DESCRIPTION

This 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.

USAGE
An M8260_SIO_CHAN structure is used to describe the chip.
The BSP's sysHwInit() routine typically calls sysSerialHwInit(),
which initializes  values in the M8260_SCC_CHAN structure (except
the SIO_DRV_FUNCS) before calling m8260SioDevInit(). 

The BSP's sysHwInit2() routine typically calls sysSerialHwInit2() which
connects the chip's interrupts via intConnect().

INCLUDE FILES: m8260SccSio.h m8260IntrCtl.h drv/sio/m8260Cp.h

NOTE
- This drive assume 1 Rx BD followed by 1 Tx BD.
  [change this according to driver for SMC]
- change stop bit via IO control is supported, set request to
  SIO_HW_OPTS_SET and set arg to STOPB.

*/

/* includes */

#include "vxWorks.h"
#include "intLib.h"
#include "errno.h"
#include "sioLib.h"
#include "cacheLib.h"

#include "drv/sio/m8260Cp.h"
#include "drv/sio/m8260CpmMux.h"
#include "drv/sio/m8260Brg.h"
#include "drv/sio/m8260Scc.h"

#include "m8260IntrCtl.h"
#include "m8260SccSio.h"

/* debug */

#define DEBUG_SCC
#undef  DEBUG_SCC

#ifdef DEBUG_SCC
# include "logLib.h"
# define SCC_LOG(FLG, X0, X1, X2, X3, X4, X5, X6) \
        logMsg(X0, X1, X2, X3, X4, X5, X6)
 
# define SCC_ISR_TOTAL_ADD  numIsrEntriesTotal++;
# define SCC_ISR_RX_ADD     numIsrEntriesRx++;
# define SCC_ISR_TX_ADD     numIsrEntriesTx++;  
#else
# define SCC_LOG(FLG, X0, X1, X2, X3, X4, X5, X6)
# define SCC_ISR_TOTAL_ADD 
# define SCC_ISR_RX_ADD    
# define SCC_ISR_TX_ADD    
#endif

/* defines */

#define SCC_DEFAULT_BAUD 9600

/* 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 int    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,
    (int (*)())			m8260SioCallbackInstall,
    (int (*)())			m8260SioPollInput,
    (int (*)(SIO_CHAN *,char))	m8260SioPollOutput
    };

/* macro */

#define WAIT_CP_COMPLETE_CMD()                                          \
 {                                                                      \
    /* wait until the CP is clear */                                    \
 int ix = 0;                                                            \
 do                                                                     \
     {                                                                  \
     /* get CPCR value */                                               \
                                                                        \
     M8260_SCC_32_RD((M8260_CPCR (immrVal)), cpcrVal);                  \
                                                                        \
     if (ix++ == M8260_CPCR_LATENCY)                                    \
         break;                                                         \
     } while (cpcrVal & M8260_CPCR_FLG);  /* wait FLA bit clear */      \
                                                                        \
 if (ix >= M8260_CPCR_LATENCY)                                          \
     {                                                                  \
                                                                        \
     /* what to do, other than log an error? */                         \
     }                                                                  \
 }

/*******************************************************************************
*
* 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 1 ~ 4.
* 
*/

void m8260SioDevInit
    (
    M8260_SCC_CHAN *pSccChan
    )
    {
    UINT32  immrVal = pSccChan->immrVal;     /* holder for the immr value */
    UINT8   sccNum = pSccChan->sccNum;       /* holder for the scc number */
    
    UINT8   scc = sccNum - 1;                /* a convenience */
    VINT16 *pSCCM = (VINT16 *) (immrVal + M8260_SCC_BASE + M8260_SCCM_OFFSET +
	                       (scc * M8260_SCC_OFFSET_NEXT_SCC));

     /* Always flush cache pipe before first read */

    CACHE_PIPE_FLUSH ();

    /* Disable receive and transmit interrupts. Use SIMR instead? */
    
    *pSCCM &= ~(M8260_SCC_UART_SCCX_RX | M8260_SCC_UART_SCCX_TX);

    pSccChan->baudRate  = SCC_DEFAULT_BAUD;
    pSccChan->pDrvFuncs = &m8260SioDrvFuncs;
    }

/*******************************************************************************
*
* m8260SioResetChannel - initialize an SCC channel
*
* This routines initialize an SCC channel. Initialized are:
* 
* - CPCR
* - CMXSCR
* - 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
*
*/

void m8260SioResetChannel 
    (
    M8260_SCC_CHAN *pSccChan
    )
    {
    UINT32  immrVal = pSccChan->immrVal;        /* holder for the immr value */
    UINT8   sccNum = pSccChan->sccNum;          /* holder for the scc number */
    UINT8   scc = sccNum - 1;            	/* a convenience */
    UINT8   baud = pSccChan->bgrNum - 1;         /* a convenience */
    VINT32  cpcrVal = 0;         		/* a convenience */

    VINT32 *pBRGC = (VINT32 *) (immrVal + M8260_BRGC_BASE + 
			        (baud * 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));

    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 oldlevel = intLock ();	/* lock interrupts */

    /* set interrupt mask */
    pSccChan->intMask = 0x00800000 >> scc;
    
    /* RBASE address, value in RBASE is RxBD base address */
    
    if (pSccChan->pRBASE == NULL)
        {
        pSccChan->pRBASE = (VINT16 *) (immrVal + M8260_SCC_PRAM_BASE +
                                       M8260_SCC_PRAM_RBASE +
                                       (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM));
        } 

    /* TBASE address, value in TBASE is TxBD base address */

    if (pSccChan->pTBASE == NULL)
        {
        pSccChan->pTBASE = (VINT16 *) (immrVal + M8260_SCC_PRAM_BASE +
                                       M8260_SCC_PRAM_TBASE +
                                       (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM));
        }

    CACHE_PIPE_FLUSH ();

    /* wait until the CP is clear */

    WAIT_CP_COMPLETE_CMD();

    /* 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 */
    
    WAIT_CP_COMPLETE_CMD();
    
    /* CMXSCR: no grant mechanism, NMSI, select Tx/Rx Baud Rate Generator */

    * M8260_CMXSCR(immrVal) |=
        ((M8260_CMXSCR_R1CS_MSK & (baud << 27)) |
         (M8260_CMXSCR_T1CS_MSK & (baud << 24))) >> (scc * 8);
    
    /* reset baud rate generator */
 
    * pBRGC |= M8260_BRGC_RST;

    /* flush cache pipe when switching from write to read */

    CACHE_PIPE_FLUSH ();

    /* wait for reset to clear... */

    while ((*pBRGC) & M8260_BRGC_RST);

    /* set baud rate */

    m8260SioIoctl (pSccChan, SIO_BAUD_SET, pSccChan->baudRate);

    /* set up the RECEIVE buffer descriptors */

    /*
     * buffer status/control
     * Empty, Wrap, Interrupt
     */
    
    M8260_SCC_16_WR((pSccChan->pBdBase + 
                     M8260_SCC_RCV_BD_OFF + 
                     M8260_SCC_BD_STAT_OFF), 0xB000);
    CACHE_PIPE_FLUSH ();

    /* buffer length. 1 byte */
    
    M8260_SCC_16_WR((pSccChan->pBdBase + 
                     M8260_SCC_RCV_BD_OFF + 

⌨️ 快捷键说明

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