Tuesday, 29 December 2015

MAXI09 initial bring up

After a wait of only about a week and a half, I have now received five MAXI09 PCBs from Botech. Here they are in the wallet:

I was surprised at how much they all weigh! And the bottom:

As you can see, they look great. Especially noticeable is the silk screen which is beautifully crisp and clear.

After doing some basic continuity checks, the first step was to attach the power related parts. 

Unfortunately the SR10S05 (PDF) regulator refused to play, and I measured exactly same voltage at the output side as the input side. This was a bit of a puzzle until I looked again at the datasheet and realised that the footprint was backwards. The regulator was one of the few parts of the computer which I didn't prototype. Had I done so this mistake would have been spotted. In any case, it was a trivial job to re-solder the part around the correct way, upon doing so a healthy 5V was observed at the Vcc points. So the only damage from that error was the fact that the silk screen didn't match the installed part.

Next I soldered the configuration flash, JTAG header and FPGAs; the point being to verify that the JTAG chain was intact and that I could program the EPC2 configuration flash with the board powered up. After fixing an error, I inadvertently soldered a PLCC socket in the wrong orientation, I received an error about an unreliable connection in the JTAG chain. This turned out to be caused by a faulty EPC2 configuration flash. Swapping it out for a known good one removed the error and I was able to program the configuration flash. So far so good.

At this point the VHDL for MuDdy and DISCo was, and still is, very minimal; just very basic glue logic. DISCo has a single register for turning on and off the attached LED. To keep things as simple as possible the value cannot be read back by the MPU, yet.

The next step was to attach the CPU, oscillator can, and memory. I hacked together a 4 pin socket for the 8Mhz oscillator can by pulling half the contacts from a 8 pin DIP socket. It seems to work quite well.

Next, the first grand switch on: would the LED flash? No chance. The first obvious issue was with the BA and BS LEDs. They were flashing randomly, indicating that the MPU wasn't owning the busses properly. It was clear that something was very wrong. Next I attached my logic analyser to the E clock pin. Nothing. Things weren't looking good at all.

After a few days, and relaxing over Christmas, I had a closer look at the problem. The first job was to figure out what was wrong with the E clock. I decided that, better late then never, I would prototype using a can oscillator with a 6809. All my previous computers had used a resonator, and though the datasheet clearly stated that the EXTAL and XTAL pins could be fed a TTL clock signal, I had not seen it done before. So I breadboarded the minimal parts: MPU, oscillator can and some wires.

Initially I had the same problem, wether I used a can oscillator or a crystal: no E clock. After a little while I realised that the E clock was in fact running, but only for a few hundred milliseconds after applying power to the breadboard. This was encouraging in some ways, confusing in others. As it turned out the breadboard had a problem the MAXI09 had, some missing connections.

It seems that in the switch to KiCAD I managed to forget to connect two vital pins, /DMAREQ and MRDY to Vcc. Therefore these inputs were floating, and hence the MPU was not properly owning the busses, since this is exactly what these two pins are used for: bus mastering control. Unfortunately the only solution to this problem was to attach some jumper wires from a convenient Vcc point (I chose the power pin on the 6809 itself since it was near) to the requisite pins.

After this, and fixing some problems with the MuDdy VHDL: success, a blinking LED! In the end I went back to how I bought up the first 6809 computer on breadboard. First I drove the LED using only code in the EEPROM, then I made things more interesting by using RAM to hold a delay value, and changed this delay through the run of the program. It was a big relief to see this work, since at one point I thought MAXI09 was dead on arrival.

The next step was the UART, or rather QUART, in the form of the SC16C654 (PDF). This, too, was never prototyped. As it turns out this part is quite different from the XR88C681 (PDF) used on my previous board. One of the differences is that the QUART has two bus modes: one for Intel (called 16 in the datasheet) and one for Motorola (called 68). The bus mode is hard configured through a pin. Low for 68 and high for 16.  I naturally chose 68 mode; I'm using a Motorola 6809 after all. Also in 68 mode there is only one interrupt and chip select line. They are shared across all four UARTs. In Intel mode there is one select and interrupt per port. This would have required many more precious FPGA pins.

