Mike Fruge / OneWire

Dependents:   Max32630_One_Wire_Interface

Files at this revision

API Documentation at this revision

Comitter:
IanBenzMaxim
Date:
Mon Mar 21 14:12:28 2016 -0500
Parent:
20:ba60c076e92b
Child:
22:686273e55cdc
Commit message:
Added class for DS2465. Added a ReadBytePower operation to OneWireMaster since this is required by the authenticators including the DS28E15. Tweaked member data of OneWireMaster. Added path to header file includes to reduce compiler setup required.

Changed in this revision

OneWire_Bridge/DS28E17/ds28e17.h Show annotated file Show diff for this revision Revisions of this file
OneWire_Masters/DS2465/DS2465.cpp Show annotated file Show diff for this revision Revisions of this file
OneWire_Masters/DS2465/DS2465.hpp Show annotated file Show diff for this revision Revisions of this file
OneWire_Masters/DS248x/ds248x.cpp Show annotated file Show diff for this revision Revisions of this file
OneWire_Masters/DS248x/ds248x.h Show annotated file Show diff for this revision Revisions of this file
OneWire_Masters/GPIO/owgpio.cpp Show annotated file Show diff for this revision Revisions of this file
OneWire_Masters/ISha256MacCoprocessor.hpp Show annotated file Show diff for this revision Revisions of this file
OneWire_Masters/OneWireMaster.cpp Show annotated file Show diff for this revision Revisions of this file
OneWire_Masters/OneWireMaster.h Show annotated file Show diff for this revision Revisions of this file
OneWire_Masters/OneWireMasters.h Show annotated file Show diff for this revision Revisions of this file
OneWire_Masters/RomId.cpp Show diff for this revision Revisions of this file
OneWire_Masters/RomId.hpp Show diff for this revision Revisions of this file
OneWire_Switches/DS2413/ds2413.h Show annotated file Show diff for this revision Revisions of this file
OneWire_Switches/OneWireSwitches.h Show annotated file Show diff for this revision Revisions of this file
RomId.cpp Show annotated file Show diff for this revision Revisions of this file
RomId.hpp Show annotated file Show diff for this revision Revisions of this file
--- a/OneWire_Bridge/DS28E17/ds28e17.h	Mon Mar 21 01:28:34 2016 +0000
+++ b/OneWire_Bridge/DS28E17/ds28e17.h	Mon Mar 21 14:12:28 2016 -0500
@@ -36,7 +36,7 @@
 
 
 #include "mbed.h"
-#include "OneWireMasters.h"
+#include "OneWire_Masters/OneWireMasters.h"
 
 
 class Ds28e17
