Main Page | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members | Related Pages

LOW_link.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           LOW_link.cpp  -  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  
00019 #include "LOW_link.h"
00020 #include "LOW_device.h"
00021 
00022 
00023 //=====================================================================================
00024 //
00025 // constructors
00026 //
00027 
00028 LOW_link::LOW_link( const bool inHasProgramPulse, const bool inHasExternalPower, const bool inAllowProgPulse) :
00029   linkID( LOW_objectIDFactory::getNewObjectID()),
00030   hasProgramPulse( inHasProgramPulse),
00031   hasExternalPower( inHasExternalPower),
00032   allowProgPulse( inAllowProgPulse)
00033 {
00034   __linkRecMutex = LOW_thread_Factory::new_mutex( LOW_thread_mutex::mutexKind_recursive);
00035 }
00036 
00037 
00038 LOW_link::~LOW_link()
00039 {
00040   delete __linkRecMutex;
00041 }
00042 
00043 
00044 
00045 //=====================================================================================
00046 //
00047 // operator overloading
00048 //
00049   
00050 bool LOW_link::operator==(LOW_link &inLink) const
00051 {
00052   return (linkID==inLink.linkID);
00053 }
00054 
00055 
00056   
00057 //=====================================================================================
00058 //
00059 // methods
00060 //
00061 
00062 uint32_t LOW_link::getID() const
00063 {
00064   return linkID;
00065 }
00066 
00067 
00068 bool LOW_link::getHasProgramPulse() const
00069 {
00070   return hasProgramPulse;
00071 }
00072 
00073   
00074 bool LOW_link::getHasExternalPower() const
00075 {
00076   return hasExternalPower;
00077 }
00078 
00079 
00080 bool LOW_link::getAllowProgPulse() const
00081 {
00082   return allowProgPulse;
00083 }
00084 
00085 
00086 
00087 //=====================================================================================
00088 //
00089 // Bus touch (write/read) methods
00090 //
00091 
00092 byteVec_t LOW_link::touchBlock( const byteVec_t &inBytes, const strongPullup_t inPullup)
00093 {
00094   if ( inBytes.size() == 0 ) return byteVec_t( 0);
00095 
00096   commLock lock( *this);
00097 
00098   byteVec_t retVal = byteVec_t( inBytes.size());
00099 
00100   for( unsigned int i=0; i<inBytes.size()-1; i++) {
00101     retVal[i] = touchByte( inBytes[i], pullUp_NONE);
00102   }
00103   retVal[inBytes.size()-1] = touchByte( inBytes[inBytes.size()-1], inPullup);
00104   
00105   return retVal;
00106 }
00107 
00108 
00109 //=====================================================================================
00110 //
00111 // read data methods
00112 //
00113 
00114 bool LOW_link::readDataBit( const strongPullup_t inPullup)
00115 {
00116   commLock lock( *this);
00117 
00118   return touchBit( true, inPullup);
00119 }
00120 
00121 
00122 uint8_t LOW_link::readDataByte( const strongPullup_t inPullup)
00123 {
00124   commLock lock( *this);
00125 
00126   return touchByte( 0xff, inPullup);
00127 }
00128 
00129 
00130 void LOW_link::readData( byteVec_t &outBytes, const strongPullup_t inPullup)
00131 {
00132   commLock lock( *this);
00133 
00134   byteVec_t  sendBytes = byteVec_t( outBytes.size(), 0xff);
00135   byteVec_t  recBytes;
00136 
00137   recBytes = touchBlock( sendBytes, inPullup);
00138   std::copy( recBytes.begin(), recBytes.end(), outBytes.begin());
00139 }
00140 
00141 
00142 
00143 //=====================================================================================
00144 //
00145 // write data methods
00146 //
00147 
00148 void LOW_link::writeData( const bool inSendBit, const strongPullup_t inPullup)
00149 {
00150   commLock lock( *this);
00151 
00152   if ( touchBit( inSendBit, inPullup) != inSendBit )
00153     throw comm_error( "Response not equal to sent bit", __FILE__, __LINE__);
00154 }
00155 
00156 
00157 void LOW_link::writeData( const uint8_t inSendByte, const strongPullup_t inPullup)
00158 {
00159   commLock lock( *this);
00160 
00161   if ( touchByte( inSendByte, inPullup) != inSendByte )
00162     throw comm_error( "Response not equal to sent byte", __FILE__, __LINE__);
00163 }
00164 
00165 
00166 void LOW_link::writeData( const byteVec_t &inSendBytes, const strongPullup_t inPullup)
00167 {
00168   commLock lock( *this);
00169 
00170   byteVec_t readVec = touchBlock( inSendBytes, inPullup);
00171 
00172   for( unsigned int i=0; i<inSendBytes.size(); i++)
00173     if ( readVec[i] != inSendBytes[i] ) {
00174       throw comm_error( "Response not equal to sent byte", __FILE__, __LINE__);
00175     }
00176 }
00177 
00178 
00179 
00180 //=====================================================================================
00181 //
00182 // Higher level actions
00183 //
00184 
00185 LOW_deviceID::deviceIDVec_t LOW_link::searchDevices( const bool inOnlyAlarm, const LOW_deviceIDRaw inPreload,
00186                                                      const LOW_deviceIDRaw::devFamCode_t inFamCode, const bool inDoReset)
00187 {
00188   commLock lock( *this);
00189 
00190   LOW_deviceIDRaw                searchVec = LOW_deviceIDRaw( inPreload);
00191   LOW_deviceIDRaw                foundID;
00192   LOW_deviceIDRaw                discrVec;
00193   int                            lastDiscr = 0;
00194   LOW_deviceID::deviceIDVec_t    foundIDVec;
00195 
00196   // preload family type
00197   if ( inFamCode != LOW_device::anyDev_famCode )
00198     searchVec.setFamilyCode( inFamCode);
00199 
00200   while ( true ) {
00201 
00202     if ( resetBus() == false )
00203       return foundIDVec;
00204       //throw LOW_device::noDevice_error( "Reset indicated no devices", __FILE__, __LINE__);
00205 
00206     if ( inOnlyAlarm )
00207       writeData( LOW_device::SearchAlarmROM_COMMAND);
00208     else
00209       writeData( LOW_device::SearchROM_COMMAND);
00210 
00211     doSearchSequence( searchVec, foundID, discrVec);
00212 
00213     if ( foundID.getBit( 63)==true && discrVec.getBit( 63)==true) // no devices found
00214       return foundIDVec;
00215       //throw LOW_device::noDevice_error( "No devices during search found", __FILE__, __LINE__);
00216 
00217     LOW_deviceID newID = LOW_deviceID( foundID);
00218 
00219     if ( inFamCode!=LOW_device::anyDev_famCode && newID.getFamilyCode()!=inFamCode )
00220       break;
00221 
00222     foundIDVec.push_back( newID);
00223 
00224     // find last discrepancy
00225     int newDiscr = 0xff;
00226     for( int a=63 ; a>=0; a--) {
00227       if ( discrVec.getBit( a)==true && foundID.getBit( a)==false) {
00228         newDiscr = a;
00229         break;
00230       }
00231     }
00232 
00233     if ( newDiscr==0xff /*|| newDiscr==lastDiscr*/ ) {  // search has ended
00234       break;
00235     }
00236 
00237     lastDiscr = newDiscr;
00238 
00239     // prepare next search vector
00240     for( int a=0; a<64; a++) {
00241       if ( a<lastDiscr ) {
00242         searchVec.setBit( a, foundID.getBit( a));
00243       }
00244       else if ( a==lastDiscr ) {
00245         searchVec.setBit( a, true);
00246       }
00247       else {
00248         searchVec.setBit( a, false);
00249       }
00250     }
00251 
00252   }
00253 
00254   if ( inDoReset )
00255     if ( resetBus() == false )
00256       throw LOW_device::noDevice_error( "Reset indicated no devices", __FILE__, __LINE__);
00257 
00258   return foundIDVec;
00259 }
00260 
00261 
00262 //=====================================================================================
00263 //
00264 // methods
00265 //
00266 
00267 void LOW_link::doSearchSequence( const LOW_deviceIDRaw &inBranchVector, 
00268                                  LOW_deviceIDRaw &outFoundID, LOW_deviceIDRaw &outDiscrVec)
00269 {
00270   commLock lock( *this);
00271   
00272   for( int a=0; a<64; a++) {
00273     
00274     bool readB = readDataBit();
00275     bool cmplB = readDataBit();
00276   
00277     if ( readB == cmplB ) {
00278       writeData( inBranchVector.getBit( a));
00279       outFoundID.setBit( a, inBranchVector.getBit( a));
00280       outDiscrVec.setBit( a, true);
00281     }
00282     else {
00283       writeData( readB);
00284       outFoundID.setBit( a, readB);
00285       outDiscrVec.setBit( a, false);
00286     }
00287     
00288   }
00289 }

Generated on Tue Feb 3 11:30:25 2004 for OneWireLibrary++ by doxygen 1.3.2