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

📄 vgacon_lcd.c

📁 T6963LCD屏的驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  vgacon_lcd.c -- console driver for LCDs with a Toshiba T6963C controller * *  Version 0.1, 11 Apr 2000, for Linux kernel 2.2.10 * *  (c) 1999-2000 Alexander Frink <Alexander.Frink@Uni-Mainz.DE> * *  Replace linux/drivers/video/vgacon.c with this file to use the *  display as the primary "video card". * *  Adjust LCD_NUM_COLUMNS and LCD_NUM_LINES to the size of your display. *  *  This file is based on the original console drivers for VGA and MDA *  cards (linux/drivers/video/vgacon.c and linux/drivers/video/mdacon.c) *  mainly written by Linus Torvalds, Jay Estabrook, Geert Uytterhoeven, *  Martin Mares, Patrick Caulfield and Andrew Apted 1991-1998. *  The logic to access the T6963C is taken from a program written *  by John P. Beale 1997. * *  This file is subject to the terms and conditions of the GNU General Public *  License.  See the file LICENSE in the main directory of this archive for *  more details. *///#define STANDALONE//#define LCD_DEBUG#ifndef STANDALONE#include <linux/types.h>#include <linux/sched.h>#include <linux/fs.h>#include <linux/kernel.h>#include <linux/module.h>#include <linux/tty.h>#include <linux/console.h>#include <linux/console_struct.h>#include <linux/string.h>#include <linux/kd.h>#include <linux/malloc.h>#include <linux/vt_kern.h>#include <linux/vt_buffer.h>#include <linux/selection.h>#include <linux/ioport.h>#include <linux/delay.h>#include <linux/init.h>#include <asm/io.h>#include <asm/vga.h>#else // ndef STANDALONE#include <asm/io.h>#include <unistd.h>typedef unsigned short u16;typedef unsigned char u8;void cli(void) {}void save_flags(unsigned long f) {}void restore_flags(unsigned long f) {}void vc_resize_con(unsigned int l, unsigned int c, unsigned short n) {}struct vc_data {    unsigned int vc_rows;    unsigned short vc_complement_mask;    struct vc_data **vc_display_fg;    unsigned int vc_cols;    unsigned short vc_num;    unsigned int vc_x;    unsigned int vc_y;    unsigned short vc_video_erase_char;    unsigned int vc_cursor_type;};struct console_font_op {};struct consw {	const char *(*con_startup)(void);	void	(*con_init)(struct vc_data *, int);	void	(*con_deinit)(struct vc_data *);	void	(*con_clear)(struct vc_data *, int, int, int, int);	void	(*con_putc)(struct vc_data *, int, int, int);	void	(*con_putcs)(struct vc_data *, const unsigned short *, int, int, int);	void	(*con_cursor)(struct vc_data *, int);	int	(*con_scroll)(struct vc_data *, int, int, int, int);	void	(*con_bmove)(struct vc_data *, int, int, int, int, int, int);	int	(*con_switch)(struct vc_data *);	int	(*con_blank)(struct vc_data *, int);	int	(*con_font_op)(struct vc_data *, struct console_font_op *);	int	(*con_set_palette)(struct vc_data *, unsigned char *);	int	(*con_scrolldelta)(struct vc_data *, int);	int	(*con_set_origin)(struct vc_data *);	void	(*con_save_screen)(struct vc_data *);	u8	(*con_build_attr)(struct vc_data *, u8, u8, u8, u8, u8);	void	(*con_invert_region)(struct vc_data *, u16 *, int);	u16    *(*con_screen_pos)(struct vc_data *, int);	unsigned long (*con_getxy)(struct vc_data *, unsigned long, int *, int *);};void take_over_console(struct consw *con, int f, int l, int dummy) {}#define printk printf#define KERN_DEBUG ""//#define NULL 0#define __initfunc(X) X#define MAX_NR_CONSOLES 64#define SM_UP (1)#define SM_DOWN (2)#define MOD_INC_USE_COUNT#define MOD_DEC_USE_COUNT#define EINVAL 0#define ENOSYS 0#define CM_ERASE (2)#define CUR_LOWER_THIRD 3#define CUR_LOWER_HALF 4#define CUR_TWO_THIRDS 5#define CUR_BLOCK 6#define CUR_NONE 1#endif // ndef STANDALONE/* *  Interface used by the world */static const char *lcdcon_startup(void);static void lcdcon_init(struct vc_data *c, int init);static void lcdcon_deinit(struct vc_data *c);static void lcdcon_cursor(struct vc_data *c, int mode);static int lcdcon_switch(struct vc_data *c);static int lcdcon_blank(struct vc_data *c, int blank);static int lcdcon_font_op(struct vc_data *c, struct console_font_op *op);static int lcdcon_set_palette(struct vc_data *c, unsigned char *table);static int lcdcon_scrolldelta(struct vc_data *c, int lines);static int lcdcon_set_origin(struct vc_data *c);static void lcdcon_save_screen(struct vc_data *c);static int lcdcon_scroll(struct vc_data *c, int t, int b, int dir, int lines);static u8 lcdcon_build_attr(struct vc_data *c, u8 color, u8 intensity, u8 blink, u8 underline, u8 reverse);static void lcdcon_invert_region(struct vc_data *c, u16 *p, int count);static unsigned long lcdcon_uni_pagedir[2];/* description of the hardware layout */static unsigned long	lcd_vram_base;		/* Base of video memory */static unsigned long	lcd_vram_len;		/* Size of video memory */static unsigned int	lcd_num_columns;	/* Number of text columns */static unsigned int	lcd_num_lines;		/* Number of text lines */static unsigned int lcd_data_port;static unsigned int lcd_status_port;static unsigned int lcd_control_port;/* current hardware state */static int	lcd_origin_loc=-1;static int	lcd_cursor_size_from=-1;static int	lcd_cursor_size_to=-1;static u8       lcd_display_mode=0;static enum { TYPE_LCD } lcd_type;static char *lcd_type_name;static struct vc_data	*lcd_display_fg = NULL;// take PC 1 HI#define CEHI    outb_p(inb_p(lcd_control_port) & 0xfe, lcd_control_port)// take PC 1 LO#define CELO    outb_p(inb_p(lcd_control_port) | 0x01, lcd_control_port)// take PC 14 HI#define RDHI    outb_p(inb_p(lcd_control_port) & 0xfd, lcd_control_port)// take PC 14 LO#define RDLO    outb_p(inb_p(lcd_control_port) | 0x02, lcd_control_port)// take PC 16 HI#define WRHI    outb_p(inb_p(lcd_control_port) | 0x04, lcd_control_port)// take PC 16 LO#define WRLO    outb_p(inb_p(lcd_control_port) & 0xfb, lcd_control_port)// take PC 17 HI#define CDHI    outb_p(inb_p(lcd_control_port) & 0xf7, lcd_control_port)// take PC 17 LO#define CDLO    outb_p(inb_p(lcd_control_port) | 0x08, lcd_control_port)// 8bit Data input#define DATAIN  outb_p(inb_p(lcd_control_port) | 0x20, lcd_control_port)// 8bit Data output#define DATAOUT outb_p(inb_p(lcd_control_port) & 0xdf, lcd_control_port)// get LCD display status bytestatic inline u8 read_lcd_status(void){    unsigned long flags;    u8 lcd_status;    save_flags(flags); cli();    DATAIN;                  // make 8-bit parallel port an input    CDHI;                    // bring LCD C/D line high (read status byte)    RDLO;                    // bring LCD /RD line low (read active)    CELO;                    // bring LCD /CE line low (chip-enable active)    lcd_status =         inb_p(lcd_data_port);  // read LCD status byte    CEHI;                    // bring LCD /CE line high, disabling it    RDHI;                    // deactivate LCD read mode    DATAOUT;                 // make 8-bit parallel port an output port    // printk(KERN_DEBUG "lcdcon: status=%i\n",lcd_status);    restore_flags(flags);    return(lcd_status);}static inline void lcd_wait_until_ready(void){    do {    } while ((0x03 & read_lcd_status()) != 0x03);}// write data byte to LCD module over par. port// assume PC port in data OUTPUT modestatic inline void write_lcd_data(u8 byte){    unsigned long flags;    save_flags(flags); cli();    lcd_wait_until_ready();    CDLO;    WRLO;                       // activate LCD's write mode    outb_p(byte,lcd_data_port);   // write value to data port    CELO;                       // pulse enable LOW > 80 ns (hah!)    CEHI;                       // return enable HIGH    WRHI;                       // restore Write mode to inactive    // using my P5/75 MHz PC with ISA bus, CE stays low for 2 microseconds    restore_flags(flags);} // get data byte from LCD modulestatic inline u8 read_lcd_data(void){    unsigned long flags;    u8 lcd_byte;    save_flags(flags); cli();    lcd_wait_until_ready();    DATAIN;                        // make PC's port an input port    WRHI;                          // make sure WRITE mode is inactive    CDLO;                          // data mode    RDLO;                          // activate READ mode    CELO;                          // enable chip, which outputs data    lcd_byte = inb_p(lcd_data_port); // read data from LCD    CEHI;                          // disable chip    RDHI;                          // turn off READ mode    DATAOUT;                       // make 8-bit parallel port an output port    restore_flags(flags);    return(lcd_byte);}// write command byte to LCD module// assumes port is in data OUTPUT modestatic inline void write_lcd_command(u8 byte){    unsigned long flags;    save_flags(flags); cli();    lcd_wait_until_ready();    outb_p(byte,lcd_data_port);  // present data to LCD on PC's port pins    CDHI;                      // control/status mode    RDHI;                      // make sure LCD read mode is off    WRLO;                      // activate LCD write mode    CELO;                      // pulse ChipEnable LOW, > 80 ns, enables LCD I/O    CEHI;                      // disable LCD I/O    WRHI;                      // deactivate write mode    restore_flags(flags);}#define LCD_NUM_COLUMNS 40#define LCD_NUM_LINES 16#define SCREENSIZE (LCD_NUM_COLUMNS*LCD_NUM_LINES)#define CHARGEN_BASE 0x0000#define TEXT_BASE 0x0800#define ATTRIB_BASE 0x1000#define SET_CURSOR_POINTER 0x21#define SET_OFFSET_REGISTER 0x22#define SET_ADDRESS_POINTER 0x24#define SET_TEXT_HOME_ADDRESS 0x40#define SET_TEXT_AREA 0x41#define SET_GRAPHIC_HOME_ADDRESS 0x42#define SET_GRAPHIC_AREA 0x43#define SET_MODE 0x80#define OR_MODE 0x00#define EXOR_MODE 0x01#define AND_MODE 0x03#define ATTRIBUTE_MODE 0x04#define INTERNAL_CG 0x00#define EXTERNAL_CG 0x08#define SET_DISPLAY_MODE 0x90#define BLINK_ON 0x01#define CURSOR_ON 0x02#define TEXT_ON 0x04#define GRAPHIC_ON 0x08#define SET_CURSOR_PATTERN 0xa0#define DATA_WRITE_INC 0xc0#define DATA_READ_INC 0xc1#define DATA_WRITE_DEC 0xc2#define DATA_READ_DEC 0xc3#define DATA_WRITE 0xc4#define DATA_READ 0xc5#define AUTO_WRITE 0xb0#define AUTO_READ 0xb1#define AUTO_RESET 0xb2#include "font_6x8.c"#define POSITION(x,y)  ((y)*lcd_num_columns + (x))static u16 screen[SCREENSIZE];static u16 vram[SCREENSIZE];static inline void write_lcd_command_word(u8 cmd, u16 word){    write_lcd_data(word%256);    write_lcd_data(word>>8);    write_lcd_command(cmd);}static inline void write_lcd_command_2_bytes(u8 cmd, u8 byte1, u8 byte2){    write_lcd_data(byte1);    write_lcd_data(byte2);    write_lcd_command(cmd);}static inline void write_lcd_command_byte(u8 cmd, u8 byte){    write_lcd_data(byte);    write_lcd_command(cmd);}static void init_auto_read(u16 addr){    write_lcd_command_word(SET_ADDRESS_POINTER,addr);    write_lcd_command(AUTO_READ);    DATAIN;                        // make PC's port an input port    WRHI;                          // make sure WRITE mode is inactive    RDHI;                          // make sure READ mode is inactive}static void status_check_2(void){    u8 lcd_byte;    CDHI;                          // command mode    WRHI;    do {        RDLO;                          // activate READ mode        CELO;        lcd_byte = inb_p(lcd_data_port); // read data from LCD#ifdef LCD_DEBUG        printk(KERN_DEBUG "lcdcon: status_check_2 %i\n",lcd_byte);#endif        CEHI;        RDHI;    } while ((lcd_byte & 0x4) == 0);}static u8 next_auto_read(void){    u8 lcd_byte;    status_check_2();    WRHI;    CDLO;    RDLO;    CELO;    lcd_byte=inb_p(lcd_data_port);    CEHI;    RDHI;    return lcd_byte;}static void end_auto_read(void){    status_check_2();    RDHI;    WRHI;    DATAOUT;    write_lcd_command(AUTO_RESET);}static void lcd_enable_cursor(void){    lcd_display_mode |= CURSOR_ON;    write_lcd_command(SET_DISPLAY_MODE | lcd_display_mode);}static void lcd_disable_cursor(void){    lcd_display_mode &= ~CURSOR_ON;    write_lcd_command(SET_DISPLAY_MODE | lcd_display_mode);}static void lcd_enable_blink(void){    lcd_display_mode |= BLINK_ON;    write_lcd_command(SET_DISPLAY_MODE | lcd_display_mode);}static void lcd_disable_blink(void){    lcd_display_mode &= ~BLINK_ON;    write_lcd_command(SET_DISPLAY_MODE | lcd_display_mode);}static void lcd_enable_text(void){    lcd_display_mode |= TEXT_ON;    write_lcd_command(SET_DISPLAY_MODE | lcd_display_mode);}static void lcd_disable_text(void){    lcd_display_mode &= ~TEXT_ON;    write_lcd_command(SET_DISPLAY_MODE | lcd_display_mode);}static void lcd_enable_graphic(void){    lcd_display_mode |= GRAPHIC_ON;    write_lcd_command(SET_DISPLAY_MODE | lcd_display_mode);}static void lcd_disable_graphic(void){    lcd_display_mode &= ~GRAPHIC_ON;    write_lcd_command(SET_DISPLAY_MODE | lcd_display_mode);}static inline void lcd_set_cursor_size(u8 from, u8 to){#ifdef LCD_DEBUG        printk(KERN_DEBUG "lcdcon: lcd_set_cursor_size %i,%i\n",               from,to);#endif	if (lcd_cursor_size_from==from && lcd_cursor_size_to==to)		return;		if (from > to) {                lcd_disable_cursor();	} else {                if (to>7) to=7;	        write_lcd_command(SET_CURSOR_PATTERN | to);                lcd_enable_cursor();	}	lcd_cursor_size_from = from;	lcd_cursor_size_to   = to;}static void lcd_clear_text_area(void){    u16 i;#ifdef LCD_DEBUG        printk(KERN_DEBUG "lcdcon: lcd_clear_text_area\n");#endif    // clear memory screen buffer    for (i=0; i<SCREENSIZE; ++i) {        screen[i]=0;    }    // clear LCD text area    write_lcd_command_word(SET_ADDRESS_POINTER,TEXT_BASE);    for (i=0; i<SCREENSIZE; ++i) {        write_lcd_command_byte(DATA_WRITE_INC,0);    }    // clear LCD attribute area    write_lcd_command_word(SET_ADDRESS_POINTER,ATTRIB_BASE);    for (i=0; i<SCREENSIZE; ++i) {        write_lcd_command_byte(DATA_WRITE_INC,0);    }}void no_scroll(char *str, int *ints){}__initfunc(static const char *lcdcon_startup(void))

⌨️ 快捷键说明

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