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

📄 sdc.c

📁 文件内包含了nuclues的内核代码和针对Power PC的编译器。需要用VirtNet生成一个虚拟网卡才可使用
💻 C
📖 第 1 页 / 共 4 页
字号:

DV_DEVICE_ENTRY *device;
INT             deviceVector;

#endif /* NU_ENABLE_PPP */

        /* Find the port stucture for this vector. */
        receive = 0;
        while ((SDC_Port_List[receive] != NU_NULL)             &&
               (SDC_Port_List[receive] -> vector != vector)    &&
               (receive < SD_MAX_UARTS) )
            receive++;
        
        /* See if we found one. Better have since we got an interrupt
           from one. */
        if (SDC_Port_List[receive] -> vector == vector)
        {
            /* Point our local structure to it. */
            uart = SDC_Port_List[receive];
            vector_found = NU_TRUE;
        }

#ifdef NU_ENABLE_PPP        

        else
        { 
            /* Find the device for this interrupt */

            /*************** Begin Port Specific Section *************/

            /* Since there is only one interrupt for the UART (as opposed
               to seperate Rx,Tx,etc.) the deviceVector used to determine
               the PPP device will be the same as the vector that activated
               this LISR. */
            deviceVector = vector;

            /**************** End Port Specific Section **************/

            if ( (device = DEV_Get_Dev_For_Vector(deviceVector)) != NU_NULL)
            {
                /* Get the address of the uart structure for this device. */ 
                uart = &((PPP_LAYER *) device->ppp_layer)->uart;
                vector_found = NU_TRUE;    
            }
        } 

#endif /* NU_ENABLE_PPP */

    if (vector_found == NU_TRUE)
    {
        /**************** Begin Port Specific Section **************/

        /*  Read the Interrupt Identification Register (iir) and Line Status
            Register (lsr) into local copies for processing and to clear
            them. */
        iir = SD_INBYTE (uart->base_address + SD_IIR_OFFSET);

        /* Process all interrupts in the UART */
        while ((iir&SD_IIR_INT_PENDING_MASK)==0)
        {
            /* Determint if interrupt is Rx using iir value. */
            if (iir & SD_IIR_INT_RX)
            {
                /* Process every character in the receive FIFO */
                do 
                {   
                    /* Check for Line Status errors */
                    lsr = SD_INBYTE (uart->base_address + SD_LSR_OFFSET);

                    /* Check for a damaged or incorrectly received character */
                    if (lsr  & (SD_LSR_FRAME_ERR | SD_LSR_PARITY_ERR))
                    {
                        if (lsr & SD_LSR_FRAME_ERR)
                        {
                            uart->frame_errors++;
                        }

                        if (lsr & SD_LSR_PARITY_ERR)
                        {
                            uart->parity_errors++;
                        }   

                        /* Consume the character to clear the error bits */
                        receive = SD_INBYTE (uart->base_address + SD_DATA_OFFSET);
                    }
                    else
                    {
                        /* If an overrun has occured, log it */
                        if (lsr & SD_LSR_OVERRUN_ERR)
                        {
                            uart->overrun_errors++;     
                        }
                            
                        switch(uart->communication_mode)
                        {
                            case SERIAL_MODE:
                            
                                 /* Put char into buffer */
                                 receive = SD_INBYTE (uart->base_address + SD_DATA_OFFSET);

                                 if (uart->rx_buffer_status != NU_BUFFER_FULL)
                                 {
                                    /* Put the character into the buffer */
                                    uart->rx_buffer[uart->rx_buffer_write++] = receive;
                    
                                    /* If write pointer is at end, wrap it around */
                                    uart->rx_buffer_write %= uart->sd_buffer_size;
                                
                                    /* Set status field based on latest character */
                                    if (uart->rx_buffer_write == uart->rx_buffer_read)
                                        uart->rx_buffer_status = NU_BUFFER_FULL;
                                    else
                                        uart->rx_buffer_status = NU_BUFFER_DATA;
                                 }
                                 break;
                    
#ifdef NU_ENABLE_PPP                      
                            /* call PPP processing functions */

                            case MDM_NETWORK_COMMUNICATION:
                                 /* Call this devices receive routine */
                                 device->dev_receive(device);
                                 break;

                            case MDM_TERMINAL_COMMUNICATION:
                                 default:
                                 MDM_Receive(device);
                                 break;
#endif /* NU_ENABLE_PPP */
                        } /* end switch */

                    } /* end else */

                /*  Read lsr to get next pending interrupt and clear it. */
                lsr = SD_INBYTE (uart->base_address + SD_LSR_OFFSET);

                } while (lsr & SD_USR_RXRDY);

            } /* end Rx interrupt */

            /* Determine if interrupt is Tx using iir value. */
            else if (iir & SD_IIR_INT_TX)
            {
                if (uart->communication_mode == SERIAL_MODE)
                {    
                    /* update read pointer */
                    uart->tx_buffer_read++;

                    /* Check for wrap of buffer. */
                    uart->tx_buffer_read %= uart->sd_buffer_size;

                    /* Update the status. */
                    if (uart->tx_buffer_write == uart->tx_buffer_read)
                    {
                        uart->tx_buffer_status = NU_BUFFER_EMPTY;

                        /* Since it is now empty turn off the TX
                           interrupt, we do not need it anymore. */
                        SD_OUTBYTE (uart->base_address + SD_IER_OFFSET, 
                           (SD_INBYTE(uart->base_address + SD_IER_OFFSET)
                            & ~(SD_IER_ENABLE_TX)));
                    }
                    
                    else
                    {
                        /* Update the status. */
                        uart->tx_buffer_status = NU_BUFFER_DATA;

                        /* Get next CHAR to be sent. */
                        ch = uart->tx_buffer[uart->tx_buffer_read];
                            
                        /* Send the next byte in the queue. */
                        SD_OUTBYTE (uart->base_address + SD_DATA_OFFSET,ch);
                    }
                }
#ifdef NU_ENABLE_PPP
                else
                {
#ifndef PPP_POLLED_TX
                   /* Check for a transmit interrupt. */
                   /* Is there another byte in the TX buffer to send? */
                   if (uart->tx_buffer_read != uart->tx_buffer_write)
                   {
                       /* Send the next byte in the queue. */
                       SD_OUTBYTE (uart->base_address + SD_DATA_OFFSET,
                                 uart->tx_buffer[uart->tx_buffer_read++]); 
                        
                       /* Check for wrap of ring buffer. */
                       uart->tx_buffer_read %= uart->sd_buffer_size;
                   }
                    
                   else
                   {
                       SD_OUTBYTE (uart->base_address + SD_IER_OFFSET, 
                           (SD_INBYTE(uart->base_address + SD_IER_OFFSET)
                            & ~(SD_IER_ENABLE_TX)));

                       /* Only activate the HISR if we are tranmitting
                          network data. */
                       if (uart->communication_mode == MDM_NETWORK_COMMUNICATION)
                       {
                           /* Add this device to the list of PPP devices that have finished
                              sending a packet. */
                           _ppp_tx_dev_ptr_queue [_ppp_tx_dev_ptr_queue_write++] = device;

                           /* Activate the HISR that will take care of processing the
                              next packet in queue, if one is ready. */
                           NU_Activate_HISR (&PPP_TX_HISR);

                           /* Check for wrap of ring buffer. */
                           _ppp_tx_dev_ptr_queue_write %= PPP_MAX_TX_QUEUE_PTRS;
                        }
                    }
#endif /* PPP_POLLED_TX */
                }
#endif /* NU_ENABLE_PPP */


            } /* end Tx interrupt */
    
            /* Read iir value again. */
            iir = SD_INBYTE (uart->base_address + SD_IIR_OFFSET);        

        } /* end while */

        /* Send the PIC 'EOI' End of interrupt */
        SD_OUTBYTE(SD_BASE + SD_PIC1_BASE_OFFSET, SD_PIC_EOI);

    /**************** End Port Specific Section **************/

    } /* end (vector_found == NU_TRUE) */
    
    /* No port is associated with the vector */
    else 
    {
       ERC_System_Error(NU_UNHANDLED_INTERRUPT);
    }   

}


