Extended MaximInterface

Dependents:   mbed_DS28EC20_GPIO

Committer:
IanBenzMaxim
Date:
Wed Jan 23 13:11:04 2019 -0600
Revision:
6:a8c83a2e6fa4
Parent:
0:f77ad7f72d04
Child:
7:471901a04573
Updated to version 1.6 and removed platform files that are incompatible with mbed.

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 0:f77ad7f72d04 209 Config newConfig = curConfig;
IanBenzMaxim 0:f77ad7f72d04 210 newConfig.setSPU(level == StrongLevel);
IanBenzMaxim 0:f77ad7f72d04 211 return writeConfig(newConfig);
IanBenzMaxim 0:f77ad7f72d04 212 }
IanBenzMaxim 0:f77ad7f72d04 213
IanBenzMaxim 0:f77ad7f72d04 214 error_code DS2465::setLevel(Level newLevel) {
IanBenzMaxim 0:f77ad7f72d04 215 if (newLevel == StrongLevel) {
IanBenzMaxim 0:f77ad7f72d04 216 return make_error_code(InvalidLevelError);
IanBenzMaxim 0:f77ad7f72d04 217 }
IanBenzMaxim 0:f77ad7f72d04 218
IanBenzMaxim 0:f77ad7f72d04 219 return configureLevel(newLevel);
IanBenzMaxim 0:f77ad7f72d04 220 }
IanBenzMaxim 0:f77ad7f72d04 221
IanBenzMaxim 0:f77ad7f72d04 222 error_code DS2465::setSpeed(Speed newSpeed) {
IanBenzMaxim 0:f77ad7f72d04 223 // Check if supported speed
IanBenzMaxim 0:f77ad7f72d04 224 if (!((newSpeed == OverdriveSpeed) || (newSpeed == StandardSpeed))) {
IanBenzMaxim 0:f77ad7f72d04 225 return make_error_code(InvalidSpeedError);
IanBenzMaxim 0:f77ad7f72d04 226 }
IanBenzMaxim 0:f77ad7f72d04 227 // Check if requested speed is already set
IanBenzMaxim 0:f77ad7f72d04 228 if (curConfig.get1WS() == (newSpeed == OverdriveSpeed)) {
IanBenzMaxim 0:f77ad7f72d04 229 return error_code();
IanBenzMaxim 0:f77ad7f72d04 230 }
IanBenzMaxim 0:f77ad7f72d04 231 // Set the speed
IanBenzMaxim 0:f77ad7f72d04 232 Config newConfig = curConfig;
IanBenzMaxim 0:f77ad7f72d04 233 newConfig.set1WS(newSpeed == OverdriveSpeed);
IanBenzMaxim 0:f77ad7f72d04 234 return writeConfig(newConfig);
IanBenzMaxim 0:f77ad7f72d04 235 }
IanBenzMaxim 0:f77ad7f72d04 236
IanBenzMaxim 0:f77ad7f72d04 237 error_code DS2465::triplet(TripletData & data) {
IanBenzMaxim 0:f77ad7f72d04 238 // 1-Wire Triplet (Case B)
IanBenzMaxim 0:f77ad7f72d04 239 // S AD,0 [A] 1WT [A] SS [A] Sr AD,1 [A] [Status] A [Status] A\ P
IanBenzMaxim 0:f77ad7f72d04 240 // \--------/
IanBenzMaxim 0:f77ad7f72d04 241 // Repeat until 1WB bit has changed to 0
IanBenzMaxim 0:f77ad7f72d04 242 // [] indicates from slave
IanBenzMaxim 0:f77ad7f72d04 243 // SS indicates byte containing search direction bit value in msbit
IanBenzMaxim 0:f77ad7f72d04 244
IanBenzMaxim 0:f77ad7f72d04 245 const uint_least8_t command[] = {
IanBenzMaxim 6:a8c83a2e6fa4 246 0x78, static_cast<uint_least8_t>(data.writeBit ? 0x80 : 0x00)};
IanBenzMaxim 6:a8c83a2e6fa4 247 error_code result = writeMemory(commandReg, command);
IanBenzMaxim 0:f77ad7f72d04 248 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 249 uint_least8_t status;
IanBenzMaxim 0:f77ad7f72d04 250 result = pollBusy(&status);
IanBenzMaxim 0:f77ad7f72d04 251 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 252 // check bit results in status byte
IanBenzMaxim 0:f77ad7f72d04 253 data.readBit = ((status & Status_SBR) == Status_SBR);
IanBenzMaxim 0:f77ad7f72d04 254 data.readBitComplement = ((status & Status_TSB) == Status_TSB);
IanBenzMaxim 0:f77ad7f72d04 255 data.writeBit = ((status & Status_DIR) == Status_DIR);
IanBenzMaxim 0:f77ad7f72d04 256 }
IanBenzMaxim 0:f77ad7f72d04 257 }
IanBenzMaxim 0:f77ad7f72d04 258 return result;
IanBenzMaxim 0:f77ad7f72d04 259 }
IanBenzMaxim 0:f77ad7f72d04 260
IanBenzMaxim 6:a8c83a2e6fa4 261 error_code DS2465::readBlock(span<uint_least8_t> recvBuf) {
IanBenzMaxim 0:f77ad7f72d04 262 // 1-Wire Receive Block (Case A)
IanBenzMaxim 0:f77ad7f72d04 263 // S AD,0 [A] CommandReg [A] 1WRF [A] PR [A] P
IanBenzMaxim 0:f77ad7f72d04 264 // [] indicates from slave
IanBenzMaxim 0:f77ad7f72d04 265 // PR indicates byte containing parameter
IanBenzMaxim 0:f77ad7f72d04 266
IanBenzMaxim 0:f77ad7f72d04 267 error_code result;
IanBenzMaxim 6:a8c83a2e6fa4 268 span<uint_least8_t>::index_type recvIdx = 0;
IanBenzMaxim 6:a8c83a2e6fa4 269 while (recvIdx < recvBuf.size() && !result) {
IanBenzMaxim 0:f77ad7f72d04 270 const uint_least8_t command[] = {
IanBenzMaxim 6:a8c83a2e6fa4 271 0xE1,
IanBenzMaxim 6:a8c83a2e6fa4 272 static_cast<uint_least8_t>(std::min<span<uint_least8_t>::index_type>(
IanBenzMaxim 6:a8c83a2e6fa4 273 recvBuf.size() - recvIdx, maxBlockSize))};
IanBenzMaxim 6:a8c83a2e6fa4 274 result = writeMemory(commandReg, command);
IanBenzMaxim 0:f77ad7f72d04 275 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 276 result = pollBusy();
IanBenzMaxim 0:f77ad7f72d04 277 }
IanBenzMaxim 0:f77ad7f72d04 278 if (!result) {
IanBenzMaxim 6:a8c83a2e6fa4 279 result = readMemory(scratchpad, recvBuf.subspan(recvIdx, command[1]));
IanBenzMaxim 0:f77ad7f72d04 280 }
IanBenzMaxim 6:a8c83a2e6fa4 281 recvIdx += command[1];
IanBenzMaxim 0:f77ad7f72d04 282 }
IanBenzMaxim 0:f77ad7f72d04 283 return result;
IanBenzMaxim 0:f77ad7f72d04 284 }
IanBenzMaxim 0:f77ad7f72d04 285
IanBenzMaxim 6:a8c83a2e6fa4 286 error_code DS2465::writeBlock(span<const uint_least8_t> sendBuf) {
IanBenzMaxim 0:f77ad7f72d04 287 error_code result;
IanBenzMaxim 6:a8c83a2e6fa4 288 span<const uint_least8_t>::index_type sendIdx = 0;
IanBenzMaxim 6:a8c83a2e6fa4 289 while (sendIdx < sendBuf.size() && !result) {
IanBenzMaxim 0:f77ad7f72d04 290 const uint_least8_t command[] = {
IanBenzMaxim 6:a8c83a2e6fa4 291 owTransmitBlockCmd, static_cast<uint_least8_t>(
IanBenzMaxim 6:a8c83a2e6fa4 292 std::min<span<const uint_least8_t>::index_type>(
IanBenzMaxim 6:a8c83a2e6fa4 293 sendBuf.size() - sendIdx, maxBlockSize))};
IanBenzMaxim 0:f77ad7f72d04 294
IanBenzMaxim 0:f77ad7f72d04 295 // prefill scratchpad with required data
IanBenzMaxim 6:a8c83a2e6fa4 296 result = writeMemory(scratchpad, sendBuf.subspan(sendIdx, command[1]));
IanBenzMaxim 0:f77ad7f72d04 297
IanBenzMaxim 0:f77ad7f72d04 298 // 1-Wire Transmit Block (Case A)
IanBenzMaxim 0:f77ad7f72d04 299 // S AD,0 [A] CommandReg [A] 1WTB [A] PR [A] P
IanBenzMaxim 0:f77ad7f72d04 300 // [] indicates from slave
IanBenzMaxim 0:f77ad7f72d04 301 // PR indicates byte containing parameter
IanBenzMaxim 0:f77ad7f72d04 302 if (!result) {
IanBenzMaxim 6:a8c83a2e6fa4 303 result = writeMemory(commandReg, command);
IanBenzMaxim 0:f77ad7f72d04 304 }
IanBenzMaxim 0:f77ad7f72d04 305 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 306 result = pollBusy();
IanBenzMaxim 0:f77ad7f72d04 307 }
IanBenzMaxim 6:a8c83a2e6fa4 308 sendIdx += command[1];
IanBenzMaxim 0:f77ad7f72d04 309 }
IanBenzMaxim 0:f77ad7f72d04 310 return result;
IanBenzMaxim 0:f77ad7f72d04 311 }
IanBenzMaxim 0:f77ad7f72d04 312
IanBenzMaxim 0:f77ad7f72d04 313 error_code DS2465::writeMacBlock() const {
IanBenzMaxim 0:f77ad7f72d04 314 // 1-Wire Transmit Block (Case A)
IanBenzMaxim 0:f77ad7f72d04 315 // S AD,0 [A] CommandReg [A] 1WTB [A] PR [A] P
IanBenzMaxim 0:f77ad7f72d04 316 // [] indicates from slave
IanBenzMaxim 0:f77ad7f72d04 317 // PR indicates byte containing parameter
IanBenzMaxim 0:f77ad7f72d04 318
IanBenzMaxim 6:a8c83a2e6fa4 319 const uint_least8_t command[] = {owTransmitBlockCmd, 0xFF};
IanBenzMaxim 6:a8c83a2e6fa4 320 error_code result = writeMemory(commandReg, command);
IanBenzMaxim 0:f77ad7f72d04 321 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 322 result = pollBusy();
IanBenzMaxim 0:f77ad7f72d04 323 }
IanBenzMaxim 0:f77ad7f72d04 324 return result;
IanBenzMaxim 0:f77ad7f72d04 325 }
IanBenzMaxim 0:f77ad7f72d04 326
IanBenzMaxim 0:f77ad7f72d04 327 error_code DS2465::readByteSetLevel(uint_least8_t & recvByte,
IanBenzMaxim 0:f77ad7f72d04 328 Level afterLevel) {
IanBenzMaxim 0:f77ad7f72d04 329 // 1-Wire Read Bytes (Case C)
IanBenzMaxim 0:f77ad7f72d04 330 // S AD,0 [A] CommandReg [A] 1WRB [A] Sr AD,1 [A] [Status] A [Status] A
IanBenzMaxim 0:f77ad7f72d04 331 // \--------/
IanBenzMaxim 0:f77ad7f72d04 332 // Repeat until 1WB bit has changed to 0
IanBenzMaxim 0:f77ad7f72d04 333 // Sr AD,0 [A] SRP [A] E1 [A] Sr AD,1 [A] DD A\ P
IanBenzMaxim 0:f77ad7f72d04 334 //
IanBenzMaxim 0:f77ad7f72d04 335 // [] indicates from slave
IanBenzMaxim 0:f77ad7f72d04 336 // DD data read
IanBenzMaxim 0:f77ad7f72d04 337
IanBenzMaxim 0:f77ad7f72d04 338 error_code result = configureLevel(afterLevel);
IanBenzMaxim 0:f77ad7f72d04 339 if (result) {
IanBenzMaxim 0:f77ad7f72d04 340 return result;
IanBenzMaxim 0:f77ad7f72d04 341 }
IanBenzMaxim 0:f77ad7f72d04 342
IanBenzMaxim 6:a8c83a2e6fa4 343 const uint_least8_t command = 0x96;
IanBenzMaxim 6:a8c83a2e6fa4 344 result = writeMemory(commandReg, make_span(&command, 1));
IanBenzMaxim 6:a8c83a2e6fa4 345 if (result) {
IanBenzMaxim 6:a8c83a2e6fa4 346 return result;
IanBenzMaxim 0:f77ad7f72d04 347 }
IanBenzMaxim 0:f77ad7f72d04 348
IanBenzMaxim 6:a8c83a2e6fa4 349 result = pollBusy();
IanBenzMaxim 6:a8c83a2e6fa4 350 if (result) {
IanBenzMaxim 6:a8c83a2e6fa4 351 return result;
IanBenzMaxim 0:f77ad7f72d04 352 }
IanBenzMaxim 0:f77ad7f72d04 353
IanBenzMaxim 6:a8c83a2e6fa4 354 result = readMemory(0x62, make_span(&recvByte, 1));
IanBenzMaxim 0:f77ad7f72d04 355 return result;
IanBenzMaxim 0:f77ad7f72d04 356 }
IanBenzMaxim 0:f77ad7f72d04 357
IanBenzMaxim 0:f77ad7f72d04 358 error_code DS2465::writeByteSetLevel(uint_least8_t sendByte, Level afterLevel) {
IanBenzMaxim 0:f77ad7f72d04 359 // 1-Wire Write Byte (Case B)
IanBenzMaxim 0:f77ad7f72d04 360 // S AD,0 [A] CommandReg [A] 1WWB [A] DD [A] Sr AD,1 [A] [Status] A [Status]
IanBenzMaxim 0:f77ad7f72d04 361 // A\ P
IanBenzMaxim 0:f77ad7f72d04 362 // \--------/
IanBenzMaxim 0:f77ad7f72d04 363 // Repeat until 1WB bit has changed to 0
IanBenzMaxim 0:f77ad7f72d04 364 // [] indicates from slave
IanBenzMaxim 0:f77ad7f72d04 365 // DD data to write
IanBenzMaxim 0:f77ad7f72d04 366
IanBenzMaxim 0:f77ad7f72d04 367 error_code result = configureLevel(afterLevel);
IanBenzMaxim 0:f77ad7f72d04 368 if (result) {
IanBenzMaxim 0:f77ad7f72d04 369 return result;
IanBenzMaxim 0:f77ad7f72d04 370 }
IanBenzMaxim 0:f77ad7f72d04 371
IanBenzMaxim 6:a8c83a2e6fa4 372 const uint_least8_t command[] = {0xA5, sendByte};
IanBenzMaxim 6:a8c83a2e6fa4 373 result = writeMemory(commandReg, command);
IanBenzMaxim 6:a8c83a2e6fa4 374 if (result) {
IanBenzMaxim 6:a8c83a2e6fa4 375 return result;
IanBenzMaxim 0:f77ad7f72d04 376 }
IanBenzMaxim 0:f77ad7f72d04 377
IanBenzMaxim 6:a8c83a2e6fa4 378 result = pollBusy();
IanBenzMaxim 0:f77ad7f72d04 379 return result;
IanBenzMaxim 0:f77ad7f72d04 380 }
IanBenzMaxim 0:f77ad7f72d04 381
IanBenzMaxim 0:f77ad7f72d04 382 error_code DS2465::touchBitSetLevel(bool & sendRecvBit, Level afterLevel) {
IanBenzMaxim 0:f77ad7f72d04 383 // 1-Wire bit (Case B)
IanBenzMaxim 0:f77ad7f72d04 384 // S AD,0 [A] CommandReg [A] 1WSB [A] BB [A] Sr AD,1 [A] [Status] A [Status]
IanBenzMaxim 0:f77ad7f72d04 385 // A\ P
IanBenzMaxim 0:f77ad7f72d04 386 // \--------/
IanBenzMaxim 0:f77ad7f72d04 387 // Repeat until 1WB bit has changed to 0
IanBenzMaxim 0:f77ad7f72d04 388 // [] indicates from slave
IanBenzMaxim 0:f77ad7f72d04 389 // BB indicates byte containing bit value in msbit
IanBenzMaxim 0:f77ad7f72d04 390
IanBenzMaxim 0:f77ad7f72d04 391 error_code result = configureLevel(afterLevel);
IanBenzMaxim 0:f77ad7f72d04 392 if (result) {
IanBenzMaxim 0:f77ad7f72d04 393 return result;
IanBenzMaxim 0:f77ad7f72d04 394 }
IanBenzMaxim 0:f77ad7f72d04 395
IanBenzMaxim 0:f77ad7f72d04 396 const uint_least8_t command[] = {
IanBenzMaxim 6:a8c83a2e6fa4 397 0x87, static_cast<uint_least8_t>(sendRecvBit ? 0x80 : 0x00)};
IanBenzMaxim 6:a8c83a2e6fa4 398 result = writeMemory(commandReg, command);
IanBenzMaxim 6:a8c83a2e6fa4 399 if (result) {
IanBenzMaxim 6:a8c83a2e6fa4 400 return result;
IanBenzMaxim 0:f77ad7f72d04 401 }
IanBenzMaxim 0:f77ad7f72d04 402
IanBenzMaxim 6:a8c83a2e6fa4 403 uint_least8_t status;
IanBenzMaxim 6:a8c83a2e6fa4 404 result = pollBusy(&status);
IanBenzMaxim 0:f77ad7f72d04 405 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 406 sendRecvBit = ((status & Status_SBR) == Status_SBR);
IanBenzMaxim 0:f77ad7f72d04 407 }
IanBenzMaxim 0:f77ad7f72d04 408 return result;
IanBenzMaxim 0:f77ad7f72d04 409 }
IanBenzMaxim 0:f77ad7f72d04 410
IanBenzMaxim 6:a8c83a2e6fa4 411 error_code DS2465::writeMemory(uint_least8_t addr,
IanBenzMaxim 6:a8c83a2e6fa4 412 span<const uint_least8_t> buf) const {
IanBenzMaxim 0:f77ad7f72d04 413 // Write SRAM (Case A)
IanBenzMaxim 0:f77ad7f72d04 414 // S AD,0 [A] VSA [A] DD [A] P
IanBenzMaxim 0:f77ad7f72d04 415 // \-----/
IanBenzMaxim 0:f77ad7f72d04 416 // Repeat for each data byte
IanBenzMaxim 0:f77ad7f72d04 417 // [] indicates from slave
IanBenzMaxim 0:f77ad7f72d04 418 // VSA valid SRAM memory address
IanBenzMaxim 0:f77ad7f72d04 419 // DD memory data to write
IanBenzMaxim 0:f77ad7f72d04 420
IanBenzMaxim 6:a8c83a2e6fa4 421 error_code result = master->start(address_);
IanBenzMaxim 0:f77ad7f72d04 422 if (result) {
IanBenzMaxim 6:a8c83a2e6fa4 423 master->stop();
IanBenzMaxim 0:f77ad7f72d04 424 return result;
IanBenzMaxim 0:f77ad7f72d04 425 }
IanBenzMaxim 6:a8c83a2e6fa4 426 result = master->writeByte(addr);
IanBenzMaxim 0:f77ad7f72d04 427 if (result) {
IanBenzMaxim 6:a8c83a2e6fa4 428 master->stop();
IanBenzMaxim 0:f77ad7f72d04 429 return result;
IanBenzMaxim 0:f77ad7f72d04 430 }
IanBenzMaxim 6:a8c83a2e6fa4 431 result = master->writeBlock(buf);
IanBenzMaxim 0:f77ad7f72d04 432 if (result) {
IanBenzMaxim 6:a8c83a2e6fa4 433 master->stop();
IanBenzMaxim 0:f77ad7f72d04 434 return result;
IanBenzMaxim 0:f77ad7f72d04 435 }
IanBenzMaxim 6:a8c83a2e6fa4 436 result = master->stop();
IanBenzMaxim 0:f77ad7f72d04 437 return result;
IanBenzMaxim 0:f77ad7f72d04 438 }
IanBenzMaxim 0:f77ad7f72d04 439
IanBenzMaxim 6:a8c83a2e6fa4 440 error_code DS2465::readMemory(uint_least8_t addr,
IanBenzMaxim 6:a8c83a2e6fa4 441 span<uint_least8_t> buf) const {
IanBenzMaxim 0:f77ad7f72d04 442 // Read (Case A)
IanBenzMaxim 0:f77ad7f72d04 443 // S AD,0 [A] MA [A] Sr AD,1 [A] [DD] A [DD] A\ P
IanBenzMaxim 0:f77ad7f72d04 444 // \-----/
IanBenzMaxim 0:f77ad7f72d04 445 // Repeat for each data byte, NAK last byte
IanBenzMaxim 0:f77ad7f72d04 446 // [] indicates from slave
IanBenzMaxim 0:f77ad7f72d04 447 // MA memory address
IanBenzMaxim 0:f77ad7f72d04 448 // DD memory data read
IanBenzMaxim 0:f77ad7f72d04 449
IanBenzMaxim 6:a8c83a2e6fa4 450 error_code result = master->start(address_);
IanBenzMaxim 0:f77ad7f72d04 451 if (result) {
IanBenzMaxim 6:a8c83a2e6fa4 452 master->stop();
IanBenzMaxim 0:f77ad7f72d04 453 return result;
IanBenzMaxim 0:f77ad7f72d04 454 }
IanBenzMaxim 6:a8c83a2e6fa4 455 result = master->writeByte(addr);
IanBenzMaxim 0:f77ad7f72d04 456 if (result) {
IanBenzMaxim 6:a8c83a2e6fa4 457 master->stop();
IanBenzMaxim 0:f77ad7f72d04 458 return result;
IanBenzMaxim 0:f77ad7f72d04 459 }
IanBenzMaxim 6:a8c83a2e6fa4 460 result = readMemory(buf);
IanBenzMaxim 0:f77ad7f72d04 461 return result;
IanBenzMaxim 0:f77ad7f72d04 462 }
IanBenzMaxim 0:f77ad7f72d04 463
IanBenzMaxim 6:a8c83a2e6fa4 464 error_code DS2465::readMemory(span<uint_least8_t> buf) const {
IanBenzMaxim 6:a8c83a2e6fa4 465 error_code result = master->start(address_ | 1);
IanBenzMaxim 0:f77ad7f72d04 466 if (result) {
IanBenzMaxim 6:a8c83a2e6fa4 467 master->stop();
IanBenzMaxim 0:f77ad7f72d04 468 return result;
IanBenzMaxim 0:f77ad7f72d04 469 }
IanBenzMaxim 6:a8c83a2e6fa4 470 result = master->readBlock(I2CMaster::Nack, buf);
IanBenzMaxim 0:f77ad7f72d04 471 if (result) {
IanBenzMaxim 6:a8c83a2e6fa4 472 master->stop();
IanBenzMaxim 0:f77ad7f72d04 473 return result;
IanBenzMaxim 0:f77ad7f72d04 474 }
IanBenzMaxim 6:a8c83a2e6fa4 475 result = master->stop();
IanBenzMaxim 0:f77ad7f72d04 476 return result;
IanBenzMaxim 0:f77ad7f72d04 477 }
IanBenzMaxim 0:f77ad7f72d04 478
IanBenzMaxim 0:f77ad7f72d04 479 error_code DS2465::writeConfig(Config config) {
IanBenzMaxim 6:a8c83a2e6fa4 480 const uint_least8_t configReg = 0x67;
IanBenzMaxim 6:a8c83a2e6fa4 481 uint_least8_t configBuf =
IanBenzMaxim 6:a8c83a2e6fa4 482 ((config.readByte() ^ 0xF) << 4) | config.readByte();
IanBenzMaxim 6:a8c83a2e6fa4 483 error_code result = writeMemory(configReg, make_span(&configBuf, 1));
IanBenzMaxim 0:f77ad7f72d04 484 if (!result) {
IanBenzMaxim 6:a8c83a2e6fa4 485 result = readMemory(configReg, make_span(&configBuf, 1));
IanBenzMaxim 0:f77ad7f72d04 486 }
IanBenzMaxim 0:f77ad7f72d04 487 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 488 if (configBuf != config.readByte())
IanBenzMaxim 0:f77ad7f72d04 489 result = make_error_code(HardwareError);
IanBenzMaxim 0:f77ad7f72d04 490 }
IanBenzMaxim 0:f77ad7f72d04 491 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 492 curConfig = config;
IanBenzMaxim 0:f77ad7f72d04 493 }
IanBenzMaxim 0:f77ad7f72d04 494 return result;
IanBenzMaxim 0:f77ad7f72d04 495 }
IanBenzMaxim 0:f77ad7f72d04 496
IanBenzMaxim 0:f77ad7f72d04 497 error_code DS2465::writePortParameter(PortParameter param, int val) {
IanBenzMaxim 0:f77ad7f72d04 498 if (val < 0 || val > 15) {
IanBenzMaxim 0:f77ad7f72d04 499 return make_error_code(ArgumentOutOfRangeError);
IanBenzMaxim 0:f77ad7f72d04 500 }
IanBenzMaxim 0:f77ad7f72d04 501
IanBenzMaxim 0:f77ad7f72d04 502 uint_least8_t addr = 0;
IanBenzMaxim 0:f77ad7f72d04 503 switch (param) {
IanBenzMaxim 0:f77ad7f72d04 504 case tRSTL_STD:
IanBenzMaxim 0:f77ad7f72d04 505 case tRSTL_OD:
IanBenzMaxim 6:a8c83a2e6fa4 506 addr = 0x68;
IanBenzMaxim 0:f77ad7f72d04 507 break;
IanBenzMaxim 0:f77ad7f72d04 508 case tMSP_STD:
IanBenzMaxim 0:f77ad7f72d04 509 case tMSP_OD:
IanBenzMaxim 6:a8c83a2e6fa4 510 addr = 0x69;
IanBenzMaxim 0:f77ad7f72d04 511 break;
IanBenzMaxim 0:f77ad7f72d04 512 case tW0L_STD:
IanBenzMaxim 0:f77ad7f72d04 513 case tW0L_OD:
IanBenzMaxim 6:a8c83a2e6fa4 514 addr = 0x6A;
IanBenzMaxim 0:f77ad7f72d04 515 break;
IanBenzMaxim 0:f77ad7f72d04 516 case tREC0:
IanBenzMaxim 6:a8c83a2e6fa4 517 addr = 0x6B;
IanBenzMaxim 0:f77ad7f72d04 518 break;
IanBenzMaxim 0:f77ad7f72d04 519 case RWPU:
IanBenzMaxim 6:a8c83a2e6fa4 520 addr = 0x6C;
IanBenzMaxim 0:f77ad7f72d04 521 break;
IanBenzMaxim 0:f77ad7f72d04 522 case tW1L_OD:
IanBenzMaxim 6:a8c83a2e6fa4 523 addr = 0x6D;
IanBenzMaxim 0:f77ad7f72d04 524 break;
IanBenzMaxim 0:f77ad7f72d04 525 }
IanBenzMaxim 0:f77ad7f72d04 526
IanBenzMaxim 0:f77ad7f72d04 527 uint_least8_t data;
IanBenzMaxim 6:a8c83a2e6fa4 528 error_code result = readMemory(addr, make_span(&data, 1));
IanBenzMaxim 0:f77ad7f72d04 529 if (result) {
IanBenzMaxim 0:f77ad7f72d04 530 return result;
IanBenzMaxim 0:f77ad7f72d04 531 }
IanBenzMaxim 0:f77ad7f72d04 532
IanBenzMaxim 0:f77ad7f72d04 533 uint_least8_t newData;
IanBenzMaxim 0:f77ad7f72d04 534 if (param == tRSTL_OD || param == tMSP_OD || param == tW0L_OD) {
IanBenzMaxim 0:f77ad7f72d04 535 newData = (data & 0x0F) | (val << 4);
IanBenzMaxim 0:f77ad7f72d04 536 } else {
IanBenzMaxim 0:f77ad7f72d04 537 newData = (data & 0xF0) | val;
IanBenzMaxim 0:f77ad7f72d04 538 }
IanBenzMaxim 0:f77ad7f72d04 539
IanBenzMaxim 0:f77ad7f72d04 540 if (newData != data) {
IanBenzMaxim 6:a8c83a2e6fa4 541 result = writeMemory(addr, make_span(&newData, 1));
IanBenzMaxim 0:f77ad7f72d04 542 }
IanBenzMaxim 0:f77ad7f72d04 543 return result;
IanBenzMaxim 0:f77ad7f72d04 544 }
IanBenzMaxim 0:f77ad7f72d04 545
IanBenzMaxim 0:f77ad7f72d04 546 error_code DS2465::pollBusy(uint_least8_t * pStatus) const {
IanBenzMaxim 0:f77ad7f72d04 547 const int pollLimit = 200;
IanBenzMaxim 0:f77ad7f72d04 548
IanBenzMaxim 0:f77ad7f72d04 549 int pollCount = 0;
IanBenzMaxim 0:f77ad7f72d04 550 uint_least8_t status;
IanBenzMaxim 0:f77ad7f72d04 551 do {
IanBenzMaxim 6:a8c83a2e6fa4 552 error_code result = readMemory(make_span(&status, 1));
IanBenzMaxim 0:f77ad7f72d04 553 if (result) {
IanBenzMaxim 0:f77ad7f72d04 554 return result;
IanBenzMaxim 0:f77ad7f72d04 555 }
IanBenzMaxim 0:f77ad7f72d04 556 if (pStatus != NULL) {
IanBenzMaxim 0:f77ad7f72d04 557 *pStatus = status;
IanBenzMaxim 0:f77ad7f72d04 558 }
IanBenzMaxim 0:f77ad7f72d04 559 if (pollCount++ >= pollLimit) {
IanBenzMaxim 0:f77ad7f72d04 560 return make_error_code(HardwareError);
IanBenzMaxim 0:f77ad7f72d04 561 }
IanBenzMaxim 0:f77ad7f72d04 562 } while (status & Status_1WB);
IanBenzMaxim 0:f77ad7f72d04 563
IanBenzMaxim 0:f77ad7f72d04 564 return error_code();
IanBenzMaxim 0:f77ad7f72d04 565 }
IanBenzMaxim 0:f77ad7f72d04 566
IanBenzMaxim 0:f77ad7f72d04 567 error_code DS2465::reset() {
IanBenzMaxim 0:f77ad7f72d04 568 // 1-Wire reset (Case B)
IanBenzMaxim 0:f77ad7f72d04 569 // S AD,0 [A] CommandReg [A] 1WRS [A] Sr AD,1 [A] [Status] A [Status] A\ P
IanBenzMaxim 0:f77ad7f72d04 570 // \--------/
IanBenzMaxim 0:f77ad7f72d04 571 // Repeat until 1WB bit has changed to 0
IanBenzMaxim 0:f77ad7f72d04 572 // [] indicates from slave
IanBenzMaxim 0:f77ad7f72d04 573
IanBenzMaxim 6:a8c83a2e6fa4 574 uint_least8_t buf = 0xB4;
IanBenzMaxim 6:a8c83a2e6fa4 575 error_code result = writeMemory(commandReg, make_span(&buf, 1));
IanBenzMaxim 0:f77ad7f72d04 576
IanBenzMaxim 0:f77ad7f72d04 577 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 578 result = pollBusy(&buf);
IanBenzMaxim 0:f77ad7f72d04 579 }
IanBenzMaxim 0:f77ad7f72d04 580
IanBenzMaxim 0:f77ad7f72d04 581 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 582 if ((buf & Status_SD) == Status_SD) {
IanBenzMaxim 0:f77ad7f72d04 583 result = make_error_code(ShortDetectedError);
IanBenzMaxim 6:a8c83a2e6fa4 584 } else if ((buf & Status_PPD) != Status_PPD) {
IanBenzMaxim 0:f77ad7f72d04 585 result = make_error_code(NoSlaveError);
IanBenzMaxim 0:f77ad7f72d04 586 }
IanBenzMaxim 0:f77ad7f72d04 587 }
IanBenzMaxim 0:f77ad7f72d04 588
IanBenzMaxim 0:f77ad7f72d04 589 return result;
IanBenzMaxim 0:f77ad7f72d04 590 }
IanBenzMaxim 0:f77ad7f72d04 591
IanBenzMaxim 0:f77ad7f72d04 592 error_code DS2465::resetDevice() {
IanBenzMaxim 0:f77ad7f72d04 593 // Device Reset
IanBenzMaxim 0:f77ad7f72d04 594 // S AD,0 [A] CommandReg [A] 1WMR [A] Sr AD,1 [A] [SS] A\ P
IanBenzMaxim 0:f77ad7f72d04 595 // [] indicates from slave
IanBenzMaxim 0:f77ad7f72d04 596 // SS status byte to read to verify state
IanBenzMaxim 0:f77ad7f72d04 597
IanBenzMaxim 6:a8c83a2e6fa4 598 uint_least8_t buf = 0xF0;
IanBenzMaxim 6:a8c83a2e6fa4 599 error_code result = writeMemory(commandReg, make_span(&buf, 1));
IanBenzMaxim 0:f77ad7f72d04 600
IanBenzMaxim 0:f77ad7f72d04 601 if (!result) {
IanBenzMaxim 6:a8c83a2e6fa4 602 result = readMemory(make_span(&buf, 1));
IanBenzMaxim 0:f77ad7f72d04 603 }
IanBenzMaxim 0:f77ad7f72d04 604
IanBenzMaxim 0:f77ad7f72d04 605 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 606 if ((buf & 0xF7) != 0x10) {
IanBenzMaxim 0:f77ad7f72d04 607 result = make_error_code(HardwareError);
IanBenzMaxim 0:f77ad7f72d04 608 }
IanBenzMaxim 0:f77ad7f72d04 609 }
IanBenzMaxim 0:f77ad7f72d04 610
IanBenzMaxim 0:f77ad7f72d04 611 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 612 reset(); // do a command to get 1-Wire master reset out of holding state
IanBenzMaxim 0:f77ad7f72d04 613 }
IanBenzMaxim 0:f77ad7f72d04 614
IanBenzMaxim 0:f77ad7f72d04 615 return result;
IanBenzMaxim 0:f77ad7f72d04 616 }
IanBenzMaxim 0:f77ad7f72d04 617
IanBenzMaxim 6:a8c83a2e6fa4 618 error_code
IanBenzMaxim 6:a8c83a2e6fa4 619 DS2465::computeNextMasterSecret(AuthenticationData::const_span data) {
IanBenzMaxim 6:a8c83a2e6fa4 620 error_code result = writeMemory(scratchpad, data);
IanBenzMaxim 0:f77ad7f72d04 621 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 622 result = computeNextMasterSecret(false, 0, FullPage);
IanBenzMaxim 0:f77ad7f72d04 623 }
IanBenzMaxim 0:f77ad7f72d04 624 return result;
IanBenzMaxim 0:f77ad7f72d04 625 }
IanBenzMaxim 0:f77ad7f72d04 626
IanBenzMaxim 6:a8c83a2e6fa4 627 error_code
IanBenzMaxim 6:a8c83a2e6fa4 628 DS2465::computeNextMasterSecretWithSwap(AuthenticationData::const_span data,
IanBenzMaxim 6:a8c83a2e6fa4 629 int pageNum, PageRegion region) {
IanBenzMaxim 6:a8c83a2e6fa4 630 error_code result = writeMemory(scratchpad, data);
IanBenzMaxim 0:f77ad7f72d04 631 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 632 result = computeNextMasterSecret(true, pageNum, region);
IanBenzMaxim 0:f77ad7f72d04 633 }
IanBenzMaxim 0:f77ad7f72d04 634 return result;
IanBenzMaxim 0:f77ad7f72d04 635 }
IanBenzMaxim 0:f77ad7f72d04 636
IanBenzMaxim 6:a8c83a2e6fa4 637 error_code DS2465::computeWriteMac(WriteMacData::const_span data) const {
IanBenzMaxim 6:a8c83a2e6fa4 638 error_code result = writeMemory(scratchpad, data);
IanBenzMaxim 0:f77ad7f72d04 639 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 640 result = computeWriteMac(false, false, 0, 0);
IanBenzMaxim 0:f77ad7f72d04 641 }
IanBenzMaxim 0:f77ad7f72d04 642 return result;
IanBenzMaxim 0:f77ad7f72d04 643 }
IanBenzMaxim 0:f77ad7f72d04 644
IanBenzMaxim 6:a8c83a2e6fa4 645 error_code DS2465::computeWriteMac(WriteMacData::const_span data,
IanBenzMaxim 6:a8c83a2e6fa4 646 Hash::span mac) const {
IanBenzMaxim 0:f77ad7f72d04 647 error_code result = computeWriteMac(data);
IanBenzMaxim 0:f77ad7f72d04 648 if (!result) {
IanBenzMaxim 6:a8c83a2e6fa4 649 result = readMemory(mac);
IanBenzMaxim 0:f77ad7f72d04 650 }
IanBenzMaxim 0:f77ad7f72d04 651 return result;
IanBenzMaxim 0:f77ad7f72d04 652 }
IanBenzMaxim 0:f77ad7f72d04 653
IanBenzMaxim 6:a8c83a2e6fa4 654 error_code
IanBenzMaxim 6:a8c83a2e6fa4 655 DS2465::computeAndTransmitWriteMac(WriteMacData::const_span data) const {
IanBenzMaxim 0:f77ad7f72d04 656 error_code result = computeWriteMac(data);
IanBenzMaxim 0:f77ad7f72d04 657 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 658 result = writeMacBlock();
IanBenzMaxim 0:f77ad7f72d04 659 }
IanBenzMaxim 0:f77ad7f72d04 660 return result;
IanBenzMaxim 0:f77ad7f72d04 661 }
IanBenzMaxim 0:f77ad7f72d04 662
IanBenzMaxim 6:a8c83a2e6fa4 663 error_code DS2465::computeWriteMacWithSwap(WriteMacData::const_span data,
IanBenzMaxim 0:f77ad7f72d04 664 int pageNum, int segmentNum) const {
IanBenzMaxim 6:a8c83a2e6fa4 665 error_code result = writeMemory(scratchpad, data);
IanBenzMaxim 0:f77ad7f72d04 666 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 667 result = computeWriteMac(false, true, pageNum, segmentNum);
IanBenzMaxim 0:f77ad7f72d04 668 }
IanBenzMaxim 0:f77ad7f72d04 669 return result;
IanBenzMaxim 0:f77ad7f72d04 670 }
IanBenzMaxim 0:f77ad7f72d04 671
IanBenzMaxim 6:a8c83a2e6fa4 672 error_code DS2465::computeWriteMacWithSwap(WriteMacData::const_span data,
IanBenzMaxim 0:f77ad7f72d04 673 int pageNum, int segmentNum,
IanBenzMaxim 6:a8c83a2e6fa4 674 Hash::span mac) const {
IanBenzMaxim 0:f77ad7f72d04 675 error_code result = computeWriteMacWithSwap(data, pageNum, segmentNum);
IanBenzMaxim 0:f77ad7f72d04 676 if (!result) {
IanBenzMaxim 6:a8c83a2e6fa4 677 result = readMemory(mac);
IanBenzMaxim 0:f77ad7f72d04 678 }
IanBenzMaxim 0:f77ad7f72d04 679 return result;
IanBenzMaxim 0:f77ad7f72d04 680 }
IanBenzMaxim 0:f77ad7f72d04 681
IanBenzMaxim 6:a8c83a2e6fa4 682 error_code
IanBenzMaxim 6:a8c83a2e6fa4 683 DS2465::computeAndTransmitWriteMacWithSwap(WriteMacData::const_span data,
IanBenzMaxim 6:a8c83a2e6fa4 684 int pageNum, int segmentNum) const {
IanBenzMaxim 0:f77ad7f72d04 685 error_code result = computeWriteMacWithSwap(data, pageNum, segmentNum);
IanBenzMaxim 0:f77ad7f72d04 686 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 687 result = writeMacBlock();
IanBenzMaxim 0:f77ad7f72d04 688 }
IanBenzMaxim 0:f77ad7f72d04 689 return result;
IanBenzMaxim 0:f77ad7f72d04 690 }
IanBenzMaxim 0:f77ad7f72d04 691
IanBenzMaxim 6:a8c83a2e6fa4 692 error_code DS2465::computeSlaveSecret(AuthenticationData::const_span data) {
IanBenzMaxim 6:a8c83a2e6fa4 693 error_code result = writeMemory(scratchpad, data);
IanBenzMaxim 0:f77ad7f72d04 694 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 695 result = computeSlaveSecret(false, 0, FullPage);
IanBenzMaxim 0:f77ad7f72d04 696 }
IanBenzMaxim 0:f77ad7f72d04 697 return result;
IanBenzMaxim 0:f77ad7f72d04 698 }
IanBenzMaxim 0:f77ad7f72d04 699
IanBenzMaxim 6:a8c83a2e6fa4 700 error_code
IanBenzMaxim 6:a8c83a2e6fa4 701 DS2465::computeSlaveSecretWithSwap(AuthenticationData::const_span data,
IanBenzMaxim 6:a8c83a2e6fa4 702 int pageNum, PageRegion region) {
IanBenzMaxim 6:a8c83a2e6fa4 703 error_code result = writeMemory(scratchpad, data);
IanBenzMaxim 0:f77ad7f72d04 704 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 705 result = computeSlaveSecret(true, pageNum, region);
IanBenzMaxim 0:f77ad7f72d04 706 }
IanBenzMaxim 0:f77ad7f72d04 707 return result;
IanBenzMaxim 0:f77ad7f72d04 708 }
IanBenzMaxim 0:f77ad7f72d04 709
IanBenzMaxim 6:a8c83a2e6fa4 710 error_code DS2465::computeAuthMac(AuthenticationData::const_span data) const {
IanBenzMaxim 6:a8c83a2e6fa4 711 error_code result = writeMemory(scratchpad, data);
IanBenzMaxim 0:f77ad7f72d04 712 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 713 result = computeAuthMac(false, 0, FullPage);
IanBenzMaxim 0:f77ad7f72d04 714 }
IanBenzMaxim 0:f77ad7f72d04 715 return result;
IanBenzMaxim 0:f77ad7f72d04 716 }
IanBenzMaxim 0:f77ad7f72d04 717
IanBenzMaxim 6:a8c83a2e6fa4 718 error_code DS2465::computeAuthMac(AuthenticationData::const_span data,
IanBenzMaxim 6:a8c83a2e6fa4 719 Hash::span mac) const {
IanBenzMaxim 0:f77ad7f72d04 720 error_code result = computeAuthMac(data);
IanBenzMaxim 0:f77ad7f72d04 721 if (!result) {
IanBenzMaxim 6:a8c83a2e6fa4 722 result = readMemory(mac);
IanBenzMaxim 0:f77ad7f72d04 723 }
IanBenzMaxim 0:f77ad7f72d04 724 return result;
IanBenzMaxim 0:f77ad7f72d04 725 }
IanBenzMaxim 0:f77ad7f72d04 726
IanBenzMaxim 6:a8c83a2e6fa4 727 error_code
IanBenzMaxim 6:a8c83a2e6fa4 728 DS2465::computeAndTransmitAuthMac(AuthenticationData::const_span data) const {
IanBenzMaxim 0:f77ad7f72d04 729 error_code result = computeAuthMac(data);
IanBenzMaxim 0:f77ad7f72d04 730 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 731 result = writeMacBlock();
IanBenzMaxim 0:f77ad7f72d04 732 }
IanBenzMaxim 0:f77ad7f72d04 733 return result;
IanBenzMaxim 0:f77ad7f72d04 734 }
IanBenzMaxim 0:f77ad7f72d04 735
IanBenzMaxim 6:a8c83a2e6fa4 736 error_code DS2465::computeAuthMacWithSwap(AuthenticationData::const_span data,
IanBenzMaxim 6:a8c83a2e6fa4 737 int pageNum,
IanBenzMaxim 0:f77ad7f72d04 738 PageRegion region) const {
IanBenzMaxim 6:a8c83a2e6fa4 739 error_code result = writeMemory(scratchpad, data);
IanBenzMaxim 0:f77ad7f72d04 740 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 741 result = computeAuthMac(true, pageNum, region);
IanBenzMaxim 0:f77ad7f72d04 742 }
IanBenzMaxim 0:f77ad7f72d04 743 return result;
IanBenzMaxim 0:f77ad7f72d04 744 }
IanBenzMaxim 0:f77ad7f72d04 745
IanBenzMaxim 6:a8c83a2e6fa4 746 error_code DS2465::computeAuthMacWithSwap(AuthenticationData::const_span data,
IanBenzMaxim 6:a8c83a2e6fa4 747 int pageNum, PageRegion region,
IanBenzMaxim 6:a8c83a2e6fa4 748 Hash::span mac) const {
IanBenzMaxim 0:f77ad7f72d04 749 error_code result = computeAuthMacWithSwap(data, pageNum, region);
IanBenzMaxim 0:f77ad7f72d04 750 if (!result) {
IanBenzMaxim 6:a8c83a2e6fa4 751 result = readMemory(mac);
IanBenzMaxim 0:f77ad7f72d04 752 }
IanBenzMaxim 0:f77ad7f72d04 753 return result;
IanBenzMaxim 0:f77ad7f72d04 754 }
IanBenzMaxim 0:f77ad7f72d04 755
IanBenzMaxim 6:a8c83a2e6fa4 756 error_code DS2465::computeAndTransmitAuthMacWithSwap(
IanBenzMaxim 6:a8c83a2e6fa4 757 AuthenticationData::const_span data, int pageNum, PageRegion region) const {
IanBenzMaxim 0:f77ad7f72d04 758 error_code result = computeAuthMacWithSwap(data, pageNum, region);
IanBenzMaxim 0:f77ad7f72d04 759 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 760 result = writeMacBlock();
IanBenzMaxim 0:f77ad7f72d04 761 }
IanBenzMaxim 0:f77ad7f72d04 762 return result;
IanBenzMaxim 0:f77ad7f72d04 763 }
IanBenzMaxim 0:f77ad7f72d04 764
IanBenzMaxim 0:f77ad7f72d04 765 const error_category & DS2465::errorCategory() {
IanBenzMaxim 0:f77ad7f72d04 766 static class : public error_category {
IanBenzMaxim 0:f77ad7f72d04 767 public:
IanBenzMaxim 0:f77ad7f72d04 768 virtual const char * name() const { return "DS2465"; }
IanBenzMaxim 0:f77ad7f72d04 769
IanBenzMaxim 0:f77ad7f72d04 770 virtual std::string message(int condition) const {
IanBenzMaxim 0:f77ad7f72d04 771 switch (condition) {
IanBenzMaxim 0:f77ad7f72d04 772 case HardwareError:
IanBenzMaxim 0:f77ad7f72d04 773 return "Hardware Error";
IanBenzMaxim 0:f77ad7f72d04 774
IanBenzMaxim 0:f77ad7f72d04 775 case ArgumentOutOfRangeError:
IanBenzMaxim 0:f77ad7f72d04 776 return "Argument Out of Range Error";
IanBenzMaxim 0:f77ad7f72d04 777
IanBenzMaxim 0:f77ad7f72d04 778 default:
IanBenzMaxim 0:f77ad7f72d04 779 return defaultErrorMessage(condition);
IanBenzMaxim 0:f77ad7f72d04 780 }
IanBenzMaxim 0:f77ad7f72d04 781 }
IanBenzMaxim 0:f77ad7f72d04 782 } instance;
IanBenzMaxim 0:f77ad7f72d04 783 return instance;
IanBenzMaxim 0:f77ad7f72d04 784 }
IanBenzMaxim 0:f77ad7f72d04 785
IanBenzMaxim 0:f77ad7f72d04 786 } // namespace MaximInterface