'File: GSED256A.BAS 'Program to test the SED1330 Controller based graphic LCD 'To be used with the GLTOOLS Ver 1.4 Windows application 'Written in PICBasicPro Ver 2.42 'Revision 1.0 'Display to be used: 256x128 Graphic LCD 'Development board GLiPIC w/ 256x128 lcd and negative voltage adapter. '================================================================== ' ***** THIS CODE IS NOT FOR COMMERCIAL USE ***** '================================================================== ' ' Author: Ranjit Diol, COMPSys Date: July, 2002 ' (c) Copyright COMPSys, 2002 ' ' DISCLAIMER: This file is being released as non-commericial ' software. It is being provided "AS IS", neither the author, ' nor COMPSys shall be held liable for any damages caused ' by its use. ' ' It can be distributed freely in its entirety, portions may be used in ' non-commercial applications as long as the author is given credit for those ' portions used. ' ' Contact: rsdiol@compsys1.com for more information ' '********************************************************************************** ' ' PLEASE NOTE: This is an abreviated version of a larger application, hence, ' You may find numerous defined variables that are never used, ' and will lack much documentation. ' '********************************************************************************** ' 'clear all variables clear DEFINE ONINT_USED 1 'Required if using ISP DEFINE OSC 20 'OSC speed, you may have to tweak the 'strobe' 'routine's e_pause constant for other speeds ADCON1 = 7 'Make all pins digital, you may adjust as needed ' Set receive register to receiver enabled DEFINE HSER_RCSTA 90h DEFINE HSER_BAUD 19200 'Baud = 19200 DEFINE HSER_SPBRG 15 'Must be changed depending on Osc. used, see PIC datasheet ' Set transmit register to transmitter enabled DEFINE HSER_TXSTA 20h DEFINE HSER_CLROERR 1 'Hser clear overflow automatically ' Set baud rate 'DEFINE HSER_SPBRG 31 'Hser spbrg init 'DEFINE HSER_BAUD 9600 'Temp variables used tmp_x var BYTE tmp_y var BYTE tmp_x = 0 tmp_y = 0 '*** PIC PINS REQUIRED *** ' 'PLEASE NOTE: '================================================================== 'Following is the GLiPIC pcb configuration 'Change the assignments as needed if you do not use the GLiPIC pcb '================================================================== 'Set pins for output TRISB.1 = 0 'LCD Reset TRISB.2 = 0 'LCD RD TRISD = 0 'LCD 8 bit data bus TRISC.0 = 0 'LCD A0 data/command TRISC.1 = 0 'LCD WR TRISC.2 = 0 'LCD CS 'Variable assignments gl_dat var PORTD gl_a0 var PORTC.0 gl_rd var PORTB.2 gl_wr var PORTC.1 gl_cs var PORTC.2 gl_rst var PORTB.1 gl_tris var TRISD gl_cs = 0 'Chip select active 'Serial I/O definitions and variables out_pin var PORTC.6 'Serial OUT pin in_pin var PORTC.7 'Serial IN pin ser_baud con 32 '19200 Baud 813=2400 in_dat var BYTE 'In coming byte data in_lsb var BYTE 'In coming lsb of word in_msb var BYTE 'In coming msb of word gl_chr var BYTE 'Character byte eep_addr var WORD 'External eeprom address hex_nibble var BYTE 'Var used for incoming data 'Terminal variables in_array var BYTE[64] 'In coming array in_ctl var BYTE[10] 'In coming control array buff_count var BYTE 'General counter gl_size var WORD 'Delay variable gl_idx var BYTE 'General use gl_idy var BYTE 'General use 'Added for placement of small images imgX var BYTE 'Start pos X and Y imgY var BYTE imgW var BYTE 'Image width imgH var BYTE 'Image height xcnt var BYTE ycnt var BYTE l_end var BYTE bLCD var BYTE 'Byte ti be displayed xStep con 8 'Byte width horiz yStep con 8 'Byte height vert 'EEprom scl VAR PORTC.3 'I2C SCL for ext eeprom sda VAR PORTC.4 'I2C SDA for ext eeprom ctl CON $A0 'EEprom control code XON con $11 XOFF con $13 e_size var WORD w_tmp var WORD w_cnt var WORD 'Constants used SYS_SET con $40 SYS_SLEEP con $53 SYS_CGRAM_ADDR con $5C SYS_SCROLL con $44 SYS_SCROLL_HDOT con $5a SYS_SCROLL_RATE con $5a SYS_CUR_FORM con $5d SYS_CUR_ADDR con $46 SYS_CUR_READ con $47 SYS_CUR_DIR_RT con $4c SYS_CUR_DIR_LT con $4d SYS_CUR_DIR_UP con $4e SYS_CUR_DIR_DN con $4f SYS_OVER_LAY con $5b SYS_MWRITE con $42 SYS_MREAD con $43 LCD_DISP_ON con $59 LCD_DISP_OFF con $58 LCD_INVERSE con $ff LCD_NORMAL con $00 LCD_CR con $20 '32 Chars/bytes per line LCD_W con $100 '256 pixels wide LCD_H con $80 '128 pixels high LCD_Lh con $08 'Height of line (8x8 characters) LCD_L1 con $00 'Line 1 LCD_L2 con $20 'Line 2 LCD_L3 con $40 'Line 3 LCD_L4 con $60 'Line 4 LCD_L5 con $80 'Line 5 LCD_L6 con $A0 'Line 6 LCD_L7 con $C0 'Line 7 LCD_L8 con $E0 'Line 8 LCD_L9 con $100 'Line 9 LCD_L10 con $120 'Line 10 LCD_L11 con $140 'Line 11 LCD_L12 con $160 'Line 12 LCD_L13 con $180 'Line 13 LCD_L14 con $1A0 'Line 14 LCD_L15 con $1C0 'Line 15 LCD_L16 con $1E0 'Line 16 LCD_GRH con $1000 'Graphic home position 'General Variables used gl_cmd var BYTE gl_cur var BYTE gl_byte var BYTE gl_i var BYTE gl_j var BYTE gl_k var BYTE gl_x var WORD gl_y var WORD gl_addr var WORD gl_w var WORD gl_read var BYTE gl_old var BYTE pix_x var WORD pix_y var WORD gl_addrlo var WORD gl_addrhi var WORD gl_nib var BYTE gl_rst = 0 pause 1 gl_rst = 1 'Make sure reset is high pause 100 'serout2 out_pin,ser_baud,["Starting...",10,13] hserout ["Starting.."] 'xloop: ' hserin [wait ("]"),HEX gl_k] ' hserout [hex gl_k] 'goto xloop: goto main 'Jump over subroutines ' '===== SUBROUTINES ============ ' send_dat: gl_a0 = 0 gl_dat = gl_byte goto gl_strobe send_cmd: gl_a0 = 1 gl_dat = gl_cmd gl_strobe: gl_wr = 0 @ nop gl_wr = 1 gl_a0 = 0 return 'Clear Graphic Screen gl_grfclr: gl_cmd = SYS_CUR_ADDR 'CSRW command gosub send_cmd gl_byte = $00 gosub send_dat gl_byte = $10 gosub send_dat gl_cmd = SYS_CUR_DIR_RT 'Cur movement right gosub send_cmd gl_cmd = SYS_MWRITE gosub send_cmd gl_byte = LCD_NORMAL for gl_i = 1 to 128 for gl_j = 1 to 32 gosub send_dat next gl_j next gl_i gl_cmd = SYS_CUR_ADDR 'CSRW command gosub send_cmd gl_byte = $00 gosub send_dat gl_byte = $10 gosub send_dat gl_cmd = SYS_CUR_DIR_RT 'Cur movement right gosub send_cmd return gl_grfhome: gl_cmd = SYS_CUR_ADDR 'CSRW command gosub send_cmd gl_byte = $00 gosub send_dat gl_byte = $10 gosub send_dat gl_cmd = SYS_CUR_DIR_RT 'Cur movement right gosub send_cmd return 'Clear Text screen gl_txtclr: gl_cmd = SYS_CUR_ADDR 'CSRW command gosub send_cmd gl_byte = $00 gosub send_dat gl_byte = $00 gosub send_dat gl_cmd = SYS_CUR_DIR_RT 'Cur movement right gosub send_cmd gl_cmd = SYS_MWRITE gosub send_cmd for gl_i = 1 to 16 for gl_j = 1 to 32 gl_byte = $20 'ASCII Space gosub send_dat next gl_j next gl_i gl_cmd = SYS_CUR_ADDR 'CSRW command gosub send_cmd gl_byte = $00 gosub send_dat gl_byte = $00 gl_cmd = SYS_CUR_DIR_RT 'Cur movement right gosub send_cmd return gl_init: 'Setup LCD gl_cmd = SYS_SET gosub send_cmd for gl_i = 0 to 7 'P1 P2 P3 P4 P5 P6 P7 P8 lookup gl_i,[$30,$87,$07,$1f,$52,$7f,$20,$0],gl_byte gosub send_dat next gl_i 'scroll gl_cmd = SYS_SCROLL gosub send_cmd for gl_i = 0 to 5 lookup gl_i,[$0,$0,$7f,$00,$10,$7f],gl_byte gosub send_dat next gl_i 'Hdot gl_cmd = SYS_SCROLL_RATE gosub send_cmd gl_byte =$0 gosub send_dat 'Overlay gl_cmd = SYS_OVER_LAY gosub send_cmd gl_byte = %00000001 gosub send_dat 'DISP OFF gl_cmd =LCD_DISP_OFF gosub send_cmd gl_byte = %00010110 gosub send_dat 'Clear Graphic screen gosub gl_grfclr 'Clear Text screen gosub gl_txtclr 'CSRW set cursor home gl_cmd = SYS_CUR_ADDR gosub send_cmd gl_byte = $0 gosub send_dat gl_byte = $0 gosub send_dat gl_cmd = SYS_CUR_DIR_RT gosub send_cmd gl_byte = SYS_MWRITE gosub send_dat gl_byte = $0 gosub send_dat 'CSR FORM gl_cmd =SYS_CUR_FORM gosub send_cmd gl_byte = $04 gosub send_dat gl_byte = $86 gosub send_dat 'DISP ON gl_cmd = LCD_DISP_ON gosub send_cmd gl_byte = %00010100 'cursor off gosub send_dat 'CSR DIR gl_cmd = SYS_CUR_DIR_RT gosub send_cmd return 'Find hex nibble gl_find: Lookdown in_array[gl_i],["0123456789ABCDEF"],hex_nibble return 'Routine to set the address 'assumes address is in gl_addr and cursor movment in gl_cur gl_setaddr: 'CSRW set cursor home gl_cmd = SYS_CUR_ADDR 'Address command gosub send_cmd gl_byte = gl_addr.BYTE0 'Vram text memory starts at $0000 and graphics at $1000 gosub send_dat gl_byte = gl_addr.BYTE1 gosub send_dat gl_cmd = gl_cur 'Set cursor movement to left,right,up or down gosub send_cmd return 'End of subroutines '============================================ ' BEGIN MAIN PROGRAM '============================================ main: 'Begin Program gosub gl_init 'Initialize display 'Display a message and draw a border around it 'First set text address and cursor direction '*** Message centered in LCD ****** gl_addr = LCD_L6 + 5 'Line 7 and 5 bytes to right gl_cur = SYS_CUR_DIR_RT gosub gl_setaddr 'MWRITE gl_cmd =SYS_MWRITE gosub send_cmd for gl_i = 0 to 21 lookup gl_i,["PIC Controlled SED1330"],gl_byte gosub send_dat next gl_i gl_addr = LCD_L7 + 6 'Line 7 and 5 bytes to right gl_cur = SYS_CUR_DIR_RT gosub gl_setaddr 'MWRITE gl_cmd =SYS_MWRITE gosub send_cmd for gl_i = 0 to 18 lookup gl_i,["256x128 Graphic LCD"],gl_byte gosub send_dat next gl_i gl_addr = LCD_L8 + 3 'Line 8 and 3 bytes to right gl_cur = SYS_CUR_DIR_RT gosub gl_setaddr 'MWRITE gl_cmd =SYS_MWRITE gosub send_cmd for gl_i = 0 to 26 lookup gl_i,["Using PicBasicPro Ver. 2.42"],gl_byte gosub send_dat next gl_i gl_addr = LCD_L9 + 5 'Line 8 and 3 bytes to right gl_cur = SYS_CUR_DIR_RT gosub gl_setaddr 'MWRITE gl_cmd =SYS_MWRITE gosub send_cmd for gl_i = 0 to 20 lookup gl_i,["Ranjit Diol - COMPSys"],gl_byte gosub send_dat next gl_i gl_addr = LCD_L10 + 4 'Line 10 and 3 bytes to right gl_cur = SYS_CUR_DIR_RT gosub gl_setaddr 'MWRITE gl_cmd =SYS_MWRITE gosub send_cmd for gl_i = 0 to 22 lookup gl_i,["http://www.compsys1.com"],gl_byte gosub send_dat next gl_i gl_addr = LCD_L13 + 2 'Line 10 and 3 bytes to right gl_cur = SYS_CUR_DIR_RT gosub gl_setaddr 'MWRITE gl_cmd =SYS_MWRITE gosub send_cmd for gl_i = 0 to 26 lookup gl_i,["Use with GLCD TOOLS Ver 1.4"],gl_byte gosub send_dat next gl_i 'Now draw a border around LCD '============================ ' 'Left vert Line gl_addr = LCD_GRH + 0 'Graphic home position $1000 gl_cur = SYS_CUR_DIR_DN 'Cur movement to right gosub gl_setaddr 'MWRITE gl_cmd =SYS_MWRITE gosub send_cmd gl_byte = %10000000 'Bit 7 set for gl_i = 0 to 127 gosub send_dat next gl_i 'Right vert Line gl_addr = LCD_GRH + 31 'Graphic home position $1000 gl_cur = SYS_CUR_DIR_DN 'Cur movement to right gosub gl_setaddr 'MWRITE gl_cmd =SYS_MWRITE gosub send_cmd gl_byte = %00000001 'Bit 0 set for gl_i = 0 to 127 gosub send_dat next gl_i 'Top Line gl_addr = LCD_GRH + 0 'Graphic home position $1000 gl_cur = SYS_CUR_DIR_RT 'Cur movement to right gosub gl_setaddr 'MWRITE gl_cmd =SYS_MWRITE gosub send_cmd gl_byte = %11111111 'All bits set for gl_i = 0 to 31 gosub send_dat next gl_i 'Bottom Line gl_addr = LCD_GRH + $0FE0 'Set bottom right addr gl_cur = SYS_CUR_DIR_RT 'Cur movement to left gosub gl_setaddr 'MWRITE gl_cmd =SYS_MWRITE gosub send_cmd gl_byte = %11111111 'All bits set for gl_i = 0 to 31 gosub send_dat next gl_i 'Terminal Subroutine term: 'Assumes Home Position ' gosub gl_grfhome ' gosub send_cmd 'Setup variables gl_j=0 gl_i=0 gl_k=0 buff_count = 32 gl_addr = 0 gl_x = 0 gl_y = 0 gl_idx = 120 gl_idy = 0 'MAIN LOOP Get the initial parameters hserout ["Waiting..",10,13] get_param: hserout[XON,XON,XON] hserin [wait ("@"),STR in_ctl\11] hserout [XOFF,XOFF,XOFF,XOFF] 'Get the attention of the PC gosub gl_txtclr for gl_i = 0 to 10 Lookdown in_ctl[gl_i],["0123456789ABCDEF"],hex_nibble in_ctl[gl_i]=hex_nibble next gl_j=in_ctl[0] buff_count = (in_ctl[1]<<4) | in_ctl[2] gl_addr.byte1 = (in_ctl[3] <<4) | in_ctl[4] gl_addr.byte0 = (in_ctl[5] <<4) | in_ctl[6] imgW = (in_ctl[7]<<4) | in_ctl[8] imgH = (in_ctl[9]<<4) | in_ctl[10] imgX = gl_addr.byte1 imgY = gl_addr.byte0 'EEProm setup 'LCD Tools send the Address and the the Size in bytes eep_addr = gl_addr e_size.byte1 = imgW e_size.byte0 = imgH 'Options if gl_j = 0 then lcd_set 'Display img on LCD without clearing the display if gl_j = 1 then lcd_clrset 'Display img on LCD but first clear the display if gl_j = 2 then eep_load 'Load ext eeprom if gl_j = 3 then eep_disp 'For Horiz bytes if gl_j = 4 then lcd_fill 'Display images loop if gl_j = 5 then clr_lcd ' goto get_param '=========== CONTINUE LOOPING =========== '=============== OPTIONS ================ 'Option 5 clr_lcd: gosub gl_txtclr gosub gl_grfclr gl_addr = LCD_GRH 'Graphic home position $1000 gl_cur = SYS_CUR_DIR_RT 'Cur movement to right gosub gl_setaddr gl_cmd =SYS_MWRITE gosub send_cmd goto get_param 'Option 4 lcd_fill: gl_idx = 248 gl_idy = 0 gl_x = 0 gl_y = 0 gosub gl_txtclr gosub gl_grfclr gl_addr = LCD_GRH 'Graphic home position $1000 gl_cur = SYS_CUR_DIR_RT 'Cur movement to right gosub gl_setaddr gl_cmd =SYS_MWRITE gosub send_cmd gl_byte = imgX 'The byte to fill the screen with for gl_x = 1 to 32 for gl_y = 1 to 128 gosub send_dat next gl_y next gl_x 'All done go get next command and parameters goto get_param 'Option 3 eep_disp: 'The eeprom start address is in eep_addr (WORD var) 'The X,Y limits are in imgW nd imgH bytes 'Setup display clear it and go to home postion gosub gl_txtclr gosub gl_grfclr gl_addr = LCD_GRH 'Graphic home position $1000 gl_cur = SYS_CUR_DIR_RT 'Cur movement to right gosub gl_setaddr gl_cmd =SYS_MWRITE gosub send_cmd xcnt = 0 w_tmp = imgW * imgH for w_cnt = 1 to w_tmp I2CREAD sda,scl,ctl,eep_addr,[bLCD] if xcnt = ImgW then gl_addr = gl_addr + LCD_CR '+ imgX 'gosub gl_setaddr gl_cmd = SYS_CUR_ADDR 'CSRW command (set cursor command) gosub send_cmd 'Set low byte of addr gl_byte = gl_addr.byte0 gosub send_dat 'Set high byte of addr gl_byte = gl_addr.byte1 gosub send_dat gl_cmd = SYS_CUR_DIR_RT 'Cur movement right gosub send_cmd xcnt = 0 endif gl_cmd = SYS_MWRITE gosub send_cmd gl_dat = bLCD gl_wr = 0 @ nop gl_wr = 1 xcnt = xcnt + 1 eep_addr = eep_addr + 1 next w_cnt goto get_param 'Option 2 'GIVEN: ' eep_addr is given (WORD val) ' e_size in bytes (WORD val) eep_load: w_tmp = 0 eep_load1: hserout[XON,XON,XON] 'Get PC's attention hserin 1000,get_param,[wait ("]"),STR in_array\buff_count] 'Wait for ] and the load in_array hserout [XOFF,XOFF,XOFF] 'Tell the PC to hold data for gl_i = 0 to (buff_count-1) 'Get char and place in array Lookdown in_array[gl_i],["0123456789ABCDEF"],hex_nibble in_array[gl_i]=hex_nibble next for gl_i = 0 to (buff_count-1) step 2 gl_byte = (in_array[gl_i]<<4) | (in_array[gl_i+1]) 'Form a hex number MSB-LSB I2CWRITE sda,scl,ctl,eep_addr,[gl_byte] pause 5 eep_addr=eep_addr+1 w_tmp = w_tmp + 1 if w_tmp = e_size then goto get_param next goto eep_load1 'Option = 1 lcd_clrset: gosub gl_grfclr 'Option = 0 lcd_set: 'Calculate image placement 'Need to know: imgX Width and imgY Height, and starting point gl_x, gl_y 'The home position of the graphics is LCD_GRH 'Each line on a 256 wide LCD that equals 32 ($20) bytes 'LCD_CR is the LCD line length gl_idx = 248 gl_idy = 0 gl_x = 0 gl_y = 0 xcnt = 0 ycnt = 0 'gosub gl_grfhome 'Set Graphic address at starting position for the image (top-left corner of image) 'Calculate the address strting point gl_addr = LCD_GRH + imgX + imgY*LCD_CR gl_cmd = SYS_CUR_ADDR 'CSRW command (set cursor command) gosub send_cmd 'Set low byte of addr gl_byte = gl_addr.byte0 gosub send_dat 'Set high byte of addr gl_byte = gl_addr.byte1 gosub send_dat gl_cmd = SYS_CUR_DIR_RT 'Cur movement right gosub send_cmd ' gosub gl_setaddr lcd_loop: hserout[XON,XON,XON] 'Get PC's attention 'Load array with bytes. If 5 seconds elapse then goto the main loop hserin 3000,get_param,[wait ("]"),STR in_array\buff_count] hserout [XOFF,XOFF,XOFF] 'Tell the PC to hold data for gl_i = 0 to (buff_count - 1) Lookdown in_array[gl_i],["0123456789ABCDEF"],hex_nibble 'Get char and place in array in_array[gl_i]=hex_nibble next for gl_i = 0 to (buff_count - 1) step 2 bLCD = (in_array[gl_i]<<4) | (in_array[gl_i+1]) 'Form a hex number MSB-LSB 'Params received 'Upon entry xcnt = 0 and the address is set to starting position 'Image dimensions: imgW , imgH 'LCD top left start position imgX, imgY 'LCD_GRH is the graphic page home position 'LCD_CR is the LCD line length 'xStep is 8 if xcnt = ImgW then gl_addr = gl_addr + LCD_CR '+ imgX 'gosub gl_setaddr gl_cmd = SYS_CUR_ADDR 'CSRW command (set cursor command) gosub send_cmd 'Set low byte of addr gl_byte = gl_addr.byte0 gosub send_dat 'Set high byte of addr gl_byte = gl_addr.byte1 gosub send_dat gl_cmd = SYS_CUR_DIR_RT 'Cur movement right gosub send_cmd xcnt = 0 endif gl_cmd = SYS_MWRITE gosub send_cmd gl_dat = bLCD gl_wr = 0 @ nop gl_wr = 1 xcnt = xcnt + 1 next goto lcd_loop eep_done: 'hserout ["last byte at:",DEC eep_addr,10,13] goto get_param end '==================== ' END OF PROGARM '====================