An updated version of the RF12demo sketch has been checked in. Also available as ZIP.
This adds preliminary support for the 1 Mbyte dataflash memory present in the JeeLink v2.
The idea is very simple: the RF12demo app reports all incoming packets as before, but now also stores all valid packets in flash memory, if present. This is done by collecting packets into a 248-byte RAM buffer, and saving it to flash whenever it fills up. Small portions at the high and low end of flash memory are reserved for future use, the remainder is treated as a circular buffer of 256-byte pages – 3808 to be exact (i.e. 952 Kbyte).
The RF12demo commands have been extended accordingly, here is the startup screen on a JeeLink v2:
There is a “DF” line at the top which shows that dataflash memory was found, with page #41 written to last, and that we’re in the 3rd reboot since the flash was wiped. This unit picks up incoming data in group 5 @ 868 MHz.
The new “d” (dump) command reports which pages contain data:
At this point, I did a reset of the JeeLink, and then left it on to collect some more data. Here are the last few lines of a subsequent dump:
The new entries were added starting on page 42, and the clock started at zero again (there is no RTC). Some 248 seconds later, new entries were logged on page 43. The last number on these lines is a page checksum, btw.
The new “e” (erase) and “w” (wipe) commands require specific constant values as input arguments so that these destructive commands are not activated by a mere typo.
So far so good. The JeeLink can now keep track of what is coming in. But that’s just half the story. We also need to be able to get data out again, “replaying” the log from a certain point. This takes a bit more work.
Firstly, whenever a page gets saved to flash, something like this is sent out to USB:
This means that page 44 with seqnum 3 was saved with some entries starting at time 505 (seconds since the JeeLink was powered up). Here are the last few lines of a dump made right after that save:
The sequence number is an integer which increments on each reboot, and whenever the flash memory buffer wraps back to the first page. So the combination (seqnum,time) is unique and monotonically increasing, over time and across reboots.
On the PC side, these DF “packets” should be treated as readings and stored like any other incoming packet.
To get the saved entries out of the JeeLink, the PC has to send a “replay” command when it connects to it. This replay command must contain the last sequence number and time stored on the PC for the above DF packets. The JeeLink will look for the location of this page in flash memory (or the earliest one thereafter) and will then replay everything stored from there on.
This code is still work-in-progress, but the plan is to replay these packets as lines starting with “R seqnum time” instead of the usual “OK” prefix. Replay takes place at full speed, but depending on the amount of data stored this can still take a substantial amount of time.
After the requested data has been replayed, the JeeLink resumes its normal mode of reporting “OK” packets, “?” checksum errors, and “DF S” save commands.
I haven’t finished implementing the replay command yet, but storage of incoming packets seems to be working, so an updated version will be able to get at that stored data later.
One last point to note is that this storage implementation has built-in automatic “wear leveling” and hence creates no “hot spots”: there is no page in flash memory which gets written to more often than others, so this memory will be usable for at least its full 100,000 rated cycles. This is done by scanning the entire flash memory on startup to determine the last page written to, and by erasing 4 Kbyte blocks only when needed, ahead of the write pointer.
Total size of the new RF12demo is under 10 Kb, so there’s still lots of room left.
Update – several fixes and replay code added. Not 100% right yet, but all functions are implemented now.