Reverse engineering the Nokia 2730 QVGA LCD

You may have noticed that I have a bit of a ‘thing’ for the little TFT displays that you can commonly get on ebay. There’s something satisfying about writing your own driver code and seeing one of these little panels come alive with your graphics.

Why the 2730 LCD?

  • It’s high resolution (320×240, 200ppi) which means that graphics will look good.
  • It’s used in a lot of models: Nokia 5000, 2730, 5130, 5220, 7100. Good for availability.
  • It’s cheap, as low as £3.99 on ebay.
  • It supports 262K (18-bit) colour mode.
  • It looks like I can find the connector for it. Don’t underestimate the difficulty of this!
  • The 24-pin connector has too few pins to be a direct drive LCD. That means it has a controller with embedded display RAM that I hope I can program.
  • The service schematics give away the connector pinout. It’s definitely a controller and not direct drive.

Where do you start?

I started by getting a second-hand 2730 off ebay for less than 30 pounds. I had some vague notion that I’d be able to hook up my Ant18e logic analyser to the display connector to analyse the conversation between the phone’s MCU and the display.


The Nokia 2730 I bought on ebay

That hope was scotched pretty quickly. There’s no way I can get probes on to the connector pins. I don’t know what I was thinking. Never mind, it’s not a bad phone and I might actually keep it as a backup.

While I had the phone in bits I was able to examine the connector mounted to the FPC. It’s a 24-pin 0.4mm pitch board-to-board connector that I have not yet been able to positively identify.

There are no markings on it and it ‘looks like’ a lot of products from Hirose, Molex, Kyocera and others. The problem with ‘looking like’ is that the differences between these parts is in the 0.1mm range and I know from some speculative purchases that if you get the wrong one then it just doesn’t mate.


The connector on the phone pcb

When attempting to reverse engineer these connectors look for short traces that run directly to a plane. These are guaranteed to be ground connections.


The connector on the LCD FPC cable

Fortunately I was able to source a handful of the board-side of these connectors from an online phone parts store. Still no clue as to the manufacturer though, and I’d like to hear from anyone who knows for sure what they are.

Known sources for the connector

It seems like there is considerable interest in sources for the 24 pin connector. I still don’t know who the OEM is. I’d suspect Hirose as they have past form in supplying Nokia connectors but I’ve been through their online catalogue with a magnifying glass and it’s not any one of the current production lines. Here are some links to online stores that have been found to sell the connector:

gsmserver.com

cellnetos.com

stellatech.com

Examining the schematic

Nokia schematic RM-578 and RM-579 for the 2730 is available for download on the internet. I get the feeling from the copyright notices on the document that it was not meant to be publicly available so I will not host it on my site.


The connector schematic

There are a number of key facts that I can deduce from the schematic.

  1. The interface to the controller is 8-bit. That means 3 transfers per pixel for the 262K colour mode supported by the 2730 phone. That’s quite expensive but certainly workable.
  2. The control lines indicate that it’s either 8080 or 6800 protocol. The world at large seems to prefer 8080 so I’m going to guess that’s what this one uses.
  3. The backlight comprises of 4 white LEDs in series and I can see there’s a step-up DC-DC converter that looks like a constant current LED driver.

For those not familiar with the 8080 protocol here’s what the signals mean.

D0-D7 The data lines. In this implementation 8 bits are transferred in one transaction.
CSX Chip select. Active low. Can be tied low if there’s nothing else sharing these lines.
DCX Data/command select. Set high when transferring graphic data or parameters to commands. Set low when transferring a command (register) number.
WRX Write enable. Data is transferred from D0-D7 to the controller on the rising edge of this signal.
RDX Read enable. Data is transferred from the controller to D0-D7 on the rising edge of this signal. Can be tied high if reading is not required.
RESX Hardware reset. Active low. The datasheet for the controller will specify minimum timings for the reset sequence.
TE Tearing effect. This is a pin that the MCU reads from in order to synchronise writing to graphic RAM with the display refresh. An MCU that can refresh the display faster than the frame rate could cause strange ‘tearing effects’ in animation if it is not synchronized with this signal.

Building a development board

Using the information gleaned so far I came up with the schematic for a basic development board that should work with my STM32.

The constant current LED driver is an OnSemi NCP5007 designed for powering up to 5 white LEDs in series. The circuit is straight from the datasheet and the feedback resistor is chosen to be 10Ω which gives a current of 20mA.



The Eagle schematic (click for larger)

