P2 Nokia 5110 LCD PASM Driver
Cluso99
Posts: 18,071
Here is a P2 Driver for the Nokia 5110 LCD giving a 16x6 text screen.
It is a fairly simple conversion of my P1 pasm driver.
The 5110 pcb plugs nicely into the I/O socket of the Parallax DE0 expansion board. No other connections are required.
This is an extract of the main P2 code excluding the font table...
It is a fairly simple conversion of my P1 pasm driver.
The 5110 pcb plugs nicely into the I/O socket of the Parallax DE0 expansion board. No other connections are required.
This is an extract of the main P2 code excluding the font table...
orgh $00E00/4 ' start of hub ram
org 0
entry
' Initialize the LCD
mov outa, _init ' preset outputs
mov dira, _dira ' enable outputs
call #pause
' andn outa, _blight ' BL=0=on
call #pause
andn outa, _rst ' reset=0
call #pause
or outa, _rst ' reset=1
call #pause
' setup the display
mov x, #$21 ' PD=0=active, V=0=normal mode, H=1=extended commands follow
call #writec
mov x, #$C8 ' Vop=$48 (contrast)
call #writec
mov x, #$06 ' Temp=$02
call #writec
mov x, #$12 ' Bias=$02
call #writec
mov x, #$20 ' PD=0=active, V=0=normal mode, H=0=normal commands follow
call #writec
mov x, #$0C ' DE=10=normal display
call #writec
' mov x, #$0D ' DE=11=inverse
' call #writec
' mov x, #$09 ' DE=01=all segments on
' call #writec
call #clear ' clear screen
' output full char sequence $20-$7F, then looping
mov z, #" "
begin1 mov t, wait1 '\ delay
:here djnz t, @:here '/
mov x, z
call #writech
add z, #1
cmp z, #$80 wz
if_z mov z, #" "
jmp #begin1
wait1 long 1 << 23
'------------------------------------------------------------------------------------------------
' Write char in "x" to LCD
writech and x, #$7F ' chr = ((ch - $20) * 5)
sub x, #$20
mov y, x
shl x, #2 ' *4
add x, y ' *5
locptra #font
addptra x ' + Font hub addr
' fetch and write 5 cols of dots
mov y, #5
:wrloop rdbyte x, ptra++
call #writed
djnz y, @:wrloop
mov x, #0
call #writed
writech_ret ret
'------------------------------------------------------------------------------------------------
' Write a single command or data byte to the LCD
writec andn outa, _cmd ' /CMD=0 (sampled with D0)
jmp #writex
writed or outa, _cmd ' /CMD=1=DATA
writex andn outa, _ce ' /CE=0
call #pause
' transmit D7 first, DI is sampled on +ve edge of CLK
shl x, #24 ' D7 in b31
mov n, #8 ' 8 bit count
:loop rol x, #1 wc ' sample b31
if_nc andn outa, _di ' Dn=0
if_c or outa, _di ' Dn=1
andn outa, _clk '\ /CLK=0
call #pause '|
or outa, _clk '| /CLK=1 (samples this edge)
call #pause '/
djnz n, @:loop
or outa, _ce ' /CE=1
call #pause
writec_ret
writed_ret ret
'------------------------------------------------------------------------------------------------
' Clear screen
clear mov x, #$00
mov y, #(84 * 48 / 8)
:clear call #writed
djnz y, @:clear
mov x, #0
mov y, #0
call #goto
clear_ret ret
'------------------------------------------------------------------------------------------------
' Goto(x,y) valid values from (0,0) to (14*6-1,5)
goto shl x, #1 ' *2
mov n, x
shl x, #1 ' *4
add x, n ' *6
add x, #$80 ' x = $80 + x*6
call #writec
mov x, y
add x, #$40 ' y = $40 + y
call #writec
goto_ret ret
'------------------------------------------------------------------------------------------------
' small delay as LCD is 4MHz max
pause mov t, #8
:here djnz t, @:here
pause_ret ret
'------------------------------------------------------------------------------------------------
x long 0
y long 0
z long 0
n long 0
t long 0
ptr long 0
'------------------------------------------------------------------------------------------------
' |------------------------ PIN_GND = 24 '8 GND pwr supplied by prop pin
' | |---------------------- PIN_LED = 22 '7 LED backlight enable pin BL=0
' | | |-------------------- PIN_3V3 = 20 '6 3v3 pwr supplied by prop pin
' | | | |----------------- PIN_SCLK = 18 '5 Serial Clock pin
' | | | | |--------------- PIN_SDIN = 16 '4 Serial Data pin
' | | | | | |------------- PIN_DC = 14 '3 Data / Command selection pin D=1
' | | | | | | |----------- PIN_SCE = 12 '2 Serial clock enable pin
' | | | | | | | |--------- PIN_RST = 10 '1 Reset pin
_dira long %101010_101010101 << 10
_init long %001010_101010101 << 10
_blight long %001000_000000000 << 10
_clk long %000000_100000000 << 10
_di long %000000_001000000 << 10
_cmd long %000000_000010000 << 10
_ce long %000000_000000100 << 10
_rst long %000000_000000001 << 10
'------------------------------------------------------------------------------------------------
'================================================================================================
orgh
'Bit definitions for the font table. Each character is stored as 5 bytes,
'where each byte represents one vertical row of 8 pixels
FONT
Nokia5110A_021.spin 