However, there was a vital extra difference in the form of bus timings. I hadn't paid enough attention to the fact that the 68 mode is actually for 68000 MPUs not 680x MPUs. There is a vital difference between the two. In the 68000, the chip selects are always asserted after read/write. In the 8 bit Motorola parts it is the other way around. So in summary, the UART didn't work, at least initially. After struggling with the problem for a little while I came up with a fairly simple fix by delaying the QUART's chip select to a point after the R/W signal is asserted. There were probably multiple ways to do this, but the way I went for was to only select the QUART when the MPU's Q clock was high. Q goes high about a quarter of a machine cycle later then the QUART's address appears on the address bus. See page 3 of the 6809 datasheet for more info on the machine 6809's machine cycle.

After this small change to MuDdy's VHDL I was finally able to communicate with MAXI09. This was a big milestone. Using the old monitor which I wrote a few years ago I will be able to test out the peripheral ICs on the MAXI09 board, as well as use it to test out things like the DMA controller and MMU, when they are eventually implemented.

I'm now in the process of soldering up the peripheral ICs and testing each one with the monitor. So far I have attached the 6522 (PDF) VIA, and one of the joystick ports, and I'm happy to report that both appear to be working fine.

Here's a picture of the board as it currently stands:

There's obviously quite a bit more to do, construction wise, before I start on the implementations for things like the MMU, DMAC, disk interface, and SPI controller.

While the MAXI09 board is not, of course, fully made up yet I thought it would be interesting to list a few of the things I would improve upon, and list the mistakes I've thus far found:

  • Obviously the previously mentioned problems with the /DMAREQ and MRDY pins and the switching regulator.
  • The keyboard flex connector is not quite central, horizontally, on the board. This means that the keyboard will not be centred across the board, at least not without folding the flex cable.
  • If I had more time I would have done more to reduce the size of the board. There is quite a bit of "dead space", particularly around the bottom left section, and this could be "squashed out". It would not be a massive saving, perhaps 500-700mils, for a large amount of work though.
  • There are not enough screw holes in the board. The board is quite large and so flexes fairly easily. More evenly spaced holes, and perhaps a screw hole in the centre of the board, would remedy this.
  • I hadn't appreciated at the time that whilst all the ICs in a horizontal or vertical direction are orientated in the same way (generally a good idea in PCB layout) the horizontal ones are, nonetheless, all upside down. It's not a big problem, and no doubt the orientation makes for a better layout of the traces, it's just not very aesthetically pleasing seeing all those IC markings upside down.
Anyway, I'm very pleased with how MAXI09 has worked out so far. Time will tell wether all the peripherals, like the OPL2 and the V9958, will function correctly. But I'm hopefully they will, so that I can get on with the really interesting parts, the DMAC and MMU implementations...

Wednesday, 9 December 2015

MAXI09 PCB ordered and yet more prototyping

Two more bits of prototyping work have been completed recently.

The first is the keyboard controller portion. Since the MAXI09 now includes a new Amiga 600 keyboard, and because this keyboard has many more connections then the old C64 one, I have mocked up the controller on breadboard.

I was able to establish the pining on the 30 way flex connector for this keyboard by examining the schematic of the A600 (PDF). The following lines are used:
  • 5 Key rows
  • 15 Ordinary key columns
  • 7 "Shifting" key columns
  • 1 Ground for the shifting row
  • 2 Caps Lock LED connections (cathode and anode)
The shift row is interesting. Ordinary key matrix keyboards surfer from phantom key presses. This is especially a problem for shift keys, where pressing, say, left shift with control and one other letter will, quite possibly, introduce a fourth key press. This problem can be reduced if shifting keys are tested outside of ordinary keys, so the A600 has the shift, control, alt, and Amiga keys on dedicated lines.

