asix-sigma: rephrase firmware dependent param upload at acquisition start
The 100/200MHz supporting FPGA netlists differ in their register set from 50MHz netlists. Adjust the parameter download at acquisition start. Raise awareness of the "TriggerSelect" and "TriggerSelect2" difference (the former only exists in 50MHz netlists, the latter's meaning differs between firmware variants). "ClockSelect" semantics also differs between netlists. Stop sending four bytes to a register that is just one byte deep, channel selection happened to work by mere coincidence. Eliminate a few more magic numbers, unobfuscate respective code paths. Though some questions remain (trigger related, not a blocker for now, needs to get addressed later).
This commit is contained in:
parent
abcd477196
commit
419f109505
|
@ -380,9 +380,10 @@ static int config_list(uint32_t key, GVariant **data,
|
||||||
static int dev_acquisition_start(const struct sr_dev_inst *sdi)
|
static int dev_acquisition_start(const struct sr_dev_inst *sdi)
|
||||||
{
|
{
|
||||||
struct dev_context *devc;
|
struct dev_context *devc;
|
||||||
struct clockselect_50 clockselect;
|
uint16_t pindis_mask;
|
||||||
|
uint8_t async, div;
|
||||||
int triggerpin, ret;
|
int triggerpin, ret;
|
||||||
uint8_t triggerselect;
|
uint8_t trigsel2;
|
||||||
struct triggerinout triggerinout_conf;
|
struct triggerinout triggerinout_conf;
|
||||||
struct triggerlut lut;
|
struct triggerlut lut;
|
||||||
uint8_t regval, trgconf_bytes[2], clock_bytes[4], *wrptr;
|
uint8_t regval, trgconf_bytes[2], clock_bytes[4], *wrptr;
|
||||||
|
@ -417,9 +418,10 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi)
|
||||||
if (ret != SR_OK)
|
if (ret != SR_OK)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
triggerselect = 0;
|
trigsel2 = 0;
|
||||||
if (devc->samplerate >= SR_MHZ(100)) {
|
if (devc->samplerate >= SR_MHZ(100)) {
|
||||||
/* 100 and 200 MHz mode. */
|
/* 100 and 200 MHz mode. */
|
||||||
|
/* TODO Decipher the 0x81 magic number's purpose. */
|
||||||
ret = sigma_set_register(devc, WRITE_TRIGGER_SELECT2, 0x81);
|
ret = sigma_set_register(devc, WRITE_TRIGGER_SELECT2, 0x81);
|
||||||
if (ret != SR_OK)
|
if (ret != SR_OK)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -433,23 +435,28 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set trigger pin and light LED on trigger. */
|
/* Set trigger pin and light LED on trigger. */
|
||||||
triggerselect = TRGSEL2_LEDSEL1 | (triggerpin & 0x7);
|
trigsel2 = triggerpin & TRGSEL2_PINS_MASK;
|
||||||
|
trigsel2 |= TRGSEL2_LEDSEL1;
|
||||||
|
|
||||||
/* Default rising edge. */
|
/* Default rising edge. */
|
||||||
|
/* TODO Documentation disagrees, bit set means _rising_ edge. */
|
||||||
if (devc->trigger.fallingmask)
|
if (devc->trigger.fallingmask)
|
||||||
triggerselect |= 1 << 3;
|
trigsel2 |= TRGSEL2_PINPOL_RISE;
|
||||||
|
|
||||||
} else if (devc->samplerate <= SR_MHZ(50)) {
|
} else if (devc->samplerate <= SR_MHZ(50)) {
|
||||||
/* All other modes. */
|
/* 50MHz firmware modes. */
|
||||||
|
|
||||||
|
/* Translate application specs to hardware perspective. */
|
||||||
ret = sigma_build_basic_trigger(devc, &lut);
|
ret = sigma_build_basic_trigger(devc, &lut);
|
||||||
if (ret != SR_OK)
|
if (ret != SR_OK)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
/* Communicate resulting register values to the device. */
|
||||||
ret = sigma_write_trigger_lut(devc, &lut);
|
ret = sigma_write_trigger_lut(devc, &lut);
|
||||||
if (ret != SR_OK)
|
if (ret != SR_OK)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
triggerselect = TRGSEL2_LEDSEL1 | TRGSEL2_LEDSEL0;
|
trigsel2 = TRGSEL2_LEDSEL1 | TRGSEL2_LEDSEL0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup trigger in and out pins to default values. */
|
/* Setup trigger in and out pins to default values. */
|
||||||
|
@ -481,36 +488,42 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* Leave trigger programming mode. */
|
/* Leave trigger programming mode. */
|
||||||
ret = sigma_set_register(devc, WRITE_TRIGGER_SELECT2, triggerselect);
|
ret = sigma_set_register(devc, WRITE_TRIGGER_SELECT2, trigsel2);
|
||||||
if (ret != SR_OK)
|
if (ret != SR_OK)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* Set clock select register. */
|
/*
|
||||||
clockselect.async = 0;
|
* Samplerate dependent clock and channels configuration. Some
|
||||||
clockselect.fraction = 1; /* Divider 1. */
|
* channels by design are not available at higher clock rates.
|
||||||
clockselect.disabled_channels = 0x0000; /* All channels enabled. */
|
* Register layout differs between firmware variants (depth 1
|
||||||
if (devc->samplerate == SR_MHZ(200)) {
|
* with LSB channel mask above 50MHz, depth 4 with more details
|
||||||
/* Enable 4 channels. */
|
* up to 50MHz).
|
||||||
clockselect.disabled_channels = 0xfff0;
|
*
|
||||||
} else if (devc->samplerate == SR_MHZ(100)) {
|
* Derive a mask where bits are set for unavailable channels.
|
||||||
/* Enable 8 channels. */
|
* Either send the single byte, or the full byte sequence.
|
||||||
clockselect.disabled_channels = 0xff00;
|
*/
|
||||||
|
pindis_mask = ~((1UL << devc->num_channels) - 1);
|
||||||
|
if (devc->samplerate > SR_MHZ(50)) {
|
||||||
|
ret = sigma_set_register(devc, WRITE_CLOCK_SELECT,
|
||||||
|
pindis_mask & 0xff);
|
||||||
} else {
|
} else {
|
||||||
|
wrptr = clock_bytes;
|
||||||
|
/* Select 50MHz base clock, and divider. */
|
||||||
|
async = 0;
|
||||||
|
div = SR_MHZ(50) / devc->samplerate - 1;
|
||||||
/*
|
/*
|
||||||
* 50 MHz mode, or fraction thereof. The 50MHz reference
|
* TODO Optionally use external clock.
|
||||||
* can get divided by any integer in the range 1 to 256.
|
* async[0] = 1 to enable external clock
|
||||||
* Divider minus 1 gets written to the hardware.
|
* div[5] = 1 to select falling edge
|
||||||
* (The driver lists a discrete set of sample rates, but
|
* div[4] = 1 to select rising edge
|
||||||
* all of them fit the above description.)
|
* div[3:0] = 1..16 to select clock pin
|
||||||
*/
|
*/
|
||||||
clockselect.fraction = SR_MHZ(50) / devc->samplerate;
|
write_u8_inc(&wrptr, async);
|
||||||
|
write_u8_inc(&wrptr, div);
|
||||||
|
write_u16be_inc(&wrptr, pindis_mask);
|
||||||
|
ret = sigma_write_register(devc, WRITE_CLOCK_SELECT,
|
||||||
|
clock_bytes, wrptr - clock_bytes);
|
||||||
}
|
}
|
||||||
wrptr = clock_bytes;
|
|
||||||
write_u8_inc(&wrptr, clockselect.async);
|
|
||||||
write_u8_inc(&wrptr, clockselect.fraction - 1);
|
|
||||||
write_u16be_inc(&wrptr, clockselect.disabled_channels);
|
|
||||||
count = wrptr - clock_bytes;
|
|
||||||
ret = sigma_write_register(devc, WRITE_CLOCK_SELECT, clock_bytes, count);
|
|
||||||
if (ret != SR_OK)
|
if (ret != SR_OK)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
|
|
@ -458,10 +458,13 @@ SR_PRIV int sigma_write_trigger_lut(struct dev_context *devc,
|
||||||
wrptr = buf;
|
wrptr = buf;
|
||||||
write_u8_inc(&wrptr, tmp[0]);
|
write_u8_inc(&wrptr, tmp[0]);
|
||||||
write_u8_inc(&wrptr, tmp[1]);
|
write_u8_inc(&wrptr, tmp[1]);
|
||||||
ret = sigma_write_register(devc, WRITE_TRIGGER_SELECT, buf, wrptr - buf);
|
ret = sigma_write_register(devc, WRITE_TRIGGER_SELECT,
|
||||||
|
buf, wrptr - buf);
|
||||||
if (ret != SR_OK)
|
if (ret != SR_OK)
|
||||||
return ret;
|
return ret;
|
||||||
ret = sigma_set_register(devc, WRITE_TRIGGER_SELECT2, 0x30 | i);
|
ret = sigma_set_register(devc, WRITE_TRIGGER_SELECT2,
|
||||||
|
TRGSEL2_RESET | TRGSEL2_LUT_WRITE |
|
||||||
|
(i & TRGSEL2_LUT_ADDR_MASK));
|
||||||
if (ret != SR_OK)
|
if (ret != SR_OK)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1799,7 +1802,7 @@ static void add_trigger_function(enum triggerop oper, enum triggerfunc func,
|
||||||
SR_PRIV int sigma_build_basic_trigger(struct dev_context *devc,
|
SR_PRIV int sigma_build_basic_trigger(struct dev_context *devc,
|
||||||
struct triggerlut *lut)
|
struct triggerlut *lut)
|
||||||
{
|
{
|
||||||
int i,j;
|
int i, j;
|
||||||
uint16_t masks[2];
|
uint16_t masks[2];
|
||||||
|
|
||||||
memset(lut, 0, sizeof(*lut));
|
memset(lut, 0, sizeof(*lut));
|
||||||
|
|
|
@ -124,6 +124,11 @@ enum sigma_read_register {
|
||||||
READ_TEST = 15,
|
READ_TEST = 15,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define TRGSEL2_PINS_MASK (0x07 << 0)
|
||||||
|
#define TRGSEL2_PINPOL_RISE (1 << 3)
|
||||||
|
#define TRGSEL2_LUT_ADDR_MASK (0x0f << 0)
|
||||||
|
#define TRGSEL2_LUT_WRITE (1 << 4)
|
||||||
|
#define TRGSEL2_RESET (1 << 5)
|
||||||
#define TRGSEL2_LEDSEL0 (1 << 6)
|
#define TRGSEL2_LEDSEL0 (1 << 6)
|
||||||
#define TRGSEL2_LEDSEL1 (1 << 7)
|
#define TRGSEL2_LEDSEL1 (1 << 7)
|
||||||
|
|
||||||
|
@ -211,12 +216,6 @@ struct sigma_dram_line {
|
||||||
} cluster[CLUSTERS_PER_ROW];
|
} cluster[CLUSTERS_PER_ROW];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct clockselect_50 {
|
|
||||||
uint8_t async;
|
|
||||||
uint64_t fraction;
|
|
||||||
uint16_t disabled_channels;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* The effect of all these are still a bit unclear. */
|
/* The effect of all these are still a bit unclear. */
|
||||||
struct triggerinout {
|
struct triggerinout {
|
||||||
uint8_t trgout_resistor_enable : 1;
|
uint8_t trgout_resistor_enable : 1;
|
||||||
|
|
Loading…
Reference in New Issue