Sunday, 31 March 2013

EEPROM programmer improvements and... stripboard sucks

This Easter weekend I've been working on the EEPROM programmer again.

The programmer PCB has been "in production" now for about a week, with a few weeks left.  In the meantime I thought I would brush up on my soldering "skills" and make the circuit up on stripboard.  This turned out to be a slightly crazy thing to do; stripboard does not lend itself to circuits with busses.  There are far too many wire connects.  The result is good though; I now have a nice working EEPROM programmer in a much smaller space then the masses of breadboard.

My extremely dodgy soldering:

I was so used to breaking tracks that a couple of times I broke a track between two components which I could have used.  One day I will try my hand at non tracked protoboard.

Every IC is socketed.  I even socketed the ZIF slot!  I didn't have a narrow 28pin DIP socket for the ATMega8, so I made one out of two 14 pin sockets.  The 10pin IDC programmer header (top right on the underside picture) involved some awkward track cuts.

The bodges in upload.c to disable page mode for certain locations are now not needed.  They were necessary when the circuit was on breadboard, not for bad memory locations in the EEPROM like I suspected, but for dodgy breadboard wiring.

I've also (code on github) improved upload.c such that it can be used for downloading the content of the EEPROM.  You can also set the serialport TTY on the commandline.  The options are:
  • -s : set the TTY of the serial port (eg /dev/ttyS0). The rate is still fixed at 9600.
  • -f : set the name of the file to upload.
  • -r : set the number of bytes to read from (file download mode).
  • -o : offset to start reading from, when the -r option is used.
With the -r option, the ROM content will appear on stdout, so redirection is necessary to write the result to a file.

While working on the stripboard version of the circuit I found it useful to quickly write test data into the EEPROM, and then read it back, checking that this was what was written.

To do this automatically, the "testwrites" command within the programmer firmware can now write variable data, by writing the test pattern (which is just the number of bytes into the current page) XOR'd with a negation pattern.  A corresponding "testreads" will read the n pages from the ROM, XORing the result with the pattern and then checking this is what it should be.  By altering the negation pattern on each test, we can ensure that the data checked was written by the previous write, and not from some historical write that happened to write the same data.

So far I've been using the same AT28C256 for all my EEPROM programming.  I ordered a couple more from China, but when these arrived I was unable to program them.  The data read always comes back as 0xff.  These chips are datastamped 1996 and 1997, which is much older then the 2012 stamp on the "working" ROM.  It's possible they've stopped working, but then they look unused so this is unlikely.  The alternative is that they were shipped with the software lock in place.  Unlocking them could be difficult.

Now I have a working, and reliable EEPROM programmer my next task is to make the simplest possible 6809 computer, containing just the 6809, EEPROM and some LED to use for output.  I can then write a simple program to drive the LEDs...

Sunday, 24 March 2013

Adventures with an ATTiny85

As a little diversion on the bumpy road to the 8bit world of the 6809, I've been playing about with some AVR ATTiny's, specifically the ATTiny85. Mostly to see what they can do and to see if they could be used for interfacing peripherals to an 8bit MPU.

These are amazing little beauties; 8Kbyte flash, a tiny amount of RAM, some EEPROM, 5 I/O pins, 4 ADCs, timers, a watchdog - all in a 8 pin package! Programmable with an ISP programmer, just like an ATMega. The biggest difference to its bigger brother is perhaps the lack of a UART.

As a test and learning exercise I've made an attempt at replicating the LED strobe effect on an Apple Mac; an LED that appears to slowly dim and brighten when the machine is in standby. This works by turning the LED on and off rapidly with differing amounts of on and off time to effect an apparent level of brightness. To make things more fun the speed with which the LED ramps between dim and bright is to be controlled by the analog to digital converter, which has a pot attached giving a full Vcc to 0V swing.

For completeness, the circuit below includes the ISP programmer header and MCU reset button. Even then it is still trivial. It seems to be harmless having an LED attached to the ISP lines; you do get to see pulses as the AVR is programmed though. I put the pot on the last ADC port, just because it requires abit more code to do so.

