--- /dev/null
+#CC = sdcc
+CC = /home/johan/sdcc/bin/sdcc
+
+MFLAGS = -mds390 --model-flat24 --stack-10bit
+LFLAGS = --xram-loc 0x180080 --code-loc 0x10000 -Wl-r
+
+TARGETS = tstfind.hex temp.hex swtloop.hex swtoper.hex counter.hex \
+ tstow.hex thermodl.hex
+
+OW_OBJECTS = ownetu.rel owsesu.rel owllu.rel owlli.rel owtrnu.rel \
+ crcutil.rel tinilnk.rel findtype.rel ds2480ut.rel owfile.rel
+
+SENSOR_OBJECTS = temp10.rel swt12.rel cnt1d.rel thermo21.rel
+
+TINI_TEST_OBJECTS = time.rel
+
+all: ow.lib sensors.lib $(TINI_TEST_OBJECTS) $(TARGETS)
+
+ow.lib: $(OW_OBJECTS)
+ rm -f $@; \
+ for object in $(OW_OBJECTS) $(TINI_TEST_OBJECTS); do \
+ echo $$object >>$@; \
+ done;
+
+sensors.lib: $(SENSOR_OBJECTS)
+ rm -f $@; \
+ for object in $(SENSOR_OBJECTS); do \
+ echo $$object >>$@; \
+ done;
+
+clean:
+ rm -f core *~ \#* *.asm *.cdb *.rel *.hex *.ihx *.lst *.map \
+ *.rst *.sym *.lnk *.lib
+
+%.hex: ow.lib sensors.lib $(TINI_TEST_OBJECTS) %.rel
+ $(CC) $(MFLAGS) $(LFLAGS) $*.rel $(TINI_TEST_OBJECTS) \
+ -L . ow.lib sensors.lib
+ packihx $*.ihx >$@
+ #tinitalk -c execute $@
+
+%.rel: %.c
+ $(CC) -c $(MFLAGS) $<
--- /dev/null
+//---------------------------------------------------------------------------
+// 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.
+//---------------------------------------------------------------------------
+//
+// cnt1D.c - Module to read the DS2423 - counter.
+//
+// Version: 2.00
+//
+//
+#include "ownet.h"
+#include "cnt1d.h"
+
+//----------------------------------------------------------------------
+// Read the counter on a specified page of a DS2423.
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
+// indicate the symbolic port number.
+// 'SerialNum' - Serial Number of DS2423 that contains the counter
+// to be read
+// 'CounterPage' - page number that the counter is associated with
+// 'Count' - pointer to variable where that count will be returned
+//
+// Returns: TRUE(1) counter has been read and verified
+// FALSE(0) could not read the counter, perhaps device is not
+// in contact
+//
+int ReadCounter(int portnum, uchar SerialNum[8], int CounterPage,
+ unsigned long *Count)
+{
+ int rt=FALSE;
+ uchar send_block[30];
+ int send_cnt=0, address, i;
+ ushort lastcrc16;
+
+ setcrc16(portnum,0);
+
+ // set the device serial number to the counter device
+ owSerialNum(portnum,SerialNum,FALSE);
+
+ // access the device
+ if (owAccess(portnum))
+ {
+ // create a block to send that reads the counter
+ // read memory and counter command
+ send_block[send_cnt++] = 0xA5;
+ docrc16(portnum,0xA5);
+ // address of last data byte before counter
+ address = (CounterPage << 5) + 31; // (1.02)
+ send_block[send_cnt++] = (uchar)(address & 0xFF);
+ docrc16(portnum,(ushort)(address & 0xFF));
+ send_block[send_cnt++] = (uchar)(address >> 8);
+ docrc16(portnum,(ushort)(address >> 8));
+ // now add the read bytes for data byte,counter,zero bits, crc16
+ for (i = 0; i < 11; i++)
+ send_block[send_cnt++] = 0xFF;
+
+ // now send the block
+ if (owBlock(portnum,FALSE,send_block,send_cnt))
+ {
+ // perform the CRC16 on the last 11 bytes of packet
+ for (i = send_cnt - 11; i < send_cnt; i++)
+ lastcrc16 = docrc16(portnum,send_block[i]);
+
+ // verify CRC16 is correct
+ if (lastcrc16 == 0xB001)
+ {
+ // success
+ rt = TRUE;
+ // extract the counter value
+ *Count = 0;
+ for (i = send_cnt - 7; i >= send_cnt - 10; i--)
+ {
+ *Count <<= 8;
+ *Count |= send_block[i];
+ }
+ }
+ }
+ }
+
+ // return the result flag rt
+ return rt;
+}
--- /dev/null
+extern int ReadCounter(int, uchar *SerialNum, int, unsigned long *);
--- /dev/null
+//---------------------------------------------------------------------------
+// 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.
+//---------------------------------------------------------------------------
+//
+// counter.c - Application to read the 1-Wire Net DS2423 - counter.
+//
+// This application uses the files from the 'Public Domain'
+// 1-Wire Net libraries ('general' and 'userial').
+//
+// Version: 2.00
+//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "ownet.h"
+#include "cnt1d.h"
+
+// defines
+#define MAXDEVICES 20
+
+// local functions
+void PrintSerialNum(uchar *SerialNum);
+
+// local serial numbers
+static uchar FamilySN[MAXDEVICES][8];
+
+// tini hack
+int argc=2;
+char *argv[]={__FILE__, "exow"};
+
+//----------------------------------------------------------------------
+// Main Test for the DS2423 - counter
+//
+int main() //short argc, char **argv)
+{
+ char return_msg[128];
+ int NumDevices=0;
+ int i;
+ int CounterPage;
+ ulong Count;
+ int portnum=0;
+
+ //------------------------------------------------------
+ // Introduction header
+ printf("\n/---------------------------------------------\n");
+ printf(" Counter Application - V2.00\n"
+ " The following is a test to excersize a\n"
+ " DS2423 - counter \n\n");
+
+ printf(" Press any CTRL-C to stop this program.\n\n");
+ printf(" Output [Serial Number(s) ... Counter Value ... Counter Value ... "
+ "Counter Value ... Counter Value] \n\n");
+
+ // check for required port name
+ if (argc != 2)
+ {
+ printf("1-Wire Net name required on command line!\n"
+ " (example: \"COM1\" (Win32 DS2480),\"/dev/cua0\" "
+ "(Linux DS2480),\"1\" (Win32 TMEX)\n");
+ exit(1);
+ }
+
+ // attempt to acquire the 1-Wire Net
+ if (!owAcquire(portnum, argv[1], return_msg))
+ {
+ printf("%s",return_msg);
+ exit(1);
+ }
+
+ // success
+ printf("%s",return_msg);
+
+ // Find the device(s)
+ NumDevices = FindDevices(portnum, &FamilySN[0], 0x1D, MAXDEVICES);
+ if (NumDevices>0)
+ {
+ printf("\n");
+ printf("Device(s) Found: \n");
+ for (i = 0; i < NumDevices; i++)
+ {
+ PrintSerialNum(FamilySN[i]);
+ printf("\n");
+ }
+ printf("\n\n");
+
+ // (stops on CTRL-C)
+ do
+ {
+ // read the current counters
+ for (i = 0; i < NumDevices; i++)
+ {
+ printf("\n");
+ PrintSerialNum(FamilySN[i]);
+
+ for (CounterPage = 12; CounterPage <= 15; CounterPage++)
+ {
+ if (ReadCounter(portnum, FamilySN[i], CounterPage, &Count))
+ {
+ printf(" %10ld ", Count);
+ }
+ else
+ printf("\nError reading counter, verify device present:%d\n",
+ owVerify(portnum,FALSE));
+ }
+ }
+ printf("\n\n");
+ }
+ while (!key_abort());
+ }
+ else
+ printf("\n\n\n ERROR, device not found!\n");
+
+ // release the 1-Wire Net
+ owRelease(portnum,return_msg);
+ printf("%s",return_msg);
+ exit(0);
+
+ return 0;
+}
+
+// -------------------------------------------------------------------------------
+// Read and print the serial number
+//
+void PrintSerialNum(uchar *SerialNum)
+{
+ int i;
+
+ for (i = 7; i>=0; i--)
+ printf("%02X", SerialNum[i]);
+}
+
+
+
--- /dev/null
+//---------------------------------------------------------------------------
+// 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.
+//--------------------------------------------------------------------------
+//
+// crcutil.c - Keeps track of the CRC for 16 and 8 bit operations
+// version 2.00
+
+// tinihack, data is a reserved keyword for sdcc. So:
+#define data DaTa
+
+// Include files
+#include "ownet.h"
+
+// Local global variables
+static ushort utilcrc16[MAX_PORTNUM];
+static uchar utilcrc8[MAX_PORTNUM];
+static short oddparity[16] = { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 };
+static uchar dscrc_table[] = {
+ 0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,
+ 157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220,
+ 35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98,
+ 190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,
+ 70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7,
+ 219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154,
+ 101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36,
+ 248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185,
+ 140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205,
+ 17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80,
+ 175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238,
+ 50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115,
+ 202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139,
+ 87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22,
+ 233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,
+ 116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53};
+
+//--------------------------------------------------------------------------
+// Reset crc16 to the value passed in
+//
+// 'reset' - data to set crc16 to.
+//
+void setcrc16(int portnum, ushort reset)
+{
+ utilcrc16[portnum] = reset;
+ return;
+}
+
+//--------------------------------------------------------------------------
+// Reset crc8 to the value passed in
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
+// indicate the symbolic port number.
+// 'reset' - data to set crc8 to
+//
+void setcrc8(int portnum, uchar reset)
+{
+ utilcrc8[portnum] = reset;
+ return;
+}
+
+//--------------------------------------------------------------------------
+// Calculate a new CRC16 from the input data shorteger. Return the current
+// CRC16 and also update the global variable CRC16.
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
+// indicate the symbolic port number.
+// 'data' - data to perform a CRC16 on
+//
+// Returns: the current CRC16
+//
+ushort docrc16(int portnum, ushort data)
+{
+ data = (data ^ (utilcrc16[portnum] & 0xff)) & 0xff;
+ utilcrc16[portnum] >>= 8;
+
+ if (oddparity[data & 0xf] ^ oddparity[data >> 4])
+ utilcrc16[portnum] ^= 0xc001;
+
+ data <<= 6;
+ utilcrc16[portnum] ^= data;
+ data <<= 1;
+ utilcrc16[portnum] ^= data;
+
+ return utilcrc16[portnum];
+}
+
+//--------------------------------------------------------------------------
+// Update the Dallas Semiconductor One Wire CRC (utilcrc8) from the global
+// variable utilcrc8 and the argument.
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
+// indicate the symbolic port number.
+// 'x' - data byte to calculate the 8 bit crc from
+//
+// Returns: the updated utilcrc8.
+//
+uchar docrc8(int portnum, uchar x)
+{
+ utilcrc8[portnum] = dscrc_table[utilcrc8[portnum] ^ x];
+ return utilcrc8[portnum];
+}
--- /dev/null
+//---------------------------------------------------------------------------
+// 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.
+//---------------------------------------------------------------------------
+//
+// DS2480.H - This file contains the DS2480 constants
+//
+// Version: 2.00
+//
+// History: 1.02 -> 1.03 Make sure uchar is not defined twice.
+//
+//
+
+// Mode Commands
+#define MODE_DATA 0xE1
+#define MODE_COMMAND 0xE3
+#define MODE_STOP_PULSE 0xF1
+
+// Return byte value
+#define RB_CHIPID_MASK 0x1C
+#define RB_RESET_MASK 0x03
+#define RB_1WIRESHORT 0x00
+#define RB_PRESENCE 0x01
+#define RB_ALARMPRESENCE 0x02
+#define RB_NOPRESENCE 0x03
+
+#define RB_BIT_MASK 0x03
+#define RB_BIT_ONE 0x03
+#define RB_BIT_ZERO 0x00
+
+// Masks for all bit ranges
+#define CMD_MASK 0x80
+#define FUNCTSEL_MASK 0x60
+#define BITPOL_MASK 0x10
+#define SPEEDSEL_MASK 0x0C
+#define MODSEL_MASK 0x02
+#define PARMSEL_MASK 0x70
+#define PARMSET_MASK 0x0E
+
+// Command or config bit
+#define CMD_COMM 0x81
+#define CMD_CONFIG 0x01
+
+// Function select bits
+#define FUNCTSEL_BIT 0x00
+#define FUNCTSEL_SEARCHON 0x30
+#define FUNCTSEL_SEARCHOFF 0x20
+#define FUNCTSEL_RESET 0x40
+#define FUNCTSEL_CHMOD 0x60
+
+// Bit polarity/Pulse voltage bits
+#define BITPOL_ONE 0x10
+#define BITPOL_ZERO 0x00
+#define BITPOL_5V 0x00
+#define BITPOL_12V 0x10
+
+// One Wire speed bits
+#define SPEEDSEL_STD 0x00
+#define SPEEDSEL_FLEX 0x04
+#define SPEEDSEL_OD 0x08
+#define SPEEDSEL_PULSE 0x0C
+
+// Data/Command mode select bits
+#define MODSEL_DATA 0x00
+#define MODSEL_COMMAND 0x02
+
+// 5V Follow Pulse select bits (If 5V pulse
+// will be following the next byte or bit.)
+#define PRIME5V_TRUE 0x02
+#define PRIME5V_FALSE 0x00
+
+// Parameter select bits
+#define PARMSEL_PARMREAD 0x00
+#define PARMSEL_SLEW 0x10
+#define PARMSEL_12VPULSE 0x20
+#define PARMSEL_5VPULSE 0x30
+#define PARMSEL_WRITE1LOW 0x40
+#define PARMSEL_SAMPLEOFFSET 0x50
+#define PARMSEL_ACTIVEPULLUPTIME 0x60
+#define PARMSEL_BAUDRATE 0x70
+
+// Pull down slew rate.
+#define PARMSET_Slew15Vus 0x00
+#define PARMSET_Slew2p2Vus 0x02
+#define PARMSET_Slew1p65Vus 0x04
+#define PARMSET_Slew1p37Vus 0x06
+#define PARMSET_Slew1p1Vus 0x08
+#define PARMSET_Slew0p83Vus 0x0A
+#define PARMSET_Slew0p7Vus 0x0C
+#define PARMSET_Slew0p55Vus 0x0E
+
+// 12V programming pulse time table
+#define PARMSET_32us 0x00
+#define PARMSET_64us 0x02
+#define PARMSET_128us 0x04
+#define PARMSET_256us 0x06
+#define PARMSET_512us 0x08
+#define PARMSET_1024us 0x0A
+#define PARMSET_2048us 0x0C
+#define PARMSET_infinite 0x0E
+
+// 5V strong pull up pulse time table
+#define PARMSET_16p4ms 0x00
+#define PARMSET_65p5ms 0x02
+#define PARMSET_131ms 0x04
+#define PARMSET_262ms 0x06
+#define PARMSET_524ms 0x08
+#define PARMSET_1p05s 0x0A
+#define PARMSET_2p10s 0x0C
+#define PARMSET_infinite 0x0E
+
+// Write 1 low time
+#define PARMSET_Write8us 0x00
+#define PARMSET_Write9us 0x02
+#define PARMSET_Write10us 0x04
+#define PARMSET_Write11us 0x06
+#define PARMSET_Write12us 0x08
+#define PARMSET_Write13us 0x0A
+#define PARMSET_Write14us 0x0C
+#define PARMSET_Write15us 0x0E
+
+// Data sample offset and Write 0 recovery time
+#define PARMSET_SampOff3us 0x00
+#define PARMSET_SampOff4us 0x02
+#define PARMSET_SampOff5us 0x04
+#define PARMSET_SampOff6us 0x06
+#define PARMSET_SampOff7us 0x08
+#define PARMSET_SampOff8us 0x0A
+#define PARMSET_SampOff9us 0x0C
+#define PARMSET_SampOff10us 0x0E
+
+// Active pull up on time
+#define PARMSET_PullUp0p0us 0x00
+#define PARMSET_PullUp0p5us 0x02
+#define PARMSET_PullUp1p0us 0x04
+#define PARMSET_PullUp1p5us 0x06
+#define PARMSET_PullUp2p0us 0x08
+#define PARMSET_PullUp2p5us 0x0A
+#define PARMSET_PullUp3p0us 0x0C
+#define PARMSET_PullUp3p5us 0x0E
+
+// Baud rate bits
+#define PARMSET_9600 0x00
+#define PARMSET_19200 0x02
+#define PARMSET_57600 0x04
+#define PARMSET_115200 0x06
+
+// DS2480 program voltage available
+#define DS2480PROG_MASK 0x20
+
+// mode bit flags
+#define MODE_NORMAL 0x00
+#define MODE_OVERDRIVE 0x01
+#define MODE_STRONG5 0x02
+#define MODE_PROGRAM 0x04
+#define MODE_BREAK 0x08
+
+extern int DS2480Detect(int);
+extern int DS2480ChangeBaud(int, uchar);
+
+// global DS2480 state
+extern int ULevel[MAX_PORTNUM]; // current DS2480 1-Wire Net level
+extern int UBaud[MAX_PORTNUM]; // current DS2480 baud rate
+extern int UMode[MAX_PORTNUM]; // current DS2480 command or data mode state
+extern int USpeed[MAX_PORTNUM]; // current DS2480 1-Wire Net comm speed
+
--- /dev/null
+//---------------------------------------------------------------------------
+// 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.
+//---------------------------------------------------------------------------
+//
+// ds2480ut.c - DS2480 utility functions.
+//
+// Version: 2.00
+//
+// History: 1.00 -> 1.01 Default PDSRC changed from 0.83 to 1.37V/us
+// in DS2480Detect. Changed to use msDelay instead
+// of Delay.
+// 1.01 -> 1.02 Changed global declarations from 'uchar' to 'int'.
+// Changed DSO/WORT from 7 to 10us in DS2480Detect.
+// 1.02 -> 1.03 Removed caps in #includes for Linux capatibility
+// 1.03 -> 2.00 Changed 'MLan' to 'ow'. Added support for
+// multiple ports. Changed W1LT to 8us.
+
+#include "ownet.h"
+#include "ds2480.h"
+
+// global DS2480 state
+int ULevel[MAX_PORTNUM]; // current DS2480 1-Wire Net level
+int UBaud[MAX_PORTNUM]; // current DS2480 baud rate
+int UMode[MAX_PORTNUM]; // current DS2480 command or data mode state
+int USpeed[MAX_PORTNUM]; // current DS2480 1-Wire Net communication speed
+
+//---------------------------------------------------------------------------
+// Attempt to resyc and detect a DS2480
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
+// OpenCOM to indicate the port number.
+//
+// Returns: TRUE - DS2480 detected successfully
+// FALSE - Could not detect DS2480
+//
+int DS2480Detect(int portnum)
+{
+ uchar sendpacket[10],readbuffer[10];
+ short sendlen=0;
+ short rt=FALSE;
+
+ // reset modes
+ ULevel[portnum] = MODE_NORMAL;
+ UMode[portnum] = MODSEL_COMMAND;
+ UBaud[portnum] = PARMSET_9600;
+ USpeed[portnum] = SPEEDSEL_FLEX;
+
+ // set the baud rate to 9600
+ SetBaudCOM(portnum,(uchar)UBaud[portnum]);
+
+ // send a break to reset the DS2480
+ BreakCOM(portnum);
+
+ // delay to let line settle
+ msDelay(2);
+
+ // flush the buffers
+ FlushCOM(portnum);
+
+ // send the timing byte
+ sendpacket[0] = 0xC1;
+ if (WriteCOM(portnum,1,sendpacket) != 1)
+ return FALSE;
+
+ // set the FLEX configuration parameters
+ // default PDSRC = 1.37Vus
+ sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_SLEW | PARMSET_Slew1p37Vus;
+ // default W1LT = 8us
+ sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_WRITE1LOW | PARMSET_Write8us;
+ // default DSO/WORT = 10us
+ sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_SAMPLEOFFSET | PARMSET_SampOff10us;
+
+ // construct the command to read the baud rate (to test command block)
+ sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_PARMREAD | (PARMSEL_BAUDRATE >> 3);
+
+ // also do 1 bit operation (to test 1-Wire block)
+ sendpacket[sendlen++] = CMD_COMM | FUNCTSEL_BIT | UBaud[portnum] | BITPOL_ONE;
+
+ // flush the buffers
+ FlushCOM(portnum);
+
+ // send the packet
+ if (WriteCOM(portnum,sendlen,sendpacket))
+ {
+ // read back the response
+ if (ReadCOM(portnum,5,readbuffer) == 5)
+ {
+ // look at the baud rate and bit operation
+ // to see if the response makes sense
+ if (((readbuffer[3] & 0xF1) == 0x00) &&
+ ((readbuffer[3] & 0x0E) == UBaud[portnum]) &&
+ ((readbuffer[4] & 0xF0) == 0x90) &&
+ ((readbuffer[4] & 0x0C) == UBaud[portnum]))
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+//---------------------------------------------------------------------------
+// Change the DS2480 from the current baud rate to the new baud rate.
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
+// OpenCOM to indicate the port number.
+// 'newbaud' - the new baud rate to change to, defined as:
+// PARMSET_9600 0x00
+// PARMSET_19200 0x02
+// PARMSET_57600 0x04
+// PARMSET_115200 0x06
+//
+// Returns: current DS2480 baud rate.
+//
+int DS2480ChangeBaud(int portnum, uchar newbaud)
+{
+ int rt=FALSE;
+ uchar readbuffer[5],sendpacket[5],sendpacket2[5];
+ int sendlen=0,sendlen2=0;
+
+ // see if diffenent then current baud rate
+ if (UBaud[portnum] == newbaud)
+ return TRUE;
+ else
+ {
+ // build the command packet
+ // check if correct mode
+ if (UMode[portnum] != MODSEL_COMMAND)
+ {
+ UMode[portnum] = MODSEL_COMMAND;
+ sendpacket[sendlen++] = MODE_COMMAND;
+ }
+ // build the command
+ sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_BAUDRATE | newbaud;
+
+ // flush the buffers
+ FlushCOM(portnum);
+
+ // send the packet
+ if (!WriteCOM(portnum,sendlen,sendpacket))
+ rt = FALSE;
+ else
+ {
+ // make sure buffer is flushed
+ msDelay(5);
+
+ // change our baud rate
+ SetBaudCOM(portnum,newbaud);
+ UBaud[portnum] = newbaud;
+
+ // wait for things to settle
+ msDelay(5);
+
+ // build a command packet to read back baud rate
+ sendpacket2[sendlen2++] = CMD_CONFIG | PARMSEL_PARMREAD | (PARMSEL_BAUDRATE >> 3);
+
+ // flush the buffers
+ FlushCOM(portnum);
+
+ // send the packet
+ if (WriteCOM(portnum,sendlen2,sendpacket2))
+ {
+ // read back the 1 byte response
+ if (ReadCOM(portnum,1,readbuffer) == 1)
+ {
+ // verify correct baud
+ if (((readbuffer[0] & 0x0E) == (sendpacket[sendlen-1] & 0x0E)))
+ rt = TRUE;
+ }
+ }
+ }
+ }
+
+ // if lost communication with DS2480 then reset
+ if (rt != TRUE)
+ DS2480Detect(portnum);
+
+ return UBaud[portnum];
+}
--- /dev/null
+//---------------------------------------------------------------------------
+// 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.
+//---------------------------------------------------------------------------
+//
+// findtype.c - Test module to find all devices of one type.
+//
+// Version: 2.00
+//
+//----------------------------------------------------------------------
+//
+//
+#include "ownet.h"
+
+//----------------------------------------------------------------------
+// Search for devices
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
+// indicate the symbolic port number.
+//
+// Returns: TRUE(1) success, device type found
+// FALSE(0) device not found
+//
+int FindDevices(int portnum, uchar FamilySN[][8], int family_code, int MAXDEVICES)
+{
+ int NumDevices=0;
+ int TotalDevices=0;
+
+ // find the devices
+ // set the search to first find that family code
+ owFamilySearchSetup(portnum,family_code);
+
+ // loop to find all of the devices up to MAXDEVICES
+ NumDevices = 0;
+ do
+ {
+ // perform the search
+ if (!owNext(portnum,TRUE, FALSE))
+ break;
+ owSerialNum(portnum,FamilySN[NumDevices], TRUE);
+ if (FamilySN[NumDevices][0] == family_code)
+ {
+ NumDevices++;
+ }
+ }
+ while (NumDevices < (MAXDEVICES - 1));
+
+ // check if not at least 1 device
+ return NumDevices;
+}
--- /dev/null
+//---------------------------------------------------------------------------
+// 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.
+//---------------------------------------------------------------------------
+//
+// owFile.C: Rudimentary level functions for reading and writing TMEX
+// files on NVRAM iButton using the packet level functions.
+//
+// Version: 2.00
+//
+// History:
+// 1.02 -> 1.03 Removed caps in #includes for Linux capatibility
+// 1.03 -> 2.00 Changed 'MLan' to 'ow'. Added support for
+// multiple ports.
+//
+
+#include "ownet.h"
+
+//--------------------------------------------------------------------------
+// Read a TMEX file return it in the provided buffer.
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
+// OpenCOM to indicate the port number.
+// 'filename' - pointer to five byte filename to read where the
+// the first four bytes are the name and the fifth is
+// the extension (0 to 101 decimal).
+// 'buf' - pointer to a buffer to place the file information into.
+// This may need to be as large as 7084 bytes.
+//
+// Supported devices: All devices supported by owReadPacketStd
+//
+// Returns: >=0 success, number of bytes in the buffer
+// <0 failed to read the file (error code)
+//
+int owReadFile(int portnum, uchar *filename, uchar *buf)
+{
+ uchar dirpg=0,pgbuf[32],filepg=0,pglen;
+ short bufcnt=0,i;
+
+ // loop read directory pages until the file entry is found
+ do
+ {
+ // read a directory page
+ pglen = owReadPacketStd(portnum,TRUE,dirpg,pgbuf);
+
+ // check for reading error
+ if (pglen <= 0)
+ return READ_ERROR;
+
+ // if this is the first page make sure this is a directory
+ // structure
+ if ( ((dirpg == 0) &&
+ ((pgbuf[0] != 0xAA) || (pgbuf[1] != 0) || (pglen < 7)))
+ ||
+ ((pglen-1) % 7) )
+ return INVALID_DIR;
+
+ // loop through each file entry in directory page (page 0 exception)
+ for (i = (dirpg == 0) ? 7 : 0; i < 28; i += 7)
+ {
+ // file entry found?
+ if ((filename[0] == pgbuf[i]) &&
+ (filename[1] == pgbuf[i+1]) &&
+ (filename[2] == pgbuf[i+2]) &&
+ (filename[3] == pgbuf[i+3]) &&
+ (filename[4] == (pgbuf[i+4] & 0x7F)) )
+ {
+ // get the file starting page number
+ filepg = pgbuf[i+5];
+ break;
+ }
+ }
+
+ // get the next directory page (from page pointer)
+ dirpg = pgbuf[pglen-1];
+ }
+ while (dirpg && (filepg == 0));
+
+ // check if file found
+ if (!filepg)
+ return NO_FILE;
+
+ // loop to read the file pages
+ do
+ {
+ // read a file page
+ pglen = owReadPacketStd(portnum,TRUE,filepg,pgbuf);
+
+ // check result of read
+ if (pglen <= 0)
+ return READ_ERROR;
+
+ // append the page data to the buffer
+ for (i = 0; i < (pglen - 1); i++)
+ buf[bufcnt++] = pgbuf[i];
+
+ // get the next file page (from page pointer)
+ filepg = pgbuf[pglen-1];
+ }
+ while (filepg);
+
+ // return the number of data bytes read
+ return bufcnt;
+}
+
+
+//--------------------------------------------------------------------------
+// Format and Write a TMEX file.
+// Any previous files will be removed in the Format operation.
+// The file length 'fllen' can be up to:
+// 420 bytes for a DS1993
+// 1736 bytes for a DS1995
+// 7084 bytes for a DS1996.
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
+// OpenCOM to indicate the port number.
+// 'filename' - pointer to five byte filename to write where the
+// the first four bytes are the name and the fifth is
+// the extension (0 to 101 decimal).
+// 'buf' - pointer to a buffer containing the file information to write.
+//
+// Supported devices: DS1993, DS1994, DS1995, DS1996
+//
+// Returns: TRUE(1) success, device formated and file written
+// <0 failed to read the file (error code)
+//
+//
+int owFormatWriteFile(int portnum, uchar *filename, int fllen, uchar *buf)
+{
+ uchar dummydir[] = { 0xAA, 0, 0x80, 0x01, 0, 0, 0, 0 },
+ newdir[] = { 0xAA, 0, 0x80, 0x01, 0, 0, 0, ' ', ' ', ' ', ' ', 0, 1, 1, 0 },
+ bmpg1[] = { 0x03,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x02 },
+ bmpg2[] = { 0,0,0,0,0 }, pgbuf[32];
+ int i,numdirpgs,flpg,bmpg1len,bmpg2len,cntleft,pos,numpgs;
+
+ // calculate the number of pages needed to write the file
+ numpgs = (fllen / 28) + ((fllen % 28) ? 1 : 0);
+
+ // put the file in the newdirectory
+ for(i = 0; i < 5; i++)
+ newdir[i+7] = filename[i];
+ newdir[13] = (uchar)numpgs;
+
+ // set the directory pages for formatting device depending on the device type
+ switch (SerialNum[portnum][0]) //jpe
+ {
+ case 0x06: // DS1993
+ // check for file too big
+ if (numpgs > 15)
+ return FILE_TOO_BIG;
+ // set the bitmap in the directory page
+ for (i = 0; i < numpgs; i++)
+ bitacc(WRITE_FUNCTION,1,i+1,&newdir[3]);
+ numdirpgs = 1;
+ flpg = 1;
+ newdir[12] = (uchar)flpg;
+ break;
+ case 0x0A: // DS1995
+ // check for file too big
+ if (numpgs > 62)
+ return FILE_TOO_BIG;
+ // set to external bitmap file
+ newdir[2] = 0;
+ // set the bitmap in the first (and only) bitmap page
+ for (i = 0; i < numpgs; i++)
+ bitacc(WRITE_FUNCTION,1,i+2,&bmpg1[0]);
+ numdirpgs = 2;
+ flpg = 2;
+ newdir[12] = (uchar)flpg; // startpage
+ bmpg1len = 9;
+ newdir[3] = 0; // remove local bitmap
+ newdir[5] = 1; // bitmap start page
+ newdir[6] = 1; // bitmap number of pages
+ break;
+ case 0x0C: // DS1996
+ // check for file too big
+ if (numpgs > 253)
+ return FILE_TOO_BIG;
+ // set to external bitmap file
+ newdir[2] = 0;
+ // set the 3rd bitmap page in the bitmap
+ bitacc(WRITE_FUNCTION,1,2,&bmpg1[0]);
+
+ // set the bitmap in the first and second bitmap page
+ for (i = 0; i < numpgs; i++)
+ {
+ if (i <= 221)
+ bitacc(WRITE_FUNCTION,1,i+3,&bmpg1[0]);
+ else
+ bitacc(WRITE_FUNCTION,1,i-221,&bmpg2[0]);
+ }
+ numdirpgs = 3;
+ flpg = 3;
+ newdir[12] = (uchar)flpg; // startpage
+ bmpg1len = 29;
+ bmpg2len = 5;
+ newdir[3] = 0; // remove local bitmap
+ newdir[5] = 1; // bitmap start page
+ newdir[6] = 2; // bitmap number of pages
+ break;
+ default:
+ return WRONG_TYPE;
+ }
+
+ // write a dummy directory in page 0 in case we get interrupted
+ if (!owWritePacketStd(portnum,0,dummydir,8,FALSE,FALSE))
+ return WRITE_ERROR;
+
+ // loop to write the file in contiguous pages start with flpg
+ cntleft = fllen; // count of bytes left to write
+ pos = 0; // current position in the buffer to write
+ while (cntleft > 0)
+ {
+ // get a page of data to write
+ for (i = 0; i < ((cntleft > 28) ? 28 : cntleft); i++)
+ pgbuf[i] = buf[pos++];
+
+ // adjust the bytes left
+ cntleft -= i;
+
+ // set the next page pointer
+ pgbuf[i] = (cntleft == 0) ? 0 : flpg+1;
+
+ // write the page and check to result
+ if (!owWritePacketStd(portnum,flpg,pgbuf,i+1,FALSE,FALSE))
+ return WRITE_ERROR;
+
+ // set the next page
+ flpg++;
+ }
+
+ // now write the second bitmap page if needed
+ if (numdirpgs == 3)
+ if (!owWritePacketStd(portnum,2,bmpg2,bmpg2len,FALSE,FALSE))
+ return WRITE_ERROR;
+
+ // now write the first bitmap page if needed
+ if (numdirpgs >= 2)
+ if (!owWritePacketStd(portnum,1,bmpg1,bmpg1len,FALSE,FALSE))
+ return WRITE_ERROR;
+
+ // now write the directory page
+ if (!owWritePacketStd(portnum,0,newdir,15,FALSE,FALSE))
+ return WRITE_ERROR;
+
+ // success file written
+ return TRUE;
+}
+
--- /dev/null
+//---------------------------------------------------------------------------
+// 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.
+//---------------------------------------------------------------------------
+//
+// iow.c
+//
+// Minimal access routines for TINI internal one-wire bus patched together
+// from Dallas example code (hence the copyright notice above).
+//
+// Kevin Vigor, 11/20/2000
+
+#include <stdio.h>
+#include "ownet.h"
+
+/* The internal 1-wire bus is hooked to P3.5, a.k.a T1 */
+/* The "activity" LED is also hooked to this line. */
+#define INT_OW_PORT T1
+
+// local variables for this module to hold search state information
+static int LastDiscrepancy;
+static int LastFamilyDiscrepancy;
+static int LastDevice;
+static unsigned char iSerialNum[8];
+
+static uchar iowTouchBit(uchar);
+static uchar iowTouchByte(uchar);
+
+//--------------------------------------------------------------------------
+// Reset all of the devices on the 1-Wire Net and return the result.
+//
+// Returns: TRUE(1): presense pulse(s) detected, device(s) reset
+// FALSE(0): no presense pulses detected
+//
+unsigned char iowTouchReset(void)
+{
+ unsigned char result;
+
+ //printf ("iowTouchReset(): ");
+
+ /* Code stolen straight from appnote 126. */
+ INT_OW_PORT = 0; /* drive bus low. */
+ ClockMicroSecondsDelay(480);
+ INT_OW_PORT = 1; /* bus high. */
+ ClockMicroSecondsDelay(120);
+ result = INT_OW_PORT; /* get presence detect pulse. */
+ ClockMicroSecondsDelay(360);
+
+ //printf ("%d\n", result);
+ return result;
+}
+
+//--------------------------------------------------------------------------
+// Send 1 bit of communication to the 1-Wire Net and return the
+// result 1 bit read from the 1-Wire Net. The parameter 'sendbit'
+// least significant bit is used and the least significant bit
+// of the result is the return bit.
+//
+// Returns: 0: 0 bit read from sendbit
+// 1: 1 bit read from sendbit
+//
+static unsigned char iowTouchBit(unsigned char sendbit)
+{
+ unsigned char result;
+
+ INT_OW_PORT = 0; /* start timeslot. */
+ ClockMicroSecondsDelay(1);
+
+ INT_OW_PORT = sendbit; /* send bit out. */
+ ClockMicroSecondsDelay(9);
+ result = INT_OW_PORT; /* sample result @ 10 us. */
+ ClockMicroSecondsDelay(50);
+ INT_OW_PORT = 1; /* timeslot done. */
+ ClockMicroSecondsDelay(5);
+
+ return result;
+}
+
+//--------------------------------------------------------------------------
+// Send 8 bits of communication to the 1-Wire Net and return the
+// result 8 bits read from the 1-Wire Net. The parameter 'sendbyte'
+// least significant 8 bits are used and the least significant 8 bits
+// of the result is the return byte.
+//
+// 'sendbyte' - 8 bits to send (least significant byte)
+//
+// Returns: 8 bytes read from sendbyte
+//
+static unsigned char iowTouchByte(unsigned char sendbyte)
+{
+ unsigned char i;
+ unsigned char result = 0;
+
+ //printf ("iowTouchByte(%02x): ", sendbyte);
+
+ for (i = 0; i < 8; i++)
+ {
+ result |= (iowTouchBit(sendbyte & 1) << i);
+ sendbyte >>= 1;
+ }
+
+ //printf ("%02x\n", result);
+ return result;
+}
+
+//--------------------------------------------------------------------------
+// Send 8 bits of communication to the 1-Wire Net and verify that the
+// 8 bits read from the 1-Wire Net is the same (write operation).
+// The parameter 'sendbyte' least significant 8 bits are used.
+//
+// 'sendbyte' - 8 bits to send (least significant byte)
+//
+// Returns: TRUE: bytes written and echo was the same
+// FALSE: echo was not the same
+//
+unsigned char iowWriteByte(unsigned char sendbyte)
+{
+ return (iowTouchByte(sendbyte) == sendbyte) ? TRUE : FALSE;
+}
+
+//--------------------------------------------------------------------------
+// The 'owBlock' transfers a block of data to and from the
+// 1-Wire Net with an optional reset at the begining of communication.
+// The result is returned in the same buffer.
+//
+// 'do_reset' - cause a owTouchReset to occure at the begining of
+// communication TRUE(1) or not FALSE(0)
+// 'tran_buf' - pointer to a block of unsigned
+// chars of length 'TranferLength' that will be sent
+// to the 1-Wire Net
+// 'tran_len' - length in bytes to transfer
+
+// Supported devices: all
+//
+// Returns: TRUE (1) : The optional reset returned a valid
+// presence (do_reset == TRUE) or there
+// was no reset required.
+// FALSE (0): The reset did not return a valid prsence
+// (do_reset == TRUE).
+//
+// The maximum tran_len is 64
+//
+unsigned char iowBlock(unsigned char do_reset,
+ unsigned char *tran_buf,
+ unsigned char tran_len)
+{
+ int i;
+
+ // check for a block too big
+ if (tran_len > 64)
+ return FALSE;
+
+ // check if need to do a owTouchReset first
+ if (do_reset)
+ {
+ if (!iowTouchReset())
+ return FALSE;
+ }
+
+ // send and receive the buffer
+ for (i = 0; i < tran_len; i++)
+ tran_buf[i] = iowTouchByte(tran_buf[i]);
+
+ return TRUE;
+}
+
+//--------------------------------------------------------------------------
+// Send 8 bits of read communication to the 1-Wire Net and and return the
+// result 8 bits read from the 1-Wire Net.
+//
+// Returns: 8 bytes read from 1-Wire Net
+//
+unsigned char iowReadByte(void)
+{
+ return iowTouchByte(0xFF);
+}
+
+//--------------------------------------------------------------------------
+// The 'owFirst' finds the first device on the 1-Wire Net This function
+// contains one parameter 'alarm_only'. When
+// 'alarm_only' is TRUE (1) the find alarm command 0xEC is
+// sent instead of the normal search command 0xF0.
+// Using the find alarm command 0xEC will limit the search to only
+// 1-Wire devices that are in an 'alarm' state.
+//
+// 'do_reset' - TRUE (1)
+// perform reset before search.
+// 'alarm_only' - TRUE (1) the find alarm command 0xEC is
+// sent instead of the normal search command 0xF0
+//
+// Returns: TRUE (1) : when a 1-Wire device was found and it's
+// Serial Number placed in the global iSerialNum[portnum]
+// FALSE (0): There are no devices on the 1-Wire Net.
+//
+unsigned char iowFirst(unsigned char do_reset, unsigned char alarm_only)
+{
+ // reset the search state
+ LastDiscrepancy = 0;
+ LastDevice = FALSE;
+ LastFamilyDiscrepancy = 0;
+
+ return iowNext(do_reset,alarm_only);
+}
+
+//--------------------------------------------------------------------------
+// The 'owNext' function does a general search. This function
+// continues from the previos search state. The search state
+// can be reset by using the 'owFirst' function.
+// This function contains one parameter 'alarm_only'.
+// When 'alarm_only' is TRUE (1) the find alarm command
+// 0xEC is sent instead of the normal search command 0xF0.
+// Using the find alarm command 0xEC will limit the search to only
+// 1-Wire devices that are in an 'alarm' state.
+//
+// 'do_reset' - TRUE (1) perform reset before search, FALSE (0) do not
+// perform reset before search.
+// 'alarm_only' - TRUE (1) the find alarm command 0xEC is
+// sent instead of the normal search command 0xF0
+//
+// Returns: TRUE (1) : when a 1-Wire device was found and it's
+// Serial Number placed in the global iSerialNum[portnum]
+// FALSE (0): when no new device was found. Either the
+// last search was the last device or there
+// are no devices on the 1-Wire Net.
+//
+unsigned char iowNext(unsigned char do_reset, unsigned char alarm_only)
+{
+ int bit_test, search_direction, bit_number;
+ int last_zero, serial_byte_number, next_result;
+ unsigned char serial_byte_mask;
+ unsigned char lastcrc8;
+
+ //printf ("iowNext(%d,%d)\n", do_reset, alarm_only);
+
+ // initialize for search
+ bit_number = 1;
+ last_zero = 0;
+ serial_byte_number = 0;
+ serial_byte_mask = 1;
+ next_result = 0;
+ lastcrc8 = 0;
+
+ // if the last call was not the last one
+ if (!LastDevice)
+ {
+ // check if reset first is requested
+ if (do_reset)
+ {
+ // reset the 1-wire
+ // if there are no parts on 1-wire, return FALSE
+ if (!iowTouchReset())
+ {
+ // reset the search
+ LastDiscrepancy = 0;
+ LastFamilyDiscrepancy = 0;
+ return FALSE;
+ }
+ }
+
+ // If finding alarming devices issue a different command
+ if (alarm_only)
+ iowWriteByte(0xEC); // issue the alarming search command
+ else
+ iowWriteByte(0xF0); // issue the search command
+
+ // loop to do the search
+ do
+ {
+ // read a bit and its compliment
+ bit_test = iowTouchBit(1) << 1;
+ bit_test |= iowTouchBit(1);
+
+ // check for no devices on 1-wire
+ if (bit_test == 3)
+ {
+ break;
+ }
+ else
+ {
+ // all devices coupled have 0 or 1
+ if (bit_test > 0)
+ {
+ search_direction = !(bit_test & 0x01); // bit write value for search
+ }
+ else
+ {
+ // if this discrepancy if before the Last Discrepancy
+ // on a previous next then pick the same as last time
+ if (bit_number < LastDiscrepancy)
+ search_direction = ((iSerialNum[serial_byte_number] & serial_byte_mask) > 0);
+ else
+ // if equal to last pick 1, if not then pick 0
+ search_direction = (bit_number == LastDiscrepancy);
+
+ // if 0 was picked then record its position in LastZero
+ if (search_direction == 0)
+ last_zero = bit_number;
+
+ // check for Last discrepancy in family
+ if (last_zero < 9)
+ LastFamilyDiscrepancy = last_zero;
+ }
+
+ // set or clear the bit in the iSerialNum byte serial_byte_number
+ // with mask serial_byte_mask
+ if (search_direction == 1)
+ iSerialNum[serial_byte_number] |= serial_byte_mask;
+ else
+ iSerialNum[serial_byte_number] &= ~serial_byte_mask;
+
+ // serial number search direction write bit
+ iowTouchBit(search_direction);
+
+ // increment the byte counter bit_number
+ // and shift the mask serial_byte_mask
+ bit_number++;
+ serial_byte_mask <<= 1;
+
+ // if the mask is 0 then go to new iSerialNum byte serial_byte_number
+ // and reset mask
+ if (serial_byte_mask == 0)
+ {
+ lastcrc8 = docrc8(lastcrc8,iSerialNum[serial_byte_number]); // accumulate the CRC
+ serial_byte_number++;
+ serial_byte_mask = 1;
+ }
+ }
+ }
+ while(serial_byte_number < 8); // loop until through all iSerialNum bytes 0-7
+
+ // if the search was successful then
+ if (!((bit_number < 65) || lastcrc8))
+ {
+ // search successful so set LastDiscrepancy,LastDevice,next_result
+ LastDiscrepancy = last_zero;
+ LastDevice = (LastDiscrepancy == 0);
+ next_result = TRUE;
+ }
+ }
+
+ // if no device found then reset counters so next 'next' will be
+ // like a first
+ if (!next_result || !iSerialNum[0])
+ {
+ LastDiscrepancy = 0;
+ LastDevice = FALSE;
+ LastFamilyDiscrepancy = 0;
+ next_result = FALSE;
+ }
+
+ return next_result;
+}
+
+//--------------------------------------------------------------------------
+// The 'owSerialNum' function either reads or sets the SerialNum buffer
+// that is used in the search functions 'owFirst' and 'owNext'.
+// This function contains two parameters, 'serialnum_buf' is a pointer
+// to a buffer provided by the caller. 'serialnum_buf' should point to
+// an array of 8 unsigned chars. The second parameter is a flag called
+// 'do_read' that is TRUE (1) if the operation is to read and FALSE
+// (0) if the operation is to set the internal SerialNum buffer from
+// the data in the provided buffer.
+//
+// 'serialnum_buf' - buffer to that contains the serial number to set
+// when do_read = FALSE (0) and buffer to get the serial
+// number when do_read = TRUE (1).
+// 'do_read' - flag to indicate reading (1) or setting (0) the current
+// serial number.
+//
+void iowSerialNum(unsigned char *serialnum_buf, unsigned char do_read)
+{
+ int i;
+
+ // read the internal buffer and place in 'serialnum_buf'
+ if (do_read)
+ {
+ for (i = 0; i < 8; i++)
+ {
+ serialnum_buf[i] = iSerialNum[i];
+ }
+ }
+ // set the internal buffer from the data in 'serialnum_buf'
+ else
+ {
+ for (i = 0; i < 8; i++)
+ {
+ iSerialNum[i] = serialnum_buf[i];
+ }
+ }
+}
+
+// unsupported routines
+
+uchar iowSpeed(int speed) {
+ speed; // hush the compiler
+ printf ("No owSpeed for internal ow yet\n");
+ return FALSE;
+}
+
+uchar iowLevel(int level) {
+ level; // hush the compiler
+ printf ("No owLevel for internal ow yet\n");
+ return FALSE;
+}
+
+uchar iowProgramPulse() {
+ printf ("No owProgramPulse for internal ow yet\n");
+ return FALSE;
+}
--- /dev/null
+//---------------------------------------------------------------------------
+// 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.
+//---------------------------------------------------------------------------
+//
+// owLLU.C - Link Layer 1-Wire Net functions using the DS2480/DS2480B (U)
+// serial interface chip.
+//
+// Version: 2.00
+//
+// History: 1.00 -> 1.01 DS2480 version number now ignored in
+// owTouchReset.
+// 1.02 -> 1.03 Removed caps in #includes for Linux capatibility
+// Removed #include <windows.h>
+// Add #include "ownet.h" to define TRUE,FALSE
+// 1.03 -> 2.00 Changed 'MLan' to 'ow'. Added support for
+// multiple ports.
+
+#include "ownet.h"
+#include "ds2480.h"
+
+// local varable flag, true if program voltage available
+static int ProgramAvailable[MAX_PORTNUM];
+
+//--------------------------------------------------------------------------
+// Reset all of the devices on the 1-Wire Net and return the result.
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
+// OpenCOM to indicate the port number.
+//
+// Returns: TRUE(1): presense pulse(s) detected, device(s) reset
+// FALSE(0): no presense pulses detected
+//
+// WARNING: This routine will not function correctly on some
+// Alarm reset types of the DS1994/DS1427/DS2404 with
+// Rev 1,2, and 3 of the DS2480/DS2480B.
+//
+int owTouchReset(int portnum)
+{
+ uchar readbuffer[10],sendpacket[10];
+ int sendlen=0;
+
+ // make sure normal level
+ owLevel(portnum,MODE_NORMAL);
+
+ // check if correct mode
+ if (UMode[portnum] != MODSEL_COMMAND)
+ {
+ UMode[portnum] = MODSEL_COMMAND;
+ sendpacket[sendlen++] = MODE_COMMAND;
+ }
+
+ // construct the command
+ sendpacket[sendlen++] = (uchar)(CMD_COMM | FUNCTSEL_RESET | USpeed[portnum]);
+
+ // flush the buffers
+ FlushCOM(portnum);
+
+ // send the packet
+ if (WriteCOM(portnum,sendlen,sendpacket))
+ {
+ // read back the 1 byte response
+ if (ReadCOM(portnum,1,readbuffer) == 1)
+ {
+ // make sure this byte looks like a reset byte
+ if (((readbuffer[0] & RB_RESET_MASK) == RB_PRESENCE) ||
+ ((readbuffer[0] & RB_RESET_MASK) == RB_ALARMPRESENCE))
+ {
+ // check if programming voltage available
+ ProgramAvailable[portnum] = ((readbuffer[0] & 0x20) == 0x20);
+ return TRUE;
+ }
+ else
+ return FALSE;
+ }
+ }
+
+ // an error occured so re-sync with DS2480
+ DS2480Detect(portnum);
+
+ return FALSE;
+}
+
+//--------------------------------------------------------------------------
+// Send 1 bit of communication to the 1-Wire Net and return the
+// result 1 bit read from the 1-Wire Net. The parameter 'sendbit'
+// least significant bit is used and the least significant bit
+// of the result is the return bit.
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
+// OpenCOM to indicate the port number.
+// 'sendbit' - the least significant bit is the bit to send
+//
+// Returns: 0: 0 bit read from sendbit
+// 1: 1 bit read from sendbit
+//
+int owTouchBit(int portnum, int sendbit)
+{
+ uchar readbuffer[10],sendpacket[10];
+ int sendlen=0;
+
+ // make sure normal level
+ owLevel(portnum,MODE_NORMAL);
+
+ // check if correct mode
+ if (UMode[portnum] != MODSEL_COMMAND)
+ {
+ UMode[portnum] = MODSEL_COMMAND;
+ sendpacket[sendlen++] = MODE_COMMAND;
+ }
+
+ // construct the command
+ sendpacket[sendlen] = (sendbit != 0) ? BITPOL_ONE : BITPOL_ZERO;
+ sendpacket[sendlen++] |= CMD_COMM | FUNCTSEL_BIT | USpeed[portnum];
+
+ // flush the buffers
+ FlushCOM(portnum);
+
+ // send the packet
+ if (WriteCOM(portnum,sendlen,sendpacket))
+ {
+ // read back the response
+ if (ReadCOM(portnum,1,readbuffer) == 1)
+ {
+ // interpret the response
+ if (((readbuffer[0] & 0xE0) == 0x80) &&
+ ((readbuffer[0] & RB_BIT_MASK) == RB_BIT_ONE))
+ return 1;
+ else
+ return 0;
+ }
+ }
+
+ // an error occured so re-sync with DS2480
+ DS2480Detect(portnum);
+
+ return 0;
+}
+
+//--------------------------------------------------------------------------
+// Send 8 bits of communication to the 1-Wire Net and verify that the
+// 8 bits read from the 1-Wire Net is the same (write operation).
+// The parameter 'sendbyte' least significant 8 bits are used.
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
+// OpenCOM to indicate the port number.
+// 'sendbyte' - 8 bits to send (least significant byte)
+//
+// Returns: TRUE: bytes written and echo was the same
+// FALSE: echo was not the same
+//
+int owWriteByte(int portnum, int sendbyte)
+{
+ return (owTouchByte(portnum,sendbyte) == sendbyte) ? TRUE : FALSE;
+}
+
+
+//--------------------------------------------------------------------------
+// Send 8 bits of read communication to the 1-Wire Net and and return the
+// result 8 bits read from the 1-Wire Net.
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
+// OpenCOM to indicate the port number.
+//
+// Returns: 8 bytes read from 1-Wire Net
+//
+int owReadByte(int portnum)
+{
+ return owTouchByte(portnum,0xFF);
+}
+
+//--------------------------------------------------------------------------
+// Send 8 bits of communication to the 1-Wire Net and return the
+// result 8 bits read from the 1-Wire Net. The parameter 'sendbyte'
+// least significant 8 bits are used and the least significant 8 bits
+// of the result is the return byte.
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
+// OpenCOM to indicate the port number.
+// 'sendbyte' - 8 bits to send (least significant byte)
+//
+// Returns: 8 bytes read from sendbyte
+//
+int owTouchByte(int portnum, int sendbyte)
+{
+ uchar readbuffer[10],sendpacket[10];
+ int sendlen=0;
+
+ // make sure normal level
+ owLevel(portnum,MODE_NORMAL);
+
+ // check if correct mode
+ if (UMode[portnum] != MODSEL_DATA)
+ {
+ UMode[portnum] = MODSEL_DATA;
+ sendpacket[sendlen++] = MODE_DATA;
+ }
+
+ // add the byte to send
+ sendpacket[sendlen++] = (uchar)sendbyte;
+
+ // check for duplication of data that looks like COMMAND mode
+ if (sendbyte == MODE_COMMAND)
+ sendpacket[sendlen++] = (uchar)sendbyte;
+
+ // flush the buffers
+ FlushCOM(portnum);
+
+ // send the packet
+ if (WriteCOM(portnum,sendlen,sendpacket))
+ {
+ // read back the 1 byte response
+ if (ReadCOM(portnum,1,readbuffer) == 1)
+ {
+ // return the response
+ return (int)readbuffer[0];
+ }
+ }
+
+ // an error occured so re-sync with DS2480
+ DS2480Detect(portnum);
+
+ return 0;
+}
+
+//--------------------------------------------------------------------------
+// Set the 1-Wire Net communucation speed.
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
+// OpenCOM to indicate the port number.
+// 'new_speed' - new speed defined as
+// MODE_NORMAL 0x00
+// MODE_OVERDRIVE 0x01
+//
+// Returns: current 1-Wire Net speed
+//
+int owSpeed(int portnum, int new_speed)
+{
+ uchar sendpacket[5];
+ short sendlen=0;
+ int rt = FALSE;
+
+ // check if change from current mode
+ if (((new_speed == MODE_OVERDRIVE) &&
+ (USpeed[portnum] != SPEEDSEL_OD)) ||
+ ((new_speed == MODE_NORMAL) &&
+ (USpeed[portnum] != SPEEDSEL_FLEX)))
+ {
+ if (new_speed == MODE_OVERDRIVE)
+ {
+ // if overdrive then switch to 115200 baud
+ if (DS2480ChangeBaud(portnum,PARMSET_115200) == PARMSET_115200)
+ {
+ USpeed[portnum] = SPEEDSEL_OD;
+ rt = TRUE;
+ }
+ }
+ else if (new_speed == MODE_NORMAL)
+ {
+ // else normal so set to 9600 baud
+ if (DS2480ChangeBaud(portnum,PARMSET_9600) == PARMSET_9600)
+ {
+ USpeed[portnum] = SPEEDSEL_FLEX;
+ rt = TRUE;
+ }
+ }
+
+ // if baud rate is set correctly then change DS2480 speed
+ if (rt)
+ {
+ // check if correct mode
+ if (UMode[portnum] != MODSEL_COMMAND)
+ {
+ UMode[portnum] = MODSEL_COMMAND;
+ sendpacket[sendlen++] = MODE_COMMAND;
+ }
+
+ // proceed to set the DS2480 communication speed
+ sendpacket[sendlen++] = CMD_COMM | FUNCTSEL_SEARCHOFF | USpeed[portnum];
+
+ // send the packet
+ if (!WriteCOM(portnum,sendlen,sendpacket))
+ {
+ rt = FALSE;
+ // lost communication with DS2480 then reset
+ DS2480Detect(portnum);
+ }
+ }
+ }
+
+ // return the current speed
+ return (USpeed[portnum] == SPEEDSEL_OD) ? MODE_OVERDRIVE : MODE_NORMAL;
+}
+
+//--------------------------------------------------------------------------
+// Set the 1-Wire Net line level. The values for new_level are
+// as follows:
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
+// OpenCOM to indicate the port number.
+// 'new_level' - new level defined as
+// MODE_NORMAL 0x00
+// MODE_STRONG5 0x02
+// MODE_PROGRAM 0x04
+// MODE_BREAK 0x08 (not supported)
+//
+// Returns: current 1-Wire Net level
+//
+int owLevel(int portnum, int new_level)
+{
+ uchar sendpacket[10],readbuffer[10];
+ short sendlen=0;
+ short rt=FALSE;
+
+ // check if need to change level
+ if (new_level != ULevel[portnum])
+ {
+ // check if just putting back to normal
+ if (new_level == MODE_NORMAL)
+ {
+ // check if correct mode
+ if (UMode[portnum] != MODSEL_COMMAND)
+ {
+ UMode[portnum] = MODSEL_COMMAND;
+ sendpacket[sendlen++] = MODE_COMMAND;
+ }
+
+ // stop pulse command
+ sendpacket[sendlen++] = MODE_STOP_PULSE;
+
+ // flush the buffers
+ FlushCOM(portnum);
+
+ // send the packet
+ if (WriteCOM(portnum,sendlen,sendpacket))
+ {
+ // read back the 1 byte response
+ if (ReadCOM(portnum,1,readbuffer) == 1)
+ {
+ // check response byte
+ if ((readbuffer[0] & 0xE0) == 0xE0)
+ {
+ rt = TRUE;
+ ULevel[portnum] = MODE_NORMAL;
+ }
+ }
+ }
+ }
+ // set new level
+ else
+ {
+ // check if correct mode
+ if (UMode[portnum] != MODSEL_COMMAND)
+ {
+ UMode[portnum] = MODSEL_COMMAND;
+ sendpacket[sendlen++] = MODE_COMMAND;
+ }
+
+ // strong 5 volts
+ if (new_level == MODE_STRONG5)
+ {
+ // set the SPUD time value
+ sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_5VPULSE | PARMSET_infinite;
+ // add the command to begin the pulse
+ sendpacket[sendlen++] = CMD_COMM | FUNCTSEL_CHMOD | SPEEDSEL_PULSE | BITPOL_5V;
+ }
+ // 12 volts
+ else if (new_level == MODE_PROGRAM)
+ {
+ // check if programming voltage available
+ if (!ProgramAvailable[portnum])
+ return MODE_NORMAL;
+
+ // set the PPD time value
+ sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_12VPULSE | PARMSET_infinite;
+ // add the command to begin the pulse
+ sendpacket[sendlen++] = CMD_COMM | FUNCTSEL_CHMOD | SPEEDSEL_PULSE | BITPOL_12V;
+ }
+
+ // flush the buffers
+ FlushCOM(portnum);
+
+ // send the packet
+ if (WriteCOM(portnum,sendlen,sendpacket))
+ {
+ // read back the 1 byte response from setting time limit
+ if (ReadCOM(portnum,1,readbuffer) == 1)
+ {
+ // check response byte
+ if ((readbuffer[0] & 0x81) == 0)
+ {
+ ULevel[portnum] = new_level;
+ rt = TRUE;
+ }
+ }
+ }
+ }
+
+ // if lost communication with DS2480 then reset
+ if (rt != TRUE)
+ DS2480Detect(portnum);
+ }
+
+ // return the current level
+ return ULevel[portnum];
+}
+
+//--------------------------------------------------------------------------
+// This procedure creates a fixed 480 microseconds 12 volt pulse
+// on the 1-Wire Net for programming EPROM iButtons.
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
+// OpenCOM to indicate the port number.
+//
+// Returns: TRUE successful
+// FALSE program voltage not available
+//
+int owProgramPulse(int portnum)
+{
+ uchar sendpacket[10],readbuffer[10];
+ short sendlen=0;
+
+ // check if programming voltage available
+ if (!ProgramAvailable[portnum])
+ return FALSE;
+
+ // make sure normal level
+ owLevel(portnum,MODE_NORMAL);
+
+ // check if correct mode
+ if (UMode[portnum] != MODSEL_COMMAND)
+ {
+ UMode[portnum] = MODSEL_COMMAND;
+ sendpacket[sendlen++] = MODE_COMMAND;
+ }
+
+ // set the SPUD time value
+ sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_12VPULSE | PARMSET_512us;
+
+ // pulse command
+ sendpacket[sendlen++] = CMD_COMM | FUNCTSEL_CHMOD | BITPOL_12V | SPEEDSEL_PULSE;
+
+ // flush the buffers
+ FlushCOM(portnum);
+
+ // send the packet
+ if (WriteCOM(portnum,sendlen,sendpacket))
+ {
+ // read back the 2 byte response
+ if (ReadCOM(portnum,2,readbuffer) == 2)
+ {
+ // check response byte
+ if (((readbuffer[0] | CMD_CONFIG) ==
+ (CMD_CONFIG | PARMSEL_12VPULSE | PARMSET_512us)) &&
+ ((readbuffer[1] & 0xFC) ==
+ (0xFC & (CMD_COMM | FUNCTSEL_CHMOD | BITPOL_12V | SPEEDSEL_PULSE))))
+ return TRUE;
+ }
+ }
+
+ // an error occured so re-sync with DS2480
+ DS2480Detect(portnum);
+
+ return FALSE;
+}
--- /dev/null
+//---------------------------------------------------------------------------
+// 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.
+//---------------------------------------------------------------------------
+//
+// ownet.h - Include file for 1-Wire Net library
+//
+// Version: 2.00
+//
+// History: 1.02 -> 1.03 Make sure uchar is not defined twice.
+// 1.03 -> 2.00 Changed 'MLan' to 'ow'.
+//
+
+// Typedefs
+#ifndef OW_UCHAR
+#define OW_UCHAR
+ typedef unsigned char uchar;
+ typedef unsigned int ushort;
+ typedef unsigned long ulong;
+#endif
+
+// general defines
+#define WRITE_FUNCTION 1
+#define READ_FUNCTION 0
+
+// error codes
+#define READ_ERROR -1
+#define INVALID_DIR -2
+#define NO_FILE -3
+#define WRITE_ERROR -4
+#define WRONG_TYPE -5
+#define FILE_TOO_BIG -6
+
+// Misc
+#define FALSE 0
+#define TRUE 1
+#define MAX_PORTNUM 16
+
+// mode bit flags
+#define MODE_NORMAL 0x00
+#define MODE_OVERDRIVE 0x01
+#define MODE_STRONG5 0x02
+#define MODE_PROGRAM 0x04
+#define MODE_BREAK 0x08
+
+// family codes of devices
+#define DIR_FAMILY 0x01
+#define TEMP_FAMILY 0x10
+#define SWITCH_FAMILY 0x12
+#define COUNT_FAMILY 0x1D
+#define ATOD_FAMILY 0X20
+#define THERMO_FAM 0x21
+// this is weird, the DS2502 should be 0x09
+#define DS2502_FAMILY 0x89
+
+// tinilnk.c
+extern void FlushCOM(int);
+extern int WriteCOM(int,int,uchar*);
+extern int ReadCOM(int,int,uchar*);
+extern void BreakCOM(int);
+extern void SetBaudCOM(int,int);
+extern void msDelay(int);
+extern long msGettick(void);
+extern int OpenCOM(int,char *);
+extern void CloseCOM(int);
+
+// ownetu.c
+extern int owFirst(int,int,int);
+extern int owNext(int,int,int);
+extern void owSerialNum(int,uchar *, int);
+extern void owFamilySearchSetup(int,int);
+extern void owSkipFamily(int);
+extern int owAccess(int);
+extern int owVerify(int,int);
+extern int owOverdriveAccess(int);
+extern int bitacc(int,int,int,uchar *);
+extern uchar SerialNum[MAX_PORTNUM][8];
+
+// owtrnu.c
+extern int owBlock(int,int,uchar *,int);
+extern int owReadPacketStd(int,int,int,uchar *);
+extern int owWritePacketStd(int,int,uchar *,int,int,int);
+extern int owProgramByte(int,int,int,int,int,int);
+
+// crcutil.c
+extern void setcrc16(int,ushort);
+extern ushort docrc16(int,ushort);
+extern void setcrc8(int,uchar);
+extern uchar docrc8(int,uchar);
+
+// owllu.c
+extern int owTouchReset(int);
+extern int owTouchByte(int, int);
+extern int owWriteByte(int,int);
+extern int owReadByte(int);
+extern int owSpeed(int,int);
+extern int owLevel(int,int);
+extern int owProgramPulse(int);
+
+// owlli for the internal (TINI) ow bus
+extern uchar iowTouchReset(void);
+extern uchar iowReadByte(void);
+extern uchar iowWriteByte(uchar);
+extern uchar iowBlock(uchar, uchar*, uchar);
+extern uchar iowFirst(uchar do_reset, uchar alarm_only);
+extern uchar iowNext(uchar do_reset, uchar alarm_only);
+extern uchar iowSpeed(int speed);
+extern uchar iowLevel(int level);
+extern uchar iowProgramPulse(void);
+extern void iowSerialNum(uchar *, uchar);
+
+// owsesu.c
+extern int owAcquire(int,char *, char *);
+//extern int owAcquire(int,char *);
+extern void owRelease(int, char *);
+//extern void owRelease(int);
+
+// findtype.c
+extern int FindDevices(int, uchar FamilySN[][8], int, int);
+
+// offile.c
+int owReadFile(int,uchar *,uchar *);
+int owFormatWriteFile(int,uchar *, int, uchar *);
+
+// sdcc has no exit
+#define exit return
+// sdcc has no double
+#define double float
+// sdcc has no key_abort
+#define key_abort Serial0CharArrived
--- /dev/null
+//---------------------------------------------------------------------------
+// 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.
+//---------------------------------------------------------------------------
+//
+// owNetU.C - Network functions for 1-Wire Net devices
+// using the DS2480/DS2480B (U) serial interface chip.
+//
+// Version: 2.00
+//
+// 1.02 -> 1.03 Removed caps in #includes for Linux capatibility
+// 1.03 -> 2.00 Changed 'MLan' to 'ow'. Added support for
+// multiple ports.
+//
+
+#include "ownet.h"
+#include "ds2480.h"
+
+// local functions
+static int bitacc(int,int,int,uchar *);
+
+// globally used
+uchar SerialNum[MAX_PORTNUM][8];
+
+// local variables for this module to hold search state information
+static int LastDiscrepancy[MAX_PORTNUM];
+static int LastFamilyDiscrepancy[MAX_PORTNUM];
+static int LastDevice[MAX_PORTNUM];
+
+//--------------------------------------------------------------------------
+// The 'owFirst' finds the first device on the 1-Wire Net This function
+// contains one parameter 'alarm_only'. When
+// 'alarm_only' is TRUE (1) the find alarm command 0xEC is
+// sent instead of the normal search command 0xF0.
+// Using the find alarm command 0xEC will limit the search to only
+// 1-Wire devices that are in an 'alarm' state.
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
+// indicate the symbolic port number.
+// 'do_reset' - TRUE (1) perform reset before search, FALSE (0) do not
+// perform reset before search.
+// 'alarm_only' - TRUE (1) the find alarm command 0xEC is
+// sent instead of the normal search command 0xF0
+//
+// Returns: TRUE (1) : when a 1-Wire device was found and it's
+// Serial Number placed in the global SerialNum
+// FALSE (0): There are no devices on the 1-Wire Net.
+//
+int owFirst(int portnum, int do_reset, int alarm_only)
+{
+ // reset the search state
+ LastDiscrepancy[portnum] = 0;
+ LastDevice[portnum] = FALSE;
+ LastFamilyDiscrepancy[portnum] = 0;
+
+ return owNext(portnum, do_reset, alarm_only);
+}
+
+//--------------------------------------------------------------------------
+// The 'owNext' function does a general search. This function
+// continues from the previos search state. The search state
+// can be reset by using the 'owFirst' function.
+// This function contains one parameter 'alarm_only'.
+// When 'alarm_only' is TRUE (1) the find alarm command
+// 0xEC is sent instead of the normal search command 0xF0.
+// Using the find alarm command 0xEC will limit the search to only
+// 1-Wire devices that are in an 'alarm' state.
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
+// OpenCOM to indicate the port number.
+// 'do_reset' - TRUE (1) perform reset before search, FALSE (0) do not
+// perform reset before search.
+// 'alarm_only' - TRUE (1) the find alarm command 0xEC is
+// sent instead of the normal search command 0xF0
+//
+// Returns: TRUE (1) : when a 1-Wire device was found and it's
+// Serial Number placed in the global SerialNum
+// FALSE (0): when no new device was found. Either the
+// last search was the last device or there
+// are no devices on the 1-Wire Net.
+//
+int owNext(int portnum, int do_reset, int alarm_only)
+{
+ int i,tmp_last_desc,pos;
+ uchar tmp_serial_num[8];
+ uchar readbuffer[20],sendpacket[40];
+ int sendlen=0;
+ uchar lastcrc8;
+
+ // if the last call was the last one
+ if (LastDevice[portnum])
+ {
+ // reset the search
+ LastDiscrepancy[portnum] = 0;
+ LastDevice[portnum] = FALSE;
+ LastFamilyDiscrepancy[portnum] = 0;
+ return FALSE;
+ }
+
+ // check if reset first is requested
+ if (do_reset)
+ {
+ // reset the 1-wire
+ // if there are no parts on 1-wire, return FALSE
+ if (!owTouchReset(portnum))
+ {
+ // reset the search
+ LastDiscrepancy[portnum] = 0;
+ LastFamilyDiscrepancy[portnum] = 0;
+ return FALSE;
+ }
+ }
+
+ // build the command stream
+ // call a function that may add the change mode command to the buff
+ // check if correct mode
+ if (UMode[portnum] != MODSEL_DATA)
+ {
+ UMode[portnum] = MODSEL_DATA;
+ sendpacket[sendlen++] = MODE_DATA;
+ }
+
+ // search command
+ if (alarm_only)
+ sendpacket[sendlen++] = 0xEC; // issue the alarming search command
+ else
+ sendpacket[sendlen++] = 0xF0; // issue the search command
+
+ // change back to command mode
+ UMode[portnum] = MODSEL_COMMAND;
+ sendpacket[sendlen++] = MODE_COMMAND;
+
+ // search mode on
+ sendpacket[sendlen++] = (uchar)(CMD_COMM | FUNCTSEL_SEARCHON | USpeed[portnum]);
+
+ // change back to data mode
+ UMode[portnum] = MODSEL_DATA;
+ sendpacket[sendlen++] = MODE_DATA;
+
+ // set the temp Last Descrep to none
+ tmp_last_desc = 0xFF;
+
+ // add the 16 bytes of the search
+ pos = sendlen;
+ for (i = 0; i < 16; i++)
+ sendpacket[sendlen++] = 0;
+
+ // only modify bits if not the first search
+ if (LastDiscrepancy[portnum] != 0xFF)
+ {
+ // set the bits in the added buffer
+ for (i = 0; i < 64; i++)
+ {
+ // before last discrepancy
+ if (i < (LastDiscrepancy[portnum] - 1))
+ bitacc(WRITE_FUNCTION,
+ bitacc(READ_FUNCTION,0,i,&SerialNum[portnum][0]),
+ (short)(i * 2 + 1),
+ &sendpacket[pos]);
+ // at last discrepancy
+ else if (i == (LastDiscrepancy[portnum] - 1))
+ bitacc(WRITE_FUNCTION,1,
+ (short)(i * 2 + 1),
+ &sendpacket[pos]);
+ // after last discrepancy so leave zeros
+ }
+ }
+
+ // change back to command mode
+ UMode[portnum] = MODSEL_COMMAND;
+ sendpacket[sendlen++] = MODE_COMMAND;
+
+ // search OFF
+ sendpacket[sendlen++] = (uchar)(CMD_COMM | FUNCTSEL_SEARCHOFF | USpeed[portnum]);
+
+ // flush the buffers
+ FlushCOM(portnum);
+
+ // send the packet
+ if (WriteCOM(portnum,sendlen,sendpacket))
+ {
+ // read back the 1 byte response
+ if (ReadCOM(portnum,17,readbuffer) == 17)
+ {
+ // interpret the bit stream
+ for (i = 0; i < 64; i++)
+ {
+ // get the SerialNum bit
+ bitacc(WRITE_FUNCTION,
+ bitacc(READ_FUNCTION,0,(short)(i * 2 + 1),&readbuffer[1]),
+ i,
+ &tmp_serial_num[0]);
+ // check LastDiscrepancy
+ if ((bitacc(READ_FUNCTION,0,(short)(i * 2),&readbuffer[1]) == 1) &&
+ (bitacc(READ_FUNCTION,0,(short)(i * 2 + 1),&readbuffer[1]) == 0))
+ {
+ tmp_last_desc = i + 1;
+ // check LastFamilyDiscrepancy
+ if (i < 8)
+ LastFamilyDiscrepancy[portnum] = i + 1;
+ }
+ }
+
+ // do dowcrc
+ setcrc8(portnum,0);
+ for (i = 0; i < 8; i++)
+ lastcrc8 = docrc8(portnum,tmp_serial_num[i]);
+
+ // check results
+ if ((lastcrc8 != 0) || (LastDiscrepancy[portnum] == 63) || (tmp_serial_num[0] == 0))
+ {
+ // error during search
+ // reset the search
+ LastDiscrepancy[portnum] = 0;
+ LastDevice[portnum] = FALSE;
+ LastFamilyDiscrepancy[portnum] = 0;
+ return FALSE;
+ }
+ // successful search
+ else
+ {
+ // check for lastone
+ if ((tmp_last_desc == LastDiscrepancy[portnum]) || (tmp_last_desc == 0xFF))
+ LastDevice[portnum] = TRUE;
+
+ // copy the SerialNum to the buffer
+ for (i = 0; i < 8; i++)
+ SerialNum[portnum][i] = tmp_serial_num[i];
+
+ // set the count
+ LastDiscrepancy[portnum] = tmp_last_desc;
+ return TRUE;
+ }
+ }
+ }
+
+ // an error occured so re-sync with DS2480
+ DS2480Detect(portnum);
+
+ // reset the search
+ LastDiscrepancy[portnum] = 0;
+ LastDevice[portnum] = FALSE;
+ LastFamilyDiscrepancy[portnum] = 0;
+
+ return FALSE;
+}
+
+//--------------------------------------------------------------------------
+// The 'owSerialNum' function either reads or sets the SerialNum buffer
+// that is used in the search functions 'owFirst' and 'owNext'.
+// This function contains two parameters, 'serialnum_buf' is a pointer
+// to a buffer provided by the caller. 'serialnum_buf' should point to
+// an array of 8 unsigned chars. The second parameter is a flag called
+// 'do_read' that is TRUE (1) if the operation is to read and FALSE
+// (0) if the operation is to set the internal SerialNum buffer from
+// the data in the provided buffer.
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
+// OpenCOM to indicate the port number.
+// 'serialnum_buf' - buffer to that contains the serial number to set
+// when do_read = FALSE (0) and buffer to get the serial
+// number when do_read = TRUE (1).
+// 'do_read' - flag to indicate reading (1) or setting (0) the current
+// serial number.
+//
+void owSerialNum(int portnum, uchar *serialnum_buf, int do_read)
+{
+ int i;
+
+ // read the internal buffer and place in 'serialnum_buf'
+ if (do_read)
+ {
+ for (i = 0; i < 8; i++)
+ serialnum_buf[i] = SerialNum[portnum][i];
+ }
+ // set the internal buffer from the data in 'serialnum_buf'
+ else
+ {
+ for (i = 0; i < 8; i++)
+ SerialNum[portnum][i] = serialnum_buf[i];
+ }
+}
+
+//--------------------------------------------------------------------------
+// Setup the search algorithm to find a certain family of devices
+// the next time a search function is called 'owNext'.
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
+// OpenCOM to indicate the port number.
+// 'search_family' - family code type to set the search algorithm to find
+// next.
+//
+void owFamilySearchSetup(int portnum, int search_family)
+{
+ int i;
+
+ // set the search state to find search_family type devices
+ SerialNum[portnum][0] = (uchar)search_family;
+ for (i = 1; i < 8; i++)
+ SerialNum[portnum][i] = 0;
+ LastDiscrepancy[portnum] = 64;
+ LastDevice[portnum] = FALSE;
+}
+
+//--------------------------------------------------------------------------
+// Set the current search state to skip the current family code.
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
+// OpenCOM to indicate the port number.
+//
+void owSkipFamily(int portnum)
+{
+ // set the Last discrepancy to last family discrepancy
+ LastDiscrepancy[portnum] = LastFamilyDiscrepancy[portnum];
+
+ // check for end of list
+ if (LastDiscrepancy[portnum] == 0)
+ LastDevice[portnum] = TRUE;
+}
+
+//--------------------------------------------------------------------------
+// The 'owAccess' function resets the 1-Wire and sends a MATCH Serial
+// Number command followed by the current SerialNum code. After this
+// function is complete the 1-Wire device is ready to accept device-specific
+// commands.
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
+// OpenCOM to indicate the port number.
+//
+// Returns: TRUE (1) : reset indicates present and device is ready
+// for commands.
+// FALSE (0): reset does not indicate presence or echos 'writes'
+// are not correct.
+//
+int owAccess(int portnum)
+{
+ uchar sendpacket[9];
+ int i;
+
+ // reset the 1-wire
+ if (owTouchReset(portnum))
+ {
+ // create a buffer to use with block function
+ // match Serial Number command 0x55
+ sendpacket[0] = 0x55;
+ // Serial Number
+ for (i = 1; i < 9; i++)
+ sendpacket[i] = SerialNum[portnum][i-1];
+
+ // send/recieve the transfer buffer
+ if (owBlock(portnum,FALSE,sendpacket,9))
+ {
+ // verify that the echo of the writes was correct
+ for (i = 1; i < 9; i++)
+ if (sendpacket[i] != SerialNum[portnum][i-1])
+ return FALSE;
+ if (sendpacket[0] != 0x55)
+ return FALSE;
+ else
+ return TRUE;
+ }
+ }
+
+ // reset or match echo failed
+ return FALSE;
+}
+
+//----------------------------------------------------------------------
+// The function 'owVerify' verifies that the current device
+// is in contact with the 1-Wire Net.
+// Using the find alarm command 0xEC will verify that the device
+// is in contact with the 1-Wire Net and is in an 'alarm' state.
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
+// OpenCOM to indicate the port number.
+// 'alarm_only' - TRUE (1) the find alarm command 0xEC
+// is sent instead of the normal search
+// command 0xF0.
+//
+// Returns: TRUE (1) : when the 1-Wire device was verified
+// to be on the 1-Wire Net
+// with alarm_only == FALSE
+// or verified to be on the 1-Wire Net
+// AND in an alarm state when
+// alarm_only == TRUE.
+// FALSE (0): the 1-Wire device was not on the
+// 1-Wire Net or if alarm_only
+// == TRUE, the device may be on the
+// 1-Wire Net but in a non-alarm state.
+//
+int owVerify(int portnum, int alarm_only)
+{
+ int i,sendlen=0,goodbits=0,cnt=0,s,tst;
+ uchar sendpacket[50];
+
+ // construct the search rom
+ if (alarm_only)
+ sendpacket[sendlen++] = 0xEC; // issue the alarming search command
+ else
+ sendpacket[sendlen++] = 0xF0; // issue the search command
+ // set all bits at first
+ for (i = 1; i <= 24; i++)
+ sendpacket[sendlen++] = 0xFF;
+ // now set or clear apropriate bits for search
+ for (i = 0; i < 64; i++)
+ bitacc(WRITE_FUNCTION,bitacc(READ_FUNCTION,0,i,&SerialNum[portnum][0]),(int)((i+1)*3-1),&sendpacket[1]);
+
+ // send/recieve the transfer buffer
+ if (owBlock(portnum,TRUE,sendpacket,sendlen))
+ {
+ // check results to see if it was a success
+ for (i = 0; i < 192; i += 3)
+ {
+ tst = (bitacc(READ_FUNCTION,0,i,&sendpacket[1]) << 1) |
+ bitacc(READ_FUNCTION,0,(int)(i+1),&sendpacket[1]);
+
+ s = bitacc(READ_FUNCTION,0,cnt++,&SerialNum[portnum][0]);
+
+ if (tst == 0x03) // no device on line
+ {
+ goodbits = 0; // number of good bits set to zero
+ break; // quit
+ }
+
+ if (((s == 0x01) && (tst == 0x02)) ||
+ ((s == 0x00) && (tst == 0x01)) ) // correct bit
+ goodbits++; // count as a good bit
+ }
+
+ // check too see if there were enough good bits to be successful
+ if (goodbits >= 8)
+ return TRUE;
+ }
+
+ // block fail or device not present
+ return FALSE;
+}
+
+//----------------------------------------------------------------------
+// Perform a overdrive MATCH command to select the 1-Wire device with
+// the address in the ID data register.
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
+// OpenCOM to indicate the port number.
+//
+// Returns: TRUE: If the device is present on the 1-Wire Net and
+// can do overdrive then the device is selected.
+// FALSE: Device is not present or not capable of overdrive.
+//
+// *Note: This function could be converted to send DS2480
+// commands in one packet.
+//
+int owOverdriveAccess(int portnum)
+{
+ uchar sendpacket[8];
+ int i, bad_echo = FALSE;
+
+ // make sure normal level
+ owLevel(portnum,MODE_NORMAL);
+
+ // force to normal communication speed
+ owSpeed(portnum,MODE_NORMAL);
+
+ // call the 1-Wire Net reset function
+ if (owTouchReset(portnum))
+ {
+ // send the match command 0x69
+ if (owWriteByte(portnum,0x69))
+ {
+ // switch to overdrive communication speed
+ owSpeed(portnum,MODE_OVERDRIVE);
+
+ // create a buffer to use with block function
+ // Serial Number
+ for (i = 0; i < 8; i++)
+ sendpacket[i] = SerialNum[portnum][i];
+
+ // send/recieve the transfer buffer
+ if (owBlock(portnum,FALSE,sendpacket,8))
+ {
+ // verify that the echo of the writes was correct
+ for (i = 0; i < 8; i++)
+ if (sendpacket[i] != SerialNum[portnum][i])
+ bad_echo = TRUE;
+ // if echo ok then success
+ if (!bad_echo)
+ return TRUE;
+ }
+ }
+ }
+
+ // failure, force back to normal communication speed
+ owSpeed(portnum,MODE_NORMAL);
+
+ return FALSE;
+}
+
+//--------------------------------------------------------------------------
+// Bit utility to read and write a bit in the buffer 'buf'.
+//
+// 'op' - operation (1) to set and (0) to read
+// 'state' - set (1) or clear (0) if operation is write (1)
+// 'loc' - bit number location to read or write
+// 'buf' - pointer to array of bytes that contains the bit
+// to read or write
+//
+// Returns: 1 if operation is set (1)
+// 0/1 state of bit number 'loc' if operation is reading
+//
+int bitacc(int op, int state, int loc, uchar *buf)
+{
+ int nbyt,nbit;
+
+ nbyt = (loc / 8);
+ nbit = loc - (nbyt * 8);
+
+ if (op == WRITE_FUNCTION)
+ {
+ if (state)
+ buf[nbyt] |= (0x01 << nbit);
+ else
+ buf[nbyt] &= ~(0x01 << nbit);
+
+ return 1;
+ }
+ else
+ return ((buf[nbyt] >> nbit) & 0x01);
+}
--- /dev/null
+//---------------------------------------------------------------------------
+// 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.
+//---------------------------------------------------------------------------
+//
+// owSesU.C - Acquire and release a Session on the 1-Wire Net.
+//
+// Version: 2.00
+//
+// History: 1.03 -> 2.00 Changed 'MLan' to 'ow'. Added support for
+// multiple ports.
+
+#include <stdio.h>
+#include "ownet.h"
+#include "ds2480.h"
+
+// keep port name for later message when closing
+static char portname[MAX_PORTNUM][128];
+
+//---------------------------------------------------------------------------
+// Attempt to acquire a 1-Wire net using a com port and a DS2480 based
+// adapter.
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
+// OpenCOM to indicate the port number.
+// 'port_zstr' - zero terminated port name. For this platform
+// use format COMX where X is the port number.
+// 'return_msg' - zero terminated return message.
+//
+// Returns: TRUE - success, COM port opened
+//
+int owAcquire(int portnum, char *port_zstr, char *return_msg)
+{
+ int cnt=0;
+ portname[portnum][0] = 0;
+
+ // attempt to open the communications port
+ if (OpenCOM(portnum,port_zstr))
+ cnt += sprintf(&return_msg[cnt],"%s opened\n",port_zstr);
+ else
+ {
+ cnt += sprintf(&return_msg[cnt],"Could not open port %s,"
+ " aborting.\nClosing port %s.\n",port_zstr,port_zstr);
+ return FALSE;
+ }
+ printf (return_msg); // TODO: tini hack
+
+ // detect DS2480
+ if (DS2480Detect(portnum))
+ cnt += sprintf(&return_msg[cnt],"DS2480-based adapter detected\n");
+ else
+ {
+ cnt += sprintf(&return_msg[cnt],"DS2480-based adapter not detected, aborting program\n");
+ cnt += sprintf(&return_msg[cnt],"Closing port %s.\n",port_zstr);
+ CloseCOM(portnum);
+ return FALSE;
+ }
+
+ // success
+ sprintf(portname[portnum],"%s",port_zstr);
+ return TRUE;
+}
+
+//---------------------------------------------------------------------------
+// Release the previously acquired a 1-Wire net.
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
+// OpenCOM to indicate the port number.
+// 'return_msg' - zero terminated return message.
+//
+void owRelease(int portnum, char *return_msg)
+{
+ // close the communications port
+ sprintf(return_msg,"Closing port %s.\n",portname[portnum]);
+ CloseCOM(portnum);
+}
--- /dev/null
+//---------------------------------------------------------------------------
+// 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.
+//---------------------------------------------------------------------------
+//
+// owTranU.C - Transport functions for 1-Wire Net
+// using the DS2480 (U) serial interface chip.
+//
+// Version: 2.00
+//
+// History: 1.02 -> 1.03 Removed caps in #includes for Linux capatibility
+// 1.03 -> 2.00 Changed 'MLan' to 'ow'. Added support for
+// multiple ports.
+//
+
+#include "ownet.h"
+#include "ds2480.h"
+
+// local functions
+static int Write_Scratchpad(int,uchar *,int,int);
+static int Copy_Scratchpad(int,int,int);
+
+//--------------------------------------------------------------------------
+// The 'owBlock' transfers a block of data to and from the
+// 1-Wire Net with an optional reset at the begining of communication.
+// The result is returned in the same buffer.
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
+// indicate the symbolic port number.
+// 'do_reset' - cause a owTouchReset to occure at the begining of
+// communication TRUE(1) or not FALSE(0)
+// 'tran_buf' - pointer to a block of unsigned
+// chars of length 'tran_len' that will be sent
+// to the 1-Wire Net
+// 'tran_len' - length in bytes to transfer
+
+// Supported devices: all
+//
+// Returns: TRUE (1) : The optional reset returned a valid
+// presence (do_reset == TRUE) or there
+// was no reset required.
+// FALSE (0): The reset did not return a valid prsence
+// (do_reset == TRUE).
+//
+// The maximum tran_length is 64
+//
+int owBlock(int portnum, int do_reset, uchar *tran_buf, int tran_len)
+{
+ uchar sendpacket[150];
+ int sendlen=0,pos,i;
+
+ // check for a block too big
+ if (tran_len > 64)
+ return FALSE;
+
+ // check if need to do a owTouchReset first
+ if (do_reset)
+ {
+ if (!owTouchReset(portnum))
+ return FALSE;
+ }
+
+ // construct the packet to send to the DS2480
+ // check if correct mode
+ if (UMode[portnum] != MODSEL_DATA)
+ {
+ UMode[portnum] = MODSEL_DATA;
+ sendpacket[sendlen++] = MODE_DATA;
+ }
+
+ // add the bytes to send
+ pos = sendlen;
+ for (i = 0; i < tran_len; i++)
+ {
+ sendpacket[sendlen++] = tran_buf[i];
+
+ // check for duplication of data that looks like COMMAND mode
+ if (tran_buf[i] == MODE_COMMAND)
+ sendpacket[sendlen++] = tran_buf[i];
+ }
+
+ // flush the buffers
+ FlushCOM(portnum);
+
+ // send the packet
+ if (WriteCOM(portnum,sendlen,sendpacket))
+ {
+ // read back the response
+ if (ReadCOM(portnum,tran_len,tran_buf) == tran_len)
+ return TRUE;
+ }
+
+ // an error occured so re-sync with DS2480
+ DS2480Detect(portnum);
+
+ return FALSE;
+}
+
+//--------------------------------------------------------------------------
+// Read a Universal Data Packet from a standard NVRAM iButton
+// and return it in the provided buffer. The page that the
+// packet resides on is 'start_page'. Note that this function is limited
+// to single page packets. The buffer 'read_buf' must be at least
+// 29 bytes long.
+//
+// The Universal Data Packet always start on page boundaries but
+// can end anywhere. The length is the number of data bytes not
+// including the length byte and the CRC16 bytes. There is one
+// length byte. The CRC16 is first initialized to the starting
+// page number. This provides a check to verify the page that
+// was intended is being read. The CRC16 is then calculated over
+// the length and data bytes. The CRC16 is then inverted and stored
+// low byte first followed by the high byte.
+//
+// Supported devices: DS1992, DS1993, DS1994, DS1995, DS1996, DS1982,
+// DS1985, DS1986, DS2407, and DS1971.
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
+// indicate the symbolic port number.
+// 'do_access' - flag to indicate if an 'owAccess' should be
+// peformed at the begining of the read. This may
+// be FALSE (0) if the previous call was to read the
+// previous page (start_page-1).
+// 'start_page' - page number to start the read from
+// 'read_buf' - pointer to a location to store the data read
+//
+// Returns: >=0 success, number of data bytes in the buffer
+// -1 failed to read a valid UDP
+//
+//
+int owReadPacketStd(int portnum, int do_access, int start_page, uchar *read_buf)
+{
+ int i,length,sendlen=0,head_len=0;
+ uchar sendpacket[50];
+ ushort lastcrc16;
+
+ // check if access header is done
+ // (only use if in sequention read with one access at begining)
+ if (do_access)
+ {
+ // match command
+ sendpacket[sendlen++] = 0x55;
+ for (i = 0; i < 8; i++)
+ sendpacket[sendlen++] = SerialNum[portnum][i];
+ // read memory command
+ sendpacket[sendlen++] = 0xF0;
+ // write the target address
+ sendpacket[sendlen++] = ((start_page << 5) & 0xFF);
+ sendpacket[sendlen++] = (start_page >> 3);
+ // check for DS1982 exception (redirection byte)
+ if (SerialNum[portnum][0] == 0x09)
+ sendpacket[sendlen++] = 0xFF;
+ // record the header length
+ head_len = sendlen;
+ }
+ // read the entire page length byte
+ for (i = 0; i < 32; i++)
+ sendpacket[sendlen++] = 0xFF;
+
+ // send/recieve the transfer buffer
+ if (owBlock(portnum,do_access,sendpacket,sendlen))
+ {
+ // seed crc with page number
+ setcrc16(portnum,(ushort)start_page);
+
+ // attempt to read UDP from sendpacket
+ length = sendpacket[head_len];
+ docrc16(portnum,(ushort)length);
+
+ // verify length is not too large
+ if (length <= 29)
+ {
+ // loop to read packet including CRC
+ for (i = 0; i < length; i++)
+ {
+ read_buf[i] = sendpacket[i+1+head_len];
+ docrc16(portnum,read_buf[i]);
+ }
+
+ // read and compute the CRC16
+ docrc16(portnum,sendpacket[i+1+head_len]);
+ lastcrc16 = docrc16(portnum,sendpacket[i+2+head_len]);
+
+ // verify the CRC16 is correct
+ if (lastcrc16 == 0xB001)
+ return length; // return number of byte in record
+ }
+ }
+
+ // failed block or incorrect CRC
+ return -1;
+}
+
+//--------------------------------------------------------------------------
+// Write a Universal Data Packet onto a standard NVRAM 1-Wire device
+// on page 'start_page'. This function is limited to UDPs that
+// fit on one page. The data to write is provided as a buffer
+// 'write_buf' with a length 'write_len'.
+//
+// The Universal Data Packet always start on page boundaries but
+// can end anywhere. The length is the number of data bytes not
+// including the length byte and the CRC16 bytes. There is one
+// length byte. The CRC16 is first initialized to the starting
+// page number. This provides a check to verify the page that
+// was intended is being read. The CRC16 is then calculated over
+// the length and data bytes. The CRC16 is then inverted and stored
+// low byte first followed by the high byte.
+//
+// Supported devices: is_eprom=0
+// DS1992, DS1993, DS1994, DS1995, DS1996
+// is_eprom=1, crc_type=0(CRC8)
+// DS1982
+// is_eprom=1, crc_type=1(CRC16)
+// DS1985, DS1986, DS2407
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
+// indicate the symbolic port number.
+// 'start_page' - page number to write packet to
+// 'write_buf' - pointer to buffer containing data to write
+// 'write_len' - number of data byte in write_buf
+// 'is_eprom' - flag set if device is an EPROM (1 EPROM, 0 NVRAM)
+// 'crc_type' - if is_eprom=1 then indicates CRC type
+// (0 CRC8, 1 CRC16)
+//
+// Returns: TRUE(1) success, packet written
+// FALSE(0) failure to write, contact lost or device locked
+//
+//
+int owWritePacketStd(int portnum, int start_page, uchar *write_buf,
+ int write_len, int is_eprom, int crc_type)
+{
+ uchar construct_buffer[32];
+ int i,buffer_cnt=0,start_address,do_access;
+ ushort lastcrc16;
+
+ // check to see if data too long to fit on device
+ if (write_len > 29)
+ return FALSE;
+
+ // seed crc with page number
+ setcrc16(portnum,(ushort)start_page);
+
+ // set length byte
+ construct_buffer[buffer_cnt++] = (uchar)(write_len);
+ docrc16(portnum,(ushort)write_len);
+
+ // fill in the data to write
+ for (i = 0; i < write_len; i++)
+ {
+ lastcrc16 = docrc16(portnum,write_buf[i]);
+ construct_buffer[buffer_cnt++] = write_buf[i];
+ }
+
+ // add the crc
+ construct_buffer[buffer_cnt++] = (uchar)(~(lastcrc16 & 0xFF));
+ construct_buffer[buffer_cnt++] = (uchar)(~((lastcrc16 & 0xFF00) >> 8));
+
+ // check if not EPROM
+ if (!is_eprom)
+ {
+ // write the page
+ if (!Write_Scratchpad(portnum,construct_buffer,start_page,buffer_cnt))
+ return FALSE;
+
+ // copy the scratchpad
+ if (!Copy_Scratchpad(portnum,start_page,buffer_cnt))
+ return FALSE;
+
+ // copy scratch pad was good then success
+ return TRUE;
+ }
+ // is EPROM
+ else
+ {
+ // calculate the start address
+ start_address = ((start_page >> 3) << 8) | ((start_page << 5) & 0xFF);
+ do_access = TRUE;
+ // loop to program each byte
+ for (i = 0; i < buffer_cnt; i++)
+ {
+ if (owProgramByte(portnum,construct_buffer[i], start_address + i,
+ 0x0F, crc_type, do_access) != construct_buffer[i])
+ return FALSE;
+ do_access = FALSE;
+ }
+ return TRUE;
+ }
+}
+
+//--------------------------------------------------------------------------
+// Write a byte to an EPROM 1-Wire device.
+//
+// Supported devices: crc_type=0(CRC8)
+// DS1982
+// crc_type=1(CRC16)
+// DS1985, DS1986, DS2407
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
+// indicate the symbolic port number.
+// 'write_byte' - byte to program
+// 'addr' - address of byte to program
+// 'write_cmd' - command used to write (0x0F reg mem, 0x55 status)
+// 'crc_type' - CRC used (0 CRC8, 1 CRC16)
+// 'do_access' - Flag to access device for each byte
+// (0 skip access, 1 do the access)
+// WARNING, only use do_access=0 if programing the NEXT
+// byte immediatly after the previous byte.
+//
+// Returns: >=0 success, this is the resulting byte from the program
+// effort
+// -1 error, device not connected or program pulse voltage
+// not available
+//
+int owProgramByte(int portnum, int write_byte, int addr, int write_cmd,
+ int crc_type, int do_access)
+{
+ ushort lastcrc16;
+ uchar lastcrc8;
+
+ // optionally access the device
+ if (do_access)
+ {
+ if (!owAccess(portnum))
+ return -1;
+
+ // send the write command
+ if (!owWriteByte(portnum,write_cmd))
+ return -1;
+
+ // send the address
+ if (!owWriteByte(portnum,addr & 0xFF))
+ return -1;
+ if (!owWriteByte(portnum,addr >> 8))
+ return -1;
+ }
+
+ // send the data to write
+ if (!owWriteByte(portnum,write_byte))
+ return -1;
+
+ // read the CRC
+ if (crc_type == 0)
+ {
+ // calculate CRC8
+ if (do_access)
+ {
+ setcrc8(portnum,0);
+ docrc8(portnum,(uchar)write_cmd);
+ docrc8(portnum,(uchar)(addr & 0xFF));
+ docrc8(portnum,(uchar)(addr >> 8));
+ }
+ else
+ setcrc8(portnum,(uchar)(addr & 0xFF));
+
+ docrc8(portnum,(uchar)write_byte);
+ // read and calculate the read crc
+ lastcrc8 = docrc8(portnum,(uchar)owReadByte(portnum));
+ // crc should now be 0x00
+ if (lastcrc8 != 0)
+ return -1;
+ }
+ else
+ {
+ // CRC16
+ if (do_access)
+ {
+ setcrc16(portnum,0);
+ docrc16(portnum,(ushort)write_cmd);
+ docrc16(portnum,(ushort)(addr & 0xFF));
+ docrc16(portnum,(ushort)(addr >> 8));
+ }
+ else
+ setcrc16(portnum,(ushort)addr);
+ docrc16(portnum,(ushort)write_byte);
+ // read and calculate the read crc
+ docrc16(portnum,(ushort)owReadByte(portnum));
+ lastcrc16 = docrc16(portnum,(ushort)owReadByte(portnum));
+ // crc should now be 0xB001
+ if (lastcrc16 != 0xB001)
+ return -1;
+ }
+
+ // send the program pulse
+ if (!owProgramPulse(portnum))
+ return -1;
+
+ // read back and return the resulting byte
+ return owReadByte(portnum);
+}
+
+//--------------------------------------------------------------------------
+// Write the scratchpad of a standard NVRam device such as the DS1992,3,4
+// and verify its contents.
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
+// indicate the symbolic port number.
+// 'write_buf' - pointer to buffer containing data to write
+// 'start_page' - page number to write packet to
+// 'write_len' - number of data byte in write_buf
+//
+// Returns: TRUE(1) success, the data was written and verified
+// FALSE(0) failure, the data could not be written
+//
+//
+int Write_Scratchpad(int portnum, uchar *write_buf, int start_page, int write_len)
+{
+ int i,sendlen=0;
+ uchar sendpacket[50];
+
+ // match command
+ sendpacket[sendlen++] = 0x55;
+ for (i = 0; i < 8; i++)
+ sendpacket[sendlen++] = SerialNum[portnum][i];
+ // write scratchpad command
+ sendpacket[sendlen++] = 0x0F;
+ // write the target address
+ sendpacket[sendlen++] = ((start_page << 5) & 0xFF);
+ sendpacket[sendlen++] = (start_page >> 3);
+
+ // write packet bytes
+ for (i = 0; i < write_len; i++)
+ sendpacket[sendlen++] = write_buf[i];
+
+ // send/recieve the transfer buffer
+ if (owBlock(portnum,TRUE,sendpacket,sendlen))
+ {
+ // now attempt to read back to check
+ sendlen = 0;
+ // match command
+ sendpacket[sendlen++] = 0x55;
+ for (i = 0; i < 8; i++)
+ sendpacket[sendlen++] = SerialNum[portnum][i];
+ // read scratchpad command
+ sendpacket[sendlen++] = 0xAA;
+ // read the target address, offset and data
+ for (i = 0; i < (write_len + 3); i++)
+ sendpacket[sendlen++] = 0xFF;
+
+ // send/recieve the transfer buffer
+ if (owBlock(portnum,TRUE,sendpacket,sendlen))
+ {
+ // check address and offset of scratchpad read
+ if ((sendpacket[10] != (int)((start_page << 5) & 0xFF)) ||
+ (sendpacket[11] != (int)(start_page >> 3)) ||
+ (sendpacket[12] != (int)(write_len - 1)))
+ return FALSE;
+
+ // verify each data byte
+ for (i = 0; i < write_len; i++)
+ if (sendpacket[i+13] != write_buf[i])
+ return FALSE;
+
+ // must have verified
+ return TRUE;
+ }
+ }
+
+ // failed a block tranfer
+ return FALSE;
+}
+
+//--------------------------------------------------------------------------
+// Copy the contents of the scratchpad to its intended nv ram page. The
+// page and length of the data is needed to build the authorization bytes
+// to copy.
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
+// indicate the symbolic port number.
+// 'start_page' - page number to write packet to
+// 'write_len' - number of data bytes that are being copied
+//
+// Returns: TRUE(1) success
+// FALSE(0) failure
+//
+int Copy_Scratchpad(int portnum, int start_page, int write_len)
+{
+ int i,sendlen=0;
+ uchar sendpacket[50];
+
+ // match command
+ sendpacket[sendlen++] = 0x55;
+ for (i = 0; i < 8; i++)
+ sendpacket[sendlen++] = SerialNum[portnum][i];
+ // copy scratchpad command
+ sendpacket[sendlen++] = 0x55;
+ // write the target address
+ sendpacket[sendlen++] = ((start_page << 5) & 0xFF);
+ sendpacket[sendlen++] = (start_page >> 3);
+ sendpacket[sendlen++] = write_len - 1;
+ // read copy result
+ sendpacket[sendlen++] = 0xFF;
+
+ // send/recieve the transfer buffer
+ if (owBlock(portnum,TRUE,sendpacket,sendlen))
+ {
+ // check address and offset of scratchpad read
+ if ((sendpacket[10] != (int)((start_page << 5) & 0xFF)) ||
+ (sendpacket[11] != (int)(start_page >> 3)) ||
+ (sendpacket[12] != (int)(write_len - 1)) ||
+ (sendpacket[13] & 0xF0))
+ return FALSE;
+ else
+ return TRUE;
+ }
+
+ // failed a block tranfer
+ return FALSE;
+}
+
--- /dev/null
+//---------------------------------------------------------------------------
+// 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.
+//--------------------------------------------------------------------------
+//
+// swt12.c - Modifies Channel A and B and returns info byte data for
+// the DS2406 and DS2407.
+// version 2.00
+
+
+// Include files
+#include <stdio.h>
+#include "ownet.h"
+#include "swt12.h"
+
+//----------------------------------------------------------------------
+// SUBROUTINE - ReadSwitch12
+//
+// This routine gets the Channel Info Byte and returns it.
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
+// OpenCOM to indicate the port number.
+// 'ClearActivity' - To reset the button
+//
+// Returns: (-1) If the Channel Info Byte could not be read.
+// (Info Byte) If the Channel Info Byte could be read.
+//
+int ReadSwitch12(int portnum, int ClearActivity)
+{
+ int rt=-1; //this is the return value depending if the byte was read
+ int trans_cnt=0; //this is the counter for the number of bytes to send
+ uchar transfer[30]; //this is the whole block of byte info
+
+ // access and verify it is there
+ if (owAccess(portnum))
+ {
+ // reset CRC
+ setcrc16(portnum,0);
+
+ // channel access command
+ transfer[trans_cnt++] = 0xF5;
+ docrc16(portnum,0xF5);
+
+ // control bytes
+ if (ClearActivity)
+ {
+ transfer[trans_cnt++] = 0xD5;
+ docrc16(portnum,0xD5);
+ }
+ else
+ {
+ transfer[trans_cnt++] = 0x55;
+ docrc16(portnum,0x55);
+ }
+
+ transfer[trans_cnt++] = 0xFF;
+ docrc16(portnum,0xFF);
+
+ // read the info byte
+ transfer[trans_cnt++] = 0xFF;
+
+ // dummy data
+ transfer[trans_cnt++] = 0xFF;
+ transfer[trans_cnt++] = 0xFF;
+ transfer[trans_cnt++] = 0xFF;
+
+ if (owBlock(portnum,FALSE,transfer,trans_cnt))
+ {
+ rt = transfer[3];
+ // read a dummy read byte and CRC16
+ docrc16(portnum,transfer[trans_cnt-4]);
+ docrc16(portnum,transfer[trans_cnt-3]);
+ docrc16(portnum,transfer[trans_cnt-2]);
+ if(docrc16(portnum,transfer[trans_cnt-1]) != 0xB001)
+ rt = -1;
+ }
+ }
+ else
+ rt = -1;
+
+ return rt;
+}
+
+//----------------------------------------------------------------------
+// SUBROUTINE - SetSwitch12
+//
+// This routine sets the channel state of the specified DS2406
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
+// OpenCOM to indicate the port number.
+// 'SerialNum' - Serial Number of DS2406 to set the switch state
+// 'State' - Is a type containing what to set A and/or B to. It
+// also contains the other fields that maybe written later
+//
+// Returns: TRUE(1) State of DS2406 set and verified
+// FALSE(0) could not set the DS2406, perhaps device is not
+// in contact
+//
+int SetSwitch12(int portnum, uchar *SerialNum, SwitchProps *State)
+{
+ ushort st;
+ int rt=FALSE;
+ uchar send_block[30];
+ int send_cnt=0;
+
+ setcrc16(portnum,0);
+
+ // set the device serial number to the counter device
+ owSerialNum(portnum,SerialNum,FALSE);
+
+ // access the device
+ if (owAccess(portnum))
+ {
+ // create a block to send that reads the counter
+ // write status command
+ send_block[send_cnt++] = 0x55;
+ docrc16(portnum,0x55);
+
+ // address of switch state
+ send_block[send_cnt++] = 0x07;
+ docrc16(portnum,0x07);
+ send_block[send_cnt++] = 0x00;
+ docrc16(portnum,0x00);
+
+ // write state
+ st = 0x1F;
+ if(!State->Chan_B) st |= 0x40;
+ if(!State->Chan_A) st |= 0x20;
+ // more ifs can be added here for the other fields.
+
+ send_block[send_cnt++] = (uchar)st;
+ docrc16(portnum,st);
+
+ // read CRC16
+ send_block[send_cnt++] = 0xFF;
+ send_block[send_cnt++] = 0xFF;
+
+ // now send the block
+ if (owBlock(portnum,FALSE,send_block,send_cnt))
+ {
+ // perform the CRC16 on the last 2 bytes of packet
+ docrc16(portnum,send_block[send_cnt-2]);
+
+ // verify crc16 is correct
+ if(docrc16(portnum,send_block[send_cnt-1]) == 0xB001)
+ rt = TRUE;
+ }
+ }
+
+ // return the result flag rt
+ return rt;
+}
+
+
+//----------------------------------------------------------------------
+// SUBROUTINE - SwitchStateToString12
+//
+// This routine uses the info byte to return a string with all the data.
+//
+// 'infobyte' - This is the information byte data from the hardware.
+// 'outstr' - This will be the output string. It gets set in the
+// the procedure.
+//
+int SwitchStateToString12(int infobyte, char *outstr)
+{
+
+ int cnt = 0;
+
+ if(infobyte & 0x40)
+ {
+ cnt += sprintf(outstr+cnt, "%s", "Channel A and B\n");
+
+ if(infobyte & 0x80)
+ cnt += sprintf(outstr+cnt, "%s", "Supply\n");
+ else
+ cnt += sprintf(outstr+cnt, "%s", "No Supply\n");
+
+ if(infobyte & 0x20)
+ cnt += sprintf(outstr+cnt, "%s", "Activity on PIO-B\n");
+ else
+ cnt += sprintf(outstr+cnt, "%s", "No activity on PIO-B\n");
+
+ if(infobyte & 0x10)
+ cnt += sprintf(outstr+cnt, "%s", "Activity on PIO-A\n");
+ else
+ cnt += sprintf(outstr+cnt, "%s", "No activity on PIO-A\n");
+
+ if(infobyte & 0x08)
+ cnt += sprintf(outstr+cnt, "%s", "Hi level on PIO B\n");
+ else
+ cnt += sprintf(outstr+cnt, "%s", "Lo level on PIO B\n");
+
+ if(infobyte & 0x04)
+ cnt += sprintf(outstr+cnt, "%s", "Hi level on PIO A\n");
+ else
+ cnt += sprintf(outstr+cnt, "%s", "Lo level on PIO A\n");
+
+ if(infobyte & 0x02)
+ cnt += sprintf(outstr+cnt, "%s", "Channel B off\n");
+ else
+ cnt += sprintf(outstr+cnt, "%s", "Channel B on\n");
+
+ if(infobyte & 0x01)
+ cnt += sprintf(outstr+cnt, "%s", "Channel A off\n");
+ else
+ cnt += sprintf(outstr+cnt, "%s", "Channel A on\n");
+ }
+ else
+ {
+ cnt += sprintf(outstr+cnt, "%s", "Channel A\n");
+
+ if(infobyte & 0x80)
+ cnt += sprintf(outstr+cnt, "%s", "Supply\n");
+ else
+ cnt += sprintf(outstr+cnt, "%s", "No Supply\n");
+
+ if(infobyte & 0x10)
+ cnt += sprintf(outstr+cnt, "%s", "Activity on PIO-A\n");
+ else
+ cnt += sprintf(outstr+cnt, "%s", "No activity on PIO-A\n");
+
+ if(infobyte & 0x04)
+ cnt += sprintf(outstr+cnt, "%s", "Hi level on PIO A\n");
+ else
+ cnt += sprintf(outstr+cnt, "%s", "Lo level on PIO A\n");
+
+ if(infobyte & 0x01)
+ cnt += sprintf(outstr+cnt, "%s", "Channel A off\n");
+ else
+ cnt += sprintf(outstr+cnt, "%s", "Channel A on\n");
+
+ }
+
+ return cnt;
+}
+
+
--- /dev/null
+typedef struct tagSRAM
+{
+ uchar Supply;
+ uchar Chan_B;
+ uchar Chan_A;
+ uchar Chan_Sel;
+ uchar Sour_Sel;
+ uchar Polarity;
+} SwitchProps;
+
+int ReadSwitch12(int,int);
+int SetSwitch12(int,uchar *,SwitchProps*);
+int SwitchStateToString12(int,char *);
--- /dev/null
+//---------------------------------------------------------------------------
+// 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.
+//--------------------------------------------------------------------------
+//
+// swtloop.C - Goes through the testing of the DS2406(DS2407) switch
+// Version 2.00
+
+
+// Include files
+#include <stdio.h>
+#include <stdlib.h>
+#include "ownet.h"
+#include "swt12.h"
+
+// Constant definition
+#define MAXDEVICES 15
+
+// tini hack
+int argc=2;
+char *argv[]={__FILE__, "exow"};
+#define getkeystroke getchar
+
+//--------------------------------------------------------------------------
+// This is the begining of the program that tests the different Channels
+int main() //short argc, char **argv)
+{
+ char return_msg[128]; //returned message from 1-wire operations
+ int i,j,k,n; //loop counters
+ short test=0; //info byte data
+ short clear=0; //used to clear the button
+ SwitchProps sw; //used to set Channel A and B
+ uchar SwitchSN[MAXDEVICES][8]; //the serial numbers for the devices
+ int num; //for the number of devices present
+ int ch; //inputed character from user
+ char out[140]; //used for output of the info byte data
+ int portnum=0;
+
+ //----------------------------------------
+ // Introduction header
+ printf("\n/---------------------------------------------\n");
+ printf(" swtest - V2.00\n"
+ " The following is a test to excersize the\n"
+ " different channels on the DS2406.\n");
+ printf(" Press any CTRL-C to stop this program.\n\n");
+
+ // check for required port name
+ if (argc != 2)
+ {
+ printf("1-Wire Net name required on command line!\n"
+ " (example: \"COM1\" (Win32 DS2480),\"/dev/cua0\" "
+ "(Linux DS2480),\"1\" (Win32 TMEX)\n");
+ exit(1);
+ }
+
+ // attempt to acquire the 1-Wire Net
+ if (!owAcquire(portnum, argv[1], return_msg))
+ {
+ printf("%s",return_msg);
+ exit(1);
+ }
+
+ // success
+ printf("%s",return_msg);
+
+ // this is to get the number of the devices and the serial numbers
+ num = FindDevices(portnum, &SwitchSN[0], SWITCH_FAMILY, MAXDEVICES);
+
+ // setting up the first print out for the frist device
+ owSerialNum(portnum, SwitchSN[0], FALSE);
+
+ j=1;
+ n=0;
+ do
+ {
+ // This is for after the different combinations of channels
+ // have been tested to reset to a different device to be tested.
+ if( ((test & 0x40) && (j==5)) ||
+ ((!(test & 0x40)) && (j==3)) )
+ {
+ printf("\n\n");
+ for(k=0; k < num; k++)
+ {
+ printf("%d ", k+1);
+ for(i=7; i>=0; i--)
+ {
+ printf("%02X", SwitchSN[k][i]);
+ }
+ printf("\n");
+ }
+ printf("%d To quit or any other key.\n", k+1);
+
+ printf("\n");
+ printf("Pick a device\n");
+
+ ch = getkeystroke();
+ n = 0;
+ n = (10*n + (ch - '0')) - 1;
+
+ if( (n>num-1) || (n<0) )
+ {
+ n = 0; //used to finish off the loop
+ break;
+ }
+
+ owSerialNum(portnum, SwitchSN[n], FALSE);
+ j = 1;
+ }
+ printf("\n");
+
+ test = ReadSwitch12(portnum,clear);
+
+ // This looks at the info byte to determine if it is a
+ // two or one channel device.
+ if(test & 0x40)
+ {
+
+ switch(j)
+ {
+ case 1:
+ sw.Chan_A = 0;
+ sw.Chan_B = 0;
+ break;
+ case 2:
+ sw.Chan_A = 0;
+ sw.Chan_B = 1;
+ break;
+ case 3:
+ sw.Chan_A = 1;
+ sw.Chan_B = 0;
+ break;
+ case 4:
+ sw.Chan_A = 1;
+ sw.Chan_B = 1;
+ break;
+ default:
+ sw.Chan_A = 1;
+ sw.Chan_B = 1;
+ j=0;
+ break;
+ }
+ }
+ else
+ {
+ switch(j)
+ {
+ case 1:
+ sw.Chan_B = 0;
+ sw.Chan_A = 0;
+ break;
+ case 2:
+ sw.Chan_B = 0;
+ sw.Chan_A = 1;
+ break;
+ default:
+ sw.Chan_B = 0;
+ sw.Chan_A = 1;
+ j = 0;
+ break;
+ }
+ }
+
+ if(!SetSwitch12(portnum, SwitchSN[n], &sw))
+ {
+ msDelay(50);
+ if(SetSwitch12(portnum, SwitchSN[n], &sw))
+ msDelay(50);
+ else
+ printf("Switch not set\n");
+ }
+
+ test = ReadSwitch12(portnum,clear);
+
+ printf("\n");
+
+ for(i=7; i>=0; i--)
+ {
+ printf("%02X", SwitchSN[n][i]);
+ }
+ printf("\n");
+
+ SwitchStateToString12(test, out);
+ printf("%s", out);
+
+ j++;
+
+ }
+ while(1);
+
+ // release the 1-Wire Net
+ owRelease(portnum,return_msg);
+ printf("%s",return_msg);
+ exit(0);
+
+ return 0;
+}
+
--- /dev/null
+//---------------------------------------------------------------------------
+// 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.
+//--------------------------------------------------------------------------
+//
+// swtoper.C - Menu-driven test of DS2406(DS2407) 1-Wire switch
+// version 2.00
+
+
+// Include files
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include "ownet.h"
+#include "swt12.h"
+
+// Constant definition
+#define MAXDEVICES 15
+
+// tini hack
+int argc=2;
+char *argv[]={__FILE__, "exow"};
+#define getkeystroke getchar
+
+//---------------------------------------------------------------------------
+// The main program that performs the operations on switches
+//
+int main() //short argc, char **argv)
+{
+ char return_msg[128]; //returned message from 1-wire operations
+ short test; //info byte data
+ short clear=0; //used to clear the button
+ short done; //to tell when the user is done
+ SwitchProps sw; //used to set Channel A and B
+ uchar SwitchSN[MAXDEVICES][8]; //the serial number for the devices
+ int num; //for the number of devices present
+ int ch; //inputed character from user
+ int i,j,n; //loop counters and indexes
+ char out[140]; //used for output of the info byte data
+ int count; //the number of characters in the info byte data
+ int portnum=0;
+
+ //----------------------------------------
+ // Introduction header
+ printf("\n/---------------------------------------------\n");
+ printf(" Switch - V2.00\n"
+ " The following is a test to excersize the \n"
+ " setting of the state in a DS2406.\n");
+
+ printf(" Press any CTRL-C to stop this program.\n\n");
+
+ // check for required port name
+ if (argc != 2)
+ {
+ printf("1-Wire Net name required on command line!\n"
+ " (example: \"COM1\" (Win32 DS2480),\"/dev/cua0\" "
+ "(Linux DS2480),\"1\" (Win32 TMEX)\n");
+ exit(1);
+ }
+
+ // attempt to acquire the 1-Wire Net
+ if (!owAcquire(portnum, argv[1], return_msg))
+ {
+ printf("%s",return_msg);
+ exit(1);
+ }
+
+ // success
+ printf("%s",return_msg);
+
+ // this is to get the number of the devices and the serial numbers
+ num = FindDevices(portnum, &SwitchSN[0], SWITCH_FAMILY, MAXDEVICES);
+
+ // setting up the first print out for the frist device
+ owSerialNum(portnum, SwitchSN[0], FALSE);
+
+ printf("\n");
+ n=0;
+ if(owAccess(portnum))
+ {
+ // loop while not done
+ do
+ {
+ test = ReadSwitch12(portnum, clear);
+
+ for(i=7; i>=0; i--)
+ printf("%02X", SwitchSN[n][i]);
+
+ printf("\n");
+
+ count = SwitchStateToString12(test, out);
+ printf("%s", out);
+
+ // print menu
+ printf("\n\n(1) Display the switch Info\n"
+ "(2) Clear activity Latches\n"
+ "(3) Set Flip Flop(s) on switch\n"
+ "(4) Select different device\n"
+ "(5) Quit\n"
+ "Select a Number:");
+ ch = getkeystroke();
+ printf("\n\n");
+
+ // do something from the menu selection
+ clear = FALSE;
+ switch(ch)
+ {
+ case '1': // Display the switch Info
+ done = FALSE;
+ break;
+ case '2': // Clear activity Latches
+ clear = TRUE;
+ done = FALSE;
+ break;
+ case '3': // Set Flip Flop(s) on switch
+ printf("Channel %c Flip Flop (1 set, 0 clear):",'A');
+ ch = getkeystroke();
+ if (ch == '0')
+ sw.Chan_A = 0;
+ else
+ sw.Chan_A = 1;
+ printf("\n");
+
+ if(test & 0x40)
+ {
+ printf("Channel %c Flip Flop (1 set, 0 clear):",'B');
+ ch = getkeystroke();
+ if (ch == '0')
+ sw.Chan_B = 0;
+ else
+ sw.Chan_B = 1;
+ printf("\n");
+ }
+ else
+ {
+ printf("\n");
+ sw.Chan_B = 0;
+ }
+ printf("\n");
+
+ if(!SetSwitch12(portnum, SwitchSN[n], &sw))
+ {
+ msDelay(50);
+ if(SetSwitch12(portnum, SwitchSN[n], &sw))
+ msDelay(50);
+ else
+ printf("Switch not set\n");
+ }
+ done = FALSE;
+ break;
+ case '4': // Switch Devices
+ for(j=0; j < num; j++)
+ {
+ printf("%d ", j+1);
+ for(i=7; i>=0; i--)
+ {
+ printf("%02X", SwitchSN[j][i]);
+ }
+ printf("\n");
+ }
+ printf("\n");
+
+ do
+ {
+ printf("Pick a device\n");
+ ch = getkeystroke();
+ n = 0;
+ n = (10*n + (ch - '0')) - 1;
+ printf("\n");
+ }
+ while((!isalnum(ch)) || (n>num-1));
+ printf("\n");
+
+ n = 0;
+ n = (10*n + (ch - '0')) - 1;
+
+ owSerialNum(portnum, SwitchSN[n], FALSE);
+
+ done = FALSE;
+ break;
+
+ case '5': case 'q': case 'Q': // Done
+ done = TRUE;
+ break;
+ default:
+ break;
+ }
+ }
+ while (!done);
+ }
+ //One Wire Access
+ owRelease(portnum,return_msg);
+ printf("%s",return_msg);
+ exit(0);
+
+ return 0;
+}
+
--- /dev/null
+//---------------------------------------------------------------------------
+// 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.
+//---------------------------------------------------------------------------
+//
+// temp.c - Application to find and read the 1-Wire Net
+// DS1920/DS1820/DS18S20 - temperature measurement.
+//
+// This application uses the files from the 'Public Domain'
+// 1-Wire Net libraries ('general' and 'userial').
+//
+//
+// Version: 2.00
+//
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "ownet.h"
+#include "temp10.h"
+
+// defines
+#define MAXDEVICES 20
+
+// local functions
+static void PrintSerialNum(uchar FamilySN[8]);
+
+// local serial numbers
+static uchar FamilySN[MAXDEVICES][8];
+
+// variables
+static int family_code;
+
+// tini hack
+int argc=2;
+char *argv[]={__FILE__, "exow"};
+
+//----------------------------------------------------------------------
+// Main Test for DS1920/DS1820 temperature measurement
+//
+int main() //short argc, char **argv)
+{
+ float current_temp;
+ char return_msg[128];
+ int i = 0;
+ int j = 0;
+ int NumDevices=0;
+ int portnum = 0;
+
+ //----------------------------------------
+ // Introduction header
+ printf("\n/---------------------------------------------\n");
+ printf(" Temperature application DS1920/DS1820 - Version 1.00 \n"
+ " The following is a test to excersize a DS1920/DS1820.\n"
+ " Temperature Find and Read from a: \n"
+ " DS1920/DS1820 (at least 1)\n\n");
+
+ printf(" Press any CTRL-C to stop this program.\n\n");
+ printf(" Output [Serial Number(s) ........ Temp1(C)] \n\n");
+
+ // check for required port name
+ if (argc != 2)
+ {
+ printf("1-Wire Net name required on command line!\n"
+ " (example: \"COM1\" (Win32 DS2480),\"/dev/cua0\" "
+ "(Linux DS2480),\"1\" (Win32 TMEX)\n");
+ exit(1);
+ }
+
+
+ // attempt to acquire the 1-Wire Net
+ if (!owAcquire(portnum, argv[1], return_msg))
+ {
+ printf("%s",return_msg);
+ exit(1);
+ }
+
+ // success
+ printf("%s",return_msg);
+
+ // Find the device(s)
+ NumDevices = FindDevices(portnum, &FamilySN[0], 0x10, MAXDEVICES);
+ if (NumDevices>0)
+ {
+ printf("\n");
+ printf("Device(s) Found: \n");
+ for (i = 0; i < NumDevices; i++)
+ {
+ PrintSerialNum(FamilySN[i]);
+ printf("\n");
+ }
+ printf("\n\n");
+
+ // (stops on CTRL-C)
+ do
+ {
+ // read the temperature and print serial number and temperature
+ for (i = 0; i < NumDevices; i++)
+ {
+
+ if (ReadTemperature(portnum, FamilySN[i],¤t_temp))
+ {
+ PrintSerialNum(FamilySN[i]);
+ printf(" %5.1f \n", current_temp);
+ }
+ else
+ printf(" Error reading temperature, verify device present:%d\n",
+ owVerify(portnum, FALSE));
+ }
+ printf("\n");
+ }
+ while (!key_abort());
+ }
+ else
+ printf("\n\n\nERROR, device DS1920/DS1820 not found!\n");
+
+ // release the 1-Wire Net
+ owRelease(portnum, return_msg);
+ printf("%s",return_msg);
+ exit(0);
+
+ return 0;
+}
+
+// -------------------------------------------------------------------------------
+// Read and print the serial number.
+//
+void PrintSerialNum(uchar FamilySN[8])
+{
+ int i;
+
+ for (i = 7; i>=0; i--)
+ printf("%02X", FamilySN[i]);
+}
--- /dev/null
+//---------------------------------------------------------------------------
+// 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.
+// ---------------------------------------------------------------------------
+//
+// temp10.C - Module to read the DS1920/DS1820 - temperature measurement.
+//
+// Version: 2.00
+//
+// ---------------------------------------------------------------------------
+//
+//
+#include "ownet.h"
+#include "temp10.h"
+
+//----------------------------------------------------------------------
+// Read the temperature of a DS1920/DS1820
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
+// OpenCOM to indicate the port number.
+// 'SerialNum' - Serial Number of DS1920/DS1820 to read temperature from
+// 'Temp ' - pointer to variable where that temperature will be
+// returned
+//
+// Returns: TRUE(1) temperature has been read and verified
+// FALSE(0) could not read the temperature, perhaps device is not
+// in contact
+//
+int ReadTemperature(int portnum, uchar *SerialNum, float *Temp)
+{
+ int rt=FALSE;
+ uchar send_block[30],lastcrc8;
+ int send_cnt=0, tsht, i, loop=0;
+ float tmp,cr,cpc;
+
+
+ setcrc8(portnum,0);
+
+ // set the device serial number to the counter device
+ owSerialNum(portnum,SerialNum,FALSE);
+
+ for (loop = 0; rt==FALSE && loop < 2; loop ++)
+ {
+ // access the device
+ if (owAccess(portnum))
+ {
+ // send the convert temperature command
+ owTouchByte(portnum,0x44);
+
+ // set the 1-Wire Net to strong pull-up
+ if (owLevel(portnum,MODE_STRONG5) != MODE_STRONG5)
+ return FALSE;
+
+ // sleep for 1 second
+ msDelay(1000);
+
+ // turn off the 1-Wire Net strong pull-up
+ if (owLevel(portnum,MODE_NORMAL) != MODE_NORMAL)
+ return FALSE;
+
+ // access the device
+ if (owAccess(portnum))
+ {
+ // create a block to send that reads the temperature
+ // read scratchpad command
+ send_block[send_cnt++] = 0xBE;
+ // now add the read bytes for data bytes and crc8
+ for (i = 0; i < 9; i++)
+ send_block[send_cnt++] = 0xFF;
+
+ // now send the block
+ if (owBlock(portnum,FALSE,send_block,send_cnt))
+ {
+ // perform the CRC8 on the last 8 bytes of packet
+ for (i = send_cnt - 9; i < send_cnt; i++)
+ lastcrc8 = docrc8(portnum,send_block[i]);
+
+ // verify CRC8 is correct
+ if (lastcrc8 == 0x00)
+ {
+ // calculate the high-res temperature
+ tsht = send_block[1]/2;
+ if (send_block[2] & 0x01)
+ tsht |= -128;
+ tmp = (float)(tsht);
+ cr = send_block[7];
+ cpc = send_block[8];
+ if (((cpc - cr) == 1) && (loop == 0))
+ continue;
+ if (cpc == 0)
+ return FALSE;
+ else
+ tmp = tmp - (float)0.25 + (cpc - cr)/cpc;
+
+ *Temp = tmp;
+ // success
+ rt = TRUE;
+ }
+ }
+ }
+ }
+
+ }
+
+ // return the result flag rt
+ return rt;
+
+}
--- /dev/null
+extern int ReadTemperature(int, uchar *, float *);
--- /dev/null
+//---------------------------------------------------------------------------
+// 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.
+//---------------------------------------------------------------------------
+//
+// thermo21.c - Thermochron iButton utility functions
+//
+// Version: 2.00
+//
+// History:
+// 1.03 -> 2.00 Reorganization of Public Domain Kit
+// Convert to global CRC utility functions
+// Y2K fix.
+
+#include <stdio.h>
+#include "time.h"
+#include <string.h>
+#include "ownet.h"
+#include "thermo21.h"
+
+// a hack for sdcc/TINI, just printf to stdout
+int fprintf (FILE *fp, xdata char *format, ...) reentrant {
+ va_list arg;
+ *fp; // hush the compiler
+ va_start(arg, format);
+ vsprintf(NULL, format, arg);
+ va_end(arg);
+}
+
+static int RunThermoScript(int,ThermoStateType *,ThermoScript script[], FILE *fp);
+static int ThermoStep(int,ThermoStateType *,ThermoScript *,int *,int *,int *,char *);
+static int ReadPages(int,int,int,int *,uchar *);
+static int WriteScratch(int,uchar *,int,int);
+static int CopyScratch(int,int,int);
+static int WriteMemory(int,uchar *, int, int);
+
+// step constants
+enum { ST_SETUP=0, ST_READ_STATUS, ST_READ_ALARM, ST_READ_HIST,
+ ST_READ_LOG, ST_CLEAR_MEM, ST_CLEAR_VERIFY, ST_WRITE_TIME,
+ ST_WRITE_CONTROL, ST_WRITE_RATE, ST_FINISH, ST_GET_SESSION,
+ ST_FIND_THERMO, ST_REL_SESSION, ST_READ_PAGES, ST_WRITE_MEM,
+ ST_CLEAR_SETUP };
+
+// status contants
+enum { STATUS_STEP_COMPLETE, STATUS_COMPLETE, STATUS_INPROGRESS,
+ STATUS_ERROR_HALT, STATUS_ERROR_TRANSIENT };
+
+// download steps
+static ThermoScript Download[] =
+ {{ ST_READ_STATUS, "Setup to read the mission status"},
+ { ST_READ_PAGES, "Read the status page"},
+ { ST_READ_ALARM, "Setup to read alarm pages"},
+ { ST_READ_PAGES, "Read the alarm pages"},
+ { ST_READ_HIST, "Setup to read histogram pages"},
+ { ST_READ_PAGES, "Read the histogram pages"},
+ { ST_READ_LOG, "Setup to read log pages"},
+ { ST_READ_PAGES, "Read the log pages"},
+ { ST_FINISH, "Finished"}};
+
+// read status only steps
+static ThermoScript GetStatus[] =
+ {{ ST_READ_STATUS, "Setup to read the mission status"},
+ { ST_READ_PAGES, "Read the status page"},
+ { ST_FINISH, "Finished"}};
+
+// mission steps (assume already did StatusThermo)
+static ThermoScript Mission[] =
+ {{ ST_CLEAR_SETUP, "Setup clear memory"},
+ { ST_WRITE_MEM, "Write clear memory bit"},
+ { ST_CLEAR_MEM, "Clear the memory"},
+ { ST_READ_STATUS, "Setup to read the mission status"},
+ { ST_READ_PAGES, "Read the status page"},
+ { ST_CLEAR_VERIFY, "Verify memory is clear"},
+ { ST_WRITE_TIME, "Setup to write the real time clock"},
+ { ST_WRITE_MEM, "Write the real time clock"},
+ { ST_WRITE_CONTROL,"Setup to write the control"},
+ { ST_WRITE_MEM, "Write the control"},
+ { ST_WRITE_RATE, "Setup to write the sample rate to start mission"},
+ { ST_WRITE_MEM, "Write the sample rate"},
+ { ST_READ_STATUS, "Read the new mission status"},
+ { ST_FINISH, "Finished"}};
+
+// global state information
+static int current_speed[MAX_PORTNUM];
+
+//--------------------------------------------------------------------------
+// The 'DownloadThermo' downloads the specified Thermochron in 'SerialNum'
+// and puts the data in the state variable 'ThermoState'. Progress output
+// is printed to the specified file 'fp'.
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
+// indicate the symbolic port number.
+// 'SerialNum' - Device serial number to download
+// 'ThermoState' - pointer to a structure type that holds the raw and
+// translated Thermochron data.
+// 'fp' - file pointer to print status information to
+//
+// Returns: TRUE (1) : Thermochron download with raw data in ThermoState
+// FALSE (0): not downloaded. Abort due to repeated errors
+// or user keypress.
+//
+int DownloadThermo(int portnum, uchar *SerialNum,
+ ThermoStateType *ThermoState, FILE *fp)
+{
+ // set the serial num
+ owSerialNum(portnum, SerialNum, FALSE);
+
+ // run the script and download thermochron
+ return RunThermoScript(portnum,ThermoState,Download,fp);
+}
+
+//--------------------------------------------------------------------------
+// The 'ReadThermoStatus' reads the Thermochron status in 'SerialNum'
+// and puts the data in the state variable 'ThermoState'. Progress output
+// is printed to the specified file 'fp'.
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
+// indicate the symbolic port number.
+// 'SerialNum' - Device serial number to download
+// 'ThermoState' - pointer to a structure type that holds the raw and
+// translated Thermochron data.
+// 'fp' - file pointer to print status information to
+//
+// Returns: TRUE (1) : Thermochron status read with raw data in ThermoState
+// FALSE (0): status not read. Abort due to repeated errors
+// or user keypress.
+//
+int ReadThermoStatus(int portnum, uchar *SerialNum,
+ ThermoStateType *ThermoState, FILE *fp)
+{
+ // set the serial num
+ owSerialNum(portnum, SerialNum, FALSE);
+
+ // run the script and read status of thermochron
+ return RunThermoScript(portnum,ThermoState,GetStatus,fp);
+}
+
+//--------------------------------------------------------------------------
+// The 'MissionThermo' starts a new Thermochron mission on 'SerialNum'
+// from the state information provided in 'ThermoState'. Progress output
+// is printed to the specified file 'fp'.
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
+// indicate the symbolic port number.
+// 'SerialNum' - Device serial number to download
+// 'ThermoState' - pointer to a structure type that holds the raw and
+// translated Thermochron data.
+// 'fp' - file pointer to print status information to
+//
+// Returns: TRUE (1) : Thermochron missioned
+// FALSE (0): not missioned. Abort due to repeated errors
+// or user keypress.
+//
+int MissionThermo(int portnum, uchar *SerialNum,
+ ThermoStateType *ThermoState, FILE *fp)
+{
+ // set the serial num
+ owSerialNum(portnum, SerialNum, FALSE);
+
+ // run the script and mission thermochron
+ return RunThermoScript(portnum,ThermoState,Mission,fp);
+}
+
+//--------------------------------------------------------------------------
+// Run the specified script. Return TRUE if all steps completed else FALSE.
+// Status is printed to file 'fp'.
+//
+int RunThermoScript(int portnum, ThermoStateType *ThermoState,
+ ThermoScript script[], FILE *fp)
+{
+ char msg[256],LastDescription[256],LastMsg[256];
+ int StepCount,SubStep,ErrorCount,Status;
+ int last_clear_step=0;
+
+ // reset the step to the begining
+ StepCount = 0;
+ SubStep = 0;
+ ErrorCount = 0;
+ Status = STATUS_INPROGRESS;
+
+ // loop to perform all of the steps to download the Thermochron
+ do
+ {
+ // switch on the status of the last step done
+ switch(Status)
+ {
+ // step complete so go to the next
+ case STATUS_STEP_COMPLETE:
+ StepCount++;
+ SubStep = 0;
+ ErrorCount = 0;
+ Status = STATUS_INPROGRESS;
+ LastDescription[0] = 0;
+ LastMsg[0] = 0;
+ break;
+ // in progress so call again
+ case STATUS_INPROGRESS:
+ // record the step position of the last memory clear
+ // this is in case we need to attempt a clear again
+ if (script[StepCount].Step == ST_CLEAR_SETUP)
+ last_clear_step = StepCount;
+
+ // print step description if different
+ if (strcmp(LastDescription,
+ script[StepCount].StepDescription) != 0)
+ {
+ fprintf(fp,"%s --> ",script[StepCount].StepDescription);
+ sprintf(LastDescription,"%s",script[StepCount].StepDescription);
+ }
+
+ // perform a step in the job
+ ThermoStep(portnum,ThermoState,&script[StepCount],&SubStep,
+ &Status, &ErrorCount, msg);
+
+ // print results if different
+ if (strcmp(LastMsg,msg) != 0)
+ {
+ fprintf(fp,"%s\n",msg);
+ sprintf(LastMsg,"%s",msg);
+ }
+ else
+ fprintf(fp,".");
+ break;
+ // encountered a transient error
+ case STATUS_ERROR_TRANSIENT:
+ // check if transient error is a memory clear
+ if (script[StepCount].Step == ST_CLEAR_VERIFY)
+ {
+ // put back to starting clear over again
+ StepCount = last_clear_step;
+ SubStep = 0;
+ ErrorCount = 0;
+ Status = STATUS_INPROGRESS;
+ break;
+ }
+ // if 20 tansient errors in a row then abort
+ if (ErrorCount > 20)
+ Status = STATUS_ERROR_HALT;
+ else
+ Status = STATUS_INPROGRESS;
+ break;
+ // all steps complete
+ case STATUS_COMPLETE:
+ fprintf(fp,"End script normally\n");
+ return TRUE;
+ break;
+ // non-recoverable error
+ case STATUS_ERROR_HALT:
+ fprintf(fp,"Aborting script due to non-recoverable error\n");
+ return FALSE;
+ break;
+ }
+ }
+ while (!Serial0CharArrived());
+
+ // key abort
+ fprintf(fp,"Aborting script due to key press\n");
+ return FALSE;
+}
+
+//----------------------------------------------------------------------
+// Use the script to perform a step and return.
+//
+int ThermoStep(int portnum, ThermoStateType *ThermoState,
+ ThermoScript *StateScript, int *SubStep,
+ int *Status, int *ErrorCount, char *msg)
+{
+ short rslt;
+ static int read_page_num, read_pages, write_addr, write_len;
+ static uchar *read_buf, *write_buf;
+ static uchar tbuf[5];
+
+ ErrorCount; // hush the compiler
+
+ // do the current step
+ switch (StateScript->Step)
+ {
+ // the operation is complete
+ case ST_FINISH:
+ sprintf(msg,"Operation complete");
+ *Status = STATUS_COMPLETE;
+ break;
+
+ // read the mission status page
+ case ST_READ_STATUS:
+ read_page_num = STATUS_PAGE;
+ read_pages = 1;
+ read_buf = ThermoState->MissStat.status_raw;
+ sprintf(msg,"Ready to read status page %d",
+ read_page_num);
+ *Status = STATUS_STEP_COMPLETE;
+ break;
+
+ // set up to read the alarm registers
+ case ST_READ_ALARM:
+ read_page_num = 17;
+ read_pages = 3;
+ read_buf = ThermoState->AlarmData.alarm_raw;
+ sprintf(msg,"Ready to read alarm pages %d to %d",
+ read_page_num, read_page_num + read_pages - 1);
+ *Status = STATUS_STEP_COMPLETE;
+ break;
+
+ // set up to read the histogram data
+ case ST_READ_HIST:
+ read_page_num = 64;
+ read_pages = 4;
+ read_buf = ThermoState->HistData.hist_raw;
+ sprintf(msg,"Ready to read histogram pages %d to %d",
+ read_page_num, read_page_num + read_pages - 1);
+ *Status = STATUS_STEP_COMPLETE;
+ break;
+
+ // set up to read the log data
+ case ST_READ_LOG:
+ read_page_num = 128;
+ read_pages = 64;
+ read_buf = ThermoState->LogData.log_raw;
+ sprintf(msg,"Ready to read log pages %d to %d",
+ read_page_num, read_page_num + read_pages - 1);
+ *Status = STATUS_STEP_COMPLETE;
+ break;
+
+ // read the specified pages
+ case ST_READ_PAGES:
+ // check for last page
+ if (*SubStep == 0)
+ // set the sub-step to the current page being read
+ *SubStep = read_page_num;
+ // read the status page
+ rslt = ReadPages(portnum, read_page_num, read_pages, SubStep, read_buf);
+ if (rslt == FALSE)
+ {
+ sprintf(msg,"Thermochron not on 1-Wire Net");
+ *Status = STATUS_INPROGRESS;
+ }
+ else
+ {
+ sprintf(msg,"Pages read from Thermochron");
+ *Status = STATUS_STEP_COMPLETE;
+ }
+ break;
+
+ // setup the clear memory
+ case ST_CLEAR_SETUP:
+ // create a small buff to write to start the clear memory
+ tbuf[0] = 0x40;
+ write_buf = &tbuf[0];
+ write_len = 1;
+ write_addr = 0x20E;
+ sprintf(msg,"Write to setup clear memory");
+ *Status = STATUS_STEP_COMPLETE;
+ break;
+
+ // clear the memory
+ case ST_CLEAR_MEM:
+ // set the clear memory command (not check return because verify)
+ owAccess(portnum);
+ owWriteByte(portnum,0x3C);
+ msDelay(3);
+ owTouchReset(portnum);
+ sprintf(msg,"Clear memory command sent");
+ *Status = STATUS_STEP_COMPLETE;
+ break;
+
+ // clear the memory
+ case ST_CLEAR_VERIFY:
+ // look at the memory clear bit
+ if ((ThermoState->MissStat.status_raw[0x14] & 0x40) == 0x40)
+ {
+ sprintf(msg,"Memory is clear");
+ *Status = STATUS_STEP_COMPLETE;
+ break;
+ }
+ else
+ {
+ sprintf(msg,"Memory did NOT clear");
+ *Status = STATUS_ERROR_TRANSIENT;
+ break;
+ }
+ break;
+
+ // setup write time, clock alarm, control, trips
+ case ST_WRITE_TIME:
+ // create the write buffer
+ FormatMission(&ThermoState->MissStat);
+ write_buf = &ThermoState->MissStat.status_raw[0x00];
+ write_len = 13;
+ write_addr = 0x200;
+ sprintf(msg,"Write time, clock alarm, and trips setup");
+ *Status = STATUS_STEP_COMPLETE;
+ break;
+
+ // write the control, mission delay and clear flags
+ case ST_WRITE_CONTROL:
+ write_buf = &ThermoState->MissStat.status_raw[0x0E];
+ write_len = 7;
+ write_addr = 0x20E;
+ sprintf(msg,"Write control, mission delay, clear flags setup");
+ *Status = STATUS_STEP_COMPLETE;
+ break;
+
+ case ST_WRITE_RATE:
+ write_buf = &ThermoState->MissStat.status_raw[0x0D];
+ write_len = 1;
+ write_addr = 0x20D;
+ sprintf(msg,"Write sample rate setup");
+ *Status = STATUS_STEP_COMPLETE;
+ break;
+
+ // write the specified memory location
+ case ST_WRITE_MEM:
+ if (WriteMemory(portnum, write_buf, write_len, write_addr))
+ {
+ sprintf(msg,"Memory written to Thermochron");
+ *Status = STATUS_STEP_COMPLETE;
+ }
+ else
+ {
+ sprintf(msg,"Thermochron not on 1-Wire Net");
+ *Status = STATUS_INPROGRESS;
+ }
+ default:
+ break;
+ }
+
+ return *Status;
+}
+
+//----------------------------------------------------------------------
+// Read a specified number of pages in overdrive
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
+// indicate the symbolic port number.
+//
+int ReadPages(int portnum, int start_pg, int num_pgs, int *last_pg, uchar *finalbuf)
+{
+ int skip_overaccess = 0, skip_access = 0;
+ uchar pkt[60];
+ int len,i;
+ uchar SerialNumber[8];
+ ushort lastcrc16;
+
+ // read the rom number
+ owSerialNum(portnum,SerialNumber,TRUE);
+
+ // verify device is in overdrive
+ if (current_speed[portnum] == MODE_OVERDRIVE)
+ {
+ if (owVerify(portnum,FALSE))
+ skip_overaccess = 1;
+ }
+
+ if (!skip_overaccess)
+ {
+ if (owOverdriveAccess(portnum))
+ current_speed[portnum] = MODE_OVERDRIVE;
+ else
+ current_speed[portnum] = MODE_NORMAL;
+ }
+
+ // loop while there is pages to read
+ do
+ {
+ // create a packet to read a page
+ len = 0;
+ setcrc16(portnum,0);
+ // optional skip access on subsequent pages
+ if (!skip_access)
+ {
+ // match
+ pkt[len++] = 0x55;
+ // rom number
+ for (i = 0; i < 8; i++)
+ pkt[len++] = SerialNumber[i];
+ // read memory with crc command
+ pkt[len] = 0xA5;
+ docrc16(portnum,pkt[len++]);
+ // address
+ pkt[len] = (uchar)((*last_pg << 5) & 0xFF);
+ docrc16(portnum,pkt[len++]);
+ pkt[len] = (uchar)(*last_pg >> 3);
+ docrc16(portnum,pkt[len++]);
+ }
+
+ // set 32 reads for data and 2 for crc
+ for (i = 0; i < 34; i++)
+ pkt[len++] = 0xFF;
+
+ // send the bytes
+ if (owBlock(portnum,!skip_access,pkt,len))
+ {
+ // calucate the CRC over the last 34 bytes
+ for (i = 0; i < 34; i++)
+ lastcrc16 = docrc16(portnum,pkt[len - 34 + i]);
+
+ // check crc
+ if (lastcrc16 == 0xB001)
+ {
+ // copy the data into the buffer
+#ifdef LetsCrashTheCompiler
+ for (i = 0; i < 32; i++)
+ finalbuf[i + (*last_pg - start_pg) * 32] = pkt[len - 34 + i];
+#endif
+ {
+ ushort k;
+ for (i = 0; i < 32; i++) {
+ k=i + (*last_pg - start_pg) * 32;
+ finalbuf[k] = pkt[len - 34 + i];
+ }
+ }
+ // change number of pages
+ *last_pg = *last_pg + 1;
+
+ // now skip access
+ skip_access = TRUE;
+ }
+ else
+ return FALSE;
+ }
+ else
+ return FALSE;
+ }
+ while ((*last_pg - start_pg) < num_pgs);
+
+ return TRUE;
+}
+
+//----------------------------------------------------------------------------}
+// Write a memory location. Data must all be on the same page
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
+// indicate the symbolic port number.
+//
+int WriteMemory(int portnum, uchar *Buf, int ln, int adr)
+{
+ // write to scratch and then copy
+ if (WriteScratch(portnum,Buf,ln,adr))
+ return CopyScratch(portnum,ln,adr);
+
+ return FALSE;
+}
+
+//----------------------------------------------------------------------------}
+// Write the scratch pad
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
+// indicate the symbolic port number.
+//
+int WriteScratch(int portnum, uchar *Buf, int ln, int adr)
+{
+ int i;
+ uchar pbuf[80];
+
+ // check for alarm indicator
+ if (owAccess(portnum))
+ {
+ // construct a packet to send
+ pbuf[0] = 0x0F; // write scratch command
+ pbuf[1] = (adr & 0xFF); // address 1
+ pbuf[2] = ((adr >> 8) & 0xFF); // address 2
+
+ // the write bytes
+ for (i = 0; i < ln; i++)
+ pbuf[3 + i] = (uchar)(Buf[i]); // data
+
+ // perform the block
+ if (!owBlock(portnum,FALSE,pbuf,ln+3))
+ return FALSE;
+
+ // Now read back the scratch
+ if (owAccess(portnum))
+ {
+ // construct a packet to send
+ pbuf[0] = 0xAA; // read scratch command
+ pbuf[1] = 0xFF; // address 1
+ pbuf[2] = 0xFF; // address 2
+ pbuf[3] = 0xFF; // offset
+
+ // the write bytes
+ for (i = 0; i < ln; i++)
+ pbuf[4 + i] = 0xFF; // data
+
+ // perform the block
+ if (!owBlock(portnum,FALSE,pbuf,ln+4))
+ return FALSE;
+
+ // read address 1
+ if (pbuf[1] != (adr & 0xFF))
+ return FALSE;
+ // read address 2
+ if (pbuf[2] != ((adr >> 8) & 0xFF))
+ return FALSE;
+ // read the offset
+ if (pbuf[3] != ((adr + ln - 1) & 0x1F))
+ return FALSE;
+ // read and compare the contents
+ for (i = 0; i < ln; i++)
+ {
+ if (pbuf[4 + i] != Buf[i])
+ return FALSE;
+ }
+ // success
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+
+//----------------------------------------------------------------------------}
+// Copy the scratch pad
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
+// indicate the symbolic port number.
+//
+int CopyScratch(int portnum, int ln, int adr)
+{
+ int i;
+ uchar pbuf[50];
+
+ // check for alarm indicator
+ if (owAccess(portnum))
+ {
+ // construct a packet to send
+ pbuf[0] = 0x55; // copy scratch command
+ pbuf[1] = (adr & 0xFF); // address 1
+ pbuf[2] = ((adr >> 8) & 0xFF); // address 2
+ pbuf[3] = (adr + ln - 1) & 0x1F; // offset
+ for (i = 0; i <= 9; i++)
+ pbuf[4 + i] = 0xFF; // result of copy
+
+ // perform the block
+ if (owBlock(portnum,FALSE,pbuf,14))
+ {
+ if ((pbuf[13] == 0x55) ||
+ (pbuf[13] == 0xAA))
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+//----------------------------------------------------------------------
+// Interpret the Status by looking at the 'raw' portion of the
+// mission status structure.
+//
+void InterpretStatus(MissionStatus *mstatus)
+{
+ timedate td,tdtmp;
+ int offset;
+ ulong tmtmp;
+ time_t tlong;
+ struct tm *tstruct;
+
+ // mission in progress flag
+ mstatus->mission_in_progress = (0x20 & mstatus->status_raw[0x14]) >> 5;
+
+ // sample rate
+ mstatus->sample_rate = mstatus->status_raw[0x0D];
+
+ // rollover enabled
+ mstatus->rollover_enable = (0x08 & mstatus->status_raw[0x0E]) >> 3;
+
+ // startdelay
+ mstatus->start_delay = ((int)mstatus->status_raw[0x13] << 8) |
+ mstatus->status_raw[0x12];
+
+ // number of samples in this mission
+ mstatus->mission_samples = ((long)mstatus->status_raw[0x1C] << 16) |
+ ((int)mstatus->status_raw[0x1B] << 8) |
+ mstatus->status_raw[0x1A];
+
+ // total number of samples
+ mstatus->samples_total = ((long)mstatus->status_raw[0x1F] << 16) |
+ ((int)mstatus->status_raw[0x1E] << 8) |
+ mstatus->status_raw[0x1D];
+
+ // temperature thresholds
+ mstatus->high_threshold = mstatus->status_raw[0x0C];
+ mstatus->low_threshold = mstatus->status_raw[0x0B];
+
+ // rollover occurred
+ if ((mstatus->mission_samples > 2048) && mstatus->rollover_enable)
+ mstatus->rollover_occurred = 1;
+ else
+ mstatus->rollover_occurred = 0;
+
+ // current real-time clock value
+ offset = 0x00;
+ td.second = BCDToBin((uchar)(mstatus->status_raw[offset] & 0x7F));
+ td.minute = BCDToBin((uchar)(mstatus->status_raw[offset + 1] & 0x7F));
+ // check for 12 hour mode
+ if (mstatus->status_raw[offset + 2] & 0x40)
+ {
+ td.hour = BCDToBin((uchar)(mstatus->status_raw[offset + 2] & 0x1F));
+ // check for PM
+ if (mstatus->status_raw[offset + 2] & 0x20)
+ td.hour += 12;
+ }
+ else
+ td.hour = BCDToBin((uchar)(mstatus->status_raw[offset + 2] & 0x3F));
+ td.day = BCDToBin((uchar)(mstatus->status_raw[offset + 4] & 0x3F));
+ td.month = BCDToBin((uchar)(mstatus->status_raw[offset + 5] & 0x1F));
+ td.year = BCDToBin(mstatus->status_raw[offset + 6]) + 1900;
+ // check for century bit
+ if (mstatus->status_raw[offset + 5] & 0x80)
+ td.year = BCDToBin(mstatus->status_raw[offset + 6]) + 2000; // (2.00)
+ // convert to seconds since 1970
+ mstatus->current_time = DateToSeconds(&td);
+
+ // date/time when mission started
+ offset = 0x15;
+ td.second = (uchar)0;
+ td.minute = BCDToBin((uchar)(mstatus->status_raw[offset] & 0x7F));
+ // check for 12 hour mode
+ if (mstatus->status_raw[offset + 1] & 0x40)
+ {
+ td.hour = BCDToBin((uchar)(mstatus->status_raw[offset + 1] & 0x1F));
+ // check for PM
+ if (mstatus->status_raw[offset + 1] & 0x20)
+ td.hour += 12;
+ }
+ else
+ td.hour = BCDToBin((uchar)(mstatus->status_raw[offset + 1] & 0x3F));
+ td.day = BCDToBin((uchar)(mstatus->status_raw[offset + 2] & 0x3F));
+ td.month = BCDToBin((uchar)(mstatus->status_raw[offset + 3] & 0x1F));
+ td.year = BCDToBin((uchar)(mstatus->status_raw[offset + 4])); // (2.00)
+ // (2.00) logic to decide on century of mission stamp
+ // check if century bit set in mission stamp
+ if (mstatus->status_raw[offset + 3] & 0x80)
+ td.year += 2000;
+ // check in mission in progress
+ else if (mstatus->mission_in_progress)
+ {
+ // calculate the mission start year back from real time clock
+ tmtmp = mstatus->current_time -
+ (mstatus->sample_rate * mstatus->mission_samples * 60);
+ SecondsToDate(&tdtmp,tmtmp);
+ td.year = tdtmp.year;
+ }
+ else
+ {
+ // mission stopped so get century by year window
+ if (td.year <= 70)
+ td.year += 2000;
+ else
+ td.year += 1900;
+ }
+ // convert to seconds since 1970
+ if ((td.month == 0) || (td.day == 0))
+ mstatus->mission_start_time = 0;
+ else
+ mstatus->mission_start_time = DateToSeconds(&td);
+
+ // download stations time of reading
+ time(&tlong);
+ tstruct = localtime(&tlong);
+ td.day = tstruct->tm_mday;
+ td.month = tstruct->tm_mon + 1; // (1.01)
+ td.year = tstruct->tm_year + 1900;
+ td.hour = tstruct->tm_hour;
+ td.minute = tstruct->tm_min;
+ td.second = tstruct->tm_sec;
+ mstatus->download_time = DateToSeconds(&td);
+
+ // skip alarm modes and status for now
+}
+
+//--------------------------------------------------------------------------
+// Take the Mission Status structure and create new raw data to start
+// a new mission.
+//
+void FormatMission(MissionStatus *mstatus)
+{
+ int i;
+ time_t tlong;
+ struct tm *tstruct;
+
+ // clear the buffer
+ for (i = 0; i < 32; i++)
+ mstatus->status_raw[i] = 0;
+
+ // Real Time Clock
+ time(&tlong);
+ tlong++; // add 1 second
+ tstruct = localtime(&tlong);
+ // convert to BCD
+ mstatus->status_raw[0x00] = ToBCD((short)tstruct->tm_sec);
+ mstatus->status_raw[0x01] = ToBCD((short)tstruct->tm_min);
+ mstatus->status_raw[0x02] = ToBCD((short)tstruct->tm_hour);
+ mstatus->status_raw[0x03] = ToBCD((short)(tstruct->tm_wday + 1));
+ mstatus->status_raw[0x04] = ToBCD((short)tstruct->tm_mday);
+ mstatus->status_raw[0x05] = ToBCD((short)(tstruct->tm_mon + 1));
+ if (tstruct->tm_year >= 100)
+ mstatus->status_raw[0x05] |= 0x80;
+ mstatus->status_raw[0x06] = ToBCD((short)(tstruct->tm_year % 100));
+ // Real Time clock Alarm (leave 0's)
+ // Low temp alarm
+ mstatus->status_raw[0x0B] = mstatus->low_threshold;
+ // High temp alarm
+ mstatus->status_raw[0x0C] = mstatus->high_threshold;
+ // sample rate
+ mstatus->status_raw[0x0D] = mstatus->sample_rate;
+ // control
+ mstatus->status_raw[0x0E] = 0x40;
+ if (mstatus->rollover_enable)
+ mstatus->status_raw[0x0E] |= 0x08;
+ // mission start delay
+ mstatus->status_raw[0x12] = mstatus->start_delay & 0xFF;
+ mstatus->status_raw[0x13] = (mstatus->start_delay >> 8) & 0xFF;
+}
+
+//--------------------------------------------------------------------------
+// Convert an integer to a 1 Byte BCD number (99 max)
+//
+uchar ToBCD(short num)
+{
+ uchar rtbyte;
+
+ rtbyte = (num - ((num / 10) * 10)) & 0x0F;
+ rtbyte = rtbyte | ((num / 10) << 4);
+
+ return rtbyte;
+}
+
+
+//--------------------------------------------------------------------------
+// Take the Mission Status structure and convert to string format
+//
+void MissionStatusToString(MissionStatus *mstatus, int ConvertToF, char *str)
+{
+ int cnt=0,i;
+ timedate td;
+ time_t tlong;
+ struct tm *tstruct;
+
+ // title
+ cnt += sprintf(&str[cnt],"Mission State\n-------------\n");
+
+ // serial number
+ cnt += sprintf(&str[cnt],"Serial Number of DS1921: ");
+ for (i = 7; i >= 0; i--)
+ cnt += sprintf(&str[cnt],"%02X",mstatus->serial_num[i]);
+
+ // mission state
+ if (mstatus->mission_in_progress)
+ cnt += sprintf(&str[cnt],"\nMission is in progress\n");
+ else
+ cnt += sprintf(&str[cnt],"\nMission is ended\n");
+
+ // sample rate
+ cnt += sprintf(&str[cnt],"Sample rate: %d minute(s)\n",mstatus->sample_rate);
+
+ // rollover
+ cnt += sprintf(&str[cnt],"Roll-Over Enabled: ");
+ if (mstatus->rollover_enable)
+ cnt += sprintf(&str[cnt],"yes\n");
+ else
+ cnt += sprintf(&str[cnt],"no\n");
+ cnt += sprintf(&str[cnt],"Roll-Over Occurred: ");
+ if (mstatus->rollover_occurred)
+ cnt += sprintf(&str[cnt],"yes\n");
+ else
+ cnt += sprintf(&str[cnt],"no\n");
+
+ // mission start time
+ if (mstatus->start_delay == 0)
+ {
+ SecondsToDate(&td,mstatus->mission_start_time);
+ if (mstatus->mission_start_time == 0)
+ cnt += sprintf(&str[cnt],"Mission Start time: not started yet\n");
+ else
+ cnt += sprintf(&str[cnt],"Mission Start time: %02d/%02d/%04d %02d:%02d:%02d\n",
+ td.month,td.day,td.year,td.hour,td.minute,td.second);
+ }
+ else
+ cnt += sprintf(&str[cnt],"Mission Start time: na\n");
+
+ // mission start delay
+ cnt += sprintf(&str[cnt],"Mission Start delay: %d minute(s)\n",mstatus->start_delay);
+
+ // mission samples
+ cnt += sprintf(&str[cnt],"Mission Samples: %d\n",mstatus->mission_samples);
+
+ // device total samples
+ cnt += sprintf(&str[cnt],"Device total samples: %d\n",mstatus->samples_total);
+
+ // temperature display mode
+ cnt += sprintf(&str[cnt],"Temperature displayed in: ");
+ if (ConvertToF)
+ cnt += sprintf(&str[cnt],"(Fahrenheit)\n");
+ else
+ cnt += sprintf(&str[cnt],"(Celsius)\n");
+
+ // thresholds
+ cnt += sprintf(&str[cnt],"High Threshold: %6.1f\n",
+ TempToFloat(mstatus->high_threshold,ConvertToF));
+ cnt += sprintf(&str[cnt],"Low Threshold: %6.1f\n",
+ TempToFloat(mstatus->low_threshold,ConvertToF));
+
+ // time from D1921
+ SecondsToDate(&td,mstatus->current_time);
+ cnt += sprintf(&str[cnt],"Current Real-Time Clock from DS1921: %02d/%02d/%04d %02d:%02d:%02d\n",
+ td.month,td.day,td.year,td.hour,td.minute,td.second);
+
+ // current PC time
+ time(&tlong);
+ tstruct = localtime(&tlong);
+ cnt += sprintf(&str[cnt],"Current PC Time: %02d/%02d/%04d %02d:%02d:%02d\n",
+ tstruct->tm_mon + 1,tstruct->tm_mday,tstruct->tm_year + 1900,
+ tstruct->tm_hour,tstruct->tm_min,tstruct->tm_sec);
+
+ // zero terminate string
+ str[cnt] = 0;
+}
+
+//----------------------------------------------------------------------
+// Interpret the Histogram by looking at the 'raw' portion of the
+// Histogram structure. Store the temperature range values in Celsius.
+//
+void InterpretHistogram(Histogram *hist)
+{
+ int i;
+
+ // loop through each bin value
+ for (i = 0; i < 126; i += 2) // (2.00)
+ {
+ // get the bin value
+ hist->bin_count[i / 2] = hist->hist_raw[i] | ((int)hist->hist_raw[i + 1] << 8);
+
+ // start value for this bin
+ hist->start_range[i / 2] = TempToFloat((uchar)((i / 2) << 2),FALSE);
+
+ // end value for this bin
+ hist->end_range[i / 2] = TempToFloat((uchar)(((i / 2) << 2) | 0x03),FALSE);
+ }
+}
+
+//--------------------------------------------------------------------------
+// Take the Histogram structure and convert to string format
+//
+void HistogramToString(Histogram *hist, int ConvertToF, char *str)
+{
+ int cnt=0,i;
+
+ // title
+ cnt += sprintf(&str[cnt],"Temperature Histogram\n---------------------\n"
+ "Format: [Temp Range, Count] ");
+ if (ConvertToF)
+ cnt += sprintf(&str[cnt],"(Fahrenheit)\n");
+ else
+ cnt += sprintf(&str[cnt],"(Celsius)\n");
+
+ // loop through bins
+ for (i = 0; i < 63; i++) // (2.00)
+ {
+ cnt += sprintf(&str[cnt],"%6.1f to %6.1f, %d\n",
+ (ConvertToF) ? CToF(hist->start_range[i]): hist->start_range[i],
+ (ConvertToF) ? CToF(hist->end_range[i]): hist->end_range[i],
+ hist->bin_count[i]);
+ }
+
+ // zero terminate string
+ str[cnt] = 0;
+}
+
+//----------------------------------------------------------------------
+// Interpret the Temperature Alarm Event data by looking at the 'raw'
+// portion of the TempAlarmEvents structure. Mission Status is needed
+// to interpret the events.
+//
+void InterpretAlarms(TempAlarmEvents *alarm, MissionStatus *mstatus)
+{
+ int i;
+ ulong event_mission_count;
+ uchar duration;
+
+ // low events
+ alarm->num_low = 0;
+ for (i = 0; i < 48; i += 4)
+ {
+ // get the mission start count of this event
+ event_mission_count = ((long)alarm->alarm_raw[i + 2] << 16) |
+ ((int)alarm->alarm_raw[i + 1] << 8) |
+ alarm->alarm_raw[i];
+
+ // check if done with low events
+ if (!event_mission_count)
+ break;
+
+ // get the duration
+ duration = alarm->alarm_raw[i + 3];
+
+ // calculate the start time
+ alarm->low_start_time[alarm->num_low] =
+ mstatus->mission_start_time +
+ (event_mission_count - 1) * (mstatus->sample_rate * 60);
+
+ // calculate the end time
+ alarm->low_end_time[alarm->num_low] =
+ alarm->low_start_time[alarm->num_low] +
+ (duration - 1) * (mstatus->sample_rate * 60);
+
+ // increment number of low events
+ alarm->num_low++;
+ }
+
+ // high events
+ alarm->num_high = 0;
+ for (i = 48; i < 96; i += 4)
+ {
+ // get the mission start count of this event
+ event_mission_count = ((long)alarm->alarm_raw[i + 2] << 16) |
+ ((int)alarm->alarm_raw[i + 1] << 8) |
+ alarm->alarm_raw[i];
+
+ // check if done with low events
+ if (!event_mission_count)
+ break;
+
+ // get the duration
+ duration = alarm->alarm_raw[i + 3];
+
+ // calculate the start time
+ alarm->high_start_time[alarm->num_high] =
+ mstatus->mission_start_time +
+ (event_mission_count - 1) * (mstatus->sample_rate * 60);
+
+ // calculate the end time
+ alarm->high_end_time[alarm->num_high] =
+ alarm->high_start_time[alarm->num_high] +
+ (duration - 1) * (mstatus->sample_rate * 60);
+
+ // increment number of low events
+ alarm->num_high++;
+ }
+}
+
+//--------------------------------------------------------------------------
+// Take the Temperature Alarms Events structure and convert to string
+// format
+//
+void AlarmsToString(TempAlarmEvents *alarm, char *str)
+{
+ int i, cnt=0;
+ timedate td;
+
+ // title
+ cnt += sprintf(&str[cnt],"Temperature Alarms\n------------------\n"
+ "Format: [(HIGH/LOW), Time/Date Range]\n");
+
+ // loop through each low alarm
+ for (i = 0; i < alarm->num_low; i++)
+ {
+ cnt += sprintf(&str[cnt],"LOW , ");
+ // start time
+ SecondsToDate(&td,alarm->low_start_time[i]);
+ cnt += sprintf(&str[cnt]," %02d/%02d/%04d %02d:%02d to ",
+ td.month,td.day,td.year,td.hour,td.minute);
+ // end time
+ SecondsToDate(&td,alarm->low_end_time[i]);
+ cnt += sprintf(&str[cnt]," %02d/%02d/%04d %02d:%02d\n",
+ td.month,td.day,td.year,td.hour,td.minute);
+ }
+
+ // loop through each high alarm
+ for (i = 0; i < alarm->num_high; i++)
+ {
+ cnt += sprintf(&str[cnt],"HIGH , ");
+ // start time
+ SecondsToDate(&td,alarm->high_start_time[i]);
+ cnt += sprintf(&str[cnt]," %02d/%02d/%04d %02d:%02d to ",
+ td.month,td.day,td.year,td.hour,td.minute);
+ // end time
+ SecondsToDate(&td,alarm->high_end_time[i]);
+ cnt += sprintf(&str[cnt]," %02d/%02d/%04d %02d:%02d\n",
+ td.month,td.day,td.year,td.hour,td.minute);
+ }
+
+ // zero terminate string
+ str[cnt] = 0;
+}
+
+//----------------------------------------------------------------------
+// Interpret the Log data by looking at the 'raw'
+// portion of the Log structure. Mission Status is needed
+// to interpret when the logs occurred.
+//
+void InterpretLog(Log *log, MissionStatus *mstatus)
+{
+ ulong loops=0,overlap=0,lastlog=2048,i;
+ int logcnt=0;
+
+ // check if wrap occurred
+ if (mstatus->rollover_occurred)
+ {
+ // calculate the number loops
+ loops = (mstatus->mission_samples / 2048) - 1;
+ // calculate the number of overlap
+ overlap = mstatus->mission_samples % 2048;
+ log->num_log = 2048;
+ }
+ else
+ {
+ log->start_time = mstatus->mission_start_time;
+ if (mstatus->mission_samples > 2048) // (1.02)
+ lastlog = 2048;
+ else
+ lastlog = mstatus->mission_samples;
+ log->num_log = (int)lastlog;
+ }
+
+ // set the interval
+ log->interval = mstatus->sample_rate * 60;
+
+ // caluclate the start time of the first log value
+ log->start_time = mstatus->mission_start_time +
+ loops * 2048 * log->interval + overlap * log->interval;
+
+ // loop to fill in the remainder first
+ for (i = overlap; i < lastlog; i++)
+ log->temp[logcnt++] = TempToFloat(log->log_raw[i],FALSE);
+
+ // loop to get the overlap
+ for (i = 0; i < overlap; i++)
+ log->temp[logcnt++] = TempToFloat(log->log_raw[i],FALSE);
+}
+
+//--------------------------------------------------------------------------
+// Take the Log structure and convert to string
+// format
+//
+void LogToString(Log *log, int ConvertToF, char *str)
+{
+ int i,cnt=0;
+ ulong logtime;
+ timedate td;
+
+ // title
+ cnt += sprintf(&str[cnt],"Log Data\n--------\n"
+ "Format: [Time/Date , Temperature] ");
+ if (ConvertToF)
+ cnt += sprintf(&str[cnt],"(Fahrenheit)\n");
+ else
+ cnt += sprintf(&str[cnt],"(Celsius)\n");
+
+ // loop through the logs
+ logtime = log->start_time;
+ for (i = 0; i < log->num_log; i++)
+ {
+ // time
+ SecondsToDate(&td,logtime);
+ cnt += sprintf(&str[cnt],"%02d/%02d/%04d %02d:%02d ,",
+ td.month,td.day,td.year,td.hour,td.minute);
+ // temp
+ cnt += sprintf(&str[cnt],"%6.1f\n",
+ (ConvertToF) ? CToF(log->temp[i]): log->temp[i]);
+
+ // increment the time
+ logtime += log->interval;
+ }
+
+ // zero terminate string
+ str[cnt] = 0;
+}
+
+//--------------------------------------------------------------------------
+// Convert the raw debug data to a string
+//
+void DebugToString(MissionStatus *mstatus, TempAlarmEvents *alarm,
+ Histogram *hist, Log *log, char *str)
+{
+ int i,cnt=0;
+
+ // title
+ cnt += sprintf(&str[cnt],"Debug Dump\n----------\nRegister Page:\n");
+
+ // reg
+ for (i = 0; i < 32; i++)
+ {
+ cnt += sprintf(&str[cnt],"%02X ",mstatus->status_raw[i]);
+ if (i && (((i + 1) % 16) == 0))
+ cnt += sprintf(&str[cnt],"\n");
+ }
+
+ // alarms
+ cnt += sprintf(&str[cnt],"Alarms:\n");
+ for (i = 0; i < 96; i++)
+ {
+ cnt += sprintf(&str[cnt],"%02X ",alarm->alarm_raw[i]);
+ if (i && (((i + 1) % 16) == 0))
+ cnt += sprintf(&str[cnt],"\n");
+ }
+
+ // histogram
+ cnt += sprintf(&str[cnt],"Histogram:\n");
+ for (i = 0; i < 128; i++)
+ {
+ cnt += sprintf(&str[cnt],"%02X ",hist->hist_raw[i]);
+ if (i && (((i + 1) % 16) == 0))
+ cnt += sprintf(&str[cnt],"\n");
+ }
+
+
+ // log
+ cnt += sprintf(&str[cnt],"Log:\n");
+ for (i = 0; i < ((log->num_log > 2048) ? 2048 : log->num_log); i++)
+ {
+ cnt += sprintf(&str[cnt],"%02X ",log->log_raw[i]);
+ if (i && (((i + 1) % 16) == 0))
+ cnt += sprintf(&str[cnt],"\n");
+ }
+
+ // zero terminate string
+ str[cnt] = 0;
+}
+
+//--------------------------------------------------------------------------
+// Take one byte BCD value and return binary value
+//
+uchar BCDToBin(uchar bcd)
+{
+ return (((bcd & 0xF0) >> 4) * 10) + (bcd & 0x0F);
+}
+
+
+//--------------------------------------------------------------------------
+// Take a 4 byte long string and convert it into a timedata structure.
+//
+static int dm[] = { 0,0,31,59,90,120,151,181,212,243,273,304,334,365 };
+
+void SecondsToDate(timedate *td, ulong x)
+{
+ short tmp,i,j;
+ ulong y;
+
+ // check to make sure date is not over 2070 (sanity check)
+ if (x > 0xBBF81E00L)
+ x = 0;
+
+ y = x/60; td->second = (ushort)(x-60*y);
+ x = y/60; td->minute = (ushort)(y-60*x);
+ y = x/24; td->hour = (ushort)(x-24*y);
+ x = 4*(y+731); td->year = (ushort)(x/1461);
+ i = (int)((x-1461*(ulong)(td->year))/4); td->month = 13;
+
+ do
+ {
+ td->month -= 1;
+ tmp = (td->month > 2) && ((td->year & 3)==0) ? 1 : 0;
+ j = dm[td->month]+tmp;
+
+ } while (i < j);
+
+ td->day = i-j+1;
+
+ // slight adjustment to algorithm
+ if (td->day == 0)
+ td->day = 1;
+
+ td->year = (td->year < 32) ? td->year + 68 + 1900: td->year - 32 + 2000;
+}
+
+//--------------------------------------------------------------------------
+// DateToSeconds takes a time/date structure and converts it into the
+// number of seconds since 1970
+//
+ulong DateToSeconds(timedate *td)
+{
+ ulong Sv,Bv,Xv;
+
+ // convert the date/time values into the 5 byte format used in the touch
+ if (td->year >= 2000)
+ Sv = td->year + 32 - 2000;
+ else
+ Sv = td->year - 68 - 1900;
+
+ if ((td->month > 2) && ( (Sv & 3) == 0))
+ Bv = 1;
+ else
+ Bv = 0;
+
+ Xv = 365 * (Sv-2) + (Sv-1)/4 + dm[td->month] + td->day + Bv - 1;
+
+ Xv = 86400 * Xv + (ulong)(td->second) + 60*((ulong)(td->minute) + 60*(ulong)(td->hour));
+
+ return Xv;
+}
+
+//--------------------------------------------------------------------------
+// Convert from DS1921 termature format to a float
+//
+//
+float TempToFloat(uchar tmp, int ConvertToF)
+{
+ float tfloat;
+
+ tfloat = (float)((tmp / 2.0) - 40.0);
+
+ if (ConvertToF)
+ return (float)(tfloat * 9.0 / 5.0 + 32.0);
+ else
+ return tfloat;
+}
+
+//--------------------------------------------------------------------------
+// Convert from Celsius to Fahrenheit
+//
+float CToF(float CVal)
+{
+ return (float)(CVal * 9.0 / 5.0 + 32.0);
+}
--- /dev/null
+//---------------------------------------------------------------------------
+// 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.
+//---------------------------------------------------------------------------
+//
+// thermo.h - Include file for Thermochron demo.
+//
+// Version: 2.00
+//
+// History:
+// 1.03 -> 2.00 Reorganization of Public Domain Kit
+
+#ifndef THERMO_TYPES
+
+#define THERMO_TYPES
+
+// hacks for sdcc->TINI
+#define NULL ((void*)0)
+#define FILE void
+#define stdin ((void *)0)
+#define stdout ((void *)0)
+#define stderr ((void *)0)
+int fprintf (FILE *fp, xdata char *format, ...) reentrant;
+
+// defines
+#define STATUS_PAGE 16
+#define THERMO_FAM 0x21
+
+#include <stdlib.h>
+
+// Typedefs
+#ifndef OW_UCHAR
+ #define OW_UCHAR
+ typedef unsigned char uchar;
+ #ifdef WIN32
+ typedef unsigned short ushort;
+ typedef unsigned long ulong;
+ #endif
+#endif
+
+// structure to hold the mission status
+typedef struct
+{
+ uchar serial_num[8]; // serial number of thermochron
+
+ uchar mission_in_progress; // 1 mission in progres, 0 mission over
+
+ uchar sample_rate; // minutes between samples
+
+ uchar rollover_enable; // 1 if roll-over enabled
+ uchar rollover_occurred; // 1 if roll-over occurred
+
+ ushort start_delay; // minutes before mission starts
+
+ ulong mission_start_time; // date/time when mission started
+ ulong current_time; // current real-time clock value
+ ulong download_time; // download stations time of reading
+
+ ulong mission_samples; // number of samples in this mission
+ ulong samples_total; // total number of samples taken by device
+
+ uchar high_threshold; // raw temp of high threshold
+ uchar low_threshold; // raw temp of low threshold
+
+ // skip alarm modes and status for now
+
+ uchar status_raw[32];
+
+} MissionStatus;
+
+// structure to hold the histogram data
+typedef struct
+{
+ ushort bin_count[56]; // counter per bin 0 to 55
+ float start_range[56]; // start temp range (C) in bin 0 to 55
+ float end_range[56]; // end temp range (C) in bin 0 to 55
+
+ uchar hist_raw[128]; // raw data for histogram
+
+} Histogram;
+
+// structure to hold the histogram data
+typedef struct
+{
+ int num_low; // number of low events
+ ulong low_start_time[12]; // start time of event 0 to 12
+ ulong low_end_time[12]; // end time of event 0 to 12
+ int num_high; // number of high events
+ ulong high_start_time[12]; // start time of event 0 to 12
+ ulong high_end_time[12]; // end time of event 0 to 12
+
+ uchar alarm_raw[96]; // raw data for alarm events
+
+} TempAlarmEvents;
+
+// structure to hold the log data
+typedef struct
+{
+ int num_log; // number of logs
+ float temp[2048]; // temperature log in (C)
+ ulong start_time; // start time of log
+ int interval; // interval in seconds between logs
+
+ uchar log_raw[2048]; // raw data for log
+
+} Log;
+
+// structure to hold all of the thermochron data state
+typedef struct
+{
+ MissionStatus MissStat; // mission state
+ Histogram HistData; // histogram data
+ TempAlarmEvents AlarmData; // temperature alarm event data
+ Log LogData; // log data
+
+} ThermoStateType;
+
+// type structure to holde time/date
+typedef struct
+{
+ ushort second;
+ ushort minute;
+ ushort hour;
+ ushort day;
+ ushort month;
+ ushort year;
+} timedate;
+
+// structure to hold each state in the StateMachine
+typedef struct
+{
+ int Step;
+ char StepDescription[50];
+
+} ThermoScript;
+
+// Global Function Prototypes
+ int DownloadThermo(int,uchar *,ThermoStateType *, FILE *);
+int ReadThermoStatus(int,uchar *,ThermoStateType *, FILE *);
+int MissionThermo(int,uchar *,ThermoStateType *, FILE *);
+void SecondsToDate(timedate *, ulong);
+ulong DateToSeconds(timedate *);
+uchar BCDToBin(uchar);
+ void InterpretStatus(MissionStatus *);
+ void MissionStatusToString(MissionStatus *, int, char *);
+void FormatMission(MissionStatus *);
+ void InterpretHistogram(Histogram *);
+ void HistogramToString(Histogram *, int, char *);
+ void InterpretAlarms(TempAlarmEvents *, MissionStatus *);
+ void AlarmsToString(TempAlarmEvents *, char *);
+ void InterpretLog(Log *, MissionStatus *);
+ void LogToString(Log *, int, char *);
+ void DebugToString(MissionStatus *, TempAlarmEvents *, Histogram *, Log *, char *);
+float TempToFloat(uchar, int);
+float CToF(float);
+uchar ToBCD(short);
+
+#endif
--- /dev/null
+//---------------------------------------------------------------------------
+// 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.
+//---------------------------------------------------------------------------
+//
+// thermodl.c - This utility uses to download the results of the
+// current mission of a DS1921 Thermochron iButton.
+//
+// Version: 2.00
+//
+// History:
+// 1.03 -> 2.00 Reorganization of Public Domain Kit
+// Y2K update, display all histogram bins, debug
+// dump. Supports multiple thermochons.
+//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "ownet.h"
+#include "thermo21.h"
+
+// TINI hack
+#define ExitProg(msg,exit_code) {printf("%s\n",msg); exit(exit_code);}
+
+// defines
+#define MAXDEVICES 20
+
+// local function prototypes
+static void PrintResults(ThermoStateType *,FILE *,int);
+
+//----------------------------------------------------------------------
+// This is the Main routine for thermodl.
+//
+int main()
+{
+ int Fahrenheit=FALSE,num,i,j;
+ FILE *fp=stdout;
+ char return_msg[128];
+ ThermoStateType ThermoState;
+ uchar ThermoSN[MAXDEVICES][8]; //the serial numbers for the devices
+ int portnum=0;
+
+ // attempt to acquire the 1-Wire Net
+ if (!owAcquire(portnum,""))
+ return 0;
+
+ // success
+
+ //----------------------------------------
+ // Introduction
+ printf("\n/----------------------------------------------\n");
+ printf(" Find and download DS1921 Thermochron iButton(s)\n"
+ " Version 2.00\n\n");
+
+ // check arguments for temperature conversion and filename
+ Fahrenheit = FALSE;
+
+ // get list of Thermochron's
+ num = FindDevices(portnum, &ThermoSN[0],THERMO_FAM, MAXDEVICES);
+
+ // check if not present or more then 1 present
+ if (num == 0)
+ ExitProg("Thermochron not present on 1-Wire\n",1);
+
+ // loop to download each Thermochron
+ for (i = 0; i < num; i++)
+ {
+ // set the serial number portion in the thermo state
+ printf("\nDownloading: ");
+ for (j = 7; j >= 0; j--)
+ {
+ ThermoState.MissStat.serial_num[j] = ThermoSN[i][j];
+ printf("%02X",ThermoSN[i][j]);
+ }
+ printf("\n");
+
+ // download the Thermochron found
+ if (DownloadThermo(portnum,&ThermoSN[i][0],&ThermoState,stdout))
+ {
+ // interpret the results of the download
+ InterpretStatus(&ThermoState.MissStat);
+ InterpretAlarms(&ThermoState.AlarmData, &ThermoState.MissStat);
+ InterpretHistogram(&ThermoState.HistData);
+ InterpretLog(&ThermoState.LogData, &ThermoState.MissStat);
+
+ // print the output
+ PrintResults(&ThermoState,fp,Fahrenheit);
+ }
+ else
+ {
+ fprintf(fp,"\nError downloading device: ");
+ for (j = 0; j < 8; j++)
+ fprintf(fp,"%02X",ThermoSN[i][j]);
+ fprintf(fp,"\n");
+ }
+ }
+
+ // release the 1-Wire Net
+ owRelease(portnum);
+ printf("\n%s",return_msg);
+ ExitProg("End program normally\n",0);
+
+ return 0;
+}
+
+//--------------------------------------------------------------------------
+// Prints the mission data optionaly to a file or standard out
+//
+void PrintResults(ThermoStateType *ThermoState, FILE *fp, int ConvertToF)
+{
+ //char *str;
+ char str[80000];
+
+ // check if need to use standard out
+ if (fp == NULL)
+ fp = stdout;
+
+ // get big block to use as a buffer
+#if 0
+ str = malloc(80000);
+ if (str == NULL)
+ {
+ printf("Insufficient memory available to print!\n");
+ return;
+ }
+#endif
+
+ // mission status
+ MissionStatusToString(&ThermoState->MissStat, ConvertToF, &str[0]);
+ fprintf(fp,"\n%s\n",str);
+
+ // alarm events
+ AlarmsToString(&ThermoState->AlarmData, &str[0]);
+ fprintf(fp,"%s\n",str);
+
+ // histogram
+ HistogramToString(&ThermoState->HistData, ConvertToF, &str[0]);
+ fprintf(fp,"%s\n",str);
+
+ // log data
+ LogToString(&ThermoState->LogData, ConvertToF, &str[0]);
+ fprintf(fp,"%s\n",str);
+
+ // debug raw data
+ DebugToString(&ThermoState->MissStat, &ThermoState->AlarmData,
+ &ThermoState->HistData, &ThermoState->LogData, &str[0]);
+ fprintf(fp,"%s\n",str);
+
+ // free the memory block used
+ //free(str);
+}
+
--- /dev/null
+#include "time.h"
+
+// let's just pretend it's 01 jan 1970 00.00:00 for now
+
+time_t time(time_t *t) {
+ *t=0;
+ return *t;
+}
+
+struct tm lastTime;
+
+struct tm *localtime(const time_t *timep) {
+ timep; // hush the compiler
+ lastTime.tm_sec=0;
+ lastTime.tm_min=0;
+ lastTime.tm_hour=0;
+ lastTime.tm_mday=1;
+ lastTime.tm_mon=0;
+ lastTime.tm_year=101;
+ lastTime.tm_wday=0;
+ lastTime.tm_yday=0;
+ lastTime.tm_isdst=0;
+ return &lastTime;
+}
--- /dev/null
+struct tm
+{
+ int tm_sec; /* Seconds. [0-60] (1 leap second) */
+ int tm_min; /* Minutes. [0-59] */
+ int tm_hour; /* Hours. [0-23] */
+ int tm_mday; /* Day. [1-31] */
+ int tm_mon; /* Month. [0-11] */
+ int tm_year; /* Year - 1900. */
+ int tm_wday; /* Day of week. [0-6] */
+ int tm_yday; /* Days in year.[0-365] */
+ int tm_isdst; /* Daylight saving time */
+};
+
+typedef unsigned long time_t;
+
+time_t time(time_t *t);
+struct tm *localtime(time_t *timep);
--- /dev/null
+//---------------------------------------------------------------------------
+// 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.
+//---------------------------------------------------------------------------
+//
+// TODO.C - COM functions required by MLANLL.C, MLANTRNU, MLANNETU.C and
+// MLanFile.C for MLANU to communicate with the DS2480 based
+// Universal Serial Adapter 'U'. Fill in the platform specific code.
+//
+// Version: 1.02
+//
+// History: 1.00 -> 1.01 Added function msDelay.
+//
+// 1.01 -> 1.02 Changed to generic OpenCOM/CloseCOM for easier
+// use with other platforms.
+//
+
+//--------------------------------------------------------------------------
+// Copyright (C) 1998 Andrea Chambers and University of Newcastle upon Tyne,
+// 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 THE UNIVERSITY OF NEWCASTLE UPON TYNE OR ANDREA CHAMBERS
+// 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.
+//---------------------------------------------------------------------------
+//
+// LinuxLNK.C - COM functions required by MLANLLU.C, MLANTRNU.C, MLANNETU.C
+// and MLanFile.C for MLANU to communicate with the DS2480 based
+// Universal Serial Adapter 'U'. Platform specific code.
+//
+// Version: 1.03
+// History: 1.00 -> 1.03 modifications by David Smiczek
+// Changed to use generic OpenCOM/CloseCOM
+// Pass port name to OpenCOM instead of hard coded
+// Changed msDelay to handle long delays
+// Reformatted to look like 'TODO.C'
+// Added #include "ds2480.h" to use constants.
+// Added function SetBaudCOM()
+// Added function msGettick()
+// Removed delay from WriteCOM(), used tcdrain()
+// Added wait for byte available with timeout using
+// select() in ReadCOM()
+//
+// 1.03 -> 2.00 Support for multiple ports. Include "ownet.h". Use
+// 'uchar'. Reorder functions. Provide correct
+// return values to OpenCOM. Replace 'makeraw' call.
+// Should now be POSIX.
+//
+
+#include <stdio.h>
+
+#include "ownet.h"
+#include "ds2480.h"
+
+//---------------------------------------------------------------------------
+// Attempt to open a com port.
+// Set the starting baud rate to 9600.
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number provided will
+// be used to indicate the port number desired when calling
+// all other functions in this library.
+//
+// 'port_zstr' - zero terminate port name. For this platform
+// ignored for now
+//
+//
+// Returns: TRUE(1) - success, COM port opened
+// FALSE(0) - failure, could not open specified port
+//
+int OpenCOM(int portnum, char *port_zstr)
+{
+ unsigned long baud=9600;
+
+ //printf ("OpenCOM(%d,\"%s\")\n", portnum, port_zstr);
+
+ // hush the compiler
+ portnum;
+ port_zstr;
+
+ Serial1Init(baud,1);
+
+ return TRUE; // changed (2.00), used to return fd;
+}
+
+//---------------------------------------------------------------------------
+// Closes the connection to the port.
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
+// OpenCOM to indicate the port number.
+//
+void CloseCOM(int portnum)
+{
+ //printf ("CloseCOM(%d)\n", portnum);
+
+ // hush the compiler
+ portnum;
+}
+
+
+//--------------------------------------------------------------------------
+// Write an array of bytes to the COM port, verify that it was
+// sent out. Assume that baud rate has been set.
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number provided will
+// be used to indicate the port number desired when calling
+// all other functions in this library.
+// Returns 1 for success and 0 for failure
+//
+int WriteCOM(int portnum, int outlen, uchar *outbuf)
+{
+ int i;
+
+ //printf ("WriteCOM(%d, %d,...): ", portnum, outlen, outbuf);
+
+ // hush the compiler
+ portnum;
+
+ for (i=0; i<outlen; i++) {
+ //printf ("%02x ", outbuf[i]);
+ Serial1PutChar(outbuf[i]);
+ }
+ //printf ("\n");
+ return TRUE;
+}
+
+//--------------------------------------------------------------------------
+// Read an array of bytes to the COM port, verify that it was
+// sent out. Assume that baud rate has been set.
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
+// OpenCOM to indicate the port number.
+// 'outlen' - number of bytes to write to COM port
+// 'outbuf' - pointer ot an array of bytes to write
+//
+// Returns: TRUE(1) - success
+// FALSE(0) - failure
+//
+int ReadCOM(int portnum, int inlen, uchar *inbuf)
+{
+ int i;
+
+ //printf ("ReadCOM(%d,%d,...): ", portnum, inlen);
+
+ // hush the compiler
+ portnum;
+
+ for (i=0; i<inlen; i++) {
+ inbuf[i]=Serial1GetChar();
+ //printf ("%02x ", inbuf[i]);
+ }
+ //printf ("\n");
+
+ // success, so return desired length
+ return i;
+}
+
+
+//---------------------------------------------------------------------------
+// Description:
+// flush the rx and tx buffers
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
+// OpenCOM to indicate the port number.
+//
+void FlushCOM(int portnum)
+{
+ //printf ("FlushCOM(%d): ", portnum);
+
+ // hush the compiler
+ portnum;
+
+ Serial1Flush();
+}
+
+
+//--------------------------------------------------------------------------
+// Description:
+// Send a break on the com port for at least 2 ms
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
+// OpenCOM to indicate the port number.
+//
+
+void BreakCOM(int portnum)
+{
+ //printf ("BreakCOM(%d)\n", portnum);
+ // hush the compiler
+ portnum;
+
+ Serial1SendBreak();
+}
+
+
+//--------------------------------------------------------------------------
+// Set the baud rate on the com port.
+//
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
+// OpenCOM to indicate the port number.
+// 'new_baud' - new baud rate defined as
+// PARMSET_9600 0x00
+// PARMSET_19200 0x02
+// PARMSET_57600 0x04
+// PARMSET_115200 0x06
+//
+
+void SetBaudCOM(int portnum, int new_baud)
+{
+ unsigned long baud;
+ //printf ("SetBaudCOM(%d,%d)\n", portnum, new_baud);
+
+ portnum; // hush the compiler
+
+ switch (new_baud) {
+ case PARMSET_9600: baud=9600; break;
+ case PARMSET_19200: baud=19200; break;
+ case PARMSET_57600: baud=57600; break;
+ case PARMSET_115200: baud=115200; break;
+ default:
+ return;
+ }
+ Serial1Baud(baud);
+}
+
+//--------------------------------------------------------------------------
+// Get the current millisecond tick count. Does not have to represent
+// an actual time, it just needs to be an incrementing timer.
+//
+long msGettick(void)
+{
+ return ClockTicks();
+}
+
+
+//--------------------------------------------------------------------------
+// Description:
+// Delay for at least 'len' ms
+//
+void msDelay(int len)
+{
+ ClockMilliSecondsDelay(len);
+}
+
--- /dev/null
+//---------------------------------------------------------------------------
+// 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.
+//---------------------------------------------------------------------------
+//
+// tstfind.C - Test application to search for all 1-Wire devices on 1-Wire
+// Net.
+//
+// Version: 2.00
+//
+// 1.02 -> 1.03 Removed caps in #includes for Linux capatibility
+// Removed "ds2480.h", <windows.h> and <conio.h>
+// includes because not needed
+// Added "ownet.h" include to define TRUE/FALSE
+// Prompt to search again
+// Changed to use Acquire/Release 1-Wire Net functions
+// 1.03 -> 2.00 Changed 'MLan' to 'ow'. Added support for
+// multiple ports. Don't stop loop at end of each
+// search round.
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "ownet.h"
+
+// local funcitons
+static void PrintSerialNum(int);
+
+// tini hack
+int argc=2;
+char *argv[]={__FILE__, "exow"};
+
+//----------------------------------------------------------------------
+// Main for tstfind
+//
+int main() //short argc, char **argv)
+{
+ int rslt,cnt;
+ char return_msg[128];
+ int portnum=0;
+
+ // check for required port name
+ if (argc != 2)
+ {
+ printf("1-Wire Net name required on command line!\n"
+ " (example: \"COM1\" (Win32 DS2480),\"/dev/cua0\" "
+ "(Linux DS2480),\"1\" (Win32 TMEX)\n");
+ exit(1);
+ }
+
+ // attempt to acquire the 1-Wire Net
+ if (!owAcquire(portnum,argv[1],return_msg))
+ {
+ printf("%s",return_msg);
+ exit(1);
+ }
+
+ // success
+ printf("%s",return_msg);
+
+ //----------------------------------------
+ // Introduction
+ printf("\n/---------------------------------------------\n");
+ printf(" Loop to find all iButton on 1-Wire Net.\n\n");
+
+ do
+ {
+ printf("-------------------- Start of search\n");
+ cnt = 0;
+
+ // find the first device (all devices not just alarming)
+ rslt = owFirst(portnum, TRUE, FALSE);
+ while (rslt)
+ {
+ // print the device number
+ cnt++;
+ printf("(%d) ",cnt);
+
+ // print the Serial Number of the device just found
+ PrintSerialNum(portnum);
+
+ // find the next device
+ rslt = owNext(portnum, TRUE, FALSE);
+ }
+ printf("-------------------- End of search\n\n");
+
+ }
+ while (!key_abort());
+
+ // release the 1-Wire Net
+ owRelease(portnum,return_msg);
+ printf("%s",return_msg);
+ exit(0);
+
+ return 0;
+}
+
+//----------------------------------------------------------------------
+// Read and print the Serial Number.
+//
+void PrintSerialNum(int portnum)
+{
+ uchar serial_num[8];
+ int i;
+
+ owSerialNum(portnum,serial_num,TRUE);
+ for (i = 7; i >= 0; i--)
+ printf("%02X",serial_num[i]);
+ printf("\n");
+}