The build of the MAXI000 board is proceeding fairly normally.
There have been a few issues along the way, all caused by either bridges or open pins on PLCC parts. As predicted these packages are a pain to rework with the iron; fixing them up after reflowing paste has been somewhat tricky.
The biggest headache is not fixing bridges but fixing open circuits; PLCC pins which do not attach properly to the pad. These are extremely difficult to see, even with the microscope. Here’s a closeup of the 68HC000:
This is after some rework with the iron, which is why some of the pins have solder on them and are a little shiny. Dragging solder under the J lead is tedious, but is doable with lots of flux.
After attaching the 68000, reset circuit and SST39SF040 (PDF) flash memory sockets, it was time to test that I could program the flashes using my XGecu TL866II Plus USB programmer. As expected this went well.
These PLCC32 ICs are tiny compared to the massive DIP EEPROMs that I’ve been used to. I hadn’t appreciated, until I opened the anti-static packaging, that these PLCC32 devices are also half height compared to regular PLCC32 parts. This means that you must be particularly careful pushing them into the socket to make sure they go in squarely.
As per my usual process, I wrote a simple test routine for the 68000 to flash the Alpha LED on and off and programmed it into the upper and lower flash memories. Of course it didn’t work immediately.
At this point I thought the reset circuit was faulty and removed the related parts, the 74HC03 (PDF) quad NAND gates with open collector outputs and pullups. The /HALT line was staying low instead of rising when the SYSCLEAR signal flipped low. Here is the schematic for this section:
Not shown is that SYSCLEAR is also pulled up, which is necessary because the Alpha EPF10K20 (PDF) FPGA, which generates this signal, tristates IO pins during configuration. This is when the 68000 /RESET and /HALT pins stay low for the minimum 100mS at power on.
I’d known, from reading the 68000 User Manual, that the 68K can assert /HALT in some situations. It will assert it on a double bus fault, which is when a bus error is asserted while handling a bus error exception. But my conclusion, which I should confirm, is that it can also happen when other errors happen inside other exception handlers. In any case, the reset circuit was not faulty and instead the problem was with an 68000 address pin. The hardest connections to test are the logical address (A12 to A23) bus pins, since they only route to the Alpha FPGA; all other pins also route to the expansion connector, making continuity testing easy.
After reattaching the reset circuit parts and fixing the open pins on the 68000, success! A blinking LED.
The next step was to attach the SRAM. This went surprisingly well. I reflowed one memory IC then visually inspected both sides of pins, paying particular attention to the side that would be virtually hidden by the second IC.
After reflowing both system memory ICs it was time to exercise them. The initial test, flashing the LED with a delay held in memory (a word, so using both memory ICs) went fine. After that I thought a more comprehensive test was warranted to make sure all the memory ICs pins were properly soldered.
This test consisted of writing and reading bit patterns across the memory space, varying the pattern (by incrementing it) along the way. This also exercised the stack as subroutine calls were used, and that was also held in memory. The tests had to allow for this by not overwriting the memory used for the stack.
This test revealed a problem with an address pin on the lower memory IC, but it was quickly fixed. Luckily the problem, an open circuit, was with an “outside” pin. One thing to learn from this is a visual inspection, even with a microscope, is not always sufficient. I made a quick video of the test run:
The next job was to attach the quad UART IC, an SC16C654 (PDF) as used on the MAXI09 board. In summary this has proven to be a bit of a pain. The first attempt resulted in bridges behind the bottom of three adjacent “J” pins which were impossible to see, yet alone fix, without removing the part and reattaching it. Removing a large PLCC IC is tricky as all the solder on all the pins must be molten for the part to lift off. I ended up bending the prongs on some tweezers to make a removal tool that allowed me to lift up the IC from the corners. The alternative is to wedge up the IC from the bottom, but this risks damaging the PCB. After removal, the IC leads and the pads were cleaned up with some flux, braid, and a bevel tipped iron.
The second attempt was more successful. No bridges, but a few pins needed a touch more solder. One slight issue is the IC is not aligned as well as it could be. It’s not aligned badly enough to cause connection problems, but it’s still not great. If it wasn’t an hours work, and a small risk of damaging the board or IC, I’d reattach it to align it properly.
So far only the TTL header has been soldered:
I took the usual approach of writing a test routine that inputted a string, storing it in memory, and echoing it back out again. This worked well after fixing another open UART pin on none other then the TTL header’s TX pin.
The next job was a proper-sized software task: to modify my existing bootloader to read a software image from the serial port (for now the TTL header, on port C), and write it to the SST39SF040 flashes, in a similar way to the method used by the MINI000 board to write to the AT28C256 (PDF) EEPROMs, and the MAXI09 before it.
Reading through the datasheet it became apparent that whilst the writing process for the flash ICs is quite a bit more complicated then using an EEPROM, which essentially acts like an SRAM for reading and writing, it nonetheless looked simple enough to translate the programming commands into 68000 code.
Pages (sectors in the datasheet) are 4KB vs 64 bytes for the AT28C256. Because of writing the two flashes in parallel, this results in 8KB pages from the 68000 point of view.
Here’s the relevant table from the datasheet:
The sequence needed for the bootloader to follow, once it has determined that the connected computer wants to upload a new flash image, is approximately the following, with both upper and lower flashes programmed simultaneously:
- Copy the first 8KB of flash space, which includes the exception vectors and bootloader code, into RAM and calculate and jump to the reprogramming routine
- Receive a network order (big endian) word containing the number of 8KB pages that the remote end needs to send
- Receive each 8KB page into RAM
- Write the fixed portion (5 bytes) of the sector erase command
- Write the page sector address, which is the first address of this sector with the command byte given in the table (0x30)
- Delay for the sector erase interval, 25mS
- Write the fixed portion (3 bytes) of the byte program command
- Write the actual byte to program into the target flash memory location, incrementing the write pointer
- Delay for the byte program interval, 10uS
- Loop back writing the rest of the 8KB page
- Loop back writing the rest of the pages, as determined from the page count
- Send the new content of the flash to the connected computer so it can check what has been written into the flash
Translating the needed flash commands, given in the table above, into 68000 assembly is simple enough as shown by the code used in the first byte of the sector erase command:
move.w #0xaaaa,ROMB+(0x5555*2) | sector erase 1st cycle
ROMB is the base address for the 1MB of flashes, currently 0xf00000. The address that is written is shifted up one position because A1 on the 68K is connected to A0 on the flashes. The same byte (0xaa) is written into both upper and lower flashes using a move.w instruction.
The last job was to modify my flashing program, which runs on the Linux server and is written in C, to change it to use a 8KB instead of 64 byte page size.
This all works very well. I’m pleased that I will hopefully never have to extract the flashes from the MAXI000 board and insert them in my USB programmer. The only reason for having to use the USB programmer again would be if I wanted to improve the bootloader. It does actually have one current deficiency: the flashing process runs at only 9600 baud.
The code I have programmed into the flashes is, naturally, a modified version of my machine code monitor originally written for the MINI000 board. It had to be modified for two reasons: to remove commands related to hardware that the MAXI000 board will never have, such as the OPL2, and to switch it over to using the SC16C654’s port C, which is the TTL header.
Here’s a pointless picture of the monitor running inside of minicom:
The next step will be to beep out the untested connections on the quad UART, needed by the dual RJ45 sockets and RJ10 keyboard connection before I solder up the remaining UART related parts. It will be harder to fix any problems after attaching the connectors so it makes sense to thoroughly check continuity before plowing ahead.
After that I can start to solder up the video portion, starting with the SOJ video SRAM…