Extended MaximInterface

Dependents:   mbed_DS28EC20_GPIO

Committer:
IanBenzMaxim
Date:
Mon Nov 06 14:39:18 2017 -0600
Revision:
0:f77ad7f72d04
Child:
6:a8c83a2e6fa4
Initial commit.

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 enum MemoryAddress {
IanBenzMaxim 0:f77ad7f72d04 41 Scratchpad = 0x00,
IanBenzMaxim 0:f77ad7f72d04 42 CommandReg = 0x60,
IanBenzMaxim 0:f77ad7f72d04 43 StatusReg = 0x61,
IanBenzMaxim 0:f77ad7f72d04 44 ReadDataReg = 0x62,
IanBenzMaxim 0:f77ad7f72d04 45 MacReadoutReg = 0x63,
IanBenzMaxim 0:f77ad7f72d04 46 MemoryProtectionReg = 0x64,
IanBenzMaxim 0:f77ad7f72d04 47 ConfigReg = 0x67,
IanBenzMaxim 0:f77ad7f72d04 48 tRSTL_Reg = 0x68,
IanBenzMaxim 0:f77ad7f72d04 49 tMSP_Reg = 0x69,
IanBenzMaxim 0:f77ad7f72d04 50 tW0L_Reg = 0x6A,
IanBenzMaxim 0:f77ad7f72d04 51 tREC0_Reg = 0x6B,
IanBenzMaxim 0:f77ad7f72d04 52 RWPU_Reg = 0x6C,
IanBenzMaxim 0:f77ad7f72d04 53 tW1L_Reg = 0x6D,
IanBenzMaxim 0:f77ad7f72d04 54 UserMemoryPage0 = 0x80,
IanBenzMaxim 0:f77ad7f72d04 55 UserMemoryPage1 = 0xA0
IanBenzMaxim 0:f77ad7f72d04 56 };
IanBenzMaxim 0:f77ad7f72d04 57
IanBenzMaxim 0:f77ad7f72d04 58 /// Delay required after writing an EEPROM segment.
IanBenzMaxim 0:f77ad7f72d04 59 static const int eepromSegmentWriteDelayMs = 10;
IanBenzMaxim 0:f77ad7f72d04 60 /// Delay required after writing an EEPROM page such as the secret memory.
IanBenzMaxim 0:f77ad7f72d04 61 static const int eepromPageWriteDelayMs = 8 * eepromSegmentWriteDelayMs;
IanBenzMaxim 0:f77ad7f72d04 62 /// Delay required for a SHA computation to complete.
IanBenzMaxim 0:f77ad7f72d04 63 static const int shaComputationDelayMs = 2;
IanBenzMaxim 0:f77ad7f72d04 64
IanBenzMaxim 0:f77ad7f72d04 65 /// DS2465 Commands
IanBenzMaxim 0:f77ad7f72d04 66 enum Command {
IanBenzMaxim 0:f77ad7f72d04 67 DeviceResetCmd = 0xF0,
IanBenzMaxim 0:f77ad7f72d04 68 WriteDeviceConfigCmd = 0xD2,
IanBenzMaxim 0:f77ad7f72d04 69 OwResetCmd = 0xB4,
IanBenzMaxim 0:f77ad7f72d04 70 OwWriteByteCmd = 0xA5,
IanBenzMaxim 0:f77ad7f72d04 71 OwReadByteCmd = 0x96,
IanBenzMaxim 0:f77ad7f72d04 72 OwSingleBitCmd = 0x87,
IanBenzMaxim 0:f77ad7f72d04 73 OwTripletCmd = 0x78,
IanBenzMaxim 0:f77ad7f72d04 74 OwTransmitBlockCmd = 0x69,
IanBenzMaxim 0:f77ad7f72d04 75 OwReceiveBlockCmd = 0xE1,
IanBenzMaxim 0:f77ad7f72d04 76 CopyScratchpadCmd = 0x5A,
IanBenzMaxim 0:f77ad7f72d04 77 ComputeSlaveSecretCmd = 0x4B,
IanBenzMaxim 0:f77ad7f72d04 78 ComputeSlaveAuthMacCmd = 0x3C,
IanBenzMaxim 0:f77ad7f72d04 79 ComputeSlaveWriteMacCmd = 0x2D,
IanBenzMaxim 0:f77ad7f72d04 80 ComputeNextMasterSecretCmd = 0x1E,
IanBenzMaxim 0:f77ad7f72d04 81 SetProtectionCmd = 0x0F
IanBenzMaxim 0:f77ad7f72d04 82 };
IanBenzMaxim 0:f77ad7f72d04 83
IanBenzMaxim 0:f77ad7f72d04 84 /// DS2465 Status Bits
IanBenzMaxim 0:f77ad7f72d04 85 enum StatusBit {
IanBenzMaxim 0:f77ad7f72d04 86 Status_1WB = 0x01,
IanBenzMaxim 0:f77ad7f72d04 87 Status_PPD = 0x02,
IanBenzMaxim 0:f77ad7f72d04 88 Status_SD = 0x04,
IanBenzMaxim 0:f77ad7f72d04 89 Status_LL = 0x08,
IanBenzMaxim 0:f77ad7f72d04 90 Status_RST = 0x10,
IanBenzMaxim 0:f77ad7f72d04 91 Status_SBR = 0x20,
IanBenzMaxim 0:f77ad7f72d04 92 Status_TSB = 0x40,
IanBenzMaxim 0:f77ad7f72d04 93 Status_DIR = 0x80
IanBenzMaxim 0:f77ad7f72d04 94 };
IanBenzMaxim 0:f77ad7f72d04 95
IanBenzMaxim 0:f77ad7f72d04 96 static const size_t maxBlockSize = 63;
IanBenzMaxim 0:f77ad7f72d04 97
IanBenzMaxim 0:f77ad7f72d04 98 error_code DS2465::initialize(Config config) {
IanBenzMaxim 0:f77ad7f72d04 99 // reset DS2465
IanBenzMaxim 0:f77ad7f72d04 100 error_code result = resetDevice();
IanBenzMaxim 0:f77ad7f72d04 101 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 102 // write the default configuration setup
IanBenzMaxim 0:f77ad7f72d04 103 result = writeConfig(config);
IanBenzMaxim 0:f77ad7f72d04 104 }
IanBenzMaxim 0:f77ad7f72d04 105 return result;
IanBenzMaxim 0:f77ad7f72d04 106 }
IanBenzMaxim 0:f77ad7f72d04 107
IanBenzMaxim 0:f77ad7f72d04 108 error_code DS2465::computeNextMasterSecret(bool swap, int pageNum,
IanBenzMaxim 0:f77ad7f72d04 109 PageRegion region) {
IanBenzMaxim 0:f77ad7f72d04 110 error_code result = make_error_code(ArgumentOutOfRangeError);
IanBenzMaxim 0:f77ad7f72d04 111 if (pageNum >= 0) {
IanBenzMaxim 0:f77ad7f72d04 112 uint_least8_t command[] = {
IanBenzMaxim 0:f77ad7f72d04 113 ComputeNextMasterSecretCmd,
IanBenzMaxim 0:f77ad7f72d04 114 static_cast<uint_least8_t>(swap ? (0xC8 | (pageNum << 4) | region)
IanBenzMaxim 0:f77ad7f72d04 115 : 0xBF)};
IanBenzMaxim 0:f77ad7f72d04 116 result =
IanBenzMaxim 0:f77ad7f72d04 117 writeMemory(CommandReg, command, sizeof(command) / sizeof(command[0]));
IanBenzMaxim 0:f77ad7f72d04 118 }
IanBenzMaxim 0:f77ad7f72d04 119 return result;
IanBenzMaxim 0:f77ad7f72d04 120 }
IanBenzMaxim 0:f77ad7f72d04 121
IanBenzMaxim 0:f77ad7f72d04 122 error_code DS2465::computeWriteMac(bool regwrite, bool swap, int pageNum,
IanBenzMaxim 0:f77ad7f72d04 123 int segmentNum) const {
IanBenzMaxim 0:f77ad7f72d04 124 error_code result = make_error_code(ArgumentOutOfRangeError);
IanBenzMaxim 0:f77ad7f72d04 125 if (pageNum >= 0 && segmentNum >= 0) {
IanBenzMaxim 0:f77ad7f72d04 126 uint_least8_t command[] = {
IanBenzMaxim 0:f77ad7f72d04 127 ComputeSlaveWriteMacCmd,
IanBenzMaxim 0:f77ad7f72d04 128 static_cast<uint_least8_t>((regwrite << 7) | (swap << 6) |
IanBenzMaxim 0:f77ad7f72d04 129 (pageNum << 4) | segmentNum)};
IanBenzMaxim 0:f77ad7f72d04 130 result =
IanBenzMaxim 0:f77ad7f72d04 131 writeMemory(CommandReg, command, sizeof(command) / sizeof(command[0]));
IanBenzMaxim 0:f77ad7f72d04 132 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 133 (*sleep)(shaComputationDelayMs);
IanBenzMaxim 0:f77ad7f72d04 134 }
IanBenzMaxim 0:f77ad7f72d04 135 }
IanBenzMaxim 0:f77ad7f72d04 136 return result;
IanBenzMaxim 0:f77ad7f72d04 137 }
IanBenzMaxim 0:f77ad7f72d04 138
IanBenzMaxim 0:f77ad7f72d04 139 error_code DS2465::computeAuthMac(bool swap, int pageNum,
IanBenzMaxim 0:f77ad7f72d04 140 PageRegion region) const {
IanBenzMaxim 0:f77ad7f72d04 141 error_code result = make_error_code(ArgumentOutOfRangeError);
IanBenzMaxim 0:f77ad7f72d04 142 if (pageNum >= 0) {
IanBenzMaxim 0:f77ad7f72d04 143 uint_least8_t command[] = {
IanBenzMaxim 0:f77ad7f72d04 144 ComputeSlaveAuthMacCmd,
IanBenzMaxim 0:f77ad7f72d04 145 static_cast<uint_least8_t>(swap ? (0xC8 | (pageNum << 4) | region)
IanBenzMaxim 0:f77ad7f72d04 146 : 0xBF)};
IanBenzMaxim 0:f77ad7f72d04 147 result =
IanBenzMaxim 0:f77ad7f72d04 148 writeMemory(CommandReg, command, sizeof(command) / sizeof(command[0]));
IanBenzMaxim 0:f77ad7f72d04 149 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 150 (*sleep)(shaComputationDelayMs * 2);
IanBenzMaxim 0:f77ad7f72d04 151 }
IanBenzMaxim 0:f77ad7f72d04 152 }
IanBenzMaxim 0:f77ad7f72d04 153 return result;
IanBenzMaxim 0:f77ad7f72d04 154 }
IanBenzMaxim 0:f77ad7f72d04 155
IanBenzMaxim 0:f77ad7f72d04 156 error_code DS2465::computeSlaveSecret(bool swap, int pageNum,
IanBenzMaxim 0:f77ad7f72d04 157 PageRegion region) {
IanBenzMaxim 0:f77ad7f72d04 158 error_code result = make_error_code(ArgumentOutOfRangeError);
IanBenzMaxim 0:f77ad7f72d04 159 if (pageNum >= 0) {
IanBenzMaxim 0:f77ad7f72d04 160 uint_least8_t command[] = {
IanBenzMaxim 0:f77ad7f72d04 161 ComputeSlaveSecretCmd,
IanBenzMaxim 0:f77ad7f72d04 162 static_cast<uint_least8_t>(swap ? (0xC8 | (pageNum << 4) | region)
IanBenzMaxim 0:f77ad7f72d04 163 : 0xBF)};
IanBenzMaxim 0:f77ad7f72d04 164 result =
IanBenzMaxim 0:f77ad7f72d04 165 writeMemory(CommandReg, command, sizeof(command) / sizeof(command[0]));
IanBenzMaxim 0:f77ad7f72d04 166 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 167 (*sleep)(shaComputationDelayMs * 2);
IanBenzMaxim 0:f77ad7f72d04 168 }
IanBenzMaxim 0:f77ad7f72d04 169 }
IanBenzMaxim 0:f77ad7f72d04 170 return result;
IanBenzMaxim 0:f77ad7f72d04 171 }
IanBenzMaxim 0:f77ad7f72d04 172
IanBenzMaxim 0:f77ad7f72d04 173 error_code DS2465::readPage(int pageNum, Page & data) const {
IanBenzMaxim 0:f77ad7f72d04 174 uint_least8_t addr;
IanBenzMaxim 0:f77ad7f72d04 175 switch (pageNum) {
IanBenzMaxim 0:f77ad7f72d04 176 case 0:
IanBenzMaxim 0:f77ad7f72d04 177 addr = UserMemoryPage0;
IanBenzMaxim 0:f77ad7f72d04 178 break;
IanBenzMaxim 0:f77ad7f72d04 179 case 1:
IanBenzMaxim 0:f77ad7f72d04 180 addr = UserMemoryPage1;
IanBenzMaxim 0:f77ad7f72d04 181 break;
IanBenzMaxim 0:f77ad7f72d04 182 default:
IanBenzMaxim 0:f77ad7f72d04 183 return make_error_code(ArgumentOutOfRangeError);
IanBenzMaxim 0:f77ad7f72d04 184 }
IanBenzMaxim 0:f77ad7f72d04 185 return readMemory(addr, data.data(), data.size());
IanBenzMaxim 0:f77ad7f72d04 186 }
IanBenzMaxim 0:f77ad7f72d04 187
IanBenzMaxim 0:f77ad7f72d04 188 error_code DS2465::writePage(int pageNum, const Page & data) {
IanBenzMaxim 0:f77ad7f72d04 189 error_code result = writeMemory(Scratchpad, data.data(), data.size());
IanBenzMaxim 0:f77ad7f72d04 190 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 191 result = copyScratchpad(false, pageNum, false, 0);
IanBenzMaxim 0:f77ad7f72d04 192 }
IanBenzMaxim 0:f77ad7f72d04 193 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 194 (*sleep)(eepromPageWriteDelayMs);
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::writeSegment(int pageNum, int segmentNum,
IanBenzMaxim 0:f77ad7f72d04 200 const Segment & data) {
IanBenzMaxim 0:f77ad7f72d04 201 error_code result = writeMemory(Scratchpad, data.data(), data.size());
IanBenzMaxim 0:f77ad7f72d04 202 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 203 result = copyScratchpad(false, pageNum, true, segmentNum);
IanBenzMaxim 0:f77ad7f72d04 204 }
IanBenzMaxim 0:f77ad7f72d04 205 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 206 (*sleep)(eepromSegmentWriteDelayMs);
IanBenzMaxim 0:f77ad7f72d04 207 }
IanBenzMaxim 0:f77ad7f72d04 208 return result;
IanBenzMaxim 0:f77ad7f72d04 209 }
IanBenzMaxim 0:f77ad7f72d04 210
IanBenzMaxim 0:f77ad7f72d04 211 error_code DS2465::writeMasterSecret(const Hash & masterSecret) {
IanBenzMaxim 0:f77ad7f72d04 212 error_code result =
IanBenzMaxim 0:f77ad7f72d04 213 writeMemory(Scratchpad, masterSecret.data(), masterSecret.size());
IanBenzMaxim 0:f77ad7f72d04 214 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 215 result = copyScratchpad(true, 0, false, 0);
IanBenzMaxim 0:f77ad7f72d04 216 }
IanBenzMaxim 0:f77ad7f72d04 217 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 218 (*sleep)(eepromPageWriteDelayMs);
IanBenzMaxim 0:f77ad7f72d04 219 }
IanBenzMaxim 0:f77ad7f72d04 220 return result;
IanBenzMaxim 0:f77ad7f72d04 221 }
IanBenzMaxim 0:f77ad7f72d04 222
IanBenzMaxim 0:f77ad7f72d04 223 error_code DS2465::copyScratchpad(bool destSecret, int pageNum, bool notFull,
IanBenzMaxim 0:f77ad7f72d04 224 int segmentNum) {
IanBenzMaxim 0:f77ad7f72d04 225 error_code result = make_error_code(ArgumentOutOfRangeError);
IanBenzMaxim 0:f77ad7f72d04 226 if (pageNum >= 0 && segmentNum >= 0) {
IanBenzMaxim 0:f77ad7f72d04 227 uint_least8_t command[] = {
IanBenzMaxim 0:f77ad7f72d04 228 CopyScratchpadCmd,
IanBenzMaxim 0:f77ad7f72d04 229 static_cast<uint_least8_t>(destSecret ? 0
IanBenzMaxim 0:f77ad7f72d04 230 : (0x80 | (pageNum << 4) |
IanBenzMaxim 0:f77ad7f72d04 231 (notFull << 3) | segmentNum))};
IanBenzMaxim 0:f77ad7f72d04 232 result =
IanBenzMaxim 0:f77ad7f72d04 233 writeMemory(CommandReg, command, sizeof(command) / sizeof(command[0]));
IanBenzMaxim 0:f77ad7f72d04 234 }
IanBenzMaxim 0:f77ad7f72d04 235 return result;
IanBenzMaxim 0:f77ad7f72d04 236 }
IanBenzMaxim 0:f77ad7f72d04 237
IanBenzMaxim 0:f77ad7f72d04 238 error_code DS2465::configureLevel(Level level) {
IanBenzMaxim 0:f77ad7f72d04 239 // Check if supported level
IanBenzMaxim 0:f77ad7f72d04 240 if (!((level == NormalLevel) || (level == StrongLevel))) {
IanBenzMaxim 0:f77ad7f72d04 241 return make_error_code(InvalidLevelError);
IanBenzMaxim 0:f77ad7f72d04 242 }
IanBenzMaxim 0:f77ad7f72d04 243 // Check if requested level already set
IanBenzMaxim 0:f77ad7f72d04 244 if (curConfig.getSPU() == (level == StrongLevel)) {
IanBenzMaxim 0:f77ad7f72d04 245 return error_code();
IanBenzMaxim 0:f77ad7f72d04 246 }
IanBenzMaxim 0:f77ad7f72d04 247 // Set the level
IanBenzMaxim 0:f77ad7f72d04 248 Config newConfig = curConfig;
IanBenzMaxim 0:f77ad7f72d04 249 newConfig.setSPU(level == StrongLevel);
IanBenzMaxim 0:f77ad7f72d04 250 return writeConfig(newConfig);
IanBenzMaxim 0:f77ad7f72d04 251 }
IanBenzMaxim 0:f77ad7f72d04 252
IanBenzMaxim 0:f77ad7f72d04 253 error_code DS2465::setLevel(Level newLevel) {
IanBenzMaxim 0:f77ad7f72d04 254 if (newLevel == StrongLevel) {
IanBenzMaxim 0:f77ad7f72d04 255 return make_error_code(InvalidLevelError);
IanBenzMaxim 0:f77ad7f72d04 256 }
IanBenzMaxim 0:f77ad7f72d04 257
IanBenzMaxim 0:f77ad7f72d04 258 return configureLevel(newLevel);
IanBenzMaxim 0:f77ad7f72d04 259 }
IanBenzMaxim 0:f77ad7f72d04 260
IanBenzMaxim 0:f77ad7f72d04 261 error_code DS2465::setSpeed(Speed newSpeed) {
IanBenzMaxim 0:f77ad7f72d04 262 // Check if supported speed
IanBenzMaxim 0:f77ad7f72d04 263 if (!((newSpeed == OverdriveSpeed) || (newSpeed == StandardSpeed))) {
IanBenzMaxim 0:f77ad7f72d04 264 return make_error_code(InvalidSpeedError);
IanBenzMaxim 0:f77ad7f72d04 265 }
IanBenzMaxim 0:f77ad7f72d04 266 // Check if requested speed is already set
IanBenzMaxim 0:f77ad7f72d04 267 if (curConfig.get1WS() == (newSpeed == OverdriveSpeed)) {
IanBenzMaxim 0:f77ad7f72d04 268 return error_code();
IanBenzMaxim 0:f77ad7f72d04 269 }
IanBenzMaxim 0:f77ad7f72d04 270 // Set the speed
IanBenzMaxim 0:f77ad7f72d04 271 Config newConfig = curConfig;
IanBenzMaxim 0:f77ad7f72d04 272 newConfig.set1WS(newSpeed == OverdriveSpeed);
IanBenzMaxim 0:f77ad7f72d04 273 return writeConfig(newConfig);
IanBenzMaxim 0:f77ad7f72d04 274 }
IanBenzMaxim 0:f77ad7f72d04 275
IanBenzMaxim 0:f77ad7f72d04 276 error_code DS2465::triplet(TripletData & data) {
IanBenzMaxim 0:f77ad7f72d04 277 // 1-Wire Triplet (Case B)
IanBenzMaxim 0:f77ad7f72d04 278 // S AD,0 [A] 1WT [A] SS [A] Sr AD,1 [A] [Status] A [Status] A\ P
IanBenzMaxim 0:f77ad7f72d04 279 // \--------/
IanBenzMaxim 0:f77ad7f72d04 280 // Repeat until 1WB bit has changed to 0
IanBenzMaxim 0:f77ad7f72d04 281 // [] indicates from slave
IanBenzMaxim 0:f77ad7f72d04 282 // SS indicates byte containing search direction bit value in msbit
IanBenzMaxim 0:f77ad7f72d04 283
IanBenzMaxim 0:f77ad7f72d04 284 const uint_least8_t command[] = {
IanBenzMaxim 0:f77ad7f72d04 285 OwTripletCmd, static_cast<uint_least8_t>(data.writeBit ? 0x80 : 0x00)};
IanBenzMaxim 0:f77ad7f72d04 286 error_code result =
IanBenzMaxim 0:f77ad7f72d04 287 writeMemory(CommandReg, command, sizeof(command) / sizeof(command[0]));
IanBenzMaxim 0:f77ad7f72d04 288 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 289 uint_least8_t status;
IanBenzMaxim 0:f77ad7f72d04 290 result = pollBusy(&status);
IanBenzMaxim 0:f77ad7f72d04 291 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 292 // check bit results in status byte
IanBenzMaxim 0:f77ad7f72d04 293 data.readBit = ((status & Status_SBR) == Status_SBR);
IanBenzMaxim 0:f77ad7f72d04 294 data.readBitComplement = ((status & Status_TSB) == Status_TSB);
IanBenzMaxim 0:f77ad7f72d04 295 data.writeBit = ((status & Status_DIR) == Status_DIR);
IanBenzMaxim 0:f77ad7f72d04 296 }
IanBenzMaxim 0:f77ad7f72d04 297 }
IanBenzMaxim 0:f77ad7f72d04 298 return result;
IanBenzMaxim 0:f77ad7f72d04 299 }
IanBenzMaxim 0:f77ad7f72d04 300
IanBenzMaxim 0:f77ad7f72d04 301 error_code DS2465::readBlock(uint_least8_t * recvBuf, size_t recvLen) {
IanBenzMaxim 0:f77ad7f72d04 302 // 1-Wire Receive Block (Case A)
IanBenzMaxim 0:f77ad7f72d04 303 // S AD,0 [A] CommandReg [A] 1WRF [A] PR [A] P
IanBenzMaxim 0:f77ad7f72d04 304 // [] indicates from slave
IanBenzMaxim 0:f77ad7f72d04 305 // PR indicates byte containing parameter
IanBenzMaxim 0:f77ad7f72d04 306
IanBenzMaxim 0:f77ad7f72d04 307 error_code result;
IanBenzMaxim 0:f77ad7f72d04 308 while ((recvLen > 0) && !result) {
IanBenzMaxim 0:f77ad7f72d04 309 const uint_least8_t command[] = {
IanBenzMaxim 0:f77ad7f72d04 310 OwReceiveBlockCmd,
IanBenzMaxim 0:f77ad7f72d04 311 static_cast<uint_least8_t>(std::min(recvLen, maxBlockSize))};
IanBenzMaxim 0:f77ad7f72d04 312 result =
IanBenzMaxim 0:f77ad7f72d04 313 writeMemory(CommandReg, command, sizeof(command) / sizeof(command[0]));
IanBenzMaxim 0:f77ad7f72d04 314 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 315 result = pollBusy();
IanBenzMaxim 0:f77ad7f72d04 316 }
IanBenzMaxim 0:f77ad7f72d04 317 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 318 result = readMemory(Scratchpad, recvBuf, command[1]);
IanBenzMaxim 0:f77ad7f72d04 319 }
IanBenzMaxim 0:f77ad7f72d04 320 recvBuf += command[1];
IanBenzMaxim 0:f77ad7f72d04 321 recvLen -= command[1];
IanBenzMaxim 0:f77ad7f72d04 322 }
IanBenzMaxim 0:f77ad7f72d04 323 return result;
IanBenzMaxim 0:f77ad7f72d04 324 }
IanBenzMaxim 0:f77ad7f72d04 325
IanBenzMaxim 0:f77ad7f72d04 326 error_code DS2465::writeBlock(const uint_least8_t * sendBuf, size_t sendLen) {
IanBenzMaxim 0:f77ad7f72d04 327 error_code result;
IanBenzMaxim 0:f77ad7f72d04 328 while ((sendLen > 0) && !result) {
IanBenzMaxim 0:f77ad7f72d04 329 const uint_least8_t command[] = {
IanBenzMaxim 0:f77ad7f72d04 330 OwTransmitBlockCmd,
IanBenzMaxim 0:f77ad7f72d04 331 static_cast<uint_least8_t>(std::min(sendLen, maxBlockSize))};
IanBenzMaxim 0:f77ad7f72d04 332
IanBenzMaxim 0:f77ad7f72d04 333 // prefill scratchpad with required data
IanBenzMaxim 0:f77ad7f72d04 334 result = writeMemory(Scratchpad, sendBuf, command[1]);
IanBenzMaxim 0:f77ad7f72d04 335
IanBenzMaxim 0:f77ad7f72d04 336 // 1-Wire Transmit Block (Case A)
IanBenzMaxim 0:f77ad7f72d04 337 // S AD,0 [A] CommandReg [A] 1WTB [A] PR [A] P
IanBenzMaxim 0:f77ad7f72d04 338 // [] indicates from slave
IanBenzMaxim 0:f77ad7f72d04 339 // PR indicates byte containing parameter
IanBenzMaxim 0:f77ad7f72d04 340 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 341 result = writeMemory(CommandReg, command,
IanBenzMaxim 0:f77ad7f72d04 342 sizeof(command) / sizeof(command[0]));
IanBenzMaxim 0:f77ad7f72d04 343 }
IanBenzMaxim 0:f77ad7f72d04 344 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 345 result = pollBusy();
IanBenzMaxim 0:f77ad7f72d04 346 }
IanBenzMaxim 0:f77ad7f72d04 347 sendBuf += command[1];
IanBenzMaxim 0:f77ad7f72d04 348 sendLen -= command[1];
IanBenzMaxim 0:f77ad7f72d04 349 }
IanBenzMaxim 0:f77ad7f72d04 350 return result;
IanBenzMaxim 0:f77ad7f72d04 351 }
IanBenzMaxim 0:f77ad7f72d04 352
IanBenzMaxim 0:f77ad7f72d04 353 error_code DS2465::writeMacBlock() const {
IanBenzMaxim 0:f77ad7f72d04 354 // 1-Wire Transmit Block (Case A)
IanBenzMaxim 0:f77ad7f72d04 355 // S AD,0 [A] CommandReg [A] 1WTB [A] PR [A] P
IanBenzMaxim 0:f77ad7f72d04 356 // [] indicates from slave
IanBenzMaxim 0:f77ad7f72d04 357 // PR indicates byte containing parameter
IanBenzMaxim 0:f77ad7f72d04 358
IanBenzMaxim 0:f77ad7f72d04 359 const uint_least8_t command[] = {OwTransmitBlockCmd, 0xFF};
IanBenzMaxim 0:f77ad7f72d04 360 error_code result =
IanBenzMaxim 0:f77ad7f72d04 361 writeMemory(CommandReg, command, sizeof(command) / sizeof(command[0]));
IanBenzMaxim 0:f77ad7f72d04 362 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 363 result = pollBusy();
IanBenzMaxim 0:f77ad7f72d04 364 }
IanBenzMaxim 0:f77ad7f72d04 365 return result;
IanBenzMaxim 0:f77ad7f72d04 366 }
IanBenzMaxim 0:f77ad7f72d04 367
IanBenzMaxim 0:f77ad7f72d04 368 error_code DS2465::readByteSetLevel(uint_least8_t & recvByte,
IanBenzMaxim 0:f77ad7f72d04 369 Level afterLevel) {
IanBenzMaxim 0:f77ad7f72d04 370 // 1-Wire Read Bytes (Case C)
IanBenzMaxim 0:f77ad7f72d04 371 // S AD,0 [A] CommandReg [A] 1WRB [A] Sr AD,1 [A] [Status] A [Status] A
IanBenzMaxim 0:f77ad7f72d04 372 // \--------/
IanBenzMaxim 0:f77ad7f72d04 373 // Repeat until 1WB bit has changed to 0
IanBenzMaxim 0:f77ad7f72d04 374 // Sr AD,0 [A] SRP [A] E1 [A] Sr AD,1 [A] DD A\ P
IanBenzMaxim 0:f77ad7f72d04 375 //
IanBenzMaxim 0:f77ad7f72d04 376 // [] indicates from slave
IanBenzMaxim 0:f77ad7f72d04 377 // DD data read
IanBenzMaxim 0:f77ad7f72d04 378
IanBenzMaxim 0:f77ad7f72d04 379 error_code result = configureLevel(afterLevel);
IanBenzMaxim 0:f77ad7f72d04 380 if (result) {
IanBenzMaxim 0:f77ad7f72d04 381 return result;
IanBenzMaxim 0:f77ad7f72d04 382 }
IanBenzMaxim 0:f77ad7f72d04 383
IanBenzMaxim 0:f77ad7f72d04 384 uint_least8_t buf = OwReadByteCmd;
IanBenzMaxim 0:f77ad7f72d04 385 result = writeMemory(CommandReg, &buf, 1);
IanBenzMaxim 0:f77ad7f72d04 386
IanBenzMaxim 0:f77ad7f72d04 387 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 388 result = pollBusy();
IanBenzMaxim 0:f77ad7f72d04 389 }
IanBenzMaxim 0:f77ad7f72d04 390
IanBenzMaxim 0:f77ad7f72d04 391 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 392 result = readMemory(ReadDataReg, &buf, 1);
IanBenzMaxim 0:f77ad7f72d04 393 }
IanBenzMaxim 0:f77ad7f72d04 394
IanBenzMaxim 0:f77ad7f72d04 395 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 396 recvByte = buf;
IanBenzMaxim 0:f77ad7f72d04 397 }
IanBenzMaxim 0:f77ad7f72d04 398
IanBenzMaxim 0:f77ad7f72d04 399 return result;
IanBenzMaxim 0:f77ad7f72d04 400 }
IanBenzMaxim 0:f77ad7f72d04 401
IanBenzMaxim 0:f77ad7f72d04 402 error_code DS2465::writeByteSetLevel(uint_least8_t sendByte, Level afterLevel) {
IanBenzMaxim 0:f77ad7f72d04 403 // 1-Wire Write Byte (Case B)
IanBenzMaxim 0:f77ad7f72d04 404 // S AD,0 [A] CommandReg [A] 1WWB [A] DD [A] Sr AD,1 [A] [Status] A [Status]
IanBenzMaxim 0:f77ad7f72d04 405 // A\ P
IanBenzMaxim 0:f77ad7f72d04 406 // \--------/
IanBenzMaxim 0:f77ad7f72d04 407 // Repeat until 1WB bit has changed to 0
IanBenzMaxim 0:f77ad7f72d04 408 // [] indicates from slave
IanBenzMaxim 0:f77ad7f72d04 409 // DD data to write
IanBenzMaxim 0:f77ad7f72d04 410
IanBenzMaxim 0:f77ad7f72d04 411 error_code result = configureLevel(afterLevel);
IanBenzMaxim 0:f77ad7f72d04 412 if (result) {
IanBenzMaxim 0:f77ad7f72d04 413 return result;
IanBenzMaxim 0:f77ad7f72d04 414 }
IanBenzMaxim 0:f77ad7f72d04 415
IanBenzMaxim 0:f77ad7f72d04 416 const uint_least8_t command[] = {OwWriteByteCmd, sendByte};
IanBenzMaxim 0:f77ad7f72d04 417
IanBenzMaxim 0:f77ad7f72d04 418 result =
IanBenzMaxim 0:f77ad7f72d04 419 writeMemory(CommandReg, command, sizeof(command) / sizeof(command[0]));
IanBenzMaxim 0:f77ad7f72d04 420 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 421 result = pollBusy();
IanBenzMaxim 0:f77ad7f72d04 422 }
IanBenzMaxim 0:f77ad7f72d04 423
IanBenzMaxim 0:f77ad7f72d04 424 return result;
IanBenzMaxim 0:f77ad7f72d04 425 }
IanBenzMaxim 0:f77ad7f72d04 426
IanBenzMaxim 0:f77ad7f72d04 427 error_code DS2465::touchBitSetLevel(bool & sendRecvBit, Level afterLevel) {
IanBenzMaxim 0:f77ad7f72d04 428 // 1-Wire bit (Case B)
IanBenzMaxim 0:f77ad7f72d04 429 // S AD,0 [A] CommandReg [A] 1WSB [A] BB [A] Sr AD,1 [A] [Status] A [Status]
IanBenzMaxim 0:f77ad7f72d04 430 // A\ P
IanBenzMaxim 0:f77ad7f72d04 431 // \--------/
IanBenzMaxim 0:f77ad7f72d04 432 // Repeat until 1WB bit has changed to 0
IanBenzMaxim 0:f77ad7f72d04 433 // [] indicates from slave
IanBenzMaxim 0:f77ad7f72d04 434 // BB indicates byte containing bit value in msbit
IanBenzMaxim 0:f77ad7f72d04 435
IanBenzMaxim 0:f77ad7f72d04 436 error_code result = configureLevel(afterLevel);
IanBenzMaxim 0:f77ad7f72d04 437 if (result) {
IanBenzMaxim 0:f77ad7f72d04 438 return result;
IanBenzMaxim 0:f77ad7f72d04 439 }
IanBenzMaxim 0:f77ad7f72d04 440
IanBenzMaxim 0:f77ad7f72d04 441 const uint_least8_t command[] = {
IanBenzMaxim 0:f77ad7f72d04 442 OwSingleBitCmd, static_cast<uint_least8_t>(sendRecvBit ? 0x80 : 0x00)};
IanBenzMaxim 0:f77ad7f72d04 443 uint_least8_t status;
IanBenzMaxim 0:f77ad7f72d04 444
IanBenzMaxim 0:f77ad7f72d04 445 result =
IanBenzMaxim 0:f77ad7f72d04 446 writeMemory(CommandReg, command, sizeof(command) / sizeof(command[0]));
IanBenzMaxim 0:f77ad7f72d04 447
IanBenzMaxim 0:f77ad7f72d04 448 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 449 result = pollBusy(&status);
IanBenzMaxim 0:f77ad7f72d04 450 }
IanBenzMaxim 0:f77ad7f72d04 451
IanBenzMaxim 0:f77ad7f72d04 452 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 453 sendRecvBit = ((status & Status_SBR) == Status_SBR);
IanBenzMaxim 0:f77ad7f72d04 454 }
IanBenzMaxim 0:f77ad7f72d04 455
IanBenzMaxim 0:f77ad7f72d04 456 return result;
IanBenzMaxim 0:f77ad7f72d04 457 }
IanBenzMaxim 0:f77ad7f72d04 458
IanBenzMaxim 0:f77ad7f72d04 459 error_code DS2465::writeMemory(uint_least8_t addr, const uint_least8_t * buf,
IanBenzMaxim 0:f77ad7f72d04 460 size_t bufLen) const {
IanBenzMaxim 0:f77ad7f72d04 461 // Write SRAM (Case A)
IanBenzMaxim 0:f77ad7f72d04 462 // S AD,0 [A] VSA [A] DD [A] P
IanBenzMaxim 0:f77ad7f72d04 463 // \-----/
IanBenzMaxim 0:f77ad7f72d04 464 // Repeat for each data byte
IanBenzMaxim 0:f77ad7f72d04 465 // [] indicates from slave
IanBenzMaxim 0:f77ad7f72d04 466 // VSA valid SRAM memory address
IanBenzMaxim 0:f77ad7f72d04 467 // DD memory data to write
IanBenzMaxim 0:f77ad7f72d04 468
IanBenzMaxim 0:f77ad7f72d04 469 error_code result = i2cMaster->start(i2cAddress_);
IanBenzMaxim 0:f77ad7f72d04 470 if (result) {
IanBenzMaxim 0:f77ad7f72d04 471 i2cMaster->stop();
IanBenzMaxim 0:f77ad7f72d04 472 return result;
IanBenzMaxim 0:f77ad7f72d04 473 }
IanBenzMaxim 0:f77ad7f72d04 474 result = i2cMaster->writeByte(addr);
IanBenzMaxim 0:f77ad7f72d04 475 if (result) {
IanBenzMaxim 0:f77ad7f72d04 476 i2cMaster->stop();
IanBenzMaxim 0:f77ad7f72d04 477 return result;
IanBenzMaxim 0:f77ad7f72d04 478 }
IanBenzMaxim 0:f77ad7f72d04 479 result = i2cMaster->writeBlock(buf, bufLen);
IanBenzMaxim 0:f77ad7f72d04 480 if (result) {
IanBenzMaxim 0:f77ad7f72d04 481 i2cMaster->stop();
IanBenzMaxim 0:f77ad7f72d04 482 return result;
IanBenzMaxim 0:f77ad7f72d04 483 }
IanBenzMaxim 0:f77ad7f72d04 484 result = i2cMaster->stop();
IanBenzMaxim 0:f77ad7f72d04 485 return result;
IanBenzMaxim 0:f77ad7f72d04 486 }
IanBenzMaxim 0:f77ad7f72d04 487
IanBenzMaxim 0:f77ad7f72d04 488 error_code DS2465::readMemory(uint_least8_t addr, uint_least8_t * buf,
IanBenzMaxim 0:f77ad7f72d04 489 size_t bufLen) const {
IanBenzMaxim 0:f77ad7f72d04 490 // Read (Case A)
IanBenzMaxim 0:f77ad7f72d04 491 // S AD,0 [A] MA [A] Sr AD,1 [A] [DD] A [DD] A\ P
IanBenzMaxim 0:f77ad7f72d04 492 // \-----/
IanBenzMaxim 0:f77ad7f72d04 493 // Repeat for each data byte, NAK last byte
IanBenzMaxim 0:f77ad7f72d04 494 // [] indicates from slave
IanBenzMaxim 0:f77ad7f72d04 495 // MA memory address
IanBenzMaxim 0:f77ad7f72d04 496 // DD memory data read
IanBenzMaxim 0:f77ad7f72d04 497
IanBenzMaxim 0:f77ad7f72d04 498 error_code result = i2cMaster->start(i2cAddress_);
IanBenzMaxim 0:f77ad7f72d04 499 if (result) {
IanBenzMaxim 0:f77ad7f72d04 500 i2cMaster->stop();
IanBenzMaxim 0:f77ad7f72d04 501 return result;
IanBenzMaxim 0:f77ad7f72d04 502 }
IanBenzMaxim 0:f77ad7f72d04 503 result = i2cMaster->writeByte(addr);
IanBenzMaxim 0:f77ad7f72d04 504 if (result) {
IanBenzMaxim 0:f77ad7f72d04 505 i2cMaster->stop();
IanBenzMaxim 0:f77ad7f72d04 506 return result;
IanBenzMaxim 0:f77ad7f72d04 507 }
IanBenzMaxim 0:f77ad7f72d04 508 result = readMemory(buf, bufLen);
IanBenzMaxim 0:f77ad7f72d04 509 return result;
IanBenzMaxim 0:f77ad7f72d04 510 }
IanBenzMaxim 0:f77ad7f72d04 511
IanBenzMaxim 0:f77ad7f72d04 512 error_code DS2465::readMemory(uint_least8_t * buf, size_t bufLen) const {
IanBenzMaxim 0:f77ad7f72d04 513 error_code result = i2cMaster->start(i2cAddress_ | 1);
IanBenzMaxim 0:f77ad7f72d04 514 if (result) {
IanBenzMaxim 0:f77ad7f72d04 515 i2cMaster->stop();
IanBenzMaxim 0:f77ad7f72d04 516 return result;
IanBenzMaxim 0:f77ad7f72d04 517 }
IanBenzMaxim 0:f77ad7f72d04 518 result = i2cMaster->readBlock(I2CMaster::Nack, buf, bufLen);
IanBenzMaxim 0:f77ad7f72d04 519 if (result) {
IanBenzMaxim 0:f77ad7f72d04 520 i2cMaster->stop();
IanBenzMaxim 0:f77ad7f72d04 521 return result;
IanBenzMaxim 0:f77ad7f72d04 522 }
IanBenzMaxim 0:f77ad7f72d04 523 result = i2cMaster->stop();
IanBenzMaxim 0:f77ad7f72d04 524 return result;
IanBenzMaxim 0:f77ad7f72d04 525 }
IanBenzMaxim 0:f77ad7f72d04 526
IanBenzMaxim 0:f77ad7f72d04 527 error_code DS2465::writeConfig(Config config) {
IanBenzMaxim 0:f77ad7f72d04 528 uint_least8_t configBuf = ((config.readByte() ^ 0xF) << 4) | config.readByte();
IanBenzMaxim 0:f77ad7f72d04 529 error_code result = writeMemory(ConfigReg, &configBuf, 1);
IanBenzMaxim 0:f77ad7f72d04 530 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 531 result = readMemory(ConfigReg, &configBuf, 1);
IanBenzMaxim 0:f77ad7f72d04 532 }
IanBenzMaxim 0:f77ad7f72d04 533 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 534 if (configBuf != config.readByte())
IanBenzMaxim 0:f77ad7f72d04 535 result = make_error_code(HardwareError);
IanBenzMaxim 0:f77ad7f72d04 536 }
IanBenzMaxim 0:f77ad7f72d04 537 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 538 curConfig = config;
IanBenzMaxim 0:f77ad7f72d04 539 }
IanBenzMaxim 0:f77ad7f72d04 540 return result;
IanBenzMaxim 0:f77ad7f72d04 541 }
IanBenzMaxim 0:f77ad7f72d04 542
IanBenzMaxim 0:f77ad7f72d04 543 error_code DS2465::writePortParameter(PortParameter param, int val) {
IanBenzMaxim 0:f77ad7f72d04 544 if (val < 0 || val > 15) {
IanBenzMaxim 0:f77ad7f72d04 545 return make_error_code(ArgumentOutOfRangeError);
IanBenzMaxim 0:f77ad7f72d04 546 }
IanBenzMaxim 0:f77ad7f72d04 547
IanBenzMaxim 0:f77ad7f72d04 548 uint_least8_t addr = 0;
IanBenzMaxim 0:f77ad7f72d04 549 switch (param) {
IanBenzMaxim 0:f77ad7f72d04 550 case tRSTL_STD:
IanBenzMaxim 0:f77ad7f72d04 551 case tRSTL_OD:
IanBenzMaxim 0:f77ad7f72d04 552 addr = tRSTL_Reg;
IanBenzMaxim 0:f77ad7f72d04 553 break;
IanBenzMaxim 0:f77ad7f72d04 554 case tMSP_STD:
IanBenzMaxim 0:f77ad7f72d04 555 case tMSP_OD:
IanBenzMaxim 0:f77ad7f72d04 556 addr = tMSP_Reg;
IanBenzMaxim 0:f77ad7f72d04 557 break;
IanBenzMaxim 0:f77ad7f72d04 558 case tW0L_STD:
IanBenzMaxim 0:f77ad7f72d04 559 case tW0L_OD:
IanBenzMaxim 0:f77ad7f72d04 560 addr = tW0L_Reg;
IanBenzMaxim 0:f77ad7f72d04 561 break;
IanBenzMaxim 0:f77ad7f72d04 562 case tREC0:
IanBenzMaxim 0:f77ad7f72d04 563 addr = tREC0_Reg;
IanBenzMaxim 0:f77ad7f72d04 564 break;
IanBenzMaxim 0:f77ad7f72d04 565 case RWPU:
IanBenzMaxim 0:f77ad7f72d04 566 addr = RWPU_Reg;
IanBenzMaxim 0:f77ad7f72d04 567 break;
IanBenzMaxim 0:f77ad7f72d04 568 case tW1L_OD:
IanBenzMaxim 0:f77ad7f72d04 569 addr = tW1L_Reg;
IanBenzMaxim 0:f77ad7f72d04 570 break;
IanBenzMaxim 0:f77ad7f72d04 571 }
IanBenzMaxim 0:f77ad7f72d04 572
IanBenzMaxim 0:f77ad7f72d04 573 uint_least8_t data;
IanBenzMaxim 0:f77ad7f72d04 574 error_code result = readMemory(addr, &data, 1);
IanBenzMaxim 0:f77ad7f72d04 575 if (result) {
IanBenzMaxim 0:f77ad7f72d04 576 return result;
IanBenzMaxim 0:f77ad7f72d04 577 }
IanBenzMaxim 0:f77ad7f72d04 578
IanBenzMaxim 0:f77ad7f72d04 579 uint_least8_t newData;
IanBenzMaxim 0:f77ad7f72d04 580 if (param == tRSTL_OD || param == tMSP_OD || param == tW0L_OD) {
IanBenzMaxim 0:f77ad7f72d04 581 newData = (data & 0x0F) | (val << 4);
IanBenzMaxim 0:f77ad7f72d04 582 } else {
IanBenzMaxim 0:f77ad7f72d04 583 newData = (data & 0xF0) | val;
IanBenzMaxim 0:f77ad7f72d04 584 }
IanBenzMaxim 0:f77ad7f72d04 585
IanBenzMaxim 0:f77ad7f72d04 586 if (newData != data) {
IanBenzMaxim 0:f77ad7f72d04 587 result = writeMemory(addr, &newData, 1);
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::pollBusy(uint_least8_t * pStatus) const {
IanBenzMaxim 0:f77ad7f72d04 593 const int pollLimit = 200;
IanBenzMaxim 0:f77ad7f72d04 594
IanBenzMaxim 0:f77ad7f72d04 595 int pollCount = 0;
IanBenzMaxim 0:f77ad7f72d04 596 uint_least8_t status;
IanBenzMaxim 0:f77ad7f72d04 597 do {
IanBenzMaxim 0:f77ad7f72d04 598 error_code result = readMemory(&status, 1);
IanBenzMaxim 0:f77ad7f72d04 599 if (result) {
IanBenzMaxim 0:f77ad7f72d04 600 return result;
IanBenzMaxim 0:f77ad7f72d04 601 }
IanBenzMaxim 0:f77ad7f72d04 602 if (pStatus != NULL) {
IanBenzMaxim 0:f77ad7f72d04 603 *pStatus = status;
IanBenzMaxim 0:f77ad7f72d04 604 }
IanBenzMaxim 0:f77ad7f72d04 605 if (pollCount++ >= pollLimit) {
IanBenzMaxim 0:f77ad7f72d04 606 return make_error_code(HardwareError);
IanBenzMaxim 0:f77ad7f72d04 607 }
IanBenzMaxim 0:f77ad7f72d04 608 } while (status & Status_1WB);
IanBenzMaxim 0:f77ad7f72d04 609
IanBenzMaxim 0:f77ad7f72d04 610 return error_code();
IanBenzMaxim 0:f77ad7f72d04 611 }
IanBenzMaxim 0:f77ad7f72d04 612
IanBenzMaxim 0:f77ad7f72d04 613 error_code DS2465::reset() {
IanBenzMaxim 0:f77ad7f72d04 614 // 1-Wire reset (Case B)
IanBenzMaxim 0:f77ad7f72d04 615 // S AD,0 [A] CommandReg [A] 1WRS [A] Sr AD,1 [A] [Status] A [Status] A\ P
IanBenzMaxim 0:f77ad7f72d04 616 // \--------/
IanBenzMaxim 0:f77ad7f72d04 617 // Repeat until 1WB bit has changed to 0
IanBenzMaxim 0:f77ad7f72d04 618 // [] indicates from slave
IanBenzMaxim 0:f77ad7f72d04 619
IanBenzMaxim 0:f77ad7f72d04 620 uint_least8_t buf = OwResetCmd;
IanBenzMaxim 0:f77ad7f72d04 621 error_code result = writeMemory(CommandReg, &buf, 1);
IanBenzMaxim 0:f77ad7f72d04 622
IanBenzMaxim 0:f77ad7f72d04 623 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 624 result = pollBusy(&buf);
IanBenzMaxim 0:f77ad7f72d04 625 }
IanBenzMaxim 0:f77ad7f72d04 626
IanBenzMaxim 0:f77ad7f72d04 627 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 628 if ((buf & Status_SD) == Status_SD) {
IanBenzMaxim 0:f77ad7f72d04 629 result = make_error_code(ShortDetectedError);
IanBenzMaxim 0:f77ad7f72d04 630 }
IanBenzMaxim 0:f77ad7f72d04 631 else if ((buf & Status_PPD) != Status_PPD) {
IanBenzMaxim 0:f77ad7f72d04 632 result = make_error_code(NoSlaveError);
IanBenzMaxim 0:f77ad7f72d04 633 }
IanBenzMaxim 0:f77ad7f72d04 634 }
IanBenzMaxim 0:f77ad7f72d04 635
IanBenzMaxim 0:f77ad7f72d04 636 return result;
IanBenzMaxim 0:f77ad7f72d04 637 }
IanBenzMaxim 0:f77ad7f72d04 638
IanBenzMaxim 0:f77ad7f72d04 639 error_code DS2465::resetDevice() {
IanBenzMaxim 0:f77ad7f72d04 640 // Device Reset
IanBenzMaxim 0:f77ad7f72d04 641 // S AD,0 [A] CommandReg [A] 1WMR [A] Sr AD,1 [A] [SS] A\ P
IanBenzMaxim 0:f77ad7f72d04 642 // [] indicates from slave
IanBenzMaxim 0:f77ad7f72d04 643 // SS status byte to read to verify state
IanBenzMaxim 0:f77ad7f72d04 644
IanBenzMaxim 0:f77ad7f72d04 645 uint_least8_t buf = DeviceResetCmd;
IanBenzMaxim 0:f77ad7f72d04 646 error_code result = writeMemory(CommandReg, &buf, 1);
IanBenzMaxim 0:f77ad7f72d04 647
IanBenzMaxim 0:f77ad7f72d04 648 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 649 result = readMemory(&buf, 1);
IanBenzMaxim 0:f77ad7f72d04 650 }
IanBenzMaxim 0:f77ad7f72d04 651
IanBenzMaxim 0:f77ad7f72d04 652 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 653 if ((buf & 0xF7) != 0x10) {
IanBenzMaxim 0:f77ad7f72d04 654 result = make_error_code(HardwareError);
IanBenzMaxim 0:f77ad7f72d04 655 }
IanBenzMaxim 0:f77ad7f72d04 656 }
IanBenzMaxim 0:f77ad7f72d04 657
IanBenzMaxim 0:f77ad7f72d04 658 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 659 reset(); // do a command to get 1-Wire master reset out of holding state
IanBenzMaxim 0:f77ad7f72d04 660 }
IanBenzMaxim 0:f77ad7f72d04 661
IanBenzMaxim 0:f77ad7f72d04 662 return result;
IanBenzMaxim 0:f77ad7f72d04 663 }
IanBenzMaxim 0:f77ad7f72d04 664
IanBenzMaxim 0:f77ad7f72d04 665 error_code DS2465::computeNextMasterSecret(const SlaveSecretData & data) {
IanBenzMaxim 0:f77ad7f72d04 666 error_code result = writeMemory(Scratchpad, data.data(), data.size());
IanBenzMaxim 0:f77ad7f72d04 667 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 668 result = computeNextMasterSecret(false, 0, FullPage);
IanBenzMaxim 0:f77ad7f72d04 669 }
IanBenzMaxim 0:f77ad7f72d04 670 return result;
IanBenzMaxim 0:f77ad7f72d04 671 }
IanBenzMaxim 0:f77ad7f72d04 672
IanBenzMaxim 0:f77ad7f72d04 673 error_code DS2465::computeNextMasterSecretWithSwap(const SlaveSecretData & data,
IanBenzMaxim 0:f77ad7f72d04 674 int pageNum,
IanBenzMaxim 0:f77ad7f72d04 675 PageRegion region) {
IanBenzMaxim 0:f77ad7f72d04 676 error_code result = writeMemory(Scratchpad, data.data(), data.size());
IanBenzMaxim 0:f77ad7f72d04 677 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 678 result = computeNextMasterSecret(true, pageNum, region);
IanBenzMaxim 0:f77ad7f72d04 679 }
IanBenzMaxim 0:f77ad7f72d04 680 return result;
IanBenzMaxim 0:f77ad7f72d04 681 }
IanBenzMaxim 0:f77ad7f72d04 682
IanBenzMaxim 0:f77ad7f72d04 683 error_code DS2465::computeWriteMac(const WriteMacData & data) const {
IanBenzMaxim 0:f77ad7f72d04 684 error_code result = writeMemory(Scratchpad, data.data(), data.size());
IanBenzMaxim 0:f77ad7f72d04 685 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 686 result = computeWriteMac(false, false, 0, 0);
IanBenzMaxim 0:f77ad7f72d04 687 }
IanBenzMaxim 0:f77ad7f72d04 688 return result;
IanBenzMaxim 0:f77ad7f72d04 689 }
IanBenzMaxim 0:f77ad7f72d04 690
IanBenzMaxim 0:f77ad7f72d04 691 error_code DS2465::computeWriteMac(const WriteMacData & data,
IanBenzMaxim 0:f77ad7f72d04 692 Hash & mac) const {
IanBenzMaxim 0:f77ad7f72d04 693 error_code result = computeWriteMac(data);
IanBenzMaxim 0:f77ad7f72d04 694 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 695 result = readMemory(mac.data(), mac.size());
IanBenzMaxim 0:f77ad7f72d04 696 }
IanBenzMaxim 0:f77ad7f72d04 697 return result;
IanBenzMaxim 0:f77ad7f72d04 698 }
IanBenzMaxim 0:f77ad7f72d04 699
IanBenzMaxim 0:f77ad7f72d04 700 error_code DS2465::computeAndTransmitWriteMac(const WriteMacData & data) const {
IanBenzMaxim 0:f77ad7f72d04 701 error_code result = computeWriteMac(data);
IanBenzMaxim 0:f77ad7f72d04 702 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 703 result = writeMacBlock();
IanBenzMaxim 0:f77ad7f72d04 704 }
IanBenzMaxim 0:f77ad7f72d04 705 return result;
IanBenzMaxim 0:f77ad7f72d04 706 }
IanBenzMaxim 0:f77ad7f72d04 707
IanBenzMaxim 0:f77ad7f72d04 708 error_code DS2465::computeWriteMacWithSwap(const WriteMacData & data,
IanBenzMaxim 0:f77ad7f72d04 709 int pageNum, int segmentNum) const {
IanBenzMaxim 0:f77ad7f72d04 710 error_code result = writeMemory(Scratchpad, data.data(), data.size());
IanBenzMaxim 0:f77ad7f72d04 711 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 712 result = computeWriteMac(false, true, pageNum, segmentNum);
IanBenzMaxim 0:f77ad7f72d04 713 }
IanBenzMaxim 0:f77ad7f72d04 714 return result;
IanBenzMaxim 0:f77ad7f72d04 715 }
IanBenzMaxim 0:f77ad7f72d04 716
IanBenzMaxim 0:f77ad7f72d04 717 error_code DS2465::computeWriteMacWithSwap(const WriteMacData & data,
IanBenzMaxim 0:f77ad7f72d04 718 int pageNum, int segmentNum,
IanBenzMaxim 0:f77ad7f72d04 719 Hash & mac) const {
IanBenzMaxim 0:f77ad7f72d04 720 error_code result = computeWriteMacWithSwap(data, pageNum, segmentNum);
IanBenzMaxim 0:f77ad7f72d04 721 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 722 result = readMemory(mac.data(), mac.size());
IanBenzMaxim 0:f77ad7f72d04 723 }
IanBenzMaxim 0:f77ad7f72d04 724 return result;
IanBenzMaxim 0:f77ad7f72d04 725 }
IanBenzMaxim 0:f77ad7f72d04 726
IanBenzMaxim 0:f77ad7f72d04 727 error_code DS2465::computeAndTransmitWriteMacWithSwap(const WriteMacData & data,
IanBenzMaxim 0:f77ad7f72d04 728 int pageNum,
IanBenzMaxim 0:f77ad7f72d04 729 int segmentNum) const {
IanBenzMaxim 0:f77ad7f72d04 730 error_code result = computeWriteMacWithSwap(data, pageNum, segmentNum);
IanBenzMaxim 0:f77ad7f72d04 731 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 732 result = writeMacBlock();
IanBenzMaxim 0:f77ad7f72d04 733 }
IanBenzMaxim 0:f77ad7f72d04 734 return result;
IanBenzMaxim 0:f77ad7f72d04 735 }
IanBenzMaxim 0:f77ad7f72d04 736
IanBenzMaxim 0:f77ad7f72d04 737 error_code DS2465::computeSlaveSecret(const SlaveSecretData & data) {
IanBenzMaxim 0:f77ad7f72d04 738 error_code result = writeMemory(Scratchpad, data.data(), data.size());
IanBenzMaxim 0:f77ad7f72d04 739 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 740 result = computeSlaveSecret(false, 0, FullPage);
IanBenzMaxim 0:f77ad7f72d04 741 }
IanBenzMaxim 0:f77ad7f72d04 742 return result;
IanBenzMaxim 0:f77ad7f72d04 743 }
IanBenzMaxim 0:f77ad7f72d04 744
IanBenzMaxim 0:f77ad7f72d04 745 error_code DS2465::computeSlaveSecretWithSwap(const SlaveSecretData & data,
IanBenzMaxim 0:f77ad7f72d04 746 int pageNum, PageRegion region) {
IanBenzMaxim 0:f77ad7f72d04 747 error_code result = writeMemory(Scratchpad, data.data(), data.size());
IanBenzMaxim 0:f77ad7f72d04 748 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 749 result = computeSlaveSecret(true, pageNum, region);
IanBenzMaxim 0:f77ad7f72d04 750 }
IanBenzMaxim 0:f77ad7f72d04 751 return result;
IanBenzMaxim 0:f77ad7f72d04 752 }
IanBenzMaxim 0:f77ad7f72d04 753
IanBenzMaxim 0:f77ad7f72d04 754 error_code DS2465::computeAuthMac(const AuthMacData & data) const {
IanBenzMaxim 0:f77ad7f72d04 755 error_code result = writeMemory(Scratchpad, data.data(), data.size());
IanBenzMaxim 0:f77ad7f72d04 756 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 757 result = computeAuthMac(false, 0, FullPage);
IanBenzMaxim 0:f77ad7f72d04 758 }
IanBenzMaxim 0:f77ad7f72d04 759 return result;
IanBenzMaxim 0:f77ad7f72d04 760 }
IanBenzMaxim 0:f77ad7f72d04 761
IanBenzMaxim 0:f77ad7f72d04 762 error_code DS2465::computeAuthMac(const AuthMacData & data, Hash & mac) const {
IanBenzMaxim 0:f77ad7f72d04 763 error_code result = computeAuthMac(data);
IanBenzMaxim 0:f77ad7f72d04 764 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 765 result = readMemory(mac.data(), mac.size());
IanBenzMaxim 0:f77ad7f72d04 766 }
IanBenzMaxim 0:f77ad7f72d04 767 return result;
IanBenzMaxim 0:f77ad7f72d04 768 }
IanBenzMaxim 0:f77ad7f72d04 769
IanBenzMaxim 0:f77ad7f72d04 770 error_code DS2465::computeAndTransmitAuthMac(const AuthMacData & data) const {
IanBenzMaxim 0:f77ad7f72d04 771 error_code result = computeAuthMac(data);
IanBenzMaxim 0:f77ad7f72d04 772 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 773 result = writeMacBlock();
IanBenzMaxim 0:f77ad7f72d04 774 }
IanBenzMaxim 0:f77ad7f72d04 775 return result;
IanBenzMaxim 0:f77ad7f72d04 776 }
IanBenzMaxim 0:f77ad7f72d04 777
IanBenzMaxim 0:f77ad7f72d04 778 error_code DS2465::computeAuthMacWithSwap(const AuthMacData & data, int pageNum,
IanBenzMaxim 0:f77ad7f72d04 779 PageRegion region) const {
IanBenzMaxim 0:f77ad7f72d04 780 error_code result = writeMemory(Scratchpad, data.data(), data.size());
IanBenzMaxim 0:f77ad7f72d04 781 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 782 result = computeAuthMac(true, pageNum, region);
IanBenzMaxim 0:f77ad7f72d04 783 }
IanBenzMaxim 0:f77ad7f72d04 784 return result;
IanBenzMaxim 0:f77ad7f72d04 785 }
IanBenzMaxim 0:f77ad7f72d04 786
IanBenzMaxim 0:f77ad7f72d04 787 error_code DS2465::computeAuthMacWithSwap(const AuthMacData & data, int pageNum,
IanBenzMaxim 0:f77ad7f72d04 788 PageRegion region, Hash & mac) const {
IanBenzMaxim 0:f77ad7f72d04 789 error_code result = computeAuthMacWithSwap(data, pageNum, region);
IanBenzMaxim 0:f77ad7f72d04 790 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 791 result = readMemory(mac.data(), mac.size());
IanBenzMaxim 0:f77ad7f72d04 792 }
IanBenzMaxim 0:f77ad7f72d04 793 return result;
IanBenzMaxim 0:f77ad7f72d04 794 }
IanBenzMaxim 0:f77ad7f72d04 795
IanBenzMaxim 0:f77ad7f72d04 796 error_code DS2465::computeAndTransmitAuthMacWithSwap(const AuthMacData & data,
IanBenzMaxim 0:f77ad7f72d04 797 int pageNum,
IanBenzMaxim 0:f77ad7f72d04 798 PageRegion region) const {
IanBenzMaxim 0:f77ad7f72d04 799 error_code result = computeAuthMacWithSwap(data, pageNum, region);
IanBenzMaxim 0:f77ad7f72d04 800 if (!result) {
IanBenzMaxim 0:f77ad7f72d04 801 result = writeMacBlock();
IanBenzMaxim 0:f77ad7f72d04 802 }
IanBenzMaxim 0:f77ad7f72d04 803 return result;
IanBenzMaxim 0:f77ad7f72d04 804 }
IanBenzMaxim 0:f77ad7f72d04 805
IanBenzMaxim 0:f77ad7f72d04 806 const error_category & DS2465::errorCategory() {
IanBenzMaxim 0:f77ad7f72d04 807 static class : public error_category {
IanBenzMaxim 0:f77ad7f72d04 808 public:
IanBenzMaxim 0:f77ad7f72d04 809 virtual const char * name() const { return "DS2465"; }
IanBenzMaxim 0:f77ad7f72d04 810
IanBenzMaxim 0:f77ad7f72d04 811 virtual std::string message(int condition) const {
IanBenzMaxim 0:f77ad7f72d04 812 switch (condition) {
IanBenzMaxim 0:f77ad7f72d04 813 case HardwareError:
IanBenzMaxim 0:f77ad7f72d04 814 return "Hardware Error";
IanBenzMaxim 0:f77ad7f72d04 815
IanBenzMaxim 0:f77ad7f72d04 816 case ArgumentOutOfRangeError:
IanBenzMaxim 0:f77ad7f72d04 817 return "Argument Out of Range Error";
IanBenzMaxim 0:f77ad7f72d04 818
IanBenzMaxim 0:f77ad7f72d04 819 default:
IanBenzMaxim 0:f77ad7f72d04 820 return defaultErrorMessage(condition);
IanBenzMaxim 0:f77ad7f72d04 821 }
IanBenzMaxim 0:f77ad7f72d04 822 }
IanBenzMaxim 0:f77ad7f72d04 823 } instance;
IanBenzMaxim 0:f77ad7f72d04 824 return instance;
IanBenzMaxim 0:f77ad7f72d04 825 }
IanBenzMaxim 0:f77ad7f72d04 826
IanBenzMaxim 0:f77ad7f72d04 827 } // namespace MaximInterface