X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=hardware%2Fmic-985xx%2Fprotocol.c;h=15368065a6d3145c29754da7bbc0f0d74d83e442;hb=4472867a9f17101c7849f26fff9dcce7010f7ac7;hp=ed1aae7ad7b8587ad209b75a3b047e08542d0c6c;hpb=0cd8e23140612703406a57316bb0a507fb8f1994;p=libsigrok.git diff --git a/hardware/mic-985xx/protocol.c b/hardware/mic-985xx/protocol.c index ed1aae7a..15368065 100644 --- a/hardware/mic-985xx/protocol.c +++ b/hardware/mic-985xx/protocol.c @@ -20,8 +20,6 @@ #include "protocol.h" -#define PACKET_SIZE 10 - static int mic_send(struct sr_serial_dev_inst *serial, const char *cmd) { int ret; @@ -44,7 +42,18 @@ static int mic_cmd_set_realtime_mode(struct sr_serial_dev_inst *serial) return mic_send(serial, "S 1 M 2 32 3\r"); } -static gboolean packet_valid(const uint8_t *buf) +SR_PRIV gboolean packet_valid_temp(const uint8_t *buf) +{ + if (buf[0] != 'v' || buf[1] != ' ' || buf[5] != '\r') + return FALSE; + + if (!isdigit(buf[2]) || !isdigit(buf[3]) || !isdigit(buf[4])) + return FALSE; + + return TRUE; +} + +SR_PRIV gboolean packet_valid_temp_hum(const uint8_t *buf) { if (buf[0] != 'v' || buf[1] != ' ' || buf[5] != ' ' || buf[9] != '\r') return FALSE; @@ -58,11 +67,12 @@ static gboolean packet_valid(const uint8_t *buf) return TRUE; } -static int packet_parse(const char *buf, float *temp, float *humidity) +static int packet_parse(const char *buf, int idx, float *temp, float *humidity) { char tmp[4]; - /* Packet format: "v ttt hhh\r". */ + /* Packet format MIC98581: "v ttt\r". */ + /* Packet format MIC98583: "v ttt hhh\r". */ /* TODO: Sanity check on buf. For now we assume well-formed ASCII. */ @@ -71,8 +81,10 @@ static int packet_parse(const char *buf, float *temp, float *humidity) strncpy((char *)&tmp, &buf[2], 3); *temp = g_ascii_strtoull((const char *)&tmp, NULL, 10) / 10; - strncpy((char *)&tmp, &buf[6], 3); - *humidity = g_ascii_strtoull((const char *)&tmp, NULL, 10) / 10; + if (mic_devs[idx].has_humidity) { + strncpy((char *)&tmp, &buf[6], 3); + *humidity = g_ascii_strtoull((const char *)&tmp, NULL, 10) / 10; + } return SR_OK; } @@ -90,12 +102,15 @@ static int handle_packet(const uint8_t *buf, struct sr_dev_inst *sdi, int idx) devc = sdi->priv; - ret = packet_parse((const char *)buf, &temperature, &humidity); + ret = packet_parse((const char *)buf, idx, &temperature, &humidity); if (ret < 0) { sr_err("Failed to parse packet."); return SR_ERR; } + /* Clear 'analog', otherwise it'll contain random garbage. */ + memset(&analog, 0, sizeof(struct sr_datafeed_analog)); + /* Common values for both probes. */ packet.type = SR_DF_ANALOG; packet.payload = &analog; @@ -112,14 +127,16 @@ static int handle_packet(const uint8_t *buf, struct sr_dev_inst *sdi, int idx) g_slist_free(l); /* Humidity. */ - l = g_slist_copy(sdi->probes); - l = g_slist_remove_link(l, g_slist_nth(l, 0)); - analog.probes = l; - analog.mq = SR_MQ_RELATIVE_HUMIDITY; - analog.unit = SR_UNIT_PERCENTAGE; - analog.data = &humidity; - sr_session_send(devc->cb_data, &packet); - g_slist_free(l); + if (mic_devs[idx].has_humidity) { + l = g_slist_copy(sdi->probes); + l = g_slist_remove_link(l, g_slist_nth(l, 0)); + analog.probes = l; + analog.mq = SR_MQ_RELATIVE_HUMIDITY; + analog.unit = SR_UNIT_PERCENTAGE; + analog.data = &humidity; + sr_session_send(devc->cb_data, &packet); + g_slist_free(l); + } devc->num_samples++; @@ -129,13 +146,15 @@ static int handle_packet(const uint8_t *buf, struct sr_dev_inst *sdi, int idx) static void handle_new_data(struct sr_dev_inst *sdi, int idx) { struct dev_context *devc; + struct sr_serial_dev_inst *serial; int len, i, offset = 0; devc = sdi->priv; + serial = sdi->conn; /* Try to get as much data as the buffer can hold. */ len = SERIAL_BUFSIZE - devc->buflen; - len = serial_read(devc->serial, devc->buf + devc->buflen, len); + len = serial_read(serial, devc->buf + devc->buflen, len); if (len < 1) { sr_err("Serial port read error: %d.", len); return; @@ -144,10 +163,10 @@ static void handle_new_data(struct sr_dev_inst *sdi, int idx) devc->buflen += len; /* Now look for packets in that data. */ - while ((devc->buflen - offset) >= PACKET_SIZE) { - if (packet_valid(devc->buf + offset)) { + while ((devc->buflen - offset) >= mic_devs[idx].packet_size) { + if (mic_devs[idx].packet_valid(devc->buf + offset)) { handle_packet(devc->buf + offset, sdi, idx); - offset += PACKET_SIZE; + offset += mic_devs[idx].packet_size; } else { offset++; } @@ -165,6 +184,7 @@ static int receive_data(int fd, int revents, int idx, void *cb_data) struct dev_context *devc; int64_t t; static gboolean first_time = TRUE; + struct sr_serial_dev_inst *serial; (void)fd; @@ -174,13 +194,15 @@ static int receive_data(int fd, int revents, int idx, void *cb_data) if (!(devc = sdi->priv)) return TRUE; + serial = sdi->conn; + if (revents == G_IO_IN) { /* New data arrived. */ handle_new_data(sdi, idx); } else { /* Timeout. */ if (first_time) { - mic_cmd_set_realtime_mode(devc->serial); + mic_cmd_set_realtime_mode(serial); first_time = FALSE; } } @@ -208,4 +230,5 @@ SR_PRIV int receive_data_##ID_UPPER(int fd, int revents, void *cb_data) { \ return receive_data(fd, revents, ID_UPPER, cb_data); } /* Driver-specific receive_data() wrappers */ +RECEIVE_DATA(MIC_98581) RECEIVE_DATA(MIC_98583)