You are on page 1of 124

1

CHAPTER ONE
INTRODUCTION 1.1 OVERVIEW

It is really dazzling how digital systems have taken up the world of electronics. Virtually all electronic appliances and devices today are microprocessor or microcomputer based. Digital systems have indeed displaced the analog options in most fields. To the layman, all credit would go to the microprocessors for these great performances. But, little do we know about the co-operation of the microprocessors and memory. The microprocessors work hand in hand with appropriate memory devices to carry out its function. The microprocessor is a very powerful digital device but is indeed useless without a memory. Thus the usefulness of the memory in the digital world cannot be overemphasized. Apart from the system bus, the two main components of a microprocessor based system are the microprocessor and the memory. A microprocessor basically gets instructions to execute from a memory device and also uses another for its working space that is, a temporary storage space. Microprocessor based system design involves the programming of the microprocessor to be used. Programming a microprocessor may sound like the process of loading instructions into a microprocessor, but in the real sense, a memory is programmed for the microprocessor. So, designers of microprocessor systems face the problem of burning their codes into a memory chip. This project involves the utilization of the some basic principle acquired during the course of study in this institution to solve the problem of memory programming for digital systems design. A major advantage of digital systems over analog systems is their ability to easily store large quantities of digital information and data for short or long periods. This memory capability is what makes digital systems so versatile and adaptable to many situations.

2 1.2 MEMORY HIERARCHY Simply put, the term memory hierarchy refers to the ranking, ordering or arrangement of the various groups of memories in terms of their order of importance, cost, size and even access time. Figure 1 below shows the order of memories on the basis of the determinants above.

Register Cache Prima ry memory S econda ry memory T ertiary Memory

Figure 1: Memory Hierarchy

As can be seen from the figure above, registers are at the highest level of the memory hierarchy and the tertiary memories at the lowest level. Generally, capacity and access time decreases as you go up the hierarchy. Cost and importance of the memory increases as the hierarchy goes up.

1.2.1

Registers Registers are at the top of this hierarchy. They are usually situated on the same silicon real estate as the microprocessor. Because of the size of the silicon real estate, the register memory is the smallest in terms of capacity. Registers could be as small as 8 bits in size. They serve as temporary storage devices for the microprocessor. These memories are extensively used when the microprocessor is carrying out arithmetic and logical operations. They have the advantage of being the fastest in terms of their access time.

3 1.2.2 Cache The Cache memory comes after the register in the hierarchy. The cache is a small semiconductor memory that could be situated on the microprocessor (Level 1 cache) or outside the microprocessor (Level 2 cache). This is exactly what cache memory does for you. Cache memory sits between the CPU and main memory. It is a small amount of very fast memory. Unlike normal memory, the bytes appearing within a cache do not have fixed addresses. Instead, cache memory can reassign the address of a data object. This allows the system to keep recently accessed values in the cache.

1.2.3

Primary Memory Next on the hierarchy is the primary memory. This comprises essentially semi-conductor memories. The semi-conductor memory is made of an array of registers that are uniquely addressable. These memories include the Read Only Memory (ROM) and the Random Access Memory (RAM). The ROM is a non-volatile memory. It has the ability to retain its content even after the source of power has been removed. This is the reason why ROM is specifically used in applications where the data is permanent or will not change frequently.

1.2.4

Secondary Memory The secondary memory is essentially made of the magnetic storage. The hard disk fall into this level in the hierarchy. This device devices access time is slow compared to the previous three but it has the advantage of having the largest capacity of them all. It is at present the main permanent storage medium for computers. Though magnetic media could come in the form of either magnetic tape or disks, for microcomputers, tape storage is somewhat inconvenient as it is a serial access medium with very little parallelism. Therefore disk storage is preferred in many, but not all applications.

1.2.5

Tertiary Memory This is last in the memory hierarchy. This implies that they are the slowest and the least expensive. This class is basically comprised of all removable storage devices like the Flash disk, floppy disk, CDs, DVDs and even the Blue Laser.

1.2.6

The place of the EPROM The EPROM belongs to the class of primary memory. This implies a relatively moderate speed, fair cost and size and that the memory is of good importance. The EPROM falls into the highest memory class that is disposed to the user or system designer for use or programming. So, it was justified spending a great deal of time and resources in the development of an EPROM programmer.

1.3

SYSTEM DESIGN OBJECTIVE In the early part of this chapter, the introduction to be specific, it was stated that one of the challenges faced by a digital system designer is the means of writing data onto a nonvolatile memory device. Bearing this in mind, we structured our objectives towards implementing and designing a system that could solve this problem. This design was carried out with the following objectives in mind.

(1) To design a circuit that meets the demands of the hardware requirements for the programming of the EPROM chip (The 27C64). (2) To demonstrate proficiency in computer interfacing by interfacing the circuit with the microcomputer such that they can communicate effectively. (3) To develop the software driver for this hardware circuit. The software is to act as an interface between the user (human) and the entire software and hardware system. (4) This software driver should have two basic functionalities. Primarily, the software driver should be able to write desired data to specified locations in the EPROM chip. (5) This software driver should have the capability to read data from specified locations or address range on the EPROM chip. (6) The software should be able to create data files where the contents read from the EPROM could be saved.

5 1.4 INTERFACING TECHNIQUES Peripheral devices are usually external to the computer systems internal bus. They are devices with no direct connection to the system bus. Printers, mice, video cameras, scanners, data/fax modems, plotters and lots of other peripheral devices exist. Unfortunately, their existence is beyond the confines of the desktop or server machine. We need a way to reach out to them. The process we undergo in order to reach out to them is called interfacing. In the computer world, a port is a set of signal lines that the microprocessor, or CPU, uses to exchange data with other components especially peripheral devices. Most computer ports are digital, where each signal, or bit, is either a 0 or a 1. A parallel port transfers multiple bits at once, while a serial port transfers a bit at a time. This is the basic difference between the serial port and the parallel port though the serial port can transfer data in both directions simultaneously. Interfacing external devices to the computer could be achieved either through the serial port, the parallel port or even the USB port of the computer.

The Serial Port is relatively harder to interface than the Parallel Port. Generally, serial transmission and reception of data involves and requires complex circuitry. Any device connected to the serial port will have its data converted to a serial form before transmission and then back to its parallel format after reception. This can be done using a Universal Asynchronous Receiver/Transmitter (UART). The Parallel Port is the most commonly used port for interfacing home made projects. This port will allow the input of up to 9 bits or the output of 12 bits at any one given time, thus requiring minimal external circuitry to implement many simpler tasks. The port is composed of 4 control lines, 5 status lines and 8 data lines. It's found commonly on the back of your PC as a D-Type 25 Pin female connector.

The parallel port of the computer is the option chosen for the interfacing of the EPROM programmer circuit to the computer system. This is due to some reasons such as its wide availability, its ease of interfacing and the timing of the project.

6 CHAPTER TWO FUNDAMENTAL CONCEPTS

2.1

THE CONCEPT OF MEMORY

In the digital sense, a memory is basically a group of registers capable of holding binary values for a given period of time and under specific conditions. In other words, a memory device is a storage device and is made up of a storage medium which could either be a magnetic, optical or a semiconductor medium. Magnetic media are generally capable of storing larger quantities of data than semiconductor memories, but the access time (time it takes to locate, then read or write data) is usually much more for magnetic devices. Optical media memories such as compact discs (CDs) and digital versatile discs (DVDs) uses crystal alloys to hold data and optical means (light rays) to read data from and write data onto the media. Semiconductor memories are at the higher level of the memory hierarchy. They are the fastest, smallest in size and capacity and most expensive. Despite the cost issue, they have really being of great significance in the enhancement of the performance of digital systems. The cache semiconductor memory is a very good acceleration technique used in increasing the speed of microprocessor systems. Also, in computer systems, the microprocessor does not work directly with the hard disk because of the significant difference in their speed of operation. Current research on semiconductors promises that semiconductor memories would replace the hard disk drives in computer systems in the near future. In this write-up, attention is only given to semiconductor memories because of their increasing significance and the scope of this project.

7 2.2 DEFINITION OF SOME BASIC TERMS Memory: A group of registers capable of holding binary values for a given period of time. Memory cell: The smallest division of a memory circuit or integrated circuit. It contains a single bit of data (1 or 0) Access Time: This is the time it takes to read the memory device. It is the time interval between the appearance of address on the address inputs of the memory and the appearance of data on the data output. Bus: A group of conduction lines performing the same function. Byte: 8 bits of data Nibble: 4 bits of data.

2.3

EXTERNAL ARCHITECTURE OF SEMICONDUCTOR MEMORIES

In digital systems, a memory system is made up of addressable locations. The concept of addressing is such that the memory has some subunits known as memory locations within it. These subunits are all capable of holding binary data. So, data can be written to the memory location one at a time. Each location can be selected by placing a unique identifying bit combination on the address bus.

Generally, a memory has three main connections to the digital circuit in which it is embedded in apart form its power supply and ground connections. These connections are in the form of buses or lines and are as below:

2.3.1

The Address connections

All memory devices have address input that select a memory location within the memory device. This is made up of a group of connection lines to the memory system that carry bits used in the selection of a memory location. These connections are always unidirectional, pointing into the memory. Address inputs are always labeled from A0 to

8 An (where A0 is the LSB and An the MSB). The subscript n can be any value but is always one less than the total number of address pins. For example, a memory device with 10 address pins has its address labeled from A0 to A9.

Figure 2.1: Common external features of a semiconductor memory chip The capacity of a memory device is related to the number of address selection bits by the number of locations being equal to the value of the expression 2n. That is, Memory capacity = 2n = 2(number of address bits)

This implies that a byte organized memory device of capacity 1Kilobyte (1024 bytes) has 10 address bits because 1024 = 210 It implies that n = 10

2.3.2

The Data bus:

The data bus is a group of connection that carries binary data values to and fro the memory systems. They are bidirectional for programmable memories and unidirectional for non-programmable memories. Data pins on memory devices are labeled D0 through D7 for an 8-bit-wide memory device. In this sample device, there are eight I/O connections, which means that the memory devices stores eight bits of data in each of its memory locations. An 8-bit-wide memory device is often tagged byte-wide-memory.

9 Catalog listings of memory devices often refer memory capacity as the number of memory locations by the bits per location. For example, an 8K memory locations and eight bits in each location is often listed as an 8K x 8-bit.

2.3.3

The control bus:

The control bus is made up of a group of connections to the memory device that carry control information to the memory chip. For most semiconductor memories, the control signals mostly used are the chip select (CS), the output enable (OE) the read (RD) and the write (WR) signals. The control signals determines which of the memory devices is active at a particular time and also tells the active memory what action to be performed at that instant. The chip select makes the memory chip active, the output enable activates the memorys output buffer. Output enable is mostly used to eliminate or avoid bus contention. The read and write operation specifies if data is to be read off the memory chip or written into it.

2.4

SEMICONDUCTOR MEMORY CLASSIFICATIONS In digital systems, memory circuits provide means of storing data on a temporary or permanent basis for future recall. The memories available for use can be classified into two broad categories: volatile and nonvolatile. Volatile memory loses its contents when power is turned off. Nonvolatile memory retains its contents indefinitely, even when there is no power present. Nonvolatile memory can be used to hold the boot code for a computer so that the microprocessor can have a place to get started. Once a microprocessor system is turned on, by default, it initializes by searching for the bootstrap from a nonvolatile memory at a specified address. The bootstrap contains the pointing address to the memory location from which the main program can be read. Volatile memory is used to store dynamic variables, including the stack and other programs that may be loaded from a disk drive. The figure below shows the semiconductor memory classification

10

Figure 2.2: semiconductor memory classification

As stated above, semiconductor memories are broadly classified into two main categories which are the Random Access Memory (RAM- Volatile) and the Read Only Memory (ROM- Non-volatile). Under the RAM are two subtypes, the Dynamic RAM and the Static RAM. The differences between these two are based on their structure and technology of storage. The ROM is also classified into two types which are the nonprogrammable (masked Rom) and the programmable ROM. The entire classes are discussed below. 2.4.1 The Random Access Memory (RAM) Random access memories are easily read from and written to by the microprocessor. They are mainly used as a working space by the microprocessor. The RAM is a Volatile memory and can also be classified into two subcategories: 2.4.1.1 Static RAM These are memory devices whose contents are nonvolatile for as long as power is applied. The RAM chips are generally used for temporary program storage after loading program from slower data drives and storage of variables. They are relatively very fast

11 both for reading and writing when compared with secondary memories. They also tend to be volatile in that as soon as power is removed, all of the data is lost. 2.4.1.2 Dynamic RAM These are memory devices whose contents require periodic refreshing to avoid loss of data even while power is present. On first thought, the category of dynamic devices may seem absurd. What possible benefit is there to a memory chip that cannot retain its memory without assistance? The benefit is significantly higher density of memory per unit silicon area, and hence lower cost of dynamic versus static memory. One downside to dynamic memory is somewhat increased system complexity to manage its periodic update requirement. 2.4.2 Read-Only Memories (ROM) Read-only memories are basically memory devices that are non-volatile. They do not lose their contents even when power is taken off. ROMs or Nonvolatile memories can be classified into two subcategories: Masked ROMs and Programmable ROMs 2.4.2.1 Masked ROM These are memory devices whose contents are programmed at a factory at the time of manufacture without the expectation of the data changing over time. Some ROMs can be programmed by the ROM manufacturer and then either sold off the shelf or supplied to electronic device manufacturers. For products requiring ROM code such as in a microwave or GameBoy, the code must be very stable and have bug-free operation because it will be impossible for users to reprogram the code themselves. In these cases, the microwave or GameBoy manufacturer might want to buy the ROMs already programmed with their code. These ROMs are called custom masked ROMs. To do this, the final version of code is sent to the ROM manufacturer. The ROM manufacturer then designs a special pattern of logic gates that duplicates this code. This type of ROM is not programmable. The code is actually designed directly into the silicon.

12 The process of designing a new custom masked ROM is very expensive, but if this cost is distributed across enough products, it ends up being cheaper than all other options. It typically takes volumes of more than 2000 for this to be a cost effective alternative. In general, Custom Masked ROMs are:

manufactured by the ROM manufacturer with code/data sent to them by the ROM purchaser;

used only when manufacturing large quantities of a single product; cheaper to use than other ROM technologies for more than 2000 parts; easier for the OEM manufacturer to use since they don't have to program the ROM (this removes a step in the manufacturing process);

very expensive due to the creation of the custom mask; very expensive to make any software changes; and not reprogrammable.

2.4.2.2

Programmable Read Only Memory (PROM) These are memory devices whose contents are loaded during system manufacture with anticipation of in-circuit or out-circuit updates during the life of the product. ROMs are intended primarily for reading data and the procedure used to store data to them is not usually the duty of the processor. Just like RAM, development in the field of electronics has brought a number of different ROM technologies, each one carrying its own set of characteristics making it more desirable for some applications rather than others. The major PROM types along with information on how data is written into them are given in the following sub-sections. All of these devices are non-volatile meaning that data is not lost with the removal of power.

2.4.2.3 Non-Erasable PROM (One-Time Programmable Read Only Memory OTPROM) As the name implies, OTPROMs are programmable using a PROM programmer, but only once. They use a fuse for each bit of each memory location. The programmer "blows" the

13 fuse to change the logic value for that location. Once the fuse is blown, however, it cannot be replaced. Therefore, if the program that is in the OTPROM has a bug or needs to be replaced due to some other software revision, the memory is thrown away and replaced with another OTPROM. This may sound wasteful but they still have some benefits. The benefit of OTPROMs is that they are the cheapest option for quantities up to 10,000. They can be purchased off-the-shelf by any manufacturer and using a PROM programmer can be programmed with any code for their product. In general, OTPROMs:

use a fuse at each bit location that is burned to change the logic value of that bit; are programmed with a PROM programmer; can only have data stored once (changes in code mean that the old OTPROM must be thrown away);

are very cheap for quantities of up to 10,000 (there are cheaper options past that level);

have a simple design allowing for a wide variety of packaging options; are a standard "off-the-shelf" component making availability high; and should only be used for stable design.

2.4.2.4 Eraseable Programmable Read Only Memory (EPROM) Compared to the other types of ROMs discussed here, EPROMs are older technology. They still have limited application though and may be found containing the BIOS in older computers. As should be obvious from the name, EPROMs have an advantage over OTPROMs in that they can be erased and programmed over again. Another subclassification of memories exists under the erasable read-only memories. This susbclassification differentiates EPROMs based on the method of erasure. There are two main categories, they are:

14 The UV-EPROM: Ultra Violet Erasable PROMs and the E-EPROM: Electrically Erasable PROMs.

2.4.2.5 The UV-EPROM: These are EPROMs whose contents can be erased only by exposing their internals to moderate energy ultra violet rays. They are identified by a small, circular window in the top of the chip. This is the mechanism by which the UV-EPROM is erased. If the program that is contained in the UV-EPROM needs to be changed, the entire chip is erased by passing ultraviolet light through the window for a specified duration. Once the chip has been erased, it can be programmed using a PROM programmer. UV-EPROMs are generally referred to as EPROM and are used mostly for development purposes where new code can be loaded and tested. In general, EPROMs:

are programmed with a PROM programmer; can be erased by shining ultraviolet light through the window on top of the memory; and

are relatively expensive.

2.4.4.6 Electronically Erasable Programmable Read Only Memory (EEPROM) The PROMs discussed up to now are not programmable by the processor, only a PROM programmer. EEPROMs, however, are programmable by the processor in the same way that data is stored to memory locations in RAM. The difference is that storing data to a memory location in an EEPROM is very slow, often taking 100 to 10,000 times longer than RAM. Lastly, the circuitry for each bit of memory in an EEPROM is more complicated than that of OTPROMs or EPROMs. Therefore, the density of memory inside of an EEPROM is lower than that of OTPROMs and EEPROMs. EEPROMs are also very expensive

15 compared to other types of PROMs. This makes them an unlikely choice for cheap electronic devices that require code such as hand-held toys or small appliances. EEPROMs are used in applications where a non-volatile ROM is required, but that changes in code may require the processor to update the EEPROM occasionally. A good example of this is the BIOS of a computer. It may only need updated once or twice during the life of the computer, but since the vast majority of computer users are not capable of pulling out a PROM and installing a new one, the task of updating the BIOS is left to the processor. This means that the PROM needs to be eraseable and reprogrammable. In general, EEPROMs are:

Written to with either programmer or the processor; Erased with either a programmer or the processor; Programmable a single location at a time; Expensive due to complex circuitry; Available only in smaller sizes due to lower density; and Extremely slow to write to (10 mS versus 100 to 200 nS for RAM).

2.5

PROM PROGRAMMING METHODS There are a number of ways that ROMs are programmed, each method usually being the factor that differentiates the different types of ROMs. The majority of PROMs can be programmed with special-purpose equipment referred to as PROM programmers. These programmers have connectors where one or more memories can be inserted in order to be programmed. During the process, the programmer supplies special voltages and bit patterns to the memory in order to store data in each location. In a manufacturing environment, a PROM programmer called a batch programmer may have enough connectors for a hundred memories allowing for the fast programming of ROMs for a product being manufactured.

16 A few PROMs can be programmed by the microprocessor, but there usually is a catch that makes it more difficult than a simple write as when storing data to a RAM. Difficulties may include very long delays between writes or only allowing large blocks to be written to at one time. The third way data is written to ROMs is by having the ROM manufacturer program them. This eliminates the need for programming by the OEM manufacturer during the manufacture of the product that requires the programmed ROM.

2.6

THE NONVOLATILE UV-ERASABLE PROGRAMMABLE READ-ONLY MEMORIES

The concept of non-volatility is used to describe memories whose contents remains intact when power is removed from the memory chip or device. Such memory devices are called nonvolatile memories. A few nonvolatile memories are programmable just once. These have arrays of diodes or transistors with fuses or antifuses in series with each semiconductor cross point. Aluminum, titanium, tungsten, platinum silicide, and polysilicon have all been successfully used as fuse technology (see Figure 3 below)

Figure 2.3: Prom cell structure Most nonvolatile cells rely on trapped charge stored on a floating gate in an FET. These can be rewritten many times. The trapped charge is subject to very long term leakage, on the order of ten years. The number of times the cell may be rewritten is limited by programming stress-induced degradation of the dielectric. Charge reaches the floating

17 gate either by tunneling or by avalanche injection from a region near the drain. Both phenomena are induced by over-voltage conditions and hence the degradation after repeated erase/write cycles. Commercially available chips typically promise 100 to 100,000 write cycles. Erasure of charge from the floating gate may be by tunneling or by exposure to ultraviolet light. Asperities on the polysilicon gate and silicon-rich oxide have both been shown to enhance charging and discharging of the gate. The nomenclature used is not entirely consistent throughout the industry. However, EPROM is generally used to describe cells which are electronically written but UV erased. EEPROM is used to describe cells which are electronically both written and erased. Cells are of either a two- or a one-transistor design. Where two transistors are used, the second transistor is a conventional enhancement mode transistor. The second transistor works to minimize the disturb of unselected cells. It also removes some constraints on the writing limits of the programmable transistor, which in one state may be depletion mode.

Figure 2.4: Cross section of two transistor EEPROM cell

The two transistors in series then assume the threshold of the second (enhancement) transistor, or a very high threshold as determined by the programmable transistor. Some designs are so cleverly integrated that the features of the two transistors are merged.

2.7

PROGRAMMING MECHANISM FOR AN EPROM

Since ROMs are meant for permanent storage of data, they can only be programmed once. Typically, when a customer orders a ROM, he has to specify the truth table he wants in terms of memory address input versus data outputs. Accordingly, a mask is made at the time of manufacturing the chip so as to leave the MOSFETs floating or connect them to the respective word lines, depending upon whethter a logic 1 or 0 is

18 to be stored for that bit. This type of customized masks prove to be very expensive for individual buyers, since mass production is not possible. This is why many manufacturers supply field-programmable arrays, PROMs which are user configurable. Here, all the diodes/MOSFETs are fabricated with each having a fusible link in series. These links burn out when a large current is passed through them (typically of the order 20-50mA). Usually, Nichrome or polycrystalline silicon is used to form these links. Thus, a user can selectively burn these links to tailor the ROM to his specifications.

An EPROM is structurally same as the ROM, but it uses a special type of MOSFET called FAMOS for each bit. A FAMOS (Floating-gate Avalanche-injection Metal Oxide Semiconductor) has got two gates as shown in the figure below

Figure 2.5: A typical FAMOS structure

Gate 1 is a polysilicon gate which is left floating in SiO2. The EPROM can be programmed by applying sufficient voltage (with respect to substrate) to both the drain and the source. This induces avalanche breakdown at both the junctions. Simultaneously the application of large positive voltage (~25V) to gate 2, with respect to the substrate, causes the electrons to be attracted and accelerated by the intense electric field towards gate 2. These electrons manage to penetrate the thin SiO2 layer and reach gate 1 but are trapped there and cannot cross the much thicker SiO2 layer between gate 1 and gate 2. Hence, when the high voltage is removed, these electrons trapped in gate 1 with no discharge path, cause the formation of negative potential in gate 1. This negative

19 potential opposes the field intensities caused by normal voltages of the order of 5V applied at gate 2. Thus, the gate 2 loses control over channel formation in the substrate and effectively the FAMOS becomes an open circuited MOS. This results in a permanent logic 1 stored in this bit.

2.8

EPROM ERASURE MECHANISM

The SiO2 layer is a very good insulator and it has been found that 70% of the electrons are still trapped after 10 years even if storage temperature is 1250C. The only way these electrons can be liberated back to their original place is by exposing it to UV light. SiO2 becomes slightly conducting under UV light and this restores the FAMOS to its original status. Now, the FAMOS EPROM can be reprogrammed with positive voltage applied between gate 2 and substrate.

2.9

THE PARALLEL PORT INTERFACE

The parallel port interface is a computer peripheral device interface used to connect devices to the system bus. It was originally designed and intended for use by printers but afterwards, other devices found it as a way to communicate with the computer system. The parallel port interface carries out transmission of data in parallel. Parallel Ports are standardized under the IEEE 1284 standard first released in 1994. This standard defines 5 modes of operation which are as follows, 1. Compatibility Mode 2. Nibble Mode 3. Byte Mode 4. EPP Mode (Enhanced Parallel Port) 5. ECP Mode (Extended Capabilities Mode)

20 The aim was to design new drivers and devices which were compatible with each other and also backwards compatible with the Standard Parallel Port (SPP). Compatibility, Nibble & Byte modes use just the standard hardware available on the original Parallel Port cards while EPP & ECP modes require additional hardware which can run at faster speeds, while still being downwards compatible with the Standard Parallel Port. Compatibility mode or "Centronics Mode" is used for the project because of its availability on most computers, its features and configuration. The parallel port in this mode can only send data through the data lines in the forward direction at a typical speed of 50 kbytes per second but can be as high as 150+ kbytes a second. In this mode, the status lines functions as an input bus while the control lines serves as an extra output path. The parallel port has 4 function types for a total of its 25 pins. These functions are as below (i) (ii) (iii) (iv) The data lines (8 pins) The control lines (4 pins) The status lines (5 pins) and The ground lines (8 pins)

But, of all these, the most important functions with respect to the design are the Data, Status and the Control lines. To understand the function of the data, control and status types, consider what happens when the parallel port is to be used to control a group of motors. For example, 8 different motors can be turned on with the 8 data output bits. The 5 status lines can be used for 5 digital INPUT lines. Thus 5 different sensors can be monitored in parallel or 25 different digital information can be read in. The 4 control lines can be used for 4 additional digital output lines.

2.10

THE PARALLEL PORT HARDWARE PROPERTIES Below is a table of the "Pin Outs" of the D-Type 25 Pin connector. The D-Type 25 pin connector is the most common connector found on the Parallel Port of the computer. The IEEE 1284 standard however specifies 3 different connectors for use with the Parallel

21 Port. The first one, 1284 Type A is the D-Type 25 connector found on the back of most computers. The 2nd is the 1284 Type B which is the 36 pin Centronics Connector found on most printers. IEEE 1284 Type C however, is a 36 conductor connector like the Centronics, but smaller. This connector is claimed to have a better clip latch, better electrical properties and is easier to assemble. It also contains two more pins for signals which can be used to see whether the other device connected, has power. 1284 Type C connectors are recommended for new designs. Pin No (D-Type 25) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 Direction In/out In/Out Out Out Out Out Out Out Out Out In In In In In/Out In In/Out In/Out Hardware Inverted Yes

SPP Signal nStrobe Data 0 Data 1 Data 2 Data 3 Data 4 Data 5 Data 6 Data 7 nAck Busy Paper-Out / Paper-End Select nAuto-Linefeed nError / nFault nInitialize nSelect-Printer / nSelect-In

Register Control Data Data Data Data Data Data Data Data Status Status Status Status Control Status Control Control

Yes

Yes

Yes

18 - 25 Ground Gnd Table 2.1: Pin Assignments of the D-Type 25 pin Parallel Port Connector. The above table uses "n" in front of the signal name to denote that the signal is active low. e.g. nError. The "Hardware Inverted" means the signal is inverted by the Parallel

22 card's hardware. Such an example is the Busy line. If +5v (Logic 1) was applied to this pin and the status register read, it would return back a 0 in Bit 7 of the Status Register. The output of the Parallel Port is normally TTL logic levels. The voltage levels are the easy part. The current you can sink and source varies from port to port. Most Parallel Ports implemented in ASIC, can sink and source around 12mA. However a common value taken from a data sheets specifies a sink current of 16mA and source current of 4mA. The safest method of interfacing with the parallel port without damaging it is to use a buffer, so the least current is drawn from the Parallel Port. 2.11 PARALLEL PORTS PORT ADDRESSING The Parallel Port has three commonly used base addresses. These are listed in table 2, below. The 3BCh base address was originally introduced used for Parallel Ports on early Video Cards. This address then disappeared for a while, when Parallel Ports were later removed from Video Cards. They have now reappeared as an option for Parallel Ports integrated onto motherboards, upon which their configuration can be changed using BIOS. Three parallel printer ports can exist on a computer, they are referred to as the LPT1 (the primary port), LPT2 and LPT3 ( the secondary ports). LPT1 is normally assigned base address 378h, while LPT2 is assigned 278h. However this may not always be the case as explained later. 378h & 278h have always been commonly used for Parallel Ports. The lower case h denotes that it is in hexadecimal. These addresses may change from machine to machine.

Address 3BCh - 3BFh 378h - 37Fh 278h - 27Fh

Notes: Used for Parallel Ports which were incorporated on to Video Cards Usual Address For LPT 1 Usual Address For LPT 2 Table 2.2: Port Addresses

23 The parallel port is structured in such a way that the three functions (data, status and control) are taken to be individual ports within the parallel port. The three different ports within the parallel port can be addressed individually and independently. The port addresses are always with respect to the base address. Each of the ports is have a corresponding eight bit software register. When a port is to be addressed, its register is selected by the specified address and the read or write operation is done on the register itself which is directly connected to the physical port. Generally, the references to each register of the port are the followings:
o o o

Data

base+0 base+1 base+2

Status = Control =

Figure 2.6: Three bus architecture of the parallel port

24 Example: if it was observed that the base address of a parallel port is 378h, then the addresses of the registration of data, status and control will be:
o o o

Data

378h 379h 37Ah

Status = Status =

