//---------------------------------------------------------------------------
// Copyright (C) 2000 Dallas Semiconductor Corporation, All Rights Reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES
// OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
// Except as contained in this notice, the name of Dallas Semiconductor
// shall not be used except as stated in the Dallas Semiconductor
// Branding Policy.
//---------------------------------------------------------------------------
//
//  gethumd.c - This utility gets the Volts for pins Vad and Vdd from the DS2438.
//
//  Version:   2.00
//  History:

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include "ownet.h"
#include "atod26.h"
#include "findtype.h"
#include "math.h"

#define MAXDEVICES 5
#define ONEKBITADD 0x89

#define SLOPE (34.249672152)
#define OFFSET (762.374681772)

/* 35.949367089 751.075949363 */

float pressure_at_msl(float pres, float temp, int altitude) {
#define __CONST_G (9.80665)
#define __CONST_R (287.04)
  float kt = temp + 273.15;
  float x = (__CONST_G * altitude / (__CONST_R * kt));
  pres *= exp(x);
  return pres;
}

float GetPressure(float Vad, float temp, int alt) {
  float pres = SLOPE * Vad + OFFSET;
  return (alt) ? pressure_at_msl(pres, temp, alt) : pres;
}

static void w1_make_serial(char *asc, unsigned char *bin) {
  int i, j;
  for (i = j = 0; i < 8; i++) {
    bin[i] = ToHex(asc[j]) << 4;
    j++;
    bin[i] += ToHex(asc[j]);
    j++;
  }
}

int main(int argc, char **argv) {
  int portnum = 0;
  float Vdd, Vad;
  int c, alt = 0;
  char *dev;
  char *serial = NULL;
  u_char ident[8];
  int verbose = 0;
  short dac = 0;

  while ((c = getopt(argc, argv, "da:s:v")) != EOF) {
    switch (c) {
    case 'v':
      verbose = 1;
      break;
    case 's':
      serial = strdup(optarg);
      break;
    case 'a':
      alt = atoi(optarg);
      break;
    case 'd':
      dac = 1;
      break;
    default:
      break;
    }
  }
  dev = argv[optind];
  if (dev == NULL || serial == NULL) {
    fputs("1-Wire Net name required on command line!\n"
          " (example: \"COM1\" (Win32 DS2480),\"/dev/cua0\" "
          "(Linux DS2480),\"1\" (Win32 TMEX)\n",
          stderr);
    return 0;
  }

  if ((portnum = owAcquireEx(dev)) < 0) {
    fputs("Failed to acquire port.\n", stderr);
    return 0;
  } else {
    w1_make_serial(serial, ident);
    if (verbose) {
      int i;
      fprintf(stderr, "Serial: %s\n", serial);
      fputs("Ident: ", stderr);
      for (i = 0; i < 8; i++) {
        fprintf(stderr, "%02X", ident[i]);
      }
      fputc('\n', stderr);
      fprintf(stderr, "Altitude: %d\n", alt);
    }

    Vdd = ReadAtoD(portnum, TRUE, ident);
    if (Vdd > 5.8) {
      Vdd = (float)5.8;
    } else if (Vdd < 4.0) {
      Vdd = (float)4.0;
    }
    Vad = ReadAtoD(portnum, FALSE, ident);
    printf("VSup %.2f Vout %.2f", Vdd, Vad);
    if (dac) {
      fputc('\n', stdout);
    } else {
      float temp = Get_Temperature(portnum, ident);
      float pres = GetPressure(Vad, temp, alt);
      printf(" Temp %.2f Pressure %.1f\n", temp, pres);
    }
  }
  return 0;
}
