X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=src%2Fhardware%2Funi-t-dmm%2Fprotocol.c;h=94abb16bc8ae1277d07d5bf8511999803469c8e6;hb=755793e991c4d429f99254f23008bfddb89d8e00;hp=8355382fb466f6f49f5d0fa7b53d0217747a1077;hpb=f3cde30904b2bc5ac5b1782d5e65d1ec8ce60ed6;p=libsigrok.git diff --git a/src/hardware/uni-t-dmm/protocol.c b/src/hardware/uni-t-dmm/protocol.c index 8355382f..94abb16b 100644 --- a/src/hardware/uni-t-dmm/protocol.c +++ b/src/hardware/uni-t-dmm/protocol.c @@ -14,18 +14,16 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * along with this program; if not, see . */ +#include #include #include -#include "libsigrok.h" +#include #include "libsigrok-internal.h" #include "protocol.h" -extern struct dmm_info udmms[]; - /* * Driver for various UNI-T multimeters (and rebranded ones). * @@ -53,39 +51,48 @@ extern struct dmm_info udmms[]; * f1 d1 00 00 00 00 00 00 (1 data byte, 0xd1) */ -static void decode_packet(struct sr_dev_inst *sdi, int dmm, const uint8_t *buf, - void *info) +static void decode_packet(struct sr_dev_inst *sdi, const uint8_t *buf) { struct dev_context *devc; + struct dmm_info *dmm; 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 floatval; + void *info; int ret; devc = sdi->priv; - memset(&analog, 0, sizeof(struct sr_datafeed_analog)); + dmm = (struct dmm_info *)sdi->driver; + /* Note: digits/spec_digits will be overridden by the DMM parsers. */ + sr_analog_init(&analog, &encoding, &meaning, &spec, 0); + info = g_malloc(dmm->info_size); /* Parse the protocol packet. */ - ret = udmms[dmm].packet_parse(buf, &floatval, &analog, info); + ret = dmm->packet_parse(buf, &floatval, &analog, info); if (ret != SR_OK) { sr_dbg("Invalid DMM packet, ignoring."); + g_free(info); return; } /* If this DMM needs additional handling, call the resp. function. */ - if (udmms[dmm].dmm_details) - udmms[dmm].dmm_details(&analog, info); + if (dmm->dmm_details) + dmm->dmm_details(&analog, info); + + g_free(info); /* Send a sample packet with one analog value. */ - analog.channels = sdi->channels; + analog.meaning->channels = sdi->channels; analog.num_samples = 1; analog.data = &floatval; packet.type = SR_DF_ANALOG; packet.payload = &analog; - sr_session_send(devc->cb_data, &packet); + sr_session_send(sdi, &packet); - /* Increase sample count. */ - devc->num_samples++; + sr_sw_limits_update_samples_read(&devc->limits, 1); } static int hid_chip_init(struct sr_dev_inst *sdi, uint16_t baudrate) @@ -95,8 +102,7 @@ static int hid_chip_init(struct sr_dev_inst *sdi, uint16_t baudrate) struct sr_usb_dev_inst *usb; usb = sdi->conn; - - /* Detach kernel drivers which grabbed this device (if any). */ + if (libusb_kernel_driver_active(usb->devhdl, 0) == 1) { ret = libusb_detach_kernel_driver(usb->devhdl, 0); if (ret < 0) { @@ -104,18 +110,13 @@ static int hid_chip_init(struct sr_dev_inst *sdi, uint16_t baudrate) libusb_error_name(ret)); return SR_ERR; } - sr_dbg("Successfully detached kernel driver."); - } else { - sr_dbg("No need to detach a kernel driver."); } - /* Claim interface 0. */ if ((ret = libusb_claim_interface(usb->devhdl, 0)) < 0) { sr_err("Failed to claim interface 0: %s.", libusb_error_name(ret)); return SR_ERR; } - sr_dbg("Successfully claimed interface 0."); /* Set data for the HID feature report (e.g. baudrate). */ buf[0] = baudrate & 0xff; /* Baudrate, LSB */ @@ -151,8 +152,6 @@ static int hid_chip_init(struct sr_dev_inst *sdi, uint16_t baudrate) return SR_ERR; } - sr_dbg("Successfully sent initial HID feature report."); - return SR_OK; } @@ -171,20 +170,22 @@ static void log_dmm_packet(const uint8_t *buf) buf[7], buf[8], buf[9], buf[10], buf[11], buf[12], buf[13]); } -static int get_and_handle_data(struct sr_dev_inst *sdi, int dmm, void *info) +static int get_and_handle_data(struct sr_dev_inst *sdi) { struct dev_context *devc; + struct dmm_info *dmm; uint8_t buf[CHUNK_SIZE], *pbuf; int i, ret, len, num_databytes_in_chunk; struct sr_usb_dev_inst *usb; devc = sdi->priv; + dmm = (struct dmm_info *)sdi->driver; usb = sdi->conn; pbuf = devc->protocol_buf; /* On the first run, we need to init the HID chip. */ if (devc->first_run) { - if ((ret = hid_chip_init(sdi, udmms[dmm].baudrate)) != SR_OK) { + if ((ret = hid_chip_init(sdi, dmm->baudrate)) != SR_OK) { sr_err("HID chip init failed: %d.", ret); return SR_ERR; } @@ -236,38 +237,39 @@ static int get_and_handle_data(struct sr_dev_inst *sdi, int dmm, void *info) num_databytes_in_chunk = buf[0] & 0x0f; for (i = 0; i < num_databytes_in_chunk; i++, devc->buflen++) { pbuf[devc->buflen] = buf[1 + i]; - if ((udmms[dmm].packet_parse == sr_es519xx_19200_14b_parse) || - (udmms[dmm].packet_parse == sr_ut71x_parse)) { + if ((dmm->packet_parse == sr_es519xx_19200_14b_parse) || + (dmm->packet_parse == sr_es519xx_19200_11b_parse) || + (dmm->packet_parse == sr_es519xx_2400_11b_parse) || + (dmm->packet_parse == sr_ut71x_parse)) { /* Mask off the parity bit. */ pbuf[devc->buflen] &= ~(1 << 7); } } /* Now look for packets in that data. */ - while ((devc->buflen - devc->bufoffset) >= udmms[dmm].packet_size) { - if (udmms[dmm].packet_valid(pbuf + devc->bufoffset)) { + while ((devc->buflen - devc->bufoffset) >= dmm->packet_size) { + if (dmm->packet_valid(pbuf + devc->bufoffset)) { log_dmm_packet(pbuf + devc->bufoffset); - decode_packet(sdi, dmm, pbuf + devc->bufoffset, info); - devc->bufoffset += udmms[dmm].packet_size; + decode_packet(sdi, pbuf + devc->bufoffset); + devc->bufoffset += dmm->packet_size; } else { devc->bufoffset++; } } /* Move remaining bytes to beginning of buffer. */ - for (i = 0; i < devc->buflen - devc->bufoffset; i++) - pbuf[i] = pbuf[devc->bufoffset + i]; + if (devc->bufoffset < devc->buflen) + memmove(pbuf, pbuf + devc->bufoffset, devc->buflen - devc->bufoffset); devc->buflen -= devc->bufoffset; return SR_OK; } -static int receive_data(int fd, int revents, int dmm, void *info, void *cb_data) +SR_PRIV int uni_t_dmm_receive_data(int fd, int revents, void *cb_data) { int ret; struct sr_dev_inst *sdi; struct dev_context *devc; - int64_t time_ms; (void)fd; (void)revents; @@ -275,52 +277,12 @@ static int receive_data(int fd, int revents, int dmm, void *info, void *cb_data) sdi = cb_data; devc = sdi->priv; - if ((ret = get_and_handle_data(sdi, dmm, info)) != SR_OK) + if ((ret = get_and_handle_data(sdi)) != SR_OK) return FALSE; /* Abort acquisition if we acquired enough samples. */ - 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); - } - - if (devc->limit_msec) { - time_ms = (g_get_monotonic_time() - devc->starttime) / 1000; - if (time_ms > (int64_t)devc->limit_msec) { - sr_info("Requested time limit reached."); - sdi->driver->dev_acquisition_stop(sdi, cb_data); - return TRUE; - } - } + if (sr_sw_limits_check(&devc->limits)) + sr_dev_acquisition_stop(sdi); return TRUE; } - -#define RECEIVE_DATA(ID_UPPER, DMM_DRIVER) \ -SR_PRIV int receive_data_##ID_UPPER(int fd, int revents, void *cb_data) { \ - struct DMM_DRIVER##_info info; \ - return receive_data(fd, revents, ID_UPPER, &info, cb_data); } - -/* Driver-specific receive_data() wrappers */ -RECEIVE_DATA(TECPEL_DMM_8061, fs9721) -RECEIVE_DATA(UNI_T_UT372, ut372) -RECEIVE_DATA(UNI_T_UT60A, fs9721) -RECEIVE_DATA(UNI_T_UT60E, fs9721) -RECEIVE_DATA(UNI_T_UT60G, es519xx) -RECEIVE_DATA(UNI_T_UT61B, fs9922) -RECEIVE_DATA(UNI_T_UT61C, fs9922) -RECEIVE_DATA(UNI_T_UT61D, fs9922) -RECEIVE_DATA(UNI_T_UT61E, es519xx) -RECEIVE_DATA(UNI_T_UT71A, ut71x) -RECEIVE_DATA(UNI_T_UT71B, ut71x) -RECEIVE_DATA(UNI_T_UT71C, ut71x) -RECEIVE_DATA(UNI_T_UT71D, ut71x) -RECEIVE_DATA(UNI_T_UT71E, ut71x) -RECEIVE_DATA(VOLTCRAFT_VC820, fs9721) -RECEIVE_DATA(VOLTCRAFT_VC830, fs9922) -RECEIVE_DATA(VOLTCRAFT_VC840, fs9721) -RECEIVE_DATA(VOLTCRAFT_VC920, ut71x) -RECEIVE_DATA(VOLTCRAFT_VC940, ut71x) -RECEIVE_DATA(VOLTCRAFT_VC960, ut71x) -RECEIVE_DATA(TENMA_72_7745, es519xx) -RECEIVE_DATA(TENMA_72_7750, es519xx)