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