Outline of the Software Registers for the Standard Parallel Port (SPP) Offset Base + 0 Name Data Port Read/Write Write (Note-1) Bit No. D7 D6 D5 D4 D3 D2 D1 D0 Table 2.3: Data Port Register Properties Data 7 Data 6 Data 5 Data 4 Data 3 Data 2 Data 1 Data 0

The base address, usually called the Data Port or Data Register is simply used for outputting data on the Parallel Port's data lines (Pins 2-9). This register is normally a write only port. Offset Base + 1 Name Status Port Read/Write Read Only Bit No. S7 S6 S5 S4 S3 S2 S1 Properties Busy Ack Paper Out Select In Error IRQ (Not) Reserved

S0 Reserved Table 2.4: Status Port Register

25 The Status Port (base address + 1) is a read only port. Any data written to this port will be ignored. The Status Port is made up of 5 input lines (Pins 10,11,12,13 & 15), a IRQ status register and two reserved bits. Offset Name Read/Write Bit No. C7 C6 C5 C4 C3 C2 C1 C0 Table 2.5: Control Port Properties Unused Unused Enable Bi-Directional Port Enable IRQ Via Ack Line Select Printer Initialize Printer (Reset) Auto Linefeed Strobe

Base + 2 Control Read/Write Port

The Control Port (base address + 2) was intended as a write only port. When a printer is attached to the Parallel Port, four "controls" are used. These are Strobe, Auto Linefeed, Initialize and Select Printer, all of which are inverted except Initialize. Each one of the outline software register for the ports allows access to the following bits :
o o o

Base (data) Status Control

= = =

D0, D1, D2, D3, D4, D5, D6, D7 S3, S4, S5, S6, S7 C0, C1, C2, C3

Some procedures for the determination and confirmation of which the base addresses of the port being used is necessary before reading or writing to the port. For Microsoft windows operating system, the address is determined through the MS-DOS prompt. Under MS DOS, the command external debug.exe is use in one of the following ways: To execute the command: type debug.exe, then the symbol appears.

26 Then, after the symbol, d 40:0008 is typed in On the screen several lines that looks like that below with hex data appears, but only the first line is analyzed. 0040:0000 ______________________78 03 00 00 00 00 00 00 The address of the port is in inverted form (78 03), then the address is: 0378 in hexadecimal. It is necessary to make notice that this address can be different in different personal computers.

27 CHAPTER THREE

DESIGN METHODS

The main essence of this project was to design and implement hardware and software integrated system to read and write desired data onto an EPROM memory chip. The EPROM chip under study was the 27C64 which will be discussed in details in the following section. For every one of the desired functions, there were electrical conditions that were to be implemented in order for this function to be achieved. These functions were generally classified by the device manufacturers as the modes of operation. The design methodology employed in the implementation of the EPROM programmer was a function of the requirements of the operating modes of the EPROM (the 27C64). Below are the details of the EPROM chip and a discussion on the various modes of operation available.

3.1

THE 27C64 EPROM EPROMS are available in a wide range of capacities and access time; devices with a capacity of 512k x 8bits with an access time of 20nS are common place. The 27C64 is an example of a small EPROM. The 27C64 is an 8K x 8 CMOS EPROM that operates from a single 5V power source during normal operation. The figure below is the logic symbol for the 27C64.

Figure 3.1 (a): Block representation of the 27C64s external architecture

28

Figure 3.1 (b): The pinout of the 27C64 EPROM

Where E is the chip enable pin (CE), P is the program pulse input (PGM) and G is the
output enable (OE). It shows 13 address input. This is true because 213 = 8192, and 8 data outputs. It has four control inputs. CE is the chip enable that is used to place the device in a standby mode where its power consumption is reduced. OE is the output enable and is used to control the devices data output tri-state buffers so that the device can be connected to the microprocessors data bus without bus contention. Vpp is a special voltage required during the programming process. PGM is the program enable input that is activated to store data at the selected address.

Figure 3.2: Physical structure of the 27C64 EPROM showing the window

The 27C64 package shown in figure xxx above shows the characteristic window. This window allows the internal circuitry to be exposed to UV light when the complete

29 memory contents are to be erased. A sticker is placed over the window after erasure and reprogramming to protect against accidental erasure from ambient light. The 27C64 has several operating modes that are controlled by the CE, OE, Vpp, and PGM. The program mode is used to write new data into the EPROM cells. This is most often done on a clean EPROM, one that has previously been erased with UV light so that all cells are 1s. A programming process writes one 8 bits word into one address location at a time.

3.2

THE 27C64 DEVICE OPERATION The 27C64 EPROM has six modes of operation but seven when the chip identification mode is added. The modes of operation of the 27C64A are listed in the Operating Modes table below. A single power supply is required in the read mode. For other modes like program and electronic signature (chip identification) modes, all inputs are TTL levels except for VPP and 12V on A9 for Electronic Signature.

Table 3.1: Table showing the operating modes

Of all the operating modes listed above, the only modes relevant to this project are the Read, Program, Program verify and electronic signature modes. These modes are discussed below.

30 3.2.1 Electronic Signature Mode The Electronic Signature (ES) mode allows the reading out of a binary code from an EPROM that will identify its manufacturer and the EPROM type. This mode is intended for use by the programming equipment to automatically match the device to be programmed with its corresponding programming algorithm. The electronic signature mode is functional in the 25C 5C ambient temperature range that is required when programming the 27C64. To activate the electronic signature mode, the programming equipment must force 11.5V to 12.5V on address line A9 of the M27C64A, with VPP = VCC = 5V. Two identifier bytes may then be sequenced from the device outputs by toggling address line A0 from VIL to VIH. All other address lines must be held at VIL during Electronic Signature mode. Byte 0 (A0 = VIL) represents the manufacturer code and byte 1 (A0=VIH) the device identifier code. For the ST Microelectronics 27C64, these two identifier bytes are given in Table xxx and can be read-out on outputs Q0 to Q7.
Hex data 9b 08 8f C2

Identifier Manufacturers code Device code Manufacturers code Device code

A0 ViL VIH ViL VIH

D7 1 0 1 1

D6 0 0 0 1

D5 0 0 0 0

D4 1 0 0 0

D3 1 1 1 0

D2 0 0 1 0

D1 1 0 1 1

D0 1 0 1 0

Manufacturer

ST Microelectronics

National

Table 3.2: Manufacturers code for different manufacturers

3.2.2

Read Mode The M27C64A has two control functions, both of which must be logically active in order to obtain data at the outputs. Chip Enable (CE) is the power control is used for device selection. Output Enable (OE) is the output control and is used to gate data to the output pins, independent of device selection. Assuming that the addresses are stable, the address access time (tAVQV) is equal to the delay from E to output (tELQV). Data is available at the output after a delay of tGLQV from the falling edge of G, assuming that E has been low and the addresses have been stable for at least tAVQV-tGLQV.

31

Figure 3.3: Timing Diagram for the Read Operation

3.2.3 Programming and Program Verify Modes The programming mode and the program verify mode works hand in hand with each other. The program verify mode was used to verify that the exact data for a particular memory location was successfully written. When delivered (and after each erasure for UV EPROM), all bits of the M27C64A are in the "1" state. Data is introduced by selectively programming "0"s into the desired bit locations. Although only "0"s will be programmed, both "1"s and "0"s would be present in the data word. The only way to change a "0" to a "1" is by die exposition to ultraviolet light (UV EPROM). The 27C64 is in the programming mode when Vpp input is at 12.5V, CE is at VIL and PGM is pulsed to VIL. The data to be programmed is applied to 8 bits in parallel to the data output pins. The levels required for the address and data inputs are TTL. VCC is specified to be 6V 0.25V. A verify (read) should be performed on the programmed bits to determine that they were correctly programmed. The verify is accomplished with CE and OE at VIL, PGM at VIH, VPP at 12.5V and VCC at 6V. The timing diagrams associated with these two modes are shown in figure xxx below:

32

Figure 3.4: Timing diagram for the program and program verify modes

3.3

HARDWARE DESIGN METHOD From the external architecture of the 27C64 EPROM, it can be observed that the EPROM has a dedicated address and data bus. The programming procedure demands that 1- The address of the location of interest is placed first on the address lines of the memory chip. 2- The data to be written is placed on the data pins of the parallel port. 3- Set up the control or conditions for programming. 4- A 0.5 millisecond pulse is applied to the PGM input.

These are the least settings required for the chip to be programmed assuming an ideal situation where data was properly written into the memory chip and no verification is needed. From the statements above, it was observed that since the memory chip had a dedicated bus system, the address, data and control information all needed to be present simultaneously at the pins of the memory device at the instant of programming. This implied that, at the point of programming, 8 bits of data information, 13 bits of address information and 4 bits of control information needed to be present. This gave a total of 25 bits of information. But on the contrary, the parallel port interface could only give 8 bits

33 of data out on the data bus and one nibble of control information on the control bus. From these observations, the parallel port on its own could not handle the programming of the memory chip without the aid of a latching system. This led to the introduction of a major component of the hardware design the latching system.

3.3.1

The Latching System The latching system is basically a system of latches designed in order to capture the data that momentarily appear on the data bus. This is accomplished with the aid of the octal latch integrated circuit, the 74F374. The 74F374 is an 8-bit edge triggered register coupled to eight 3-State output buffers. The two sections of the device are controlled independently by clock (CP) and output enable (OE) control gates. The register is fully edge triggered. The state of the D input, one setup time before the low-to-high clock transition is transferred to the corresponding flip-flops Q output. The 3-State output buffers are designed to drive heavily loaded 3State buses, MOS memories, or MOS microprocessors. The active low output enable (OE) controls all eight 3-State buffers independent of the register operation. When OE is low, the data in the register appears at the outputs. When OE is high, the outputs are in high impedance off state, which means they will neither drive nor load the bus.

Figure 3.5: Diagram of the pinout of the 74F374

Two latches were used for the address latching. This was because the address bus of the 27C64 had 13 lines which could not all be handled by one 8-bit latch. The parallel port

34 could not also write the 13 bits of address all at once. So, the 13 address bits were broken down into the lower order byte and higher order byte. The higher order byte had five real address bits and the three remaining upper bits were used for some control implementation as will be discussed latter in this write up. The address latches were labeled latch1 for the lower order address byte and latch2 for the higher order address byte. The output enable (OE) for the address latches were permanently held low because the address bus was unidirectional and there was no possible source of bus contention or conflict. The latching procedure was of three basic steps namely; 1- The actual value is written to the data bus (all the latches data input lines are connected to the data port of the parallel port) 2- A clock pulse strobe is applied to the CP input of the latch which activates the internal buffer to hold onto the data on the input lines. 3- The data at the latchs input at the moment of the CP strobe was captured by the latch and made available instantly at the output lines because the OE is permanently grounded. The data latching process was similar to the address latching process. But the data latching was only done once because the word length of the data was 8 bits. The only difference was that the output enable for the data latch was controlled by the read and write control signals. When a read operation was to be executed, the data latch was disabled by the read control in order to avoid bus conflict. Also, when data was written to the EPROM chip, the output enable of the data latch was enabled and that of the EPROM disabled.

A block diagram of the latching system is as below:

35

Figure 3.6: Block diagram of the latching system

From the figure above, the latches were designed to function with a 3 to 8 line decoder (the 74LS138). The decoders function was to perform the task of clocking. It provided the clock pulse needed by the latches to latch unto the data on the data bus. The decoder selected the active line with an active low signal and the latch needed a negative edge signal at its clock pulse input. The negative edge was provided to the clock pulse input by a transitional TTL voltage level. This was accomplished by enabling the decoders (74LS138) output to the latch and disabling it immediately. This caused a low to high and

36 a high to low transition on the CP input when a NOT gate was used at the decoders select output lines. For the system shown above, all the addresses and data were latched by the following sequence of events: 1- The lower order address byte was written onto the data bus. 2- The first bit of the decoders output was used to clock latch1 to hold the address byte. 3- The remaining upper address byte was written onto the data bus 4- The second bit of the decoders output was then used to clock latch2 to hold the upper address byte. 5- The data to be written onto the EPROM chip was written onto the data bus of the parallel port. 6- The third bit of the decoders output was used to clock the data latch (latch3) to hold onto the data to be programmed into the specified location on the chip.

This summarizes the whole latching process involved in the programming of the memory device. Another interesting part of the hardware design was the multiplexer system.

3.3.2

The Multiplexer Sub-system When data is read from the 27C64 EPROM, the output is given out as an 8bit (1 byte) value. This value cannot be read into the computer by the parallel port without the aid of multiplexing. The only input port available on the parallel port is the status port which has but only 5 input lines. The solution to this insufficient line problem was gotten by the implementation of multiplexer sub-system. This sub-system broke the 8 bits of data into upper and lower nibble and therefore read 4 bits at a time which was concatenated afterwards to get the original 8 bits of data. The multiplexer sub-system was made up of two main devices: 1- The Quad 2-input multiplexer: this acts as an 8 to 4 lines multiplexer. The 74HCT257 is used here. The 74HCT257 are high-speed Si-gate CMOS devices and are pin compatible with low power Schottky TTL (LSTTL). The 74HC/HCT257 have four identical 2-input multiplexers with 3-state outputs,

37 which selects 4 bits of data from two sources and are controlled by a common data select input (S).

Figure 3.7: Block diagram of the 74HCT257 (Quad 2-input multiplexer) The data inputs from source 0 (1I0 to 4I0) are selected when input S is LOW and the data inputs from source 1 (1I1 to 4I1) are selected when S is HIGH. Data appears at the outputs (1Y to 4Y) in true (non-inverting) form from the selected inputs.

2- A Buffer: a 74LS244 chip is placed between the data bus of the programmer circuit and the multiplexer in order to isolate the multiplexer from the bus system and also make up for the voltage drops that occurred on the bus.

Figure 3.8: Circuit diagram of the 74LS244 buffer

38

Table 3.3: Function table of the 74LS244 buffer Though the buffer had two independent sets of lines, their outputs were both permanently enabled. The schematic of the multiplexer sub-system is a below:

Figure 3.9: Schematic of the multiplexer sub-system for data input to the status port

The buffer was used as a gate between the multiplexer and the data bus. The two select inputs were permanently kept low (active) so that data was made available to the multiplexer at the instant data is presented by the chip. On the multiplexer chip, when the S input was set to logic 0, the four 0 lines as indicated by figure 3.4 above were switched to the output of the multiplexer and when S was set to logic 1, the four 1 lines were made available at the multiplexers output. So, when a read procedure was executed, the main hardware procedure was that the read conditions be set up first. The read conditions will be discussed in detail later in this chapter. After setting up the read condition, the data requested for was presented on the data bus by the

39 EPROM. The parallel ports data port then collected the 8 bits of data nibble by nibble. First, the lower order nibble was read by placing a logic one on the multiplexers select input. After this, the higher order nibble was then read by placing logic 0 on the multiplexers select input. This summarizes the multiplexer sub-system implementation utilized in the design of the circuitry for this EPROM programmer.

3.3.3

