Apr 19, 2014

Sainsmart display (320x240 LCD - 3.2'') (SSD1289 controller) framebuffer driver + touch (ADS7843) for RasperryPi

Sainsmart display become popular on  Ozzmarket.com  because it is very cheap (ebay) and also because Marks-Space kickstarter campain starts promotion LCD displays for RaspberryPi.  Their LCD display is based on different LCD driver controller (ILI9481)  and different touchscreen controller  (XPT2046) than SainSmart LCD. Sainsmart display is based on SPI SSD1289 chip with ADS7843 4-WIRE touch controller.

Sainsmart display has 40 pin - two row connector. For connecting to RaspberryPi following connections is needed:

It is possible to power it also from 3.3V(pin 2) (I use it). Schematic explanation can be found on Valdovov page

Running sainsmart display under raspberyPi
Under Linux all similar small TFT displays use common fbtft layer - Linux Framebuffer drivers for small TFT LCD display modules. This layer is written for new Linux kernels, therefore I used 3.10.33+ kernel. Base raspbian "wheezy" image with included fbtft drivers (compiled as modules) can be downloaded from this page: https://github.com/notro/fbtft/wiki
Direct link for downloading image 2014-01-07-wheezy-raspbian-2014-03-12-fbtft-master-firmware.zip
It is also possible to upgrade your running kernel - no need to download new image. Try this tutorial for upgrading your kernel. We use our downloaded Raspbian image.
Now copy unzipped file to your SDcard.

$unzip  2014-01-07-wheezy-raspbian-2014-03-12-fbtft-master-firmware.zip - d <your destination folder>

$dd if=2014-01-07-wheezy-raspbian-2014-03-12-fbtft-master-firmware.img of=/dev/mmcblk0

All fbtft module drivers are stored in /lib/modules/<your kernel version>/kernel/drivers/video/fbtft/ directory. You can check whats inside.
After booting image (this image expands partition first) run this command for running sainsmart driver:

$sudo modprobe fbtft_device name=sainsmart32_spi rotate=90 speed=16000000 debug=$((1<<5)) gpios=reset:25,dc:24

Check your gpio connection if it matches to your schematic. Now type 


Now you should see something something like this:
[   28.903126] Adding 102396k swap on /var/swap.  Priority:-1 extents:2 across:2723836k SSFS
[  334.704250] fbtft_device:  SPI devices registered:
[  334.704304] fbtft_device:      spidev spi0.0 500kHz 8 bits mode=0x00
[  334.704322] fbtft_device:      spidev spi0.1 500kHz 8 bits mode=0x00
[  334.704332] fbtft_device:  'fb' Platform devices registered:
[  334.704352] fbtft_device:      bcm2708_fb id=-1 pdata? no
[  334.704417] fbtft_device: Deleting spi0.0
[  334.933076] fb_ssd1289 spi0.0: Display update: 1797 kB/s (83.404 ms), fps=0 (0.000 ms)
[  334.938457] graphics fb1: fb_ssd1289 frame buffer, 320x240, 150 KiB video memory, 4 KiB DMA buffer memory, fps=20, spi0.0 at 16 MHz
[  334.938560] fbtft_device:  GPIOS used by 'sainsmart32_spi':
[  334.938579] fbtft_device:    'reset' = GPIO25
[  334.938590] fbtft_device:    'dc' = GPIO24
[  334.938599] fbtft_device:  SPI devices registered:
[  334.938615] fbtft_device:      spidev spi0.1 500kHz 8 bits mode=0x00
[  334.938629] fbtft_device:      fb_ssd1289 spi0.0 16000kHz 8 bits mode=0x00
[  365.483655] fb_ssd1289 spi0.0: Display update: 1784 kB/s (83.695 ms), fps=0 (30550.286 ms)
[  365.566928] fb_ssd1289 spi0.0: Display update: 1794 kB/s (83.189 ms), fps=11 (83.782 ms)

Now try to start X11 on your new fb device /dev/fb1

$FRAMEBUFFER=/dev/fb1 startx

For enabling touch screen driver run:

