📄 m68360sio.c
字号:
/* m68360Sio.c - Motorola MC68360 SCC UART serial driver *//* Copyright 1984-2002 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01g,24apr02,pmr SPR 75161: returning int from m68360Startup() as required.01f,28may96,dat fixed SPR #5526, baud rate divisor calculation01e,10oct95,ms made poll input routine work if len(RX FIFO)>1 (SPR #5130).01d,08sep95,myz fixed the SPR #467801c,20jun95,ms fixed comments for mangen01b,15jun95,ms updated for new driver structure01a,22may95,myz written (using m68360Serial.c).*//*DESCRIPTIONThis is the driver for the SCC's in the internal Communications Processor (CP)of the Motorola MC68360. This driver only supports the SCC's in asynchronousUART mode.USAGEA m68360_CHAN structure is used to describe the chip.The BSP's sysHwInit() routine typically calls sysSerialHwInit()which initializes all the values in the M68360_CHAN structure (exceptthe SIO_DRV_FUNCS) before calling m68360DevInit().The BSP's sysHwInit2() routine typically calls sysSerialHwInit2() whichconnects the chips interrupt (m68360Int) via intConnect().INCLUDE FILES: drv/sio/m68360Sio.h*//* includes */#include "vxWorks.h"#include "intLib.h"#include "errno.h"#include "sioLib.h"#include "drv/sio/m68360Sio.h"/* defines */#define DEFAULT_BAUD 9600/* forward declarations */static STATUS m68360Ioctl (M68360_CHAN *pChan,int request,int arg);static void m68360ResetChannel (M68360_CHAN *pChan);static int m68360PollOutput (SIO_CHAN *,char);static int m68360PollInput (SIO_CHAN *,char *);static int m68360Startup (M68360_CHAN *);static int m68360CallbackInstall (SIO_CHAN *, int, STATUS (*)(), void *);/* local driver function table */static SIO_DRV_FUNCS m68360SioDrvFuncs = { (int (*)())m68360Ioctl, (int (*)())m68360Startup, (int (*)())m68360CallbackInstall, (int (*)())m68360PollInput, (int (*)(SIO_CHAN *,char))m68360PollOutput };/********************************************************************************* m68360DevInit - initialize the SCC** This routine is called to initialize the chip to a quiescent state.*/void m68360DevInit ( M68360_CHAN *pChan ) { /* masks off this SCC's interrupt. */ *M360_CPM_CIMR(pChan->regBase) &= (~(CPIC_CIXR_SCC4 << (3 - (pChan->uart.sccNum - 1) ))); pChan->baudRate = DEFAULT_BAUD; pChan->pDrvFuncs = &m68360SioDrvFuncs; }/********************************************************************************* m68360ResetChannel - initialize the SCC*/static void m68360ResetChannel ( M68360_CHAN *pChan ) { int scc; /* the SCC number being initialized */ int baud; /* the baud rate generator being used */ int frame; int oldlevel = intLock (); /* LOCK INTERRUPTS */ scc = pChan->uart.sccNum - 1; /* get SCC number */ baud = pChan->bgrNum - 1; /* get BRG number */ pChan->uart.intMask = CPIC_CIXR_SCC4 << (3 - scc); /* set up SCC as NMSI */ *M360_CPM_SICR(pChan->regBase) |= (UINT32) (baud << (scc << 3)); *M360_CPM_SICR(pChan->regBase) |= (UINT32) ((baud << 3) << (scc << 3)); /* reset baud rate generator */ *pChan->pBaud |= BRG_CR_RST; while (*pChan->pBaud & BRG_CR_RST); m68360Ioctl (pChan, SIO_BAUD_SET, pChan->baudRate); /* set up transmit buffer descriptors */ pChan->uart.txBdBase = (SCC_BUF *) (pChan->regBase + ((UINT32) pChan->uart.txBdBase & 0xfff)); pChan->uart.pScc->param.tbase = (UINT16) ((UINT32) pChan->uart.txBdBase & 0xfff); pChan->uart.pScc->param.tbptr = (UINT16) ((UINT32) pChan->uart.txBdBase & 0xfff); pChan->uart.txBdNext = 0; /* initialize each transmit buffer descriptor */ for (frame = 0; frame < pChan->uart.txBdNum; frame++) { pChan->uart.txBdBase[frame].statusMode = SCC_UART_TX_BD_INT; 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 |= SCC_UART_TX_BD_WRAP; /* set up receive buffer descriptors */ pChan->uart.rxBdBase = (SCC_BUF *) (pChan->regBase + ((UINT32) pChan->uart.rxBdBase & 0xfff)); pChan->uart.pScc->param.rbase = (UINT16) ((UINT32) pChan->uart.rxBdBase & 0xfff); pChan->uart.pScc->param.rbptr = (UINT16) ((UINT32) pChan->uart.rxBdBase & 0xfff); pChan->uart.rxBdNext = 0; /* initialize each receive buffer descriptor */ for (frame = 0; frame < pChan->uart.rxBdNum; frame++) { pChan->uart.rxBdBase[frame].statusMode = SCC_UART_RX_BD_EMPTY | SCC_UART_RX_BD_INT; pChan->uart.rxBdBase[frame].dataLength = 1; /* char oriented */ pChan->uart.rxBdBase[frame].dataPointer = pChan->uart.rxBufBase + frame; } /* set the last BD to wrap to the first */ pChan->uart.rxBdBase[(frame - 1)].statusMode |= SCC_UART_TX_BD_WRAP; /* set SCC attributes to UART mode */ pChan->uart.pSccReg->gsmrl = SCC_GSMRL_RDCR_X16 | SCC_GSMRL_TDCR_X16 | SCC_GSMRL_UART; pChan->uart.pSccReg->gsmrh = SCC_GSMRH_RFW | SCC_GSMRH_TFL; pChan->uart.pSccReg->psmr = SCC_UART_PSMR_FLC | SCC_UART_PSMR_CL_8BIT; pChan->uart.pSccReg->dsr = 0x7e7e; /* no fractional stop bits */ pChan->uart.pScc->param.rfcr = 0x18; /* supervisor data access */ pChan->uart.pScc->param.tfcr = 0x18; /* supervisor data access */ pChan->uart.pScc->param.mrblr = 0x1; /* one character rx buffers */ /* initialize parameter the SCC RAM */ ((SCC_UART_PROTO *)pChan->uart.pScc->prot)->maxIdl = 0x0; ((SCC_UART_PROTO *)pChan->uart.pScc->prot)->brkcr = 0x1; ((SCC_UART_PROTO *)pChan->uart.pScc->prot)->parec = 0x0; ((SCC_UART_PROTO *)pChan->uart.pScc->prot)->frmer = 0x0; ((SCC_UART_PROTO *)pChan->uart.pScc->prot)->nosec = 0x0; ((SCC_UART_PROTO *)pChan->uart.pScc->prot)->brkec = 0x0; ((SCC_UART_PROTO *)pChan->uart.pScc->prot)->uaddr1 = 0x0; ((SCC_UART_PROTO *)pChan->uart.pScc->prot)->uaddr2 = 0x0; ((SCC_UART_PROTO *)pChan->uart.pScc->prot)->toseq = 0x0; ((SCC_UART_PROTO *)pChan->uart.pScc->prot)->character1 = 0x8000; ((SCC_UART_PROTO *)pChan->uart.pScc->prot)->character2 = 0x8000; ((SCC_UART_PROTO *)pChan->uart.pScc->prot)->character3 = 0x8000; ((SCC_UART_PROTO *)pChan->uart.pScc->prot)->character4 = 0x8000; ((SCC_UART_PROTO *)pChan->uart.pScc->prot)->character5 = 0x8000; ((SCC_UART_PROTO *)pChan->uart.pScc->prot)->character6 = 0x8000; ((SCC_UART_PROTO *)pChan->uart.pScc->prot)->character7 = 0x8000; ((SCC_UART_PROTO *)pChan->uart.pScc->prot)->character8 = 0x8000; ((SCC_UART_PROTO *)pChan->uart.pScc->prot)->rccm = 0x8000; pChan->uart.pSccReg->scce = 0xffff; /* clr events */ /* enables the transmitter and receiver */ pChan->uart.pSccReg->gsmrl |= SCC_GSMRL_ENR | SCC_GSMRL_ENT; /* unmask interrupt */ pChan->uart.pSccReg->sccm = SCC_UART_SCCX_RX | SCC_UART_SCCX_TX; *M360_CPM_CIMR(pChan->regBase) |= pChan->uart.intMask; intUnlock (oldlevel); /* UNLOCK INTERRUPTS */ }/********************************************************************************* m68360Ioctl - special device control** RETURNS: OK on success, EIO on device error, ENOSYS on unsupported* request.**/LOCAL STATUS m68360Ioctl ( M68360_CHAN *pChan, /* device to control */ int request, /* request code */ int arg /* some argument */ ) { int baudRate; int oldlevel; STATUS status = OK; switch (request) { case SIO_BAUD_SET: if (arg >= 50 && arg <= 38400) /* could go higher... */ { /* calculate proper counter value, then enable BRG */ baudRate = (pChan->clockRate / (16 * arg)) - 1; if (baudRate > 0xfff) *pChan->pBaud = (BRG_CR_CD & ((baudRate / 16) << 1)) | BRG_CR_EN | BRG_CR_DIV16; else *pChan->pBaud = (BRG_CR_CD & (baudRate << 1)) | BRG_CR_EN; 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) m68360ResetChannel(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 & SCC_UART_TX_BD_READY); } if (arg == SIO_MODE_INT)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -