Close

♫ Flash! (aa-aahh!) Saver of the Usersettings! ♫

A project log for HP 82240B IR Receiver and Printer Interface

This is an IR receiver and interface for adapting a commodity receipt printer to be 82240B-compatible.

ziggurat29ziggurat29 07/12/2017 at 19:020 Comments

Summary:

It occurred to me that it would be useful to save some configuration in a non-volatile manner. This board and this chip does not have any conventional non-volatile storage (e.g. EE or external serial EE), but there's plenty of pages of unused program memory, so I use the last one to be used for infrequently changed NVRAM settings.

Also, I validated my HP82240B rendering engine.

Deets:

Over the past couple weeks it occurred to me that this interface board has some utility beyond the primary intent of being an adapter to a receipt printer to emulate a HP82240B -- for instance, it could be also useful as an IR-to-serial adapter, forwarding IR data to the USB port (or UART if you need to, and don't have a printer there). This is easy enough to do and it's easy enough to set the system up in that manner, but this state will not persist boot-to-boot. So, time for some persistent settings.

Most non-volatile memory is known for the exhaustion phenomenon, so you generally try to avoid burning/erasing except when needed. Frankly, for this application: storing user settings, the burning/erasing will naturally happen very infrequently since it is a user-initiated activity that is only occaisionally performed. I'm sure all readers of this log post will have long since passed on to the hackerspace in the sky before they have exhausted the million flash erase-write cycles for settings changes. That being said, like my friend Ming the Merciless says: "I like to play with things awhile, before annihilation." So I'm going to go a little further with this featurette.

The flash is organized in 'pages' which is the smallest unit of erasure. On this part, the page size is 1 KiB. That should be more than enough for my setting storage -- at least until I have a need for large object like strings -- but for now it's just a few integers.

What I'm doing in this implementation is to store a struct of my settings in the last page of flash on the device (leaving all the previous pages for the program). That last page will have zero or more copies of the settings. The last copy of the settings is considered the current values.

So, upon boot up, the code searches for the last copy of settings, and initializes the RAM-based copy with that data. If it doesn't find any settings, then it will intialize the RAM-based copy with the baked-in default values. The rest of the system then proceeds to use whatever is in the RAM-based copy.

I want to have the RAM-based copy because I want to be able to change settings on the fly via the monitor interface (yet-to-be-implemented; it will be on the USB CDC). When you have the device dialed in the way you like, then you can persist the settings.

Persisting works like this:

  1. find the last valid settings image
  2. see if there is space after it for one more settings
    a) if there is, that is where we will be programming
    b) if there is not, erase the page, and let the start be the place we will be programming
  3. program the flash at the place we located

A simple scheme, but I wanted to document it here. This way, the flash exhaustion is reduced by a factor of how ever many settings structures can be fit on a page, which presently for me is 64 (but this will go down as I add more settings, but still).

Other News

I did validate my HP82240 printer rasterizer functionality. It was a bit painful, but I managed to dump the image over the serial port, then meticulously hand-craft a bitmap of the data. For example:

0E 00 00 02 00 00 02 00 04 0E 00 00 00 00 00 00 00 00 00 00 00 
C2 07 00 02 00 38 02 00 04 08 00 00 00 00 00 00 00 00 00 00 00 
42 B0 3C 47 04 04 87 E3 25 08 00 00 00 00 00 00 00 00 00 00 00 
C2 53 45 42 04 38 02 14 14 08 00 00 00 00 00 00 00 00 00 00 00 
42 50 45 42 04 40 82 17 0C 08 00 00 00 00 00 00 00 00 00 00 00 
42 50 3D 8A 07 44 4A 14 14 08 00 00 00 00 00 00 00 00 00 00 00 
CE 17 05 04 04 38 84 E7 25 0E 00 00 00 00 00 00 00 00 00 00 00 
00 00 04 80 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 

renders into:

v       v       v       v       v       v       v       v       v       v       v
.###.....................#.......................#................#......###....
.#....#####..............#.................###...#................#........#....
.#....#.....##.#..####..###...#...#.......#.....###....###...####.#..#.....#....
.#....####..#.#.#.#...#..#....#...#........###...#........#.#.....#.#......#....
.#....#.....#.#.#.#...#..#....#...#...........#..#.....####.#.....##.......#....
.#....#.....#.#.#.####...#.#...####.......#...#..#.#..#...#.#.....#.#......#....
.###..#####.#...#.#.......#.......#........###....#....####..####.#..#...###....
..................#............###..............................................

Tada!

That bitmap was captured from within the physical printer rendering task, so that means data is now flowing correctly from sender (HP28C calculator in my testing), to IR detector, to IR decoder, to HP82240 rendering engine, to physical printer rendering engine. So it's getting close to being a working system, once my printer arrives (and I have coded and debugged that module).

Next:

Now I have to transform that bitmap into graphics commands for the physical printer.

And then there will be cake.

Discussions