Archive for August 13th, 2009

Programming Algorithm for 27HC641 EPROMs

General idea: replacing a failing Mostek MK36000-series masked ROM in a Tektronix 492 Spectrum Analyzer memory board with an equally obsolete 27HC641 EPROM, using the bits found there.

The various datasheets give contradictory advice concerning device programming:

EPROM Burn - Microchip algorithm

EPROM Burn - Microchip algorithm

Assuming you have appropriate power supplies, then the waveform on VCE looks like this. The upper trace is the -OE signal for the data latch supplying the byte-to-be-burned, the lower trace is VCE on EPROM pin 21. Set VCC = 6 V on pin 24 while all this is going on. The currents range into the hundreds of mA; this is not a low-power device!

The squirts on the -OE latch signal before each programming cycle are eight quick writes to those antique DL-1414 displays that share the data bus with the EPROM. They show the current address and data byte during programming, plus other status & error messages.

The Microchip and GI datasheets both claim that the EPROM cells erase to all 1 bits, like every other EPROM I’ve ever used. The Philips datasheet says:

… after each erasure, all bits of the 27HC641 are in an undefined state. [...] which is neither a logical “1” or a logical “0”

27HC641 EPROM in programming socket

27HC641 EPROM in programming socket

The chip markings suggest they were made by Signetics, which got Borged by Philips some years ago. Lo and behold, the chip erases to a bizarre pattern that may be “undefined” but is perfectly consistent from erasure to erasure.

Therefore, you cannot blank-check a 27HC641 EPROM before programming it!

The Philips / Signetics datasheet doesn’t have a programming algorithm and the GI datasheet says you’re supposed to hold VCE at +12.5 V except when you’re asserting the programming data. So I used the Microchip algorithm on a Signetics chip and it seems to program properly.

The only quirk is that the Arduino Diecimila doesn’t have enough storage to hold the entire EPROM at once, so I verified each data byte as I wrote it, rather than doing the whole chip after the entire programming loop. The top picture shows a single 1 ms programming pulse followed by the 3-ms overburn pulse; the byte read back from the EPROM must agree with the source byte after each pulse. When it’s all done, I manually dump the entire EPROM as an Intel HEX file and verify that against the original HEX file: if it matches, the burn is good.

The byte-burning function goes a little something like this:

int BurnByte(word Address, byte Data) {

unsigned Iteration;
byte Success;

 SetVcc(VH);                              // bump VCC to programming level
 SetVce(VIH);                             // disable EPROM outputs
 Outbound.Address = Address;              // set up address and data values
 Outbound.DataOut = Data;
Success = 0;
for (Iteration = 1; Iteration <= MAX_PROG_PULSES; ++Iteration) {

RunShiftRegister();
digitalWrite(PIN_DISABLE_DO,LOW);       // present data to EPROM

SetVce(VH);                             // bump VCE to programming level
delayMicroseconds(1000);                // burn data for a millisecond
SetVce(VIH);                            // return VCE to normal logic level

digitalWrite(PIN_DISABLE_DO,HIGH);      // turn off data latch buffer
SetVce(VIL);                            // activate EPROM outputs
CaptureDataIn();                        // grab EPROM output
SetVce(VIH);                            // disable EPROM outputs

RunShiftRegister();                     // fetch data

if (Data == Inbound.DataIn) {           // did it stick?
Success = 1;
break;
}
}

MaxBurns = max(MaxBurns,Iteration);

if (Success) {                           // if it worked, overburn the data

digitalWrite(PIN_DISABLE_DO,LOW);       // present data to EPROM (again!)
SetVce(VH);                             // bump VCE to programming level
delay(3 * Iteration);                   // overburn data

SetVce(VIH);                            // return VCE to normal logic level
digitalWrite(PIN_DISABLE_DO,HIGH);      // turn off latch buffers

SetVce(VIL);                            // activate EPROM outputs
CaptureDataIn();                        // grab EPROM output
SetVce(VIH);                            // disable EPROM outputs

RunShiftRegister();                     // fetch data

Success = (Data == Inbound.DataIn);     // did overburn stick?
}

return !Success;                         // return zero for success
}

NOTE: the MK36000 and 27HC641 have slightly different address bit assignments.

The MK36000 address bits look like this:

  • pin 18 = A11
  • pin 19 = A10
  • pin 21 = A12

The 27HC641 address bits look like this:

  • pin 18 = A12
  • pin 19 = A11
  • pin 21 = A10

Now, if you’re building a programmer, just wire up the 27HC641 socket as if it were a MK36000 and everything will be fine. The byte locations within the chip won’t match those in the original MK36000, but it doesn’t matter because you store bytes at and the Tek CPU fetches bytes from the same addresses.

However, if you’re using a commercial EPROM programmer, it will write the bytes at the locations defined by the 27HC641 address bit assignments (because that’s all it knows), which will not work when plugged into the Tek board. Choose one of the following options:

  • build an interposer board to permute the address bits
  • cut-and-rewire the Tek board (ugh!)
  • write a program to permute the bytes in the HEX file

Think about it very carefully before you build or program anything, OK? The checksum will most likely come out right even with permuted bits, but the CPU will crash hard as it fetches the wrong instructions.

Memo to Self: always RTFM, but don’t believe everything you read.

About these ads

,

5 Comments