$sudo modprobe ads7846_device verbose=2  cs=1 speed=2000000 model=7843 x_min=300 x_max=3800 y_min=700 y_max=3400 x_plate_ohms=60 pressure_max=255 gpio_pendown=17 keep_vref_on=1 swap_xy=1

Check your gpio connection if it matches to your schematic.  

For testing functionality type 

$cat /dev/input/event0 

or more sophisticated output


//if not installed type 

$sudo apt-get -y install xinput evtest

For tuning ads7846 module driver parameters see description:

Calibrate touch screen for X11

At beginning, you can read more about resistive touchscreens principle here. You can skip reading this article, but in general, after reading it, you will have more knowledge to deal with problems. 

DISPLAY=:0.0 xinput_calibrator

you should get result like this:

Calibrating EVDEV driver for "ADS7843 Touchscreen" id=6 current calibration values (from XInput): min_x=421, max_x=3869 and min_y=351, max_y=3818

Doing dynamic recalibration: Setting new calibration data: 372, 3863, 274, 3836

--> Making the calibration permanent<--
  copy the snippet below into '/etc/X11/xorg.conf.d/99-calibration.conf'
Section "InputClass" 
          Identifier "calibration" 
          MatchProduct "ADS7843 Touchscreen"
Option "Calibration" "372 3863 274 3836"

Edit 99-calibration.conf and add result from xinput_calibrator
sudo nano /etc/X11/xorg.conf.d/99-calibration.conf 
In ubuntu there is one file for evdev input configuration: /usr/share/X11/xorg.conf.d/10-evdev.conf
You can find here InputClass section for touchscreen:

Section "InputClass"
        Identifier "evdev touchscreen catchall"
        MatchIsTouchscreen "on"
        MatchDevicePath "/dev/input/event*"
        Driver "evdev"
#        Option  "Calibration"   "389 3837 344 3755"
#        Option "InvertX" "false"
#        Option "InvertY" "false"
#        Option  "SwapAxes"      "1"


It is possible to add configuration parameters for touchscreen here (try remove # )

Editing 99-calibration.conf doesn't worked for me!.

I found that, after first start xinput_calibrator, it create new file (/etc/pointercal.xinput)containing calibration data. This data are taken as default for X11. Therefore we need to delete this file after any xinput_calibrator is started again.

sudo rm /etc/pointercal.xinput 

Calibration log is stored in  /var/log/xinput_calibrator.pointercal.log

Getting current config for touchscreen or any input device

Run xinput and get pointer ID for your device

DISPLAY=:0.0 xinput

now list properties for specified ID

DISPLAY=:0.0 xinput list-props <your_device_ID>

cat /var/log/Xorg.0.log

You can set properties for display by set-props parameter. We can use it for touchscreen axis rotation:
DISPLAY=:0 xinput --set-prop 'ADS7846 Touchscreen' 'Evdev Axis Inversion' 1 1

Calibrate touch screen with tslib
export TSLIB_FBDEVICE=/dev/fb1 
export TSLIB_TSDEVICE=/dev/input/event0
sudo ts_calibrate
sudo ts_test
For calibrating touch also see tutorial:

Make permanent  sainsmart32_spi TFT driver (Debian)
Add to file /etc/modules
fbtft_device name=sainsmart32_spi rotate=90 speed=16000000 debug=0 gpios=reset:25,dc:24

There is one nice article about how resistive touch screen works and how to calibrate them:


Official fbtft wiki:
Hints for Frame buffer can be found here:
Supported fbtft devices:
SSD1289 driver description:
Setting image while booting:
Performance tests and with module insertion commands
Some hints how to build drivers under raspberry

Some raspberryPi 320x240 LCD blog


  1. The module that valdovov use in your design is different from fbtft driver. How did you manage to make it work with this circuit?

  2. the module is compatible for Raspberry pi 2?

    1. there is GPIO compatibility, but no sw module compatibility. There is need to chose module compiled for RPIv2.

    2. there is GPIO compatibility, but no sw module compatibility. There is need to chose module compiled for RPIv2.

  3. We read your blog website, share most practical information in blog. https://bit.ly/3-5-small-tft-lcd