--- /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;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OneWire_Masters/DS2465/DS2465.hpp	Mon Mar 21 14:12:28 2016 -0500
@@ -0,0 +1,136 @@
+#ifndef DS2465_H
+#define DS2465_H
+
+#include "mbed.h"
+#include "OneWire_Masters/OneWireMaster.h"
+#include "OneWire_Masters/ISha256MacCoprocessor.hpp"
+
+class DS2465 : public OneWireMaster, public ISha256MacCoprocessor
+{
+public:  
+  enum Direction
+  {
+    DIRECTION_WRITE_ZERO = 0,
+    DIRECTION_WRITE_ONE = 1
+  };
+  
+  enum PageRegion
+  {
+    REGION_FULL_PAGE = 0x03,
+    REGION_FIRST_HALF = 0x01,
+    REGION_SECOND_HALF = 0x02
+  };
+  
+  enum OWConfigAddr
+  {
+    ADDR_TRSTL_REG = 0x68,
+    ADDR_TMSP_REG = 0x69,
+    ADDR_TW0L_REG = 0x6A,
+    ADDR_TREC0_REG = 0x6B,
+    ADDR_RWPU_REG = 0x6C,
+    ADDR_TW1L_REG = 0x6D
+  };
+  
+  // DS2465 addresses
+  enum MemoryAddr
+  {
+    ADDR_SPAD = 0x00,
+    ADDR_CMD_REG = 0x60,
+    ADDR_STATUS_REG = 0x61,
+    ADDR_DATA_REG = 0x62,
+    ADDR_MAC_READ = 0x63,
+    ADDR_SHA_SELECT_REG = 0x66,
+    ADDR_WCFG_REG = 0x67,
+    ADDR_USER_MEM_PAGE_0 = 0x80,
+    ADDR_USER_MEM_PAGE_1 = 0xA0
+  };
+  
+  DS2465(I2C & I2C_interface, std::uint8_t I2C_address);
+  
+  // Const member functions should not change the settings of the DS2465 or affect the state of the 1-Wire bus.
+  // Read pointer, scratchpad, MAC output register, and command register on the DS2465 are considered mutable.
+
+  //Misc. Functions
+  OneWireMaster::CmdResult Detect(void);
+  OneWireMaster::CmdResult Reset(void);                                      // Resets DS2465 (NOTE: This is NOT a 1-Wire Reset)
+
+  // DS2465 Memory Commands
+  OneWireMaster::CmdResult ReadMemory(std::uint8_t addr, std::uint8_t * buf, size_t bufLen, bool skip_set_pointer = false) const;
+  OneWireMaster::CmdResult WriteScratchpad(std::uint8_t addr, const std::uint8_t * buf, size_t bufLen) const;
+  OneWireMaster::CmdResult CopyScratchpad(bool dest_secret, unsigned int pageNum, bool notFull, unsigned int segmentNum);
+
+  // DS2465 Configuration Commands
+  OneWireMaster::CmdResult ReadOneWireConfig(OWConfigAddr addr, std::uint8_t & config) const;
+  OneWireMaster::CmdResult WriteOneWireConfig(OWConfigAddr addr, unsigned int ovr, unsigned int std);
+  
+  // 1-Wire Master Commands
+  virtual OneWireMaster::CmdResult OWInitMaster(void);
+  virtual OneWireMaster::CmdResult OWReset(void);                                   // Issues a 1-Wire Reset Pulse
+  virtual OneWireMaster::CmdResult OWWriteByte(uint8_t sendbyte);
+  virtual OneWireMaster::CmdResult OWReadByte(uint8_t & recvbyte);
+  virtual OneWireMaster::CmdResult OWTouchByte(uint8_t & sendrecvbyte);
+  virtual OneWireMaster::CmdResult OWTouchBit(uint8_t & sendrecvbit);
+  virtual OneWireMaster::CmdResult OWWriteBit(uint8_t sendbit);
+  virtual OneWireMaster::CmdResult OWReadBit(uint8_t & recvbit);
+  virtual OneWireMaster::CmdResult OWBlock(uint8_t *tran_buf, uint8_t tran_len);
+  virtual OneWireMaster::CmdResult OWFirst(RomId & romId);
+  virtual OneWireMaster::CmdResult OWNext(RomId & romId);
+  virtual OneWireMaster::CmdResult OWVerify(const RomId & romId);
+  virtual void OWTargetSetup(RomId & romId);
+  virtual void OWFamilySkipSetup(void);
+  virtual OneWireMaster::CmdResult OWSearch(RomId & romId);
+  virtual OneWireMaster::CmdResult OWReadROM(RomId & romId);
+  virtual OneWireMaster::CmdResult OWSkipROM(void);
+  virtual OneWireMaster::CmdResult OWMatchROM(const RomId & romId);
+  virtual OneWireMaster::CmdResult OWOverdriveSkipROM(void);
+  virtual OneWireMaster::CmdResult OWResume(void);
+  virtual OneWireMaster::CmdResult OWOverdriveMatchROM(const RomId & romId);
+  
+  // Extended 1-Wire functions
+  virtual OneWireMaster::CmdResult OWSpeed(OW_SPEED new_speed);
+  virtual OneWireMaster::CmdResult OWLevel(OW_LEVEL new_level);
+  virtual OneWireMaster::CmdResult OWWriteBytePower(uint8_t sendbyte);
+  virtual OneWireMaster::CmdResult OWReadBytePower(uint8_t & recvbyte);
+  virtual OneWireMaster::CmdResult OWReadBitPower(uint8_t applyPowerResponse);
+  virtual OneWireMaster::CmdResult OWWriteBlock(const uint8_t *tran_buf, uint8_t tran_len);
+  OneWireMaster::CmdResult OWWriteBlock(bool tx_mac, const uint8_t *tran_buf, uint8_t tran_len);
+  virtual OneWireMaster::CmdResult OWReadBlock(uint8_t *rx_buf, uint8_t rx_len);
+  OneWireMaster::CmdResult OWPowerDown(void);
+  OneWireMaster::CmdResult OWPowerUp(void);
+  OneWireMaster::CmdResult ConfigureAPU(bool apu_enable);
+
+  OneWireMaster::CmdResult Triplet(Direction search_direction, uint8_t & status);
+  
+  //DS2465 Coprocessor Commands
+  OneWireMaster::CmdResult Compute_NextMasterSecret(bool swap, unsigned int pageNum, PageRegion region);
+  OneWireMaster::CmdResult Compute_WriteMAC(bool regwrite, bool swap, unsigned int pageNum, unsigned int segmentNum) const;
+  OneWireMaster::CmdResult Compute_SSecret(bool swap, unsigned int pageNum, PageRegion region);
+  OneWireMaster::CmdResult Compute_AuthMAC(bool swap, unsigned int pageNum, PageRegion region) const;
+  
+  virtual ISha256MacCoprocessor::CmdResult setMasterSecret(const std::uint8_t (&secret)[ISha256MacCoprocessor::secret_len]);
+  virtual ISha256MacCoprocessor::CmdResult ComputeAndRead_WriteMAC(const std::uint8_t (&WriteMAC_data)[WriteMAC_data_len], std::uint8_t (&mac)[mac_len]) const;
+  virtual ISha256MacCoprocessor::CmdResult 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;
+  virtual ISha256MacCoprocessor::CmdResult Compute_SSecret(const std::uint8_t (&devicePage)[devicePage_len],
+                               const std::uint8_t (&deviceScratchpad)[deviceScratchpad_len], const std::uint8_t (&SSecret_data)[SSecret_data_len]);
+  
+private:
+  static const int POLL_LIMIT = 200;
+  
+  I2C & m_I2C_interface;
+  std::uint8_t m_I2C_address;
+
+  std::uint8_t c1WS, cSPU, cPDN, cAPU;
+  bool short_detected;
+
+  // Search state
+  std::uint8_t m_lastDiscrepancy;
+  std::uint8_t m_lastFamilyDiscrepancy;
+  std::uint8_t m_lastDeviceFlag;
+
+  //DS2465 Configuration Commands
+  OneWireMaster::CmdResult Write_Config(uint8_t config);
+  OneWireMaster::CmdResult Write_Command_Reg(uint8_t cmd, uint8_t par, bool poll) const;
+};
+
+#endif
--- a/OneWire_Masters/DS248x/ds248x.cpp	Mon Mar 21 01:28:34 2016 +0000
+++ b/OneWire_Masters/DS248x/ds248x.cpp	Mon Mar 21 14:12:28 2016 -0500
@@ -849,6 +849,35 @@
 }
 
 
