📄 lm6063.c
字号:
/** LCD, LED and Button interface for Cobalt** This file is subject to the terms and conditions of the GNU General * License. See the file "COPYING" in the main directory of this archi* for more details.** Copyright (C) 1996, 1997 by Andrew Bose** Linux kernel version history:* March 2001: Ported from 2.0.34 by Liam Davies**/ #include <linux/types.h>#include <linux/module.h>#include <linux/init.h>#include <linux/kernel.h>#include <linux/cdev.h>#include <linux/errno.h>#include <linux/fs.h>#include <linux/slab.h>#include <linux/ioport.h>#include <linux/fcntl.h>#include <linux/sched.h>#include <linux/delay.h>//#include "lm6063.h"#include "lcd.h"#define delay1us(value) udelay(value) //use udelay() in linux#define LCD_LEFT_WARD 0#define LCD_RIGHT_WARD 1#define CHAR_MODE 0#define GRAPH_MODE 1#define HIGH_8 8#define HIGH_16 16#define HIGH_24 24#define HIGH_32 32#define HIGH_64 64#define D_X 0#define D_Y 1#define LM6063_SCR_BUF_SIZE ((128*64)/8)#define LCD_A0 (1 << 5)#define LCD_EN (1 << 7)#define LCD_RES (1 << 6)#define LCD_SDA (1 << 3)#define LCD_SCL (1 << 4) #define lcd_io_07_oen (volatile unsigned char *)(0xbf004100+0x00)#define lcd_io_07_do (volatile unsigned char *)(0xbf004100+0x20)#define lcd_int_en (volatile unsigned char *)(0xbf003200+0x18) //typedef unsigned char uchar; static int lcd_major;static int lcd_minor=0;static unsigned int lcd_open_flag; // 1:openning 0:closestatic unsigned char *lcd_screen_buf;static struct cdev *lcd_cdev;static struct lcd_dev *lcd_devp; extern void lcd_io_init(void); extern void A0(const unsigned char value); extern void EN(const unsigned char value); extern void RES(const unsigned char value); extern void DATA(const unsigned char value); #define nop() asm("nop")//delay(500) //delay(1)--about 1us /* lcd module list */ #define LCD_LM12232C 0 #define LCD_LM6063A 1 /******************** next thress macro for version control *************************/ //#include <stdio.h> //#include <stdarg.h> //#define LCD_PMON #ifdef LCD_PMON #define lprint(fmt,...) printf(fmt,...) #endif #ifdef LCD_LINUX #define lprint(fmt,...) printk(KERN_DEBUG fmt,...) #endif #ifdef LCD_RELEASE #define lprint(fmt,...) #endif /****************** version control end. *******************************************/ struct lcd_config{ unsigned char mode; //should support char mode and grachical mode unsigned char high; //char high,only use at char mode unsigned char contrast; //lcd contrast lever, only use soft control contrast lcd module use. /* char data direct. but now only support y direct dir=y means: A C | / | B D dir=x means A - B / C - D */ unsigned char dir; /* support lcd module list. now support lm12232c,lm6063a. */ unsigned char m_type; /* The display ram address seg output correspondence. for lm12232c: at normal mode(right ward), each block visual seg address is seg0 to seg60(right to left). at reverse mdode(left ward),each block visual seg address is seg19 to seg 79(left to right). for lm6063a: at normal mode(left ward), visual seg address is seg4 to seg131(left t0 right). at reverse mode(right ward), visual seg address is seg0 to seg127(right to left). */ unsigned char ward; //left ward or right /* full screen data buffer size. for lm6063a visual buffer 128x64, scr_buf_size = (128x64)/8 */ unsigned char scr_buf_size; unsigned int s_seg; //first display seg address unsigned int l_seg; //last display seg address /* max line number of lcd. for lm6063 line number is 0 to 7, for lm12232c line number is 0 to 3. */ unsigned int max_line; }; static struct lcd_config lcd_cfg; #define max_col() (lcd_cfg.l_seg - lcd_cfg.s_seg) /* this function don't recommend use in linux. */ static void lcd_delay1ms(const unsigned int nms){ int i; for (i = 0; i < nms; i++){ delay1us(1000); } } static void lcd_io_init(void){ *lcd_io_07_oen |= LCD_A0 | LCD_EN | LCD_RES | LCD_SDA | LCD_SCL; } static void A0(const unsigned char value){ (value) ? (*lcd_io_07_do |= LCD_A0) : (*lcd_io_07_do &= ~LCD_A0); } static void EN(const unsigned char value){ (value) ? (*lcd_io_07_do |= LCD_EN) : (*lcd_io_07_do &= ~LCD_EN); } static void RES(const unsigned char value){ (value) ? (*lcd_io_07_do |= LCD_RES) : (*lcd_io_07_do &= ~LCD_RES); } //iob1 static void DATA(const unsigned char out_data){ char i; for (i = 7; i >= 0; i--){ *lcd_io_07_do &= ~LCD_SCL; nop();nop();nop();nop(); //delay1us(100); if (out_data & (1 << i)){ *lcd_io_07_do |= LCD_SDA; }else{ *lcd_io_07_do &= ~LCD_SDA; } nop();nop();nop();nop(); //delay1us(100); *lcd_io_07_do |= LCD_SCL; nop();nop();nop();nop(); //delay1us(100); } } static void send_data(unsigned char value){ DATA(value); nop();nop(); //delay1us(100); A0(1); nop();nop(); delay1us(2); EN(0); delay1us(5); //udelay(2); EN(1); delay1us(2); } static void send_cmd(unsigned char value){ DATA(value); nop();nop(); //delay1us(100); A0(0); nop();nop(); //delay1us(100); EN(0); delay1us(2); //udelay(2); EN(1); //delay1us(100); } static void lcd_init(void){ lcd_cfg.ward = LCD_LEFT_WARD; lcd_cfg.mode = CHAR_MODE; lcd_cfg.high = HIGH_16; lcd_cfg.dir = D_Y; lcd_cfg.contrast = 0x2c; lcd_cfg.s_seg = 4; lcd_cfg.l_seg = 131; lcd_cfg.max_line = 7; //lcd_cfg.scr_buf_size = ()LM6063_SCR_BUF_SIZE; lcd_io_init(); RES(0); //reset lcd module recommand > 1ms lcd_delay1ms(1000); RES(1); lcd_delay1ms(20); //send_cmd(0xae); //display off send_cmd(0xaf); //display on send_cmd(0x40); //start common address 0 //send_cmd(0xa1); //ADC: set the display ram address seg reverse output. In demo code is 0xa0 send_cmd(0xa0); send_cmd(0xa6); //REV: display normal, reverse display value is 0xa7 send_cmd(0xa4); //EON: display all point off, display all point on value is 0xa5 send_cmd(0xa2); //BIAS: set the lcd driving voltage bias: 1/9 bias send_cmd(0xc0); //SHL: set the com scanning direction normal. In demo code is 0xc8,fipped in y direction send_cmd(0x2f); //VC VR VF: all the power circuit of lcd on send_cmd(0xf8); //booster ratio command send_cmd(0x01); //set booster ratio 5X send_cmd(0x81); //set contrast command send_cmd(lcd_cfg.contrast); } /* for lm6063a page -> line 7 0 6 1 0 7 */ static void set_line(unsigned char line){ send_cmd((7-line) | 0xb0); } static void set_page(unsigned char page){ send_cmd(page | 0xb0); } static void set_address(unsigned char addr){ addr += lcd_cfg.s_seg; //change to real seg address. send_cmd(0x10 | (addr>>4)); send_cmd(addr & 0x0f); } static void set_contrast(unsigned char contrast){ send_cmd(0x81); send_cmd(contrast); } /****************************** the ioctl function *******************************/ static void lcd_on(void){ send_cmd(0xaf);}static void lcd_off(void){ send_cmd(0xae);} static void lcd_clear_scr(void){ unsigned char page,seg; for (page = 0; page < 8; page++){ set_page(page); set_address(0); for (seg = 0; seg < (max_col()+1); seg++){ send_data(0); } } } static void lcd_full_scr(void){ unsigned char page,seg; for (page = 0; page < 8; page++){ set_page(page); set_address(0); for (seg = 0; seg < (max_col()+1); seg++){ send_data(0xff); } } } static void lcd_darker(void){ if (lcd_cfg.contrast > 0){ lcd_cfg.contrast--; set_contrast(lcd_cfg.contrast); } //printf("lcd contrast is %d.\n",lcd_cfg.contrast); } static void lcd_lighter(void){ if (lcd_cfg.contrast < 0x3f){ lcd_cfg.contrast++; set_contrast(lcd_cfg.contrast); } //printf("lcd contrast is %d.\n",lcd_cfg.contrast); } static void lcd_set_contrast(unsigned char contrast){ lcd_cfg.contrast= contrast; set_contrast(lcd_cfg.contrast); } static int lcd_set_ward(unsigned char ward){ lcd_cfg.ward = ward; if (lcd_cfg.ward == LCD_RIGHT_WARD){ send_cmd(0xa1); lcd_cfg.s_seg = 0; }else if(lcd_cfg.ward == LCD_LEFT_WARD){ send_cmd(0xa0); lcd_cfg.s_seg = 4; }else{ //printf("input error.\n"); } //printf("lcd start seg is %d.\n",lcd_cfg.s_seg); return 0; } /* static int lcd_set_char_high(int argc,char **argv){ lcd_cfg.high = (unsigned char)strtoul(argv[1],0,0); printf("set lcd char high %d.\n",lcd_cfg.high); return 0; } static int lcd_set_char_dir(int argc, char **argv){ lcd_cfg.dir = (unsigned char)strtoul(argv[1],0,0); printf("set lcd char dir %d.\n",lcd_cfg.dir); return 0; } */ /************************* ioctl function end. *********************************/ static unsigned char LineToPage(unsigned char line){ if (line == 0){ return 1; }else if (line == 1){ return 0; }else if (line == 2){ return 3; }else if (line == 3){ return 2; }else{ //never run to here. return -1; } } /* this function only use for draw bitmap for LdmChar.exe generate database. */ static void draw_bmp(unsigned char x0, unsigned char y0, unsigned char x_cnt, unsigned char y_cnt, unsigned char *bmp) { unsigned char i; unsigned char index; unsigned char line_tmp; //unsigned char y_cnt; unsigned int y_offset; unsigned int x,y; int test = 0; //printk("x0=%d,y0=%d,x_cnt=%d,y_cnt=%d.\n",x0,y0,x_cnt,y_cnt); if (D_Y == lcd_cfg.dir){ y = y0; //printf("y = %d\n", y); for (i=0; i <y_cnt; i++,y++){ y_offset = 0; set_line(y); set_address(x0); for (x=0; x<x_cnt; x++){ //printk("\nK:buf[%d] = 0x%x.\n",i+y_offset,bmp[i+y_offset]); send_data(bmp[i+y_offset]); y_offset += y_cnt; test++; } //printf("i = %d.\n",i); } }else{ //normal never run to here. //printf("can't support this font now.\n"); } //printk("\ntest = %d.\n",test); } static void draw_bmp_zk(unsigned char x0, unsigned char y0, unsigned char x_cnt, unsigned char y_cnt, unsigned char *bmp) { unsigned char i; unsigned char index; unsigned char line_tmp; //unsigned char y_cnt; unsigned int y_offset; unsigned int x,y; int test = 0; //printk("x0=%d,y0=%d,x_cnt=%d,y_cnt=%d.\n",x0,y0,x_cnt,y_cnt); if (D_Y == lcd_cfg.dir){ y = y0; //printf("y = %d\n", y);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -