1 \documentclass[a4paper]{article}
7 \title{Programming the AT89S8252 using SPI}
9 \author{Jelmer Vernooij}
13 Thanks to Hans Tjeerdsma for his help with understanding the datasheets and debugging
17 Copyright \copyright\ 2003 Jelmer Vernooij (jelmer@samba.org).
18 This documentation is distributed under the GNU General Public License (GPL) version 2 or later.
25 \section{Introduction}
27 The 8051 and 8052 microprocessors are very common processors. Quite some
28 manufacturers (among them are Intel, Atmel and Analog Devices) produce 8051
29 processors. Personally, I have experience with the Atmel and the Analog Devices
32 Atmel's 8051 processors can be programmed with two different protocols:
33 a parallel protocol that I will not discuss here, and the SPI protocol.
35 \section{Reasons for writing my own programmer}
37 There are several SPI programmers available for the Atmel 8051 series, however
38 only few of them are available for Linux, and none that I could find used
39 a serial port or had a GUI.
41 Available programmers (and reasons not to use them):
44 \item ponyprog --- has a GUI and is written in C++
45 \item 89prog --- uses the parallel port
46 \item sp89 --- uses the parallel port
47 \item atmel-isp --- only for windows, no source code available
50 And of course, figuring out the protocol with the help of a logic analyser and
51 some datasheets is a lot of fun...
53 \section{The way other manufacturers do it}
55 Previously, for my work, I have written a programmer for Analog Devices
56 8051. Their protocol is quite a bit better since it uses the standard RS232
57 protocol. Something that also helps is the fact that their microcontroller
58 acknowledges or (refuses) commands it gets, while with the AT89 processors,
59 you just have to guess that the processor understood what you wanted.
61 Next to that, Analog Devices provided an example program that could be
62 used to program the microcontroller of the serial port.
64 \section{Other data lines used by the Atmel}
66 Next to the lines necessary for SPI, there is another used for putting
67 the processor in programmable mode:
70 \item[RST] Reset. Used to put microprocessor in programmable state. Also used to restart running program (by toggling). (Connected to DTR on my board)
73 My own circuit board has uses an additional port that is used to confirm
74 that CHK has been set.
76 When the RST port on the 8051 has been set, the processor listens for SPI
77 input and handles incoming data.
79 \section{The SPI protocol}
81 So, what is SPI? SPI is a very simple serial data protocol. This means
82 that bytes are send serially instead of parallel. SPI is a standard protocol
83 that is used mainly in embedded devices. It falls in the same family as
86 As can be read in Atmel's datasheets (document 0401 to be precise),
87 the SPI protocol uses 3 lines:
90 \item[MOSI] {\em (Master Out, Slave In)} Data line, in my case sitting on the TxD of my serial port
91 \item[MISO] {\em (Master In, Slave Out)} Data line, controlled by client. (In my case on CTS)
92 \item[SCK] The Clock (in my case on RTS of the serial port)
95 \subsection{How does SPI work?}
97 The SPI works with two parties: the slave and the master. The master controls
98 the line. In my case the personal computer is the master and the 8051 is
99 the slave. There is another data line ({\em Slave Select}) that is used to select
100 who the slave is, but I didn't need to use that bit.
102 The master sets a bit on the {\em MOSI} and then generates a clock pulse, after
103 which the next bit is set and another clock pulse is generated, etc.
106 \caption{Sending the bit pattern $0011 0100$ using SPI}
108 \includegraphics{SPI1}
111 A clock pulse is generated by simply setting the {\em SCK} bit high and then low
112 again after a few microseconds.
114 Here is my {\em SPI\_Out} function:
121 for(i = 7; i >= 0; i--) {
122 if(b & (1 << i)) SetMOSI();
134 Reading data from the slave is done in a similar way. The server requests
135 data from the slave, after which it generates clock pulses on which the slave
138 My {\em SPI\_In} function:
144 for(i = 7; i >= 0; i--) {
147 if(GetMISO())b |= 1 << i;
156 That's basically all that SPI does. It's that simple!
158 \section{AT89* commands}
160 This section describes the various commands that can be sent
161 to the 8051 over SPI when it's {\em RST} bit is set.
163 \subsection{Enabling program modus}
165 Before the 8051 accepts any commands, it needs to be put into command mode.
166 That's what this command is for. Always run this command before you
167 run any other command.
172 /* Send enable serial instruction to MOSI */
173 SPI_Out(0xAC); /* 1010 1100 */
174 SPI_Out(0x53); /* 0101 0011 */
175 SPI_Out(0x00); /* xxxx xxxx (don't care) */
180 \subsection{Erasing code and data memory}
185 SPI_Out(0xAC); /* 1010 1100 */
186 SPI_Out(0x04); /* xxxx x100 (x = don't care) */
187 SPI_Out(0x00); /* xxxx xxxx (don't care) */
193 \subsection{Writing data to code memory}
196 void writecode(int addr, char b)
199 SPI_Out(0x02 | ((addr >> 5) & 0xF8) | ((addr >> 11) & 0x04));
200 SPI_Out(addr & 0xFF); /* llll llll */
206 \subsection{Reading from code memory}
209 int readcode(int addr)
212 SPI_Out(0x01 | ((addr >> 5) & 0xF8) | ((addr >> 11) & 0x04));
213 SPI_Out(addr & 0xFF); /* llll llll */
218 \subsection{Writing to data memory}
221 void writedata(int addr, char b)
223 SPI_Out(0x06 | ((addr >> 5) & 0xF8));
224 SPI_Out(addr & 0xFF); /* llll llll */
229 \subsection{Reading from data memory}
231 int readdata(int addr)
234 SPI_Out(0x05 | ((addr >> 5) & 0xF8));
235 SPI_Out(addr & 0xFF); /* llll llll */
240 \subsection{Locking memory}
245 int mask = 0xff & ~byte;
247 SPI_Out(0xAC); /* 1010 1100 */
248 SPI_Out(mask | 0x07); /* pqrx x111 */
249 SPI_Out(0); /* xxxx xxxx */
256 These are some random tips that might be useful when you are interested in
257 implementing the SPI protocol or the 8051 programming that is running over it.
260 \item Make sure you clear and set the RST line in
261 the beginning of your program
262 \item Make sure you wait long enough between clock pulses and that
263 clock pulses are long enough
264 \item A logic analyser is very useful when debugging timing problems
269 \begin{thebibliography}{99}
270 \bibitem{} Atmel: AT89S8252 Datasheet, \emph{http://www.atmel.com/dyn/resources/prod\_documents/doc0401.pdf}
271 \bibitem{} Rob~Melby: Atmel 89 programmer, \emph{http://www.cc.gatech.edu/gvu/ccg/people/rob/software/89prog.tar.gz}
272 \end{thebibliography}