+OneWireInterface::CmdResult Ds248x::OWReadBytePower(uint8_t & recvbyte)
+{
+    OneWireInterface::CmdResult result = Success;
+    uint8_t recvbit;
+    
+    recvbyte = 0;
+    for (unsigned int i = 1; i <= 8; i++)
+    {
+        // Set strong pull-up on last bit
+        if (i == 8)
+        {
+            // set strong pull-up enable
+            _cSPU = CONFIG_SPU;
+
+            // write the new config
+            result = write_config(_c1WS | _cSPU | _cPDN | _cAPU);
+            if (result != Success)
+                break;
+        }
+        result = OWReadBit(recvbit);
+        if (result != Success)
+            break;
+        recvbyte = (recvbyte << 1) | recvbit;
+    }
+    
+    return result;
+}
+
+
 //*********************************************************************
 void Ds248x::set_i2c_adrs(DS248X_I2C_ADRS adrs)
 {
--- a/OneWire_Masters/DS248x/ds248x.h	Mon Mar 21 01:28:34 2016 +0000
+++ b/OneWire_Masters/DS248x/ds248x.h	Mon Mar 21 14:12:28 2016 -0500
@@ -297,6 +297,8 @@
 
     virtual OneWireInterface::CmdResult OWReadBitPower(uint8_t applyPowerResponse);
     
+    virtual OneWireInterface::CmdResult OWReadBytePower(uint8_t & recvbyte);
+    
     private:
     
     //private fx for initializing _w_adrs and _r_adrs
--- a/OneWire_Masters/GPIO/owgpio.cpp	Mon Mar 21 01:28:34 2016 +0000
+++ b/OneWire_Masters/GPIO/owgpio.cpp	Mon Mar 21 14:12:28 2016 -0500
@@ -302,6 +302,7 @@
    uint8_t last_zero, rom_byte_number;
    uint8_t id_bit, cmp_id_bit;
    uint8_t rom_byte_mask, search_direction;
+   uint8_t crc8 = 0;
    
    bool search_result = false;
 
@@ -310,7 +311,6 @@
    last_zero = 0;
    rom_byte_number = 0;
    rom_byte_mask = 1;
-   _crc8 = 0;
 
    // if the last call was not the last one
    if (!_last_device_flag)
@@ -383,7 +383,7 @@
             // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask
             if (rom_byte_mask == 0)
             {
-                romId.calculateCRC8(romId[rom_byte_number], _crc8);  // accumulate the CRC
+                romId.calculateCRC8(romId[rom_byte_number], crc8);  // accumulate the CRC
                 rom_byte_number++;
                 rom_byte_mask = 1;
             }
@@ -392,7 +392,7 @@
       while(rom_byte_number < 8);  // loop until through all ROM bytes 0-7
 
       // if the search was successful then
-      if (!((id_bit_number < 65) || (_crc8 != 0)))
+      if (!((id_bit_number < 65) || (crc8 != 0)))
       {
          // search successful so set _last_discrepancy,_last_device_flag,search_result
          _last_discrepancy = last_zero;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OneWire_Masters/ISha256MacCoprocessor.hpp	Mon Mar 21 14:12:28 2016 -0500
@@ -0,0 +1,35 @@
+#ifndef ISHA256MACCOPROCESSOR_H
+#define ISHA256MACCOPROCESSOR_H
+
+#include <cstddef>
+#include <cstdint>
+
+class ISha256MacCoprocessor
+{
+public:
+  enum CmdResult
+  {
+    Success,
+    OperationFailure
+  };
+
+  static const std::size_t devicePage_len = 32;
+  static const std::size_t deviceScratchpad_len = 32;
+  static const std::size_t secret_len = 32;
+  
+  static const std::size_t mac_len = 32;
+  
+  static const std::size_t WriteMAC_data_len = 20;
+  static const std::size_t AuthMAC_data_len = 12;
+  static const std::size_t SSecret_data_len = 12;
+  
+  virtual CmdResult setMasterSecret(const std::uint8_t (&secret)[secret_len]) = 0;
+  
+  virtual CmdResult ComputeAndRead_WriteMAC(const std::uint8_t (&WriteMAC_data)[WriteMAC_data_len], std::uint8_t (&mac)[mac_len]) const = 0;
+  virtual CmdResult 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 = 0;
+  virtual CmdResult Compute_SSecret(const std::uint8_t (&devicePage)[devicePage_len],
+                               const std::uint8_t (&deviceScratchpad)[deviceScratchpad_len], const std::uint8_t (&SSecret_data)[SSecret_data_len]) = 0;
+};
+
+#endif
\ No newline at end of file
--- a/OneWire_Masters/OneWireMaster.cpp	Mon Mar 21 01:28:34 2016 +0000
+++ b/OneWire_Masters/OneWireMaster.cpp	Mon Mar 21 14:12:28 2016 -0500
@@ -120,7 +120,7 @@
 
     // set search to find the same device
     _last_discrepancy = 64;
-    _last_device_flag = 0;
+    _last_device_flag = false;
 
     result = OWSearch(romIdCopy);
     if (result == OneWireInterface::Success) 
@@ -326,5 +326,4 @@
   for (size_t i = data_offset; i < (data_len + data_offset); i++)
     crc = calculateCRC16(crc, data[i]);
   return crc;
-}
-
+}
\ No newline at end of file
--- a/OneWire_Masters/OneWireMaster.h	Mon Mar 21 01:28:34 2016 +0000
+++ b/OneWire_Masters/OneWireMaster.h	Mon Mar 21 14:12:28 2016 -0500
@@ -54,7 +54,7 @@
     
     static uint16_t calculateCRC16(uint16_t CRC16, uint16_t data);
     
