This repository was archived by the owner on Sep 30, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 495
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
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.
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--+
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
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")