Monday, 21 April 2014

PCB ordered, and improvements to homemade PCBs

This last month or so I have been working on two fronts: finalising the circuit for the computer, and working on my home made PCB fascilities.

So, the circuit is finished. For power the board has two options: USB, like the previous design, and a Molex harddisk power connector. Because of the high current sourcing with a PC power supply I have included a fuse, rated at 1A on the board. The idea is that if I should have a short circuit somewhere, or similar fault, the fuse will blow before the several amps from the PSU can flow into the whole circuit and destroys most of the ICs. That's the theory anyway. Below is the schematic:


A few tweaks and additions since my last post:
  • A piezoelectric sounder has been added, with a series resistor. This is connected to the CPLD.
  • A general purpose button, which will probably be used to generate an NMI signal. It is connected to a pin in the CPLD, so can in theory be made to do anything.
  • A "Econo reset" DS1813 (PDF) handler now takes care of generating the RESET line, eliminating the capacitor. This should generate a nice clean reset signal at power on, and when the button is pressed.
  • The run/halt push button has been replaced with a more sensible miniature sliding switch.
  • Two supporting connectors, which double up as power connectors serve to give future daughter boards some rigidity when they are plugged into the expansion connector. There are two to deal with long and short daughter boards.
  • The IDE port has the option of supplying 5V at pin 20. This is useful for some Compact Flash adapters, but for normal hard disks this pin is missing and is blanked out on the IDE cable so if there is a pin in the connector the cable will not fit. I have arranged the PCB so it can work either way.
  • Various decoupling capacitors have been added including as many as I could squeeze around the CPLD, and a pair onto the circuit as a whole.
The finished PCB design is below:


Before finalising the PCB design, I thought it would be a good idea to check that all the components would physically fit where I'd put them. Some of the "footprints" for the components are not quite right, and without ensuring the space given to each one is adequate, it is possible that two components don't physically fit next to each other. I had this problem with the previous design, whereby I hadn't left adequate spacing around the crystal. Anyway, a simple way to check things out is to print out the design on paper, and then physically lay the components on top of where they need to go:


This check prompted me to make a small change to the placement of the DUART crystal, to give it some room around the "power support", at the right of the board. Otherwise, everything appeared fine.

Last week I placed an order with my favorite PCB manufacturer, botech. I have ordered 5, for a total cost of £45 including shipping, which I though was quite reasonable. The board is even bigger then the last one, at about 12.5 by 14.5 cm. This would be considered large to most PCB houses who do small runs for hobbyists. The number of holes is also quite alot, at about 650. Anyway, with luck I will be soldering up the board next weekend.

The VHDL coding for the CPLD design is mostly done, with only things like the sound interface and the IDE latch to finish. Of course the cool thing about programmable logic is these things can be done, and redone, after the non-programmable hardware has been decided upon.

The other area I've been working on is PCB production at home. In the end I concluded that the iron on method for toner transfer is not dependable enough; occasionally the transfer was just about acceptable, but only after five or six attempts. The better method for doing toner transfers involves the use of a laminator, the kind of machine meant for laminating paper documents. Instead of heating plastic with paper inside, toner can be transferred to a piece of copper clad. It works better then an iron because the temperature is, in theory, more constant and the heated rollers apply a consistant pressure.

So I duly went and bought the cheapest laminator I could find: about £15 from Argos. After some experiments it was obvious that it wasn't getting hot enough for the toner to transfer, which happens at about 170C. Using the thermocouple on the multimeter showed the temperature was only reaching about 150C. Worse, it was fluctuating a lot going from 150C down to about 110C until the characterisic "pop" and the current being applied to the heater causing the cycle to repeat. Pulling it apart revealed the temperature control to be done with two bimetalic thermostats. I did try to buy a new thermostat, rated at 180C and this made for some better results, but still the hysteresis curve was too wide with the temperature going between 185C and then down to about 140C. Better then before but still not good enough for reliable transfer.

Using the multimeter I was able to prove that with reliable temperature control, it would be possible to do consistent toner transfer. With the temperature around 180C, and quickly feeding the copper clad with tracks printed onto thin magazine paper ontop, after about five feeds I was able to get perfect transfers. I even did an etch to see if it would give me a good etched PCB:


The result was better then I'd hoped for and a million miles cleaner then I could get with the iron. The PCB, by the way, is a shrink DIP to regular 0.1 inch adapter. Eventually I will need this when I want to integrate a Yamaha YM9958 video controller into my computer. These ICs are a little odd in that they use the uncommon shrinked DIP formfactor which have pins with a 0.07 inch pitch.

