Device interface library for multiple platforms including Mbed.
Dependents: DeepCover Embedded Security in IoT MaximInterface MAXREFDES155#
Maxim Interface is a library framework focused on providing flexible and expressive hardware interfaces. Both communication interfaces such as I2C and 1-Wire and device interfaces such as DS18B20 are supported. Modern C++ concepts are used extensively while keeping compatibility with C++98/C++03 and requiring no external dependencies. The embedded-friendly design does not depend on exceptions or RTTI.
The full version of the project is hosted on GitLab: https://gitlab.com/iabenz/MaximInterface
Diff: MaximInterfaceDevices/DS28E15_22_25.cpp
- Revision:
- 8:5ea891c7d1a1
- Parent:
- 7:9cd16581b578
- Child:
- 10:947d3f44e0a0
--- a/MaximInterfaceDevices/DS28E15_22_25.cpp Mon Jul 22 11:44:07 2019 -0500 +++ b/MaximInterfaceDevices/DS28E15_22_25.cpp Mon Sep 16 11:13:37 2019 -0500 @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* Copyright (C) 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"), @@ -31,10 +31,13 @@ *******************************************************************************/ #include <algorithm> -#include <MaximInterfaceCore/crc.hpp> +#include <MaximInterfaceCore/Crc.hpp> #include <MaximInterfaceCore/Error.hpp> #include "DS28E15_22_25.hpp" +#define TRY MaximInterfaceCore_TRY +#define TRY_VALUE MaximInterfaceCore_TRY_VALUE + namespace MaximInterfaceDevices { using namespace Core; @@ -48,27 +51,18 @@ static const int ds28e22_25_pagesPerBlock = 2; -static error_code +static Result<void> 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); - if (result) { - return result; - } + TRY(master.writeBlock(data)); uint_least8_t response[2]; - result = master.readByte(response[0]); - if (result) { - return result; + TRY_VALUE(response[0], master.readByte()); + TRY_VALUE(response[1], master.readByteSetLevel(level)); + if (calculateCrc16(calculateCrc16(crcStart, data), response) != 0xB001u) { + return DS28E15_22_25::CrcError; } - result = master.readByteSetLevel(response[1], level); - if (result) { - return result; - } - if (calculateCrc16(calculateCrc16(crcStart, data), response) != 0xB001) { - result = make_error_code(DS28E15_22_25::CrcError); - } - return result; + return none; } const int DS28E15_22_25::segmentsPerPage; @@ -79,11 +73,11 @@ return *this; } -error_code +Result<void> DS28E15_22_25::writeCommandWithCrc(Command command, uint_least8_t parameter, OneWireMaster::Level level) const { - error_code result = selectRom(*master); - if (!result) { + Result<void> result = selectRom(*master); + if (result) { const uint_least8_t data[] = {static_cast<uint_least8_t>(command), parameter}; result = writeDataWithCrc(*master, data, level); @@ -91,44 +85,41 @@ return result; } -static error_code readDataWithCrc(OneWireMaster & master, - span<uint_least8_t> data) { - error_code result = master.readBlock(data); - if (result) { +static Result<void> readDataWithCrc(OneWireMaster & master, + span<uint_least8_t> data) { + Result<void> result = master.readBlock(data); + if (!result) { return result; } uint_least8_t response[2]; result = master.readBlock(response); - if (result) { + if (!result) { return result; } - if (calculateCrc16(calculateCrc16(data), response) != 0xB001) { - result = make_error_code(DS28E15_22_25::CrcError); + if (calculateCrc16(calculateCrc16(data), response) != 0xB001u) { + result = DS28E15_22_25::CrcError; } return result; } -static error_code readCsByte(OneWireMaster & master) { - uint_least8_t response; - error_code result = master.readByte(response); - if (result) { - return result; +static Result<void> readCsByte(OneWireMaster & master) { + const Result<uint_least8_t> response = master.readByte(); + if (!response) { + return response.error(); } - if (response != 0xAA) { - result = make_error_code(DS28E15_22_25::OperationFailure); - } - return result; + return (response.value() == 0xAA) ? makeResult(none) + : DS28E15_22_25::OperationFailure; } -static error_code releaseSequence(OneWireMaster & master, Sleep & sleep, - int delayTimeMs) { - error_code result = master.writeBytePower(0xAA); - if (result) { +static Result<void> releaseSequence(OneWireMaster & master, Sleep & sleep, + int delayTimeMs) { + Result<void> result = master.writeBytePower(0xAA); + if (!result) { return result; } sleep(delayTimeMs); result = master.setLevel(OneWireMaster::NormalLevel); - if (result) { + if (!result) { return result; } return readCsByte(master); @@ -215,29 +206,29 @@ return *this; } -error_code +Result<void> DS28E15_22_25::writeAuthBlockProtection(BlockProtection newProtection, Page::const_span mac) { - error_code result = + Result<void> result = writeCommandWithCrc(AuthWriteBlockProtection, newProtection.statusByte(), OneWireMaster::StrongLevel); - if (result) { + if (!result) { return result; } sleep->invoke(shaComputationDelayMs); result = master->setLevel(OneWireMaster::NormalLevel); - if (result) { + if (!result) { return result; } result = writeDataWithCrc(*master, mac); - if (result) { + if (!result) { return result; } result = readCsByte(*master); - if (result) { + if (!result) { return result; } @@ -245,10 +236,10 @@ return result; } -error_code DS28E15_22_25::writeBlockProtection(BlockProtection protection) { - error_code result = +Result<void> DS28E15_22_25::writeBlockProtection(BlockProtection protection) { + Result<void> result = writeCommandWithCrc(WriteBlockProtection, protection.statusByte()); - if (result) { + if (!result) { return result; } @@ -256,52 +247,51 @@ return result; } -error_code DS28E15_22_25::doReadBlockProtection(int blockNum, - BlockProtection & protection, - Variant variant) const { +Result<DS28E15_22_25::BlockProtection> +DS28E15_22_25::doReadBlockProtection(int blockNum, Variant variant) const { uint_least8_t buffer = blockNum; if (variant == DS28E22 || variant == DS28E25) { buffer *= ds28e22_25_pagesPerBlock; } - error_code result = writeCommandWithCrc(ReadStatus, buffer); - if (!result) { - result = master->readByte(buffer); - if (!result) { - protection.setStatusByte(buffer); - } - } - return result; + TRY(writeCommandWithCrc(ReadStatus, buffer)); + TRY_VALUE(buffer, master->readByte()); + return BlockProtection(buffer); } -error_code DS28E15_22_25::computeReadPageMac(int page_num, bool anon, - Page::span mac) const { - error_code result = +Result<DS28E15_22_25::Page::array> +DS28E15_22_25::computeReadPageMac(int page_num, bool anon) const { + Result<void> result = writeCommandWithCrc(ComputePageMac, (anon ? 0xE0 : 0x00) | page_num, OneWireMaster::StrongLevel); - if (result) { - return result; + if (!result) { + return result.error(); } sleep->invoke(shaComputationDelayMs * 2); result = master->setLevel(OneWireMaster::NormalLevel); - if (result) { - return result; + if (!result) { + return result.error(); } result = readCsByte(*master); - if (result) { - return result; + if (!result) { + return result.error(); } + Page::array mac; result = readDataWithCrc(*master, mac); - return result; + if (!result) { + return result.error(); + } + + return mac; } -error_code DS28E15_22_25::doComputeSecret(int page_num, bool lock, - bool lowPower) { - error_code result = writeCommandWithCrc(ComputeAndLockSecret, - lock ? (0xE0 | page_num) : page_num); - if (result) { +Result<void> DS28E15_22_25::doComputeSecret(int page_num, bool lock, + bool lowPower) { + Result<void> result = writeCommandWithCrc( + ComputeAndLockSecret, lock ? (0xE0 | page_num) : page_num); + if (!result) { return result; } @@ -311,12 +301,12 @@ return result; } -error_code DS28E15_22_25::doWriteScratchpad(Page::const_span data, - Variant variant) { +Result<void> DS28E15_22_25::doWriteScratchpad(Page::const_span data, + Variant variant) { const uint_least8_t parameter = (variant == DS28E22 || variant == DS28E25) ? 0x20 : 0x00; - error_code result = writeCommandWithCrc(ReadWriteScratchpad, parameter); - if (result) { + Result<void> result = writeCommandWithCrc(ReadWriteScratchpad, parameter); + if (!result) { return result; } @@ -324,23 +314,28 @@ return result; } -error_code DS28E15_22_25::doReadScratchpad(Page::span data, - Variant variant) const { +Result<DS28E15_22_25::Page::array> +DS28E15_22_25::doReadScratchpad(Variant variant) const { const uint_least8_t parameter = (variant == DS28E22 || variant == DS28E25) ? 0x2F : 0x0F; - error_code result = writeCommandWithCrc(ReadWriteScratchpad, parameter); - if (result) { - return result; + Result<void> result = writeCommandWithCrc(ReadWriteScratchpad, parameter); + if (!result) { + return result.error(); } + Page::array data; result = readDataWithCrc(*master, data); - return result; + if (!result) { + return result.error(); + } + + return data; } -error_code DS28E15_22_25::doLoadSecret(bool lock, bool lowPower) { - error_code result = +Result<void> DS28E15_22_25::doLoadSecret(bool lock, bool lowPower) { + Result<void> result = writeCommandWithCrc(LoadAndLockSecret, lock ? 0xE0 : 0x00); - if (result) { + if (!result) { return result; } @@ -348,47 +343,49 @@ return result; } -error_code DS28E15_22_25::readPage(int page, Page::span rdbuf) const { - error_code result = writeCommandWithCrc(ReadMemory, page); - if (result) { - return result; +Result<DS28E15_22_25::Page::array> DS28E15_22_25::readPage(int page) const { + const Result<void> result = writeCommandWithCrc(ReadMemory, page); + if (!result) { + return result.error(); } - result = continueReadPage(rdbuf); - return result; + return continueReadPage(); } -error_code DS28E15_22_25::continueReadPage(Page::span rdbuf) const { - return readDataWithCrc(*master, rdbuf); +Result<DS28E15_22_25::Page::array> DS28E15_22_25::continueReadPage() const { + Page::array rdbuf; + TRY(readDataWithCrc(*master, rdbuf)); + return rdbuf; } -error_code DS28E15_22_25::doWriteAuthSegment(Segment::const_span newData, - Page::const_span mac, - Variant variant, bool continuing) { +Result<void> DS28E15_22_25::doWriteAuthSegment(Segment::const_span newData, + Page::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 = + Result<void> result = writeDataWithCrc(*master, newData, OneWireMaster::StrongLevel, crcStart); - if (result) { + if (!result) { return result; } sleep->invoke(shaComputationDelayMs); result = master->setLevel(OneWireMaster::NormalLevel); - if (result) { + if (!result) { return result; } result = writeDataWithCrc(*master, mac); - if (result) { + if (!result) { return result; } result = readCsByte(*master); - if (result) { + if (!result) { return result; } @@ -396,13 +393,13 @@ return result; } -error_code DS28E15_22_25::doWriteAuthSegment(int pageNum, int segmentNum, - Segment::const_span newData, - Page::const_span mac, - Variant variant) { - error_code result = +Result<void> DS28E15_22_25::doWriteAuthSegment(int pageNum, int segmentNum, + Segment::const_span newData, + Page::const_span mac, + Variant variant) { + Result<void> result = writeCommandWithCrc(AuthWriteMemory, (segmentNum << 5) | pageNum); - if (result) { + if (!result) { return result; } @@ -410,30 +407,32 @@ return result; } -error_code DS28E15_22_25::doContinueWriteAuthSegment( +Result<void> DS28E15_22_25::doContinueWriteAuthSegment( Segment::const_span newData, Page::const_span mac, Variant variant) { return doWriteAuthSegment(newData, mac, variant, true); } -error_code DS28E15_22_25::readSegment(int page, int segment, - Segment::span data) const { - error_code result = writeCommandWithCrc(ReadMemory, (segment << 5) | page); - if (result) { - return result; +Result<DS28E15_22_25::Segment::array> +DS28E15_22_25::readSegment(int page, int segment) const { + Result<void> result = writeCommandWithCrc(ReadMemory, (segment << 5) | page); + if (!result) { + return result.error(); } - result = continueReadSegment(data); - return result; + return continueReadSegment(); } -error_code DS28E15_22_25::continueReadSegment(Segment::span data) const { - return master->readBlock(data); +Result<DS28E15_22_25::Segment::array> +DS28E15_22_25::continueReadSegment() const { + Segment::array data; + TRY(master->readBlock(data)); + return data; } -error_code DS28E15_22_25::writeSegment(int page, int block, - Segment::const_span data) { - error_code result = writeCommandWithCrc(WriteMemory, (block << 5) | page); - if (result) { +Result<void> DS28E15_22_25::writeSegment(int page, int block, + Segment::const_span data) { + Result<void> result = writeCommandWithCrc(WriteMemory, (block << 5) | page); + if (!result) { return result; } @@ -441,9 +440,9 @@ return result; } -error_code DS28E15_22_25::continueWriteSegment(Segment::const_span data) { - error_code result = writeDataWithCrc(*master, data); - if (result) { +Result<void> DS28E15_22_25::continueWriteSegment(Segment::const_span data) { + Result<void> result = writeDataWithCrc(*master, data); + if (!result) { return result; } @@ -451,10 +450,10 @@ return result; } -error_code +Result<void> DS28E15_22_25::doReadAllBlockProtection(span<BlockProtection> protection, Variant variant) const { - error_code result = writeCommandWithCrc(ReadStatus, 0); + Result<void> result = writeCommandWithCrc(ReadStatus, 0); if (!result) { if (variant == DS28E22 || variant == DS28E25) { // Need to read extra data on DS28E22 to get CRC16. @@ -502,151 +501,166 @@ case OperationFailure: return "Operation Failure"; - - default: - return defaultErrorMessage(condition); } + return defaultErrorMessage(condition); } } instance; return instance; } -error_code DS28E15_22_25::loadSecret(bool lock) { +Result<void> DS28E15_22_25::loadSecret(bool lock) { // Use worst-case low power timing if the device type is not known. return doLoadSecret(lock, true); } -error_code DS28E15_22_25::computeSecret(int pageNum, bool lock) { +Result<void> DS28E15_22_25::computeSecret(int pageNum, bool lock) { // Use worst-case low power timing if the device type is not known. return doComputeSecret(pageNum, lock, true); } -error_code DS28E15_22_25::readPersonality(Personality & personality) const { - error_code result = writeCommandWithCrc(ReadStatus, 0xE0); +Result<DS28E15_22_25::Personality> DS28E15_22_25::readPersonality() const { + Result<void> result = writeCommandWithCrc(ReadStatus, 0xE0); + if (!result) { + return result.error(); + } + + uint_least8_t data[4]; + result = readDataWithCrc(*master, data); if (!result) { - uint_least8_t data[4]; - result = readDataWithCrc(*master, data); - if (!result) { - personality.PB1 = data[0]; - personality.PB2 = data[1]; - personality.manId[0] = data[2]; - personality.manId[1] = data[3]; - } + return result.error(); } - return result; + + Personality personality; + personality.PB1 = data[0]; + personality.PB2 = data[1]; + personality.manId[0] = data[2]; + personality.manId[1] = data[3]; + return personality; } const int DS28EL15::memoryPages; const int DS28EL15::protectionBlocks; -error_code DS28EL15::writeScratchpad(Page::const_span data) { +Result<void> DS28EL15::writeScratchpad(Page::const_span data) { return doWriteScratchpad(data, DS28E15); } -error_code DS28EL15::readScratchpad(Page::span data) const { - return doReadScratchpad(data, DS28E15); +Result<DS28E15_22_25::Page::array> DS28EL15::readScratchpad() const { + return doReadScratchpad(DS28E15); } -error_code DS28EL15::readBlockProtection(int blockNum, - BlockProtection & protection) const { - return doReadBlockProtection(blockNum, protection, DS28E15); +Result<DS28E15_22_25::BlockProtection> +DS28EL15::readBlockProtection(int blockNum) const { + return doReadBlockProtection(blockNum, DS28E15); } -error_code DS28EL15::writeAuthSegment(int pageNum, int segmentNum, - Segment::const_span newData, - Page::const_span mac) { +Result<void> DS28EL15::writeAuthSegment(int pageNum, int segmentNum, + Segment::const_span newData, + Page::const_span mac) { return doWriteAuthSegment(pageNum, segmentNum, newData, mac, DS28E15); } -error_code DS28EL15::continueWriteAuthSegment(Segment::const_span newData, - Page::const_span mac) { +Result<void> DS28EL15::continueWriteAuthSegment(Segment::const_span newData, + Page::const_span mac) { return doContinueWriteAuthSegment(newData, mac, DS28E15); } -error_code DS28EL15::readAllBlockProtection( - span<BlockProtection, protectionBlocks> protection) const { - return doReadAllBlockProtection(protection, DS28E15); +Result<array<DS28E15_22_25::BlockProtection, DS28E15::protectionBlocks> > +DS28EL15::readAllBlockProtection() const { + array<BlockProtection, protectionBlocks> protection; + TRY(doReadAllBlockProtection(protection, DS28E15)); + return protection; } -error_code DS28E15::loadSecret(bool lock) { return doLoadSecret(lock, false); } +Result<void> DS28E15::loadSecret(bool lock) { + return doLoadSecret(lock, false); +} -error_code DS28E15::computeSecret(int pageNum, bool lock) { +Result<void> DS28E15::computeSecret(int pageNum, bool lock) { return doComputeSecret(pageNum, lock, false); } const int DS28EL22::memoryPages; const int DS28EL22::protectionBlocks; -error_code DS28EL22::writeScratchpad(Page::const_span data) { +Result<void> DS28EL22::writeScratchpad(Page::const_span data) { return doWriteScratchpad(data, DS28E22); } -error_code DS28EL22::readScratchpad(Page::span data) const { - return doReadScratchpad(data, DS28E22); +Result<DS28E15_22_25::Page::array> DS28EL22::readScratchpad() const { + return doReadScratchpad(DS28E22); } -error_code DS28EL22::readBlockProtection(int blockNum, - BlockProtection & protection) const { - return doReadBlockProtection(blockNum, protection, DS28E22); +Result<DS28E15_22_25::BlockProtection> +DS28EL22::readBlockProtection(int blockNum) const { + return doReadBlockProtection(blockNum, DS28E22); } -error_code DS28EL22::writeAuthSegment(int pageNum, int segmentNum, - Segment::const_span newData, - Page::const_span mac) { +Result<void> DS28EL22::writeAuthSegment(int pageNum, int segmentNum, + Segment::const_span newData, + Page::const_span mac) { return doWriteAuthSegment(pageNum, segmentNum, newData, mac, DS28E22); } -error_code DS28EL22::continueWriteAuthSegment(Segment::const_span newData, - Page::const_span mac) { +Result<void> DS28EL22::continueWriteAuthSegment(Segment::const_span newData, + Page::const_span mac) { return doContinueWriteAuthSegment(newData, mac, DS28E22); } -error_code DS28EL22::readAllBlockProtection( - span<BlockProtection, protectionBlocks> protection) const { - return doReadAllBlockProtection(protection, DS28E22); +Result<array<DS28E15_22_25::BlockProtection, DS28E22::protectionBlocks> > +DS28EL22::readAllBlockProtection() const { + array<BlockProtection, protectionBlocks> protection; + TRY(doReadAllBlockProtection(protection, DS28E22)); + return protection; } -error_code DS28E22::loadSecret(bool lock) { return doLoadSecret(lock, false); } +Result<void> DS28E22::loadSecret(bool lock) { + return doLoadSecret(lock, false); +} -error_code DS28E22::computeSecret(int pageNum, bool lock) { +Result<void> DS28E22::computeSecret(int pageNum, bool lock) { return doComputeSecret(pageNum, lock, false); } const int DS28EL25::memoryPages; const int DS28EL25::protectionBlocks; -error_code DS28EL25::writeScratchpad(Page::const_span data) { +Result<void> DS28EL25::writeScratchpad(Page::const_span data) { return doWriteScratchpad(data, DS28E25); } -error_code DS28EL25::readScratchpad(Page::span data) const { - return doReadScratchpad(data, DS28E25); +Result<DS28E15_22_25::Page::array> DS28EL25::readScratchpad() const { + return doReadScratchpad(DS28E25); } -error_code DS28EL25::readBlockProtection(int blockNum, - BlockProtection & protection) const { - return doReadBlockProtection(blockNum, protection, DS28E25); +Result<DS28E15_22_25::BlockProtection> +DS28EL25::readBlockProtection(int blockNum) const { + return doReadBlockProtection(blockNum, DS28E25); } -error_code DS28EL25::writeAuthSegment(int pageNum, int segmentNum, - Segment::const_span newData, - Page::const_span mac) { +Result<void> DS28EL25::writeAuthSegment(int pageNum, int segmentNum, + Segment::const_span newData, + Page::const_span mac) { return doWriteAuthSegment(pageNum, segmentNum, newData, mac, DS28E25); } -error_code DS28EL25::continueWriteAuthSegment(Segment::const_span newData, - Page::const_span mac) { +Result<void> DS28EL25::continueWriteAuthSegment(Segment::const_span newData, + Page::const_span mac) { return doContinueWriteAuthSegment(newData, mac, DS28E25); } -error_code DS28EL25::readAllBlockProtection( - span<BlockProtection, protectionBlocks> protection) const { - return doReadAllBlockProtection(protection, DS28E25); +Result<array<DS28E15_22_25::BlockProtection, DS28E25::protectionBlocks> > +DS28EL25::readAllBlockProtection() const { + array<BlockProtection, protectionBlocks> protection; + TRY(doReadAllBlockProtection(protection, DS28E25)); + return protection; } -error_code DS28E25::loadSecret(bool lock) { return doLoadSecret(lock, false); } +Result<void> DS28E25::loadSecret(bool lock) { + return doLoadSecret(lock, false); +} -error_code DS28E25::computeSecret(int pageNum, bool lock) { +Result<void> DS28E25::computeSecret(int pageNum, bool lock) { return doComputeSecret(pageNum, lock, false); }