Ok, so you saw the thing in action and now you want to know more – maybe even build an interface yourself because you’re one of the other ~15 guys on this planet still fooling around with Transputers 😉
Good news! This time I created circuit diagram so you can actually make you own T2I2C – and that’s not enough: I’ve already laid out a TRAM-1 size circuit board using SMD parts of the C011 and 8574 making space for piggy-backing an Arduino Uno on top of that board.
But let’s start with the other details I mentioned the chapter before. I’m totally aware that there are many, many things to improve and optimize – and then there are probably even more I’m not aware of.
Here’s the how and why I did things they way I did:
For this first version of T2I2C I’m using an C011 in ‘mode 1’ – that means it is offering actually two 8-bit buses, one for receiving (input, I0-7)) and one for transmitting (output, Q0-7). Because it’s quick and easy I don’t use the I-bus and therefor grounded it.
This means there’s no way for the Arduino to talk to the Transputer side of things. But using an extra bus for input would mean using a second 8574 and obviously using another 4 wires on the ATMega.
The elegant solution to this is using the C011 in ‘mode-2’ – it then behaves like a C012 which means it provides a single butbidirectional 8-bit bus. So why didn’t I used mode-2 in the first-place?
Well, while mode-1 just requires 2 lines for data-control, mode-2 needs 4 lines and some more coding in the ATMega ‘firmware’ e.g. handling the 2 registers provided by a C012 – So yes, I was just lazy and wanted results quick. The next release will certainly use mode-2.
So what is that data-control you’ve mentioned? Using 2 converters (C011/8574) in a row there’s obviously a need for all parties to know when data has arrived and needs to be processed.
The C011 as well as the 8574 provide a pin which flags a “hey, we have something here!” signal (QValid in the C011, /INT in the 8574) . But in contrast to the 8574 the C011 also needs an “Ok, got the data, feel free to fetch the next one” – which is called “QAck”. So the ATMega controls the data-flow talking to the C011 and completely ignores the 8574 which makes it somewhat transparent.
The comms protocol of the C011 can be found in its data-sheet here. It’s all about reading, holding and releasing QValid/QAck in the right timing.
First I was using an external interrupt line on the ATMega connected to QValid because it’s so obvious. But somehow the results were flaky – sometimes the ATMega seemed do choke on some bytes which simply didn’t make it through(*). After some cursing and hair-ripping I decided to switch back to polling – again because I was lazy and wanted to get results 😉
Up to now polling QValid just works great, probably because the ATMega is pretty fast and I2C is pretty slow.
(*) Yes, of course I’ve read all the docs about interrupt-programing and its caveats (short routines, volatile vars etc…) didn’t help.
So what is actually going on in the ATMega running “Se Fiiiirmwarrre”? As mentioned in the previous chapter, I decided not to send a complete ‘bitmap’ of 128bytes each time an update occurs. Instead I created a simple command protocol, (currently) consisting of 3 bytes:
- 1st byte: If < 255 it’s the number of the Transputer data. If 255 (0xFF) command flag set.
- 2nd byte: If 1st-byte < 255, it’s the CPU-load in percent, else it’s acommand.
- 3rd byte: If 1st-byte < 255, it’s the Memory-load in percent.
This means a single Transputer information update only takes 3 bytes. A command like “clear the display” is just a single byte.
Of course there are downsides. Updating a complete display of 128 Transputer-loads means sending 384 bytes instead of 128 bytes needed for a bitmap (512 pixels, 2 bits each = 1024bits = 128bytes) – But OTOH you could enhance the firmware for just that case: One command initiates a bitmap-transfer and then you send the 128bytes of data. Mind the could, i.e. this command doesn’t exist yet.
What comes on top of the handling/processing is the calculations needed to be done by the ATMega. There’s a command telling the ATMega how to setup the panel according to columns. If there are less than 33 Transputers to be displayed, each Transputers gets its own line of 16 LEDs. To display 64 Transputers, it will be divided into 2 columns with 8 LED each. 96 Transputers have to get along with 5 LEDs and 128 can only use 4.
No matter how many Transputers have to be displayed, poor ATMega first has to calculate the percentage value into 16, 8, 5 or 4 LEDs, then decide into which column this value goes and finally handle the displaying itself – worst case a 128 times. All this could be circumvent with a bitmap-transfer, offloading all those calculations to the sender (a Transputer in this case). But I’m not sure if this is much cleverer…
These are the commands currently implemented (in decimal):
001 – 015 : Set display brightness (0..15)
031 – 034 : Set the columns to be displayed (1..4)
099 : Clear the panel display
100 : Toggle CPU-load-only vs. CPU & RAM load mode
Like you’ve seen in the video, there’s no real circuit board existing yet there wasn’t a real circuit board around back then. But I’ve created a board layout for a TRAM-1 containing an SMD C011 and 8574 which provides the space needed for a socket to plug in anArduino Nano (the small version of an Arduino Duemilanove) – Version 3.x to be precise. You have to use a V3.0 or higher if you want to use my ‘firmware’ out of the box! This is because the analogue pins (A0-A7) have been rotated in V3.x and up – if you plan to use an earlier version of the Nano, you have to adjust the i2c-pin definition in the firmware source.
Anyhow – Using an Arduino Nano is much more flexible -and cost saving- than putting everything incl. the ATMega on the board itself.
The socket is laid out to be “double-row”, so you can still plug wires right next the Arduinos pins – well, actually this is mandatory at least for connecting to the LED panel.
Currently (v1.0) these pins are used/defined by the firmware on Arduino:
- Portd: 7, 6, 5 and 4 for connecting the LED panel
- Analogue input pins 4 & 5 (SDA/SCL) for the I2C bus
- Portd: Pin 2 connects to QVAL, Pin 3 to QACK on the C011
I tried to layout the board in such way that it could also be used as stand-alone, i.e. without being seated into a TRAM slot. Then you would have to provide the Links, 5V, GND, a 5MHz clock and Reset yourself via the alternative connector in the middle of the board, called “ALT_C” . There is still room left which I’ve used for a little breadboard section.
This design is to be considered v1.0 – still things to improve, especially a way to choose the link to be used if the board is actually plugged into a TRAM socket. v1.0 routes LinkIn/Out to the ALT_C socket which needs to be air-wired to the TRAM-pins… not nice but does its job.
If interested, you can download the Eagle CAD files here.
After nearly a year I was able to get a hand full of boards created and populated one using my brand new reflow oven (Reworked pizza oven) and voilá, here’s the T2i2c in flesh, naked:
…a bit more dressed (all parts place)…
…and finally fully dressed (Nano plugged in):
So the final question was: Will it actually work? Yes it did! I plugged it into slot 2 of my beloved BOZO, connected the LED panel and adjusted my Helios test-sources a bit, and tadaa:
The cool side-effect of this project is, that you can keep the USB cable connected to your host, while the T2i2c is actually running in a system, giving a perfect OS-link-sniffer for what’s going on in a Transputer setup.
Also, I reworked my Helios tools for checking the T2I2C functionality. Everthing is now in one single tool, i.e. test-pattern, clearing the panel or manually sending a command. Here’s the source as well as the executable… read the source header before using! You can crash your Helios system – you’ve been warned!
I won’t say the sky is the limit, but if the T2I2C-TRAM will be full-duplex in the next release (ie. C011 in Mode-2) driving an LED panel would be just one of many other uses this TRAM could fulfill.
Think of all the million things people did with their ATMega/Arduinos: LCD-Displays, SD-Card Interface, Ethernet and then some more. Ok, the speed of I2C will limit that somewhat (I already have made prerequisites in my ‘firmware’ to put I2C into 400kHz/kbps “fast mode”) but still a nice interface for connecting today-tech to your yester-tech.