Download:
/*
In the following C language code, 1- wire I/O is accomplished using the
serial port of an IBM PC or compatible. The serial port must be capable
of a 115,200 bps data rate. Setup must be called before any of the
touch functions to verify the existence of the specified com port and
initialize it.
--------------------------------------------------------------------
The setup function makes sure that the com port number passed to it
is from 1 to 4 and has a valid address associated with it.
*/
#include <assert.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <dos.h>
#include <malloc.h>
typedef unsigned char uchar;
typedef unsigned int uint;
typedef unsigned long ulong;
static uchar com_port; /* 0x2F8 = COM2 */
static char *TouchMemStatus[5] = {
" 0 no presence detect",
" 1 presence pulse no alarm OK",
" 2 alarm followed by presence",
" 3 short circuit to ground",
" 4 no com port found" };
#define FL 0
#define TR 1
uchar
Setup (uchar CmPt)
{
uint far *ptr = (uint far *) 0x00400000;
uint SPA;
com_port = CmPt;
/* check to see if it is a valid com port number and address */
SPA = *(ptr + CmPt - 1); /* get the address */
if (CmPt < 1 || CmPt > 4 || !SPA)
return FL;
/* serial port initialization */
outportb (SPA + 3, 0x83); /* set DLAB */
outportb (SPA, 0x01); /* bit rate is 115200 */
outportb (SPA + 1, 0x00);
outportb (SPA + 3, 0x03); /* 8 dta, 1 stp, no par */
outportb (SPA + 1, 0x00); /* no interrupts */
outportb (SPA + 4, 0x03); /* RTS and DTR on */
printf("COM port #%d at 0x%0x\n", com_port, SPA);
return TR;
}
/*------------------------------------------------------------------------
* Do a reset on the 1 wire port and return
* 0 no presence detect
* 1 presence pulse no alarm
* 2 alarm followed by presence
* 3 short circuit to ground
* 4 no com port found
*
* The global variable 'com_port' must be set to the com port that the
* DS9097 COM Port Adapter is attached to before calling this routine.
*
*/
uchar
TouchReset (void)
{
uint SPA, F, X, Y, tmp, trst = 0;
uint far *ptr = (uint far *) 0x00400000;
ulong far *sysclk = (ulong far *) 0x0040006c;
ulong M;
/* get the serial port address */
SPA = *(ptr + com_port - 1);
/* return if there is no address */
if (!SPA)
return 4;
/* serial port initialization */
outportb (SPA + 3, 0x83); /* set DLAB */
outportb (SPA, 0x01); /* bit rate is 115200 */
outportb (SPA + 1, 0x00);
outportb (SPA + 3, 0x03); /* 8 dta, 1 stp, no par */
outportb (SPA + 1, 0x00); /* no interrupts */
outportb (SPA + 4, 0x03); /* RTS and DTR on */
/* Initialize the time limit */
M = *sysclk + 1;
/* loop to clear the buffers */
do
{
tmp = inportb (SPA + 5) & 0x60;
}
while (tmp != 0x60);
/* flush input */
while (inportb (SPA + 5) & 0x1)
X = inportb (SPA);
outportb (SPA + 3, 0x83); /* set DLAB */
outportb (SPA + 1, 0x00); /* baud rate is 10473 */
outportb (SPA, 0x0B);
outportb (SPA + 3, 0x03); /* 8 dta, 1 stp, no par */
outportb (SPA, 0xF0); /* send the reset pulse */
/* wait until character back or timeout */
do
{
Y = inportb (SPA + 5);
F = Y & 0x1;
}
while (!F && (*sysclk <= M));
if (F)
X = inportb (SPA);
else
return 3;
if (X != 0xF0) /* if more bits back than sent then there */
{ /* is a device if framing error or break */
trst = TR;
if ((Y & 0x18) != 0)
{
trst = 2;
/* loop to clear the buffers */
do
{
tmp = inportb (SPA + 5) & 0x60;
}
while (tmp != 0x60);
/* wait until character back or timeout */
do
{
Y = inportb (SPA + 5);
F = Y & 0x1;
}
while (!F && (*sysclk <= M));
if (F)
X = inportb (SPA);
else
return 3;
}
}
outportb (SPA + 3, 0x83); /* set DLAB */
outportb (SPA, 0x01); /* bit rate is 115200 */
outportb (SPA + 3, 0x03); /* 8 dta, 1 stp, no par */
return trst;
}
/*------------------------------------------------------------------------
* This is the 1- Wire routine 'TouchByte', sometimes called 'DataByte'.
* It transmits 8 bits onto the 1- Wire data line and receives 8 bits
* concurrently. The global variable 'com_port' must be set to the
* com port that the serial brick is attached to before calling this
* routine. This com port must also be set to 115200 baud, 8 dta, 1 stp,
* and no parity. This routine returns the uchar 8 bit value received.
* If it times out waiting for a character then 0xFF is returned.
*/
uchar
TouchByte (uchar outch)
{
uchar inch = 0, sendbit, Mask = 1;
uint SPA;
uint far *ptr = (uint far *) 0x00400000;
ulong far *sysclk = (ulong far *) 0x0040006c;
ulong M;
/* get the serial port address */
SPA = *(ptr + com_port - 1);
/* Initialize the time limit */
M = *sysclk + 2;
/* wait to TBE and TSRE */
do
{
}
while ((inportb (SPA + 5) & 0x60) != 0x60);
/* flush input */
while ((inportb (SPA + 5) & 0x1))
inportb (SPA);
/* get first bit ready to go out */
sendbit = (outch & 0x1) ? 0xFF : 0x00;
/* loop to send and receive 8 bits */
do
{
outportb (SPA, sendbit); /* send out the bit */
/* get next bit ready to go out */
Mask <<= 1;
sendbit = (outch & Mask) ? 0xFF : 0x00;
/* shift input char over ready for next bit */
inch >>= 1;
/* loop to look for the incoming bit */
for (;;)
{
/* return if out of time */
if (*sysclk > M)
return 0xFF;
if (inportb (SPA + 5) & 0x01)
{
inch |= ((inportb (SPA) & 0x01) ? 0x80 : 0x00);
break;
}
}
}
while (Mask);
return inch; /* return the input char */
}
static unsigned char **rom_table;
static int sensors;
static int read_time;
static int read_config(void)
{
char buf[80];
int i;
FILE *f = fopen("digitemp.cfg", "r");
if (f == NULL)
{
perror("digitemp.cfg");
return -1;
}
while (!feof(f))
{
fgets(buf, 80, f);
if (strncmp (buf, "SENSORS", 7) == 0)
{
sscanf(buf+7, "%d", &sensors);
printf("%d sensors in table\n", sensors);
rom_table = (unsigned char **)
malloc(sensors*sizeof(unsigned char *));
for (i = 0; i < sensors; i++)
rom_table[i] = (unsigned char *) malloc(8);
continue;
}
if (strncmp (buf, "ROM", 3) == 0)
{
int num, rom[8];
sscanf(buf+3, "%d%d%d%d%d%d%d%d%d", &num,
&rom[0], &rom[1], &rom[2], &rom[3],
&rom[4], &rom[5], &rom[6], &rom[7]);
for (i = 0; i < 8; i++)
{
rom_table[num][i] = (unsigned char)rom[i];
}
continue;
}
if (strncmp (buf, "READ_TIME", 9) == 0)
sscanf(buf+9, "%d", &read_time);
}
return 0;
}
static void dump(void)
{
int i;
for (i = 0; i < sensors; i++)
{
int j;
printf("%02X%02X%02X%02X%02X%02X%02X%02X\t",
rom_table[i][0], rom_table[i][1],
rom_table[i][2], rom_table[i][3],
rom_table[i][4], rom_table[i][5],
rom_table[i][6], rom_table[i][7]);
TouchReset();
TouchByte(0x55); /* Match ROM */
for (j = 0; j < 8; j++)
TouchByte(rom_table[i][j]);
TouchByte(0xBE); /* Read scratchpad */
for (j = 0; j < 8; j++)
printf("%02X ", (int)TouchByte(0xFF));
TouchReset();
printf("\n");
}
printf("read_time = %d\n", read_time);
}
void write_E2(int device_num, unsigned char byte1, unsigned char byte2)
{
int i;
TouchReset();
TouchByte(0x55); /* Match ROM */
for (i = 0; i < 8; i++)
TouchByte(rom_table[device_num][i]);
TouchByte(0x4E); /* Write scratchpad */
TouchByte(byte1);
TouchByte(byte2);
TouchReset();
TouchByte(0x55); /* Match ROM */
for (i = 0; i < 8; i++)
TouchByte(rom_table[device_num][i]);
TouchByte(0x48); /* copy scratchpad */
delay(20);
TouchReset();
}
unsigned char *read_temp(int device_num)
{
int i;
static unsigned char scratchpad[9];
TouchReset();
TouchByte(0x55); /* Match ROM */
for (i = 0; i < 8; i++)
TouchByte(rom_table[device_num][i]);
TouchByte(0x44); /* Convert T */
delay(read_time);
TouchReset();
TouchByte(0x55); /* Match ROM */
for (i = 0; i < 8; i++)
TouchByte(rom_table[device_num][i]);
TouchByte(0xBE); /* Convert T */
for (i = 0; i < 9; i++)
scratchpad[i] = TouchByte(0xFF);
TouchReset();
return scratchpad;
}
float temp(unsigned char *scratchpad)
{
short temp_read;
float d;
temp_read = scratchpad[0] & 0xFE | scratchpad[1] << 8;
d = (float)(scratchpad[7] -scratchpad[6])/(float)scratchpad[7];
return (float)temp_read/2.0 - 0.25 + d
+ (float)(scratchpad[2] * 256 + scratchpad[3])/100.0;
}
int
main()
{
uchar status;
uint address;
uchar data;
uint single;
uint portnum = 1;
char filename[150];
FILE *fp;
read_config();
Setup(portnum); /* COM port number */
status = TouchReset();
printf("TouchReset: %s\n", TouchMemStatus[status]);
for (;;)
{
fflush(stdin);
printf("1:Dump 2:Single 3:All 4:Clibrate 5:Clear calib. 6:Port num 7:Exit >>>");
switch(getchar())
{
case '1':
dump();
break;
case '2':
{
int i;
printf("Device number:");
scanf("%d", &i);
printf("T = %.2f C\n", temp(read_temp(i)));
}
break;
case '3':
{
int i;
for(i = 0; i < sensors; i++)
printf("T%d = %.2f C\n", i, temp(read_temp(i)));
}
break;
case '4':
{
#ifdef OVERLALL_AVERAGING
float *t, *diff, avg;
int i, j, iterations;
printf("Averaging iterations:");
scanf("%d", &iterations);
t = (float *)malloc(sensors * sizeof(float));
diff = (float *)malloc(sensors * sizeof(float));
for (i = 0; i < sensors; i++)
{
t[i] = 0.0;
diff[i] = 0.0;
}
for (j = 0; j < iterations; j++)
{
printf("[%d]", j);
avg = 0.0;
for (i = 0; i < sensors; i++)
{
t[i] = temp(read_temp(i));
avg += t[i];
}
avg /= sensors;
for (i = 0; i < sensors; i++)
diff[i] += t[i] - avg;
}
for (i = 0; i < sensors; i++)
{
short d = - diff[i]/iterations*100.0;
unsigned char th = d >> 8;
unsigned char tl = d & 0x00FF;
write_E2(i, th, tl);
}
free(t);
free(diff);
#else /* TRUE calibration */
float reference;
int i;
printf("Reference temperature:");
scanf("%f", &reference);
for (i = 0; i < sensors; i++)
{
short d = 100*(reference - temp(read_temp(i)));
unsigned char th = d >> 8;
unsigned char tl = d & 0x00FF;
write_E2(i, th, tl);
}
#endif
}
break;
case '5':
{
int i;
for (i = 0; i < sensors; i++)
write_E2(i, 0, 0);
}
break;
case '6':
printf("COM port number (1,2):");
scanf("%d", &portnum);
Setup(portnum); /* COM port number */
status = TouchReset();
printf("TouchReset: %s\n", TouchMemStatus[status]);
break;
case '7':
return 0;
default:
printf("Input error\n");
}
}
}
/*
In the following C language code, 1- wire I/O is accomplished using the
serial port of an IBM PC or compatible. The serial port must be capable
of a 115,200 bps data rate. Setup must be called before any of the
touch functions to verify the existence of the specified com port and
initialize it.
--------------------------------------------------------------------
The setup function makes sure that the com port number passed to it
is from 1 to 4 and has a valid address associated with it.
*/
#include <ctype.h>
#include <stdio.h>
#include <dos.h>
typedef unsigned char uchar;
typedef unsigned int uint;
typedef unsigned long ulong;
static uchar com_port; /* 0x2F8 = COM2 */
static char *TouchMemStatus[5] = {
" 0 no presence detect",
" 1 presence pulse no alarm",
" 2 alarm followed by presence",
" 3 short circuit to ground",
" 4 no com port found" };
#define FL 0
#define TR 1
uchar
Setup (uchar CmPt)
{
uint far *ptr = (uint far *) 0x00400000;
uint SPA;
com_port = CmPt;
/* check to see if it is a valid com port number and address */
SPA = *(ptr + CmPt - 1); /* get the address */
if (CmPt < 1 || CmPt > 4 || !SPA)
return FL;
/* serial port initialization */
outportb (SPA + 3, 0x83); /* set DLAB */
outportb (SPA, 0x01); /* bit rate is 115200 */
outportb (SPA + 1, 0x00);
outportb (SPA + 3, 0x03); /* 8 dta, 1 stp, no par */
outportb (SPA + 1, 0x00); /* no interrupts */
outportb (SPA + 4, 0x03); /* RTS and DTR on */
printf("COM port #%d at 0x%0x\n", com_port, SPA);
return TR;
}
/*------------------------------------------------------------------------
* Do a reset on the 1 wire port and return
* 0 no presence detect
* 1 presence pulse no alarm
* 2 alarm followed by presence
* 3 short circuit to ground
* 4 no com port found
*
* The global variable 'com_port' must be set to the com port that the
* DS9097 COM Port Adapter is attached to before calling this routine.
*
*/
uchar
TouchReset (void)
{
uint SPA, F, X, Y, tmp, trst = 0;
uint far *ptr = (uint far *) 0x00400000;
ulong far *sysclk = (ulong far *) 0x0040006c;
ulong M;
/* get the serial port address */
SPA = *(ptr + com_port - 1);
/* return if there is no address */
if (!SPA)
return 4;
/* serial port initialization */
outportb (SPA + 3, 0x83); /* set DLAB */
outportb (SPA, 0x01); /* bit rate is 115200 */
outportb (SPA + 1, 0x00);
outportb (SPA + 3, 0x03); /* 8 dta, 1 stp, no par */
outportb (SPA + 1, 0x00); /* no interrupts */
outportb (SPA + 4, 0x03); /* RTS and DTR on */
/* Initialize the time limit */
M = *sysclk + 1;
/* loop to clear the buffers */
do
{
tmp = inportb (SPA + 5) & 0x60;
}
while (tmp != 0x60);
/* flush input */
while (inportb (SPA + 5) & 0x1)
X = inportb (SPA);
outportb (SPA + 3, 0x83); /* set DLAB */
outportb (SPA + 1, 0x00); /* baud rate is 10473 */
outportb (SPA, 0x0B);
outportb (SPA + 3, 0x03); /* 8 dta, 1 stp, no par */
outportb (SPA, 0xF0); /* send the reset pulse */
/* wait until character back or timeout */
do
{
Y = inportb (SPA + 5);
F = Y & 0x1;
}
while (!F && (*sysclk <= M));
if (F)
X = inportb (SPA);
else
return 3;
if (X != 0xF0) /* if more bits back than sent then there */
{ /* is a device if framing error or break */
trst = TR;
if ((Y & 0x18) != 0)
{
trst = 2;
/* loop to clear the buffers */
do
{
tmp = inportb (SPA + 5) & 0x60;
}
while (tmp != 0x60);
/* wait until character back or timeout */
do
{
Y = inportb (SPA + 5);
F = Y & 0x1;
}
while (!F && (*sysclk <= M));
if (F)
X = inportb (SPA);
else
return 3;
}
}
outportb (SPA + 3, 0x83); /* set DLAB */
outportb (SPA, 0x01); /* bit rate is 115200 */
outportb (SPA + 3, 0x03); /* 8 dta, 1 stp, no par */
return trst;
}
/*------------------------------------------------------------------------
* This is the 1- Wire routine 'TouchByte', sometimes called 'DataByte'.
* It transmits 8 bits onto the 1- Wire data line and receives 8 bits
* concurrently. The global variable 'com_port' must be set to the
* com port that the serial brick is attached to before calling this
* routine. This com port must also be set to 115200 baud, 8 dta, 1 stp,
* and no parity. This routine returns the uchar 8 bit value received.
* If it times out waiting for a character then 0xFF is returned.
*/
uchar
TouchByte (uchar outch)
{
uchar inch = 0, sendbit, Mask = 1;
uint SPA;
uint far *ptr = (uint far *) 0x00400000;
ulong far *sysclk = (ulong far *) 0x0040006c;
ulong M;
/* get the serial port address */
SPA = *(ptr + com_port - 1);
/* Initialize the time limit */
M = *sysclk + 2;
/* wait to TBE and TSRE */
do
{
}
while ((inportb (SPA + 5) & 0x60) != 0x60);
/* flush input */
while ((inportb (SPA + 5) & 0x1))
inportb (SPA);
/* get first bit ready to go out */
sendbit = (outch & 0x1) ? 0xFF : 0x00;
/* loop to send and receive 8 bits */
do
{
outportb (SPA, sendbit); /* send out the bit */
/* get next bit ready to go out */
Mask <<= 1;
sendbit = (outch & Mask) ? 0xFF : 0x00;
/* shift input char over ready for next bit */
inch >>= 1;
/* loop to look for the incoming bit */
for (;;)
{
/* return if out of time */
if (*sysclk > M)
return 0xFF;
if (inportb (SPA + 5) & 0x01)
{
inch |= ((inportb (SPA) & 0x01) ? 0x80 : 0x00);
break;
}
}
}
while (Mask);
return inch; /* return the input char */
}
static uchar rom[8];
void
ReadRom(void)
{
int i;
uchar code;
TouchReset();
TouchByte(0x33);
for (i=0; i < 8; i++)
rom[i] = TouchByte(0xFF);
}
#define DEVICE_ID (uchar)rom[0]
#define SERIAL (unsigned long )(*((unsigned long *)(rom+1)))
#define CRC (uchar)rom[7]
uchar
ReadMem(uint address)
{
TouchReset();
TouchByte(0xCC);
TouchByte(0xF0);
TouchByte(address & 0x00FF);
TouchByte((address >> 8) & 0x00FF);
return TouchByte(0xFF);
}
void DumpMemory(void)
{
uint address;
TouchReset();
TouchByte(0xCC);
TouchByte(0xF0);
TouchByte(0x00);
TouchByte(0x00);
for (address = 0; address < 128; address++)
{
uchar asc[17];
asc[16] = '\0';
if(address % 16 == 0)
printf("\n%04X ",address);
printf("%02X ", (asc[address % 16] = TouchByte(0xFF)));
if(address % 16 == 15)
{
int i;
for (i = 0; i < 16; i++)
if (!isalnum(asc[i]))
asc[i] = '.';
printf("%16s",asc);
}
}
printf("\n");
TouchReset();
}
#define TB(x) printf("TouchByte(0x%02X)= 0x%02X\n", (x), TouchByte(x))
uchar WriteMem(uint address, uchar data)
{
uchar TA1, TA2, ES;
TA1 = (uchar)address;
TA2 = (uchar)(address >> 8);
/* Write to scratchpad */
TouchReset();
TouchByte(0xCC);
TouchByte(0x0F);
TouchByte(TA1);
TouchByte(TA2);
TouchByte(data);
/* Read from scratchpad */
TouchReset();
TouchByte(0xCC);
TouchByte(0xAA);
if ( TouchByte(0xFF) != TA1 )
printf("Error: Invalid LOW address return\n");
if ( TouchByte(0xFF) != TA2 )
printf("Error: Invalid HIGH address return\n");
if ( (ES = TouchByte(0xFF)) & 0x40)
printf("Error: Overflow\n");
if ( TouchByte(0xFF) != data)
printf("Invalid data returned\n");
/* COPY scratchpad */
TouchReset();
TouchByte(0xCC);
TouchByte(0x55);
TouchByte(TA1);
TouchByte(TA2);
TouchByte(ES);
return 0;
}
int
main()
{
uchar status;
uint address;
uchar data;
uint single;
uint portnum = 2;
char filename[150];
FILE *fp;
Setup(portnum); /* COM port number */
status = TouchReset();
printf("TouchReset: %s\n", TouchMemStatus[status]);
ReadRom();
printf("Device ID: %d, Serial number: %08lX\, CRC: 0x%0X\n",
DEVICE_ID, SERIAL, CRC);
for (;;)
{
fflush(stdin);
printf("1:Dump 2:Single 3:Polute 4:Load 5:Save mem. 6:Port num 7:Exit >>>");
switch(getchar())
{
case '1':
ReadRom();
printf("Device ID: %d, Serial number: %08lX\, CRC: 0x%0X\n",
DEVICE_ID, SERIAL, CRC);
DumpMemory();
break;
case '2':
printf("Address (hex):"); scanf("%x", &single);
printf("Data (hex):"); scanf("%x", &data);
printf("Writting : (%04x) <- %02x\n", single, data);
WriteMem(single, data);
break;
case '3':
printf("Data for polution (hex):"); scanf("%X", &data);
for(address = 0 ; address < 128; address++)
WriteMem(address, data);
break;
case '4':
printf("Filename to read:"); scanf("%s", filename);
fp = fopen(filename, "r");
if (fp == NULL)
{
perror(filename);
break;
}
for (address = 0; address < 128; address++)
{
fscanf(fp, "%x", &data);
printf("%02x%c", data,
address % 16 == 15 ? '\n' : ' ');
WriteMem(address, data);
}
fclose(fp);
break;
case '5':
printf("Filename to write:"); scanf("%s", filename);
fp = fopen(filename, "w");
if (fp == NULL)
{
perror(filename);
break;
}
for (address = 0; address < 128; address++)
{
data = ReadMem(address);
fprintf(fp, "%02x%c", data,
address % 16 == 15 ? '\n' : ' ');
}
fclose(fp);
break;
case '6':
printf("COM port number (1,2):");
scanf("%d", &portnum);
Setup(portnum); /* COM port number */
status = TouchReset();
printf("TouchReset: %s\n", TouchMemStatus[status]);
break;
case '7':
return 0;
default:
printf("Input error\n");
}
}
}