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:
139:f0e0a7976846
Parent:
120:200109b73e3c
--- a/Slaves/Authenticators/DS28E15_22_25/DS28E15_22_25.cpp	Fri Dec 02 19:21:55 2016 +0000
+++ b/Slaves/Authenticators/DS28E15_22_25/DS28E15_22_25.cpp	Tue Dec 13 13:31:30 2016 -0800
@@ -31,8 +31,12 @@
 **********************************************************************/
 
 #include "DS28E15_22_25.h"
+#include "DS28E15.h"
+#include "DS28E22.h"
+#include "DS28E25.h"
 #include "Masters/OneWireMaster.h"
 #include "Utilities/crc.h"
+#include "Utilities/type_traits.h"
 #include "wait_api.h"
 
 using namespace OneWire;
@@ -53,41 +57,28 @@
     AuthWriteBlockProtection = 0xCC,
 };
 
-/// Number for memory pages for each device.
-enum MemoryPages
-{
-    DS28E25_Pages = 16,
-    DS28E22_Pages = 8,
-    DS28E15_Pages = 2
-};
-
-/// Number of protection blocks for each device.
-enum ProtectionBlocks
-{
-    DS28E25_Blocks = 8,
-    DS28E22_Blocks = 4,
-    DS28E15_Blocks = 4
-};
-
-DS28E15_22_25::Segment DS28E15_22_25::Page::toSegment(unsigned int segmentNum) const
+DS28E15_22_25::Segment DS28E15_22_25::segmentFromPage(unsigned int segmentNum, const Page & page)
 {
     if (segmentNum > (segmentsPerPage - 1))
     {
         segmentNum = (segmentsPerPage - 1);
     }
-    return Segment(*reinterpret_cast<const Segment::Buffer *>(&m_data[segmentNum * sizeof(Segment::Buffer)]));
+    Segment segment;
+    Page::const_iterator copyBegin = page.begin() + (segmentNum * Segment::size());
+    std::copy(copyBegin, copyBegin + Segment::size(), segment.begin());
+    return segment;
 }
 
-void DS28E15_22_25::Page::fromSegment(unsigned int segmentNum, const Segment & segment)
+void DS28E15_22_25::segmentToPage(unsigned int segmentNum, const Segment & segment, Page & page)
 {
     if (segmentNum > (segmentsPerPage - 1))
     {
         segmentNum = (segmentsPerPage - 1);
     }
-    std::memcpy(&m_data[segmentNum * sizeof(Segment::Buffer)], &static_cast<const Segment::Buffer &>(segment), Segment::length);
+    std::copy(segment.begin(), segment.end(), page.begin() + (segmentNum * segment.size()));
 }
 
-DS28E15_22_25::BlockProtection::BlockProtection(bool readProtection, bool writeProtection, bool eepromEmulation, bool authProtection, uint8_t blockNum)
+DS28E15_22_25::BlockProtection::BlockProtection(bool readProtection, bool writeProtection, bool eepromEmulation, bool authProtection, unsigned int blockNum)
 {
     setReadProtection(readProtection);
     setWriteProtection(writeProtection);
@@ -96,7 +87,7 @@
     setBlockNum(blockNum);
 }
 
-void DS28E15_22_25::BlockProtection::setBlockNum(uint8_t blockNum)
+void DS28E15_22_25::BlockProtection::setBlockNum(unsigned int blockNum)
 {
     m_status &= ~blockNumMask;
     m_status |= (blockNum & blockNumMask);
@@ -155,10 +146,10 @@
     }
 }
 
-DS28E15_22_25::DS28E15_22_25(RandomAccessRomIterator & selector, bool lowVoltage, FamilyCode variant)
-    : OneWireSlave(selector), m_lowVoltage(lowVoltage), m_variant(variant)
+DS28E15_22_25::DS28E15_22_25(RandomAccessRomIterator & selector, bool lowVoltage)
+    : OneWireSlave(selector), m_manId(), m_lowVoltage(lowVoltage)
 {
-    std::memset(m_manId, 0x00, m_manId.length);
+
 }
 
 OneWireSlave::CmdResult DS28E15_22_25::writeAuthBlockProtection(const ISha256MacCoproc & MacCoproc, const BlockProtection & newProtection, const BlockProtection & oldProtection)
@@ -191,7 +182,7 @@
     master().OWSetLevel(OneWireMaster::NormalLevel);
 
     // check CRC16
