00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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
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();
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
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
00077 serSendByte = inSendBit ? 0xFF : 0x00;
00078
00079
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
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
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
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
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
00224 serialPort->tty_write( resetSendByte);
00225
00226 uint8_t tmpByte = serialPort->tty_readByte();
00227
00228 if( tmpByte == 0 )
00229 throw comm_error( "Possible short to ground detected", __FILE__, __LINE__);
00230
00231
00232
00233 if( tmpByte != resetSendByte )
00234 devFound = true;
00235 else
00236 devFound = false;
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 )
00257 {
00258 commLock lock( *this);
00259
00260
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
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