Extended MaximInterface
Dependents: mbed_DS28EC20_GPIO
Diff: Devices/DS28E15_22_25.cpp
- Revision:
- 6:a8c83a2e6fa4
- Parent:
- 0:f77ad7f72d04
--- a/Devices/DS28E15_22_25.cpp Fri Jan 19 10:25:02 2018 -0600 +++ b/Devices/DS28E15_22_25.cpp Wed Jan 23 13:11:04 2019 -0600 @@ -31,29 +31,28 @@ *******************************************************************************/ #include <algorithm> -#include "DS28E15_22_25.hpp" #include <MaximInterface/Utilities/crc.hpp> #include <MaximInterface/Utilities/Error.hpp> - -using std::copy; +#include "DS28E15_22_25.hpp" namespace MaximInterface { using namespace Sha256; +using std::copy; static const int shaComputationDelayMs = 3; static const int eepromWriteDelayMs = 10; static inline int secretEepromWriteDelayMs(bool lowPower) { return lowPower ? 200 : 100; } + static const int ds28e22_25_pagesPerBlock = 2; static error_code -writeDataWithCrc(OneWireMaster & master, const uint_least8_t * data, - size_t dataLen, +writeDataWithCrc(OneWireMaster & master, span<const uint_least8_t> data, OneWireMaster::Level level = OneWireMaster::NormalLevel, uint_fast16_t crcStart = 0) { - error_code result = master.writeBlock(data, dataLen); + error_code result = master.writeBlock(data); if (result) { return result; } @@ -66,13 +65,20 @@ if (result) { return result; } - if (calculateCrc16(response, sizeof(response) / sizeof(response[0]), - calculateCrc16(data, dataLen, crcStart)) != 0xB001) { + if (calculateCrc16(response, calculateCrc16(data, crcStart)) != 0xB001) { result = make_error_code(DS28E15_22_25::CrcError); } return result; } +const int DS28E15_22_25::segmentsPerPage; + +DS28E15_22_25::AuthenticationData & +DS28E15_22_25::AuthenticationData::setAnonymousRomId() { + std::fill(romId().begin(), romId().end(), 0xFF); + return *this; +} + error_code DS28E15_22_25::writeCommandWithCrc(Command command, uint_least8_t parameter, OneWireMaster::Level level) const { @@ -80,26 +86,23 @@ if (!result) { const uint_least8_t data[] = {static_cast<uint_least8_t>(command), parameter}; - result = - writeDataWithCrc(*master, data, sizeof(data) / sizeof(data[0]), level); + result = writeDataWithCrc(*master, data); } return result; } -static error_code readDataWithCrc(OneWireMaster & master, uint_least8_t * data, - size_t dataLen) { - error_code result = master.readBlock(data, dataLen); +static error_code readDataWithCrc(OneWireMaster & master, + span<uint_least8_t> data) { + error_code result = master.readBlock(data); if (result) { return result; } uint_least8_t response[2]; - const size_t responseLen = sizeof(response) / sizeof(response[0]); - result = master.readBlock(response, responseLen); + result = master.readBlock(response); if (result) { return result; } - if (calculateCrc16(response, responseLen, calculateCrc16(data, dataLen)) != - 0xB001) { + if (calculateCrc16(response, calculateCrc16(data)) != 0xB001) { result = make_error_code(DS28E15_22_25::CrcError); } return result; @@ -117,7 +120,7 @@ return result; } -static error_code releaseSequence(OneWireMaster & master, const Sleep & sleep, +static error_code releaseSequence(OneWireMaster & master, Sleep & sleep, int delayTimeMs) { error_code result = master.writeBytePower(0xAA); if (result) { @@ -131,21 +134,11 @@ return readCsByte(master); } -DS28E15_22_25::BlockProtection::BlockProtection(bool readProtection, - bool writeProtection, - bool eepromEmulation, - bool authProtection, - int blockNum) { - setReadProtection(readProtection); - setWriteProtection(writeProtection); - setEepromEmulation(eepromEmulation); - setAuthProtection(authProtection); - setBlockNum(blockNum); -} - -void DS28E15_22_25::BlockProtection::setBlockNum(int blockNum) { +DS28E15_22_25::BlockProtection & +DS28E15_22_25::BlockProtection::setBlockNum(int blockNum) { status &= ~blockNumMask; status |= (blockNum & blockNumMask); + return *this; } bool DS28E15_22_25::BlockProtection::noProtection() const { @@ -153,41 +146,78 @@ !authProtection(); } -void DS28E15_22_25::BlockProtection::setReadProtection(bool readProtection) { +DS28E15_22_25::BlockProtection & +DS28E15_22_25::BlockProtection::setReadProtection(bool readProtection) { if (readProtection) { status |= readProtectionMask; } else { status &= ~readProtectionMask; } + return *this; } -void DS28E15_22_25::BlockProtection::setWriteProtection(bool writeProtection) { +DS28E15_22_25::BlockProtection & +DS28E15_22_25::BlockProtection::setWriteProtection(bool writeProtection) { if (writeProtection) { status |= writeProtectionMask; } else { status &= ~writeProtectionMask; } + return *this; } -void DS28E15_22_25::BlockProtection::setEepromEmulation(bool eepromEmulation) { +DS28E15_22_25::BlockProtection & +DS28E15_22_25::BlockProtection::setEepromEmulation(bool eepromEmulation) { if (eepromEmulation) { status |= eepromEmulationMask; } else { status &= ~eepromEmulationMask; } + return *this; } -void DS28E15_22_25::BlockProtection::setAuthProtection(bool authProtection) { +DS28E15_22_25::BlockProtection & +DS28E15_22_25::BlockProtection::setAuthProtection(bool authProtection) { if (authProtection) { status |= authProtectionMask; } else { status &= ~authProtectionMask; } + return *this; +} + +DS28E15_22_25::ProtectionWriteMacData::ProtectionWriteMacData() + : result_(), oldProtection_(), newProtection_() { + setOldProtection(oldProtection_); + setNewProtection(newProtection_); +} + +DS28E15_22_25::ProtectionWriteMacData & +DS28E15_22_25::ProtectionWriteMacData::setOldProtection( + BlockProtection oldProtection) { + result_[oldProtectionIdx] = oldProtection.authProtection() ? 1 : 0; + result_[oldProtectionIdx + 1] = oldProtection.eepromEmulation() ? 1 : 0; + result_[oldProtectionIdx + 2] = oldProtection.writeProtection() ? 1 : 0; + result_[oldProtectionIdx + 3] = oldProtection.readProtection() ? 1 : 0; + oldProtection_ = oldProtection; + return *this; +} + +DS28E15_22_25::ProtectionWriteMacData & +DS28E15_22_25::ProtectionWriteMacData::setNewProtection( + BlockProtection newProtection) { + result_[blockNumIdx] = newProtection.blockNum(); + result_[newProtectionIdx] = newProtection.authProtection() ? 1 : 0; + result_[newProtectionIdx + 1] = newProtection.eepromEmulation() ? 1 : 0; + result_[newProtectionIdx + 2] = newProtection.writeProtection() ? 1 : 0; + result_[newProtectionIdx + 3] = newProtection.readProtection() ? 1 : 0; + newProtection_ = newProtection; + return *this; } error_code -DS28E15_22_25::writeAuthBlockProtection(const BlockProtection & newProtection, - const Hash & mac) { +DS28E15_22_25::writeAuthBlockProtection(BlockProtection newProtection, + Hash::const_span mac) { error_code result = writeCommandWithCrc(AuthWriteBlockProtection, newProtection.statusByte(), OneWireMaster::StrongLevel); @@ -195,13 +225,13 @@ return result; } - (*sleep)(shaComputationDelayMs); + sleep->invoke(shaComputationDelayMs); result = master->setLevel(OneWireMaster::NormalLevel); if (result) { return result; } - result = writeDataWithCrc(*master, mac.data(), mac.size()); + result = writeDataWithCrc(*master, mac); if (result) { return result; } @@ -215,8 +245,7 @@ return result; } -error_code -DS28E15_22_25::writeBlockProtection(const BlockProtection & protection) { +error_code DS28E15_22_25::writeBlockProtection(BlockProtection protection) { error_code result = writeCommandWithCrc(WriteBlockProtection, protection.statusByte()); if (result) { @@ -244,33 +273,8 @@ return result; } -AuthMacData DS28E15_22_25::createAuthMacData(const Page & pageData, int pageNum, - const Scratchpad & challenge, - const RomId & romId, - const ManId & manId) { - AuthMacData authMacData; - AuthMacData::iterator authMacDataIt = authMacData.begin(); - authMacDataIt = copy(pageData.begin(), pageData.end(), authMacDataIt); - authMacDataIt = copy(challenge.begin(), challenge.end(), authMacDataIt); - authMacDataIt = copy(romId.begin(), romId.end(), authMacDataIt); - *authMacDataIt = manId[1]; - *(++authMacDataIt) = manId[0]; - *(++authMacDataIt) = pageNum; - *(++authMacDataIt) = 0x00; - return authMacData; -} - -AuthMacData DS28E15_22_25::createAnonAuthMacData(const Page & pageData, - int pageNum, - const Scratchpad & challenge, - const ManId & manId) { - RomId romId; - romId.fill(0xFF); - return createAuthMacData(pageData, pageNum, challenge, romId, manId); -} - error_code DS28E15_22_25::computeReadPageMac(int page_num, bool anon, - Hash & mac) const { + Hash::span mac) const { error_code result = writeCommandWithCrc(ComputePageMac, (anon ? 0xE0 : 0x00) | page_num, OneWireMaster::StrongLevel); @@ -278,7 +282,7 @@ return result; } - (*sleep)(shaComputationDelayMs * 2); + sleep->invoke(shaComputationDelayMs * 2); result = master->setLevel(OneWireMaster::NormalLevel); if (result) { return result; @@ -289,7 +293,7 @@ return result; } - result = readDataWithCrc(*master, mac.data(), mac.size()); + result = readDataWithCrc(*master, mac); return result; } @@ -307,7 +311,7 @@ return result; } -error_code DS28E15_22_25::doWriteScratchpad(const Scratchpad & data, +error_code DS28E15_22_25::doWriteScratchpad(Scratchpad::const_span data, Variant variant) { const uint_least8_t parameter = (variant == DS28E22 || variant == DS28E25) ? 0x20 : 0x00; @@ -316,11 +320,11 @@ return result; } - result = writeDataWithCrc(*master, data.data(), data.size()); + result = writeDataWithCrc(*master, data); return result; } -error_code DS28E15_22_25::doReadScratchpad(Scratchpad & data, +error_code DS28E15_22_25::doReadScratchpad(Scratchpad::span data, Variant variant) const { const uint_least8_t parameter = (variant == DS28E22 || variant == DS28E25) ? 0x2F : 0x0F; @@ -329,7 +333,7 @@ return result; } - result = readDataWithCrc(*master, data.data(), data.size()); + result = readDataWithCrc(*master, data); return result; } @@ -344,7 +348,7 @@ return result; } -error_code DS28E15_22_25::readPage(int page, Page & rdbuf) const { +error_code DS28E15_22_25::readPage(int page, Page::span rdbuf) const { error_code result = writeCommandWithCrc(ReadMemory, page); if (result) { return result; @@ -354,31 +358,31 @@ return result; } -error_code DS28E15_22_25::continueReadPage(Page & rdbuf) const { - return readDataWithCrc(*master, rdbuf.data(), rdbuf.size()); +error_code DS28E15_22_25::continueReadPage(Page::span rdbuf) const { + return readDataWithCrc(*master, rdbuf); } -error_code DS28E15_22_25::doWriteAuthSegment(const Segment & newData, - const Hash & mac, Variant variant, - bool continuing) { +error_code DS28E15_22_25::doWriteAuthSegment(Segment::const_span newData, + Hash::const_span mac, + Variant variant, bool continuing) { // CRC gets calculated with CS byte when continuing on DS28E22 and DS28E25. const uint_fast16_t crcStart = ((variant == DS28E22 || variant == DS28E25) && continuing) ? calculateCrc16(0xAA) : 0; - error_code result = writeDataWithCrc(*master, newData.data(), newData.size(), - OneWireMaster::StrongLevel, crcStart); + error_code result = + writeDataWithCrc(*master, newData, OneWireMaster::StrongLevel, crcStart); if (result) { return result; } - (*sleep)(shaComputationDelayMs); + sleep->invoke(shaComputationDelayMs); result = master->setLevel(OneWireMaster::NormalLevel); if (result) { return result; } - result = writeDataWithCrc(*master, mac.data(), mac.size()); + result = writeDataWithCrc(*master, mac); if (result) { return result; } @@ -393,8 +397,8 @@ } error_code DS28E15_22_25::doWriteAuthSegment(int pageNum, int segmentNum, - const Segment & newData, - const Hash & mac, + Segment::const_span newData, + Hash::const_span mac, Variant variant) { error_code result = writeCommandWithCrc(AuthWriteMemory, (segmentNum << 5) | pageNum); @@ -406,67 +410,13 @@ return result; } -error_code DS28E15_22_25::doContinueWriteAuthSegment(const Segment & newData, - const Hash & mac, - Variant variant) { +error_code DS28E15_22_25::doContinueWriteAuthSegment( + Segment::const_span newData, Hash::const_span mac, Variant variant) { return doWriteAuthSegment(newData, mac, variant, true); } -WriteMacData DS28E15_22_25::createSegmentWriteMacData( - int pageNum, int segmentNum, const Segment & newData, - const Segment & oldData, const RomId & romId, const ManId & manId) { - WriteMacData MT; - - // insert ROM number - copy(romId.begin(), romId.end(), MT.begin()); - - MT[11] = segmentNum; - MT[10] = pageNum; - MT[9] = manId[0]; - MT[8] = manId[1]; - - // insert old data - copy(oldData.begin(), oldData.end(), MT.begin() + 12); - - // insert new data - copy(newData.begin(), newData.end(), MT.begin() + 16); - - return MT; -} - -WriteMacData DS28E15_22_25::createProtectionWriteMacData( - const BlockProtection & newProtection, - const BlockProtection & oldProtection, const RomId & romId, - const ManId & manId) { - WriteMacData MT; - - // insert ROM number - copy(romId.begin(), romId.end(), MT.begin()); - - // instert block and page - MT[11] = 0; - MT[10] = newProtection.blockNum(); - - MT[9] = manId[0]; - MT[8] = manId[1]; - - // old data - MT[12] = oldProtection.authProtection() ? 0x01 : 0x00; - MT[13] = oldProtection.eepromEmulation() ? 0x01 : 0x00; - MT[14] = oldProtection.writeProtection() ? 0x01 : 0x00; - MT[15] = oldProtection.readProtection() ? 0x01 : 0x00; - // new data - MT[16] = newProtection.authProtection() ? 0x01 : 0x00; - MT[17] = newProtection.eepromEmulation() ? 0x01 : 0x00; - MT[18] = newProtection.writeProtection() ? 0x01 : 0x00; - MT[19] = newProtection.readProtection() ? 0x01 : 0x00; - - // compute the mac - return MT; -} - error_code DS28E15_22_25::readSegment(int page, int segment, - Segment & data) const { + Segment::span data) const { error_code result = writeCommandWithCrc(ReadMemory, (segment << 5) | page); if (result) { return result; @@ -476,12 +426,12 @@ return result; } -error_code DS28E15_22_25::continueReadSegment(Segment & data) const { - return master->readBlock(data.data(), data.size()); +error_code DS28E15_22_25::continueReadSegment(Segment::span data) const { + return master->readBlock(data); } error_code DS28E15_22_25::writeSegment(int page, int block, - const Segment & data) { + Segment::const_span data) { error_code result = writeCommandWithCrc(WriteMemory, (block << 5) | page); if (result) { return result; @@ -491,8 +441,8 @@ return result; } -error_code DS28E15_22_25::continueWriteSegment(const Segment & data) { - error_code result = writeDataWithCrc(*master, data.data(), data.size()); +error_code DS28E15_22_25::continueWriteSegment(Segment::const_span data) { + error_code result = writeDataWithCrc(*master, data); if (result) { return result; } @@ -501,55 +451,37 @@ return result; } -SlaveSecretData -DS28E15_22_25::createSlaveSecretData(const Page & bindingPage, - int bindingPageNum, - const Scratchpad & partialSecret, - const RomId & romId, const ManId & manId) { - SlaveSecretData slaveSecretData; - SlaveSecretData::iterator slaveSecretDataIt = slaveSecretData.begin(); - slaveSecretDataIt = - copy(bindingPage.begin(), bindingPage.end(), slaveSecretDataIt); - slaveSecretDataIt = - copy(partialSecret.begin(), partialSecret.end(), slaveSecretDataIt); - slaveSecretDataIt = copy(romId.begin(), romId.end(), slaveSecretDataIt); - *slaveSecretDataIt = manId[1]; - *(++slaveSecretDataIt) = manId[0]; - *(++slaveSecretDataIt) = bindingPageNum; - *(++slaveSecretDataIt) = 0x00; - return slaveSecretData; -} - -error_code DS28E15_22_25::doReadAllBlockProtection(BlockProtection * protection, - const size_t protectionLen, - Variant variant) const { +error_code +DS28E15_22_25::doReadAllBlockProtection(span<BlockProtection> protection, + Variant variant) const { error_code result = writeCommandWithCrc(ReadStatus, 0); if (!result) { if (variant == DS28E22 || variant == DS28E25) { // Need to read extra data on DS28E22 to get CRC16. uint_least8_t buf[DS28E25::memoryPages]; - result = readDataWithCrc(*master, buf, DS28E25::memoryPages); + result = readDataWithCrc(*master, buf); if (!result) { const int blocks = ((variant == DS28E22) ? DS28E22::memoryPages : DS28E25::memoryPages) / ds28e22_25_pagesPerBlock; - for (size_t i = 0; - i < std::min(protectionLen, static_cast<size_t>(blocks)); i++) { + for (span<BlockProtection>::index_type i = 0; + i < std::min<span<BlockProtection>::index_type>(protection.size(), + blocks); + ++i) { protection[i].setStatusByte( (buf[i * ds28e22_25_pagesPerBlock] & 0xF0) | // Upper nibble ((buf[i * ds28e22_25_pagesPerBlock] & 0x0F) / ds28e22_25_pagesPerBlock)); // Lower nibble } } - } else // DS28E15 - { + } else { // DS28E15 uint_least8_t buf[DS28E15::protectionBlocks]; - result = readDataWithCrc(*master, buf, DS28E15::protectionBlocks); + result = readDataWithCrc(*master, buf); if (!result) { - for (size_t i = 0; - i < std::min(protectionLen, - static_cast<size_t>(DS28E15::protectionBlocks)); - i++) { + for (span<BlockProtection>::index_type i = 0; + i < std::min<span<BlockProtection>::index_type>( + protection.size(), DS28E15::protectionBlocks); + ++i) { protection[i].setStatusByte(buf[i]); } } @@ -592,8 +524,8 @@ error_code DS28E15_22_25::readPersonality(Personality & personality) const { error_code result = writeCommandWithCrc(ReadStatus, 0xE0); if (!result) { - array<uint_least8_t, 4> data; - result = readDataWithCrc(*master, data.data(), data.size()); + uint_least8_t data[4]; + result = readDataWithCrc(*master, data); if (!result) { personality.PB1 = data[0]; personality.PB2 = data[1]; @@ -604,11 +536,14 @@ return result; } -error_code DS28EL15::writeScratchpad(const Scratchpad & data) { +const int DS28EL15::memoryPages; +const int DS28EL15::protectionBlocks; + +error_code DS28EL15::writeScratchpad(Scratchpad::const_span data) { return doWriteScratchpad(data, DS28E15); } -error_code DS28EL15::readScratchpad(Scratchpad & data) const { +error_code DS28EL15::readScratchpad(Scratchpad::span data) const { return doReadScratchpad(data, DS28E15); } @@ -618,20 +553,19 @@ } error_code DS28EL15::writeAuthSegment(int pageNum, int segmentNum, - const Segment & newData, - const Hash & mac) { + Segment::const_span newData, + Hash::const_span mac) { return doWriteAuthSegment(pageNum, segmentNum, newData, mac, DS28E15); } -error_code DS28EL15::continueWriteAuthSegment(const Segment & newData, - const Hash & mac) { +error_code DS28EL15::continueWriteAuthSegment(Segment::const_span newData, + Hash::const_span mac) { return doContinueWriteAuthSegment(newData, mac, DS28E15); } error_code DS28EL15::readAllBlockProtection( - array<BlockProtection, protectionBlocks> & protection) const { - return doReadAllBlockProtection(protection.data(), protection.size(), - DS28E15); + span<BlockProtection, protectionBlocks> protection) const { + return doReadAllBlockProtection(protection, DS28E15); } error_code DS28E15::loadSecret(bool lock) { return doLoadSecret(lock, false); } @@ -640,11 +574,14 @@ return doComputeSecret(pageNum, lock, false); } -error_code DS28EL22::writeScratchpad(const Scratchpad & data) { +const int DS28EL22::memoryPages; +const int DS28EL22::protectionBlocks; + +error_code DS28EL22::writeScratchpad(Scratchpad::const_span data) { return doWriteScratchpad(data, DS28E22); } -error_code DS28EL22::readScratchpad(Scratchpad & data) const { +error_code DS28EL22::readScratchpad(Scratchpad::span data) const { return doReadScratchpad(data, DS28E22); } @@ -654,20 +591,19 @@ } error_code DS28EL22::writeAuthSegment(int pageNum, int segmentNum, - const Segment & newData, - const Hash & mac) { + Segment::const_span newData, + Hash::const_span mac) { return doWriteAuthSegment(pageNum, segmentNum, newData, mac, DS28E22); } -error_code DS28EL22::continueWriteAuthSegment(const Segment & newData, - const Hash & mac) { +error_code DS28EL22::continueWriteAuthSegment(Segment::const_span newData, + Hash::const_span mac) { return doContinueWriteAuthSegment(newData, mac, DS28E22); } error_code DS28EL22::readAllBlockProtection( - array<BlockProtection, protectionBlocks> & protection) const { - return doReadAllBlockProtection(protection.data(), protection.size(), - DS28E22); + span<BlockProtection, protectionBlocks> protection) const { + return doReadAllBlockProtection(protection, DS28E22); } error_code DS28E22::loadSecret(bool lock) { return doLoadSecret(lock, false); } @@ -676,11 +612,14 @@ return doComputeSecret(pageNum, lock, false); } -error_code DS28EL25::writeScratchpad(const Scratchpad & data) { +const int DS28EL25::memoryPages; +const int DS28EL25::protectionBlocks; + +error_code DS28EL25::writeScratchpad(Scratchpad::const_span data) { return doWriteScratchpad(data, DS28E25); } -error_code DS28EL25::readScratchpad(Scratchpad & data) const { +error_code DS28EL25::readScratchpad(Scratchpad::span data) const { return doReadScratchpad(data, DS28E25); } @@ -690,20 +629,19 @@ } error_code DS28EL25::writeAuthSegment(int pageNum, int segmentNum, - const Segment & newData, - const Hash & mac) { + Segment::const_span newData, + Hash::const_span mac) { return doWriteAuthSegment(pageNum, segmentNum, newData, mac, DS28E25); } -error_code DS28EL25::continueWriteAuthSegment(const Segment & newData, - const Hash & mac) { +error_code DS28EL25::continueWriteAuthSegment(Segment::const_span newData, + Hash::const_span mac) { return doContinueWriteAuthSegment(newData, mac, DS28E25); } error_code DS28EL25::readAllBlockProtection( - array<BlockProtection, protectionBlocks> & protection) const { - return doReadAllBlockProtection(protection.data(), protection.size(), - DS28E25); + span<BlockProtection, protectionBlocks> protection) const { + return doReadAllBlockProtection(protection, DS28E25); } error_code DS28E25::loadSecret(bool lock) { return doLoadSecret(lock, false); }