Shop OBEX P1 Docs P2 Docs Events
LCD Graphics/Text Driver for cheap SPI LCD's with optional Touch screen support — Parallax Forums

LCD Graphics/Text Driver for cheap SPI LCD's with optional Touch screen support

Cluso99Cluso99 Posts: 18,066
edited 2021-04-17 03:02 in Propeller 2
4.0" TFT SPI 480x320 LCD ST7796 -Spin2 and PASM Driver & Demo
Touch and non-touch versions
Previously "4.0in TFT SPI 480x320 LCD ST7796 Driver and TCS2046 touchscreen support"

P2 Quick Byte

Update 10-Mar-2021 v3.01 Now supports many SPI LCD boards of various resolutions and optional Touch Panel code from Mike Roberts, and includes changes by Greg LaPolla for 3.2 in 320x240 ILIp341 SPI LCD

Routines for
  • Draws Text with both 6x8 and 8x8 fonts
  • Draws Lines
  • Draws Circles
  • Draws Rectangles
  • Draws filled boxes
  • Draws an analog clock face

Supports these LCDs and similar
  • 4.0 in 480x320 ST7796S SPI LCD with/without Touch
  • 3.2 in 320x240 ILI9341 SPI LCD with/without Touch
  • 1.44 in 128x128 ILI9163 SPI LCD (no Touch)
Should also support these
  • 3.5 in 480x320 ILI9488 SPI LCD with/without Touch (one on order)
  • 2.8 in 320x240 ILI9341 SPI LCD with/without Touch
  • 2.4 in 320x240 ILI9341 SPI LCD with/without Touch
  • 2.2 in 320x240 ILI9163 SPI LCD (no Touch)
  • 1.3 in 240x240 ST7789 SPI LCD (no Touch) (one on order)

Update 31-Jan-2021 v207-TS (actually v208): @mwroberts added TCS2064 touchscreen support

V2.0: First release - Software Driver and demo
v204: Uses the new DRVx instructions rather than the older OUTA/DIRA.
v205: Better demo (still has circle bug)
v206: On RetroBlade2 P42-47
v207: Circle bug fixed

It’s based on my 1.44” ILI9163 LCD Driver (hence v2.0)
and my P1 version

* P2 PASM COG (CPU) supporting...
o clear screen
o set foreground and background colors
o set window (x,y start and end)
o fill window
o set column and row (x,y start)
o draw characters in 6*8 and 8*8 fonts (both fonts loaded into the pasm cog)
o also supports low level LCD calls to directly manipulate the LCD
* P2 SPIN2 COG (CPU) supporting...
o supports above pasm calls plus
o draw strings (6*8 and 8*8 fonts)
o draw line (x,y start and end with color)
o draw circle (x,y center, diameter, color)
o fill rectangle (x,y start and end, color)
o draw round clock face and hour/minute/second hands - includes sample program to redraw hands each second

Note: I am still using the old DIRA/OUTA methods to drive the LCD, so currently it's limited to the P0-31 I/O pins. Fixed in v204

Uses I/O (later versions use P47-42)
' LCD Connector:
' PIN_VCC                                ' 3v3 ~59mA or 5V ~113mA power supplied by power supply
' PIN_GND                                ' GND pwr supplied by power supply
  PIN_CE        = 0                      ' Serial clock enable pin
  PIN_RST       = 1                      ' Reset pin (can be reset by software)
  PIN_DC        = 2                      ' Data / Command selection pin
  PIN_SDA       = 3                      ' Serial Data MOSI pin
  PIN_CLK       = 4                      ' Serial Clock pin
  PIN_LED       = 5                      ' LED backlight enable pin (hi to enable - ~2.4mA)
  PIN_SDO       = 6                      ' Serial Data MISO pin (not used)

Enjoy :sunglasses:

