So I was thinking about which device(s) to use as the MB128 replacement.
I have the following requirements:
- must meet timing requirements stated above for normal situations, and to drive outputs (including a chip select output switching between joypad and MB128)
- must be able to store 128KB of memory, virtually unlimited times
- must be able to survive in 'standby' mode on batteries for "a while"
- should be able to detect blatant violations of protocol
- must be a low total part count
- must have development tools (both hardware and software) accessible to a hobbyist
Nice to haves:
- would be nice to have a non-volatile storage
- would like it to be able to communicate with a computer (diagnostics, extra backups, etc.)
- would like it to be 5V-compatible (not just 5V tolerant)
The interesting thing about getting back into electronics is how much support hobbyists get these days... And how much time you can spend just seeing the landscape, and reviewing the vast array of parts and tools that are available.
So, the 'gold standard' would of course be imple,ented directly in silicon - either a CPLD or FPGA, driving memory directly. And MRAM, while expensive, could solve a few of the goals (reduce part count, non-volatile...). But I'd have to be more familiar with designing for hardware definition languages. Maybe later.
Microcontrollers are pretty handy, but so many of them fall short of the goals. Well, they can be augmented ith additional boards, but that adds cost and parts count. But on the other hand, the development environment is pretty easy these days.
The classic Arduino UNO sells for around $10-$15, and is a 16MHz, 5V-compatible microcontroller on a board about the size of a pack of cards.
But it has a tiny amount of memory, and 'C' language support for its GPIO pins is incredibly slow. Well, 4 microseconds may not seem so slow, but that would be an entire bit cycle for the MB128. So this device is 'out'.
But once you buy on of those, you see that there are many other options (although they immediately switch to 3.3V logic). In fact, the UNO seems like an expensive dinosaur, once you look at what else is out there.
Looking at
www.adafruit.com, one quickly finds that the next step up is an ARM Cortex M0-based system, and has a surprising value proposition (Feather M0 Express):
- CPU is 48MHz instead of 16MHz
- 32KB of RAM instead of 2KB
- 256KB of Flash instead of 32KB
- a much smaller board for a couple of dollars more ($20), but with a battery connector/charging circuit built in
...but unfortunately, it's still not enough
Moving up, we have the Cortex M4 (specifically, the 'ItsyBitsy M4 Express'):
- CPU is now 120MHz
- flash is now 512KB
- RAM is now 192 KB (*** finally, we have enough RAM !!!)
- 2 MB of SPI Flash for non-volatile storage
- several other neat features, and on an even smaller package
- for a price of $15US ... which is back to the original price range of the UNO above. Now the UNO seems like an outright ripoff.
There are other even more interesting options, like the ESP32 - but it seems the Arduino development environment isn't quite all there yet for that module.
So, let's see if the M4 is fast enough to "bit bang" the protocol (use CPU brute force to do something a chip could probably do trivially).
Using the arduino IDE, a read (poll) of a GPIO port is about 1.02 microseconds with cache disabled, and 0.39 microseconds with cache enabled. This is pretty good; maybe good enough.
But the Arduino GPIO libraries are not designed for speed; they are designed to handle all possible circumstances (different pin mappings for different devices; is the pin set to a pulse-wdith modulation, etc.).
Going one step further by reading the actual port and bit-masking the individual pins, the numbers came down dramatically:
cache disabled: 0.059 microseconds
cache enabled: 0.038 microseconds
(Notes: This page explained how to do it on a cortex M0-based board:
forum.arduino.cc/index.php?topic=334073.0This page details the pinouts and mappings on various Cortex M4 boards:
docs.google.com/spreadsheets/d/1hWHiM1Sk-gxcUmfgm5XQctqf9yaOnkmY66cwd_sRCiY/edit#gid=0 )
...This is definitely fast enough for the polling loop (remember that the 'short' clock pulse is 16 cycles, so a little over 2 microseconds). I just have to make sure that the other logic triggered by the state changes is also fast.
(Don't worry, I'll share my code when I have something worth sharing.)
Note: yes, I could use interrupts, but I understand that they introduce a 16-cycle latency, followed by possibly as many as 70 cycles of register pushes - this doesn't doesn't more efficient; just easier to code for.
So, now I just need to wait for my oscilloscope to arrive, in order to check real timings and conduct some tests.