-    if (calculateCrc16(buf, 0, cnt) != 0xB001)
+    if (calculateCrc16(buf, cnt) != 0xB001)
     {
         return CrcError;
     }
@@ -205,14 +196,14 @@
     cnt = 0;
 
     // send the MAC
-    master().OWWriteBlock(mac, mac.length);
+    master().OWWriteBlock(mac.data(), mac.size());
 
     // Read CRC and CS byte
     master().OWReadBlock(&buf[cnt], 3);
     cnt += 3;
 
     // check CRC16
-    if (calculateCrc16(buf, 0, (cnt - 1), calculateCrc16(mac, 0, mac.length)) != 0xB001)
+    if (calculateCrc16(buf, cnt - 1, calculateCrc16(mac.data(), mac.size())) != 0xB001)
     {
         return CrcError;
     }
@@ -266,7 +257,7 @@
     cnt += 2;
 
     // check CRC16
-    if (calculateCrc16(buf, 0, cnt) != 0xB001)
+    if (calculateCrc16(buf, cnt) != 0xB001)
     {
         return CrcError;
     }
@@ -291,12 +282,13 @@
     return OperationFailure;
 }
 
-OneWireSlave::CmdResult DS28E15_22_25::readBlockProtection(unsigned int blockNum, BlockProtection & protection)
+template <class T>
+OneWireSlave::CmdResult DS28E15_22_25::doReadBlockProtection(unsigned int blockNum, BlockProtection & protection) const
 {
     uint8_t buf;
     CmdResult result;
     
-    result = readStatus(false, false, blockNum, &buf);
+    result = readStatus<T>(false, false, blockNum, &buf);
     if (result == Success)
     {
         protection.setStatusByte(buf);
@@ -304,11 +296,19 @@
     return result;
 }
 
-OneWireSlave::CmdResult DS28E15_22_25::readPersonality(Personality & personality) const
+template <class T>
+OneWireSlave::CmdResult DS28E15_22_25::doReadPersonality(Personality & personality) const
 {
-    return readStatus(true, false, 0, personality.bytes);
+    Personality::Buffer buffer;
+    CmdResult result = readStatus<T>(true, false, 0, buffer.data());
+    if (result == Success)
+    {
+        personality = Personality(buffer);
+    }
+    return result;
 }
 
+template <class T>
 OneWireSlave::CmdResult DS28E15_22_25::readStatus(bool personality, bool allpages, unsigned int blockNum, uint8_t * rdbuf) const
 {
     const size_t crcLen = 4, ds28e22_25_pagesPerBlock = 2;
@@ -334,7 +334,7 @@
     {
         // Convert to page number for DS28E22 and DS28E25
         buf[cnt] = blockNum;
-        if ((m_variant == DS28E25_Family) || (m_variant == DS28E22_Family))
+        if (is_same<T, DS28E22>::value || is_same<T, DS28E25>::value)
         {
             buf[cnt] *= ds28e22_25_pagesPerBlock;
         }
@@ -356,13 +356,13 @@
     {
         rdnum = 1;
     }
-    else if ((m_variant == DS28E22_Family) || (m_variant == DS28E25_Family))
+    else if (is_same<T, DS28E22>::value || is_same<T, DS28E25>::value)
     {
-        rdnum = DS28E25_Pages; // Need to read extra data on DS28E22 to get CRC16.
+        rdnum = DS28E25::memoryPages; // Need to read extra data on DS28E22 to get CRC16.
     }
     else // DS28E15
     {
-        rdnum = DS28E15_Blocks;
+        rdnum = DS28E15::protectionBlocks;
     }
     rdnum += crcLen; // Add in CRC length
 
@@ -371,7 +371,7 @@
     cnt += rdnum;
 
     // check the first CRC16
-    if (calculateCrc16(buf, 0, offset) != 0xB001)
+    if (calculateCrc16(buf, offset) != 0xB001)
     {
         return CrcError;
     }
@@ -379,7 +379,7 @@
     if (personality || allpages)
     {
         // check the second CRC16
-        if (calculateCrc16(buf, offset, (cnt - offset)) != 0xB001)
+        if (calculateCrc16(buf + offset, cnt - offset) != 0xB001)
         {
             return CrcError;
         }
@@ -387,11 +387,11 @@
 
     // copy the data to the read buffer
     rdnum -= crcLen;
-    if (allpages && ((m_variant == DS28E25_Family) || (m_variant == DS28E22_Family)))
+    if (allpages && (is_same<T, DS28E22>::value || is_same<T, DS28E25>::value))
     {
-        if (m_variant == DS28E22_Family)
+        if (is_same<T, DS28E22>::value)
         {
-            rdnum -= (DS28E25_Pages - DS28E22_Pages);
+            rdnum -= (DS28E25::memoryPages - DS28E22::memoryPages);
         }
 
         for (size_t i = 0; i < (rdnum / ds28e22_25_pagesPerBlock); i++)
@@ -413,7 +413,7 @@
     ISha256MacCoproc::AuthMacData authMacData;
 
     // insert ROM number or FF
-    std::memcpy(authMacData, romId, RomId::byteLen);
+    std::memcpy(authMacData.data(), romId.buffer.data(), romId.buffer.size());
 
     authMacData[10] = pageNum;
 
@@ -428,7 +428,7 @@
 ISha256MacCoproc::CmdResult DS28E15_22_25::computeAuthMacAnon(const ISha256MacCoproc & MacCoproc, const Page & pageData, unsigned int pageNum, const Scratchpad & challenge, const ManId & manId, Mac & mac)
 {
     RomId romId;
-    std::memset(romId, 0xFF, RomId::byteLen);
+    romId.buffer.fill(0xFF);
     return computeAuthMac(MacCoproc, pageData, pageNum, challenge, romId, manId, mac);
 }
 
@@ -461,7 +461,7 @@
     master().OWSetLevel(OneWireMaster::NormalLevel);
 
     // check CRC16
-    if (calculateCrc16(buf, 0, cnt) != 0xB001)
+    if (calculateCrc16(buf, cnt) != 0xB001)
     {
         return CrcError;
     }
@@ -474,16 +474,16 @@
     }
 
     // read the MAC and CRC
-    master().OWReadBlock(&buf[0], (Mac::length + 2));
+    master().OWReadBlock(&buf[0], (Mac::size() + 2));
 
     // check CRC16
-    if (calculateCrc16(buf, 0, (Mac::length + 2)) != 0xB001)
+    if (calculateCrc16(buf, Mac::size() + 2) != 0xB001)
     {
         return CrcError;
     }
 
     // copy MAC to return buffer
-    std::memcpy(mac, buf, Mac::length);
+    std::memcpy(mac.data(), buf, mac.size());
 
     return Success;
 }
@@ -509,7 +509,7 @@
     cnt += 2;
 
     // check CRC16
-    if (calculateCrc16(buf, 0, cnt) != 0xB001)
+    if (calculateCrc16(buf, cnt) != 0xB001)
     {
         return CrcError;
     }
@@ -534,7 +534,8 @@
     return OperationFailure;
 }
 
-OneWireSlave::CmdResult DS28E15_22_25::writeScratchpad(const Scratchpad & data) const
+template <class T>
+OneWireSlave::CmdResult DS28E15_22_25::doWriteScratchpad(const Scratchpad & data) const
 {
     uint8_t buf[256];
     int cnt = 0, offset;
@@ -545,7 +546,7 @@
     }
 
     buf[cnt++] = ReadWriteScratchpad;
-    if ((m_variant == DS28E25_Family) || (m_variant == DS28E22_Family))
+    if (is_same<T, DS28E22>::value || is_same<T, DS28E25>::value)
     {
         buf[cnt++] = 0x20;
     }
@@ -564,24 +565,24 @@
     offset = cnt;
 
     // add the data
-    std::memcpy(&buf[cnt], data, data.length);
-    cnt += data.length;
+    std::memcpy(&buf[cnt], data.data(), data.size());
+    cnt += data.size();
 
     // Send the data
-    master().OWWriteBlock(data, data.length);
+    master().OWWriteBlock(data.data(), data.size());
 
     // Read CRC
     master().OWReadBlock(&buf[cnt], 2);
     cnt += 2;
 
     // check first CRC16
-    if (calculateCrc16(buf, 0, offset) != 0xB001)
+    if (calculateCrc16(buf, offset) != 0xB001)
     {
         return CrcError;
     }
 
     // check the second CRC16
-    if (calculateCrc16(buf, offset, (cnt - offset)) != 0xB001)
+    if (calculateCrc16(buf + offset, cnt - offset) != 0xB001)
     {
         return CrcError;
     }
@@ -589,7 +590,8 @@
     return Success;
 }
 
-OneWireSlave::CmdResult DS28E15_22_25::readScratchpad(Scratchpad & data) const
+template <class T>
+OneWireSlave::CmdResult DS28E15_22_25::doReadScratchpad(Scratchpad & data) const
 {
     uint8_t buf[256];
     int cnt = 0, offset;
@@ -600,7 +602,7 @@
     }
 
     buf[cnt++] = ReadWriteScratchpad;
-    if ((m_variant == DS28E25_Family) || (m_variant == DS28E22_Family))
+    if (is_same<T, DS28E22>::value || is_same<T, DS28E25>::value)
     {
         buf[cnt++] = 0x2F;
     }
@@ -619,27 +621,27 @@
     offset = cnt;
 
     // Receive the data
-    master().OWReadBlock(&buf[cnt], data.length);
-    cnt += data.length;
+    master().OWReadBlock(&buf[cnt], data.size());
+    cnt += data.size();
 
     // Read CRC
     master().OWReadBlock(&buf[cnt], 2);
     cnt += 2;
 
     // check first CRC16
-    if (calculateCrc16(buf, 0, offset) != 0xB001)
+    if (calculateCrc16(buf, offset) != 0xB001)
     {
         return CrcError;
     }
 
     // check the second CRC16
-    if (calculateCrc16(buf, offset, (cnt - offset)) != 0xB001)
+    if (calculateCrc16(buf + offset, cnt - offset) != 0xB001)
     {
         return CrcError;
     }
 
     // Copy to output
-    std::memcpy(data, &buf[offset], data.length);
+    std::memcpy(data.data(), &buf[offset], data.size());
 
     return Success;
 }
