00001 /*************************************************************************** 00002 LOW_link.h - description 00003 ------------------- 00004 begin : Sun Jul 7 2002 00005 copyright : (C) 2002 by Harald Roelle, Helmut Reiser 00006 email : roelle@informatik.uni-muenchen.de, reiser@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 "LOW_types.h" 00023 #include "LOW_deviceIDRaw.h" 00024 #include "LOW_exception.h" 00025 #include "LOW_semaphoreSet.h" 00026 #include "LOW_platformMisc.h" 00027 #include "LOW_IPCKeyGenerator.h" 00028 00029 00030 00031 /** Abstract base class for 1-Wire link adapters. 00032 00033 Any link class representing a concrete 1-Wire link adapter must inherit from this class. 00034 00035 @author Harald Roelle, Helmut Reiser 00036 */ 00037 class LOW_link { 00038 00039 //======================================================================================= 00040 public: 00041 00042 //===================================================================================== 00043 // 00044 // exceptions 00045 // 00046 00047 /** Exception base class for all exceptions thrown by LOW_link. */ 00048 class_DERIVE_FROM_EXCEPTION( link_error, LOW_exception); 00049 00050 class_DERIVE_FROM_EXCEPTION( comm_error, link_error); 00051 class_DERIVE_FROM_EXCEPTION( internal_error, link_error); 00052 class_DERIVE_FROM_EXCEPTION( illegalSpeed_error, link_error); 00053 class_DERIVE_FROM_EXCEPTION( illegalLevel_error, link_error); 00054 class_DERIVE_FROM_EXCEPTION( notAllowed_error, link_error); 00055 class_DERIVE_FROM_EXCEPTION( sizeMismatch_error, link_error); 00056 00057 00058 //===================================================================================== 00059 // 00060 // locks 00061 // 00062 00063 /** Locking class to ensure exclusive access to a link. 00064 00065 The class is intended to be used in a "locking is creation" design pattern. 00066 On creation an exclusive lock is optained for the device, and on destruction 00067 the lock is released. 00068 */ 00069 class commLock { 00070 public: 00071 /** Obtain the lock. 00072 00073 @param inLink Reference to the link the lock is for. 00074 */ 00075 commLock( LOW_link &inLink); 00076 00077 /** Release the lock. 00078 @throw internal_error Thrown on illegal lock state (should not happen). 00079 */ 00080 ~commLock(); 00081 00082 private: 00083 LOW_link &link; /**< Reference to the link the lock is for. */ 00084 }; 00085 00086 00087 //===================================================================================== 00088 // 00089 // type definitions 00090 // 00091 00092 /** Vector type of link class pointers. */ 00093 typedef std::vector<LOW_link*> linkPtrVec_t; 00094 00095 /** Type for individual link ID number. */ 00096 typedef uint32_t linkID_t; 00097 00098 /** Type for strong pullup period specification. */ 00099 typedef enum { pullUp_16_4=0x00, /**< 16.4 ms */ 00100 pullUp_65_5, /**< 65.5 ms */ 00101 pullUp_131, /**< 131 ms */ 00102 pullUp_262, /**< 262 ms */ 00103 pullUp_524, /**< 524 ms */ 00104 pullUp_1048, /**< 1048 ms */ 00105 pullUp_NONE=0xff /**< no pullup */ 00106 } strongPullup_t; 00107 00108 00109 //===================================================================================== 00110 // 00111 // constructors 00112 // 00113 00114 /** Destructor. 00115 */ 00116 virtual ~LOW_link(); 00117 00118 00119 //===================================================================================== 00120 // 00121 // operator overloading 00122 // 00123 00124 bool operator==(LOW_link &inLink) const; /**< Comparison based on linkID. */ 00125 00126 00127 //===================================================================================== 00128 /** 00129 @name Bus touch (write/read) methods 00130 */ 00131 //!@{ 00132 00133 /** Send 1 bit of communication to the 1-Wire net and return the 00134 result 1 bit read from the 1-Wire net. 00135 00136 @param inSendBit Bit to send. 00137 @param inPullup Optional strong pullup time following the write/read cycle. 00138 00139 @return Bit that was reveived. 00140 */ 00141 virtual bool touchBit( const bool inSendBit, const strongPullup_t inPullup = pullUp_NONE) = 0; 00142 00143 00144 /** Send 8 bits of communication to the 1-Wire net and return the 00145 result 8 bits read from the 1-Wire net. 00146 00147 @param inSendByte Byte to send. 00148 @param inPullup Optional strong pullup time following the 8 bit write/read cycle. 00149 00150 @return Byte that was reveived. 00151 */ 00152 virtual uint8_t touchByte( const uint8_t inSendByte, const strongPullup_t inPullup = pullUp_NONE) = 0; 00153 00154 00155 /** Send block of communication to the 1-Wire net and return the 00156 resulting bytes read from the 1-Wire net. 00157 00158 <B>Note:</B>: When the strong pullup is selected it will appear after each byte 00159 sent and NOT only after the last byte. 00160 00161 @param inBytes Byte block to send. 00162 @param inPullup Optional strong pullup time following each 8 bit write/read cycle. 00163 00164 @return Byte block that was reveived. Length is equal to number of sent bytes. 00165 */ 00166 virtual byteVec_t touchBlock( const byteVec_t &inBytes, const strongPullup_t inPullup = pullUp_NONE) = 0; 00167 00168 //!@} 00169 00170 00171 //===================================================================================== 00172 /** 00173 @name Bus read methods 00174 */ 00175 //!@{ 00176 00177 /** Receive 1 bit from the 1-Wire net by previously sending one bit of 00178 read communication to the 1-Wire net. 00179 00180 @param inPullup Optional strong pullup time following the write/read cycle. 00181 00182 @return Bit that was reveived. 00183 */ 00184 virtual bool readDataBit( const strongPullup_t inPullup = pullUp_NONE) = 0; 00185 00186 00187 /** Receive 1 byte from the 1-Wire net by previously sending 00188 8 bits of read communication to the 1-Wire net. 00189 00190 @param inPullup Optional strong pullup time following the write/read cycle. 00191 00192 @return Byte that was reveived. 00193 */ 00194 virtual uint8_t readDataByte( const strongPullup_t inPullup = pullUp_NONE) = 0; 00195 00196 00197 /** Receive a block of bytes from the 1-Wire net by previously sending 00198 a block of bytes of read communication to the 1-Wire Net. 00199 00200 <B>Note:</B> When the strong pullup is selected it will appear after each byte 00201 sent and NOT only after the last byte. 00202 00203 @param outBytes Values that were reveived. Read length is determined 00204 by the preset length of the vector. 00205 00206 @param inPullup Optional strong pullup time following each 8 bit write/read cycle. 00207 */ 00208 virtual void readData( byteVec_t &outBytes, const strongPullup_t inPullup = pullUp_NONE) = 0; 00209 00210 //!@} 00211 00212 00213 //===================================================================================== 00214 /** 00215 @name Bus write methods 00216 */ 00217 //!@{ 00218 00219 /** Send 1 bit to the 1-Wire net and verify that the 00220 bit read from the 1-Wire net is the same (bus write operation). 00221 00222 @param inSendBit Bit to send. 00223 @param inPullup Optional strong pullup time following the write/read cycle. 00224 */ 00225 virtual void writeData( const bool inSendBit, const strongPullup_t inPullup = pullUp_NONE) = 0; 00226 00227 00228 /** Send 1 byte to the 1-Wire net and verify that the 00229 byte read from the 1-Wire net is the same (bus write operation). 00230 00231 @param inSendByte Byte to send. 00232 @param inPullup Optional strong pullup time following the write/read cycle. 00233 */ 00234 virtual void writeData( const uint8_t inSendByte, const strongPullup_t inPullup = pullUp_NONE) = 0; 00235 00236 00237 /** Send block of bytes to the 1-Wire net and verify that the 00238 bytes block read from the 1-Wire net are the same (bus write operation). 00239 00240 <B>Note:</B>: When the strong pullup is selected it will appear after each byte 00241 sent and NOT only after the last byte. 00242 00243 @param inSendBytes Block of bytes to send. 00244 @param inPullup Optional strong pullup time following each 8 bit write/read cycle. 00245 */ 00246 virtual void writeData( const byteVec_t &inSendBytes, const strongPullup_t inPullup = pullUp_NONE) = 0; 00247 00248 //!@} 00249 00250 00251 //===================================================================================== 00252 /** 00253 @name Misc methods 00254 */ 00255 //!@{ 00256 00257 /** Get ID of the link. 00258 00259 @return ID of the link. 00260 */ 00261 linkID_t getID() const; 00262 00263 00264 /** Get whether there is an external power line on the segment. 00265 00266 @return Whether there is an external power line on the segment. 00267 */ 00268 bool getHasExternalPower() const; 00269 00270 00271 /** Reset the adapter. 00272 00273 <B>Note:</B> This does not necessarily include a reset on the 1-Wire net. 00274 Whether this is done or net is left to the concrete implementation. 00275 */ 00276 virtual void resetLinkAdapter() = 0; 00277 00278 00279 /** Reset all of the devices on the 1-Wire net. 00280 00281 @return true: Presense pulse(s) detected, device(s) reset 00282 false: No presense pulses detected 00283 */ 00284 virtual bool resetBus() = 0; 00285 00286 00287 /** Set the 1-Wire net line level to strong pullup for a specified time. 00288 00289 @param inMicroSecs Pullup time in micro seconds. 00290 */ 00291 virtual void strongPullup( const unsigned long inMicroSecs) = 0; 00292 00293 00294 /** Create a fixed 480 microseconds 12 volt pulse on the 1-Wire net 00295 for programming EPROM devices. 00296 00297 For EPROM programming, only a single slave device should be connected 00298 to the 1-Wire bus and the cable must be short, not to exceed a few meters. 00299 00300 <B>Note:</B> One should not attempt generating a programming pulse with 00301 a non-EPROM device on the bus; this may damage the device 00302 as well as the link controller. 00303 00304 */ 00305 virtual void programPulse() = 0; 00306 00307 00308 /** Discover devices on the bus. 00309 00310 @param inBranchVector 00311 @param outFoundID 00312 @param outDiscrVec 00313 */ 00314 virtual void doSearchSequence( const LOW_deviceIDRaw &inBranchVector, 00315 LOW_deviceIDRaw &outFoundID, LOW_deviceIDRaw &outDiscrVec) = 0; 00316 00317 //!@} 00318 00319 00320 00321 //======================================================================================= 00322 protected: 00323 00324 //===================================================================================== 00325 // 00326 // static attributes 00327 // 00328 00329 static linkID_t linkCounter; /**< Incremented on instance creation to get individual IDs. */ 00330 00331 00332 //===================================================================================== 00333 // 00334 // type definitions 00335 // 00336 00337 /** Semaphore numbers for semaphore set. */ 00338 typedef enum { 00339 counterSemNo = 0, 00340 lockSemNo, 00341 semaphoreCount // MUST ALWAYS be the last! 00342 } semNum_t; 00343 00344 00345 //===================================================================================== 00346 // 00347 // attributes 00348 // 00349 00350 const linkID_t linkID; /**< Individual ID of the link adapter. */ 00351 bool hasProgramPulse; /**< Wether the adapter is capable of 12V Program pulse. */ 00352 const bool hasOverDrive; /**< Wether the adapter is capable of overdrive bus speed. */ 00353 const bool hasExternalPower; /**< Wether the attached bus supplies external power. */ 00354 const bool allowProgPulse; /**< Wether the program pulse should be allowed. */ 00355 LOW_semaphoreSet *semSet; /**< Semaphore set for locking. */ 00356 00357 00358 //===================================================================================== 00359 // 00360 // constructors 00361 // 00362 00363 /** Constructor. 00364 00365 @param inHasProgramPulse Wether the adapter is capable of 12V Program pulse. 00366 @param inHasOverDrive Wether the adapter is capable of overdrive bus speed. 00367 @param inHasExternalPower Wether the attached bus supplies external power. 00368 @param inAllowProgPulse Wether the program pulse should be allowed. 00369 */ 00370 LOW_link( const bool inHasProgramPulse, const bool inHasOverDrive, 00371 const bool inHasExternalPower, const bool inAllowProgPulse = false); 00372 00373 00374 //======================================================================================= 00375 private: 00376 00377 //===================================================================================== 00378 // 00379 // type definitions 00380 // 00381 00382 friend class commLock; /**< Needed to access the semaphore set. */ 00383 00384 00385 //===================================================================================== 00386 // 00387 // attributes 00388 // 00389 00390 unsigned int aquireCount; /**< Counters how often a lock was aquired. */ 00391 LOW_platformMiscFactory::threadIdent_t aquirePID; /**< Process which ows the lock. */ 00392 00393 }; 00394 00395 00396 #endif