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

📄 sc28l198serial.c

📁 Embedded Planet公司的ep8260单板计算机的BSP包(VxWorks)
💻 C
📖 第 1 页 / 共 4 页
字号:
    return(OK);

} /* sc28l198Ioctl() */

/******************************************************************************
 * Reset a specific channel in the SC28L198.
 ******************************************************************************/
LOCAL void
sc28l198ResetChan(int uart, int chan)
{
    SC28L198_DEV_CHAN *pTxChan;
    SC28L198_DEV_CHAN *pRxChan;

    pTxChan = (SC28L198_DEV_CHAN*) &(sc28l198Uart[uart].channel[chan].devHdr);
    pRxChan = SAME_PCHANNEL_IN_OTHER_OCTART(pTxChan);

    /* Reset the receiver, error status, and break change interrupts.
     */
    pRxChan->lastCR &= CR_ENABLES_MASK;
    pRxChan->lastCR |= RST_RCVR;
    *pRxChan->uartCommandReg = pRxChan->lastCR;

    pRxChan->lastCR &= CR_ENABLES_MASK;
    pRxChan->lastCR |= RST_ERR;
    *pRxChan->uartCommandReg = pRxChan->lastCR;

    pRxChan->lastCR &= CR_ENABLES_MASK;
    pRxChan->lastCR |= RST_BCI;
    *pRxChan->uartCommandReg = pRxChan->lastCR;

    /* Reset the transmitter.
     */
    pTxChan->lastCR &= CR_ENABLES_MASK;
    pTxChan->lastCR |= RST_XMIT;
    *pTxChan->uartCommandReg = pTxChan->lastCR;

    /* Disable receiver and transmitter    */
    pTxChan->lastCR &= CR_ENABLES_MASK;
    pTxChan->lastCR &= ~(TX_ENABLE);
    *pTxChan->uartCommandReg = pTxChan->lastCR;

    pRxChan->lastCR &= CR_ENABLES_MASK;
    pRxChan->lastCR &= ~(RX_ENABLE);
    *pRxChan->uartCommandReg = pRxChan->lastCR;

} /* sc28l198ResetChan() */

/******************************************************************************
 * Convert the user specified data bits to SC28L198-specific value.
 ******************************************************************************/
LOCAL int
sc28l198DataBits(int dataBits)
{
    switch(dataBits)
    {
        case 5:
            return(BPC_CS5);
        case 6:
            return(BPC_CS6);
        case 7:
            return(BPC_CS7);
        case 8:
            return(BPC_CS8);

        default:
            return(ERROR);          
    } /* switch */     
} /* sc28l198DataBits */

/******************************************************************************
 * Convert the user specified stop bits to SC28L198-specific value.
 ******************************************************************************/
LOCAL int
sc28l198StopBits(int stopBits)
{
    switch(stopBits)
    {
        case 1:
            return(STOP_BIT_1);
        case 2:
            return(STOP_BIT_2);

        default:
            return(ERROR);
    } /* switch */
} /* sc28l198StopBits() */

/******************************************************************************
 * Convert the user specified parity setting to SC28L198-specific value.
 ******************************************************************************/
LOCAL int
sc28l198Parity(char *parity)
{
    /* Normal parity modes */
    if(strcmp(parity, "NONE"  ) == 0) return(PARITY_NONE);
    if(strcmp(parity, "EVEN"  ) == 0) return(PARITY_EVEN);
    if(strcmp(parity, "ODD"   ) == 0) return(PARITY_ODD);

    /* Special wake up mode */
    if(strcmp(parity, "SPECIAL") == 0) return(PARITY_SPECIAL);

    return(ERROR);                  
} /* sc28l198Parity() */


/******************************************************************************
 * Convert the user specified baud setting to SC28L198-specific value.
 ******************************************************************************/
LOCAL int
sc28l198BaudRate(int baudRate)
{
    FAST int   baud;              /* Counter to index the baud rate table   */

    /* Search the baud rate table looking for a match. When one is found,
     * return the correct value   
     */
    for (baud = 0; baud < NELEMENTS(baudTable); baud++)
    {
        if (baudTable[baud].baudRate == baudRate)
            return (baudTable[baud].baudValue);
    } /* for */

    /* Specified baud rate not available      */
    return(ERROR);                  

} /* sc28l198BaudRate() */

/******************************************************************************
 * Configure the operational mode of a given channel.  
 * 
 * Including setting the line parameters (stop, data & parity bits)
 * using the actual bit settings for the SC28L198.  
 ******************************************************************************/
