5 //---------------------------------------------------------------------------
6 // Copyright (C) 2000 Dallas Semiconductor Corporation, All Rights Reserved.
8 // Permission is hereby granted, free of charge, to any person obtaining a
9 // copy of this software and associated documentation files (the "Software"),
10 // to deal in the Software without restriction, including without limitation
11 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 // and/or sell copies of the Software, and to permit persons to whom the
13 // Software is furnished to do so, subject to the following conditions:
15 // The above copyright notice and this permission notice shall be included
16 // in all copies or substantial portions of the Software.
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 // IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES
22 // OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 // OTHER DEALINGS IN THE SOFTWARE.
26 // Except as contained in this notice, the name of Dallas Semiconductor
27 // shall not be used except as stated in the Dallas Semiconductor
29 //---------------------------------------------------------------------------
31 // owLLU.C - Link Layer 1-Wire Net functions using the DS2480/DS2480B (U)
32 // serial interface chip.
36 // History: 1.00 -> 1.01 DS2480 version number now ignored in
38 // 1.02 -> 1.03 Removed caps in #includes for Linux capatibility
39 // Removed #include <windows.h>
40 // Add #include "ownet.h" to define TRUE,FALSE
41 // 1.03 -> 2.00 Changed 'MLan' to 'ow'. Added support for
47 // local varable flag, true if program voltage available
48 static int ProgramAvailable[MAX_PORTNUM];
50 //--------------------------------------------------------------------------
51 // Reset all of the devices on the 1-Wire Net and return the result.
53 // 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
54 // OpenCOM to indicate the port number.
56 // Returns: TRUE(1): presense pulse(s) detected, device(s) reset
57 // FALSE(0): no presense pulses detected
59 // WARNING: This routine will not function correctly on some
60 // Alarm reset types of the DS1994/DS1427/DS2404 with
61 // Rev 1,2, and 3 of the DS2480/DS2480B.
63 int owTouchReset(int portnum)
65 uchar readbuffer[10],sendpacket[10];
69 printf ("owTouchReset\n");
71 // make sure normal level
72 owLevel(portnum,MODE_NORMAL);
74 // check if correct mode
75 if (UMode[portnum] != MODSEL_COMMAND)
77 UMode[portnum] = MODSEL_COMMAND;
78 sendpacket[sendlen++] = MODE_COMMAND;
81 // construct the command
82 sendpacket[sendlen++] = (uchar)(CMD_COMM | FUNCTSEL_RESET | USpeed[portnum]);
88 if (WriteCOM(portnum,sendlen,sendpacket))
90 // read back the 1 byte response
91 if (ReadCOM(portnum,1,readbuffer) == 1)
93 // make sure this byte looks like a reset byte
94 if (((readbuffer[0] & RB_RESET_MASK) == RB_PRESENCE) ||
95 ((readbuffer[0] & RB_RESET_MASK) == RB_ALARMPRESENCE))
97 // check if programming voltage available
98 ProgramAvailable[portnum] = ((readbuffer[0] & 0x20) == 0x20);
106 // an error occured so re-sync with DS2480
107 DS2480Detect(portnum);
112 //--------------------------------------------------------------------------
113 // Send 1 bit of communication to the 1-Wire Net and return the
114 // result 1 bit read from the 1-Wire Net. The parameter 'sendbit'
115 // least significant bit is used and the least significant bit
116 // of the result is the return bit.
118 // 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
119 // OpenCOM to indicate the port number.
120 // 'sendbit' - the least significant bit is the bit to send
122 // Returns: 0: 0 bit read from sendbit
123 // 1: 1 bit read from sendbit
125 int owTouchBit(int portnum, int sendbit)
127 uchar readbuffer[10],sendpacket[10];
130 // make sure normal level
131 owLevel(portnum,MODE_NORMAL);
133 // check if correct mode
134 if (UMode[portnum] != MODSEL_COMMAND)
136 UMode[portnum] = MODSEL_COMMAND;
137 sendpacket[sendlen++] = MODE_COMMAND;
140 // construct the command
141 sendpacket[sendlen] = (sendbit != 0) ? BITPOL_ONE : BITPOL_ZERO;
142 sendpacket[sendlen++] |= CMD_COMM | FUNCTSEL_BIT | USpeed[portnum];
148 if (WriteCOM(portnum,sendlen,sendpacket))
150 // read back the response
151 if (ReadCOM(portnum,1,readbuffer) == 1)
153 // interpret the response
154 if (((readbuffer[0] & 0xE0) == 0x80) &&
155 ((readbuffer[0] & RB_BIT_MASK) == RB_BIT_ONE))
162 // an error occured so re-sync with DS2480
163 DS2480Detect(portnum);
168 //--------------------------------------------------------------------------
169 // Send 8 bits of communication to the 1-Wire Net and verify that the
170 // 8 bits read from the 1-Wire Net is the same (write operation).
171 // The parameter 'sendbyte' least significant 8 bits are used.
173 // 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
174 // OpenCOM to indicate the port number.
175 // 'sendbyte' - 8 bits to send (least significant byte)
177 // Returns: TRUE: bytes written and echo was the same
178 // FALSE: echo was not the same
180 int owWriteByte(int portnum, int sendbyte)
182 return (owTouchByte(portnum,sendbyte) == sendbyte) ? TRUE : FALSE;
186 //--------------------------------------------------------------------------
187 // Send 8 bits of read communication to the 1-Wire Net and and return the
188 // result 8 bits read from the 1-Wire Net.
190 // 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
191 // OpenCOM to indicate the port number.
193 // Returns: 8 bytes read from 1-Wire Net
195 int owReadByte(int portnum)
197 return owTouchByte(portnum,0xFF);
200 //--------------------------------------------------------------------------
201 // Send 8 bits of communication to the 1-Wire Net and return the
202 // result 8 bits read from the 1-Wire Net. The parameter 'sendbyte'
203 // least significant 8 bits are used and the least significant 8 bits
204 // of the result is the return byte.
206 // 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
207 // OpenCOM to indicate the port number.
208 // 'sendbyte' - 8 bits to send (least significant byte)
210 // Returns: 8 bytes read from sendbyte
212 int owTouchByte(int portnum, int sendbyte)
214 uchar readbuffer[10],sendpacket[10];
217 // make sure normal level
218 owLevel(portnum,MODE_NORMAL);
220 // check if correct mode
221 if (UMode[portnum] != MODSEL_DATA)
223 UMode[portnum] = MODSEL_DATA;
224 sendpacket[sendlen++] = MODE_DATA;
227 // add the byte to send
228 sendpacket[sendlen++] = (uchar)sendbyte;
230 // check for duplication of data that looks like COMMAND mode
231 if (sendbyte == MODE_COMMAND)
232 sendpacket[sendlen++] = (uchar)sendbyte;
238 if (WriteCOM(portnum,sendlen,sendpacket))
240 // read back the 1 byte response
241 if (ReadCOM(portnum,1,readbuffer) == 1)
243 // return the response
244 return (int)readbuffer[0];
248 // an error occured so re-sync with DS2480
249 DS2480Detect(portnum);
254 //--------------------------------------------------------------------------
255 // Set the 1-Wire Net communucation speed.
257 // 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
258 // OpenCOM to indicate the port number.
259 // 'new_speed' - new speed defined as
261 // MODE_OVERDRIVE 0x01
263 // Returns: current 1-Wire Net speed
265 int owSpeed(int portnum, int new_speed)
272 printf ("starting owSpeed: %d\n", new_speed);
274 // check if change from current mode
275 if (((new_speed == MODE_OVERDRIVE) &&
276 (USpeed[portnum] != SPEEDSEL_OD)) ||
277 ((new_speed == MODE_NORMAL) &&
278 (USpeed[portnum] != SPEEDSEL_FLEX)))
280 if (new_speed == MODE_OVERDRIVE)
282 // if overdrive then switch to 115200 baud
283 if (DS2480ChangeBaud(portnum,PARMSET_115200) == PARMSET_115200)
285 USpeed[portnum] = SPEEDSEL_OD;
289 else if (new_speed == MODE_NORMAL)
291 // else normal so set to 9600 baud
292 if (DS2480ChangeBaud(portnum,PARMSET_9600) == PARMSET_9600)
294 USpeed[portnum] = SPEEDSEL_FLEX;
299 // if baud rate is set correctly then change DS2480 speed
302 // check if correct mode
303 if (UMode[portnum] != MODSEL_COMMAND)
305 UMode[portnum] = MODSEL_COMMAND;
306 sendpacket[sendlen++] = MODE_COMMAND;
309 // proceed to set the DS2480 communication speed
310 sendpacket[sendlen++] = CMD_COMM | FUNCTSEL_SEARCHOFF | USpeed[portnum];
313 if (!WriteCOM(portnum,sendlen,sendpacket))
316 // lost communication with DS2480 then reset
317 DS2480Detect(portnum);
322 printf ("owSpeed: %d\n", rt);
324 // return the current speed
325 return (USpeed[portnum] == SPEEDSEL_OD) ? MODE_OVERDRIVE : MODE_NORMAL;
328 //--------------------------------------------------------------------------
329 // Set the 1-Wire Net line level. The values for new_level are
332 // 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
333 // OpenCOM to indicate the port number.
334 // 'new_level' - new level defined as
338 // MODE_BREAK 0x08 (not supported)
340 // Returns: current 1-Wire Net level
342 int owLevel(int portnum, int new_level)
344 uchar sendpacket[10],readbuffer[10];
349 printf ("owLevel: %d\n", new_level);
351 // check if need to change level
352 if (new_level != ULevel[portnum])
354 // check if just putting back to normal
355 if (new_level == MODE_NORMAL)
357 // check if correct mode
358 if (UMode[portnum] != MODSEL_COMMAND)
360 UMode[portnum] = MODSEL_COMMAND;
361 sendpacket[sendlen++] = MODE_COMMAND;
364 // stop pulse command
365 sendpacket[sendlen++] = MODE_STOP_PULSE;
371 if (WriteCOM(portnum,sendlen,sendpacket))
373 // read back the 1 byte response
374 if (ReadCOM(portnum,1,readbuffer) == 1)
376 // check response byte
377 if ((readbuffer[0] & 0xE0) == 0xE0)
380 ULevel[portnum] = MODE_NORMAL;
388 // check if correct mode
389 if (UMode[portnum] != MODSEL_COMMAND)
391 UMode[portnum] = MODSEL_COMMAND;
392 sendpacket[sendlen++] = MODE_COMMAND;
396 if (new_level == MODE_STRONG5)
398 // set the SPUD time value
399 sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_5VPULSE | PARMSET_infinite;
400 // add the command to begin the pulse
401 sendpacket[sendlen++] = CMD_COMM | FUNCTSEL_CHMOD | SPEEDSEL_PULSE | BITPOL_5V;
404 else if (new_level == MODE_PROGRAM)
406 // check if programming voltage available
407 if (!ProgramAvailable[portnum])
410 // set the PPD time value
411 sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_12VPULSE | PARMSET_infinite;
412 // add the command to begin the pulse
413 sendpacket[sendlen++] = CMD_COMM | FUNCTSEL_CHMOD | SPEEDSEL_PULSE | BITPOL_12V;
420 if (WriteCOM(portnum,sendlen,sendpacket))
422 // read back the 1 byte response from setting time limit
423 if (ReadCOM(portnum,1,readbuffer) == 1)
425 // check response byte
426 if ((readbuffer[0] & 0x81) == 0)
428 ULevel[portnum] = new_level;
435 // if lost communication with DS2480 then reset
437 DS2480Detect(portnum);
440 // return the current level
441 return ULevel[portnum];
444 //--------------------------------------------------------------------------
445 // This procedure creates a fixed 480 microseconds 12 volt pulse
446 // on the 1-Wire Net for programming EPROM iButtons.
448 // 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
449 // OpenCOM to indicate the port number.
451 // Returns: TRUE successful
452 // FALSE program voltage not available
454 int owProgramPulse(int portnum)
456 uchar sendpacket[10],readbuffer[10];
459 // check if programming voltage available
460 if (!ProgramAvailable[portnum])
463 // make sure normal level
464 owLevel(portnum,MODE_NORMAL);
466 // check if correct mode
467 if (UMode[portnum] != MODSEL_COMMAND)
469 UMode[portnum] = MODSEL_COMMAND;
470 sendpacket[sendlen++] = MODE_COMMAND;
473 // set the SPUD time value
474 sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_12VPULSE | PARMSET_512us;
477 sendpacket[sendlen++] = CMD_COMM | FUNCTSEL_CHMOD | BITPOL_12V | SPEEDSEL_PULSE;
483 if (WriteCOM(portnum,sendlen,sendpacket))
485 // read back the 2 byte response
486 if (ReadCOM(portnum,2,readbuffer) == 2)
488 // check response byte
489 if (((readbuffer[0] | CMD_CONFIG) ==
490 (CMD_CONFIG | PARMSEL_12VPULSE | PARMSET_512us)) &&
491 ((readbuffer[1] & 0xFC) ==
492 (0xFC & (CMD_COMM | FUNCTSEL_CHMOD | BITPOL_12V | SPEEDSEL_PULSE))))
497 // an error occured so re-sync with DS2480
498 DS2480Detect(portnum);