This adds a dump function for the ostc3 series computers. This function dumps the whole external eprom, that contains the dive-headers and the dive data.
Signed-off-by: Anton Lundin glance@acc.umu.se ---
I haven't seen the code for the simulator, but the relevant parts are that the dive headers are located at: ; 1st: 200000h-2000FFh ; 2nd: 201000h-2010FFh ; 3rd: 202000h-2020FFh ; 100: 264000h-2640FFh ; 256: 2FF000h-2FF0FFh
And in those headers at byte 2 and 5 are the pointers to where in the memory the actual dive profile are, in little endian.
It shouldn't be too hard to write simulator code for that.
src/hw_ostc3.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-)
diff --git a/src/hw_ostc3.c b/src/hw_ostc3.c index a5f96bf..4487d15 100644 --- a/src/hw_ostc3.c +++ b/src/hw_ostc3.c @@ -109,15 +109,17 @@ static const unsigned char ostc3_key[16] = { };
static dc_status_t hw_ostc3_device_set_fingerprint (dc_device_t *abstract, const unsigned char data[], unsigned int size); +static dc_status_t hw_ostc3_device_dump (dc_device_t *abstract, dc_buffer_t *buffer); static dc_status_t hw_ostc3_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, void *userdata); static dc_status_t hw_ostc3_device_close (dc_device_t *abstract); +static dc_status_t hw_ostc3_firmware_block_read (hw_ostc3_device_t *device, unsigned int addr, unsigned char block[], unsigned int block_size);
static const dc_device_vtable_t hw_ostc3_device_vtable = { DC_FAMILY_HW_OSTC3, hw_ostc3_device_set_fingerprint, /* set_fingerprint */ NULL, /* read */ NULL, /* write */ - NULL, /* dump */ + hw_ostc3_device_dump, /* dump */ hw_ostc3_device_foreach, /* foreach */ hw_ostc3_device_close /* close */ }; @@ -443,6 +445,65 @@ hw_ostc3_device_set_fingerprint (dc_device_t *abstract, const unsigned char data }
+static dc_status_t +hw_ostc3_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) +{ + hw_ostc3_device_t *device = (hw_ostc3_device_t *) abstract; + + // Erase the current contents of the buffer. + if (!dc_buffer_clear (buffer)) { + ERROR (abstract->context, "Insufficient buffer space available."); + return DC_STATUS_NOMEMORY; + } + + // Make sure the device is in service mode + dc_status_t rc = hw_ostc3_device_init (device, SERVICE); + if (rc != DC_STATUS_SUCCESS) { + return rc; + } + + // Enable progress notifications. + dc_event_progress_t progress = EVENT_PROGRESS_INITIALIZER; + //unsigned int size = (RB_LOGBOOK_SIZE * RB_LOGBOOK_COUNT) + SZ_MEMORY; + unsigned int size = 0x400000; + progress.maximum = size; + device_event_emit (abstract, DC_EVENT_PROGRESS, &progress); + + // Allocate the required amount of memory. + if (!dc_buffer_resize (buffer, size)) { + ERROR (abstract->context, "Insufficient buffer space available."); + return DC_STATUS_NOMEMORY; + } + + unsigned char *data = dc_buffer_get_data (buffer); + + unsigned int nbytes = 0; + while (nbytes < size) { + // packet size. Can be almost arbetary size. + unsigned int len = 4096; + + // Limit the packet size to the total size. + if (nbytes + len > size) + len = size - nbytes; + + // Read a block + rc = hw_ostc3_firmware_block_read (device, nbytes, data + nbytes, len); + if (rc != DC_STATUS_SUCCESS) { + ERROR (abstract->context, "Failed to read block."); + return rc; + } + + // Update and emit a progress event. + progress.current += len; + device_event_emit (abstract, DC_EVENT_PROGRESS, &progress); + + nbytes += len; + } + + return DC_STATUS_SUCCESS; +} + + dc_status_t hw_ostc3_device_version (dc_device_t *abstract, unsigned char data[], unsigned int size) {
On 2015-04-25 18:33, Anton Lundin wrote:
This adds a dump function for the ostc3 series computers. This function dumps the whole external eprom, that contains the dive-headers and the dive data.
Signed-off-by: Anton Lundin glance@acc.umu.se
I haven't seen the code for the simulator, but the relevant parts are that the dive headers are located at: ; 1st: 200000h-2000FFh ; 2nd: 201000h-2010FFh ; 3rd: 202000h-2020FFh ; 100: 264000h-2640FFh ; 256: 2FF000h-2FF0FFh
And in those headers at byte 2 and 5 are the pointers to where in the memory the actual dive profile are, in little endian.
It shouldn't be too hard to write simulator code for that.
The simulator code is located here (as pre-compiled binaries, a tarball, or a patch series against libdivecomputer git):
http://libdivecomputer.org/simulator/
I don't mind applying your patch, but I wonder whether this is the "right" kind of memory dump. For me, the main use case for memory dumps is to be able to replay a download on the simulator. Now, one of the nice features of the ostc3 protocol is that we don't need to know the internal memory layout, and can just ask for the dives. With a raw dump of the eeprom, we'll need all those details again in the simulator. Certainly not impossible, but not ideal either.
An alternative that I have been thinking about, for those devices without support for memory dumps, is to define a simple binary data format that can store multiple dives. That way, the simulator can easily read and send individual dives, all without needing any internal knowledge.
Of course that's not mutually exclusive with your patch, so let's apply it after a few modifications:
- //unsigned int size = (RB_LOGBOOK_SIZE * RB_LOGBOOK_COUNT) +
SZ_MEMORY;
Remove this uncommented code.
- unsigned int size = 0x400000;
Can you add a macro? Something like SZ_EEPROM for example.
// packet size. Can be almost arbetary size.
unsigned int len = 4096;
Same here. You can re-use SZ_FIRMWARE_BLOCK here.
// Limit the packet size to the total size.
if (nbytes + len > size)
len = size - nbytes;
This isn't strictly necessary if the total size is a multiple of the packet size.
Jef
On 01 May, 2015 - Jef Driesen wrote:
On 25-04-15 18:33, Anton Lundin wrote:
This adds a dump function for the ostc3 series computers. This function dumps the whole external eprom, that contains the dive-headers and the dive data.
The patch has been applied (with a few minor modifications).
Thanks. I didn't get around to fix the minor things you pointed out. I agreed with all of them, and i was obviously to tired when i sent that patch to notice them myself.
For me it really doesn't matter if we write our own "mem-dump" format or we use the external eprom format straight off. The external eprom is generally bigger, but its completely independent of everything. I kinda thought it would be nice to have all the data if i needed to reset my logbook for some reason, and its nice to be able to hack on subsurface/libdivecomputer without pulling out my dc's, and its nice to be able to generate weird data to test the chain.
//Anton