📄 m8260sio.c
字号:
/* m8260Sio.c - Motorola MPC8260 SCC UART serial driver *//* Copyright 1984-2002 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01p,03sep03,dtr Removing reference to m8260IntrCtl.h.01o,24apr02,pmr SPR 75161: returning int as required from m8260SioStartup().01n,30nov01,rcs allow pSccChan->pRBASE and pSccChan->pTBASE to be passed in SPR# 3452401m,22may01,rcs changed m8260SioIoctl SIO_BAUD_SET to use M8260_BRGC_DIVISOR01l,15may01,rcs changes m8260SioIoctl SIO_BAUD_SET to correctly calculate baudrate, added include "drv/sio/m8260Brg.h SPR#6698901k,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_SCC_CHAN structure (exceptthe SIO_DRV_FUNCS) before calling m8260SioDevInit(). This driver requires that the BSP create and initialize the global variablebaudRateGenClk. This global variable must contain the value of the Baud Rate Generator Input Clock. The value should be calculated as: VCO_OUT/SCCR[DFBRG]. Typically this will be: (CPM clock * 2) / 16This driver requires the BSP Parameter M8260_BRGC_DIVISOR. This Parametermust be initialized according to the system oscillator present on the board.For the ads8260 BSP this is automatic. The Parameter will be initialzed toM8260_BRGC_DIV1 for a 40 MHz system oscillator and M8260_BRGC_DIV16 for 33 MHzand 66 MHz.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/sio/m8260Brg.h"/* defines */#define DEFAULT_BAUD 9600#define INUM_CPM_SCC1 40#define INUM_CPM_SCC2 41/* 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 };/********************************************************************************* 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 */ UINT16 *pSCCM = (UINT16*) (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 */ VUINT32 *pBRGC = (VUINT32 *) (immrVal + M8260_BRGC_BASE + (scc * M8260_BRGC_OFFSET_NEXT_BRGC)); VUINT32 *pGSMR_L = (VUINT32 *) (immrVal + M8260_SCC_BASE + M8260_GSMR_L_OFFSET + (scc * M8260_SCC_OFFSET_NEXT_SCC)); VUINT32 *pGSMR_H = (VUINT32 *) (immrVal + M8260_SCC_BASE + M8260_GSMR_H_OFFSET + (scc * M8260_SCC_OFFSET_NEXT_SCC)); VUINT16 *pPSMR = (VUINT16 *) (immrVal + M8260_SCC_BASE + (scc * M8260_SCC_OFFSET_NEXT_SCC) + M8260_PSMR_OFFSET); VUINT16 *pSCCM = (VUINT16 *) (immrVal + M8260_SCC_BASE + M8260_SCCM_OFFSET + (scc * M8260_SCC_OFFSET_NEXT_SCC)); VUINT8 * pRFCR = (VUINT8 *) (immrVal + M8260_SCC_PRAM_BASE + M8260_SCC_PRAM_RFCR + (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM)); VUINT8 * pTFCR = (VUINT8 *) (immrVal + M8260_SCC_PRAM_BASE + M8260_SCC_PRAM_TFCR + (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM)); VUINT16 *pMRBLR = (VUINT16 *) (immrVal + M8260_SCC_PRAM_BASE + M8260_SCC_PRAM_MRBLR + (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM)); VUINT16 *pMAX_IDL = (VUINT16 *) (immrVal + M8260_SCC_PRAM_BASE + 0x38 + (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM)); VUINT16 *pBRKCR = (VUINT16 *) (immrVal + M8260_SCC_PRAM_BASE + 0x3C + (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM)); VUINT16 *pPAREC = (VUINT16 *) (immrVal + M8260_SCC_PRAM_BASE + M8260_SCC_UART_PRAM_PAREC + (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM)); VUINT16 *pFRMEC = (VUINT16 *) (immrVal + M8260_SCC_PRAM_BASE + M8260_SCC_UART_PRAM_FRMEC + (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM)); VUINT16 *pNOSEC = (VUINT16 *) (immrVal + M8260_SCC_PRAM_BASE + M8260_SCC_UART_PRAM_NOSEC + (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM)); VUINT16 *pBRKEC = (VUINT16 *) (immrVal + M8260_SCC_PRAM_BASE + M8260_SCC_UART_PRAM_BRKEC + (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM)); VUINT16 *pUADDR1 = (VUINT16 *) (immrVal + M8260_SCC_PRAM_BASE + 0x48 + (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM)); VUINT16 *pUADDR2 = (VUINT16 *) (immrVal + M8260_SCC_PRAM_BASE + 0x4A + (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM)); VUINT16 *pTOSEQ = (VUINT16 *) (immrVal + M8260_SCC_PRAM_BASE + 0x4E + (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM)); VUINT16 *pCHARACTER1 = (VUINT16 *) (immrVal + M8260_SCC_PRAM_BASE + 0x50 + (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM)); VUINT16 *pCHARACTER2 = (VUINT16 *) (immrVal + M8260_SCC_PRAM_BASE + 0x52 + (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM)); VUINT16 *pCHARACTER3 = (VUINT16 *) (immrVal + M8260_SCC_PRAM_BASE + 0x54 + (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM)); VUINT16 *pCHARACTER4 = (VUINT16 *) (immrVal + M8260_SCC_PRAM_BASE + 0x56 + (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM)); VUINT16 *pCHARACTER5 = (VUINT16 *) (immrVal + M8260_SCC_PRAM_BASE + 0x58 + (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM)); VUINT16 *pCHARACTER6 = (VUINT16 *) (immrVal + M8260_SCC_PRAM_BASE + 0x5A + (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM)); VUINT16 *pCHARACTER7 = (VUINT16 *) (immrVal + M8260_SCC_PRAM_BASE + 0x5C + (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM)); VUINT16 *pCHARACTER8 = (VUINT16 *) (immrVal + M8260_SCC_PRAM_BASE + 0x5E + (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM)); VUINT16 *pRCCM = (VUINT16 *) (immrVal + M8260_SCC_PRAM_BASE + 0x60 + (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM)); int ix = 0; int oldlevel = intLock (); /* lock interrupts */ if (pSccChan->pRBASE == NULL) { pSccChan->pRBASE = (VINT16 *) (immrVal + M8260_SCC_PRAM_BASE + M8260_SCC_PRAM_RBASE + (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM)); } 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 */ 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 ();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -