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

📄 mdacon_lcd.c

📁 T6963LCD屏的驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
    u16 i;#ifdef LCD_DEBUG        printk(KERN_DEBUG "mdacon.c for lcd: 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);    }}#ifdef MODULEstatic void mda_initialize(void)#else__initfunc(static void mda_initialize(void))#endif{    u16 i;    // initialize control port    CEHI;  // disable chip    RDHI;  // disable reading from LCD    WRHI;  // disable writing to LCD    CDHI;  // command/status mode    DATAOUT; // make 8-bit parallel port an output port    write_lcd_command_word(SET_GRAPHIC_HOME_ADDRESS,ATTRIB_BASE);    write_lcd_command_word(SET_GRAPHIC_AREA,LCD_NUM_COLUMNS);    write_lcd_command_word(SET_TEXT_HOME_ADDRESS,TEXT_BASE);    write_lcd_command_word(SET_TEXT_AREA,LCD_NUM_COLUMNS);    write_lcd_command(SET_MODE | ATTRIBUTE_MODE | EXTERNAL_CG);    write_lcd_command_2_bytes(SET_OFFSET_REGISTER,CHARGEN_BASE>>11,0);    write_lcd_command(SET_CURSOR_PATTERN | 7); // cursor is 8 lines high    write_lcd_command_2_bytes(SET_CURSOR_POINTER,0,0);        // load 6x8 font with VGA map    write_lcd_command_word(SET_ADDRESS_POINTER,CHARGEN_BASE);    for (i=0; i<FONTDATAMAX; ++i) {        write_lcd_command_byte(DATA_WRITE_INC,fontdata_6x8[i]);    }    lcd_enable_text();    lcd_enable_graphic();    lcd_enable_cursor();    lcd_enable_blink();    lcd_clear_text_area();}#ifdef MODULEstatic const char *mdacon_startup(void)#else__initfunc(static const char *mdacon_startup(void))#endif{	lcd_num_columns = LCD_NUM_COLUMNS;	lcd_num_lines   = LCD_NUM_LINES;        lcd_ram_len  = 0x2000;	lcd_data_port = 0x378;	lcd_status_port = lcd_data_port+1;	lcd_control_port = lcd_data_port+2;	lcd_type = TYPE_LCD;	lcd_type_name = "generic Toshiba T6963C";	if (! mda_detect()) {		printk("mdacon.c for lcd: LCD not detected.\n");		return NULL;	}	mda_initialize();	printk("mdacon: %s with %ldK of memory detected.\n",		lcd_type_name, lcd_ram_len/1024);	return "LCD-0";}static void mdacon_init(struct vc_data *c, int init){#ifdef LCD_DEBUG        printk(KERN_DEBUG "mdacon.c for lcd: mdacon_init %i\n",init);#endif	c->vc_complement_mask = 0x0800;	 /* reverse video */	c->vc_display_fg = &lcd_display_fg;	if (init) {		c->vc_cols = lcd_num_columns;		c->vc_rows = lcd_num_lines;	} else {		vc_resize_con(lcd_num_lines, lcd_num_columns, c->vc_num);        }		/* make the first MDA console visible */	if (lcd_display_fg == NULL)		lcd_display_fg = c;	MOD_INC_USE_COUNT;}static void mdacon_deinit(struct vc_data *c){#ifdef LCD_DEBUG        printk(KERN_DEBUG "mdacon.c for lcd: mdacon_deinit\n");#endif	/* con_set_default_unimap(c->vc_num); */	if (lcd_display_fg == c)		lcd_display_fg = NULL;	MOD_DEC_USE_COUNT;}static inline u16 lcd_convert_attr(u16 ch){    /* only reverse, blinking and reverse+blinking supported */    /* underline simulated by reverse */    u16 attr=0;#ifdef LCD_DEBUG        printk(KERN_DEBUG "mdacon.c for lcd: mdacon_convert_attr %i\n",ch);#endif    if (ch & 0x8000) {        // blink        attr |= 0x0800;    }    if (ch & 0x1000) {        // reverse        attr |= 0x0500;    }    if (ch & 0x0800) {        // underline, simulate by reverse        attr |= 0x0500;    }    return (ch & 0x00ff) | attr;}static u8 mdacon_build_attr(struct vc_data *c, u8 color, u8 intensity, 			    u8 blink, u8 underline, u8 reverse){#ifdef LCD_DEBUG        printk(KERN_DEBUG "mdacon.c for lcd: mdacon_build_attr "               "%i,%i,%i,%i,%i\n",color,intensity,blink,underline,reverse);#endif    return (intensity & 3) |           ((underline & 1) << 2) |           ((reverse   & 1) << 3) |           ((blink     & 1) << 7);}static void mdacon_invert_region(struct vc_data *c, u16 *p, int count){  /*        u16 i;        printk(KERN_DEBUG "mdacon.c for lcd: unimplemented mdacon_invert_region begin"               "%p,%i\n",p,count);	for (i=0; i<count; ++i) {	  printk(KERN_DEBUG "mdacon.c for lcd: pos %i=%i\n",i,*(p+i));	}        printk(KERN_DEBUG "mdacon.c for lcd: mdacon_invert_region end\n");	*/}static void mdacon_putc(struct vc_data *c, int ch, int y, int x){    u16 ch_converted;    u16 position;#ifdef LCD_DEBUG        printk(KERN_DEBUG "mdacon.c for lcd: mdacon_putc "               "%i,%i,%i\n",ch,y,x);#endif    position=POSITION(x,y);    ch_converted=lcd_convert_attr(ch);    // save character to memory buffer    screen[position]=ch_converted;    // write character code to LCD    write_lcd_command_word(SET_ADDRESS_POINTER,TEXT_BASE+position);    write_lcd_command_byte(DATA_WRITE,ch_converted & 0x00ff);    // write character attribute to LCD    write_lcd_command_word(SET_ADDRESS_POINTER,ATTRIB_BASE+position);    write_lcd_command_byte(DATA_WRITE,ch_converted>>8);    //lcd_enable_text();    //lcd_enable_graphic();}static void mdacon_putcs(struct vc_data *c, const unsigned short *s,		         int count, int y, int x){    u16 i;    u16 position;#ifdef LCD_DEBUG        printk(KERN_DEBUG "mdacon.c for lcd: mdacon_putcs begin "               "%p,%i,%i,%i\n",s,count,y,x);#endif    position=POSITION(x,y);    // save characters to memory buffer    for (i=0; i<count; ++i) {#ifdef LCD_DEBUG        printk(KERN_DEBUG "mdacon.c for lcd: mdacon_putcs char "               "%i\n",*(s+i));#endif        screen[position+i]=lcd_convert_attr(*(s+i));    }    // write character codes to LCD    write_lcd_command_word(SET_ADDRESS_POINTER,TEXT_BASE+position);    for (i=0; i<count; ++i) {        write_lcd_command_byte(DATA_WRITE_INC,screen[position+i] & 0x00ff);    }    // write character attributes to LCD    write_lcd_command_word(SET_ADDRESS_POINTER,ATTRIB_BASE+position);    for (i=0; i<count; ++i) {        write_lcd_command_byte(DATA_WRITE_INC,screen[position+i]>>8);    }#ifdef LCD_DEBUG        printk(KERN_DEBUG "mdacon.c for lcd: mdacon_putcs end\n");#endif    //lcd_enable_text();    //lcd_enable_graphic();}static void mdacon_clear(struct vc_data *c, int y, int x,             		  int height, int width){    int xx,yy;#ifdef LCD_DEBUG        printk(KERN_DEBUG "mdacon.c for lcd: mdacon_clear "               "%i,%i,%i,%i\n",y,x,height,width);#endif    if (width <= 0 || height <= 0)      	return;    for (yy=0; yy<height; ++yy) {        for (xx=0; xx<width; ++xx) {            mdacon_putc(c,c->vc_video_erase_char,y+yy,x+xx);        }    }}                        static void mdacon_bmove(struct vc_data *c, int sy, int sx, 			 int dy, int dx, int height, int width){        printk("mdacon.c for lcd: unimplemented mdacon_bmove "               "%i,%i,%i,%i,%i,%i\n",sy,sx,dy,dx,height,width);}static int mdacon_switch(struct vc_data *c){	return 1;	/* redrawing needed */}static int mdacon_set_palette(struct vc_data *c, unsigned char *table){	return -EINVAL;}static int mdacon_blank(struct vc_data *c, int blank){        printk("mdacon.c for lcd: unimplemented mdacon_blank %i\n",blank);	return 0;}static int mdacon_font_op(struct vc_data *c, struct console_font_op *op){	return -ENOSYS;}static int mdacon_scrolldelta(struct vc_data *c, int lines){#ifdef LCD_DEBUG        printk(KERN_DEBUG "mdacon.c for lcd: mdacon_scrolldelta %i\n",lines);#endif	return 0;}static void mdacon_cursor(struct vc_data *c, int mode){#ifdef LCD_DEBUG        printk(KERN_DEBUG "mdacon.c for lcd: mdacon_cursor %i\n",mode);#endif	if (mode == CM_ERASE) {                lcd_disable_cursor();		return;	}        write_lcd_command_2_bytes(SET_CURSOR_POINTER,c->vc_x,c->vc_y);	switch (c->vc_cursor_type & 0x0f) {		case CUR_LOWER_THIRD:	lcd_set_cursor_size(0, 1); break;		case CUR_LOWER_HALF:	lcd_set_cursor_size(0, 3); break;		case CUR_TWO_THIRDS:	lcd_set_cursor_size(0, 5); break;		case CUR_BLOCK:		lcd_set_cursor_size(0, 7); break;		case CUR_NONE:		lcd_set_cursor_size(8, 7); break;		default:		lcd_set_cursor_size(0, 1); break;	}        lcd_enable_cursor();}static void lcd_memset(u16 d, const unsigned short ch, u16 count){    u16 i;    u16 ch_converted;    ch_converted=lcd_convert_attr(ch);    // memset to memory buffer    for (i=0; i<count; ++i) {        screen[d+i]=ch_converted;    }    // memset to LCD text area    write_lcd_command_word(SET_ADDRESS_POINTER,TEXT_BASE+d);    for (i=0; i<count; ++i) {        write_lcd_command_byte(DATA_WRITE_INC,ch_converted & 0x00ff);    }    // memset to LCD attribute area    write_lcd_command_word(SET_ADDRESS_POINTER,ATTRIB_BASE+d);    for (i=0; i<count; ++i) {        write_lcd_command_byte(DATA_WRITE_INC,ch_converted>>8);    }}static void lcd_memmove(u16 d, u16 s, u16 count){    u16 i;    if (d<s) {        // move memory buffer        for (i=0; i<count; ++i) {            screen[d+i]=screen[s+i];	}    } else {        // move memory buffer        for (i=0; i<count; ++i) {            screen[d+count-1-i]=screen[s+count-1-i];	}    }    // update LCD text area    write_lcd_command_word(SET_ADDRESS_POINTER,TEXT_BASE+d);    for (i=0; i<count; ++i) {        write_lcd_command_byte(DATA_WRITE_INC,screen[d+i] & 0x00ff);    }    // update LCD attribute area    write_lcd_command_word(SET_ADDRESS_POINTER,ATTRIB_BASE+d);    for (i=0; i<count; ++i) {        write_lcd_command_byte(DATA_WRITE_INC,screen[d+i]>>8);    }}static int mdacon_scroll(struct vc_data *c, int t, int b, int dir, int lines){#ifdef LCD_DEBUG        printk(KERN_DEBUG "mdacon.c for lcd: mdacon_scroll "               "t=%i,b=%i,dir=%i,lines=%i\n",t,b,dir,lines);#endif        if (!lines) return 0;        if (lines>c->vc_rows) lines=c->vc_rows;        switch (dir) {        case SM_UP:            lcd_memmove(POSITION(0,t),POSITION(0,t+lines),                        (b-t-lines)*lcd_num_columns);            lcd_memset(POSITION(0,b-lines),c->vc_video_erase_char,                       lines*lcd_num_columns);            break;        case SM_DOWN:            lcd_memmove(POSITION(0,t+lines),POSITION(0,t),                        (b-t-lines)*lcd_num_columns);            lcd_memset(POSITION(0,t),c->vc_video_erase_char,                       lines*lcd_num_columns);            break;        }        //lcd_enable_text();        //lcd_enable_graphic();#ifdef LCD_DEBUG        printk(KERN_DEBUG "mdacon.c for lcd: mdacon_scroll more "               "eattr=%i,lines=%i,lcd_num_columns=%i,c->vc_rows=%i\n",               c->vc_video_erase_char,lines,lcd_num_columns,c->vc_rows);#endif	return 0;}/* *  The console `switch' structure for the MDA based console */struct consw mda_con = {	mdacon_startup,		/* con_startup */	mdacon_init,		/* con_init */	mdacon_deinit,		/* con_deinit */	mdacon_clear,		/* con_clear */	mdacon_putc,		/* con_putc */	mdacon_putcs,		/* con_putcs */	mdacon_cursor,		/* con_cursor */	mdacon_scroll,		/* con_scroll */	mdacon_bmove,		/* con_bmove */	mdacon_switch,		/* con_switch */	mdacon_blank,		/* con_blank */	mdacon_font_op,		/* con_font_op */	mdacon_set_palette,	/* con_set_palette */	mdacon_scrolldelta,	/* con_scrolldelta */	NULL,			/* con_set_origin */	NULL,			/* con_save_screen */	mdacon_build_attr,	/* con_build_attr */	mdacon_invert_region,	/* con_invert_region */};#ifdef MODULEvoid mda_console_init(void)#else__initfunc(void mda_console_init(void))#endif{	if (mda_first_vc > mda_last_vc)		return;	take_over_console(&mda_con, mda_first_vc-1, mda_last_vc-1, 0);}#ifdef MODULEint init_module(void){	mda_console_init();	return 0;}void cleanup_module(void){	give_up_console(&mda_con);}#endif#ifdef STANDALONEint main(void){    unsigned short buffer[80];    struct vc_data c;    int i;    ioperm(0x378,3,1);    ioperm(0x80,1,1);    c.vc_rows=16;    c.vc_cols=40;    c.vc_video_erase_char=32;    mdacon_startup();    mdacon_init(&c,1);    for (i=0; i<16; ++i) {        buffer[0]=i/10+48;        buffer[1]=i%10+48;        mdacon_putcs(&c,buffer,2,i,0);    }    mdacon_scroll(&c,0,16,1,1);    return 0;}#endif // def STANDALONE

⌨️ 快捷键说明

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