Implement the read function
The read command appears to be limited to the range 0x1000-0x1100. That range seems to correspond with the first 256 bytes of the full memory dump. The packet size of 32 bytes is an arbitrary choice.
This commit is contained in:
parent
39aa859d19
commit
c3dc368163
@ -45,6 +45,9 @@
|
|||||||
#define RB_PROFILE_END SZ_MEMORY
|
#define RB_PROFILE_END SZ_MEMORY
|
||||||
#define RB_PROFILE_DISTANCE(a,b) ringbuffer_distance (a, b, 0, RB_PROFILE_BEGIN, RB_PROFILE_END)
|
#define RB_PROFILE_DISTANCE(a,b) ringbuffer_distance (a, b, 0, RB_PROFILE_BEGIN, RB_PROFILE_END)
|
||||||
|
|
||||||
|
#define MAXRETRIES 4
|
||||||
|
#define PACKETSIZE 32
|
||||||
|
|
||||||
typedef struct cressi_leonardo_device_t {
|
typedef struct cressi_leonardo_device_t {
|
||||||
dc_device_t base;
|
dc_device_t base;
|
||||||
dc_serial_t *port;
|
dc_serial_t *port;
|
||||||
@ -52,6 +55,7 @@ typedef struct cressi_leonardo_device_t {
|
|||||||
} cressi_leonardo_device_t;
|
} cressi_leonardo_device_t;
|
||||||
|
|
||||||
static dc_status_t cressi_leonardo_device_set_fingerprint (dc_device_t *abstract, const unsigned char data[], unsigned int size);
|
static dc_status_t cressi_leonardo_device_set_fingerprint (dc_device_t *abstract, const unsigned char data[], unsigned int size);
|
||||||
|
static dc_status_t cressi_leonardo_device_read (dc_device_t *abstract, unsigned int address, unsigned char data[], unsigned int size);
|
||||||
static dc_status_t cressi_leonardo_device_dump (dc_device_t *abstract, dc_buffer_t *buffer);
|
static dc_status_t cressi_leonardo_device_dump (dc_device_t *abstract, dc_buffer_t *buffer);
|
||||||
static dc_status_t cressi_leonardo_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, void *userdata);
|
static dc_status_t cressi_leonardo_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, void *userdata);
|
||||||
static dc_status_t cressi_leonardo_device_close (dc_device_t *abstract);
|
static dc_status_t cressi_leonardo_device_close (dc_device_t *abstract);
|
||||||
@ -60,13 +64,102 @@ static const dc_device_vtable_t cressi_leonardo_device_vtable = {
|
|||||||
sizeof(cressi_leonardo_device_t),
|
sizeof(cressi_leonardo_device_t),
|
||||||
DC_FAMILY_CRESSI_LEONARDO,
|
DC_FAMILY_CRESSI_LEONARDO,
|
||||||
cressi_leonardo_device_set_fingerprint, /* set_fingerprint */
|
cressi_leonardo_device_set_fingerprint, /* set_fingerprint */
|
||||||
NULL, /* read */
|
cressi_leonardo_device_read, /* read */
|
||||||
NULL, /* write */
|
NULL, /* write */
|
||||||
cressi_leonardo_device_dump, /* dump */
|
cressi_leonardo_device_dump, /* dump */
|
||||||
cressi_leonardo_device_foreach, /* foreach */
|
cressi_leonardo_device_foreach, /* foreach */
|
||||||
cressi_leonardo_device_close /* close */
|
cressi_leonardo_device_close /* close */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
cressi_leonardo_make_ascii (const unsigned char raw[], unsigned int rsize, unsigned char ascii[], unsigned int asize)
|
||||||
|
{
|
||||||
|
assert (asize == 2 * (rsize + 3));
|
||||||
|
|
||||||
|
// Header
|
||||||
|
ascii[0] = '{';
|
||||||
|
|
||||||
|
// Data
|
||||||
|
array_convert_bin2hex (raw, rsize, ascii + 1, 2 * rsize);
|
||||||
|
|
||||||
|
// Checksum
|
||||||
|
unsigned short crc = checksum_crc_ccitt_uint16 (ascii + 1, 2 * rsize);
|
||||||
|
unsigned char checksum[] = {
|
||||||
|
(crc >> 8) & 0xFF, // High
|
||||||
|
(crc ) & 0xFF}; // Low
|
||||||
|
array_convert_bin2hex (checksum, sizeof(checksum), ascii + 1 + 2 * rsize, 4);
|
||||||
|
|
||||||
|
// Trailer
|
||||||
|
ascii[asize - 1] = '}';
|
||||||
|
}
|
||||||
|
|
||||||
|
static dc_status_t
|
||||||
|
cressi_leonardo_packet (cressi_leonardo_device_t *device, const unsigned char command[], unsigned int csize, unsigned char answer[], unsigned int asize)
|
||||||
|
{
|
||||||
|
dc_status_t status = DC_STATUS_SUCCESS;
|
||||||
|
dc_device_t *abstract = (dc_device_t *) device;
|
||||||
|
|
||||||
|
if (device_is_cancelled (abstract))
|
||||||
|
return DC_STATUS_CANCELLED;
|
||||||
|
|
||||||
|
// Send the command to the device.
|
||||||
|
status = dc_serial_write (device->port, command, csize, NULL);
|
||||||
|
if (status != DC_STATUS_SUCCESS) {
|
||||||
|
ERROR (abstract->context, "Failed to send the command.");
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Receive the answer of the device.
|
||||||
|
status = dc_serial_read (device->port, answer, asize, NULL);
|
||||||
|
if (status != DC_STATUS_SUCCESS) {
|
||||||
|
ERROR (abstract->context, "Failed to receive the answer.");
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify the header and trailer of the packet.
|
||||||
|
if (answer[0] != '{' || answer[asize - 1] != '}') {
|
||||||
|
ERROR (abstract->context, "Unexpected answer header/trailer byte.");
|
||||||
|
return DC_STATUS_PROTOCOL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert the checksum of the packet.
|
||||||
|
unsigned char checksum[2] = {0};
|
||||||
|
array_convert_hex2bin (answer + asize - 5, 4, checksum, sizeof(checksum));
|
||||||
|
|
||||||
|
// Verify the checksum of the packet.
|
||||||
|
unsigned short crc = array_uint16_be (checksum);
|
||||||
|
unsigned short ccrc = checksum_crc_ccitt_uint16 (answer + 1, asize - 6);
|
||||||
|
if (crc != ccrc) {
|
||||||
|
ERROR (abstract->context, "Unexpected answer checksum.");
|
||||||
|
return DC_STATUS_PROTOCOL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DC_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static dc_status_t
|
||||||
|
cressi_leonardo_transfer (cressi_leonardo_device_t *device, const unsigned char command[], unsigned int csize, unsigned char answer[], unsigned int asize)
|
||||||
|
{
|
||||||
|
unsigned int nretries = 0;
|
||||||
|
dc_status_t rc = DC_STATUS_SUCCESS;
|
||||||
|
while ((rc = cressi_leonardo_packet (device, command, csize, answer, asize)) != DC_STATUS_SUCCESS) {
|
||||||
|
// Automatically discard a corrupted packet,
|
||||||
|
// and request a new one.
|
||||||
|
if (rc != DC_STATUS_PROTOCOL && rc != DC_STATUS_TIMEOUT)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
// Abort if the maximum number of retries is reached.
|
||||||
|
if (nretries++ >= MAXRETRIES)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
// Discard any garbage bytes.
|
||||||
|
dc_serial_sleep (device->port, 100);
|
||||||
|
dc_serial_purge (device->port, DC_DIRECTION_INPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
dc_status_t
|
dc_status_t
|
||||||
cressi_leonardo_device_open (dc_device_t **out, dc_context_t *context, const char *name)
|
cressi_leonardo_device_open (dc_device_t **out, dc_context_t *context, const char *name)
|
||||||
{
|
{
|
||||||
@ -168,6 +261,47 @@ cressi_leonardo_device_set_fingerprint (dc_device_t *abstract, const unsigned ch
|
|||||||
return DC_STATUS_SUCCESS;
|
return DC_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static dc_status_t
|
||||||
|
cressi_leonardo_device_read (dc_device_t *abstract, unsigned int address, unsigned char data[], unsigned int size)
|
||||||
|
{
|
||||||
|
dc_status_t rc = DC_STATUS_SUCCESS;
|
||||||
|
cressi_leonardo_device_t *device = (cressi_leonardo_device_t *) abstract;
|
||||||
|
|
||||||
|
unsigned int nbytes = 0;
|
||||||
|
while (nbytes < size) {
|
||||||
|
// Calculate the packet size.
|
||||||
|
unsigned int len = size - nbytes;
|
||||||
|
if (len > PACKETSIZE)
|
||||||
|
len = PACKETSIZE;
|
||||||
|
|
||||||
|
// Build the raw command.
|
||||||
|
unsigned char raw[] = {
|
||||||
|
(address >> 8) & 0xFF, // High
|
||||||
|
(address ) & 0xFF, // Low
|
||||||
|
(len >> 8) & 0xFF, // High
|
||||||
|
(len ) & 0xFF}; // Low
|
||||||
|
|
||||||
|
// Build the ascii command.
|
||||||
|
unsigned char command[2 * (sizeof (raw) + 3)] = {0};
|
||||||
|
cressi_leonardo_make_ascii (raw, sizeof (raw), command, sizeof (command));
|
||||||
|
|
||||||
|
// Send the command and receive the answer.
|
||||||
|
unsigned char answer[2 * (PACKETSIZE + 3)] = {0};
|
||||||
|
rc = cressi_leonardo_transfer (device, command, sizeof (command), answer, 2 * (len + 3));
|
||||||
|
if (rc != DC_STATUS_SUCCESS)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
// Extract the raw data from the packet.
|
||||||
|
array_convert_hex2bin (answer + 1, 2 * len, data, len);
|
||||||
|
|
||||||
|
nbytes += len;
|
||||||
|
address += len;
|
||||||
|
data += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
static dc_status_t
|
static dc_status_t
|
||||||
cressi_leonardo_device_dump (dc_device_t *abstract, dc_buffer_t *buffer)
|
cressi_leonardo_device_dump (dc_device_t *abstract, dc_buffer_t *buffer)
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user