X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=src%2Fhardware%2Fkern-scale%2Fprotocol.c;h=8845ae39f6676e1f794635baf64d0c6d5dd9bb1b;hb=3be42bc22f8b36599a448273c12a76d3e0f7a940;hp=51ad9be19b938c7d603eff2e19a7b1cc46182cda;hpb=9380ec2f05e67518b1b23057749df3684a0cf05e;p=libsigrok.git diff --git a/src/hardware/kern-scale/protocol.c b/src/hardware/kern-scale/protocol.c index 51ad9be1..8845ae39 100644 --- a/src/hardware/kern-scale/protocol.c +++ b/src/hardware/kern-scale/protocol.c @@ -18,12 +18,92 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include +#include +#include +#include +#include +#include +#include "libsigrok-internal.h" #include "protocol.h" +static void handle_packet(const uint8_t *buf, struct sr_dev_inst *sdi, + void *info) +{ + struct scale_info *scale; + float floatval; + struct sr_datafeed_packet packet; + struct sr_datafeed_analog_old analog; + struct dev_context *devc; + + scale = (struct scale_info *)sdi->driver; + + devc = sdi->priv; + + memset(&analog, 0, sizeof(struct sr_datafeed_analog_old)); + + analog.channels = sdi->channels; + analog.num_samples = 1; + analog.mq = -1; + + scale->packet_parse(buf, &floatval, &analog, info); + analog.data = &floatval; + + if (analog.mq != -1) { + /* Got a measurement. */ + packet.type = SR_DF_ANALOG_OLD; + packet.payload = &analog; + sr_session_send(devc->cb_data, &packet); + devc->num_samples++; + } +} + +static void handle_new_data(struct sr_dev_inst *sdi, void *info) +{ + struct scale_info *scale; + struct dev_context *devc; + int len, i, offset = 0; + struct sr_serial_dev_inst *serial; + + scale = (struct scale_info *)sdi->driver; + + devc = sdi->priv; + serial = sdi->conn; + + /* Try to get as much data as the buffer can hold. */ + len = SCALE_BUFSIZE - devc->buflen; + len = serial_read_nonblocking(serial, devc->buf + devc->buflen, len); + if (len == 0) + return; /* No new bytes, nothing to do. */ + if (len < 0) { + sr_err("Serial port read error: %d.", len); + return; + } + devc->buflen += len; + + /* Now look for packets in that data. */ + while ((devc->buflen - offset) >= scale->packet_size) { + if (scale->packet_valid(devc->buf + offset)) { + handle_packet(devc->buf + offset, sdi, info); + offset += scale->packet_size; + } else { + offset++; + } + } + + /* If we have any data left, move it to the beginning of our buffer. */ + for (i = 0; i < devc->buflen - offset; i++) + devc->buf[i] = devc->buf[offset + i]; + devc->buflen -= offset; +} + SR_PRIV int kern_scale_receive_data(int fd, int revents, void *cb_data) { - const struct sr_dev_inst *sdi; + struct sr_dev_inst *sdi; struct dev_context *devc; + struct scale_info *scale; + int64_t time; + void *info; (void)fd; @@ -33,7 +113,28 @@ SR_PRIV int kern_scale_receive_data(int fd, int revents, void *cb_data) if (!(devc = sdi->priv)) return TRUE; + scale = (struct scale_info *)sdi->driver; + if (revents == G_IO_IN) { + /* Serial data arrived. */ + info = g_malloc(scale->info_size); + handle_new_data(sdi, info); + g_free(info); + } + + if (devc->limit_samples && devc->num_samples >= devc->limit_samples) { + sr_info("Requested number of samples reached."); + sdi->driver->dev_acquisition_stop(sdi, cb_data); + return TRUE; + } + + if (devc->limit_msec) { + time = (g_get_monotonic_time() - devc->starttime) / 1000; + if (time > (int64_t)devc->limit_msec) { + sr_info("Requested time limit reached."); + sdi->driver->dev_acquisition_stop(sdi, cb_data); + return TRUE; + } } return TRUE;