Skip to content
This repository has been archived by the owner on Sep 30, 2024. It is now read-only.

SPI interface circuit

notro edited this page May 17, 2013 · 20 revisions

Work in progress...

This is an interface circuit for connecting a parallel interface LCD display with SPI.

The circuit is based on SpriteMods circuit.

                                                                 74HC4094
                                                               +--------------+
                                                               |              |
  MOSI o-------------------------------------------------------| D        QP0 |-------------o DB0
                                                               |              |
  SCLK o---------+---------------------------------------------| CP       QP1 |-------------o DB1
                 |                                             |              |
   CSn o------+  |                                     Vcc o---| OE       QP2 |-------------o DB2
              |  |                                             |              |
              |  |      74HC4040                               |          QP3 |-------------o DB3
              |  |    +--------------+                         |              |
              |  |    |              |                         |          QP4 |-------------o DB4
              |  |    |           Q0 |--                       |              |
              |  |    |              |                         |          QP5 |-------------o DB5
              |  |    |           Q1 |--                       |              |
              |  |    |              |                         |          QP6 |-------------o DB6
              |  |    |           Q2 |-------------+-----------| STR          |
              |  |    |              |             |           |          QP7 |-------------o DB7
              |  |    |           Q3 |--           |           |              |
              |  |    |              |             |           |              |
              |  |    |           Q4 |--           |           |          QS1 |--
              |  |    |              |             |           |              |
              |  |    |           Q5 |--           |           |          QS2 |--
              |  +----| CP           |             |           |              |
              |       |           Q6 |--           |           +--------------+
              +-------| MR           |             |
              |       |           Q7 |--           |
              |       |              |             |               74HC04
              |       |           Q8 |--           +-----------------|>o--------------------o WR
              |       |              |
              |       |           Q9 |--                                             Vcc o--o RD
              |       |              |
              |       |          Q10 |--
              |       |              |
              |       |          Q11 |--
              |       |              |
              |       +--------------+
              |
              |
              +-----------------------------------------------------------------------------o CS

Timing analysis

This is an analysis of the circuits timing constraints.

Constraints is examined for a SPI speed of 32 MHz.

See appendix for details about the 3.3 V values.

Clock (SPI)

These are connected to the SPI clock:

IC          Symbol         Parameter                        Conditions                 Min  Typ  Max  Unit
-----------------------------------------------------------------------------------------------------------
RPi                         SPI speed                        VCC = 3.3 V                     32        MHz
74HC4040     fmax           maximum operating frequency      VCC = 3.3 V                20   55   -    MHz
74HC4094     fmax           maximum frequency                VCC = 3.3 V                20   58   -    MHz

32 MHz falls within the typical values, but fails the minimum values.

STR (74HC4094)

The 74HC4094 clocks in data on the rising edge of the clock.
The 74HC4040 counts on the falling edge of the clock.

On the 4th clock cycle: SCLK goes LOW -> 74HC4040 Q2 goes HIGH -> 74HC4094 STR goes HIGH -> shift register data goes to the outputs.
On the 8th clock cycle: SCLK goes LOW -> 74HC4040 Q2 goes LOW -> 74HC4094 STR goes LOW -> outputs are locked (latched).
If STR is HIGH, QPn changes when CP goes HIGH.

IC          Symbol         Parameter                        Conditions                 Min  Typ  Max  Unit
----------------------------------------------------------------------------------------------------------
RPi          twl            pulse width LOW                  32 MHz                          16        ns
74HC4094     tpd            propagation delay CP to QPn      VCC = 3.3 V                -    34   58   ns
74HC4040     tPHL, tPLH     propagation delay CP to Q0       VCC = 3.3 V                -    25   45   ns

Constraint
STR must go LOW before new data enters into the shift register: RPi twl + 74HC4094 tpd > 74HC4040 ttPHL
Typ: 16 + 34 > 25
Worst case: 16 + 34 > 45

WR (LCD)

Data is latched in on the rising edge of /WR.

After 4 clock cycles: STR goes HIGH -> 74HC04 nA goes HIGH -> 74HC04 nY goes LOW -> /WR goes LOW
After 8 clock cycles: STR goes LOW -> 74HC04 nA goes LOW -> 74HC04 nY goes HIGH -> /WR goes HIGH -> data latches in

SSD1289
-------
Symbol   Parameter                               Min  Typ  Max  Unit
---------------------------------------------------------------------------------------
 tcycle   Clock Cycle Time (write cycle)         100   -    -    ns
 PWL      Pulse Width low (write cycle)           50   -    -    ns
 PWH      Pulse Width high (write cycle)          50   -    -    ns
 tDSW     Data Setup Time                          5   -    -    ns
 tDHW     Data Hold Time                           5   -    -    ns

ILI9325
-------
  18.3.1 Display Parallel 18/16/9/8-bit Interface Timing Characteristics (8080-I system)
Symbol   Parameter                               Min  Typ  Max  Unit
---------------------------------------------------------------------------------------
 twc      Write cycle                             66        -    ns
 twrl     Write Control pulse L duration          15        -    ns
 twrh     Write Control pulse H duration          15        -    ns
 tdst     Write data setup time                   10        -    ns
 tdht     Write data hold time                    10        -    ns

IC          Symbol         Parameter                        Conditions                 Min  Typ  Max  Unit
----------------------------------------------------------------------------------------------------------
74HC04       tpd            propagation delay                VCC = 3.3 V                -    13   25   ns

Constraints
Pulse Width Low and Pulse Width High is both 4 clock cycles long: 4 x SPI speed > 50 ns => SPI speed < 80 MHz
Data Setup Time is the time from the last bit is clocked in and available on the outputs, and to /WR goes HIGH: the 74HC04 inverter propagation delay is enough to satisify this.
Data Hold Time is the time from /WR is HIGH to data can change on the bus: this is 4 clock cycles since STR is LOW for so long: 4x32 > 10ns

Backlight

There is 5 inverters left in the 74HC04 Hex Inverter IC. These can be used to drive a LCD backlight.

  • Backlight pulled to +3.3V. It can deliver 4x25mA = 100mA
  • Backlight pulled to GND. Remove the first inverter and put it in parallel. It can sink 5x20mA = 100mA
  led o-----|>o----+--|>o--+-----o LCD backlight
                   |       |
                   +--|>o--+
                   |       |
                   +--|>o--+
                   |       |
                   +--|>o--+

ITDB02-2.8

The circuit is tested with this display. I get ~17fps at 32MHz (parallel ~25 fps).
I haven't updated the itdb28fb driver to support SPI yet, so I use flexfb for now

modprobe fbtft_device name=flexfb gpios=reset:25,dc:24,led:18

modprobe flexfb debug=3 rotate=0 width=240 height=320 regwidth=16 setaddrwin=1 init=-1,0x00E3,0x3008,-1,0x00E7,0x0012,-1,0x00EF,0x1231,-1,0x0001,0x0100,-1,0x0002,0x0700,-1,0x0003,0x1030,-1,0x0004,0x0000,-1,0x0008,0x0207,-1,0x0009,0x0000,-1,0x000A,0x0000,-1,0x000C,0x0000,-1,0x000D,0x0000,-1,0x000F,0x0000,-1,0x0010,0x0000,-1,0x0011,0x0007,-1,0x0012,0x0000,-1,0x0013,0x0000,-2,200,-1,0x0010,0x1690,-1,0x0011,0x0223,-2,50,-1,0x0012,0x000D,-2,50,-1,0x0013,0x1200,-1,0x0029,0x000A,-1,0x002B,0x000C,-2,50,-1,0x0020,0x0000,-1,0x0021,0x0000,-1,0x0030,0x0000,-1,0x0031,0x0506,-1,0x0032,0x0104,-1,0x0035,0x0207,-1,0x0036,0x000F,-1,0x0037,0x0306,-1,0x0038,0x0102,-1,0x0039,0x0707,-1,0x003C,0x0702,-1,0x003D,0x1604,-1,0x0050,0x0000,-1,0x0051,0x00EF,-1,0x0052,0x0000,-1,0x0053,0x013F,-1,0x0060,0xA700,-1,0x0061,0x0001,-1,0x006A,0x0000,-1,0x0080,0x0000,-1,0x0081,0x0000,-1,0x0082,0x0000,-1,0x0083,0x0000,-1,0x0084,0x0000,-1,0x0085,0x0000,-1,0x0090,0x0010,-1,0x0092,0x0600,-1,0x0007,0x0133,-3

Appendix

Dynamic charateristics

The datasheets doesn't mention values with a 3.3V supply voltage.
In the 74HC User guide theres is a graph: Fig. 7 Propagation delay as a function of supply voltage; Tamb = 25 °C; CL = 50 pF
From this we can find that: VCC = 3.3V gives a factor of ~1.5 relative to 4.5V which is 1

Excerpts

74HC4040
--------
Symbol  Parameter                      Conditions                 Min  Typ  Max  Unit
 fmax    maximum operating frequency    VCC = 2.0 V; CL= 50 pF      6   27   -    MHz
                                        VCC = 4.5 V; CL= 50 pF     30   82   -    MHz
                    Using factor 1.5    VCC = 3.3 V;               20   55   -    MHz



Symbol        Parameter                      Conditions                 Min  Typ  Max  Unit
 tPHL, tPLH    propagation delay CP to Q0     VCC = 2.0 V; CL = 50 pF    -    47  150   ns
                                              VCC = 4.5 V; CL = 50 pF    -    17   30   ns
                          using factor 1.5    VCC = 3.3 V                -    25   45   ns

               propagation delay Qn to Qn+1   VCC = 2.0 V; CL = 50 pF    -    28  100   ns
                                              VCC = 4.5 V; CL = 50 pF    -    10   20   ns
                          using factor 1.5    VCC = 3.3 V                -    15   30   ns



