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, 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 
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 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   byteVec_t  condReg = byteVec_t( 1);
00102 
00103   cmd_ReadStatus( (uint8_t)0x07, condReg);
00104   
00105   outStatusRegister->activePolarity    = (activePolarity_t)(condReg[0]&0x01);
00106   outStatusRegister->sourceSelect      = (sourceSelect_t)((condReg[0]>>1)&0x03);
00107   outStatusRegister->channelSelect     = (chanSelect_t)((condReg[0]>>3)&0x03);
00108   outStatusRegister->channelFFQ_pioA   = (pioTransistor_t)((condReg[0]>>5)&0x01);
00109   outStatusRegister->channelFFQ_pioB   = (pioTransistor_t)((condReg[0]>>6)&0x01);
00110   outStatusRegister->isExternalPowered = (condReg[0]>>7)&0x01;
00111 }
00112 
00113   
00114 void LOW_devDS2406::setSearchCondition( const LOW_devDS2406::chanSelect_t inChanSelect, 
00115                                         const LOW_devDS2406::sourceSelect_t inSourceSelect, 
00116                                         const LOW_devDS2406::activePolarity_t inPolaritySelect,
00117                                         const LOW_devDS2406::pioTransistor_t inPioATrans, 
00118                                         const LOW_devDS2406::pioTransistor_t inPioBTrans) const
00119 {
00120   if ( ! getHasPioB() && ( inChanSelect==chanBSelect || inChanSelect==chanBothSelect ) )
00121     throw devDS2406_error( "Channel B selected, but device has only PIO A", __FILE__, __LINE__);
00122 
00123   byteVec_t  condReg = byteVec_t( 1);
00124 
00125   condReg[0] = 0;
00126   condReg[0] |= inPolaritySelect;
00127   condReg[0] |= inSourceSelect<<1;
00128   condReg[0] |= inChanSelect<<3;
00129   condReg[0] |= inPioATrans<<5;
00130   condReg[0] |= inPioBTrans<<6;
00131 
00132   cmd_WriteStatus( (uint8_t)0x07, condReg);
00133 }
00134 
00135 
00136 void LOW_devDS2406::cmd_ReadMemory( const uint8_t inStartAddr, byteVec_t &outBytes) const
00137 {
00138   readMemUniversal( inStartAddr, outBytes, 128, ReadMemory_COMMAND);
00139 }
00140 
00141     
00142 void LOW_devDS2406::cmd_ReadStatus( const uint8_t inStartAddr, byteVec_t &outBytes) const
00143 {
00144   readMemUniversal( inStartAddr, outBytes, 8, ReadStatus_COMMAND);
00145 }
00146 
00147 
00148 void LOW_devDS2406::cmd_WriteStatus( const uint8_t inStartAddr, const byteVec_t &inWriteBytes) const
00149 {
00150   if ( inStartAddr+inWriteBytes.size() > 8 )
00151     throw devDS2406_error( "Too many bytes to write", __FILE__, __LINE__);
00152   
00153   if ( inStartAddr==0x05 || inStartAddr==0x06 )
00154     throw devDS2406_error( "Address not writeable", __FILE__, __LINE__);
00155   
00156   // not yet supported registers
00157   if ( /*inStartAddr>=0x00 &&*/ inStartAddr<=0x04 )
00158     throw devDS2406_error( "Access to address not supported in this version", __FILE__, __LINE__);
00159   
00160   // only address 7 remains, i.e. address must be 7 and length of inWriteBytes is 1
00161   
00162   byteVec_t  sendBytes = byteVec_t( 4);
00163   sendBytes[0] = WriteStatus_COMMAND;
00164   sendBytes[1] = inStartAddr&0xff;
00165   sendBytes[2] = inStartAddr>>8;
00166   sendBytes[3] = inWriteBytes[0];
00167   
00168   cmd_MatchROM();
00169 
00170   getLink().writeData( sendBytes);
00171     
00172   uint16_t expectedCrc16 = 0x0000;
00173   expectedCrc16 |= (getLink().readDataByte() ^ 0xff);      // NOTE: CRC bytzes are sent _inverted_!
00174   expectedCrc16 |= (getLink().readDataByte() ^ 0xff) << 8; // NOTE: CRC bytzes are sent _inverted_!
00175   if ( LOW_helper_CRC::calcCRC16( sendBytes) != expectedCrc16 )
00176     throw LOW_helper_CRC::crc_error( "CRC error in write operation", __FILE__, __LINE__);
00177 
00178   getLink().writeData( (uint8_t)0xff);
00179 
00180   // skip validation byte
00181   //uint8_t validationByte = getLink().readDataByte();
00182 
00183   getLink().resetBus();
00184 }
00185 
00186 
00187 
00188 //=====================================================================================
00189 //
00190 // protected methods
00191 //
00192 
00193 void LOW_devDS2406::readMemUniversal( const uint16_t inStartAddr, byteVec_t &outBytes, 
00194                                       const uint16_t inMaxLen, const owCommand_t inCommand) const
00195 {
00196   if ( inStartAddr >= inMaxLen )
00197     throw devDS2406_error( "Illegal address to read", __FILE__, __LINE__);
00198   
00199   if ( inStartAddr+outBytes.size() > inMaxLen )
00200     throw devDS2406_error( "Too many bytes to read", __FILE__, __LINE__);
00201 
00202   linkLock  lock( *this);
00203     
00204   byteVec_t  sendBytes = byteVec_t( 3);
00205   sendBytes[0] = inCommand;
00206   sendBytes[1] = inStartAddr&0xff;
00207   sendBytes[2] = inStartAddr>>8;
00208   
00209   cmd_MatchROM();
00210 
00211   getLink().writeData( sendBytes);
00212   getLink().readData( outBytes);
00213   
00214   if ( inStartAddr+outBytes.size() == inMaxLen ) { // read to end of mem => CRC16 checksumm is available
00215     uint16_t expectedCrc16 = 0x0000;
00216     expectedCrc16 |= (getLink().readDataByte() ^ 0xff);      // NOTE: CRC bytzes are sent _inverted_!
00217     expectedCrc16 |= (getLink().readDataByte() ^ 0xff) << 8; // NOTE: CRC bytzes are sent _inverted_!
00218     if ( LOW_helper_CRC::calcCRC16( outBytes, LOW_helper_CRC::calcCRC16( sendBytes)) != expectedCrc16 )
00219       throw LOW_helper_CRC::crc_error( "CRC error in read operation", __FILE__, __LINE__);
00220   }
00221 
00222   getLink().resetBus();
00223 }
00224 
00225 
00226 
00227 //=====================================================================================
00228 //
00229 // class cmd_ChannelAccess
00230 //
00231 
00232 LOW_devDS2406::cmd_ChannelAccess::cmd_ChannelAccess( 
00233     const LOW_devDS2406 &inDevice,
00234     const CRCtype_t inCRCtype, const chanSelect_t inChanSelect, 
00235     const interleaveMode_t inInterleaveMode, const toggleMode_t inToggleMode, 
00236     const initialMode_t inInitialMode, const activityLatchReset_t inALR) :
00237   linkLock( inDevice),
00238   device( inDevice)
00239 {
00240   if ( inChanSelect == noneSelect )
00241     throw devDS2406_error( "At least one channel must be selected", __FILE__, __LINE__);
00242 
00243   if ( ! device.getHasPioB() && ( inChanSelect==chanBSelect || inChanSelect==chanBothSelect ) )
00244     throw devDS2406_error( "Channel B selected, but device has only PIO A", __FILE__, __LINE__);
00245 
00246   if ( inChanSelect!=chanBothSelect && inInterleaveMode )
00247     throw devDS2406_error( "Interleave mode only available when selected both channels", __FILE__, __LINE__);
00248     
00249   byteVec_t  outBytes = byteVec_t( 3);
00250   outBytes[0] =  ChannelAccess_COMMAND;
00251   outBytes[1] =  (inCRCtype&0x3)                  |
00252                  ((inChanSelect&0x3)<<2)          |
00253                  (((uint8_t)inInterleaveMode)<<4) |
00254                  (((uint8_t)inToggleMode)<<5)     |
00255                  (((uint8_t)inInitialMode)<<6)    |
00256                  (((uint8_t)inALR)<<7);
00257   outBytes[2] =  0xff;  // reserved, 0xff sent as specified
00258   
00259   
00260   device.cmd_MatchROM();
00261   device.getLink().writeData( outBytes);
00262   
00263   uint8_t infoByte = device.getLink().readDataByte();
00264 
00265   channelInfo.channelFFQ_pioA    = (infoByte>>0)&0x01;
00266   channelInfo.channelFFQ_pioB    = (infoByte>>1)&0x01;
00267   channelInfo.sensedLevel_pioA   = (infoByte>>2)&0x01;
00268   channelInfo.sensedLevel_pioB   = (infoByte>>3)&0x01;
00269   channelInfo.activityLatch_pioA = (infoByte>>4)&0x01;
00270   channelInfo.activityLatch_pioB = (infoByte>>5)&0x01;
00271   channelInfo.hasPioB            = (infoByte>>6)&0x01;
00272   channelInfo.isExternalPowered  = (infoByte>>7)&0x01;
00273 }
00274 
00275 
00276 LOW_devDS2406::cmd_ChannelAccess::~cmd_ChannelAccess()
00277 {
00278   device.getLink().resetBus();
00279 }
00280 
00281     
00282 //-------------------------------------------------------------------------------------
00283 // methods
00284 //
00285 
00286 LOW_devDS2406::cmd_ChannelAccess::channelInfo_t&  LOW_devDS2406::cmd_ChannelAccess::getChannelInfo()
00287 {
00288   return channelInfo;
00289 }
00290 
00291 bool  LOW_devDS2406::cmd_ChannelAccess::readDataBit() const
00292 { 
00293   return device.getLink().readDataBit();
00294 }
00295 
00296 uint8_t  LOW_devDS2406::cmd_ChannelAccess::readDataByte() const
00297 {
00298   return device.getLink().readDataByte();
00299 }
00300 
00301 void  LOW_devDS2406::cmd_ChannelAccess::readData( byteVec_t &outBytes) const
00302 {
00303   device.getLink().readData( outBytes);
00304 }
00305 
00306 void  LOW_devDS2406::cmd_ChannelAccess::writeData( const bool inSendBit) const
00307 {
00308   device.getLink().writeData( inSendBit);
00309 }
00310 
00311 void  LOW_devDS2406::cmd_ChannelAccess::writeData( const uint8_t inSendByte) const
00312 {
00313   device.getLink().writeData( inSendByte);
00314 }
00315 
00316 void  LOW_devDS2406::cmd_ChannelAccess::writeData( const byteVec_t &inSendBytes) const
00317 { 
00318   device.getLink().writeData( inSendBytes);
00319 }

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