PCI USB 2.0 Adapter Lessons

You get what you pay for. Buy cheap, buy twice. I’ve heard them all before. But a couple of my old-but-useful Linux PCs needed an upgrade to high speed USB recently, and I didn’t want to spend much. A quick search on allegro.pl (the Polish equivalent of eBay) turned up just what I was looking for. USB 2.0 adapter cards to fit the now-retro PCI bus, for just 20 złoty, or a bit less than four quid in old money. “Five USB 2.0 ports”, exclaimed the advert, in Polish. “Four external and one internal”. Perfect – I wanted to connect an internal card reader so the internal port was just the ticket.

The cards arrived this afternoon and I examined them. What do you get for four quid? A generic Chinese box and the card in an anti-static bag. No instructions or other such luxuries.

There’s just one chip on the card: a Via VT6212L. Wanting to know what I’d got, I looked it up. It’s still listed on the legacy section of Via’s website. The specification there, though, shows that it’s a 4-port USB controller. So how had my card got 5 ports?

A close look at the PCB tracks on the card reveals all. The internal USB port is wired in parallel with the topmost external port, so you can’t use both at once. Looking more closely, there’s a footprint for a 10-pin Molex header which would be ideal for my internal card reader, but it’s not fitted. Examining the tracks round the header, it turns out that the two USB ports it provides are connected in parallel with the top two external sockets. If you want to use the header, those two external sockets are no use!

Oh well. I can live with 4 ports, and remove or ignore the ones that won’t work. But there’s another design “feature” that came to light while I was examining how the sockets were wired up.

One of the functions of a USB port is to supply power to the device that’s connected. That’s very useful. Last time I designed anything with USB host ports on it for public use, it was important to make sure that power was monitored and limited so that a misbehaving device or damaged cable can’t affect other devices or, worse, cause overheating. All this is written into the USB specification and there are handy chips available to make it easy to implement. But they cost money.

Examining this board, it became clear that the designers took no such precautions. The 5 volt power comes straight from the PCI bus to the USB connectors without so much as a fuse, or even a decoupling capacitor. Any mishap on a USB connector can therefore receive the full force of the PC’s power supply, which can be tens of amps. Yay! A short circuit will at least crash the PC, or even result in melted cables and scorched PCB tracks.

Time for some modifications.

  • Remove the top two external USB sockets, which are wired in parallel with the internal connector
  • Remove the internal USB connector
  • Fit the Molex connector for easy hookup of my card reader
  • Cut the track carrying 5V power from the PCI bus to the USB sockets and insert a sacrificial zero-ohm resistor to act as a last-ditch fuse
  • Splash out on a few microfarads of decoupling capacitor fitted to the place marked out on the PCB but kindly left free.

Here’s a picture of the results. The board is now in service and working nicely.

Incidentally, I have just retired an old USB1.1 board which shows how it used to be done ‘properly’, in the days when anyone cared about these things.

Note the little 8-pin chip on the left hand side. That’s the one responsible for switching and protecting the power output to the USB sockets. The one fitted is a Micrel M2526, but there’s also space for a Texas TPS2052 which does the same job. Belt and braces!

Super Breakout to JAMMA, Part 1: Power Supply

In a previous post I resurrected an Atari ‘Super Breakout’ PCB from 1978. One of the rules of my collection of arcade game boards is that they should all be playable, if they’re working. To that end I try to construct adapters to make the games all compatible with the JAMMA wiring standard, so I can just plug them in to my gaming setup and enjoy them. Usually it’s just a matter of wiring: most game PCBs after about 1980 use similar power and control signals to the later JAMMA standard, but differently wired, so no electronics are needed. Plug time: the Deluxe Arcade JAMMA fingerboard is really handy for making adapters, and I sell them. They’re great value. Buy lots and give them to all your friends.

Super Breakout isn’t such an easy case, though. About the only things which can be wired directly to a modern arcade setup are the coin contacts and start button. Everything else is unusual, starting with the power supplies.

JAMMA wiring provides +5V for powering the main logic, +12V which is usually used by the audio power amplifier, and -5V which is also used on some boards by the sound generation circuitry. Super Breakout’s power input circuitry looks like this.


The circuit appears to expect +10V DC, and a pair of centre-tapped AC supplies, one of 16.5V AC and one of 25V AC. The end result of it all is supplies annoyingly similar to the JAMMA standard: +5V, +12V and -5V, with an extra +20V for the audio power amplifier. I could, of course, just modify the board so that those supplies come straight from the JAMMA wiring, but that would violate another of my rules: no modifications to the original PCBs. Any conversions or adaptations must be done so that the original board, unmodified, can plug into my adapter and thence into a JAMMA connector.

