1-Wire implementation, using DS2480B controller interfaced with serial port, working example to read DS18B20, based on work already in progress / Dallas - Public domain code

Dependencies:   mbed

Committer:
pwheels
Date:
Thu Mar 24 17:21:29 2011 +0000
Revision:
0:1193dbfe28e2

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pwheels 0:1193dbfe28e2 1 //---------------------------------------------------------------------------
pwheels 0:1193dbfe28e2 2 // Copyright (C) 2000 Dallas Semiconductor Corporation, All Rights Reserved.
pwheels 0:1193dbfe28e2 3 //
pwheels 0:1193dbfe28e2 4 // Permission is hereby granted, free of charge, to any person obtaining a
pwheels 0:1193dbfe28e2 5 // copy of this software and associated documentation files (the "Software"),
pwheels 0:1193dbfe28e2 6 // to deal in the Software without restriction, including without limitation
pwheels 0:1193dbfe28e2 7 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
pwheels 0:1193dbfe28e2 8 // and/or sell copies of the Software, and to permit persons to whom the
pwheels 0:1193dbfe28e2 9 // Software is furnished to do so, subject to the following conditions:
pwheels 0:1193dbfe28e2 10 //
pwheels 0:1193dbfe28e2 11 // The above copyright notice and this permission notice shall be included
pwheels 0:1193dbfe28e2 12 // in all copies or substantial portions of the Software.
pwheels 0:1193dbfe28e2 13 //
pwheels 0:1193dbfe28e2 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
pwheels 0:1193dbfe28e2 15 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
pwheels 0:1193dbfe28e2 16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
pwheels 0:1193dbfe28e2 17 // IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES
pwheels 0:1193dbfe28e2 18 // OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
pwheels 0:1193dbfe28e2 19 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
pwheels 0:1193dbfe28e2 20 // OTHER DEALINGS IN THE SOFTWARE.
pwheels 0:1193dbfe28e2 21 //
pwheels 0:1193dbfe28e2 22 // Except as contained in this notice, the name of Dallas Semiconductor
pwheels 0:1193dbfe28e2 23 // shall not be used except as stated in the Dallas Semiconductor
pwheels 0:1193dbfe28e2 24 // Branding Policy.
pwheels 0:1193dbfe28e2 25 //---------------------------------------------------------------------------
pwheels 0:1193dbfe28e2 26 //
pwheels 0:1193dbfe28e2 27 // ownet.C - Network functions for 1-Wire net devices.
pwheels 0:1193dbfe28e2 28 //
pwheels 0:1193dbfe28e2 29 // Version: 3.00
pwheels 0:1193dbfe28e2 30 //
pwheels 0:1193dbfe28e2 31 // History: 1.00 -> 1.01 Change to owFamilySearchSetup, LastDiscrepancy[portnum]
pwheels 0:1193dbfe28e2 32 // was set to 64 instead of 8 to enable devices with
pwheels 0:1193dbfe28e2 33 // early contention to go in the '0' direction first.
pwheels 0:1193dbfe28e2 34 // 1.02 -> 1.03 Initialized goodbits in owVerify
pwheels 0:1193dbfe28e2 35 // 1.03 -> 2.00 Changed 'MLan' to 'ow'. Added support for
pwheels 0:1193dbfe28e2 36 // multiple ports.
pwheels 0:1193dbfe28e2 37 // 2.00 -> 2.01 Added support for owError library
pwheels 0:1193dbfe28e2 38 // 2.01 -> 3.00 Make search functions consistent with AN187
pwheels 0:1193dbfe28e2 39 //
pwheels 0:1193dbfe28e2 40
pwheels 0:1193dbfe28e2 41 #include <stdio.h>
pwheels 0:1193dbfe28e2 42 #include "ownet.h"
pwheels 0:1193dbfe28e2 43
pwheels 0:1193dbfe28e2 44 // exportable functions defined in ownet.c
pwheels 0:1193dbfe28e2 45 SMALLINT bitacc(SMALLINT,SMALLINT,SMALLINT,uchar *);
pwheels 0:1193dbfe28e2 46
pwheels 0:1193dbfe28e2 47 // global variables for this module to hold search state information
pwheels 0:1193dbfe28e2 48 static SMALLINT LastDiscrepancy[MAX_PORTNUM];
pwheels 0:1193dbfe28e2 49 static SMALLINT LastFamilyDiscrepancy[MAX_PORTNUM];
pwheels 0:1193dbfe28e2 50 static SMALLINT LastDevice[MAX_PORTNUM];
pwheels 0:1193dbfe28e2 51 uchar SerialNum[MAX_PORTNUM][8];
pwheels 0:1193dbfe28e2 52
pwheels 0:1193dbfe28e2 53 //--------------------------------------------------------------------------
pwheels 0:1193dbfe28e2 54 // The 'owFirst' finds the first device on the 1-Wire Net This function
pwheels 0:1193dbfe28e2 55 // contains one parameter 'alarm_only'. When
pwheels 0:1193dbfe28e2 56 // 'alarm_only' is TRUE (1) the find alarm command 0xEC is
pwheels 0:1193dbfe28e2 57 // sent instead of the normal search command 0xF0.
pwheels 0:1193dbfe28e2 58 // Using the find alarm command 0xEC will limit the search to only
pwheels 0:1193dbfe28e2 59 // 1-Wire devices that are in an 'alarm' state.
pwheels 0:1193dbfe28e2 60 //
pwheels 0:1193dbfe28e2 61 // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
pwheels 0:1193dbfe28e2 62 // indicate the symbolic port number.
pwheels 0:1193dbfe28e2 63 // 'do_reset' - TRUE (1) perform reset before search, FALSE (0) do not
pwheels 0:1193dbfe28e2 64 // perform reset before search.
pwheels 0:1193dbfe28e2 65 // 'alarm_only' - TRUE (1) the find alarm command 0xEC is
pwheels 0:1193dbfe28e2 66 // sent instead of the normal search command 0xF0
pwheels 0:1193dbfe28e2 67 //
pwheels 0:1193dbfe28e2 68 // Returns: TRUE (1) : when a 1-Wire device was found and it's
pwheels 0:1193dbfe28e2 69 // Serial Number placed in the global SerialNum[portnum]
pwheels 0:1193dbfe28e2 70 // FALSE (0): There are no devices on the 1-Wire Net.
pwheels 0:1193dbfe28e2 71 //
pwheels 0:1193dbfe28e2 72 SMALLINT owFirst(int portnum, SMALLINT do_reset, SMALLINT alarm_only)
pwheels 0:1193dbfe28e2 73 {
pwheels 0:1193dbfe28e2 74 // reset the search state
pwheels 0:1193dbfe28e2 75 LastDiscrepancy[portnum] = 0;
pwheels 0:1193dbfe28e2 76 LastDevice[portnum] = FALSE;
pwheels 0:1193dbfe28e2 77 LastFamilyDiscrepancy[portnum] = 0;
pwheels 0:1193dbfe28e2 78
pwheels 0:1193dbfe28e2 79 return owNext(portnum,do_reset,alarm_only);
pwheels 0:1193dbfe28e2 80 }
pwheels 0:1193dbfe28e2 81
pwheels 0:1193dbfe28e2 82 //--------------------------------------------------------------------------
pwheels 0:1193dbfe28e2 83 // The 'owNext' function does a general search. This function
pwheels 0:1193dbfe28e2 84 // continues from the previos search state. The search state
pwheels 0:1193dbfe28e2 85 // can be reset by using the 'owFirst' function.
pwheels 0:1193dbfe28e2 86 // This function contains one parameter 'alarm_only'.
pwheels 0:1193dbfe28e2 87 // When 'alarm_only' is TRUE (1) the find alarm command
pwheels 0:1193dbfe28e2 88 // 0xEC is sent instead of the normal search command 0xF0.
pwheels 0:1193dbfe28e2 89 // Using the find alarm command 0xEC will limit the search to only
pwheels 0:1193dbfe28e2 90 // 1-Wire devices that are in an 'alarm' state.
pwheels 0:1193dbfe28e2 91 //
pwheels 0:1193dbfe28e2 92 // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
pwheels 0:1193dbfe28e2 93 // indicate the symbolic port number.
pwheels 0:1193dbfe28e2 94 // 'do_reset' - TRUE (1) perform reset before search, FALSE (0) do not
pwheels 0:1193dbfe28e2 95 // perform reset before search.
pwheels 0:1193dbfe28e2 96 // 'alarm_only' - TRUE (1) the find alarm command 0xEC is
pwheels 0:1193dbfe28e2 97 // sent instead of the normal search command 0xF0
pwheels 0:1193dbfe28e2 98 //
pwheels 0:1193dbfe28e2 99 // Returns: TRUE (1) : when a 1-Wire device was found and it's
pwheels 0:1193dbfe28e2 100 // Serial Number placed in the global SerialNum[portnum]
pwheels 0:1193dbfe28e2 101 // FALSE (0): when no new device was found. Either the
pwheels 0:1193dbfe28e2 102 // last search was the last device or there
pwheels 0:1193dbfe28e2 103 // are no devices on the 1-Wire Net.
pwheels 0:1193dbfe28e2 104 //
pwheels 0:1193dbfe28e2 105 SMALLINT owNext(int portnum, SMALLINT do_reset, SMALLINT alarm_only)
pwheels 0:1193dbfe28e2 106 {
pwheels 0:1193dbfe28e2 107 uchar bit_test, search_direction, bit_number;
pwheels 0:1193dbfe28e2 108 uchar last_zero, serial_byte_number, next_result;
pwheels 0:1193dbfe28e2 109 uchar serial_byte_mask;
pwheels 0:1193dbfe28e2 110 uchar lastcrc8=0;
pwheels 0:1193dbfe28e2 111
pwheels 0:1193dbfe28e2 112 // initialize for search
pwheels 0:1193dbfe28e2 113 bit_number = 1;
pwheels 0:1193dbfe28e2 114 last_zero = 0;
pwheels 0:1193dbfe28e2 115 serial_byte_number = 0;
pwheels 0:1193dbfe28e2 116 serial_byte_mask = 1;
pwheels 0:1193dbfe28e2 117 next_result = 0;
pwheels 0:1193dbfe28e2 118 setcrc8(portnum,0);
pwheels 0:1193dbfe28e2 119
pwheels 0:1193dbfe28e2 120 // if the last call was not the last one
pwheels 0:1193dbfe28e2 121 if (!LastDevice[portnum])
pwheels 0:1193dbfe28e2 122 {
pwheels 0:1193dbfe28e2 123 // check if reset first is requested
pwheels 0:1193dbfe28e2 124 if (do_reset)
pwheels 0:1193dbfe28e2 125 {
pwheels 0:1193dbfe28e2 126 // reset the 1-wire
pwheels 0:1193dbfe28e2 127 // if there are no parts on 1-wire, return FALSE
pwheels 0:1193dbfe28e2 128 if (!owTouchReset(portnum))
pwheels 0:1193dbfe28e2 129 {
pwheels 0:1193dbfe28e2 130 // printf("owTouchReset failed\r\n");
pwheels 0:1193dbfe28e2 131 // reset the search
pwheels 0:1193dbfe28e2 132 LastDiscrepancy[portnum] = 0;
pwheels 0:1193dbfe28e2 133 LastFamilyDiscrepancy[portnum] = 0;
pwheels 0:1193dbfe28e2 134 OWERROR(OWERROR_NO_DEVICES_ON_NET);
pwheels 0:1193dbfe28e2 135 return FALSE;
pwheels 0:1193dbfe28e2 136 }
pwheels 0:1193dbfe28e2 137 }
pwheels 0:1193dbfe28e2 138
pwheels 0:1193dbfe28e2 139 // If finding alarming devices issue a different command
pwheels 0:1193dbfe28e2 140 if (alarm_only)
pwheels 0:1193dbfe28e2 141 owWriteByte(portnum,0xEC); // issue the alarming search command
pwheels 0:1193dbfe28e2 142 else
pwheels 0:1193dbfe28e2 143 owWriteByte(portnum,0xF0); // issue the search command
pwheels 0:1193dbfe28e2 144
pwheels 0:1193dbfe28e2 145 //pause before beginning the search
pwheels 0:1193dbfe28e2 146 //usDelay(100);
pwheels 0:1193dbfe28e2 147
pwheels 0:1193dbfe28e2 148 // loop to do the search
pwheels 0:1193dbfe28e2 149 do
pwheels 0:1193dbfe28e2 150 {
pwheels 0:1193dbfe28e2 151 // read a bit and its compliment
pwheels 0:1193dbfe28e2 152 bit_test = owTouchBit(portnum,1) << 1;
pwheels 0:1193dbfe28e2 153 bit_test |= owTouchBit(portnum,1);
pwheels 0:1193dbfe28e2 154
pwheels 0:1193dbfe28e2 155 // check for no devices on 1-wire
pwheels 0:1193dbfe28e2 156 if (bit_test == 3)
pwheels 0:1193dbfe28e2 157 break;
pwheels 0:1193dbfe28e2 158 else
pwheels 0:1193dbfe28e2 159 {
pwheels 0:1193dbfe28e2 160 // all devices coupled have 0 or 1
pwheels 0:1193dbfe28e2 161 if (bit_test > 0)
pwheels 0:1193dbfe28e2 162 search_direction = !(bit_test & 0x01); // bit write value for search
pwheels 0:1193dbfe28e2 163 else
pwheels 0:1193dbfe28e2 164 {
pwheels 0:1193dbfe28e2 165 // if this discrepancy if before the Last Discrepancy
pwheels 0:1193dbfe28e2 166 // on a previous next then pick the same as last time
pwheels 0:1193dbfe28e2 167 if (bit_number < LastDiscrepancy[portnum])
pwheels 0:1193dbfe28e2 168 search_direction = ((SerialNum[portnum][serial_byte_number] & serial_byte_mask) > 0);
pwheels 0:1193dbfe28e2 169 else
pwheels 0:1193dbfe28e2 170 // if equal to last pick 1, if not then pick 0
pwheels 0:1193dbfe28e2 171 search_direction = (bit_number == LastDiscrepancy[portnum]);
pwheels 0:1193dbfe28e2 172
pwheels 0:1193dbfe28e2 173 // if 0 was picked then record its position in LastZero
pwheels 0:1193dbfe28e2 174 if (search_direction == 0)
pwheels 0:1193dbfe28e2 175 {
pwheels 0:1193dbfe28e2 176 last_zero = bit_number;
pwheels 0:1193dbfe28e2 177
pwheels 0:1193dbfe28e2 178 // check for Last discrepancy in family
pwheels 0:1193dbfe28e2 179 if (last_zero < 9)
pwheels 0:1193dbfe28e2 180 LastFamilyDiscrepancy[portnum] = last_zero;
pwheels 0:1193dbfe28e2 181 }
pwheels 0:1193dbfe28e2 182 }
pwheels 0:1193dbfe28e2 183
pwheels 0:1193dbfe28e2 184 // set or clear the bit in the SerialNum[portnum] byte serial_byte_number
pwheels 0:1193dbfe28e2 185 // with mask serial_byte_mask
pwheels 0:1193dbfe28e2 186 if (search_direction == 1)
pwheels 0:1193dbfe28e2 187 SerialNum[portnum][serial_byte_number] |= serial_byte_mask;
pwheels 0:1193dbfe28e2 188 else
pwheels 0:1193dbfe28e2 189 SerialNum[portnum][serial_byte_number] &= ~serial_byte_mask;
pwheels 0:1193dbfe28e2 190
pwheels 0:1193dbfe28e2 191 // serial number search direction write bit
pwheels 0:1193dbfe28e2 192 owTouchBit(portnum,search_direction);
pwheels 0:1193dbfe28e2 193
pwheels 0:1193dbfe28e2 194 // increment the byte counter bit_number
pwheels 0:1193dbfe28e2 195 // and shift the mask serial_byte_mask
pwheels 0:1193dbfe28e2 196 bit_number++;
pwheels 0:1193dbfe28e2 197 serial_byte_mask <<= 1;
pwheels 0:1193dbfe28e2 198
pwheels 0:1193dbfe28e2 199 // if the mask is 0 then go to new SerialNum[portnum] byte serial_byte_number
pwheels 0:1193dbfe28e2 200 // and reset mask
pwheels 0:1193dbfe28e2 201 if (serial_byte_mask == 0)
pwheels 0:1193dbfe28e2 202 {
pwheels 0:1193dbfe28e2 203 // The below has been added to accomidate the valid CRC with the
pwheels 0:1193dbfe28e2 204 // possible changing serial number values of the DS28E04.
pwheels 0:1193dbfe28e2 205 if (((SerialNum[portnum][0] & 0x7F) == 0x1C) && (serial_byte_number == 1))
pwheels 0:1193dbfe28e2 206 lastcrc8 = docrc8(portnum,0x7F);
pwheels 0:1193dbfe28e2 207 else
pwheels 0:1193dbfe28e2 208 lastcrc8 = docrc8(portnum,SerialNum[portnum][serial_byte_number]); // accumulate the CRC
pwheels 0:1193dbfe28e2 209
pwheels 0:1193dbfe28e2 210 serial_byte_number++;
pwheels 0:1193dbfe28e2 211 serial_byte_mask = 1;
pwheels 0:1193dbfe28e2 212 }
pwheels 0:1193dbfe28e2 213 }
pwheels 0:1193dbfe28e2 214 }
pwheels 0:1193dbfe28e2 215 while(serial_byte_number < 8); // loop until through all SerialNum[portnum] bytes 0-7
pwheels 0:1193dbfe28e2 216
pwheels 0:1193dbfe28e2 217 // if the search was successful then
pwheels 0:1193dbfe28e2 218 if (!((bit_number < 65) || lastcrc8))
pwheels 0:1193dbfe28e2 219 {
pwheels 0:1193dbfe28e2 220 // search successful so set LastDiscrepancy[portnum],LastDevice[portnum],next_result
pwheels 0:1193dbfe28e2 221 LastDiscrepancy[portnum] = last_zero;
pwheels 0:1193dbfe28e2 222 LastDevice[portnum] = (LastDiscrepancy[portnum] == 0);
pwheels 0:1193dbfe28e2 223 next_result = TRUE;
pwheels 0:1193dbfe28e2 224 }
pwheels 0:1193dbfe28e2 225 }
pwheels 0:1193dbfe28e2 226
pwheels 0:1193dbfe28e2 227 // if no device found then reset counters so next 'next' will be
pwheels 0:1193dbfe28e2 228 // like a first
pwheels 0:1193dbfe28e2 229 if (!next_result || !SerialNum[portnum][0])
pwheels 0:1193dbfe28e2 230 {
pwheels 0:1193dbfe28e2 231 LastDiscrepancy[portnum] = 0;
pwheels 0:1193dbfe28e2 232 LastDevice[portnum] = FALSE;
pwheels 0:1193dbfe28e2 233 LastFamilyDiscrepancy[portnum] = 0;
pwheels 0:1193dbfe28e2 234 next_result = FALSE;
pwheels 0:1193dbfe28e2 235 }
pwheels 0:1193dbfe28e2 236
pwheels 0:1193dbfe28e2 237 return next_result;
pwheels 0:1193dbfe28e2 238 }
pwheels 0:1193dbfe28e2 239
pwheels 0:1193dbfe28e2 240 //--------------------------------------------------------------------------
pwheels 0:1193dbfe28e2 241 // The 'owSerialNum' function either reads or sets the SerialNum buffer
pwheels 0:1193dbfe28e2 242 // that is used in the search functions 'owFirst' and 'owNext'.
pwheels 0:1193dbfe28e2 243 // This function contains two parameters, 'serialnum_buf' is a pointer
pwheels 0:1193dbfe28e2 244 // to a buffer provided by the caller. 'serialnum_buf' should point to
pwheels 0:1193dbfe28e2 245 // an array of 8 unsigned chars. The second parameter is a flag called
pwheels 0:1193dbfe28e2 246 // 'do_read' that is TRUE (1) if the operation is to read and FALSE
pwheels 0:1193dbfe28e2 247 // (0) if the operation is to set the internal SerialNum buffer from
pwheels 0:1193dbfe28e2 248 // the data in the provided buffer.
pwheels 0:1193dbfe28e2 249 //
pwheels 0:1193dbfe28e2 250 // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
pwheels 0:1193dbfe28e2 251 // indicate the symbolic port number.
pwheels 0:1193dbfe28e2 252 // 'serialnum_buf' - buffer to that contains the serial number to set
pwheels 0:1193dbfe28e2 253 // when do_read = FALSE (0) and buffer to get the serial
pwheels 0:1193dbfe28e2 254 // number when do_read = TRUE (1).
pwheels 0:1193dbfe28e2 255 // 'do_read' - flag to indicate reading (1) or setting (0) the current
pwheels 0:1193dbfe28e2 256 // serial number.
pwheels 0:1193dbfe28e2 257 //
pwheels 0:1193dbfe28e2 258 void owSerialNum(int portnum, uchar *serialnum_buf, SMALLINT do_read)
pwheels 0:1193dbfe28e2 259 {
pwheels 0:1193dbfe28e2 260 uchar i;
pwheels 0:1193dbfe28e2 261
pwheels 0:1193dbfe28e2 262 // read the internal buffer and place in 'serialnum_buf'
pwheels 0:1193dbfe28e2 263 if (do_read)
pwheels 0:1193dbfe28e2 264 {
pwheels 0:1193dbfe28e2 265 for (i = 0; i < 8; i++)
pwheels 0:1193dbfe28e2 266 serialnum_buf[i] = SerialNum[portnum][i];
pwheels 0:1193dbfe28e2 267 }
pwheels 0:1193dbfe28e2 268 // set the internal buffer from the data in 'serialnum_buf'
pwheels 0:1193dbfe28e2 269 else
pwheels 0:1193dbfe28e2 270 {
pwheels 0:1193dbfe28e2 271 for (i = 0; i < 8; i++)
pwheels 0:1193dbfe28e2 272 SerialNum[portnum][i] = serialnum_buf[i];
pwheels 0:1193dbfe28e2 273 }
pwheels 0:1193dbfe28e2 274 }
pwheels 0:1193dbfe28e2 275
pwheels 0:1193dbfe28e2 276 //--------------------------------------------------------------------------
pwheels 0:1193dbfe28e2 277 // Setup the search algorithm to find a certain family of devices
pwheels 0:1193dbfe28e2 278 // the next time a search function is called 'owNext'.
pwheels 0:1193dbfe28e2 279 //
pwheels 0:1193dbfe28e2 280 // 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
pwheels 0:1193dbfe28e2 281 // OpenCOM to indicate the port number.
pwheels 0:1193dbfe28e2 282 // 'search_family' - family code type to set the search algorithm to find
pwheels 0:1193dbfe28e2 283 // next.
pwheels 0:1193dbfe28e2 284 //
pwheels 0:1193dbfe28e2 285 void owFamilySearchSetup(int portnum, SMALLINT search_family)
pwheels 0:1193dbfe28e2 286 {
pwheels 0:1193dbfe28e2 287 uchar i;
pwheels 0:1193dbfe28e2 288
pwheels 0:1193dbfe28e2 289 // set the search state to find SearchFamily type devices
pwheels 0:1193dbfe28e2 290 SerialNum[portnum][0] = search_family;
pwheels 0:1193dbfe28e2 291 for (i = 1; i < 8; i++)
pwheels 0:1193dbfe28e2 292 SerialNum[portnum][i] = 0;
pwheels 0:1193dbfe28e2 293 LastDiscrepancy[portnum] = 64;
pwheels 0:1193dbfe28e2 294 LastDevice[portnum] = FALSE;
pwheels 0:1193dbfe28e2 295 }
pwheels 0:1193dbfe28e2 296
pwheels 0:1193dbfe28e2 297 //--------------------------------------------------------------------------
pwheels 0:1193dbfe28e2 298 // Set the current search state to skip the current family code.
pwheels 0:1193dbfe28e2 299 //
pwheels 0:1193dbfe28e2 300 // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
pwheels 0:1193dbfe28e2 301 // indicate the symbolic port number.
pwheels 0:1193dbfe28e2 302 //
pwheels 0:1193dbfe28e2 303 void owSkipFamily(int portnum)
pwheels 0:1193dbfe28e2 304 {
pwheels 0:1193dbfe28e2 305 // set the Last discrepancy to last family discrepancy
pwheels 0:1193dbfe28e2 306 LastDiscrepancy[portnum] = LastFamilyDiscrepancy[portnum];
pwheels 0:1193dbfe28e2 307 LastFamilyDiscrepancy[portnum] = 0;
pwheels 0:1193dbfe28e2 308
pwheels 0:1193dbfe28e2 309 // check for end of list
pwheels 0:1193dbfe28e2 310 if (LastDiscrepancy[portnum] == 0)
pwheels 0:1193dbfe28e2 311 LastDevice[portnum] = TRUE;
pwheels 0:1193dbfe28e2 312 }
pwheels 0:1193dbfe28e2 313
pwheels 0:1193dbfe28e2 314 //--------------------------------------------------------------------------
pwheels 0:1193dbfe28e2 315 // The 'owAccess' function resets the 1-Wire and sends a MATCH Serial
pwheels 0:1193dbfe28e2 316 // Number command followed by the current SerialNum code. After this
pwheels 0:1193dbfe28e2 317 // function is complete the 1-Wire device is ready to accept device-specific
pwheels 0:1193dbfe28e2 318 // commands.
pwheels 0:1193dbfe28e2 319 //
pwheels 0:1193dbfe28e2 320 // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
pwheels 0:1193dbfe28e2 321 // indicate the symbolic port number.
pwheels 0:1193dbfe28e2 322 //
pwheels 0:1193dbfe28e2 323 // Returns: TRUE (1) : reset indicates present and device is ready
pwheels 0:1193dbfe28e2 324 // for commands.
pwheels 0:1193dbfe28e2 325 // FALSE (0): reset does not indicate presence or echos 'writes'
pwheels 0:1193dbfe28e2 326 // are not correct.
pwheels 0:1193dbfe28e2 327 //
pwheels 0:1193dbfe28e2 328 SMALLINT owAccess(int portnum)
pwheels 0:1193dbfe28e2 329 {
pwheels 0:1193dbfe28e2 330 uchar sendpacket[9];
pwheels 0:1193dbfe28e2 331 uchar i;
pwheels 0:1193dbfe28e2 332
pwheels 0:1193dbfe28e2 333 // reset the 1-wire
pwheels 0:1193dbfe28e2 334 if (owTouchReset(portnum))
pwheels 0:1193dbfe28e2 335 {
pwheels 0:1193dbfe28e2 336 // create a buffer to use with block function
pwheels 0:1193dbfe28e2 337 // match Serial Number command 0x55
pwheels 0:1193dbfe28e2 338 sendpacket[0] = 0x55;
pwheels 0:1193dbfe28e2 339 // Serial Number
pwheels 0:1193dbfe28e2 340 for (i = 1; i < 9; i++)
pwheels 0:1193dbfe28e2 341 sendpacket[i] = SerialNum[portnum][i-1];
pwheels 0:1193dbfe28e2 342
pwheels 0:1193dbfe28e2 343 // send/recieve the transfer buffer
pwheels 0:1193dbfe28e2 344 if (owBlock(portnum,FALSE,sendpacket,9))
pwheels 0:1193dbfe28e2 345 {
pwheels 0:1193dbfe28e2 346 // verify that the echo of the writes was correct
pwheels 0:1193dbfe28e2 347 for (i = 1; i < 9; i++)
pwheels 0:1193dbfe28e2 348 if (sendpacket[i] != SerialNum[portnum][i-1])
pwheels 0:1193dbfe28e2 349 return FALSE;
pwheels 0:1193dbfe28e2 350 if (sendpacket[0] != 0x55)
pwheels 0:1193dbfe28e2 351 {
pwheels 0:1193dbfe28e2 352 OWERROR(OWERROR_WRITE_VERIFY_FAILED);
pwheels 0:1193dbfe28e2 353 return FALSE;
pwheels 0:1193dbfe28e2 354 }
pwheels 0:1193dbfe28e2 355 else
pwheels 0:1193dbfe28e2 356 return TRUE;
pwheels 0:1193dbfe28e2 357 }
pwheels 0:1193dbfe28e2 358 else
pwheels 0:1193dbfe28e2 359 OWERROR(OWERROR_BLOCK_FAILED);
pwheels 0:1193dbfe28e2 360 }
pwheels 0:1193dbfe28e2 361 else
pwheels 0:1193dbfe28e2 362 OWERROR(OWERROR_NO_DEVICES_ON_NET);
pwheels 0:1193dbfe28e2 363
pwheels 0:1193dbfe28e2 364 // reset or match echo failed
pwheels 0:1193dbfe28e2 365 return FALSE;
pwheels 0:1193dbfe28e2 366 }
pwheels 0:1193dbfe28e2 367
pwheels 0:1193dbfe28e2 368 //----------------------------------------------------------------------
pwheels 0:1193dbfe28e2 369 // The function 'owVerify' verifies that the current device
pwheels 0:1193dbfe28e2 370 // is in contact with the 1-Wire Net.
pwheels 0:1193dbfe28e2 371 // Using the find alarm command 0xEC will verify that the device
pwheels 0:1193dbfe28e2 372 // is in contact with the 1-Wire Net and is in an 'alarm' state.
pwheels 0:1193dbfe28e2 373 //
pwheels 0:1193dbfe28e2 374 // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
pwheels 0:1193dbfe28e2 375 // indicate the symbolic port number.
pwheels 0:1193dbfe28e2 376 // 'alarm_only' - TRUE (1) the find alarm command 0xEC
pwheels 0:1193dbfe28e2 377 // is sent instead of the normal search
pwheels 0:1193dbfe28e2 378 // command 0xF0.
pwheels 0:1193dbfe28e2 379 //
pwheels 0:1193dbfe28e2 380 // Returns: TRUE (1) : when the 1-Wire device was verified
pwheels 0:1193dbfe28e2 381 // to be on the 1-Wire Net
pwheels 0:1193dbfe28e2 382 // with alarm_only == FALSE
pwheels 0:1193dbfe28e2 383 // or verified to be on the 1-Wire Net
pwheels 0:1193dbfe28e2 384 // AND in an alarm state when
pwheels 0:1193dbfe28e2 385 // alarm_only == TRUE.
pwheels 0:1193dbfe28e2 386 // FALSE (0): the 1-Wire device was not on the
pwheels 0:1193dbfe28e2 387 // 1-Wire Net or if alarm_only
pwheels 0:1193dbfe28e2 388 // == TRUE, the device may be on the
pwheels 0:1193dbfe28e2 389 // 1-Wire Net but in a non-alarm state.
pwheels 0:1193dbfe28e2 390 //
pwheels 0:1193dbfe28e2 391 SMALLINT owVerify(int portnum, SMALLINT alarm_only)
pwheels 0:1193dbfe28e2 392 {
pwheels 0:1193dbfe28e2 393 uchar i,sendlen=0,goodbits=0,cnt=0,s,tst;
pwheels 0:1193dbfe28e2 394 uchar sendpacket[50];
pwheels 0:1193dbfe28e2 395
pwheels 0:1193dbfe28e2 396 // construct the search
pwheels 0:1193dbfe28e2 397 if (alarm_only)
pwheels 0:1193dbfe28e2 398 sendpacket[sendlen++] = 0xEC; // issue the alarming search command
pwheels 0:1193dbfe28e2 399 else
pwheels 0:1193dbfe28e2 400 sendpacket[sendlen++] = 0xF0; // issue the search command
pwheels 0:1193dbfe28e2 401 // set all bits at first
pwheels 0:1193dbfe28e2 402 for (i = 1; i <= 24; i++)
pwheels 0:1193dbfe28e2 403 sendpacket[sendlen++] = 0xFF;
pwheels 0:1193dbfe28e2 404 // now set or clear apropriate bits for search
pwheels 0:1193dbfe28e2 405 for (i = 0; i < 64; i++)
pwheels 0:1193dbfe28e2 406 bitacc(WRITE_FUNCTION,bitacc(READ_FUNCTION,0,i,&SerialNum[portnum][0]),(int)((i+1)*3-1),&sendpacket[1]);
pwheels 0:1193dbfe28e2 407
pwheels 0:1193dbfe28e2 408 // send/recieve the transfer buffer
pwheels 0:1193dbfe28e2 409 if (owBlock(portnum,TRUE,sendpacket,sendlen))
pwheels 0:1193dbfe28e2 410 {
pwheels 0:1193dbfe28e2 411 // check results to see if it was a success
pwheels 0:1193dbfe28e2 412 for (i = 0; i < 192; i += 3)
pwheels 0:1193dbfe28e2 413 {
pwheels 0:1193dbfe28e2 414 tst = (bitacc(READ_FUNCTION,0,i,&sendpacket[1]) << 1) |
pwheels 0:1193dbfe28e2 415 bitacc(READ_FUNCTION,0,(int)(i+1),&sendpacket[1]);
pwheels 0:1193dbfe28e2 416
pwheels 0:1193dbfe28e2 417 s = bitacc(READ_FUNCTION,0,cnt++,&SerialNum[portnum][0]);
pwheels 0:1193dbfe28e2 418
pwheels 0:1193dbfe28e2 419 if (tst == 0x03) // no device on line
pwheels 0:1193dbfe28e2 420 {
pwheels 0:1193dbfe28e2 421 goodbits = 0; // number of good bits set to zero
pwheels 0:1193dbfe28e2 422 break; // quit
pwheels 0:1193dbfe28e2 423 }
pwheels 0:1193dbfe28e2 424
pwheels 0:1193dbfe28e2 425 if (((s == 0x01) && (tst == 0x02)) ||
pwheels 0:1193dbfe28e2 426 ((s == 0x00) && (tst == 0x01)) ) // correct bit
pwheels 0:1193dbfe28e2 427 goodbits++; // count as a good bit
pwheels 0:1193dbfe28e2 428 }
pwheels 0:1193dbfe28e2 429
pwheels 0:1193dbfe28e2 430 // check too see if there were enough good bits to be successful
pwheels 0:1193dbfe28e2 431 if (goodbits >= 8)
pwheels 0:1193dbfe28e2 432 return TRUE;
pwheels 0:1193dbfe28e2 433 }
pwheels 0:1193dbfe28e2 434 else
pwheels 0:1193dbfe28e2 435 OWERROR(OWERROR_BLOCK_FAILED);
pwheels 0:1193dbfe28e2 436
pwheels 0:1193dbfe28e2 437 // block fail or device not present
pwheels 0:1193dbfe28e2 438 return FALSE;
pwheels 0:1193dbfe28e2 439 }
pwheels 0:1193dbfe28e2 440
pwheels 0:1193dbfe28e2 441 //----------------------------------------------------------------------
pwheels 0:1193dbfe28e2 442 // Perform a overdrive MATCH command to select the 1-Wire device with
pwheels 0:1193dbfe28e2 443 // the address in the ID data register.
pwheels 0:1193dbfe28e2 444 //
pwheels 0:1193dbfe28e2 445 // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
pwheels 0:1193dbfe28e2 446 // indicate the symbolic port number.
pwheels 0:1193dbfe28e2 447 //
pwheels 0:1193dbfe28e2 448 // Returns: TRUE: If the device is present on the 1-Wire Net and
pwheels 0:1193dbfe28e2 449 // can do overdrive then the device is selected.
pwheels 0:1193dbfe28e2 450 // FALSE: Device is not present or not capable of overdrive.
pwheels 0:1193dbfe28e2 451 //
pwheels 0:1193dbfe28e2 452 // *Note: This function could be converted to send DS2480
pwheels 0:1193dbfe28e2 453 // commands in one packet.
pwheels 0:1193dbfe28e2 454 //
pwheels 0:1193dbfe28e2 455 SMALLINT owOverdriveAccess(int portnum)
pwheels 0:1193dbfe28e2 456 {
pwheels 0:1193dbfe28e2 457 uchar sendpacket[8];
pwheels 0:1193dbfe28e2 458 uchar i, bad_echo = FALSE;
pwheels 0:1193dbfe28e2 459
pwheels 0:1193dbfe28e2 460 // make sure normal level
pwheels 0:1193dbfe28e2 461 owLevel(portnum,MODE_NORMAL);
pwheels 0:1193dbfe28e2 462
pwheels 0:1193dbfe28e2 463 // force to normal communication speed
pwheels 0:1193dbfe28e2 464 owSpeed(portnum,MODE_NORMAL);
pwheels 0:1193dbfe28e2 465
pwheels 0:1193dbfe28e2 466 // call the 1-Wire Net reset function
pwheels 0:1193dbfe28e2 467 if (owTouchReset(portnum))
pwheels 0:1193dbfe28e2 468 {
pwheels 0:1193dbfe28e2 469 // send the match command 0x69
pwheels 0:1193dbfe28e2 470 if (owWriteByte(portnum,0x69))
pwheels 0:1193dbfe28e2 471 {
pwheels 0:1193dbfe28e2 472 // switch to overdrive communication speed
pwheels 0:1193dbfe28e2 473 owSpeed(portnum,MODE_OVERDRIVE);
pwheels 0:1193dbfe28e2 474
pwheels 0:1193dbfe28e2 475 // create a buffer to use with block function
pwheels 0:1193dbfe28e2 476 // Serial Number
pwheels 0:1193dbfe28e2 477 for (i = 0; i < 8; i++)
pwheels 0:1193dbfe28e2 478 sendpacket[i] = SerialNum[portnum][i];
pwheels 0:1193dbfe28e2 479
pwheels 0:1193dbfe28e2 480 // send/recieve the transfer buffer
pwheels 0:1193dbfe28e2 481 if (owBlock(portnum,FALSE,sendpacket,8))
pwheels 0:1193dbfe28e2 482 {
pwheels 0:1193dbfe28e2 483 // verify that the echo of the writes was correct
pwheels 0:1193dbfe28e2 484 for (i = 0; i < 8; i++)
pwheels 0:1193dbfe28e2 485 if (sendpacket[i] != SerialNum[portnum][i])
pwheels 0:1193dbfe28e2 486 bad_echo = TRUE;
pwheels 0:1193dbfe28e2 487 // if echo ok then success
pwheels 0:1193dbfe28e2 488 if (!bad_echo)
pwheels 0:1193dbfe28e2 489 return TRUE;
pwheels 0:1193dbfe28e2 490 else
pwheels 0:1193dbfe28e2 491 OWERROR(OWERROR_WRITE_VERIFY_FAILED);
pwheels 0:1193dbfe28e2 492 }
pwheels 0:1193dbfe28e2 493 else
pwheels 0:1193dbfe28e2 494 OWERROR(OWERROR_BLOCK_FAILED);
pwheels 0:1193dbfe28e2 495 }
pwheels 0:1193dbfe28e2 496 else
pwheels 0:1193dbfe28e2 497 OWERROR(OWERROR_WRITE_BYTE_FAILED);
pwheels 0:1193dbfe28e2 498 }
pwheels 0:1193dbfe28e2 499 else
pwheels 0:1193dbfe28e2 500 OWERROR(OWERROR_NO_DEVICES_ON_NET);
pwheels 0:1193dbfe28e2 501
pwheels 0:1193dbfe28e2 502 // failure, force back to normal communication speed
pwheels 0:1193dbfe28e2 503 owSpeed(portnum,MODE_NORMAL);
pwheels 0:1193dbfe28e2 504
pwheels 0:1193dbfe28e2 505 return FALSE;
pwheels 0:1193dbfe28e2 506 }
pwheels 0:1193dbfe28e2 507
pwheels 0:1193dbfe28e2 508 //--------------------------------------------------------------------------
pwheels 0:1193dbfe28e2 509 // Bit utility to read and write a bit in the buffer 'buf'.
pwheels 0:1193dbfe28e2 510 //
pwheels 0:1193dbfe28e2 511 // 'op' - operation (1) to set and (0) to read
pwheels 0:1193dbfe28e2 512 // 'state' - set (1) or clear (0) if operation is write (1)
pwheels 0:1193dbfe28e2 513 // 'loc' - bit number location to read or write
pwheels 0:1193dbfe28e2 514 // 'buf' - pointer to array of bytes that contains the bit
pwheels 0:1193dbfe28e2 515 // to read or write
pwheels 0:1193dbfe28e2 516 //
pwheels 0:1193dbfe28e2 517 // Returns: 1 if operation is set (1)
pwheels 0:1193dbfe28e2 518 // 0/1 state of bit number 'loc' if operation is reading
pwheels 0:1193dbfe28e2 519 //
pwheels 0:1193dbfe28e2 520 SMALLINT bitacc(SMALLINT op, SMALLINT state, SMALLINT loc, uchar *buf)
pwheels 0:1193dbfe28e2 521 {
pwheels 0:1193dbfe28e2 522 SMALLINT nbyt,nbit;
pwheels 0:1193dbfe28e2 523
pwheels 0:1193dbfe28e2 524 nbyt = (loc / 8);
pwheels 0:1193dbfe28e2 525 nbit = loc - (nbyt * 8);
pwheels 0:1193dbfe28e2 526
pwheels 0:1193dbfe28e2 527 if (op == WRITE_FUNCTION)
pwheels 0:1193dbfe28e2 528 {
pwheels 0:1193dbfe28e2 529 if (state)
pwheels 0:1193dbfe28e2 530 buf[nbyt] |= (0x01 << nbit);
pwheels 0:1193dbfe28e2 531 else
pwheels 0:1193dbfe28e2 532 buf[nbyt] &= ~(0x01 << nbit);
pwheels 0:1193dbfe28e2 533
pwheels 0:1193dbfe28e2 534 return 1;
pwheels 0:1193dbfe28e2 535 }
pwheels 0:1193dbfe28e2 536 else
pwheels 0:1193dbfe28e2 537 return ((buf[nbyt] >> nbit) & 0x01);
pwheels 0:1193dbfe28e2 538 }