|
| 1 | +spi-dump |
| 2 | +======== |
| 3 | + |
| 4 | +spi-dump is a commandline utility for dumping SPI EEPROMs, using an Arduino as a |
| 5 | +bridge between a console and SPI bus. |
| 6 | + |
| 7 | + |
| 8 | + |
| 9 | +There are quite a few quick tutorials and code snippets floating around |
| 10 | +demonstrating how to use an Arduino to interface with SPI EEPROMs, but all that |
| 11 | +I've come across implement the majority of the logic on the Arduino side. I |
| 12 | +found this to be problematic for a couple of reasons: |
| 13 | + |
| 14 | + * **Arduinos are difficult to debug**: If your sketch crashes, it can be |
| 15 | + non-trivial to work out why. This can be particularly frustrating when |
| 16 | + implementing extra functionality. |
| 17 | + |
| 18 | + * **Many cheaper Arduinos have pretty extreme resource constraints**: When |
| 19 | + trying to extend several of the more popular code snippets, my off-brand |
| 20 | + board soft-locked regularly. The more host resources you can use, the better. |
| 21 | + |
| 22 | +With spi-dump, the Arduino serves only as a dumb bridge; the amount of code |
| 23 | +needed to drive it is minimal. This allows the added convenience of the host's |
| 24 | +friendlier development environment and vastly greater resources to be leveraged |
| 25 | +in the implementation of some handy features: |
| 26 | + |
| 27 | +### Checksumming |
| 28 | + |
| 29 | +In-system programming often yields sub-optimal reads, making the creation of |
| 30 | +large EEPROM dumps next to impossible. This is the killer feature I really |
| 31 | +needed, and similarly the reason this program exists. |
| 32 | + |
| 33 | +The way this is implemented isn't exactly efficient, however: The redundancy |
| 34 | +comes from performing every array read twice. As such, checksumming cuts an |
| 35 | +already bitterly slow transfer speed in half. This seems to be a necessary cost, |
| 36 | +since any bit in the stream could potentially be flipped. There are a couple of |
| 37 | +ways this could be improved in the future though: |
| 38 | + |
| 39 | + * Currently, spi-dump uses opcode 0x03 to perform reads since it and its |
| 40 | + parameters seem to be reasonably universal. However, most EEPROMs define |
| 41 | + vendor-specific opcodes which allow reading data at a higher rate. Attempting |
| 42 | + to leverage this will be a challenge, but it should be possible. |
| 43 | + |
| 44 | + * A commandline switch to disable checksumming would probably be a good idea. |
| 45 | + |
| 46 | +### Progress metering |
| 47 | + |
| 48 | +With the host computer in the driver's seat, keeping track of where in the |
| 49 | +transfer we're up to and working out roughly how long we have left is a little |
| 50 | +easier. As such, spi-dump provides a progress meter with the standard bells and |
| 51 | +whistles to tell you that, yes, that transfer really is going to take three |
| 52 | +hours. |
| 53 | + |
| 54 | +It's a little spartan, being driven by printf padding and `\r`, but it works |
| 55 | +alright for the time being. |
| 56 | + |
| 57 | +## "How do I use this?" |
| 58 | + |
| 59 | + 1. Flash `spi-dump.ino` to your Arduino and reset it |
| 60 | + 2. Install spi-dump: |
| 61 | +``` |
| 62 | +sudo dnf install glib2-devel |
| 63 | +./autogen.sh |
| 64 | +sudo make install |
| 65 | +``` |
| 66 | + 3. You're ready to go! |
| 67 | +``` |
| 68 | +spi-dump -o my_dump.bin -n 0xffff /dev/ttyUSB0 |
| 69 | +``` |
| 70 | + |
| 71 | +## "This is broken" |
| 72 | + |
| 73 | +Some stuff to be weary of: |
| 74 | + |
| 75 | + * Most EEPROM datasheets I've read outline opcodes whose purpose is to wipe the |
| 76 | + entire chip, and often they're only a bitflip away from more useful ones. |
| 77 | + Having had several stomach-sinking close calls in the development of this |
| 78 | + tool, I have some advice: read the datasheet carefully, quintuple check your |
| 79 | + wiring and be sure spi-dump isn't going to accidentally nuke your data. |
| 80 | + |
| 81 | + * Something that frustrated me for quite some time were issues of the host |
| 82 | + machine and the Arduino getting out of sync. If spi-dump appears to have hung |
| 83 | + and the transfer lights aren't flashing, this is probably your problem. It |
| 84 | + took me a while to work out that [DTR][dtr] will cause an Arduino reset and |
| 85 | + this problem along with it, but this [can be fixed][reset fix]. |
| 86 | + |
| 87 | + * I'm by no means an expert, so this program may or may not eat your babies. If |
| 88 | + your offspring are indeed offered as sacrifice to the Dark Lord, however, a |
| 89 | + bug report would be much appreciated. |
| 90 | + |
| 91 | +[dtr]: https://en.wikipedia.org/wiki/Data_Terminal_Ready |
| 92 | +[reset fix]: http://playground.arduino.cc/Main/DisablingAutoResetOnSerialConnection |
| 93 | + |
| 94 | +## "What's so special about `0xff`?" |
| 95 | + |
| 96 | +For the most part, SPI and RS-232 are pretty compatible. Data in, data out, |
| 97 | +that's no problem. But the extra pins, usually required to operate an EEPROM, |
| 98 | +don't map so conveniently. So spi-dump (and the Arduino sketch it comes with) |
| 99 | +implement a sort of mini-protocol. Basically, `0xff` serves like an escape |
| 100 | +opcode; the next byte the Arduino receives should be interpreted as a command |
| 101 | +for the Arduino itself, rather than being forwarded onto the SPI bus. For |
| 102 | +example, pulling the chip select pin low might go something like this: |
| 103 | + |
| 104 | + 1. spi-dump sends `0xff 0x01` (escape command, pull low command) |
| 105 | + 2. As an acknowledgement, the Arduino will reply with `0xfe` (`0x01` ⊕ |
| 106 | + `0xff`) |
| 107 | + |
| 108 | +That's all there is to it. |
| 109 | + |
| 110 | +I hate to be that guy, but if you want more detail then the source really is the |
| 111 | +best place to find it. |
| 112 | + |
| 113 | +## "Goddamn, this README is _long_" |
| 114 | + |
| 115 | +Yes. Yes it is. |
0 commit comments