Looking more closely at the circuit diagram, the situation isn’t as bad as it looks. The +10VDC just feeds the input to a regulator which generates the +5V, so it just needs to be a DC voltage large enough to allow the LM323 regulator to do its job. With a regulator this old, this ‘dropout voltage’ is about 3V, so anything from 8V DC upwards should be fine. The lower we can keep this voltage, the less power the regulator will have to dissipate as heat, so the game will run cooler. That’s got to be a good thing.

The 16.5V AC turns out to be used just to power the -5V regulator, so any negative DC voltage greater than about -8V (again allowing for the dropout voltage) will be OK. It doesn’t need to be AC at all. The 25V AC input is simply used to generate the +20V and +12V supplies, so it also doesn’t need to be AC. +20V DC will do fine.

Having figured this lot out, the power supply problem is much less daunting. Converting the +5V and +12V from JAMMA to +8V, +20V and -8V is perfectly manageable.

Various power supply modules are available at low cost from far-eastern suppliers on eBay, including the very popular 150W boost converter module. One of those is just right for converting +5V up to +8V, and a smaller off-the-shelf module can convert +12V up to +20V. Incidentally, though it would seem easier to convert +12V down to +8V, I chose not to do this: the +8V supply to Super Breakout needs to be able to deliver several amps to power all the logic, and the +12V JAMMA supply isn’t rated to handle that sort of load. JAMMA power supplies assume that the lion’s share of the load is on the +5V rail, so that’s where I’ve put it.

Deriving -8V is a bit more tricky. The commonly-available boost converter modules only handle positive voltages, and I can’t play any funny tricks with ground because the +8V and +20V supplies need to share ground with -8V. The answer is a Ćuk converter. A few components hooked on to the switch output of the +20V boost converter can deliver a negative voltage. It’s not regulated, and will depend somewhat on how hard the +20V boost converter is working, but it’s good enough to feed the -5V regulator on the Super Breakout board. Below is a picture of the arrangement. The components inside the dotted pencil outline are on the off-the-shelf boost converter (of the ‘LM2577‘ type commonly available on eBay).


The overall arrangement looks like this, in diagram form:img_20160917_204933

and in real life, it all fits together quite neatly.


The 5V-to-8V boost converter is the large red board at the top. The 12V-to-20V boost converter is the blue board at bottom right, and the components for the Ćuk converter are on the matrix board at bottom left. Note the red wire taking the signal from pin 4 of the LM2577 chip to feed the converter. Game on!




Making BeagleBone Black serial number available to user applications

The BeagleBone Black is a handy little board. It has a 1GHz ARM processor and 4GB of on-board Flash storage, and runs Linux very easily. In particular, the Debian distribution is available ready-made to just copy on to the board from an SD card. I’ve been using them in various embedded applications recently.


One of the applications I’m working on at the moment will be deploying BeagleBone Black boards in hundreds of locations, and we have to manage them sensibly. When managing all these boards, it will make our lives much easier to know their identities. Happily, the BeagleBone Black is fitted with an EEPROM which contains various useful information about it, including its serial number and a copy of the barcode stuck to the board.

The EEPROM is accessible via the I2C bus. The bus itself is accessible via /dev/i2c-0 at address 0x50. As standard, Debian Linux is set up so that the group i2c has access to this device. However, the kernel device tree is one step ahead of us. A special at24 driver takes over access to the EEPROM, so any attempt to access it directly via /dev/i2c-0 just gets denied with ‘Device or resource busy’. The contents of the EEPROM are available, however, in sysfs under /sys/bus/i2c/0-0050/eeprom.

There is also a bone-capemgr driver which presents some of the EEPROM contents in a more convenient way, as a series of files elsewhere in sysfs, under /sys/devices/bone_capemgr.9/baseboard/

This is all very handy, but all the files in sysfs are only readable by root. That’s not helpful for my applications. I don’t want to be running things as root if I can possibly help it. I wanted to find a reasonably legitimate way to make the relevant sysfs files available to a group of users. We can’t just change the permissions on those files because sysfs is created dynamically, so any changes would be lost after a reboot.

The obvious way to do this would be via a udev rule so that the permissions are set up when the relevant devices are found. However, udev rules don’t seem to have a direct way to change the permissions and ownership of files in sysfs. After some experimentation I came up with a couple of rules which did what I wanted. They match on the narrowest set of keys I could work out, and run chmod and chown to set the permissions the way I’d like them:

