#picaxe 20x2
; ********************************************
; Note you must uncomment just one of these two options
; depending on whether you have an LCD or OLED module
#define use_OLED
;#define use_LCD
; ********************************************
; Supported Commands
; 0-7, 8-15 CGRAM characters
; 16-252 normal ASCII characters, according to selected character map table
; 253, X display 16 character pre-saved message from EEPROM memory, X can be 0-15
; 254, X LCD command, X can be 0 to 255
; 255, X control outputs C.2, C.1, C.0 (via lower 3 bits of X)
; So, if using a backlit LCD with the active low transistor driver
; on output C.2, then 255,%000 switches backlight on and 255,%100 switches off
#define use_welcome ; display the welcome message upon power up
symbol line_length = 16 ; change to 20 for displays with 20 character lines
'symbol spare0 = B.0 ; spare output 0
'symbol spare1 = B.1 ; spare output 1
'symbol spare2 = B.2 ; spare output 2
'symbol spare3 = B.3 ; spare output 3
symbol enable = B.4 ; LCD enable
symbol rs = B.6 ; LCD RS
symbol mode = b5 ; 0 = character, 1 = command, 2 = message, 3 = outputs
; LCD data pins are on C.0 to C.7, B.6 instead of C.6
; Store the 16 character user defined messages in EEPROM data memory
; First two messages are optionally used as welcome message
; If using a display with 20 characters you will need to edit
; the start addresses to be multiples of 20 (currently at 16)
; and add 4 characters to each message.
; Please remember 4 line displays always use the strange 1-3-2-4 layout.
#ifdef use_OLED
EEPROM $00, (" i2c OLED ") ; store msg in the EEPROM memory
#else
EEPROM $00, (" i2c LCD ") ; store msg in the EEPROM memory
#endif
EEPROM $10, (" www.picaxe.com ") ; store msg in the EEPROM memory
EEPROM $20, ("This is msg 2 ") ; store msg in the EEPROM memory
EEPROM $30, ("This is msg 3 ") ; store msg in the EEPROM memory
EEPROM $40, ("This is msg 4 ") ; store msg in the EEPROM memory
EEPROM $50, ("This is msg 5 ") ; store msg in the EEPROM memory
EEPROM $60, ("This is msg 6 ") ; store msg in the EEPROM memory
EEPROM $70, ("This is msg 7 ") ; store msg in the EEPROM memory
EEPROM $80, ("This is msg 8 ") ; store msg in the EEPROM memory
EEPROM $90, ("This is msg 9 ") ; store msg in the EEPROM memory
EEPROM $A0, ("This is msg 10 ") ; store msg in the EEPROM memory
EEPROM $B0, ("This is msg 11 ") ; store msg in the EEPROM memory
EEPROM $C0, ("This is msg 12 ") ; store msg in the EEPROM memory
EEPROM $D0, ("This is msg 13 ") ; store msg in the EEPROM memory
EEPROM $E0, ("This is msg 14 ") ; store msg in the EEPROM memory
EEPROM $F0, ("This is msg 15 ") ; store msg in the EEPROM memory
gosub LCD_init
; display welcome message if desired
#ifdef use_welcome
low rs
let outpinsA = 128 >> 6
let outpinsC = 128 ; Top line
pulsout enable,1
let b1 = 0
gosub msg ; Message #0
low rs
let outpinsA = 192 >> 6
let outpinsC = 192
pulsout enable,1 ; 2nd line
let b1 = 1
gosub msg ; Message #1
#endif
; Configure the address here
hi2csetup i2cslave, %10100000 'set up slave mode
setintflags %01000000,%01000000 'set up i2c interrupt
main:
goto main
interrupt:
'get digits from scratch
let bptr = 0
get bptr,b0
do while b0 > 0 or mode > 0
if b0 < 253 and mode = 0 then
let outpinsA = b0 >> 6
let outpinsC = b0 ; output the data
pulsout enable,1 ; pulse the enable pin to send data.
high rs ; stay in character mode
else if b0 < 253 and mode = 2 then
let b1 = b0 ; b1 is the message number
gosub msg
else if b0 < 253 and mode = 3 then
let b1 = b0 ; b1 is the command param
gosub out
else if b0 = 254 then
low rs ; change to command mode for next character
else if b0 = 253 then
let mode = 2 ; change to message mode
else ; must be 255
let mode = 3 ; change output mode
endif
put bptr,0
inc bptr
get bptr,b0
loop
hi2cflag = 0 'reset flag
setintflags %01000000,%01000000 'reset i2c interrupt
return
LCD_init:
'set up output pins
let dirsA = %00000001
let dirsB = %01011111
let dirsC = %11111111
low rs
#ifdef use_OLED
; Winstar OLED Module Initialisation
; according to WS0010 datasheet (8 bit mode)
pause 500 ; Power stabilistation = 500ms
; Function set - select only one of these 4 character table modes
;let pinsB = %00111000 ; 8 bit, 2 line, 5x8 , English_Japanese table
let outpinsC = %00111001 ; 8 bit, 2 line, 5x8 , Western_European table1
;let pinsB = %00111010 ; 8 bit, 2 line, 5x8 , English_Russian table
;let pinsB = %00111011 ; 8 bit, 2 line, 5x8 , Western_European table2
pulsout enable,1 ;
let outpinsC = %00001100 ; Display on, no cursor, no blink
pulsout enable,1
let outpinsC = %00000001 ; Display Clear
pulsout enable,1
pause 7 ; Allow 6.2ms to clear display
setfreq m64 ; now change to 64Mhz
let outpinsC = %00000010 ; Return Home
pulsout enable,1
let outpinsC = %00000110 ; Entry Mode, ID=1, SH=0
pulsout enable, 1
#else
; Standard LCD Module Initialisation
pause 15 ; Wait 15ms for LCD to reset.
let outpinsC = %00110000 ; 8 bit, 2 line
pulsout enable,1 ; Send data by pulsing enable
pause 5 ; Wait 5 ms
pulsout enable,1 ; Send data 48 again
pulsout enable,1 ; Send data 48 again
setfreq m64 ; now change to 64Mhz
let outpinsC = %00111000 ; LCD - 8 bit, 2 line, 5x8
pulsout enable,1
let outpinsC = %00000001 ; Clear Display
pulsout enable,1
pause 8 ; 8 = 2ms at 16MHz
let outpinsC = %00000010 ; return home
pulsout enable,1
let outpinsC = %00000110 ; Entry mode
pulsout enable,1
pause 1
let outpinsC = %00001100 ; Display on, no cursor, no blink
pulsout enable,1
#endif
high rs ; Leave in character mode
return
; display message from EEPROM sub routine
; message number 0-15 must be in b1 when called
; uses (alters) b1, b2, b3, b4
msg:
high rs
let b2 = b1 * line_length
; EEPROM start address is 0 to 15 multiplied by 16
let b3 = b2 + line_length - 1 ; end address is start address + (line_length - 1)
for b4 = b2 to b3 ; for 16 times
read b4,b0
let outpinsA = b0 >> 6
let outpinsC = b0 ; output the data
pulsout enable,1 ; pulse the enable pin to send data.
next b4
let mode = 0 ; back to character mode
return
out:
let outpinsB = b1 & %00001111 ; Set B.0 B.1 B.2 B.3
high rs
let mode = 0 ; back to character mode
return
; Check end user has defined just one type of display
#ifndef use_OLED
#ifndef use_LCD
#error "Oops - no OLED / LCD type defined at top of program!"
#endif
#endif
#ifdef use_OLED
#ifdef use_LCD
#error "Oops - both OLED / LCD types defined at top of program!"
#endif
#endif