>From 440b04f7988d407b197a42ce25462225af22a1d0 Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Sun, 19 Oct 2014 08:05:12 -0700 Subject: [PATCH 5/5] Add capability to read larger pages to atom2 backend This adds pagesize, crc_size, read_cmd and an alignment flag to the private device structure and modifies the reads accordingly. It does not bother with caching and never switches read commands, so even on dive computers that can switch between different sizes we take the penalty for reading in larger chunks even if we don't need them - during a typical download from the dive computer that will result in about twice the number of reads than a perfect algorithm would need (but still 1/8 of the reads that not supporting the larger pagesize would give us) but keeps our code much simpler. So far this is only enabled for the Aeris A300CS Signed-off-by: Dirk Hohndel --- src/oceanic_atom2.c | 50 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/src/oceanic_atom2.c b/src/oceanic_atom2.c index f507241a0d66..b5de4fcdf705 100644 --- a/src/oceanic_atom2.c +++ b/src/oceanic_atom2.c @@ -49,6 +49,10 @@ typedef struct oceanic_atom2_device_t { oceanic_common_device_t base; serial_t *port; unsigned int delay; + unsigned int pagesize; + unsigned int crc_size; + unsigned char read_cmd; + unsigned char aligned; } oceanic_atom2_device_t; static dc_status_t oceanic_atom2_device_read (dc_device_t *abstract, unsigned int address, unsigned char data[], unsigned int size); @@ -423,9 +427,16 @@ oceanic_atom2_transfer (oceanic_atom2_device_t *device, const unsigned char comm return EXITCODE (n); } - // Verify the checksum of the answer. - unsigned char crc = answer[asize - 1]; - unsigned char ccrc = checksum_add_uint8 (answer, asize - 1, 0x00); + // Verify the checksum of the answer; we can use unsigned short in both cases + unsigned short crc, ccrc; + if (asize == 256 + 2) { // 256 byte pages get two crc bytes + crc = (answer[asize - 1] << 8) | answer[asize - 2] ; + ccrc = checksum_add_uint16 (answer, asize - 2, 0x0000); + } else { + crc = answer[asize - 1]; + ccrc = checksum_add_uint8 (answer, asize - 1, 0x00); + } + if (crc != ccrc) { ERROR (abstract->context, "Unexpected answer checksum."); return DC_STATUS_PROTOCOL; @@ -468,6 +479,10 @@ oceanic_atom2_device_open (dc_device_t **out, dc_context_t *context, const char // Set the default values. device->port = NULL; device->delay = 0; + device->read_cmd = 0xB1; + device->pagesize = PAGESIZE; + device->crc_size = 1; + device->aligned = 0; // Open the device. int rc = serial_open (&device->port, context, name); @@ -549,6 +564,10 @@ oceanic_atom2_device_open (dc_device_t **out, dc_context_t *context, const char device->base.layout = &oceanic_reactpro_layout; } else if (OCEANIC_COMMON_MATCH (device->base.version, aeris_a300cs_version)) { device->base.layout = &aeris_a300cs_layout; + device->read_cmd = 0xB8; + device->pagesize = 16 * PAGESIZE; + device->crc_size = 2; + device->aligned = 1; } else { device->base.layout = &oceanic_default_layout; } @@ -633,21 +652,30 @@ oceanic_atom2_device_read (dc_device_t *abstract, unsigned int address, unsigned unsigned int nbytes = 0; while (nbytes < size) { // Read the package. - unsigned int number = address / PAGESIZE; - unsigned char answer[PAGESIZE + 1] = {0}; - unsigned char command[4] = {0xB1, + unsigned int offset = 0; + if (device->aligned) + offset = (address % device->pagesize); + unsigned int page_address = address - offset; + unsigned int number = page_address / PAGESIZE; + unsigned char answer[256 + 2] = {0}; // that's the largest we'll encounter + unsigned char command[4] = {device->read_cmd, (number >> 8) & 0xFF, // high (number ) & 0xFF, // low 0}; - dc_status_t rc = oceanic_atom2_transfer (device, command, sizeof (command), answer, sizeof (answer)); + dc_status_t rc = oceanic_atom2_transfer (device, command, sizeof (command), answer, + device->pagesize + device->crc_size); if (rc != DC_STATUS_SUCCESS) return rc; - memcpy (data, answer, PAGESIZE); + unsigned int read_size = device->pagesize - offset; + if (nbytes + read_size > size) + read_size = size - nbytes; - nbytes += PAGESIZE; - address += PAGESIZE; - data += PAGESIZE; + memcpy (data, answer + offset, read_size); + + nbytes += read_size; + address += read_size; + data += read_size; } return DC_STATUS_SUCCESS; -- 1.8.0.rc0.18.gf84667d