1 //---------------------------------------------------------------------------
2 // Copyright (C) 2000 Dallas Semiconductor Corporation, All Rights Reserved.
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:
11 // The above copyright notice and this permission notice shall be included
12 // in all copies or substantial portions of the Software.
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.
22 // Except as contained in this notice, the name of Dallas Semiconductor
23 // shall not be used except as stated in the Dallas Semiconductor
25 //---------------------------------------------------------------------------
29 // Minimal access routines for TINI internal one-wire bus patched together
30 // from Dallas example code (hence the copyright notice above).
32 // Kevin Vigor, 11/20/2000
37 /* The internal 1-wire bus is hooked to P3.5, a.k.a T1 */
38 /* The "activity" LED is also hooked to this line. */
39 #define INT_OW_PORT T1
41 // local variables for this module to hold search state information
42 static int LastDiscrepancy;
43 static int LastFamilyDiscrepancy;
44 static int LastDevice;
45 static unsigned char iSerialNum[8];
47 static uchar iowTouchBit(uchar);
48 static uchar iowTouchByte(uchar);
50 //--------------------------------------------------------------------------
51 // Reset all of the devices on the 1-Wire Net and return the result.
53 // Returns: TRUE(1): presense pulse(s) detected, device(s) reset
54 // FALSE(0): no presense pulses detected
56 unsigned char iowTouchReset(void)
60 //printf ("iowTouchReset(): ");
62 /* Code stolen straight from appnote 126. */
63 INT_OW_PORT = 0; /* drive bus low. */
64 ClockMicroSecondsDelay(480);
65 INT_OW_PORT = 1; /* bus high. */
66 ClockMicroSecondsDelay(120);
67 result = INT_OW_PORT; /* get presence detect pulse. */
68 ClockMicroSecondsDelay(360);
70 //printf ("%d\n", result);
74 //--------------------------------------------------------------------------
75 // Send 1 bit of communication to the 1-Wire Net and return the
76 // result 1 bit read from the 1-Wire Net. The parameter 'sendbit'
77 // least significant bit is used and the least significant bit
78 // of the result is the return bit.
80 // Returns: 0: 0 bit read from sendbit
81 // 1: 1 bit read from sendbit
83 static unsigned char iowTouchBit(unsigned char sendbit)
87 INT_OW_PORT = 0; /* start timeslot. */
88 ClockMicroSecondsDelay(1);
90 INT_OW_PORT = sendbit; /* send bit out. */
91 ClockMicroSecondsDelay(9);
92 result = INT_OW_PORT; /* sample result @ 10 us. */
93 ClockMicroSecondsDelay(50);
94 INT_OW_PORT = 1; /* timeslot done. */
95 ClockMicroSecondsDelay(5);
100 //--------------------------------------------------------------------------
101 // Send 8 bits of communication to the 1-Wire Net and return the
102 // result 8 bits read from the 1-Wire Net. The parameter 'sendbyte'
103 // least significant 8 bits are used and the least significant 8 bits
104 // of the result is the return byte.
106 // 'sendbyte' - 8 bits to send (least significant byte)
108 // Returns: 8 bytes read from sendbyte
110 static unsigned char iowTouchByte(unsigned char sendbyte)
113 unsigned char result = 0;
115 //printf ("iowTouchByte(%02x): ", sendbyte);
117 for (i = 0; i < 8; i++)
119 result |= (iowTouchBit(sendbyte & 1) << i);
123 //printf ("%02x\n", result);
127 //--------------------------------------------------------------------------
128 // Send 8 bits of communication to the 1-Wire Net and verify that the
129 // 8 bits read from the 1-Wire Net is the same (write operation).
130 // The parameter 'sendbyte' least significant 8 bits are used.
132 // 'sendbyte' - 8 bits to send (least significant byte)
134 // Returns: TRUE: bytes written and echo was the same
135 // FALSE: echo was not the same
137 unsigned char iowWriteByte(unsigned char sendbyte)
139 return (iowTouchByte(sendbyte) == sendbyte) ? TRUE : FALSE;
142 //--------------------------------------------------------------------------
143 // The 'owBlock' transfers a block of data to and from the
144 // 1-Wire Net with an optional reset at the begining of communication.
145 // The result is returned in the same buffer.
147 // 'do_reset' - cause a owTouchReset to occure at the begining of
148 // communication TRUE(1) or not FALSE(0)
149 // 'tran_buf' - pointer to a block of unsigned
150 // chars of length 'TranferLength' that will be sent
152 // 'tran_len' - length in bytes to transfer
154 // Supported devices: all
156 // Returns: TRUE (1) : The optional reset returned a valid
157 // presence (do_reset == TRUE) or there
158 // was no reset required.
159 // FALSE (0): The reset did not return a valid prsence
160 // (do_reset == TRUE).
162 // The maximum tran_len is 64
164 unsigned char iowBlock(unsigned char do_reset,
165 unsigned char *tran_buf,
166 unsigned char tran_len)
170 // check for a block too big
174 // check if need to do a owTouchReset first
177 if (!iowTouchReset())
181 // send and receive the buffer
182 for (i = 0; i < tran_len; i++)
183 tran_buf[i] = iowTouchByte(tran_buf[i]);
188 //--------------------------------------------------------------------------
189 // Send 8 bits of read communication to the 1-Wire Net and and return the
190 // result 8 bits read from the 1-Wire Net.
192 // Returns: 8 bytes read from 1-Wire Net
194 unsigned char iowReadByte(void)
196 return iowTouchByte(0xFF);
199 //--------------------------------------------------------------------------
200 // The 'owFirst' finds the first device on the 1-Wire Net This function
201 // contains one parameter 'alarm_only'. When
202 // 'alarm_only' is TRUE (1) the find alarm command 0xEC is
203 // sent instead of the normal search command 0xF0.
204 // Using the find alarm command 0xEC will limit the search to only
205 // 1-Wire devices that are in an 'alarm' state.
207 // 'do_reset' - TRUE (1)
208 // perform reset before search.
209 // 'alarm_only' - TRUE (1) the find alarm command 0xEC is
210 // sent instead of the normal search command 0xF0
212 // Returns: TRUE (1) : when a 1-Wire device was found and it's
213 // Serial Number placed in the global iSerialNum[portnum]
214 // FALSE (0): There are no devices on the 1-Wire Net.
216 unsigned char iowFirst(unsigned char do_reset, unsigned char alarm_only)
218 // reset the search state
221 LastFamilyDiscrepancy = 0;
223 return iowNext(do_reset,alarm_only);
226 //--------------------------------------------------------------------------
227 // The 'owNext' function does a general search. This function
228 // continues from the previos search state. The search state
229 // can be reset by using the 'owFirst' function.
230 // This function contains one parameter 'alarm_only'.
231 // When 'alarm_only' is TRUE (1) the find alarm command
232 // 0xEC is sent instead of the normal search command 0xF0.
233 // Using the find alarm command 0xEC will limit the search to only
234 // 1-Wire devices that are in an 'alarm' state.
236 // 'do_reset' - TRUE (1) perform reset before search, FALSE (0) do not
237 // perform reset before search.
238 // 'alarm_only' - TRUE (1) the find alarm command 0xEC is
239 // sent instead of the normal search command 0xF0
241 // Returns: TRUE (1) : when a 1-Wire device was found and it's
242 // Serial Number placed in the global iSerialNum[portnum]
243 // FALSE (0): when no new device was found. Either the
244 // last search was the last device or there
245 // are no devices on the 1-Wire Net.
247 unsigned char iowNext(unsigned char do_reset, unsigned char alarm_only)
249 int bit_test, search_direction, bit_number;
250 int last_zero, serial_byte_number, next_result;
251 unsigned char serial_byte_mask;
252 unsigned char lastcrc8;
254 //printf ("iowNext(%d,%d)\n", do_reset, alarm_only);
256 // initialize for search
259 serial_byte_number = 0;
260 serial_byte_mask = 1;
264 // if the last call was not the last one
267 // check if reset first is requested
271 // if there are no parts on 1-wire, return FALSE
272 if (!iowTouchReset())
276 LastFamilyDiscrepancy = 0;
281 // If finding alarming devices issue a different command
283 iowWriteByte(0xEC); // issue the alarming search command
285 iowWriteByte(0xF0); // issue the search command
287 // loop to do the search
290 // read a bit and its compliment
291 bit_test = iowTouchBit(1) << 1;
292 bit_test |= iowTouchBit(1);
294 // check for no devices on 1-wire
301 // all devices coupled have 0 or 1
304 search_direction = !(bit_test & 0x01); // bit write value for search
308 // if this discrepancy if before the Last Discrepancy
309 // on a previous next then pick the same as last time
310 if (bit_number < LastDiscrepancy)
311 search_direction = ((iSerialNum[serial_byte_number] & serial_byte_mask) > 0);
313 // if equal to last pick 1, if not then pick 0
314 search_direction = (bit_number == LastDiscrepancy);
316 // if 0 was picked then record its position in LastZero
317 if (search_direction == 0)
318 last_zero = bit_number;
320 // check for Last discrepancy in family
322 LastFamilyDiscrepancy = last_zero;
325 // set or clear the bit in the iSerialNum byte serial_byte_number
326 // with mask serial_byte_mask
327 if (search_direction == 1)
328 iSerialNum[serial_byte_number] |= serial_byte_mask;
330 iSerialNum[serial_byte_number] &= ~serial_byte_mask;
332 // serial number search direction write bit
333 iowTouchBit(search_direction);
335 // increment the byte counter bit_number
336 // and shift the mask serial_byte_mask
338 serial_byte_mask <<= 1;
340 // if the mask is 0 then go to new iSerialNum byte serial_byte_number
342 if (serial_byte_mask == 0)
344 lastcrc8 = docrc8(lastcrc8,iSerialNum[serial_byte_number]); // accumulate the CRC
345 serial_byte_number++;
346 serial_byte_mask = 1;
350 while(serial_byte_number < 8); // loop until through all iSerialNum bytes 0-7
352 // if the search was successful then
353 if (!((bit_number < 65) || lastcrc8))
355 // search successful so set LastDiscrepancy,LastDevice,next_result
356 LastDiscrepancy = last_zero;
357 LastDevice = (LastDiscrepancy == 0);
362 // if no device found then reset counters so next 'next' will be
364 if (!next_result || !iSerialNum[0])
368 LastFamilyDiscrepancy = 0;
375 //--------------------------------------------------------------------------
376 // The 'owSerialNum' function either reads or sets the SerialNum buffer
377 // that is used in the search functions 'owFirst' and 'owNext'.
378 // This function contains two parameters, 'serialnum_buf' is a pointer
379 // to a buffer provided by the caller. 'serialnum_buf' should point to
380 // an array of 8 unsigned chars. The second parameter is a flag called
381 // 'do_read' that is TRUE (1) if the operation is to read and FALSE
382 // (0) if the operation is to set the internal SerialNum buffer from
383 // the data in the provided buffer.
385 // 'serialnum_buf' - buffer to that contains the serial number to set
386 // when do_read = FALSE (0) and buffer to get the serial
387 // number when do_read = TRUE (1).
388 // 'do_read' - flag to indicate reading (1) or setting (0) the current
391 void iowSerialNum(unsigned char *serialnum_buf, unsigned char do_read)
395 // read the internal buffer and place in 'serialnum_buf'
398 for (i = 0; i < 8; i++)
400 serialnum_buf[i] = iSerialNum[i];
403 // set the internal buffer from the data in 'serialnum_buf'
406 for (i = 0; i < 8; i++)
408 iSerialNum[i] = serialnum_buf[i];
413 // unsupported routines
415 uchar iowSpeed(int speed) {
416 speed; // hush the compiler
417 printf ("No owSpeed for internal ow yet\n");
421 uchar iowLevel(int level) {
422 level; // hush the compiler
423 printf ("No owLevel for internal ow yet\n");
427 uchar iowProgramPulse() {
428 printf ("No owProgramPulse for internal ow yet\n");