⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sc28l198serial.c

📁 Embedded Planet公司的ep8260单板计算机的BSP包(VxWorks)
💻 C
📖 第 1 页 / 共 4 页
字号:
                "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 + -