Voltage Level Implementation Unit The table 3.1 above states the various operating modes of the 27C64 EPROM. Some of the operating modes required some voltage levels that were higher than the usual TTL voltage levels. The modes of operation requiring the high voltage levels were; 1- The programming mode required 13 0.5V at the Vpp pin of the EPROM chip. 2- The program verify mode required 6V at the Vpp pin of the EPROM chip. 3- The chip identification mode required 12 0.5V at the A9 pin of the EPROM chip.

The realization of these voltage levels and their control is discussed below. The voltage levels were to be controlled by a TTL level voltage. The system derived is more like a high voltage buffer. A control input to the system caused the desired high voltage at the output. A simple system of the high voltage buffer comprises of an operational amplifier and a standard level voltage regulator. For the 6V and 12V levels, voltage regulators (the 7806 for 6V level and the 7812 for the 12V level) exist that can give the exact voltage level provided the input voltage exceeds the rated output voltage. That is, the 7806 would give precisely 6V at the output if the input voltage is greater than 6V and less than the rated maximum. So, the problem was how to provide the high voltage to the 7806 and the 7812. This was simply handled by an operational amplifier configured as a comparator. The LM741 which is an opamp integrated circuit was used. An opamp in the comparator mode (with infinite gain) has its output driven to its supply voltage (Vcc) when there is a significant difference between its inverting and non-inverting inputs.

The control input was a TTL logic level and this was sent to the non-inverting input of the opamp while the inverting input was set at a reference voltage level. The reference

40 voltage level was adjusted with the aid of a variable resistor (acting as a potential divider) to a level approximately equal to the circuits TTL logic 0 level. With this setting, the opamps supply voltage becomes the input to the voltage regulator when the control input is at logic 1.

Figure 3.10: Voltage level implementation using standard voltage regulators (6V & 12V)

As for the 13V level implementation, there was no standard 13V regulator so, an adjustable voltage regulator was used. The LM317 is an adjustable 3-terminal positive voltage regulator and is capable of supplying in excess of 1.5A over a 1.2V to 37V output range. It required the selection of output level with the aid of a variable resistor. The resulting configuration for the implementation of the 13V supply is as below:

41

Figure 3.11: Voltage level implementation using variable voltage regulator

With the systems above, the desired voltage levels were easily switched ON with just a control signal.

3.4

SOFTWARE DESIGN

The series of steps that software undergoes, from concept exploration through final retirement, is termed its life cycle. During this time, the product goes through a series of phases. There are five of these phases and they are listed below. 1. Requirement analysis phase. 2. Specification phase. 3. Design phase. 4. Implementation phase. 5. Integration phase. At the end of each of these phases, testing is carried out to ensure that the project meets the set target for that phase.

3.4.1

Software Development Process The software development process or software lifecycle is the series of steps we take to develop software. It incorporates the software lifecycle model, the tools we use, and most important of all, the individuals building the software.

42 The software development process differs from organization to organization. Lack of software engineering skills is a major contributor to these observed differences. Another pronounced reason is that many software managers are not knowledgeable enough in the field to handle a software project but may be excellent managers. The truth is that software is developed by human beings, and the process within a given organization is dependent on the individuals working in that organization. Irrespective of the exact procedure each organization employs, software development follows the same five phases outlined earlier. The names with which these phases are referred to may differ for example requirements and specification phases together are sometimes called system analysis. Furthermore, certain phases may be subdivided; for instance, the design phase almost always is broken down into architectural design and detailed design. Testing is not a separate phase on it own but it is an activity that goes on in all the phases throughout the software production. This testing sometimes is carried out to the total exclusion of other activities. This is usually done at the end of each phase and it is referred to as verification. Although there are times when testing predominate, it is practically unacceptable to neglect testing. If testing is treated as a separate phase, then there is the real danger that testing will not be carried out constantly through out every phase of the product development. Errors from previous phases will very easily propagate into subsequent phase. Documentation is another part of the software process that is essential. This is not a separate phase on it own but it is carried out through every phase of the development. An attendant problem with documentation is that if it is delayed, it may never be completed. Also as changes occur in the design, the documentation needs to be updated. For this reason, it is essential for documentation at each phase of the software development to be carried out by the teams responsible for that phase. The following terms will be defined in order that their usage will be clarified.

3.4.1.1 Requirements Analysis Requirements analysis is the activity of gathering, identifying, and formalizing requirements in order to understand the actual problems for which a solution is sought. In

43 the case of our software, the requirement was that it should be able to read from our 27C64 EPROM chip and also write data and instructions to it. It was required that the software read and write data to unique address locations specified by the user. The address was specified to avoid data already in memory being overwritten. The requirement analysis phase began from the inception when the project was actually considered. The requirement kept changing as the product development proceeded. The reason why this phase was carried out was to understand the purpose and scope of the system. The initial list of requirements described what the problem was. This requirement analysis was carried out thoroughly to avoid errors. These errors if allowed to propagate would eventually result in serious problems in the implementation stage. At the end of the requirement phase, a document is meant to be produced. The Software Requirement Specification (SRS) document is a detailed description of the requirement of software. For this project no SRS document was produced. The software developed in the course of this project was a driver that enabled the computer to communicate with the external hardware circuit. This software project was considered a small one and at such didnt require an SRS document.

3.4.1.2 Software Specification At the end requirements phase after the details of the software has been fully understood, the specification document is drawn up. The specification document as opposed to the informal document of the requirements phase, explicitly describes the functionality of the product. It specifies in details what the product is supposed to do. This document also lists the constraints that the product must satisfy. The specification document includes the inputs to the product and the required outputs. In addition, the specification document includes stipulations that the product must be able to handle correctly a wide range of deductions. Care must be taken to avoid writing specifications that are incomplete. Incomplete software specifications usually have relevant facts omitted. For instance, the specification may not state the actions to be taken if the input data contains errors. Moreover specifications could be drawn up that are contradictory. This problems need to be

44 corrected before development can proceed. At the end of this phase, two primary outputs are obtainable. The first is the complete specification document while the second is the project management plan. This phase was not carried out while developing our project. The omission was deliberate. Reason being that our software was not a large one and at such did not require the intricacies of such details.

3.4.1.3 Software Design Phase This phase is a necessity in all software projects. Design is the activity of transforming the document from the specifications phase into a technically feasible solution. In our case this phase involved getting a feasible solution from our requirement specification. The purpose of design is to map the various requirements to technology and to reason about the correctness of the approach before implementing the solution. Requirements may be specified using several views such as behavioral (use cases), informational (object models), and "nonfunctional" (ad hoc and other methods). The design maps these various inputs to software entities such as objects. The design activity encompasses classic object-oriented design as well as higher-level architectural design methods. The result of design is a specification of how to build the application or system and the technical constraints on the implementation. For example, a single performance requirement may map to several performance constraints on several related components, which when executed together must satisfy the performance requirement. The solution of our design was specified using the Unified Modeling Language (UML). The output from our design phase was the complete design itself. This design could be divided into two parts. The architectural design which is a description of the product in terms of the various modules it contains and the detailed design. The detailed design is a detailed description of each module.

3.4.1.4 Implementation Phase Implementation is where design is transformed into the source code that describes an executable system. Implementation also involves building and testing the system in part and in whole. This was carried out immediately at the end of the design phase. Our

45 software was implanted using the Java programming language. Our reason for implementing the software using Java was that java has the advantage of being platform independent. This means that our software can run on any operating system as long as the java virtual machine is installed. The software was built in modules. These modules had various roles they played towards making the software function properly. Each of these modules after being coded was tested individually. This test was necessary to prove that the modules were functioning properly. It could be seen that writing the source code for a system is a form of design itself. The distinction, then, between implementation and design is in the granularity or focus of the design. Some modeling tools that support UML may have rudimentary codegeneration capabilities but don't support round tripping. Round tripping is the ability to move between source code and UML views of a system's implementation. Many UML tools do support this capability and thus tend to further blur the distinction between implementation and design.

3.4.1.5 Integration Phase This stage involves combining the modules together to form the software. The different modules that make up the software were integrated using the bottom up interconnection method. A major problem with this method of integration is that if a fault is present, it will show up late necessitating an expensive rewrite. After the modules were integrated, the software was properly tested to ensure that the modules combined properly to function as required. The test proved that our system satisfied the entire requirement. This test was carried out with the hardware circuit interfaced to the computer. During these tests, attention is particularly paid to testing the module interfaces. Tests are usually carried out to check not only the correctness of the product but also its robustness. This is usually done by intentionally inputting erroneous data to determine how the system responds. The final test is the acceptance test.

3.4.1.6 Maintenance Phase The maintenance phase began as the implementation of the product was completed. During this phase, errors and bugs discovered in the software was fixed.

46 When an application or system goes into maintenance, it is considered to be complete with respect to the initial vision of the product.

3.5

SOFTWARE ALGORITHM As discussed in the previous sections, the EPROM has different operating modes. The software implementation of these several modes is through a sequence of events that must occur in the specified manner. These sequences of events are known as the software algorithm for the various operating modes. Since there are four main operation modes for the EPROM, the four different algorithms for each mode would be present in the software.

3.5.1

The Programming Algorithm The recommended flow chart representation of the programming of the EPROM as given by the manufacturer is as shown in figure 3.7. The algorithm was followed in order to get data burned into the EPROM chip. This algorithm, otherwise called the programming algorithm is discussed below. For data to be written into the EPROM chip, it is expected from the flow chart above that the board be powered by a maximum voltage of 6V. Next, the address of the starting location and the data for the location are written out to the address and data lines of the EPROM respectively. A control signal is used to switch the programming voltage input (Vpp) to a 13V supply. The data is then entered into the specified location by another control signal (the programming pulse PGM). The programming pulse is a 0.5mS pulse. The location is read immediately and its content is compared with the intended value. If they are the same, the program continues with the next address else programming is attempted again on the same address. If it fails again for 20 consecutive times, the programming process is considered to have failed. The other addresses are programmed in the same manner as stated above and the program ends when the last location has been programmed.

47

Figure 3.12: Flow chart of the programming algorithm.

48

3.5.2 The Read Algorithm The recommended flow chart representation for the read operation of the EPROM is shown in the figure below. In order for data to be read out of the EPROM chip, the following process was carried out. The user was first asked to specify the address of the location where reading should start from. The stop address was also required from the user. Next the user was prompted to specify the name of the target file where the content of the file would be written to. The target file, most preferably a text file, was then created by the software. Next, the start address specified by the user was sent on the address line of the parallel port. This address was latched and then used to select the location where the reading would start. With the address latched, the control signal for a read operation was sent on the control line and the content of the EPROM at that location was subsequently read. The content of the EPROM was written to the specified file for access by the user. The address of the memory location was by a location for the duration of the read operation. This process was carried out until the stop address was reached. At this point, the user was prompted of the end of the operation.

49

Figure 3.13: Flow chart for the read operation.

3.5.3

Program verify algorithm The verify (read) was performed on the programmed bits to determine that they were correctly programmed. The verify operation was accomplished by sending control signals that will send chip enable and output enable to VIL which is a low state, and program pin to VIH which is a high state. This same set of signals was used to send 13V to VPP and 6V to VCC. Verify operation goes on in consonance with the programming operation. When a

50 location in memory is programmed, the content of that location is immediately read. This read operation is the Verify operation.

3.5.4

Electronic Signature The Electronic signature was obtained by implementing the flow chart shown below.

Figure 3.14: Flow chart for obtaining the electronic signature The Electronic Signature (ES) mode allows the reading out of a binary code from an EPROM that will identify its manufacturer and type. This mode was used by EPROM programmer to automatically match the EPROM chip to be programmed with its corresponding programming algorithm. The ES mode was activated on the programming equipment by forcing a voltage change from 12V to 13V on address line A9 of the EPROM. Next VPP and VCC were set to 5V. With this setting, it was now possible to obtain two identifier bytes from the device outputs by toggling address line A0 from VIL to VIH. When A0 was low (VIL = 0), the manufacturers code was obtained while the device code was obtained when A0 when left high (VIH = 1). All other address lines were

51 held at VIL during Electronic Signature mode. These two identifiers were read out on output pins Q0 to Q7. This process is illustrated with the flow chart below.

3.6

PROGRAM MODULES The algorithms of the various operating modes of the EPROM presented earlier were actually implemented using Java programming language. The software was implemented using several modules. These modules were put together to obtain three classes with the main class inclusive. This approach was adopted for ease of implementation. These modules had at least a method implemented in them that helped the modules carry out their specified functions. The modules are briefly discussed below.

3.6.1

Initialization Module This was the first to be executed once the programmer was launched. This module had the task of getting the board ready for use. This module was essential to the system because it was used to get the board ready for use. In order for the circuit board to be set for use, three main operations had to be carried out. First we needed to check the circuit board if the was power. This was handled by a method called the checkPower() method. The second requirement of the initialization module was to check the chip for the manufacturers code. This code was necessary in order to select the correct programming algorithm for the chip. Checking for the correct programming algorithm is essential but it only applied to a programmer with the ability to program a variety of chips. Our programmer was built for only 27C64 EPROM chips. The method handling this was the manufacturersId() method. The final requirement of the module was to get the device code of the chip being programmed. This code was also used to select the correct device programming algorithm for the chip. This was handled by the chipIdentification() method.

The checkPower() method: This method handles the logic that determines if the circuit board has power connected to it. The theory behind the operation of this method was based on the fact that the data latch will only hold data sent to it if the data latch was powered. The presence of power

52 on the board was checked by writing a data value to the data latch and then reading the content of the latch to know if the content was the same as the value written to it. The content of the latch would only be the same as the value written to it only if the circuit board was powered. From the hardware description of the parallel port, we only had access to four lines. This was a problem because we had to read in 8 bits (1 byte) at a time. This problem was handled by carrying out bit shift operation after reading in from the status port. The bit shift operation was carried out by the nibbleProcessor method. The code snippet for the nibbleProcessor is shown below;

private int nibbleProcessor(){

lowerNibble = lowerNibble >> 3; //register shift operation, 3 bits to the left. lowerNibble = lowerNibble & 15; // to eliminate the Most Significant Bit.

upperNibble = upperNibble >> 3; //register shift operation, 3 bits to the left. upperNibble = upperNibble & 15; // to eliminate the Most Significant Bit. upperNibble = upperNibble << 4; // register shift operation, 4 bits to the left, to retain its value which is the most significant nibble

int data = upperNibble | lowerNibble;

System.out.println ("the data from nibble processor byte is = " +data); return data;

} The lower nibble was first read in through the status port. This nibble read in was then shifted three places to the right after undergoing a register shift operation. The obtained valued was used for a bitwise and operation with 15. This was done to eliminate the most significant bit. The upper nibble was then read in and passed through the same process as the lower nibble. In addition, the upper nibble was then subjected to a register shift

53 operation. Finally a bitwise or operation was carried out between the upper nibble and the lower nibble to obtain the 8 bit data read in.

