Use multipage read commands for faster transfers.

Multipage read commands can reduce the transfer time significantly,
because the overhead of processing each single page read command is
eliminated.
This commit is contained in:
Jef Driesen 2010-01-22 13:42:03 +00:00
parent 5589770f30
commit 61257a8628
2 changed files with 69 additions and 47 deletions

View File

@ -32,6 +32,7 @@
#include "checksum.h" #include "checksum.h"
#define MAXRETRIES 2 #define MAXRETRIES 2
#define MULTIPAGE 4
#define EXITCODE(rc) \ #define EXITCODE(rc) \
( \ ( \
@ -390,42 +391,52 @@ oceanic_veo250_device_read (device_t *abstract, unsigned int address, unsigned c
unsigned int nbytes = 0; unsigned int nbytes = 0;
while (nbytes < size) { while (nbytes < size) {
// Calculate the number of packages.
unsigned int npackets = (size - nbytes) / PAGESIZE;
if (npackets > MULTIPAGE)
npackets = MULTIPAGE;
// Read the package. // Read the package.
unsigned int number = address / PAGESIZE; unsigned int first = address / PAGESIZE;
unsigned char answer[PAGESIZE + 2] = {0}; unsigned int last = first + npackets - 1;
unsigned char answer[(PAGESIZE + 1) * MULTIPAGE + 1] = {0};
unsigned char command[6] = {0x20, unsigned char command[6] = {0x20,
(number ) & 0xFF, // low (first ) & 0xFF, // low
(number >> 8) & 0xFF, // high (first >> 8) & 0xFF, // high
(number ) & 0xFF, // low (last ) & 0xFF, // low
(number >> 8) & 0xFF, // high (last >> 8) & 0xFF, // high
0}; 0};
device_status_t rc = oceanic_veo250_transfer (device, command, sizeof (command), answer, sizeof (answer)); device_status_t rc = oceanic_veo250_transfer (device, command, sizeof (command), answer, (PAGESIZE + 1) * npackets + 1);
if (rc != DEVICE_STATUS_SUCCESS) if (rc != DEVICE_STATUS_SUCCESS)
return rc; return rc;
device->last = number; device->last = last;
// Verify the checksum of the answer. unsigned int offset = 0;
unsigned char crc = answer[PAGESIZE]; for (unsigned int i = 0; i < npackets; ++i) {
unsigned char ccrc = checksum_add_uint8 (answer, PAGESIZE, 0x00); // Verify the checksum of the answer.
if (crc != ccrc) { unsigned char crc = answer[offset + PAGESIZE];
WARNING ("Unexpected answer CRC."); unsigned char ccrc = checksum_add_uint8 (answer + offset, PAGESIZE, 0x00);
return DEVICE_STATUS_PROTOCOL; if (crc != ccrc) {
} WARNING ("Unexpected answer CRC.");
return DEVICE_STATUS_PROTOCOL;
}
memcpy (data, answer, PAGESIZE); memcpy (data, answer + offset, PAGESIZE);
#ifndef NDEBUG #ifndef NDEBUG
message ("VEO250Read(0x%04x,%d)=\"", address, PAGESIZE); message ("VEO250Read(0x%04x,%d)=\"", address, PAGESIZE);
for (unsigned int i = 0; i < PAGESIZE; ++i) { for (unsigned int i = 0; i < PAGESIZE; ++i) {
message("%02x", data[i]); message("%02x", data[i]);
} }
message("\"\n"); message("\"\n");
#endif #endif
nbytes += PAGESIZE; offset += PAGESIZE + 1;
address += PAGESIZE; nbytes += PAGESIZE;
data += PAGESIZE; address += PAGESIZE;
data += PAGESIZE;
}
} }
return DEVICE_STATUS_SUCCESS; return DEVICE_STATUS_SUCCESS;

View File

@ -32,6 +32,7 @@
#include "checksum.h" #include "checksum.h"
#define MAXRETRIES 2 #define MAXRETRIES 2
#define MULTIPAGE 4
#define EXITCODE(rc) \ #define EXITCODE(rc) \
( \ ( \
@ -444,40 +445,50 @@ oceanic_vtpro_device_read (device_t *abstract, unsigned int address, unsigned ch
unsigned int nbytes = 0; unsigned int nbytes = 0;
while (nbytes < size) { while (nbytes < size) {
// Calculate the number of packages.
unsigned int npackets = (size - nbytes) / PAGESIZE;
if (npackets > MULTIPAGE)
npackets = MULTIPAGE;
// Read the package. // Read the package.
unsigned int number = address / PAGESIZE; unsigned int first = address / PAGESIZE;
unsigned char answer[PAGESIZE + 1] = {0}; unsigned int last = first + npackets - 1;
unsigned char answer[(PAGESIZE + 1) * MULTIPAGE] = {0};
unsigned char command[6] = {0x34, unsigned char command[6] = {0x34,
(number >> 8) & 0xFF, // high (first >> 8) & 0xFF, // high
(number ) & 0xFF, // low (first ) & 0xFF, // low
(number >> 8) & 0xFF, // high (last >> 8) & 0xFF, // high
(number ) & 0xFF, // low (last ) & 0xFF, // low
0x00}; 0x00};
device_status_t rc = oceanic_vtpro_transfer (device, command, sizeof (command), answer, sizeof (answer)); device_status_t rc = oceanic_vtpro_transfer (device, command, sizeof (command), answer, (PAGESIZE + 1) * npackets);
if (rc != DEVICE_STATUS_SUCCESS) if (rc != DEVICE_STATUS_SUCCESS)
return rc; return rc;
// Verify the checksum of the answer. unsigned int offset = 0;
unsigned char crc = answer[PAGESIZE]; for (unsigned int i = 0; i < npackets; ++i) {
unsigned char ccrc = checksum_add_uint8 (answer, PAGESIZE, 0x00); // Verify the checksum of the answer.
if (crc != ccrc) { unsigned char crc = answer[offset + PAGESIZE];
WARNING ("Unexpected answer CRC."); unsigned char ccrc = checksum_add_uint8 (answer + offset, PAGESIZE, 0x00);
return DEVICE_STATUS_PROTOCOL; if (crc != ccrc) {
} WARNING ("Unexpected answer CRC.");
return DEVICE_STATUS_PROTOCOL;
}
memcpy (data, answer, PAGESIZE); memcpy (data, answer + offset, PAGESIZE);
#ifndef NDEBUG #ifndef NDEBUG
message ("VTPRORead(0x%04x,%d)=\"", address, PAGESIZE); message ("VTPRORead(0x%04x,%d)=\"", address, PAGESIZE);
for (unsigned int i = 0; i < PAGESIZE; ++i) { for (unsigned int i = 0; i < PAGESIZE; ++i) {
message("%02x", data[i]); message("%02x", data[i]);
} }
message("\"\n"); message("\"\n");
#endif #endif
nbytes += PAGESIZE; offset += PAGESIZE + 1;
address += PAGESIZE; nbytes += PAGESIZE;
data += PAGESIZE; address += PAGESIZE;
data += PAGESIZE;
}
} }
return DEVICE_STATUS_SUCCESS; return DEVICE_STATUS_SUCCESS;