And here is a picture of the circuit on breadboard. I finally got fedup with my solution to the 10 pin IDC ISP header problem and soldered up a small piece of stripboard with an IDC pin header on one side and 10 PCB pins on the other. Much nicer then stuffing wires in the plug!

The software is simple enough. I had to play with the microsecond sleep values to get the right effect and it will be different for different LEDs. I'm fairly happy with the results, though a diffuser would mean the LED could go dimmer.  A more elegant solution would involve reading the ADC on an interrupt and using PWM mode outputs to strobe the LED. Perhaps if I get time I will.

#include <avr/io.h>
#include <util/delay.h>

void strobeled(int brightness);

int main(void)
    int b = 0; int up = 1;
    DDRB = 0x01;           /* make the LED pin an output */

    ADMUX = 0;
    ADMUX |= (1 << MUX0) | (1 << MUX1);    /* Use ADC3. */
    ADMUX |= (1 << ADLAR);    /* Left align. */
    ADCSRA |= (1 << ADATE);    /* Free running. */
    ADCSRA |= (1 << ADEN);  /* Enable DC. */
    ADCSRA |= (1 << ADSC);  /* Start converting. */

    while (1)
        int step = (ADCH / 4) + 2;
        if (up)
            b += step;
            if (b > 255)
                b = 255; up = 0;
            b -= step;
            if (b < 0)
                b = 0; up = 1;
    return 0;               /* never reached */

/* brighness is from 0 to 255. */
void strobeled(int brightness)
    PORTB = 1;
    PORTB = 0;
    _delay_us((255 - brightness) * 75);

Sadly I managed to lock myself out of two of my ATTiny85s by flashing in the wrong fuses values. I won't bin them though as its possible I could rescue them at a later date.

In other news, I was annoyed with myself today to find a small mistake in the EEPROM programmer circuit. The low byte 74HC590 should have its pin 12 tied low. This is the carry-in pin. While it still works when I tested it without the tie on breadboard, its not ideal. Hopefully the circuit is not yet being manufsctured.... If it is then it might need a jump wire fix, or some other bodge.

Sunday, 10 March 2013

EEPROM programmer source code

The software for the programmer is in two parts, the "firmware" that runs on the ATMEGA8, and a program intended to run on a Linux machine which sends a file to the ATMEGA8 which it then writes onto the EEPROM.

Both bits of software are available on my github account.  This is not the nicest code I've written, but it does the job.  There are almost certainly buffer overflows....

The baudrate between the PC and the ATMEGA8 is fixed at 9600.  I played with higher rates, but did not have much success, probably because of inaccuracies in the built in RC oscilator.  9600 is fine for the size of files I will writing to the EEPROM anyway.

Programmer Firmware

The command set the ATMEGA8 software understands was designed both for the task of programming the EEPROM and general debugging.  All commands are in lowercase, and the first argument to the command is usually some kind of count value.  If the count value is missing, it will default to 1.  All commands emit "Done" on success, or some kind of error message on error.
  • echo N -  Enable (or disable) local echo based on N. Useful for interacting with the programmer via a TTY terminal program.
  • debug N - Enable (or disable) debug mode, based on N being 0 or 1.
  • reset - Pulse the counter reset line, and clear the counter (address bus) back to zero.
  • clock N - "Manually" pulse the counter clock line N times to advance the address by N.
  • getcount - Prints the current value of the counter. This value is updated by the reset and clock actions, as it cannot be directly read by the ATMEGA8.
  • dumphex N - Prints N bytes from the EEPROM in hex. The output is fairly basic, but serviceable.  Note that the left hand field is the count of bytes read in the current read operation, not a mempry address.
  • dumptext N - Like the above, but print only printable ASCII values and translate CR and LF for the terminal.
  • dumpraw N - Raw output of N bytes. No translation and every byte is output.
  • writemembytes N M - Writes the byte M (in decimal, hex, or any format strtol() understands), N times. Used for testing.
  • upblock N M - Writes N "pages".  M sets weather to use page write mode. See below
  • testwrites N M - Writes N "pages". M sets wether to use page write mode. Here the data is preset instead of coming from the serial port.
  • writedelay N - Changes the write delay, in milliseconds. Defaults to 10, which is valid for the 28C256.
Page mode needs some explanation.