The output capacitor, C2, needs to have a voltage rating higher than the maximum the IC can supply (which is 22V) to protect it in the case of an open circuit. The inductor L1 must have a self-resonant frequency above 1Mhz because the NCP5007 operates at 1Mhz. So the full parts list is:

Name Part Package
U1 OnSemi NCP5007 SOT23-5
L1 22µH inductor 1212
D1 Schottky Diode DO214AC
C1,C5 4.7µF capacitors 0805
C2 1µF 50V output capacitor 0805
C3,C4 100nF capacitors 0603
SV1 10×2 header 2.54mm male
C-2730 12×2 receptacle 0.4mm Nokia (please see comments at the bottom of this post for links to known supplier)

I hand-routed the traces and designed it so that the FPC cable from the 24-pin connector would wrap-around the board so that the LCD could be mounted on the opposite side to the LED driver components, with the 2.54mm MCU interface pins sticking up next to it.



The Eagle PCB layout (click for larger)

The datasheet for the NCP5007 is pretty clear that you can’t just throw together the components and get optimal noise-free operation of the step-up converter. Care needs to be taken to minimise trace lengths and ideally ground and power planes should be used to reduce noise. I placed the components as close to each other as I dare and also used ground and power planes on the bottom layer.

The eagle Gerber CAD files were sent off to ITead Studios for manufacturing and two weeks later (yes, patience is a virtue, especially when the Chinese are out celebrating their new year) they were delivered.


The bare PCB, front and back

Note the horrendously fine 0.4mm pitch connector footprint up the top left. The footprint design includes the four ‘posts’ around the corners that help to hold the connector securely to the board. The two 100nF decoupling capacitors next to it are in a fiddly small 0603 package. I chose this size to minimise the chance of them interfering with the FPC connector when it’s pressed down into the board receptacle.


After reflow and cleaning

My favoured method of mounting SMT components these days is to tin the pads with ordinary solder so you get little bumps, then liberally apply a paste flux and use it as a glue in which to position the SMD components. I then reflow the board carefully on a hot-plate.

Generally this works well, particularly with the large multi-pin ICs and connectors. They tend to just sit down nicely when the solder reflows. The smaller passive components such as the capacitors and resistors have a habit of sliding off their bumps before the solder has reflowed. I correct this at the time with a little nudge or afterwards with my heat gun.

The 2.54mm connector is hand-soldered after the SMD components have been reflowed.

The V+ and V- pins are not normally connected. They are used to test the backlight driver by connecting it up to an external LED string. i.e. you can connect V+ to the anode of LED1 and chain a further 3 LEDs anode-to-cathode with the final cathode going back to V-.

The EN pin is used to control the backlight. It is active HIGH. Applying a PWM signal to this pin will control the brightness of the backlight.

Blue smoke?

Lets hope not. The issue at stake is whether the controller can take the 3.3V from my STM32 on both VIO and VDD, with VDD being the logic interface that is often driven at 2.8V or even 1.8V by a phone. Every controller datasheet that I have is clear that 3.3V is in range for VDD but we don’t know what this is so this is going to be a nervous power-on.

Whatever you do, do not connect this circuit directly to a device with 5V levels such as the Arduino. The inputs and voltages are not 5V tolerant. An Arduino could be used to interface with this LCD with the addition of a level converter.


Well I’ll be, it works!

So far so good. No reason to get too excited though, in the above photograph all that I’ve done is test that the backlight circuit works and that the LCD powers up. Clearly it’s working so far.

You can also see four white LEDs wired in series in a breadboard behind the LCD. I used this LED string to test the output of the constant current driver before actually connecting the LCD. That’s why my development board exposes the V+ and V- output and feedback pins from the LED driver.


The dev board, front and back.

With the LCD mated snugly to the development board using double-sided sticky pads that keep it clear of the traces on the back of the PCB we’re ready to start reverse engineering the bus protocol.

Interrogating the controller

Most controllers have a register that allows you to read back information about the device and manufacturer. This will yield vital clues as to the controller’s identity. I wrote a quick program to read back 8 bytes from each of the controller’s registers. Most of them will be write-only and won’t tickle the bus but the ones that do will tell us vital information about the controller.

Here’s the output from that program. The first column is the register index, the next 8 bytes are the data response. I’ve stripped registers that return just zeros.