@@ -665,7 +667,7 @@
     cnt += 2;
 
     // check CRC16
-    if (calculateCrc16(buf, 0, cnt) != 0xB001)
+    if (calculateCrc16(buf, cnt) != 0xB001)
     {
         return CrcError;
     }
@@ -693,10 +695,8 @@
 OneWireSlave::CmdResult DS28E15_22_25::readPage(unsigned int page, Page & rdbuf, bool continuing) const
 {
     uint8_t buf[256];
-    int cnt, offset;
-
-    cnt = 0;
-    offset = 0;
+    int cnt = 0;
+    int offset = 0;
 
     // check if not continuing a previous block write
     if (!continuing)
@@ -720,31 +720,32 @@
     }
 
     // read data and CRC16
-    master().OWReadBlock(&buf[cnt], (rdbuf.length + 2));
+    master().OWReadBlock(&buf[cnt], (rdbuf.size() + 2));
     cnt += 34;
 
     // check the first CRC16
     if (!continuing)
     {
-        if (calculateCrc16(buf, 0, offset) != 0xB001)
+        if (calculateCrc16(buf, offset) != 0xB001)
         {
             return CrcError;
         }
     }
 
     // check the second CRC16
-    if (calculateCrc16(buf, offset, (cnt - offset)) != 0xB001)
+    if (calculateCrc16(buf + offset, cnt - offset) != 0xB001)
     {
         return CrcError;
     }
 
     // copy the data to the read buffer