The 28C256 needs 10ms for each write operation.  This would render write mode stupidly slow but for the ability to write a 64byte "page" in a single write step.  This is implemented in the EEPROM programmer code by the uplock command.  It will read 64bytes from the serial port and then write out a page containing that data.  With page writes, my EEPROM programmer software can write the EEPROM at near to the maximum speed of 10ms per 64byte page.  Note that page writes need to start at a 64byte boundary.

Although the circuit includes an IO pin for the /CE (Chip Enable) line, the programmer code simply puts this line low for the duration it is running.  This is because there is only one EEPROM to program.  The /WE (Write Enable) and /OE (Output Enable) lines are manipulated in the read and write operations roughly in line with what the datasheet for the 28C256 suggests.


The "upload" program is a simple end-user EEPROM writer for pretty much any version of Linux.  It accepts a single argument, the file to write to the EEPROM.  It assumes the ATMEGA8 is attached to a USB TTY port (/dev/ttyUSB0), and will first write the file using the "upblock" command, and then verify the file was written correctly by reading it back again with the "readraw" command.  You should probably ensure the ATMEGA8 has been reset before running "upload".

Note that my particular 28C256 appears to have some "bad addresses".  In page write mode, writes would consistently fail at the same address, but only in page write mode.  The upload.c code contains some special code to flip certain write locations back to non page mode to work around these bad areas in my EEPROMs.

  • It would be nice if upload could be used to dump out the contents of the EEPROM
  • All buffer overflows should be eliminated
  • The command set should be better documented
  • The code (both programs) need more comments
Next Steps

I'm currently waiting for my good friend Richard Gellman to layout my EEPROM programmer circuit for me so I can make it up on a PCB. That will then freeup the breadboard for my 6809 efforts.

Until then, I have a lot of reading on 6809 assembly, planning what my 6809 computer will do, and so on....

Saturday, 9 March 2013

EEPROM programmer circuit

The circuit is relatively simple once the block diagram has been devised. For the serial port, a USB lead meant for interfacing to the RS232 port on a mobile phone was used instead of something more conventional like a MAX232 level shifter. Something like this from ebay would also work.

On the ATMEGA8, the whole of PORTB is used for the data bus, whilst the rest of the IO (counter control and EEPROM control lines) uses PORTD.  Because this application is not really time critical (other then the UART baud rate), the internal RC oscillator is used instead of an external crystal.

The 16bit address bus counter is implemented using a pair of 74HC590s (PDF) - each one is a 8 bit counter, and they can easily be cascaded to make counters of any width.

The rest of the circuit, below, is made up of components to hang everything together: some LEDs to indicate the status of the I/O lines, a reset button for the ATMEGA8, and the ISP programmer port for the MCU.

You can download this image in postscript format.

This circuit was implemented first on breadboard:

Top to bottom:
  • The serial input comes in on the screw terminals
  • The ATMEGA8. along with a reset button (buried under wires)
  • The ISP programmer header
  • Two 74HC590s, along with LEDs indicating the reset and clock signals
  • There are some extra LEDs here, one for each address line
  • Three LEDs, one each for Output Enable, Write Enable and Chip Enable
  • The 28C256 EEPROM (the big IC at the bottom)
The circuit was tested as it was laid out, and thus is somewhat spaced out, to the point that a total of 3 lead "hops" is required to get from PORTD on the ATMEGA8 to the data bus pins on the EEPROM.  This is because at one point LEDs were used to indicate the state of the data bus.  If I could be bothered the circuit could probably be made to fit on a single breadboard "slab".

Next up is, of course, the software required to drive the programmer...

An AVR EEPROM parallel programmer

My 6809 Single Board Computer will need, at least, the following:
  • A CPU
  • Some RAM
  • Some ROM
  • Some I/O devices
While there are other options for somewhere to hold a core set of routines*, the traditional method is with a ROM.  But a ROM needs to be loaded with code via a programmer.

For the ROM a 28C256 is a nice choice.  It is easily programmable using ordinary TTL voltages, and has enough capacity (256Kbit or 32Kbyte) to hold all the 6809 code I could write.  In fact, it is unlikely that I will want to use all the address lines.  One downside of the 28C256 is they are expensive; about £9 off ebay.

