/******************************************************************************
** Copyright 2015 MBARI - Monterey Bay Aquarium Research Institute
*******************************************************************************
*******************************************************************************
** Summary  : Routines to access DS2433 1Wire EEPROM 
** Filename : ds2433.c
** Author   : Luke Coletti
** Project  :
** Version  : 1.0
** Compiler : MetroWerks Code Warrior v8.3
** Created  : 3/17/17
** Archived :
*******************************************************************************
** Modification History:
** 03/017/17 : CF2 Port, LJC
*******************************************************************************/

#include	<cfxbios.h>		// Persistor BIOS and I/O Definitions
#include	<stdio.h>
#include 	<time.h>
#include    <math.h>
#include    <string.h>
#include	<userio.h>
#include	<ds2433.h>
#include	<ds2482.h>


int DS2433_GetVal(ushort ADDR, uchar DATBYTES, void *vp1)
{
uchar data[4];
int   i, t_ret, sd_ret;

    if( ( (DATBYTES != 1) && (DATBYTES != 2) && (DATBYTES != 4) ) || (vp1 == NULL) )
      return( ERROR );

    t_ret=DS2482_OWReset(&sd_ret);          // initialize bus
    if( sd_ret == TRUE )
      return( ERROR );

    DS2482_OWWriteByte(0xCC);               // skip ROM ID command

    DS2482_OWWriteByte(0xF0);               // read memory command
    DS2482_OWWriteByte(ADDR & 0x00FF);      // send LSB of target addr then MSB */
    DS2482_OWWriteByte((ADDR & 0xFF00) >> 8);


//  for(i = DATBYTES-1; i >= 0; i--){       // retrieve bytes in lil-endian order, (LSB at lowest mem addr).
    for(i = 0; i <= DATBYTES-1; i++){       // retrieve bytes in big-endian order, (MSB at lowest mem addr), TT8 uP is big-endian and so is DuraFET data.
      data[i] = DS2482_OWReadByte();
      //printf("\nRDdata[%d] = 0x%02X", i, data[i]);
      }
    //printf("\n");

    t_ret&=DS2482_OWReset(&sd_ret);         // initialize bus

    // synthesize value from byte array.
    memcpy(vp1, (uchar*)data, (size_t)DATBYTES);

    return( t_ret );

}

int DS2433_GetStr(ushort ADDR, ushort DATBYTES, uchar *DATA)
{
int i, t_ret, sd_ret;

    if( (DATBYTES < 1) || (DATBYTES > 0x1FF) || (DATA == NULL) )
      return( ERROR );

    t_ret=DS2482_OWReset(&sd_ret);          // initialize bus
    if( sd_ret == TRUE )
      return( ERROR );

    DS2482_OWWriteByte(0xCC);               // skip ROM ID command

    DS2482_OWWriteByte(0xF0);               // read memory command

    DS2482_OWWriteByte(ADDR & 0x00FF);      // send LSB of target addr then MSB */
    DS2482_OWWriteByte((ADDR & 0xFF00) >> 8);

    for(i = 0; i <= DATBYTES-1; i++){       // retrieve bytes in big-endian order, (MSB at lowest mem addr), TT8 uP is big-endian and so is DuraFET data.
      DATA[i] = DS2482_OWReadByte();
      }

    t_ret&=DS2482_OWReset(&sd_ret);         // initialize bus

    return( t_ret );

}

int LoadDuraFetIIICalVals(void)
{
int ret;
float R, F;

    // Retrieve Values from DuraFET III DS2433 EEPROM

    // retrieve DuraFET Sensor Serial Number
    ret =  DS2433_GetStr(SERIAL_NUM_PTR, SERIAL_NUM_BYTES, (uchar *)DURASN);

    // retrieve Iso-Potential EMF, or K0, which is the zero Kelvin Standard Potential (y intercept of K2 at zero Kelvin)
    ret &= DS2433_GetVal(K0_PTR, sizeof(float), (float*)&K0);

    // retrieve Iso-Potential pH which is the pH value where the EMF of the electrode pair is temperature invariant and occurs when Vrs and K0 are equal
    ret &= DS2433_GetVal(ISOPH_PTR, sizeof(float), (float*)&IsopH);

    // retrieve Percent/Fractional Theoretical Slope
    ret &= DS2433_GetVal(PTS_PTR, sizeof(float), (float*)&PTS);

    // Now Compute K1 and K2

    if( ret == TRUE ){
      R  = 8.3144621;               // molar gas constant (NIST), Joules/mol-K
      F  = 96485.3365;              // Faraday constant (NIST), Coulombs/mol
      K1 = R * log(10.0) / F;       // Nernst factor, V/pH-K, which is 0.059159343V at STD Temp or 298.15K
      K2 = -(PTS * K1 * IsopH);     // standard potential tempco, V/K
      }
    else
      K0=K1=K2=PTS=IsopH=-1.00;

    return( ret );

}


int DumpDuraFetIIIEEPROM(void)
{
uchar data[48];
int   sd_ret, i, j;


    if( DS2433_GetStr(SERIAL_NUM_PTR, SERIAL_NUM_BYTES, (uchar *)DURASN) != TRUE )
      return( ERROR );

    printf("DuraFET Serial Num =  %s\n", DURASN);

    DS2482_OWReset(&sd_ret);
    DS2482_OWWriteByte(0x33);
    printf("DS2433 Family Code =  %02Xh\n", DS2482_OWReadByte());
    printf("DS2433 Serial Numb =  ");
    for(i = 1; i <= 6; i++) //Output is MSB...LSB see fig 3 of DS2433 datasheet
      printf("%02X", DS2482_OWReadByte());
    printf("h\nDS2433 CRC value   =  %02Xh\n", DS2482_OWReadByte());

    printf("DS2433 Memory Dump (16 32 BYTE Pages)\n\n");
    printf("      000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F\n\n");
    for(i = 0; i < 16; i++){
      DS2433_GetStr((ushort)(i*32), (ushort)32, (uchar *)data);
      printf("%04X: ", i*32);
      for(j = 0; j < 32; j++)
        printf("%02X", (uchar)data[j]);
      printf("\n");
      }

    return( OK );

}

int PeekDuraFetIIIEEPROM(void)
{
ulong  ivar;
ushort addr, bytes;
short  sval;
ushort usval;
long   lval;
ulong  ulval;
float  fval;
uchar  str[128];


    if( DS2433_GetStr(SERIAL_NUM_PTR, SERIAL_NUM_BYTES, (uchar *)DURASN) != TRUE )
      return( ERROR );

    printf("DuraFET Serial Num =  %s\n", DURASN);

    ivar = 0;
    QueryNum("\nEnter DS2433 Address", "%lx", "%lx", &ivar);
    addr=(ushort)ivar;

    ivar = 0;
    QueryNum("\nEnter Data Type: 1=Float 2=Short 3=Long 4=Ushort 5=Ulong 6=Str", "%lu", "%lu", &ivar);

    if( ivar == 1 ){
      DS2433_GetVal(addr, sizeof(float), (float*)&fval);
      DS2433_GetVal(addr, sizeof(long), (long*)&lval);
      printf("\nValue at 0x%03X = 0x%08lX = %f\n", addr, lval, fval);
      }
    else if( ivar == 2 ){
      DS2433_GetVal(addr, sizeof(short), (short*)&sval);
      printf("\nValue at 0x%03X = 0x%04X = %d\n", addr, sval, sval);
      }
    else if( ivar == 3 ){
      DS2433_GetVal(addr, sizeof(long), (long*)&lval);
      printf("\nValue at 0x%03X = 0x%08lX = %ld\n", addr, lval, lval);
      }
    else if( ivar == 4 ){
      DS2433_GetVal(addr, sizeof(ushort), (ushort*)&usval);
      printf("\nValue at 0x%03X = 0x%04X = %hu\n", addr, usval, usval);
      }
    else if( ivar == 5 ){
      DS2433_GetVal(addr, sizeof(ulong), (ulong*)&ulval);
      printf("\nValue at 0x%03X = 0x%08lX = %lu\n", addr, ulval, ulval);
      }
    else if( ivar == 6 ){
      ivar = 0;
      QueryNum("\nEnter String Length", "%lu", "%lu", &ivar);
      bytes=(ushort)ivar;
      if( bytes < 64 ){
        memset(str, '\0', sizeof(str));
        DS2433_GetStr(addr, bytes, (uchar *)str);
        printf("\nValue at 0x%03X = %s\n", addr, str);
        }
      else
        printf("\nBAD string length!\n");
      }
    else
      printf("\nBAD TYPE!\n");

    return( OK );

}
