📄 ppc860sccsio.c
字号:
#include "vxWorks.h"
#include "intLib.h"
#include "errno.h"
#include "sioLib.h"
#include "drv/multi/ppc860Siu.h"
#include "drv/multi/ppc860Cpm.h"
#include "drv/sio/ppc860Sio.h"
#define DEFAULT_BAUD 9600 /* default baudrate */
SCC_UART_PROTO *scc1Param; /* the uart protocal parameter ram of scc1 */
SCC_UART_PROTO *scc2Param; /* the uart protocal parameter ram of scc2 */
SCC_UART_PROTO *scc3Param; /* the uart protocal parameter ram of scc3 */
SCC_UART_PROTO *scc4Param; /* the uart protocal parameter ram of scc4 */
static STATUS ppc860SccIoctl (PPC860SCC_CHAN *pChan,int request,int arg);
static void ppc860SccResetChannel (PPC860SCC_CHAN *pChan);
static int ppc860SccPollOutput (SIO_CHAN *,char);
static int ppc860SccPollInput (SIO_CHAN *,char *);
static void ppc860SccStartup (PPC860SCC_CHAN *);
static int ppc860SccCallbackInstall (SIO_CHAN *, int, STATUS (*)(), void *);
static SIO_DRV_FUNCS ppc860SccSioDrvFuncs =
{
(int (*)()) ppc860SccIoctl,
(int (*)()) ppc860SccStartup,
(int (*)()) ppc860SccCallbackInstall,
(int (*)()) ppc860SccPollInput,
(int (*)(SIO_CHAN *,char)) ppc860SccPollOutput
};
/*******************************************************************************
*
* ppc860SccDevInit - initialize the SCC
*
* This routine is called to initialize the chip to a quiescent state.
* Note that the `sccNum' field of PPC860SCC_CHAN must be either 1 or 2.
*/
void ppc860SccDevInit(PPC860SCC_CHAN *pChan)
{
int scc;
scc=pChan->uart.sccNum-1;
/* masks off this SCC's interrupt. */
* CIMR(pChan->regBase) &= ~(CIMR_SCC1>>scc);
pChan->baudRate = DEFAULT_BAUD;
pChan->pDrvFuncs = &ppc860SccSioDrvFuncs;
}
/*******************************************************************************
*
* ppc860SccResetChannel - initialize the SCC
*/
static void ppc860SccResetChannel(PPC860SCC_CHAN *pChan)
{
int scc;
int baud;
int frame;
int oldLevel=intLock();
scc=pChan->uart.sccNum-1;
baud=pChan->bgrNum-1;
pChan->uart.intMask=CIMR_SCC1>>scc;
switch(baud)
{
case 0:
*SICR(pChan->regBase)|=((SICR_R1CS_BRG1<<(scc*8))|(SICR_T1CS_BRG1<<(scc*8)));
break;
case 1:
*SICR(pChan->regBase)|=((SICR_R1CS_BRG2<<(scc*8))|(SICR_T1CS_BRG2<<(scc*8)));
break;
case 2:
*SICR(pChan->regBase)|=((SICR_R1CS_BRG3<<(scc*8))|(SICR_T1CS_BRG3<<(scc*8)));
break;
case 3:
*SICR(pChan->regBase)|=((SICR_R1CS_BRG4<<(scc*8))|(SICR_T1CS_BRG4<<(scc*8)));
break;
}
/* reset baud rate generator, wait for reset to clear... */
*pChan->pBaud |= BRGC_RST;
while (*pChan->pBaud & BRGC_RST);
ppc860SccIoctl (pChan, SIO_BAUD_SET, pChan->baudRate);
/* set up transmit buffer descriptors */
pChan->uart.txBdBase = (SCC_BUF *) (pChan->regBase +
((UINT32) pChan->uart.txBdBase ));
pChan->uart.pScc->param.tbase = (UINT16) ((UINT32) pChan->uart.txBdBase);
pChan->uart.pScc->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 = (SCC_BUF *) (pChan->regBase +
((UINT32) pChan->uart.rxBdBase ));
pChan->uart.pScc->param.rbase = (UINT16) ((UINT32) pChan->uart.rxBdBase);
pChan->uart.pScc->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 = 0; /* 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 |= BD_RX_WRAP_BIT;
/* initialize the SCC parameter ram */
pChan->uart.pScc->param.rfcr = 0x18; /* supervisor data access */
pChan->uart.pScc->param.tfcr = 0x18; /* supervisor data access */
pChan->uart.pScc->param.mrblr = 0x01; /* 64 character rx buffers */
switch(scc)
{
case 0:
scc1Param=(SCC_UART_PROTO *)pChan->uart.pScc->prot;
scc1Param->maxIdl=0x10;
scc1Param->brkcr=0x0001;
scc1Param->parec=0x00;
scc1Param->frmer=0x00;
scc1Param->nosec=0x00;
scc1Param->brkec=0x00;
scc1Param->uaddr1=0x00;
scc1Param->uaddr2=0x00;
scc1Param->toseq=0x00;
scc1Param->character1=0x8000;
scc1Param->character2=0x8000;
scc1Param->character3=0x8000;
scc1Param->character4=0x8000;
scc1Param->character5=0x8000;
scc1Param->character6=0x8000;
scc1Param->character7=0x8000;
scc1Param->character8=0x8000;
scc1Param->rccm=0xc0ff;
break;
case 1:
scc2Param=(SCC_UART_PROTO *)pChan->uart.pScc->prot;
scc2Param->maxIdl=0x10;
scc2Param->brkcr=0x0001;
scc2Param->parec=0x00;
scc2Param->frmer=0x00;
scc2Param->nosec=0x00;
scc2Param->brkec=0x00;
scc2Param->uaddr1=0x00;
scc2Param->uaddr2=0x00;
scc2Param->toseq=0x00;
scc2Param->character1=0x8000;
scc2Param->character2=0x8000;
scc2Param->character3=0x8000;
scc2Param->character4=0x8000;
scc2Param->character5=0x8000;
scc2Param->character6=0x8000;
scc2Param->character7=0x8000;
scc2Param->character8=0x8000;
scc2Param->rccm=0xc0ff;
break;
case 2:
scc3Param=(SCC_UART_PROTO *)pChan->uart.pScc->prot;
scc3Param->maxIdl=0x10;
scc3Param->brkcr=0x0001;
scc3Param->parec=0x00;
scc3Param->frmer=0x00;
scc3Param->nosec=0x00;
scc3Param->brkec=0x00;
scc3Param->uaddr1=0x00;
scc3Param->uaddr2=0x00;
scc3Param->toseq=0x00;
scc3Param->character1=0x8000;
scc3Param->character2=0x8000;
scc3Param->character3=0x8000;
scc3Param->character4=0x8000;
scc3Param->character5=0x8000;
scc3Param->character6=0x8000;
scc3Param->character7=0x8000;
scc3Param->character8=0x8000;
scc3Param->rccm=0xc0ff;
break;
case 3:
scc4Param=(SCC_UART_PROTO *)pChan->uart.pScc->prot;
scc4Param->maxIdl=0x10;
scc4Param->brkcr=0x0001;
scc4Param->parec=0x00;
scc4Param->frmer=0x00;
scc4Param->nosec=0x00;
scc4Param->brkec=0x00;
scc4Param->uaddr1=0x00;
scc4Param->uaddr2=0x00;
scc4Param->toseq=0x00;
scc4Param->character1=0x8000;
scc4Param->character2=0x8000;
scc4Param->character3=0x8000;
scc4Param->character4=0x8000;
scc4Param->character5=0x8000;
scc4Param->character6=0x8000;
scc4Param->character7=0x8000;
scc4Param->character8=0x8000;
scc4Param->rccm=0xc0ff;
break;
}
/* clear all events */
pChan->uart.pSccReg->scce = 0xffff;
/* enables the transmitter and receiver */
pChan->uart.pSccReg->sccm=0x03;
pChan->uart.pSccReg->gsmrh=0x20;
pChan->uart.pSccReg->gsmrl=0x28004;
pChan->uart.pSccReg->psmr=0x3000;
pChan->uart.pSccReg->gsmrl|=0x30;
*CIMR(pChan->regBase) |= pChan->uart.intMask;
intUnlock (oldLevel); /* UNLOCK INTERRUPTS */
}
/*******************************************************************************
*
* ppc860SccIoctl - special device control
*
* RETURNS: OK on success, EIO on device error, ENOSYS on unsupported
* request.
*
*/
LOCAL STATUS ppc860SccIoctl
(
PPC860SCC_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 + (8 * arg)) / (16 * arg);
if (--baudRate > 0xfff)
*pChan->pBaud = (BRGC_CD_MSK &
(((baudRate + 8) / 16) << BRGC_CD_SHIFT)) | BRGC_EN |
BRGC_DIV16;
else
*pChan->pBaud = (BRGC_CD_MSK &
(baudRate << 1)) | BRGC_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)
ppc860SccResetChannel(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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -