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

SPI interface circuit

notro edited this page May 15, 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

The circuit seem to work fine at 32MHz on a breadboard.

I need to look into these timing constraints

  • the time from the shift register data is stable to the time WR goes HIGH has to be long enough.
  • clock signal delay through the 4040. It has to pull STR LOW before the clock rises again.

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

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