74HC4094
--------
Symbol  Parameter                      Conditions                 Min  Typ  Max  Unit
 tpd     propagation delay CP to QPn    VCC = 2.0 V                -    63  195   ns
                                        VCC = 4.5 V                -    23   39   ns
                   using factor 1.5     VCC = 3.3 V                -    34   58   ns

 fmax    maximum frequency              CP
                                        VCC = 2.0 V                 6   28   -    MHz
                                        VCC = 4.5 V                30   87   -    MHz
                   using factor 1.5     VCC = 3.3 V                20   58   -    MHz

74HC04
------
Symbol  Parameter                      Conditions                 Min  Typ  Max  Unit
 tpd     propagation delay nA to nY     VCC = 2.0 V                -   25    85   ns
                                        VCC = 4.5 V                -    9    17   ns
                   using factor 1.5     VCC = 3.3 V                -   13    25   ns

Datasheets

Test script

I used this script to sort out some miswiring. Must be run as root.

import os
import time
import subprocess

# put a backslash before 007. Markdown messes it up.
def beep():
	if subprocess.call(["echo", "-ne", "007"]) != 0:
		raise OSError

def writef(file, val):
#	print "%s <- %s" % (file, val)
	with open(file, 'w') as f: f.write(val)

class GPIO:
	def __init__(self, num):
		self.num = num
		self.val = 0
		writef("/sys/class/gpio/export", "%s" % num)
		writef("/sys/class/gpio/gpio%s/direction" % num, "out")

	def close(self):
		writef("/sys/class/gpio/gpio%s/direction" % self.num, "in")
		writef("/sys/class/gpio/unexport", "%s" % self.num)

	def set(self, val=1):
		if val == 0:
			self.val = 0
		else:
			self.val = 1
		writef("/sys/class/gpio/gpio%s/value" % self.num, "%s" % self.val)
		return self.val

	def clear(self):
		self.set(0)

	def pulse(self):
		beep()
		if (self.val):
			self.set(0)
			time.sleep(1)
			self.set(1)
		else:
			self.set(1)
			time.sleep(1)
			self.set(0)

class SPI:
	def __init__(self, sclk_gpio, mosi_gpio, ce_gpio):
		self.sclk = GPIO(sclk_gpio)
		self.mosi = GPIO(mosi_gpio)
		self.ce = GPIO(ce_gpio)
		self.ce.set(1)
		self.sclk.set(0)
		self.mosi.set(0)

	def close(self):
		self.sclk.close()
		self.mosi.close()
		self.ce.close()

	def start(self):
		self.ce.set(0)

	def end(self):
		self.ce.set(1)

	def clock(self, value):
#		print("value: %i" % value)
		ret = self.mosi.set(value)
		self.sclk.set(1)
#		time.sleep(1)
		self.sclk.set(0)
#		time.sleep(1)
		return ret

	def write(self, byte):
		for i in range(8):
			spi.clock( (byte << i) & 0b10000000 )

# echo "11" > /sys/class/gpio/unexport; echo "10" > /sys/class/gpio/unexport; echo "8" > /sys/class/gpio/unexport


SCLK = 11
MOSI = 10
CE0 = 8

value = 0b11001101

count = 0

# Setup
value &= 0xFF
spi = SPI(SCLK, MOSI, CE0)

# Clear contents of shift register
spi.write(0)

print("\nPress ENTER on each step to proceed\nOnly changing signals is shown")

print("\nByte to transfer: %s" % bin(value))

# Start Transmit
print("\n  => SCLK = 0, MOSI = 0, CS=1")
print("\n  => 74HC4040 Q2 = 0\n")
raw_input("Initiate transfer by lowering CE(CS)")
spi.start()
print("\n  => CS=0\n")

raw_input("Set MOSI=1 and take SCLK HIGH")
bit = (value << count) & 0b10000000
spi.mosi.set(bit)
count += 1
spi.sclk.set(1)
print("\n  => SCLK=1, MOSI=1\n")

raw_input("Take SCLK LOW")
spi.sclk.set(0)
print("\n  => SCLK=0\n")

for i in range(3):
	bit = (value << count) & 0b10000000
	if bit: bit = 1
	count += 1
	raw_input("Clock out bit: %i" % bit)
	spi.clock(bit)

print("\n  => 74HC4040 Q2 = 1  =>  74HC4094 STR = 1  =>  Shift register content is available on the outputs")
print("                      =>  74HC04 1A = 1     =>  WR = 0  =>  Display ready to receive data\n")

for i in range(4):
	bit = (value << count) & 0b10000000
	if bit: bit = 1
	count += 1
	raw_input("Clock out bit: %i" % bit)
	spi.clock(bit)

print("\n  => 74HC4040 Q2 = 0  =>  74HC4094 STR = 0  =>  Shift register outputs is frozen (latched)")
print("                      =>  74HC04 1A = 0     =>  WR = 1  =>  Data latched in\n")

raw_input("Stop transfer by raising CE")
spi.end()
print("\n  => CS=1\n")

raw_input("Release GPIOs")
spi.close()

print("\n  => All pins floating\n")

piwik

Clone this wiki locally