So the next job is to make the temperature much more stable so I don't need a multimeter with thermocouple attached, and I don't have a narrow window with which to put the copper clad through before the temperature goes too low. There are a couple of ways to do this, but my choice is with a microcontroller attached to a thermocouple and some way to turn the heater on when the temperature is too low and off when it is too high. I should then be able to keep the laminator rollers within a narrow temperature range around the ideal toner transfer temperature.

The first thing to do is to select a method of obtaining the temperature in the microcontroller. As usual there a number of options but in the end I went for a MAX6675 (PDF) IC attached to a thermocouple. A nice breakout board is available, on good old eBay, which combines the IC with a type K thermocouple, all for about £9. The MAX6675 interfaces via good old fashioned SPI which, through my experiments with the 65SPI, I have some experience with. But not, oddly, with my microcontroller of choice; the AVR ATMega8.

Because I don't have the thermocouple and MAX6675 board yet, I needed to find out how to do SPI with the AVR some other way. In the end I went for the simple approach of hooking up an AVR to a DS1305 Real Time Clock. This was easier then expected. Hardware wise, I breadboareded up the ATMega8, DS1305 (with 32.768KHz crystal) along with an ISP header and reset button. For comms back to the PC the AVR's UART was used.

The circuit is trivial, so I won't bother to include it.

Here's is the equally trivial breadboard setup:


Software wise, I was lazy and opted to borrow the core of the code from the EEPROM programmer I made back last spring, taking just the serial comms parts.

The code added includes a section to setup the SPI port:

/* Configure input pins on SPI port */
DDRB = (1 << 5) | (1 << 3) | (1 << 2);
/* SPE = SPI Enable, MSTR = MSB first, CHPA mode, SPR0 = Slow down clock */
SPCR = (1 << SPE)|(1 << MSTR)|(1 << CPHA)|(1 << SPR0);
/* Disable DS1305 */
PORTB = 0x00;

Here is the code for displaying the time:

else if (strcmp(args[0], "showtime") == 0)
{
    unsigned char timebuffer[0x11];
    memset(timebuffer, 0, 0x11);

    PORTB = 0x04;
    _delay_us(10);

    spitxrxbyte(0);
    spitxrxbuffer(NULL, 0, timebuffer, 0x11);

    _delay_us(10);
    PORTB = 0x00;

    snprintf(serialoutput, BUFFER_SIZE - 1, "%02x:%02x:%02x %s %02x/%02x/%02x\r\n",
        timebuffer[2], timebuffer[1], timebuffer[0],
        daysofweek[timebuffer[3]],
        timebuffer[4], timebuffer[5], timebuffer[6]);

        writestring(serialoutput, 0);
 }

And here is code for setting the time:

else if (strcmp(args[0], "settime") == 0)
{
    unsigned char timebuffer[0x11];
    memset(timebuffer, 0, 0x11);

    timebuffer[2] = strtol(args[1], NULL, 0);
    timebuffer[1] = strtol(args[2], NULL, 0);
    timebuffer[0] = strtol(args[3], NULL, 0);
    timebuffer[3] = strtol(args[4], NULL, 0);
    timebuffer[4] = strtol(args[5], NULL, 0);
    timebuffer[5] = strtol(args[6], NULL, 0);
    timebuffer[6] = strtol(args[7], NULL, 0);

    PORTB = 0x04;
    _delay_us(10);

    spitxrxbyte(0x80);
    spitxrxbuffer(timebuffer, 0x11, NULL, 0);

    _delay_us(10);
    PORTB = 0x00;
}

The two SPI routines are as follows:

unsigned char spitxrxbyte(unsigned char data)
{
    SPDR = data;
    while(!(SPSR & (1 << SPIF)))
        ;
    return SPDR;
}

void spitxrxbuffer(unsigned char *tx, int txcount,
        unsigned char *rx, int rxcount)
{
    int c;

    for (c = 0; c < txcount; c++)
        spitxrxbyte(tx[c]);
    for (c = 0; c < rxcount; c++)
        rx[c] = spitxrxbyte(0);
}

Interestingly these routines are very similar in function to the 6809 code I wrote for the SPI handling in my monitor program. The first routine sends and gets a byte, the second routine sends a buffer then gets a buffer. Both transfers are optional.

Here's a simple screenshot of a terminal program attached to the AVR, with the clock being set and then shown a number of times. The command for setting the time is crappy as it involves using hex notation, but this is just a prototype so who cares:


For fun, I hooked up the Logic16 and did some captures. Here I am setting the time:


So now I'm just waiting for the thermocouple with MAX6675 to turn up, along with the PCB for my 6809 computer.

Hurry up postie!