' V.Pohlers 12.8.2010
' Nokia 3310 Display = 84x48 picture elements, chip Philips PCD5584
' Nokia 3410 Display = 96(102)×65 picture elements, chip Philips OM6206 

'3410
'Lcd chip: Philips OM6206 (102x65) ! lcd zeigt nur die ersten 96 Spalten an!
'Resolution: 96x65 , B/W
'Technology: FSTN
'    Pin1 Vdd
'    Pin2 Sclk
'    Pin3 Sdata
'    Pin4 D/_C
'    Pin5 _Sce (enable)
'    Pin6 Gnd
'    Pin7 Vlcd
'    Pin8 _Reset

CON
  _clkmode = xtal1 + pll16x
  _xinfreq = 5_000_000

  MODE_NORMAL = $0C
  MODE_INVERSE = $0D

  nok_SCK = 19                  ' die genutzen PINs
  nok_SI  = 20
  nok_DC  = 21
  nok_CS  = 24                  ' HB-LED; CS ist mit Masse verbunden
  nok_RES = 22

  COLS = 102                    ' Nokia 3410 
  COLSV = 96                    ' Nokia 3410 
  ROWS = 65

  'COLS = 84                    ' Nokia 3310 
  'COLSV = 84 
  'ROWS = 48

OBJ
  'num : "Numbers"

VAR
  byte Mode                     'Keeps track of current screen mode (inverse or normal)

PUB Main
  Init

  'InverseMode

  'Display Test Msg
  GotoXY(0,0)
  str(string("Demo..Nokia 3410"))
  GotoXY(0,1)
  str(string("Volker Pohlers"))
  waitcnt(clkfreq + cnt) 'wait 1s
  'clear

  'demo_checkerboard
  demo_charset
  waitcnt(clkfreq + cnt) 'wait 1s
  demo_border
  waitcnt(clkfreq + cnt) 'wait 1s

  GotoXY(0,4)
  drawImg(logo)
  repeat

Pub demo_checkerboard
  GotoXY(0,0)
  repeat COLS/2
    repeat ROWS/8
      WriteData (%1010_1010)
      WriteData (%0101_0101)


pub demo_border | y 
'' Produce a border outline
  y := 2
  GotoXY (0,y++)
  WriteData (%1111_1111)
  repeat COLSV+1-4
    WriteData (%0000_0001)
  WriteData (%1111_1111)
  repeat 4
    GotoXY (0,y++)
    WriteData (%1111_1111)
    repeat COLSV+1-4
        WriteData (%0000_0000)
    WriteData (%1111_1111)
  GotoXY (0,y++)
  WriteData (%1111_1111)
  repeat COLSV+1-4
    WriteData (%1000_0000)
  WriteData (%1111_1111)

  WriteData (0)


pub demo_charset | i,x,y
  i := 32
  repeat y from 2 to 7
    repeat x from 0 to 15
      GotoXY(x*6,y)
      PutChar(i++)


PUB Init
  'Set pins to output
  dira[nok_SCK]~~
  dira[nok_SI]~~
  dira[nok_DC]~~
  dira[nok_CS]~~
  dira[nok_RES]~~

  outa[nok_RES] := 1            ' set RES high
  outa[nok_CS] := 1             ' disable chip
  outa[nok_RES] := 0            ' set RES low (toggle RES)
  waitcnt(clkfreq / 100 + cnt)  ' wait 100ms
  outa[nok_RES] := 1            ' wake from RES state
  outa[nok_CS] := 0

  writecom($21)                 ' Activate Chip, V=0, H=1
  writecom($C5)                 ' C2 Set LCD Voltage to about 7V
  writecom($06)                 ' Temp coef. 2
  writecom($13)                 ' Adjust voltage bias. 3
  writecom($20)                 ' Horizontal addressing, H=0
  writecom($09)                 ' all segments on

  Mode := MODE_NORMAL
  WriteCom(Mode)                ' Display Normal.

  clear                         ' Erase all pixel on the DDRAM.
  GotoXY(0,0)

  'num.Init


PUB str(stringptr)
'' Print a zero-terminated string

  repeat strsize(stringptr)
    PutChar(byte[stringptr++])


'PUB dec(number)
'  str(num.toStr(number, NUM#DEC) + 1)


'PUB hex(number)
'  str(num.toStr(number, NUM#HEX))


PUB drawImg(img) | i
  i := byte[img++]
  repeat(i)
    WriteData(byte[img++])


PUB PutChar(character) | tablept, i

  if (character < $20) or (character > $7F)
    return

  tablept := 5 * (character-$20)
  repeat i from 5 to 1
    WriteData(Table[tablept++])
  WriteData($00)                ' Space between chars


PRI WriteCom(toWrite)
  outa[nok_DC] := 0 'Command
  clockdata(toWrite)


PRI WriteData(toWrite)
  outa[nok_DC] := 1 'Data
  clockdata(toWrite)

PUB BlankColumn
  WriteData($00)


PUB BlankLine(line)
  GotoXY(0,line)
  repeat COLS
    BlankColumn

PRI ClockData(toSend)

  outa[nok_CS]~                 'Turn Chip On
  repeat 8                      ' 8 Bit
    outa[nok_SCK]~              ' Clock low
    if(toSend & $80)
      outa[nok_SI]~~
    else
      outa[nok_SI]~
    toSend <<= 1  
    outa[nok_SCK]~~             ' Data is read on rising edge of clock
  outa[nok_CS]~~                'Turn Chip Off


PUB clear

  GotoXY(0,0)                   ' Cursor home

  repeat COLS*(ROWS+7)/8
    writedata($00)              ' Clear all pixels


PUB GotoXY(X, Y)

  WriteCom($40 | (y & $07))
  WriteCom($80 | (x & $7F))


PUB InverseMode

  if(Mode <> MODE_INVERSE)
    Mode := MODE_INVERSE
    WriteCom(Mode)


PUB NormalMode

  if(Mode <> MODE_NORMAL)
    Mode := MODE_NORMAL
    WriteCom(Mode)


PUB GetMode
  return Mode

DAT
  'font 5x7
  table byte $00,$00,$00,$00,$00   ' Space
   byte $00,$00,$5F,$00,$00     ' !
   byte $00,$07,$00,$07,$00     ' "
   byte $14,$7f,$14,$7f,$14     ' #
   byte $24,$2a,$7f,$2a,$12     ' $
   byte $23,$13,$08,$64,$62     ' %
   byte $36,$49,$55,$22,$50     ' &
   byte $00,$05,$03,$00,$00     ' '
   byte $00,$1c,$22,$41,$00     ' (
   byte $00,$41,$22,$1c,$00     ' )
   byte $14,$08,$3e,$08,$14     ' *
   byte $08,$08,$3e,$08,$08     ' +
   byte $00,$50,$30,$00,$00     ' ,
   byte $08,$08,$08,$08,$08     ' -
   byte $00,$60,$60,$00,$00     ' .
   byte $20,$10,$08,$04,$02     ' /
   byte $3e,$51,$49,$45,$3e     ' 0
   byte $00,$42,$7f,$40,$00     ' 1
   byte $42,$61,$51,$49,$46     ' 2
   byte $21,$41,$45,$4b,$31     ' 3
   byte $18,$14,$12,$7f,$10     ' 4
   byte $27,$45,$45,$45,$39     ' 5
   byte $3c,$4a,$49,$49,$30     ' 6
   byte $01,$71,$09,$05,$03     ' 7
   byte $36,$49,$49,$49,$36     ' 8
   byte $06,$49,$49,$29,$1e     ' 9
   byte $00,$36,$36,$00,$00     ' :
   byte $00,$56,$36,$00,$00     ' ;
   byte $08,$14,$22,$41,$00     ' <
   byte $14,$14,$14,$14,$14     ' =
   byte $00,$41,$22,$14,$08     ' >
   byte $02,$01,$51,$09,$06     ' ?
   byte $32,$49,$79,$41,$3e     ' @
   byte $7e,$11,$11,$11,$7e     ' A
   byte $7f,$49,$49,$49,$36     ' B
   byte $3e,$41,$41,$41,$22     ' C
   byte $7f,$41,$41,$22,$1c     ' D
   byte $7f,$49,$49,$49,$41     ' E
   byte $7f,$09,$09,$09,$01     ' F
   byte $3e,$41,$49,$49,$7a     ' G
   byte $7f,$08,$08,$08,$7f     ' H
   byte $00,$41,$7f,$41,$00     ' I
   byte $20,$40,$41,$3f,$01     ' J
   byte $7f,$08,$14,$22,$41     ' K
   byte $7f,$40,$40,$40,$40     ' L
   byte $7f,$02,$0c,$02,$7f     ' M
   byte $7f,$04,$08,$10,$7f     ' N
   byte $3e,$41,$41,$41,$3e     ' O
   byte $7f,$09,$09,$09,$06     ' P
   byte $3e,$41,$51,$21,$5e     ' Q
   byte $7f,$09,$19,$29,$46     ' R
   byte $46,$49,$49,$49,$31     ' S
   byte $01,$01,$7f,$01,$01     ' T
   byte $3f,$40,$40,$40,$3f     ' U
   byte $1f,$20,$40,$20,$1f     ' V
   byte $3f,$40,$38,$40,$3f     ' W
   byte $63,$14,$08,$14,$63     ' X
   byte $07,$08,$70,$08,$07     ' Y
   byte $61,$51,$49,$45,$43     ' Z
   byte $00,$7f,$41,$41,$00     ' [
   byte $02,$04,$08,$10,$20     ' \
   byte $00,$41,$41,$7f,$00     ' ]
   byte $04,$02,$01,$02,$04     ' ^
   byte $40,$40,$40,$40,$40     ' _
   byte $00,$01,$02,$04,$00     ' `
   byte $20,$54,$54,$54,$78     ' a
   byte $7f,$48,$44,$44,$38     ' b
   byte $38,$44,$44,$44,$20     ' c
   byte $38,$44,$44,$48,$7f     ' d
   byte $38,$54,$54,$54,$18     ' e
   byte $08,$7e,$09,$01,$02     ' f
   byte $0c,$52,$52,$52,$3e     ' g
   byte $7f,$08,$04,$04,$78     ' h
   byte $00,$44,$7d,$40,$00     ' i
   byte $20,$40,$44,$3d,$00     ' j
   byte $7f,$10,$28,$44,$00     ' k
   byte $00,$41,$7f,$40,$00     ' l
   byte $7c,$04,$18,$04,$78     ' m
   byte $7c,$08,$04,$04,$78     ' n
   byte $38,$44,$44,$44,$38     ' o
   byte $7c,$14,$14,$14,$08     ' p
   byte $08,$14,$14,$18,$7c     ' q
   byte $7c,$08,$04,$04,$08     ' r
   byte $48,$54,$54,$54,$20     ' s
   byte $04,$3f,$44,$40,$20     ' t
   byte $3c,$40,$40,$20,$7c     ' u
   byte $1c,$20,$40,$20,$1c     ' v
   byte $3c,$40,$30,$40,$3c     ' w
   byte $44,$28,$10,$28,$44     ' x
   byte $0c,$50,$50,$50,$3c     ' y
   byte $44,$64,$54,$4c,$44     ' z
   byte $00,$08,$36,$41,$00     ' {
   byte $00,$00,$7f,$00,$00     ' |
   byte $00,$41,$36,$08,$00     ' }
   byte $10,$08,$08,$10,$08     ' ~
   byte $78,$46,$41,$46,$78     ' DEL char

logo byte 290
   byte $00,$00,$00,$00,$00,$00,$00,$00,$F8,$0C,$04,$06,$02,$02,$06,$04
   byte $1C,$F0,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$FE
   byte $FE,$FE,$FE,$FE,$00,$00,$00,$00,$00,$00,$00,$00,$00,$FE,$FE,$FE
   byte $FE,$FE,$00,$E0,$F0,$F0,$F0,$F0,$E0,$00,$00,$F0,$F0,$F0,$F0,$00
   byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$F0,$F0,$F0,$F0,$00,$00,$00
   byte $00,$80,$C0,$E0,$E0,$F0,$F0,$F0,$F0,$F0,$F0,$F0,$F0,$F0,$00,$00
   byte $00,$80,$C0,$60,$20,$20,$20,$20,$71,$FF,$8E,$04,$0C,$0C,$04,$9E
   byte $FB,$71,$20,$20,$20,$20,$60,$C0,$00,$00,$00,$00,$00,$00,$00,$FF
   byte $FF,$FF,$FF,$FF,$00,$18,$3E,$7E,$7E,$7E,$3E,$08,$00,$FF,$FF,$FF
   byte $FF,$FF,$00,$F1,$F3,$F3,$F3,$F3,$F1,$00,$00,$FF,$FF,$FF,$FF,$C0
   byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$FF,$FF,$FF,$FF,$00,$00,$FE
   byte $FF,$FF,$FF,$8F,$03,$79,$FD,$FD,$FD,$F9,$71,$01,$01,$01,$00,$00
   byte $00,$0F,$38,$60,$40,$40,$40,$40,$60,$30,$1F,$06,$06,$06,$06,$1F
   byte $30,$60,$40,$40,$40,$60,$20,$1F,$0F,$00,$00,$00,$00,$00,$00,$7F
   byte $7F,$7F,$7F,$7F,$00,$00,$00,$00,$00,$00,$00,$00,$00,$7F,$7F,$7F
   byte $7F,$7F,$00,$7F,$7F,$7F,$7F,$7F,$7F,$00,$00,$01,$07,$0F,$1F,$1F
   byte $3F,$3E,$7C,$7C,$7C,$7C,$7C,$7C,$7C,$7F,$7F,$7F,$7F,$00,$00,$01
   byte $07,$0F,$1F,$3F,$3F,$3E,$7C,$7C,$7C,$7C,$7C,$7C,$7C,$7C,$00,$00
   