The manufacturersId() method: This method was used to read the manufacturers code from the chip. This was necessary because we observed that the different EPROM chips had different manufacturers code in addition to the different device code. In order to read the manufacturers code, we used several methods to achieve this. The methods we used included methods like the lpt1.writeOneByte and the lpt1.read() which were imported with the parport package. Other methods include addressWriter() method and nibbleProcessor() method. The address writer method was used to set the address requirements for the manufacturers code. This involved setting A0 to A12 = 0. A9 was set to 13V. With these bits set to their respective values, the manufacturers code was then read out from the output pins Q0 to Q7. The code snippet for the addressWriter method is given below; public void addressWriter(int lowAddress, int highAddress){ //low address refers to the address latched onto address latch 1 //high address refers to the address latched onto address latch 2

lpt1.writeOneByte(0x37a, 1); //To initialize the 138 to start from 10111111. This is necessary because the latches are positive edge triggered hence due to the hardware inversion, in order to latch onto the Lowest Significant address byte the transition to 01111111 can only take place after the address is valid

lpt1.write(lowAddress); // write the Lowest Significant Byte of address information to the data port. System.out.println("Output to address latch1: " + lowAddress);

lpt1.writeOneByte(0x37a, 0); //to latch onto the least significant byte of address info. 138 has 01111111

54 try{ Thread.sleep(1);//1 millisecond sleep. } catch(InterruptedException b){ System.out.println ("ERROR!!!"); // This would handle the propagation delay for the 138 as well as the propagation delay times for the 74374

lpt1.write(highAddress); // write the remaining 5bits of address information onto address latch2 System.out.println("Output to address latch2: " + highAddress); //delay(); lpt1.writeOneByte(0x37a, 1); // This was used to latch onto the Most Significant byte of address info. 138 has 10111111

try{ Thread.sleep(1); //1 millisecond sleep. } catch(InterruptedException b){ System.out.println ("ERROR!!!");}; // This would handle the propagation delay for the 138 as well as the propagation delay times for the 74374

The chipIdentification() method: This method was used to read the devices code from the chip. The sequence of codes used to read the device code from the chip was similar to the sequence of codes used to read the manufacturers code. The only difference between the two methods was that for the device code, the addressWriter method sent a high bit (0) to pin A0. A9 was still left at 13V. Similarly with these bits set to their respective values, the manufacturers code was then read out from the output pins Q0 to Q7. The code snippet for the chipIdentification() method is given below;

55

public int chipIdentification(){ addressWriter(1, 192);

lpt1.writeOneByte(0x37a,2); //this is used to ensure that the lower nibble can be read.

lowerNibble = lpt1.read(); lpt1.writeOneByte(0x37a,10); // i.e. set control 1010...read upper nibble upperNibble = lpt1.read();

int chipIdentifier = nibbleProcessor(); return chipIdentifier;

3.6.2

Write Module This module of was used to handle all write operations to the programmer. This was implemented using the writeToProgrammer method. For a successful write operation to the programmer, we had to disable the output of the EPROM chip. This pin is an active low pin. In order for the write operation to be carried out, the address of the location to be written to had to be sent first for it to be latched. Our EPROM was an 8K x 8 bit chip. This meant that we required 13 address bits to select a location in the chip. Our data port was an 8 bit data port so the address information had to be read twice. This implied that two latches would be used for holding the address of a location in memory. The module had to send the address information a byte at a time i.e. lower address byte and the higher address byte. The control signal for the address to be latched was then sent through the control port. The write operation was actually carried out by dataWriter() method.

The dataWriter() method:

56 This method was used to write a byte of information to the data port. The source code for the dataWriter() method is given below;

public void dataWriter(int data){

lpt1.write(data); // write a byte to the port's DATA port lpt1.writeOneByte(0x37a, 2); //latch data onto L2 System.out.println("Output to data port: " + data);

3.6.3

Chip Verify Module Chip verification is a read operation that was carried out while the chip was in programming mode. The way it functioned was that after a location was written to, the verify module will read the content of that location. The verify module also read the content of the whole chip after the write operation. The condition for the verify operation was that the output enable of the EPROM be enabled and the output enable of the data latch be disabled. Other conditions were similar to that of the programming module. The source code for the verify operation is given below;

public boolean verify(int addressMsb, int dataForVerification){

addressMsb = addressMsb | 160; // this is done to include the control bit that enables the output of the 27C64, disables the output of the data latch and leaves Vpp at 13V lpt1.write(addressMsb); // write this address to the data port lpt1.writeOneByte(0x37a, 1); // latch the data on the data port onto the second address latch

try{

57 Thread.sleep(1); //1 millisecond sleep. } catch(InterruptedException b){ System.out.println("ERROR!!!"); //this should handle the propagation delay for the 13 as well as the propagation delay times for the 74374

lowerNibble = lpt1.read(); //read lower nibble lpt1.writeOneByte(0x37a, 13 ); //enable upper nibble

try{ Thread.sleep(1);//1 millisecond sleep. } catch(InterruptedException b){ System.out.println("EROR!!!"); // this should handle the propagation delay for the 138 as well as the propagation delay times for the 74374

upperNibble = lpt1.read(); //read upper nibble int verifiedData = nibbleProcessor();

//JOptionPane.showMessageDialog(null,"the data read from address "+addr+ "is" + verifiedData); //System.out.println("the verified data is = " +verifiedData); boolean proceedStat;

if(verifiedData == dataForVerification){

proceedStat = true;

lpt1.writeOneByte(0x37a, 4); //to apply the final programming pulse i.e the 3millisecond pulse lpt1.writeOneByte(0x37a, 3);

58 try{ Thread.sleep(3); //3 millisecond delay } catch(InterruptedException b){ System.out.println("ERROR!!!"); }

lpt1.writeOneByte(0x37a, 4); } else{ proceedStat = false; //JOptionPane.showMessageDialog(null, " error the location did not program!!"); } //JOptionPane.showMessageDialog(null,"about to leave verify");

return proceedStat; }

3.6.4

Read Module The read module was used to read the content of the chip. First of all we set the programmer in the read mode. This was achieved by sending the control signal through

the control port to the control circuitry to implement the required control. After setting the chip in the read mode, we handled the addressing. The start address and the end address were obtained and saved in a temporary file. These addresses were now used to determine the exact length of the data to be read into the file because the size of the array needed to be declared. The difference between the end address and the start address gave us the size of the array that was created. The array declared was used to hold the data before it was written to the file. A loop was entered with start value equal to the start address. This was terminated after the end address. Each time the loop was executed, the

59 addressWriter() method was used to write the address of the location to be read from on the data port. The source code for this module is shown below.

Public void readFromProgrammer(String startAddress, String endAddress){ // startAddress and endAddress are string variables used to hold the desired start and stop locations of the read operation Address myAddress = new Address(); myAddress.addressProcessor(startAddress); //processes the address string

lowerAddressByte = myAddress.getLowerAddressByte(); upperAddressByte = myAddress.getUppperAddressByte(); int startAddressInt = myAddress.getAddressInteger(); startAddressInt = startAddressInt & 8191; //to remove the effect of the "ORING" in the address class myAddress.saveStartAddressIntegerForFileProcessor(startAddressInt); //In handling the file processing, it is necessary to determine the exact length of the data to be read into the file because an array is used to hold the data before it is written onto the file.

//JOptionPane.showMessageDialog(null,"saved start address successfuly");

upperAddressByte = upperAddressByte | 128; //this is used to add the control bits

//System.out.println("startadd " +startAddressInt); myAddress.addressProcessor(endAddress); int endAddressInt = myAddress.getAddressInteger(); endAddressInt = endAddressInt & 8191; //to remove the effect of the "ORING" in the address class

myAddress.saveEndAddressIntegerForFileProcessor(endAddressInt);

//JOptionPane.showMessageDialog(null,"saved end address successfuly");

60 arraySize = myAddress.setArraySizeAddressByte(); //to return the size of the array

dataArray = new String [getArraySizeAddressByte()]; //declare an array with size of the expected file int m =0; //counter used for the array int n = 1;

//JOptionPane.showMessageDialog(null,"made +getArraySizeAddressByte());

it

through

the

arrays

"

for(startAddressInt = startAddressInt; startAddressInt <= endAddressInt;){

addressWriter(lowerAddressByte , upperAddressByte); startAddressInt = startAddressInt + 1;

// System.out.println("startadd plus1 " +startAddressInt);

myAddress.addressProcessor(Integer.toHexString(startAddressInt));

lowerAddressByte = myAddress.getLowerAddressByte(); upperAddressByte = myAddress.getUppperAddressByte(); startAddressInt = myAddress.getAddressInteger(); startAddressInt = startAddressInt & 8191; //to remove the effect of the "ORING" in the address class

upperAddressByte = upperAddressByte | 128; //this is used to add the control bits

if(startAddressInt == 0) break;

// System.out.println("lab" +startAddressInt);

61

lpt1.writeOneByte(0x37a, 6 ); // First, this sets the programmer to read mode. It is also the control signal to select the lower order nibble of the 257`s input. This is done by the MSB of the data written to the control port i.e. D3 = 0>> select lower nibble D3 = 1>> select upper nibble. Tthis permits the lower nibble to pass thru to the 257 and to the data por.t try{ Thread.sleep(1);//1 millisecond sleep. } catch(InterruptedException b){ System.out.println("ERROR!!!"); // this should handle the propagation delay for the 138 as well as the propagation delay times for the 74374.

lowerNibble = lpt1.read(); //read lower nibble //delay();

lpt1.writeOneByte(0x37a, 14 ); //enable upper nibble

try{ Thread.sleep(1);//1 millisecond sleep. } catch(InterruptedException b){ System.out.println("ERROR!!!");

upperNibble = lpt1.read(); //read upper nibble //delay();

int inputData = nibbleProcessor(); System.out.println("inputdata= " +inputData) //startAddress = startAddress + 1 ;

62 dataArray[m] = Integer.toHexString(inputData); // populate the cells of the array with the data read from the chip m = m + 2; //data stored in the even array cells dataArray[n] = Integer.toHexString(startAddressInt); n = n + 2; //addresses stored in the odd address cells

} }

The entire code for the EPROM programmer can be found in Appendix C

63 CHAPTER FOUR

SYSTEM DESIGN

4.1

THE HARDWARE SYSTEM

The hardware circuitry for the EPROM programmer is the totality of the circuits discussed in the previous chapter. The several units discussed are integrated to form the desired circuit. The latching system directly connects to the parallel ports data bus. Clock pulses for its latching functions are from the 3 to 8 line decoder (the 74LS138) whose inputs are from the control bus of the parallel port. The bits 1 and 2 of the control bus are hardware inverted and so are passed through a NOT gate to normalize the signal to its true level. Bit 0 of the control port goes straight to the decoder because it is not hardware inverted. The true binary information written to it is what appears at the output. The NOT function was derived with the quad NAND gate chip (the 74LS00) because of its flexibility. That is, other desired gates can be derived from the NAND gate. The NAND gate becomes a NOT gate when its two inputs are linked up. When this is done, the output becomes the inverse of the input. Three bits of control information are required by the decoder. With the help of the decoder, the problem of limited number of control output bits was solved. The decoder gave eight different control outputs from its three bits input. Latching involves the presentation of the data or address information and the appropriate clock pulse to the latch to hold the value. Input to the computer system is through the status port of the parallel port. The status port is the only input port of the parallel port and has only five physical pins. The five physical pins corresponds to the bits 2 to 7 of the software register for the status port. In this design, input to the parallel port was done nibble by nibble. Only bits 2 to 6 are used, though all five bits are read in, the most significant bit is neglected. Software manipulations on the two nibbles give the true byte written out by the 27C64 EPROM. The manipulation is done by shifting the lower nibble two steps to the right and the upper nibble two steps to the right also.

64 Assuming the 8 bit value 1 0 0 1 1 0 1 1 is to be read bu the status port, the manipulations are as below When lower nibble is read in the following data will be obtained Lower nibble X01011XX Shifting it two steps to the right The precise nibble is obtained by ANDing with This result in X01011 1111 1011

The upper nibble is handled differently. The data obtained for the upper nibble is X01001XX The data obtained is put through the same process the lower nibble went through to give the value 1 0 0 1. This is now given the right positioning by shifting it four steps to the left. The resulting value is then ORed with the lower order nibble to give the real data value. Shifting 1 0 0 1 four steps to the left gives 1 0 0 1 0 0 0 0 When ORed with 1 0 1 1 we have 1 0 0 1 0 0 0 0 OR 1 0 1 1 = 1 0 0 1 1 0 1 1 The result is therefore equal to the real data. With the quad 2 input multiplexer, it was possible to read the 8 bit data nibble by nibble. When the select input which is controlled by the third bit of the control port (C3) is made low, the lower nibble from the buffer is linked to the status port input (S2 to S6). Also, when the select input is made high, the higher order nibble from the buffer is made available on the output path to the status port.

4.2

SOFTWARE CONTROLS The circuit is an implementation of the hardware for the EPROM programmer. It cannot program, read or even do anything without some software control and its co-operation with the software. The software acts as the controller. It tells the circuit what function to perform and checks for the expected response from the circuit by reading the value returned to it.

65 All controls for setting up the EPROM chip in the various modes it can be could not be accomplished using the control port despite the fact that a decoder was used to achieve more control lines. The problem with the decoders output is that the control outputs are not independent. That is, for one control line to be active, the others has to be inactive. The unused bits of the upper address byte was used as to implement more control lines for the circuit. The EPROM has 13 address bits, the first 8 bits are latched onto Latch1 as shown in the circuit diagram. The second latch only holds 5 bits of address and has three free bits. This allows for a 3-bit control information to be concatenated with the 5-bit address information to give an 8-bit value of address and control information. In the circuitry, the first five bits output of latch2 were connected to the topmost five address bits of the EPROM while the remaining three bits from the latch goes to the input of their respective controlled units. The controls used in this design and their functions are listed below; The first group of controls are the first three bits of the control port. These are used for the latching process.

S0 S1 S2 0 0 0

FUNCTION This enables the first output bit of the decoder which clocks latch1 to latch onto the data contained on the data register of the parallel port to form the least significant byte of the address information. The 74374 latch is used. The clock signal was sent through a NOT gate which inverts the low output from the decoder to a high. This causes a positive rising voltage for the latchs clock input SOFTWARE ROUTINE:

1. Write data to data port 2. Delay 3. Write X001 to control port. 3. Delay

66

This enables the second output bit of the decoder which clocks the second latch (latch2) through a NOT gate to latch onto the data contained on the data register of the parallel port. The data latched forms the most significant 5 bits of the address information and 3 concatenated control information. SOFTWARE ROUTINE

1. Write data to the data port. 2. Delay 3. Write X001 to the control port 4. Delay

This enables the third output bit of the decoder which clocks the third latch (latch3) to latch onto the data contained on the data register of the parallel port. This latch holds the data to be written onto the 2764. Here, the data to be burnt onto the address location already contained on latch 1 and latch 2 is written onto the parallel ports data registers and is captured by the data latch.

SOFTWARE ROUTINE

1. Write data to the data port. 2. Delay 3. Write X011 to the control port 4. Delay

This bit acts as a software-controlled programming strobe to the PGM input of the EPROM. The software provides the timing requirement for the

67 programming pulse. The programming pulse is introduced after the data and the destination address has been latched onto the EPROMs bus. A software procedure provides the 0.5Ms programming pulse. Table 4.1: C0, C1, & C2 control signals and their functions Another control bit from the computer system to the circuit is the fourth bit of the control port (C3). This is used to control the output of the quad 2-input multiplexer. It is used to determine which nibble input to the multiplexer is to be read by the status port.

C3 0 1

Multiplexer output D0, D1, D2, D3 D4, D5, D6, D7

Table 4.2: The C3 Control signal multiplexer data enabled The next controls are those obtained from higher order address latch. Address bit A13 is used to set up a TTL level for the switching of the opamp that handles the 13V supply for the programming mode. The TTL level causes a significant difference between the inverting and non-inverting inputs of the opamp configured as an infinite gain comparator. The voltage supply for the opamp is 15V, this happens to be the output voltage when its non-inverting input becomes greater than the reference voltage at the inverting input. This output drives the variable voltage regulator (LM317) to give the expected programming voltage level (13V). Address bit A14 functions just like A13 discussed above. It is used to switch on the circuitry that provides the 12V voltage level on pin A9 on the EPROM for the chips identity. Finally, the last control is the address bit A15 which is used to avoid bus conflict between the data latch and the EPROM. The original and inverted level of this control bit is

68 generated. These two versions of the control bit are connected to the output enable (one to each) of the data latch and the EPROM. When one is enabled, the other is disable. By so doing, conflict on the data bus is eliminated. Diodes were used in the circuit to avoid having a short circuit at junction of two voltage levels. This is seen in the situation where a pin takes up a voltage level for a given mode and another voltage level for another mode. Such is seen in the case of pin A9 on the EPROM chip. Pin A9 is expected to have a normal TTL voltage level but it requires an unusual voltage level (12V) for the chip identification mode. The TTL and the 12V voltage level are from different sources but ends up at the same point. The build up and cancellation (short) of both voltage levels are eliminated by the use of two forward biased diodes. This can be observed in the circuit diagram.

4.3

HARDWARE CONTROL SUMMARY The entire hardware control for the implementation of the different modes of operation are given below Mode Chip Identification Control and function A13 is set to TTL logic 0, this makes Vpp = 5V 011 input to the decoder gives the PGM TTL logic 1 via output D3 A15 is set to TTL logic 1 which when inverted enables the OE of the EPROM A14 is set to TTL logic 1- this switches the 12V voltage level to A9 of the EPROM Read A13 is set to TTL logic 0, this makes Vpp = 5V 011 input to the decoder gives the PGM TTL logic 1 via output D3

69

A15 is set to TTL logic 1 which when inverted enables the OE of the EPROM Program A13 is set to TTL logic 1, this makes Vpp = 13V A15 is set to TTL logic 0 which when inverted disables the output of the EPROM 011 input to the decoder gives the programming pulse at the PGM for 0.5mS. Verify A13 is set to TTL logic 1, this makes Vpp = 13V 011 input to the decoder gives the PGM TTL logic 1 via output D3 A15 is set to TTL logic 1 which when inverted enables the OE of the EPROM Table 4.3: Summary of the hardware control sequence

4.4

SOFTWARE SUBSYSTEM

The two most important concepts in the object-oriented programming are the class and the object. Put simply, an object is a thing, both tangible and intangible, that we can imagine. A program written in object-oriented style will consist of objects interacting with each other. An object consist of data an operations that manipulate this data. A class provides the definition needed to create an object. A class is a kind of template that dictates what an object can do and what it cannot. Different objects interact with each other by sending messages. For the object which is the recipient of this message, to process this message, it must be programmed to do so. This programmed implementation is called a method. A method is a sequence of instructions that a class or an object must follow in order to perform a task. The concepts discussed above were used in implementing our software subsystem.

70

4.5

CLASSES IN OUR SOFTWARE

The Unified Modeling Language is a standardized way of providing graphical notations that can be used to model computer systems developed using object-oriented software engineering (OOSE). In OOSE, objects are defined to represent these elements during the system analysis and design process. UML diagrams allow software engineers to indicate the relationships among the objects used to define the system. Most of these objects will need to be implemented using software in the final system. UML is particularly useful when the plan is to implement the system in an object oriented language like Java. In implementing this software, we had to break our implementation down to three classes. These classes had the functionality of reading from the EPROM chip, writing this read data in a file, and also writing to the EPROM chip. These classes were; 1. Address Class. 2. Programmer Class. 3. MainProgrammer Class. UML class diagrams are used to create logical models of computer-based system. A class diagram shows the class structure and contents. It basically contains the class name, its associated data members and methods within the class. The UML class diagrams for these three main classes are explained below.

4.5.1

The Address Class This class basically was used to handle all the addressing needs of our system. The address formatting and manipulations needed were all handled by this class. The segmentation of addresses into the upper and lower order byte and the systems control based on the start and end addresses are examples of the functions carried out by this class. The class diagram of this class is given below.

71

Figure 4.1: Class diagram for the Address class There is no way we could have over emphasized the functions carried out by this class. First of all our memory is a device which has several locations and these locations are uniquely addressable. These addresses were required in order to either read from a location or write to a location in this memory chip. This class had the duty of breaking our specified address into lower order address byte and the higher order address byte. This was necessary because our data port on the parallel port could only handle a byte of data at a time. Thus our 13 bit address had to be broken down into 2 bytes of 8 bit each. The first 8 bit sent to the data bus made up the lower order address bit while the subsequent 8 bit constituted the higher order address bit. The higher order address byte had only it first 5 bit actually used for our addressing needs. The remaining bits were used for implement control functions.

4.5.2 The Programmer Class The next class we worked with was the programmer class. This class was responsible for handling the logic required for communication to be successful between the circuit

72 hardware and the software. If this did not happen, then the objective of our project would have been defeated. The class diagram of this class is given below.

Figure 4.2: Class diagram for the Programmer class

73 This class handled the process of reading from the chip and also writing to it. A prominent method implemented by this class was the initialize method which handles the process of checking the status of the board before any process could be carried out. This was essential as it

4.5.3

The mainProgrammer Class

This was the main class for our programmer. This class had one method, the main method. This method was in charge of coordinating the object to object interaction that went on between the different classes. This object to object interaction is what gave our software its functionality. The mainProgrammer class is the main class and without the main class, our software wouldnt work. This is true because when the software is ran, execution starts from the main class. The class diagram of the mainProgrammer class with its instance data values and associated methods is shown below;

74

Figure 4.3: Class diagram of the mainProgrammer class

75 4.6 HARDWARE AND SOFTWARE INTEGRATION In order for the EPROM programmer to become functional, the developed software and the designed hardware had to work hand in hand with each other. Neither of the hardware or software could function as a standalone system. Their functionalities were independent of each other. The parallel port acted as the entry point between the circuitry and the software. As explained in the previous sections, the software sent address locations, data values and control codes to the circuitry through the parallel port and also gets response from the circuitry through the parallel port. The overall operation of the EPROM programmer (that is the hardware and software integrated system) is given in the following sub-section. It has three main processes.

When the software is first executed, it declares the parameters for the graphical user interface as well as that for the variables. This is essential because it is what enhances the user interactivity with the system. This is a basic process in every software or computer program.

4.6.1

The Initialization Process

After the declaration of the necessary parameters and variables, the initialization process begins. The initialization process is a series of events that ensures that the program is up and running and that the circuitry is connected and meets the requirements for the read and write process to commence. In this process, the software tests for the presence of power on the board using the checkPower method. If there is no power on the board the user is informed about it and the program halts. Else, if power was detected on the board, the initialization process continues to the next phase. The next phase of the initialization process is to check if the right chip has been inserted into the provided socket on the board. This is done by the manufacturersId and chipIdentification methods. Manufacturers identity is needed because different manufacturers have different identifying codes for every EPROM chip. The detection of the inserted chip is so as to know which programming algorithm that is to be used on the chip. Chip identity basically tells the capacity of the chip. So, the program continues only if the right chip with the one

76 out of the few expected identification code the programmer is capable of handling was inserted. The initialization process if successful presents three options to the user. The user can either choose to read data from the chip, write data onto the chip or end the program execution. If the cancel option is selected, the program execution will be terminated else, the chip would be read or written to.

4.6.2

The Read Process

The read process works with various methods to read data off an EPROM chip from the specified address locations. The user specifies the address range to be read and the file in which the read data should be stored. The main method for the read process is the readFromProgrammer which makes use of some other methods for successful write operation. It makes great use of most methods in the address class such as the getLowerAddressByte, getUpperAddressByte, getAddressInteger and the

addressProcessor methods. After getting the users response, an output file is created and data is read from the chip address by address until the final address is read. The data values read and the corresponding addresses are stored in the created file. The actual program for this process is contained in Appendix D. A typical output read from the EPROM chip can be found in Appendix D.

4.6.3

The Write Process

This process begins immediately after the user clicks on the button for write from the given options. The user is then prompted by the software to select the file he will be writing to the chip. The selected file contains the hex codes which are written to the chip one byte at a time until the end of the file is reached. After every write operation comes the verify operation which is actually hidden from the user. All this were achieved by the write process because a number of methods played their various roles. For instance, the addressWriter method was used to handle all the addressing needs of this process. Most the especially the dataWriter method was used to write the specified data to the data port

77 of the parallel port. For complete source codes of this process, refer to Appendix D while the flow chart representation of the entire process can be found in Appendix C.

The complexity of the entire system was hidden from the user by hiding it under the simplicity of the software.

78 CHAPTER FIVE

COST ANALYSIS AND PROJECT APPRAISAL

5.1

COST OF SYSTEM DEVELOPMENT

This project on the EPROM programmer may seem to be of a very fair cost when the final circuit diagram is analyzed. But, though the final circuitry may seem to be cheap, it does not imply that the project was of a fair cost. The project really costed much both financially, mentally, time-wise cost and lots more. But any which way, it was worth the effort and the sacrifices. Research costed most both in terms of finances involved and the mental tasks. Miscellaneous costs are also of great significance. The costs in terms of finances are as listed on the table below and are not the exact cost but approximate cost of the project.

Description 27C64(EPROM) x 10 74HCT374 X 8 74HCT257 X 4 Verro-board x 2 Bread board x 2 Soldering Iron & lead x2 IC sockets x 20 Resistors x 40 Parallel port cable x 2 Connectors Voltage regulators (7805, -06, -12, -15) Variable voltage regulator (LM317) x 3 Op-amp (LM741) x 5

Amount 2,500 680 240 200 1,000 600 400 200 1,000 200 400 150 200

79 Variable resistors Wire stripper 74LS244 74138 7400 Research Miscellaneous Total 200 350 400 200 200 7,000 8,000 24,120

The table above is basically for hardware design implementation and a little of software. Software cost may be mistakenly assumed to be fair, but the bulk of the time spent on the project was on software development, debugging and troubleshooting. From the table above, approximately twenty five thousand naira was spent in the quest for the realization of the project. It was really worth the cost because a great deal of experience which we ordinarily wouldnt have gotten was achieved and a great problem which posed to be a great challenge to digital systems design in Nigeria was solved.

5.2

LIMITATIONS AND DIFFICULTIES

During the course of this project, difficulties were encountered and they were honestly accepted as challenges. These challenges aroused our creative instinct and most of the problems encountered were resolved and some others werent due to time constraint. The very first limitation encountered was on interfacing. Most successes on interfacing were only on windows 98 and lower versions of operating systems. It seemed to be impossible to carry out computer interfacing without some application specific resources and devices. But, some weeks of research cracked the hard shell. This was made possible by the discovery of a package in Java programming language and a DLL system file. The pport package was used to crack the parallel port interface for interfacing using windows NT (that is windows 2000 and windows Xp). The jnpou32.dll was the direct library link that aided in the control of the parallel port. The documentation of the package and the jnpout32.dll system file can be found in Appendix C.

80

Another limitation we had was knowledge based. We had little or no knowledge of the programming language we desired to use. This was a great motivation and enabled us launch into the Java programming language deep enough to develop the software part of the programmer.

It was really difficult combining our school work with the project research process and development. The weather/climatic conditions werent encouraging and they

consequently had a terrible effect on our schedule as some basic amenities such as power supply which was a very vital need for construction, simulation and test-running was poor. There were situations in which we were handicapped for a week and some for close to a week due to power failure. This influenced the timing and the extent reached in our research but still yet it was a success. The aim of the project was achieved.

5.3

PROJECT EVALUATION

The end product of the project is in real consonance with the objective of the project which was to design and implement an EPROM programmer. The device built functions perfectly and can perform both the read and the write functions effectively. With the device, some EPROM chip contents were copied and the outputs were held in a file. Concerning the write function, the device functioned flawlessly and as a test program, the control sequence for a three-way traffic light system was written into the chip. The chip was then used to implement the three-way traffic light system which functioned well. The circuitry for the implementation of a three-way traffic light system would ordinarily be so big and complicated. But, with the use of the EPROM, only a clock generator and a latch was needed along with the EPROM chip to implement a traffic light system which ordinarily would have costed close to a hundred thousand naira. The EPROM programmer functioned at some good speed, performed the required functions and really proved its worth of the time and resources put in place for its implementation.

81 5.4 SUGGESTIONS FOR FURTHER WORK This project was implemented simple concepts and common tools. It is amazing how some components such as the latches, tri-state buffer, decoders, multiplexers and some other components a mere designer fiddles with are interconnected and controlled to give an EPROM programmer. Further development on this work could be by: 1- Implementation of the whole circuitry using an FPGA chip 2- The use of the Universal Serial Bus (USB) interface on the computer as the interfacing technique. 3- The implementation of a more complex system to program a series of the EPROM chip

82 REFERENCES

Nagrath, I.J. (2001), Electronics: Analog and Digital. New delhi-110001, India, PrenticeHall.

Balch, M (2003), Complete Digital Design: A Comprehensive Guide to Digital Electronics and Computer System Architecture. New york, McGraw-Hill.

Richard S. et al (1998), Systems Engineering Coping with Complexities. London, Prentice Hall Europe

Odigboh, E.U., Osuagwu, C.C. (2003), Effective Communication of Technical Ideas in Scince and Engineering. Nsukka, University of Nigeria Press.

Milind S.P. (1993), How Computers Really Work. Berkeley, Osborne McGrawHill.

FairChild Semiconductor: DM74LS138 Datasheet

ST Microelectronics: 27C64 Datasheet.

Philips Semiconductor: 74HCT257 Datasheet

83 Philips Semiconductor: 74F374 Datasheet

FairChild Semiconductor: DM74LS244 Datasheet

Parallel port interfacing made easy: http://www.epanorama.net/circuits/parallel_output.html

Printer Port interfacing 1: http://www.programmershelp.co.uk/printerport1.php

Parallel Port Explained : http://www.bb-elec.com/tech_articles/parallel_port_explained.asp

Interfacing the Standard Parallel Port : http://www.beyondlogic.org/spp/parallel.htm

How Inpout32.dll works : http://www.logix4u.net/inpout32.htm

84 Appendix A Circuit Diagram

85 Appendix B Datasheets Used

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101 Appendix C Device Flow Chart

102

103

Appendix D Source Code


The Programmer Class
/* * Programmer.java * * Created on 17 May 2006, 12:42 */ /** * * @author VIC */ import parport.ParallelPort; import javax.swing.*; import java.io.*; import java.util.*; public class Programmer { /** Creates a new instance of Programmer */ public Programmer() { } ParallelPort lpt1 = new ParallelPort(0x378); // FileOutputStream gh = new FileOutputStream("bullshit"); int startstate; int d0 ;//LSB of data read in from the status port during initialization //used to determine the initial state of the flip flop used to initiate the chip id mode int d1 ;//second bit of data read in from the status port during initialization used to //determine the initial state of the flip flop used to disable the output of the data latch in order to prermit //a read form the programmer int powerStatus ; int lowerNibble, lowerNibbleOne, lowerNibbleTwo; int upperNibble, upperNibbleOne, upperNibbleTwo; //int dataByte; int chipId; // int startAddress; //int endAddress; int lowerAddressByte; int upperAddressByte; boolean error = true; int manufacturersIdentifier , chipIdentifier; String[] dataArray; int arraySize;

104
public void initialize(MainProgrammer myEprom2){//my eprom2 is used to hold the jframe object passed to the routine from the main prog

int dataByte = checkPower();// determine the value of dataByte. for initialization, the value should be 1. i.e. the programmer is connected if(dataByte == 1){//this is to check if the device is connected or if the power is on System.out.println("the device is connected");// this routine is unable to detect when the device is not powered cos the //port powers the device enough to deceive the routine //its operation is somewhat unpredictable cos the power the programmer derives from the parallel port isnt much manufacturersIdentifier = manufacturersId();//to read the manufacturers id manufacturersIdentifier = manufacturersId();//immediately the device is turned on, //the first manufac id is usually erroneous or rather unpredictable

if(manufacturersIdentifier == 155){//to identify the chip and get the chip id. //the double identification was necessasry as it was seen that the same 2764 chips //from different manufacturers had different chip identifiers, thus in order to fully identify any chip, it //was necessasry to get the manu id as well as the chip id JOptionPane.showMessageDialog(myEprom2 ,"st chip with manuf id " + manufacturersIdentifier); myEprom2.setManufacturersId(manufacturersIdentifier);//calling an accessor designated for gui purposes //although not yet fully developed chipIdentifier = chipIdentification();//identify the chip System.out.println("the chip id is" +chipIdentifier); int i =0; do { // detect a max of 10 errors and then zap i++; JOptionPane.showMessageDialog(myEprom2, " hey!!!!! please insert the chip");//place holder for elaborate GUI feature if (i > 10){

JOptionPane.showMessageDialog(myEprom2, " ERROR");

105
System.exit(1);

} chipIdentifier = chipIdentification(); } while(chipIdentifier != 8 ); myEprom2.setChipId(chipIdentifier );// another accessor for gui not yet fully devd error = false;// used to determine if the the third if i.e. IF(ERROR)....below is valid myEprom2.setProceedStatus();// another accessor }

if(manufacturersIdentifier == 143){// all the gist here is the same as above ...... JOptionPane.showMessageDialog(myEprom2 ,"national chip with manufacturers id " +manufacturersIdentifier); myEprom2.setManufacturersId(manufacturersIdentifier); chipIdentifier = chipIdentification(); System.out.println("the chip id is" +chipIdentifier); int j =0; do{ j++; JOptionPane.showMessageDialog(myEprom2, " hey!!!!! please insert the chip");//place holder for elaborate GUI feature if (j > 10){ JOptionPane.showMessageDialog(myEprom2, " ERROR"); System.exit(1);

} chipIdentifier = chipIdentification(); } while(chipIdentifier != 194 ); myEprom2.setChipId(chipIdentifier ); error = false; myEprom2.setProceedStatus(); }

if(error){

106
JOptionPane.showMessageDialog(myEprom2, " mumu please insert the chip from default"); JOptionPane.showMessageDialog(myEprom2, " CHICKEN HEAD!!!!!!!"); // myEprom2.reSetProceedStatus(); System.exit(1);

} }

else{// FOR WHEN THE DEVICE IS NOT CONNECTED System.out.println("the device is NOT connected"); System.out.println("the dataByte read when it is not connected is = " +dataByte); myEprom2.reSetProceedStatus(); }

} public void identifier(int dataByte){

} public int manufacturersId(){ /*this method is used to read the manufacturers identifier from the chip *this was necessasry as we observed that the different chips not only had different chip id's *, they also had different manufacturer id's. the logic employed in this method is similar to that *for the chip id hence explicit details on how the method works is outlined on the chip id method body * */ addressWriter(0, 192); //set address requirements for manuf id i.e A0 - A12 = 0 // i'm still considering the possibility of using the possibility of sing A1 i.e. bit 5 on latch 2 for // setting the programming mode! however a pitfall to be weary of is its interaction with the control sequences of the others // as examplified in the command preceeding this gist!

107
lpt1.writeOneByte(0x37a,2);// initializing D3....reason more explicitly stated in chipId method lowerNibble = lpt1.read(); lpt1.writeOneByte(0x37a,10);// i.e. set control 1010...read upper nibble upperNibble = lpt1.read(); int manufacturersIdentifier = nibbleProcessor(); return manufacturersIdentifier; }

public int chipIdentification(){ addressWriter(1, 192); /*although addressWriter(1,0) may seem like a better the chip id routine specifies that the address on the *address bus of the 2764 be 000(A9)000000001 during writing 64 to L#2 still acchieves this and sets the control * signal for chipid as well because 192 = 11000000; diaables the o/p of the L#2. */

command as chip id, id it also

lpt1.writeOneByte(0x37a,2);//this is used to ensure that the lower nibble can be read i.e. //D3 on the control port = 0; using 2 here, induces latching on L3 which may be seen as a disadvantage // but it is of no consequence as L3`s o/p is disabled. the gain is the independence this line grants this routine, // as the latching control can be initialized to a known value rather than whatever value any preceeding //routine leaves it at. lowerNibble = lpt1.read(); lpt1.writeOneByte(0x37a,10);// i.e. set control 1010...read upper nibble upperNibble = lpt1.read(); int chipIdentifier = nibbleProcessor(); return chipIdentifier;

public int checkPower(){//this routine handles the logic that determines if the device is conected. /*its operation is based on the fact that the data latch will only hold the data written onto it *if it is powered. hence to check for power, data is written to the data latch and thn the data is read

108
*by the program. if the values are the same then the device is powered. */ //dataByte = 0;// just initializing

lpt1.write(1);// this places00000001 on the data port lpt1.writeOneByte(0x37a , 0);//this is used in combination with the next line of code //to latch the data onto the data latch i.e. L#3. the combo is necessasry cos the latches are //pos edge triggered(though they were rigged to be that way) lpt1.writeOneByte(0x37a , 2);// this latches the data on the data port onto l#3. lpt1.writeOneByte(0x37a , 1);//this is here to write 00000001 to D#2. the most sig //3 bits of the data held on D#2 are control lines . // i.e A15 = 1....enable o/p of 2764 and disable o/p of L#3 // A15 = 0....do oposite. // A14 = 1.... do chip id // A14 = 0.... opposite. //hence writing 00000001 to l#2 acchieves the desired goal as it is needed to set the //programmer to disable the o/p of the 2764. // delay(); lowerNibble = lpt1.read();// the lowr nibble of the data available to the 257 //is selected and passed to the status port by using D3 on the control port //i.i D3 = 0 ; lower nibble sel // D3 = 1 ; upperNibble sel. //by default, this command then reads the lower nibble of the data available to //the 257 as the last nibble written on the previous line of code dictates. lpt1.writeOneByte(0x37a, 9);// this sets D3 on the control port to 1 i.e //the ctrl port has 1001 so as well as settn D3 to 1, it doesnt induce anymore latching //delay(); upperNibble = lpt1.read(); int powerStatus = nibbleProcessor(); System.out.println("the dataByte from check power method is = " +powerStatus); return powerStatus; } private int nibbleProcessor(){ lowerNibble = lowerNibble >> 3;//register shift operation, 3 bits to the left. lowerNibble = lowerNibble & 15;// to eliminate the MSB.

109
upperNibble = upperNibble >> 3;//register shift operation, 3 bits to the left. upperNibble = upperNibble & 15;// to eliminate the MSB. upperNibble = upperNibble << 4;// reg shift op, 4 bits to the left, to retain its number value i.e. most sig nibble int data = upperNibble | lowerNibble; System.out.println("the data from nibble processor byte is = " +data); return data; } public void writeToProgrammer(String address, int data){//method handles any write operation to the programmer //for a write to the programmer, it is important to disable the o/p of the 2764 and enable L#3 also disable chipid. int addressLSB , addressMSB; Address location = new Address(); location.addressProcessor(address); addressLSB = location.getLowerAddressByte(); addressMSB = location.getUppperAddressByte(); addressMSB = addressMSB | 32;// this is done to include the control bits to l#2. //i.e. 32 = 00100000. since all but the msb are 0, ORING with the address info doesnt alter it //but just includes control to disable the o/p of the 2764, disable chip id mode and enable program mode // i.e. Vpp = +13v;

addressWriter(addressLSB, addressMSB);// select address and set device to program mode try{ Thread.sleep(1);//1 millisecond sleep..worst worst case timing scenario!!!!!!!! } catch(InterruptedException b){ System.out.println("yawa!");};// this should handle the propagation delay for the 138 // as well as the propagation delay times for the 74374 dataWriter(data);//send specified data to the data bus try{ Thread.sleep(1);//1 millisecond sleep..worst worst case timing scenario!!!!!!!! } catch(InterruptedException b){ System.out.println("yawa!");};// this should handle the propagation delay for the 138 // as well as the propagation delay times for the 74374

110
lpt1.writeOneByte(0x37a, 4);//just initialization to make sure that the next command is valid //i.e. there is a high to low transition. from the cct diagram Y4 on the 138 is unconnected so //we can get away with this.. lpt1.writeOneByte(0x37a, 3);// set the programmer to write mode. write mode disables the output of the 2764 try{ Thread.sleep(1);//1 millisecond programming pulse...i.e. from programming algorithm } catch(InterruptedException b){ System.out.println("yawa!"); } lpt1.writeOneByte(0x37a, 4);//i.e. high to low to high // just provided the 1 millisecond programming pulse. try{ Thread.sleep(1);//1 millisecond sleep..worst worst case timing scenario!!!!!!!! } catch(InterruptedException b){ System.out.println("yawa!");};// this should handle the propagation delay for the 138 boolean proceedStatus = verify(addressMSB , data);// true if the data is positively verified and false otherwise if(!proceedStatus){ JOptionPane.showMessageDialog(null, "PROGRAMMING ERROR, PLEASE CHECK THE CHIP"); System.exit(1); }

public void addressWriter(int lowAddress, int highAddress){ // low address refers to the address latched onto address latch 1 //high address refers to the address latched onto address latch 2 /* the latch enable pin on the 74374 is an active high pin.the address and data latches * latch onto the data at their inputs when the 138's outputs translate from the control code mapped to them to the next higher code however, in order to modularize this routine, it is necessasry to prevent the latching from occuring as the control code translates to the next higher position as when the ddata latch is involved, the next higher position

111
forces the chip to be programmed i.e. PROGRAMMING MODE whether it is desired or not consequently, in order to prevent this problem, the latch enable pins of all the latches are inverted in order to acchieve the latching in the transition to their respective control codes rather than on their *respective subsequent control codes. */ lpt1.writeOneByte(0x37a, 1);//to initialise the 138 to start from 10111111. necessasry cos the latches are positive //edge triggered hence due to the hardware inversion,in order to latch onto the LS address byte the //transition to 01111111 can only take place after the address is valid

lpt1.write(lowAddress); // write the LSByte of address information to the data port. System.out.println("Output to address latch1: " + lowAddress);

lpt1.writeOneByte(0x37a, 0);// to latch onto the least significant byte of address info. 138 has 01111111 try{ Thread.sleep(1);//1 millisecond sleep..worst worst case timing scenario!!!!!!!! } catch(InterruptedException b){ System.out.println("yawa!");};// this should handle the propagation delay for the 138 // as well as the propagation delay times for the 74374

lpt1.write(highAddress); // write the remaining 5bits of address information onto address latch2 System.out.println("Output to address latch2: " + highAddress); //delay(); lpt1.writeOneByte(0x37a, 1);// to latch onto the MSbyte of address info. 138 has 10111111 try{ Thread.sleep(1);//1 millisecond sleep..worst worst case timing scenario!!!!!!!! } catch(InterruptedException b){ System.out.println("yawa!");};// this should handle the propagation delay for the 138 // as well as the propagation delay times for the 74374

112
} public void dataWriter(int data){ lpt1.write(data); // write a byte to the port's DATA pi lpt1.writeOneByte(0x37a, 2);//latch data onto L2 System.out.println("Output to data port: " + data); }

public boolean verify(int addressMsb, int dataForVerification){ //verification involves a read operation while the chip is still partly in programming mode //when this function is caalled,the address to be read from is the last one written to so //the address present on the latches is still valid hence te control bits as well are. however, //the data is to be read from the EPROM and not the data latch hence the output from the data latch needs to be disabled // while that from the 2764 is enabled. addressMsb = addressMsb | 160;// this is done to include the the control bit that enables the o/p of the //2464, disables the o/p of the data latch and leaves Vpp at 13v lpt1.write(addressMsb);// write this to the // ports data port lpt1.writeOneByte(0x37a, 1);// latch the data on the data port onto address latch #2 // at this point, the device is set to the the verify mode and after the accompanying delay, //the data at the o/p can then be read try{ Thread.sleep(1);//1 millisecond sleep..worst worst case timing scenario!!!!!!!! } catch(InterruptedException b){ System.out.println("yawa!");};// this should handle the propagation delay for the 138 // as well as the propagation delay times for the 74374

lowerNibble = lpt1.read();//read lower nibble lpt1.writeOneByte(0x37a, 13 );//enable upper nibble try{ Thread.sleep(1);//1 millisecond sleep..worst worst case timing scenario!!!!!!!! } catch(InterruptedException b){ System.out.println("yawa!");};// this should handle the propagation delay for the 138 // as well as the propagation delay times for the 74374

113
upperNibble = lpt1.read();//read upper nibble int verifiedData = nibbleProcessor(); //System.out.println("the verified data is = " +verifiedData); boolean proceedStat; if(verifiedData == dataForVerification){ proceedStat = true; } else proceedStat = false; return proceedStat;

public void readFromProgrammer(String startAddress, String endAddress){ // startAddress and endAddress are string variables used to hold the desired start and stop locations of thr read op Address myAddress = new Address(); /*declares a new Address object. the class has accessors and mutators as listed below as well as their functions. the class data types are also outlined. * *mutator : addressProcessor : *this method accepts a hexadecimal string representing an addres location and performs the following functions: * 1. converts the string to binary * 2. gets the integer rep of the address string and stores it in Instance var addressInteger * 3. it breaks up the binary string into the upperByte and lowerByte and stores them in their respectively * named Instance variables * *accessor : getLowerAddressByte, getUpperAddressByte, getAddressInteger * *they return the values of the instance variables referred to by their names. */ myAddress.addressProcessor(startAddress);// processes the address string as previously described lowerAddressByte = myAddress.getLowerAddressByte(); upperAddressByte = myAddress.getUppperAddressByte(); int startAddressInt = myAddress.getAddressInteger(); startAddressInt = startAddressInt & 8191;//to remove the effect of the "ORING" in the address class

114
myAddress.saveStartAddressIntegerForFileProcessor( startAddressInt);// in handling the file processing, it is necessasry to //determine the exact length of the data to be read into the file cos an array(the size of the array needs to be declared) is used to hold the data before it is written onto the //file. i.e. the start address int minus the end address int gives an indication of how long the file should be //JOptionPane.showMessageDialog(null,"saved start address successfuly");

upperAddressByte = upperAddressByte | 128; //this is used to add the control bits // i.e. disable the chip id and the o/p of l#3.

//System.out.println("startadd " +startAddressInt); myAddress.addressProcessor(endAddress); int endAddressInt = myAddress.getAddressInteger(); endAddressInt = endAddressInt & 8191;//to remove the effect of the "ORING" in the address class myAddress.saveEndAddressIntegerForFileProcessor(endAddressInt); //JOptionPane.showMessageDialog(null,"saved end address successfuly"); arraySize = myAddress.setArraySizeAddressByte();//to return the size of the array dataArray = new String [getArraySizeAddressByte()];//declare an array with size of the expected file int m =0;//counter used for the array int n = 1;

//JOptionPane.showMessageDialog(null,"made it through the arrays " +getArraySizeAddressByte());

for(startAddressInt = startAddressInt; startAddressInt <= endAddressInt;){

addressWriter(lowerAddressByte , upperAddressByte); startAddressInt = startAddressInt + 1; // System.out.println("startadd plus1 +startAddressInt); "

myAddress.addressProcessor(Integer.toHexString(startAddressInt));

115
lowerAddressByte = myAddress.getLowerAddressByte(); upperAddressByte = myAddress.getUppperAddressByte(); startAddressInt = myAddress.getAddressInteger(); startAddressInt = startAddressInt & 8191;//to remove the effect of the "ORING" in the address class upperAddressByte = upperAddressByte | 128; //this is used to add the control bits // i.e. disable the chip id and the o/p of l#3.

if(startAddressInt == 0) break;

// System.out.println("lab" +startAddressInt);

lpt1.writeOneByte(0x37a, 6 );// first, this sets the programmer to read mode. //it is also the control signal to select the lower order nibble of the 257`s input. //this is done by the MSB of the data written to the //control port i.e D3 = 0>> select lower nibble //D3 = 1>> select upper nibble. // this permits the lower nibble to pass thru to the 257 and to the data port try{ Thread.sleep(1);//1 millisecond sleep..worst worst case timing scenario!!!!!!!! } catch(InterruptedException b){ System.out.println("yawa!");}// this should handle the propagation delay for the 138 // as well as the propagation delay times for the 74374

lowerNibble = lpt1.read();//read lower nibble //delay();

lpt1.writeOneByte(0x37a, 14 );//enable upper nibble try{ Thread.sleep(1);//1 millisecond sleep..worst worst case timing scenario!!!!!!!! } catch(InterruptedException b){ System.out.println("yawa!");}

upperNibble = lpt1.read();//read upper nibble

116
//delay(); int inputData = nibbleProcessor(); System.out.println("inputdata= " +inputData); //startAddress = startAddress + 1 ;

dataArray[m] = Integer.toHexString(inputData);// populate the cells of the array with the data read from the chip m = m + 2;//data stored in the even array cells dataArray[n] = Integer.toHexString(startAddressInt); n = n + 2;//addresses stored in the odd address cells

} } public String[] getArray(){//this retusns the array to its caller. in this case its caller is the main programmer. return dataArray; } public int getArraySizeAddressByte(){ return arraySize; } public void delay() throws InterruptedException {//this method is used to implememnt delays Thread.sleep(1);//1 millisecond sleep..worst worst case timing scenario!!!!! }

public void test(){ try{ Thread.sleep(1); } catch(InterruptedException b){};

// setFlops(0 , 0); //System.out.println("d1 = " +determine_d1()); // // lpt1.writeOneByte(0x37a , 4);// enables the status info to be read. //delay(); //delay(); //delay(); // delay(); //lpt1.writeOneByte(0x37a , 4); //System.out.println("d0 = " +determine_d0());

117
// while(1 <2){ // //// // //

lpt1.writeOneByte(0x37a , 7); // delay(); delay(); //delay();

//lpt1.writeOneByte(0x37a , 0); //delay(); //delay(); // delay(); // System.out.println("im working"); // } //lpt1.write( 0); //lpt1.writeOneByte(0x37a , 0); //lpt1.writeOneByte(0x37a,1);

/* chipIdentification(); System.out.println("the chip id is" +dataByte); while(35 != dataByte ){ JOptionPane.showMessageDialog(null, " hey!!!!! please insert the chip");//place holder for elaborate GUI feature chipIdentification();

} **/ //checkPower(); addressWriter(0, 192); //set address requirements for manuf id i.e A0 - A12 = 0 lpt1.writeOneByte(0x37a,2);// initializing D3....reason more explicitly stated in chipId method lowerNibble = lpt1.read(); lpt1.writeOneByte(0x37a,10);// i.e. set control 1010...read upper nibble upperNibble = lpt1.read(); nibbleProcessor();

118

The Address Class


/* * Address.java * * Created on May 26, 2006, 11:08 AM *this class provides the necessasry methods for processing *the hex string addresses specified by the users.it converts them to binary, splits them *into LSB and MSB and also returns the integer rep of the addresses. */ /** * * @author eibuka */ import javax.swing.*;

public class Address { /** Creates a new instance of Address */ public Address() { } int lowerAddressByte; int upperAddressByte; int addressInteger; int startAddress; int endAddress; int arraySize;

public void addressProcessor(String hexAddress){ //PLACE HOLDER FOR INVALID ADDRESS TRAPS

addressInteger = Integer.parseInt(hexAddress, 16);//convert hex string address into decimal integer //System.out.println("address integer class address " +addressInteger ); addressInteger = addressInteger | 8192 ;// done to ensure that the .substring //method can processs data less than 13 bits as the .toBinaryString method //does its conversion leaving no extra lead digits. String binaryAddressString = Integer.toBinaryString(addressInteger);// converts to binary string String lowerByteString = binaryAddressString.substring(6 ,14);//selects the LSB from the address String upperByteString = binaryAddressString.substring(1 ,6);//selects the MSB from the address

119
lowerAddressByte = Integer.parseInt(lowerByteString , 2);// transforms the lower byte of the binary address //string to a decimal integer upperAddressByte = Integer.parseInt(upperByteString , 2);// transforms the upper byte of the binary address //string to a decimal integer }

public int getLowerAddressByte(){//accessors that return what their names refer to.......... return lowerAddressByte; }

public int getUppperAddressByte(){ return upperAddressByte; }

public int getAddressInteger(){ return addressInteger; } public void saveStartAddressIntegerForFileProcessor(int savedStartAddress){ startAddress = savedStartAddress; } public void saveEndAddressIntegerForFileProcessor(int savedEndAddress){ endAddress = savedEndAddress; } public int setArraySizeAddressByte(){ // JOptionPane.showMessageDialog(null,"the end address is " +endAddress); // JOptionPane.showMessageDialog(null,"the start address is " +startAddress);

arraySize = endAddress - startAddress; //JOptionPane.showMessageDialog(null,"the array size is " +arraySize); arraySize = arraySize + 1;// try it ......you`ll see why arraySize = arraySize * 2;// the plan, though uncertain, is to store both address and data from the chip into the file return arraySize; }

120

The MainProgrammer Class


/** * MainProgrammer.java * * Created on July 3, 2006, 4:51 AM */ /** * * @author */

VIC

/*this class is meant to handle the GUI features of the programmer. *it is also the main class of the programmer */ import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.io.*; public class MainProgrammer extends JFrame implements ActionListener { private final int FRAME_WIDTH = 500; private final int FRAME_HEIGHT = 250; private final int FRAME_X_ORIGIN= 300; private final int FRAME_Y_ORIGIN = 100; private final int BUTTON_WIDTH = 75; private final int BUTTON_HEIGHT = 20;

JButton readButton; JButton writeButton; Programmer eprom = new Programmer(); String startAddress, endAddress; String address, fileAddress; int data; int chipId , manufacturersId; boolean proceed = false; Address myAddress = new Address(); boolean fileStatus; FileOutputStream outFileStream; // File outFile; String [] dataArray;

public static void main(String[] args) throws IOException { MainProgrammer myEprom = new MainProgrammer(); MainProgrammer frame = new MainProgrammer(); frame.setVisible(true); Programmer myProgrammer = new Programmer();

121
myProgrammer.initialize(myEprom);//passing a jframe object to the init routine /*the idea is to return multiple values from the initialize routine, *i.e. 1, manufacturers id *2, chip id *3, device connection status **/

if ( myEprom.getProceedStatus()){ JOptionPane.showInputDialog(null,"PROCEED!!!!!"); } else{ frame.setTitle("ERROR MUMU"); JOptionPane.showMessageDialog(frame,"HEY! please check that the device is powered, connected or if the chip is inserted"); System.exit(1); } } public void setChipId( int DataByte){ chipId = DataByte; } public void setManufacturersId( int dAtaByte){ manufacturersId = dAtaByte; } public void setProceedStatus(){ proceed = true; } public int getChipId( int dataByte){ return chipId; } public int getManufacturersId( int dataByte){ return manufacturersId; } public boolean getProceedStatus(){ return proceed; } public void setConnectionStatus(){ } public void reSetProceedStatus(){ proceed = false; } public boolean getReSetProceedStatus(){ return proceed; }

122

public MainProgrammer() { Container contentPane = getContentPane(); setTitle("2764 PROGRAMMER"); setResizable(true); setSize(FRAME_WIDTH, FRAME_HEIGHT); setLocation(FRAME_X_ORIGIN, FRAME_Y_ORIGIN);

contentPane.setLayout(null); contentPane.setBackground(Color.BLACK);

readButton = new JButton("READ"); readButton.setBounds(350, 100, BUTTON_WIDTH, BUTTON_HEIGHT); contentPane.add(readButton);

writeButton = new JButton("WRITE"); writeButton.setBounds(250, 100, BUTTON_WIDTH, BUTTON_HEIGHT); contentPane.add(writeButton);

setDefaultCloseOperation(EXIT_ON_CLOSE);

readButton.addActionListener(this); writeButton.addActionListener(this); }

public void actionPerformed(ActionEvent event){ MainProgrammer window = new MainProgrammer(); JButton clickedButton = (JButton) event.getSource(); if(clickedButton == readButton) { try{ myReadButtonHandler();} catch(IOException e){ System.out.println("jammed an error");} } else{ //myWriteButtonHandler(); } } public void myWriteButtonHandler(){ // all about blank............................................................. }

123
public void myReadButtonHandler() throws IOException{ startAddress = JOptionPane.showInputDialog(null,"please specify the start address in hex"); //prompt the user for the required start address. the address where ther reading starts endAddress = JOptionPane.showInputDialog(null,"please specify the end address in hex"); //prompt the user for the required start address. i.e the last read address fileAddress = JOptionPane.showInputDialog(null,"please specify where the data is to be saved"); //prompt the user for the address in which the data is to be saved File myFile = new File(fileAddress); //create a new file object fileStatus = myFile.createNewFile();// check if the file was created with success if(fileStatus){ JOptionPane.showMessageDialog(null," the file was created successfully at:" +myFile.getAbsolutePath()); } else{ int decision = JOptionPane.showConfirmDialog(null, "the file could not be created, it already exists.OVERWRITE??!"); switch (decision){ case 0 : myFile.delete();//if the user okays overwriting the already existent file, delete it and create a new file myFile.createNewFile(); break; // for case 1, the user may either want to quit or specify another location case 1 : int decision2 = JOptionPane.showConfirmDialog(null, "would you like to select another file!"); switch(decision2){ case 0: fileAddress = JOptionPane.showInputDialog(null,"please specify new location where the data is to be saved"); boolean fileStat = myFile.createNewFile(); if (fileStat){ JOptionPane.showMessageDialog(null," the file was created successfully at:" +myFile.getAbsolutePath()); } else{ JOptionPane.showMessageDialog(null,"just lost ur chance"); System.exit(1); } break;

124
case 1: JOptionPane.showMessageDialog(null,"gaseous ignorant and i'm out!"); System.exit(1); break; default: JOptionPane.showMessageDialog(null,"gaseous ignorant and i'm out!"); System.exit(1); break; } default: System.exit(1); break; } } eprom.readFromProgrammer( startAddress, endAddress); //JOptionPane.showMessageDialog(null,"the size of the array from the main programmer is:" +eprom.getArraySizeAddressByte());

dataArray = new String[eprom.getArraySizeAddressByte()];//declare an array with size of the expected file dataArray = eprom.getArray(); FileOutputStream outStream = new FileOutputStream(myFile); JOptionPane.showMessageDialog(null,"outputstream created with success");

JOptionPane.showMessageDialog(null,"i dey here 0"); PrintWriter myPrintStream = new PrintWriter(outStream); JOptionPane.showMessageDialog(null,"i dey here 1");

for(int p =0; p < eprom.getArraySizeAddressByte(); p = p + 2 ){ String dataForFile = dataArray[p]; myPrintStream.print(" "); myPrintStream.println("data from chip : " +dataForFile);// outStream.println(dataArray[p]); dataForFile = dataArray[p + 1]; myPrintStream.print( "address :"+dataForFile); //System.out.println("i am in the loop"); //System.out.println("data written to the array"+dataArray[p]); } JOptionPane.showMessageDialog(null,"i dey here 2"); myPrintStream.close(); } }

You might also like