An Even Newer, Even More Improved V2 Power Supply: Part 6
After working out the accounting, it was back to firmware.
I love long weekends: I get enough time to write programs. This July 4th holiday, I finally got around to writing a simple windowing system for the LCD. OK, it's a trivial windowing system. I'm not sure why it took so many years to finally do it.
Anyway, the window system is built on top of the hardware LCD driver. Basically, I can use it to allocate LCD frame buffers for whatever display purposes I feel like. The active frame buffer gets displayed on the LCD. Updates to the other frame buffers occur in the background, and are applied to the hardware LCD when a frame buffer gets made visible. It may be simple, but it is really effective at increasing the amount of LCD real estate.
I had a push-button on the PCB that was dying for a use, so I set it up to cycle through the frame buffers. That was easy: I have things set up so that every frame buffer that gets created is automatically stuck onto a list of all the frame buffers that have been created. When a button press is detected, the program merely makes the 'next' frame buffer in the list visible. If it hits the end of the list, it starts over again from the start.
Right now, I have one frame buffer for the main power supply status page. There is a second frame buffer for the 'big clock'. That clock uses the ability of those Hitachi-based LCD controllers to create a custom character set that can display the digits 0-9 as really large numbers. I found that big-digit app on the web years ago, and it has been really useful.
The third frame buffer is the most interesting. I set it up as a window that accepts commands from the host computer so that the host can display messages on the LCD. The SheevaPlug is a headless beast, and as much as like that, there are times when I just wish I knew what it was doing without having to SSH into it. And now, I can.
The Window objects extend the command language as follows:
- erase - erase the entire display, leaving the cursor at 0,0 (upper left)
- show - tells the window system to put this window on the active LCD display
- row=<n> - set the cursor to row n
- col=<n> - set the cursor to col n
- msg=<msg> - display <msg> at the current row,col. The message can be a quoted string.
To reference a window in the command language, you specify the main object ("window"), and then the name of the specific instance of that object. In this case, the name given to the window that the host can write is called "host". As with the entire command language processor, the commands can be strung together:
- window:host erase msg="Hello, world!" show
That command would erase the frame buffer, write "Hello, world!" starting at (0,0), and then cause that window to be the visible window on the real LCD, as shown below:
The main reason to use the "show" argument would be for some kind of situation that required my attention. Otherwise, you don't really need it: the writes go to the frame buffer, and if I care about what is going on, I can cycle through them with the push-button.
The final firmware upgrade was to allow the command language to deal with quoted strings, \-protected double quotes, and conversion of \n and \r into newline and return operations for the LCD. It's the little things that make life better.
So what to display? I decided that I would take the best of 'df' and 'uptime' and show that. I set up a cron job to update the display once a minute.
Here is a pic of the status display:
I currently have a 750G laptop hard drive connected to it. It looks like it is starting to get full.
Finally, I like clocks, but I don't like setting them by hand. I added a command to set the SheevaPower clock in the same cron job. That means the SheevaPower clock will track the SheevaPlug's notion of time to within a minute, even correcting for daylight savings changes.
Life is very, very good.
Next up: Who Knows?
It will be worth it in the end.