/****************************************************************************
* FUNCTION                                                                 
*                                                                          
*    SDC_Set_Baud_Rate                                                     
*                                                                          
* DESCRIPTION                                                              
*                                                                          
*    This function sets the UART buad rate.                                
*                                                                          
* INPUTS                                                                  
*                                                                         
*    UINT32      :  The new baud rate.                                  
*    SD_PORT *     :  Serial port to set the baud rate.                   
*                                                                         
* OUTPUTS                                                                 
*                                                                         
*    none                                                                 
*                                                                         
****************************************************************************/
static VOID  SDC_Set_Baud_Rate(UINT32 baud_rate, SD_PORT *uart)
{

UINT16    baud_div;           /* baud rate divisor */
CHAR lcr;

    /**************** Begin Port Specific Section **************/

    /* Set the baud rate */
    baud_div = EXT_SERIAL_CLOCK / baud_rate;

    /* Set the divisor latch bit. */
    lcr = SD_INBYTE(uart->base_address + SD_LCR_OFFSET);
    SD_OUTBYTE(uart->base_address + SD_LCR_OFFSET, lcr | SD_LCR_DLAB);

    /* First write the LSB of the baud rate divisor. */
    SD_OUTBYTE(uart->base_address + SD_DATA_OFFSET, baud_div & 0xff);

    /* Now write the MSB of the baud rate divisor. */
    SD_OUTBYTE(uart->base_address + SD_IER_OFFSET, (baud_div >> 8) & 0xff);

    /* Now that the baud rate has been set turn off DLAB to reference data in
       line control */
    SD_OUTBYTE(uart->base_address + SD_LCR_OFFSET, lcr);

    /**************** End Port Specific Section ****************/

}

⌨️ 快捷键说明

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