X-Git-Url: http://sigrok.org/gitweb/?a=blobdiff_plain;f=src%2Fhardware%2Ffluke-dmm%2Ffluke.c;h=89849f420b0f8ec88d375c0e3e4ffb50d73c0790;hb=6cf1a87bfb803e088234e2e313891d27379880cf;hp=edb6734adbd06166a1204cbd02012c16f77e060f;hpb=155b680da482cea2381becb73c51cfb838bff31e;p=libsigrok.git diff --git a/src/hardware/fluke-dmm/fluke.c b/src/hardware/fluke-dmm/fluke.c index edb6734a..89849f42 100644 --- a/src/hardware/fluke-dmm/fluke.c +++ b/src/hardware/fluke-dmm/fluke.c @@ -17,12 +17,12 @@ * along with this program. If not, see . */ +#include #include #include #include -#include #include -#include "libsigrok.h" +#include #include "libsigrok-internal.h" #include "fluke-dmm.h" @@ -30,6 +30,9 @@ static struct sr_datafeed_analog *handle_qm_18x(const struct sr_dev_inst *sdi, char **tokens) { struct sr_datafeed_analog *analog; + struct sr_analog_encoding encoding; + struct sr_analog_meaning meaning; + struct sr_analog_spec spec; float fvalue; char *e, *u; gboolean is_oor; @@ -40,14 +43,14 @@ static struct sr_datafeed_analog *handle_qm_18x(const struct sr_dev_inst *sdi, if ((e = strstr(tokens[1], "Out of range"))) { is_oor = TRUE; fvalue = -1; - while(*e && *e != '.') + while (*e && *e != '.') e++; } else { is_oor = FALSE; /* Delimit the float, since sr_atof_ascii() wants only * a valid float here. */ e = tokens[1]; - while(*e && *e != ' ') + while (*e && *e != ' ') e++; *e++ = '\0'; if (sr_atof_ascii(tokens[1], &fvalue) != SR_OK || fvalue == 0.0) { @@ -56,97 +59,97 @@ static struct sr_datafeed_analog *handle_qm_18x(const struct sr_dev_inst *sdi, return NULL; } } - while(*e && *e == ' ') + while (*e && *e == ' ') e++; - if (!(analog = g_try_malloc0(sizeof(struct sr_datafeed_analog)))) - return NULL; - if (!(analog->data = g_try_malloc(sizeof(float)))) - return NULL; - analog->channels = sdi->channels; + analog = g_malloc0(sizeof(struct sr_datafeed_analog)); + /* TODO: Use proper 'digits' value for this device (and its modes). */ + sr_analog_init(analog, &encoding, &meaning, &spec, 2); + analog->data = g_malloc(sizeof(float)); + analog->meaning->channels = sdi->channels; analog->num_samples = 1; if (is_oor) - *analog->data = NAN; + *((float *)analog->data) = NAN; else - *analog->data = fvalue; - analog->mq = -1; + *((float *)analog->data) = fvalue; + analog->meaning->mq = 0; if ((u = strstr(e, "V DC")) || (u = strstr(e, "V AC"))) { - analog->mq = SR_MQ_VOLTAGE; - analog->unit = SR_UNIT_VOLT; + analog->meaning->mq = SR_MQ_VOLTAGE; + analog->meaning->unit = SR_UNIT_VOLT; if (!is_oor && e[0] == 'm') - *analog->data /= 1000; + *((float *)analog->data) /= 1000; /* This catches "V AC", "V DC" and "V AC+DC". */ if (strstr(u, "AC")) - analog->mqflags |= SR_MQFLAG_AC | SR_MQFLAG_RMS; + analog->meaning->mqflags |= SR_MQFLAG_AC | SR_MQFLAG_RMS; if (strstr(u, "DC")) - analog->mqflags |= SR_MQFLAG_DC; + analog->meaning->mqflags |= SR_MQFLAG_DC; } else if ((u = strstr(e, "dBV")) || (u = strstr(e, "dBm"))) { - analog->mq = SR_MQ_VOLTAGE; + analog->meaning->mq = SR_MQ_VOLTAGE; if (u[2] == 'm') - analog->unit = SR_UNIT_DECIBEL_MW; + analog->meaning->unit = SR_UNIT_DECIBEL_MW; else - analog->unit = SR_UNIT_DECIBEL_VOLT; - analog->mqflags |= SR_MQFLAG_AC | SR_MQFLAG_RMS; + analog->meaning->unit = SR_UNIT_DECIBEL_VOLT; + analog->meaning->mqflags |= SR_MQFLAG_AC | SR_MQFLAG_RMS; } else if ((u = strstr(e, "Ohms"))) { - analog->mq = SR_MQ_RESISTANCE; - analog->unit = SR_UNIT_OHM; + analog->meaning->mq = SR_MQ_RESISTANCE; + analog->meaning->unit = SR_UNIT_OHM; if (is_oor) - *analog->data = INFINITY; + *((float *)analog->data) = INFINITY; else if (e[0] == 'k') - *analog->data *= 1000; + *((float *)analog->data) *= 1000; else if (e[0] == 'M') - *analog->data *= 1000000; + *((float *)analog->data) *= 1000000; } else if (!strcmp(e, "nS")) { - analog->mq = SR_MQ_CONDUCTANCE; - analog->unit = SR_UNIT_SIEMENS; - *analog->data /= 1e+9; + analog->meaning->mq = SR_MQ_CONDUCTANCE; + analog->meaning->unit = SR_UNIT_SIEMENS; + *((float *)analog->data) /= 1e+9; } else if ((u = strstr(e, "Farads"))) { - analog->mq = SR_MQ_CAPACITANCE; - analog->unit = SR_UNIT_FARAD; + analog->meaning->mq = SR_MQ_CAPACITANCE; + analog->meaning->unit = SR_UNIT_FARAD; if (!is_oor) { if (e[0] == 'm') - *analog->data /= 1e+3; + *((float *)analog->data) /= 1e+3; else if (e[0] == 'u') - *analog->data /= 1e+6; + *((float *)analog->data) /= 1e+6; else if (e[0] == 'n') - *analog->data /= 1e+9; + *((float *)analog->data) /= 1e+9; } } else if ((u = strstr(e, "Deg C")) || (u = strstr(e, "Deg F"))) { - analog->mq = SR_MQ_TEMPERATURE; + analog->meaning->mq = SR_MQ_TEMPERATURE; if (u[4] == 'C') - analog->unit = SR_UNIT_CELSIUS; + analog->meaning->unit = SR_UNIT_CELSIUS; else - analog->unit = SR_UNIT_FAHRENHEIT; + analog->meaning->unit = SR_UNIT_FAHRENHEIT; } else if ((u = strstr(e, "A AC")) || (u = strstr(e, "A DC"))) { - analog->mq = SR_MQ_CURRENT; - analog->unit = SR_UNIT_AMPERE; + analog->meaning->mq = SR_MQ_CURRENT; + analog->meaning->unit = SR_UNIT_AMPERE; /* This catches "A AC", "A DC" and "A AC+DC". */ if (strstr(u, "AC")) - analog->mqflags |= SR_MQFLAG_AC | SR_MQFLAG_RMS; + analog->meaning->mqflags |= SR_MQFLAG_AC | SR_MQFLAG_RMS; if (strstr(u, "DC")) - analog->mqflags |= SR_MQFLAG_DC; + analog->meaning->mqflags |= SR_MQFLAG_DC; if (!is_oor) { if (e[0] == 'm') - *analog->data /= 1e+3; + *((float *)analog->data) /= 1e+3; else if (e[0] == 'u') - *analog->data /= 1e+6; + *((float *)analog->data) /= 1e+6; } } else if ((u = strstr(e, "Hz"))) { - analog->mq = SR_MQ_FREQUENCY; - analog->unit = SR_UNIT_HERTZ; + analog->meaning->mq = SR_MQ_FREQUENCY; + analog->meaning->unit = SR_UNIT_HERTZ; if (e[0] == 'k') - *analog->data *= 1e+3; + *((float *)analog->data) *= 1e+3; } else if (!strcmp(e, "%")) { - analog->mq = SR_MQ_DUTY_CYCLE; - analog->unit = SR_UNIT_PERCENTAGE; + analog->meaning->mq = SR_MQ_DUTY_CYCLE; + analog->meaning->unit = SR_UNIT_PERCENTAGE; } else if ((u = strstr(e, "ms"))) { - analog->mq = SR_MQ_PULSE_WIDTH; - analog->unit = SR_UNIT_SECOND; - *analog->data /= 1e+3; + analog->meaning->mq = SR_MQ_PULSE_WIDTH; + analog->meaning->unit = SR_UNIT_SECOND; + *((float *)analog->data) /= 1e+3; } - if (analog->mq == -1) { + if (analog->meaning->mq == 0) { /* Not a valid measurement. */ g_free(analog->data); g_free(analog); @@ -160,6 +163,9 @@ static struct sr_datafeed_analog *handle_qm_28x(const struct sr_dev_inst *sdi, char **tokens) { struct sr_datafeed_analog *analog; + struct sr_analog_encoding encoding; + struct sr_analog_meaning meaning; + struct sr_analog_spec spec; float fvalue; if (!tokens[1]) @@ -170,93 +176,93 @@ static struct sr_datafeed_analog *handle_qm_28x(const struct sr_dev_inst *sdi, return NULL; } - if (!(analog = g_try_malloc0(sizeof(struct sr_datafeed_analog)))) - return NULL; - if (!(analog->data = g_try_malloc(sizeof(float)))) - return NULL; - analog->channels = sdi->channels; + analog = g_malloc0(sizeof(struct sr_datafeed_analog)); + /* TODO: Use proper 'digits' value for this device (and its modes). */ + sr_analog_init(analog, &encoding, &meaning, &spec, 2); + analog->data = g_malloc(sizeof(float)); + analog->meaning->channels = sdi->channels; analog->num_samples = 1; - *analog->data = fvalue; - analog->mq = -1; + *((float *)analog->data) = fvalue; + analog->meaning->mq = 0; if (!strcmp(tokens[1], "VAC") || !strcmp(tokens[1], "VDC")) { - analog->mq = SR_MQ_VOLTAGE; - analog->unit = SR_UNIT_VOLT; + analog->meaning->mq = SR_MQ_VOLTAGE; + analog->meaning->unit = SR_UNIT_VOLT; if (!strcmp(tokens[2], "NORMAL")) { if (tokens[1][1] == 'A') { - analog->mqflags |= SR_MQFLAG_AC; - analog->mqflags |= SR_MQFLAG_RMS; + analog->meaning->mqflags |= SR_MQFLAG_AC; + analog->meaning->mqflags |= SR_MQFLAG_RMS; } else - analog->mqflags |= SR_MQFLAG_DC; + analog->meaning->mqflags |= SR_MQFLAG_DC; } else if (!strcmp(tokens[2], "OL") || !strcmp(tokens[2], "OL_MINUS")) { - *analog->data = NAN; + *((float *)analog->data) = NAN; } else - analog->mq = -1; + analog->meaning->mq = 0; } else if (!strcmp(tokens[1], "dBV") || !strcmp(tokens[1], "dBm")) { - analog->mq = SR_MQ_VOLTAGE; + analog->meaning->mq = SR_MQ_VOLTAGE; if (tokens[1][2] == 'm') - analog->unit = SR_UNIT_DECIBEL_MW; + analog->meaning->unit = SR_UNIT_DECIBEL_MW; else - analog->unit = SR_UNIT_DECIBEL_VOLT; - analog->mqflags |= SR_MQFLAG_AC | SR_MQFLAG_RMS; + analog->meaning->unit = SR_UNIT_DECIBEL_VOLT; + analog->meaning->mqflags |= SR_MQFLAG_AC | SR_MQFLAG_RMS; } else if (!strcmp(tokens[1], "CEL") || !strcmp(tokens[1], "FAR")) { if (!strcmp(tokens[2], "NORMAL")) { - analog->mq = SR_MQ_TEMPERATURE; + analog->meaning->mq = SR_MQ_TEMPERATURE; if (tokens[1][0] == 'C') - analog->unit = SR_UNIT_CELSIUS; + analog->meaning->unit = SR_UNIT_CELSIUS; else - analog->unit = SR_UNIT_FAHRENHEIT; + analog->meaning->unit = SR_UNIT_FAHRENHEIT; } } else if (!strcmp(tokens[1], "OHM")) { if (!strcmp(tokens[3], "NONE")) { - analog->mq = SR_MQ_RESISTANCE; - analog->unit = SR_UNIT_OHM; + analog->meaning->mq = SR_MQ_RESISTANCE; + analog->meaning->unit = SR_UNIT_OHM; if (!strcmp(tokens[2], "OL") || !strcmp(tokens[2], "OL_MINUS")) { - *analog->data = INFINITY; + *((float *)analog->data) = INFINITY; } else if (strcmp(tokens[2], "NORMAL")) - analog->mq = -1; + analog->meaning->mq = 0; } else if (!strcmp(tokens[3], "OPEN_CIRCUIT")) { - analog->mq = SR_MQ_CONTINUITY; - analog->unit = SR_UNIT_BOOLEAN; - *analog->data = 0.0; + analog->meaning->mq = SR_MQ_CONTINUITY; + analog->meaning->unit = SR_UNIT_BOOLEAN; + *((float *)analog->data) = 0.0; } else if (!strcmp(tokens[3], "SHORT_CIRCUIT")) { - analog->mq = SR_MQ_CONTINUITY; - analog->unit = SR_UNIT_BOOLEAN; - *analog->data = 1.0; + analog->meaning->mq = SR_MQ_CONTINUITY; + analog->meaning->unit = SR_UNIT_BOOLEAN; + *((float *)analog->data) = 1.0; } } else if (!strcmp(tokens[1], "F") && !strcmp(tokens[2], "NORMAL") && !strcmp(tokens[3], "NONE")) { - analog->mq = SR_MQ_CAPACITANCE; - analog->unit = SR_UNIT_FARAD; + analog->meaning->mq = SR_MQ_CAPACITANCE; + analog->meaning->unit = SR_UNIT_FARAD; } else if (!strcmp(tokens[1], "AAC") || !strcmp(tokens[1], "ADC")) { - analog->mq = SR_MQ_CURRENT; - analog->unit = SR_UNIT_AMPERE; + analog->meaning->mq = SR_MQ_CURRENT; + analog->meaning->unit = SR_UNIT_AMPERE; if (!strcmp(tokens[2], "NORMAL")) { if (tokens[1][1] == 'A') { - analog->mqflags |= SR_MQFLAG_AC; - analog->mqflags |= SR_MQFLAG_RMS; + analog->meaning->mqflags |= SR_MQFLAG_AC; + analog->meaning->mqflags |= SR_MQFLAG_RMS; } else - analog->mqflags |= SR_MQFLAG_DC; + analog->meaning->mqflags |= SR_MQFLAG_DC; } else if (!strcmp(tokens[2], "OL") || !strcmp(tokens[2], "OL_MINUS")) { - *analog->data = NAN; + *((float *)analog->data) = NAN; } else - analog->mq = -1; + analog->meaning->mq = 0; } if (!strcmp(tokens[1], "Hz") && !strcmp(tokens[2], "NORMAL")) { - analog->mq = SR_MQ_FREQUENCY; - analog->unit = SR_UNIT_HERTZ; + analog->meaning->mq = SR_MQ_FREQUENCY; + analog->meaning->unit = SR_UNIT_HERTZ; } else if (!strcmp(tokens[1], "PCT") && !strcmp(tokens[2], "NORMAL")) { - analog->mq = SR_MQ_DUTY_CYCLE; - analog->unit = SR_UNIT_PERCENTAGE; + analog->meaning->mq = SR_MQ_DUTY_CYCLE; + analog->meaning->unit = SR_UNIT_PERCENTAGE; } else if (!strcmp(tokens[1], "S") && !strcmp(tokens[2], "NORMAL")) { - analog->mq = SR_MQ_PULSE_WIDTH; - analog->unit = SR_UNIT_SECOND; + analog->meaning->mq = SR_MQ_PULSE_WIDTH; + analog->meaning->unit = SR_UNIT_SECOND; } else if (!strcmp(tokens[1], "SIE") && !strcmp(tokens[2], "NORMAL")) { - analog->mq = SR_MQ_CONDUCTANCE; - analog->unit = SR_UNIT_SIEMENS; + analog->meaning->mq = SR_MQ_CONDUCTANCE; + analog->meaning->unit = SR_UNIT_SIEMENS; } - if (analog->mq == -1) { + if (analog->meaning->mq == 0) { /* Not a valid measurement. */ g_free(analog->data); g_free(analog); @@ -303,8 +309,10 @@ static void handle_qm_19x_meta(const struct sr_dev_inst *sdi, char **tokens) return; meas_char = strtol(tokens[4], NULL, 10); - devc->mq = devc->unit = -1; + devc->mq = 0; + devc->unit = 0; devc->mqflags = 0; + switch (meas_unit) { case 1: devc->mq = SR_MQ_VOLTAGE; @@ -348,7 +356,7 @@ static void handle_qm_19x_meta(const struct sr_dev_inst *sdi, char **tokens) default: sr_dbg("unknown unit: %d", meas_unit); } - if (devc->mq == -1 && devc->unit == -1) + if (devc->mq == 0 && devc->unit == 0) return; /* If we got here, we know how to interpret the measurement. */ @@ -367,6 +375,9 @@ static void handle_qm_19x_data(const struct sr_dev_inst *sdi, char **tokens) struct dev_context *devc; struct sr_datafeed_packet packet; struct sr_datafeed_analog analog; + struct sr_analog_encoding encoding; + struct sr_analog_meaning meaning; + struct sr_analog_spec spec; float fvalue; if (!strcmp(tokens[0], "9.9E+37")) { @@ -382,11 +393,10 @@ static void handle_qm_19x_data(const struct sr_dev_inst *sdi, char **tokens) } devc = sdi->priv; - if (devc->mq == -1 || devc->unit == -1) + if (devc->mq == 0 || devc->unit == 0) /* Don't have valid metadata yet. */ return; - if (devc->mq == SR_MQ_RESISTANCE && isnan(fvalue)) fvalue = INFINITY; else if (devc->mq == SR_MQ_CONTINUITY) { @@ -396,17 +406,19 @@ static void handle_qm_19x_data(const struct sr_dev_inst *sdi, char **tokens) fvalue = 1.0; } - analog.channels = sdi->channels; + /* TODO: Use proper 'digits' value for this device (and its modes). */ + sr_analog_init(&analog, &encoding, &meaning, &spec, 2); + analog.meaning->channels = sdi->channels; analog.num_samples = 1; analog.data = &fvalue; - analog.mq = devc->mq; - analog.unit = devc->unit; - analog.mqflags = 0; + analog.meaning->mq = devc->mq; + analog.meaning->unit = devc->unit; + analog.meaning->mqflags = 0; packet.type = SR_DF_ANALOG; packet.payload = &analog; - sr_session_send(devc->cb_data, &packet); - devc->num_samples++; + sr_session_send(sdi, &packet); + sr_sw_limits_update_samples_read(&devc->limits, 1); } static void handle_line(const struct sr_dev_inst *sdi) @@ -438,7 +450,7 @@ static void handle_line(const struct sr_dev_inst *sdi) if (devc->profile->model == FLUKE_187 || devc->profile->model == FLUKE_189) { devc->expect_response = FALSE; analog = handle_qm_18x(sdi, tokens); - } else if (devc->profile->model == FLUKE_287) { + } else if (devc->profile->model == FLUKE_287 || devc->profile->model == FLUKE_289) { devc->expect_response = FALSE; analog = handle_qm_28x(sdi, tokens); } else if (devc->profile->model == FLUKE_190) { @@ -456,9 +468,8 @@ static void handle_line(const struct sr_dev_inst *sdi) /* Slip the request in now, before the main * timer loop asks for metadata again. */ n = sprintf(cmd, "QM %d\r", devc->meas_type); - if (serial_write(serial, cmd, n) == -1) - sr_err("Unable to send QM (measurement): %s.", - strerror(errno)); + if (serial_write_blocking(serial, cmd, n, SERIAL_WRITE_TIMEOUT_MS) < 0) + sr_err("Unable to send QM (measurement)."); } } else { /* Response to QM measurement request. */ @@ -473,8 +484,8 @@ static void handle_line(const struct sr_dev_inst *sdi) /* Got a measurement. */ packet.type = SR_DF_ANALOG; packet.payload = analog; - sr_session_send(devc->cb_data, &packet); - devc->num_samples++; + sr_session_send(sdi, &packet); + sr_sw_limits_update_samples_read(&devc->limits, 1); g_free(analog->data); g_free(analog); } @@ -500,8 +511,8 @@ SR_PRIV int fluke_receive_data(int fd, int revents, void *cb_data) serial = sdi->conn; if (revents == G_IO_IN) { /* Serial data arrived. */ - while(FLUKEDMM_BUFSIZE - devc->buflen - 1 > 0) { - len = serial_read(serial, devc->buf + devc->buflen, 1); + while (FLUKEDMM_BUFSIZE - devc->buflen - 1 > 0) { + len = serial_read_nonblocking(serial, devc->buf + devc->buflen, 1); if (len < 1) break; devc->buflen++; @@ -514,8 +525,8 @@ SR_PRIV int fluke_receive_data(int fd, int revents, void *cb_data) } } - if (devc->limit_samples && devc->num_samples >= devc->limit_samples) { - sdi->driver->dev_acquisition_stop(sdi, cb_data); + if (sr_sw_limits_check(&devc->limits)) { + sdi->driver->dev_acquisition_stop(sdi); return TRUE; } @@ -526,8 +537,8 @@ SR_PRIV int fluke_receive_data(int fd, int revents, void *cb_data) * out-of-sync or temporary disconnect issues. */ if ((devc->expect_response == FALSE && elapsed > devc->profile->poll_period) || elapsed > devc->profile->timeout) { - if (serial_write(serial, "QM\r", 3) == -1) - sr_err("Unable to send QM: %s.", strerror(errno)); + if (serial_write_blocking(serial, "QM\r", 3, SERIAL_WRITE_TIMEOUT_MS) < 0) + sr_err("Unable to send QM."); devc->cmd_sent_at = now; devc->expect_response = TRUE; }