04 00 54 80 00 00 00 00 00
09 00 00 61 00 00 00 00 00
0a 08 08 08 08 08 08 08 08
0c 06 06 06 06 06 06 06 06
26 01 01 01 01 01 01 01 01
2a 00 00 00 00 ef 00 00 00
2b 00 00 00 01 3f 00 00 00
2e 00 80 bc b0 f8 00 f8 a4
30 00 00 00 01 3f 00 00 00
33 00 00 00 01 40 00 00 00
3a 00 06 00 00 00 00 00 00
6a ff ff ff ff ff ff ff ff
a1 00 54 80 00 0d 03 01 ff
a8 00 00 54 80 00 0d 03 01
da 54 54 54 54 54 54 54 54
db 80 80 80 80 80 80 80 80

Right away we’re on to something. Trawling through my collection of datasheets for TFTs I can see that the Leadis LDS285 uses 04h as its read device identifier (RDDID) code. The first byte returned by these controllers is always a dummy read, the real data is the values 54h and 80h, with 54h being the manufacturer code.

A quick search of the online list of MIPI manufacturer ids shows that 54h belongs to Arasan Chip Systems, Inc. Arasan is not a familiar name to me but their website reveals that they are engaged in making vertically integrated MIPI chipsets, i.e. the LCD controller, camera, file system etc. that you’d need if you were building a phone. The worrying news is that Leadis, whom we suspect of being the controller manufacturer have gone bust. I’m guessing that there is some kind of licensing agreement going on whereby Arasan and Leadis have collaborated to create an integrated controller.

Back to the device output, there is more evidence to support our theory that we’re looking at either an LDS285 or something that’s command-compatible with it. The datasheet states that commands DAh and DBh return the two identifier codes, and we can see that in the output.

More evidence in our favour is that registers 2Ah and 2Bh hold the column and row address start and end values. 0..239 and 0..319. The values that we see match. This is looking good.

Some random googling shows that there is someone else who’s experimented with LCDs from similar models to this one and determined that they tend to be command-compatible with a controller called the Magnachip MC2PA8201. This controller is itself a cut-down version of the LDS285. I’m going to assume that this is the one and see how far I get. Now it’s time to write an stm32plus driver for it and see if we can it to work!

Success!

After much experimentation I’ve determined the following about the LCD in the 2730:

  • The controller is documented to support colour depths up to 24-bit but this LCD will not go higher than 262K colours. Attempts to use 24-bit mode results in display corruption. This is not surprising given that the phone specifications are for a 262K colour display. Colours transferred in 262K mode must have their lower 2-bits zeroed.
  • 262K colours (3 transfers per pixel) and 64K colours (2 transfers per pixel) work perfectly. There are lower colour depths documented but I’m not concerned with them. I believe “an exercise for the reader” is the usual excuse wheeled out at this juncture.
  • Hardware scrolling is supported.
  • Portrait and landscape modes are supported and you can choose the orientation of each mode to suit which way up you’re mounting the LCD.
  • Low power (sleep) mode works.
  • Four gamma curve configurations are supported. My experimentation shows that the default gamma is probably the best.
  • Either some of the colours are verboten or this cheap LCD has problems with a very small subset of colours. Very rarely an attempt to write a run of a certain solid colour will result in weird corruption. This is odd because adjusting the colour by only 1-bit will correct the problem.

Here’s a few photographs of the LCD in action.


Testing the LCD

As usual the sensor in the digital camera fails to capture just how pin-sharp the little LCD appears to the human eye.


Displaying a bitmap

Watch the demo video

stm32plus 1.1.2 comes with drivers for the 64K and 262K colour modes for this LCD. You can see my usual demo sequence that exercises the capabilities of both the LCD and my graphics library in the video below.


Initialisation sequence

The key to getting any of these TFT devices up and running is the initialisation sequence, i.e. what you have to do after power-on in order to get the display powered up and ready for commands. To help you on the way, this is the basic sequence for this controller. The extract is from the stm32plus driver, but the code should be self-explanatory.

// reset the LCD

resetPin.reset();
MillisecondTimer::delay(5);
resetPin.set();
MillisecondTimer::delay(10);

// send the init sequence

writeCommand(SLEEP_OUT);
writeCommand(DISPLAY_INVERSION_OFF);
writeCommand(IDLE_MODE_OFF);
writeCommand(NORMAL_DISPLAY_MODE_ON);

if(_orientation==Orientation::Portrait)
  writeCommand(MEMORY_ACCESS_CONTROL,0xc8);     // BGR
else
  writeCommand(MEMORY_ACCESS_CONTROL,0xa8);     // BGR and horiz

// wait

MillisecondTimer::delay(125);

// turn the display on

writeCommand(DISPLAY_ON);

Drawing on the LCD

Drawing on these devices requires a fairly common set of operations. Firstly you move the drawing window to define a rectangle whose top left is at the first point you want to draw, then you send as many pixels to the display as you need.

If you send just one pixel then you get a single point at the top left of your drawing window and you can then move the window for the next point. This is useful for complex objects. Here’s a code sample for moving the drawing window to a point and extending the window from that point to fill the rest of the display.

    void moveTo(int16_t x,int16_t y) {

      _xpos=x;
      _ypos=y;

      writeCommand(COLUMN_ADDRESS_SET);

      if(_orientation==Orientation::Portrait) {

        writeData(0);               // x=0..239
        writeData(x);
        writeData(0);
        writeData(0xef);
      }
      else {

        writeData(x >> 8);          // x=0..319
        writeData(x & 0xff);
        writeData(1);
        writeData(0x3f);
      }

      writeCommand(PAGE_ADDRESS_SET);

      if(_orientation==Orientation::Portrait) {

        writeData(y >> 8);          // y=0..319
        writeData(y & 0xff);
        writeData(1);
        writeData(0x3f);
      }
      else {

        writeData(0);               // y=0..239
        writeData(y);
        writeData(0);
        writeData(0xef);
      }
    }

If you can divide your drawing requirements into discreet rectangles then it is far more efficient to send a command that defines the drawing window to match that rectangle and then repeatedly send pixels until the rectangle is filled. This is the approach taken by many of the algorithms in the stm32plus graphics library.

Schematic, CAD and gerbers available

You can now download the Eagle schematic, PCB artwork and Gerber files for this development board from my downloads page.

  • nordpol

    Wow, thanks for the great research. I´am going to buy the monitor for a project. :)
    Is there anyway to donate?

  • Ira

    Hi… It's an excelent experiment.. Thanks for shared..

  • vasu

    can you please explain how to play MP4 (h.245) video on this Nokia 2730-LCD ?

  • Alexq7

    can you please explain how to play MP4 (h.245) video on this Nokia 2730-LCD ?
    Very nice..

    • http://www.andybrown.me.uk Andy Brown

      Hi Alex, I don't think this is an appropriate display for full motion video. Assuming you've already solved how to decode the video stream in real-time then you'd be better off with a display that has a wider bus and can be addressed in parallel (RGB) mode rather than by MCU commands.

  • http://pcb.ucoz.ru Kirill

    Why on SV1 output voltage connector +U and -U?

    • http://www.andybrown.me.uk Andy Brown

      It's the output from the step-up regulator used to generate the voltage for the backlight. During testing I used those terminals to ensure that the voltage was being correctly generated before connecting a real screen to the PCB.

  • omkar dandekar

    hey andy iam from india i like ur concept i have sony satio u1 and its display in working i wnt to connect it to raspberry pie so what i do or for connecting arduino uno i dnt have pcb printer plzzzz andy help meeeee…….
    rgrds

  • Toan

    Hello Andy, I had just finished PCB without TE pin :(. Any problem with it?
    Can you help me simple C source code for test this module. Just write command and data, initialization procedure. I will do config to port it (I only had LPC2103 customs board.)
    Thank you so much.

    • http://www.andybrown.me.uk Andy Brown

      Hi Toan,

      The init procedure for the MC2PA8201 is remarkably simple. You can see the code for it here:
      https://github.com/andysworkshop/stm32plus/blob/m

      The compatible FSMC access mode is here:
      https://github.com/andysworkshop/stm32plus/blob/m

      This access mode uses the external memory interface built into the STM32. You would need to port that to the equivalent LPC peripheral, or if none is present then you'll need to develop a GPIO access mode.

      • toan

        Hi Andy,
        Thank you very much. My LCD board has work probably.
        I have used your initial procedure, and with normal GPIO access.
        Currently, It just display solid color, and too slow with 2sec/frame. 😐
        Thank for your interested topics 😀

  • Gennadiy

    Hi Andy!
    Can you provide your connection diagram by the LCD module to the STM32 board and demo program source code?
    Thank you so much.

    • http://www.andybrown.me.uk Andy Brown

      Hi Gennadiy,

      It's all on github, click here. Of particular interest will be mc2pa8201.cpp because the comment at the top of file contains the pinout (basically it's the FSMC pins).

  • boxochi

    hello my friend
    help me!
    Is there a way to set up LCD Nokia n70 is by avr ?

  • konradxdx

    I bet you a beer 😀