00001 /*************************************************************************** 00002 LOW_link.h - description 00003 ------------------- 00004 begin : Sun Jul 7 2002 00005 copyright : (C) 2002 by Harald Roelle 00006 email : roelle@informatik.uni-muenchen.de 00007 ***************************************************************************/ 00008 00009 /*************************************************************************** 00010 * * 00011 * This program is free software; you can redistribute it and/or modify * 00012 * it under the terms of the GNU General Public License as published by * 00013 * the Free Software Foundation; either version 2 of the License, or * 00014 * (at your option) any later version. * 00015 * * 00016 ***************************************************************************/ 00017 00018 #ifndef LOW_LINK_H 00019 #define LOW_LINK_H 00020 00021 00022 #include <vector> 00023 00024 00025 #include "LOW_types.h" 00026 #include "LOW_exception.h" 00027 #include "LOW_deviceID.h" 00028 #include "LOW_objectIDFactory.h" 00029 00030 00031 00032 /** Abstract base class for 1-Wire link adapters. 00033 00034 Any link class representing a concrete 1-Wire link adapter must inherit from this class. 00035 00036 The class provides some generic implementations relying only on touch*() methods. 00037 Although beeing sufficient for basic functionality, deriving classes are invited to 00038 overload those methods, especially in case the hardware provides a native implementation. 00039 Prominent examples for that: 00040 00041 - LOW_linkDS2480B: doSearchSequence() uses the built-in "search accelerator" 00042 00043 - LOW_linkDS2490: searchDevices() uses the built-in "SearchAccess" command. 00044 00045 This class is thread-safe. 00046 00047 @todo Provide assignment operator and copy constructor 00048 @todo Provide strongPullup method with specialized type 00049 00050 @author Harald Roelle 00051 @author Parts of the documentation by Dallas Semiconductors / Maxim Integrated Products 00052 */ 00053 class LOW_link { 00054 00055 //======================================================================================= 00056 public: 00057 00058 //===================================================================================== 00059 // 00060 // exceptions 00061 // 00062 00063 /** Exception base class for all exceptions thrown by LOW_link. */ 00064 class_DERIVE_FROM_EXCEPTION( link_error, LOW_exception); 00065 00066 /** Exception class to be thrown on communication errors. */ 00067 class_DERIVE_FROM_EXCEPTION( comm_error, link_error); 00068 /** Exception class to be thrown on pure internal errors. */ 00069 class_DERIVE_FROM_EXCEPTION( internal_error, link_error); 00070 /** Exception class to be thrown on errors related to currently selected wire speed. */ 00071 class_DERIVE_FROM_EXCEPTION( illegalSpeed_error, link_error); 00072 /** Exception class to be thrown on errors related to requested voltage level. */ 00073 class_DERIVE_FROM_EXCEPTION( illegalLevel_error, link_error); 00074 /** Exception class to be thrown on access violation errors. */ 00075 class_DERIVE_FROM_EXCEPTION( notAllowed_error, link_error); 00076 class_DERIVE_FROM_EXCEPTION( sizeMismatch_error, link_error); 00077 00078 00079 //===================================================================================== 00080 // 00081 // locks 00082 // 00083 00084 /** Locking class to ensure exclusive access to a link. 00085 00086 The class is intended to be used in a "locking is creation" design pattern. 00087 On creation an exclusive lock is optained for the device, and on destruction 00088 the lock is released. 00089 00090 Uses a recursive mutex, i.e. does not distinguish reads/writes but my be called 00091 multiple times by the same thread without blocking. 00092 00093 Class is inlined for performance reasons. 00094 00095 @see LOW_thread_mutex 00096 */ 00097 class commLock { 00098 public: 00099 /** Obtain the lock. 00100 @param inLink Reference to the link the lock is for. 00101 */ 00102 inline commLock( LOW_link &inLink) : link( inLink) 00103 { 00104 link.__linkRecMutex->lock(); 00105 }; 00106 00107 /** Release the lock. 00108 */ 00109 inline ~commLock() 00110 { 00111 link.__linkRecMutex->unlock(); 00112 }; 00113 00114 private: 00115 LOW_link &link; /**< Reference to the link the lock is for. */ 00116 }; 00117 00118 00119 //===================================================================================== 00120 // 00121 // type definitions 00122 // 00123 00124 typedef std::vector<LOW_link*> linkPtrVec_t; /**< Vector type of link class pointers. */ 00125 00126 typedef LOW_objectIDFactory::objectID_t linkID_t; /**< Type for individual link ID number. */ 00127 00128 /** Type for strong pullup period specification. 00129 Period may vary a little, depending on actual device. */ 00130 typedef enum { pullUp_16_4=0x00, /**< 16 / 16.4 ms */ 00131 pullUp_65_5, /**< 64 / 65.5 ms */ 00132 pullUp_131, /**< 128 / 131 ms */ 00133 pullUp_262, /**< 256 / 262 ms */ 00134 pullUp_524, /**< 512 / 524 ms */ 00135 pullUp_1048, /**< 1024 / 1048 ms */ 00136 pullUp_NONE=0xff /**< no pullup */ 00137 } strongPullup_t; 00138 00139 /** Type for 12V program pulse period specification. 00140 Period may vary a little, depending on actual device. */ 00141 typedef enum { progPulse_32=0x00, /**< 32 microsec */ 00142 progPulse_64, /**< 64 microsec */ 00143 progPulse_128, /**< 128 microsec */ 00144 progPulse_256, /**< 256 microsec */ 00145 progPulse_512, /**< 512 microsec */ 00146 progPulse_1024, /**< 1024 microsec */ 00147 progPulse_2048 /**< 2032 / 2048 microsec */ 00148 } progPulse_t; 00149 00150 00151 //===================================================================================== 00152 // 00153 // constructors 00154 // 00155 00156 /** Destructor. 00157 */ 00158 virtual ~LOW_link(); 00159 00160 00161 //===================================================================================== 00162 // 00163 // operator overloading 00164 // 00165 00166 virtual bool operator==(LOW_link &inLink) const; /**< Comparison based on linkID. */ 00167 00168 00169 //===================================================================================== 00170 /** 00171 @name Bus touch (write/read) methods 00172 */ 00173 //!@{ 00174 00175 /** Send 1 bit of communication to the 1-Wire net and return the 00176 result 1 bit read from the 1-Wire net. 00177 00178 @param inSendBit Bit to send. 00179 @param inPullup Optional strong pullup time following the write/read cycle. 00180 00181 @return Bit that was reveived. 00182 */ 00183 virtual bool touchBit( const bool inSendBit, const strongPullup_t inPullup = pullUp_NONE) = 0; 00184 00185 00186 /** Send 8 bits of communication to the 1-Wire net and return the 00187 result 8 bits read from the 1-Wire net. 00188 00189 @param inSendByte Byte to send. 00190 @param inPullup Optional strong pullup time following the 8 bit write/read cycle. 00191 00192 @return Byte that was reveived. 00193 */ 00194 virtual uint8_t touchByte( const uint8_t inSendByte, const strongPullup_t inPullup = pullUp_NONE) = 0; 00195 00196 00197 /** Send block of communication to the 1-Wire net and return the 00198 resulting bytes read from the 1-Wire net. 00199 00200 A default implementation relying on the touchByte() method is provided. 00201 00202 <B>Note:</B> When the strong pullup is selected it will NOT appear after each byte 00203 sent, only after the last byte the pullup is done! 00204 00205 @param inBytes Byte block to send. 00206 @param inPullup Optional strong pullup time following each 8 bit write/read cycle. 00207 00208 @return Byte block that was reveived. Length is equal to number of sent bytes. 00209 */ 00210 virtual byteVec_t touchBlock( const byteVec_t &inBytes, const strongPullup_t inPullup = pullUp_NONE); 00211 00212 //!@} 00213 00214 00215 //===================================================================================== 00216 /** 00217 @name Bus read methods 00218 */ 00219 //!@{ 00220 00221 /** Receive 1 bit from the 1-Wire net by previously sending one bit of 00222 read communication to the 1-Wire net. 00223 00224 A default implementation relying on the touch methods is provided. 00225 00226 @param inPullup Optional strong pullup time following the write/read cycle. 00227 00228 @return Bit that was reveived. 00229 */ 00230 virtual bool readDataBit( const strongPullup_t inPullup = pullUp_NONE); 00231 00232 00233 /** Receive 1 byte from the 1-Wire net by previously sending 00234 8 bits of read communication to the 1-Wire net. 00235 00236 A default implementation relying on the touch methods is provided. 00237 00238 @param inPullup Optional strong pullup time following the write/read cycle. 00239 00240 @return Byte that was reveived. 00241 */ 00242 virtual uint8_t readDataByte( const strongPullup_t inPullup = pullUp_NONE); 00243 00244 00245 /** Receive a block of bytes from the 1-Wire net by previously sending 00246 a block of bytes of read communication to the 1-Wire Net. 00247 00248 <B>Note:</B> When the strong pullup is selected it will NOT appear after each byte 00249 sent, only after the last byte the pullup is done! 00250 00251 A default implementation relying on the touch methods is provided. 00252 00253 @param outBytes Values that were reveived. Read length is determined 00254 by the preset length of the vector. 00255 @param inPullup Optional strong pullup time following each 8 bit write/read cycle. 00256 */ 00257 virtual void readData( byteVec_t &outBytes, const strongPullup_t inPullup = pullUp_NONE); 00258 00259 //!@} 00260 00261 00262 //===================================================================================== 00263 /** 00264 @name Bus write methods 00265 */ 00266 //!@{ 00267 00268 /** Send 1 bit to the 1-Wire net and verify that the 00269 bit read from the 1-Wire net is the same (bus write operation). 00270 00271 A default implementation relying on the touch methods is provided. 00272 00273 @param inSendBit Bit to send. 00274 @param inPullup Optional strong pullup time following the write/read cycle. 00275 */ 00276 virtual void writeData( const bool inSendBit, const strongPullup_t inPullup = pullUp_NONE); 00277 00278 00279 /** Send 1 byte to the 1-Wire net and verify that the 00280 byte read from the 1-Wire net is the same (bus write operation). 00281 00282 A default implementation relying on the touch methods is provided. 00283 00284 @param inSendByte Byte to send. 00285 @param inPullup Optional strong pullup time following the write/read cycle. 00286 */ 00287 virtual void writeData( const uint8_t inSendByte, const strongPullup_t inPullup = pullUp_NONE); 00288 00289 00290 /** Send block of bytes to the 1-Wire net and verify that the 00291 bytes block read from the 1-Wire net are the same (bus write operation). 00292 00293 A default implementation relying on the touch methods is provided. 00294 00295 <B>Note:</B> When the strong pullup is selected it will NOT appear after each byte 00296 sent, only after the last byte the pullup is done! 00297 00298 @param inSendBytes Block of bytes to send. 00299 @param inPullup Optional strong pullup time following each 8 bit write/read cycle. 00300 */ 00301 virtual void writeData( const byteVec_t &inSendBytes, const strongPullup_t inPullup = pullUp_NONE); 00302 00303 //!@} 00304 00305 00306 //===================================================================================== 00307 /** 00308 @name Higher level actions 00309 */ 00310 //!@{ 00311 00312 /** Execute a complete search sequence from preloaded ID vector. 00313 00314 Search is executed on the currently active bus configuration. No branch selection 00315 is done in advance. 00316 00317 A default implementation relying on the doSearchSequence() method is provided. 00318 00319 @param inOnlyAlarm Select normal search or alarmin only search. 00320 @param inPreload The ID vector to start the search from. 00321 @param inFamCode Narrow search to given family code. To not narrow use LOW_device::anyDev_famCode. 00322 @return List of devices found on the currently active bus configuration. 00323 */ 00324 virtual LOW_deviceID::deviceIDVec_t searchDevices( const bool inOnlyAlarm, const LOW_deviceIDRaw inPreload, 00325 const LOW_deviceIDRaw::devFamCode_t inFamCode, const bool inDoReset); 00326 00327 00328 //!@} 00329 00330 00331 //===================================================================================== 00332 /** 00333 @name Misc methods 00334 */ 00335 //!@{ 00336 00337 /** Get ID of the link. 00338 00339 @return ID of the link. 00340 */ 00341 linkID_t getID() const; 00342 00343 00344 /** Get the link's family type. 00345 <B>Note:</B> Subclasses must implement this method to return a clear text 00346 name of their kind. 00347 @return Family type name of the link. 00348 */ 00349 virtual std::string getLinkFamily() const = 0; 00350 00351 00352 /** Get wether the adapter is capable of 12V Program pulse. 00353 00354 @return Wether the adapter is capable of 12V Program pulse. 00355 */ 00356 bool getHasProgramPulse() const; 00357 00358 00359 /** Get whether there is an external power line on the segment. 00360 00361 @return Whether there is an external power line on the segment. 00362 */ 00363 bool getHasExternalPower() const; 00364 00365 00366 /** Get wether the program pulse should be allowed. 00367 00368 @return Wether the program pulse should be allowed. 00369 */ 00370 bool getAllowProgPulse() const; 00371 00372 00373 /** Reset the adapter. 00374 00375 <B>Note:</B> This does not necessarily include a reset on the 1-Wire net. 00376 Whether this is done or net is left to the concrete implementation. 00377 */ 00378 virtual void resetLinkAdapter() = 0; 00379 00380 00381 /** Reset all of the devices on the 1-Wire net. 00382 00383 @return true: Presense pulse(s) detected, device(s) reset 00384 false: No presense pulses detected 00385 00386 @todo Differentiate simple presence pulse and alarming presence pulse. 00387 */ 00388 virtual bool resetBus() = 0; 00389 00390 00391 /** Set the 1-Wire net line level to strong pullup for a specified time. 00392 00393 <B>Note:</B> Dependening on the implementation, time may only as accurate 00394 as the operating system permits (scheduling!). 00395 00396 @param inMicroSecs Pullup time in micro seconds. 00397 */ 00398 virtual void strongPullup( const unsigned long inMicroSecs) = 0; 00399 00400 00401 /** Set the 1-Wire net line level to strong pullup for a specified time. 00402 00403 <B>Note:</B> Dependening on the implementation, time may only as accurate 00404 as the operating system permits (scheduling!). 00405 00406 @param inPullupTime Pullup time by predefined type. 00407 */ 00408 virtual void strongPullup( const strongPullup_t inPullupTime) = 0; 00409 00410 00411 /** Create a 12 volt pulse on the 1-Wire net for programming EPROM devices. 00412 00413 For EPROM programming, only a single slave device should be connected 00414 to the 1-Wire bus and the cable must be short, not to exceed a few meters. 00415 00416 <B>Note:</B> One should not attempt generating a programming pulse with 00417 a non-EPROM device on the bus; this may damage the device 00418 as well as the link controller. 00419 00420 <B>Note:</B> Dependening on the implementation, time may only as accurate 00421 as the operating system permits (scheduling!). 00422 00423 @param inMicroSecs Pulse time in micro seconds. 00424 */ 00425 virtual void programPulse( const unsigned long inMicroSecs) = 0; 00426 00427 00428 /** Create a 12 volt pulse on the 1-Wire net for programming EPROM devices. 00429 00430 For EPROM programming, only a single slave device should be connected 00431 to the 1-Wire bus and the cable must be short, not to exceed a few meters. 00432 00433 <B>Note:</B> One should not attempt generating a programming pulse with 00434 a non-EPROM device on the bus; this may damage the device 00435 as well as the link controller. 00436 00437 <B>Note:</B> Dependening on the implementation, time may only as accurate 00438 as the operating system permits (scheduling!). 00439 00440 @param inPulseTime Pulse time by predefined type. 00441 */ 00442 virtual void programPulse( const progPulse_t inPulseTime) = 0; 00443 00444 00445 //!@} 00446 00447 00448 00449 //======================================================================================= 00450 protected: 00451 00452 //===================================================================================== 00453 // 00454 // attributes 00455 // 00456 00457 const linkID_t linkID; /**< Individual ID of the link adapter. */ 00458 bool hasProgramPulse; /**< Wether the adapter is capable of 12V Program pulse. */ 00459 const bool hasExternalPower; /**< Wether the attached bus supplies external power. */ 00460 const bool allowProgPulse; /**< Wether the program pulse should be allowed. */ 00461 00462 00463 //===================================================================================== 00464 // 00465 // constructors 00466 // 00467 00468 /** Constructor. 00469 00470 @param inHasProgramPulse Whether the adapter is capable of 12V Program pulse. 00471 @param inHasExternalPower Whether the attached bus supplies external power. 00472 @param inAllowProgPulse Whether the program pulse should be allowed. 00473 */ 00474 LOW_link( const bool inHasProgramPulse, const bool inHasExternalPower, const bool inAllowProgPulse = false); 00475 00476 00477 //===================================================================================== 00478 // 00479 // methods 00480 // 00481 00482 /** Execute a single search sequence on the bus. 00483 00484 A default implementation relying on bit i/o methods is provided. 00485 00486 @param inBranchVector ID vector to start the search sequence. 00487 @param outFoundID Device ID found. 00488 @param outDiscrVec Discrepancy vector after the search. 00489 */ 00490 virtual void doSearchSequence( const LOW_deviceIDRaw &inBranchVector, 00491 LOW_deviceIDRaw &outFoundID, LOW_deviceIDRaw &outDiscrVec); 00492 00493 00494 //======================================================================================= 00495 private: 00496 00497 //===================================================================================== 00498 // 00499 // friends 00500 // 00501 00502 friend class commLock; /**< Needed to access the mutex. */ 00503 00504 00505 //===================================================================================== 00506 // 00507 // attributes 00508 // 00509 00510 LOW_thread_mutex *__linkRecMutex; /**< Mutex for exclusive access. */ 00511 00512 }; 00513 00514 00515 #endif