demo: User-configurable number of probes.
The sigrok and incremental patterns repeat every 8 probes, shifted by one probe.
This commit is contained in:
parent
bf90d4c666
commit
c07f60e73d
|
@ -33,11 +33,10 @@
|
||||||
|
|
||||||
#define LOG_PREFIX "demo"
|
#define LOG_PREFIX "demo"
|
||||||
|
|
||||||
/* TODO: Number of probes should be configurable. */
|
#define DEFAULT_NUM_LOGIC_PROBES 8
|
||||||
#define NUM_PROBES 8
|
#define DEFAULT_NUM_ANALOG_PROBES 4
|
||||||
|
|
||||||
/* The size of chunks to send through the session bus. */
|
/* The size of chunks to send through the session bus. */
|
||||||
/* TODO: Should be configurable. */
|
|
||||||
#define LOGIC_BUFSIZE 4096
|
#define LOGIC_BUFSIZE 4096
|
||||||
|
|
||||||
/* Patterns we can generate */
|
/* Patterns we can generate */
|
||||||
|
@ -45,14 +44,17 @@ enum {
|
||||||
/**
|
/**
|
||||||
* Spells "sigrok" across 8 probes using '0's (with '1's as
|
* Spells "sigrok" across 8 probes using '0's (with '1's as
|
||||||
* "background") when displayed using the 'bits' output format.
|
* "background") when displayed using the 'bits' output format.
|
||||||
|
* The pattern is repeasted every 8 probes, shifted to the right
|
||||||
|
* in time by one bit.
|
||||||
*/
|
*/
|
||||||
PATTERN_SIGROK,
|
PATTERN_SIGROK,
|
||||||
|
|
||||||
/** Pseudo-)random values on all probes. */
|
/** Pseudo-random values on all probes. */
|
||||||
PATTERN_RANDOM,
|
PATTERN_RANDOM,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Incrementing number across all probes.
|
* Incrementing number across 8 probes. The pattern is repeasted
|
||||||
|
* every 8 probes, shifted to the right in time by one bit.
|
||||||
*/
|
*/
|
||||||
PATTERN_INC,
|
PATTERN_INC,
|
||||||
|
|
||||||
|
@ -78,12 +80,19 @@ struct dev_context {
|
||||||
uint64_t cur_samplerate;
|
uint64_t cur_samplerate;
|
||||||
uint64_t limit_samples;
|
uint64_t limit_samples;
|
||||||
uint64_t limit_msec;
|
uint64_t limit_msec;
|
||||||
uint8_t sample_generator;
|
|
||||||
uint64_t samples_counter;
|
uint64_t samples_counter;
|
||||||
void *cb_data;
|
|
||||||
int64_t starttime;
|
int64_t starttime;
|
||||||
unsigned char logic_data[LOGIC_BUFSIZE];
|
|
||||||
uint64_t step;
|
uint64_t step;
|
||||||
|
int32_t num_logic_probes;
|
||||||
|
unsigned int logic_unitsize;
|
||||||
|
uint8_t logic_pattern;
|
||||||
|
unsigned char logic_data[LOGIC_BUFSIZE];
|
||||||
|
int32_t num_analog_probes;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int32_t hwopts[] = {
|
||||||
|
SR_CONF_NUM_LOGIC_PROBES,
|
||||||
|
SR_CONF_NUM_ANALOG_PROBES,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int hwcaps[] = {
|
static const int hwcaps[] = {
|
||||||
|
@ -113,15 +122,12 @@ static uint8_t pattern_sigrok[] = {
|
||||||
0xbe, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0xbe, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Private, per-device-instance driver context. */
|
|
||||||
/* TODO: struct context as with the other drivers. */
|
|
||||||
|
|
||||||
/* List of struct sr_dev_inst, maintained by dev_open()/dev_close(). */
|
|
||||||
SR_PRIV struct sr_dev_driver demo_driver_info;
|
SR_PRIV struct sr_dev_driver demo_driver_info;
|
||||||
static struct sr_dev_driver *di = &demo_driver_info;
|
static struct sr_dev_driver *di = &demo_driver_info;
|
||||||
|
|
||||||
static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data);
|
static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data);
|
||||||
|
|
||||||
|
|
||||||
static int dev_clear(void)
|
static int dev_clear(void)
|
||||||
{
|
{
|
||||||
return std_dev_clear(di, NULL);
|
return std_dev_clear(di, NULL);
|
||||||
|
@ -134,20 +140,32 @@ static int init(struct sr_context *sr_ctx)
|
||||||
|
|
||||||
static GSList *scan(GSList *options)
|
static GSList *scan(GSList *options)
|
||||||
{
|
{
|
||||||
struct sr_dev_inst *sdi;
|
|
||||||
struct sr_probe *probe;
|
|
||||||
struct drv_context *drvc;
|
struct drv_context *drvc;
|
||||||
struct dev_context *devc;
|
struct dev_context *devc;
|
||||||
GSList *devices;
|
struct sr_dev_inst *sdi;
|
||||||
int i;
|
struct sr_probe *probe;
|
||||||
|
struct sr_config *src;
|
||||||
|
GSList *devices, *l;
|
||||||
|
int num_logic_probes, num_analog_probes, i;
|
||||||
char probe_name[16];
|
char probe_name[16];
|
||||||
|
|
||||||
(void)options;
|
|
||||||
|
|
||||||
drvc = di->priv;
|
drvc = di->priv;
|
||||||
|
|
||||||
devices = NULL;
|
num_logic_probes = DEFAULT_NUM_LOGIC_PROBES;
|
||||||
|
num_analog_probes = DEFAULT_NUM_ANALOG_PROBES;
|
||||||
|
for (l = options; l; l = l->next) {
|
||||||
|
src = l->data;
|
||||||
|
switch (src->key) {
|
||||||
|
case SR_CONF_NUM_LOGIC_PROBES:
|
||||||
|
num_logic_probes = g_variant_get_int32(src->data);
|
||||||
|
break;
|
||||||
|
case SR_CONF_NUM_ANALOG_PROBES:
|
||||||
|
num_analog_probes = g_variant_get_int32(src->data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
devices = NULL;
|
||||||
sdi = sr_dev_inst_new(0, SR_ST_ACTIVE, "Demo device", NULL, NULL);
|
sdi = sr_dev_inst_new(0, SR_ST_ACTIVE, "Demo device", NULL, NULL);
|
||||||
if (!sdi) {
|
if (!sdi) {
|
||||||
sr_err("Device instance creation failed.");
|
sr_err("Device instance creation failed.");
|
||||||
|
@ -155,13 +173,20 @@ static GSList *scan(GSList *options)
|
||||||
}
|
}
|
||||||
sdi->driver = di;
|
sdi->driver = di;
|
||||||
|
|
||||||
for (i = 0; i < NUM_PROBES; i++) {
|
for (i = 0; i < num_logic_probes; i++) {
|
||||||
sprintf(probe_name, "D%d", i);
|
sprintf(probe_name, "D%d", i);
|
||||||
if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, probe_name)))
|
if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, probe_name)))
|
||||||
return NULL;
|
return NULL;
|
||||||
sdi->probes = g_slist_append(sdi->probes, probe);
|
sdi->probes = g_slist_append(sdi->probes, probe);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < num_analog_probes; i++) {
|
||||||
|
sprintf(probe_name, "A%d", i);
|
||||||
|
if (!(probe = sr_probe_new(i, SR_PROBE_ANALOG, TRUE, probe_name)))
|
||||||
|
return NULL;
|
||||||
|
sdi->probes = g_slist_append(sdi->probes, probe);
|
||||||
|
}
|
||||||
|
|
||||||
devices = g_slist_append(devices, sdi);
|
devices = g_slist_append(devices, sdi);
|
||||||
drvc->instances = g_slist_append(drvc->instances, sdi);
|
drvc->instances = g_slist_append(drvc->instances, sdi);
|
||||||
|
|
||||||
|
@ -169,12 +194,14 @@ static GSList *scan(GSList *options)
|
||||||
sr_err("Device context malloc failed.");
|
sr_err("Device context malloc failed.");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
devc->cur_samplerate = SR_KHZ(200);
|
devc->cur_samplerate = SR_KHZ(200);
|
||||||
devc->limit_samples = 0;
|
devc->limit_samples = 0;
|
||||||
devc->limit_msec = 0;
|
devc->limit_msec = 0;
|
||||||
devc->sample_generator = PATTERN_SIGROK;
|
devc->step = 0;
|
||||||
devc->step =0;
|
devc->num_logic_probes = num_logic_probes;
|
||||||
|
devc->logic_unitsize = (devc->num_logic_probes + 7) / 8;
|
||||||
|
devc->logic_pattern = PATTERN_SIGROK;
|
||||||
|
devc->num_analog_probes = num_analog_probes;
|
||||||
|
|
||||||
sdi->priv = devc;
|
sdi->priv = devc;
|
||||||
|
|
||||||
|
@ -208,10 +235,11 @@ static int cleanup(void)
|
||||||
static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
|
static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
|
||||||
const struct sr_probe_group *probe_group)
|
const struct sr_probe_group *probe_group)
|
||||||
{
|
{
|
||||||
struct dev_context *const devc = sdi->priv;
|
struct dev_context *devc;
|
||||||
|
|
||||||
(void)probe_group;
|
(void)probe_group;
|
||||||
|
|
||||||
|
devc = sdi->priv;
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case SR_CONF_SAMPLERATE:
|
case SR_CONF_SAMPLERATE:
|
||||||
*data = g_variant_new_uint64(devc->cur_samplerate);
|
*data = g_variant_new_uint64(devc->cur_samplerate);
|
||||||
|
@ -223,7 +251,13 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
|
||||||
*data = g_variant_new_uint64(devc->limit_msec);
|
*data = g_variant_new_uint64(devc->limit_msec);
|
||||||
break;
|
break;
|
||||||
case SR_CONF_PATTERN_MODE:
|
case SR_CONF_PATTERN_MODE:
|
||||||
*data = g_variant_new_string(pattern_strings[devc->sample_generator]);
|
*data = g_variant_new_string(pattern_strings[devc->logic_pattern]);
|
||||||
|
break;
|
||||||
|
case SR_CONF_NUM_LOGIC_PROBES:
|
||||||
|
*data = g_variant_new_int32(devc->num_logic_probes);
|
||||||
|
break;
|
||||||
|
case SR_CONF_NUM_ANALOG_PROBES:
|
||||||
|
*data = g_variant_new_int32(devc->num_analog_probes);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return SR_ERR_NA;
|
return SR_ERR_NA;
|
||||||
|
@ -264,7 +298,7 @@ static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi,
|
||||||
ret = SR_ERR;
|
ret = SR_ERR;
|
||||||
for (i = 0; i < ARRAY_SIZE(pattern_strings); i++) {
|
for (i = 0; i < ARRAY_SIZE(pattern_strings); i++) {
|
||||||
if (!strcmp(stropt, pattern_strings[i])) {
|
if (!strcmp(stropt, pattern_strings[i])) {
|
||||||
devc->sample_generator = i;
|
devc->logic_pattern = i;
|
||||||
ret = SR_OK;
|
ret = SR_OK;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -292,6 +326,10 @@ static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
|
||||||
(void)probe_group;
|
(void)probe_group;
|
||||||
|
|
||||||
switch (key) {
|
switch (key) {
|
||||||
|
case SR_CONF_SCAN_OPTIONS:
|
||||||
|
*data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
|
||||||
|
hwopts, ARRAY_SIZE(hwopts), sizeof(int32_t));
|
||||||
|
break;
|
||||||
case SR_CONF_DEVICE_OPTIONS:
|
case SR_CONF_DEVICE_OPTIONS:
|
||||||
*data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
|
*data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
|
||||||
hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
|
hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
|
||||||
|
@ -313,18 +351,23 @@ static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
|
||||||
return SR_OK;
|
return SR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sample_generator(struct sr_dev_inst *sdi, uint64_t size)
|
static void logic_generator(struct sr_dev_inst *sdi, uint64_t size)
|
||||||
{
|
{
|
||||||
struct dev_context *devc;
|
struct dev_context *devc;
|
||||||
uint64_t i;
|
uint64_t i, j;
|
||||||
|
uint8_t pat;
|
||||||
|
|
||||||
devc = sdi->priv;
|
devc = sdi->priv;
|
||||||
|
|
||||||
switch (devc->sample_generator) {
|
switch (devc->logic_pattern) {
|
||||||
case PATTERN_SIGROK:
|
case PATTERN_SIGROK:
|
||||||
for (i = 0; i < size; i++) {
|
memset(devc->logic_data, 0x00, size);
|
||||||
devc->logic_data[i] = ~(pattern_sigrok[
|
for (i = 0; i < size; i += devc->logic_unitsize) {
|
||||||
devc->step++ % sizeof(pattern_sigrok)] >> 1);
|
for (j = 0; j < devc->logic_unitsize; j++) {
|
||||||
|
pat = pattern_sigrok[(devc->step + j) % sizeof(pattern_sigrok)] >> 1;
|
||||||
|
devc->logic_data[i + j] = ~pat;
|
||||||
|
}
|
||||||
|
devc->step++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PATTERN_RANDOM:
|
case PATTERN_RANDOM:
|
||||||
|
@ -332,15 +375,19 @@ static void sample_generator(struct sr_dev_inst *sdi, uint64_t size)
|
||||||
devc->logic_data[i] = (uint8_t)(rand() & 0xff);
|
devc->logic_data[i] = (uint8_t)(rand() & 0xff);
|
||||||
break;
|
break;
|
||||||
case PATTERN_INC:
|
case PATTERN_INC:
|
||||||
for (i = 0; i < size; i++)
|
for (i = 0; i < size; i++) {
|
||||||
devc->logic_data[i] = devc->step++;
|
for (j = 0; j < devc->logic_unitsize; j++) {
|
||||||
|
devc->logic_data[i + j] = devc->step;
|
||||||
|
}
|
||||||
|
devc->step++;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case PATTERN_ALL_LOW:
|
case PATTERN_ALL_LOW:
|
||||||
case PATTERN_ALL_HIGH:
|
case PATTERN_ALL_HIGH:
|
||||||
/* These were set when the pattern mode was selected. */
|
/* These were set when the pattern mode was selected. */
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
sr_err("Unknown pattern: %d.", devc->sample_generator);
|
sr_err("Unknown pattern: %d.", devc->logic_pattern);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -352,7 +399,7 @@ static int prepare_data(int fd, int revents, void *cb_data)
|
||||||
struct dev_context *devc;
|
struct dev_context *devc;
|
||||||
struct sr_datafeed_packet packet;
|
struct sr_datafeed_packet packet;
|
||||||
struct sr_datafeed_logic logic;
|
struct sr_datafeed_logic logic;
|
||||||
static uint64_t samples_to_send, expected_samplenum, sending_now;
|
uint64_t samples_to_send, expected_samplenum, sending_now;
|
||||||
int64_t time, elapsed;
|
int64_t time, elapsed;
|
||||||
|
|
||||||
(void)fd;
|
(void)fd;
|
||||||
|
@ -374,16 +421,17 @@ static int prepare_data(int fd, int revents, void *cb_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
while (samples_to_send > 0) {
|
while (samples_to_send > 0) {
|
||||||
sending_now = MIN(samples_to_send, LOGIC_BUFSIZE);
|
sending_now = MIN(samples_to_send, LOGIC_BUFSIZE / devc->logic_unitsize);
|
||||||
samples_to_send -= sending_now;
|
samples_to_send -= sending_now;
|
||||||
sample_generator(sdi, sending_now);
|
|
||||||
|
|
||||||
|
/* Logic */
|
||||||
|
logic_generator(sdi, sending_now * devc->logic_unitsize);
|
||||||
packet.type = SR_DF_LOGIC;
|
packet.type = SR_DF_LOGIC;
|
||||||
packet.payload = &logic;
|
packet.payload = &logic;
|
||||||
logic.length = sending_now;
|
logic.length = sending_now * devc->logic_unitsize;
|
||||||
logic.unitsize = 1;
|
logic.unitsize = devc->logic_unitsize;
|
||||||
logic.data = devc->logic_data;
|
logic.data = devc->logic_data;
|
||||||
sr_session_send(devc->cb_data, &packet);
|
sr_session_send(sdi, &packet);
|
||||||
devc->samples_counter += sending_now;
|
devc->samples_counter += sending_now;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -405,7 +453,6 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
|
||||||
return SR_ERR_DEV_CLOSED;
|
return SR_ERR_DEV_CLOSED;
|
||||||
|
|
||||||
devc = sdi->priv;
|
devc = sdi->priv;
|
||||||
devc->cb_data = cb_data;
|
|
||||||
devc->samples_counter = 0;
|
devc->samples_counter = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -458,7 +505,7 @@ static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
|
||||||
|
|
||||||
/* Send last packet. */
|
/* Send last packet. */
|
||||||
packet.type = SR_DF_END;
|
packet.type = SR_DF_END;
|
||||||
sr_session_send(devc->cb_data, &packet);
|
sr_session_send(sdi, &packet);
|
||||||
|
|
||||||
return SR_OK;
|
return SR_OK;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue