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

LOW_linkPassiveSerial.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           LOW_linkPassiveSerial.cpp  -  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 
00019 #include <string>
00020 #include <memory>
00021 
00022 
00023 #include "LOW_linkPassiveSerial.h"
00024 
00025 #include "LOW_platformMisc.h"
00026 #include "LOW_IPCKeyGeneratorFactory.h"
00027 #include "LOW_semaphoreSetFactory.h"
00028 
00029 
00030 
00031 //=====================================================================================
00032 //
00033 // constructors
00034 //
00035 
00036 LOW_linkPassiveSerial::LOW_linkPassiveSerial( const LOW_portSerialFactory::portSpecifier_t &inSerPortSpec,
00037                                               const bool inAllowProgPulse) :
00038   LOW_link( false, false, false, inAllowProgPulse)
00039 {
00040   serialPort   = LOW_portSerialFactory::new_portSerial( inSerPortSpec);
00041 
00042   auto_ptr<LOW_IPCKeyGenerator> keyGenerator (LOW_IPCKeyGeneratorFactory::new_IPCKeyGenerator());
00043 
00044   semSet       = LOW_semaphoreSetFactory::new_semaphoreSet( keyGenerator->getSemSetKey( inSerPortSpec), semaphoreCount, 1);
00045   
00046   resetLinkAdapter();
00047   resetBus(); // to detect a missing adapter
00048 }
00049 
00050   
00051 
00052 LOW_linkPassiveSerial::~LOW_linkPassiveSerial()
00053 {
00054   serialPort->tty_flush();
00055 
00056   delete semSet;
00057   delete serialPort;
00058 }
00059 
00060 
00061 
00062 //=====================================================================================
00063 //
00064 // touch data methods
00065 //
00066 
00067 bool LOW_linkPassiveSerial::touchBit( const bool inSendBit, const strongPullup_t inPullup)
00068 {
00069   commLock lock( *this);
00070   
00071   uint8_t         serSendByte;
00072   bool            retVal;
00073 
00074   serialPort->tty_flush();
00075 
00076   // get bit ready to be sent
00077   serSendByte = inSendBit ? 0xFF : 0x00;
00078 
00079   // Send the bit
00080   serialPort->tty_write( serSendByte);
00081 
00082   uint8_t tmpByte = serialPort->tty_readByte();        
00083   if ( tmpByte & 0x01 )
00084     retVal = true;
00085   else
00086     retVal = false;
00087   
00088   strongPullup( inPullup);
00089   
00090   return retVal;
00091 }  
00092     
00093 
00094 uint8_t LOW_linkPassiveSerial::touchByte( const uint8_t inSendByte, const strongPullup_t inPullup)
00095 {
00096   commLock lock( *this);
00097   
00098   uint8_t  mask    = 0x01;
00099   uint8_t  retVal  = 0x00;
00100   
00101   for( int a=0; a<8; a++) {
00102     retVal |= touchBit( inSendByte & mask) ? mask : 0x00;
00103     mask <<= 1;
00104   }
00105   
00106   strongPullup( inPullup);
00107   
00108   return retVal;
00109 }
00110 
00111   
00112 byteVec_t LOW_linkPassiveSerial::touchBlock( const byteVec_t &inBytes, const strongPullup_t inPullup)
00113 {
00114   commLock lock( *this);
00115   
00116   byteVec_t retVal = byteVec_t( inBytes.size());
00117   
00118   for( unsigned int i=0; i<inBytes.size(); i++) {
00119     retVal[i] = touchByte( inBytes[i], inPullup);
00120   }
00121   
00122   return retVal;
00123 }
00124 
00125 
00126 //=====================================================================================
00127 //
00128 // read data methods
00129 //
00130   
00131 bool LOW_linkPassiveSerial::readDataBit( const strongPullup_t inPullup)
00132 {
00133   commLock lock( *this);
00134   
00135   return touchBit( true, inPullup);
00136 }
00137 
00138     
00139 uint8_t LOW_linkPassiveSerial::readDataByte( const strongPullup_t inPullup)
00140 {
00141   commLock lock( *this);
00142   
00143   return touchByte( 0xff, inPullup);
00144 }
00145 
00146     
00147 void LOW_linkPassiveSerial::readData( byteVec_t &outBytes, const strongPullup_t inPullup)
00148 {
00149   commLock lock( *this);
00150   
00151   for( unsigned int i=0; i<outBytes.size(); i++)
00152     outBytes[i] = readDataByte( inPullup);
00153 }
00154     
00155 
00156 //=====================================================================================
00157 //
00158 // write data methods
00159 //
00160 
00161 void LOW_linkPassiveSerial::writeData( const bool inSendBit, const strongPullup_t inPullup)
00162 {
00163   commLock lock( *this);
00164   
00165   if ( touchBit( inSendBit, inPullup) != inSendBit )
00166     throw comm_error( "Response not equal to sent bit", __FILE__, __LINE__);
00167 }
00168 
00169 
00170 void LOW_linkPassiveSerial::writeData( const uint8_t inSendByte, const strongPullup_t inPullup)
00171 {
00172   commLock lock( *this);
00173   
00174   if ( touchByte( inSendByte, inPullup) != inSendByte )
00175     throw comm_error( "Response not equal to sent byte", __FILE__, __LINE__);
00176 }
00177 
00178 
00179 void LOW_linkPassiveSerial::writeData( const byteVec_t &inSendBytes, const strongPullup_t inPullup)
00180 {
00181   commLock lock( *this);
00182   
00183   byteVec_t readVec = touchBlock( inSendBytes, inPullup);
00184   
00185   for( unsigned int i=0; i<inSendBytes.size(); i++)
00186     if ( readVec[i] != inSendBytes[i] )
00187       throw comm_error( "Response not equal to sent byte", __FILE__, __LINE__);
00188 }
00189 
00190 
00191 //=====================================================================================
00192 //
00193 // misc methods
00194 //
00195 
00196 void LOW_linkPassiveSerial::resetLinkAdapter()
00197 {
00198   commLock lock( *this);
00199   
00200   serialPort->tty_configure( LOW_portSerial::none_flowControl, LOW_portSerial::bit6_size, 
00201                              LOW_portSerial::no_parity, LOW_portSerial::bit1_stopBit, LOW_portSerial::B115200_speed);
00202   
00203   serialPort->tty_flush();
00204 }
00205 
00206     
00207 bool LOW_linkPassiveSerial::resetBus()
00208 {
00209   commLock lock( *this);
00210   
00211   const uint8_t   resetSendByte = 0xF0;
00212   
00213   bool            devFound = false;
00214     
00215   try {
00216     
00217     // Flush the input and output buffers
00218     serialPort->tty_flush();
00219     
00220     serialPort->tty_configure( LOW_portSerial::none_flowControl, LOW_portSerial::bit8_size, 
00221                                LOW_portSerial::no_parity, LOW_portSerial::bit1_stopBit, LOW_portSerial::B10472_speed);
00222     
00223     // Send the reset pulse
00224     serialPort->tty_write( resetSendByte);
00225 
00226     uint8_t tmpByte = serialPort->tty_readByte();
00227 
00228     if( tmpByte == 0 )  // if answer is still zero, then it is a short to ground
00229       throw comm_error( "Possible short to ground detected", __FILE__, __LINE__);
00230 
00231     // If the byte read is not what we sent, check for an error
00232     // For now just return a 1 and discount any errors??
00233     if( tmpByte != resetSendByte )
00234       devFound = true; // got a response of some type
00235     else
00236       devFound = false; // no device responding
00237   }
00238   catch( ... ) {
00239     
00240     try { 
00241       serialPort->tty_configure( LOW_portSerial::none_flowControl, LOW_portSerial::bit6_size, 
00242                                  LOW_portSerial::no_parity, LOW_portSerial::bit1_stopBit, LOW_portSerial::B115200_speed);
00243     }
00244     catch( ... ) {}
00245     
00246     throw;
00247   }  
00248   
00249   serialPort->tty_configure( LOW_portSerial::none_flowControl, LOW_portSerial::bit6_size, 
00250                              LOW_portSerial::no_parity, LOW_portSerial::bit1_stopBit, LOW_portSerial::B115200_speed);
00251 
00252   return devFound;
00253 }
00254 
00255 
00256 void LOW_linkPassiveSerial::strongPullup( const unsigned long /*inMicroSecs*/ )
00257 { 
00258   commLock lock( *this);
00259   
00260   //LOW_helper_timer::microSleep( inMicroSecs);
00261   
00262   LOW_platformMisc::secSleep( strongPullupEmuTime);
00263 }
00264 
00265   
00266 void LOW_linkPassiveSerial::programPulse()
00267 {
00268   commLock lock( *this);
00269   
00270   if ( ! allowProgPulse )
00271     throw notAllowed_error( "Program pulse not allowed", __FILE__, __LINE__);
00272 
00273   if ( ! hasProgramPulse )
00274     throw illegalLevel_error( "Program pulse not available", __FILE__, __LINE__);
00275 
00276   throw internal_error( "Program pulse not available, should never be reached", __FILE__, __LINE__);
00277 }
00278 
00279   
00280 void LOW_linkPassiveSerial::doSearchSequence( const LOW_deviceIDRaw &inBranchVector, 
00281                                               LOW_deviceIDRaw &outFoundID, LOW_deviceIDRaw &outDiscrVec)
00282 {
00283   commLock lock( *this);
00284   
00285   for( int a=0; a<64; a++) {
00286     
00287     bool readB = readDataBit();
00288     bool cmplB = readDataBit();
00289   
00290     if ( readB == cmplB ) {
00291       writeData( inBranchVector.getBit( a));
00292       outFoundID.setBit( a, inBranchVector.getBit( a));
00293       outDiscrVec.setBit( a, true);
00294     }
00295     else {
00296       writeData( readB);
00297       outFoundID.setBit( a, readB);
00298       outDiscrVec.setBit( a, false);
00299     }
00300     
00301   }
00302 }
00303 
00304     
00305 
00306 //=========================================================================================
00307 //
00308 // private methods
00309 //
00310 
00311 void LOW_linkPassiveSerial::strongPullup( const strongPullup_t inPullup)
00312 {
00313   commLock lock( *this);
00314   
00315   switch ( inPullup )
00316   {
00317     case pullUp_NONE: break;
00318     case pullUp_16_4: strongPullup(   16400);  break;
00319     case pullUp_65_5: strongPullup(   65500);  break;
00320     case pullUp_131:  strongPullup(  131000);  break;
00321     case pullUp_262:  strongPullup(  262000);  break;
00322     case pullUp_524:  strongPullup(  524000);  break;
00323     case pullUp_1048: strongPullup( 1048000);  break;
00324     default:          throw internal_error( "Unknown strong pullup type", __FILE__, __LINE__);
00325   }
00326 }
00327 
00328     

Generated on Sun Jan 12 21:07:43 2003 by doxygen1.2.13.1 written by Dimitri van Heesch, © 1997-2001