void                
sc28l198ConfigChan(int uart, int chan, int dataBits, int stopBits, int parity)
{
    /* Configure same channel (by channel index) in other octart the same
     * way to ensure that Tx and Rx use the same settings.  This demands
     * a restriction that both octarts always use the same number of data
     * bits, stop bits, and parity in the channels with the same indices.
     *
     * For example, octart0 channel 3 and octart1 channel 3 must set these
     * parameters the same, but octart0 channel 3 can be set differently than
     * octart1 channel 4.
     */
    int otherUart = (uart ? 0 : 1);

    /* Disable Xon/Xoff and address recognition */
    /* Set Tx interrupt on empty */
    /* Disable internal flow control */
    *SC28L198_MR0(uart, chan)      = XON_XOFF_TRANS_OFF | ADDR_TRANS_OFF |
                                     TXINT_MT | FLOW_CTRL_HOST | ADDR_CTRL_NONE;

    *SC28L198_MR0(otherUart, chan) = XON_XOFF_TRANS_OFF | ADDR_TRANS_OFF |
                                     TXINT_MT | FLOW_CTRL_HOST | ADDR_CTRL_NONE;

    /* Disable internal receiver RTS control */
    /* Enable interrupt status masking */
    /* Status bits provided on a character by character basis */
    /* Initialize parity and data bit settings */
    *SC28L198_MR1(uart, chan)      = RXRTS_CTRL_OFF | ISR_RD_MASKED |
                                     ERR_MODE_CHAR | parity | dataBits;

    *SC28L198_MR1(otherUart, chan) = RXRTS_CTRL_OFF | ISR_RD_MASKED |
                                     ERR_MODE_CHAR | parity | dataBits;

    /* Put the device in mormal mode */
    /* Disable internal transmitter RTS control */
    /* Trasmitter ignores CTS */
    /* Set Rx interrupt on a single character */
    /* Initialize stop bit setting */
    *SC28L198_MR2(uart, chan)      = NORMAL_MODE | TXRTS_CTRL_OFF |
                                     CTSN_CTRL_TX_OFF | RXINT_RRDY | stopBits;

    *SC28L198_MR2(otherUart, chan) = NORMAL_MODE | TXRTS_CTRL_OFF |
                                     CTSN_CTRL_TX_OFF | RXINT_RRDY | stopBits;

} /* sc28l198ConfigChan() */

/******************************************************************************
 * Set the baud rate using the actual bit settings for the SC28L198. 
 ******************************************************************************/
void 
sc28l198SetBaudRate(int uart, int chan, int baudRate)
{
    int otherUart = (uart ? 0 : 1);

    /* Configure the xmit/rcvr baud rates.  Rx channel is actually in the
     * other uart.
     */
    *SC28L198_TXCSR(uart,chan)=baudRate;
    *SC28L198_RXCSR(otherUart,chan)=baudRate;

} /* sio32SetBaudRate() */

/******************************************************************************
 * Initialize the SC28L198.
 ******************************************************************************/
LOCAL STATUS
sc28l198HrdInit(int uart)
{
    FAST   int chan;              

    /* Setup the GCCR:
     *
     * !!!! NOTE that the datasheet states that the GCCR must be the first 
     * register addressed during initialization.
     *
     * Configure to:
     *   - Support arbitrarily long (asynchronous) bus cycles.
     *   - Chip is not to supply an interrupt vector at interrupt time.
     *   - Power on (enable chip).
     */
    *SC28L198_GCCR(uart)=ASYNC_BUS | (IVC_MASK&IVC_NONE) | PWR_ON;

    /* Initialize all the channels in the uart. */
    for(chan = 0; chan < SC28L198_CHAN_PER_UART; chan ++)
    {
        /* Disable Tx and Rx. */
        sc28l198Uart[uart].channel[chan].lastCR = 0;
        *SC28L198_CR(uart,chan)=sc28l198Uart[uart].channel[chan].lastCR;

        /* Disable all interrupts for this channel */
        sc28l198Uart[uart].channel[chan].lastIMR = 0;
        *SC28L198_IMR(uart,chan) = sc28l198Uart[uart].channel[chan].lastIMR;

    } /* for */

    return(OK);

} /* sc28l198HrdInit() */

/******************************************************************************
 * SC28L198 Driver Initialization Routine.
 ******************************************************************************/
STATUS
sc28l198Drv(void)
{
    FAST    int chan;           
    FAST    int uart; 

    /* Get the physical location of the IMMR register for use later by
     * interrupt routine.
     */
    immrVal = vxImmrGet();

    /* Set the number of channels in the second octart based on which
     * SBC number (3 or 4) on the Axcelis board we are plugged into.
     */
    if (ptrGetBoardID() == 2)  /* Note ID 2 == SBC3 */
    {
      sc28l198Cfg[1].numChannels = SC28L198_NUM_CHANNELS_SBC3;
    }
    else
    {
      sc28l198Cfg[1].numChannels = SC28L198_NUM_CHANNELS_SBC4;
    }

    /* For each physical device in the system */
    for(uart=0; uart<SC28L198_MAX_UARTS; uart++ )
    {
        /* check if driver already installed */
        if(sc28l198Uart[uart].drvNum > 0)
        {
            DRV_LOG(DRV_DEBUG_INIT,
                    "Driver already installed for device %d with driver %d\n",
                    uart, sc28l198Uart[uart].drvNum,0,0,0,0);
            return(OK);
        }

        /* Minimal initialization of the device hardware */
        sc28l198HrdInit(uart);                
        sc28l198Uart[uart].exists = TRUE; 

        /* Allocate channel control structure.     */
        if((sc28l198Uart[uart].channel =
            calloc(SC28L198_CHAN_PER_UART, sizeof(SC28L198_DEV_CHAN))) == NULL)
        {
            sc28l198Error(1, "Channel structure malloc failed\n");
            return(ERROR);
        } /* if */

        /* Fill in the channel control structure for each channel */
        for (chan = 0; chan < SC28L198_CHAN_PER_UART; chan++)
        {
            /* Initialize channel control data structers  */
            sc28l198Uart[uart].channel[chan].uart         = uart;
            sc28l198Uart[uart].channel[chan].chan         = chan;
            sc28l198Uart[uart].channel[chan].created      = FALSE;
            sc28l198Uart[uart].channel[chan].chanOpen     = FALSE;
            sc28l198Uart[uart].channel[chan].wrtStateBusy = FALSE;

            /* Address of Channel Command reg  */
            sc28l198Uart[uart].channel[chan].uartCommandReg =
                                                   SC28L198_CR(uart, chan);

            /* Address of RX/TX Data reg for channel */
            sc28l198Uart[uart].channel[chan].uartTxDataReg =
                                                   SC28L198_TXFIFO(uart, chan);
            sc28l198Uart[uart].channel[chan].uartRxDataReg =
                                                   SC28L198_RXFIFO(uart, chan);

            /* Address of interrupt status reg for channel */
            sc28l198Uart[uart].channel[chan].uartIntStatusReg =
                                                   SC28L198_ISR(uart, chan);

            /* Allocate read and write ring buffers */
            sc28l198Uart[uart].channel[chan].wrtBuf = rngCreate(BUFFER_SIZE);
            sc28l198Uart[uart].channel[chan].rdBuf  = rngCreate(BUFFER_SIZE);

            if ((sc28l198Uart[uart].channel[chan].wrtBuf == NULL) ||
                (sc28l198Uart[uart].channel[chan].rdBuf  == NULL))
            {
              sc28l198Error(0, "Cannot allocate ring buffers\n");
              return(ERROR);
            } /* if */

            /* Create our mutex */
            sc28l198Uart[uart].channel[chan].mutexSem =
                                    semMCreate (SEM_Q_FIFO | SEM_DELETE_SAFE);

        } /* for */
    } /* for */

    /* This loop continues the initialization.  Since some of these
     * initializations reference the Rx channels in the "other" octart,
     * they cannot be done until after the above init loop has setup
     * the basic fields in all channels of both octarts.
     */
    /* For each physical device in the system */
    for(uart=0; uart<SC28L198_MAX_UARTS; uart++ )
    {
        for (chan = 0; chan < SC28L198_CHAN_PER_UART; chan++)
        {
            /* Reset the channel to a known good state */
            sc28l198ResetChan(uart, chan);

            /* Set the channel to a default baud rate of 9600 baud */
            sc28l198SetBaudRate(uart, chan, B9600);

            /* Configure the channel with a default configuration */
            sc28l198ConfigChan(uart, chan, BPC_CS8, STOP_BIT_1, PARITY_NONE);

        } /* for */

        /* Initialize Interrupt Handling */
        sc28l198InitInterrupts(uart);

        /* Add the driver to the vxWorks IO System */
        if((sc28l198Uart[uart].drvNum = 
            iosDrvInstall(  (FUNCPTR) sc28l198Open, (FUNCPTR) NULL,
                            (FUNCPTR) sc28l198Open, (FUNCPTR) sc28l198Close,
                            (FUNCPTR) sc28l198Read, (FUNCPTR) sc28l198Write,
                            (FUNCPTR) sc28l198Ioctl)) < 0)
        {
            /* error number set by iosDrvInstall */
            return(ERROR);
        }

        DRV_LOG(DRV_DEBUG_INIT,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -