I've always been interested in the idea of re-using old laptop LCDs, but it always seemed out of my reach until recently I had a huge urge to wire up a special sunlight-readable Portege R500 "transflective" LCD, and I discovered it isn't that hard to do!
In this project I'll show you exactly how I was able to reverse-engineer an LCD panel and get it to work with an LVDS-equipped linux board. If you want to know more about the details, you should check out my article on Driving FPD-Link Displays.
The biggest problem in re-using an old laptop LCD panel is that the panels do not use a standard protocol like HDMI or DVI, so they cannot be directly hooked up to a computer. Instead they use a protocol called "FPD-Link", commonly referred to as LVDS. Fortunately LVDS is very similar to HDMI/DVI, and all that is required is a small HDMI-to-LVDS converter board.
To make things easier I purchased a RIoTBoard SBC, which features native LVDS outputs! It's worth noting that it only has a single channel 18bpp LVDS output (even though the i.MX6 chip itself supports two 24bpp channels), which means it can't drive anything higher than approximately 1280x800 through the LVDS connector.
It is fairly similar to the Raspberry Pi, featuring USB, ethernet, HDMI, and an integrated GPU for hardware-accelerated graphics and video. Eventually I plan to write my own GUI application that will run on the RIoTBoard with some attached laptop LCD panel.
First LCD Panel
Because the R500 LCD has a rather tricky connecter, I wanted to make sure I could get LVDS to work with a simpler panel first. I chose a random laptop out of my collection and extracted the panel:
The next step is to locate the LVDS pairs and the power wires, but I saved myself the trouble of reverse-engineering the exact pinout and managed to find a datasheet floating around on the internet.
The flurorescent backlight driver proved to be a bit more tricky but a bit of probing around revealed the correct connections.
Tip: When searching for datasheets, look for part numbers on the LCD and search google for: "PARTNUMBER filetype:pdf"
From there it was a simple matter of wiring the LVDS cable and hooking it up to the RIoTBoard:
Note: The micro-HDMI connector on the RIoTBoard is actually LVDS, not HDMI!
Portege R500 LCD
On to the real challenge!
The LCD pictured to the right is a special panel made for the Toshiba R500/R600 laptop series, which allows the laptop to be used outdoors in full sunlight. I had a few of these laptops spare, and I thought it could be useful in my own projects, so I decided to have a try at getting it to work with my board.
The panel takes 2.5V, and has an LED backlight which requires about 30V. It has a resolution of 1280x800, and has a single FPD-Link channel (3 data lines + 1 clock).
Initially I couldn't find a datasheet for the panel (although I did find one later!), so I started by attempting to reverse engineer the laptop panel to work out the correct pinout. I did this by careful observation of the PCB layouts, and by probing the panel in a live system.
The LVDS pairs were fairly obvious on the laptop motherboard, but figuring out which one was which was a bit more tricky. I actually found out I could squeeze the wires and it would cause the display to become corrupted, and by comparing the colours on the display with the FPD-Link packet format I was able to determine the 3 data channels and 1 clock channel! The clock LVDS pair was the easiest to find, as the display simply freezes or goes black when it loses the clock.
When I found the datasheet later on, I compared it with my findings and I was actually very close - I had missed the EDID signals, and had the polarity of the LVDS signals reversed. Not bad! Having EDID signals also means I can make the display "plug'n'play" with pretty much any system, meaning the computer will be able to automatically detect the correct resolution and panel type.
The next stage was to find a way to connect the display to my RIoTBoard, which wasn't easy due to the extremely fine wiring. Initially I tried to use the existing LCD cable to solder to, but it turns out the wires are actually very small micro-coaxial cables, and soldering them causes a dead short to ground!
So I decided to develop a breakout board using the same connector as on the laptop motherboard, including a backlight driver based on the same chip as the laptop motherboard. (I couldn't actually find a place to buy the connector, so I just extracted one from a dead laptop)
I decided I would try to etch the PCB at home to see if it was actually possible. The PCB ended up being a big test of my skills, as it included some incredibly fine traces (the LVDS traces are 0.254mm wide!)
It took me 4 attempts to actually get the iron-on toner transfer to stick properly, but eventually I was able to get an almost perfect transfer! My first etch wasn't successful though - it ate right through my thin LVDS traces!
Tip: Don't over-saturate your Ammonium Persulfate solution - it doesn't make it etch faster, in fact it prevents any etching from happening at all! I had to dilute my solution with water before it actually did anything.
After soldering everything up I powered it up and attached it to my RIoTBoard, and amazingly an image appeared on the screen! (Although note that the image doesn't quite completely fill the display)
The final step of the project was to implement the backlight driver. This proved to be a lot trickier than I thought due to the high operating frequency (0.5-1.0MHz), making the circuit unstable and causing components to heat up. After a bit of trial and error I eventually found an appropriate MOSFET, diode, and inductor that worked.
The final breakout board is pictured below:
As for the RIoTBoard, some configuration was necessary to get it to output the correct resolution, as the linux kernel doesn't seem to pick up the EDID information (although I can dump it through the i2c-read program). This is done by entering the U-Boot console on boot and modifying the video bootargs:
Hit any key to stop autoboot...U-Boot> setenv bootargs console=ttymxc1,115200 init=/init nosmp video=mxcfb0:dev=ldb,1280x800M@60,bpp=32 video=mxcfb1:off fbmem=10M
In the above configuration, video is modified to use the ldb output and set to a resolution of 1280x800 with reduced blanking (M)
The project was a success! I was able to get a very tricky LCD panel working with a linux board, complete with a home-etched breakout PCB! Now to figure out what to use it for...
This is an intro to the FPD-Link display interface, commonly used in laptop and monitor LCD panels. Information surrounding the exact nature of this interface is scattered all over the internet, so I wrote this article to try and make it easier to understand, and potentially useable in your own projects!
FPD-Link is also known as simply "LVDS", although this is technically incorrect since this refers to just the electrical interface, and LVDS is used for many other interfaces too. The actual interface is called FPD-Link (or also FlatLink by some manufacturers), and describes a general interface for connecting LCD panels to graphics controllers, much like VGA or DVI. However it doesn't describe an exact data format, so many different options exist for different panels, making it not quite as inter-operable as VGA or DVI.
Fortunately you'll find most (old) laptop LCD panels will use a de-facto format, so it's actually not too hard to re-use the screens out of that old stack of laptops you have in the basement!
You can't juts connect FPD-Link to a computer however, so if you want to use an FPD-Link capable panel you'll need one of the following:
An LVDS->HDMI/DVI converter (either a monitor-style one from eBay/Aliexpress, or one that simply converts the signals)
A board with native LVDS support (Some embedded ARM boards have native LVDS!)
The other thing you will need is a datasheet for your LCD panel, or good reverse-engineering skills!
The rest of this article details the FPD-Link/LVDS interface, and other related things like EDID and converter boards.
Interfacing - How to use your panel in an embedded project
Flat Panel Display Link (FPD-Link) was created by National Semiconductor as a free and open standard for connecting the output of a GPU or video processor to an LCD panel's timing controller. It superseeds TTL/CMOS parallel interfaces which were very limited in the resolution they could achieve. Although FPD-Link itself is becoming outdated with the rise of next generation LCD monitors (2440p and 4K!), it is still used in most current generation laptops and desktop monitors. You can read more about the FPD-Link standard in Texas Instruments' app-note.
The protocol itself is fairly straight-forward; there's no complex control/configuration/packetization of the video data, and usually a panel will accept any resolution given to it since it relies on horizontal and vertical synchronization signals like most other video interfaces (See the Synchronization & Timing Section for how this works).
At it's core, FPD-Link uses a number of Low-Voltage Differential Signalling (LVDS) pairs in order to transfer video data over a high speed link, which is then de-serialized in the LCD panel and used to drive the display. Even though it has less wires than a parallel interface, it allows for much higher speeds due to increased noise tolerance and capabilities of the LVDS pairs (much like how SATA proivdes faster speeds for hard disks than IDE/PATA).
Each LVDS pair consists of two wires: positive and negative, plus a ground shield/reference. This allows the wires to travel much longer distances since the pair is immune to interference and has reduced cross-talk between pairs.
LVDS pairs are quite easy to locate on a PCB, because they are almost always routed as close together as possible, and sometimes have sqiuggly patterns to match the lengths. Keep in mind that the polarity of the LVDS pair is important!
NOTE: Because the LVDS signals are very sensitive and operate at very high speeds, you should be careful when modifying LVDS wiring. You should use twisted pair wire with each pair individually shielded, and you should ensure the lengths of the wires are matched. If you're not careful, you may introduce too much skew into the data over long distances, causing some bits to arrive later than other bits, corrupting the image!
The video data sent to the display consists of raw RGB pixels, plus synchronization and control signals (HSYNC, VSYNC, and DE). This is the same as other video interfaces such as TTL Parallel, VGA, DVI, etc.
FPD-Link serializes this data into channels containing 7 bits of data per clock cycle, as shown in Figure 2. For a typical video interface with 18 bits per pixel (bpp), there are 21 bits of data per clock serialized into a total of 4 LVDS channels (3 data + 1 clock, or "3D+1C"). There are of course many other configurations possible depending on the number of links and data bits. For example, a dual-link 24 bpp interface (common in desktop monitors) would use 2x 4 LVDS data channels + 2 LVDS clock channels, or "8D+2C". Looking at the pairs of wires on the LCD's circuit board can provide a very good hint as to which format it uses!
The actual layout of bits in this serial stream varies depending on how the manufacturer has decided to implement it, and is described in the Data Framing section below. For 18 bpp displays there is only one specfic format used, but FPD-Link itself is not limited to just 18 bpp video.
FPD-Link has a maximum bandwidth of somewhere around 130Mpps (Mega pixels per second) depending on the transceiver, while the LVDS channels operate at 7x this rate. This limits the maximum allowable resolution to about 1280x800@60Hz. It is usually not possible to drive a 1920x1080p display at 60Hz with just one FPD-Link channel, so two channels are doubled up to support higher resolutions. Some extra high resolution monitors may even use up to 4 FPDLink channels, or eDP (embedded Display Port, a completely different protocol) to further increase the bandwidth.
Most old laptop LCDs will likely be 18 bits per pixel (6 bits per colour), and thus use 3 LVDS data pairs and 1 LVDS clock pair (3D+1C). A total of 21 bits are serialized, and the layout inside the LVDS stream is shown in the following timing diagram:
Some panels will support 24 bpp (8 bits per colour), which uses a fourth LVDS data pair (4D+1C) to increase the bit depth while keeping the bandwidth the same. Unfortunately there are two different standards for how the data is serialized for 24 bpp panels! The difference is which bits the fourth data channel (Y3) contains, and it may either contian the least significant bits (LSB) or most significant bits (MSB) of the pixel. According to Texas Instruments, most 24 bit panels assume the MSB is in the 4th channel, although contradicting info says that 24 bit LSB panels are the most common. So if in doubt, check your datasheet! The two different formats are shown in the following timing diagrams:
Note that an 18 bpp panel can be driven by a 24 bpp LSB transmitter by simply omitting the 4th channel (Y3), in which case the lower bits are discarded and it acts as if it was transmitting 6 bits per colour. You cannot drive an 18 bpp panel from a 24 bpp MSB transmitter!
Some transceivers may even support 30 bit RGB data, which use an additional channel (5 LVDS data channels in total). I'm unsure on the exact format of this data as I don't have any 30 bit LCD panels.
Dual-channel FPD-Link uses a second FPD-Link, sending even pixels on one and odd pixels on the other in order to double the effective bandwidth, thus supporting higher resolutions (eg. 1920x1080@60Hz). Usually two identical clocks are sent for both FPD-Links (8D+2C). Again, this can be 18 or 24 bpp (or higher). According to Texas Instruments there is only one de-facto mapping for dual-channel 24 bit mode (MSB Format):
Note that there are two sets of CLK/VSYNC/HSYNC/DE lines, but these are probably the same signals.
Synchronization & Timing
The data framing format is only half the story when interfacing with an FPD-Link display; the synchronization and timing are also important to ensure the pixels the panel receives actually match the physical panel! This is done through the HSYNC, VYSNC, and DE synchronization signals. It's not immediately obvious, but not all pixels transmitted are actually displayed - some end up in the so called "blank-time" interval. This is a leftover artifact from the days of CRT monitors when the electron beam actually needed time to move between rows and frames! For backwards compatibility the blank-time is still present in DVI & VGA outputs, which is sad because it's not required at all in digital panels!
The DE (Data Enable) signal marks active pixels, so whenever DE is low it is blanking. The HSYNC signal is toggled at the start of every row, while the VSYNC is toggled at the start of every frame. Pixels are scanned left-to-right, top-to-bottom.
The following is a generic timing diagram that shows how these signals relate to one another:
NOTE: CLK is the pixel clock, not the LVDS clock!
If you have a datasheet for your LCD panel, it will usually include a timing diagram specifying the values you should use to display a valid picture. This information is also reflected in the panel's EDID (if present). Generally this information can be represented in the form of a Coordinated Video Timing (CVT), a VESA standard specifying common timing formats for different resolutions.
The actual format of the pixel data depends on the protocol and wiring. For FPD-Link the pixels are serialized into the format specified in the previous section.
Digital Visual Interface (DVI)
Digital Visual Interface (DVI) is actually very similar to FPDLink, in that it uses the exact same data framing format (RGB pixel data + HSYNC/VSYNC/DE). However it uses Transition-Minimized Differential Signalling (TMDS) not LVDS, so it is not electrically compatible. The digital encoding of data is also different, as it uses a special encoding algorithm to convert the 11 bit inputs to 10 bit codes. The DVI video stream is always 24 bpp, and contains various control signals including HSYNC, VSYNC, and ENABLE (DE). This makes it fully compatible with FPD Link, with an appropriate converter chip!
Embedded DisplayPort (eDP)
Some next-gen monitors are moving to a eDP (embedded Display Port), which is pretty much just display port, so it is possible to connect such a display directly to a display port capable video card. I will not go into more detail about it here since I don't have any of these types of display panels, and my computer doesn't have display port anyway! However I have heard you can obtain iPad displays cheaply online which use eDP, and can be used as a secondary high-DPI monitor with a simple re-wired display port cable and backlight driver.
MIPI DSI is another protocol widely used in current-gen smartphone/tablet LCDs. It is lower power than FPD-Link and supports higher resolutions. Unfortunately the standard isn't available to the public so it's shrouded in mystery, although I have seen one project successfully interface such a display through the use of an FPGA, and another project reverse engineering the iPod nano LCD. The popular Raspberry Pi also has a MIPI DSI connector for driving an LCD, but as of the time of writing there is no information on how to use it.
Extended Display Identification Data (EDID)
Extended Display Identification Data (EDID) is used as a way to tell the host computer how to drive the panel, and what formats it supports. It's simply a 256 byte EEPROM chip that communicates over I2C, and both VGA and DVI cables provide signals for this. It makes it possible to connect a panel to a computer and have the computer automatically know what resolution it should output.
This makes re-using an LCD panel a lot easier, since the computer will know exactly how to drive your panel! (provided you have an appropriate LVDS driver)
If for some reason the computer doesn't detect your EDID chip, you can override the default EDID under both Windows and Linux using your own data file. This data file may be extracted from another working computer, or you could construct it yourself (not covered in this article).
Extracting the EDID data is pretty easy to do in linux with the following command:
> tvservice -d edid.dat
or if this isn't available, you can query it directly from the I2C bus, since the EDID chip is just an EEPROM with the address 0x50: (You need to know which I2C bus the EDID chip is connected to though)
> i2cdetect -r N # Detect all I2C devices on bus 'N'. Should show a device at 0x50> i2cdump -y N 0x50 # Dump the contents of the device at address 0x50, in ASCII format
Here's a sample dump from my Portege R500 LCD (LTD121EWEK) connected to a RIoTBoard: (LVDS EDID is connected to /dev/i2c-dev-2)
Dumping EDID in windows is also possible through the use of a 3rd party tool.
Reverse Engineering LCD Panels
DISCLAIMER: Reverse-engineering is tricky buisiness. You may permanently damage either your panel or laptop, so don't do it on anything important! You are responsible for your own safety.
If you don't have a datsheet for your LCD panel, it is still possible to re-use it with some reverse-engineering skills. This is easiest if you have the LCD connected to a working laptop so you can probe the signals.
I won't do a full guide into reverse engineering here, but here are some basic tips:
First you need to locate the power supply, LVDS pairs, and optionally the EDID lines.
Ground should be easy to locate, as it is usually connected to large copper pours, the LCD frame, LVDS shields, and the connector casing.
V+ should have the thickest tracks on the PCB, and measure a common voltage such as 2.5, 3.3, or 5.0V. Verify this with a multimeter
EDID should consist of 3 wires: SDA, SCL, and V_EDID. SDA/SCL will be pulled high to V_EDID, so you should find 3 pins at a common voltage. You can verify that they are EDID by using an oscilloscope and checking for data when you boot the laptop.
The LVDS wires should also be easy to locate - they are always routed as pairs on the PCB, and the wires may be twisted or shielded. For a laptop LCD there should be 3-4 pairs.
The backlight may or may not be on the same connector as the data. For LED screens, look for high voltages (>12V)
There are two main types of backlighting in LCD panels: CCFL (Flurorescent), and LED. CCFL was widely used in older laptops before LED backlights came around, and are pretty obvious because you will find a large inverter module with a transformer on it, probably covered in "Warning: High Voltage!" stickers. These transformers usually have multiple pins: +V, GND, and Enable/Dimming pins. +V is usually either +12V or +5V.
LED backlights result in much thinner displays, and usually need a dedicated driver, which may or may not be built into the LCD panel. LED backlights may be split into an Anode and several Cathode wires, consiting of several "strings" of LEDs.
The LVDS configuration is trickier to figure out, but you shouldn't need an oscilloscope (as the signals are much too fast for most low-end oscilloscopes anyway). Try disconnecting a pair from the cable and see what effect it has on the screen (refer to the data framing diagrams):
If you lose the picture, it is the CLK pair
If the picture becomes scrambled horizontally, it is probably the Y2 pair (which contains HSYNC/VSYNC signals)
If the picture gains a red or cyan tint, it is probably the Y0 pair (contians red colours)
If the picture gains a green or purple tint, it is probably the Y1 pair (contains green colours)
Also the LVDS pairs are usually routed in order: Y0,Y1,Y2,Y3, while CLK could appear on either side.
Start by disconnecting the power supply & backlight and connecting it to your own supply (with the LVDS still connected to your laptop if possible). You should hopefully see some change in appearance of the panel.
You should be good to connect the LVDS pairs to your driver of choice, and hopefully it will get up and work. If the picture appears corrupted, you either have the polarity wrong, or have flipped Y1/Y2/Y3. If not, well I can't really offer any advice, so you're on your own ;)
If you want to use an LVDS LCD panel with a computer or SBC, you will need to find a way to interface it with your device. Since most computers/SBCs don't have LVDS outputs, you will probably need an HDMI/DVI to LVDS converter board. Here are some options for interfacing:
Purchase a converter board from China (eg. Aliexpress/eBay)
Apparently you can ask the seller to match the driver board to your LCD's datasheet, although I've never tried this. It should mostly just work with your panel provided it has an EDID chip.
Use a direct LVDS-to-HDMI converter board eg. ChalkElec's LVDSConverter (Which is open-source!).
It is very straight-forward - all it does is convert HDMI to TTL parallel to LVDS. There is no on-screen display or scaling involved, so whatever your computer outputs is what is displayed!
Parallel output to LVDS Some SBCs (eg. Beaglebone Black) will have a TTL Parallel video output, which can be converted to LVDS easily with an appropriate chip.
In all the above cases you will need to ensure the data format of your LCD panel matches the data format of your LVDS driver. As mentioned earlier, the most common format for old LCD panels is 18bpp (3D+1C), which is compatible with a 24bpp LSB driver (since the 4th output channel Y3 can be ommitted)
Thanks for reading! Hopefully this guide is useful to you - if you think so, leave a comment. Knowing that people find this stuff useful gives me energy to do more experiments!
Also check out my RIoTLCD project, where I re-purposed a laptop LCD using the above knowledge and connected it to a RIoTBoard:
Smart-watches are becoming the next big thing, but with increased miniaturization it is
becoming impossible to build these sorts of devices yourself. This project aims to provide
a "smart-watch" which can be built from readily available components (eg. from element14, digikey, etc.),
and able to be soldered by hand. Of course, processing power must be sacrificed, but who
needs a camera and 60FPS graphics on a watch???
I have been working on this watch since early 2013, and it has come a long way!
It is still very much a work-in-progress though, and I am working on another hardware revision
which will fix all the hardware bugs.
(you can read more about those from my previous posts on the project)
The watch features a PIC24F microcontroller and a 128x128 RGB OLED display, along with an
accelerometer and magnetometer. The goal is to have both USB-HID (driverless) and
Bluetooth 4.0 LE connectivity, so I can sync the calendar quickly and easily.
Real-Time Clock - It can tell the time!
University Timetable - I can tell when and where my next class is
USB-HID comms and bootloader
Basic accelerometer logging
Battery charging & monitoring
Anti-aliased font drawing (Just grayscale at the moment, no "clear-type")
Bluetooth 4.0 LE
Alarm clock with peizo buzzer
Desktop GUI for updating the calendar
The hardware is a 2-layer design utilizing SMD components, and is fully open-source in case you'd like to build your own.
Schematics and PCB layout were done using Altium, which unfortunately is quite expensive, but they recently announced they
would be releasing a free version sometime in the future!
Watch sometimes resets when waking up (possibly supply decoupling issues)
USB comms task sometimes doesn't go to sleep (drains the battery)
OLED display has some weird ghosting artifacts
In the schematic I got the connector around the wrong way, so the OLED is on the opposite side of the PCB than I wanted.
I didn't assign the OLED data lines to the PIC24's TFT driver, so I can't make use of it and drawing performance is less than what it could be.
Bluetooth 4.0 is untested
There are a few minor "bodges" on the PCB required to make it function correctly
Future (Rev 3)
I am working on a revision 3, which will fix all of the above issues and make the PCB much more compact!
Stay tuned... (Subscribe to the RSS feed to keep up-to-date)
The firmware is available on my github: jorticus/zeitgeber-firmware
You will need the MPLAB-X IDE, the XC16 free compiler, and the Microchip Application Framework.
Alternatively you can download the bootloader & firmware binaries here: oshwatch-binaries.zip
Custom RTOS, with power saving
Custom graphics library, with anti-aliased text drawing