X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=hardware%2Fnorma-dmm%2Fprotocol.c;h=8e1466a42df76e0a5504890cf492bd21fb233380;hb=d405193074b11296e33acb56945978c08f2f4f98;hp=3b2bff7cb1e8026ec4e7965b18765e3a4b595e33;hpb=f8e76e2e74bf09024af50d68a0e90a558be126b9;p=libsigrok.git diff --git a/hardware/norma-dmm/protocol.c b/hardware/norma-dmm/protocol.c index 3b2bff7c..8e1466a4 100644 --- a/hardware/norma-dmm/protocol.c +++ b/hardware/norma-dmm/protocol.c @@ -19,19 +19,45 @@ #include "protocol.h" -#include -#include -#include -#include +SR_PRIV const struct nmadmm_req nmadmm_requests[] = { + { NMADMM_REQ_IDN, "IDN?" }, + { NMADMM_REQ_IDN, "STATUS?" }, + { 0, NULL }, +}; + +static int nma_send_req(const struct sr_dev_inst *sdi, int req, char *params) +{ + struct sr_serial_dev_inst *serial; + struct dev_context *devc; + char buf[NMADMM_BUFSIZE]; + int len; + + if (!sdi || !(serial = sdi->conn) || !(devc = sdi->priv)) + return SR_ERR_BUG; + len = snprintf(buf, sizeof(buf), "%s%s\r\n", + nmadmm_requests[req].req_str, params ? params : ""); -static int nma_send_req(const struct sr_dev_inst *sdi, enum nmadmm_req_t reqt, - char* params); + sr_spew("Sending request: '%s'.", buf); + devc->last_req = req; + devc->last_req_pending = TRUE; -/** Convert hexadecimal digit to int. - * \param[in] xgit Hexadecimal digit to convert. - * \return Int value of xgit (0 on invalid xgit). + if (serial_write(serial, buf, len) == -1) { + sr_err("Unable to send request: %d %s.", + errno, strerror(errno)); + devc->last_req_pending = FALSE; + return SR_ERR; + } + + return SR_OK; +} + +/** + * Convert hexadecimal digit to int. + * + * @param[in] xgit Hexadecimal digit to convert. + * @return Int value of xgit (0 on invalid xgit). */ SR_PRIV int xgittoint(char xgit) { @@ -43,9 +69,10 @@ SR_PRIV int xgittoint(char xgit) return 0; } - -/** Process received line. It consists of 20 hex digits + \r\n, - * e.g. '08100400018100400000'. */ +/** + * Process received line. It consists of 20 hex digits + \\r\\n, + * e.g. '08100400018100400000'. + */ static void nma_process_line(const struct sr_dev_inst *sdi) { struct dev_context *devc; @@ -54,7 +81,6 @@ static void nma_process_line(const struct sr_dev_inst *sdi) int mmode, devstat; /* Measuring mode, device status */ float value; /* Measured value */ float scale; /* Scaling factor depending on range and function */ - struct sr_datafeed_analog analog; struct sr_datafeed_packet packet; @@ -64,84 +90,103 @@ static void nma_process_line(const struct sr_dev_inst *sdi) sr_spew("Received line '%s'.", devc->buf); - /* Check line */ - if (strlen((char*)devc->buf) != 20) { - sr_err("line: Invalid status '%s', must be 20 hex digits"); + /* Check line. */ + if (strlen((const char *)devc->buf) != 20) { + sr_err("line: Invalid status '%s', must be 20 hex digits.", + devc->buf); devc->buflen = 0; return; } - for (pos = 0; pos < 20; pos++) + + for (pos = 0; pos < 20; pos++) { if (!isxdigit(devc->buf[pos])) { sr_err("line: Expected hex digit in '%s' at pos %d!", devc->buf, pos); devc->buflen = 0; return; } + } /* Start decoding. */ value = 0.0; scale = 1.0; memset(&analog, 0, sizeof(analog)); - /* The numbers are hex digits, starting from 0. */ - /* 0: Keyboard status, currently not interesting. */ - /* 1: Central switch status, currently not interesting. */ - /* 2: Type of measured value */ + /* + * The numbers are hex digits, starting from 0. + * 0: Keyboard status, currently not interesting. + * 1: Central switch status, currently not interesting. + * 2: Type of measured value. + */ vt = xgittoint(devc->buf[2]); switch (vt) { - case 0: analog.mq = SR_MQ_VOLTAGE; + case 0: + analog.mq = SR_MQ_VOLTAGE; break; - case 1: analog.mq = SR_MQ_CURRENT; // 2A + case 1: + analog.mq = SR_MQ_CURRENT; /* 2A */ break; - case 2: analog.mq = SR_MQ_RESISTANCE; + case 2: + analog.mq = SR_MQ_RESISTANCE; break; - case 3: analog.mq = SR_MQ_CAPACITANCE; + case 3: + analog.mq = SR_MQ_CAPACITANCE; break; - case 4: analog.mq = SR_MQ_TEMPERATURE; + case 4: + analog.mq = SR_MQ_TEMPERATURE; break; - case 5: analog.mq = SR_MQ_FREQUENCY; + case 5: + analog.mq = SR_MQ_FREQUENCY; break; - case 6: analog.mq = SR_MQ_CURRENT; // 10A + case 6: + analog.mq = SR_MQ_CURRENT; /* 10A */ break; - case 7: analog.mq = SR_MQ_GAIN; // TODO: Scale factor + case 7: + analog.mq = SR_MQ_GAIN; /* TODO: Scale factor */ break; - case 8: analog.mq = SR_MQ_GAIN; // Percentage + case 8: + analog.mq = SR_MQ_GAIN; /* Percentage */ scale /= 100.0; break; - case 9: analog.mq = SR_MQ_GAIN; // dB + case 9: + analog.mq = SR_MQ_GAIN; /* dB */ scale /= 100.0; break; - default:sr_err("Unknown value type 0x%02x", vt); - break; + default: + sr_err("Unknown value type: 0x%02x.", vt); + break; } + /* 3: Measurement range for measured value */ range = xgittoint(devc->buf[3]); switch (vt) { - case 0: // V + case 0: /* V */ scale *= pow(10.0, range - 5); break; - case 1: // A + case 1: /* A */ scale *= pow(10.0, range - 7); break; - case 2: // Ω + case 2: /* Ω */ scale *= pow(10.0, range - 2); break; - case 3: // F + case 3: /* F */ scale *= pow(10.0, range - 12); break; - case 4: // °C + case 4: /* °C */ scale *= pow(10.0, range - 1); break; - case 5: // Hz + case 5: /* Hz */ scale *= pow(10.0, range - 2); break; - // No default, other value types have fixed display format + // No default, other value types have fixed display format. } /* 5: Sign and 1st digit */ flags = xgittoint(devc->buf[5]); value = (flags & 0x03); - if (flags & 0x04) scale *= -1; + if (flags & 0x04) + scale *= -1; + /* 6-9: 2nd-4th digit */ for (pos = 6; pos < 10; pos++) value = value * 10 + xgittoint(devc->buf[pos]); @@ -150,55 +195,57 @@ static void nma_process_line(const struct sr_dev_inst *sdi) /* 10: Display counter */ mmode = xgittoint(devc->buf[10]); switch (mmode) { - case 0: /* Frequency */ + case 0: /* Frequency */ analog.unit = SR_UNIT_HERTZ; break; - case 1: /* V TRMS, only type 5 */ + case 1: /* V TRMS, only type 5 */ analog.unit = SR_UNIT_VOLT; analog.mqflags |= (SR_MQFLAG_AC | SR_MQFLAG_DC | SR_MQFLAG_RMS); break; - case 2: /* V AC */ + case 2: /* V AC */ analog.unit = SR_UNIT_VOLT; analog.mqflags |= SR_MQFLAG_AC; - if (devc->type >= 3) analog.mqflags |= SR_MQFLAG_RMS; + if (devc->type >= 3) + analog.mqflags |= SR_MQFLAG_RMS; break; - case 3: /* V DC */ + case 3: /* V DC */ analog.unit = SR_UNIT_VOLT; analog.mqflags |= SR_MQFLAG_DC; break; - case 4: /* Ohm */ + case 4: /* Ohm */ analog.unit = SR_UNIT_OHM; break; - case 5: /* Continuity */ + case 5: /* Continuity */ analog.unit = SR_UNIT_BOOLEAN; analog.mq = SR_MQ_CONTINUITY; - /* TODO Continuity handling is a bit odd in sigrok. */ + /* TODO: Continuity handling is a bit odd in libsigrok. */ break; case 6: /* Degree Celsius */ analog.unit = SR_UNIT_CELSIUS; break; - case 7: /* Capacity */ + case 7: /* Capacity */ analog.unit = SR_UNIT_FARAD; break; case 8: /* Current DC */ analog.unit = SR_UNIT_AMPERE; analog.mqflags |= SR_MQFLAG_DC; break; - case 9: /* Current AC */ + case 9: /* Current AC */ analog.unit = SR_UNIT_AMPERE; analog.mqflags |= SR_MQFLAG_AC; - if (devc->type >= 3) analog.mqflags |= SR_MQFLAG_RMS; + if (devc->type >= 3) + analog.mqflags |= SR_MQFLAG_RMS; break; - case 0xA:/* Current TRMS, only type 5 */ + case 0xa: /* Current TRMS, only type 5 */ analog.unit = SR_UNIT_AMPERE; analog.mqflags |= (SR_MQFLAG_AC | SR_MQFLAG_DC | SR_MQFLAG_RMS); break; - case 0x0B:/* Diode */ + case 0xb: /* Diode */ analog.unit = SR_UNIT_VOLT; analog.mqflags |= (SR_MQFLAG_DIODE | SR_MQFLAG_DC); break; default: - sr_err("unknown mmode 0x%02x", mmode); + sr_err("Unknown mmode: 0x%02x.", mmode); break; } @@ -206,18 +253,18 @@ static void nma_process_line(const struct sr_dev_inst *sdi) devstat = xgittoint(devc->buf[11]); switch (devstat) { - case 1: // Normal measurement + case 1: /* Normal measurement */ break; - case 2: // Input loop (limit, reference values) + case 2: /* Input loop (limit, reference values) */ break; - case 3: // TRANS/SENS + case 3: /* TRANS/SENS */ break; - case 4: // Error - sr_err("Device error. Fuse?"); // TODO: Wirklich abbrechen??? + case 4: /* Error */ + sr_err("Device error. Fuse?"); /* TODO: Really abort? */ devc->buflen = 0; - return; // Cannot continue. + return; /* Cannot continue. */ default: - sr_err("Unknown device status 0x02x", devstat); + sr_err("Unknown device status: 0x%02x", devstat); break; } @@ -225,10 +272,12 @@ static void nma_process_line(const struct sr_dev_inst *sdi) /* 12, 13 */ flags = (xgittoint(devc->buf[12]) << 8) | xgittoint(devc->buf[13]); /* 0x80: PRINT TODO: Stop polling when discovered? */ - /* 0x40: EXTR */ + /* 0x40: EXTR */ if (analog.mq == SR_MQ_CONTINUITY) { - if (flags & 0x20) value = 1.0; /* Beep */ - else value = 0.0; + if (flags & 0x20) + value = 1.0; /* Beep */ + else + value = 0.0; } /* 0x10: AVG */ /* 0x08: Diode */ @@ -240,66 +289,67 @@ static void nma_process_line(const struct sr_dev_inst *sdi) /* 14, 15 */ flags = (xgittoint(devc->buf[14]) << 8) | xgittoint(devc->buf[15]); - if (!(flags & 0x80)) /* MAN Manual range */ + if (!(flags & 0x80)) /* MAN: Manual range */ analog.mqflags |= SR_MQFLAG_AUTORANGE; - if (flags & 0x40)/* LOBAT1 Low battery,measurement still within specs.*/ + if (flags & 0x40) /* LOBATT1: Low battery, measurement still within specs */ devc->lowbatt = 1; - /* 0x20: PEAK */ - /* 0x10: COUNT */ - if (flags & 0x08) // HOLD + /* 0x20: PEAK */ + /* 0x10: COUNT */ + if (flags & 0x08) /* HOLD */ analog.mqflags |= SR_MQFLAG_HOLD; /* 0x04: LIMIT */ - if (flags & 0x02) // MAX + if (flags & 0x02) /* MAX */ analog.mqflags |= SR_MQFLAG_MAX; - if (flags & 0x01) // MIN + if (flags & 0x01) /* MIN */ analog.mqflags |= SR_MQFLAG_MIN; /* 16, 17 */ flags = (xgittoint(devc->buf[16]) << 8) | xgittoint(devc->buf[17]); /* 0xe0: undefined */ - if (flags & 0x10) { /* LOBATT2 Low battery, measurement inaccurate */ + if (flags & 0x10) { /* LOBATT2: Low battery, measurement inaccurate */ devc->lowbatt = 2; sr_warn("Low battery, measurement quality degraded!"); } /* 0x08: SCALED */ /* 0x04: RATE (=lower resolution, allows higher rata rate up to 10/s. */ - /* 0x02: Current Clamp */ - if (flags & 0x01) { /* dB */ + /* 0x02: Current clamp */ + if (flags & 0x01) { /* dB */ + /* + * TODO: The Norma has an adjustable dB reference value. If + * changed from default, this is not correct. + */ if (analog.unit == SR_UNIT_VOLT) analog.unit = SR_UNIT_DECIBEL_VOLT; - /* TODO: The Norma has an adjustable dB reference value. If - * changed from default, this is not correct. */ else analog.unit = SR_UNIT_UNITLESS; } /* 18, 19 */ - /* flags = (xgittoint(devc->buf[18]) << 8) | xgittoint(devc->buf[19]);*/ + /* flags = (xgittoint(devc->buf[18]) << 8) | xgittoint(devc->buf[19]); */ /* 0x80: Undefined. */ /* 0x40: Remote mode, keyboard locked */ /* 0x38: Undefined. */ - /* 0x04: MIN>MAX */ + /* 0x04: MIN > MAX */ /* 0x02: Measured value < Min */ /* 0x01: Measured value > Max */ - /* 4: Flags. Evaluating this after setting value! */ + /* 4: Flags. Evaluating this after setting value! */ flags = xgittoint(devc->buf[4]); - if (flags & 0x04) { // Invalid value + if (flags & 0x04) /* Invalid value */ value = NAN; - } - else if (flags & 0x01) { // Overload + else if (flags & 0x01) /* Overload */ value = INFINITY; - } - if (flags & 0x02) { // Duplicate value, has been sent before. + if (flags & 0x02) { /* Duplicate value, has been sent before. */ sr_spew("Duplicate value, dismissing!"); devc->buflen = 0; return; } - sr_spew("range=%d/scale=%f/value=%f",range,(double)scale,(double)value); + sr_spew("range=%d/scale=%f/value=%f", range, + (double)scale, (double)value); - /* Finish and send packet */ - analog.probes = sdi->probes; + /* Finish and send packet. */ + analog.channels = sdi->channels; analog.num_samples = 1; analog.data = &value; @@ -308,12 +358,11 @@ static void nma_process_line(const struct sr_dev_inst *sdi) packet.payload = &analog; sr_session_send(devc->cb_data, &packet); - /* Finish processing */ + /* Finish processing. */ devc->num_samples++; devc->buflen = 0; } - SR_PRIV int norma_dmm_receive_data(int fd, int revents, void *cb_data) { struct sr_dev_inst *sdi; @@ -321,6 +370,7 @@ SR_PRIV int norma_dmm_receive_data(int fd, int revents, void *cb_data) struct sr_serial_dev_inst *serial; int len; gboolean terminating; + gdouble elapsed_s; (void)fd; @@ -333,15 +383,17 @@ SR_PRIV int norma_dmm_receive_data(int fd, int revents, void *cb_data) serial = sdi->conn; if (revents == G_IO_IN) { /* Serial data arrived. */ - while(NMADMM_BUFSIZE - devc->buflen - 1 > 0) { + while (NMADMM_BUFSIZE - devc->buflen - 1 > 0) { len = serial_read(serial, devc->buf + devc->buflen, 1); if (len < 1) break; devc->buflen += len; *(devc->buf + devc->buflen) = '\0'; if (*(devc->buf + devc->buflen - 1) == '\n') { - /* TODO: According to specs, should be \r, but - * then we'd have to get rid of the \n */ + /* + * TODO: According to specs, should be \r, but + * then we'd have to get rid of the \n. + */ devc->last_req_pending = FALSE; nma_process_line(sdi); break; @@ -349,7 +401,7 @@ SR_PRIV int norma_dmm_receive_data(int fd, int revents, void *cb_data) } } - // If number of samples or time limit reached, stop aquisition. + /* If number of samples or time limit reached, stop acquisition. */ terminating = FALSE; if (devc->limit_samples && (devc->num_samples >= devc->limit_samples)) { sdi->driver->dev_acquisition_stop(sdi, cb_data); @@ -357,14 +409,14 @@ SR_PRIV int norma_dmm_receive_data(int fd, int revents, void *cb_data) } if (devc->limit_msec) { - gdouble elapsed_s = g_timer_elapsed(devc->elapsed_msec, NULL); - if ((elapsed_s * 1000) >= devc->limit_msec) { + elapsed_s = g_timer_elapsed(devc->elapsed_msec, NULL); + if ((elapsed_s * 1000) >= devc->limit_msec) { sdi->driver->dev_acquisition_stop(sdi, cb_data); terminating = TRUE; } } - // Request next package + /* Request next package. */ if (!terminating && !devc->last_req_pending) { if (nma_send_req(sdi, NMADMM_REQ_STATUS, NULL) != SR_OK) return FALSE; @@ -372,41 +424,3 @@ SR_PRIV int norma_dmm_receive_data(int fd, int revents, void *cb_data) return TRUE; } - - -static int nma_send_req(const struct sr_dev_inst *sdi, enum nmadmm_req_t req, - char* params) -{ - struct sr_serial_dev_inst *serial; - struct dev_context *devc; - char buf[NMADMM_BUFSIZE]; - int len; - - - if (!sdi || !(serial = sdi->conn) || !(devc = sdi->priv)) - return SR_ERR_BUG; - - len = snprintf(buf, sizeof(buf), "%s%s\r\n", - nmadmm_requests[req].reqstr, params?params:""); - - sr_spew("Sending request: '%s'", buf); - - devc->last_req = req; - devc->last_req_pending = TRUE; - - if (serial_write(serial, buf, len) == -1) { - sr_err("Unable to send request: %d %s.", - errno, strerror(errno)); - devc->last_req_pending = FALSE; - return SR_ERR; - } - - return SR_OK; -} - - -SR_PRIV const struct nmadmm_req nmadmm_requests[] = { - { NMADMM_REQ_IDN, "IDN?"}, - { NMADMM_REQ_IDN, "STATUS?"}, - { 0, NULL } -};