0

It's one small step for (a) man.....

Posted by Chris on Friday, July 10, 2009 in , , ,
....one giant leap for Nokia 6610 colour LCD display boards!
Armed with little more than a Phillips PCF8833 datasheet and some Arduino code libraries, excitement reigned around Nerd Towers today, as this little colour LCD Arduino shield flickered into life.

The screen uses SPI to send byte commands to the screen.
After initialising the screen, data is written using the following format:

First a "window" is defined, by providing start-x, end-x, start-y and end-y co-ordinates (0-131). Then, a stream of data is sent, with (in 8-bit mode) each byte representing a pixel colour.
You can define how the screen behaves after each pixel-byte is received. I set my display up to draw pixels from top-to-bottom. When the current pixel reaches the bottom of the defined window size, it increases the column counter and returns to the top of the window



Unlike most serially-driven devices, the Nokia 6610 display uses 9-bits NOT 8 to transfer data to the screen. The first bit tells the display whether the following byte is a command (first bit is zero) or some data (first bit is set).

Although Oshonsoft includes built-in software driven SPI routines, I decided to write my own (using the ones in the Arduino library as a base) which send 9-bits in a continuous stream. Because Oshonsoft Basic is so simple to understand, this implementation could be easily ported to a compiler of your choice. The full code listing follows. Below is a summary of how to use the device:

Creating a window:
Put the display into "command mode" (set the first bit of the stream of 9)
Send the command bit followed by 0x2A (command to set the column/x co-ord)
Put the display into "data mode" (clear the first bit of the next stream of 9)
Send the x-start value as a byte (0-131)
Send the x-end value as a byte (0-131, must be greater than x-start)

Put the display into "command mode" (set the first bit of the stream of 9)
Send the command bit followed by 0x2B (command to set the column/y co-ord)
Put the display into "data mode" (clear the first bit of the next stream of 9)
Send the y-start value as a byte (0-131)
Send the y-end value as a byte (0-131, must be greater than y-start)

Put the display into "command mode" (set the first bit of the stream of 9)
Send the command bit followed by 0x2C (command to start writing pixel data)
Put the display into "data mode" (clear the first bit of the next stream of 9)
Send each pixel colour as a byte (assuming 8-bit colour mode)
Repeat for each pixel in the window

Here's the full code for a working PIC project:

Define CLOCK_FREQUENCY = 20
Define CONFIG1L = 0x24
Define CONFIG1H = 0x0c
Define CONFIG2L = 0x3e
Define CONFIG2H = 0x00
Define CONFIG3L = 0x00
Define CONFIG3H = 0x83
Define CONFIG4L = 0x80
Define CONFIG4H = 0x00
Define CONFIG5L = 0x0f
Define CONFIG5H = 0xc0
Define CONFIG6L = 0x0f
Define CONFIG6H = 0xe0
Define CONFIG7L = 0x0f
Define CONFIG7H = 0x40

UsbSetVendorId 0x1221
UsbSetProductId 0x1003
UsbSetVersionNumber 0x1122
UsbSetManufacturerString "www.nerdclub.co.uk"
UsbSetProductString "Usb-to-SPI device"
UsbSetSerialNumberString "1111111111"
UsbOnIoInGosub usbonioin
UsbOnIoOutGosub usbonioout
UsbOnFtInGosub usbonftin
UsbOnFtOutGosub usbonftout

AllDigital

Symbol glcd_bl = PORTB.5
Symbol glcd_rst = PORTB.4
Symbol glcd_cs = PORTB.3
Symbol glcd_sda = PORTB.2
Symbol glcd_miso = PORTB.1
Symbol glcd_sck = PORTB.0
Symbol led = PORTA.0

Define SPI_SCK_REG = PORTB 'defines the port where sck line is connected To
Define SPI_SCK_BIT = 0 'defines the pin where sck line is connected To
Define SPI_SDO_REG = PORTB 'defines the port where sdo line is connected To
Define SPI_SDO_BIT = 1 'defines the pin where sdo line is connected To
Define SPI_SDI_REG = PORTB 'defines the port where sdi line is connected To
Define SPI_SDI_BIT = 2 'defines the pin where sdi line is connected To
Define SPI_CS_REG = PORTB 'defines the port where cs line is connected To
Define SPI_CS_BIT = 3 'defines the pin where cs line is connected To

'SDO is not used - but is mapped to MISO on the display
'(serial data out on the MCU to serial data out on the lcd)

Dim spibyte As Byte 'a byte to send to the lcd
Dim spibit As Bit 'first bit is 0=command, 1=data
Dim spiclockdelay As Byte 'how long to wait between spi clock pulses
Dim spiclockus As Bit 'whether clock pulse delay is us or ms

Dim xs As Byte 'x co-ord to start bitmap from
Dim ys As Byte 'y co-ord to start bitmap from
Dim xe As Byte 'x co-ord to draw up to
Dim ye As Byte 'y co-ord to draw up to

Dim i As Byte '}
Dim j As Byte '} general variables
Dim k As Byte '}


init:
  spiclockus = 1
  spiclockdelay = 4
  
  'drive an LED high so we can see what's going on
  High led
  Gosub lcdinitialise

  'drive the led low
  Low led

  UsbStart
  UsbService

loop:
  UsbService
Goto loop

End


sendspi9bits:

  '--------------------------------------------------------
  'FROM THE NOKIA DATASHEET
  'the serial interface is
  'initialized when SCE is High. In this state, SCLK pulses
  'have no effect And no power is consumed by the serial
  'interface. A falling edge On pin sce enables the serial
  'interface And indicates the start of data transmission.
  '--------------------------------------------------------

  'flash the led high
  High led

  Low glcd_sda

  'drive the cs low
  Low glcd_cs
  Gosub spidelay

  'first send the init bit, for either command or data
  If spibit = 1 Then High glcd_sda Else Low glcd_sda
  Gosub toggleclockpin

  'now clock 8 bits from the spibyte value starting with bit 7
  If spibyte.7 = 1 Then High glcd_sda Else Low glcd_sda
  Gosub toggleclockpin

  If spibyte.6 = 1 Then High glcd_sda Else Low glcd_sda
  Gosub toggleclockpin

  If spibyte.5 = 1 Then High glcd_sda Else Low glcd_sda
  Gosub toggleclockpin

  If spibyte.4 = 1 Then High glcd_sda Else Low glcd_sda
  Gosub toggleclockpin

  If spibyte.3 = 1 Then High glcd_sda Else Low glcd_sda
  Gosub toggleclockpin

  If spibyte.2 = 1 Then High glcd_sda Else Low glcd_sda
  Gosub toggleclockpin

  If spibyte.1 = 1 Then High glcd_sda Else Low glcd_sda
  Gosub toggleclockpin

  If spibyte.0 = 1 Then High glcd_sda Else Low glcd_sda
  Gosub toggleclockpin

  'bring cs high to indicate end of transmission
  High glcd_cs
  Gosub spidelay

  'flash the led off
  Low led
Return


toggleclockpin:
  'take the clock pin high, wait a second, drive it low
  Gosub spidelay
  Low glcd_sck
  Gosub spidelay
  High glcd_sck
Return


spidelay:
  If spiclockus = 1 Then
    WaitUs spiclockdelay
  Else
    WaitMs spiclockdelay
  Endif
Return


lcdinitialise:
  'this is taken from teh pcf8833.c file: Arduino library

  'turn on the backlight
  High glcd_bl
  WaitMs 1

  'send a dummy data byte
  spibyte = 0 'all zeros is interpreted as NOP in the display chip
  Gosub sendcommand

  'send software reset command
  spibyte = 0x01
  Gosub sendcommand
  WaitMs 10

  spibyte = 0x11 'sleepout
  Gosub sendcommand

  spibyte = 0x36 'memory access control
  Gosub sendcommand

  'when a bitmap is drawn to screen, you give a start x, start y
  'and end x and end y co-ordinate. Then drawing can go from left-to-right,
  'up-and-down, or up-and-down, wrapping round to move the pixel left-to-right.
  'For our fonts and so on, we draw each pixel top to bottom, then
  'when we get to the bottom of the column of data, move left to right
  'This is called vertical addressing mode.

  spibyte = 0xe0 'memory access options:
  '1 - my mx v lao rgb x x x
  'my=mirror in Y, mx=mirror in x, V=vertical addressing,
  'lao=line address order, rgb= colour order rgb/bgr
  'e0 came from the Arduino library and is 11100000b
  
  Gosub senddata 'note: data, not command

  spibyte = 0x25 'set contrast
  Gosub sendcommand

  spibyte = 0x40 'contrast value
  Gosub senddata 'note: data=contrast value, not a command!

  WaitMs 10 'allow things to stablise

  spibyte = 0x3a 'set colour mode
  Gosub sendcommand

  spibyte = 0x02 'xxxxx010 = 8-bit colour
  Gosub senddata 'note: data=colour mode value, not a command

  spibyte = 0x00 'dummy command - dunno why, but it's in the C library!
  Gosub sendcommand

  Gosub clearscreen
Return


createwindow:
  spibyte = 0x2a 'set x start and end co-ordinates
  Gosub sendcommand
  
  spibyte = xs
  Gosub senddata

  spibyte = xe
  Gosub senddata

  spibyte = 0x2b 'set y start and end co-ordinates
  Gosub sendcommand
  
  spibyte = ys
  Gosub senddata

  spibyte = ye
  Gosub senddata

Return


clearscreen:

  'turn off the display while the screen is cleared
  spibyte = 0x28
  Gosub sendcommand

  'create a rectangle area the size of the window
  xs = 0
  xe = 131
  ys = 0
  ye = 131
  Gosub createwindow

  'put the display into "write mode"
  spibyte = 0x2c
  Gosub sendcommand

  'fill the rectangle with black pixels
  spibyte = 0x00
  For i = 0 To 131
    For j = 0 To 131
      Gosub senddata
    Next j
  Next i

  spibyte = 0x29 'display on?
  Gosub sendcommand

Return


sendcommand:
  spibit = 0
  Gosub sendspi9bits
Return


senddata:
  spibit = 1
  Gosub sendspi9bits
Return


usbonftin:

Return


usbonftout:

Return


usbonioout:
  'we've received some data on the data i/o (from PC to device)
  i = UsbIoBuffer(0)
  Select Case i
    Case 1 'this is the token to say "send byte"
    If UsbIoBuffer(1) = 1 Then spibit = 1 Else spibit = 0
    spibyte = UsbIoBuffer(2)
    Gosub sendspi9bits


    Case 2 'this is the token to say "set delay time/length"
    If UsbIoBuffer(1) = 1 Then spiclockus = 1 Else spiclockus = 0
    spiclockdelay = UsbIoBuffer(2)

    
    Case 3 'this is the token to say "run the init sequence"
    Gosub lcdinitialise


    Case 4 'this is the token to say "draw a window"
    xs = 10
    xe = 60
    ys = 10
    ys = 60
    Gosub createwindow

    For i = 0 To 20
      For j = 0 To 20
        spibyte = 0
        spibit = 1 '1=data, 0=command
        Gosub sendspi9bits
      Next j
    Next i


    Case 5 'this is the backlight token
    If UsbIoBuffer(1) = 1 Then High glcd_bl Else Low glcd_bl


  EndSelect
Return


usbonioin:
  'we've received an io/data request from the PC (usbioin = send to PC)
  'for some data from the device.
  
Return





Once again, a big thanks to Robot Steve for lending me his Arduino kit while I try to source one of my own!

0 Comments

Post a Comment

whos.amung.us

Copyright © 2009 .Nerd Club All rights reserved. Theme by Laptop Geek. | Bloggerized by FalconHive Supported by Blogger Templates.