The whole purpose of me making a test PCB was to try and push the speed up from what I was able to achieve with breadboard.
On the breadboard I was able to reliably use the I2C bus speed of 800KHz, above which I'd get garbage back from the cartridge. Probably down to a multitude of reasons in between the I2C signal leaving the pi, going across large jump wires to the chips, then large jump wires carrying the address and bus data to/from the cartridge, not to mention the known crappiness of the breadboard itself for carrying signals with any kind of integrity. there's stray capacitance all over the place, the wires pick up noise like antennas... basically good for demonstrating proof of concept and not much more.
so with the PCB I can eliminate a good chunk of that uncertainly. I can have ground planes, data pairs, short signal lines, decoupling caps... the whole shooting match.
the 23017's can run at an I2C speed of 1.7MHz. more than double I've been able to get so far.
I spent last night going through the bus speeds to see how much effect it had. in the above vid, at 800KHz, tetris dumps in just under 20 seconds. Upping that to 1.2MHz was not only successful (MD5Sum checked out) but came down to 14 seconds. not bad but I think we can do better (it's only 32K after all at ~2KB/s)
So what happens when we go for the full monty of 1.7MHz? Success! MD5 checks out ok, but the dump time was only down to 12 seconds... which sounds like we have a bandwidth between the pi and chips problem. Starting with the easy, I overclocked the pi (it was default 700MHz) and bumping up to TURBO (1.0GHz) helped and brought the dump time down to 9.5 secs. better but still not great (when we have a large cartridge like Perfect Dark, it's still going to be 5 seconds per bank with 128 banks still comes in at over 10 mins
)
Optimise, optimise, optimise (Prime)
so now I need to start looking at where there are inefficiencies in my code. I was holding an input buffer of 64 bytes and writing that to SD so figured that operation may have added some slowening. and increasing that to 4096 bytes (4K) improved things a little bit. I took out a load of redundant code from the early days which was doing diagnostic logging, another minor improvement, so now I'm looking at how the bytes get transferred to and from the 23017's.
One of my very first major optimisations that I made in the early days was that the wiring pi library was only working in a pin mode sense. so to change all 8 pins on a port (each chip has 2 8-pin ports) I effectively had to send 8 commands to the chip. but each command carried the whole byte, so my code was slow by a factor of 8 as I only needed one command with all 8 pins updated in one go. So I bypassed the top level pin write function and pulled out the lower level read/write register functions and bit shifted my data in as necessary in memory beforehand and placed whole bytes onto the register.
now for every read operation, I have to:
place the address onto the address bus (chip 1 port A and B) = two write operations
set the read/write pins of the cartridge (chip 2 port B) = one write operation.
read the data bus (chip 2 port A) = one read operation
re-set the read/write pins (chip 2 port B) = one write operation.
now wiring pi has a few layers of abstraction in order to have a consistent interface across lots and lots of devices so I can pare that back (and probably get rid of the wiring pi dependency altogether, which has the added advantage that I can run this on C.H.I.P.) but I think the biggest potential help I just found was by digging through the datasheet of the devices... fast sequential mode.
fast sequential mode lets me write multiple bytes in one hit as long as the registers are sequential, removing some extra overhead. Beyond that I think I'm then done with how far I can go with Pi1 (or zero) and I2C. I haven't yet tried on a Pi2 or 3 mainly because I want to keep it usable on an original or Zero, meaning I may have to bite the bullet and get the SPI version of the chip (MCP23S17). The pins are more or less identical so I should be able to re-use this PCB with minimal modding.
So interesting times ahead!