The format of a scancode byte is naturally different to the one used for the C64 controller:
  • bit 7 - 1 -> up, 0 -> down
  • bit 6 - row bit 2
  • bit 5 - row bit 1
  • bit 4 - row bit 0
  • bit 3 - 0 -> low half of columns, 1-> high half of columns
  • bit 2 - column bit 2
  • bit 1 - column bit 1
  • bit 0 - column bit 0
Here is the updated keyboard controller schematic section:

You can see that nearly every pin on the AVR is used. As well as the keyboard flex connector and UART lines, the AVR is also attached to an RGB LED. This will be used as both a power indicator and a system error indicator. Another output, marked /KBDREQ is used to generate a signal for the DISCo FPGA, as will be described later.

Prototyping first required a DIP adapter for the A600 keyboard's 30 way flex cable. This turned out to be a nice trivial project for KiCAD and showed that it can be useful for home made PCBs as well as those professionally made. Here's a picture of the little adapter board (well three of them on a single piece of copper clad) prior to drilling and soldering:

I was quite pleased with this little adapter board.

Here is a picture of the keyboard and controller in its prototyping state:

It's a bit of a jungle, with the following parts squeezed onto one breadboard:
  • The afore-mentioned 30 way flex adapter
  • ATmega8515 (PDF) on a 44 way DIP adapter
  • An RGB LED
  • UART cable
  • ISP header
The purpose of the prototype was to verify that I knew how to scan the keyboard, and to test out a few other things including the RGB LED and the Caps Lock LED.

After modifying the C64 keyboard controller code, I could successfully see the generated scancodes across the UART. I also verified the function of the Caps Lock LED by, in AVR code, toggling it on and off when the button was pressed. A similar thing was done for the RGB LED, using the R, G and B keys. Note that in the finished MAXI09 commands from the 6809 MPU will control these LEDs, based on system, and keyboard, activity.

At this point I was pretty pleased. Through the prototyping phase the keyboard controller code for MAXI09 was mostly written. But then I had another idea: instead of generating the system /RESET when the FPGAs have been configured, how about having the AVR generate it instead? This would allow the system to be reset under keyboard control. But because the AVR also needs to be reset its not possible to simply tie an AVR's output back to its /RESET pin because it would never come out of reset the moment it went low.

The solution to this feedback loop is to instead only hold the /RESET signal low for a few milliseconds, before raising it again, so that the AVR and the rest of the system will start running. This can be done using various ways, including a 555 timer, configured in monostable mode but I have settled on using the DISCo FPGA and the system E clock to hold the /RESET line low for a few ticks just after /KEYREQ goes low.

The final part of this puzzle is FPGA config time. Since /RESET is now an FPGA output it will be tristated whilst the FPGA is configured. This would be a big problem but it is easily solved with a pull down resistor, which serves to lock the system in reset whilst the FPGA receives its config from the configuration flash.

Having the system reset signal being generated by logic in this way introduces some fun ideas. It would be possible, for instance, to implement a watchdog mechanism whereby if a special IO port wasn't written to for a certain number of ticks, say every five seconds, a system reset would be generated. Thus a system crash would be recovered.

Since /RESET handling is a critical system action, I decided to prototype this new idea. Thus here is a picture of probably the worst bit of hacking I have so far done:

Despite appearances the actual key events are not routed to the MPU via the DUART. All of these parts are just for prototyping the system reset action! I'm perhaps naively assuming that this part of the computer won't pose any problems.

The reset generator has once again been removed from the old CPLD SBC board, and /RESET is generated from the FPGA breadboard. This signal is also routed to the AVR keyboard controller which also generates the keyboard request signal when a random key (I used the Help key, just for fun) is pressed.