Driven by my RetroBlade2 on pins P42-47


  • Cluso99Cluso99 Posts: 18,066
    edited 2020-11-06 23:58
    The ST7796 registers are the same as the ILI9163 so i just tried my code with slight mods. Basically works :sunglasses:
  • Cluso99Cluso99 Posts: 18,066
    Here are a few measurements...
    Powered from 5V = 113mA
    Powered from 3V3 = 59mA (vreg not bypassed on LCD board) - DO NOT power (or GND) from a P2 pin! (This works for the 1.44" LCD)
    LED 2.4mA @ 3V3 so can be safely connected to P2 pin
  • Cluso99Cluso99 Posts: 18,066
    Currently i am not using the MISO pin so there are only 6 IO pins being used.
    You may have noticed i need to rotate 90 degrees and invert. The screen pixel size doesn’t seem to be working as it should either. But this was a 5 minute job and I didn’t really expect to be able to use the ILI driver so easily. I will try and make it as parameterised as possible.
  • Cluso99Cluso99 Posts: 18,066
    Ok, now have mirroring fixed.
    Next is to convert some lcd commands to use 16bit parameters for row and column addressing etc (was 8bit for the smaller LCD).
  • RaymanRayman Posts: 13,475
    Interesting to see larger display with RAM for low cost...

    How fast with the SPI bus run? Will it do QPI too?

    Are you planning on using P2 ADC to do the touchscreen?
    I'd like to see how well that works...
  • Cluso99Cluso99 Posts: 18,066
    The SPI is bit bashed in pasm (cog). Currently no delays. No QSPI. There are 8 & 16 bit parallel alternatives to these displays but I opted for the SPI. So far, I am not using miso ie not reading from the lcd.

    My clock happily ticks by every second, but it’s small an in the corner.

    The touch has an onboard chip and IIRC which converts to SPI. it’s capacitive touch and also came with plastic pen.
  • RaymanRayman Posts: 13,475
    SPI for the cap touch? Usually it's I2C...
  • Cluso99Cluso99 Posts: 18,066
    The touch chip is XPT2046 with connections CLK/CS/DI/DO/IRQ so looks like SPI to me.
  • Xpt2046 is resistive touch?? Or am I missing something?
  • Cluso99Cluso99 Posts: 18,066
    Yes, I think I misread the LCD specs from another site.
    My current code requires a change in my pixel counter mailbox from 16bit to 32bit. I’ve already changed the x and y start and end addresses from 8bit to 16bit (the old code was for 128*128/160 pixel screens). I’ve been doing the changes as I get time. My demos work, drawing 6*8 and 8*8 characters (yes both supported concurrently and both fonts inbuilt), drawing lines, boxes with fill, circles, and my clock face. When filling boxes (and clearing the screen) your code gives two x,y addresses and the code needs to calculate and pass (to the pasm driver cog) the number of pixels in that box and this needs to be >16 bits that I allowed. This is used in the clear screen routine too.
  • Cluso99Cluso99 Posts: 18,066
    See first post for code release and pic :sunglasses:
  • RaymanRayman Posts: 13,475
    edited 2020-11-07 02:55
    I see this is the display often used by RasPi. Thought needed super high speed SPI but apparently not...
  • Cluso99Cluso99 Posts: 18,066
    Posted v205 in first post.
    There is bug in drawing the circles which I suspect is to do with the maths overflowing as the x or y position cannot be greater than ~160-170 so I'm posting it while I think about the problem some more.
    This is my code
    PRI drawCircle(xc, yc, dia, rgb) | i, x, y, d
    ' Draw Circle d^2 = x^2 + y^2; y = SQRT(d^2 - x^2) (Pythagoras theorum)
      repeat i from 0 to dia-1
        x := i
        y := SQRT((dia*dia) - (x*x))
        'plot incrementing x axis
        drawPixel(x+xc, y+yc, rgb)
        drawPixel(xc-x, y+yc, rgb)
        drawPixel(x+xc, yc-y, rgb)
        drawPixel(xc-x, yc-y, rgb)
        'plot incrementing y axis
        drawPixel(y+yc, x+xc, rgb)
        drawPixel(yc-y, x+xc, rgb)
        drawPixel(y+yc, yc-x, rgb)
        drawPixel(yc-y, yc-x, rgb)
  • Cluso99Cluso99 Posts: 18,066
    edited 2020-11-07 07:13
    Now working on P42-47 on my RetroBlade2 (pic on first post)
  • Cluso99Cluso99 Posts: 18,066
    edited 2020-11-08 02:16
    Draw circle bug fixed. See first post for v207 code. :sunglasses:
  • Cluso99Cluso99 Posts: 18,066
    edited 2020-11-10 02:07
    Demo updated to v208 that includes a full screen text demo..
    20 lines are 80 chars of 6*8 font followed by 20 lines of 60 chars 8*8 font

  • Hi @Cluso99
    See first post for code release and pic :sunglasses:

    I cant find any link on post 1 for the code for this display.
    Have just received mine.
    I see you say your ILI9361 code worked so I can try mine as is, but I would like to compare. :)

  • PublisonPublison Posts: 12,366
    edited 2020-11-11 17:34
    tritonium wrote: »
    Hi @Cluso99
    See first post for code release and pic :sunglasses:

    I cant find any link on post 1 for the code for this display.
    Have just received mine.
    I see you say your ILI9361 code worked so I can try mine as is, but I would like to compare. :)


    Can you see all the ZIP files at the bottom of the first post? You may need to refresh. I notice sometimes they disappear.
  • Hi Publison

    Gosh! You're right!
    Why does that happen?

    Nice clean elegant code- makes mine look positively grubby. :blush:

    Thanks Cluso99
    I went about it a different way- not so much room on the prop1.
    Like the way you implemented the mailbox.
    And the 5X7 font is handy.
    On the 2 inch display I used the prop1's built in font table- much bigger- easier to see.

  • Cluso99Cluso99 Posts: 18,066
    Thanks for you kind words.
    I need the small font to get 80 chars wide. An 8*12 font might be better and there’s room as LUT is not used.
    I have been looking at scrolling but it seems I can only achieve horizontal because I’ve flipped the display to 480x320 w-h. Will have to ultimately do it in code. Project for another day.
  • Hi @Cluso99

    I added a driver for the 2046 touchscreen chip into your st7796 driver and added a demo into your st7796 demo.

    I used the same pins you used.

    It seems to work pretty good, I'm curious to see what you think...


  • Cluso99Cluso99 Posts: 18,066


    Thanks so much for doing this! Looks great :)

    I will update the title!

  • Cluso99Cluso99 Posts: 18,066

    Here is an update just for text 8x8 font with 60 characters of 40 lines with auto-scrolling

  • Hi
    OH good you've figured out the auto scrolling. Must take a look and update my flexbasic version. :)

  • Cluso99Cluso99 Posts: 18,066

    If anyone has experience with these or similar LCD controllers, I’m looking for how to use the internals to scroll.

    There might be two ways. Best to use the ic scrolling feature but first looks seem to be able to only scroll when in portrait mode and I’m in landscape. Second is to read back the pixel data and rewrite to the new locations as this saves keeping an external copy. With the external copy, colour formatting gets lost.

    Any help appreciated.

  • Cluso99Cluso99 Posts: 18,066

    I have been trying to utilise the LCD chip to perform the scrolling. Seems it might be only be able to do vertical scrolling in portrait mode :(
    I'm running in landscape mode (a simple 1-bit config change) but alas the v scroll now shifts horizontally.

    If anyone has seen code to drive the scrolling without doing it manually outside the chip then please let me know.

  • Cluso99Cluso99 Posts: 18,066

    I have just posted a text only version where the LCD Driver is decoupled from the formatting object. It also uses a serial port as well.

    P2 Serial and LCD (60x40 text) Drivers using a common Formatting Object and Buffers


    • Doesn't scroll, just wraps from bottom to top
    • 60x40 columns x rows with 8x8 font in landscape mode
    • Only supports control characters CR and LF for now.
    • Green foreground, black background (change by CON when compiling)
    • Doesn't support touch
  • Cluso99Cluso99 Posts: 18,066

    @mwroberts said:
    Hi @Cluso99
    I added a driver for the 2046 touchscreen chip into your st7796 driver and added a demo into your st7796 demo.
    I used the same pins you used.
    It seems to work pretty good, I'm curious to see what you think...

    I need to get time to test it and put it into my latest LCD driver :(

  • Cluso99Cluso99 Posts: 18,066

    V3.01 code now posted in the first post and in P2 Quick Bytes

    Now supports many cheap SPI LCDs from 1.44in 128x128 to 4.0in 480x320. Larger ones should also be possible. Optional Touch support has been added.

    Thanks to Mike Roberts and Greg LaPolla for their contributions.

Sign In or Register to comment.