Comments
I don't have a LCD to try it but I do like how you comment the code.
Have you updated your P2 spreadsheet lately?
Here's the data sheet for the PCD8544 display driver if anyone is interested.:
https://www.sparkfun.com/datasheets/LCD/Monochrome/Nokia5110.pdf
BEWARE: The pinout is DIFFERENT for the Sparkfun version.
Note only the registers (variables and constants) remain in cog (plus the jmp #hubex instruction due to DE0 limitation).
DAT '================================================================================================ orgh $00E00/4 ' start of hub ram org 0 ' start of cog ram entry jmp #hubex ' go execute from hub ram '------------------------------------------------------------------------------------------------ ' |------------------------ PIN_GND = 24 '8 GND pwr supplied by prop pin ' | |---------------------- PIN_LED = 22 '7 LED backlight enable pin BL=0 ' | | |-------------------- PIN_3V3 = 20 '6 3v3 pwr supplied by prop pin ' | | | |----------------- PIN_SCLK = 18 '5 Serial Clock pin ' | | | | |--------------- PIN_SDIN = 16 '4 Serial Data pin ' | | | | | |------------- PIN_DC = 14 '3 Data / Command selection pin D=1 ' | | | | | | |----------- PIN_SCE = 12 '2 Serial clock enable pin ' | | | | | | | |--------- PIN_RST = 10 '1 Reset pin _dira long %101010_101010101 << 10 _init long %001010_101010101 << 10 _blight long %001000_000000000 << 10 _clk long %000000_100000000 << 10 _di long %000000_001000000 << 10 _cmd long %000000_000010000 << 10 _ce long %000000_000000100 << 10 _rst long %000000_000000001 << 10 '------------------------------------------------------------------------------------------------ wait1 long 1 << 23 x long 0 y long 0 z long 0 n long 0 t long 0 '------------------------------------------------------------------------------------------------ '================================================================================================ orgh ' hubex code hubex ' Initialize the LCD mov outa, _init ' preset outputs mov dira, _dira ' enable outputs call @pause ' andn outa, _blight ' BL=0=on call @pause andn outa, _rst ' reset=0 call @pause or outa, _rst ' reset=1 call @pause ' setup the display mov x, #$21 ' PD=0=active, V=0=normal mode, H=1=extended commands follow call @writec mov x, #$C8 ' Vop=$48 (contrast) call @writec mov x, #$06 ' Temp=$02 call @writec mov x, #$12 ' Bias=$02 call @writec mov x, #$20 ' PD=0=active, V=0=normal mode, H=0=normal commands follow call @writec mov x, #$0C ' DE=10=normal display call @writec ' mov x, #$0D ' DE=11=inverse ' call @writec ' mov x, #$09 ' DE=01=all segments on ' call @writec call @clear ' clear screen ' output full char sequence $20-$7F, then looping mov z, #" " begin1 mov t, wait1 '\ delay :here djnz t, @:here '/ mov x, z call @writech add z, #1 cmp z, #$80 wz if_z mov z, #" " jmp @begin1 '------------------------------------------------------------------------------------------------ ' Write char in "x" to LCD writech and x, #$7F ' chr = ((ch - $20) * 5) sub x, #$20 mov y, x shl x, #2 ' *4 add x, y ' *5 locptra #font addptra x ' + Font hub addr ' fetch and write 5 cols of dots mov y, #5 :wrloop rdbyte x, ptra++ call @writed djnz y, @:wrloop mov x, #0 call @writed writech_ret ret '------------------------------------------------------------------------------------------------ ' Write a single command or data byte to the LCD writec andn outa, _cmd ' /CMD=0 (sampled with D0) jmp @writex writed or outa, _cmd ' /CMD=1=DATA writex andn outa, _ce ' /CE=0 call @pause ' transmit D7 first, DI is sampled on +ve edge of CLK shl x, #24 ' D7 in b31 mov n, #8 ' 8 bit count :loop rol x, #1 wc ' sample b31 if_nc andn outa, _di ' Dn=0 if_c or outa, _di ' Dn=1 andn outa, _clk '\ /CLK=0 call @pause '| or outa, _clk '| /CLK=1 (samples this edge) call @pause '/ djnz n, @:loop or outa, _ce ' /CE=1 call @pause writec_ret writed_ret ret '------------------------------------------------------------------------------------------------ ' Clear screen clear mov x, #$00 mov y, #(84 * 48 / 8) :clear call @writed djnz y, @:clear mov x, #0 mov y, #0 call @goto clear_ret ret '------------------------------------------------------------------------------------------------ ' Goto(x,y) valid values from (0,0) to (14*6-1,5) goto shl x, #1 ' *2 mov n, x shl x, #1 ' *4 add x, n ' *6 add x, #$80 ' x = $80 + x*6 call @writec mov x, y add x, #$40 ' y = $40 + y call @writec goto_ret ret '------------------------------------------------------------------------------------------------ ' small delay as LCD is 4MHz max pause mov t, #8 :here djnz t, @:here pause_ret ret '================================================================================================ orgh 'Bit definitions for the font table. Each character is stored as 5 bytes, 'where each byte represents one vertical row of 8 pixels fontNokia5110A_023.spinThanks Ray! Great job on the Doc's. I can tell that you've been working hard keep up with the constant changes.
Interesting example of HUBEX usage.
Yes, the HUBEXEC mode was quite simple to implement. However, with a depth of 4 for the LIFO (stack) for CALL/RET, I must be on the limit. Any more and I will have to use CALLX/RETX using the AUX & PTRX for the stack.
I have a whole passel of little bw LCD modules, I should check the model number. I remember they needed a funny small smt connector...
These modules come with a pcb with the same 8pin 0.1" pitch on top andbottom edge ofthe pcb so it plugs straight into the expansion connector on the parallax expansion board. Nothing else required. Mine has ablue backlight (off in the photo) all for $3 posted on eBay.