OpenCores
URL https://opencores.org/ocsvn/sockit_owm/sockit_owm/trunk

Subversion Repositories sockit_owm

[/] [sockit_owm/] [trunk/] [HAL/] [src/] [ownet.c] - Blame information for rev 2

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.