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

LOW_linkDS2490.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           LOW_linkDS2490.cpp  -  description
00003                              -------------------
00004     begin                : Sun Oct 12 2003
00005     copyright            : (C) 2003 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_linkDS2490.h"
00020 #include "LOW_device.h"
00021 
00022 
00023 
00024 //=====================================================================================
00025 //
00026 // constructors
00027 //
00028 
00029 LOW_linkDS2490::LOW_linkDS2490( const LOW_portUsb_Factory::usbDeviceSpecifier_t inUsbDevSpec,
00030                                 const bool inHasExternalPower, const bool inAllowProgPulse) :
00031   LOW_link( true, inHasExternalPower, inAllowProgPulse),
00032   LOW_linkFlexibleSpeed( normal_speed, pdSlewRate_1_37, w1LowTime_11, soW0RecTime_10) // use normal speed, but preconfigure the recommeded optimal parameters as of app note #148
00033 {
00034   usbDevice = LOW_portUsb_Factory::new_portUsbDevice( inUsbDevSpec);
00035 
00036   if ( usbDevice->getVendorID() != usbVendorID || usbDevice->getProductID() != usbProductID )
00037     throw link_error( "Requested device has wrong vendor/product ID", __FILE__, __LINE__);
00038 
00039   commonConstructorActions();
00040 }
00041 
00042 
00043 LOW_linkDS2490::~LOW_linkDS2490()
00044 {
00045   ctlCmd_resetDevice();
00046   usbDevice->releaseInterface( usbDefaultInterface);
00047   delete usbDevice;
00048 }
00049 
00050 
00051 //=====================================================================================
00052 //
00053 // Standard methods required by LOW_link
00054 //
00055 
00056 //-------------------------------------------------------------------------------------
00057 //
00058 // Bus touch (write/read) methods required by LOW_link
00059 //
00060 
00061 bool LOW_linkDS2490::touchBit( const bool inSendBit, const strongPullup_t inPullup)
00062 {
00063   commLock lock( *this);
00064 
00065   if ( inPullup != pullUp_NONE ) {
00066     comCmd_setDuration( strongPullup_2_spFactor( inPullup), // inTimeFactor
00067                         false,                              // inSpecifyProgPulse
00068                         resultOnError_rsltHdl,              // inResultHandling
00069                         false);                             // inImmediateExec
00070   }
00071 
00072   comCmd_bitIO( inSendBit,                        // inWriteBit
00073                 inPullup==pullUp_NONE?false:true, // inDoStrongPullup
00074                 false,                            // inSuppressPullupOnRead1
00075                 resultOnError_rsltHdl,            // inResultHandling, resultOnError_rsltHdl is necessary to get response byte
00076                 false);                           // inImmediateExec
00077 
00078   ctlCmd_startExecution();
00079 
00080   deviceFeedback_t  deviceFeedback;
00081   resultCodeVec_t   resultCodeVec;
00082   waitUntilIdle( deviceFeedback, resultCodeVec, 1000);
00083 
00084   if ( deviceFeedback.dataInBufferUsage != 1 )
00085     throw comm_error( "Unexpected data amount in IN buffer", __FILE__, __LINE__);
00086 
00087   uint8_t      readByte;
00088   unsigned int readSize = usbDevice->bulkRead( usbDataInEP, 1, &readByte, 1000);
00089   if ( readSize != 1 )
00090     throw comm_error( "Short read from IN buffer", __FILE__, __LINE__);
00091   
00092   return (readByte&0x01)==0x01;
00093 }
00094 
00095 
00096 uint8_t LOW_linkDS2490::touchByte( const uint8_t inSendByte, const strongPullup_t inPullup)
00097 {
00098   commLock lock( *this);
00099 
00100   if ( inPullup != pullUp_NONE ) {
00101     comCmd_setDuration( strongPullup_2_spFactor( inPullup), // inTimeFactor
00102                         false,                              // inSpecifyProgPulse
00103                         resultOnError_rsltHdl,              // inResultHandling
00104                         false);                             // inImmediateExec
00105   }
00106 
00107   comCmd_byteIO( inSendByte,                       // inWriteByte
00108                  inPullup==pullUp_NONE?false:true, // inDoStrongPullup
00109                  resultOnError_rsltHdl,            // inResultHandling, resultOnError_rsltHdl is necessary to get response byte
00110                  false);                           // inImmediateExec
00111 
00112   ctlCmd_startExecution();
00113 
00114   deviceFeedback_t  deviceFeedback;
00115   resultCodeVec_t   resultCodeVec;
00116   waitUntilIdle( deviceFeedback, resultCodeVec, 1000);
00117 
00118   if ( deviceFeedback.dataInBufferUsage != 1 )
00119     throw comm_error( "Unexpected data amount in IN buffer", __FILE__, __LINE__);
00120 
00121   uint8_t      readByte;
00122   unsigned int readSize = usbDevice->bulkRead( usbDataInEP, 1, &readByte, 1000);
00123   if ( readSize != 1 )
00124     throw comm_error( "Short read from IN buffer", __FILE__, __LINE__);
00125 
00126   return readByte;
00127 }
00128 
00129 
00130 byteVec_t LOW_linkDS2490::touchBlock( const byteVec_t &inBytes, const strongPullup_t inPullup)
00131 {
00132   commLock lock( *this);
00133   
00134   const unsigned int  maxBlockSize = (usbDataOutEP_FIFOsize < usbDataInEP_FIFOsize) ? usbDataOutEP_FIFOsize-1 : usbDataInEP_FIFOsize-1;
00135   const unsigned int  total        = inBytes.size();
00136   uint8_t             *writeBuffer = new uint8_t[total];
00137   uint8_t             *readBuffer  = new uint8_t[maxBlockSize];
00138   byteVec_t           retVec       = byteVec_t( total);
00139   
00140   if ( inPullup != pullUp_NONE ) {
00141     comCmd_setDuration( strongPullup_2_spFactor( inPullup), // inTimeFactor
00142                         false,                              // inSpecifyProgPulse
00143                         resultOnError_rsltHdl,              // inResultHandling
00144                         false);                             // inImmediateExec
00145   }
00146 
00147   try {
00148     std::copy( inBytes.begin(), inBytes.end(), writeBuffer);
00149     
00150     unsigned int  written   = 0;
00151     unsigned int  remaining = total;
00152     unsigned int  totalRead = 0;
00153     unsigned int  read      = 0;
00154     uint8_t       *writePtr = writeBuffer;
00155     do {
00156       const unsigned int blockSize = (remaining < maxBlockSize) ? remaining : maxBlockSize;
00157       
00158       written = usbDevice->bulkWrite( usbDataOutEP, blockSize, writePtr, 1000);
00159       remaining -= written;
00160       writePtr  += written;
00161     
00162       comCmd_blockIO( written,                                 // inWriteSize
00163                       false,                                   // inBusResetBefore
00164                       (remaining==0) ? (inPullup==pullUp_NONE?false:true) : false, // inDoStrongPullup
00165                       resultOnError_rsltHdl,                   // inResultHandling,
00166                       false);                                  // inImmediateExec
00167    
00168       ctlCmd_startExecution();
00169 
00170       deviceFeedback_t  deviceFeedback;
00171       resultCodeVec_t   resultCodeVec;
00172       waitUntilIdle( deviceFeedback, resultCodeVec, 1000);
00173    
00174       read = usbDevice->bulkRead( usbDataInEP, written, readBuffer, 1000);
00175       if ( read != written )
00176         throw comm_error( "Short read from IN buffer", __FILE__, __LINE__);
00177       std::copy( readBuffer, readBuffer+read, retVec.begin()+totalRead);
00178       totalRead += read;
00179     }
00180     while ( remaining != 0);
00181   }
00182   catch( ... ) {
00183     delete[] writeBuffer;
00184     delete[] readBuffer;
00185     throw;
00186   }
00187   
00188   delete[] writeBuffer;
00189   delete[] readBuffer;
00190   
00191   return retVec;
00192   
00193   
00194   byteVec_t retBytes = byteVec_t( inBytes.size());
00195   for( unsigned int a=0; a<inBytes.size()-1; ++a) {
00196     retBytes[a] = touchByte( inBytes[a], pullUp_NONE);
00197   }
00198   retBytes[inBytes.size()-1] = touchByte( inBytes[inBytes.size()-1], inPullup);
00199 
00200   return retBytes;
00201 }
00202 
00203 
00204 //-------------------------------------------------------------------------------------
00205 //
00206 // Higher level methods by LOW_link
00207   
00208 LOW_deviceID::deviceIDVec_t LOW_linkDS2490::searchDevices( const bool inOnlyAlarm, const LOW_deviceIDRaw inPreload,
00209                                                            const LOW_deviceIDRaw::devFamCode_t inFamCode, const bool inDoReset)
00210 {
00211   commLock lock( *this);
00212 
00213   const uint8_t                maxDevs = usbDataInEP_FIFOsize/sizeof( LOW_deviceIDRaw::devRomID_t) - 1;  // FIFO_size / ID_size - place_for_discr_vec
00214   LOW_deviceID::deviceIDVec_t  returnIDs;
00215   
00216   LOW_deviceIDRaw preloadVec = inPreload;
00217   
00218   // preload family type
00219   if ( inFamCode != LOW_device::anyDev_famCode )
00220     preloadVec.setFamilyCode( inFamCode);
00221 
00222   if ( resetBus() == false )
00223     return returnIDs;
00224 
00225   bool searchRunning = true;
00226   while ( searchRunning ) {
00227     
00228     unsigned int writeSize = usbDevice->bulkWrite( usbDataOutEP, preloadVec.getRomIDVec(), 1000);
00229     if ( writeSize != preloadVec.getRomIDVec().size() )
00230       throw comm_error( "Short write to OUT buffer", __FILE__, __LINE__);
00231 
00232     comCmd_searchAccess( maxDevs,              // inMaxDevNum
00233                          inOnlyAlarm ? LOW_device::SearchAlarmROM_COMMAND : LOW_device::SearchROM_COMMAND, // inSearchCommand
00234                          true,                 // inSearchWithoutFullAccess
00235                          true,                 // inReturnDiscrepancyInfo
00236                          true,                 // inBusResetBefore
00237                          true,                 // inFlushBuffersOnErr
00238                          resultAlways_rsltHdl, // inResultHandling
00239                          false);               // inImmediateExec
00240   
00241     ctlCmd_startExecution();
00242   
00243     deviceFeedback_t  deviceFeedback;
00244     resultCodeVec_t   resultCodeVec;
00245     waitUntilIdle( deviceFeedback, resultCodeVec, 30000);
00246   
00247     if ( (deviceFeedback.dataInBufferUsage % sizeof( LOW_deviceIDRaw::devRomID_t)) != 0 )
00248       throw comm_error( "Illegal byte count in IN buffer", __FILE__, __LINE__);
00249       
00250     unsigned int rawDevCnt = deviceFeedback.dataInBufferUsage / sizeof( LOW_deviceIDRaw::devRomID_t);
00251     LOW_deviceIDRaw::devRomID_t *readRawIDs = new LOW_deviceIDRaw::devRomID_t[rawDevCnt];
00252     
00253     try {
00254       unsigned int readSize = usbDevice->bulkRead( usbDataInEP, deviceFeedback.dataInBufferUsage, reinterpret_cast<LOW_portUsbDevice::msgData_t>(readRawIDs), 1000);
00255       if ( readSize != deviceFeedback.dataInBufferUsage )
00256         throw comm_error( "Short read from IN buffer", __FILE__, __LINE__);
00257   
00258       unsigned int realIDCnt = rawDevCnt<=maxDevs ? rawDevCnt : maxDevs;
00259       for( unsigned int a=0; a<realIDCnt; ++a) {
00260         LOW_deviceID newID = LOW_deviceID( readRawIDs[a]);
00261         if ( inFamCode!=LOW_device::anyDev_famCode && newID.getFamilyCode()!=inFamCode ) {
00262           searchRunning = false;
00263           break;
00264         }
00265         else
00266           returnIDs.push_back( newID);
00267       }
00268   
00269       if ( rawDevCnt <= maxDevs )
00270         searchRunning = false;
00271       else
00272         preloadVec = readRawIDs[rawDevCnt-1];
00273     }
00274     catch ( ... ) {
00275       delete[] readRawIDs;
00276       throw;
00277     }
00278   
00279     delete[] readRawIDs;
00280   }
00281 
00282   if ( inDoReset )
00283     resetBus();
00284   
00285   return returnIDs;
00286 }
00287 
00288 
00289                                                      
00290 //-------------------------------------------------------------------------------------
00291 //
00292 // Misc methods required by LOW_link
00293 //
00294 
00295 void LOW_linkDS2490::resetLinkAdapter()
00296 {
00297   commLock lock( *this);
00298 
00299   // reset device
00300   ctlCmd_resetDevice();
00301   
00302   modCmd_setEnablePulse( true, allowProgPulse);
00303   modCmd_setEnableSpeedChange( false);
00304   
00305   // restore former settings
00306   setWireSpeed( wireSpeed);
00307   if ( wireSpeed == flexible_speed ) {
00308     setPullDownSlewRate( pdSlewRate);
00309     setWrite1LowTime( w1LowTime);
00310     setSampleOffsetWrite0Rec( soW0RecTime);
00311   }
00312   
00313   deviceFeedback_t devFeedback;
00314   resultCodeVec_t  resultCodeVec;
00315   readDeviceStatus( devFeedback, resultCodeVec);
00316   hasProgramPulse = devFeedback.progVoltagePresent;
00317 }
00318 
00319 
00320 bool LOW_linkDS2490::resetBus()
00321 {
00322   commLock lock( *this);
00323   
00324   comCmd_oneWireReset( false,                // inLoopUntilPresenceDetect
00325                        false,                // inEnableSpeedChange
00326                        normal_OWSPEED,       // inSpeedSelector
00327                        true,                 // inFlushBuffersOnErr
00328                        resultAlways_rsltHdl, // inResultHandling
00329                        false);               // inImmediateExec
00330   ctlCmd_startExecution();
00331   
00332   deviceFeedback_t  deviceFeedback;
00333   resultCodeVec_t   resultCodeVec;
00334   waitUntilIdle( deviceFeedback, resultCodeVec, 1000);
00335 
00336 //  printf( " isStrongPullupEnabled       = %d\n", deviceFeedback.isStrongPullupEnabled);
00337 //  printf( " isProgPulseEnabled          = %d\n", deviceFeedback.isProgPulseEnabled);
00338 //  printf( " isDynSpeedChangeEnabled     = %d\n", deviceFeedback.isDynSpeedChangeEnabled);
00339 //  printf( " oneWireSpeed;               = %d\n", deviceFeedback.oneWireSpeed);
00340 //  printf( " strongPullupDurationFactor; = %d\n", deviceFeedback.strongPullupDurationFactor);
00341 //  printf( " progPulseDurationFactor;    = %d\n", deviceFeedback.progPulseDurationFactor);
00342 //  printf( " pulldownSlewRate;           = %d\n", deviceFeedback.pulldownSlewRate);
00343 //  printf( " write1LowTime;              = %d\n", deviceFeedback.write1LowTime);
00344 //  printf( " dsow0RecTime;               = %d\n", deviceFeedback.dsow0RecTime);
00345 //  printf( " strongPullupCurrentActive;  = %d\n", deviceFeedback.strongPullupCurrentActive);
00346 //  printf( " progPulseCurrentActive;     = %d\n", deviceFeedback.progPulseCurrentActive);
00347 //  printf( " progVoltagePresent;         = %d\n", deviceFeedback.progVoltagePresent);
00348 //  printf( " deviceExternalPowered;      = %d\n", deviceFeedback.deviceExternalPowered);
00349 //  printf( " deviceHalted;               = %d\n", deviceFeedback.deviceHalted);
00350 //  printf( " deviceIdle;                 = %d\n", deviceFeedback.deviceIdle);
00351 //  printf( " ep0FifoOverflowError;       = %d\n", deviceFeedback.ep0FifoOverflowError);
00352 //  printf( " currentCommCmd;             = %d\n", deviceFeedback.currentCommCmd);
00353 //  printf( " commCmdBufferUsage;         = %d\n", deviceFeedback.commCmdBufferUsage);
00354 //  printf( " dataOutBufferUsage;         = %d\n", deviceFeedback.dataOutBufferUsage);
00355 //  printf( " dataInBufferUsage;          = %d\n", deviceFeedback.dataInBufferUsage);
00356 //  printf( " resultCount;                = %d\n", deviceFeedback.resultCount);
00357 //  printf( " resultCodeVec.size()        = %d\n", resultCodeVec.size());
00358   
00359   if ( resultCodeVec.size() == 0)
00360     throw comm_error( "Expected answer not found", __FILE__, __LINE__);
00361 
00362     /** @todo Check if and how "alarming presence pulse" response works. */
00363   if ( resultCodeVec.back().alarmingPresencePulse )  return true;
00364   if ( resultCodeVec.back().noPresencePulse )        return false;
00365   if ( resultCodeVec.back().shortToGround )          throw comm_error( "Short to ground detected", __FILE__, __LINE__);
00366 
00367   return true;
00368 }
00369 
00370 
00371 void LOW_linkDS2490::strongPullup( const unsigned long inMilliSecs)
00372 {
00373   commLock lock( *this);
00374 
00375   if ( inMilliSecs>=16 && inMilliSecs<=4064 && (inMilliSecs%16)==0 ) {  // 16ms <= length <= 4096ms AND dividable by 16ms
00376     strongPullupInternal( inMilliSecs/16);
00377     return;
00378   }
00379 
00380   comCmd_setDuration( 0x00,                  // inTimeFactor = infinite
00381                       false,                 // inSpecifyProgPulse
00382                       resultOnError_rsltHdl, // inResultHandling
00383                       true);                 // inImmediateExec
00384 
00385   comCmd_pulse( false,                  // inSpecifyProgPulse
00386                 true,                   // inFlushBuffersOnErr,
00387                 resultOnError_rsltHdl,  // inResultHandling
00388                 true);                  // inImmediateExec
00389 
00390   LOW_platformMisc::milliSleep( inMilliSecs);
00391   ctlCmd_haltExecutionWhenDone();  // stop the pullup
00392   ctlCmd_resumeExecution();
00393 
00394   deviceFeedback_t  deviceFeedback;
00395   resultCodeVec_t   resultCodeVec;
00396   readDeviceStatus( deviceFeedback, resultCodeVec);
00397 
00398   if ( resultCodeVec.size() != 0)
00399     throw comm_error( "Unexpected error reply found", __FILE__, __LINE__);
00400 }
00401 
00402 
00403 void LOW_linkDS2490::strongPullup( const strongPullup_t inPullupTimes)
00404 {
00405   commLock lock( *this);
00406 
00407   strongPullupInternal( strongPullup_2_spFactor( inPullupTimes));
00408 }
00409 
00410 
00411 void LOW_linkDS2490::programPulse( const unsigned long inMicroSecs)
00412 {
00413   commLock lock( *this);
00414 
00415   if ( ! allowProgPulse )
00416     throw notAllowed_error( "Program pulse not allowed", __FILE__, __LINE__);
00417 
00418   if ( ! hasProgramPulse )
00419     throw illegalLevel_error( "Program pulse not available", __FILE__, __LINE__);
00420 
00421   if ( inMicroSecs>=8 && inMicroSecs<=2032 && (inMicroSecs%8)==0 ) { // 8us <= length <= 2032us AND dividable by 8us
00422     progPulseInternal( inMicroSecs/8);
00423     return;
00424   }
00425 
00426   comCmd_setDuration( 0x00,                  // inTimeFactor = infinite
00427                       true,                  // inSpecifyProgPulse
00428                       resultOnError_rsltHdl, // inResultHandling
00429                       true);                 // inImmediateExec
00430 
00431   comCmd_pulse( true,                  // inSpecifyProgPulse
00432                 true,                  // inFlushBuffersOnErr,
00433                 resultAlways_rsltHdl,  // inResultHandling
00434                 true);                 // inImmediateExec
00435 
00436   LOW_platformMisc::microSleep( inMicroSecs);;
00437   ctlCmd_haltExecutionWhenDone();  // stop the pulse
00438   ctlCmd_resumeExecution();
00439 
00440   deviceFeedback_t  deviceFeedback;
00441   resultCodeVec_t   resultCodeVec;
00442   readDeviceStatus( deviceFeedback, resultCodeVec);
00443 
00444   if ( resultCodeVec.size() == 0)
00445     throw comm_error( "Expected answer not found", __FILE__, __LINE__);
00446 
00447   if ( resultCodeVec.back().progVoltageMissingOnBus )
00448     throw comm_error( "12V program pulse not detected on bus", __FILE__, __LINE__);
00449 }
00450 
00451 
00452 void LOW_linkDS2490::programPulse( const progPulse_t inPulseTime)
00453 {
00454   commLock lock( *this);
00455 
00456   if ( ! allowProgPulse )
00457     throw notAllowed_error( "Program pulse not allowed", __FILE__, __LINE__);
00458 
00459   if ( ! hasProgramPulse )
00460     throw illegalLevel_error( "Program pulse not available", __FILE__, __LINE__);
00461 
00462   progPulseInternal( progPulse_2_ppFactor( inPulseTime));
00463 }
00464 
00465 
00466 void LOW_linkDS2490::doSearchSequence( const LOW_deviceIDRaw& /*inBranchVector*/,
00467                                        LOW_deviceIDRaw& /*outFoundID*/, LOW_deviceIDRaw& /*outDiscrVec*/)
00468 {
00469   throw internal_error( "doSearchSequence() not implemented. Should never be called as searchDevices() is overloaded.", __FILE__, __LINE__);
00470 } 
00471 
00472 
00473 
00474 //=====================================================================================
00475 //
00476 // Standard methods required by LOW_linkFlexibleSpeed
00477 //
00478 
00479 void LOW_linkDS2490::setWireSpeed( const wireSpeed_t inWireSpeed)
00480 {
00481   commLock lock( *this);
00482 
00483   LOW_linkFlexibleSpeed::setWireSpeed( inWireSpeed); // conserve the setting via superclass
00484 
00485   modCmd_setOneWireSpeed( wireSpeed_2_OWSPEED_val( inWireSpeed));
00486 
00487   // restore former settings
00488   if ( wireSpeed == flexible_speed ) {
00489     setPullDownSlewRate( pdSlewRate);
00490     setWrite1LowTime( w1LowTime);
00491     setSampleOffsetWrite0Rec( soW0RecTime);
00492   }
00493 }
00494 
00495 
00496 LOW_linkDS2490::wireSpeed_t LOW_linkDS2490::getWireSpeed()
00497 {
00498   commLock lock( *this);
00499 
00500   deviceFeedback_t devFeedback;
00501   resultCodeVec_t  resultCodeVec;
00502   readDeviceStatus( devFeedback, resultCodeVec);
00503   return OWSPEED_val_2_wireSpeed( devFeedback.oneWireSpeed);
00504 }
00505 
00506 
00507 void LOW_linkDS2490::setPullDownSlewRate( const pdSlewRate_t inPDSR)
00508 {
00509   commLock lock( *this);
00510 
00511   LOW_linkFlexibleSpeed::setPullDownSlewRate( inPDSR);  // conserve the setting via superclass
00512 
00513   modCmd_setPulldownSlewRate( pdSlewRate_2_PDSR_val( inPDSR));
00514 }
00515 
00516 
00517 LOW_linkDS2490::pdSlewRate_t LOW_linkDS2490::getPullDownSlewRate()
00518 {
00519   commLock lock( *this);
00520 
00521   LOW_linkFlexibleSpeed::getPullDownSlewRate();  // sanity checking in superclass
00522 
00523   deviceFeedback_t devFeedback;
00524   resultCodeVec_t  resultCodeVec;
00525   readDeviceStatus( devFeedback, resultCodeVec);
00526   return PDSR_val_2_pdSlewRate( devFeedback.pulldownSlewRate);
00527 }
00528 
00529 
00530 void LOW_linkDS2490::setWrite1LowTime( const w1LowTime_t inW1LT)
00531 {
00532   commLock lock( *this);
00533 
00534   LOW_linkFlexibleSpeed::setWrite1LowTime( inW1LT);  // conserve the setting via superclass
00535 
00536   modCmd_setWrite1LowTime( w1LowTime_2_W1LT_val( inW1LT));
00537 }
00538 
00539 
00540 LOW_linkDS2490::w1LowTime_t LOW_linkDS2490::getWrite1LowTime()
00541 {
00542   commLock lock( *this);
00543 
00544   LOW_linkFlexibleSpeed::getWrite1LowTime();  // sanity checking in superclass
00545 
00546   deviceFeedback_t devFeedback;
00547   resultCodeVec_t  resultCodeVec;
00548   readDeviceStatus( devFeedback, resultCodeVec);
00549   return W1LT_val_2_w1LowTime( devFeedback.write1LowTime);
00550 }
00551 
00552 
00553 void LOW_linkDS2490::setSampleOffsetWrite0Rec( const soW0RecTime_t inSOW0RT)
00554 {
00555   commLock lock( *this);
00556 
00557   LOW_linkFlexibleSpeed::setSampleOffsetWrite0Rec( inSOW0RT);  // conserve the setting via superclass
00558 
00559   modCmd_setDsoW0RecoveryTime( soW0RecTime_2_SOW0RT_val( inSOW0RT));
00560 }
00561 
00562 
00563 LOW_linkDS2490::soW0RecTime_t LOW_linkDS2490::getSampleOffsetWrite0Rec()
00564 {
00565   commLock lock( *this);
00566 
00567   LOW_linkFlexibleSpeed::getSampleOffsetWrite0Rec();  // sanity checking in superclass
00568 
00569   deviceFeedback_t devFeedback;
00570   resultCodeVec_t  resultCodeVec;
00571   readDeviceStatus( devFeedback, resultCodeVec);
00572   return SOW0RT_val_2_soW0RecTime( devFeedback.dsow0RecTime);
00573 }
00574 
00575 
00576 
00577 
00578 //=====================================================================================
00579 //
00580 // private methods
00581 //
00582 
00583 
00584 //-------------------------------------------------------------------------------------
00585 //
00586 // Mid-layer methods.
00587 //
00588 
00589 void LOW_linkDS2490::commonConstructorActions()
00590 {
00591   // locking done in publicly accessible methods
00592 
00593   usbDevice->claimInterface( usbDefaultInterface);
00594   
00595   resetLinkAdapter();
00596 }
00597 
00598 
00599 void LOW_linkDS2490::readDeviceStatus( deviceFeedback_t &outDevFeedback, resultCodeVec_t &outResultCodeVec)
00600 {
00601   // locking done in publicly accessible methods
00602 
00603   deviceFeedbackRaw_t  feedbackData;
00604 
00605   unsigned int readBytes = usbDevice->bulkRead( usbStatusInEP, sizeof( feedbackData),
00606                                                 reinterpret_cast<LOW_portUsbDevice::msgData_t>(&feedbackData), 500);
00607   if ( readBytes < 16 )
00608     throw comm_error( "Short read from status endpoint", __FILE__, __LINE__);
00609 
00610   // analyze standard data
00611   outDevFeedback.isStrongPullupEnabled      = feedbackData.enableFlags & SPUE_bitmask;
00612   outDevFeedback.isProgPulseEnabled         = feedbackData.enableFlags & PRGE_bitmask;
00613   outDevFeedback.isDynSpeedChangeEnabled    = feedbackData.enableFlags & SPCE_bitmask;
00614   outDevFeedback.oneWireSpeed               = static_cast<OWSPEED_val_t>(feedbackData.oneWireSpeed);
00615   outDevFeedback.strongPullupDurationFactor = feedbackData.strongPullupDuration;
00616   outDevFeedback.progPulseDurationFactor    = feedbackData.progPulseDuration;
00617   outDevFeedback.pulldownSlewRate           = static_cast<PDSR_val_t>(feedbackData.pulldownSlewRate);
00618   outDevFeedback.write1LowTime              = static_cast<W1LT_val_t>(feedbackData.write1LowTime);
00619   outDevFeedback.dsow0RecTime               = static_cast<SOW0RT_val_t>(feedbackData.dsow0RecTime);
00620   outDevFeedback.strongPullupCurrentActive  = feedbackData.deviceStatusFlags & SPUA_bitmask;
00621   outDevFeedback.progPulseCurrentActive     = feedbackData.deviceStatusFlags & PRGA_bitmask;
00622   outDevFeedback.progVoltagePresent         = feedbackData.deviceStatusFlags & VP12_bitmask;
00623   outDevFeedback.deviceExternalPowered      = feedbackData.deviceStatusFlags & PMOD_bitmask;
00624   outDevFeedback.deviceHalted               = feedbackData.deviceStatusFlags & HALT_bitmask;
00625   outDevFeedback.deviceIdle                 = feedbackData.deviceStatusFlags & IDLE_bitmask;
00626   outDevFeedback.ep0FifoOverflowError       = feedbackData.deviceStatusFlags & EP0F_bitmask;
00627   outDevFeedback.currentCommCmd             = (feedbackData.commCmdHI<<8) | feedbackData.commCmdLO;
00628   outDevFeedback.commCmdBufferUsage         = feedbackData.commCmdBufferStatus;
00629   outDevFeedback.dataOutBufferUsage         = feedbackData.dataOutBufferStatus;
00630   outDevFeedback.dataInBufferUsage          = feedbackData.dataInBufferStatus;
00631   outDevFeedback.resultCount                = readBytes - 16;
00632   outDevFeedback.compoundResults.deviceDetected             = false;
00633   outDevFeedback.compoundResults.searchAccessDeviceUnderrun = false;
00634   outDevFeedback.compoundResults.pageIsRedirected           = false;
00635   outDevFeedback.compoundResults.crcError                   = false;
00636   outDevFeedback.compoundResults.compareError               = false;
00637   outDevFeedback.compoundResults.progVoltageMissingOnBus    = false;
00638   outDevFeedback.compoundResults.alarmingPresencePulse      = false;
00639   outDevFeedback.compoundResults.shortToGround              = false;
00640   outDevFeedback.compoundResults.noPresencePulse            = false;
00641   
00642   // analyze extra result codes and calc compound results
00643   for( int a=0; a<outDevFeedback.resultCount; a++) {
00644     resultCode_t theResult = { false, false, false, false, false, false, false, false, false};
00645 
00646     if ( feedbackData.resultCode[a] == devDetect_code ) {
00647       theResult.deviceDetected             = true;
00648     }
00649     else {
00650       theResult.searchAccessDeviceUnderrun = feedbackData.resultCode[a] & EOS_bitmask;
00651       theResult.pageIsRedirected           = feedbackData.resultCode[a] & RDP_bitmask;
00652       theResult.crcError                   = feedbackData.resultCode[a] & CRC_bitmask;
00653       theResult.compareError               = feedbackData.resultCode[a] & CMP_bitmask;
00654       theResult.progVoltageMissingOnBus    = feedbackData.resultCode[a] & VPP_bitmask;
00655       theResult.alarmingPresencePulse      = feedbackData.resultCode[a] & APP_bitmask;
00656       theResult.shortToGround              = feedbackData.resultCode[a] & SH_bitmask;
00657       theResult.noPresencePulse            = feedbackData.resultCode[a] & NRS_bitmask;
00658     }
00659 
00660     outDevFeedback.compoundResults.deviceDetected             |= theResult.deviceDetected;
00661     outDevFeedback.compoundResults.searchAccessDeviceUnderrun |= theResult.searchAccessDeviceUnderrun;
00662     outDevFeedback.compoundResults.pageIsRedirected           |= theResult.pageIsRedirected;
00663     outDevFeedback.compoundResults.crcError                   |= theResult.crcError;
00664     outDevFeedback.compoundResults.compareError               |= theResult.compareError;
00665     outDevFeedback.compoundResults.progVoltageMissingOnBus    |= theResult.progVoltageMissingOnBus;
00666     outDevFeedback.compoundResults.alarmingPresencePulse      |= theResult.alarmingPresencePulse;
00667     outDevFeedback.compoundResults.shortToGround              |= theResult.shortToGround;
00668     outDevFeedback.compoundResults.noPresencePulse            |= theResult.noPresencePulse;
00669 
00670     outResultCodeVec.push_back( theResult);
00671   }
00672 
00673   // ep0 fifo overrun makes the device unusable anyway so we handle it here centrally
00674   if ( outDevFeedback.ep0FifoOverflowError ) {
00675     ctlCmd_resetDevice();
00676     throw comm_error( "EP0 FIFO overrund. Reset command was sent to device.", __FILE__, __LINE__);
00677   }
00678 }
00679 
00680 
00681 void LOW_linkDS2490::waitUntilIdle( deviceFeedback_t &outDeviceFeedback, resultCodeVec_t &outResultCodeVec,
00682                                     const LOW_portUsbDevice::usbTimeout_t inTimeout)
00683 {
00684   // locking done in publicly accessible methods
00685 
00686   static const unsigned long sleepTime_ms = 1;
00687 
00688   resultCode_t cmpdResults = { false, false, false, false, false, false, false, false, false};
00689   
00690   for ( unsigned int a=0; a<(inTimeout/sleepTime_ms)+1; ++a) {
00691     deviceFeedback_t  feedbackData;
00692     readDeviceStatus( feedbackData, outResultCodeVec);
00693     
00694     cmpdResults.deviceDetected             |= feedbackData.compoundResults.deviceDetected;
00695     cmpdResults.searchAccessDeviceUnderrun |= feedbackData.compoundResults.searchAccessDeviceUnderrun;
00696     cmpdResults.pageIsRedirected           |= feedbackData.compoundResults.pageIsRedirected;
00697     cmpdResults.crcError                   |= feedbackData.compoundResults.crcError;
00698     cmpdResults.compareError               |= feedbackData.compoundResults.compareError;
00699     cmpdResults.progVoltageMissingOnBus    |= feedbackData.compoundResults.progVoltageMissingOnBus;
00700     cmpdResults.alarmingPresencePulse      |= feedbackData.compoundResults.alarmingPresencePulse;
00701     cmpdResults.shortToGround              |= feedbackData.compoundResults.shortToGround;
00702     cmpdResults.noPresencePulse            |= feedbackData.compoundResults.noPresencePulse;
00703     
00704     if ( feedbackData.deviceIdle && feedbackData.commCmdBufferUsage==0 ) {
00705       outDeviceFeedback = feedbackData;
00706       outDeviceFeedback.compoundResults = cmpdResults;
00707       return;
00708     }
00709 
00710     LOW_platformMisc::milliSleep( sleepTime_ms);
00711   }
00712   throw comm_error( "Timeout waiting for device to become idle.", __FILE__, __LINE__);
00713 }
00714 
00715 
00716 void LOW_linkDS2490::strongPullupInternal( const unsigned int inPullupFactor)
00717 {
00718   // locking done in publicly accessible methods
00719 
00720   comCmd_setDuration( inPullupFactor,          // inTimeFactor
00721                       false,                   // inSpecifyProgPulse
00722                       resultOnError_rsltHdl,   // inResultHandling
00723                       true);                   // inImmediateExec
00724 
00725   comCmd_pulse( false,                 // inSpecifyProgPulse
00726                 true,                  // inFlushBuffersOnErr,
00727                 resultOnError_rsltHdl, // inResultHandling
00728                 true);                 // inImmediateExec
00729 
00730   deviceFeedback_t  deviceFeedback;
00731   resultCodeVec_t   resultCodeVec;
00732   waitUntilIdle( deviceFeedback, resultCodeVec, (16*inPullupFactor) + 1000);  // (16ms * factor) + 1s
00733 
00734   if ( resultCodeVec.size() != 0)
00735     throw comm_error( "Unexpected error reply found", __FILE__, __LINE__);
00736 }
00737 
00738 
00739 void LOW_linkDS2490::progPulseInternal( const unsigned int inPulseFactor)
00740 {
00741   // locking done in publicly accessible methods
00742 
00743   comCmd_setDuration( inPulseFactor,           // inTimeFactor
00744                       true,                    // inSpecifyProgPulse
00745                       resultOnError_rsltHdl,   // inResultHandling
00746                       true);                   // inImmediateExec
00747 
00748   comCmd_pulse( true,                  // inSpecifyProgPulse
00749                 true,                  // inFlushBuffersOnErr,
00750                 resultAlways_rsltHdl,  // inResultHandling
00751                 true);                 // inImmediateExec
00752 
00753   deviceFeedback_t  deviceFeedback;
00754   resultCodeVec_t   resultCodeVec;
00755   waitUntilIdle( deviceFeedback, resultCodeVec, (8*inPulseFactor)/1000 + 1000);  // (8us * factor)/1000us + 1s
00756 
00757   if ( resultCodeVec.size() == 0)
00758     throw comm_error( "Expected answer not found", __FILE__, __LINE__);
00759 
00760   if ( resultCodeVec.back().progVoltageMissingOnBus )
00761     throw comm_error( "12V program pulse not detected on bus", __FILE__, __LINE__);
00762 }
00763 
00764 
00765 
00766 //-------------------------------------------------------------------------------------
00767 //
00768 // Control command methods.
00769 //
00770 
00771 void LOW_linkDS2490::ctlCmd_resetDevice()
00772 {
00773   // locking done in publicly accessible methods
00774 
00775   usbDevice->controlMsg( vendorCmd_requestType, control_cmdType, resetDevice_ctlCmd,
00776                          0x0000, 0x0000, 0, ctlCmd_usbTimeout);
00777 }
00778 
00779 
00780 void LOW_linkDS2490::ctlCmd_startExecution()
00781 {
00782   // locking done in publicly accessible methods
00783 
00784   usbDevice->controlMsg( vendorCmd_requestType, control_cmdType, startExe_ctlCmd,
00785                          0x0000, 0x0000, 0, ctlCmd_usbTimeout);
00786 }
00787 
00788 
00789 void LOW_linkDS2490::ctlCmd_resumeExecution()
00790 {
00791   // locking done in publicly accessible methods
00792 
00793   usbDevice->controlMsg( vendorCmd_requestType, control_cmdType, resumeExe_ctlCmd,
00794                          0x0000, 0x0000, 0, ctlCmd_usbTimeout);
00795 }
00796 
00797 
00798 void LOW_linkDS2490::ctlCmd_haltExecutionWhenIdle()
00799 {
00800   // locking done in publicly accessible methods
00801 
00802   usbDevice->controlMsg( vendorCmd_requestType, control_cmdType, haltExeIdle_ctlCmd,
00803                          0x0000, 0x0000, 0, ctlCmd_usbTimeout);
00804 }
00805 
00806 
00807 void LOW_linkDS2490::ctlCmd_haltExecutionWhenDone()
00808 {
00809   // locking done in publicly accessible methods
00810 
00811   usbDevice->controlMsg( vendorCmd_requestType, control_cmdType, haltExeDone_ctlCmd,
00812                          0x0000, 0x0000, 0, ctlCmd_usbTimeout);
00813 }
00814 
00815 
00816 void LOW_linkDS2490::ctlCmd_flushCommCmds()
00817 {
00818   // locking done in publicly accessible methods
00819 
00820   usbDevice->controlMsg( vendorCmd_requestType, control_cmdType, flushCommCmds_ctlCmd,
00821                          0x0000, 0x0000, 0, ctlCmd_usbTimeout);
00822 }
00823 
00824 
00825 void LOW_linkDS2490::ctlCmd_flushDataRcvBuffer()
00826 {
00827   // locking done in publicly accessible methods
00828 
00829   usbDevice->controlMsg( vendorCmd_requestType, control_cmdType, flushRcvBuffer_ctlCmd,
00830                          0x0000, 0x0000, 0, ctlCmd_usbTimeout);
00831 }
00832 
00833 
00834 void LOW_linkDS2490::ctlCmd_flushDataXmtBuffer()
00835 {
00836   // locking done in publicly accessible methods
00837 
00838   usbDevice->controlMsg( vendorCmd_requestType, control_cmdType, flushXmtBuffer_ctlCmd,
00839                          0x0000, 0x0000, 0, ctlCmd_usbTimeout);
00840 }
00841 
00842 
00843 void LOW_linkDS2490::ctlCmd_getCommCmds( byteVec_t &outBytes)
00844 {
00845   // locking done in publicly accessible methods
00846 
00847   usbDevice->controlMsg( vendorCmd_requestType, control_cmdType, getCommCmds_ctlCmd,
00848                          0x0000, outBytes, ctlCmd_usbTimeout);
00849 }
00850 
00851 
00852 
00853 //-------------------------------------------------------------------------------------
00854 //
00855 // Mode command methods.
00856 //
00857   
00858 void LOW_linkDS2490::modCmd_setEnablePulse( const bool inEnableStrongPullup, const bool inEnableProgPulse)
00859 {
00860   // locking done in publicly accessible methods
00861 
00862   LOW_portUsbDevice::wIndex_t indexVal = 0x0000;
00863   
00864   if ( inEnableStrongPullup ) indexVal |= 0x0002;
00865   if ( inEnableProgPulse )    indexVal |= 0x0001;
00866   
00867   usbDevice->controlMsg( vendorCmd_requestType, mode_cmdType, pulseEn_modCmd,
00868                          indexVal, 0x0000, 0, modCmd_usbTimeout);
00869 }
00870 
00871   
00872 void LOW_linkDS2490::modCmd_setEnableSpeedChange( const bool inEnableSpeedChange)
00873 {
00874   // locking done in publicly accessible methods
00875 
00876   LOW_portUsbDevice::wIndex_t indexVal = 0x0000;
00877   
00878   if ( inEnableSpeedChange ) indexVal |= 0x0001;
00879   
00880   usbDevice->controlMsg( vendorCmd_requestType, mode_cmdType, speedChangeEn_modCmd,
00881                          indexVal, 0x0000, 0, modCmd_usbTimeout);
00882 }
00883 
00884   
00885 void LOW_linkDS2490::modCmd_setOneWireSpeed( const OWSPEED_val_t inWireSpeed)
00886 {
00887   // locking done in publicly accessible methods
00888 
00889   LOW_portUsbDevice::wIndex_t indexVal = 0x0000 | inWireSpeed;
00890   
00891   usbDevice->controlMsg( vendorCmd_requestType, mode_cmdType, oneWireSpeed_modCmd,
00892                          indexVal, 0x0000, 0, modCmd_usbTimeout);
00893 }
00894 
00895   
00896 void LOW_linkDS2490::modCmd_setStrongPullupDuration( const uint8_t inSpuDurationFactor)
00897 {
00898   // locking done in publicly accessible methods
00899 
00900   LOW_portUsbDevice::wIndex_t indexVal = 0x0000 | inSpuDurationFactor;
00901   
00902   usbDevice->controlMsg( vendorCmd_requestType, mode_cmdType, strongPuDuration_modCmd,
00903                          indexVal, 0x0000, 0, modCmd_usbTimeout);
00904 }
00905 
00906   
00907 void LOW_linkDS2490::modCmd_setProgPulseDuration( const uint8_t inPpDurationFactor)
00908 {
00909   // locking done in publicly accessible methods
00910 
00911   LOW_portUsbDevice::wIndex_t indexVal = 0x0000 | inPpDurationFactor;
00912   
00913   usbDevice->controlMsg( vendorCmd_requestType, mode_cmdType, progPulseDuration_modCmd,
00914                          indexVal, 0x0000, 0, modCmd_usbTimeout);
00915 }
00916 
00917   
00918 void LOW_linkDS2490::modCmd_setPulldownSlewRate( const PDSR_val_t inPDSR)
00919 {
00920   // locking done in publicly accessible methods
00921 
00922   LOW_portUsbDevice::wIndex_t indexVal = 0x0000 | inPDSR;
00923   
00924   usbDevice->controlMsg( vendorCmd_requestType, mode_cmdType, pulldownSlewRate_modCmd,
00925                          indexVal, 0x0000, 0, modCmd_usbTimeout);
00926 }
00927 
00928   
00929 void LOW_linkDS2490::modCmd_setWrite1LowTime( const W1LT_val_t inW1LT)
00930 {
00931   // locking done in publicly accessible methods
00932 
00933   LOW_portUsbDevice::wIndex_t indexVal = 0x0000 | inW1LT;
00934   
00935   usbDevice->controlMsg( vendorCmd_requestType, mode_cmdType, write1LowTime_modCmd,
00936                          indexVal, 0x0000, 0, modCmd_usbTimeout);
00937 }
00938 
00939   
00940 void LOW_linkDS2490::modCmd_setDsoW0RecoveryTime( const SOW0RT_val_t inSOW0RT)
00941 {
00942   // locking done in publicly accessible methods
00943 
00944   LOW_portUsbDevice::wIndex_t indexVal = 0x0000 | inSOW0RT;
00945   
00946   usbDevice->controlMsg( vendorCmd_requestType, mode_cmdType, dsow0Trec_modCmd,
00947                          indexVal, 0x0000, 0, modCmd_usbTimeout);
00948 }
00949 
00950 
00951 
00952 //-------------------------------------------------------------------------------------
00953 //
00954 // Communication command methods.
00955 //
00956 
00957 void LOW_linkDS2490::comCmd_setDuration( const uint8_t inTimeFactor,
00958                                          const bool inSpecifyProgPulse,
00959                                          const resultHandling_t inResultHandling,
00960                                          const bool inImmediateExec)
00961 {
00962   // locking done in publicly accessible methods
00963 
00964   LOW_portUsbDevice::wValue_t valueCmd = setDuration_comCmdBase;
00965   if ( inSpecifyProgPulse ) valueCmd |= TYPE_bitmask;
00966   handleCommonComCmdBits( valueCmd, inResultHandling, inImmediateExec);
00967 
00968   LOW_portUsbDevice::wIndex_t indexVal = 0x0000 | inTimeFactor;
00969 
00970   usbDevice->controlMsg( vendorCmd_requestType, comm_cmdType, valueCmd,
00971                          indexVal, 0x0000, 0, comCmd_usbTimeout);
00972 }
00973 
00974 
00975 void LOW_linkDS2490::comCmd_pulse( const bool inSpecifyProgPulse,
00976                                    const bool inFlushBuffersOnErr,
00977                                    const resultHandling_t inResultHandling,
00978                                    const bool inImmediateExec)
00979 {
00980   // locking done in publicly accessible methods
00981 
00982   LOW_portUsbDevice::wValue_t valueCmd = pulse_comCmdBase;
00983   if ( inSpecifyProgPulse )  valueCmd |= TYPE_bitmask;
00984   if ( inFlushBuffersOnErr ) valueCmd |= F_bitmask;
00985   handleCommonComCmdBits( valueCmd, inResultHandling, inImmediateExec);
00986 
00987   usbDevice->controlMsg( vendorCmd_requestType, comm_cmdType, valueCmd,
00988                          0x0000, 0x0000, 0, comCmd_usbTimeout);
00989 }
00990 
00991 
00992 void LOW_linkDS2490::comCmd_oneWireReset( const bool inLoopUntilPresenceDetect,
00993                                           const bool inEnableSpeedChange,
00994                                           const OWSPEED_val_t inSpeedSelector,
00995                                           const bool inFlushBuffersOnErr,
00996                                           const resultHandling_t inResultHandling,
00997                                           const bool inImmediateExec)
00998 {
00999   // locking done in publicly accessible methods
01000 
01001   LOW_portUsbDevice::wValue_t valueCmd = oneWireReset_comCmdBase;
01002   if ( inLoopUntilPresenceDetect ) valueCmd |= PST_bitmask;
01003   if ( inEnableSpeedChange )       valueCmd |= SE_bitmask;
01004   if ( inFlushBuffersOnErr )       valueCmd |= F_bitmask;
01005   handleCommonComCmdBits( valueCmd, inResultHandling, inImmediateExec);
01006 
01007   LOW_portUsbDevice::wIndex_t indexVal = 0x0000 | inSpeedSelector;
01008 
01009   usbDevice->controlMsg( vendorCmd_requestType, comm_cmdType, valueCmd,
01010                          indexVal, 0x0000, 0, comCmd_usbTimeout);
01011 }
01012 
01013 
01014 void LOW_linkDS2490::comCmd_bitIO( const bool inWriteBit,
01015                                    const bool inDoStrongPullup,
01016                                    const bool inSuppressPullupOnRead1,
01017                                    const resultHandling_t inResultHandling,
01018                                    const bool inImmediateExec)
01019 {
01020   // locking done in publicly accessible methods
01021 
01022   LOW_portUsbDevice::wValue_t valueCmd = bitIO_comCmdBase;
01023   if ( inWriteBit )              valueCmd |= D_bitmask;
01024   if ( inDoStrongPullup )        valueCmd |= SPU_bitmask;
01025   if ( inSuppressPullupOnRead1 ) valueCmd |= CIB_bitmask;
01026   handleCommonComCmdBits( valueCmd, inResultHandling, inImmediateExec);
01027 
01028   usbDevice->controlMsg( vendorCmd_requestType, comm_cmdType, valueCmd,
01029                          0x0000, 0x0000, 0, comCmd_usbTimeout);
01030 }
01031 
01032 
01033 void LOW_linkDS2490::comCmd_byteIO( const uint8_t inWriteByte,
01034                                     const bool inDoStrongPullup,
01035                                     const resultHandling_t inResultHandling,
01036                                     const bool inImmediateExec)
01037 {
01038   // locking done in publicly accessible methods
01039 
01040   LOW_portUsbDevice::wValue_t valueCmd = byteIO_comCmdBase;
01041   if ( inDoStrongPullup ) valueCmd |= SPU_bitmask;
01042   handleCommonComCmdBits( valueCmd, inResultHandling, inImmediateExec);
01043 
01044   LOW_portUsbDevice::wIndex_t indexVal = 0x0000 | inWriteByte;
01045 
01046   usbDevice->controlMsg( vendorCmd_requestType, comm_cmdType, valueCmd,
01047                          indexVal, 0x0000, 0, comCmd_usbTimeout);
01048 }
01049 
01050 
01051 void LOW_linkDS2490::comCmd_blockIO( const uint16_t inWriteSize,
01052                                      const bool inBusResetBefore,
01053                                      const bool inDoStrongPullup,
01054                                      const resultHandling_t inResultHandling,
01055                                      const bool inImmediateExec)
01056 {
01057   // locking done in publicly accessible methods
01058 
01059   LOW_portUsbDevice::wValue_t valueCmd = blockIO_comCmdBase;
01060   if ( inBusResetBefore ) valueCmd |= RST_bitmask;
01061   if ( inDoStrongPullup ) valueCmd |= SPU_bitmask;
01062   handleCommonComCmdBits( valueCmd, inResultHandling, inImmediateExec);
01063 
01064   LOW_portUsbDevice::wIndex_t indexVal = inWriteSize;
01065 
01066   usbDevice->controlMsg( vendorCmd_requestType, comm_cmdType, valueCmd,
01067                          indexVal, 0x0000, 0, comCmd_usbTimeout);
01068 }
01069 
01070 
01071 void LOW_linkDS2490::comCmd_matchAccess( const uint8_t inMatchCommand,
01072                                          const bool inBusResetBefore,
01073                                          const bool inEnableSpeedChange,
01074                                          const OWSPEED_val_t inSpeedSelector,
01075                                          const resultHandling_t inResultHandling,
01076                                          const bool inImmediateExec)
01077 {
01078   // locking done in publicly accessible methods
01079 
01080   LOW_portUsbDevice::wValue_t valueCmd = matchAccess_comCmdBase;
01081   if ( inBusResetBefore )    valueCmd |= RST_bitmask;
01082   if ( inEnableSpeedChange ) valueCmd |= SE_bitmask;
01083   handleCommonComCmdBits( valueCmd, inResultHandling, inImmediateExec);
01084 
01085   LOW_portUsbDevice::wIndex_t indexVal = ((inSpeedSelector&0xff)<<8) | (inMatchCommand&0xff);
01086 
01087   usbDevice->controlMsg( vendorCmd_requestType, comm_cmdType, valueCmd,
01088                          indexVal, 0x0000, 0, comCmd_usbTimeout);
01089 }
01090 
01091 
01092 void LOW_linkDS2490::comCmd_readStraight( const uint8_t inWritePreambleSize,
01093                                           const uint16_t inReadSize,
01094                                           const bool inBusResetBefore,
01095                                           const resultHandling_t inResultHandling,
01096                                           const bool inImmediateExec)
01097 {
01098   // locking done in publicly accessible methods
01099 
01100   LOW_portUsbDevice::wValue_t valueCmd = readStraight_comCmdBase;
01101   if ( inBusResetBefore ) valueCmd = 0x0000 | ((inWritePreambleSize&0xff)<<8);
01102 
01103   // special bit positions for this command
01104   switch ( inResultHandling ) {
01105     case noResult_rsltHdl:      valueCmd |= 0x0004; break;  // NTF=x  ICP=1
01106     case resultOnError_rsltHdl:                     break;  // NTF=0  ICP=0
01107     case resultAlways_rsltHdl:  valueCmd |= 0x0008; break;  // NTF=1  ICP=0
01108     default :                   throw internal_error( "Unknown resultHandling_t value detected", __FILE__, __LINE__);
01109   }
01110   if ( inBusResetBefore )       valueCmd |= 0x0002;  // RST=1
01111   if ( inImmediateExec )        valueCmd |= 0x0001;  // IM=1
01112   
01113   LOW_portUsbDevice::wIndex_t indexVal = inReadSize;
01114 
01115   LOW_portUsbDevice::wLength_t lengthVal = 0x0000 | inWritePreambleSize;
01116 
01117   usbDevice->controlMsg( vendorCmd_requestType, comm_cmdType, valueCmd,
01118                          indexVal, lengthVal, 0, comCmd_usbTimeout);
01119 }
01120 
01121 
01122 void LOW_linkDS2490::comCmd_doAndRelease( const uint8_t inWritePreambleSize,
01123                                           const bool inDoReadOperation,
01124                                           const bool inDoStrongPullup,
01125                                           const bool inFlushBuffersOnErr,
01126                                           const resultHandling_t inResultHandling,
01127                                           const bool inImmediateExec)
01128 {
01129   // locking done in publicly accessible methods
01130 
01131   LOW_portUsbDevice::wValue_t valueCmd = doAndRelease_comCmdBase;
01132   if ( inDoReadOperation )   valueCmd |= R_bitmask;
01133   if ( inDoStrongPullup )    valueCmd |= SPU_bitmask;
01134   if ( inFlushBuffersOnErr ) valueCmd |= F_bitmask;
01135   handleCommonComCmdBits( valueCmd, inResultHandling, inImmediateExec);
01136 
01137   LOW_portUsbDevice::wIndex_t indexVal = 0x0000 | inWritePreambleSize;
01138 
01139   usbDevice->controlMsg( vendorCmd_requestType, comm_cmdType, valueCmd,
01140                          indexVal, 0x0000, 0, comCmd_usbTimeout);
01141 }
01142 
01143 
01144 void LOW_linkDS2490::comCmd_setPath( const uint8_t inPreloadPathSize,
01145                                      const bool inBusResetBefore,
01146                                      const bool inFlushBuffersOnErr,
01147                                      const resultHandling_t inResultHandling,
01148                                      const bool inImmediateExec)
01149 {
01150   // locking done in publicly accessible methods
01151 
01152   LOW_portUsbDevice::wValue_t valueCmd = setPath_comCmdBase;
01153   if ( inBusResetBefore )    valueCmd |= RST_bitmask;
01154   if ( inFlushBuffersOnErr ) valueCmd |= F_bitmask;
01155   handleCommonComCmdBits( valueCmd, inResultHandling, inImmediateExec);
01156 
01157   LOW_portUsbDevice::wIndex_t indexVal = 0x0000 | inPreloadPathSize;
01158 
01159   usbDevice->controlMsg( vendorCmd_requestType, comm_cmdType, valueCmd,
01160                          indexVal, 0x0000, 0, comCmd_usbTimeout);
01161 }
01162 
01163 
01164 void LOW_linkDS2490::comCmd_writeSramPage( const uint8_t inWriteSize,
01165                                            const bool inShortPreambleSize,
01166                                            const bool inActivateCrc16,
01167                                            const bool inFlushBuffersOnErr,
01168                                            const resultHandling_t inResultHandling,
01169                                            const bool inImmediateExec)
01170 {
01171   // locking done in publicly accessible methods
01172 
01173   LOW_portUsbDevice::wValue_t valueCmd = writeSramPage_comCmdBase;
01174   if ( inShortPreambleSize ) valueCmd |= PS_bitmask;
01175   if ( inActivateCrc16 )     valueCmd |= DT_bitmask;
01176   if ( inFlushBuffersOnErr ) valueCmd |= F_bitmask;
01177   handleCommonComCmdBits( valueCmd, inResultHandling, inImmediateExec);
01178 
01179   LOW_portUsbDevice::wIndex_t indexVal = 0x0000 | inWriteSize;
01180 
01181   usbDevice->controlMsg( vendorCmd_requestType, comm_cmdType, valueCmd,
01182                          indexVal, 0x0000, 0, comCmd_usbTimeout);
01183 }
01184 
01185 
01186 void LOW_linkDS2490::comCmd_writeEprom( const uint16_t inWriteSize,
01187                                         const bool inActivateCrc16,
01188                                         const bool inCheck0BitsOnly,
01189                                         const bool inFlushBuffersOnErr,
01190                                         const resultHandling_t inResultHandling,
01191                                         const bool inImmediateExec)
01192 {
01193   // locking done in publicly accessible methods
01194 
01195   LOW_portUsbDevice::wValue_t valueCmd = writeEprom_comCmdBase;
01196   if ( inActivateCrc16 )     valueCmd |= DT_bitmask;
01197   if ( inCheck0BitsOnly )    valueCmd |= Z_bitmask;
01198   if ( inFlushBuffersOnErr ) valueCmd |= F_bitmask;
01199   handleCommonComCmdBits( valueCmd, inResultHandling, inImmediateExec);
01200 
01201   LOW_portUsbDevice::wIndex_t indexVal = inWriteSize;
01202 
01203   usbDevice->controlMsg( vendorCmd_requestType, comm_cmdType, valueCmd,
01204                          indexVal, 0x0000, 0, comCmd_usbTimeout);
01205 }
01206 
01207 
01208 void LOW_linkDS2490::comCmd_readCrcProtPage( const uint8_t inPageCount,
01209                                              const uint8_t inPageSizeLog2,
01210                                              const bool inShortPreambleSize,
01211                                              const bool inActivateCrc16,
01212                                              const bool inFlushBuffersOnErr,
01213                                              const resultHandling_t inResultHandling,
01214                                              const bool inImmediateExec)
01215 {
01216   // locking done in publicly accessible methods
01217 
01218   LOW_portUsbDevice::wValue_t valueCmd = readCrcProtPage_comCmdBase;
01219   if ( inShortPreambleSize ) valueCmd |= PS_bitmask;
01220   if ( inActivateCrc16 )     valueCmd |= DT_bitmask;
01221   if ( inFlushBuffersOnErr ) valueCmd |= F_bitmask;
01222   handleCommonComCmdBits( valueCmd, inResultHandling, inImmediateExec);
01223 
01224   LOW_portUsbDevice::wIndex_t indexVal = ((inPageCount&0xff)<<8) | (inPageSizeLog2&0xff);
01225 
01226   usbDevice->controlMsg( vendorCmd_requestType, comm_cmdType, valueCmd,
01227                          indexVal, 0x0000, 0, comCmd_usbTimeout);
01228 }
01229 
01230 
01231 void LOW_linkDS2490::comCmd_readRedirectPageCrc( const uint8_t inPageNumber,
01232                                                  const uint8_t inPageSize,
01233                                                  const bool inFollowRedirect,
01234                                                  const bool inFlushBuffersOnErr,
01235                                                  const resultHandling_t inResultHandling,
01236                                                  const bool inImmediateExec)
01237 {
01238   // locking done in publicly accessible methods
01239 
01240   LOW_portUsbDevice::wValue_t valueCmd = readRedirectPageCrc_comCmdBase;
01241   if ( inFollowRedirect )    valueCmd |= CH_bitmask;
01242   if ( inFlushBuffersOnErr ) valueCmd |= F_bitmask;
01243   handleCommonComCmdBits( valueCmd, inResultHandling, inImmediateExec);
01244 
01245   LOW_portUsbDevice::wIndex_t indexVal = ((inPageNumber&0xff)<<8) | (inPageSize&0xff);
01246 
01247   usbDevice->controlMsg( vendorCmd_requestType, comm_cmdType, valueCmd,
01248                          indexVal, 0x0000, 0, comCmd_usbTimeout);
01249 }
01250 
01251 
01252 void LOW_linkDS2490::comCmd_searchAccess( const uint8_t inMaxDevNum,
01253                                           const uint8_t inSearchCommand,
01254                                           const bool inSearchWithoutFullAccess,
01255                                           const bool inReturnDiscrepancyInfo,
01256                                           const bool inBusResetBefore,
01257                                           const bool inFlushBuffersOnErr,
01258                                           const resultHandling_t inResultHandling,
01259                                           const bool inImmediateExec)
01260 {
01261   // locking done in publicly accessible methods
01262 
01263   LOW_portUsbDevice::wValue_t valueCmd = searchAccess_comCmdBase;
01264   if ( inSearchWithoutFullAccess ) valueCmd |= SM_bitmask;
01265   if ( inReturnDiscrepancyInfo )   valueCmd |= RTS_bitmask;
01266   if ( inBusResetBefore )          valueCmd |= RST_bitmask;
01267   if ( inFlushBuffersOnErr )       valueCmd |= F_bitmask;
01268   handleCommonComCmdBits( valueCmd, inResultHandling, inImmediateExec);
01269 
01270   LOW_portUsbDevice::wIndex_t indexVal = ((inMaxDevNum&0xff)<<8) | (inSearchCommand&0xff);
01271 
01272   usbDevice->controlMsg( vendorCmd_requestType, comm_cmdType, valueCmd,
01273                          indexVal, 0x0000, 0, comCmd_usbTimeout);
01274 }
01275 
01276 
01277 void LOW_linkDS2490::handleCommonComCmdBits( LOW_portUsbDevice::wValue_t &inOutValueCmd,
01278                                              const resultHandling_t inResultHandling, const bool inImmediateExec)
01279 {
01280   // locking done in publicly accessible methods
01281 
01282   // special bit positions for this command
01283   switch ( inResultHandling ) {
01284     case noResult_rsltHdl:      inOutValueCmd |= ICP_bitmask; break;  // NTF=x  ICP=1
01285     case resultOnError_rsltHdl:                               break;  // NTF=0  ICP=0
01286     case resultAlways_rsltHdl:  inOutValueCmd |= NTF_bitmask; break;  // NTF=1  ICP=0
01287     default :                   throw internal_error( "Unknown resultHandling_t value detected", __FILE__, __LINE__);
01288   }
01289   if ( inImmediateExec )        inOutValueCmd |= IM_bitmask;  // IM=1
01290 }
01291 
01292 
01293 
01294 
01295 //-------------------------------------------------------------------------------------
01296 //
01297 // Enumeration type conversion methods
01298 //
01299 
01300 const LOW_linkDS2490::pdSlewRate_t LOW_linkDS2490::PDSR_val_2_pdSlewRate( const PDSR_val_t inPDSR_val) const
01301 {
01302   // fully const, no locking necessary
01303 
01304   switch( inPDSR_val ) {
01305     case PDSR_15:   return pdSlewRate_15;
01306     case PDSR_2_2:  return pdSlewRate_2_2;
01307     case PDSR_1_65: return pdSlewRate_1_65;
01308     case PDSR_1_37: return pdSlewRate_1_37;
01309     case PDSR_1_1:  return pdSlewRate_1_1;
01310     case PDSR_0_83: return pdSlewRate_0_83;
01311     case PDSR_0_7:  return pdSlewRate_0_7;
01312     case PDSR_0_55: return pdSlewRate_0_55;
01313     default:           throw internal_error( "Unknown PDSR_val_t value detected", __FILE__, __LINE__);
01314   }
01315 }
01316 
01317 const LOW_linkDS2490::PDSR_val_t LOW_linkDS2490::pdSlewRate_2_PDSR_val( const pdSlewRate_t inPdSlewRate_t) const
01318 {
01319   // fully const, no locking necessary
01320 
01321   switch( inPdSlewRate_t ) {
01322     case pdSlewRate_15:    return PDSR_15;
01323     case pdSlewRate_2_2:   return PDSR_2_2;
01324     case pdSlewRate_1_65:  return PDSR_1_65;
01325     case pdSlewRate_1_37:  return PDSR_1_37;
01326     case pdSlewRate_1_1:   return PDSR_1_1;
01327     case pdSlewRate_0_83:  return PDSR_0_83;
01328     case pdSlewRate_0_7:   return PDSR_0_7;
01329     case pdSlewRate_0_55:  return PDSR_0_55;
01330     default:           throw internal_error( "Unknown pdSlewRate_t value detected", __FILE__, __LINE__);
01331   }
01332 }
01333 
01334 
01335 const LOW_linkDS2490::w1LowTime_t LOW_linkDS2490::W1LT_val_2_w1LowTime( const W1LT_val_t inW1LT_val) const
01336 {
01337   // fully const, no locking necessary
01338 
01339   switch( inW1LT_val ) {
01340     case W1LT_8:  return w1LowTime_8;
01341     case W1LT_9:  return w1LowTime_9;
01342     case W1LT_10: return w1LowTime_10;
01343     case W1LT_11: return w1LowTime_11;
01344     case W1LT_12: return w1LowTime_12;
01345     case W1LT_13: return w1LowTime_13;
01346     case W1LT_14: return w1LowTime_14;
01347     case W1LT_15: return w1LowTime_15;
01348     default:      throw internal_error( "Unknown W1LT_val_t value detected", __FILE__, __LINE__);
01349   }
01350 }
01351 
01352 const LOW_linkDS2490::W1LT_val_t LOW_linkDS2490::w1LowTime_2_W1LT_val( const w1LowTime_t inW1LowTime) const
01353 {
01354   // fully const, no locking necessary
01355 
01356   switch( inW1LowTime ) {
01357     case w1LowTime_8:  return W1LT_8;
01358     case w1LowTime_9:  return W1LT_9;
01359     case w1LowTime_10: return W1LT_10;
01360     case w1LowTime_11: return W1LT_11;
01361     case w1LowTime_12: return W1LT_12;
01362     case w1LowTime_13: return W1LT_13;
01363     case w1LowTime_14: return W1LT_14;
01364     case w1LowTime_15: return W1LT_15;
01365     default:           throw internal_error( "Unknown w1LowTime_t value detected", __FILE__, __LINE__);
01366   }
01367 }
01368 
01369 
01370 const LOW_linkDS2490::soW0RecTime_t LOW_linkDS2490::SOW0RT_val_2_soW0RecTime( const SOW0RT_val_t inSOW0RT_val) const
01371 {
01372   // fully const, no locking necessary
01373 
01374   switch( inSOW0RT_val ) {
01375     case SOW0RT_3:  return soW0RecTime_3;
01376     case SOW0RT_4:  return soW0RecTime_4;
01377     case SOW0RT_5:  return soW0RecTime_5;
01378     case SOW0RT_6:  return soW0RecTime_6;
01379     case SOW0RT_7:  return soW0RecTime_7;
01380     case SOW0RT_8:  return soW0RecTime_8;
01381     case SOW0RT_9:  return soW0RecTime_9;
01382     case SOW0RT_10: return soW0RecTime_10;
01383     default:        throw internal_error( "Unknown SOW0RT_val_t value detected", __FILE__, __LINE__);
01384   }
01385 }
01386 
01387 const LOW_linkDS2490::SOW0RT_val_t LOW_linkDS2490::soW0RecTime_2_SOW0RT_val( const soW0RecTime_t inSoW0RecTime) const
01388 {
01389   // fully const, no locking necessary
01390 
01391   switch( inSoW0RecTime ) {
01392     case soW0RecTime_3:  return SOW0RT_3;
01393     case soW0RecTime_4:  return SOW0RT_4;
01394     case soW0RecTime_5:  return SOW0RT_5;
01395     case soW0RecTime_6:  return SOW0RT_6;
01396     case soW0RecTime_7:  return SOW0RT_7;
01397     case soW0RecTime_8:  return SOW0RT_8;
01398     case soW0RecTime_9:  return SOW0RT_9;
01399     case soW0RecTime_10: return SOW0RT_10;
01400     default:             throw internal_error( "Unknown soW0RecTime_t value detected", __FILE__, __LINE__);
01401   }
01402 }
01403 
01404 
01405 const LOW_linkDS2490::wireSpeed_t LOW_linkDS2490::OWSPEED_val_2_wireSpeed( const OWSPEED_val_t inOWSPEED_val) const
01406 {
01407   // fully const, no locking necessary
01408 
01409   switch( inOWSPEED_val ) {
01410     case normal_OWSPEED:    return normal_speed;
01411     case flexible_OWSPEED:  return flexible_speed;
01412     case overdrive_OWSPEED: return overdrive_speed;
01413     default:                throw internal_error( "Unknown OWSPEED_val_t value detected", __FILE__, __LINE__);
01414   }
01415 }
01416 
01417 const LOW_linkDS2490::OWSPEED_val_t LOW_linkDS2490::wireSpeed_2_OWSPEED_val( const wireSpeed_t inWireSpeed) const
01418 {
01419   // fully const, no locking necessary
01420 
01421   switch( inWireSpeed ) {
01422     case normal_speed:    return normal_OWSPEED;
01423     case flexible_speed:  return flexible_OWSPEED;
01424     case overdrive_speed: return overdrive_OWSPEED;
01425     default:              throw internal_error( "Unknown wireSpeed_t value detected", __FILE__, __LINE__);
01426   }
01427 }
01428 
01429 
01430 const uint8_t LOW_linkDS2490::strongPullup_2_spFactor( const strongPullup_t inPullup) const
01431 {
01432   // fully const, no locking necessary
01433 
01434   switch( inPullup ) {
01435     case pullUp_16_4:  return  1;
01436     case pullUp_65_5:  return  4;
01437     case pullUp_131:   return  8;
01438     case pullUp_262:   return 16;
01439     case pullUp_524:   return 32;
01440     case pullUp_1048:  return 64;
01441     default:           throw internal_error( "Unknown strongPullup_t value detected", __FILE__, __LINE__);
01442   }
01443 }
01444 
01445 
01446 const uint8_t LOW_linkDS2490::progPulse_2_ppFactor( const progPulse_t inPulse) const
01447 {
01448   // fully const, no locking necessary
01449 
01450   switch( inPulse ) {
01451     case progPulse_32:   return   4;
01452     case progPulse_64:   return   8;
01453     case progPulse_128:  return  16;
01454     case progPulse_256:  return  32;
01455     case progPulse_512:  return  64;
01456     case progPulse_1024: return 128;
01457     case progPulse_2048: return 254;
01458     default:             throw internal_error( "Unknown progPulse_t value detected", __FILE__, __LINE__);
01459   }
01460 }
01461 

Generated on Mon Nov 10 10:32:26 2003 by doxygen1.2.13.1 written by Dimitri van Heesch, © 1997-2001