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

Committer:
IanBenzMaxim
Date:
Mon Jul 22 11:44:07 2019 -0500
Revision:
7:9cd16581b578
Child:
8:5ea891c7d1a1
Updated to version 1.9.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
IanBenzMaxim 7:9cd16581b578 1 /*******************************************************************************
IanBenzMaxim 7:9cd16581b578 2 * Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved.
IanBenzMaxim 7:9cd16581b578 3 *
IanBenzMaxim 7:9cd16581b578 4 * Permission is hereby granted, free of charge, to any person obtaining a
IanBenzMaxim 7:9cd16581b578 5 * copy of this software and associated documentation files (the "Software"),
IanBenzMaxim 7:9cd16581b578 6 * to deal in the Software without restriction, including without limitation
IanBenzMaxim 7:9cd16581b578 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
IanBenzMaxim 7:9cd16581b578 8 * and/or sell copies of the Software, and to permit persons to whom the
IanBenzMaxim 7:9cd16581b578 9 * Software is furnished to do so, subject to the following conditions:
IanBenzMaxim 7:9cd16581b578 10 *
IanBenzMaxim 7:9cd16581b578 11 * The above copyright notice and this permission notice shall be included
IanBenzMaxim 7:9cd16581b578 12 * in all copies or substantial portions of the Software.
IanBenzMaxim 7:9cd16581b578 13 *
IanBenzMaxim 7:9cd16581b578 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
IanBenzMaxim 7:9cd16581b578 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
IanBenzMaxim 7:9cd16581b578 16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IanBenzMaxim 7:9cd16581b578 17 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
IanBenzMaxim 7:9cd16581b578 18 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
IanBenzMaxim 7:9cd16581b578 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
IanBenzMaxim 7:9cd16581b578 20 * OTHER DEALINGS IN THE SOFTWARE.
IanBenzMaxim 7:9cd16581b578 21 *
IanBenzMaxim 7:9cd16581b578 22 * Except as contained in this notice, the name of Maxim Integrated
IanBenzMaxim 7:9cd16581b578 23 * Products, Inc. shall not be used except as stated in the Maxim Integrated
IanBenzMaxim 7:9cd16581b578 24 * Products, Inc. Branding Policy.
IanBenzMaxim 7:9cd16581b578 25 *
IanBenzMaxim 7:9cd16581b578 26 * The mere transfer of this software does not imply any licenses
IanBenzMaxim 7:9cd16581b578 27 * of trade secrets, proprietary technology, copyrights, patents,
IanBenzMaxim 7:9cd16581b578 28 * trademarks, maskwork rights, or any other form of intellectual
IanBenzMaxim 7:9cd16581b578 29 * property whatsoever. Maxim Integrated Products, Inc. retains all
IanBenzMaxim 7:9cd16581b578 30 * ownership rights.
IanBenzMaxim 7:9cd16581b578 31 *******************************************************************************/
IanBenzMaxim 7:9cd16581b578 32
IanBenzMaxim 7:9cd16581b578 33 #include <MaximInterfaceCore/Error.hpp>
IanBenzMaxim 7:9cd16581b578 34 #include "DS2465.hpp"
IanBenzMaxim 7:9cd16581b578 35
IanBenzMaxim 7:9cd16581b578 36 namespace MaximInterfaceDevices {
IanBenzMaxim 7:9cd16581b578 37
IanBenzMaxim 7:9cd16581b578 38 using namespace Core;
IanBenzMaxim 7:9cd16581b578 39
IanBenzMaxim 7:9cd16581b578 40 /// Delay required after writing an EEPROM segment.
IanBenzMaxim 7:9cd16581b578 41 static const int eepromSegmentWriteDelayMs = 10;
IanBenzMaxim 7:9cd16581b578 42 /// Delay required after writing an EEPROM page such as the secret memory.
IanBenzMaxim 7:9cd16581b578 43 static const int eepromPageWriteDelayMs = 8 * eepromSegmentWriteDelayMs;
IanBenzMaxim 7:9cd16581b578 44 /// Delay required for a SHA computation to complete.
IanBenzMaxim 7:9cd16581b578 45 static const int shaComputationDelayMs = 2;
IanBenzMaxim 7:9cd16581b578 46
IanBenzMaxim 7:9cd16581b578 47 static const uint_least8_t scratchpad = 0x00;
IanBenzMaxim 7:9cd16581b578 48 static const uint_least8_t commandReg = 0x60;
IanBenzMaxim 7:9cd16581b578 49
IanBenzMaxim 7:9cd16581b578 50 static const uint_least8_t owTransmitBlockCmd = 0x69;
IanBenzMaxim 7:9cd16581b578 51
IanBenzMaxim 7:9cd16581b578 52 /// DS2465 Status bits.
IanBenzMaxim 7:9cd16581b578 53 enum StatusBit {
IanBenzMaxim 7:9cd16581b578 54 Status_1WB = 0x01,
IanBenzMaxim 7:9cd16581b578 55 Status_PPD = 0x02,
IanBenzMaxim 7:9cd16581b578 56 Status_SD = 0x04,
IanBenzMaxim 7:9cd16581b578 57 Status_LL = 0x08,
IanBenzMaxim 7:9cd16581b578 58 Status_RST = 0x10,
IanBenzMaxim 7:9cd16581b578 59 Status_SBR = 0x20,
IanBenzMaxim 7:9cd16581b578 60 Status_TSB = 0x40,
IanBenzMaxim 7:9cd16581b578 61 Status_DIR = 0x80
IanBenzMaxim 7:9cd16581b578 62 };
IanBenzMaxim 7:9cd16581b578 63
IanBenzMaxim 7:9cd16581b578 64 static const int maxBlockSize = 63;
IanBenzMaxim 7:9cd16581b578 65
IanBenzMaxim 7:9cd16581b578 66 const int DS2465::memoryPages;
IanBenzMaxim 7:9cd16581b578 67 const int DS2465::segmentsPerPage;
IanBenzMaxim 7:9cd16581b578 68
IanBenzMaxim 7:9cd16581b578 69 error_code DS2465::initialize(Config config) {
IanBenzMaxim 7:9cd16581b578 70 // reset DS2465
IanBenzMaxim 7:9cd16581b578 71 error_code result = resetDevice();
IanBenzMaxim 7:9cd16581b578 72 if (!result) {
IanBenzMaxim 7:9cd16581b578 73 // write the default configuration setup
IanBenzMaxim 7:9cd16581b578 74 result = writeConfig(config);
IanBenzMaxim 7:9cd16581b578 75 }
IanBenzMaxim 7:9cd16581b578 76 return result;
IanBenzMaxim 7:9cd16581b578 77 }
IanBenzMaxim 7:9cd16581b578 78
IanBenzMaxim 7:9cd16581b578 79 error_code DS2465::computeNextMasterSecret(bool swap, int pageNum,
IanBenzMaxim 7:9cd16581b578 80 PageRegion region) {
IanBenzMaxim 7:9cd16581b578 81 error_code result = make_error_code(ArgumentOutOfRangeError);
IanBenzMaxim 7:9cd16581b578 82 if (pageNum >= 0) {
IanBenzMaxim 7:9cd16581b578 83 const uint_least8_t command[] = {
IanBenzMaxim 7:9cd16581b578 84 0x1E, static_cast<uint_least8_t>(swap ? (0xC8 | (pageNum << 4) | region)
IanBenzMaxim 7:9cd16581b578 85 : 0xBF)};
IanBenzMaxim 7:9cd16581b578 86 result = writeMemory(commandReg, command);
IanBenzMaxim 7:9cd16581b578 87 }
IanBenzMaxim 7:9cd16581b578 88 return result;
IanBenzMaxim 7:9cd16581b578 89 }
IanBenzMaxim 7:9cd16581b578 90
IanBenzMaxim 7:9cd16581b578 91 error_code DS2465::computeWriteMac(bool regwrite, bool swap, int pageNum,
IanBenzMaxim 7:9cd16581b578 92 int segmentNum) const {
IanBenzMaxim 7:9cd16581b578 93 error_code result = make_error_code(ArgumentOutOfRangeError);
IanBenzMaxim 7:9cd16581b578 94 if (pageNum >= 0 && segmentNum >= 0) {
IanBenzMaxim 7:9cd16581b578 95 const uint_least8_t command[] = {
IanBenzMaxim 7:9cd16581b578 96 0x2D, static_cast<uint_least8_t>((regwrite << 7) | (swap << 6) |
IanBenzMaxim 7:9cd16581b578 97 (pageNum << 4) | segmentNum)};
IanBenzMaxim 7:9cd16581b578 98 result = writeMemory(commandReg, command);
IanBenzMaxim 7:9cd16581b578 99 if (!result) {
IanBenzMaxim 7:9cd16581b578 100 sleep->invoke(shaComputationDelayMs);
IanBenzMaxim 7:9cd16581b578 101 }
IanBenzMaxim 7:9cd16581b578 102 }
IanBenzMaxim 7:9cd16581b578 103 return result;
IanBenzMaxim 7:9cd16581b578 104 }
IanBenzMaxim 7:9cd16581b578 105
IanBenzMaxim 7:9cd16581b578 106 error_code DS2465::computeAuthMac(bool swap, int pageNum,
IanBenzMaxim 7:9cd16581b578 107 PageRegion region) const {
IanBenzMaxim 7:9cd16581b578 108 error_code result = make_error_code(ArgumentOutOfRangeError);
IanBenzMaxim 7:9cd16581b578 109 if (pageNum >= 0) {
IanBenzMaxim 7:9cd16581b578 110 const uint_least8_t command[] = {
IanBenzMaxim 7:9cd16581b578 111 0x3C, static_cast<uint_least8_t>(swap ? (0xC8 | (pageNum << 4) | region)
IanBenzMaxim 7:9cd16581b578 112 : 0xBF)};
IanBenzMaxim 7:9cd16581b578 113 result = writeMemory(commandReg, command);
IanBenzMaxim 7:9cd16581b578 114 if (!result) {
IanBenzMaxim 7:9cd16581b578 115 sleep->invoke(shaComputationDelayMs * 2);
IanBenzMaxim 7:9cd16581b578 116 }
IanBenzMaxim 7:9cd16581b578 117 }
IanBenzMaxim 7:9cd16581b578 118 return result;
IanBenzMaxim 7:9cd16581b578 119 }
IanBenzMaxim 7:9cd16581b578 120
IanBenzMaxim 7:9cd16581b578 121 error_code DS2465::computeSlaveSecret(bool swap, int pageNum,
IanBenzMaxim 7:9cd16581b578 122 PageRegion region) {
IanBenzMaxim 7:9cd16581b578 123 error_code result = make_error_code(ArgumentOutOfRangeError);
IanBenzMaxim 7:9cd16581b578 124 if (pageNum >= 0) {
IanBenzMaxim 7:9cd16581b578 125 const uint_least8_t command[] = {
IanBenzMaxim 7:9cd16581b578 126 0x4B, static_cast<uint_least8_t>(swap ? (0xC8 | (pageNum << 4) | region)
IanBenzMaxim 7:9cd16581b578 127 : 0xBF)};
IanBenzMaxim 7:9cd16581b578 128 result = writeMemory(commandReg, command);
IanBenzMaxim 7:9cd16581b578 129 if (!result) {
IanBenzMaxim 7:9cd16581b578 130 sleep->invoke(shaComputationDelayMs * 2);
IanBenzMaxim 7:9cd16581b578 131 }
IanBenzMaxim 7:9cd16581b578 132 }
IanBenzMaxim 7:9cd16581b578 133 return result;
IanBenzMaxim 7:9cd16581b578 134 }
IanBenzMaxim 7:9cd16581b578 135
IanBenzMaxim 7:9cd16581b578 136 error_code DS2465::readPage(int pageNum, Page::span data) const {
IanBenzMaxim 7:9cd16581b578 137 uint_least8_t addr;
IanBenzMaxim 7:9cd16581b578 138 switch (pageNum) {
IanBenzMaxim 7:9cd16581b578 139 case 0:
IanBenzMaxim 7:9cd16581b578 140 addr = 0x80;
IanBenzMaxim 7:9cd16581b578 141 break;
IanBenzMaxim 7:9cd16581b578 142 case 1:
IanBenzMaxim 7:9cd16581b578 143 addr = 0xA0;
IanBenzMaxim 7:9cd16581b578 144 break;
IanBenzMaxim 7:9cd16581b578 145 default:
IanBenzMaxim 7:9cd16581b578 146 return make_error_code(ArgumentOutOfRangeError);
IanBenzMaxim 7:9cd16581b578 147 }
IanBenzMaxim 7:9cd16581b578 148 return readMemory(addr, data);
IanBenzMaxim 7:9cd16581b578 149 }
IanBenzMaxim 7:9cd16581b578 150
IanBenzMaxim 7:9cd16581b578 151 error_code DS2465::writePage(int pageNum, Page::const_span data) {
IanBenzMaxim 7:9cd16581b578 152 error_code result = writeMemory(scratchpad, data);
IanBenzMaxim 7:9cd16581b578 153 if (!result) {
IanBenzMaxim 7:9cd16581b578 154 result = copyScratchpad(false, pageNum, false, 0);
IanBenzMaxim 7:9cd16581b578 155 }
IanBenzMaxim 7:9cd16581b578 156 if (!result) {
IanBenzMaxim 7:9cd16581b578 157 sleep->invoke(eepromPageWriteDelayMs);
IanBenzMaxim 7:9cd16581b578 158 }
IanBenzMaxim 7:9cd16581b578 159 return result;
IanBenzMaxim 7:9cd16581b578 160 }
IanBenzMaxim 7:9cd16581b578 161
IanBenzMaxim 7:9cd16581b578 162 error_code DS2465::writeSegment(int pageNum, int segmentNum,
IanBenzMaxim 7:9cd16581b578 163 Segment::const_span data) {
IanBenzMaxim 7:9cd16581b578 164 error_code result = writeMemory(scratchpad, data);
IanBenzMaxim 7:9cd16581b578 165 if (!result) {
IanBenzMaxim 7:9cd16581b578 166 result = copyScratchpad(false, pageNum, true, segmentNum);
IanBenzMaxim 7:9cd16581b578 167 }
IanBenzMaxim 7:9cd16581b578 168 if (!result) {
IanBenzMaxim 7:9cd16581b578 169 sleep->invoke(eepromSegmentWriteDelayMs);
IanBenzMaxim 7:9cd16581b578 170 }
IanBenzMaxim 7:9cd16581b578 171 return result;
IanBenzMaxim 7:9cd16581b578 172 }
IanBenzMaxim 7:9cd16581b578 173
IanBenzMaxim 7:9cd16581b578 174 error_code DS2465::writeMasterSecret(Page::const_span masterSecret) {
IanBenzMaxim 7:9cd16581b578 175 error_code result = writeMemory(scratchpad, masterSecret);
IanBenzMaxim 7:9cd16581b578 176 if (!result) {
IanBenzMaxim 7:9cd16581b578 177 result = copyScratchpad(true, 0, false, 0);
IanBenzMaxim 7:9cd16581b578 178 }
IanBenzMaxim 7:9cd16581b578 179 if (!result) {
IanBenzMaxim 7:9cd16581b578 180 sleep->invoke(eepromPageWriteDelayMs);
IanBenzMaxim 7:9cd16581b578 181 }
IanBenzMaxim 7:9cd16581b578 182 return result;
IanBenzMaxim 7:9cd16581b578 183 }
IanBenzMaxim 7:9cd16581b578 184
IanBenzMaxim 7:9cd16581b578 185 error_code DS2465::copyScratchpad(bool destSecret, int pageNum, bool notFull,
IanBenzMaxim 7:9cd16581b578 186 int segmentNum) {
IanBenzMaxim 7:9cd16581b578 187 error_code result = make_error_code(ArgumentOutOfRangeError);
IanBenzMaxim 7:9cd16581b578 188 if (pageNum >= 0 && segmentNum >= 0) {
IanBenzMaxim 7:9cd16581b578 189 const uint_least8_t command[] = {
IanBenzMaxim 7:9cd16581b578 190 0x5A,
IanBenzMaxim 7:9cd16581b578 191 static_cast<uint_least8_t>(destSecret ? 0
IanBenzMaxim 7:9cd16581b578 192 : (0x80 | (pageNum << 4) |
IanBenzMaxim 7:9cd16581b578 193 (notFull << 3) | segmentNum))};
IanBenzMaxim 7:9cd16581b578 194 result = writeMemory(commandReg, command);
IanBenzMaxim 7:9cd16581b578 195 }
IanBenzMaxim 7:9cd16581b578 196 return result;
IanBenzMaxim 7:9cd16581b578 197 }
IanBenzMaxim 7:9cd16581b578 198
IanBenzMaxim 7:9cd16581b578 199 error_code DS2465::configureLevel(Level level) {
IanBenzMaxim 7:9cd16581b578 200 // Check if supported level
IanBenzMaxim 7:9cd16581b578 201 if (!((level == NormalLevel) || (level == StrongLevel))) {
IanBenzMaxim 7:9cd16581b578 202 return make_error_code(InvalidLevelError);
IanBenzMaxim 7:9cd16581b578 203 }
IanBenzMaxim 7:9cd16581b578 204 // Check if requested level already set
IanBenzMaxim 7:9cd16581b578 205 if (curConfig.getSPU() == (level == StrongLevel)) {
IanBenzMaxim 7:9cd16581b578 206 return error_code();
IanBenzMaxim 7:9cd16581b578 207 }
IanBenzMaxim 7:9cd16581b578 208 // Set the level
IanBenzMaxim 7:9cd16581b578 209 return writeConfig(Config(curConfig).setSPU(level == StrongLevel));
IanBenzMaxim 7:9cd16581b578 210 }
IanBenzMaxim 7:9cd16581b578 211
IanBenzMaxim 7:9cd16581b578 212 error_code DS2465::setLevel(Level newLevel) {
IanBenzMaxim 7:9cd16581b578 213 if (newLevel == StrongLevel) {
IanBenzMaxim 7:9cd16581b578 214 return make_error_code(InvalidLevelError);
IanBenzMaxim 7:9cd16581b578 215 }
IanBenzMaxim 7:9cd16581b578 216
IanBenzMaxim 7:9cd16581b578 217 return configureLevel(newLevel);
IanBenzMaxim 7:9cd16581b578 218 }
IanBenzMaxim 7:9cd16581b578 219
IanBenzMaxim 7:9cd16581b578 220 error_code DS2465::setSpeed(Speed newSpeed) {
IanBenzMaxim 7:9cd16581b578 221 // Check if supported speed
IanBenzMaxim 7:9cd16581b578 222 if (!((newSpeed == OverdriveSpeed) || (newSpeed == StandardSpeed))) {
IanBenzMaxim 7:9cd16581b578 223 return make_error_code(InvalidSpeedError);
IanBenzMaxim 7:9cd16581b578 224 }
IanBenzMaxim 7:9cd16581b578 225 // Check if requested speed is already set
IanBenzMaxim 7:9cd16581b578 226 if (curConfig.get1WS() == (newSpeed == OverdriveSpeed)) {
IanBenzMaxim 7:9cd16581b578 227 return error_code();
IanBenzMaxim 7:9cd16581b578 228 }
IanBenzMaxim 7:9cd16581b578 229 // Set the speed
IanBenzMaxim 7:9cd16581b578 230 return writeConfig(Config(curConfig).set1WS(newSpeed == OverdriveSpeed));
IanBenzMaxim 7:9cd16581b578 231 }
IanBenzMaxim 7:9cd16581b578 232
IanBenzMaxim 7:9cd16581b578 233 error_code DS2465::triplet(TripletData & data) {
IanBenzMaxim 7:9cd16581b578 234 // 1-Wire Triplet (Case B)
IanBenzMaxim 7:9cd16581b578 235 // S AD,0 [A] 1WT [A] SS [A] Sr AD,1 [A] [Status] A [Status] A\ P
IanBenzMaxim 7:9cd16581b578 236 // \--------/
IanBenzMaxim 7:9cd16581b578 237 // Repeat until 1WB bit has changed to 0
IanBenzMaxim 7:9cd16581b578 238 // [] indicates from slave
IanBenzMaxim 7:9cd16581b578 239 // SS indicates byte containing search direction bit value in msbit
IanBenzMaxim 7:9cd16581b578 240
IanBenzMaxim 7:9cd16581b578 241 const uint_least8_t command[] = {
IanBenzMaxim 7:9cd16581b578 242 0x78, static_cast<uint_least8_t>(data.writeBit ? 0x80 : 0x00)};
IanBenzMaxim 7:9cd16581b578 243 error_code result = writeMemory(commandReg, command);
IanBenzMaxim 7:9cd16581b578 244 if (!result) {
IanBenzMaxim 7:9cd16581b578 245 uint_least8_t status;
IanBenzMaxim 7:9cd16581b578 246 result = pollBusy(&status);
IanBenzMaxim 7:9cd16581b578 247 if (!result) {
IanBenzMaxim 7:9cd16581b578 248 // check bit results in status byte
IanBenzMaxim 7:9cd16581b578 249 data.readBit = ((status & Status_SBR) == Status_SBR);
IanBenzMaxim 7:9cd16581b578 250 data.readBitComplement = ((status & Status_TSB) == Status_TSB);
IanBenzMaxim 7:9cd16581b578 251 data.writeBit = ((status & Status_DIR) == Status_DIR);
IanBenzMaxim 7:9cd16581b578 252 }
IanBenzMaxim 7:9cd16581b578 253 }
IanBenzMaxim 7:9cd16581b578 254 return result;
IanBenzMaxim 7:9cd16581b578 255 }
IanBenzMaxim 7:9cd16581b578 256
IanBenzMaxim 7:9cd16581b578 257 error_code DS2465::readBlock(span<uint_least8_t> recvBuf) {
IanBenzMaxim 7:9cd16581b578 258 // 1-Wire Receive Block (Case A)
IanBenzMaxim 7:9cd16581b578 259 // S AD,0 [A] CommandReg [A] 1WRF [A] PR [A] P
IanBenzMaxim 7:9cd16581b578 260 // [] indicates from slave
IanBenzMaxim 7:9cd16581b578 261 // PR indicates byte containing parameter
IanBenzMaxim 7:9cd16581b578 262
IanBenzMaxim 7:9cd16581b578 263 error_code result;
IanBenzMaxim 7:9cd16581b578 264 span<uint_least8_t>::index_type recvIdx = 0;
IanBenzMaxim 7:9cd16581b578 265 while (recvIdx < recvBuf.size() && !result) {
IanBenzMaxim 7:9cd16581b578 266 const uint_least8_t command[] = {
IanBenzMaxim 7:9cd16581b578 267 0xE1,
IanBenzMaxim 7:9cd16581b578 268 static_cast<uint_least8_t>(std::min<span<uint_least8_t>::index_type>(
IanBenzMaxim 7:9cd16581b578 269 recvBuf.size() - recvIdx, maxBlockSize))};
IanBenzMaxim 7:9cd16581b578 270 result = writeMemory(commandReg, command);
IanBenzMaxim 7:9cd16581b578 271 if (!result) {
IanBenzMaxim 7:9cd16581b578 272 result = pollBusy();
IanBenzMaxim 7:9cd16581b578 273 }
IanBenzMaxim 7:9cd16581b578 274 if (!result) {
IanBenzMaxim 7:9cd16581b578 275 result = readMemory(scratchpad, recvBuf.subspan(recvIdx, command[1]));
IanBenzMaxim 7:9cd16581b578 276 }
IanBenzMaxim 7:9cd16581b578 277 recvIdx += command[1];
IanBenzMaxim 7:9cd16581b578 278 }
IanBenzMaxim 7:9cd16581b578 279 return result;
IanBenzMaxim 7:9cd16581b578 280 }
IanBenzMaxim 7:9cd16581b578 281
IanBenzMaxim 7:9cd16581b578 282 error_code DS2465::writeBlock(span<const uint_least8_t> sendBuf) {
IanBenzMaxim 7:9cd16581b578 283 error_code result;
IanBenzMaxim 7:9cd16581b578 284 span<const uint_least8_t>::index_type sendIdx = 0;
IanBenzMaxim 7:9cd16581b578 285 while (sendIdx < sendBuf.size() && !result) {
IanBenzMaxim 7:9cd16581b578 286 const uint_least8_t command[] = {
IanBenzMaxim 7:9cd16581b578 287 owTransmitBlockCmd, static_cast<uint_least8_t>(
IanBenzMaxim 7:9cd16581b578 288 std::min<span<const uint_least8_t>::index_type>(
IanBenzMaxim 7:9cd16581b578 289 sendBuf.size() - sendIdx, maxBlockSize))};
IanBenzMaxim 7:9cd16581b578 290
IanBenzMaxim 7:9cd16581b578 291 // prefill scratchpad with required data
IanBenzMaxim 7:9cd16581b578 292 result = writeMemory(scratchpad, sendBuf.subspan(sendIdx, command[1]));
IanBenzMaxim 7:9cd16581b578 293
IanBenzMaxim 7:9cd16581b578 294 // 1-Wire Transmit Block (Case A)
IanBenzMaxim 7:9cd16581b578 295 // S AD,0 [A] CommandReg [A] 1WTB [A] PR [A] P
IanBenzMaxim 7:9cd16581b578 296 // [] indicates from slave
IanBenzMaxim 7:9cd16581b578 297 // PR indicates byte containing parameter
IanBenzMaxim 7:9cd16581b578 298 if (!result) {
IanBenzMaxim 7:9cd16581b578 299 result = writeMemory(commandReg, command);
IanBenzMaxim 7:9cd16581b578 300 }
IanBenzMaxim 7:9cd16581b578 301 if (!result) {
IanBenzMaxim 7:9cd16581b578 302 result = pollBusy();
IanBenzMaxim 7:9cd16581b578 303 }
IanBenzMaxim 7:9cd16581b578 304 sendIdx += command[1];
IanBenzMaxim 7:9cd16581b578 305 }
IanBenzMaxim 7:9cd16581b578 306 return result;
IanBenzMaxim 7:9cd16581b578 307 }
IanBenzMaxim 7:9cd16581b578 308
IanBenzMaxim 7:9cd16581b578 309 error_code DS2465::writeMacBlock() const {
IanBenzMaxim 7:9cd16581b578 310 // 1-Wire Transmit Block (Case A)
IanBenzMaxim 7:9cd16581b578 311 // S AD,0 [A] CommandReg [A] 1WTB [A] PR [A] P
IanBenzMaxim 7:9cd16581b578 312 // [] indicates from slave
IanBenzMaxim 7:9cd16581b578 313 // PR indicates byte containing parameter
IanBenzMaxim 7:9cd16581b578 314
IanBenzMaxim 7:9cd16581b578 315 const uint_least8_t command[] = {owTransmitBlockCmd, 0xFF};
IanBenzMaxim 7:9cd16581b578 316 error_code result = writeMemory(commandReg, command);
IanBenzMaxim 7:9cd16581b578 317 if (!result) {
IanBenzMaxim 7:9cd16581b578 318 result = pollBusy();
IanBenzMaxim 7:9cd16581b578 319 }
IanBenzMaxim 7:9cd16581b578 320 return result;
IanBenzMaxim 7:9cd16581b578 321 }
IanBenzMaxim 7:9cd16581b578 322
IanBenzMaxim 7:9cd16581b578 323 error_code DS2465::readByteSetLevel(uint_least8_t & recvByte,
IanBenzMaxim 7:9cd16581b578 324 Level afterLevel) {
IanBenzMaxim 7:9cd16581b578 325 // 1-Wire Read Bytes (Case C)
IanBenzMaxim 7:9cd16581b578 326 // S AD,0 [A] CommandReg [A] 1WRB [A] Sr AD,1 [A] [Status] A [Status] A
IanBenzMaxim 7:9cd16581b578 327 // \--------/
IanBenzMaxim 7:9cd16581b578 328 // Repeat until 1WB bit has changed to 0
IanBenzMaxim 7:9cd16581b578 329 // Sr AD,0 [A] SRP [A] E1 [A] Sr AD,1 [A] DD A\ P
IanBenzMaxim 7:9cd16581b578 330 //
IanBenzMaxim 7:9cd16581b578 331 // [] indicates from slave
IanBenzMaxim 7:9cd16581b578 332 // DD data read
IanBenzMaxim 7:9cd16581b578 333
IanBenzMaxim 7:9cd16581b578 334 error_code result = configureLevel(afterLevel);
IanBenzMaxim 7:9cd16581b578 335 if (result) {
IanBenzMaxim 7:9cd16581b578 336 return result;
IanBenzMaxim 7:9cd16581b578 337 }
IanBenzMaxim 7:9cd16581b578 338
IanBenzMaxim 7:9cd16581b578 339 const uint_least8_t command = 0x96;
IanBenzMaxim 7:9cd16581b578 340 result = writeMemory(commandReg, make_span(&command, 1));
IanBenzMaxim 7:9cd16581b578 341 if (result) {
IanBenzMaxim 7:9cd16581b578 342 return result;
IanBenzMaxim 7:9cd16581b578 343 }
IanBenzMaxim 7:9cd16581b578 344
IanBenzMaxim 7:9cd16581b578 345 result = pollBusy();
IanBenzMaxim 7:9cd16581b578 346 if (result) {
IanBenzMaxim 7:9cd16581b578 347 return result;
IanBenzMaxim 7:9cd16581b578 348 }
IanBenzMaxim 7:9cd16581b578 349
IanBenzMaxim 7:9cd16581b578 350 result = readMemory(0x62, make_span(&recvByte, 1));
IanBenzMaxim 7:9cd16581b578 351 return result;
IanBenzMaxim 7:9cd16581b578 352 }
IanBenzMaxim 7:9cd16581b578 353
IanBenzMaxim 7:9cd16581b578 354 error_code DS2465::writeByteSetLevel(uint_least8_t sendByte, Level afterLevel) {
IanBenzMaxim 7:9cd16581b578 355 // 1-Wire Write Byte (Case B)
IanBenzMaxim 7:9cd16581b578 356 // S AD,0 [A] CommandReg [A] 1WWB [A] DD [A] Sr AD,1 [A] [Status] A [Status]
IanBenzMaxim 7:9cd16581b578 357 // A\ P
IanBenzMaxim 7:9cd16581b578 358 // \--------/
IanBenzMaxim 7:9cd16581b578 359 // Repeat until 1WB bit has changed to 0
IanBenzMaxim 7:9cd16581b578 360 // [] indicates from slave
IanBenzMaxim 7:9cd16581b578 361 // DD data to write
IanBenzMaxim 7:9cd16581b578 362
IanBenzMaxim 7:9cd16581b578 363 error_code result = configureLevel(afterLevel);
IanBenzMaxim 7:9cd16581b578 364 if (result) {
IanBenzMaxim 7:9cd16581b578 365 return result;
IanBenzMaxim 7:9cd16581b578 366 }
IanBenzMaxim 7:9cd16581b578 367
IanBenzMaxim 7:9cd16581b578 368 const uint_least8_t command[] = {0xA5, sendByte};
IanBenzMaxim 7:9cd16581b578 369 result = writeMemory(commandReg, command);
IanBenzMaxim 7:9cd16581b578 370 if (result) {
IanBenzMaxim 7:9cd16581b578 371 return result;
IanBenzMaxim 7:9cd16581b578 372 }
IanBenzMaxim 7:9cd16581b578 373
IanBenzMaxim 7:9cd16581b578 374 result = pollBusy();
IanBenzMaxim 7:9cd16581b578 375 return result;
IanBenzMaxim 7:9cd16581b578 376 }
IanBenzMaxim 7:9cd16581b578 377
IanBenzMaxim 7:9cd16581b578 378 error_code DS2465::touchBitSetLevel(bool & sendRecvBit, Level afterLevel) {
IanBenzMaxim 7:9cd16581b578 379 // 1-Wire bit (Case B)
IanBenzMaxim 7:9cd16581b578 380 // S AD,0 [A] CommandReg [A] 1WSB [A] BB [A] Sr AD,1 [A] [Status] A [Status]
IanBenzMaxim 7:9cd16581b578 381 // A\ P
IanBenzMaxim 7:9cd16581b578 382 // \--------/
IanBenzMaxim 7:9cd16581b578 383 // Repeat until 1WB bit has changed to 0
IanBenzMaxim 7:9cd16581b578 384 // [] indicates from slave
IanBenzMaxim 7:9cd16581b578 385 // BB indicates byte containing bit value in msbit
IanBenzMaxim 7:9cd16581b578 386
IanBenzMaxim 7:9cd16581b578 387 error_code result = configureLevel(afterLevel);
IanBenzMaxim 7:9cd16581b578 388 if (result) {
IanBenzMaxim 7:9cd16581b578 389 return result;
IanBenzMaxim 7:9cd16581b578 390 }
IanBenzMaxim 7:9cd16581b578 391
IanBenzMaxim 7:9cd16581b578 392 const uint_least8_t command[] = {
IanBenzMaxim 7:9cd16581b578 393 0x87, static_cast<uint_least8_t>(sendRecvBit ? 0x80 : 0x00)};
IanBenzMaxim 7:9cd16581b578 394 result = writeMemory(commandReg, command);
IanBenzMaxim 7:9cd16581b578 395 if (result) {
IanBenzMaxim 7:9cd16581b578 396 return result;
IanBenzMaxim 7:9cd16581b578 397 }
IanBenzMaxim 7:9cd16581b578 398
IanBenzMaxim 7:9cd16581b578 399 uint_least8_t status;
IanBenzMaxim 7:9cd16581b578 400 result = pollBusy(&status);
IanBenzMaxim 7:9cd16581b578 401 if (!result) {
IanBenzMaxim 7:9cd16581b578 402 sendRecvBit = ((status & Status_SBR) == Status_SBR);
IanBenzMaxim 7:9cd16581b578 403 }
IanBenzMaxim 7:9cd16581b578 404 return result;
IanBenzMaxim 7:9cd16581b578 405 }
IanBenzMaxim 7:9cd16581b578 406
IanBenzMaxim 7:9cd16581b578 407 error_code DS2465::writeMemory(uint_least8_t addr,
IanBenzMaxim 7:9cd16581b578 408 span<const uint_least8_t> buf) const {
IanBenzMaxim 7:9cd16581b578 409 // Write SRAM (Case A)
IanBenzMaxim 7:9cd16581b578 410 // S AD,0 [A] VSA [A] DD [A] P
IanBenzMaxim 7:9cd16581b578 411 // \-----/
IanBenzMaxim 7:9cd16581b578 412 // Repeat for each data byte
IanBenzMaxim 7:9cd16581b578 413 // [] indicates from slave
IanBenzMaxim 7:9cd16581b578 414 // VSA valid SRAM memory address
IanBenzMaxim 7:9cd16581b578 415 // DD memory data to write
IanBenzMaxim 7:9cd16581b578 416
IanBenzMaxim 7:9cd16581b578 417 error_code result = master->start(address_);
IanBenzMaxim 7:9cd16581b578 418 if (result) {
IanBenzMaxim 7:9cd16581b578 419 master->stop();
IanBenzMaxim 7:9cd16581b578 420 return result;
IanBenzMaxim 7:9cd16581b578 421 }
IanBenzMaxim 7:9cd16581b578 422 result = master->writeByte(addr);
IanBenzMaxim 7:9cd16581b578 423 if (result) {
IanBenzMaxim 7:9cd16581b578 424 master->stop();
IanBenzMaxim 7:9cd16581b578 425 return result;
IanBenzMaxim 7:9cd16581b578 426 }
IanBenzMaxim 7:9cd16581b578 427 result = master->writeBlock(buf);
IanBenzMaxim 7:9cd16581b578 428 if (result) {
IanBenzMaxim 7:9cd16581b578 429 master->stop();
IanBenzMaxim 7:9cd16581b578 430 return result;
IanBenzMaxim 7:9cd16581b578 431 }
IanBenzMaxim 7:9cd16581b578 432 result = master->stop();
IanBenzMaxim 7:9cd16581b578 433 return result;
IanBenzMaxim 7:9cd16581b578 434 }
IanBenzMaxim 7:9cd16581b578 435
IanBenzMaxim 7:9cd16581b578 436 error_code DS2465::readMemory(uint_least8_t addr,
IanBenzMaxim 7:9cd16581b578 437 span<uint_least8_t> buf) const {
IanBenzMaxim 7:9cd16581b578 438 // Read (Case A)
IanBenzMaxim 7:9cd16581b578 439 // S AD,0 [A] MA [A] Sr AD,1 [A] [DD] A [DD] A\ P
IanBenzMaxim 7:9cd16581b578 440 // \-----/
IanBenzMaxim 7:9cd16581b578 441 // Repeat for each data byte, NAK last byte
IanBenzMaxim 7:9cd16581b578 442 // [] indicates from slave
IanBenzMaxim 7:9cd16581b578 443 // MA memory address
IanBenzMaxim 7:9cd16581b578 444 // DD memory data read
IanBenzMaxim 7:9cd16581b578 445
IanBenzMaxim 7:9cd16581b578 446 error_code result = master->start(address_);
IanBenzMaxim 7:9cd16581b578 447 if (result) {
IanBenzMaxim 7:9cd16581b578 448 master->stop();
IanBenzMaxim 7:9cd16581b578 449 return result;
IanBenzMaxim 7:9cd16581b578 450 }
IanBenzMaxim 7:9cd16581b578 451 result = master->writeByte(addr);
IanBenzMaxim 7:9cd16581b578 452 if (result) {
IanBenzMaxim 7:9cd16581b578 453 master->stop();
IanBenzMaxim 7:9cd16581b578 454 return result;
IanBenzMaxim 7:9cd16581b578 455 }
IanBenzMaxim 7:9cd16581b578 456 result = readMemory(buf);
IanBenzMaxim 7:9cd16581b578 457 return result;
IanBenzMaxim 7:9cd16581b578 458 }
IanBenzMaxim 7:9cd16581b578 459
IanBenzMaxim 7:9cd16581b578 460 error_code DS2465::readMemory(span<uint_least8_t> buf) const {
IanBenzMaxim 7:9cd16581b578 461 error_code result = master->start(address_ | 1);
IanBenzMaxim 7:9cd16581b578 462 if (result) {
IanBenzMaxim 7:9cd16581b578 463 master->stop();
IanBenzMaxim 7:9cd16581b578 464 return result;
IanBenzMaxim 7:9cd16581b578 465 }
IanBenzMaxim 7:9cd16581b578 466 result = master->readBlock(I2CMaster::Nack, buf);
IanBenzMaxim 7:9cd16581b578 467 if (result) {
IanBenzMaxim 7:9cd16581b578 468 master->stop();
IanBenzMaxim 7:9cd16581b578 469 return result;
IanBenzMaxim 7:9cd16581b578 470 }
IanBenzMaxim 7:9cd16581b578 471 result = master->stop();
IanBenzMaxim 7:9cd16581b578 472 return result;
IanBenzMaxim 7:9cd16581b578 473 }
IanBenzMaxim 7:9cd16581b578 474
IanBenzMaxim 7:9cd16581b578 475 error_code DS2465::writeConfig(Config config) {
IanBenzMaxim 7:9cd16581b578 476 const uint_least8_t configReg = 0x67;
IanBenzMaxim 7:9cd16581b578 477 uint_least8_t configBuf =
IanBenzMaxim 7:9cd16581b578 478 ((config.readByte() ^ 0xF) << 4) | config.readByte();
IanBenzMaxim 7:9cd16581b578 479 error_code result = writeMemory(configReg, make_span(&configBuf, 1));
IanBenzMaxim 7:9cd16581b578 480 if (!result) {
IanBenzMaxim 7:9cd16581b578 481 result = readMemory(configReg, make_span(&configBuf, 1));
IanBenzMaxim 7:9cd16581b578 482 }
IanBenzMaxim 7:9cd16581b578 483 if (!result) {
IanBenzMaxim 7:9cd16581b578 484 if (configBuf != config.readByte())
IanBenzMaxim 7:9cd16581b578 485 result = make_error_code(HardwareError);
IanBenzMaxim 7:9cd16581b578 486 }
IanBenzMaxim 7:9cd16581b578 487 if (!result) {
IanBenzMaxim 7:9cd16581b578 488 curConfig = config;
IanBenzMaxim 7:9cd16581b578 489 }
IanBenzMaxim 7:9cd16581b578 490 return result;
IanBenzMaxim 7:9cd16581b578 491 }
IanBenzMaxim 7:9cd16581b578 492
IanBenzMaxim 7:9cd16581b578 493 error_code DS2465::writePortParameter(PortParameter param, int val) {
IanBenzMaxim 7:9cd16581b578 494 if (val < 0 || val > 15) {
IanBenzMaxim 7:9cd16581b578 495 return make_error_code(ArgumentOutOfRangeError);
IanBenzMaxim 7:9cd16581b578 496 }
IanBenzMaxim 7:9cd16581b578 497
IanBenzMaxim 7:9cd16581b578 498 uint_least8_t addr = 0;
IanBenzMaxim 7:9cd16581b578 499 switch (param) {
IanBenzMaxim 7:9cd16581b578 500 case tRSTL_STD:
IanBenzMaxim 7:9cd16581b578 501 case tRSTL_OD:
IanBenzMaxim 7:9cd16581b578 502 addr = 0x68;
IanBenzMaxim 7:9cd16581b578 503 break;
IanBenzMaxim 7:9cd16581b578 504 case tMSP_STD:
IanBenzMaxim 7:9cd16581b578 505 case tMSP_OD:
IanBenzMaxim 7:9cd16581b578 506 addr = 0x69;
IanBenzMaxim 7:9cd16581b578 507 break;
IanBenzMaxim 7:9cd16581b578 508 case tW0L_STD:
IanBenzMaxim 7:9cd16581b578 509 case tW0L_OD:
IanBenzMaxim 7:9cd16581b578 510 addr = 0x6A;
IanBenzMaxim 7:9cd16581b578 511 break;
IanBenzMaxim 7:9cd16581b578 512 case tREC0:
IanBenzMaxim 7:9cd16581b578 513 addr = 0x6B;
IanBenzMaxim 7:9cd16581b578 514 break;
IanBenzMaxim 7:9cd16581b578 515 case RWPU:
IanBenzMaxim 7:9cd16581b578 516 addr = 0x6C;
IanBenzMaxim 7:9cd16581b578 517 break;
IanBenzMaxim 7:9cd16581b578 518 case tW1L_OD:
IanBenzMaxim 7:9cd16581b578 519 addr = 0x6D;
IanBenzMaxim 7:9cd16581b578 520 break;
IanBenzMaxim 7:9cd16581b578 521 }
IanBenzMaxim 7:9cd16581b578 522
IanBenzMaxim 7:9cd16581b578 523 uint_least8_t data;
IanBenzMaxim 7:9cd16581b578 524 error_code result = readMemory(addr, make_span(&data, 1));
IanBenzMaxim 7:9cd16581b578 525 if (result) {
IanBenzMaxim 7:9cd16581b578 526 return result;
IanBenzMaxim 7:9cd16581b578 527 }
IanBenzMaxim 7:9cd16581b578 528
IanBenzMaxim 7:9cd16581b578 529 uint_least8_t newData;
IanBenzMaxim 7:9cd16581b578 530 if (param == tRSTL_OD || param == tMSP_OD || param == tW0L_OD) {
IanBenzMaxim 7:9cd16581b578 531 newData = (data & 0x0F) | (val << 4);
IanBenzMaxim 7:9cd16581b578 532 } else {
IanBenzMaxim 7:9cd16581b578 533 newData = (data & 0xF0) | val;
IanBenzMaxim 7:9cd16581b578 534 }
IanBenzMaxim 7:9cd16581b578 535
IanBenzMaxim 7:9cd16581b578 536 if (newData != data) {
IanBenzMaxim 7:9cd16581b578 537 result = writeMemory(addr, make_span(&newData, 1));
IanBenzMaxim 7:9cd16581b578 538 }
IanBenzMaxim 7:9cd16581b578 539 return result;
IanBenzMaxim 7:9cd16581b578 540 }
IanBenzMaxim 7:9cd16581b578 541
IanBenzMaxim 7:9cd16581b578 542 error_code DS2465::pollBusy(uint_least8_t * pStatus) const {
IanBenzMaxim 7:9cd16581b578 543 const int pollLimit = 200;
IanBenzMaxim 7:9cd16581b578 544
IanBenzMaxim 7:9cd16581b578 545 int pollCount = 0;
IanBenzMaxim 7:9cd16581b578 546 uint_least8_t status;
IanBenzMaxim 7:9cd16581b578 547 do {
IanBenzMaxim 7:9cd16581b578 548 error_code result = readMemory(make_span(&status, 1));
IanBenzMaxim 7:9cd16581b578 549 if (result) {
IanBenzMaxim 7:9cd16581b578 550 return result;
IanBenzMaxim 7:9cd16581b578 551 }
IanBenzMaxim 7:9cd16581b578 552 if (pStatus != NULL) {
IanBenzMaxim 7:9cd16581b578 553 *pStatus = status;
IanBenzMaxim 7:9cd16581b578 554 }
IanBenzMaxim 7:9cd16581b578 555 if (pollCount++ >= pollLimit) {
IanBenzMaxim 7:9cd16581b578 556 return make_error_code(HardwareError);
IanBenzMaxim 7:9cd16581b578 557 }
IanBenzMaxim 7:9cd16581b578 558 } while (status & Status_1WB);
IanBenzMaxim 7:9cd16581b578 559
IanBenzMaxim 7:9cd16581b578 560 return error_code();
IanBenzMaxim 7:9cd16581b578 561 }
IanBenzMaxim 7:9cd16581b578 562
IanBenzMaxim 7:9cd16581b578 563 error_code DS2465::reset() {
IanBenzMaxim 7:9cd16581b578 564 // 1-Wire reset (Case B)
IanBenzMaxim 7:9cd16581b578 565 // S AD,0 [A] CommandReg [A] 1WRS [A] Sr AD,1 [A] [Status] A [Status] A\ P
IanBenzMaxim 7:9cd16581b578 566 // \--------/
IanBenzMaxim 7:9cd16581b578 567 // Repeat until 1WB bit has changed to 0
IanBenzMaxim 7:9cd16581b578 568 // [] indicates from slave
IanBenzMaxim 7:9cd16581b578 569
IanBenzMaxim 7:9cd16581b578 570 uint_least8_t buf = 0xB4;
IanBenzMaxim 7:9cd16581b578 571 error_code result = writeMemory(commandReg, make_span(&buf, 1));
IanBenzMaxim 7:9cd16581b578 572
IanBenzMaxim 7:9cd16581b578 573 if (!result) {
IanBenzMaxim 7:9cd16581b578 574 result = pollBusy(&buf);
IanBenzMaxim 7:9cd16581b578 575 }
IanBenzMaxim 7:9cd16581b578 576
IanBenzMaxim 7:9cd16581b578 577 if (!result) {
IanBenzMaxim 7:9cd16581b578 578 if ((buf & Status_SD) == Status_SD) {
IanBenzMaxim 7:9cd16581b578 579 result = make_error_code(ShortDetectedError);
IanBenzMaxim 7:9cd16581b578 580 } else if ((buf & Status_PPD) != Status_PPD) {
IanBenzMaxim 7:9cd16581b578 581 result = make_error_code(NoSlaveError);
IanBenzMaxim 7:9cd16581b578 582 }
IanBenzMaxim 7:9cd16581b578 583 }
IanBenzMaxim 7:9cd16581b578 584
IanBenzMaxim 7:9cd16581b578 585 return result;
IanBenzMaxim 7:9cd16581b578 586 }
IanBenzMaxim 7:9cd16581b578 587
IanBenzMaxim 7:9cd16581b578 588 error_code DS2465::resetDevice() {
IanBenzMaxim 7:9cd16581b578 589 // Device Reset
IanBenzMaxim 7:9cd16581b578 590 // S AD,0 [A] CommandReg [A] 1WMR [A] Sr AD,1 [A] [SS] A\ P
IanBenzMaxim 7:9cd16581b578 591 // [] indicates from slave
IanBenzMaxim 7:9cd16581b578 592 // SS status byte to read to verify state
IanBenzMaxim 7:9cd16581b578 593
IanBenzMaxim 7:9cd16581b578 594 uint_least8_t buf = 0xF0;
IanBenzMaxim 7:9cd16581b578 595 error_code result = writeMemory(commandReg, make_span(&buf, 1));
IanBenzMaxim 7:9cd16581b578 596
IanBenzMaxim 7:9cd16581b578 597 if (!result) {
IanBenzMaxim 7:9cd16581b578 598 result = readMemory(make_span(&buf, 1));
IanBenzMaxim 7:9cd16581b578 599 }
IanBenzMaxim 7:9cd16581b578 600
IanBenzMaxim 7:9cd16581b578 601 if (!result) {
IanBenzMaxim 7:9cd16581b578 602 if ((buf & 0xF7) != 0x10) {
IanBenzMaxim 7:9cd16581b578 603 result = make_error_code(HardwareError);
IanBenzMaxim 7:9cd16581b578 604 }
IanBenzMaxim 7:9cd16581b578 605 }
IanBenzMaxim 7:9cd16581b578 606
IanBenzMaxim 7:9cd16581b578 607 if (!result) {
IanBenzMaxim 7:9cd16581b578 608 reset(); // do a command to get 1-Wire master reset out of holding state
IanBenzMaxim 7:9cd16581b578 609 }
IanBenzMaxim 7:9cd16581b578 610
IanBenzMaxim 7:9cd16581b578 611 return result;
IanBenzMaxim 7:9cd16581b578 612 }
IanBenzMaxim 7:9cd16581b578 613
IanBenzMaxim 7:9cd16581b578 614 error_code
IanBenzMaxim 7:9cd16581b578 615 DS2465::computeNextMasterSecret(AuthenticationData::const_span data) {
IanBenzMaxim 7:9cd16581b578 616 error_code result = writeMemory(scratchpad, data);
IanBenzMaxim 7:9cd16581b578 617 if (!result) {
IanBenzMaxim 7:9cd16581b578 618 result = computeNextMasterSecret(false, 0, FullPage);
IanBenzMaxim 7:9cd16581b578 619 }
IanBenzMaxim 7:9cd16581b578 620 return result;
IanBenzMaxim 7:9cd16581b578 621 }
IanBenzMaxim 7:9cd16581b578 622
IanBenzMaxim 7:9cd16581b578 623 error_code
IanBenzMaxim 7:9cd16581b578 624 DS2465::computeNextMasterSecretWithSwap(AuthenticationData::const_span data,
IanBenzMaxim 7:9cd16581b578 625 int pageNum, PageRegion region) {
IanBenzMaxim 7:9cd16581b578 626 error_code result = writeMemory(scratchpad, data);
IanBenzMaxim 7:9cd16581b578 627 if (!result) {
IanBenzMaxim 7:9cd16581b578 628 result = computeNextMasterSecret(true, pageNum, region);
IanBenzMaxim 7:9cd16581b578 629 }
IanBenzMaxim 7:9cd16581b578 630 return result;
IanBenzMaxim 7:9cd16581b578 631 }
IanBenzMaxim 7:9cd16581b578 632
IanBenzMaxim 7:9cd16581b578 633 error_code DS2465::computeWriteMac(WriteMacData::const_span data) const {
IanBenzMaxim 7:9cd16581b578 634 error_code result = writeMemory(scratchpad, data);
IanBenzMaxim 7:9cd16581b578 635 if (!result) {
IanBenzMaxim 7:9cd16581b578 636 result = computeWriteMac(false, false, 0, 0);
IanBenzMaxim 7:9cd16581b578 637 }
IanBenzMaxim 7:9cd16581b578 638 return result;
IanBenzMaxim 7:9cd16581b578 639 }
IanBenzMaxim 7:9cd16581b578 640
IanBenzMaxim 7:9cd16581b578 641 error_code DS2465::computeWriteMac(WriteMacData::const_span data,
IanBenzMaxim 7:9cd16581b578 642 Page::span mac) const {
IanBenzMaxim 7:9cd16581b578 643 error_code result = computeWriteMac(data);
IanBenzMaxim 7:9cd16581b578 644 if (!result) {
IanBenzMaxim 7:9cd16581b578 645 result = readMemory(mac);
IanBenzMaxim 7:9cd16581b578 646 }
IanBenzMaxim 7:9cd16581b578 647 return result;
IanBenzMaxim 7:9cd16581b578 648 }
IanBenzMaxim 7:9cd16581b578 649
IanBenzMaxim 7:9cd16581b578 650 error_code
IanBenzMaxim 7:9cd16581b578 651 DS2465::computeAndTransmitWriteMac(WriteMacData::const_span data) const {
IanBenzMaxim 7:9cd16581b578 652 error_code result = computeWriteMac(data);
IanBenzMaxim 7:9cd16581b578 653 if (!result) {
IanBenzMaxim 7:9cd16581b578 654 result = writeMacBlock();
IanBenzMaxim 7:9cd16581b578 655 }
IanBenzMaxim 7:9cd16581b578 656 return result;
IanBenzMaxim 7:9cd16581b578 657 }
IanBenzMaxim 7:9cd16581b578 658
IanBenzMaxim 7:9cd16581b578 659 error_code DS2465::computeWriteMacWithSwap(WriteMacData::const_span data,
IanBenzMaxim 7:9cd16581b578 660 int pageNum, int segmentNum) const {
IanBenzMaxim 7:9cd16581b578 661 error_code result = writeMemory(scratchpad, data);
IanBenzMaxim 7:9cd16581b578 662 if (!result) {
IanBenzMaxim 7:9cd16581b578 663 result = computeWriteMac(false, true, pageNum, segmentNum);
IanBenzMaxim 7:9cd16581b578 664 }
IanBenzMaxim 7:9cd16581b578 665 return result;
IanBenzMaxim 7:9cd16581b578 666 }
IanBenzMaxim 7:9cd16581b578 667
IanBenzMaxim 7:9cd16581b578 668 error_code DS2465::computeWriteMacWithSwap(WriteMacData::const_span data,
IanBenzMaxim 7:9cd16581b578 669 int pageNum, int segmentNum,
IanBenzMaxim 7:9cd16581b578 670 Page::span mac) const {
IanBenzMaxim 7:9cd16581b578 671 error_code result = computeWriteMacWithSwap(data, pageNum, segmentNum);
IanBenzMaxim 7:9cd16581b578 672 if (!result) {
IanBenzMaxim 7:9cd16581b578 673 result = readMemory(mac);
IanBenzMaxim 7:9cd16581b578 674 }
IanBenzMaxim 7:9cd16581b578 675 return result;
IanBenzMaxim 7:9cd16581b578 676 }
IanBenzMaxim 7:9cd16581b578 677
IanBenzMaxim 7:9cd16581b578 678 error_code
IanBenzMaxim 7:9cd16581b578 679 DS2465::computeAndTransmitWriteMacWithSwap(WriteMacData::const_span data,
IanBenzMaxim 7:9cd16581b578 680 int pageNum, int segmentNum) const {
IanBenzMaxim 7:9cd16581b578 681 error_code result = computeWriteMacWithSwap(data, pageNum, segmentNum);
IanBenzMaxim 7:9cd16581b578 682 if (!result) {
IanBenzMaxim 7:9cd16581b578 683 result = writeMacBlock();
IanBenzMaxim 7:9cd16581b578 684 }
IanBenzMaxim 7:9cd16581b578 685 return result;
IanBenzMaxim 7:9cd16581b578 686 }
IanBenzMaxim 7:9cd16581b578 687
IanBenzMaxim 7:9cd16581b578 688 error_code DS2465::computeSlaveSecret(AuthenticationData::const_span data) {
IanBenzMaxim 7:9cd16581b578 689 error_code result = writeMemory(scratchpad, data);
IanBenzMaxim 7:9cd16581b578 690 if (!result) {
IanBenzMaxim 7:9cd16581b578 691 result = computeSlaveSecret(false, 0, FullPage);
IanBenzMaxim 7:9cd16581b578 692 }
IanBenzMaxim 7:9cd16581b578 693 return result;
IanBenzMaxim 7:9cd16581b578 694 }
IanBenzMaxim 7:9cd16581b578 695
IanBenzMaxim 7:9cd16581b578 696 error_code
IanBenzMaxim 7:9cd16581b578 697 DS2465::computeSlaveSecretWithSwap(AuthenticationData::const_span data,
IanBenzMaxim 7:9cd16581b578 698 int pageNum, PageRegion region) {
IanBenzMaxim 7:9cd16581b578 699 error_code result = writeMemory(scratchpad, data);
IanBenzMaxim 7:9cd16581b578 700 if (!result) {
IanBenzMaxim 7:9cd16581b578 701 result = computeSlaveSecret(true, pageNum, region);
IanBenzMaxim 7:9cd16581b578 702 }
IanBenzMaxim 7:9cd16581b578 703 return result;
IanBenzMaxim 7:9cd16581b578 704 }
IanBenzMaxim 7:9cd16581b578 705
IanBenzMaxim 7:9cd16581b578 706 error_code DS2465::computeAuthMac(AuthenticationData::const_span data) const {
IanBenzMaxim 7:9cd16581b578 707 error_code result = writeMemory(scratchpad, data);
IanBenzMaxim 7:9cd16581b578 708 if (!result) {
IanBenzMaxim 7:9cd16581b578 709 result = computeAuthMac(false, 0, FullPage);
IanBenzMaxim 7:9cd16581b578 710 }
IanBenzMaxim 7:9cd16581b578 711 return result;
IanBenzMaxim 7:9cd16581b578 712 }
IanBenzMaxim 7:9cd16581b578 713
IanBenzMaxim 7:9cd16581b578 714 error_code DS2465::computeAuthMac(AuthenticationData::const_span data,
IanBenzMaxim 7:9cd16581b578 715 Page::span mac) const {
IanBenzMaxim 7:9cd16581b578 716 error_code result = computeAuthMac(data);
IanBenzMaxim 7:9cd16581b578 717 if (!result) {
IanBenzMaxim 7:9cd16581b578 718 result = readMemory(mac);
IanBenzMaxim 7:9cd16581b578 719 }
IanBenzMaxim 7:9cd16581b578 720 return result;
IanBenzMaxim 7:9cd16581b578 721 }
IanBenzMaxim 7:9cd16581b578 722
IanBenzMaxim 7:9cd16581b578 723 error_code
IanBenzMaxim 7:9cd16581b578 724 DS2465::computeAndTransmitAuthMac(AuthenticationData::const_span data) const {
IanBenzMaxim 7:9cd16581b578 725 error_code result = computeAuthMac(data);
IanBenzMaxim 7:9cd16581b578 726 if (!result) {
IanBenzMaxim 7:9cd16581b578 727 result = writeMacBlock();
IanBenzMaxim 7:9cd16581b578 728 }
IanBenzMaxim 7:9cd16581b578 729 return result;
IanBenzMaxim 7:9cd16581b578 730 }
IanBenzMaxim 7:9cd16581b578 731
IanBenzMaxim 7:9cd16581b578 732 error_code DS2465::computeAuthMacWithSwap(AuthenticationData::const_span data,
IanBenzMaxim 7:9cd16581b578 733 int pageNum,
IanBenzMaxim 7:9cd16581b578 734 PageRegion region) const {
IanBenzMaxim 7:9cd16581b578 735 error_code result = writeMemory(scratchpad, data);
IanBenzMaxim 7:9cd16581b578 736 if (!result) {
IanBenzMaxim 7:9cd16581b578 737 result = computeAuthMac(true, pageNum, region);
IanBenzMaxim 7:9cd16581b578 738 }
IanBenzMaxim 7:9cd16581b578 739 return result;
IanBenzMaxim 7:9cd16581b578 740 }
IanBenzMaxim 7:9cd16581b578 741
IanBenzMaxim 7:9cd16581b578 742 error_code DS2465::computeAuthMacWithSwap(AuthenticationData::const_span data,
IanBenzMaxim 7:9cd16581b578 743 int pageNum, PageRegion region,
IanBenzMaxim 7:9cd16581b578 744 Page::span mac) const {
IanBenzMaxim 7:9cd16581b578 745 error_code result = computeAuthMacWithSwap(data, pageNum, region);
IanBenzMaxim 7:9cd16581b578 746 if (!result) {
IanBenzMaxim 7:9cd16581b578 747 result = readMemory(mac);
IanBenzMaxim 7:9cd16581b578 748 }
IanBenzMaxim 7:9cd16581b578 749 return result;
IanBenzMaxim 7:9cd16581b578 750 }
IanBenzMaxim 7:9cd16581b578 751
IanBenzMaxim 7:9cd16581b578 752 error_code DS2465::computeAndTransmitAuthMacWithSwap(
IanBenzMaxim 7:9cd16581b578 753 AuthenticationData::const_span data, int pageNum, PageRegion region) const {
IanBenzMaxim 7:9cd16581b578 754 error_code result = computeAuthMacWithSwap(data, pageNum, region);
IanBenzMaxim 7:9cd16581b578 755 if (!result) {
IanBenzMaxim 7:9cd16581b578 756 result = writeMacBlock();
IanBenzMaxim 7:9cd16581b578 757 }
IanBenzMaxim 7:9cd16581b578 758 return result;
IanBenzMaxim 7:9cd16581b578 759 }
IanBenzMaxim 7:9cd16581b578 760
IanBenzMaxim 7:9cd16581b578 761 const error_category & DS2465::errorCategory() {
IanBenzMaxim 7:9cd16581b578 762 static class : public error_category {
IanBenzMaxim 7:9cd16581b578 763 public:
IanBenzMaxim 7:9cd16581b578 764 virtual const char * name() const { return "DS2465"; }
IanBenzMaxim 7:9cd16581b578 765
IanBenzMaxim 7:9cd16581b578 766 virtual std::string message(int condition) const {
IanBenzMaxim 7:9cd16581b578 767 switch (condition) {
IanBenzMaxim 7:9cd16581b578 768 case HardwareError:
IanBenzMaxim 7:9cd16581b578 769 return "Hardware Error";
IanBenzMaxim 7:9cd16581b578 770
IanBenzMaxim 7:9cd16581b578 771 case ArgumentOutOfRangeError:
IanBenzMaxim 7:9cd16581b578 772 return "Argument Out of Range Error";
IanBenzMaxim 7:9cd16581b578 773
IanBenzMaxim 7:9cd16581b578 774 default:
IanBenzMaxim 7:9cd16581b578 775 return defaultErrorMessage(condition);
IanBenzMaxim 7:9cd16581b578 776 }
IanBenzMaxim 7:9cd16581b578 777 }
IanBenzMaxim 7:9cd16581b578 778 } instance;
IanBenzMaxim 7:9cd16581b578 779 return instance;
IanBenzMaxim 7:9cd16581b578 780 }
IanBenzMaxim 7:9cd16581b578 781
IanBenzMaxim 7:9cd16581b578 782 } // namespace MaximInterfaceDevices