📄 m8260smc.c
字号:
/********************************************************************************//* m8260Smc.c - Motorola MPC8260 SMC UART serial driver *//* Copyright 2001.04.02 CN BSP (ver: 1.00) *//* *//* DESCRIPTION *//* Change from ppc860Sio.c *//* *//* COMMENTS: *//* the following labels are used in this file: *//* (BSP_SERIAL * BSP_CLOCK) *//* *//********************************************************************************//* Modification History *//*------------------------------------------------------------------------------*//* 2000.10.24 KYF: standardize for mpc8260 *//* 2001.04.02 KYF: standadize the code again for MIN_BSP of CN BSP(ver: 1.00) *//* *//********************************************************************************/#include "copyright_wrs.h"#include "vxWorks.h"#include "intLib.h"#include "errno.h"#include "cacheLib.h"#include "sioLib.h"#include "drv/sio/m8260Brg.h"#include "m8260Smc.h"#include "drv/sio/m8260Cp.h"#include "drv/intrCtl/m8260IntrCtl.h"/* forward declarations */static STATUS m8260SmcIoctl (M8260_SMC_CHAN *pChan,int request,int arg);static void m8260SmcResetChannel (M8260_SMC_CHAN *pChan);static int m8260SmcPollOutput (SIO_CHAN *,char);static int m8260SmcPollInput (SIO_CHAN *,char *);static void m8260SmcStartup (M8260_SMC_CHAN *);static int m8260SmcCallbackInstall (SIO_CHAN *, int, STATUS (*)(), void *);extern unsigned int vxImmrGet (void) ;/* local driver function table */static SIO_DRV_FUNCS m8260SmcDrvFuncs = { (int (*)()) m8260SmcIoctl, (int (*)()) m8260SmcStartup, m8260SmcCallbackInstall, (int (*)()) m8260SmcPollInput, (int (*)(SIO_CHAN *,char)) m8260SmcPollOutput };/*********************************************************************************** m8260SmcDevInit - initialize the SMC** This routine is called to initialize the chip to a quiescent state.* Note that the `smcNum' field of M8260_SMC_CHAN must be either 1 or 2.**********************************************************************************/void m8260SmcDevInit ( M8260_SMC_CHAN *pChan ){ CACHE_PIPE_FLUSH(); /* masks off this SMC's interrupt. */ * M8260_SIMR_L(pChan->regBase) &= (~(SIMR_L_SMC1 >> (pChan->uart.smcNum - 1))); pChan->pDrvFuncs = &m8260SmcDrvFuncs; }/*********************************************************************************** m8260SmcResetChannel - initialize the SMC**********************************************************************************/static void m8260SmcResetChannel ( M8260_SMC_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 = SIMR_L_SMC1 >> smc; /* reset baud rate generator, wait for reset to clear... */ *pChan->pBaud |= M8260_BRGC_RST; CACHE_PIPE_FLUSH (); while (*pChan->pBaud & M8260_BRGC_RST); m8260SmcIoctl (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; /* kyf? */ } /* 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 = M8260_SMCMR_STD_MODE; /* initialize parameter RAM area for this SMC */ pChan->uart.pSmc->param.rfcr = 0x10; /* supervisor data access */ pChan->uart.pSmc->param.tfcr = 0x10; /* 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 */ CACHE_PIPE_FLUSH (); /* Init RX and TX Parameters */ if (pChan->uart.smcNum == 1) * M8260_CPCR(pChan->regBase) = 0x1D010000; else * M8260_CPCR(pChan->regBase) = 0x21210000; CACHE_PIPE_FLUSH (); while (*M8260_CPCR(pChan->regBase) & 0x00010000); /* clear all events */ pChan->uart.pSmcReg->smce = M8260_SMCE_UART_ALL_EVENTS; /* enables the transmitter and receiver */ pChan->uart.pSmcReg->smcmr |= M8260_SMCMR_TX_ENABLE | M8260_SMCMR_RX_ENABLE; /* unmask interrupt (Tx, Rx only) */ CACHE_PIPE_FLUSH(); pChan->uart.pSmcReg->smcm = M8260_SMCM_UART_TX_MASK | M8260_SMCM_UART_RX_MASK; CACHE_PIPE_FLUSH(); *M8260_SIMR_L(pChan->regBase) |= pChan->uart.intMask; CACHE_PIPE_FLUSH (); intUnlock (oldlevel); /* UNLOCK INTERRUPTS */}/*********************************************************************************** m8260SmcIoctl - special device control** RETURNS: OK on success, EIO on device error, ENOSYS on unsupported* request.**********************************************************************************/LOCAL STATUS m8260SmcIoctl ( M8260_SMC_CHAN * pChan, /* device to control */ int request, /* request code */ int arg /* some argument */ ){ int oldlevel; STATUS status = OK; int prescale , SccrVal , BrgClkFactor; int immrVal = vxImmrGet(); switch (request) { case SIO_BAUD_SET: if (arg >= 300 && arg <= 115200) /* could go higher... */ {/*------------------------------------------------------------------------------*//* BSP_LABEL :(BSP_SERIAL * BSP_CLOCK)modify the coefficient *//* according to the SCCR. *//*------------------------------------------------------------------------------*/ SccrVal = *(M8260_SCCR (immrVal)) ; SccrVal &= 0x00000003 ; switch (SccrVal) { case 0 : BrgClkFactor = 4 ; break ; case 1 : BrgClkFactor = 16 ; break ; case 2 : BrgClkFactor = 64 ; break ; case 3 : BrgClkFactor = 128 ; break ; }/* CTDB_MPC8280 BUG,应该根据cpu的设置,需要修改*/ prescale = (OSCILLATOR_FREQ*2)*2/BrgClkFactor/16/arg ; prescale++; /* add 1 as it counts to zero */ *pChan->pBaud = 0x00010000 | (prescale << 1);/*BUG 固定死为38400*/ *pChan->pBaud=0x10034; CACHE_PIPE_FLUSH(); 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) m8260SmcResetChannel(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) { CACHE_PIPE_FLUSH(); * 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 = M8260_SMCE_UART_RX_EVENT; /* reset the receiver status bit */ pChan->uart.pSmcReg->smcm = M8260_SMCM_UART_RX_MASK | M8260_SMCM_UART_TX_MASK; /* enables receive and transmit interrupts */ CACHE_PIPE_FLUSH(); } else { CACHE_PIPE_FLUSH(); pChan->uart.pSmcReg->smcm = 0; /* mask off the receive and transmit intrs */ * M8260_SIMR_L(pChan->regBase) &= (~(pChan->uart.intMask)); /* mask off this SMC's interrupt */ CACHE_PIPE_FLUSH(); } pChan->channelMode = arg; intUnlock(oldlevel); break; case SIO_MODE_GET: * (int *) arg = pChan->channelMode;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -