www.pudn.com > serial_se3208_2.rar > serial_se3208_2.c
#include#include #include #include #include #include #include #include #include #include #include #include #include #include #define UART0_NAME "uart0" #define UART0_MAJOR 206 #define UATR0_MINOR #define USTAT_OVERRUN_ERROR_BIT 0x00000001 #define USTAT_PARITY_ERR0R_BIT 0x00000002 #define USTAT_FRAME_ERR0R_BIT 0x00000004 #define USTAT_BREAK_DETECT_BIT 0x00000008 #define USTAT_RX_EMPTY_BIT 0x00000010 #define USTAT_TX_HOLD_BIT 0x00000020 #define USTAT_TX_EMPTY_BIT 0x00000040 #define USTAT_RX_FIFO_BIT 0x00000F00 #define USTAT_TX_FIFO_BIT 0x0000F000 static DECLARE_WAIT_QUEUE_HEAD(rx_queue); static DECLARE_WAIT_QUEUE_HEAD(tx_queue); static devfs_handle_t devfs_handle, devfs_uart0_dir; static char *dev_iduart0 = UART0_NAME; #define BUFSIZE 128 #define FIFOSIZE 16 #define TIMEOUT 10 unsigned char uart0_rx_buf[BUFSIZE]; static char uart0_tx_buf[BUFSIZE]; size_t rx_buf_count, rx_user_count; size_t tx_buf_count, tx_user_count; static ssize_t uart0_read(struct file *filp, char *buf, size_t count, loff_t *l) { char *user_buf=buf; rx_buf_count=0; rx_user_count=count; while(rx_user_count>0){ if (*USTAT0 & USTAT_RX_EMPTY_BIT){ uart0_rx_buf[rx_buf_count]=*URXB0; rx_buf_count++; }else{ interruptible_sleep_on_timeout(&rx_queue, TIMEOUT); } if (rx_user_count>BUFSIZE && rx_buf_count==BUFSIZE){ copy_to_user(user_buf, &uart0_rx_buf, BUFSIZE); user_buf+=BUFSIZE; rx_buf_count=0; rx_user_count-=BUFSIZE; }else if (rx_user_count==rx_buf_count){ copy_to_user(user_buf, &uart0_rx_buf, rx_user_count); rx_user_count=0; rx_buf_count=0; } } return count; } static ssize_t uart0_write(struct file *filp, const char *buf, size_t count, loff_t *l) { char *user_buf=buf; int i,j=0; tx_buf_count=0; tx_user_count=count; while(tx_user_count>0){ if (tx_user_count>BUFSIZE){ copy_from_user(&uart0_tx_buf, user_buf, BUFSIZE); user_buf+=BUFSIZE; tx_buf_count=BUFSIZE; j=0; tx_user_count-=BUFSIZE; }else if (tx_user_count<=BUFSIZE){ copy_from_user(&uart0_tx_buf, user_buf, tx_user_count); tx_buf_count=tx_user_count; j=0; tx_user_count=0; } while (tx_buf_count>0){ if (tx_buf_count>FIFOSIZE){ for(i=0;i