Sometime this past December, I made the unfortunate decision to start playing Magic: the Gathering again.
Banter aside, it’s been pretty fun. Well, aside from when I need a token copy of a card. Which happens quite
a bit more often than you’d think. I run Zinnia as my commander.
This means that I can make a copy of just about any creature in my deck. Except it’s got different stats, which means I can’t just say
“wow look at this funny copy”. Yeah, it kinda sucks to track.
So, after a couple games of commander, I decided I need a better solution.

Jokes aside, there was really only one answer I could think of: a digital card. In theory, it can be anything. So I did some looking around and found some 320x240 2.0 inch displays on Aliexpress for about $3 each.

Doesn’t look so bad. As a reference, the original image looks like this (credit where it’s due for the image):

Getting this uploaded over USB to the microcontroller wasn’t that bad. I just registered my device with the host computer as a vendor-specific USB device, and then wrote a simple program on my laptop to upload it. So, that was cool, but you had to re-upload the image on reboot. Not great.

Obviously the answer to that is non-volatile storage. I soldered up an SPI flash chip to a breakout board. Then, I modified the firmware to program the uploaded image to flash instead of the display memory. Oh, and it loads from flash on boot. This works okay, but you’ve only got one card. At this point, it’s even worse than buying a physical copy of the card.
Flash memory is writeable any time, but only by changing bits from 1 to 0. To reset it back to 1, you must erase a whole sector. Since flash is programmed in 256-byte pages and erased in 16-page sectors (4kb, for those who can’t do math), even if a card is only 27 bytes (it’s not), it would be very nice if it could be aligned on these boundaries. Another issue is that erasing can only be done so many times before the flash stops working. This means that you should take care to use the memory as evenly as possible. In turn, you’ve gotta track how many times each sector has been erased.
But wait, shylie, doesn’t that mean you need a dedicated spot to track this? Wouldn’t that make distributing the erases be pointless, since re-writing the metadata would require erasing that sector?
Yes. Yes, it does in fact make a central record not useful. Just don’t centralize it, and you’re fine– have each sector track its own erase count.
Since cards are uploaded to the device, and removed later when not needed, you have to track whether a “card slot” is in use or not.
But. But shylie, wouldn’t you then need to erase once to mark unused, and another time to upload the card image?
Nope. In fact, since flash can be programmed from 1 to 0 without erasing, marking a card as unused is as simple as updating just one bit. Then you can just reset it to used status when actually uploading the new card.
Too bad. I’m not done with it yet.