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