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

LOW_devDS2406.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           LOW_devDS2406.cpp  -  description
00003                              -------------------
00004     begin                : Fri Aug 23 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 
00020 #include "LOW_devDS2406.h"
00021 #include "LOW_platformMisc.h"
00022 #include "LOW_helper_msglog.h"
00023 #include "LOW_deviceFactory.h"
00024 #include "LOW_netSegment.h"
00025 #include "LOW_helper_crc.h"
00026 
00027 
00028 
00029 //=====================================================================================
00030 //
00031 // static initializer
00032 //
00033 
00034 const std::string LOW_devDS2406::familyName = "DS2406";
00035 
00036 int LOW_devDS2406::initHelper = initialize();
00037 int LOW_devDS2406::initialize()
00038 {
00039   LOW_deviceFactory::registerSpecificCtor( familyCode, &LOW_devDS2406::new_Instance);
00040   return 0;
00041 }
00042         
00043 
00044         
00045 //=====================================================================================
00046 //
00047 // static methods
00048 //
00049   
00050 LOW_device* LOW_devDS2406::new_Instance( LOW_netSegment &inNetSegment, const LOW_deviceID &inDevID)
00051 {
00052   return new LOW_devDS2406( inNetSegment, inDevID);
00053 }
00054 
00055 
00056 
00057 //=====================================================================================
00058 //
00059 // constructors
00060 //
00061 
00062 LOW_devDS2406::LOW_devDS2406( LOW_netSegment &inSegment, const LOW_deviceID &inDevID) : 
00063   LOW_device( inSegment, inDevID, familyCode)
00064 {
00065   // reset latches and get basic information
00066   cmd_ChannelAccess infoGet = cmd_ChannelAccess( *this,
00067                                                  cmd_ChannelAccess::CRC_disable, chanASelect,
00068                                                  cmd_ChannelAccess::asyncInterleaveMode, 
00069                                                  cmd_ChannelAccess::noToggleMode, cmd_ChannelAccess::readMode, 
00070                                                  cmd_ChannelAccess::resetLatches);
00071   cmd_ChannelAccess::channelInfo_t info = infoGet.getChannelInfo();
00072   isExternalPowered = info.isExternalPowered;
00073   hasPioB           = info.hasPioB;
00074 }
00075 
00076 
00077 LOW_devDS2406::~LOW_devDS2406()
00078 {
00079 }
00080 
00081 
00082 //=====================================================================================
00083 //
00084 // methods
00085 //
00086 
00087 bool LOW_devDS2406::getIsExternalPowered() const
00088 {
00089   return isExternalPowered;
00090 }
00091 
00092 
00093 bool LOW_devDS2406::getHasPioB() const
00094 {
00095   return hasPioB;
00096 }
00097 
00098 
00099 void LOW_devDS2406::getSearchCondition( LOW_devDS2406::statusRegister_t *outStatusRegister) const
00100 {
00101   // locking done by cmd_ReadStatus()
00102 
00103   byteVec_t  condReg = byteVec_t( 1);
00104 
00105   cmd_ReadStatus( 0x07, condReg);
00106   
00107   outStatusRegister->activePolarity    = static_cast<activePolarity_t>(condReg[0]&0x01);
00108   outStatusRegister->sourceSelect      = static_cast<sourceSelect_t>((condReg[0]>>1)&0x03);
00109   outStatusRegister->channelSelect     = static_cast<chanSelect_t>((condReg[0]>>3)&0x03);
00110   outStatusRegister->channelFFQ_pioA   = static_cast<pioTransistor_t>((condReg[0]>>5)&0x01);
00111   outStatusRegister->channelFFQ_pioB   = static_cast<pioTransistor_t>((condReg[0]>>6)&0x01);
00112   outStatusRegister->isExternalPowered = (condReg[0]>>7)&0x01;
00113 }
00114 
00115   
00116 void LOW_devDS2406::setSearchCondition( const LOW_devDS2406::chanSelect_t inChanSelect, 
00117                                         const LOW_devDS2406::sourceSelect_t inSourceSelect, 
00118                                         const LOW_devDS2406::activePolarity_t inPolaritySelect,
00119                                         const LOW_devDS2406::pioTransistor_t inPioATrans, 
00120                                         const LOW_devDS2406::pioTransistor_t inPioBTrans) const
00121 {
00122   if ( ! getHasPioB() && ( inChanSelect==chanBSelect || inChanSelect==chanBothSelect ) )
00123     throw devDS2406_error( "Channel B selected, but device has only PIO A", __FILE__, __LINE__);
00124 
00125   // locking done by cmd_WriteStatus()
00126 
00127   byteVec_t  condReg = byteVec_t( 1);
00128 
00129   condReg[0] = 0;
00130   condReg[0] |= inPolaritySelect;
00131   condReg[0] |= inSourceSelect<<1;
00132   condReg[0] |= inChanSelect<<3;
00133   condReg[0] |= inPioATrans<<5;
00134   condReg[0] |= inPioBTrans<<6;
00135 
00136   cmd_WriteStatus( 0x07, condReg);
00137 }
00138 
00139 
00140 void LOW_devDS2406::cmd_ReadMemory( const uint8_t inStartAddr, byteVec_t &outBytes) const
00141 {
00142   // locking done by readMemUniversal()
00143   readMemUniversal( inStartAddr, outBytes, 128, ReadMemory_COMMAND);
00144 }
00145 
00146     
00147 void LOW_devDS2406::cmd_ReadStatus( const uint8_t inStartAddr, byteVec_t &outBytes) const
00148 {
00149   // locking done by readMemUniversal()
00150   readMemUniversal( inStartAddr, outBytes, 8, ReadStatus_COMMAND);
00151 }
00152 
00153 
00154 void LOW_devDS2406::cmd_WriteStatus( const uint8_t inStartAddr, const byteVec_t &inWriteBytes) const
00155 {
00156   if ( inStartAddr+inWriteBytes.size() > 8 )
00157     throw devDS2406_error( "Too many bytes to write", __FILE__, __LINE__);
00158   
00159   if ( inStartAddr==0x05 || inStartAddr==0x06 )
00160     throw devDS2406_error( "Address not writeable", __FILE__, __LINE__);
00161   
00162   // not yet supported registers
00163   if ( /*inStartAddr>=0x00 &&*/ inStartAddr<=0x04 )
00164     throw devDS2406_error( "Access to address not supported in this version", __FILE__, __LINE__);
00165   
00166   linkLock  lock( *this);
00167 
00168   // only address 7 remains, i.e. address must be 7 and length of inWriteBytes is 1
00169   
00170   byteVec_t  sendBytes = byteVec_t( 4);
00171   sendBytes[0] = WriteStatus_COMMAND;
00172   sendBytes[1] = inStartAddr&0xff;
00173   sendBytes[2] = inStartAddr>>8;
00174   sendBytes[3] = inWriteBytes[0];
00175   
00176   cmd_MatchROM();
00177 
00178   getLink().writeData( sendBytes);
00179     
00180   uint16_t expectedCrc16 = 0x0000;
00181   expectedCrc16 |= (getLink().readDataByte() ^ 0xff);      // NOTE: CRC bytzes are sent _inverted_!
00182   expectedCrc16 |= (getLink().readDataByte() ^ 0xff) << 8; // NOTE: CRC bytzes are sent _inverted_!
00183   if ( LOW_helper_CRC::calcCRC16( sendBytes) != expectedCrc16 )
00184     throw LOW_helper_CRC::crc_error( "CRC error in write operation", __FILE__, __LINE__);
00185 
00186   getLink().writeData( static_cast<uint8_t>(0xff));
00187 
00188   // skip validation byte
00189   //uint8_t validationByte = getLink().readDataByte();
00190 
00191   getLink().resetBus();
00192 }
00193 
00194 
00195 
00196 //=====================================================================================
00197 //
00198 // protected methods
00199 //
00200 
00201 void LOW_devDS2406::readMemUniversal( const uint16_t inStartAddr, byteVec_t &outBytes, 
00202                                       const uint16_t inMaxLen, const owCommand_t inCommand) const
00203 {
00204   if ( inStartAddr >= inMaxLen )
00205     throw devDS2406_error( "Illegal address to read", __FILE__, __LINE__);
00206   
00207   if ( inStartAddr+outBytes.size() > inMaxLen )
00208     throw devDS2406_error( "Too many bytes to read", __FILE__, __LINE__);
00209 
00210   linkLock  lock( *this);
00211     
00212   byteVec_t  sendBytes = byteVec_t( 3);
00213   sendBytes[0] = inCommand;
00214   sendBytes[1] = inStartAddr&0xff;
00215   sendBytes[2] = inStartAddr>>8;
00216   
00217   cmd_MatchROM();
00218 
00219   getLink().writeData( sendBytes);
00220   getLink().readData( outBytes);
00221   
00222   if ( inStartAddr+outBytes.size() == inMaxLen ) { // read to end of mem => CRC16 checksumm is available
00223     uint16_t expectedCrc16 = 0x0000;
00224     expectedCrc16 |= (getLink().readDataByte() ^ 0xff);      // NOTE: CRC bytzes are sent _inverted_!
00225     expectedCrc16 |= (getLink().readDataByte() ^ 0xff) << 8; // NOTE: CRC bytzes are sent _inverted_!
00226     if ( LOW_helper_CRC::calcCRC16( outBytes, LOW_helper_CRC::calcCRC16( sendBytes)) != expectedCrc16 )
00227       throw LOW_helper_CRC::crc_error( "CRC error in read operation", __FILE__, __LINE__);
00228   }
00229 
00230   getLink().resetBus();
00231 }
00232 
00233 
00234 
00235 //=====================================================================================
00236 //
00237 // class cmd_ChannelAccess
00238 //
00239 
00240 LOW_devDS2406::cmd_ChannelAccess::cmd_ChannelAccess( 
00241     const LOW_devDS2406 &inDevice,
00242     const CRCtype_t inCRCtype, const chanSelect_t inChanSelect, 
00243     const interleaveMode_t inInterleaveMode, const toggleMode_t inToggleMode, 
00244     const initialMode_t inInitialMode, const activityLatchReset_t inALR) :
00245   linkLock( inDevice),
00246   device( inDevice)
00247 {
00248   // locking done by initializer
00249 
00250   if ( inChanSelect == noneSelect )
00251     throw devDS2406_error( "At least one channel must be selected", __FILE__, __LINE__);
00252 
00253   if ( ! device.getHasPioB() && ( inChanSelect==chanBSelect || inChanSelect==chanBothSelect ) )
00254     throw devDS2406_error( "Channel B selected, but device has only PIO A", __FILE__, __LINE__);
00255 
00256   if ( inChanSelect!=chanBothSelect && inInterleaveMode )
00257     throw devDS2406_error( "Interleave mode only available when selected both channels", __FILE__, __LINE__);
00258 
00259   byteVec_t  outBytes = byteVec_t( 3);
00260   outBytes[0] =  ChannelAccess_COMMAND;
00261   outBytes[1] =  (inCRCtype&0x3)                  |
00262                  ((inChanSelect&0x3)<<2)          |
00263                  ((static_cast<uint8_t>(inInterleaveMode))<<4) |
00264                  ((static_cast<uint8_t>(inToggleMode))<<5)     |
00265                  ((static_cast<uint8_t>(inInitialMode))<<6)    |
00266                  ((static_cast<int8_t>(inALR))<<7);
00267   outBytes[2] =  0xff;  // reserved, 0xff sent as specified
00268   
00269   
00270   device.cmd_MatchROM();
00271   device.getLink().writeData( outBytes);
00272   
00273   uint8_t infoByte = device.getLink().readDataByte();
00274 
00275   channelInfo.channelFFQ_pioA    = (infoByte>>0)&0x01;
00276   channelInfo.channelFFQ_pioB    = (infoByte>>1)&0x01;
00277   channelInfo.sensedLevel_pioA   = (infoByte>>2)&0x01;
00278   channelInfo.sensedLevel_pioB   = (infoByte>>3)&0x01;
00279   channelInfo.activityLatch_pioA = (infoByte>>4)&0x01;
00280   channelInfo.activityLatch_pioB = (infoByte>>5)&0x01;
00281   channelInfo.hasPioB            = (infoByte>>6)&0x01;
00282   channelInfo.isExternalPowered  = (infoByte>>7)&0x01;
00283 }
00284 
00285 
00286 LOW_devDS2406::cmd_ChannelAccess::~cmd_ChannelAccess()
00287 {
00288   // class locks device
00289   
00290   device.getLink().resetBus();
00291 }
00292 
00293     
00294 //-------------------------------------------------------------------------------------
00295 // methods
00296 //
00297 
00298 LOW_devDS2406::cmd_ChannelAccess::channelInfo_t&  LOW_devDS2406::cmd_ChannelAccess::getChannelInfo()
00299 {
00300   // class locks device
00301   return channelInfo;
00302 }
00303 
00304 bool  LOW_devDS2406::cmd_ChannelAccess::readDataBit() const
00305 { 
00306   // class locks device
00307   return device.getLink().readDataBit();
00308 }
00309 
00310 uint8_t  LOW_devDS2406::cmd_ChannelAccess::readDataByte() const
00311 {
00312   // class locks device
00313   return device.getLink().readDataByte();
00314 }
00315 
00316 void  LOW_devDS2406::cmd_ChannelAccess::readData( byteVec_t &outBytes) const
00317 {
00318   // class locks device
00319   device.getLink().readData( outBytes);
00320 }
00321 
00322 void  LOW_devDS2406::cmd_ChannelAccess::writeData( const bool inSendBit) const
00323 {
00324   // class locks device
00325   device.getLink().writeData( inSendBit);
00326 }
00327 
00328 void  LOW_devDS2406::cmd_ChannelAccess::writeData( const uint8_t inSendByte) const
00329 {
00330   // class locks device
00331   device.getLink().writeData( inSendByte);
00332 }
00333 
00334 void  LOW_devDS2406::cmd_ChannelAccess::writeData( const byteVec_t &inSendBytes) const
00335 { 
00336   // class locks device
00337   device.getLink().writeData( inSendBytes);
00338 }

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