DRIVER=="bone-capemgr", RUN+="/bin/chown root:i2c /sys$env{DEVPATH}/baseboard/serial-number"
SUBSYSTEM=="i2c", DEVPATH=="*0-0050", RUN+="/bin/chown root:i2c /sys$env{DEVPATH}/eeprom", RUN+="/bin/chmod 0640 /sys$env{DEVPATH}/eeprom"

Put those lines in a suitable rules file. I used /etc/udev/rules.d/30-bone-capemgr.rules. Then, running

udevadm trigger

Should trigger the rules and set the permissions. Because sysfs is recreated at boot time when the various devices are found and added, the rules will trigger each time and leave the permissions the way we want them.

The board serial number is to be found in bytes 16-28 of the EEPROM, and the barcode is in bytes 80-103. The hexdump utility is handy for extracting the data. For example,

hexdump -e '8/1 "%c"' /sys/bus/i2c/devices/0-0050/eeprom -s 80 -n 23

should show the barcode. Wrap that up in a script and we have a programmatic way of finding the board’s identity.

Super Breakout Saga

In the beginning, or at least in 1972, there was Pong. It was one of the first video games to become widely popular, and made Atari’s name in the games industry. It wouldn’t be overstating the case to call it seminal, even though the game itself involved only bouncing a ball between two bats. Four years later, Pong begat Breakout, which extended the bat-and-ball mechanics of Pong to knocking bricks out of a wall. Then came Super Breakout, a similar game, but more complex, with three different modes of play and even multiple bats and balls. Adding the new features needed a new, powerful ingredient: Super Breakout was one of the earliest arcade games to feature a microprocessor. This was in 1977, before Space Invaders, before Pac-Man, before Donkey Kong.


I picked up this PCB several years ago on eBay. The price was keen because, of course, it was ‘untested’. We all know what that means. Broken. That’s the way I like them. It’s hard to get to know a game board that’s in perfect working order.



Getting this one running was more than the usual challenge. From about 1980 onwards, a few conventions about how arcade games were built and wired got established. This game pre-dates those, so the usual rules don’t apply. Power? Instead of 5V and 12V DC supplies, it wants 10V and 22V AC, centre-tapped. Video? Instead of the usual colour RGB with separate sync, it delivers black-and-white composite video, and expects a screen with strips of coloured film stuck to it. Controls? No joystick here. Not even a trackball. Just an analogue potentiometer to control the paddle, and various flashing lights and switches.

My aim with every arcade game I acquire is to adapt it to the JAMMA standard, so it’s easy to plug it in and play it. This one was going need more than just a bit of wiring.

The first job was to get the board running. I rigged up temporary power supplies and a black-and-white monitor which could handle its video output.

The most serious fault was faulty RAM chips. Super Breakout has eight RAM chips of a whole one kilobit each, totalling a spectacular 1 Kbyte of RAM. Six of them were faulty. Fortunately a kind member of the most excellent UKVAC forum had some available. Identifying the faults was made easier by the board’s test mode, which makes beep-boop-boop noises to indicate which chips it thinks are faulty.


The sockets holding the program ROMs and the processor were all rubbish and had to be replaced with modern ones. Cleaning them never worked reliably. This particular version of the game uses 12 ROM chips, each holding 4 kilobits. That’s a generous 6 Kbyte of program code, but it’s also 216 pins in sockets to go wrong.


There was one faulty logic gate ( a 7420) associated with the ‘game select’ and ‘serve’ switches, and the DIP switches for choosing the game options needed a squirt of DeoxIT switch cleaner. Success!


With those problems attended to the board passed all its self tests and seemed to run quite happily. Now to design that JAMMA adapter.

Tektronix 549 Storage Oscilloscope, Restored

A couple of years ago, I restored this exquisite brute of an oscilloscope to working order. You can read the story starting with part 1. I never posted any pictures of the finished article, so here they are.

You can read more about the machinery at the TekWiki.








Switched on and working, with all four traces showing.



I made a short movie of the storage functions working.

Cracking a password-protected PDF file

Suppose you asked an insurance company for a letter. The insurance company kindly sent it as a PDF attached to an email. Sensibly, they protected that PDF with a password which they told you over the phone. You wrote it in a notebook and then left the notebook at work over the weekend.


How could you read the letter in the password-protected file at home, then? Remembering that the password was definitely an English word, and all in lower case, a dictionary attack has got to be worth a try.

Linux provides some handy tools for this. There’s a list of English words in /usr/share/dict/words, and a suite of PDF tools which can attempt to open the file using a password, indicating success or failure. A few minutes with Python and:

