The build of MIDI020 is nearly finished. There’s been some hickups along the way, but I have managed to overcome them.
My order to jlcpcb.com consisted of three boards:
- The MIDI020 main board
- The Test+SRAM expansion card
- The Ethernet+Printer+Joystick expansion card
To make things interesting, and because I wanted to try them out, each came with a solder paste stencil. Here’s the one for the Ethernet expansion card with the board:
The stencil, a thin sheet of steel, was bigger then I expected it to be; about 50cm square for a 10 x 10cm board. In KiCAD a stencil Gerber file can be generated as a part of producing the Gerbers used to make the PCB. It is essentially an outline of the pads which are not for through-hole parts.
The first board I built up, because it’s the simplest board and I wanted to get a feel for the process, was the Test+SRAM board.
Unfortunately I did not take any pictures of the build process, however a rough description is as follows.
First of all, the board and the stencil were cleaned with IPA.
Next, three spare boards were taped to the cutting mat so that the board that is to receive the paste can be made stationary. The idea here is that if multiple boards need to receive paste the boards can be swapped in and out while staying in the same relative position. While I had only one board to make, securing the board to the table in this way prevents it from moving and makes lining up the stencil easier.
Next the tricky bit: lining up the stencil. I used the microscope to position the stencil and then taped it along one edge so it can be lifted up to remove the board after pasting.
The actual application of the paste is the fun part.
After applying some paste from a syringe, an amount that has to be guessed at, to the stencil it was spread across the pad holes with a flexible filling knife. I went for some spreaders made of spring steel, instead of plastic as I thought they would work better. After applying the paste the stencil can be rotated up and out of the way.
A visual inspection was done next. I found a couple of pads that were a bit short on paste. I fixed them by adding a touch more paste from the syringe.
As an illustration of the quality of the paste depositing process obtainable through the use of a stencil, here’s a picture of the Ethernet board after the above process was applied:
You can clearly see how crisp the coating on the pads is.
The next job was placing the components. This was pretty straightforward for the test card as it only has five parts on the front side. These were placed with tweezers and the board was reflowed. The back side passives were attached using the solder paste deposited from a syringe method.
The final task was to attach the through-hole parts: the right-angled DIN 41622 connector and the header pins. The result was this:
After soldering up the Test+SRAM card I thought it would be fun to try exercising the AT24C64 (PDF) EEPROM using the MAXI000 Alpha-hosted I2C controller. It was then that I noticed the first mistake: the SDA and SCL pins were swapped on the schematic. This would mean that there was no way for this card’s EEPROM to work when attached to the MIDI020, but I did test it successfully anyway with MAXI000 by swapping the I2C connections over between the board and the card.
Construction of the MIDI020 was the next task. This started with the stencil process described above. This went well, as did the placement of the parts though it took a few hours due to the sheer number of them, around 50 all told. Partly this could be sped up by being better organised, but also a problem that came up a few times was determining the position of pin one on some of the smaller ICs; it was surprisingly tricky, even after examining the part with the microscope.
Reflow went well, except there were some bridges on the finer pitch parts, namely the EFP10K20 (PDF) FPGA, the current and voltage sensor IC INA226 (PDF) and the PCA9544 (PDF) 4 channel bus interface. Fixing the later two parts was pretty easy, but when I came to fix the EPF10K20 I noticed a big problem: the package was split. It seems reflowing the part had caused it to suffer the popcorning problem I saw when building MAXI000. I eventually ruined a further part and as I only had a few of these FPGAs left, I asked Steve Moody to help me and attach the IC with his iron since he is far more experience then me in such things and I didn’t want to risk ruining my last few parts.
After receiving the board back from Steve, touching up a couple of pins on the FPGA, and attaching the JTAG header, I had some level of success: a flashing LED.
Soldering the MPU-related through-hole parts was simple enough, and included the attachment of a single expansion connector, the SST39SF040 (PDF) flash in PLCC32, and the PGA 68020 socket itself. But getting the board capable of running code was much harder then it should have been. There were various reasons for this including:
- The VHDL (PDF) for the FPGA was not properly checked before thinking it was complete enough to use in MIDI020
- The board has an almost total lack of test points
- The lack of uncommitted FPGA pins for outputting test signals on
The first problem was easy enough to overcome; I just had to finish the VHDL coding.
It was the second and third problems which plagued and continues, to some degree, to plague this board. Every previous board I’ve built, from my earliest 6809-based computers, have had an expansion connector with all or nearly all the processor pins attached to it. This makes it very easy to attach the Logic Analyser to the board to figure out what the processor is doing. Whilst the test expansion card brings out some of the processor’s pins to a header, it is far from the complete set. Likewise my earlier boards exposed any unused FPGA (or CPLD) pins to the expansion connector. These are useful both for later experimentation, such as used by my I2C controller project, and for the bring-up, when internal FPGA signals can be monitored by exposing them on external pins.
Nonetheless, after a few days of sometimes frustrating work, I had the MIDI020 board running code off the two flashes using the SRAM, in the form of 2 x IS61C5128AL (PDF) on the test expansion card. Software wise the board has only been used to run my machine code monitor, programmed via the self-updating bootloader previously written, for the purpose of exercising the hardware. This required attaching the dual RJ45 UART sockets.
After having what appeared to be fully working SRAM in the system and a basic machine-code monitor running over a UART port, I first decided to test out the IDE interface. It was here that I encountered another problem with the schematic: the databus transceivers – 74HC245 (PDF) – on the IDE header have one of the 8 bit halves as having the direction input routed from the /WRITE signal and one from the /READ signal. They can’t both be correct, and indeed the correct connection was from the /WRITE signal. The fix was a bodge wire. Fitting the bodge wire required first removing the IC as the trace I had to cut was underneath it. After replacing the IC the bodge wire was routed from the correctly wired part. Attaching wires to SOIC leads is tricky, but not too bad:
With the addition of this bodge wire, success: I could read and write disk blocks to the IDE interface.
Next, I thought I’d try out the 68882 (PDF) FPU. If I’m honest, I didn’t expect this to work. But it did, first time.
The VHDL required some additional logic in the address decoding section. The FPU co-processor is selected like any other device, except that it uses the “CPU space”, indicated by the FC processor outputs being set to 111. This space is shared by the interrupt acknowledge and breakpoint acknowledge cycles, which are disambiguated by the A16 to A19 outputs.
The second part of this puzzle was to figure out how to write some assembly which made use of the FPU. With GNU AS, the -m68882 option is used to tell the assembler that the code being assembled contains 68882 instructions. I wrote a simple test routine, which is run via a command in the monitor:
floattest: fmove.d #0f2.0,%fp0 | put 2.0 in fp0 as extended fsqrt.x %fp0 | calculate its square root move.l (0*4+0,%a1),%a0 | get the address from the fist arg fmove.d %fp0,(%a0) | write out fp0 into address as double rts
The result of running the command is as follows:
Monitor: > floattest 80000000 Monitor: > dump 80000000 10 80000000 3ff6 a09e 667f 3bcd 0000 0000 0000 0000 [?...f.;.........]
On my Linux box I wrote a small C program to calculate the value of the square root of 2 as a double and print out the IEEE 754 floating point double internal representation and sure enough I get the same value:
... int main(void) { double r = sqrt(2.0); for (int c = sizeof(double) - 1; c >= 0; c--) { printf("%02x", ((uint8_t *)(&r))[c]); } printf("\n"); return 0; }
$ gcc -Wall floattest.c -o floattest $ ./floattest 3ff6a09e667f3bcd
The internal value is printed in reverse because the PC I’m using to run the program is little-endian, but the 68000 is big-endian.
This is all pretty exciting stuff. The 68882 is almost as complicated as the 68020, if the length of its manual is anything to go by. I’m looking forward to playing with this in a lot more depth.
Next the SIMM slot, which was a bit of a slog to put it mildly.
The first problem was about as basic as it comes: when I ordered some more SIMM connectors from mouser.com I ordered the type with the pin 1 notch at the left instead of right. Whilst I could have put the connector in backwards or ordered a replacement, I decided to desolder the slot from the breadboard adapter I’d previously made.
As a reminder, here’s the schematic for the SIMM slot in MIDI020:
In use I noticed that only half the 32 bits were being written to, and data seemingly was duplicated into multiple memory addresses. Looking at the schematic you can see that the lowest 4 bits are not fed to the MUX to form the address inputs on the SIMM. In the VHDL code I had A2 and A3 on the processor being used to decode into the four RAS lines, with A0 and A1 (along with SIZ0 and SIZ1) being used to select which byte across the SIMM should be accessed. After I looked again at the datasheet for the 8MB SIMM I was using, the problem became obvious:
The problem is in the selection of the /RAS lines. I had assumed that each RAS line acted like a bank selector, and I would need two bits of address (A2 and A3) to decode the bank number. But in fact, pairs of RAS lines like /RAS0 and /RAS2 are needed to select all 32 bits of data. In essence I was still thinking that the SIMM would be used in the same way it was for my 16 bit MAXI000 board, which does use two bits of address for the RAS lines because it treats the upper and lower half of the 32 bits of data like a distinct memory bank.
The fix I came up with this was to add the processor’s A3 into the multiplexer routing. Since I could not shift down all the address bits going into the muxes, it would have to go into the top. It was at this point I noticed a second problem.
I have in my parts collection two SIMMs, an 8MB one and a 32MB one. They are both arranged essentially the same, except the 8MB one has 10 address lines (A9 to A0) and the 32MB part has 11 (A10 to A0).
As a quick aside, the maths to arrive at a capacity of 32MByte for the part is as follows:
- 2 ^ (11 * 2) : the number of unique addresses (row * column)
- 4 : the number of bytes per address
- 2 : the number of valid combinations of RAS lines (“0101” and “1010”)
Multiply these together and one arrives at 32MByte.
So, the second problem with my SIMM schematic is that the A10 line on the SIMM is fed by higher MPU address lines then A11. It wouldn’t be possible to route the MPU A3 line into the MUX and use the 32MB SIMM without having holes in the address space. This came about because to make the PCB routing on MIDI020 easier some of the address lines into the muxes were swapped about. Luckily the MPU lines feeding the SIMM’s A9 connection do not suffer from this kind of problem: though the MPU address lines are not in order, there are no “holes”. However, this does limit the board to being used with the 8MB SIMM.
The result of this is another kludge wire. A3 was picked up from the expansion card transceiver ICs and it replaces where A23 goes into the top most mux:
While debugging and testing the SIMM slot I ended up soldering on about a dozen wires to the bottom, and top, of the PCB so I could capture some signal activity with the analyser. The board looked a bit of a mess:
The work was worth it. Here’s an interesting capture from the Logic Analyser:
This capture shows eight bytes written out. It is possible to see the CAS lines switch through the selected bytes, and after four bytes have been written the next bank is selected via the RAS lines as A2 switches state. At the right hand end of the plot a CBR refresh cycle occurs.
After achieving some level of success with the SIMM I thought I might try running the board using only the SIMM, without having the Test+SRAM expansion card plugged in.
The problem then was that although a test of reading and writing long (32 bit) values into the SIMM succeeded, a similar test with words (16 bit) failed. Eventually I tracked that down to a bug in the byte select logic in my VHDL. This logic is directly translated from the ABEL code which is printed on page 12-13 of the 68030 manual (PDF) as an application note. I had made a simple typo when converting this code into VHDL.
At this point I had a board that could run using the SIMM only, and further, it had 32 bit RAM!
After retesting the SRAM on the test exansion card I found that it too had an issue: random occasional corruption on a single data line. Luckily it was solved by simply reflowing a pin on the DIN connectors.
Unfortunately to get this running I’d had to make a compromise in my VHDL that I’m still not pleased with: the processor is clocked at 12.5MHz, half the 25MHz it is rated at. It seems that without this speed reduction the EPF10K20 can’t cope with the amount of logic in the design. This is unfortunate, but is hopefully something I can look at getting to the bottom of in the future.
The final bit of hardware, for now, that I’ve played about with are the I2C peripherals. The previously written controller was trivial to include in the FPGA design. The DS1307 (PDF) Real Time Clock was tested first, and it appeared to work fine.
I briefly played with the current and voltage sensor IC INA226 (PDF), just enough to determine that it read the 5V power supply voltage as 4.975V, pretty close to the 5.03V I read it as on my Digital Multumeter.
However I got nothing from the temperature sensor IC TCN75A (PDF). There was no acknowledgement at its I2C address. I bought this part from eBay as I ordered it in the wrong packaging from mouser.com. I’m not certain it’s a fake, but I’m reasonably sure. The wiring on it is simple so I can’t see any other reason why it wouldn’t work.
Testing the PCA9544 (PDF) 4 channel bus interface was straightforward. I first added some bodge wires to the Test+SRAM card to fix the swapped over SCL/SDA pins so the EEPROM was useable:
After doing this and exercising the AT24C64 (PDF) EEPROM through the 4 channel buffer – it has a single register to set which channel should be bridged across – I noticed some very odd behavior. Whilst it seemed to work, the EEPROM was receiving occasionally corrupt data. Initially I suspected the 4 channel buffer, but after removing the temperature sensor so I could test it off the board, the corruption disappeared.
The summary of this is the I2C bus appears to be completely functional, save for the problem with the temperature sensor, which is likely because I bought a fake part. At some point I’ll fit a replacement bought from a reputable supplier.
There remains a small amount of testing to do:
- The RJ11 Amiga 600 keyboard connector: somehow I have again used the wrong footprint. More drilling will be required. I need to go through my footprints and make sure the correct one is the only one I have.
- The PS/2 port: this has not yet been tested though I can’t foresee any problems.
- The other 3 expansion DIN sockets haven’t yet been attached, nor have their pull-up resistors, since I sourced the wrong parts from mouser.
All in all I’m very pleased with this computer board, despite the problems I had getting it running, and the bodge wires. Whilst it’s tempting to get a “bodge free” board made up, I don’t think it would be a particularly valuable experience doing so. As usual I learned a few things going through this process:
- I still need more practice with QFP IC installation.
- Solder paste masks are awesome. Though they add to the cost, it’s far from prohibitive.
- Not enough effort was spent checking the schematics and too much was probably spent checking the PCB designs for minor deficiencies which don’t, in practice, change whether the board will work or not.
After satisfying myself that the MIDI020 board was a usable computer, I had a go at building up the Ethernet+Printer port+Joysticks expansion card.
After applying the solder paste I immediately spotted a show-stopping problem: the footprint for the 100 pin RTL8019AS (PDF) QFP IC was wrong. It seems there are multiple rectangular 100 pin QFP footprints with a pin pitch of 25mil: one where the leads come out from the body an extra few millimeters, and one where they don’t. The result is the main function of the expansion card can’t work, so I’ve opted to get the card remade instead of making it up in a half-complete state. While I’m at it I will get the Test+SRAM card remade to fix the SCL/SDA problem.
As well as getting those fixed up boards built up, the next big project to complete is a video expansion card for MIDI020. It will use a Cyclone II in QFP208. After looking at building such a card with a more modern Cyclone IV in QFP144, I’ve concluded that the design I have in mind requires more pins. The only real downside to this approach is an older, non-current, version of the Quartus software has to be used.
Last but not least, since I’ve been doing rather a lot of manual pick and placing of Surface Mount parts, in the middle of the build of the MIDI020 boards I decided I would build myself a new piece of workbench gear: a pneumatic pick and place head.
The basic design is copied from this video and it consists of the following parts:
- A variable voltage DC supply
- A vacuum pump as you might use in an aquarium
- A foot operated diverter for the air supply
- Some flexible tubing
- A nozzle made out of a syringe and some canulas of various sizes
I ended up using my bench power supply to power the motor. The motor has a repurposed mains power cable soldered to it with a pair of banana plugs on the far end. The motor sits on the floor with the foot operated switch next to it, with another length of tubing going through a hole in the desk to the nozzle end. The nozzle was made by simply wrapping the tubing in enough insulation tape to make a tight seal in the open end of a syringe.
In use it seems to work well. It is perfect for placing most parts, up to small QFPs. For larger parts like PLCCs, I’d still have to use tweezers. Probably this could be improved by the use of some small suction cups on the end of a large cannula.
So, the next job is to start on that video card design. But I also want to start thinking about what kind of Operating System I want to write. I also have some new reading materials:
As usual there are many, many options for what to work on next. But the video card sounds like the most fun, so that’s what it will be…