From: Matthias Heidbrink Date: Wed, 5 Feb 2014 13:40:40 +0000 (+0100) Subject: gmc-mh-1x-2x: Cleanup, docs, minor fixes. X-Git-Tag: libsigrok-0.3.0~146 X-Git-Url: https://sigrok.org/gitaction?a=commitdiff_plain;h=6392d5992b12cf2b51d7f6704c4d23f3a2d4a294;p=libsigrok.git gmc-mh-1x-2x: Cleanup, docs, minor fixes. --- diff --git a/hardware/gmc-mh-1x-2x/api.c b/hardware/gmc-mh-1x-2x/api.c index 197522a2..02273ac5 100644 --- a/hardware/gmc-mh-1x-2x/api.c +++ b/hardware/gmc-mh-1x-2x/api.c @@ -17,16 +17,21 @@ * along with this program. If not, see . */ +/** @file + * Gossen Metrawatt Metrahit 1x/2x drivers + * @private + */ + #include #include "protocol.h" /* Serial communication parameters for Metrahit 1x/2x with 'RS232' adaptor */ #define SERIALCOMM_1X_RS232 "8228/6n1/dtr=1/rts=1/flow=0" /* =8192, closer with divider */ #define SERIALCOMM_2X_RS232 "9600/6n1/dtr=1/rts=1/flow=0" +#define SERIALCOMM_2X "9600/8n1/dtr=1/rts=1/flow=0" #define VENDOR_GMC "Gossen Metrawatt" SR_PRIV struct sr_dev_driver gmc_mh_1x_2x_rs232_driver_info; -static struct sr_dev_driver *di = &gmc_mh_1x_2x_rs232_driver_info; static const int32_t hwopts[] = { SR_CONF_CONN, @@ -35,14 +40,23 @@ static const int32_t hwopts[] = { static const int32_t hwcaps[] = { SR_CONF_MULTIMETER, + SR_CONF_THERMOMETER, /**< All GMC 1x/2x multimeters seem to support this */ SR_CONF_LIMIT_SAMPLES, SR_CONF_LIMIT_MSEC, SR_CONF_CONTINUOUS, }; +/* TODO: + * - For the 29S SR_CONF_ENERGYMETER, too. + * - SR_CONF_PATTERN_MODE for some 2x devices + * - SR_CONF_DATALOG for 22M, 26M, 29S and storage adaptors. + * Need to implement device-specific lists. + */ + +/** Init driver gmc_mh_1x_2x_rs232. */ static int init(struct sr_context *sr_ctx) { - return std_init(sr_ctx, di, LOG_PREFIX); + return std_init(sr_ctx, &gmc_mh_1x_2x_rs232_driver_info, LOG_PREFIX); } /** @@ -137,7 +151,7 @@ static GSList *scan(GSList *options) gboolean serialcomm_given; devices = NULL; - drvc = di->priv; + drvc = (&gmc_mh_1x_2x_rs232_driver_info)->priv; drvc->instances = NULL; conn = serialcomm = NULL; model = METRAHIT_NONE; @@ -206,7 +220,7 @@ static GSList *scan(GSList *options) sdi->conn = serial; sdi->priv = devc; - sdi->driver = di; + sdi->driver = &gmc_mh_1x_2x_rs232_driver_info; if (!(probe = sr_probe_new(0, SR_PROBE_ANALOG, TRUE, "P1"))) return NULL; sdi->probes = g_slist_append(sdi->probes, probe); @@ -219,12 +233,12 @@ static GSList *scan(GSList *options) static GSList *dev_list(void) { - return ((struct drv_context *)(di->priv))->instances; + return ((struct drv_context *)(gmc_mh_1x_2x_rs232_driver_info.priv))->instances; } static int dev_clear(void) { - return std_dev_clear(di, NULL); + return std_dev_clear(&gmc_mh_1x_2x_rs232_driver_info, NULL); } static int dev_close(struct sr_dev_inst *sdi) @@ -250,19 +264,27 @@ static int cleanup(void) return dev_clear(); } -/** TODO */ +/** Get value of configuration item */ static int config_get(int key, GVariant **data, const struct sr_dev_inst *sdi, const struct sr_probe_group *probe_group) { int ret; + ret = SR_OK; + struct dev_context *devc; - (void)sdi; - (void)data; (void)probe_group; + if (!sdi || !(devc = sdi->priv)) + return SR_ERR_ARG; + ret = SR_OK; switch (key) { - /* TODO */ + case SR_CONF_LIMIT_SAMPLES: + *data = g_variant_new_uint64(devc->limit_samples); + break; + case SR_CONF_LIMIT_MSEC: + *data = g_variant_new_uint64(devc->limit_msec); + break; default: return SR_ERR_NA; } diff --git a/hardware/gmc-mh-1x-2x/protocol.c b/hardware/gmc-mh-1x-2x/protocol.c index 66a73e9f..32425b4e 100644 --- a/hardware/gmc-mh-1x-2x/protocol.c +++ b/hardware/gmc-mh-1x-2x/protocol.c @@ -17,6 +17,11 @@ * along with this program. If not, see . */ +/** @file + * Gossen Metrawatt Metrahit 1x/2x drivers + * @private + */ + #include #include #include "protocol.h" @@ -358,7 +363,7 @@ static void decode_ctmv_2x(uint8_t ctmv, struct dev_context *devc) if (ctmv >= 0x02) { devc->mqflags |= SR_MQFLAG_AC; if (devc->model >= METRAHIT_24S) - devc->model |= SR_MQFLAG_RMS; + devc->mqflags |= SR_MQFLAG_RMS; } break; case 0x04: /* 00100 mA DC */ @@ -384,10 +389,12 @@ static void decode_ctmv_2x(uint8_t ctmv, struct dev_context *devc) devc->unit = SR_UNIT_FARAD; devc->scale *= 0.1; break; - case 0x0a: /* 01010 dB */ + case 0x0a: /* 01010 dBV */ devc->mq = SR_MQ_VOLTAGE; devc->unit = SR_UNIT_DECIBEL_VOLT; devc->mqflags |= SR_MQFLAG_AC; + if (devc->model >= METRAHIT_24S) + devc->mqflags |= SR_MQFLAG_RMS; break; case 0x0b: /* 01011 Hz U ACDC */ case 0x0c: /* 01100 Hz U AC */ @@ -398,8 +405,9 @@ static void decode_ctmv_2x(uint8_t ctmv, struct dev_context *devc) devc->mqflags |= SR_MQFLAG_DC; break; case 0x0d: /* 01101 W on power, mA range (29S only) */ + devc->scale *= 0.001; + /* Fall through! */ case 0x0e: /* 01110 W on power, A range (29S only) */ - /* TODO: Differences between Send Mode and bidir protocol here */ devc->mq = SR_MQ_POWER; devc->unit = SR_UNIT_WATT; break; @@ -409,7 +417,6 @@ static void decode_ctmv_2x(uint8_t ctmv, struct dev_context *devc) if (ctmv == 0x0f) { devc->mq = SR_MQ_VOLTAGE; devc->mqflags |= SR_MQFLAG_DIODE; - devc->scale *= 0.1; } else { devc->mq = SR_MQ_CONTINUITY; devc->scale *= 0.00001; @@ -476,9 +483,9 @@ static void decode_ctmv_2x(uint8_t ctmv, struct dev_context *devc) } /** - * Decode range/sign/acdc byte special chars, Metrahit 2x. + * Decode range/sign/acdc byte special chars, Metrahit 2x, table TR. * - * @param[in] rs Rance/sign byte. + * @param[in] rs Range/sign byte. */ static void decode_rs_2x(uint8_t rs, struct dev_context *devc) { @@ -486,7 +493,7 @@ static void decode_rs_2x(uint8_t rs, struct dev_context *devc) /* Sign */ if (((devc->scale > 0) && (rs & 0x08)) || - ((devc->scale < 0) && !(rs & 0x08))) + ((devc->scale < 0) && !(rs & 0x08))) devc->scale *= -1.0; /* Range */ @@ -497,17 +504,13 @@ static void decode_rs_2x(uint8_t rs, struct dev_context *devc) devc->scale *= pow(10.0, -3); else if (devc->vmains_29S) devc->scale *= pow(10.0, range - 2); - else if(devc->mqflags & SR_MQFLAG_AC) + else devc->scale *= pow(10.0, range - 6); - else /* "Undocumented feature": Between AC and DC - scaling differs by 1. */ - devc->scale *= pow(10.0, range - 5); break; case SR_MQ_CURRENT: - if (devc->scale1000 == -1) - devc->scale *= pow(10.0, range - 5); - else - devc->scale *= pow(10.0, range - 4); + if (devc->scale1000 != -1) /* uA, mA */ + range += 1;/* mA and A ranges differ by 10^4, not 10^3!*/ + devc->scale *= pow(10.0, range - 6); break; case SR_MQ_RESISTANCE: devc->scale *= pow(10.0, range - 3); @@ -521,6 +524,8 @@ static void decode_rs_2x(uint8_t rs, struct dev_context *devc) devc->scale *= pow(10.0, - 2); break; case SR_MQ_CAPACITANCE: + if (range == 7) + range -= 1; /* Same value as range 6 */ devc->scale *= pow(10.0, range - 13); break; /* TODO: 29S Mains measurements. */ @@ -593,7 +598,7 @@ static void send_value(struct sr_dev_inst *sdi) devc->num_samples++; } -/** Process 6-byte data message, Metrahit 1x/2x. */ +/** Process 6-byte data message, Metrahit 1x/2x send mode. */ static void process_msg_dta_6(struct sr_dev_inst *sdi) { struct dev_context *devc; @@ -608,8 +613,10 @@ static void process_msg_dta_6(struct sr_dev_inst *sdi) decode_rs_16(bc(devc->buf[0]), devc); else if (devc->model < METRAHIT_2X) decode_rs_18(bc(devc->buf[0]), devc); - else + else { decode_rs_2x(bc(devc->buf[0]), devc); + devc->scale *= 10; /* Compensate for format having only 5 digits, decode_rs_2x() assumes 6. */ + } /* Bytes 1-5, digits (ls first). */ for (cnt = 0; cnt < 5; cnt++) { @@ -622,7 +629,8 @@ static void process_msg_dta_6(struct sr_dev_inst *sdi) } devc->value += pow(10.0, cnt) * dgt; } - sr_spew("process_msg_dta_6() value=%f scale=%f scalet=%d", + + sr_spew("process_msg_dta_6() value=%f scale=%f scale1000=%d", devc->value, devc->scale, devc->scale1000); if (devc->value != NAN) devc->value *= devc->scale * pow(1000.0, devc->scale1000); @@ -678,7 +686,10 @@ static void process_msg_inf_10(struct sr_dev_inst *sdi) /* Now decode numbers */ for (cnt = 0; cnt < 5; cnt++) { dgt = bc(devc->buf[5 + cnt]); - if (dgt >= 10) { /* Overload */ + if (dgt == 11) { /* Empty digit */ + dgt = 0; + } + else if (dgt >= 12) { /* Overload */ devc->value = NAN; devc->scale = 1.0; break; @@ -907,9 +918,9 @@ SR_PRIV int gmc_decode_model_sm(uint8_t mcode) case 0x0f: /* 1111b */ return METRAHIT_24S; case 0x05: /* 0101b */ - return METRAHIT_25SM; + return METRAHIT_25S; case 0x01: /* 0001b */ - return METRAHIT_26S; + return METRAHIT_26SM; case 0x0c: /* 1100b */ return METRAHIT_28S; case 0x0e: /* 1110b */ @@ -920,16 +931,15 @@ SR_PRIV int gmc_decode_model_sm(uint8_t mcode) } } -/** - * Decode model in bidirectional mode. +/** Convert GMC model code in bidirectional mode to sigrok-internal one. * - * @param[in] mcode Model code. + * @param[in] mcode Model code. * - * @return Model code. + * @return Model code. */ -SR_PRIV int gmc_decode_model_bidi(uint8_t mcode) +SR_PRIV int gmc_decode_model_bd(uint8_t mcode) { - switch (mcode) { + switch (mcode & 0x1f) { case 2: return METRAHIT_22SM; case 3: @@ -937,9 +947,9 @@ SR_PRIV int gmc_decode_model_bidi(uint8_t mcode) case 4: return METRAHIT_24S; case 5: - return METRAHIT_25SM; + return METRAHIT_25S; case 1: - return METRAHIT_26S; + return METRAHIT_26SM; case 12: return METRAHIT_28S; case 14: @@ -950,6 +960,12 @@ SR_PRIV int gmc_decode_model_bidi(uint8_t mcode) } } +/** Convert sigrok-internal model code to string. + * + * @param[in] mcode Model code. + * + * @return Model code string. + */ SR_PRIV const char *gmc_model_str(enum model mcode) { switch (mcode) { @@ -975,10 +991,10 @@ SR_PRIV const char *gmc_model_str(enum model mcode) return "METRAHit 23S"; case METRAHIT_24S: return "METRAHit 24S"; - case METRAHIT_25SM: - return "METRAHit 25S/M"; - case METRAHIT_26S: - return "METRAHit 26S"; + case METRAHIT_25S: + return "METRAHit 25S"; + case METRAHIT_26SM: + return "METRAHit 26S/M"; case METRAHIT_28S: return "METRAHit 28S"; case METRAHIT_29S: diff --git a/hardware/gmc-mh-1x-2x/protocol.h b/hardware/gmc-mh-1x-2x/protocol.h index 9d742e3c..8f1c7c15 100644 --- a/hardware/gmc-mh-1x-2x/protocol.h +++ b/hardware/gmc-mh-1x-2x/protocol.h @@ -17,6 +17,11 @@ * along with this program. If not, see . */ +/** @file + * Gossen Metrawatt Metrahit 1x/2x drivers + * @private + */ + #ifndef LIBSIGROK_HARDWARE_GMC_MH_1X_2X_PROTOCOL_H #define LIBSIGROK_HARDWARE_GMC_MH_1X_2X_PROTOCOL_H @@ -36,7 +41,7 @@ #define MSGID_DTA 0x20 /**< Start of data message, displayed, averaged */ #define MSGID_DATA 0x30 /**< Data byte in message */ -#define MSGC_MASK 0x0f /**< Mask to get message byte contents */ +#define MSGC_MASK 0x0f /**< Mask to get message byte contents in send mode */ #define MSGSRC_MASK 0xc0 /**< Mask to get bits related to message source */ @@ -63,24 +68,12 @@ enum model { METRAHIT_22SM = 22, METRAHIT_23S = 23, METRAHIT_24S = 24, - METRAHIT_25SM = 25, - METRAHIT_26S = 26, + METRAHIT_25S = 25, + METRAHIT_26SM = 26, METRAHIT_28S = 28, METRAHIT_29S = 29, }; -/** Convert GMC model code in send mode to sigrok-internal one. */ -SR_PRIV int gmc_decode_model_sm(uint8_t mcode); - -/** - * Convert GMC model code in bidirectional mode to sigrok-internal one. - * - * @param[in] mcode Model code. - * - * @return Model code. - */ -SR_PRIV int gmc_decode_model_bidi(uint8_t mcode); - /** Get model string from sigrok-internal model code. */ SR_PRIV const char *gmc_model_str(enum model mcode); @@ -116,5 +109,6 @@ struct dev_context { }; SR_PRIV int gmc_mh_1x_2x_receive_data(int fd, int revents, void *cb_data); +SR_PRIV int gmc_decode_model_sm(uint8_t mcode); #endif