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 //  ds2480ut.c - DS2480B utility functions.
28 //
29 //  Version: 2.01
30 //
31 //  History: 1.00 -> 1.01  Default PDSRC changed from 0.83 to 1.37V/us
32 //                         in DS2480Detect. Changed to use msDelay instead
33 //                         of Delay.
34 //           1.01 -> 1.02  Changed global declarations from 'uchar' to 'int'.
35 //                         Changed DSO/WORT from 7 to 10us in DS2480Detect.
36 //           1.02 -> 1.03  Removed caps in #includes for Linux capatibility
37 //           1.03 -> 2.00  Changed 'MLan' to 'ow'. Added support for
38 //                         multiple ports.  Changed W1LT to 8us.
39 //           2.00 -> 2.01 Added error handling. Added circular-include check.
40 //           2.01 -> 2.10 Added raw memory error handling and SMALLINT
41 //           2.10 -> 3.00 Added memory bank functionality
42 //                        Added file I/O operations
43 //
44 
45 #include "ownet.h"
46 #include "ds2480.h"
47 
48 // external COM functions defined in system specific link file
49 extern SMALLINT WriteCOM(int,int,uchar *);
50 extern void     FlushCOM(int);
51 extern int      ReadCOM(int,int,uchar *);
52 extern void     BreakCOM(int);
53 extern void     SetBaudCOM(int,uchar);
54 extern void     msDelay(int);
55 
56 // exportable functions defined in ds2480ut.c
57 SMALLINT DS2480Detect(int);
58 SMALLINT DS2480ChangeBaud(int,uchar);
59 
60 // global DS2480B state
61 SMALLINT ULevel[MAX_PORTNUM]; // current DS2480B 1-Wire Net level
62 SMALLINT UBaud[MAX_PORTNUM];  // current DS2480B baud rate
63 SMALLINT UMode[MAX_PORTNUM];  // current DS2480B command or data mode state
64 SMALLINT USpeed[MAX_PORTNUM]; // current DS2480B 1-Wire Net communication speed
65 
66 
67 //---------------------------------------------------------------------------
68 // Attempt to resyc and detect a DS2480B
69 //
70 // 'portnum'    - number 0 to MAX_PORTNUM-1.  This number was provided to
71 //                OpenCOM to indicate the port number.
72 //
73 // Returns:  TRUE  - DS2480B detected successfully
74 //           FALSE - Could not detect DS2480B
75 //
DS2480Detect(int portnum)76 SMALLINT DS2480Detect(int portnum)
77 {
78    uchar sendpacket[10],readbuffer[10];
79    uchar sendlen=0;
80 
81    // reset modes
82    UMode[portnum] = MODSEL_COMMAND;
83    UBaud[portnum] = PARMSET_9600;
84    USpeed[portnum] = SPEEDSEL_FLEX;
85 
86    // set the baud rate to 9600
87    SetBaudCOM(portnum,(uchar)UBaud[portnum]);
88 
89    // send a break to reset the DS2480
90    BreakCOM(portnum);
91 
92    // delay to let line settle
93    msDelay(2);
94 
95    // flush the buffers
96    FlushCOM(portnum);
97 
98    // send the timing byte
99    sendpacket[0] = 0xC1;
100    if (WriteCOM(portnum,1,sendpacket) != 1)
101    {
102       OWERROR(OWERROR_WRITECOM_FAILED);
103       return FALSE;
104    }
105 
106    // delay to let line settle
107    msDelay(4);
108 
109    // set the FLEX configuration parameters
110    // default PDSRC = 1.37Vus
111    sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_SLEW | PARMSET_Slew1p37Vus;
112    // default W1LT = 10us
113    sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_WRITE1LOW | PARMSET_Write10us;
114    // default DSO/WORT = 8us
115    sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_SAMPLEOFFSET | PARMSET_SampOff8us;
116 
117    // construct the command to read the baud rate (to test command block)
118    sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_PARMREAD | (PARMSEL_BAUDRATE >> 3);
119 
120    // also do 1 bit operation (to test 1-Wire block)
121    sendpacket[sendlen++] = CMD_COMM | FUNCTSEL_BIT | UBaud[portnum] | BITPOL_ONE;
122 
123    // flush the buffers
124    FlushCOM(portnum);
125 
126    // send the packet
127    if (WriteCOM(portnum,sendlen,sendpacket))
128    {
129       // read back the response
130       if (ReadCOM(portnum,5,readbuffer) == 5)
131       {
132          // look at the baud rate and bit operation
133          // to see if the response makes sense
134          if (((readbuffer[3] & 0xF1) == 0x00) &&
135              ((readbuffer[3] & 0x0E) == UBaud[portnum]) &&
136              ((readbuffer[4] & 0xF0) == 0x90) &&
137              ((readbuffer[4] & 0x0C) == UBaud[portnum]))
138             return TRUE;
139          else
140             OWERROR(OWERROR_DS2480_BAD_RESPONSE);
141       }
142       else
143          OWERROR(OWERROR_READCOM_FAILED);
144    }
145    else
146       OWERROR(OWERROR_WRITECOM_FAILED);
147 
148    return FALSE;
149 }
150 
151 //---------------------------------------------------------------------------
152 // Change the DS2480B from the current baud rate to the new baud rate.
153 //
154 // 'portnum' - number 0 to MAX_PORTNUM-1.  This number was provided to
155 //             OpenCOM to indicate the port number.
156 // 'newbaud' - the new baud rate to change to, defined as:
157 //               PARMSET_9600     0x00
158 //               PARMSET_19200    0x02
159 //               PARMSET_57600    0x04
160 //               PARMSET_115200   0x06
161 //
162 // Returns:  current DS2480B baud rate.
163 //
DS2480ChangeBaud(int portnum,uchar newbaud)164 SMALLINT DS2480ChangeBaud(int portnum, uchar newbaud)
165 {
166    uchar rt=FALSE;
167    uchar readbuffer[5],sendpacket[5],sendpacket2[5];
168    uchar sendlen=0,sendlen2=0;
169 
170    // see if diffenent then current baud rate
171    if (UBaud[portnum] == newbaud)
172       return UBaud[portnum];
173    else
174    {
175       // build the command packet
176       // check if correct mode
177       if (UMode[portnum] != MODSEL_COMMAND)
178       {
179          UMode[portnum] = MODSEL_COMMAND;
180          sendpacket[sendlen++] = MODE_COMMAND;
181       }
182       // build the command
183       sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_BAUDRATE | newbaud;
184 
185       // flush the buffers
186       FlushCOM(portnum);
187 
188       // send the packet
189       if (!WriteCOM(portnum,sendlen,sendpacket))
190       {
191          OWERROR(OWERROR_WRITECOM_FAILED);
192          rt = FALSE;
193       }
194       else
195       {
196          // make sure buffer is flushed
197          msDelay(5);
198 
199          // change our baud rate
200          SetBaudCOM(portnum,newbaud);
201          UBaud[portnum] = newbaud;
202 
203          // wait for things to settle
204          msDelay(5);
205 
206          // build a command packet to read back baud rate
207          sendpacket2[sendlen2++] = CMD_CONFIG | PARMSEL_PARMREAD | (PARMSEL_BAUDRATE >> 3);
208 
209          // flush the buffers
210          FlushCOM(portnum);
211 
212          // send the packet
213          if (WriteCOM(portnum,sendlen2,sendpacket2))
214          {
215             // read back the 1 byte response
216             if (ReadCOM(portnum,1,readbuffer) == 1)
217             {
218                // verify correct baud
219                if (((readbuffer[0] & 0x0E) == (sendpacket[sendlen-1] & 0x0E)))
220                   rt = TRUE;
221                else
222                   OWERROR(OWERROR_DS2480_WRONG_BAUD);
223             }
224             else
225                OWERROR(OWERROR_READCOM_FAILED);
226          }
227          else
228             OWERROR(OWERROR_WRITECOM_FAILED);
229       }
230    }
231 
232    // if lost communication with DS2480 then reset
233    if (rt != TRUE)
234       DS2480Detect(portnum);
235 
236    return UBaud[portnum];
237 }
238