X-Git-Url: http://sigrok.org/gitweb/?a=blobdiff_plain;f=hardware%2Fasix-sigma%2Fasix-sigma.c;h=41df8e6a171130341255edf5c02eaa2a3b5ec159;hb=6ea7e23526b6be4d6c762b1136e361e4d3caccf6;hp=583501c02ba70033a12792cd01185e13ec291722;hpb=9996570987d362a324384ed041040e884628853e;p=libsigrok.git diff --git a/hardware/asix-sigma/asix-sigma.c b/hardware/asix-sigma/asix-sigma.c index 583501c0..41df8e6a 100644 --- a/hardware/asix-sigma/asix-sigma.c +++ b/hardware/asix-sigma/asix-sigma.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "asix-sigma.h" #define USB_VENDOR 0xa600 @@ -407,6 +408,7 @@ static int hw_init(char *deviceinfo) sigma->num_probes = 0; sigma->samples_per_event = 0; sigma->capture_ratio = 50; + sigma->use_triggers = 0; /* Register SIGMA device. */ sdi = sigrok_device_instance_new(0, ST_INITIALIZING, @@ -643,12 +645,20 @@ static int configure_probes(struct sigrok_device_instance *sdi, GSList *probes) ++trigger_set; } - if (trigger_set > 2) { - g_warning("Asix Sigma only supports 2 rising/" + /* + * Actually, Sigma supports 2 rising/falling triggers, + * but they are ORed and the current trigger syntax + * does not permit ORed triggers. + */ + if (trigger_set > 1) { + g_warning("Asix Sigma only supports 1 rising/" "falling triggers."); return SIGROK_ERR; } } + + if (trigger_set) + sigma->use_triggers = 1; } return SIGROK_OK; @@ -751,11 +761,17 @@ static int hw_set_configuration(int device_index, int capability, void *value) } else if (capability == HWCAP_PROBECONFIG) { ret = configure_probes(sdi, value); } else if (capability == HWCAP_LIMIT_MSEC) { - sigma->limit_msec = strtoull(value, NULL, 10); - ret = SIGROK_OK; + sigma->limit_msec = *(uint64_t*) value; + if (sigma->limit_msec > 0) + ret = SIGROK_OK; + else + ret = SIGROK_ERR; } else if (capability == HWCAP_CAPTURE_RATIO) { - sigma->capture_ratio = strtoull(value, NULL, 10); - ret = SIGROK_OK; + sigma->capture_ratio = *(uint64_t*) value; + if (sigma->capture_ratio < 0 || sigma->capture_ratio > 100) + ret = SIGROK_ERR; + else + ret = SIGROK_OK; } else { ret = SIGROK_ERR; } @@ -804,7 +820,8 @@ static int get_trigger_offset(uint16_t *samples, uint16_t last_sample, * spread 20 ns apart. */ static int decode_chunk_ts(uint8_t *buf, uint16_t *lastts, - uint16_t *lastsample, int triggerpos, void *user_data) + uint16_t *lastsample, int triggerpos, + uint16_t limit_chunk, void *user_data) { struct sigrok_device_instance *sdi = user_data; struct sigma *sigma = sdi->priv; @@ -836,6 +853,10 @@ static int decode_chunk_ts(uint8_t *buf, uint16_t *lastts, tsdiff = ts - *lastts; *lastts = ts; + /* Decode partial chunk. */ + if (limit_chunk && ts > limit_chunk) + return SIGROK_OK; + /* Pad last sample up to current point. */ numpad = tsdiff * sigma->samples_per_event - clustersize; if (numpad > 0) { @@ -903,20 +924,25 @@ static int decode_chunk_ts(uint8_t *buf, uint16_t *lastts, sent += tosend; } - packet.type = DF_TRIGGER; - packet.length = 0; - packet.payload = 0; - session_bus(sigma->session_id, &packet); + /* Only send trigger if explicitly enabled. */ + if (sigma->use_triggers) { + packet.type = DF_TRIGGER; + packet.length = 0; + packet.payload = 0; + session_bus(sigma->session_id, &packet); + } } /* Send rest of the chunk to sigrok. */ tosend = n - sent; - packet.type = DF_LOGIC; - packet.length = tosend * sizeof(uint16_t); - packet.unitsize = 2; - packet.payload = samples + sent; - session_bus(sigma->session_id, &packet); + if (tosend > 0) { + packet.type = DF_LOGIC; + packet.length = tosend * sizeof(uint16_t); + packet.unitsize = 2; + packet.payload = samples + sent; + session_bus(sigma->session_id, &packet); + } *lastsample = samples[n - 1]; } @@ -932,13 +958,13 @@ static int receive_data(int fd, int revents, void *user_data) const int chunks_per_read = 32; unsigned char buf[chunks_per_read * CHUNK_SIZE]; int bufsz, numchunks, i, newchunks; - uint32_t running_msec; + uint64_t running_msec; struct timeval tv; fd = fd; revents = revents; - numchunks = sigma->state.stoppos / 512; + numchunks = (sigma->state.stoppos + 511) / 512; if (sigma->state.state == SIGMA_IDLE) return FALSE; @@ -986,20 +1012,29 @@ static int receive_data(int fd, int revents, void *user_data) /* Decode chunks and send them to sigrok. */ for (i = 0; i < newchunks; ++i) { + int limit_chunk = 0; + + /* The last chunk may potentially be only in part. */ + if (sigma->state.chunks_downloaded == numchunks - 1) + { + /* Find the last valid timestamp */ + limit_chunk = sigma->state.stoppos % 512 + sigma->state.lastts; + } + if (sigma->state.chunks_downloaded + i == sigma->state.triggerchunk) decode_chunk_ts(buf + (i * CHUNK_SIZE), &sigma->state.lastts, &sigma->state.lastsample, sigma->state.triggerpos & 0x1ff, - user_data); + limit_chunk, user_data); else decode_chunk_ts(buf + (i * CHUNK_SIZE), &sigma->state.lastts, &sigma->state.lastsample, - -1, user_data); - } + -1, limit_chunk, user_data); - sigma->state.chunks_downloaded += newchunks; + ++sigma->state.chunks_downloaded; + } } return TRUE; @@ -1181,9 +1216,9 @@ static int hw_start_acquisition(int device_index, gpointer session_device_id) sigma = sdi->priv; - /* If the samplerate has not been set, default to 50 MHz. */ + /* If the samplerate has not been set, default to 200 KHz. */ if (sigma->cur_firmware == -1) - set_samplerate(sdi, MHZ(50)); + set_samplerate(sdi, KHZ(200)); /* Enter trigger programming mode. */ sigma_set_register(WRITE_TRIGGER_SELECT1, 0x20, sigma);