-
Notifications
You must be signed in to change notification settings - Fork 5
/
spi.htm
170 lines (170 loc) · 8.85 KB
/
spi.htm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>spi</title>
<style>
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
</style>
<link rel="stylesheet" href="/G-Pascal/G-Pascal.css" />
<!--[if lt IE 9]>
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
<![endif]-->
</head>
<body>
<header id="title-block-header">
<h1 class="title">SPI support</h1>
</header>
<p><strong>Author</strong>: Nick Gammon</p>
<p><strong>Date written</strong>: March 2022</p>
<div class="quick_link">
<a href="index.htm">Back to main G-Pascal page</a>
</div>
<div class="quick_link">
<a href="assembler.htm">Assembler info</a>
</div>
<div class="quick_link">
<a href="i2c.htm">I<sup>2</sup>C support</a>
</div>
<div class="quick_link">
<a href="pascal_compiler.htm">G-Pascal info</a>
</div>
<div class="quick_link">
<a href="editor.htm">Text editor</a>
</div>
<div class="quick_link">
<a href="file_menu.htm">File menu</a>
</div>
<h2 id="contents">Contents</h2>
<ul>
<li><a href="#introduction">Introduction</a></li>
<li><a href="#about">About SPI</a></li>
<li><a href="#wiring">Wiring</a></li>
<li><a href="#api">Code API</a></li>
<li><a href="#examples">Example code</a></li>
<li><a href="#credits">Credits and references</a></li>
</ul>
<hr />
<h2 id="introduction">Introduction</h2>
<p>The firmware on the EEPROM supports connecting to SPI devices. This is implemented in software and does not require any additional hardware.</p>
<p>Demonstration videos on Vimeo of:</p>
<ul>
<li><a href="https://vimeo.com/685664548">7-segment display</a></li>
<li><a href="https://vimeo.com/685666821">8x8 dot matrix display</a></li>
</ul>
<hr />
<h2 id="about">About SPI</h2>
<p>See:</p>
<ul>
<li><a href="https://en.wikipedia.org/wiki/Serial_Peripheral_Interface">Serial Peripheral Interface - Wikipedia</a></li>
<li><a href="https://www.gammon.com.au/spi">My tutorial about SPI</a></li>
</ul>
<p>SPI is commonly used in many devices such as port-expanders like the MCP23S17, micro SD cards, 7-segment and 8x8 matrix displays using the MAX7219 chip, and many others.</p>
<p>Screen capture of the logic analyzer while sending data to the MAX7219 chip (open image in new tab for more detail).</p>
<p><img src="images/spi%20example.png" /></p>
<p>SPI uses four signal lines (plus power and ground) as follows:</p>
<ul>
<li>SS (slave select)</li>
<li>MOSI (master out, slave in)</li>
<li>MISO (master in, slave out)</li>
<li>SCK (serial clock)</li>
</ul>
<p>Three of them (SS, MOSI, SCK) are outputs from the master, and one is an input from the slave. In this implementation the breadboard computer is considered to be the master.</p>
<p>Note that on some devices the signals are labelled slightly differently:</p>
<ul>
<li>MOSI can be called SIN (serial in), DIN (data in) or DI (data in)</li>
<li>SS can be called CS (chip select)</li>
<li>SCK can be called CLK (clock)</li>
</ul>
<p><img src="images/SPI%20signals%20-%20full.png" /></p>
<p>Some devices, like the MAX7219 chips used on LED displays do not output anything, so MISO can be omitted, like this:</p>
<p><img src="images/SPI%20signals%20-%20one%20way.png" /></p>
<p>There are four clock and sampling modes used by SPI, where mode 0 is the most common I have seen:</p>
<p><img src="images/SPI%20modes.png" /></p>
<hr />
<h2 id="wiring">Wiring</h2>
<p>I have used VIA ports PB0, PB1, PB2 and PB3. On Ben’s original board they were connected to the LCD display, however since I rewrote the LCD code to use only a 4-bit interface those pins are now free. So, first disconnect those ports from the LCD. That is VIA pins 10, 11, 12 and 13.</p>
<p>The code expects you to connect:</p>
<ul>
<li>SS (slave select) to PB0 on the 6522 VIA chip (that is, pin 10 on the chip); and</li>
<li>MOSI (master out, slave in) to PB1 on the 6522 VIA chip (that is, pin 11 on the chip)</li>
<li>MISO (master in, slave out) to PB2 on the 6522 VIA chip (that is, pin 12 on the chip); and</li>
<li>SCK (serial clock) to PB3 on the 6522 VIA chip (that is, pin 13 on the chip)</li>
</ul>
<hr />
<h2 id="api">Code API</h2>
<p>The firmware on the EEPROM has five exposed functions (subroutines) you can call, plus a pointer to a character-code table:</p>
<h3 id="spi_init">spi_init</h3>
<p>This initialises the VIA chip ready for SPI communications. You should load the mode (described above) into the A register before calling this. It sets SS, MOSI, and SCK to be outputs and MISO to be an input. It also sets the clock (SCK) and slave select (SS) to the correct levels. The clock is normally low in mode 0, and slave select is normally high.</p>
<p>Example:</p>
<pre><code> lda #0 ; mode zero
jsr spi_init</code></pre>
<h3 id="spi_transfer">spi_transfer</h3>
<p>This transfers one byte from the master to the slave, and simultaneously receives one byte from the slave. The byte to be sent is placed in the A register. After the transfer the byte which has been received is in the A register. The X and Y registers are preserved.</p>
<p>Example:</p>
<pre><code> lda #42
jsr spi_transfer ; send 42 to the device
sta foo ; any incoming data from the device is now in A</code></pre>
<h3 id="spi_ss_low">spi_ss_low</h3>
<p>This sets SS (slave/chip select) to low, which is the normal way of telling the slave that you are about to communicate with it. All registers are preserved.</p>
<h3 id="spi_ss_high">spi_ss_high</h3>
<p>This sets SS (slave/chip select) to high, which is the normal way of ending a session with the slave. All registers are preserved.</p>
<h3 id="spi_send_two_bytes">spi_send_two_bytes</h3>
<p>This sends two bytes to the slave. The first byte is in A, and the second byte in X. All registers are preserved.</p>
<p>This functionally is the same as:</p>
<pre><code>spi_send_two_bytes:
pha
jsr spi_ss_low ; SS low
jsr spi_transfer ; send first byte
txa ; get second byte
jsr spi_transfer ; send second byte
jsr spi_ss_high ; SS high again
pla
rts</code></pre>
<p>This is a useful helper function. Chips often expect you to send a register number first, followed by the value to put into that register.</p>
<p>Example:</p>
<pre><code> lda #MAX7219_REG_INTENSITY ; character intensity: range: 0 to 15
ldx #7 ; intensity 7
jsr spi_send_two_bytes</code></pre>
<h3 id="cp437_font">cp437_font</h3>
<p>This is a 2k chunk of memory in the EEPROM with the character encoding for the CP437 font.</p>
<p>This looks like this:</p>
<p><img src="images/cp437_fonts.png" /></p>
<p>This is very useful if you want to draw characters on a 8x8 dot matrix display, as putting the font data into your code could easily exceed your available RAM for your source.</p>
<p>The example file <a href="examples/asm/8x8%20matrix%20test.asm">Driving an 8x8 matrix display</a> shows you to use this font data. Basically each byte that can be displayed (from 0x00 to 0xFF) takes up 8 bytes of font data (one for each line of the display, therefore 8 bytes x 8 bits = 64 pixels).</p>
<p>Although this is a lot of memory devoted to a font you may not use, the EEPROM is there anyway, so it may as well have the font data in it. If you are recompiling the assembler source with your own code, and running out of memory, simply disable the inclusion of the font data. In other words, in gpascal.asm change:</p>
<pre><code>USE_CP437_FONT = 1</code></pre>
<p>to:</p>
<pre><code>USE_CP437_FONT = 0</code></pre>
<hr />
<h2 id="examples">Example code</h2>
<ul>
<li><a href="examples/asm/spi_7_segment_display.asm">7 segment display example</a></li>
<li><a href="examples/asm/spi_and_i2c_demo.asm">SPI and I2C together</a></li>
<li><a href="examples/asm/8x8%20matrix%20test.asm">Driving an 8x8 matrix display</a></li>
</ul>
<hr />
<h2 id="credits">Credits and references</h2>
<ul>
<li><a href="https://en.wikipedia.org/wiki/Serial_Peripheral_Interface">Serial Peripheral Interface - Wikipedia</a></li>
<li><a href="https://www.gammon.com.au/spi">My tutorial about SPI</a></li>
<li><a href="https://www.gammon.com.au/forum/?id=11516">Interfacing LED displays with the MAX7219 driver</a></li>
<li><a href="https://www.gammon.com.au/forum/?id=10940">Connecting a graphical LCD via a I2C/SPI using a 16-bit port expander</a></li>
</ul>
<hr />
<div class="quick_link">
<a href="index.htm">Back to main G-Pascal page</a>
</div>
<div class="quick_link">
<a href="i2c.htm">I<sup>2</sup>C support</a>
</div>
<hr />
<h2 id="license">License</h2>
<p>Information and images on this site are licensed under the <a href="https://creativecommons.org/licenses/by/3.0/au/">Creative Commons Attribution 3.0 Australia License</a> unless stated otherwise.</p>
</body>
</html>