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

📄 s3c44b0_uart.c

📁 基于s3c44b0串口uart的驱动程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
        printk("%u chars copied!\n", count );
        printk("writing tl16c760 THR\n");
#endif
        for ( i = 0 ; i <count ; i ++ )
        {
            S3C44B0_UART_FIFO = txMsg[i];
#ifdef  DEBUG
            printk("0x%x ", txMsg[ i ]);
#endif
        }
#ifdef  DEBUG
            printk("done\n");
#endif
        enable_s3c44b0_uart_thre_int( );        /*enable THRE interrup of s3c44b0_uart*/
    }
    else
    {
        if( query_queue_full( &txQueue ) != 1 )
        {
#ifdef DEBUG
            printk("the transimitter is busy!\n we will write msg into txQueue!\n");
            printk("coping msg from user... ...");
#endif
            copy_from_user( txMsg,  buf , count ) ;
#ifdef DEBUG
            printk("done\n");
            printk("writing msg into txQueue\n");
#endif

            for( i = 0 ; i < count ; i ++ )
        	{
                txQueue.data[ txQueue.rear ][ i ] == txMsg[ i ];
#ifdef DEBUG
                printk("0x%x ", txQueue.data[ txQueue.rear ][ i ]);
#endif
        	}

#ifdef DEBUG
            printk("\n");
#endif          
            txQueue.len[ txQueue.rear ] = count ;
#ifdef DEBUG
            printk("txQueue.len[ %u ] = %u\n", txQueue.rear ,count );
            printk("in txQueue... ... ");
#endif

            in_queue( &txQueue );               /*maintanence of  the rxQueue*/
#ifdef DEBUG
            printk("done\n");
            printk("txQueue.front = %u, txQueue.rear = %u",txQueue.front, txQueue.rear);
#endif
        }
        else
        {
            count = 0;  
        }
    
    }
        
    enable_irq( IRQ_S3C44B0_UART );     /*enable s3c44b0_uart interrupt on ARM*/    

    printk("exit write!\n\n");
    
    return count;
}


/*=====================================================
Description:    1.register chrdev and IRQ.
            2.configure the s3c44b0_uart.
Returns:    0--OK       	
======================================================*/    
static int s3c44b0_uart_open(struct inode *inode, struct file *filp)
{
    int ret = 0 ;
    
    if ((ret = request_irq( IRQ_S3C44B0_UART, s3c44b0_uart_handler, SA_INTERRUPT, 
                        S3C44B0_UART_NAME, dev_idkp)))
    {
        printk("s3c44b0_uart interrrupt: failed to register IRQ\n");
        
        free_irq(IRQ_S3C44B0_UART, dev_idkp);
        
        return ret;
    }

#ifdef DEBUG
    printk("Successful to open S3C44B0_UART!\n");
#endif

    disable_irq(IRQ_S3C44B0_UART);          /*disable s3c44b0_uart interrupt on ARM */

    lstCmdReqSN = -1 ;
    lstStsRepSN = 63 ;

    reset_queue( &rxQueue );        /*to initialze rxQueue*/
    reset_queue( &txQueue );            /*to initialze rxQueue*/

    config_s3c44b0_uart();              /*to initialize s3c44b0_uart*/

    enable_irq(IRQ_S3C44B0_UART);           /*enable s3c44b0_uart interrupt on ARM*/
    
    MOD_INC_USE_COUNT;  	

    return 0;
}


/*=====================================================
Description:   close a device.
Returns:    0--OK       	
======================================================*/    
static int s3c44b0_uart_release(struct inode *inode, struct file *filp)
{
    free_irq(IRQ_S3C44B0_UART, dev_idkp);
    
    reset_queue( &rxQueue); 
    reset_queue( &txQueue);

    MOD_DEC_USE_COUNT;  

#ifdef DEBUG
    printk("Successful to close S3C44B0_UART!\n");
#endif  
    return 0;
}


/*=====================================================
Description:   1.disable all the interrupt of s3c44b0_uart.
            2.according to the value of IIR, we can get the source of 
            interrupt.
            3.there are only three types of interrupt that we used here: 
            char time out, receiver line status and transmitter holding 
            register empty.
Returns:    0--OK       
            <0--Faiure.
======================================================*/    
static void s3c44b0_uart_handler(int irq, void *dev_idkp, struct pt_regs *regs)
{
    unsigned char   iir_val = 0 ;                   /*IIR's value*/

    unsigned char   i = 0 ;

    
    disable_irq(IRQ_S3C44B0_UART);                  /*disable s3c44b0_uart interrupt on ARM*/

    iir_val = S3C44B0_UART_IIR; /*get IIR*/

    printk("enter s3c44b0_uart interrupt!\n");

    printk("IIR = 0x%x\n", iir_val);    

    switch( iir_val & 0x0f )
    {
        case IIR_RDA_INT:   /*receiver data available*/

            /*excute the same actinon as IIR_CTOI_INT*/
        	
        case IIR_CTOI_INT :     /*char time out indicater*/
            printk("char time out interrupt!\n");
            if ( query_queue_full( &rxQueue ) == 0) 
            {			
                i = 0;

#ifdef DEBUG        	
                printk("reading msg from s3c44b0_uart receive FIFO......\n");
#endif  
        
                while ( ( S3C44B0_UART_LSR & LSR_DATA_READY ) == 1 )
            	{
                    rxQueue.data[ rxQueue.rear ][ i ] = S3C44B0_UART_FIFO;
#ifdef DEBUG        	
                    printk("0x%x ",rxQueue.data[ rxQueue.rear ][ i ]);
#endif
                    i ++ ;
            	}
#ifdef DEBUG        		
                printk("done\n");
#endif      
        
                rxQueue.len[ rxQueue.rear ] = i ;
#ifdef DEBUG        	
                printk("rxQueue.len[ %u ] = %u\n",  rxQueue.rear , rxQueue.len[ rxQueue.rear ]);
                printk("in rxQueue... ...");
#endif  

                in_queue( &rxQueue );   
#ifdef DEBUG        	
                printk("done!\n");
#endif  
        	}
            else
        	{
#ifdef DEBUG        	
                printk("rxQueue is full\n");
#endif
            }		
            break;
        case IIR_RLS_INT:   /*receiver line status*/
                            /*Overrun error, parity error,framing error or break interrupt*/
                            /*so we do not need to return this status to ARM*/
                            /*deal with it right now!*/
            S3C44B0_UART_LCR = S3C44B0_UART_LCR | LCR_DLAB  ;   /* DLAB = 1 */
            S3C44B0_UART_FCR = FCR_64_BYTE_MODE | FCR_56_TRIGGER_LEVEL_64 | FCR_FIFO_ENALBE| FCR_CLR_RX_FIFO |FCR_CLR_TX_FIFO ;     		
                			
            printk("line status interrupt!\n");
                			
            break;
        case IIR_THRE_INT:  /*transmitter holding register empty*/
        	
            printk("thre interrupt!\n");

            if (query_queue_empty( &txQueue ) != 1)
        	{
#ifdef DEBUG        	
                printk("txQueue is not empty\n");
#endif
                for ( i = 0 ; i < txQueue.len[ txQueue.front ] ; i ++ )
            	{
                    S3C44B0_UART_FIFO = txQueue.data[ txQueue.front][ i ];
#ifdef DEBUG        	
                    printk("0x%x ",  txQueue.data[ txQueue.front][ i ]);
#endif
            	}

#ifdef DEBUG        	
                printk("done \n");
                printk("out txQueue... ...");
#endif          	
                out_queue( &txQueue );
#ifdef DEBUG        	
                printk("done \n");
                printk("txQueue.front = %u, txQueue.rear = %u\n", txQueue.front , txQueue.rear );
#endif
        	}
            else
        	{
#ifdef DEBUG        	
                printk("txQueue is empty, so we disable THRE.\n");
#endif
                disable_s3c44b0_uart_thre_int();    /*disable THRE interrupt*/
            }			

            break;
        default:
            break;
    }

    enable_irq(IRQ_S3C44B0_UART);                   /*enable s3c44b0_uart interrupt on ARM*/
    
    printk("exit s3c44b0_uart interrupt!\n\n"); 
}


/*=====================================================
 Description:   init this module.
Returns:    0--OK       
            <0--Faiure.
======================================================*/    
int __init s3c44b0_uart_init(void)
{
    int ret = 0 ;

    /*register the char device*/
    if ((ret=register_chrdev(S3C44B0_UART_MAJOR, S3C44B0_UART_NAME, &s3c44b0_uart_fops))!=0)
    {
        printk("Failed to register "S3C44B0_UART_NAME "\n");    
        return ret;
    }

#ifdef DEBUG        
    printk("S3C44B0_UART driver initialized\n");
#endif

    return 0;
}


/*=====================================================
 Description:   1.cleanup the module.
            2.remove the registered irq and chrdev.
Returns:    0--OK       
            <0--Faiure.
======================================================*/    
void __exit s3c44b0_uart_cleanup(void)
{

    //free_irq(IRQ_S3C44B0_UART, dev_idkp); 

    unregister_chrdev(S3C44B0_UART_MAJOR, S3C44B0_UART_NAME);   
    
#ifdef DEBUG
    printk("S3C44B0_UART has been removed\n");
#endif

}

module_init(s3c44b0_uart_init); 
module_exit(s3c44b0_uart_cleanup);

EXPORT_NO_SYMBOLS;

MODULE_DESCRIPTION("The driver for S3C44B0_UART");
MODULE_SUPPORTED_DEVICE("uClinux 2.4.x Digital Jet Printer Machine");
MODULE_AUTHOR("gong");
MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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