📄 sc28l198serial.c
字号:
"Driver initialized for device %d with driver %d\n",
uart, sc28l198Uart[uart].drvNum,0,0,0,0);
} /* for */
return(OK);
} /* sc28l198Drv */
/******************************************************************************
* SC28L198 Device Creation Routine.
******************************************************************************/
STATUS sc28l198DevCreate(char *name, int channel, int baudRate,
int dataBits, int stopBits, char *parity)
{
int uart;
int chan;
/* Calculate UART and Channel number */
uart = channel / SC28L198_CHAN_PER_UART;
chan = channel % SC28L198_CHAN_PER_UART;
/* Check that the device exists */
if( uart>=SC28L198_MAX_UARTS )
{
sc28l198Error(0, "Requested device does not exist\n");
return(ERROR);
} /* if */
/* Check to see if the device is supported */
if(sc28l198Uart[uart].exists != TRUE)
{
sc28l198Error(0, "Requested device not supported\n");
return(ERROR);
} /* if */
/* Check to see if this channel is supported in hardware */
if( chan >= SC28L198_CHAN_PER_UART)
{
sc28l198Error(0, "Requested channel does not exist\n");
return(ERROR);
} /* if */
/* Check for presence of driver*/
if(sc28l198Uart[uart].drvNum <= 0)
{
sc28l198Error(0, "Driver not installed for this device\n");
return(ERROR);
} /* if */
/* check for valid channel number */
if( chan >= sc28l198Cfg[uart].numChannels)
{
sc28l198Error(0, "Channel number not supported for this device\n");
return(ERROR);
} /* if */
/* check that the channel is initialized */
if(sc28l198Uart[uart].channel[chan].chan != chan)
{
sc28l198Error(0, "Channel has not been initialized\n");
return(ERROR);
} /* if */
/* range check user specified baud rate */
/* and convert to register format */
if( (sc28l198Uart[uart].channel[chan].baudRate =
sc28l198BaudRate((int) baudRate ) ) == ERROR)
{
sc28l198Error(0, "Bad baud rate specified\n");
return(ERROR);
} /* if */
/* range check user specified data bits */
/* and convert to register format */
if((sc28l198Uart[uart].channel[chan].dataBits =
sc28l198DataBits((int) dataBits)) == ERROR)
{
sc28l198Error(0, "Bad data bits specified\n");
return(ERROR);
} /* if */
/* range check user specified stop bits */
/* and convert to register format */
if((sc28l198Uart[uart].channel[chan].stopBits =
sc28l198StopBits((int) stopBits)) == ERROR)
{
sc28l198Error(0, "Bad stop bits specified\n");
return(ERROR);
} /* if */
/* range check user specified parity */
/* and convert to register format */
if((sc28l198Uart[uart].channel[chan].parity =
sc28l198Parity(parity)) == ERROR)
{
sc28l198Error(0, "Bad parity specified\n");
return(ERROR);
} /* if */
/* Check to see if this channel has already been created */
if(sc28l198Uart[uart].channel[chan].created == TRUE)
{
sc28l198Error(0, "Channel already created\n");
return(OK);
} /* if */
/* Add the device to the vxWorks IO system*/
if(iosDevAdd(&(sc28l198Uart[uart].channel[chan].devHdr), name,
sc28l198Uart[uart].drvNum) != OK)
{
sc28l198Error(0, "Cannot add device to system\n");
return(ERROR);
} /* if */
sc28l198Uart[uart].channel[chan].created = TRUE;
DRV_LOG(DRV_DEBUG_INIT, "Device %s created\n",name,0,0,0,0,0);
return(OK);
} /* sc28l198DevCreate */
/******************************************************************************
* Interrupt Handler.
******************************************************************************/
void
sc28l198Interrupt(int uart)
{
FAST SC28L198_DEV_CHAN *pChannel; /* Channel Control Data Structure */
FAST SC28L198_DEV_CHAN *pTxChan; /* Tx Channel Control Data Structure */
/* (used in Rx interrupt) */
FAST int chan; /* Uart serial channel number */
FAST int temp; /* Temporary Register for Ring Put */
FAST char rxByte; /* Character recevied byte */
char txByte; /* Character to send byte */
FAST int cir;
/* Issue Update CIR Command to get the current interrupt information
* (interrupt type, byte count, and channel).
*/
*SC28L198_CIR(uart) = 0;
cir = *SC28L198_CIR(uart);
#if 1
DRV_LOG(DRV_DEBUG_INTR,
"<interrupt uart %d, cir = 0x%x>\n",uart,cir,0,0,0,0);
#endif
/* Determine the cause of the current interrupt */
if( ((cir&INT_TYPE_MASK)==RCV_INT) ||
((cir&INT_TYPE_MASK)==RCV_W_ERR_INT) )
{
/* Receive interrupt */
/* Determine what channel caused the interrupt */
chan = cir & CUR_CHAN_MASK;
/* Future enhancement: could get the number of bytes in the RxFIFO
* from the CIR and GIBCR and process them all at once for efficiency.
*/
/* For debug, can also check the ISR register to cross check the
* interrupt source.
*/
/* Find the channel control structure */
pChannel = sc28l198Uart[uart].channel + chan;
pTxChan = sc28l198Uart[(uart ? 0 : 1)].channel + chan;
/* Read received byte from the channel */
rxByte = *pChannel->uartRxDataReg;
/* If the channel is open then */
/* (the Tx channel (other octart) has this flag) */
if (pTxChan->chanOpen)
{
/* Read received byte from UART */
/* Save the byte in the receive buffer */
RNG_ELEM_PUT (pChannel->rdBuf, rxByte, temp);
} /* if */
}
else if( (cir&INT_TYPE_MASK)==XMIT_INT )
{
/* Transmit interrupt */
/* Determine what channel caused the interrupt */
chan = cir & CUR_CHAN_MASK;
/* Future enhancement: could get the number of bytes in the TxFIFO
* from the CIR and GIBCR and process them all at once for efficiency.
*/
/* For debug, can also check the ISR register to cross check the
* interrupt source.
*/
/* Find the channel control structure */
pChannel = sc28l198Uart[uart].channel + chan;
/* Some other interrupt type is pending */
if(pChannel->chanOpen)
{
/* Fetch next byte and send it */
if(RNG_ELEM_GET (pChannel->wrtBuf, &txByte, temp))
/* got a character to be output */
*pChannel->uartTxDataReg = txByte;
else
{
/* Last byte has been sent, disable Txmit */
pChannel->wrtStateBusy = FALSE; /* no more chars in Tx buffer */
sc28l198DisableTxInt(pChannel);
} /* else */
} /* if */
}
else
{
/* Other type of interrupt */
}
/*************************************************************************
* Interrupt Acknowledge logic specific to Axcelis carrier board.
* On this board the interrupts for octart 0 and octart 1 come into
* the processor from port C pins PC12 and PC13.
*
* Clear the pending interrupt at the SIU for this octart.
*/
if (uart == 0)
{
*M8260_SIPNR_H(immrVal) = 0x00080000; /* clear interrupt pending bit */
}
else
{
*M8260_SIPNR_H(immrVal) = 0x00040000; /* clear interrupt pending bit */
}
} /* sc28l198Interrupt() */
/******************************************************************************
* Initialize the interrupt handler.
******************************************************************************/
void
sc28l198InitInterrupts(int uart)
{
/* Attach interrupt handlers for hardware */
intConnect(INUM_TO_IVEC((char) sc28l198Cfg[uart].inum),
sc28l198Interrupt, uart);
/* Enable the interrupt */
intEnable(sc28l198Cfg[uart].inum);
} /* sc28l198InitInterrupts() */
/******************************************************************************
* Flushes a channel's read buffer.
******************************************************************************/
LOCAL void
sc28l198FlushRd (FAST SC28L198_DEV_CHAN *pChannel)
{ /* get exclusive access to the device */
SC28L198_DEV_CHAN *pRxChan = SAME_PCHANNEL_IN_OTHER_OCTART(pChannel);
semTake (pRxChan->mutexSem, WAIT_FOREVER);
rngFlush (pRxChan->rdBuf);
semGive (pRxChan->mutexSem);
} /* sc28l198FlushRd() */
/******************************************************************************
* Flushes a channel'ss write buffer.
******************************************************************************/
LOCAL void
sc28l198FlushWrt(FAST SC28L198_DEV_CHAN *pChannel)
{ /* get exclusive access to the device */
semTake (pChannel->mutexSem, WAIT_FOREVER);
rngFlush (pChannel->wrtBuf);
semGive (pChannel->mutexSem);
} /* sc28l198FlushWrt() */
/******************************************************************************
* Flushes a channel's read and write buffers.
******************************************************************************/
LOCAL void
sc28l198Flush (FAST SC28L198_DEV_CHAN *pChannel)
{
sc28l198FlushRd (pChannel);
sc28l198FlushWrt(pChannel);
} /* sc28l198Flush */
/******************************************************************************
* Task level write routine.
*
* We need to lock the interrupts because the interrupt routine manipulates
* the write state busy flag.
*******************************************************************************/
LOCAL int
sc28l198BufWrite (FAST SC28L198_DEV_CHAN *pChannel, char *buffer, int nBytes)
{
FAST bytesPut;
FAST int oldlevel;
semTake (pChannel->mutexSem, WAIT_FOREVER);
bytesPut = rngBufPut (pChannel->wrtBuf, (char *) buffer, nBytes);
if(!pChannel->wrtStateBusy)
{
oldlevel = intLock (); /* LOCK INTERRUPTS */
/* check xmitter busy again, now that we're locked out */
if(!pChannel->wrtStateBusy)
{
pChannel->wrtStateBusy = TRUE;
intUnlock (oldlevel); /* UNLOCK INTERRUPTS */
sc28l198EnableTxInt(pChannel);
} /* if */
else
{
intUnlock (oldlevel); /* UNLOCK INTERRUPTS */
}
} /* if */
semGive (pChannel->mutexSem);
return(bytesPut);
} /* sc28l198BufWrite() */
/******************************************************************************
* Task level read routine.
******************************************************************************/
LOCAL int
sc28l198BufRead(FAST SC28L198_DEV_CHAN *pChannel, char *buffer, int maxBytes)
{
FAST int nBytes;
FAST RING_ID ringId;
FAST int temp;
char rxByte;
SC28L198_DEV_CHAN *pRxChan = SAME_PCHANNEL_IN_OTHER_OCTART(pChannel);
nBytes = 0;
ringId = pRxChan->rdBuf;
/* Read bytes from rx receive ring */
while((nBytes < maxBytes) && (RNG_ELEM_GET(ringId, &rxByte, temp) != 0))
buffer[nBytes++] = rxByte;
return(nBytes);
} /* sc28l198BufRead() */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -