Extended MaximInterface

Dependents:   mbed_DS28EC20_GPIO

Committer:
reARMnimator
Date:
Mon Jan 06 15:54:55 2020 +0000
Revision:
10:de4b8812877d
Parent:
7:471901a04573
Fixed inappropriate include path.

Who changed what in which revision?

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