asix-sigma: Properly decode data gathered at 100 and 200 MHz
The hardware provides captured data at a maximum rate of 16bits per 20ns (50 MHz). For samplerates of 100 and 200 MHz one individual 16bit entity contains multiple samples for a reduced number of channels. The bits of several sample points are interleaved within the 16bit entity. This commit is based on work done by jry@ who fixed a lot of issues with the help from Ondrej at Asix. This fixes bug #840.
This commit is contained in:
parent
3281cf59aa
commit
85c032e485
|
@ -740,12 +740,59 @@ static uint16_t sigma_dram_cluster_data(struct sigma_dram_cluster *cl, int idx)
|
||||||
return sample;
|
return sample;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Deinterlace sample data that was retrieved at 100MHz samplerate.
|
||||||
|
* One 16bit item contains two samples of 8bits each. The bits of
|
||||||
|
* multiple samples are interleaved.
|
||||||
|
*/
|
||||||
|
static uint16_t sigma_deinterlace_100mhz_data(uint16_t indata, int idx)
|
||||||
|
{
|
||||||
|
uint16_t outdata;
|
||||||
|
|
||||||
|
indata >>= idx;
|
||||||
|
outdata = 0;
|
||||||
|
outdata |= (indata >> (0 * 2 - 0)) & (1 << 0);
|
||||||
|
outdata |= (indata >> (1 * 2 - 1)) & (1 << 1);
|
||||||
|
outdata |= (indata >> (2 * 2 - 2)) & (1 << 2);
|
||||||
|
outdata |= (indata >> (3 * 2 - 3)) & (1 << 3);
|
||||||
|
outdata |= (indata >> (4 * 2 - 4)) & (1 << 4);
|
||||||
|
outdata |= (indata >> (5 * 2 - 5)) & (1 << 5);
|
||||||
|
outdata |= (indata >> (6 * 2 - 6)) & (1 << 6);
|
||||||
|
outdata |= (indata >> (7 * 2 - 7)) & (1 << 7);
|
||||||
|
return outdata;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Deinterlace sample data that was retrieved at 200MHz samplerate.
|
||||||
|
* One 16bit item contains four samples of 4bits each. The bits of
|
||||||
|
* multiple samples are interleaved.
|
||||||
|
*/
|
||||||
|
static uint16_t sigma_deinterlace_200mhz_data(uint16_t indata, int idx)
|
||||||
|
{
|
||||||
|
uint16_t outdata;
|
||||||
|
|
||||||
|
indata >>= idx;
|
||||||
|
outdata = 0;
|
||||||
|
outdata |= (indata >> (0 * 4 - 0)) & (1 << 0);
|
||||||
|
outdata |= (indata >> (1 * 4 - 1)) & (1 << 1);
|
||||||
|
outdata |= (indata >> (2 * 4 - 2)) & (1 << 2);
|
||||||
|
outdata |= (indata >> (3 * 4 - 3)) & (1 << 3);
|
||||||
|
return outdata;
|
||||||
|
}
|
||||||
|
|
||||||
static void store_sr_sample(uint8_t *samples, int idx, uint16_t data)
|
static void store_sr_sample(uint8_t *samples, int idx, uint16_t data)
|
||||||
{
|
{
|
||||||
samples[2 * idx + 0] = (data >> 0) & 0xff;
|
samples[2 * idx + 0] = (data >> 0) & 0xff;
|
||||||
samples[2 * idx + 1] = (data >> 8) & 0xff;
|
samples[2 * idx + 1] = (data >> 8) & 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This size translates to: event count (1K events per cluster), times
|
||||||
|
* the sample width (unitsize, 16bits per event), times the maximum
|
||||||
|
* number of samples per event.
|
||||||
|
*/
|
||||||
|
#define SAMPLES_BUFFER_SIZE (1024 * 2 * 4)
|
||||||
|
|
||||||
static void sigma_decode_dram_cluster(struct sigma_dram_cluster *dram_cluster,
|
static void sigma_decode_dram_cluster(struct sigma_dram_cluster *dram_cluster,
|
||||||
unsigned int events_in_cluster,
|
unsigned int events_in_cluster,
|
||||||
unsigned int triggered,
|
unsigned int triggered,
|
||||||
|
@ -755,9 +802,12 @@ static void sigma_decode_dram_cluster(struct sigma_dram_cluster *dram_cluster,
|
||||||
struct sigma_state *ss = &devc->state;
|
struct sigma_state *ss = &devc->state;
|
||||||
struct sr_datafeed_packet packet;
|
struct sr_datafeed_packet packet;
|
||||||
struct sr_datafeed_logic logic;
|
struct sr_datafeed_logic logic;
|
||||||
uint16_t tsdiff, ts, sample;
|
uint16_t tsdiff, ts, sample, item16;
|
||||||
uint8_t samples[2048];
|
uint8_t samples[SAMPLES_BUFFER_SIZE];
|
||||||
|
uint8_t *send_ptr;
|
||||||
|
size_t send_count, trig_count;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
int j;
|
||||||
|
|
||||||
ts = sigma_dram_cluster_ts(dram_cluster);
|
ts = sigma_dram_cluster_ts(dram_cluster);
|
||||||
tsdiff = ts - ss->lastts;
|
tsdiff = ts - ss->lastts;
|
||||||
|
@ -786,22 +836,45 @@ static void sigma_decode_dram_cluster(struct sigma_dram_cluster *dram_cluster,
|
||||||
/*
|
/*
|
||||||
* If we have 1024 samples ready or we're at the
|
* If we have 1024 samples ready or we're at the
|
||||||
* end of submitting the padding samples, submit
|
* end of submitting the padding samples, submit
|
||||||
* the packet to Sigrok.
|
* the packet to Sigrok. Since constant data is
|
||||||
|
* sent, duplication of data for rates above 50MHz
|
||||||
|
* is simple.
|
||||||
*/
|
*/
|
||||||
if ((i == 1023) || (ts == tsdiff - 1)) {
|
if ((i == 1023) || (ts == tsdiff - 1)) {
|
||||||
logic.length = (i + 1) * logic.unitsize;
|
logic.length = (i + 1) * logic.unitsize;
|
||||||
|
for (j = 0; j < devc->samples_per_event; j++)
|
||||||
sr_session_send(sdi, &packet);
|
sr_session_send(sdi, &packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse the samples in current cluster and prepare them
|
* Parse the samples in current cluster and prepare them
|
||||||
* to be submitted to Sigrok.
|
* to be submitted to Sigrok. Cope with memory layouts that
|
||||||
|
* vary with the samplerate.
|
||||||
*/
|
*/
|
||||||
|
send_ptr = &samples[0];
|
||||||
|
send_count = 0;
|
||||||
sample = 0;
|
sample = 0;
|
||||||
for (i = 0; i < events_in_cluster; i++) {
|
for (i = 0; i < events_in_cluster; i++) {
|
||||||
sample = sigma_dram_cluster_data(dram_cluster, i);
|
item16 = sigma_dram_cluster_data(dram_cluster, i);
|
||||||
store_sr_sample(samples, i, sample);
|
if (devc->cur_samplerate == SR_MHZ(200)) {
|
||||||
|
sample = sigma_deinterlace_200mhz_data(item16, 0);
|
||||||
|
store_sr_sample(samples, send_count++, sample);
|
||||||
|
sample = sigma_deinterlace_200mhz_data(item16, 1);
|
||||||
|
store_sr_sample(samples, send_count++, sample);
|
||||||
|
sample = sigma_deinterlace_200mhz_data(item16, 2);
|
||||||
|
store_sr_sample(samples, send_count++, sample);
|
||||||
|
sample = sigma_deinterlace_200mhz_data(item16, 3);
|
||||||
|
store_sr_sample(samples, send_count++, sample);
|
||||||
|
} else if (devc->cur_samplerate == SR_MHZ(100)) {
|
||||||
|
sample = sigma_deinterlace_100mhz_data(item16, 0);
|
||||||
|
store_sr_sample(samples, send_count++, sample);
|
||||||
|
sample = sigma_deinterlace_100mhz_data(item16, 1);
|
||||||
|
store_sr_sample(samples, send_count++, sample);
|
||||||
|
} else {
|
||||||
|
sample = item16;
|
||||||
|
store_sr_sample(samples, send_count++, sample);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -821,10 +894,12 @@ static void sigma_decode_dram_cluster(struct sigma_dram_cluster *dram_cluster,
|
||||||
ss->lastsample, &devc->trigger);
|
ss->lastsample, &devc->trigger);
|
||||||
|
|
||||||
if (trigger_offset > 0) {
|
if (trigger_offset > 0) {
|
||||||
|
trig_count = trigger_offset * devc->samples_per_event;
|
||||||
packet.type = SR_DF_LOGIC;
|
packet.type = SR_DF_LOGIC;
|
||||||
logic.length = trigger_offset * logic.unitsize;
|
logic.length = trig_count * logic.unitsize;
|
||||||
sr_session_send(sdi, &packet);
|
sr_session_send(sdi, &packet);
|
||||||
events_in_cluster -= trigger_offset;
|
send_ptr += trig_count * logic.unitsize;
|
||||||
|
send_count -= trig_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Only send trigger if explicitly enabled. */
|
/* Only send trigger if explicitly enabled. */
|
||||||
|
@ -838,10 +913,10 @@ static void sigma_decode_dram_cluster(struct sigma_dram_cluster *dram_cluster,
|
||||||
* Send the data after the trigger, or all of the received data
|
* Send the data after the trigger, or all of the received data
|
||||||
* if no trigger position applies.
|
* if no trigger position applies.
|
||||||
*/
|
*/
|
||||||
if (events_in_cluster > 0) {
|
if (send_count) {
|
||||||
packet.type = SR_DF_LOGIC;
|
packet.type = SR_DF_LOGIC;
|
||||||
logic.length = events_in_cluster * logic.unitsize;
|
logic.length = send_count * logic.unitsize;
|
||||||
logic.data = samples + (trigger_offset * logic.unitsize);
|
logic.data = send_ptr;
|
||||||
sr_session_send(sdi, &packet);
|
sr_session_send(sdi, &packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue