// ==============================================
// prvdrv_app.c - application specific DLL driver
// ==============================================
// (c) Copyright 2000
// The Parvus Corporation
// 396 Ironwood Drive
// Salt Lake City, UT 84115
// Tel:      (801) 483-1533
// Fax:      (801) 483-1523
// Web:      www.parvus.com
// Email:    parvus@parvus.com
// ---------------------------------------------
//   Revision History:
// ---------------------------------------------
//
//   10/15/2000 CG - V1.00.00 release
//   10/29/2000 CG - Modified for Blank
//
// ---------------------------------------------
// Note: 06/06/2002 Do not pass integers as they do not work only longs
// Note: 06/06/2002 Pass numeric arrays ByRef and strings ByVal



// -------------
// Include Files
// -------------
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
#include<time.h>
#include<math.h>

#include "prvapp_EnvFan.h"
#include "prvdrv_lib.h"
#include "prvdrv.h"
// ----------------
// Global Variables
// ---------------

int darray[30][2];
int darray_end;
int test_num = 55;

int HUMPort;// '= &H0 '1110
int HUMDDrBit;// '= &H1 '0001
int HUMCLKBit;// '= &H4 '0100
int HUMDinBit;// ' = &H8 '1000
int HUMDoutBit;// '= &H2 '0010
long HUMShadow=0;//'= &H2 '0010

int EvPort ;//As Integer '= &H7 '0111
int EvDDrBit;// As Integer '= &H2 '0010
int EvCLKBit;// As Integer '= &H4 '0100
int EvDinBit ;//As Integer ' = &H1 '0001
int EvDoutBit;// As Integer '= &H1 '0001
long EvShadow=0 ;//As Long '= &H2 '0010
int DS1682_ADDR ;//As Integer

//For Unique Serial Number
int UnPort;
int UnDDrBit;
int UnCLKBit;
int UnDinBit;
int UnDoutBit;
long UnShadow=0;
int Un_SET_WP_CMD;
int Un_READ_CMD;
int Un_WRITE_CMD;
int Un_ASN_ADD_CMD;
int Un_CLR_ADD_CMD;





int envIOBase;		// Base address of Board

static int TempDDRBit, TempCLKBit, TempDTIBit, TempDTOBit, TempPort, TempWindow;              // 0 - Not Used
static int TempBank, TempShadow, TempType, TempResetBit, TempResetBit1; 

// Local function headers
static void TempCommand(int cmd);
static int TempInput( int Cmd);
static void TempOutput (int Cmd, int Dta);
static void TempReset(int ch);
static void TempDisable(int ch);
static void TempEnable(int ch);
static void TempBusIOWrite8(long TP, int TS);
static void sdelay(void);
static void pdelay(unsigned long dlylim);


// for the humidity sensor.
void port_init();
void s_connectionreset();
void s_transstart();
int s_measure(float *, int checksum,int mode);
int s_write_byte(int);
void s_read_byte(float * , int, int ack);

//For elapsed time and event Counter
void Evnt_Port_Init();
int Evnt_ReadFromAddr(int);
int Evnt_Read_byte(int);
void Evnt_Start_Seq();
void Evnt_CLOCK_HIGH();
void Evnt_CLOCK_LOW();
long Evnt_GET_DATA();
void Evnt_SET_DATA_HIGH();
void Evnt_SET_DATA_LOW();
void Evnt_SET_DDR_IN(); //'Set DDR for inpuT
void Evnt_SET_DDR_OUT();
void Evnt_Stop_seq();
int Evnt_Write_byte(int w_val); 
int Evnt_WriteToAddr(int addr, int dat);

//For the Unique Serial Number from EEProm
void Un_Port_Init();
void Un_ClearAddress();
void Un_CLOCK_HIGH(); //' Raise the clock
void Un_CLOCK_LOW(); //'Lower the clock
long Un_GET_DATA();
int Un_Read_byte(int nack);
void Un_SET_DATA_HIGH(); //' Make data high
void Un_SET_DATA_LOW(); //' Make data low
void Un_SET_DDR_IN(); //'Set DDR for input
void Un_SET_DDR_OUT(); //'Set DDR to output
void Un_Start_seq();
void Un_Stop_seq();
int Un_Write_byte(int w_val);


// ----------------
// Local Variables
// ---------------

static PRVDRV_RANGES*	range;					// holds the range of I/O and Memory
static PRVDRV_RESULT	OpenOK = PRVDRV_CLOSED;	// return result showing open status
static int				iIO;					// Selected IO channel

// -------------------------------------------------------------------
// app_open() - Example of a function to open I/O for a jumper setting
// -------------------------------------------------------------------
int app_open(int ioChannel)						// open for an I/O channel
{
	if (OpenOK != PRVDRV_CLOSED) return(0);		// not OK (??want this??)
	OpenOK=prvdrv_Open();
	if (OpenOK != PRVDRV_OK) return(1);			// not OK

	range = prvdrv_CardRanges();				// obtain range informaton
	iIO = ioChannel;							// Save for later use
	if (ioChannel >= 0 && (unsigned int)ioChannel < range->nIo) return(2);
	prvdrv_Close();								// Wasn't in range
	OpenOK = PRVDRV_CLOSED;
	return(1);									// not OK
}

// ---------------------------------------------
// app_open() - Example of a function to closeup
// ---------------------------------------------
void app_close(void)
{
	if (OpenOK == PRVDRV_OK)						// Opened
		{
		prvdrv_Close();								// Yes - so close
		OpenOK = PRVDRV_CLOSED;
		}
	else if (OpenOK == PRVDRV_FAIL)					// Failed
		{
		OpenOK = PRVDRV_CLOSED;
		}
	else											// Closed
		{
		}
	return;		
}

// ********************************************************************
// Default VB FUNCTIONS
// ********************************************************************

// MDE
#define	VB_IO 0
#define	VB_MEM 1

// SZE
#define VB_BYTE 0
#define VB_WORD 1
#define VB_DWORD 2

// RESULT
#define VB_OK 0
#define VB_FAIL 1
#define VB_CLOSED 2


// Open connection to board
long WINAPI vbapp_Open(long VBioChannel) {
	unsigned int ioChannel;
	long OpenStat;
	ioChannel = (unsigned int)((unsigned long)VBioChannel);
	OpenStat = (long)((int)app_open(ioChannel));

	envIOBase = 0;			// Since addressing is relative
	envInitTemp(0);
	envInitTemp(1);
	port_init();               //' initialize the port,clk,ddr,din,dout
	Evnt_Port_Init();//for elapse time counter and event counter
	Un_Port_Init(); //for Unique serial Number EEProm
    //s_connectionreset();       //' reset the sensor
	return(OpenStat);
}

// Close connection to board
void WINAPI vbapp_Close(void) {
	app_close();
	return;
}

// Turn diagnostic LED on board on
void WINAPI vbapp_LedOn(void) {
	if (OpenOK != PRVDRV_OK) return;			// Didn't open sucessfully
	prvdrv_ClearBit(PRVDRV_IO, PRVDRV_BYTE, iIO, 1, 1 );		// Set led on
	
}

// Turn diagnostic LED on board off
void WINAPI vbapp_LedOff(void) {
	if (OpenOK != PRVDRV_OK) return;			// Didn't open sucessfully
	prvdrv_SetBit(PRVDRV_IO, PRVDRV_BYTE, iIO, 1, 1);	// Set led off
	
}

// General Byte Write to I/O Offset
void WINAPI vbapp_Write(long offset, long value) {
	if (OpenOK != PRVDRV_OK) return;			// Didn't open sucessfully
	prvdrv_Write(PRVDRV_IO, PRVDRV_BYTE, iIO, offset, value);	// Write Value
	return;
}

// General Byte Read from I/O Offset
long WINAPI vbapp_Read(long offset) {
	long value;
	if (OpenOK != PRVDRV_OK) return(-1);			// Didn't open sucessfully
	value = prvdrv_Read(PRVDRV_IO, PRVDRV_BYTE, iIO, offset);	// Read Value
	return(value);
}

// Perform test to determine proper connection to DLL
long WINAPI vbapp_Test(long value) {
	value = value * 2;							// Multiply value by 2
	return(value);

}

// return version of this DLL Driver
long WINAPI vbapp_Version(void) {
	long value;
	value = 10001;								// return version in 1.00.00 format
	return(value);

}

// Collect Card Access Ranges from WinDriver
void WINAPI vbapp_CardRangesL
   (
	  unsigned int* nRanges,
	  unsigned int* nIo,
	  unsigned int* nMem,
	  unsigned int* ioBase,
	  unsigned int* ioBytes,
	  unsigned int* ioOffset,
	  unsigned int* memBase,
	  unsigned int* memBytes,
	  unsigned int* memOffset
   )
{
	unsigned int i;
	*nRanges	= range->nRanges;
	*nIo		= range->nIo;
	*nMem		= range->nMem;
	for (i=0; i<range->nIo; i++)
	{
		ioBase[i]  = range->io[i].base;
		ioBytes[i] = range->io[i].bytes;
		ioOffset[i]= range->io[i].offset;
	}
	for (i=0; i<range->nMem; i++)
	{
		memBase[i]  = range->mem[i].base;
		memBytes[i] = range->mem[i].bytes;
		memOffset[i]= range->mem[i].offset;
	}
}

void WINAPI vbapp_Init(void)
{
	int i;

	if (OpenOK != PRVDRV_OK) return;			// Didn't open sucessfully

	for(i=0;i < darray_end; i++) {
		prvdrv_Write(PRVDRV_IO, PRVDRV_BYTE, iIO, darray[i][0], darray[i][1]);
	}

	return;
}

void WINAPI vbapp_FactoryCfg(void)
{
	int i;

	if (OpenOK != PRVDRV_OK) return;			// Didn't open sucessfully
	darray[0][0] = 0; darray[0][1] = 0x32;	darray[1][0] = 0; darray[1][1] = 0x22;
	darray[2][0] = 0; darray[2][1] = 0x22;	darray[3][0] = 0; darray[3][1] = 0x26;
	darray[4][0] = 0; darray[4][1] = 0x22;	darray[5][0] = 0; darray[5][1] = 0x2A;
	darray[6][0] = 0; darray[6][1] = 0x22;	darray[7][0] = 1; darray[7][1] = 0xFD;
	darray[8][0] = 1; darray[8][1] = 0x01;	darray[9][0] = 1; darray[9][1] = 0xDD;
	darray[10][0] = 1; darray[10][1] = 0x00; darray[11][0] = 1; darray[11][1] = 0xE7;
	darray[12][0] = 1; darray[12][1] = 0x01; darray[13][0] = 1; darray[13][1] = 0xC7;
	darray[14][0] = 1; darray[14][1] = 0x00; darray[15][0] = 1; darray[15][1] = 0xC4;
	darray[16][0] = 1; darray[16][1] = 0x01; darray[17][0] = 1; darray[17][1] = 0xC5;
	darray[18][0] = 1; darray[18][1] = 0x00; darray[19][0] = 1; darray[19][1] = 0xFC;
	darray[20][0] = 1; darray[20][1] = 0x01; darray[21][0] = 1; darray[21][1] = 0xDC;
	darray[22][0] = 1; darray[22][1] = 0x00; darray[23][0] = 0; darray[23][1] = 0x20;
	darray[24][0] = 1; darray[24][1] = 0x03; darray[25][0] = 0; darray[25][1] = 0x22;
	darray_end = 26;
	for (i=0; i<darray_end;i++) {
		prvdrv_Write(PRVDRV_IO, PRVDRV_BYTE, iIO, darray[i][0], darray[i][1]);
	}
		
	prvdrv_SetBit(PRVDRV_IO, PRVDRV_BYTE, iIO, 0, 0 );	// Turn off led
	
}

// ********************************************************************
// Application Specific VB FUNCTIONS
// ********************************************************************

// Access diagnostic LED of board
long WINAPI envDiagLED(long state) {

    int f;
    f = prvdrv_Read(PRVDRV_IO, PRVDRV_BYTE, iIO,envIOBase+1);
    if (state==0) prvdrv_Write(PRVDRV_IO, PRVDRV_BYTE, iIO,envIOBase+1, f | 0x02);	// LED Off
    else if (state==1) prvdrv_Write(PRVDRV_IO, PRVDRV_BYTE, iIO,envIOBase+1,f & 0xFD);	// LED On

    if ((prvdrv_Read(PRVDRV_IO, PRVDRV_BYTE, iIO,envIOBase+1) & 0x02)==0) f = 1; else f = 0;			// LED state

    return(f);
}

// Read Configuration jumpers
long WINAPI envReadCfg(void){
    int b;
    b = prvdrv_Read(PRVDRV_IO, PRVDRV_BYTE, iIO,envIOBase+5);
    return(b);
}

// Read digital Inputs
long WINAPI envReadDig(void){
    int b;
    b = prvdrv_Read(PRVDRV_IO, PRVDRV_BYTE, iIO,envIOBase+3);
    return(b);
}

// Read Humidity Inputs
long WINAPI envReadHum(void){
    int b;
    b = prvdrv_Read(PRVDRV_IO, PRVDRV_BYTE, iIO,envIOBase+0);
    return(b);
}
// Write Humidity Inputs
void WINAPI envWriteHum(long val){
	prvdrv_Write(PRVDRV_IO, PRVDRV_BYTE, iIO,envIOBase+0, val);
	return;
}

// Write to digital outputs
long WINAPI envSetDig(long val) {
    int r;
    r = prvdrv_Read(PRVDRV_IO, PRVDRV_BYTE, iIO,envIOBase+1);
    if (val!=-1) prvdrv_Write(PRVDRV_IO, PRVDRV_BYTE, iIO,envIOBase+1,(r & 0x0F) | ((val & 0x0F)<<4));
    //r = (((prvdrv_Read(PRVDRV_IO, PRVDRV_BYTE, iIO,envIOBase+1) & 0xF0)>>4) & 0x0F);
    r = prvdrv_Read(PRVDRV_IO, PRVDRV_BYTE, iIO,envIOBase+1);
    return(r);
}

// Write to enables
long WINAPI envSetEnables(long val){
    int r;
    r = prvdrv_Read(PRVDRV_IO, PRVDRV_BYTE, iIO,envIOBase+6);
    if (val!=-1) prvdrv_Write(PRVDRV_IO, PRVDRV_BYTE, iIO,envIOBase+6,(r & 0x1F) | ((val & 0x07)<<5));
    r = (((prvdrv_Read(PRVDRV_IO, PRVDRV_BYTE, iIO,envIOBase+6) & 0xE0)>>5) & 0x07);
    return(r);
}

// Turn Fan On/Off
long WINAPI envFan(long val){
    int r;
    r = prvdrv_Read(PRVDRV_IO, PRVDRV_BYTE, iIO,envIOBase+1);
    if (val==1) prvdrv_Write(PRVDRV_IO, PRVDRV_BYTE, iIO,envIOBase+1,r | 0x04);
    else if (val==0) prvdrv_Write(PRVDRV_IO, PRVDRV_BYTE, iIO,envIOBase+1,r & (~0x04));

    r = prvdrv_Read(PRVDRV_IO, PRVDRV_BYTE, iIO,envIOBase+1) & (0x04);
    if (r!=0) r=1;
    return(r);
}


void port_init()
{
	HUMPort = 0x0; //'1110             'Indicates register 0
    HUMDDrBit = 0x1; //'0001           'Indicates least significant bit in register 0
    HUMCLKBit = 0x4; //'0100           'Indicates the 2nd bit in register 0 (from lsb if lsb=0)
    HUMDinBit = 0x8; //'1000           'Indicates the 3rd bit in register 0 (from lsb if lsb=0)
    HUMDoutBit = 0x2; //'0010          'Indicates the 1st bit in register 0 (from lsb if lsb=0)

}

double WINAPI envHumidity(void)
{
	
	float raw_hum=0;
	int er=0;
	//double humidity_value=0;
	int checksum=0;
	const float C1=-4.0;              // for 12 Bit
	const float C2=+0.0405;           // for 12 Bit
	const float C3=-0.0000028;        // for 12 Bit
	//port_init();               //' initialize the port,clk,ddr,din,dout
    s_connectionreset();       //' reset the sensor
    er = er + s_measure(&raw_hum,checksum, 0); //'measure humidity. 0 for humidity 1 for temperature
	if (er != 0)
	{
        s_connectionreset();                 //in case of an error: connection reset
        return -1;
	}
    else
	{
		raw_hum=C3*raw_hum*raw_hum + C2*raw_hum + C1;     //calc. humidity from ticks to [%RH]
		if (raw_hum<0.1)
			return 0;
		if (raw_hum>100)
			return 100;
		return raw_hum;
		//return humidity here.
        
        //' Calculate humidity % value after getting the correct MSB and LSB
	}
    //----------wait approx. 0.8s to avoid heating up SHTxx------------------------------ timer should take care of this
}

double WINAPI envTemperature(int tmp)
{
	
	float raw_tmp=0;
	int er=0;
	//double humidity_value=0;
	int checksum=0;
	//port_init();               //' initialize the port,clk,ddr,din,dout
    s_connectionreset();       //' reset the sensor
    er = er + s_measure(&raw_tmp,checksum, 1); //'measure humidity. 0 for humidity 1 for temperature
	if (er != 0)
	{
        s_connectionreset();                 //in case of an error: connection reset
        return -1;
	}
    else
	{
		raw_tmp=raw_tmp * 0.01 - 40;//calc temperature
		if(tmp==0)
			return raw_tmp;
		//convert to fahrenheit
		if(tmp==1)
		{
			raw_tmp=((9/5)*raw_tmp + 32);
			return raw_tmp;
		}
		return -1;
	}
    //----------wait approx. 0.8s to avoid heating up SHTxx------------------------------ timer should take care of this
}





int s_measure(float *raw_hum, int checksum,int mode)
{
    int er=0;
	int I;
	clock_t ticks1, ticks2;
	long portvalue=0;
    //double myhum;
        s_transstart();                //' transmission start
        switch(mode)
		{					//' send command to sensor
        case 0: //'Humidity
                er = er + s_write_byte(0x05);
				break;
        case 1: //'Temperature
                er = er + s_write_byte(0x03);
				break;
        default:
				//should never get here
				er=1;
				break;       
        }
        
		HUMShadow = HUMShadow & (~ HUMDDrBit);  //'Set DDR for input
        vbapp_Write (HUMPort, HUMShadow);

        I = 0;
		ticks1=clock();
		ticks2=ticks1;
        
        do
		{
            ticks2=clock();
			portvalue = vbapp_Read(HUMPort);                       // ' Read Port
            if ((portvalue & HUMDinBit) == 0) 
			{
                break;
			}
            I = I + 1;
			
		}
        while ((ticks2/CLOCKS_PER_SEC-ticks1/CLOCKS_PER_SEC)<3);                                        //'wait for 3 secs
        
		if ((portvalue & HUMDinBit) != 0) 
		{
			er = er + 1;
		}
    
    s_read_byte(raw_hum,15,1);                  //'read the first byte (MSB)
    //MSB_txt.Text = BitDisp$(p_value)
     s_read_byte(raw_hum,7,1);                  //'read the second byte (LSB)
    
    //calc_sth11 (p_value);
    return er;                              //'return error status
}



void s_transstart()
{    
    
    HUMShadow= HUMShadow | (HUMDDrBit);  //Set DDR for output
    vbapp_Write (HUMPort,HUMShadow);
    
    HUMShadow = HUMShadow | (HUMDoutBit);     //' Raise  Data
    vbapp_Write (HUMPort, HUMShadow);
     
    HUMShadow = HUMShadow & (~HUMCLKBit);     //' Lower Clock
    vbapp_Write(HUMPort,HUMShadow);
    
    if (1); //nop

    HUMShadow= HUMShadow | (HUMCLKBit);      //' Raise Clock
    vbapp_Write (HUMPort, HUMShadow);

	                                        //'Wait 1 clock cycle
    if(1);

    HUMShadow = HUMShadow & (~HUMDoutBit);     //' Lower  Data
    vbapp_Write (HUMPort,HUMShadow);
    
                                            //'Wait 1 clock cycle
    if (1);
        
    HUMShadow = HUMShadow & (~HUMCLKBit);     //' Lower Clock
    vbapp_Write (HUMPort, HUMShadow);
    
                                            //'Wait 1 clock cycle
    if(1);
											//'Wait 1 clock cycle
    if(1);
                                            //'Wait 1 clock cycle
    if(1);
    
    HUMShadow = HUMShadow | (HUMCLKBit);      //' Raise Clock
    vbapp_Write (HUMPort, HUMShadow);
                                            //'Wait 1 clock cycle
    if(1);

    HUMShadow = HUMShadow | (HUMDoutBit);     //' Raise  Data
    vbapp_Write (HUMPort, HUMShadow);
    
                                            //'Wait 1 clock cycle
    if(1);

    HUMShadow = HUMShadow & (~HUMCLKBit);     //' Lower Clock
    vbapp_Write(HUMPort, HUMShadow);
}

int s_write_byte(int value)
{
	int er=0;
	int i;
	long portvalue=0;
    HUMShadow = HUMShadow | (HUMDDrBit);  //'Set DDR for output
    vbapp_Write (HUMPort, HUMShadow);
    
    i=0x80;
    while (i > 0)
	{
    
        if (i & value) 
		{
            HUMShadow = HUMShadow | (HUMDoutBit);     //' Raise  Data
            vbapp_Write (HUMPort, HUMShadow);
		}
        else
		{
            HUMShadow = HUMShadow & (~HUMDoutBit);     //' Lower  Data
            vbapp_Write (HUMPort, HUMShadow);   
        }
        HUMShadow = HUMShadow | (HUMCLKBit);      //' Raise Clock
        vbapp_Write (HUMPort, HUMShadow);
      
													//'Wait 1 clock cycle
        if(1);
													//'Wait 1 clock cycle
        if(1);
                                                    //'Wait 1 clock cycle
        if(1);
        
        if (i == 1) 
		{
            HUMShadow = HUMShadow & (~HUMDDrBit);  //'Set DDR for input to release the data line for the last command bit
            vbapp_Write (HUMPort, HUMShadow);
        }
        
        HUMShadow = HUMShadow & (~HUMCLKBit);     //' Lower Clock
        vbapp_Write (HUMPort, HUMShadow);
        i = i / 2;                                   //'shift bit for masking
    }
    
    HUMShadow = HUMShadow & (~HUMDDrBit);  //'Set DDR for input to release the data line
    vbapp_Write (HUMPort,HUMShadow);
    
    HUMShadow = HUMShadow | (HUMCLKBit);      //' Raise Clock ---- clk #9 for ack
    vbapp_Write (HUMPort, HUMShadow);
    
    
    HUMShadow = HUMShadow & (~HUMDDrBit);  //'Set DDR for input
    vbapp_Write (HUMPort, HUMShadow);
    
    portvalue = vbapp_Read(HUMPort); //' Read Port
    if ((portvalue & HUMDinBit) > 0)               //'check ack (DATA will be pulled down by SHT11)
	{
            er = er + 1; //'error 
    }
    
	HUMShadow = HUMShadow & (~HUMCLKBit);     //' Lower Clock
    vbapp_Write (HUMPort, HUMShadow);  
    return er;

}
//----------------------------------------------------------------------------------
// communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart
//       _____________________________________________________         ________
// DATA:                                                      |_______|
//          _    _    _    _    _    _    _    _    _        ___     ___
// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______|   |___|   |______

void s_connectionreset()
{
    int i;
   
    HUMShadow = HUMShadow | (HUMDDrBit);  //'Set DDR for output
    vbapp_Write(HUMPort, HUMShadow);
    
     
    HUMShadow = HUMShadow | (HUMDoutBit);     //' high  Data
    vbapp_Write(HUMPort,HUMShadow);
     
     
    HUMShadow = HUMShadow & (~HUMCLKBit);     //' Lower Clock
    vbapp_Write (HUMPort, HUMShadow);
     
    for(i= 0;i<=8;i++)  //' 9 Cycles
	{
        HUMShadow = HUMShadow | HUMCLKBit;
        vbapp_Write(HUMPort,HUMShadow);                   //    ' Raise Clock
        
        HUMShadow = HUMShadow & (~HUMCLKBit);
        vbapp_Write (HUMPort,HUMShadow);                    //   ' Lower Clock
        
    }
}

void s_read_byte(float *raw_hum,int bit_pos,int ack) 
{
    
    unsigned char I;
	
	long portvalue;
        
    HUMShadow = HUMShadow & (~HUMDDrBit);  //'Set DDR for input to release data line
    vbapp_Write (HUMPort, HUMShadow);
     
    I = 0x80;
    
    while ((I) > 0)
	{
        HUMShadow = HUMShadow | (HUMCLKBit);      //' Raise Clock
        vbapp_Write (HUMPort, HUMShadow);
              
        portvalue = vbapp_Read(HUMPort);//    ' Read Port
        
        if ((portvalue & HUMDinBit) > 0)//                       'check bit
		{
                
				*raw_hum+=(float)pow(2,bit_pos);
        }
		
        HUMShadow = HUMShadow & (~HUMCLKBit);     //' Lower Clock
        vbapp_Write (HUMPort, HUMShadow);
       //' MsgBox "lower clock"
        I = I / 2;                       //                'shift bit for masking
		bit_pos--;
    }
    
    HUMShadow = HUMShadow | (HUMDDrBit) ;// 'Set DDR for output
    vbapp_Write (HUMPort, HUMShadow);
    
   
    if (ack)
	{
        HUMShadow = HUMShadow & (~HUMDoutBit);  //   ' Lower  Data ---- in case of "ack==1" pull down DATA-Line since checksum is not used
        vbapp_Write (HUMPort, HUMShadow);
     
	}
    else
	{
        HUMShadow = HUMShadow | (HUMDoutBit); //    ' Raise  Data
        vbapp_Write (HUMPort, HUMShadow);
        
    }
    HUMShadow = HUMShadow | (HUMCLKBit);      //' Raise Clock clk #9 for ack
    vbapp_Write (HUMPort, HUMShadow);
    
    
    if(1);
    if(1);
    if(1);
    
    HUMShadow = HUMShadow & (~HUMCLKBit);     //' Lower Clock
    vbapp_Write (HUMPort, HUMShadow);
    
    HUMShadow = HUMShadow & (~HUMDDrBit);//  'Set DDR for input to release data line
    vbapp_Write (HUMPort, HUMShadow);
    
}
// Read environmental analog channels
long WINAPI envReadAna(long channel){
    int dta;
    switch (channel & 0x0F) {
//		case 8:
//			dta = -1;
//			break;
		case 8:
			prvdrv_Write(PRVDRV_IO, PRVDRV_BYTE, iIO,envIOBase+8,3+0x80);		// Start conversion
			pdelay(1000);
			dta = prvdrv_Read(PRVDRV_IO, PRVDRV_BYTE, iIO,envIOBase+8);
			break;
		case 9:
			dta = -1;
			break;
		default:
			prvdrv_Write(PRVDRV_IO, PRVDRV_BYTE, iIO,envIOBase+8,channel);		// Start conversion
			pdelay(1000);
			dta = prvdrv_Read(PRVDRV_IO, PRVDRV_BYTE, iIO,envIOBase+8);
			break;
	}
    return(dta);                                // Return Data

}

//EventCounter routines

void Evnt_Port_Init()
{
    EvPort = 0x7 ;//'0111             'Indicates register 7 (consider reg0 as 1st reg)
    EvDDrBit = 0x2;// '0010           'Indicates 1st in register 7
    EvCLKBit = 0x4;// '0100           'Indicates the 2nd bit in register 7 (from lsb if lsb=0)
    EvDinBit = 0x1;// '0001           'Indicates least significant bit in register 7 (from lsb if lsb=0)
    EvDoutBit = 0x1;// '0001          'Indicates the least significant bit in register 7 (from lsb if lsb=0)
    DS1682_ADDR = 0xD6;//             'Indicates the device address
}

int WINAPI ElapsedTimerReset(void)
{
	int er;
	er=Evnt_WriteToAddr(5, 0);
	if (er>0)
		return 0;
	er=Evnt_WriteToAddr(6, 0);
	if (er>0)
		return 0;
	er=Evnt_WriteToAddr(7, 0);
	if (er>0)
		return 0;
	er=Evnt_WriteToAddr(8, 0);
	if (er>0)
		return 0;
	return 1;
}

int WINAPI PowerCycleCountReset(void)
{
	int er;
	er=Evnt_WriteToAddr(9, 0);
	if (er>0)
		return 0;
	er=Evnt_WriteToAddr(10, 0);
	if (er>0)
		return 0;
	return 1;
}

int WINAPI Evnt_GetPowerCycleMSB(void)
{
	int dat1=0; 
	dat1=Evnt_ReadFromAddr(10);
	//dat2=Evnt_ReadFromAddr(10);
	return(dat1);
}

int WINAPI Evnt_GetPowerCycleLSB(void)
{
	int dat2=0; 
	//dat1=Evnt_ReadFromAddr(9);
	dat2=Evnt_ReadFromAddr(9);
	return(dat2);
}


long WINAPI Evnt_GetTimeInSecs(void)
{
	long dat,dat1,dat2,dat3,dat4;
	dat1=Evnt_ReadFromAddr(8);//MSB
	dat2=Evnt_ReadFromAddr(7);//LSB2
	dat3=Evnt_ReadFromAddr(6);//LSB1
	dat4=Evnt_ReadFromAddr(5);//LSB
	if (dat1==-1 || dat2==-1 || dat3==-1 || dat4==-1)
	{
		return -1;
	}
	dat1=dat1<<32;
	dat2=dat2<<16;
	dat3=dat3<<8;
	dat=(dat1 | dat2 | dat3 | dat4)>>2;//to divide it by four to get in terms of seconds.
	return (dat);
}

long WINAPI Evnt_GetPowerCycleCount(void)
{
	long dat,dat1,dat2;
	dat1=Evnt_ReadFromAddr(10);//MSB
	dat2=Evnt_ReadFromAddr(9);//LSB
	if(dat1==-1 || dat2==-1)
	{
		return -1;
	}
	dat1=dat1<<8;
	dat=dat1 | dat2;
	return (dat);
}


int WINAPI Evnt_GetTimeMSB(void)
{
	int dat1;
	dat1=Evnt_ReadFromAddr(8);
	return(dat1);
}
int WINAPI Evnt_GetTimeLSB2(void)
{
	int dat1;
	dat1=Evnt_ReadFromAddr(7);
	return(dat1);
}
int WINAPI Evnt_GetTimeLSB1(void)
{
	int dat1;
	dat1=Evnt_ReadFromAddr(6);
	return(dat1);
}

int WINAPI Evnt_GetTimeLSB(void)
{
	int dat1;
	dat1=Evnt_ReadFromAddr(5);
	return(dat1);
}

void Evnt_CLOCK_LOW()
{
	EvShadow = EvShadow & (~ EvCLKBit);
    vbapp_Write (EvPort, EvShadow);
}

void Evnt_SET_DDR_OUT()
{
	EvShadow = EvShadow | (EvDDrBit);
    vbapp_Write (EvPort, EvShadow);
}

void Evnt_SET_DATA_LOW()
{
	EvShadow = EvShadow & (~EvDoutBit);
    vbapp_Write (EvPort, EvShadow);
}

void Evnt_CLOCK_HIGH()
{
	EvShadow = EvShadow | (EvCLKBit);
    vbapp_Write (EvPort, EvShadow);
}

void Evnt_SET_DATA_HIGH()
{
	EvShadow = EvShadow | (EvDoutBit);
    vbapp_Write (EvPort, EvShadow);
}

void Evnt_SET_DDR_IN() //'Set DDR for input
{
    EvShadow = EvShadow & (~EvDDrBit);//  'Set DDR for input
    vbapp_Write (EvPort, EvShadow);
}
//End Sub

long Evnt_GET_DATA()
{
	long portvalue=0;
    portvalue = vbapp_Read(EvPort);// ' Read Port
    if ((portvalue & EvDinBit) > 0)
            return(1);
    else
            return(0);
    
}
//End Function


void Evnt_Start_seq()
{
	//'START SEQUENCE:A change in the state of data line from, HIGH to LOW, while the clock is HIGH,
    //'defines the start condition

    //'         -----
    //'Data ___|__   |
    //'        |  \  |
    //'        |   \_|__________
    //'        |     |
    //'        |     |
    //'clock___|_____|___
    //'        |     |   \
    //'        |     |    \_______
    //'         -----
    
    Evnt_CLOCK_LOW();
    Evnt_SET_DDR_OUT();
    Evnt_SET_DATA_LOW();
    Evnt_CLOCK_HIGH();
    Evnt_CLOCK_LOW();
    //'Make the data line high
    Evnt_SET_DATA_HIGH();
    //'Make the clock high
    Evnt_SET_DATA_HIGH();
    
    //'Make the clock high
    Evnt_CLOCK_HIGH();
    //'Set ddr to output
    
    //'Make the data line low
    Evnt_SET_DATA_LOW();
    //'Make the clock low
    Evnt_CLOCK_LOW();

}

int Evnt_Write_byte(int w_val ) 
{
//'Purpose: To write the value passed in as argument to the register pointed by the register pointer. (It
//' is assumed the register pointer is already set. (See page 10 of data sheet for details).
//' Return: Returns true if write was successful else -1
int er=0;// As Integer
long I;
//'Set DDR to output
    Evnt_SET_DDR_OUT();
//'Lower the clock
    Evnt_CLOCK_LOW();
    
	I = 0x80;
    while (I > 0)
	{
    //'write to the dout corresponding to the value passed starting starting with msb
        if (I & w_val)
            Evnt_SET_DATA_HIGH();
        else
            Evnt_SET_DATA_LOW();
            
        
//'Raise clock
    Evnt_CLOCK_HIGH();
//'Lower clock
    Evnt_CLOCK_LOW();
    
        I = I / 2;
        
	}//Wend '..... Repeat  until 8 times (1 byte is writen)

//'Check for the ACKNOWLEDGEMENT
//'Set DDR for input
    Evnt_SET_DDR_IN();
//'Raise clock
    Evnt_CLOCK_HIGH();
//'Check the din bit (should be 0) else error
    
    if (Evnt_GET_DATA() > 0 )
            er = 1;
    else
            er = 0;
    
//'Lower the clock
    Evnt_CLOCK_LOW();

	return( er );//' return if write was successful

}

void Evnt_Stop_seq()
{
	//'STOP CONDITION: A change in the state of data line, from LOW to HIGH, while the clock line is HIGH,
    //'defines the STOP condition.
    
    //'             _____
    //'Data        |    _|______
    //'            |   / |
    //'       _____|__/  |
    //'            |     |
    //'            |     |
    //'Clock      _|_____|______
    //'          / |     |
    //'    _____/  |_____|
    
    
    //' Set DDR to output
    Evnt_SET_DDR_OUT();
    
    //' Make Dout Low
    Evnt_SET_DATA_LOW();
    //' Make Clock low
    Evnt_CLOCK_LOW();
    
    //' Make Clock high
    Evnt_CLOCK_HIGH();
    //' MaKe Dout high
    Evnt_SET_DATA_HIGH();
}

int Evnt_ReadFromAddr(int addr)
{
    
    int dat=0;// As Integer
    int er=0; //As Integer
    
    Evnt_Start_seq();
    er = er + Evnt_Write_byte(DS1682_ADDR);
    er = er + Evnt_Write_byte(addr);// ' register address
    Evnt_Stop_seq();

    Evnt_Start_seq();
    er = er + Evnt_Write_byte(DS1682_ADDR | 0x1);
    if (er > 0)
	{
        return -1;
    }
    dat = Evnt_Read_byte(1);
    Evnt_Stop_seq();
    return(dat);
    
}

int Evnt_WriteToAddr(int addr, int dat)
{
int er=0;
Evnt_Start_seq();
er = er + Evnt_Write_byte(DS1682_ADDR);
er = er + Evnt_Write_byte(addr); //' register address
er = er + Evnt_Write_byte(dat);
Evnt_Stop_seq();
return (er);

}


int Evnt_Read_byte(int nack)
{
int  Rd_val=0;// As Integer
long I=0;
//' Purpose: To read the byte from the address pointer by the register pointer. ( It is assumed that
//' the register pointer has already been set. See page10 of data sheet for more details)
//' Returns: The value read

//' Set DDR for input
    Evnt_SET_DDR_IN();
    Evnt_CLOCK_LOW();
    I = 0x80;
    Rd_val = 0;
    while (I > 0)
	{
    //' Raise clock
        Evnt_CLOCK_HIGH();
    //' Read Din bit
        if (Evnt_GET_DATA())
            Rd_val = Rd_val | (I);
    //' Lower clock
        Evnt_CLOCK_LOW();
        I = I / 2;
	}//Wend '........Continue sequence for 8 times for 8 bits (1Byte)

//'GENRATING THE ACKNOWLEDGEMENT
if (nack) 
        Evnt_SET_DATA_HIGH();// ' No acknowledge
else
        Evnt_SET_DATA_LOW();//  ' Ack

//' Set DDR for output
	Evnt_SET_DDR_OUT();

if (nack) 
        Evnt_SET_DATA_HIGH();// ' No acknowledge
else
        Evnt_SET_DATA_LOW();//  ' Ack

//' Raise clock
    Evnt_CLOCK_HIGH();
    
//' Lower clock
    Evnt_CLOCK_LOW();
    
    Evnt_SET_DDR_IN();
    
    return(Rd_val);// ' Return the value
    
}


void Un_Port_Init()
{
    UnPort = 0x7;// '0111             'Indicates register 7 (consider reg0 as 1st reg)
    UnDDrBit = 0x20;// '0010 0000           'Indicates 1st in register 7
    UnCLKBit = 0x8 ;//'00001000           'Indicates the 2nd bit in register 7 (from lsb if lsb=0)
    UnDinBit = 0x10;// '00010000           'Indicates least significant bit in register 7 (from lsb if lsb=0)
    UnDoutBit = 0x10;// '00010000          'Indicates the least significant bit in register 7 (from lsb if lsb=0)
    
    Un_SET_WP_CMD = 0x60;
    Un_READ_CMD = 0x61;
    Un_WRITE_CMD = 0x62;
    Un_ASN_ADD_CMD = 0x64;
    Un_CLR_ADD_CMD = 0x66;

}

void Un_SET_DATA_HIGH() //' Make data high
{
    UnShadow = UnShadow | (UnDoutBit);
    vbapp_Write (UnPort, UnShadow);
}

void Un_SET_DATA_LOW() //' Make data low
{
    UnShadow = UnShadow & (~UnDoutBit);
    vbapp_Write (UnPort, UnShadow);
}

void Un_CLOCK_HIGH() //' Raise the clock
{
    UnShadow = UnShadow | (UnCLKBit);
    vbapp_Write (UnPort, UnShadow);
}

void Un_CLOCK_LOW() //'Lower the clock
{
    UnShadow = UnShadow & (~UnCLKBit);
    vbapp_Write (UnPort, UnShadow);
}

void Un_SET_DDR_OUT() //'Set DDR to output
{
    UnShadow = UnShadow | (UnDDrBit);
    vbapp_Write (UnPort, UnShadow);
}

void Un_SET_DDR_IN() //'Set DDR for input
{
    UnShadow = UnShadow & (~UnDDrBit);//  'Set DDR for input
    vbapp_Write (UnPort, UnShadow);
}

long Un_GET_DATA()
{
    long portvalue;
	portvalue = vbapp_Read(UnPort);// ' Read Port
    if ((portvalue & UnDinBit) > 0)
            return 1;
    else
            return 0;
}



void Un_Stop_seq()
{
    //'STOP CONDITION: A change in the state of data line, from LOW to HIGH, while the clock line is HIGH,
    //'defines the STOP condition.
    
    //'             _____
    //'Data        |    _|______
    //'            |   / |
    //'       _____|__/  |
    //'            |     |
    //'            |     |
    //'Clock      _|_____|______
    //'          / |     |
    //'    _____/  |_____|
    
    
    //' Set DDR to output
    Un_SET_DDR_OUT();
    
    //' Make Dout Low
    Un_SET_DATA_LOW();
    //' Make Clock low
    Un_CLOCK_LOW();
    
    //' Make Clock high
    Un_CLOCK_HIGH();
    //' MaKe Dout high
    Un_SET_DATA_HIGH();
}

void Un_Start_seq()
{
    //'START SEQUENCE:A change in the state of data line from, HIGH to LOW, while the clock is HIGH,
    //'defines the start condition

    //'         -----
    //'Data ___|__   |
    //'        |  \  |
    //'        |   \_|__________
    //'        |     |
    //'        |     |
    //'clock___|_____|___
    //'        |     |   \
    //'        |     |    \_______
    //'         -----
    
    Un_CLOCK_LOW();
    Un_SET_DDR_OUT();
    Un_SET_DATA_LOW();
    Un_CLOCK_HIGH();
    Un_CLOCK_LOW();
    //'Make the data line high
    Un_SET_DATA_HIGH();
    //'Make the clock high
    Un_SET_DATA_HIGH();
    //'Make the clock high
    Un_CLOCK_HIGH();
    //'Set ddr to output
    //'Make the data line low
    Un_SET_DATA_LOW();
    //'Make the clock low
    Un_CLOCK_LOW();
}


int Un_Read_byte(int nack)
{
int Rd_val=0;
long I=0;
//' Purpose: To read the byte from the address pointer by the register pointer. ( It is assumed that
//' the register pointer has already been set. See page10 of data sheet for more details)
//' Returns: The value read

//' Set DDR for input
    Un_SET_DDR_IN();
    Un_CLOCK_LOW();
    I = 0x80;
    Rd_val = 0;
    while(I > 0)
	{
    //' Raise clock
        Un_CLOCK_HIGH();
    //' Read Din bit
        if (Un_GET_DATA())
            Rd_val = Rd_val | (I);
    //' Lower clock
        Un_CLOCK_LOW();
        I = I / 2;
	}//Wend '........Continue sequence for 8 times for 8 bits (1Byte)

//'GENRATING THE ACKNOWLEDGEMENT
if (nack)
        Un_SET_DATA_HIGH();// ' No acknowledge
else
        Un_SET_DATA_LOW();//  ' Ack


//' Set DDR for output
Un_SET_DDR_OUT();

if (nack)
        Un_SET_DATA_HIGH();// ' No acknowledge
else
        Un_SET_DATA_LOW();//  ' Ack
//' Raise clock
    Un_CLOCK_HIGH();
    
//' Lower clock
    Un_CLOCK_LOW();
    
    Un_SET_DDR_IN();
    
    return(Rd_val);// ' Return the value
    
}




int Un_Write_byte(int w_val)
{
//'Purpose: To write the value passed in as argument to the register pointed by the register pointer. (It
//' is assumed the register pointer is already set. (See page 10 of data sheet for details).
//' Return: Returns true if write was successful else -1
int er=0;
long I;

//'Set DDR to output
    Un_SET_DDR_OUT();
//'Lower the clock
    Un_CLOCK_LOW();
	I = 0x80;
    while (I > 0)
	{
    //'write to the dout corresponding to the value passed starting starting with msb
        if (I & w_val) 
            Un_SET_DATA_HIGH();
        else
            Un_SET_DATA_LOW();
		//'Raise clock
		Un_CLOCK_HIGH();
		//'Lower clock
		Un_CLOCK_LOW();
        I = I / 2;
    }//Wend '..... Repeat  until 8 times (1 byte is writen)

//'Check for the ACKNOWLEDGEMENT
//'Set DDR for input
    Un_SET_DDR_IN();
//'Raise clock
    Un_CLOCK_HIGH();
//'Check the din bit (should be 0) else error
    
    if(Un_GET_DATA() > 0) 
            er = 1;
    else
            er = 0;
//'Lower the clock
    Un_CLOCK_LOW();

	return er;// ' return if write was successful
}


void Un_ClearAddress()
{
	int er=0;
	Un_Start_seq();
    er = Un_Write_byte(Un_CLR_ADD_CMD);
    er = Un_Write_byte(0);
    //If er > 0 Then
    //    "error"
   // End If
    Un_Stop_seq();
}

int WINAPI Sn_GetSerialNumber(int byte_num)
{
int temp;
int i=0;
int er=0;
	if((byte_num<0) || (byte_num>5))
	{
		return(-1);
	}
    Un_ClearAddress();
    Un_Start_seq();
    er = Un_Write_byte(Un_ASN_ADD_CMD | 0x8);
    if (er > 0)
		return -1;
    er = Un_Write_byte(0);
    if (er > 0)
        return -1;
    temp = 0;
	for (i=0;i<=byte_num;i++)
	{
		if(i==byte_num) 
			temp = Un_Read_byte(1);
		else
			temp = Un_Read_byte(0);
    }
    

    Un_Stop_seq();
    return temp;
}
//End Function





// Initialize environmental board temperaure sensor
void WINAPI envInitTemp(long ch) {

    long TempNow, TempHi, TempLo, TempCfg;

    TempDDRBit = 0x2;            // Setup Temperature I/O
    TempCLKBit = 0x4;
    TempDTIBit = 0x1;
    TempDTOBit = 0x1;
    TempResetBit = 0x8;
    TempResetBit1 = 0x10;
    TempPort = envIOBase + 6;
    TempWindow = 0;              // 0 - Not Used
    TempBank = 1;
    TempShadow = 0;
    TempType = 0;                // 0=F, 1=C
    if (TempWindow > 0) prvdrv_Write(PRVDRV_IO, PRVDRV_BYTE, iIO,TempWindow, TempBank);     // Set access window
    TempShadow = (TempPort);	// load shadow
    TempEnable(ch);
    TempReset(ch);
    TempCommand (0xC);               // Send Temperature command
    TempCommand (0x2);               // Continuous Conversion
    TempReset(ch);
    TempCommand (0xEE);              // Start continuous Conversion
    TempReset(ch);
    TempDisable(ch);

    envReadTemp (&TempNow, &TempHi, &TempLo, &TempCfg, ch);
}

// Set environmental board thermostat limits
void WINAPI envWriteTemp (long TempHi, long TempLo, long ch) {
    TempEnable(ch);
    sdelay();
    TempShadow = prvdrv_Read(PRVDRV_IO, PRVDRV_BYTE, iIO,TempPort);	// load shadow
    TempReset(ch);
    TempCommand (0xC);               	// Send Temperature command
    TempCommand(2);               	// Continuous Conversion
    TempReset(ch);
    TempOutput(0x2, TempLo);         	// Send TL command
    TempReset(ch);
    TempOutput(0x1, TempHi);         	// Send TH command
    TempReset(ch);
    TempCommand(0xEE);              	// Start continuous Conversion
    TempReset(ch);
    sdelay();
    TempDisable(ch);
}
// Read environmental board temperature sensor
void WINAPI envReadTemp(long *TempNow, long *TempHi, long *TempLo, long *TempCfg, long ch) {
    TempEnable(ch);
    sdelay();
    TempShadow = prvdrv_Read(PRVDRV_IO, PRVDRV_BYTE, iIO,TempPort);	// load shadow
    TempReset(ch);
    *TempLo = TempInput(0xA2);       // Read Low temp set point
    TempReset(ch);
    *TempHi = TempInput(0xA1);       // Read High temp set point
    TempReset(ch);
    *TempNow = TempInput(0xAA);      // Read current temperature
    TempReset(ch);
    *TempCfg = TempInput(0xAC);      // Read current configuration
    TempReset(ch);
    sdelay();
    TempDisable(ch);
}


//////////////////////////////////////////////////////////////////////////////////////////////////
// Local Support Functions
//////////////////////////////////////////////////////////////////////////////////////////////////
static void TempBusIOWrite8(long TP, int TS) {
    prvdrv_Write(PRVDRV_IO, PRVDRV_BYTE, iIO,TP, (prvdrv_Read(PRVDRV_IO, PRVDRV_BYTE, iIO,TempPort) & 0xE0) | (TS & 0x1F));
}

static void TempCommand(int cmd){
    int i;
    
    if (TempWindow > 0) TempBusIOWrite8(TempWindow, TempBank);       // Set access window

    TempShadow = TempShadow | TempDDRBit;            		// Set As Output
    TempBusIOWrite8(TempPort, TempShadow);

    for (i=0; i<8; i++) {                                  	// LSB First
	if (((cmd >> i) & 0x01) == 0) TempShadow = TempShadow & (~TempDTOBit); // Lower Data
	else TempShadow = TempShadow | TempDTOBit;            			 // Raise Data

	TempBusIOWrite8(TempPort, TempShadow);                    	// Set data

	TempShadow = TempShadow & (~TempCLKBit);         	// Lower Clock
	TempBusIOWrite8(TempPort, TempShadow);

	TempShadow = TempShadow | TempCLKBit;                	// Raise Clock
	TempBusIOWrite8(TempPort, TempShadow);
    }

}
static int TempInput( int Cmd){
    int Dta, Bit, i;
    
    TempCommand (Cmd);

    TempShadow = TempShadow & (~TempDDRBit);         // Set As Input
    TempBusIOWrite8(TempPort, TempShadow);

    Dta = 0;
    for (i=0;i<9;i++) {
 	TempShadow = TempShadow & (~TempCLKBit);        // Lower Clock
	TempBusIOWrite8(TempPort, TempShadow);
	Bit = prvdrv_Read(PRVDRV_IO, PRVDRV_BYTE, iIO,TempPort) & TempDTIBit;
	Dta = Dta >> 1;
	if (Bit > 0) Dta = Dta + 0x100;
	TempShadow = TempShadow | TempCLKBit;                // Raise Clock
	TempBusIOWrite8(TempPort, TempShadow);
    }
    return(Dta);			// Return Temperature
}

static void TempOutput (int Cmd, int Dta) {
    int i;
    
    TempCommand (Cmd);

    TempShadow = TempShadow | TempDDRBit;            	// Set As Output
    TempBusIOWrite8(TempPort, TempShadow);

    for (i=0;i<9;i++) {	                             	// LSB First
	if (((Dta >> i) & 0x01) == 0) TempShadow = TempShadow &  (~ TempDTOBit); // Lower Data
	else TempShadow = TempShadow | TempDTOBit;            			 // Raise Data
	TempBusIOWrite8(TempPort, TempShadow);	      	// Set data
	TempShadow = TempShadow & (~TempCLKBit);     	// Lower Clock
	TempBusIOWrite8(TempPort, TempShadow);
	TempShadow = TempShadow | TempCLKBit;         	// Raise Clock
	TempBusIOWrite8(TempPort, TempShadow);
    }
}

static void TempReset(int ch){

    if (ch==0) {
	TempShadow = TempShadow & (~TempResetBit);		// Lower Reset
	TempBusIOWrite8(TempPort, TempShadow);
	sdelay();
	TempShadow = TempShadow | TempResetBit;
	TempBusIOWrite8(TempPort, TempShadow);			// Raise Reset
    }
    else {
	TempShadow = TempShadow & (~TempResetBit1);		// Lower Reset
	TempBusIOWrite8(TempPort, TempShadow);
	sdelay();
	TempShadow = TempShadow | TempResetBit1;
	TempBusIOWrite8(TempPort, TempShadow);			// Raise Reset
    }

}

static void TempDisable(int ch){

    if (ch==0) {
	TempShadow = TempShadow & (~TempResetBit);		// Lower Reset
	TempBusIOWrite8(TempPort, TempShadow);
    }
    else {
	TempShadow = TempShadow & (~TempResetBit1);		// Lower Reset
	TempBusIOWrite8(TempPort, TempShadow);
    }

}

static void TempEnable(int ch){

    if (ch==0) {
	TempShadow = TempShadow | TempResetBit;
	TempBusIOWrite8(TempPort, TempShadow);			// Raise Reset
    }
    else {
	TempShadow = TempShadow | TempResetBit1;
	TempBusIOWrite8(TempPort, TempShadow);			// Raise Reset
    }

}

static void sdelay( void){
	unsigned long delaycount;

	delaycount=0;
	do{
		delaycount++;
	}while(delaycount < 1000);
}

// Short variable delay
void pdelay(unsigned long dlylim) {

    unsigned long delaycount;
    delaycount=0;
    do{
	delaycount++;
    } while (delaycount < dlylim);
}



