00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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
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
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
00060
00061
00062 LOW_devDS2406::LOW_devDS2406( LOW_netSegment &inSegment, const LOW_deviceID &inDevID) :
00063 LOW_device( inSegment, inDevID, familyCode)
00064 {
00065
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
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
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
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
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
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
00163 if ( inStartAddr<=0x04 )
00164 throw devDS2406_error( "Access to address not supported in this version", __FILE__, __LINE__);
00165
00166 linkLock lock( *this);
00167
00168
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);
00182 expectedCrc16 |= (getLink().readDataByte() ^ 0xff) << 8;
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
00189
00190
00191 getLink().resetBus();
00192 }
00193
00194
00195
00196
00197
00198
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 ) {
00223 uint16_t expectedCrc16 = 0x0000;
00224 expectedCrc16 |= (getLink().readDataByte() ^ 0xff);
00225 expectedCrc16 |= (getLink().readDataByte() ^ 0xff) << 8;
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
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
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;
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
00289
00290 device.getLink().resetBus();
00291 }
00292
00293
00294
00295
00296
00297
00298 LOW_devDS2406::cmd_ChannelAccess::channelInfo_t& LOW_devDS2406::cmd_ChannelAccess::getChannelInfo()
00299 {
00300
00301 return channelInfo;
00302 }
00303
00304 bool LOW_devDS2406::cmd_ChannelAccess::readDataBit() const
00305 {
00306
00307 return device.getLink().readDataBit();
00308 }
00309
00310 uint8_t LOW_devDS2406::cmd_ChannelAccess::readDataByte() const
00311 {
00312
00313 return device.getLink().readDataByte();
00314 }
00315
00316 void LOW_devDS2406::cmd_ChannelAccess::readData( byteVec_t &outBytes) const
00317 {
00318
00319 device.getLink().readData( outBytes);
00320 }
00321
00322 void LOW_devDS2406::cmd_ChannelAccess::writeData( const bool inSendBit) const
00323 {
00324
00325 device.getLink().writeData( inSendBit);
00326 }
00327
00328 void LOW_devDS2406::cmd_ChannelAccess::writeData( const uint8_t inSendByte) const
00329 {
00330
00331 device.getLink().writeData( inSendByte);
00332 }
00333
00334 void LOW_devDS2406::cmd_ChannelAccess::writeData( const byteVec_t &inSendBytes) const
00335 {
00336
00337 device.getLink().writeData( inSendBytes);
00338 }