The sequence in my little mockup, then, is as follows:
  1. At power up /RESET is pulled low by a resistor
  2. After FPGA config /RESET goes high
  3. FPGA, keyboard controller and MPU are now running
  4. Help key pressed
  5. /KBDREQ lowered by AVR code
  6. FPGA lowers /RESET
  7. Clock ticks pass
  8. FPGA raises /RESET
Amazingly, and despite the 30cm or more runs of multiple wires, this all worked first time.

For completeness here is a schematic of the updated FPGA section:

This should be the last of the prototyping for the MAXI09.

Also, for the last couple of weeks I have been working away at laying out the MAXI09 PCB. For the most part, laying boards out with KiCAD is miles ahead of gEDA pcb. There are a few negatives, but the continuous enforcement of the Design Rules more then makes up for them. This makes it impossible to route a track to the wrong pad, cross an existing track, or place a via too close to a track or pad. This is a far ahead of the "after the fact" DRC report from gEDA. Another of my favourite features is how the rats nest for a part is shown as it is dragged about. This makes it easy to place parts close to other related parts, in the initial stages of laying out a board. There are a couple of annoying behaviours, of course.
  • The multiple rendering modes is odd. The OpenGL mode has push routing abilities, which I've yet to properly explore. These aren't available in the "normal" rendering mode, for some reason.
  • In normal rendering mode, multiple select is not possible except by drawing a box. This is strange, but surprisingly only a small problem.
  • I would still love the ability to easily "squash" empty board space, which comes apparent only after routing traces, but this can be worked around by rerouting and reworking, at least if the problem of empty space is noticed quickly enough.
Push routing does look amazingly useful, as this video shows, and is surely something I will need on my first SMT board. But for this through hole board the same basic feature sizes, only slightly reduced from the last SBC board made with gEDA, have sufficed: 8 mil signal traces, 12 mil via holes and 8 mil clearances. Everything is, almost exclusively, laid out on a 25 mil grid. The slightly smaller trace and via dimensions have permitted some more flexible via placements then before, which has proven useful because the MAXI09 board contains A LOT more components and thus lots more vias.

Here's a picture of the signal and silkscreen layers:

Only the top and bottom signal traces are shown. The internal layers, used for ground and the two 5V Vcc (digital and analogue) rails are not very interesting so are hidden from the above picture. But, for completeness, here is the ground layer:

And the Vcc layers:

At the bottom left is the analogue power plane. It's irregular shape catches the transistor RGB amplifiers, the OPL2 sound amplifier, and the analogue power pins on the V9958. The final board dimensions are 264mm x 194mm which is only a little bigger then I hoped at the outset of the MAXI09 project. It's still enormous though, and only a few cm from an A4 page.

Whilst I am quite sure that my board could have been routed with gEDA, it would have definitely taken a lot longer and I doubt the result would have been quite as good. The MAXI09 board is easily the most complex I have ever designed; it has at least twice the parts, and connections, as the previous board and is of course my first 4 layer board.

One of the other nice, though probably not particularly useful, features of KiCAD's PCB layout program is the ability to present a 3D view of the board. In theory this can help with determining if a part will physically fit where it's been placed, but mostly I think it's there just because it looks really cool.

Here's a picture of the MAXI09 board, in glorious 3D:

As you can see, a number of components don't have a 3D model. This is because I can't find them online and don't yet know how to make them myself, something I plan to fix when I get a chance.

Incidentally, whilst KiCAD ships with a good number of models many, including the lovely looking DIP ICs sitting in their sockets, were downloaded from this website. I have to thank Walter for his enormous efforts in making these KiCAD models.

After a lengthy (re)check of both the schematic and the board and its footprints, it has now been ordered for manufacturer from Botech Circuits. Total cost for 5 boards is about £150, so obviously I really hope it works!

While waiting for the board, I will crack on with working on the VHDL for the MuDdy and DISCo FPGAs. Initially I will write only the address decoder, and other core logic. The MMU and DMAC will come later...