-    static uint16_t calculateCRC16(const uint8_t * data, size_t data_offset, size_t data_len, uint16_t crc);
+    static uint16_t calculateCRC16(const uint8_t * data, size_t data_offset, size_t data_len, uint16_t crc = 0);
     
     //Part of OneWireInterface that should only be implemented once
     //See OneWireInterface.h for documentation
@@ -89,13 +89,16 @@
     
     virtual OneWireInterface::CmdResult OWResume(void);
     
+    virtual OneWireInterface::CmdResult OWReadBytePower(uint8_t & recvbyte) { return OperationFailure; }
+    
     protected:
     
     // Search state
     uint8_t _last_discrepancy;
     uint8_t _last_family_discrepancy;
-    uint8_t _last_device_flag;
-    uint8_t _crc8;   
+    bool _last_device_flag;
+
+    private:
     
     static const uint16_t _oddparity[16];
 };
--- a/OneWire_Masters/OneWireMasters.h	Mon Mar 21 01:28:34 2016 +0000
+++ b/OneWire_Masters/OneWireMasters.h	Mon Mar 21 14:12:28 2016 -0500
@@ -34,12 +34,12 @@
 #ifndef ONEWIREMASTERS_H
 #define ONEWIREMASTERS_H
 
-#include "ds248x.h"
-#include "ds2480b.h"
+#include "DS248x/ds248x.h"
+#include "DS2480B/ds2480b.h"
 
 //Bit-Bang Master only supported on MAX32600MBED Board
 #if(TARGET_MAX32600)
-    #include "owgpio.h"
+    #include "GPIO/owgpio.h"
 #endif
 
 #endif /*ONEWIREMASTERS_H*/
--- a/OneWire_Masters/RomId.cpp	Mon Mar 21 01:28:34 2016 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/******************************************************************//**
-* Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
-*
-* Permission is hereby granted, free of charge, to any person obtaining a
-* copy of this software and associated documentation files (the "Software"),
-* to deal in the Software without restriction, including without limitation
-* the rights to use, copy, modify, merge, publish, distribute, sublicense,
-* and/or sell copies of the Software, and to permit persons to whom the
-* Software is furnished to do so, subject to the following conditions:
-*
-* The above copyright notice and this permission notice shall be included
-* in all copies or substantial portions of the Software.
-*
-* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
-* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-* OTHER DEALINGS IN THE SOFTWARE.
-*
-* Except as contained in this notice, the name of Maxim Integrated
-* Products, Inc. shall not be used except as stated in the Maxim Integrated
-* Products, Inc. Branding Policy.
-*
-* The mere transfer of this software does not imply any licenses
-* of trade secrets, proprietary technology, copyrights, patents,
-* trademarks, maskwork rights, or any other form of intellectual
-* property whatsoever. Maxim Integrated Products, Inc. retains all
-* ownership rights.
-**********************************************************************/
-
-
-#include "RomId.hpp"
-
-
-//--------------------------------------------------------------------------
-// Calculate the CRC8 of the byte value provided with the current 
-// global 'crc8' value. 
-// Returns current global crc8 value
-//
-uint8_t RomId::calculateCRC8(uint8_t crc8, uint8_t data)
-{
-   int i; 
-
-   // See Application Note 27
-   crc8 = crc8 ^ data;
-   for (i = 0; i < 8; ++i)
-   {
-      if (crc8 & 1)
-         crc8 = (crc8 >> 1) ^ 0x8c;
-      else
-         crc8 = (crc8 >> 1);
-   }
-
-   return crc8;
-}
-
-uint8_t RomId::calculateCRC8(const uint8_t * data, size_t data_len, uint8_t crc)
-{
-  for (size_t i = 0; i < data_len; i++)
-    crc = calculateCRC8(crc, data[i]);
-  return crc;
-}
--- a/OneWire_Masters/RomId.hpp	Mon Mar 21 01:28:34 2016 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,114 +0,0 @@
-/******************************************************************//**
-* Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
-*
-* Permission is hereby granted, free of charge, to any person obtaining a
-* copy of this software and associated documentation files (the "Software"),
-* to deal in the Software without restriction, including without limitation
-* the rights to use, copy, modify, merge, publish, distribute, sublicense,
-* and/or sell copies of the Software, and to permit persons to whom the
-* Software is furnished to do so, subject to the following conditions:
-*
-* The above copyright notice and this permission notice shall be included
-* in all copies or substantial portions of the Software.
-*
-* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
-* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-* OTHER DEALINGS IN THE SOFTWARE.
-*
-* Except as contained in this notice, the name of Maxim Integrated
-* Products, Inc. shall not be used except as stated in the Maxim Integrated
-* Products, Inc. Branding Policy.
-*
-* The mere transfer of this software does not imply any licenses
-* of trade secrets, proprietary technology, copyrights, patents,
-* trademarks, maskwork rights, or any other form of intellectual
-* property whatsoever. Maxim Integrated Products, Inc. retains all
-* ownership rights.
-**********************************************************************/
-
-
-#ifndef _ROMID_HPP
-#define _ROMID_HPP
-
-#include "mbed.h"
-#include <cstdint>
-#include <cstring>
-
-class RomId
-{
-public:
-    static const std::size_t byteLen = 8;
-    typedef std::uint8_t byteBuffer[byteLen];
-
-    static std::uint8_t calculateCRC8(uint8_t crc8, uint8_t data);
-    static std::uint8_t calculateCRC8(const uint8_t * data, size_t data_len, uint8_t crc);
-
-private:
-    static const std::size_t familyCodeIdx = 0;
-    static const std::size_t crc8Idx = 7;
-    static const std::uint8_t defaultByteVal = 0x00;
-
-    byteBuffer m_romId;
-
-public:
-    const RomId & operator=(const RomId & rhs) {
-        std::memcpy(this->m_romId, rhs.m_romId, byteLen);
-        return rhs;
-    }
-    bool operator==(const RomId & rhs) const {
-        return (std::memcmp(this->m_romId, rhs.m_romId, byteLen) == 0);
-    }
-    bool operator!=(const RomId & rhs) const {
-        return !operator==(rhs);
-    }
-    operator byteBuffer &() {
-        return m_romId;    // Conversion to array reference
-    }
-    operator const byteBuffer &() const {
-        return m_romId;    // Conversion to const array reference
-    }
-
-    void reset() {
-        std::memset(m_romId, defaultByteVal, byteLen);
-    }
-
-    RomId() {
-        reset();
-    }
-    RomId(const RomId & romId) {
-        operator=(romId);
-    }
-    RomId(const byteBuffer & romIdBytes) {
-        std::memcpy(m_romId, romIdBytes, byteLen);
-    }
-
-    std::uint8_t familyCode() const {
-        return m_romId[familyCodeIdx];
-    }
-    void setFamilyCode(std::uint8_t familyCode) {
-        m_romId[familyCodeIdx] = familyCode;
-    }
-
-    std::uint8_t crc8() const {
-        return m_romId[crc8Idx];
-    }
-    void setCrc8(std::uint8_t crc8) {
-        m_romId[crc8Idx] = crc8;
-    }
-    bool crc8Valid() const {
-        return (calculateCRC8(m_romId, (byteLen - 1), 0x00) == crc8());
-    }
-    void setValidCrc8() {
-        setCrc8(calculateCRC8(m_romId, (byteLen - 1), 0x00));
-    }
-
-    bool valid() const {
-        return (crc8Valid() && (familyCode() != defaultByteVal));
-    }
-};
-
-#endif
\ No newline at end of file
--- a/OneWire_Switches/DS2413/ds2413.h	Mon Mar 21 01:28:34 2016 +0000
+++ b/OneWire_Switches/DS2413/ds2413.h	Mon Mar 21 14:12:28 2016 -0500
@@ -36,7 +36,7 @@
 
 
 #include "mbed.h"