import os,sys

while True:
  word = wf.readline().strip().lower()
  if word == '':
    print "No solution found"
  print word
  cmdline = 'pdftotext -upw "'+word+'" '+sys.argv[1]
  result = os.system(cmdline)
  if result == 0:

The same thing must be possible in a more hipsterly fashion using awk, but I couldn’t be bothered to figure out a sufficiently baroque command line.

By the way, the password was ‘orange’. Don’t tell anybody.

Reliable I2C with a Raspberry Pi and Arduino

There are many ways of connecting sensors and devices to a Raspberry Pi. One of the most popular is the I2C bus. It’s great for devices which don’t need to transfer too much data, like simple sensors and motor controllers, and it’s handy because lots of devices (up to 127, or even more) can be connected to the same pair of wires, which makes life really simple for the experimenter. I’ve mentioned using the I2C bus in another blog post, because sometimes a bit of software fiddling is needed to get it to work.

Recently I’ve been working on a project involving various devices connected to a Raspberry Pi. Some of them use I2C. The project is based around a breakout board I designed for the Multidisciplinary Design Project at Cambridge University Department of Engineering, in which students collaborate in teams to put together a robot. The breakout board is shown next to the Raspberry Pi in the photo below.


It fits on top of the Pi, and has lots of useful features including a student-proof power supply, real time clock, accelerometer, space for a Zigbee module, analogue inputs, diagnostic LEDs and four motor driving outputs, all wired to convenient connectors.

The analogue inputs and motor outputs are implemented by a PIC microcontroller connected to the I2C bus. The software for the PIC was written by an undergraduate several years ago. It works well, but seems to have some odd habits. I found that it would apparently work, but sometimes an attempt to read data from the PIC would just fail, or return wrong data, and sometimes data would get written to the wrong register. At first I suspected a wiring problem, but examining the SDA and SCL signals with a scope showed nothing wrong. I tested another device on the same bus – a Philips PCF8575 I/O expander – and it worked perfectly every time. That narrowed the problem down to the PIC. Since there was nothing I could do about the PIC’s software, I had to find a workaround.

I spent some time experimenting with where the communications seemed to go wrong. Reading from an I2C device usually involves two separate operations on the bus. The first one tells the I2C device which register address we want to read, and the second does the actual read. The diagram below shows the sequence. The ‘control byte’ in each case sends the address of the I2C device (0x30 in this case) plus a bit indicating read or write.


I found a pattern in the failures. From time to time, the write operation which sets the register address would fail, reporting ‘I/O error’. After that, reading the data would return the wrong value. I modified my code so that if the write operation failed, it would retry a couple of times before giving up. It turned out that retrying was always successful, if not on the first attempt then on the second. However, the data read would still return the wrong value. The value returned was always the address of the register I wanted! It seemed as if something was getting stuck somewhere in the I2C system. Whether it was in the Linux drivers, or the PIC software, I don’t know, and I didn’t spend long enough to find out. My assumption is that the PIC software is sometimes just too busy to respond to the I2C operations correctly.

I tried the retry strategy again, and it turned out that the second attempt to read the data byte always got the right value. The algorithm to read reliably looks like this, in pseudo-code:

  if (write_register_address() fails)
    retry up to 3 times;

  if (we had to retry writing register address)

In practice I was using the Linux I2C dev interface to implement this. Yes, it’s a bit of a nasty hacky workaround, but it did get the communications working reliably.

There was another device I wanted to talk to: an Arduino Mini running a very simple sketch to return some sensor data. This also used the I2C bus. There are handy tutorials about how to get an Arduino to behave as an I2C slave device, like this one. The I2C interface is implemented nicely by the Wire library. Implementing a slave involves responding to two events: onReceive and onRequest.

The onReceive event is called when data, like the register address, is written to the slave, and the onRequest event is called when the master wants to read data. My initial code looked like this:


void receiveEvent(int bytes) {
  registerNumber = Wire.read();
void requestEvent() {

This worked most of the time, but after a few thousand transactions, it would appear to ‘lock up’ and ignore any attempt to change registers – it would always return the same register, and in fact no more onReceive events were ever generated. Of course, it turned out to be my fault. When reading data in the onReceive event code, it turns out to be important to make sure that data is actually available, like this:

void receiveEvent(int bytes) {
    registerNumber = Wire.read();

That solved the problem. It’s annoying that reading non-existent data can lock up the whole I2C interface, so watch out for this one if you’re using an Arduino as an I2C slave.