00001 /*************************************************************************** 00002 LOW_devDS2406.h - 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 #ifndef LOW_DEVDS2406_H 00019 #define LOW_DEVDS2406_H 00020 00021 00022 00023 #include "LOW_device.h" 00024 00025 00026 00027 /** Device class for DS2406 Dual Addressable Switch Plus 1 kbit Memory. 00028 00029 DS2406 features: 00030 00031 - Open drain PIO pins are controlled and their logic level can be determined 00032 over 1-Wire bus for closed-loop control 00033 - Replaces and is fully compatible with DS2407 but no user-programmable 00034 power-on settings and no Hidden Mode 00035 - PIO channel A sink capability of 50mA at 0.4V with soft turn-on; channel B 8mA at 0.4V 00036 - Maximum operating voltage of 13V at PIO-A, 6.5V at PIO-B 00037 - 1024 bits user-programmable OTP EPROM 00038 - User-programmable status memory to control the device 00039 - Multiple DS2406 can be identified on a common 1-Wire bus and be turned on or off 00040 independently of other devices on the bus 00041 - Unique, factory-lasered and tested 64-bit registration number (8-bit family code + 48-bit 00042 serial number + 8-bit CRC tester) assures error-free selection and absolute identity 00043 because no two parts are alike 00044 - On-chip CRC16 generator allows detection of data transfer errors 00045 - Built-in multidrop controller ensures compatibility with other 1-Wire net products 00046 - Reduces control, address, data, programming and power to a single data pin 00047 - Directly connects to a single port pin of a microprocessor and communicates 00048 at up to 16.3 kbits/s 00049 - Supports Conditional Search with userselectable condition 00050 - Vcc bondout for optional external supply to the device (TSOC package only) 00051 - 1-Wire communication operates over a wide voltage range of 2.8V to 6.0V from -40°C to +85°C 00052 - Low cost TO-92 or 6-pin TSOC surface mount package 00053 00054 This class is thread-safe. 00055 00056 @author Harald Roelle 00057 @author Parts of the documentation by Dallas Semiconductors / Maxim Integrated Products 00058 */ 00059 class LOW_devDS2406 : public LOW_device { 00060 00061 //======================================================================================= 00062 public: 00063 00064 //===================================================================================== 00065 // 00066 // exceptions 00067 // 00068 00069 /** Exception base class for all exceptions thrown by LOW_devDS2406. */ 00070 class_DERIVE_FROM_EXCEPTION( devDS2406_error ,LOW_exception); 00071 00072 00073 00074 //===================================================================================== 00075 // 00076 // constants 00077 // 00078 00079 /** Family code of this specific device. */ 00080 static const LOW_deviceIDRaw::devFamCode_t familyCode = 0x12; 00081 00082 /** Family name of this specific device. */ 00083 static const std::string familyName; 00084 00085 static const owCommand_t ReadMemory_COMMAND = 0xf0; /**< 1-Wire command byte constant */ 00086 static const owCommand_t ExtendedReadMemory_COMMAND = 0xa5; /**< 1-Wire command byte constant */ 00087 static const owCommand_t WriteMemory_COMMAND = 0x0f; /**< 1-Wire command byte constant */ 00088 static const owCommand_t WriteStatus_COMMAND = 0x55; /**< 1-Wire command byte constant */ 00089 static const owCommand_t ReadStatus_COMMAND = 0xaa; /**< 1-Wire command byte constant */ 00090 static const owCommand_t ChannelAccess_COMMAND = 0xf5; /**< 1-Wire command byte constant */ 00091 00092 00093 00094 //===================================================================================== 00095 // 00096 // type definitions 00097 // 00098 00099 typedef std::vector<LOW_devDS2406*> devDS2406PtrVec_t; /**< Vector type of class device pointers. */ 00100 00101 /** Type for PIO channel selection. */ 00102 typedef enum { noneSelect=0, chanASelect=1, chanBSelect=2, chanBothSelect=3} chanSelect_t; 00103 00104 /** Type for search source selection. */ 00105 typedef enum { latchSelect=1, flipFlopSelect=2, curStatusSelect=3} sourceSelect_t; 00106 00107 /** Type for PIO transistor states. */ 00108 typedef enum { pioTransistorOn=0, pioTransistorOff=1} pioTransistor_t; 00109 00110 /** Type for activity polarity selection. */ 00111 typedef enum { activeLow=0, activeHigh=1} activePolarity_t; 00112 00113 /** DS2406 internal status register as defined by Dallas. */ 00114 typedef struct statusRegister_t { 00115 activePolarity_t activePolarity; 00116 sourceSelect_t sourceSelect; 00117 chanSelect_t channelSelect; 00118 pioTransistor_t channelFFQ_pioA; 00119 pioTransistor_t channelFFQ_pioB; 00120 bool isExternalPowered; // bit 7 00121 } statusRegister_t; 00122 00123 00124 //===================================================================================== 00125 // 00126 // classes 00127 // 00128 00129 00130 /** Class for accessing the PIO channels. 00131 00132 The Channel Access command is used to access the PIO channels to sense the logical status 00133 of the output node and the output transistor and to change the status of the output transistor. 00134 00135 As there are many combinations of reading/writing the command is implemented as a class. 00136 The programmer himself is responsible to match read/write cycles according to prior selected 00137 options on instance creation. 00138 00139 For details see the original Dallas documentation. 00140 00141 <B>Note:</B> As any other command creating an instance of this class locks the device. 00142 Remember to destroy the object to release the device. 00143 */ 00144 class cmd_ChannelAccess : public linkLock { 00145 00146 //------------------------------------------------------------------------------------- 00147 public: 00148 00149 //------------------------------------------------------------------------------------- 00150 // type definitions 00151 // 00152 00153 /** Type for CRC cycle selection. */ 00154 typedef enum { CRC_disable=0, CRC_after1Byte=1, CRC_after8Byte=2, CRC_after32Byte=3} CRCtype_t; 00155 00156 /** Type for interleave mode selection. */ 00157 typedef enum { asyncInterleaveMode=0, syncInterleaveMode=1 } interleaveMode_t; 00158 00159 /** Type for toggle mode selection. */ 00160 typedef enum { noToggleMode=0, toggleMode=1} toggleMode_t; 00161 00162 /** Type for inition I/O mode selection. */ 00163 typedef enum { writeMode=0, readMode=1} initialMode_t; 00164 00165 /** Type for latch reset selection. */ 00166 typedef enum { noResetLatches=0, resetLatches=1} activityLatchReset_t; 00167 00168 /** DS2406 channel info as defined by Dallas. */ 00169 typedef struct channelInfo_t { 00170 bool channelFFQ_pioA; // bit 0 00171 bool channelFFQ_pioB; 00172 bool sensedLevel_pioA; 00173 bool sensedLevel_pioB; 00174 bool activityLatch_pioA; 00175 bool activityLatch_pioB; 00176 bool hasPioB; 00177 bool isExternalPowered; // bit 7 00178 } channelInfo_t; 00179 00180 //------------------------------------------------------------------------------------- 00181 // constructors 00182 // 00183 00184 /** Constructor with specification of command options. 00185 Obtains a lock on the device. 00186 00187 @param inDevice Reference to the device the command operates on. 00188 @param inCRCtype CRC cycle selection. 00189 @param inChanSelect PIO channel selection. 00190 @param inInterleaveMode Interleave mode selection. 00191 @param inToggleMode Toggle mode selection. 00192 @param inInitialMode Initial I/O mode selection. 00193 @param inALR Latch reset selection. 00194 00195 @throw devDS2406_error Thrown when illegal combination of modes is selected. 00196 */ 00197 cmd_ChannelAccess( const LOW_devDS2406 &inDevice, 00198 const CRCtype_t inCRCtype, const chanSelect_t inChanSelect, 00199 const interleaveMode_t inInterleaveMode, const toggleMode_t inToggleMode, 00200 const initialMode_t inInitialMode, const activityLatchReset_t inALR); 00201 00202 /** Destructor. 00203 Releases the lock on the device. 00204 */ 00205 virtual ~cmd_ChannelAccess(); 00206 00207 //------------------------------------------------------------------------------------- 00208 // methods 00209 // 00210 00211 /** Get the channel info read after sending command. 00212 */ 00213 virtual channelInfo_t& getChannelInfo(); 00214 00215 /** Receive 1 bit from the device. 00216 @return Bit that was reveived. 00217 */ 00218 virtual bool readDataBit() const; 00219 00220 /** Receive 1 byte from the device. 00221 @return Byte that was reveived. 00222 */ 00223 virtual uint8_t readDataByte() const; 00224 00225 /** Receive a block of bytes from the device. 00226 @param outBytes Values that were reveived. Read length is determined 00227 by the preset length of the vector. 00228 */ 00229 virtual void readData( byteVec_t &outBytes) const; 00230 00231 /** Send 1 bit to the device. 00232 @param inSendBit Bit to send. 00233 */ 00234 virtual void writeData( const bool inSendBit) const; 00235 00236 /** Send 1 byte to the device. 00237 @param inSendByte Byte to send. 00238 */ 00239 virtual void writeData( const uint8_t inSendByte) const; 00240 00241 /** Send block of bytes to the device. 00242 @param inSendBytes Block of bytes to send. 00243 */ 00244 virtual void writeData( const byteVec_t &inSendBytes) const; 00245 00246 //------------------------------------------------------------------------------------- 00247 private: 00248 const LOW_devDS2406 &device; /**< Device the command is operating on */ 00249 channelInfo_t channelInfo; /**< Channel info received after issuing the command */ 00250 00251 }; 00252 00253 00254 //===================================================================================== 00255 // 00256 // constructors 00257 // 00258 00259 /** Real constructor corresponding to static pseudo constructor new_Instance(). 00260 @param inSegment Reference to network segment the device is on. 00261 @param inDevID Reference to device's ID. 00262 */ 00263 LOW_devDS2406( LOW_netSegment &inSegment, const LOW_deviceID &inDevID); 00264 00265 /** Destructor. 00266 */ 00267 virtual ~LOW_devDS2406(); 00268 00269 00270 //===================================================================================== 00271 // 00272 // methods 00273 // 00274 00275 /** Get the device's family code. 00276 <B>Note:</B> Subclasses must implement this method to return their specific family code. 00277 @return Family name of the device. 00278 */ 00279 virtual const LOW_deviceIDRaw::devFamCode_t getFamilyCode() const { return familyCode; }; 00280 00281 /** Get the device's family name. 00282 <B>Note:</B> Subclasses must implement this method to return a clear text 00283 name of their family. 00284 @return Family name of the device. 00285 */ 00286 virtual const std::string getFamilyName() const { return familyName; }; 00287 00288 /** Get wether the device is externally powered. 00289 @return Boolean indicates external power. 00290 */ 00291 virtual bool getIsExternalPowered() const; 00292 00293 00294 /** Get wether the second PIO channel is present. 00295 @return Boolean indicates presence of channel B. 00296 */ 00297 virtual bool getHasPioB() const; 00298 00299 00300 /** Get the current search condition. 00301 See also setSearchCondition(). 00302 00303 @param outStatusRegister Pointer to status register struture. Results 00304 are filled in there. 00305 */ 00306 virtual void getSearchCondition( LOW_devDS2406::statusRegister_t *outStatusRegister) const; 00307 00308 00309 /** Set the search condition and status of the PIO transistors. 00310 00311 The condition is specified by the bit functions CSS0 to CSS4 in Status Memory location 7. 00312 At power-on all these bits are 1s. As long as the device remains powered up, the 00313 modified search conditions are available for use at any time. 00314 For the conditional search, one can specify 00315 - the polarity (HIGH or LOW; CSS0) 00316 - the source (PIO-pin, channel flip flop or activity latch; CSS1, CSS2) 00317 - the channel of interest (A, B or the logical OR of A, B; CSS3, CSS4) 00318 00319 The table shows all qualifying conditions and the required settings for CSS0 to CSS4: 00320 <pre> 00321 DESCRIPTION | CONDITIONAL SEARCH SELECT CODE 00322 -----------------+---------+--------------+-------------+--------- 00323 | |CHANNEL SELECT|SOURCE SELECT|POLARITY 00324 | +------+-------+------+------+--------- 00325 CONDITION | CHANNEL | CSS4 | CSS3 | CSS2 | CSS1 | CSS0 00326 =================+=========+======+=======+======+======+========= 00327 RESERVED | | Don't care | 0 | 0 | 0/1 00328 -----------------+---------+------+-------+------+------+--------- 00329 Unconditional |neither | 0 | 0 | At least one| 0 00330 | | | | must be 1 | 00331 -----------------+---------+------+-------+------+------+--------- 00332 Activity Latch=0 | A | 0 | 1 | 0 | 1 | 0 00333 -----------------+---------+------+-------+------+------+--------- 00334 Activity Latch=1 | A | 0 | 1 | 0 | 1 | 1 00335 -----------------+---------+------+-------+------+------+--------- 00336 Channel FF = 0 | A | 0 | 1 | 1 | 0 | 0 00337 (transistor on) | | | | | | 00338 -----------------+---------+------+-------+------+------+--------- 00339 Channel FF = 1 | A | 0 | 1 | 1 | 0 | 1 00340 (transistor off) | | | | | | 00341 -----------------+---------+------+-------+------+------+--------- 00342 PIO Low | A | 0 | 1 | 1 | 1 | 0 00343 -----------------+---------+------+-------+------+------+--------- 00344 PIO High | A | 0 | 1 | 1 | 1 | 1 00345 -----------------+---------+------+-------+------+------+--------- 00346 Activity Latch=0 | B | 1 | 0 | 0 | 1 | 0 00347 -----------------+---------+------+-------+------+------+--------- 00348 Activity Latch=1 | B | 1 | 0 | 0 | 1 | 1 00349 -----------------+---------+------+-------+------+------+--------- 00350 Channel FF = 0 | B | 1 | 0 | 1 | 0 | 0 00351 (transistor on) | | | | | | 00352 -----------------+---------+------+-------+------+------+--------- 00353 Channel FF = 1 | B | 1 | 0 | 1 | 0 | 1 00354 (transistor off) | | | | | | 00355 -----------------+---------+------+-------+------+------+--------- 00356 PIO Low | B | 1 | 0 | 1 | 1 | 0 00357 -----------------+---------+------+-------+------+------+--------- 00358 PIO High | B | 1 | 0 | 1 | 1 | 1 00359 -----------------+---------+------+-------+------+------+--------- 00360 Activity Latch=0 | A or B | 1 | 1 | 0 | 1 | 0 00361 -----------------+---------+------+-------+------+------+--------- 00362 Activity Latch=1 | A or B | 1 | 1 | 0 | 1 | 1 00363 -----------------+---------+------+-------+------+------+--------- 00364 Channel FF = 0 | A or B | 1 | 1 | 1 | 0 | 0 00365 (transistor on) | | | | | | 00366 -----------------+---------+------+-------+------+------+--------- 00367 Channel FF = 1 | A or B | 1 | 1 | 1 | 0 | 1 00368 (transistor off) | | | | | | 00369 -----------------+---------+------+-------+------+------+--------- 00370 PIO Low | A or B | 1 | 1 | 1 | 1 | 0 00371 -----------------+---------+------+-------+------+------+--------- 00372 PIO High | A or B | 1 | 1 | 1 | 1 | 1 00373 -----------------+---------+------+-------+------+------+--------- 00374 </pre> 00375 00376 @param inChanSelect Select channel search condition. 00377 @param inSourceSelect Select source search condition. 00378 @param inPolaritySelect Select polarity search condition. 00379 @param inPioATrans Status of PIO transistor A. 00380 @param inPioBTrans Status of PIO transistor B. 00381 00382 @throw devDS2406_error Thrown when channel B is selected without being present. 00383 */ 00384 virtual void setSearchCondition( const chanSelect_t inChanSelect, const sourceSelect_t inSourceSelect, 00385 const activePolarity_t inPolaritySelect, 00386 const pioTransistor_t inPioATrans, const pioTransistor_t inPioBTrans) const; 00387 00388 00389 /** Read from EPROM memory. 00390 00391 The Read Memory command is used to read data from the 1024-bit EPROM data memory field. 00392 The bus master follows the command byte with a two-byte address (TA1=(T7:T0), TA2=(T15:T8)) 00393 that indicates a starting byte location within the data field. With every subsequent read 00394 data time slot the bus master receives data from the DS2406 starting at the initial address 00395 and continuing until the end of the 1024-bits data field is reached or until a Reset Pulse 00396 is issued. 00397 00398 If reading occurs through the end of memory space, the bus master issues sixteen additional 00399 read time slots and the DS2406 will respond with a 16-bit CRC of the command, address bytes 00400 and all data bytes read from the initial starting byte through the last byte of memory. 00401 This CRC is the result of clearing the CRC generator and then shifting in the command byte 00402 followed by the two address bytes and the data bytes beginning at the first addressed memory 00403 location and continuing through to the last byte of the EPROM data 00404 memory. Any reads ended by a Reset Pulse prior to reaching the end of memory will not have 00405 the 16-bit CRC available. 00406 00407 Typically the software controlling the device should store a 16-bit CRC with each page 00408 of data to insure rapid, error-free data transfers that eliminate having to read a page 00409 multiple times to determine if the received data is correct or not. (See Book of DS19xx 00410 iButton Standards, Chapter 7 for the recommended file structure to be used with the 1-Wire 00411 environment). If CRC values are imbedded within the data it is unnecessary to read the 00412 end-of-memory CRC. The Read Memory command can be ended at any point by issuing a Reset Pulse. 00413 00414 @param inStartAddr Start address for reading. 00415 @param outBytes Values that were reveived. Read length is determined 00416 by the preset length of the vector. 00417 */ 00418 virtual void cmd_ReadMemory( const uint8_t inStartAddr, byteVec_t &outBytes) const; 00419 00420 00421 //cmd_ExtendedReadMemory(); // Not implemented yet 00422 00423 00424 //cmd_WriteMemory(); // Not implemented yet 00425 00426 00427 /** Read from status memory. 00428 00429 The Read Status command is used to read data from the Status Memory field. The functional flow 00430 of this command is identical to the Read Memory command. Since the Status Memory is only 8 bytes, 00431 the DS2406 will send the 16-bit CRC after the last byte of status information has been transmitted. 00432 00433 DS2406 status memory map: 00434 <pre> 00435 ADDRESS | BIT 7 | BIT 6 | BIT 5 | BIT 4 | BIT 3 | BIT 2 | BIT 1 | BIT 0 00436 ==========+===================+===============+===============+==============+==============+=============+=============+========== 00437 0 (EPROM) | BM3 | BM2 | BM1 | BM0 | WP3 | WP2 | WP1 | WP0 00438 ----------+-------------------+---------------+---------------+--------------+--------------+-------------+-------------+---------- 00439 1 (EPROM) | 1 | 1 | 1 | 1 | 1 | 1 | Redir. 0 | Redir. 0 00440 ----------+-------------------+---------------+---------------+--------------+--------------+-------------+-------------+---------- 00441 2 (EPROM) | 1 | 1 | 1 | 1 | 1 | 1 | Redir. 1 | Redir. 1 00442 ----------+-------------------+---------------+---------------+--------------+--------------+-------------+-------------+---------- 00443 3 (EPROM) | 1 | 1 | 1 | 1 | 1 | 1 | Redir. 2 | Redir. 2 00444 ----------+-------------------+---------------+---------------+--------------+--------------+-------------+-------------+---------- 00445 4 (EPROM) | 1 | 1 | 1 | 1 | 1 | 1 | Redir. 3 | Redir. 3 00446 ----------+-------------------+---------------+---------------+--------------+--------------+-------------+-------------+---------- 00447 5 (EPROM) | EPROM Factory Test byte 00448 ----------+-------------------+---------------+---------------+--------------+--------------+-------------+-------------+---------- 00449 6 (EPROM) | Don t care, always reads 00 00450 ----------+-------------------+---------------+---------------+--------------+--------------+-------------+-------------+---------- 00451 7 (SRAM) | Supply Indication | PIO-B Channel | PIO-A Channel | CSS4 Channel | CSS3 Channel | CSS2 Source | CSS1 Source | CSS0 00452 | (read only) | Flip-flop | Flip-flop | Select | Select | Select | Select | Polarity 00453 ----------+-------------------+---------------+---------------+--------------+--------------+-------------+-------------+---------- 00454 </pre> 00455 00456 @param inStartAddr Start address for reading. 00457 @param outBytes Values that were reveived. Read length is determined 00458 by the preset length of the vector. 00459 00460 @throw devDS2406_error Thrown when illegal address is selected. 00461 */ 00462 virtual void cmd_ReadStatus( const uint8_t inStartAddr, byteVec_t &outBytes) const; 00463 00464 00465 /** Write to status memory. 00466 00467 The Write Status command is used to program the Status Memory, which includes the 00468 specification of the Conditional Search Settings. 00469 00470 The Status Memory address range is 00471 0000h to 0007h. The general programming algorithm is valid for the EPROM section of 00472 the Status Memory (addresses 0 to 4) only. The Status memory locations 5 and 6 are 00473 already pre-programmed to 00h and therefore cannot be altered. Status memory 00474 location 7 consists of static RAM, which can be reprogrammed without limitation. 00475 The supply indication (bit 7) is read-only; attempts to write to it are ignored. The 00476 function flow for writing to status memory location 7 is basically the same as for 00477 the other EPROM Status Memory Bytes. However, instead of a programming pulse the bus 00478 master sends a FFh byte (equivalent to 8 Write-One Time Slots) to transfer the new 00479 value from the scratchpad to the status memory. 00480 00481 See also cmd_ReadStatus(). 00482 00483 @param inStartAddr Start address for reading. 00484 @param inWriteBytes Values to write. 00485 00486 @throw devDS2406_error Thrown when illegal address is selected. 00487 */ 00488 virtual void cmd_WriteStatus( const uint8_t inStartAddr, const byteVec_t &inWriteBytes) const; 00489 00490 00491 00492 //======================================================================================= 00493 protected: 00494 00495 //===================================================================================== 00496 // 00497 // friends 00498 // 00499 00500 friend class cmd_ChannelAccess; /**< required for accessing the device's lock */ 00501 00502 00503 //===================================================================================== 00504 // 00505 // attributes 00506 // 00507 00508 bool isExternalPowered; /**< External supply indicator */ 00509 bool hasPioB; /**< Wether the second PIO channel is present */ 00510 00511 00512 //===================================================================================== 00513 // 00514 // static methods 00515 // 00516 00517 /** Static pseudo constructor for registering with LOW_deviceFactory. 00518 @param inSegment Reference to network segment the device is on. 00519 @param inDevID Reference to device's ID. 00520 @return New dynamic instance of specific device class. 00521 */ 00522 static LOW_device* new_Instance( LOW_netSegment &inNetSegment, const LOW_deviceID &inDevID); 00523 00524 00525 //===================================================================================== 00526 // 00527 // methods 00528 // 00529 00530 /** Universal, internal data reading. 00531 Implements common parts of memory reading. 00532 00533 @param inStartAddr Start address for reading. 00534 @param outBytes Values that were reveived. Read length is determined 00535 by the preset length of the vector. 00536 @param inMaxLen Maximum readable memory size. 00537 @param inCommand 1-Wire command to start the read cycle. 00538 00539 @throw devDS2406_error Thrown when illegal address is selected. 00540 */ 00541 virtual void readMemUniversal( const uint16_t inStartAddr, byteVec_t &outBytes, 00542 const uint16_t inMaxLen, const owCommand_t inCommand) const; 00543 00544 00545 00546 //======================================================================================= 00547 private: 00548 00549 //===================================================================================== 00550 // 00551 // static initializer 00552 // 00553 00554 /** Needed for dirty little C++ hack to force static initialization on application start. 00555 @see initialize() 00556 */ 00557 static int initHelper; 00558 00559 /** Static inizializer to register the class with LOW_deviceFactory. 00560 @see initHelper 00561 */ 00562 static int initialize(); 00563 00564 }; 00565 00566 #endif