?? m8260sio.c
字號:
/* 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 + -