-#include "OneWireMasters.h"
+#include "OneWire_Masters/OneWireMasters.h"
 
 
 class Ds2413
--- a/OneWire_Switches/OneWireSwitches.h	Mon Mar 21 01:28:34 2016 +0000
+++ b/OneWire_Switches/OneWireSwitches.h	Mon Mar 21 14:12:28 2016 -0500
@@ -35,7 +35,7 @@
 #define ONEWIRESWITCHES_H
 
 
-#include "ds2413.h"
+#include "DS2413/ds2413.h"
 
 
 #endif /*ONEWIRESWITCHES_H*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RomId.cpp	Mon Mar 21 14:12:28 2016 -0500
@@ -0,0 +1,64 @@
+/******************************************************************//**
+* Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a
+* copy of this software and associated documentation files (the "Software"),
+* to deal in the Software without restriction, including without limitation
+* the rights to use, copy, modify, merge, publish, distribute, sublicense,
+* and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included
+* in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
+* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+* OTHER DEALINGS IN THE SOFTWARE.
+*
+* Except as contained in this notice, the name of Maxim Integrated
+* Products, Inc. shall not be used except as stated in the Maxim Integrated
+* Products, Inc. Branding Policy.
+*
+* The mere transfer of this software does not imply any licenses
+* of trade secrets, proprietary technology, copyrights, patents,
+* trademarks, maskwork rights, or any other form of intellectual
+* property whatsoever. Maxim Integrated Products, Inc. retains all
+* ownership rights.
+**********************************************************************/
+
+
+#include "RomId.hpp"
+
+
+//--------------------------------------------------------------------------
+// Calculate the CRC8 of the byte value provided with the current 
+// global 'crc8' value. 
+// Returns current global crc8 value
+//
+std::uint8_t RomId::calculateCRC8(std::uint8_t crc8, std::uint8_t data)
+{
+   int i; 
+
+   // See Application Note 27
+   crc8 = crc8 ^ data;
+   for (i = 0; i < 8; ++i)
+   {
+      if (crc8 & 1)
+         crc8 = (crc8 >> 1) ^ 0x8c;
+      else
+         crc8 = (crc8 >> 1);
+   }
+
+   return crc8;
+}
+
+std::uint8_t RomId::calculateCRC8(const std::uint8_t * data, std::size_t data_len, std::uint8_t crc)
+{
+  for (std::size_t i = 0; i < data_len; i++)
+    crc = calculateCRC8(crc, data[i]);
+  return crc;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RomId.hpp	Mon Mar 21 14:12:28 2016 -0500
@@ -0,0 +1,113 @@
+/******************************************************************//**
+* Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a
+* copy of this software and associated documentation files (the "Software"),
+* to deal in the Software without restriction, including without limitation
+* the rights to use, copy, modify, merge, publish, distribute, sublicense,
+* and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included
+* in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
+* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+* OTHER DEALINGS IN THE SOFTWARE.
+*
+* Except as contained in this notice, the name of Maxim Integrated
+* Products, Inc. shall not be used except as stated in the Maxim Integrated
+* Products, Inc. Branding Policy.
+*
+* The mere transfer of this software does not imply any licenses
+* of trade secrets, proprietary technology, copyrights, patents,
+* trademarks, maskwork rights, or any other form of intellectual
+* property whatsoever. Maxim Integrated Products, Inc. retains all
+* ownership rights.
+**********************************************************************/
+
+
+#ifndef _ROMID_HPP
+#define _ROMID_HPP
+
+#include <cstdint>
+#include <cstring>
+
+class RomId
+{
+public:
+    static const std::size_t byteLen = 8;
+    typedef std::uint8_t byteBuffer[byteLen];
+
+    static std::uint8_t calculateCRC8(std::uint8_t crc8, std::uint8_t data);
+    static std::uint8_t calculateCRC8(const std::uint8_t * data, std::size_t data_len, std::uint8_t crc = 0);
+
+private:
+    static const std::size_t familyCodeIdx = 0;
+    static const std::size_t crc8Idx = 7;
+    static const std::uint8_t defaultByteVal = 0x00;
+
+    byteBuffer m_romId;
+
+public:
+    const RomId & operator=(const RomId & rhs) {
+        std::memcpy(this->m_romId, rhs.m_romId, byteLen);
+        return rhs;
+    }
+    bool operator==(const RomId & rhs) const {
+        return (std::memcmp(this->m_romId, rhs.m_romId, byteLen) == 0);
+    }
+    bool operator!=(const RomId & rhs) const {
+        return !operator==(rhs);
+    }
+    operator byteBuffer &() {
+        return m_romId;    // Conversion to array reference
+    }
+    operator const byteBuffer &() const {
+        return m_romId;    // Conversion to const array reference
+    }
+
+    void reset() {
+        std::memset(m_romId, defaultByteVal, byteLen);
+    }
+
+    RomId() {
+        reset();
+    }
+    RomId(const RomId & romId) {
+        operator=(romId);
+    }
+    RomId(const byteBuffer & romIdBytes) {
+        std::memcpy(m_romId, romIdBytes, byteLen);
+    }
+
+    std::uint8_t familyCode() const {
+        return m_romId[familyCodeIdx];
+    }
+    void setFamilyCode(std::uint8_t familyCode) {
+        m_romId[familyCodeIdx] = familyCode;
+    }
+
+    std::uint8_t crc8() const {
+        return m_romId[crc8Idx];
+    }
+    void setCrc8(std::uint8_t crc8) {
+        m_romId[crc8Idx] = crc8;
+    }
+    bool crc8Valid() const {
+        return (calculateCRC8(m_romId, (byteLen - 1), 0x00) == crc8());
+    }
+    void setValidCrc8() {
+        setCrc8(calculateCRC8(m_romId, (byteLen - 1), 0x00));
+    }
+
+    bool valid() const {
+        return (crc8Valid() && (familyCode() != defaultByteVal));
+    }
+};
+
+#endif
\ No newline at end of file