|
- #include <stdio.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <errno.h>
- #include <unistd.h>
- #include <getopt.h>
- #include <stdint.h>
- #include <syslog.h>
- #include <err.h>
- #include <linux/serial.h>
- #include "serial-util.h"
- #include <string.h>
- #include <ctype.h>
-
- int hex = 0;
- int dec = 0;
- int screen = 0;
- int unprocessed = 0;
-
- int process(const uint8_t *buf, int len);
-
- int main(int argc, char *argv[])
- {
- char *device=strdup("/dev/serial/by-id/usb-FTDI_FT232R_USB_UART_A6007wc5-if00-port0");
- int rate=500000;
- int fd;
- int getopt_index;
- char buf[1024];
- int len;
- int calibrate = 1;
-
- static struct option long_opts[] = {
- { "device", required_argument, NULL, 'd' },
- { "rate", required_argument, NULL, 'r' },
- { "hex", no_argument, NULL, 'x' },
- { "dec", no_argument, NULL, 'D' },
- { "unprocessed", no_argument, NULL, 'u' },
- { "no-calibrate", no_argument, NULL, 'n' },
- { "screen", no_argument, NULL, 's' },
- { "help", no_argument, NULL, 'h' },
- { 0, 0, 0, 0 }
- };
- int help=0;
- char c;
-
- while ((c = getopt_long(argc, argv, "d:r:xDunsh?",
- long_opts, &getopt_index)) != -1) {
- switch(c)
- {
- case 'd':
- free(device);
- device = strdup(optarg);
- break;
- case 'r':
- rate = atoi(optarg);
- if(rate == 0)
- errx(1, "invalid rate: %s",optarg);
- break;
- case 'x':
- hex = 1;
- break;
- case 'D':
- dec = 1;
- break;
- case 'u':
- unprocessed = 1;
- break;
- case 'n':
- calibrate = 0;
- break;
- case 's':
- screen = 1;
- break;
- case 'h':
- case '?':
- default:
- help = 1;
- break;
- }
- }
-
- if (help) {
- fprintf(stderr, "Zoom Nilm Client\n");
- fprintf(stderr, "usage: %s [options]\n\n", *argv);
- fprintf(stderr, " -d, --device %-14s serial port\n", device);
- fprintf(stderr, " -r, --rate %-16d baud rate\n", rate);
- fprintf(stderr, " -x, --hex hex out\n");
- fprintf(stderr, " -D, --dec dec out\n");
- fprintf(stderr, " -u, --unprocessed dump raw unprocessed data\n");
- fprintf(stderr, " -n, --no-calibrate skip calibration routine\n");
- fprintf(stderr, " -s, --screen send \\r instead of \\n\n");
- fprintf(stderr, " -h, --help this cruft\n");
- return 1;
- }
-
- if ((fd = serial_open(device, rate)) == -1)
- err(1, "serial_open failed for %s", device);
-
- if (calibrate) {
- fprintf(stderr, "performing calibration\n");
- char c = 'c';
- write(fd, &c, 1);
- drain(fd);
- }
-
- len = 0;
- while (1) {
- int processed, n;
- n = read(fd, buf + len, sizeof(buf) - len);
- if (n <= 0)
- err(1, "read");
- len += n;
- processed = process((uint8_t *) buf, len);
- memmove(buf, buf + processed, len - processed);
- len -= processed;
- }
-
- return 1;
- }
-
- int process_adc_dac(const uint8_t *buf)
- {
- uint16_t dac, tmp;
- int16_t adc;
- int overflow;
-
- /* data OK? */
- if ((buf[0] & 0xC0) != 0)
- return 0;
-
- /* extract */
-
- if (buf[0] & 0x10)
- overflow = 1;
- else
- overflow = 0;
-
- tmp = ((buf[0] & 0x0F) << 8) | buf[1];
- /* sign-extend ADC value */
- if (tmp & 0x0800)
- tmp |= 0xF000;
- else
- tmp &= ~0xF000;
- adc = (int16_t)tmp;
-
- dac = (buf[2] << 8) | buf[3];
-
- /* send it out */
- if (hex) {
- printf("%04x %03x", dac, adc & 0x0FFF);
- } else if (dec) {
- printf("%d %d", dac, adc);
- } else {
- printf("DAC: %5d ADC: % 5d Total: xxx", dac, adc);
- if (overflow)
- printf(" **** adc may have clamped");
- }
-
- if (screen)
- printf("\033[K\r");
- else
- printf("\n");
-
- return 1;
- }
-
- int process_calibration(const uint8_t *buf)
- {
- float f = *(float *)buf;
-
- fprintf(stderr, "got calibration value: %f\n", f);
-
- return 1;
- }
-
- int process(const uint8_t *buf, int len)
- {
- int n = 0;
-
- if (unprocessed) {
- n = write(fileno(stdout), buf, len);
- if (n >= 0)
- return n;
- return 0;
- }
-
- /* Process blocks */
- retry:
- for (; (n + 5) <= len; buf += 5, n += 5) {
- int ok = 0;
- switch (buf[0]) {
- case 0xA0:
- if (process_adc_dac(buf + 1)) ok = 1;
- break;
- case 0xA1:
- if (process_calibration(buf + 1)) ok = 1;
- break;
- default:
- break;
- }
- if (!ok) {
- /* badly formed data; eat one byte and retry */
- fprintf(stderr,"throwing away 0x%02x '%c'\n", buf[0], isprint(buf[0]) ? buf[0] : '.');
- buf++;
- n++;
- goto retry;
- }
- }
-
- return n;
- }
|