1 //---------------------------------------------------------------------------
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 //  swt1f.c - Does commands on the DS2409 device
28 //
29 //  version 2.00-digitemp
30 //    Fixed problem of not finding more than 1 device on main branch by
31 //    changing owBranchNext to use Smart Main instead of Main On command
32 //
33 //  version 2.00
34 //  - future version will have branch of a branch searches
35 //
36 
37 // Include files
38 #include <stdio.h>
39 #include "ownet.h"
40 
41 // external One Wire functions from nework layer
42 extern SMALLINT owAccess(int);
43 extern SMALLINT owFirst(int,SMALLINT,SMALLINT);
44 extern SMALLINT owNext(int,SMALLINT,SMALLINT);
45 extern void     owSerialNum(int,uchar *,SMALLINT);
46 
47 // external One Wire functions from transaction layer
48 extern SMALLINT owBlock(int,SMALLINT,uchar *,SMALLINT);
49 
50 // Local subroutines
51 int SetSwitch1F(int,uchar *,int,int,uchar *,int);
52 int SwitchStateToString1F(int, char *);
53 int FindBranchDevice(int,uchar *,uchar BranchSN[][8],int,int);
54 int owBranchFirst(int,uchar *,int,int);
55 int owBranchNext(int,uchar *,int,int);
56 
57 //----------------------------------------------------------------------
58 //	SUBROUTINE - SetSwitch1F
59 //
60 //  This routine sets the main and auxilary on and off for DS2409.
61 //
62 // 'portnum'     - number 0 to MAX_PORTNUM-1.  This number is provided to
63 //                 indicate the symbolic port number.
64 // 'SerialNum'   - Serial Number of DS2409 to set the switch state
65 // 'Swtch'       - '0' Sets Main and Auxilary off
66 //                 '1' Sets Main on
67 //                 '2' Sets Auxilary on
68 //                 '3' Read Status Info Byte
69 //                 '4' Smart On Main
70 // 'NumExtra'    - The number of extra bytes for a command.
71 // 'InfoByte'    - Returns the info byte and other information depending
72 //                 on the command.  The InfoByte size changes depending on
73 //                 the NumExtra which is buffer length * (NumExtra + 1)
74 // 'rst'         - True then reset the search for devices
75 //                 False don't reset search
76 //
77 //  Returns: TRUE(1)  State of DS2409 set and verified
78 //           FALSE(0) could not set the DS2409, perhaps device is not
79 //                    in contact
80 //
SetSwitch1F(int portnum,uchar * SerialNum,int Swtch,int NumExtra,uchar * InfoByte,int rst)81 int SetSwitch1F(int portnum, uchar *SerialNum, int Swtch, int NumExtra,
82                     uchar *InfoByte, int rst)
83 {
84    int send_cnt,i,cmd;
85    uchar send_block[50];
86 
87    if(owAccess(portnum))
88    {
89       send_cnt = 0;
90       // add the match command
91       send_block[send_cnt++] = 0x55;
92 
93       for (i = 0; i < 8; i++)
94          send_block[send_cnt++] = SerialNum[i];
95 
96       // the command
97       switch(Swtch)
98       {
99          case 0: // All lines off
100             send_block[send_cnt++] = 0x66;
101             cmd = 0x66;
102             break;
103 
104          case 1: // Direct on Main
105             send_block[send_cnt++] = 0xA5;
106             cmd = 0xA5;
107             break;
108 
109          case 2: // Smart on Auxilary
110             send_block[send_cnt++] = 0x33;
111             cmd = 0x33;
112             break;
113 
114          case 3: // Status Read/Write
115             send_block[send_cnt++] = 0x5A;
116             cmd = 0x5A;
117 
118             // bytes 0-2: don't care
119             // bytes 3-4: write control 0 to change status
120             // byte 5: 0 = auto-control, 1 = manual mode
121             // byte 6: 0 = main, 1 = auxiliary
122             // byte 7: value to be written to control output, manual mode only
123             // 0x00 default value
124             *InfoByte = 0x00;
125             send_block[send_cnt++] = *InfoByte;
126             break;
127 
128          case 4: // Smart on Main
129             send_block[send_cnt++] = 0xCC;
130             cmd = 0xCC;
131             break;
132 
133          default:
134             return FALSE;
135       }
136 
137       // extra bytes and confirmation
138       for(i=0; i<=NumExtra; i++)
139          send_block[send_cnt++] = 0xFF;
140 
141       // send the command string
142       if(owBlock(portnum,rst,send_block,send_cnt))
143       {
144          // returned information for the info byte and command
145          for(i=0; i<=NumExtra; i++)
146             *(InfoByte+(NumExtra-i)) = send_block[send_cnt - (i+2)];
147 
148          // Set because for the read/write command the confirmation
149          // byte is the same as the status byte
150          if (Swtch == 3)
151             cmd = send_block[send_cnt - 2];
152 
153          if (send_block[send_cnt - 1] == cmd)
154             return TRUE;
155       }
156    }
157 
158    return FALSE;
159 }
160 
161 //----------------------------------------------------------------------
162 // SUBROUTINE = FindBranchDevices
163 //
164 // This routine will find all the branches on a certain DS2409 device and
165 // will return the serial numbers down that branch
166 //
167 // 'portnum'        - number 0 to MAX_PORTNUM-1.  This number is provided to
168 //                    indicate the symbolic port number.
169 // 'Branch[8]'      - The serial number of the branch to look down
170 // 'BranchSN[][8]'  - The list of serial numbers on the branch
171 // 'MAXDEVICES'     - The Max devices on the branch
172 // 'MainBr'         - True to search down the main branch, False for Aux.
173 //
174 // Returns: Returns the number of devices found on the branch
175 //
FindBranchDevice(int portnum,uchar Branch[8],uchar BranchSN[][8],int MAXDEVICES,int MainBr)176 int FindBranchDevice(int portnum, uchar Branch[8], uchar BranchSN[][8], int MAXDEVICES,
177                      int MainBr)
178 {
179    int NumDevices = 0;
180    short result;
181 
182    result = owBranchFirst(portnum, &Branch[0], FALSE, MainBr);
183 
184    while(result)
185    {
186       owSerialNum(portnum,BranchSN[NumDevices], TRUE);
187       NumDevices++;
188 
189       result = owBranchNext(portnum, &Branch[0], FALSE, MainBr);
190    }
191 
192    return NumDevices;
193 }
194 
195 //----------------------------------------------------------------------
196 // SUBROUTINE - owBranchFirst
197 //
198 // This routine is used like owFirst but for devices on a branch.
199 //
200 // 'portnum' - number 0 to MAX_PORTNUM-1.  This number is provided to
201 //             indicate the symbolic port number.
202 // 'BrSN'    - This is the DS2409 device branch
203 // 'AlarmD'  - True or False, to do Alarm search or false for regular search
204 // 'FirMain' - True then search main branch, False search Aux. branch
205 //
206 // Returns:   TRUE (1) : when a 1-Wire device was found and it's
207 //                        Serial Number placed in the global SerialNum
208 //            FALSE (0): There are no devices on the 1-Wire Net.
209 //
owBranchFirst(int portnum,uchar BrSN[8],int AlarmD,int FirMain)210 int owBranchFirst(int portnum, uchar BrSN[8], int AlarmD, int FirMain)
211 {
212    int smart_main = 4;
213    int smart_aux = 2;
214    int numextra = 2;
215    uchar extra[3];
216 
217 
218    if(FirMain)
219    {
220       if(SetSwitch1F(portnum, &BrSN[0], smart_main, numextra, extra, TRUE))
221          if(extra[2] != 0xFF)
222             return owFirst(portnum,FALSE, AlarmD);
223    }
224    else
225    {
226       if(SetSwitch1F(portnum, &BrSN[0], smart_aux, numextra, extra, TRUE))
227          if(extra[2] != 0xFF)
228             return owFirst(portnum,FALSE, AlarmD);
229    }
230 
231    return FALSE;
232 }
233 
234 //----------------------------------------------------------------------
235 // SUBROUTINE - owBranchNext
236 //
237 // This routine is used like owFirst but for devices on a branch.
238 //
239 // 'portnum'    - number 0 to MAX_PORTNUM-1.  This number is provided to
240 //                indicate the symbolic port number.
241 // 'BrSN'       - This is the DS2409 device branch
242 // 'AlarmD'     - True or False, to do Alarm search or false for regular search
243 // 'NextMain'   - True then search main branch, False search Aux. branch
244 //
245 // Returns:   TRUE (1) : when a 1-Wire device was found and it's
246 //                        Serial Number placed in the global SerialNum
247 //            FALSE (0): There are no devices on the 1-Wire Net.
248 //
owBranchNext(int portnum,uchar BrSN[8],int AlarmD,int NextMain)249 int owBranchNext(int portnum, uchar BrSN[8], int AlarmD, int NextMain)
250 {
251    int smart_main = 4;		/* Was 1, Main On [bcl - 01132002 */
252    int smart_aux = 2;
253    int numextra = 2;
254    uchar extra[3];
255 
256    if(NextMain)
257    {
258       if(SetSwitch1F(portnum, &BrSN[0], smart_main, numextra, extra, TRUE))
259          return owNext(portnum,FALSE, AlarmD);
260    }
261    else
262    {
263       if(SetSwitch1F(portnum, &BrSN[0], smart_aux, numextra, extra, TRUE))
264          return owNext(portnum,FALSE, AlarmD);
265    }
266 
267    return FALSE;
268 }
269 
270 //----------------------------------------------------------------------
271 //	SUBROUTINE - SwitchStateToString
272 //
273 //  This routine uses the info byte to return a string with all the data.
274 //
275 // 'infobyte'   - This is the information byte data from the hardware.
276 // 'outstr'     - This will be the output string.  It gets set in the
277 //				      the procedure.
278 //
279 // Returns      - Returns the number of characters in the string
280 //
SwitchStateToString1F(int infobyte,char * outstr)281 int SwitchStateToString1F(int infobyte, char *outstr)
282 {
283    int cnt = 0;
284 
285    if(infobyte & 0x80)
286    {
287       cnt += sprintf(outstr+cnt, "%s", "Manual mode\n");
288       if(infobyte & 0x40)
289          cnt += sprintf(outstr+cnt, "%s", "Output transistor on\n");
290       else
291          cnt += sprintf(outstr+cnt, "%s", "Output transistor off\n");
292    }
293    else
294    {
295       cnt += sprintf(outstr+cnt, "%s", "Auto-control mode\n");
296       if(infobyte & 0x40)
297          cnt += sprintf(outstr+cnt, "%s", "Output association with Auxillary\n");
298       else
299          cnt += sprintf(outstr+cnt, "%s", "Output association with Main\n");
300    }
301 
302    if(infobyte & 0x20)
303       cnt += sprintf(outstr+cnt, "%s",
304          "Negative edge sensed since inactive on Main\n");
305    else
306       cnt += sprintf(outstr+cnt, "%s", "No event on Main\n");
307 
308    if(infobyte & 0x10)
309       cnt += sprintf(outstr+cnt, "%s",
310          "Negative edge sensed since inactive on Aux.\n");
311    else
312       cnt += sprintf(outstr+cnt, "%s", "No event on Aux.\n");
313 
314    if(infobyte & 0x08)
315       cnt += sprintf(outstr+cnt, "%s", "Voltage High on Aux. output\n");
316    else
317       cnt += sprintf(outstr+cnt, "%s", "Voltage Low on Aux. output\n");
318 
319    if(infobyte & 0x04)
320       cnt += sprintf(outstr+cnt, "%s", "Inactive status of Aux. output\n");
321    else
322       cnt += sprintf(outstr+cnt, "%s", "Active status of Aux. output\n");
323 
324    if(infobyte & 0x02)
325       cnt += sprintf(outstr+cnt, "%s", "Voltage High on Main output\n");
326    else
327       cnt += sprintf(outstr+cnt, "%s", "Voltage Low on Main output\n");
328 
329    if(infobyte & 0x01)
330       cnt += sprintf(outstr+cnt, "%s", "Inactive status on Main output\n");
331    else
332       cnt += sprintf(outstr+cnt, "%s", "Active status on Main output\n");
333 
334    return cnt;
335 }
336