input/trace32_ad: Add support for new file format (BINHDR2)

This commit is contained in:
Soeren Apel 2019-03-24 21:33:54 +01:00
parent 628dc330bc
commit 7ed4ae6307
1 changed files with 54 additions and 11 deletions

View File

@ -47,7 +47,6 @@
#define CHUNK_SIZE (4 * 1024 * 1024)
#define MAX_POD_COUNT 12
#define HEADER_SIZE 80
#define SPACE ' '
#define CTRLZ '\x1a'
@ -64,7 +63,8 @@
enum ad_format {
AD_FORMAT_UNKNOWN,
AD_FORMAT_BINHDR, /* Binary header, binary data, textual setup info */
AD_FORMAT_BINHDR1, /* Binary header, binary data, textual setup info, v1 */
AD_FORMAT_BINHDR2, /* Binary header, binary data, textual setup info, v2 */
AD_FORMAT_TXTHDR, /* Textual header, binary data */
};
@ -96,7 +96,7 @@ struct context {
char pod_status[MAX_POD_COUNT];
struct sr_channel *channels[MAX_POD_COUNT][17]; /* 16 + CLK */
uint64_t trigger_timestamp;
uint32_t record_size, record_count, cur_record;
uint32_t header_size, record_size, record_count, cur_record;
int32_t last_record;
uint64_t samplerate;
double timestamp_scale;
@ -212,14 +212,19 @@ static int process_header(GString *buf, struct context *inc)
enum ad_format format;
/*
* First-level file header:
* 0x00-1F file format name
* 0x20 u64 trigger timestamp
* 0x28-2F unused
* 0x30 u8 compression
* 0x31-35 ??
* 0x32 u8 0x00 (PI), 0x01 (iprobe)
* 0x36 u8 0x08 (PI 250/500), 0x0A (iprobe 250)
* 0x37 u8 0x00 (250), 0x01 (500)
* 0x36 u8 device id: 0x08 (PI 250/500), 0x0A (iprobe 250)
*/
/*
* Second-level file header, version 1:
* 0x37 u8 capture speed: 0x00 (250), 0x01 (500)
* 0x38 u8 record size
* 0x39-3B const 0x00
* 0x3C u32 number of records
@ -230,6 +235,31 @@ static int process_header(GString *buf, struct context *inc)
* 0x4E-4F ??
*/
/*
* Second-level file header, version 2:
* 0x37 u8 ??
* 0x38 u64 ??
* 0x40 u64 ??
* 0x48 u8 record size
* 0x49-4F ??
* 0x50 u64 ??
* 0x58 u64 number of records
* 0x60 u64 ??
* 0x68 u64 ??
* 0x70 u64 ??
* 0x78 u64 ??
* 0x80 u64 ??
* 0x88 u64 ?? (timestamp of some kind?)
* 0x90 u64 ??
* 0x98-9E ??
* 0x9F u8 capture speed: 0x00 (250), 0x01 (500)
* 0xA0 u64 ??
* 0xA8 u64 ??
* 0xB0 u64 ??
* 0xB8-CF version string? (e.g. '93173--96069', same for all tested .ad files)
* 0xC8 u16 ??
*/
/*
* Note: The routine is called from different contexts. Either
* to auto-detect the file format (format_match(), 'inc' is NULL),
@ -260,7 +290,7 @@ static int process_header(GString *buf, struct context *inc)
format = AD_FORMAT_UNKNOWN;
if (has_trace32) {
/* Literal "trace32" leader, binary header follows. */
format = AD_FORMAT_BINHDR;
format = AD_FORMAT_BINHDR1;
} else if (g_ascii_isdigit(format_name[0]) && (format_name[1] == SPACE)) {
/* Digit and SPACE leader, currently unsupported text header. */
format = AD_FORMAT_TXTHDR;
@ -278,12 +308,17 @@ static int process_header(GString *buf, struct context *inc)
if (!format)
return SR_ERR;
/* If the device id is 0x00, we have a v2 format file. */
if (R8(buf->str + 0x36) == 0x00)
format = AD_FORMAT_BINHDR2;
p = printable_name(format_name);
if (inc)
sr_dbg("File says it's \"%s\" -> format type %u.", p, format);
g_free(p);
record_size = R8(buf->str + 0x38);
record_size = (format == AD_FORMAT_BINHDR1) ?
R8(buf->str + 0x38) : R8(buf->str + 0x48);
device_id = 0;
if (g_strcmp0(format_name, "trace32 power integrator data") == 0) {
@ -312,10 +347,18 @@ static int process_header(GString *buf, struct context *inc)
inc->device = device_id;
inc->trigger_timestamp = RL64(buf->str + 0x20);
inc->compression = R8(buf->str + 0x30); /* Maps to the enum. */
inc->record_mode = R8(buf->str + 0x37); /* Maps to the enum. */
inc->header_size = (format == AD_FORMAT_BINHDR1) ? 0x50 : 0xCA;
inc->record_size = record_size;
inc->record_count = RL32(buf->str + 0x3C);
inc->last_record = RL32S(buf->str + 0x40);
if (format == AD_FORMAT_BINHDR1) {
inc->record_mode = R8(buf->str + 0x37); /* Maps to the enum. */
inc->record_count = RL32(buf->str + 0x3C);
inc->last_record = RL32S(buf->str + 0x40);
} else {
inc->record_mode = R8(buf->str + 0x9F); /* Maps to the enum. */
inc->record_count = RL32(buf->str + 0x58);
inc->last_record = inc->record_count;
}
sr_dbg("Trigger occured at %lf s.",
inc->trigger_timestamp * TIMESTAMP_RESOLUTION);
@ -735,7 +778,7 @@ static int process_buffer(struct sr_input *in)
if (!inc->header_read) {
res = process_header(in->buf, inc);
g_string_erase(in->buf, 0, HEADER_SIZE);
g_string_erase(in->buf, 0, inc->header_size);
if (res != SR_OK)
return res;
}