1-Wire® library for mbed. Complete 1-Wire library that supports our silicon masters along with a bit-bang master on the MAX32600MBED platform with one common interface for mbed. Slave support has also been included and more slaves will be added as time permits.

Dependents:   MAXREFDES131_Qt_Demo MAX32630FTHR_iButton_uSD_Logger MAX32630FTHR_DS18B20_uSD_Logger MAXREFDES130_131_Demo ... more

Superseded by MaximInterface.

Revision:
21:00c94aeb533e
Child:
22:686273e55cdc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OneWire_Masters/DS2465/DS2465.cpp	Mon Mar 21 14:12:28 2016 -0500
@@ -0,0 +1,1769 @@
+#include "DS2465.hpp"
+
+#define I2C_WRITE 0
+#define I2C_READ 1
+
+// DS2465 commands
+#define CMD_1WMR   0xF0
+#define CMD_WCFG   0xD2
+#define CMD_CHSL   0xC3
+#define CMD_SRP    0xE1
+
+#define CMD_1WRS   0xB4
+#define CMD_1WWB   0xA5
+#define CMD_1WRB   0x96
+#define CMD_1WSB   0x87
+#define CMD_1WT    0x78
+#define CMD_1WTB   0x69
+#define CMD_1WRF   0xE1
+#define CMD_CPS    0x5A
+#define CMD_CSS    0x4B
+#define CMD_CSAM   0x3C
+#define CMD_CSWM   0x2D
+#define CMD_CNMS   0x1E
+#define CMD_SPR    0x0F
+
+// DS2465 config bits
+#define CONFIG_APU  0x01
+#define CONFIG_PDN  0x02
+#define CONFIG_SPU  0x04
+#define CONFIG_1WS  0x08
+
+// DS2465 status bits 
+#define STATUS_1WB  0x01
+#define STATUS_PPD  0x02
+#define STATUS_SD   0x04
+#define STATUS_LL   0x08
+#define STATUS_RST  0x10
+#define STATUS_SBR  0x20
+#define STATUS_TSB  0x40
+#define STATUS_DIR  0x80
+
+// delays (if not polling for complete)
+#define EEPROM_WRITE_DELAY    30  
+#define LOAD_SECRET_DELAY     90
+#define SHA_COMPUTATION_DELAY 5
+
+static const int I2C_WRITE_OK = 0;
+
+DS2465::DS2465(I2C & I2C_interface, unsigned char I2C_address)
+  : m_I2C_interface(I2C_interface), m_I2C_address(I2C_address)
+{
+  
+}
+
+
+
+
+OneWireMaster::CmdResult DS2465::OWInitMaster()
+{
+  return Detect();
+}
+
+
+//--------------------------------------------------------------------------
+// Compute Next Master Secret DS2465 
+//
+// 'swap' - 1 if swapping a page into the computation
+// 'page' - page number to swap in
+// 'region' - (1) first 1/2 page, (2) second 1/2 page, (3) entire page 
+//
+// Returns: true write successful
+//          false failure to complete read
+//
+OneWireMaster::CmdResult DS2465::Compute_NextMasterSecret(bool swap, unsigned int pageNum, PageRegion region)
+{
+   uint8_t par;
+
+   // create parameter byte
+   if (!swap)
+      par = 0xBF;
+   else
+      par = (0xC8 | (pageNum << 4) | region); 
+
+   return Write_Command_Reg(CMD_CNMS, par, false);
+}
+
+//--------------------------------------------------------------------------
+// Compute Write MAC DS2465 
+//
+// 'regwrite' - true if writing to a register, false if regular memory
+// 'swap' - true if swapping a page into the computation
+// 'page' - page number to swap in
+// 'segment' - segment number if swaping 
+//
+// Returns: true write successful
+//          false failure to complete read
+//
+OneWireMaster::CmdResult DS2465::Compute_WriteMAC(bool regwrite, bool swap, unsigned int pageNum, unsigned int segmentNum) const
+{
+   uint8_t par;
+
+   // create parameter byte
+   par = ((regwrite << 7) | (swap << 6) | (pageNum << 4) | segmentNum); 
+   
+   return Write_Command_Reg(CMD_CSWM, par, false);
+}
+
+//--------------------------------------------------------------------------
+// Compute Slave Authentication MAC DS2465 
+//
+// 'swap' - true if swapping a page into the computation
+// 'page' - page number to swap in
+// 'region' - (1) first 1/2 page, (2) second 1/2 page, (3) entire page 
+//
+// Returns: true write successful
+//          false failure to complete read
+//
+OneWireMaster::CmdResult DS2465::Compute_AuthMAC(bool swap, unsigned int pageNum, PageRegion region) const
+{
+   uint8_t par;
+
+   // create parameter byte
+   if (!swap)
+      par = 0xBF;
+   else
+      par = (0xC8 | (pageNum << 4) | region); 
+   
+   return Write_Command_Reg(CMD_CSAM, par, false);
+}
+
+//--------------------------------------------------------------------------
+// Compute S-Secret on DS2465 
+//
+// 'swap' - true if swapping a page into the computation
+// 'page' - page number to swap in
+// 'region' - (1) first 1/2 page, (2) second 1/2 page, (3) entire page 
+//
+// Returns: true write successful
+//          false failure to complete read
+//
+OneWireMaster::CmdResult DS2465::Compute_SSecret(bool swap, unsigned int pageNum, PageRegion region)
+{
+   uint8_t par;
+
+   // create parameter byte
+   if (!swap)
+      par = 0xBF;
+   else
+      par = (0xC8 | (pageNum << 4) | region); 
+   
+   return Write_Command_Reg(CMD_CSS, par, false);
+}
+
+
+
+
+ISha256MacCoprocessor::CmdResult DS2465::setMasterSecret(const std::uint8_t (&secret)[secret_len])
+{
+  OneWireMaster::CmdResult result;
+  result = WriteScratchpad(ADDR_SPAD, secret, secret_len);
+  if (result == OneWireMaster::Success)
+    result = CopyScratchpad(1, 0, 1, 0);
+  if (result == OneWireMaster::Success)
+    wait_ms(8 * EEPROM_WRITE_DELAY);
+  return (result == OneWireMaster::Success ? ISha256MacCoprocessor::Success : ISha256MacCoprocessor::OperationFailure);
+}
+
+ISha256MacCoprocessor::CmdResult DS2465::ComputeAndRead_WriteMAC(const std::uint8_t (&WriteMAC_data)[WriteMAC_data_len], std::uint8_t (&mac)[mac_len]) const
+{
+  OneWireMaster::CmdResult result;
+  // Write input data to scratchpad
+  result = WriteScratchpad(ADDR_SPAD, WriteMAC_data, WriteMAC_data_len);
+  // Compute MAC
+  if (result == OneWireMaster::Success)
+    result = Compute_WriteMAC(false, false, 0, 0);
+  if (result == OneWireMaster::Success)
+  {
+    wait_ms(SHA_COMPUTATION_DELAY);
+    // Read MAC from register
+    result = ReadMemory(ADDR_MAC_READ, mac, mac_len, true);
+  }
+  return (result == OneWireMaster::Success ? ISha256MacCoprocessor::Success : ISha256MacCoprocessor::OperationFailure);
+}
+
+ISha256MacCoprocessor::CmdResult DS2465::ComputeAndRead_AuthMAC(const std::uint8_t (&devicePage)[devicePage_len], const std::uint8_t (&challenge)[deviceScratchpad_len],
+                                    const std::uint8_t (&AuthMAC_data)[AuthMAC_data_len], std::uint8_t (&mac)[mac_len]) const
+{
+  OneWireMaster::CmdResult result;
+  int addr = ADDR_SPAD;
+  // Write input data to scratchpad
+  result = WriteScratchpad(addr, devicePage, devicePage_len);
+  if (result == OneWireMaster::Success)
+  {
+    addr += devicePage_len;
+    result = WriteScratchpad(addr, challenge, deviceScratchpad_len);
+  }
+  if (result == OneWireMaster::Success)
+  {
+    addr += deviceScratchpad_len;
+    result = WriteScratchpad(addr, AuthMAC_data, AuthMAC_data_len);
+  }
+  // Compute MAC
+  if (result == OneWireMaster::Success)
+    result = Compute_AuthMAC(false, 0, REGION_FULL_PAGE);
+  if (result == OneWireMaster::Success)
+  {
+    wait_ms(SHA_COMPUTATION_DELAY * 2);
+    // Read MAC from register
+    result = ReadMemory(ADDR_MAC_READ, mac, mac_len, true);
+  }
+  return (result == OneWireMaster::Success ? ISha256MacCoprocessor::Success : ISha256MacCoprocessor::OperationFailure);
+}
+
+ISha256MacCoprocessor::CmdResult DS2465::Compute_SSecret(const unsigned char (&devicePage)[devicePage_len], const unsigned char (&deviceScratchpad)[deviceScratchpad_len],
+                             const unsigned char (&SSecret_data)[SSecret_data_len])
+{
+  OneWireMaster::CmdResult result;
+  int addr = ADDR_SPAD;
+  // Write input data to scratchpad
+  result = WriteScratchpad(addr, devicePage, devicePage_len);
+  if (result == OneWireMaster::Success)
+  {
+    addr += devicePage_len;
+    result = WriteScratchpad(addr, deviceScratchpad, deviceScratchpad_len);
+  }
+  if (result == OneWireMaster::Success)
+  {
+    addr += deviceScratchpad_len;
+    result = WriteScratchpad(addr, SSecret_data, SSecret_data_len);
+  }
+  // Compute secret
+  if (result == OneWireMaster::Success)
+    result = Compute_SSecret(false, 0, REGION_FULL_PAGE);
+  if (result == OneWireMaster::Success)
+    wait_ms(SHA_COMPUTATION_DELAY * 2);
+  return (result == OneWireMaster::Success ? ISha256MacCoprocessor::Success : ISha256MacCoprocessor::OperationFailure);
+}
+
+//--------------------------------------------------------------------------
+// Copy Scratchpad on DS2465 to either secret or memory page
+//
+// 'dest_secret' - 1 if destination is secret, 0 if memory page
+// 'page' - page number if dest_secret=0
+// 'notfull' - 0 if only 4 byte segment, 1 if writing to full page, 
+// 'seg' - Segment number if full=0.
+//
+// Returns: true write successful
+//          false failure to complete read
+//
+OneWireMaster::CmdResult DS2465::CopyScratchpad(bool dest_secret, unsigned int pageNum, bool notFull, unsigned int segmentNum)	
+{
+   uint8_t par;
+
+   // create parameter byte
+   if (dest_secret)
+      par = 0;
+   else
+      par = (0x80 | (pageNum << 4) | (notFull << 3) | segmentNum); 
+   
+   return Write_Command_Reg(CMD_CPS, par, false);
+}
+
+//--------------------------------------------------------------------------
+// APU enable or disable
+//
+// 'readflag' - 1 if reading current configuration
+// 'apu_enable' - 1 to enable
+//
+// Returns:  true  if write successful, or return configuration value if reading
+//   
+OneWireMaster::CmdResult DS2465::ConfigureAPU(bool apu_enable)	
+{
+   // clear power down bit in the global config state
+   cAPU = apu_enable ? CONFIG_APU : 0;
+
+   // write the new config
+   return Write_Config(c1WS | cSPU | cPDN | cAPU);
+}
+
+//--------------------------------------------------------------------------
+// Power up 1-Wire using extended function
+//
+// Returns:  true  successful
+//           false failure during communication
+//
+OneWireMaster::CmdResult DS2465::OWPowerUp(void)
+{
+   OneWireMaster::CmdResult rt;
+
+  // clear power down bit in the global config state
+   cPDN = 0;
+
+   // write the new config
+   rt = Write_Config(c1WS | cSPU | cPDN | cAPU);
+
+   // delay 2ms to allow units to power up
+   wait_ms(2);
+
+   return rt;
+}
+
+//--------------------------------------------------------------------------
+// Power down 1-Wire using extended function
+//
+// Returns:  true  successful
+//           false program voltage not available
+//
+OneWireMaster::CmdResult DS2465::OWPowerDown(void)
+{
+   // set power down bit in the global config state
+   cPDN = CONFIG_PDN;
+
+   // write the new config
+   return Write_Config(c1WS | cSPU | cPDN | cAPU);
+}
+
+//--------------------------------------------------------------------------
+// Send 1 bit of communication to the 1-Wire Net and verify that the
+// response matches the 'applyPowerResponse' bit and apply power delivery
+// to the 1-Wire net.  Note that some implementations may apply the power
+// first and then turn it off if the response is incorrect.
+//
+// 'applyPowerResponse' - 1 bit response to check, if correct then start
+//                        power delivery 
+//
+// Returns:  true: bit written and response correct, strong pullup now on
+//           false: response incorrect
+//
+OneWireMaster::CmdResult DS2465::OWReadBitPower(uint8_t applyPowerResponse)
+{
+  OneWireMaster::CmdResult result;
+  uint8_t rdbit;
+
+  // set strong pull-up enable
+  cSPU = CONFIG_SPU;
+
+  // write the new config
+  result = Write_Config(c1WS | cSPU | cPDN | cAPU);
+  if (result != OneWireMaster::Success)
+    return result;
+
+  // perform read bit
+  result = OWReadBit(rdbit);
+  if (result != OneWireMaster::Success)
+    return result;
+
+  // check if response was correct, if not then turn off strong pull-up
+  if (rdbit != applyPowerResponse)
+  {
+    OWLevel(LEVEL_NORMAL);
+    return OneWireMaster::OperationFailure;
+  }
+
+  return OneWireMaster::Success;
+}
+
+//--------------------------------------------------------------------------
+// Read 8 bits of communication from the 1-Wire Net.  After the
+// 8 bits are read then change the level of the 1-Wire net.
+//
+// Returns:  8 bits read from 1-Wire Net
+//
+OneWireMaster::CmdResult DS2465::OWReadBytePower(uint8_t & recvbyte)
+{
+  OneWireMaster::CmdResult result;
+  
+  // set strong pull-up enable
+  cSPU = CONFIG_SPU;
+
+  // write the new config
+  result = Write_Config(c1WS | cSPU | cPDN | cAPU);
+  if (result != OneWireMaster::Success)
+    return result;
+
+  // do the read byte
+  result = OWReadByte(recvbyte);
+  return result;
+}
+
+//--------------------------------------------------------------------------
+// Send 8 bits of communication to the 1-Wire Net and verify that the
+// 8 bits read from the 1-Wire Net is the same (write operation).  
+// The parameter 'sendbyte' least significant 8 bits are used.  After the
+// 8 bits are sent change the level of the 1-Wire net.
+//
+// 'sendbyte' - 8 bits to send (least significant bit)
+//
+OneWireMaster::CmdResult DS2465::OWWriteBytePower(uint8_t sendbyte)
+{
+  OneWireMaster::CmdResult result;
+  
+  // set strong pull-up enable
+  cSPU = CONFIG_SPU;
+
+  // write the new config
+  result = Write_Config(c1WS | cSPU | cPDN | cAPU);
+  if (result != OneWireMaster::Success)
+    return result;
+
+  // perform write byte
+  return OWWriteByte(sendbyte);
+}
+
+//--------------------------------------------------------------------------
+// Set the 1-Wire Net line level pull-up to normal. The DS2465 does only
+// allows enabling strong pull-up on a bit or byte event. Consequently this
+// function only allows the MODE_STANDARD argument. To enable strong pull-up
+// use OWWriteBytePower or OWReadBitPower.  
+//
+// 'new_level' - new level defined as
+//                MODE_STANDARD     0x00
+//
+// Returns:  current 1-Wire Net level
+//
+OneWireMaster::CmdResult DS2465::OWLevel(OW_LEVEL new_level)
+{
+   // function only will turn back to non-strong pull-up
+   if (new_level != LEVEL_NORMAL)
+      return OneWireMaster::OperationFailure;
+
+   // clear the strong pull-up bit in the global config state
+   cSPU = 0;
+
+   // write the new config
+   return Write_Config(c1WS | cSPU | cPDN | cAPU);
+}
+
+//--------------------------------------------------------------------------
+// The 'OWOverdriveMatchROM' function does an overdrive Match-ROM using the
+// global ROM_NO device
+//
+// Returns:   true (1) : OWReset successful and match rom sent. 
+//            false (0): OWReset did not have presence
+//
+OneWireMaster::CmdResult DS2465::OWOverdriveMatchROM(const RomId & romId)
+{
+  OneWireMaster::CmdResult result;
+  // use overdrive MatchROM 
+  OWSpeed(SPEED_STANDARD);
+  result = OWReset();
+  if (result == OneWireMaster::Success)
+  {
+    result = OWWriteByte(0x69);
+    if (result == OneWireMaster::Success)
+    {
+      OWSpeed(SPEED_OVERDRIVE);
+      // send ROM
+      result = OWWriteBlock(false, romId, RomId::byteLen);
+    }
+  }
+  return result;
+}
+
+//--------------------------------------------------------------------------
+// The 'OWMatchROM' function does a Match-ROM using the global ROM_NO device
+//
+// Returns:   true (1) : OWReset successful and match rom sent. 
+//            false (0): OWReset did not have presence
+//
+OneWireMaster::CmdResult DS2465::OWMatchROM(const RomId & romId)
+{
+  OneWireMaster::CmdResult result;
+  uint8_t buf[1 + RomId::byteLen];
+
+  // use MatchROM 
+  result = OWReset();
+  if (result == OneWireMaster::Success)
+  {
+    buf[0] = 0x55;
+    std::memcpy(&buf[1], romId, RomId::byteLen);
+    // send command and rom
+    result = OWWriteBlock(false, buf, 1 + RomId::byteLen);
+  }
+  
+  return result;
+}
+
+//--------------------------------------------------------------------------
+// Setup the search to skip the current device type on the next call
+// to OWNext().
+//
+void DS2465::OWFamilySkipSetup(void)
+{
+   // set the Last discrepancy to last family discrepancy
+   m_lastDiscrepancy = m_lastFamilyDiscrepancy;
+
+   // clear the last family discrpepancy
+   m_lastFamilyDiscrepancy = 0;
+
+   // check for end of list
+   if (m_lastDiscrepancy == 0) 
+      m_lastDeviceFlag = true;
+}
+
+//--------------------------------------------------------------------------
+// Setup the search to find the device type 'family_code' on the next call
+// to OWNext() if it is present.
+//
+void DS2465::OWTargetSetup(RomId & romId)
+{
+   // set the search state to find SearchFamily type devices
+   for (int i = 1; i < 8; i++)
+      romId[i] = 0;
+   m_lastDiscrepancy = 64;
+   m_lastFamilyDiscrepancy = 0;
+   m_lastDeviceFlag = false;
+}
+
+//--------------------------------------------------------------------------
+// Verify the device with the ROM number in ROM_NO buffer is present.
+// Return true  : device verified present
+//        false : device not present
+//
+OneWireMaster::CmdResult DS2465::OWVerify(const RomId & romId)
+{
+  OneWireMaster::CmdResult result;
+  RomId romIdCopy(romId);
+  int ld_backup, ldf_backup, lfd_backup;
+
+  // keep a backup copy of the current state
+  ld_backup = m_lastDiscrepancy;
+  ldf_backup = m_lastDeviceFlag;
+  lfd_backup = m_lastFamilyDiscrepancy;
+
+  // set search to find the same device
+  m_lastDiscrepancy = 64;
+  m_lastDeviceFlag = false;
+
+  result = OWSearch(romIdCopy);
+  if (result == OneWireMaster::Success)
+  {
+    // check if same device found
+    if (romId != romIdCopy)
+    {
+       result = OneWireMaster::OperationFailure;
+    }
+  }
+
+  // restore the search state
+  m_lastDiscrepancy = ld_backup;
+  m_lastDeviceFlag = ldf_backup;
+  m_lastFamilyDiscrepancy = lfd_backup;
+
+  // return the result of the verify
+  return result;
+}
+
+//--------------------------------------------------------------------------
+// Find the 'next' devices on the 1-Wire network
+// Return true  : device found, ROM number in ROM_NO buffer
+//        false : device not found, end of search
+//
+OneWireMaster::CmdResult DS2465::OWNext(RomId & romId)
+{
+   // leave the search state alone
+   return OWSearch(romId);
+}
+
+//--------------------------------------------------------------------------
+// Set the 1-Wire Net communication speed.
+//
+// 'new_speed' - new speed defined as
+//                MODE_STANDARD   0x00
+//                MODE_OVERDRIVE  0x01
+//
+// Returns:  current 1-Wire Net speed
+//
+OneWireMaster::CmdResult DS2465::OWSpeed(OW_SPEED new_speed)
+{
+   // set the speed 
+   if (new_speed == SPEED_OVERDRIVE)
+      c1WS = CONFIG_1WS;
+   else
+      c1WS = 0;
+
+   // write the new config
+   return Write_Config(c1WS | cSPU | cPDN | cAPU);
+}
+
+//--------------------------------------------------------------------------
+// The 'OWOverdriveSkipROM' function does an Overdrive skip-ROM. Ignores
+// result from standard speed OWReset().
+// 
+// Returns:   true (1) : OWReset and skip rom sent. 
+//            false (0): Could not change to overdrive
+//
+OneWireMaster::CmdResult DS2465::OWOverdriveSkipROM(void)
+{
+  OneWireMaster::CmdResult result = OWSpeed(SPEED_STANDARD);
+  if (result == OneWireMaster::Success)
+    result = OWReset();
+  if (result == OneWireMaster::Success)
+    result = OWWriteByte(0x3C);
+  if (result == OneWireMaster::Success)
+    result = OWSpeed(SPEED_OVERDRIVE);
+  return result;
+}
+
+//--------------------------------------------------------------------------
+// The 'OWResume' function does a Resume command 0xA5.
+//
+// Returns:   true (1) : OWReset successful and RESUME sent. 
+//            false (0): OWReset did not have presence
+//
+OneWireMaster::CmdResult DS2465::OWResume(void)
+{
+  OneWireMaster::CmdResult result;
+  result = OWReset();
+  if (result == OneWireMaster::Success)
+  {
+    result = OWWriteByte(0xA5);
+  }
+  return result;
+}
+
+//--------------------------------------------------------------------------
+// The 'OWSkipROM' function does a skip-ROM.  This function
+// uses the Skip-ROM function CCh.
+//
+// Returns:   true (1) : OWReset successful and skip rom sent. 
+//            false (0): OWReset did not have presence
+//
+OneWireMaster::CmdResult DS2465::OWSkipROM(void)
+{
+  OneWireMaster::CmdResult result;
+  result = OWReset();
+  if (result == OneWireMaster::Success)
+  {
+    result = OWWriteByte(0xCC);
+  }
+  return result;
+}
+
+//--------------------------------------------------------------------------
+// The 'OWReadROM' function does a Read-ROM.  This function
+// uses the read-ROM function 33h to read a ROM number and verify CRC8.
+//
+// Returns:   true (1) : OWReset successful and Serial Number placed 
+//                       in the global ROM, CRC8 valid 
+//            false (0): OWReset did not have presence or CRC8 invalid
+//
+OneWireMaster::CmdResult DS2465::OWReadROM(RomId & romId)	
+{
+  OneWireMaster::CmdResult result;
+  uint8_t buf[2 + RomId::byteLen];
+
+  result = OWReset();
+  if (result == OneWireMaster::Success)
+    result = OWWriteByte(0x33); // READ ROM
+      
+  // read the ROM
+  if (result == OneWireMaster::Success)
+    result = OWReadBlock(buf, RomId::byteLen);
+
+  // verify CRC8
+  if ((result == OneWireMaster::Success) && (RomId::calculateCRC8(buf, RomId::byteLen) == 0) && (buf[1] != 0))
+    romId = RomId(reinterpret_cast<std::uint8_t (&)[RomId::byteLen]>(buf[0]));
+
+  return result;
+}
+
+//--------------------------------------------------------------------------
+// Use the DS2465 help command '1-Wire triplet' to perform one bit of a 1-Wire
+// search. This command does two read bits and one write bit. The write bit
+// is either the default direction (all device have same bit) or in case of 
+// a discripancy, the 'search_direction' parameter is used. 
+//
+// Returns – The DS2465 status byte result from the triplet command
+//
+OneWireMaster::CmdResult DS2465::Triplet(Direction search_direction, uint8_t & status) 
+{
+  int poll_count = 0;
+
+  // 1-Wire Triplet (Case B)
+  //   S AD,0 [A] 1WT [A] SS [A] Sr AD,1 [A] [Status] A [Status] A\ P
+  //                                         \--------/        
+  //                           Repeat until 1WB bit has changed to 0
+  //  [] indicates from slave
+  //  SS indicates byte containing search direction bit value in msbit
+     
+  m_I2C_interface.start();
+  if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK)
+  {
+     m_I2C_interface.stop();
+     return OneWireMaster::CommunicationWriteError;
+  }
+  if (m_I2C_interface.write(ADDR_CMD_REG) != I2C_WRITE_OK)
+  {
+     m_I2C_interface.stop();
+     return OneWireMaster::CommunicationWriteError;
+  }
+  if (m_I2C_interface.write(CMD_1WT) != I2C_WRITE_OK)
+  {
+     m_I2C_interface.stop();
+     return OneWireMaster::CommunicationWriteError;
+  }
+  if (m_I2C_interface.write((unsigned char)((search_direction == DIRECTION_WRITE_ONE) ? 0x80 : 0x00)) != I2C_WRITE_OK)
+  {
+     m_I2C_interface.stop();
+     return OneWireMaster::CommunicationWriteError;
+  }
+  m_I2C_interface.start();
+  if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_READ)) != I2C_WRITE_OK)
+  {
+     m_I2C_interface.stop();
+     return OneWireMaster::CommunicationWriteError;
+  }
+
+  // loop checking 1WB bit for completion of 1-Wire operation 
+  // abort if poll limit reached
+  status = STATUS_1WB;
+  while ((status & STATUS_1WB) && (poll_count++ < POLL_LIMIT))
+  {
+     status = m_I2C_interface.read(status & STATUS_1WB);
+  }
+   
+  // one last read with NACK  
+  m_I2C_interface.read(m_I2C_interface.NoACK);
+
+  m_I2C_interface.stop();
+
+  // check for failure due to poll limit reached
+  if (poll_count >= POLL_LIMIT)
+  {
+     // handle error
+     // ...
+     Reset();
+     return OneWireMaster::TimeoutError;
+  }
+ 
+  // return status byte
+  return OneWireMaster::Success;
+}
+
+//--------------------------------------------------------------------------
+// The 'OWSearch' function does a general search.  This function
+// continues from the previos search state. The search state
+// can be reset by using the 'OWFirst' function.
+// This function contains one parameter 'alarm_only'.
+// When 'alarm_only' is true (1) the find alarm command
+// 0xEC is sent instead of the normal search command 0xF0.
+// Using the find alarm command 0xEC will limit the search to only
+// 1-Wire devices that are in an 'alarm' state.
+//
+// Returns:   true (1) : when a 1-Wire device was found and it's
+//                       Serial Number placed in the global ROM 
+//            false (0): when no new device was found.  Either the
+//                       last search was the last device or there
+//                       are no devices on the 1-Wire Net.
+//
+OneWireMaster::CmdResult DS2465::OWSearch(RomId & romId)
+{
+   int id_bit_number;
+   int last_zero, rom_byte_number;
+   int id_bit, cmp_id_bit;
+   unsigned char rom_byte_mask, status;
+   bool search_result;
+   unsigned char crc8 = 0;
+   Direction search_direction;
+
+   // initialize for search
+   id_bit_number = 1;
+   last_zero = 0;
+   rom_byte_number = 0;
+   rom_byte_mask = 1;
+   search_result = false;
+
+   // if the last call was not the last one
+   if (!m_lastDeviceFlag)
+   {       
+      // 1-Wire reset
+      OneWireMaster::CmdResult result = OWReset();
+      if (result != OneWireMaster::Success)
+      {
+         // reset the search
+         m_lastDiscrepancy = 0;
+         m_lastDeviceFlag = false;
+         m_lastFamilyDiscrepancy = 0;
+         return result;
+      }
+
+      // issue the search command 
+      OWWriteByte(0xF0);  
+
+      // loop to do the search
+      do
+      {
+         // if this discrepancy if before the Last Discrepancy
+         // on a previous next then pick the same as last time
+         if (id_bit_number < m_lastDiscrepancy)
+         {
+            if ((romId[rom_byte_number] & rom_byte_mask) > 0)
+               search_direction = DIRECTION_WRITE_ONE;
+            else
+               search_direction = DIRECTION_WRITE_ZERO;
+         }
+         else
+         {
+            // if equal to last pick 1, if not then pick 0
+            if (id_bit_number == m_lastDiscrepancy)
+               search_direction = DIRECTION_WRITE_ONE;
+            else
+               search_direction = DIRECTION_WRITE_ZERO;
+         }
+
+         // Peform a triple operation on the DS2465 which will perform 2 read bits and 1 write bit
+         Triplet(search_direction, status);
+
+         // check bit results in status byte
+         id_bit = ((status & STATUS_SBR) == STATUS_SBR);
+         cmp_id_bit = ((status & STATUS_TSB) == STATUS_TSB);
+         search_direction = ((status & STATUS_DIR) == STATUS_DIR) ? DIRECTION_WRITE_ONE : DIRECTION_WRITE_ZERO;
+
+         // check for no devices on 1-wire
+         if ((id_bit) && (cmp_id_bit))
+            break;
+         else
+         {
+            if ((!id_bit) && (!cmp_id_bit) && (search_direction == DIRECTION_WRITE_ZERO))
+            {
+               last_zero = id_bit_number;
+
+               // check for Last discrepancy in family
+               if (last_zero < 9)
+                  m_lastFamilyDiscrepancy = last_zero;
+            }
+
+            // set or clear the bit in the ROM byte rom_byte_number
+            // with mask rom_byte_mask
+            if (search_direction == DIRECTION_WRITE_ONE)
+               romId[rom_byte_number] |= rom_byte_mask;
+            else
+               romId[rom_byte_number] &= (unsigned char)~rom_byte_mask;
+
+            // increment the byte counter id_bit_number
+            // and shift the mask rom_byte_mask
+            id_bit_number++;
+            rom_byte_mask <<= 1;
+
+            // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask
+            if (rom_byte_mask == 0)
+            {
+               crc8 = RomId::calculateCRC8(crc8, romId[rom_byte_number]);  // accumulate the CRC
+               rom_byte_number++;
+               rom_byte_mask = 1;
+            }
+         }
+      }
+      while(rom_byte_number < RomId::byteLen);  // loop until through all ROM bytes 0-7
+
+      // if the search was successful then
+      if (!((id_bit_number <= (RomId::byteLen * 8)) || (crc8 != 0)))
+      {
+         // search successful so set m_lastDiscrepancy,m_lastDeviceFlag,search_result
+         m_lastDiscrepancy = last_zero;
+
+         // check for last device
+         if (m_lastDiscrepancy == 0)
+            m_lastDeviceFlag = true;
+
+         search_result = true;
+      }
+   }
+
+   // if no device found then reset counters so next 'search' will be like a first
+   if (!search_result || (romId.familyCode() == 0))
+   {
+      m_lastDiscrepancy = 0;
+      m_lastDeviceFlag = false;
+      m_lastFamilyDiscrepancy = 0;
+      search_result = false;
+   }
+
+   return search_result ? OneWireMaster::Success : OneWireMaster::OperationFailure;
+}
+
+//--------------------------------------------------------------------------
+// Find the 'first' devices on the 1-Wire network
+// Return true  : device found, ROM number in ROM_NO buffer
+//        false : no device present
+//
+OneWireMaster::CmdResult DS2465::OWFirst(RomId & romId)		
+{
+   // reset the search state
+   m_lastDiscrepancy = 0;
+   m_lastDeviceFlag = false;
+   m_lastFamilyDiscrepancy = 0;
+
+   return OWSearch(romId);
+}
+
+//--------------------------------------------------------------------------
+// The 'OWReadBlock' receives a block of data from the
+// 1-Wire Net. The destination is the mac buffer (rx_mac=1) or 
+// the scratchpad (rx_mac=0). The result is buffer is returned. 
+//
+// 'rx_buf'   - pointer to a block to receive bytes
+//              of length 'rx_len' from 1-Wire Net
+// 'rx_len' - length in bytes to read. Only valid numbers are 8,16,20,32;
+//
+OneWireMaster::CmdResult DS2465::OWReadBlock(uint8_t *rx_buf, uint8_t rx_len)	
+{
+  uint8_t status;
+  int poll_count = 0;
+  OneWireMaster::CmdResult result;
+
+  // 1-Wire Receive Block (Case A)
+  //   S AD,0 [A] ADDR_CMD_REG [A] 1WRF [A] PR [A] P
+  //  [] indicates from slave
+  //  PR indicates byte containing parameter
+   
+  m_I2C_interface.start();
+  if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK)
+  {
+     m_I2C_interface.stop();
+     return OneWireMaster::CommunicationWriteError;
+  }
+  if (m_I2C_interface.write(ADDR_CMD_REG) != I2C_WRITE_OK)
+  {
+     m_I2C_interface.stop();
+     return OneWireMaster::CommunicationWriteError;
+  }
+  if (m_I2C_interface.write(CMD_1WRF) != I2C_WRITE_OK)
+  {
+     m_I2C_interface.stop();
+     return OneWireMaster::CommunicationWriteError;
+  }
+  if (m_I2C_interface.write((unsigned char)rx_len) != I2C_WRITE_OK)
+  {
+     m_I2C_interface.stop();
+     return OneWireMaster::CommunicationWriteError;
+  }
+  m_I2C_interface.stop();
+  status = STATUS_1WB;
+   
+   // loop checking 1WB bit for completion of 1-Wire operation 
+   // abort if poll limit reached
+   while ((status & STATUS_1WB) && (poll_count++ < POLL_LIMIT))
+   {
+      result = ReadMemory(ADDR_STATUS_REG, &status, 1, false);
+      if (result != OneWireMaster::Success)
+        return result;
+   }
+
+   // check for failure due to poll limit reached
+   if (poll_count >= POLL_LIMIT)
+   {
+      // handle error
+      // ...
+      //Reset();
+      return OneWireMaster::TimeoutError;
+   }
+
+   result = ReadMemory(ADDR_SPAD, rx_buf, rx_len, false);
+
+   // read out the data
+   return result;
+}
+
+
+
+
+OneWireMaster::CmdResult DS2465::OWWriteBlock(const uint8_t *tran_buf, uint8_t tran_len)
+{
+  return OWWriteBlock(false, tran_buf, tran_len);
+}
+
+//--------------------------------------------------------------------------
+// The 'OWWriteBlock' transfers a block of data to the
+// 1-Wire Net. The mac buffer can be sent (tx_mac=1) or a
+// portion of the scratchpad can be sent. 
+//
+// 'tx_mac'   - flag to indicate if the MAC buffer is to be sent (1) or
+//              the data provided in teh tran_buf is to be sent (0)
+// 'tran_buf' - pointer to a block of bytes
+//              of length 'tran_len' that will be sent
+//              to the 1-Wire Net
+// 'tran_len' - length in bytes to transfer. Only valid numbers are 8,16,20,32;
+//
+OneWireMaster::CmdResult DS2465::OWWriteBlock(bool tx_mac, const uint8_t *tran_buf, uint8_t tran_len)
+{
+  OneWireMaster::CmdResult result;
+  uint8_t par, status;
+  int poll_count = 0;
+
+  // create parameter byte
+  if (tx_mac)
+    par = 0xFF;
+  else
+  {
+    // scratchpad is source
+    par = tran_len; 
+
+    // prefill scratchpad with required data
+    result = WriteScratchpad(ADDR_SPAD, tran_buf, tran_len);
+    if (result != OneWireMaster::Success)
+      return result;
+  }
+
+  // 1-Wire Transmit Block (Case A)
+  //   S AD,0 [A] ADDR_CMD_REG [A] 1WTB [A] PR [A] P
+  //  [] indicates from slave
+  //  PR indicates byte containing parameter
+
+  m_I2C_interface.start();
+  if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK)
+  {
+    m_I2C_interface.stop();
+    return OneWireMaster::CommunicationWriteError;
+  }
+  if (m_I2C_interface.write(ADDR_CMD_REG) != I2C_WRITE_OK)
+  {
+    m_I2C_interface.stop();
+    return OneWireMaster::CommunicationWriteError;
+  }
+  if (m_I2C_interface.write(CMD_1WTB) != I2C_WRITE_OK)
+  {
+    m_I2C_interface.stop();
+    return OneWireMaster::CommunicationWriteError;
+  }
+  if (m_I2C_interface.write(par) != I2C_WRITE_OK)
+  {
+    m_I2C_interface.stop();
+    return OneWireMaster::CommunicationWriteError;
+  }
+  m_I2C_interface.stop();
+
+  // loop checking 1WB bit for completion of 1-Wire operation 
+  // abort if poll limit reached
+  status = STATUS_1WB;
+  while ((status & STATUS_1WB) && (poll_count++ < POLL_LIMIT))
+  {
+    result = ReadMemory(ADDR_STATUS_REG, &status, 1, false);
+    if (result != OneWireMaster::Success)
+      return result;
+  }
+
+  // check for failure due to poll limit reached
+  if (poll_count >= POLL_LIMIT)
+  {
+    // handle error
+    // ...
+    //Reset();
+    return OneWireMaster::TimeoutError;
+  }
+
+  return OneWireMaster::Success;
+}
+
+//--------------------------------------------------------------------------
+// The 'OWBlock' transfers a block of data to and from the
+// 1-Wire Net. The result is returned in the same buffer.
+//
+// 'tran_buf' - pointer to a block of unsigned
+//              chars of length 'tran_len' that will be sent
+//              to the 1-Wire Net
+// 'tran_len' - length in bytes to transfer
+//
+OneWireMaster::CmdResult DS2465::OWBlock(uint8_t *tran_buf, uint8_t tran_len)
+{
+  OneWireMaster::CmdResult result;
+  for (uint8_t i = 0; i < tran_len; i++)
+  {
+    result = OWTouchByte(tran_buf[i]);
+    if (result != OneWireMaster::Success)
+      break;
+  }
+  return result;
+}
+
+//--------------------------------------------------------------------------
+// Send 8 bits of communication to the 1-Wire Net and return the
+// result 8 bits read from the 1-Wire Net.  The parameter 'sendbyte'
+// least significant 8 bits are used and the least significant 8 bits
+// of the result is the return byte.
+//
+// 'sendbyte' - 8 bits to send (least significant byte)
+//
+// Returns:  8 bits read from sendbyte
+//
+OneWireMaster::CmdResult DS2465::OWTouchByte(uint8_t & sendrecvbyte)
+{
+  OneWireMaster::CmdResult result = OWWriteByte(sendrecvbyte);
+  if (result == OneWireMaster::Success)
+    OWReadByte(sendrecvbyte);
+  return result;
+}
+
+//--------------------------------------------------------------------------
+// Send 8 bits of read communication to the 1-Wire Net and return the
+// result 8 bits read from the 1-Wire Net.
+//
+// Returns:  8 bits read from 1-Wire Net
+//
+OneWireMaster::CmdResult DS2465::OWReadByte(uint8_t & recvbyte)	
+{
+   uint8_t status;
+   int poll_count = 0;
+
+   // 1-Wire Read Bytes (Case C)
+   //   S AD,0 [A] ADDR_CMD_REG [A] 1WRB [A] Sr AD,1 [A] [Status] A [Status] A\ 
+   //                                                  \--------/        
+   //                     Repeat until 1WB bit has changed to 0
+   //   Sr AD,0 [A] SRP [A] E1 [A] Sr AD,1 [A] DD A\ P
+   //                                  
+   //  [] indicates from slave
+   //  DD data read
+   
+  m_I2C_interface.start();
+  if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK)
+  {
+     m_I2C_interface.stop();
+     return OneWireMaster::CommunicationWriteError;
+  }
+  if (m_I2C_interface.write(ADDR_CMD_REG) != I2C_WRITE_OK)
+  {
+     m_I2C_interface.stop();
+     return OneWireMaster::CommunicationWriteError;
+  }
+  if (m_I2C_interface.write(CMD_1WRB) != I2C_WRITE_OK)
+  {
+     m_I2C_interface.stop();
+     return OneWireMaster::CommunicationWriteError;
+  }
+  m_I2C_interface.start();
+  if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_READ)) != I2C_WRITE_OK)
+     return OneWireMaster::CommunicationWriteError;
+
+  // loop checking 1WB bit for completion of 1-Wire operation 
+  // abort if poll limit reached
+  status = STATUS_1WB;
+  while ((status & STATUS_1WB) && (poll_count++ < POLL_LIMIT))
+  {
+     status = m_I2C_interface.read(m_I2C_interface.ACK);
+  }
+
+  // one last read with NACK
+  m_I2C_interface.read(m_I2C_interface.NoACK);
+
+  // check for failure due to poll limit reached
+  if (poll_count >= POLL_LIMIT)
+  {
+     // handle error
+     // ...
+     //Reset();
+     return OneWireMaster::TimeoutError;
+  }
+
+  m_I2C_interface.start();
+  if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK)
+  {
+     m_I2C_interface.stop();
+     return OneWireMaster::CommunicationWriteError;
+  }
+  if (m_I2C_interface.write(ADDR_DATA_REG) != I2C_WRITE_OK)
+  {
+     m_I2C_interface.stop();
+     return OneWireMaster::CommunicationWriteError;
+  }
+  m_I2C_interface.start();
+  if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_READ)) != I2C_WRITE_OK)
+  {
+     m_I2C_interface.stop();
+     return OneWireMaster::CommunicationWriteError;
+  }
+  recvbyte = m_I2C_interface.read(m_I2C_interface.NoACK);
+  
+  m_I2C_interface.stop();
+   
+  return OneWireMaster::Success;
+}
+
+//--------------------------------------------------------------------------
+// Send 8 bits of communication to the 1-Wire Net and verify that the
+// 8 bits read from the 1-Wire Net is the same (write operation).
+// The parameter 'sendbyte' least significant 8 bits are used.
+//
+// 'sendbyte' - 8 bits to send (least significant byte)
+//
+// Returns:  true: bytes written and echo was the same
+//           false: echo was not the same
+//
+OneWireMaster::CmdResult DS2465::OWWriteByte(uint8_t sendbyte)	
+{
+  uint8_t status;
+  int poll_count = 0;
+    
+  // 1-Wire Write Byte (Case B)
+  //   S AD,0 [A] ADDR_CMD_REG [A] 1WWB [A] DD [A] Sr AD,1 [A] [Status] A [Status] A\ P
+  //                                                           \--------/        
+  //                             Repeat until 1WB bit has changed to 0
+  //  [] indicates from slave
+  //  DD data to write
+   
+  m_I2C_interface.start();
+  if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK)
+  {
+     m_I2C_interface.stop();
+     return OneWireMaster::CommunicationWriteError;
+  }
+  if (m_I2C_interface.write(ADDR_CMD_REG) != I2C_WRITE_OK)
+  {
+     m_I2C_interface.stop();
+     return OneWireMaster::CommunicationWriteError;
+  }
+  if (m_I2C_interface.write(CMD_1WWB) != I2C_WRITE_OK)
+  {
+     m_I2C_interface.stop();
+     return OneWireMaster::CommunicationWriteError;
+  }
+  if (m_I2C_interface.write(sendbyte) != I2C_WRITE_OK)
+  {
+     m_I2C_interface.stop();
+     return OneWireMaster::CommunicationWriteError;
+  }
+
+  m_I2C_interface.start();
+  if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_READ)) != I2C_WRITE_OK)
+  {
+     m_I2C_interface.stop();
+     return OneWireMaster::CommunicationWriteError;
+  }
+
+  // loop checking 1WB bit for completion of 1-Wire operation 
+  // abort if poll limit reached
+  status = STATUS_1WB;
+  while ((status & STATUS_1WB) && (poll_count++ < POLL_LIMIT))
+  {
+     status = m_I2C_interface.read(m_I2C_interface.ACK);
+  }
+
+  // one last read with NACK
+  m_I2C_interface.read(m_I2C_interface.NoACK);
+
+  m_I2C_interface.stop();
+
+  // check for failure due to poll limit reached
+  if (poll_count >= POLL_LIMIT)
+  {
+     // handle error
+     // ...
+     //Reset();
+    return OneWireMaster::TimeoutError;
+  }
+  
+  return OneWireMaster::Success;
+}
+
+//--------------------------------------------------------------------------
+// Send 1 bit of communication to the 1-Wire Net and return the
+// result 1 bit read from the 1-Wire Net.  The parameter 'sendbit'
+// least significant bit is used and the least significant bit
+// of the result is the return bit.
+//
+// 'sendbit' - the least significant bit is the bit to send
+//
+// Returns: 0:   0 bit read from sendbit
+//          1:   1 bit read from sendbit
+//
+OneWireMaster::CmdResult DS2465::OWTouchBit(uint8_t & sendrecvbit)	
+{
+  unsigned char status;
+  int poll_count = 0;
+
+  // 1-Wire bit (Case B)
+  //   S AD,0 [A] ADDR_CMD_REG [A] 1WSB [A] BB [A] Sr AD,1 [A] [Status] A [Status] A\ P
+  //                                                          \--------/        
+  //                           Repeat until 1WB bit has changed to 0
+  //  [] indicates from slave
+  //  BB indicates byte containing bit value in msbit
+   
+  m_I2C_interface.start();
+  if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK)
+  {
+   m_I2C_interface.stop();
+   return OneWireMaster::CommunicationWriteError;
+  }
+  if (m_I2C_interface.write(ADDR_CMD_REG) != I2C_WRITE_OK)
+  {
+   m_I2C_interface.stop();
+   return OneWireMaster::CommunicationWriteError;
+  }
+  if (m_I2C_interface.write(CMD_1WSB) != I2C_WRITE_OK)
+  {
+   m_I2C_interface.stop();
+   return OneWireMaster::CommunicationWriteError;
+  }
+  if (m_I2C_interface.write(sendrecvbit ? 0x80 : 0x00) != I2C_WRITE_OK)
+  {
+   m_I2C_interface.stop();
+   return OneWireMaster::CommunicationWriteError;
+  }
+  m_I2C_interface.start();
+  if (m_I2C_interface.write(m_I2C_address | I2C_READ) != I2C_WRITE_OK)
+  {
+   m_I2C_interface.stop();
+   return OneWireMaster::CommunicationWriteError;
+  }
+
+  // loop checking 1WB bit for completion of 1-Wire operation 
+  // abort if poll limit reached
+  status = STATUS_1WB;
+  while ((status & STATUS_1WB) && (poll_count++ < POLL_LIMIT))
+  {
+    status = m_I2C_interface.read(status & STATUS_1WB);
+  }
+
+  // one last read with NACK
+  m_I2C_interface.read(m_I2C_interface.NoACK);
+
+  m_I2C_interface.stop();
+
+  // check for failure due to poll limit reached
+  if (poll_count >= POLL_LIMIT)
+  {
+   // handle error
+   // ...
+   //Reset();
+   return OneWireMaster::TimeoutError;
+  }
+ 
+  // check bit state
+  sendrecvbit = (status & STATUS_SBR);
+  
+  return OneWireMaster::Success;
+}
+
+//--------------------------------------------------------------------------
+// Reads 1 bit of communication from the 1-Wire Net and returns the
+// result
+//
+// Returns:  1 bit read from 1-Wire Net
+//
+OneWireMaster::CmdResult DS2465::OWReadBit(uint8_t & recvbit)
+{
+   recvbit = 0x01;
+   return OWTouchBit(recvbit);
+}
+
+//--------------------------------------------------------------------------
+// Send 1 bit of communication to the 1-Wire Net.
+// The parameter 'sendbit' least significant bit is used.
+//
+// 'sendbit' - 1 bit to send (least significant byte)
+//
+OneWireMaster::CmdResult DS2465::OWWriteBit(uint8_t sendbit) 
+{
+   return OWTouchBit(sendbit);
+}
+
+//--------------------------------------------------------------------------
+// 
+//
+// 
+// 
+// 
+// 
+//
+// Returns: 
+//          
+//
+OneWireMaster::CmdResult DS2465::Write_Command_Reg(unsigned char cmd, unsigned char par, bool poll) const
+{
+  int poll_count = 0, status;
+ 
+  // Generic command
+  //   S AD,0 [A] ADDR_CMD_REG [A] CMD [A] PP [A]  P
+  //  [] indicates from slave
+  //  CMD command
+  //  PP parameter 
+
+  m_I2C_interface.start();
+  if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK)
+  {
+     m_I2C_interface.stop();
+     return OneWireMaster::CommunicationWriteError;
+  }
+  if (m_I2C_interface.write(ADDR_CMD_REG) != I2C_WRITE_OK)
+  {
+     m_I2C_interface.stop();
+     return OneWireMaster::CommunicationWriteError;
+  }
+  if (m_I2C_interface.write(cmd) != I2C_WRITE_OK)
+  {
+     m_I2C_interface.stop();
+     return OneWireMaster::CommunicationWriteError;
+  }
+  if (m_I2C_interface.write(par) != I2C_WRITE_OK)
+  {
+     m_I2C_interface.stop();
+     return OneWireMaster::CommunicationWriteError;
+  }
+
+  m_I2C_interface.stop();
+   
+  poll_count = 0;
+  if (poll)
+  {
+    // Poll for completion by checking for NAK on address
+    do
+    {
+       m_I2C_interface.start();
+       status = m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE));
+       m_I2C_interface.stop();
+    } while ((status != I2C_WRITE_OK) && (poll_count++ < POLL_LIMIT));
+  }
+  else
+  {  
+    // delay instead of poll, longest operation (only for SHA compute)
+    wait_ms(SHA_COMPUTATION_DELAY * 2); 
+    wait_ms(8); // Additional delay
+  }
+
+  // check for failure due to poll limit reached
+  if (poll_count >= POLL_LIMIT)
+  {
+    // handle error
+    // ...
+    //Reset();
+    return OneWireMaster::TimeoutError;
+  }
+
+  return OneWireMaster::Success;
+}
+
+//--------------------------------------------------------------------------
+// Write to Scratchpad (SRAM) memory on the DS2465
+//
+// 'addr' - address to start writing (must be in SRAM)
+// 'buf' - buffer of data to write
+// 'len' - length to write
+//
+// Returns: true write successful
+//          false failure to complete write
+//
+OneWireMaster::CmdResult DS2465::WriteScratchpad(std::uint8_t addr, const std::uint8_t * buf, size_t bufLen) const
+{
+  int i;
+
+  // Write SRAM (Case A)
+  //   S AD,0 [A] VSA [A] DD [A]  P
+  //                      \-----/
+  //                        Repeat for each data byte
+  //  [] indicates from slave
+  //  VSA valid SRAM memory address
+  //  DD memory data to write
+  
+  m_I2C_interface.start();
+  if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK)
+  {
+     m_I2C_interface.stop();
+     return OneWireMaster::CommunicationWriteError;
+  }
+  if (m_I2C_interface.write((unsigned char)addr) != I2C_WRITE_OK)
+  {
+     m_I2C_interface.stop();
+     return OneWireMaster::CommunicationWriteError;
+  }
+  // loop to write each byte
+  for (i = 0; i < bufLen; i++)
+  {
+     if (m_I2C_interface.write(buf[i]) != I2C_WRITE_OK)
+     {
+        m_I2C_interface.stop();
+        return OneWireMaster::CommunicationWriteError;
+     }
+  }
+  m_I2C_interface.stop();
+   
+   return OneWireMaster::Success;
+}
+
+//--------------------------------------------------------------------------
+// Read memory from the DS2465
+//
+// 'addr' - address to start reading
+// 'buf' - buffer to hold memory read
+// 'len' - length to read
+// 'skip_set_pointer' - flag to indicate to skip setting address pointer
+//
+// Returns: true read successful
+//          false failure to complete read
+//
+OneWireMaster::CmdResult DS2465::ReadMemory(std::uint8_t addr, std::uint8_t * buf, size_t bufLen, bool skip_set_pointer) const
+{
+   int i;
+
+   // Read (Case A)
+   //   S AD,0 [A] MA [A] Sr AD,1 [A] [DD] A [DD] A\ P
+   //                                 \-----/
+   //                                   Repeat for each data byte, NAK last byte
+   //  [] indicates from slave
+   //  MA memory address
+   //  DD memory data read
+
+      m_I2C_interface.start();
+      if (!skip_set_pointer)
+      {
+         if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK)
+         {
+            m_I2C_interface.stop();
+            return OneWireMaster::CommunicationWriteError;
+         }
+         if (m_I2C_interface.write((unsigned char)addr) != I2C_WRITE_OK)
+         {
+            m_I2C_interface.stop();
+            return OneWireMaster::CommunicationWriteError;
+         }
+         m_I2C_interface.start();
+      }
+
+      if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_READ)) != I2C_WRITE_OK)
+      {
+         m_I2C_interface.stop();
+         return OneWireMaster::CommunicationWriteError;
+      }
+      // loop to read each byte, NAK last byte
+      for (i = 0; i < bufLen; i++)
+      {
+         buf[i] = m_I2C_interface.read((i == (bufLen - 1)) ? m_I2C_interface.NoACK : m_I2C_interface.ACK);
+      }
+      m_I2C_interface.stop();
+  
+   return OneWireMaster::Success;
+}
+
+
+
+
+
+OneWireMaster::CmdResult DS2465::ReadOneWireConfig(OWConfigAddr addr, std::uint8_t & config) const
+{
+  std::uint8_t buf;
+  OneWireMaster::CmdResult result = ReadMemory(addr, &buf, 1, false);
+  if (result == OneWireMaster::Success)
+    config = buf;
+  return result;
+}
+
+
+
+
+
+OneWireMaster::CmdResult DS2465::WriteOneWireConfig(OWConfigAddr addr, unsigned int ovr, unsigned int std)
+{
+  std::uint8_t buf;
+
+   // convert and write value
+   buf = (ovr << 4) | std;
+   return (WriteScratchpad(addr, &buf, 1));
+}
+
+//--------------------------------------------------------------------------
+// Write the configuration register in the DS2465. The configuration 
+// options are provided in the lower nibble of the provided config byte. 
+// The uppper nibble in bitwise inverted when written to the DS2465.
+//  
+// Returns:  true: config written and response correct
+//           false: response incorrect
+//
+OneWireMaster::CmdResult DS2465::Write_Config(uint8_t config)
+{
+  unsigned char read_config;
+   
+  // Write configuration byte
+  //   S AD,0 [A] ADDR_WCFG_REG [A] CONIG [A] P
+  //  [] indicates from slave
+  //  CF configuration byte to write
+
+  m_I2C_interface.start();
+  
+  if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK)
+  {
+     m_I2C_interface.stop();
+     return OneWireMaster::CommunicationWriteError;
+  }
+  if (m_I2C_interface.write(ADDR_WCFG_REG) != I2C_WRITE_OK)
+  {
+     m_I2C_interface.stop();
+     return OneWireMaster::CommunicationWriteError;
+  }
+  if (m_I2C_interface.write((unsigned char)(config | (~config << 4))) != I2C_WRITE_OK)
+  {
+     m_I2C_interface.stop();
+     return OneWireMaster::CommunicationWriteError;
+  }
+  m_I2C_interface.stop();
+
+  // read it back to confirm
+  // S AD,0 [A] ADDR_WCFG_REG [A] Sr AD,1 [A] [CF] A\ 
+
+  m_I2C_interface.start();
+  if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK)
+  {
+     m_I2C_interface.stop();
+     return OneWireMaster::CommunicationWriteError;
+  }
+  if (m_I2C_interface.write(ADDR_WCFG_REG) != I2C_WRITE_OK)
+  {
+     m_I2C_interface.stop();
+     return OneWireMaster::CommunicationWriteError;
+  }
+  m_I2C_interface.start();
+  if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_READ)) != I2C_WRITE_OK)
+  {
+     m_I2C_interface.stop();
+     return OneWireMaster::CommunicationWriteError;
+  }
+  read_config = m_I2C_interface.read(m_I2C_interface.NoACK);
+  m_I2C_interface.stop();
+   
+
+   // check for failure due to incorrect read back
+   if (config != read_config)
+   {
+      // handle error
+      // ...
+      //Reset();
+
+      return OneWireMaster::TimeoutError;  
+   }
+   
+   return OneWireMaster::Success;
+}
+
+//--------------------------------------------------------------------------
+// Reset all of the devices on the 1-Wire Net and return the result.
+//
+// Returns: true(1):  presense pulse(s) detected, device(s) reset
+//          false(0): no presense pulses detected
+//
+OneWireMaster::CmdResult DS2465::OWReset(void)
+{
+   unsigned char status;
+   int poll_count = 0;
+     
+   // 1-Wire reset (Case B)
+   //   S AD,0 [A] ADDR_CMD_REG  [A] 1WRS [A] Sr AD,1 [A] [Status] A [Status] A\ P
+   //                                                  \--------/        
+   //                       Repeat until 1WB bit has changed to 0
+   //  [] indicates from slave
+   
+    m_I2C_interface.start();
+    
+    if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK)
+    {
+       m_I2C_interface.stop();
+       return OneWireMaster::CommunicationWriteError;
+    }
+    if (m_I2C_interface.write(ADDR_CMD_REG) != I2C_WRITE_OK)
+    {
+       m_I2C_interface.stop();
+       return OneWireMaster::CommunicationWriteError;
+    }
+    if (m_I2C_interface.write(CMD_1WRS) != I2C_WRITE_OK)
+    {
+      m_I2C_interface.stop();
+       return OneWireMaster::CommunicationWriteError;
+    }
+    m_I2C_interface.start();
+    if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_READ)) != I2C_WRITE_OK)
+    {
+       m_I2C_interface.stop();
+       return OneWireMaster::CommunicationWriteError;
+    }
+
+    // loop checking 1WB bit for completion of 1-Wire operation 
+    // abort if poll limit reached
+    status = STATUS_1WB;
+    while ((status & STATUS_1WB) && (poll_count++ < POLL_LIMIT))
+    {
+       status = m_I2C_interface.read(m_I2C_interface.ACK);
+    }
+
+    // one last read with NACK
+    m_I2C_interface.read(m_I2C_interface.NoACK);
+
+    m_I2C_interface.stop();
+
+    // check for failure due to poll limit reached
+    if (poll_count >= POLL_LIMIT)
+    {
+       // handle error
+       // ...
+       //Reset();
+       return OneWireMaster::TimeoutError;
+    }
+   
+   // check for short condition
+   if (status & STATUS_SD)
+      short_detected = true;
+   else
+      short_detected = false;
+   
+
+   // check for presence detect
+   if (status & STATUS_PPD)
+      return OneWireMaster::Success;
+   // else
+   return OneWireMaster::OperationFailure;
+}
+
+OneWireMaster::CmdResult DS2465::Reset(void)
+{
+  uint8_t status;
+  
+  // Device Reset
+  //   S AD,0 [A] ADDR_CMD_REG [A] 1WMR [A] Sr AD,1 [A] [SS] A\ P
+  //  [] indicates from slave
+  //  SS status byte to read to verify state
+  
+  m_I2C_interface.start(); 
+  
+  if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK)
+  {
+    m_I2C_interface.stop();
+    return OneWireMaster::CommunicationWriteError;
+  }
+  
+  if (m_I2C_interface.write(ADDR_CMD_REG) != I2C_WRITE_OK)
+  {
+     m_I2C_interface.stop();
+     return OneWireMaster::CommunicationWriteError;
+  }
+  
+  if (m_I2C_interface.write(CMD_1WMR) != I2C_WRITE_OK)
+  {
+     m_I2C_interface.stop();
+     return OneWireMaster::CommunicationWriteError;
+  }
+  
+  m_I2C_interface.start();
+  
+  if (m_I2C_interface.write((unsigned char)(m_I2C_address | I2C_READ)) != I2C_WRITE_OK)
+  {
+     m_I2C_interface.stop();
+     return OneWireMaster::CommunicationWriteError;
+  }
+ 
+  status = m_I2C_interface.read(m_I2C_interface.NoACK);
+
+  m_I2C_interface.stop();
+      
+  // do a command to get 1-Wire master reset out of holding state
+  OWReset();
+
+  // check for failure due to incorrect read back of status
+  return ((status & 0xF7) == 0x10) ? OneWireMaster::Success : OneWireMaster::OperationFailure;
+}
+
+OneWireMaster::CmdResult DS2465::Detect(void)
+{
+  OneWireMaster::CmdResult result;
+  
+  // reset DS2465 
+  result = Reset();
+  if (result != OneWireMaster::Success)
+    return result;
+  
+  // default configuration
+   c1WS = 0;
+   cSPU = 0;
+   cPDN = 0;
+   cAPU = CONFIG_APU;
+
+   // write the default configuration setup
+   result = Write_Config(c1WS | cSPU | cPDN | cAPU);
+   return result;
+}