1 //---------------------------------------------------------------------------
\r
2 // Copyright (C) 2004 Dallas Semiconductor MAXIM Corporation, All Rights Reserved.
\r
4 // Permission is hereby granted, free of charge, to any person obtaining a
\r
5 // copy of this software and associated documentation files (the "Software"),
\r
6 // to deal in the Software without restriction, including without limitation
\r
7 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
\r
8 // and/or sell copies of the Software, and to permit persons to whom the
\r
9 // Software is furnished to do so, subject to the following conditions:
\r
11 // The above copyright notice and this permission notice shall be included
\r
12 // in all copies or substantial portions of the Software.
\r
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
\r
15 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
\r
16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
\r
17 // IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES
\r
18 // OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
\r
19 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
\r
20 // OTHER DEALINGS IN THE SOFTWARE.
\r
22 // Except as contained in this notice, the name of Dallas Semiconductor MAXIM
\r
23 // shall not be used except as stated in the Dallas Semiconductor MAXIM
\r
25 //---------------------------------------------------------------------------
\r
27 // libusblds2490.c - DS2490 utility functions for Windows.
\r
28 // (Requires libusb http://libusb.sourceforge.net
\r
29 // or http://libusb-win32.sourceforge.net)
\r
34 //#include "ownet.h"
\r
35 #include "libusbds2490.h"
\r
41 #define OWERROR_ADAPTER_ERROR 110
\r
42 #define OWERROR(err) printf("%i",err);
\r
44 #define MAX_PORTNUM 20
\r
45 // handles for the USB ports
\r
46 extern struct usb_dev_handle *usb_dev_handle_list[MAX_PORTNUM];
\r
48 // global DS2490 state
\r
49 SMALLINT USBLevel[MAX_PORTNUM];
\r
50 SMALLINT USBSpeed[MAX_PORTNUM];
\r
51 SMALLINT USBVersion[MAX_PORTNUM];
\r
52 SMALLINT USBVpp[MAX_PORTNUM];
\r
54 long msGettick(void)
\r
56 #if USE_WINDOWS_TIME
\r
57 return GetTickCount();
\r
59 struct timezone tmzone;
\r
60 struct timeval tmval;
\r
63 gettimeofday(&tmval,&tmzone);
\r
64 ms = (tmval.tv_sec & 0xFFFF) * 1000 + tmval.tv_usec / 1000;
\r
69 //---------------------------------------------------------------------------
\r
70 // Attempt to resync and detect a DS2490
\r
72 // 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
\r
73 // OpenCOM to indicate the port number.
\r
75 // Returns: TRUE - DS2490 detected successfully
\r
76 // FALSE - Could not detect DS2490
\r
78 SMALLINT DS2490Detect(usb_dev_handle *hDevice)
\r
80 SMALLINT present,vpp;
\r
84 //printf("DS2490Detect\n");
\r
85 DS2490Reset(hDevice);
\r
87 // set the strong pullup duration to infinite
\r
88 setup.RequestTypeReservedBits = 0x40;
\r
89 setup.Request = COMM_CMD;
\r
90 setup.Value = COMM_SET_DURATION | COMM_IM;
\r
91 setup.Index = 0x0000;
\r
93 setup.DataOut = FALSE;
\r
94 // call the libusb driver
\r
95 /*ret =*/ usb_control_msg(hDevice,
\r
96 setup.RequestTypeReservedBits,
\r
104 // set the 12V pullup duration to 512us
\r
105 setup.RequestTypeReservedBits = 0x40;
\r
106 setup.Request = COMM_CMD;
\r
107 setup.Value = COMM_SET_DURATION | COMM_IM | COMM_TYPE;
\r
108 setup.Index = 0x0040;
\r
110 setup.DataOut = FALSE;
\r
111 // call the libusb driver
\r
112 /* ret = */usb_control_msg(hDevice,
\r
113 setup.RequestTypeReservedBits,
\r
121 // disable strong pullup, but leave program pulse enabled (faster)
\r
122 setup.RequestTypeReservedBits = 0x40;
\r
123 setup.Request = MODE_CMD;
\r
124 setup.Value = MOD_PULSE_EN;
\r
125 setup.Index = ENABLEPULSE_PRGE;
\r
126 setup.Length = 0x00;
\r
127 setup.DataOut = FALSE;
\r
128 // call the libusb driver
\r
129 /*ret = */usb_control_msg(hDevice,
\r
130 setup.RequestTypeReservedBits,
\r
138 // return result of short check
\r
139 return DS2490ShortCheck(hDevice,&present,&vpp);
\r
143 //---------------------------------------------------------------------------
\r
144 // Check to see if there is a short on the 1-Wire bus. Used to stop
\r
145 // communication with the DS2490 while the short is in effect to not
\r
146 // overrun the buffers.
\r
148 // '*present' - flag set (1) if device presence detected
\r
149 // '*vpp' - flag set (1) if Vpp programming voltage detected
\r
151 // Returns: TRUE - DS2490 1-Wire is NOT shorted
\r
152 // FALSE - Could not detect DS2490 or 1-Wire shorted
\r
154 SMALLINT DS2490ShortCheck(usb_dev_handle *hDevice, SMALLINT *present, SMALLINT *vpp)
\r
156 STATUS_PACKET status;
\r
157 uchar nResultRegisters;
\r
160 // get the result registers (if any)
\r
161 if (!DS2490GetStatus(hDevice, &status, &nResultRegisters))
\r
164 // get vpp present flag
\r
165 *vpp = ((status.StatusFlags & STATUSFLAGS_12VP) != 0);
\r
168 if(status.CommBufferStatus != 0)
\r
175 for (i = 0; i < nResultRegisters; i++)
\r
177 // check for SH bit (0x02), ignore 0xA5
\r
178 if (status.CommResultCodes[i] & COMMCMDERRORRESULT_SH)
\r
186 // check for No 1-Wire device condition
\r
188 // loop through result registers
\r
189 for (i = 0; i < nResultRegisters; i++)
\r
191 // only check for error conditions when the condition is not a ONEWIREDEVICEDETECT
\r
192 if (status.CommResultCodes[i] != ONEWIREDEVICEDETECT)
\r
194 // check for NRS bit (0x01)
\r
195 if (status.CommResultCodes[i] & COMMCMDERRORRESULT_NRS)
\r
197 // empty bus detected
\r
207 //---------------------------------------------------------------------------
\r
208 // Stop any on-going pulses
\r
210 // Returns: TRUE - pulse stopped
\r
211 // FALSE - Could not stop pulse
\r
213 SMALLINT DS2490HaltPulse(usb_dev_handle *hDevice)
\r
215 STATUS_PACKET status;
\r
216 uchar nResultRegisters;
\r
217 SETUP_PACKET setup;
\r
222 // set a time limit
\r
223 limit = msGettick() + 300;
\r
224 // loop until confirm pulse has ended or timeout
\r
227 // HalExecWhenIdle, Resume Execution to stop an infinite pulse
\r
230 setup.RequestTypeReservedBits = 0x40;
\r
231 setup.Request = CONTROL_CMD;
\r
232 setup.Value = CTL_HALT_EXE_IDLE;
\r
233 setup.Index = 0x00;
\r
234 setup.Length = 0x00;
\r
235 setup.DataOut = FALSE;
\r
237 // call the libusb driver
\r
238 ret = usb_control_msg(hDevice,
\r
239 setup.RequestTypeReservedBits,
\r
253 // Resume Execution
\r
254 setup.RequestTypeReservedBits = 0x40;
\r
255 setup.Request = CONTROL_CMD;
\r
256 setup.Value = CTL_RESUME_EXE;
\r
257 setup.Index = 0x00;
\r
258 setup.Length = 0x00;
\r
259 setup.DataOut = FALSE;
\r
261 // call the libusb driver
\r
262 ret = usb_control_msg(hDevice,
\r
263 setup.RequestTypeReservedBits,
\r
277 // read the status to see if the pulse has been stopped
\r
278 if (!DS2490GetStatus(hDevice, &status, &nResultRegisters))
\r
285 // check the SPU flag
\r
286 if ((status.StatusFlags & STATUSFLAGS_SPUA) == 0)
\r
289 // disable both pulse types
\r
290 setup.RequestTypeReservedBits = 0x40;
\r
291 setup.Request = MODE_CMD;
\r
292 setup.Value = MOD_PULSE_EN;
\r
294 setup.Length = 0x00;
\r
295 setup.DataOut = FALSE;
\r
296 // call the libusb driver
\r
297 ret = usb_control_msg(hDevice,
\r
298 setup.RequestTypeReservedBits,
\r
310 while (limit > msGettick());
\r
315 //---------------------------------------------------------------------------
\r
316 // Description: Gets the status of the DS2490 device
\r
317 // Input: hDevice - the handle to the DS2490 device
\r
318 // pStatus - the Status Packet to be filled with data
\r
319 // pResultSize - the number of result register codes returned
\r
321 // Returns: FALSE on failure, TRUE on success
\r
323 SMALLINT DS2490GetStatus(usb_dev_handle *hDevice, STATUS_PACKET *status, uchar *pResultSize)
\r
325 // buffer to retrieve status
\r
328 SMALLINT bufferlength = 0;
\r
330 // initialize buffer
\r
331 memset(&buffer[0],0x00,32);
\r
332 // get status buffer
\r
333 bufferlength = usb_bulk_read(hDevice,DS2490_EP1,&buffer[0],32,TIMEOUT_LIBUSB);
\r
335 if (bufferlength < 0)
\r
337 OWERROR(OWERROR_ADAPTER_ERROR);
\r
341 // make status packet from return buffer
\r
342 status->EnableFlags = buffer[0];
\r
343 status->OneWireSpeed = buffer[1];
\r
344 status->StrongPullUpDuration = buffer[2];
\r
345 status->ProgPulseDuration = buffer[3];
\r
346 status->PullDownSlewRate = buffer[4];
\r
347 status->Write1LowTime = buffer[5];
\r
348 status->DSOW0RecoveryTime = buffer[6];
\r
349 status->Reserved1 = buffer[7];
\r
350 status->StatusFlags = buffer[8];
\r
351 status->CurrentCommCmd1 = buffer[9];
\r
352 status->CurrentCommCmd2 = buffer[10];
\r
353 status->CommBufferStatus = buffer[11];
\r
354 status->WriteBufferStatus = buffer[12];
\r
355 status->ReadBufferStatus = buffer[13];
\r
356 status->Reserved2 = buffer[14];
\r
357 status->Reserved3 = buffer[15];
\r
359 // take care for CommResultCodes (if they exist)
\r
360 if (bufferlength > 15)
\r
362 for (i=0; i<16; i++)
\r
364 status->CommResultCodes[i] = buffer[16 + i];
\r
366 *pResultSize = bufferlength - 16; // This should be the size of CommResultCodes...
\r
376 //---------------------------------------------------------------------------
\r
377 // Description: Perfroms a hardware reset of the DS2490 equivalent to a
\r
379 // Input: hDevice - the handle to the DS2490 device
\r
380 // Returns: FALSE on failure, TRUE on success
\r
381 // Error Codes: DS2490COMM_ERR_USBDEVICE
\r
383 SMALLINT DS2490Reset(usb_dev_handle *hDevice)
\r
385 SETUP_PACKET setup;
\r
389 setup.RequestTypeReservedBits = 0x40;
\r
390 setup.Request = CONTROL_CMD;
\r
391 setup.Value = CTL_RESET_DEVICE;
\r
392 setup.Index = 0x00;
\r
393 setup.Length = 0x00;
\r
394 setup.DataOut = FALSE;
\r
395 // call the libusb driver
\r
396 ret = usb_control_msg(hDevice,
\r
397 setup.RequestTypeReservedBits,
\r
406 OWERROR(OWERROR_ADAPTER_ERROR);
\r
413 //---------------------------------------------------------------------------
\r
414 // Description: Reads data from EP3
\r
415 // Input: hDevice - the handle to the DS2490 device
\r
416 // buffer - the size must be >= nBytes
\r
417 // pnBytes - the number of bytes to read from the device
\r
418 // Returns: FALSE on failure, TRUE on success
\r
420 SMALLINT DS2490Read(usb_dev_handle *hDevice, uchar *buffer, ushort *pnBytes)
\r
423 // Synchronous read:
\r
424 SMALLINT numOfBytesToRead = *pnBytes;
\r
428 nBytes = usb_bulk_read(hDevice, // handle
\r
429 DS2490_EP3, // which endpoint to read from
\r
430 buffer, // buffer to contain read results
\r
431 numOfBytesToRead, // number of bytes to read
\r
432 TIMEOUT_LIBUSB); // libusb timeout
\r
436 OWERROR(OWERROR_ADAPTER_ERROR);
\r
439 *pnBytes = (ushort)nBytes;
\r
443 //---------------------------------------------------------------------------
\r
444 // Description: Writes data to EP2
\r
445 // Input: hDevice - the handle to the DS2490 device
\r
446 // buffer - the size must be >= nBytes
\r
447 // pnBytes - the number of bytes to write to the device
\r
448 // Returns: FALSE on failure, TRUE on success
\r
450 SMALLINT DS2490Write(usb_dev_handle *hDevice, uchar *buffer, ushort *pnBytes)
\r
452 // Synchronous write:
\r
453 // assume enough room for write
\r
455 int numOfBytesToRead = *pnBytes;
\r
458 nBytes = usb_bulk_write(hDevice, // handle
\r
459 DS2490_EP2, // which endpoint to write
\r
460 buffer, // buffer to write to endpoint
\r
461 numOfBytesToRead, // number of bytes to write
\r
462 TIMEOUT_LIBUSB); // libusb timeout
\r
466 OWERROR(OWERROR_ADAPTER_ERROR);
\r
470 *pnBytes = (ushort)nBytes;
\r