The IC isn't any use on its own - it is needs to be programmed!

There are a few ways to implement a EEPROM programmer.  Some people have bodged one together using a parrallel port and some shift registers for generating address lines.  But my preferred option, because it is more interesting, is to use a microcontroller.  After talking to various people about this project, the MCUs made by Atmel sound like the best choice.

Rough specification for an AVR ATMEGA8:
  • 8KByte Flash
  • 2KByte RAM
  • UART
  • Timers
  • Built in RC oscilator
  • TTL I/O ports
  • Some ADCs
  • Easily programmable over USB
  • Programmable in C
  • And various other cool things
All in a 28 pin DIP package.

After considering various options, the rough block diagram for my programmer is:

The ATMEGA8 communicates with the PC via good-old-fashioned RS232.  In turn the ATMEGA8 is directly connected to the EEPROMs databus in both directions - write for programming and read for verifying that the data has been saved.  Control lines for output enable, write mode, and chip enable are also connected directly to the ATMEGA8.  The address line handling is perhaps the most interesting aspect of this design.  Because the ATMEGA8 does not have enough output lines to form the whole address bus (this would require 15 independent lines), the address bus is instead formed from the outputs of a counter.

This is possible because the ROM is programmed sequentially, ie. one byte after another along the address space.  If random access to the ROM was required, this would not work.  The counter circuit is clocked (ie. the address bus is advanced to the next byte) and reset (back to zero) by the microcontroller.

To handle the serial comms, a simple command set is needed to write bytes, read bytes, advance the counter, reset the counter, and so on.

In my next post I'll include the full circuit diagram and some pictures of the programmer actually doing its thing.

* Using a microcontroller to populate RAM at startup, whilst the CPU is temporarily halted, is one other option.

Sunday, 3 March 2013

Return to the past. 8 bits are enough for anyone.

As a computer user/programmer for the past 20 years, I've always had one ambition: to build a real working computer from components.  No, not a PC (which anyone can do), but a computer from the ground up.

My inspiration comes from various sources, including using a 6502-based education board at college and being amazed at the general simplicity of the thing, and more recently from some cool things I've found on Youtube, including some awsome work of one Mark Sarnoff:

My 8 bit project will also allow me to gain experience on more modern tech, including AVR microcontrollers, i2c and suchlike.

Features I have in mind:
  • Predominately made out of 70s/80s era components, but with some modern features
  • 6809 based (Z80 would be too predictable and 6502s too limiting)
  • Serial port as primary means of I/O
  • Bank switching to make use of "massive" SRAM chips
  • General I/O ports for interfacing with ordinary TTL logic
  • Sound (perhaps using a SID, if I can stump up the cash, or some other synth
 Software wise, I'd be happy just getting a basic monitor working first.  All written by myself in 6809 asm.  None of this Linux stuff anywhere.

The first step is to make a parallel EEPROM programmer.  Whilst I could go and buy one, they are 1. expensive, 2. usually need Windows, 3. buying one is just too *easy*.

This is where the AVR micorocontroller comes in.  This will be described in the next post...

So long tank; fun while it lasted

So it's been A LONG time since I wrote here.  This will probably not make sense as it's been ages since I played about with the tank project....

The tank project was fun while it lasted.  The final state was:
  • Turret rotated - this was done using another stepper driver chip.
  • HTML/JavaScript interface kind of worked
  • Including touch!
I carted the tank into the office and had it driving around.  Pretty cool, especially with the webcam.

But there are/were a number of problems:
  • Battery life was dreadful. 15 mins if I was lucky, on a decent 7.2V RC car battery.
  • This was down to the high drain of the motors combined with the relatively high drain on the BifferBoard with WLAN gear, etc
  • And the crappy 5V regulator didn't help.  It got VERY HOT (burn'ya hot).
  • My HTML/JavaScript abilities are not up to the task of doing things nicely.
And, mostly because I'm somewhat bored of "modern software development" the Linux-in-a-tank project is shelved indefinitely.  I can't reommend the bifferboard's enough, however.  With all the attention on the Raspberry Pi, it's easy to forget these little beauties.