#include "main.h" #include "io.h" #include <stdio.h> #include <stdarg.h> #include <memory.h> #include <errno.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/mman.h> #include <sys/ioctl.h> #include <fcntl.h> #include <signal.h> #include "gpio.h" /* HW size(bit) */ #define LCD_WIDTH 320 #define LCD_HEIGHT 240
//sd133x status //#define LCDC_REG (*((volatile unsigned char *)map_base_LCDC)) #define LCDC_REG (*map_base_LCDC) //#define LCDC_REG (*((volatile unsigned char *)0x40000000)) #define FIRSTPAGE 0 #define BEEP 0x7 #define CLRSCR 0x1B
void *map_base; //phy 0xffff f000 virtual address volatile unsigned char *map_base_LCDC; //LCDC(0x40000000 virtual address
#define __lcd_param() *((unsigned long*)(map_base + ((PIOB_OFFSET + AT91_PIO_CODR)))) = 0x1<<9; //PB9 as 0 #define __lcd_cmd() *((unsigned long*)(map_base + ((PIOB_OFFSET + AT91_PIO_SODR)))) = 0x1<<9; //PB9 as 1 //0 input;1 output
#define SD1335_TIMEOUT 20000 unsigned short cur_add=0xffff; //unsigned short layer_size = ((LCD_WIDTH ) / 8-1) * LCD_HEIGHT ; unsigned short layer_size = ((LCD_WIDTH + 4) / 8) * LCD_HEIGHT ; //4 pixel cross , maybe can use the comment value
//Send command to LCD controller void sd1335_cmd(unsigned char val) { unsigned int timeout = SD1335_TIMEOUT; __lcd_param(); while ((LCDC_REG & 0x40) && (timeout-- != 0)); __lcd_cmd(); LCDC_REG = (val); // if ( timeout == 0 ) // { // LedMove(); // } }
//send command or data to LCD controller port void sd1335_outb(unsigned char val) { unsigned int timeout = SD1335_TIMEOUT; while ((LCDC_REG & 0x40) && (timeout-- != 0)); LCDC_REG= (val); // if ( timeout == 0 ) // { // LedMove(); // } }
//LCD controller init void device_init(unsigned int width, unsigned int height) { unsigned char p[10]; int i; //set PIOC pin11 as NCS5 and use up resistor and ........... //AT91F_PIO_CfgPeriph(AT91C_BASE_PIOC, AT91C_PC11_NCS5_CFCE1, 0); //AT91C_BASE_EBI->EBI_CFGR = (AT91C_EBI_DBPUC & 0x00) | (AT91C_EBI_EBSEN & 0x00); *((unsigned long*)(map_base + ((PIOC_OFFSET + AT91_PIO_PDR )))) = 0x1<<11; //PC11 not as gpio *((unsigned long*)(map_base + ((PIOC_OFFSET + AT91_PIO_PUER)))) = 0x1<<11; //use internal up resistor *((unsigned long*)(map_base + ((PIOC_OFFSET + AT91_PIO_ASR)))) = 0x1<<11; // as function A (NCS5)
//PB9 as gpio output //AT91F_PIO_CfgOutput(AT91C_BASE_PIOB, AT91C_PIO_PB9); *((unsigned long*)(map_base + ((PIOB_OFFSET + AT91_PIO_PER )))) = 0x1<<9; //PB9 as gpio *((unsigned long*)(map_base + ((PIOB_OFFSET + AT91_PIO_OER )))) = 0x1<<9; //PB9 as output
//NCS5 Static mem controler register //*((unsigned long*)(map_base +0x0f70+0x14))= 0x54c0; p[0] = 0x30; p[1] = 0x87; //Font width 8*8 p[2] = 0x07; //p[3] = width / 8-1; p[3] = width / 8; p[4] = p[3] + 4; p[5] = height - 1; //p[6] = (width / 8-1) % 256; p[6] = (width / 8) % 256; //p[7] = (width / 8-1) / 256; p[7] = (width / 8) / 256; sd1335_cmd(0x40); //init device and dispaly __lcd_param(); for (i=0; i<8; i++) sd1335_outb(p);
p[0] = 0x00; //page1 address and length p[1] = 0x00; p[2] = height; p[3] = layer_size & 0xff;//page2 address and length p[4] = layer_size >> 8; p[5] = height; p[6] = 0x00;//page3 address p[7] = 0x00; p[8] = 0x00;//page4 address p[9] = 0x00;
sd1335_cmd(0x44); //set dispaly all page start adress __lcd_param(); for (i=0; i<10; i++) sd1335_outb(p);
sd1335_cmd(0x5a); //horizontal scroll is 00 __lcd_param(); sd1335_outb(0x00);
sd1335_cmd(0x5b); //dispaly overlay format __lcd_param(); //OV=0 two layer composition // sd1335_outb(0x0c);//DM1/2=1 graphics mode ; MX=0 OR mode sd1335_outb(0x00);//DM1/2=1 graphics mode ; MX=0 OR mode //page1 is text,page2 is graphics //page1 addr:00 //page2 address and length //value is: layer_size //display result:page1 OR page2 sd1335_cmd(0x58); //display on/off and flash (set Off) // sd1335_cmd(0x59); __lcd_param(); // sd1335_outb(0x00); sd1335_outb(0x16);//Flash 2hz,Page0 flash 0;Page1 flash 2;page3 off
sd1335_cmd(0x4c); //set direction of cursor movment (right)
sd1335_cmd(0x46); //set cursor address __lcd_param(); //at 0000 sd1335_outb(0x00); sd1335_outb(0x00);
sd1335_cmd(0x42); //write to all layer,clear all screen __lcd_param(); for (i=0;i<(layer_size) * 3; i++) sd1335_outb(0x00);
sd1335_cmd(0x5d); //Set cursor type __lcd_param(); sd1335_outb(0x07);//width 8 sd1335_outb(0x87);//block cursor,high 8
sd1335_cmd(0x59);//display on/off and flash (set On) __lcd_param(); sd1335_outb(0x16);//Flash 2hz,Page0 flash 0;Page1 flash 2;page3 off
}
#if 0 //static unsigned int hacking_count = 0; //8bit reverse //0->7 //1->6 //.... //7->0 static inline unsigned char byte_rev(unsigned char b) { unsigned char tmp; int ii; unsigned char ddd[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; unsigned char sss[8] = { 7, 5, 3, 1, 1, 3, 5, 7}; tmp = 0; for (ii=0; ii<4; ii++) tmp |= ((b & ddd[ii]) >> sss[ii]); for (ii=0; ii<4; ii++) tmp |= ((b & ddd[ii + 4]) << sss[ii + 4]); return tmp; } #else #define byte_rev(b) (b) #endif // Bug hacking //put all date in buffer to screen void _sd1335_putscrn(unsigned char *map_buf) { int i, j; sd1335_cmd(0x46); __lcd_param(); sd1335_outb(0x00); sd1335_outb(0x00); sd1335_cmd(0x42); __lcd_param(); j = 0; for (i=0;i<layer_size;i++) { sd1335_outb(byte_rev(map_buf[j++])); }
}
//LCD clear screen /*------------------------------------------------------------------------------ -*/ void _sd133x_clrscr(void) { int i, j;
sd1335_cmd(0x46); __lcd_param(); sd1335_outb(0x00); sd1335_outb(0x00); sd1335_cmd(0x42); __lcd_param(); j = 0; for (i=0;i<layer_size;i++) { //clear text screen sd1335_outb(' '); } for (i=layer_size;i<2*layer_size;i++) { //clear graph screen sd1335_outb(0x00); } sd1335_cmd(0x46); __lcd_param(); sd1335_outb(0x00); sd1335_outb(0x00); cur_add=0; }
//sed133x lcd controler init void _sd133x_init(void) { device_init(LCD_WIDTH, LCD_HEIGHT); sd1335_cmd(0x46); __lcd_param(); sd1335_outb(00); sd1335_outb(00); cur_add=0; } /*------------------------------------------------------------------------------ set display mem address,only use internal call,user cannot use directly 16bit address. -- -------------------------------------------------------------------------------- -*/ void _sd133x_SetAddress(signed short add) { unsigned char cc1,cc2; signed short add1; add1=add;
sd1335_cmd(0x46); //set address __lcd_param(); cc1=add1%256; cc2=add1/256; sd1335_outb(cc1); sd1335_outb(cc2); cur_add=add1; }
/*------------------------------------------------------------------------------ set text cursor position x 0..39 y 0..29 --------------------------------------------------------------------------------*/
void _sd133x_text_cursor(signed short x,signed short y) { _sd133x_SetAddress(x+y*LCD_WIDTH/8); } /*------------------------------------------------------------------------------ set graphics cursor,our display struct is page0 is text,and page1 is graphics. if use other struct,the function have to modify for that display struct x 0..319 y 0..239 --------------------------------------------------------------------------------*/
void _sd133x_graph_cursor(signed short x,signed short y) { _sd133x_SetAddress(layer_size+x/8+y*LCD_WIDTH/8); } /*------------------------------------------------------------------------------ putpixel() of graphics if put chinese character should not use the function,if use the function to put chinese it will be slow 15x than putpixel in every 16 pixcel if cursor dispaly , the raad date will be two position ahead of the cursor */
void _sd133x_putpixel(signed short x,signed short y) { int i,j; unsigned char ch,ch1; _sd133x_graph_cursor(x,y); sd1335_cmd(0x43); //read from display mem __lcd_cmd(); ch=LCDC_REG; //get an old value in that position,can get continous _sd133x_graph_cursor(x,y); sd1335_cmd(0x42); //write to display mem __lcd_param();
ch1= ch | (1<<(7-(x % 8))); // printf("x= %d, y= %d, ch =%x, ch1=%x \n\r",x,y,ch,ch1);
sd1335_outb(ch1); } /*------------------------------------------------------------------------------ clearpixel() of graphics */ void _sd133x_clearpixel(signed short x,signed short y) { unsigned char ch,ch1; _sd133x_graph_cursor(x,y); sd1335_cmd(0x43); //read from display mem __lcd_param(); ch=LCDC_REG; //get an old value in that position,can get continous _sd133x_graph_cursor(x,y); sd1335_cmd(0x42); //write to display mem __lcd_param(); ch1= ch & (~(1<<(7-(x % 8)))); sd1335_outb(ch1); } /*------------------------------------------------------------------------------ get the text position of current cursor include graphics mode x 0..121 y 0..3 In text area return 0; In graph area return 1; --------------------------------------------------------------------------------*/
unsigned char _sd133x_curr_cursor(signed short *x, signed short *y) { //no check over limit of text or graph if (cur_add < layer_size) //in page1 of text area { *x=cur_add % (LCD_WIDTH/8) ; *y=cur_add / (LCD_WIDTH/8); return 0; } else { *x=(cur_add - layer_size) % (LCD_WIDTH/8) ; *y=(cur_add - layer_size) / (LCD_WIDTH/8) ; return 1; } }
/*------------------------------------------------------------------------------ every english charset is 8x8 bitmap only display from 0x20 to 0x7f , all ASCIII code. --------------------------------------------------------------------------------*/ void _sd133x_LcdPutCh(unsigned char ch) { signed short x,y; if (ch=='\r') //no need to do any thing return; if (ch=='\n') //need to <CR> { _sd133x_curr_cursor(&x,&y); _sd133x_text_cursor(0,y+1); // ser_send_int16(0,x); // ser_send_char(0,' '); // ser_send_int16(0,y); // ser_send_char(0,'\n'); // ser_send_char(0,'\r'); return; }
sd1335_cmd(0x42); //write to display mem __lcd_param(); sd1335_outb(ch);
} /*------------------------------------------------------------------------------ -- write a string to LCD \n will <CR>, string length must be less then 255. It will be display line by line, if display after last line,it will be display in first line --------------------------------------------------------------------------------*/ void _sd133x_LcdPutS(unsigned char *Str) { sd1335_cmd(0x42); //write to display mem __lcd_param(); while (((*Str)!=0)) { // sd1335_outb(*Str); _sd133x_LcdPutCh(*Str); Str++; } } //main fuction of LCD #define DEBUGMSG(x, y, args...) printf(y, ##args) //#define DEBUGMSG(x, y, args...) int main() { int fd,i,j; short x,y; unsigned char str1[] = " -- Aerospace Information -1234566 \n\r"; unsigned char ch,ch1;
if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1){ DEBUGMSG(DEBUG_ERR, "gpio: Error opening /dev/mem\n"); exit(-1); } //map 0xffff map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, AT91_SYS);//AT91_SYS = 0xffff f000 map_base_LCDC = mmap(0, 65535, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0x40000000); //LCDC address /* *((unsigned long*)(map_base + ((PIOA_OFFSET + AT91_PIO_PER )))) = 0x3; //PA0:PA1 as gpio *((unsigned long*)(map_base + ((PIOA_OFFSET + AT91_PIO_OER )))) = 0x3; //PA0:PA1 as output *((unsigned long*)(map_base + ((PIOB_OFFSET + AT91_PIO_PER )))) = 0x1<<27; //PB27 as gpio *((unsigned long*)(map_base + ((PIOB_OFFSET + AT91_PIO_OER )))) = 0x1<<27; //PB27 as output *((unsigned long*)(map_base + ((PIOB_OFFSET + AT91_PIO_CODR)))) = 0x1<<27; //PB27 light (0) for (i=0;i<5;i++) { *((unsigned long*)(map_base + ((PIOA_OFFSET + AT91_PIO_SODR)))) = 0x3; //PA0:PA1=1,Led will not light usleep(50000); *((unsigned long*)(map_base + ((PIOA_OFFSET + AT91_PIO_CODR)))) = i & 0x3; //PA0:PA1=0,Led will light usleep(50000); } *((unsigned long*)(map_base + ((PIOB_OFFSET + AT91_PIO_SODR)))) = 0x1<<27; //PB27 not light (1) */ /* Unmap previously mapped page */
_sd133x_init(); for (i=0;i<100;i++) { _sd133x_text_cursor(0,8); _sd133x_clrscr(); _sd133x_LcdPutS(str1);
for (x=0;x<320;x++) { _sd133x_putpixel(x,0); _sd133x_putpixel(x,239); } for (y=0;y<240;y++) { _sd133x_putpixel(0,y); _sd133x_putpixel(319,y); } for (x=40; x<320-40; x++) for (y=30;y<240-30;y++) _sd133x_putpixel(x,y); } if(munmap(map_base, MAP_SIZE) == -1){ DEBUGMSG(DEBUG_ERR, "Error unmapping memory\n"); close(fd); exit(-1); }
close(fd); }
|
|