just an example of what SDCC can do for YOU
authorjohanknol <johanknol@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Tue, 6 Feb 2001 20:37:48 +0000 (20:37 +0000)
committerjohanknol <johanknol@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Tue, 6 Feb 2001 20:37:48 +0000 (20:37 +0000)
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@598 4a8a32a2-be11-0410-ad9d-d568d2c75423

29 files changed:
device/examples/ds390/ow390/Makefile [new file with mode: 0755]
device/examples/ds390/ow390/cnt1d.c [new file with mode: 0644]
device/examples/ds390/ow390/cnt1d.h [new file with mode: 0755]
device/examples/ds390/ow390/counter.c [new file with mode: 0755]
device/examples/ds390/ow390/crcutil.c [new file with mode: 0644]
device/examples/ds390/ow390/ds2480.h [new file with mode: 0755]
device/examples/ds390/ow390/ds2480ut.c [new file with mode: 0755]
device/examples/ds390/ow390/findtype.c [new file with mode: 0644]
device/examples/ds390/ow390/owfile.c [new file with mode: 0644]
device/examples/ds390/ow390/owlli.c [new file with mode: 0644]
device/examples/ds390/ow390/owllu.c [new file with mode: 0755]
device/examples/ds390/ow390/ownet.h [new file with mode: 0755]
device/examples/ds390/ow390/ownetu.c [new file with mode: 0755]
device/examples/ds390/ow390/owsesu.c [new file with mode: 0755]
device/examples/ds390/ow390/owtrnu.c [new file with mode: 0755]
device/examples/ds390/ow390/swt12.c [new file with mode: 0644]
device/examples/ds390/ow390/swt12.h [new file with mode: 0644]
device/examples/ds390/ow390/swtloop.c [new file with mode: 0755]
device/examples/ds390/ow390/swtoper.c [new file with mode: 0755]
device/examples/ds390/ow390/temp.c [new file with mode: 0755]
device/examples/ds390/ow390/temp10.c [new file with mode: 0644]
device/examples/ds390/ow390/temp10.h [new file with mode: 0644]
device/examples/ds390/ow390/thermo21.c [new file with mode: 0644]
device/examples/ds390/ow390/thermo21.h [new file with mode: 0644]
device/examples/ds390/ow390/thermodl.c [new file with mode: 0644]
device/examples/ds390/ow390/time.c [new file with mode: 0755]
device/examples/ds390/ow390/time.h [new file with mode: 0644]
device/examples/ds390/ow390/tinilnk.c [new file with mode: 0644]
device/examples/ds390/ow390/tstfind.c [new file with mode: 0755]

diff --git a/device/examples/ds390/ow390/Makefile b/device/examples/ds390/ow390/Makefile
new file mode 100755 (executable)
index 0000000..6519e97
--- /dev/null
@@ -0,0 +1,42 @@
+#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) $<
diff --git a/device/examples/ds390/ow390/cnt1d.c b/device/examples/ds390/ow390/cnt1d.c
new file mode 100644 (file)
index 0000000..cdf66fd
--- /dev/null
@@ -0,0 +1,104 @@
+//---------------------------------------------------------------------------
+// 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;
+} 
diff --git a/device/examples/ds390/ow390/cnt1d.h b/device/examples/ds390/ow390/cnt1d.h
new file mode 100755 (executable)
index 0000000..2750069
--- /dev/null
@@ -0,0 +1 @@
+extern int ReadCounter(int, uchar *SerialNum, int, unsigned long *);
diff --git a/device/examples/ds390/ow390/counter.c b/device/examples/ds390/ow390/counter.c
new file mode 100755 (executable)
index 0000000..89e6eeb
--- /dev/null
@@ -0,0 +1,155 @@
+//---------------------------------------------------------------------------
+// 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]);
+}
+
+
+
diff --git a/device/examples/ds390/ow390/crcutil.c b/device/examples/ds390/ow390/crcutil.c
new file mode 100644 (file)
index 0000000..09add30
--- /dev/null
@@ -0,0 +1,122 @@
+//---------------------------------------------------------------------------
+// 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];
+}
diff --git a/device/examples/ds390/ow390/ds2480.h b/device/examples/ds390/ow390/ds2480.h
new file mode 100755 (executable)
index 0000000..12ab46e
--- /dev/null
@@ -0,0 +1,187 @@
+//---------------------------------------------------------------------------
+// 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
+
diff --git a/device/examples/ds390/ow390/ds2480ut.c b/device/examples/ds390/ow390/ds2480ut.c
new file mode 100755 (executable)
index 0000000..0e01b3f
--- /dev/null
@@ -0,0 +1,200 @@
+//---------------------------------------------------------------------------
+// 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];
+}
diff --git a/device/examples/ds390/ow390/findtype.c b/device/examples/ds390/ow390/findtype.c
new file mode 100644 (file)
index 0000000..5fc2a91
--- /dev/null
@@ -0,0 +1,71 @@
+//---------------------------------------------------------------------------
+// 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;
+}
diff --git a/device/examples/ds390/ow390/owfile.c b/device/examples/ds390/ow390/owfile.c
new file mode 100644 (file)
index 0000000..6ad8f9f
--- /dev/null
@@ -0,0 +1,270 @@
+//---------------------------------------------------------------------------
+// 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;
+} 
+
diff --git a/device/examples/ds390/ow390/owlli.c b/device/examples/ds390/ow390/owlli.c
new file mode 100644 (file)
index 0000000..314a0c5
--- /dev/null
@@ -0,0 +1,430 @@
+//---------------------------------------------------------------------------
+// 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;
+}
diff --git a/device/examples/ds390/ow390/owllu.c b/device/examples/ds390/ow390/owllu.c
new file mode 100755 (executable)
index 0000000..4030cf1
--- /dev/null
@@ -0,0 +1,486 @@
+//---------------------------------------------------------------------------
+// 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;
+}
diff --git a/device/examples/ds390/ow390/ownet.h b/device/examples/ds390/ow390/ownet.h
new file mode 100755 (executable)
index 0000000..96b4ef0
--- /dev/null
@@ -0,0 +1,151 @@
+//---------------------------------------------------------------------------
+// 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
diff --git a/device/examples/ds390/ow390/ownetu.c b/device/examples/ds390/ow390/ownetu.c
new file mode 100755 (executable)
index 0000000..ea34326
--- /dev/null
@@ -0,0 +1,549 @@
+//---------------------------------------------------------------------------
+// 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);
+}
diff --git a/device/examples/ds390/ow390/owsesu.c b/device/examples/ds390/ow390/owsesu.c
new file mode 100755 (executable)
index 0000000..b26eec4
--- /dev/null
@@ -0,0 +1,97 @@
+//---------------------------------------------------------------------------
+// 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);
+}
diff --git a/device/examples/ds390/ow390/owtrnu.c b/device/examples/ds390/ow390/owtrnu.c
new file mode 100755 (executable)
index 0000000..bf67642
--- /dev/null
@@ -0,0 +1,530 @@
+//---------------------------------------------------------------------------
+// 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;
+}
+                       
diff --git a/device/examples/ds390/ow390/swt12.c b/device/examples/ds390/ow390/swt12.c
new file mode 100644 (file)
index 0000000..5060458
--- /dev/null
@@ -0,0 +1,258 @@
+//---------------------------------------------------------------------------
+// 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;
+}
+
+   
diff --git a/device/examples/ds390/ow390/swt12.h b/device/examples/ds390/ow390/swt12.h
new file mode 100644 (file)
index 0000000..f13ba11
--- /dev/null
@@ -0,0 +1,13 @@
+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 *);
diff --git a/device/examples/ds390/ow390/swtloop.c b/device/examples/ds390/ow390/swtloop.c
new file mode 100755 (executable)
index 0000000..09c6006
--- /dev/null
@@ -0,0 +1,218 @@
+//---------------------------------------------------------------------------
+// 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;
+}
+
diff --git a/device/examples/ds390/ow390/swtoper.c b/device/examples/ds390/ow390/swtoper.c
new file mode 100755 (executable)
index 0000000..2954eb8
--- /dev/null
@@ -0,0 +1,219 @@
+//---------------------------------------------------------------------------
+// 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;
+}
+
diff --git a/device/examples/ds390/ow390/temp.c b/device/examples/ds390/ow390/temp.c
new file mode 100755 (executable)
index 0000000..a9c62a2
--- /dev/null
@@ -0,0 +1,154 @@
+//---------------------------------------------------------------------------
+// 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],&current_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]);
+}
diff --git a/device/examples/ds390/ow390/temp10.c b/device/examples/ds390/ow390/temp10.c
new file mode 100644 (file)
index 0000000..31c46d3
--- /dev/null
@@ -0,0 +1,129 @@
+//---------------------------------------------------------------------------
+// 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;
+      
+}
diff --git a/device/examples/ds390/ow390/temp10.h b/device/examples/ds390/ow390/temp10.h
new file mode 100644 (file)
index 0000000..e452108
--- /dev/null
@@ -0,0 +1 @@
+extern int ReadTemperature(int, uchar *, float *);
diff --git a/device/examples/ds390/ow390/thermo21.c b/device/examples/ds390/ow390/thermo21.c
new file mode 100644 (file)
index 0000000..82d3301
--- /dev/null
@@ -0,0 +1,1336 @@
+//---------------------------------------------------------------------------
+// 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);
+}
diff --git a/device/examples/ds390/ow390/thermo21.h b/device/examples/ds390/ow390/thermo21.h
new file mode 100644 (file)
index 0000000..9a8d1f9
--- /dev/null
@@ -0,0 +1,179 @@
+//---------------------------------------------------------------------------
+// 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
diff --git a/device/examples/ds390/ow390/thermodl.c b/device/examples/ds390/ow390/thermodl.c
new file mode 100644 (file)
index 0000000..13a4b7e
--- /dev/null
@@ -0,0 +1,173 @@
+//---------------------------------------------------------------------------
+// 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);
+}
+
diff --git a/device/examples/ds390/ow390/time.c b/device/examples/ds390/ow390/time.c
new file mode 100755 (executable)
index 0000000..3b61353
--- /dev/null
@@ -0,0 +1,24 @@
+#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;
+}
diff --git a/device/examples/ds390/ow390/time.h b/device/examples/ds390/ow390/time.h
new file mode 100644 (file)
index 0000000..54dd150
--- /dev/null
@@ -0,0 +1,17 @@
+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);
diff --git a/device/examples/ds390/ow390/tinilnk.c b/device/examples/ds390/ow390/tinilnk.c
new file mode 100644 (file)
index 0000000..95e95e9
--- /dev/null
@@ -0,0 +1,278 @@
+//---------------------------------------------------------------------------
+// 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);
+}
+
diff --git a/device/examples/ds390/ow390/tstfind.c b/device/examples/ds390/ow390/tstfind.c
new file mode 100755 (executable)
index 0000000..c7bc879
--- /dev/null
@@ -0,0 +1,130 @@
+//---------------------------------------------------------------------------
+// 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");
+}