1 Introduction
2 ------------
3
4 The ArduinoAm29F010 project provides software and a circuit to program
5 Am29F010 flash memory devices using an Arduino board (tested with the Arduino
6 Duemilanove, but likely to work with the Arduino Uno and directly-related
7 boards). In addition, guidance about the use of such flash memory devices is
8 provided for use with microcomputer systems, such as the Acorn Electron and
9 BBC Microcomputer range.
10
11 The Am29F010-90PC product has been used to test the software and hardware
12 design described here. The PDIP variant of the device, as opposed to the
13 various other packages employed in the product range, is the variant most
14 suitable for use with the Arduino.
15
16 It is attractive to try and use such flash memory devices as an alternative to
17 EPROM devices, mostly for the practicality and increased convenience involved
18 in programming them, needing only a suitably-wired circuit and conventional
19 microcomputer/microcontroller voltage levels. It is also interesting to try
20 and make the extra space provided by such devices available to the systems in
21 which they will be deployed.
22
23 Contact, Copyright and Licence Information
24 ------------------------------------------
25
26 The author can be contacted at the following e-mail address:
27
28 paul@boddie.org.uk
29
30 Copyright and licence information can be found in the docs directory - see
31 docs/COPYING.txt and docs/gpl-3.0.txt for more information.
32
33
34
35 Using the Software
36 ==================
37
38 First of all, to use the Arduino-based programming solution, the Arduino needs
39 to have a program transferred to it. The program is compiled using the
40 Makefile provided, using the simple command...
41
42 make
43
44 To upload the program, the "upload" target is used as follows:
45
46 make upload
47
48 It is likely that this will fail unless appropriate permissions are available
49 on the device through which the Arduino is accessed on the host machine. Thus,
50 a privileged invocation is likely to be necessary:
51
52 sudo make upload
53
54 Configuring the Software
55 ------------------------
56
57 By default, the software is configured for a circuit using 74HC273 flip-flop
58 integrated circuits. In the Makefile, the CIRCUIT variable is set as follows:
59
60 CIRCUIT = 74HC273
61
62 To change this to support 74HC595 shift register integrated circuits, the
63 variable is set as follows:
64
65 CIRCUIT = 74HC595
66
67 Clean the generated files and run make again after reconfiguring:
68
69 make clean && make
70
71 Testing the Program
72 -------------------
73
74 With the program uploaded, it should now be possible to communicate with the
75 Arduino. Unless the programming circuit has been constructed, however, there
76 will not be any effect of communicating with the Arduino, other than to check
77 that the program is operational. Running the upload.py script as follows will
78 permit such a test:
79
80 ./upload.py -i
81
82 Again, it is likely that this will need to be run in a privileged fashion as
83 follows:
84
85 sudo ./upload.py -i
86
87 The script should act as a terminal, showing a ">" prompt that can accept
88 various commands. Merely getting the prompt should be enough of an indication
89 that the program is functioning on the device.
90
91 Issuing read commands permits the testing of addresses in the device:
92
93 location sector
94 R00000 0x0000 0 (the first location in the device)
95 R07fff 0x7fff 1 (the final location in sector 1)
96 R10000 0x10000 4 (the first location in sector 4)
97 R1ffff 0x1ffff 7 (the final location in the device)
98
99 Uploading and Testing Images
100 ----------------------------
101
102 Once the programming circuit has been constructed (see "Arduino Interfacing"
103 below), the upload.py script can be used to upload data to the Am29F010
104 device. For example:
105
106 sudo ./upload.py jungle.rom
107
108 This will take jungle.rom and write it to the first sector of the Am29F010. To
109 verify the operation, the following command can be used:
110
111 sudo ./upload.py -v jungle.rom
112
113 To write to other sectors, an option can be specified. For example:
114
115 sudo ./upload.py -s 1 junglecode.rom
116
117 Again, the operation can be verified as follows:
118
119 sudo ./upload.py -s 1 -v junglecode.rom
120
121 Note that the -s option must appear first.
122
123 The upload.py script can accept multiple files and will write each of them to
124 consecutive sectors. However, it can be more prudent to write files
125 individually, especially if the circuit is behaving in a less than completely
126 reliable fashion.
127
128 A Note on Sectors
129 -----------------
130
131 Each sector is 16 kilobytes long, which corresponds to a 14-bit address range
132 (0x0000 to 0x3FFF). The Arduino interface described below supports 17-bit
133 addressing (A0...A16), permitting access to eight sectors (at 0x0000, 0x4000,
134 0x8000, 0xC000, 0x10000, 0x14000, 0x18000 and 0x1C000). The simple mapping from
135 a ROM cartridge to the device leaves A16 grounded and thus unable to access the
136 upper four sectors in the device. However, A16 could be connected to VCC to
137 access the upper four sectors.
138
139
140
141 Making a Printed Circuit Board
142 ==============================
143
144 The pcb directory contains resources for making a PCB with the Fritzing
145 software. In order to track changes in these resources, they have been
146 unpacked from a file saved by Fritzing, and so must be packed together into
147 such a file before being given to Fritzing. This can be done using a script
148 provided:
149
150 ./make_pcb.sh
151
152 This will produce a file called ArduinoAm29F010-arduinouno.fzz containing the
153 resources in a zip archive as Fritzing expects.
154
155 This PCB is featured as a project on the Fritzing Web site:
156
157 http://fritzing.org/projects/arduino-am29f010-programming-shield
158
159
160
161 Device Compatibility
162 ====================
163
164 For use with an Acorn Electron ROM cartridge or other board providing a ROM
165 socket, the compatibility of the Am29F010 needs to be assessed in the context
166 of the ROM sockets likely to be provided.
167
168 Original ROM Pinout Am29F010 Pinout
169 ------------------- ---------------
170
171 1 \/ 32 VCC
172 A16 2 31 WE#
173 1 \/ 28 VCC A15 3 30
174 A12 2 27 A14 A12 4 29 A14
175 A7 3 26 A13 A7 5 28 A13
176 A6 4 25 A8 A6 6 27 A8
177 A5 5 24 A9 A5 7 26 A9
178 A4 6 23 A11 A4 8 25 A11
179 A3 7 22 OE# A3 9 24 OE#
180 A2 8 21 A10 A2 10 23 A10
181 A1 9 20 CS# A1 11 22 CE#
182 A0 10 19 D7 A0 12 21 DQ7
183 D0 11 18 D6 DQ0 13 20 DQ6
184 D1 12 17 D5 DQ1 14 19 DQ5
185 D2 13 16 D4 DQ2 15 18 DQ4
186 GND 14 15 D3 GND/VSS 16 17 DQ3
187
188 Superimposing the Am29F010 onto a ROM socket would provide compatibility for
189 all pins from A12 to GND/VSS and from A14 to D3/DQ3.
190
191 Pin 1 in a ROM socket would correspond to A15 but is not necessarily
192 connected, nor, perhaps, is A14 since only 14 bits are required to address 16
193 kilobytes, although there may be 32 kilobyte sockets connecting A14 and using
194 15 bits to address 32K. A16 and A15 would probably be connected to ground to
195 ensure correct operation, but could also be wired to a selection mechanism so
196 that the entire contents of the flash memory might be exposed.
197
198 Pin 28 in a ROM socket would provide power, but the corresponding pin 30 on an
199 Am29F010 is not connected. Thus pin 30 would need routing to pin 32 for the
200 flash device socket.
201
202 Pin 31 for the Am29F010 would need to be asserted. Thus pin 30 might also be
203 routed to pin 31, so that the device would remain read-only at all times.
204
205 Dual ROM Adapter Usage
206 ======================
207
208 A single Am29F010 device could be wired to two ROM sockets in order to provide
209 data to both. The above wiring guide would be employed, with connections from
210 both sockets being connected to the Am29F010, but additional logic would be
211 required for the CS# signals originating from the sockets in order to expose
212 the appropriate region of flash memory. ROM #1 would be served by a "lower"
213 16K region; ROM #2 would be served by an "upper" 16K region; A14 would be used
214 to switch between these regions.
215
216 When ROM #1's CS# signal is low, an attempt to read from ROM #1 would be
217 occurring, and thus A14 would be held low. And when ROM #2's CS# signal is
218 low, an attempt to read from ROM #2 would be occurring, and thus A14 would be
219 held high.
220
221 Meanwhile, the CS# signal for the two ROM sockets would need to be combined to
222 produce a resultant CE# signal for the Am29F010.
223
224 ROM #1 CS# ROM #2 CS# Am29F010 A14 Am29F010 CE#
225 ---------- ---------- ------------ ------------
226 0 0 Not defined Not defined
227 0 1 0 0
228 1 0 1 0
229 1 1 Not defined 1
230
231 It might therefore be possible to connect A14 to ROM #1's CS# signal. And the
232 resultant CE# signal could be the product of an AND gate:
233
234 Am29F010 CE# = ROM #1 CS# AND ROM #2 CS#
235
236 Wiring Details
237 --------------
238
239 ROM #1 ROM #2 74HC08 Am29F010
240 ------ ------ ------ --------
241 CS# 1A A14
242 CS# 1B
243 1Y CE#
244 OE# OE#
245
246 ROM (Common) 74HC08 Am29F010
247 ------------ ------ --------
248 VCC VCC
249 GND GND
250 VCC VCC
251 VCC WE#
252 D0 DQ0
253 D1 DQ1
254 D2 DQ2
255 D3 DQ3
256 D4 DQ4
257 D5 DQ5
258 D6 DQ6
259 D7 DQ7
260 A0 A0
261 A1 A1
262 A2 A2
263 A3 A3
264 A4 A4
265 A5 A5
266 A6 A6
267 A7 A7
268 A8 A8
269 A9 A9
270 A10 A10
271 A11 A11
272 A12 A12
273 A13 A13
274 GND A15
275 GND A16
276 GND GND
277
278 Note that A15 and A16 are left grounded, effectively exposing only the first
279 two sectors of the device. By connecting either or both of these to VCC, other
280 pairs of sectors can be manually selected. A mechanism could also be devised
281 to allow selection using logic, but this is not explored here.
282
283
284
285 Arduino Interfacing
286 ===================
287
288 Arduino can employ at most 14 digital pins (plus 5 switchable analogue pins),
289 whereas the Am29F010B requires 17 address pins, 8 data pins, plus 3 control
290 pins to be utilised. (Note that digital pin 13 also drives an LED and pins 0
291 and 1 are unavailable if the serial interface is being used.)
292
293 Using 74HC273 Flip-Flops
294 ------------------------
295
296 One solution is to map the 3 control pins directly to the Arduino, then to
297 channel addresses and data via 8 common pins, with addresses being stored in
298 latches or flip-flops, and then to employ two remaining pins to control the
299 latches. When neither latch is selected, the data pins will be used to read or
300 write data from the flash memory.
301
302 In this scheme, A16 must be directly controlled by an additional pin, separate
303 from the latch-based mechanism. As a result, only 14 pins are needed on the
304 Arduino.
305
306 74HC273 Pinout
307 --------------
308
309 MR# 1 \/ 20 VCC
310 Q0 2 19 Q7
311 D0 3 18 D7
312 D1 4 17 D6
313 Q1 5 16 Q6
314 Q2 6 15 Q5
315 D2 7 14 D5
316 D3 8 13 D4
317 Q3 9 12 Q4
318 GND 10 11 CP
319
320 Arduino 74HC273 #1 74HC273 #2 Am29F010
321 ------- ---------- ---------- --------
322 A5 CE#
323 A4 OE#
324 A3 WE#
325 2 CP
326 3 CP
327 4 D3 D3 DQ3
328 5 D2 D2 DQ2
329 6 D1 D1 DQ1
330 7 D0 D0 DQ0
331 8 D4 D4 DQ4
332 9 D5 D5 DQ5
333 10 D6 D6 DQ6
334 11 D7 D7 DQ7
335 Q0 A0
336 Q1 A1
337 Q2 A2
338 Q3 A3
339 Q4 A4
340 Q5 A5
341 Q6 A6
342 Q7 A7
343 Q0 A8
344 Q1 A9
345 Q2 A10
346 Q3 A11
347 Q4 A12
348 Q5 A13
349 Q6 A14
350 Q7 A15
351 A2 A16
352 5V MR# MR#
353 5V VCC VCC VCC
354 GND GND GND VSS
355
356 Set Address
357 -----------
358
359 74HC273 #1 CP = 1; 74HC273 #2 CP = 0
360 74HC273 #1 D[7...0] = A[7...0]
361 74HC273 #1 CP = 0; 74HC273 #2 CP = 1
362 74HC273 #2 D[7...0] = A[15...8]
363 Am29F010 A16 = A[16]
364
365 Write Data
366 ----------
367
368 Configure pins as D[7...0]
369 WE# = 0
370 74HC273 #1 CP = 0; 74HC273 #2 CP = 0
371 74HC273 #3 D[7...0] = D[7...0]
372 WE# = 1
373
374 Read Data
375 ---------
376
377 Configure pins as Q[7...0]
378 OE# = 0
379 74HC273 #1 CP = 1; 74HC273 #2 CP = 0
380 Q[7...0] = 74HC273 #0 Q[7...0]
381 OE# = 1
382
383 Using 74HC595 Shift Registers
384 -----------------------------
385
386 Another solution is to map the 3 control pins directly to the Arduino, then to
387 channel addresses via a single pin to a pair of shift registers, and then
388 employ two remaining pins to control the shift registers. Eight separate data
389 pins will be used to read or write data from the flash memory.
390
391 In this scheme, A16 must be directly controlled by an additional pin, separate
392 from the shift-register-based mechanism. As a result, only 15 pins are needed
393 on the Arduino.
394
395 74HC595 Pinout
396 --------------
397
398 QB 1 \/ 16 VCC
399 QC 2 15 QA
400 QD 3 14 SI
401 QE 4 13 G#
402 QF 5 12 RCK
403 QG 6 11 SCK
404 QH 7 10 SCLR#
405 GND 8 9 QH'
406
407 Arduino 74HC595#1 74HC595#2 Am29F010
408 ------- --------- --------- --------
409 A5 CE#
410 A4 OE#
411 A3 WE#
412 2 SCK SCK
413 3 RCK RCK
414 4 DQ3
415 5 DQ2
416 6 DQ1
417 7 DQ0
418 8 DQ4
419 9 DQ5
420 10 DQ6
421 11 DQ7
422 12 SI
423 QA A0
424 QB A1
425 QC A2
426 QD A3
427 QE A4
428 QF A5
429 QG A6
430 QH A7
431 QA A8
432 QB A9
433 QC A10
434 QD A11
435 QE A12
436 QF A13
437 QG A14
438 QH A15
439 A2 A16
440 5V SCLR# SCLR#
441 5V VCC VCC VCC
442 GND G# G#
443 GND GND GND VSS
444
445 Pins
446 ====
447
448 A0-A16 17-bit addressing
449 DQ0-DQ7 8-bit data transfer
450 CE# chip enable
451 OE# output enable
452 WE# write enable
453 VCC 5V
454 VSS ground
455 NC (not connected)
456
457
458
459 Technical Notes
460 ===============
461
462 Information about the operation of the Am29F010 device can be gained from a
463 perusal of the datasheet, and a summary of some of the pertinent details can
464 be found below.
465
466 Low-Level Operations
467 --------------------
468
469 CE# high standby
470 CE# low read, write or output disable
471
472 OE# high, WE# high output disable
473 OE# low, WE# high read
474 OE# high, WE# low write
475
476 Thus, for reading and writing:
477
478 OE# = not WE#
479
480 Timing
481 ------
482
483 According to the datasheet, addresses are latched on the falling edge of the
484 latest of WE# and CE#, data is latched on the rising edge of the latest of WE#
485 and CE#.
486
487 Strategy:
488
489 1. Start with CE#, OE#, WE# high (standby, output disable)
490 2. Bring CE# low (output disable)
491 3. Set addresses
492 4. Bring WE# or OE# low for operation (write or read)
493 5. Read or write data
494 6. Bring WE# or OE# high (output disable)
495
496 Operation Modes
497 ---------------
498
499 By default, the device is in read mode, meaning that merely bringing OE# low
500 will produce data for the asserted address.
501
502 To issue commands to change the mode involves write operations with specific
503 address and data arguments.
504
505 Sectors
506 --------
507
508 A[16...14] selects each 16KB sector and is referred to as the sector address
509 or SA in the documentation.
510
511 Commands
512 --------
513
514 Reset (A=$5555; D=$AA); (A=$2AAA; D=$55); (A=$5555; D=$F0)
515
516 Autoselect (manufacturer) (A=$5555; D=$AA); (A=$2AAA; D=$55); (A=$5555; D=$90);
517 (A=$X00; read)
518 => D=$01
519
520 Autoselect (device) (A=$5555; D=$AA); (A=$2AAA; D=$55); (A=$5555; D=$90);
521 (A=$X01; read)
522 => D=$20
523
524 Simple reset (A=$XXXX; D=$F0)
525
526 Sector erase (A=$5555; D=$AA); (A=$2AAA; D=$55); (A=$5555; D=$80);
527 (A=$5555; D=$AA); (A=$2AAA; D=$55); (A=SA; D=$30)
528
529 Program (A=$5555; D=$AA); (A=$2AAA; D=$55); (A=$5555; D=$A0);
530 (A=PA; D=PD)
531
532 Note that A16 is held low when issuing the constant addresses in the above
533 commands.
534
535 Progress
536 --------
537
538 Programming and erasure commands employ data pins as follows:
539
540 Programming Erasure
541 DQ7 On completion: DQ7-out On completion: 1
542 DQ6 During: toggling value During: toggling value
543 DQ5 On failure: 1 On failure: 1
544 DQ3 Sector erase begun: 1
545
546 A read operation is required to obtain these outputs, typically with the same
547 address used to initiate each operation. The algorithm described in the
548 datasheet that tests DQ7 and DQ5 is employed to determine whether an operation
549 has completed. It should be noted that the toggling effect on DQ6 occurs from
550 read to read, not at some particular frequency.