-    std::memcpy(rdbuf, &buf[offset], rdbuf.length);
+    std::memcpy(rdbuf.data(), &buf[offset], rdbuf.size());
 
     return Success;
 }
 
-OneWireSlave::CmdResult DS28E15_22_25::writeAuthSegmentMac(unsigned int pageNum, unsigned int segmentNum, const Segment & newData, const Mac & mac, bool continuing)
+template <class T>
+OneWireSlave::CmdResult DS28E15_22_25::doWriteAuthSegmentMac(unsigned int pageNum, unsigned int segmentNum, const Segment & newData, const Mac & mac, bool continuing)
 {
     uint8_t buf[256], cs;
     int cnt, offset;
@@ -774,13 +775,13 @@
     }
 
     // add the data
-    for (size_t i = 0; i < newData.length; i++)
+    for (size_t i = 0; i < newData.size(); i++)
     {
         buf[cnt++] = newData[i];
     }
 
     // Send data
-    master().OWWriteBlock(newData, newData.length);
+    master().OWWriteBlock(newData.data(), newData.size());
 
     // read first CRC byte
     master().OWReadByte(buf[cnt++]);
@@ -797,7 +798,7 @@
     // check the first CRC16
     if (!continuing)
     {
-        if (calculateCrc16(buf, 0, offset) != 0xB001)
+        if (calculateCrc16(buf, offset) != 0xB001)
         {
             return CrcError;
         }
@@ -807,7 +808,7 @@
     uint16_t CRC16 = 0;
 
     // DS28E25/DS28E22, crc gets calculagted with CS byte 
-    if ((m_variant == DS28E25_Family) || (m_variant == DS28E22_Family))
+    if (is_same<T, DS28E22>::value || is_same<T, DS28E25>::value)
     {
         if (continuing)
         {
@@ -815,7 +816,7 @@
         }
     }
 
-    CRC16 = calculateCrc16(buf, offset, (cnt - offset), CRC16);
+    CRC16 = calculateCrc16(buf + offset, cnt - offset, CRC16);
 
     if (CRC16 != 0xB001)
     {
@@ -823,17 +824,17 @@
     }
 
     // transmit MAC as a block
-    master().OWWriteBlock(mac, mac.length);
+    master().OWWriteBlock(mac.data(), mac.size());
 
     // calculate CRC on MAC
-    CRC16 = calculateCrc16(mac, 0, mac.length);
+    CRC16 = calculateCrc16(mac.data(), mac.size());
 
     // append read of CRC16 and CS byte
     master().OWReadBlock(&buf[0], 3);
     cnt = 3;
 
     // ckeck CRC16
-    CRC16 = calculateCrc16(buf, 0, (cnt - 1), CRC16);
+    CRC16 = calculateCrc16(buf, cnt - 1, CRC16);
 
     if (CRC16 != 0xB001)
     {
@@ -871,7 +872,7 @@
     ISha256MacCoproc::WriteMacData MT;
 
     // insert ROM number
-    std::memcpy(&MT[0], romId, RomId::byteLen);
+    std::memcpy(&MT[0], romId.buffer.data(), romId.buffer.size());
 
     MT[11] = segmentNum;
     MT[10] = pageNum;
@@ -879,10 +880,10 @@
     MT[8] = manId[1];
 
     // insert old data
-    std::memcpy(&MT[12], oldData, Segment::length);
+    std::memcpy(&MT[12], oldData.data(), oldData.size());
 
     // insert new data
-    std::memcpy(&MT[16], newData, Segment::length);
+    std::memcpy(&MT[16], newData.data(), newData.size());
 
     return MacCoproc.computeWriteMac(MT, mac);
 }
@@ -892,7 +893,7 @@
     ISha256MacCoproc::WriteMacData MT;
 
     // insert ROM number
-    std::memcpy(MT, romId, RomId::byteLen);
+    std::memcpy(MT.data(), romId.buffer.data(), romId.buffer.size());
 
     // instert block and page
     MT[11] = 0;
@@ -916,7 +917,8 @@
     return MacCoproc.computeWriteMac(MT, mac);
 }
 
-OneWireSlave::CmdResult DS28E15_22_25::writeAuthSegment(const ISha256MacCoproc & MacCoproc, unsigned int pageNum, unsigned int segmentNum, const Segment & newData, const Segment & oldData, bool continuing)
+template <class T>
+OneWireSlave::CmdResult DS28E15_22_25::doWriteAuthSegment(const ISha256MacCoproc & MacCoproc, unsigned int pageNum, unsigned int segmentNum, const Segment & newData, const Segment & oldData, bool continuing)
 {
     uint8_t buf[256], cs;
     int cnt, offset;
@@ -946,13 +948,13 @@
     }
 
     // add the data
-    for (size_t i = 0; i < newData.length; i++)
+    for (size_t i = 0; i < newData.size(); i++)
     {
         buf[cnt++] = newData[i];
     }
 
     // Send data
-    master().OWWriteBlock(newData, newData.length);
+    master().OWWriteBlock(newData.data(), newData.size());
 
     // read first CRC byte
     master().OWReadByte(buf[cnt++]);
@@ -969,7 +971,7 @@
     // check the first CRC16
     if (!continuing)
     {
-        if (calculateCrc16(buf, 0, offset) != 0xB001)
+        if (calculateCrc16(buf, offset) != 0xB001)
         {
             return CrcError;
         }
@@ -978,14 +980,14 @@
     // check the second CRC16
     uint16_t CRC16 = 0;
 
-    // DS28E25/DS28E22, crc gets calculagted with CS byte
-    if ((m_variant == DS28E25_Family) || (m_variant == DS28E22_Family))
+    // DS28E25/DS28E22, crc gets calculated with CS byte
+    if (is_same<T, DS28E22>::value || is_same<T, DS28E25>::value)
     {
         if (continuing)
             CRC16 = calculateCrc16(CRC16, 0xAA);
     }
 
-    CRC16 = calculateCrc16(buf, offset, (cnt - offset), CRC16);
+    CRC16 = calculateCrc16(buf + offset, cnt - offset, CRC16);
 
     if (CRC16 != 0xB001)
     {
@@ -1002,17 +1004,17 @@
     }
 
     // transmit MAC as a block
-    master().OWWriteBlock(mac, mac.length);
+    master().OWWriteBlock(mac.data(), mac.size());
 
     // calculate CRC on MAC
-    CRC16 = calculateCrc16(mac, 0, mac.length);
+    CRC16 = calculateCrc16(mac.data(), mac.size());
 
     // append read of CRC16 and CS byte
     master().OWReadBlock(&buf[0], 3);
     cnt = 3;
 
     // ckeck CRC16
-    CRC16 = calculateCrc16(buf, 0, (cnt - 1), CRC16);
+    CRC16 = calculateCrc16(buf, cnt - 1, CRC16);
 
     if (CRC16 != 0xB001)
     {
@@ -1075,7 +1077,7 @@
     // Receive data
     if (result == OneWireMaster::Success)
     {
-        result = master().OWReadBlock(data, data.length);
+        result = master().OWReadBlock(data.data(), data.size());
     }
 
     return (result == OneWireMaster::Success ? OneWireSlave::Success : OneWireSlave::CommunicationError);
@@ -1112,13 +1114,13 @@
     }
 
     // add the data
-    for (size_t i = 0; i < data.length; i++)
+    for (size_t i = 0; i < data.size(); i++)
     {
         buf[cnt++] = data[i];
     }
 
     // Send data
-    master().OWWriteBlock(data, data.length);
+    master().OWWriteBlock(data.data(), data.size());
 
     // Read CRC
     master().OWReadBlock(&buf[cnt], 2);
@@ -1127,14 +1129,14 @@
     // check the first CRC16
     if (!continuing)
     {
-        if (calculateCrc16(buf, 0, offset) != 0xB001)
+        if (calculateCrc16(buf, offset) != 0xB001)
         {
             return CrcError;
         }
     }
 
     // check the second CRC16
-    if (calculateCrc16(buf, offset, (cnt - offset)) != 0xB001)
+    if (calculateCrc16(buf + offset, cnt - offset) != 0xB001)
     {
         return CrcError;
     }
@@ -1164,7 +1166,7 @@
     ISha256MacCoproc::SlaveSecretData slaveSecretData;
 
     // insert ROM number
-    std::memcpy(slaveSecretData, romId, RomId::byteLen);
+    std::memcpy(slaveSecretData.data(), romId.buffer.data(), romId.buffer.size());
 
     slaveSecretData[11] = 0x00;
     slaveSecretData[10] = bindingPageNum;
@@ -1173,3 +1175,123 @@
 
     return MacCoproc.computeSlaveSecret(ISha256MacCoproc::DevicePage(bindingPage), partialSecret, slaveSecretData);
 }
+
+template <class T, size_t N>
+OneWireSlave::CmdResult DS28E15_22_25::doReadAllBlockProtection(array<BlockProtection, N> & protection) const
+{
+    uint8_t buf[N];
+    CmdResult result = readStatus<T>(false, true, 0, buf);
+    if (result == Success)
+    {
+        for (size_t i = 0; i < N; i++)
+        {
+            protection[i].setStatusByte(buf[i]);
+        }
+    }
+    return result;
+}
+
+OneWireSlave::CmdResult DS28E15::writeScratchpad(const Scratchpad & data) const
+{
+    return doWriteScratchpad<DS28E15>(data);
+}
+
+OneWireSlave::CmdResult DS28E15::readScratchpad(Scratchpad & data) const
+{
+    return doReadScratchpad<DS28E15>(data);
+}
+
+OneWireSlave::CmdResult DS28E15::readBlockProtection(unsigned int blockNum, BlockProtection & protection) const
+{
+    return doReadBlockProtection<DS28E15>(blockNum, protection);
+}
+
+OneWireSlave::CmdResult DS28E15::readPersonality(Personality & personality) const
+{
+    return doReadPersonality<DS28E15>(personality);
+}
+
+OneWireSlave::CmdResult DS28E15::writeAuthSegment(const ISha256MacCoproc & MacCoproc, unsigned int pageNum, unsigned int segmentNum, const Segment & newData, const Segment & oldData, bool continuing)
+{
+    return doWriteAuthSegment<DS28E15>(MacCoproc, pageNum, segmentNum, newData, oldData, continuing);
+}
+
+OneWireSlave::CmdResult DS28E15::writeAuthSegmentMac(unsigned int pageNum, unsigned int segmentNum, const Segment & newData, const Mac & mac, bool continuing)
+{
+    return doWriteAuthSegmentMac<DS28E15>(pageNum, segmentNum, newData, mac, continuing);
+}
+
+OneWireSlave::CmdResult DS28E15::readAllBlockProtection(array<BlockProtection, protectionBlocks> & protection) const
+{
+    return doReadAllBlockProtection<DS28E15>(protection);
+}
+
+OneWireSlave::CmdResult DS28E22::writeScratchpad(const Scratchpad & data) const
+{
+    return doWriteScratchpad<DS28E22>(data);
+}
+
+OneWireSlave::CmdResult DS28E22::readScratchpad(Scratchpad & data) const
+{
+    return doReadScratchpad<DS28E22>(data);
+}
+
+OneWireSlave::CmdResult DS28E22::readBlockProtection(unsigned int blockNum, BlockProtection & protection) const
+{
+    return doReadBlockProtection<DS28E22>(blockNum, protection);
+}
+
+OneWireSlave::CmdResult DS28E22::readPersonality(Personality & personality) const
+{
+    return doReadPersonality<DS28E22>(personality);
+}
+
+OneWireSlave::CmdResult DS28E22::writeAuthSegment(const ISha256MacCoproc & MacCoproc, unsigned int pageNum, unsigned int segmentNum, const Segment & newData, const Segment & oldData, bool continuing)
+{
+    return doWriteAuthSegment<DS28E22>(MacCoproc, pageNum, segmentNum, newData, oldData, continuing);
+}
+
+OneWireSlave::CmdResult DS28E22::writeAuthSegmentMac(unsigned int pageNum, unsigned int segmentNum, const Segment & newData, const Mac & mac, bool continuing)
+{
+    return doWriteAuthSegmentMac<DS28E22>(pageNum, segmentNum, newData, mac, continuing);
+}
+
+OneWireSlave::CmdResult DS28E22::readAllBlockProtection(array<BlockProtection, protectionBlocks> & protection) const
+{
+    return doReadAllBlockProtection<DS28E22>(protection);
+}
+
+OneWireSlave::CmdResult DS28E25::writeScratchpad(const Scratchpad & data) const
+{
+    return doWriteScratchpad<DS28E25>(data);
+}
+
+OneWireSlave::CmdResult DS28E25::readScratchpad(Scratchpad & data) const
+{
+    return doReadScratchpad<DS28E25>(data);
+}
+
+OneWireSlave::CmdResult DS28E25::readBlockProtection(unsigned int blockNum, BlockProtection & protection) const
+{
+    return doReadBlockProtection<DS28E25>(blockNum, protection);
+}
+
+OneWireSlave::CmdResult DS28E25::readPersonality(Personality & personality) const
+{
+    return doReadPersonality<DS28E25>(personality);
+}
+
+OneWireSlave::CmdResult DS28E25::writeAuthSegment(const ISha256MacCoproc & MacCoproc, unsigned int pageNum, unsigned int segmentNum, const Segment & newData, const Segment & oldData, bool continuing)
+{
+    return doWriteAuthSegment<DS28E25>(MacCoproc, pageNum, segmentNum, newData, oldData, continuing);
+}
+
+OneWireSlave::CmdResult DS28E25::writeAuthSegmentMac(unsigned int pageNum, unsigned int segmentNum, const Segment & newData, const Mac & mac, bool continuing)
+{
+    return doWriteAuthSegmentMac<DS28E25>(pageNum, segmentNum, newData, mac, continuing);
+}
+
+OneWireSlave::CmdResult DS28E25::readAllBlockProtection(array<BlockProtection, protectionBlocks> & protection) const
+{
+    return doReadAllBlockProtection<DS28E25>(protection);
+}
\ No newline at end of file