1-Wire® library for mbed. Complete 1-Wire library that supports our silicon masters along with a bit-bang master on the MAX32600MBED platform with one common interface for mbed. Slave support has also been included and more slaves will be added as time permits.

Dependents:   MAXREFDES131_Qt_Demo MAX32630FTHR_iButton_uSD_Logger MAX32630FTHR_DS18B20_uSD_Logger MAXREFDES130_131_Demo ... more

Superseded by MaximInterface.

Committer:
IanBenzMaxim
Date:
Tue Aug 09 12:35:22 2016 -0500
Revision:
113:13e2865603df
Parent:
104:3f48daed532b
Child:
120:200109b73e3c
Begin splitting DS28E15_22_25 into separate classes.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
IanBenzMaxim 75:8b627804927c 1 /******************************************************************//**
IanBenzMaxim 75:8b627804927c 2 * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
IanBenzMaxim 75:8b627804927c 3 *
IanBenzMaxim 75:8b627804927c 4 * Permission is hereby granted, free of charge, to any person obtaining a
IanBenzMaxim 75:8b627804927c 5 * copy of this software and associated documentation files (the "Software"),
IanBenzMaxim 75:8b627804927c 6 * to deal in the Software without restriction, including without limitation
IanBenzMaxim 75:8b627804927c 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
IanBenzMaxim 75:8b627804927c 8 * and/or sell copies of the Software, and to permit persons to whom the
IanBenzMaxim 75:8b627804927c 9 * Software is furnished to do so, subject to the following conditions:
IanBenzMaxim 75:8b627804927c 10 *
IanBenzMaxim 75:8b627804927c 11 * The above copyright notice and this permission notice shall be included
IanBenzMaxim 75:8b627804927c 12 * in all copies or substantial portions of the Software.
IanBenzMaxim 75:8b627804927c 13 *
IanBenzMaxim 75:8b627804927c 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
IanBenzMaxim 75:8b627804927c 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
IanBenzMaxim 75:8b627804927c 16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IanBenzMaxim 75:8b627804927c 17 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
IanBenzMaxim 75:8b627804927c 18 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
IanBenzMaxim 75:8b627804927c 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
IanBenzMaxim 75:8b627804927c 20 * OTHER DEALINGS IN THE SOFTWARE.
IanBenzMaxim 75:8b627804927c 21 *
IanBenzMaxim 75:8b627804927c 22 * Except as contained in this notice, the name of Maxim Integrated
IanBenzMaxim 75:8b627804927c 23 * Products, Inc. shall not be used except as stated in the Maxim Integrated
IanBenzMaxim 75:8b627804927c 24 * Products, Inc. Branding Policy.
IanBenzMaxim 75:8b627804927c 25 *
IanBenzMaxim 75:8b627804927c 26 * The mere transfer of this software does not imply any licenses
IanBenzMaxim 75:8b627804927c 27 * of trade secrets, proprietary technology, copyrights, patents,
IanBenzMaxim 75:8b627804927c 28 * trademarks, maskwork rights, or any other form of intellectual
IanBenzMaxim 75:8b627804927c 29 * property whatsoever. Maxim Integrated Products, Inc. retains all
IanBenzMaxim 75:8b627804927c 30 * ownership rights.
IanBenzMaxim 75:8b627804927c 31 **********************************************************************/
IanBenzMaxim 25:bdb1c5a53b58 32
IanBenzMaxim 113:13e2865603df 33 #include "DS28E15_22_25.h"
IanBenzMaxim 73:2cecc1372acc 34 #include "Masters/OneWireMaster.h"
IanBenzMaxim 86:2ce08ca58b9e 35 #include "Utilities/crc.h"
IanBenzMaxim 73:2cecc1372acc 36 #include "wait_api.h"
IanBenzMaxim 73:2cecc1372acc 37
IanBenzMaxim 76:84e6c4994e29 38 using namespace OneWire;
IanBenzMaxim 78:0cbbac7f2016 39 using namespace OneWire::crc;
IanBenzMaxim 25:bdb1c5a53b58 40
IanBenzMaxim 49:36954b62f503 41 /// 1-Wire device commands.
IanBenzMaxim 49:36954b62f503 42 enum Command
IanBenzMaxim 49:36954b62f503 43 {
IanBenzMaxim 75:8b627804927c 44 WriteMemory = 0x55,
IanBenzMaxim 75:8b627804927c 45 ReadMemory = 0xF0,
IanBenzMaxim 75:8b627804927c 46 LoadAndLockSecret = 0x33,
IanBenzMaxim 75:8b627804927c 47 ComputeAndLockSecret = 0x3C,
IanBenzMaxim 75:8b627804927c 48 ReadWriteScratchpad = 0x0F,
IanBenzMaxim 75:8b627804927c 49 ComputePageMac = 0xA5,
IanBenzMaxim 75:8b627804927c 50 ReadStatus = 0xAA,
IanBenzMaxim 75:8b627804927c 51 WriteBlockProtection = 0xC3,
IanBenzMaxim 75:8b627804927c 52 AuthWriteMemory = 0x5A,
IanBenzMaxim 75:8b627804927c 53 AuthWriteBlockProtection = 0xCC,
IanBenzMaxim 49:36954b62f503 54 };
IanBenzMaxim 25:bdb1c5a53b58 55
IanBenzMaxim 113:13e2865603df 56 /// Number for memory pages for each device.
IanBenzMaxim 113:13e2865603df 57 enum MemoryPages
IanBenzMaxim 113:13e2865603df 58 {
IanBenzMaxim 113:13e2865603df 59 DS28E25_Pages = 16,
IanBenzMaxim 113:13e2865603df 60 DS28E22_Pages = 8,
IanBenzMaxim 113:13e2865603df 61 DS28E15_Pages = 2
IanBenzMaxim 113:13e2865603df 62 };
IanBenzMaxim 113:13e2865603df 63
IanBenzMaxim 113:13e2865603df 64 /// Number of protection blocks for each device.
IanBenzMaxim 113:13e2865603df 65 enum ProtectionBlocks
IanBenzMaxim 113:13e2865603df 66 {
IanBenzMaxim 113:13e2865603df 67 DS28E25_Blocks = 8,
IanBenzMaxim 113:13e2865603df 68 DS28E22_Blocks = 4,
IanBenzMaxim 113:13e2865603df 69 DS28E15_Blocks = 4
IanBenzMaxim 113:13e2865603df 70 };
IanBenzMaxim 113:13e2865603df 71
IanBenzMaxim 62:43039aeca2ab 72 DS28E15_22_25::Segment DS28E15_22_25::Page::toSegment(unsigned int segmentNum) const
IanBenzMaxim 62:43039aeca2ab 73 {
IanBenzMaxim 74:23be10c32fa3 74 if (segmentNum > (segmentsPerPage - 1))
IanBenzMaxim 74:23be10c32fa3 75 {
IanBenzMaxim 74:23be10c32fa3 76 segmentNum = (segmentsPerPage - 1);
IanBenzMaxim 74:23be10c32fa3 77 }
IanBenzMaxim 74:23be10c32fa3 78 return Segment(*reinterpret_cast<const Segment::Buffer *>(&m_data[segmentNum * sizeof(Segment::Buffer)]));
IanBenzMaxim 62:43039aeca2ab 79 }
IanBenzMaxim 62:43039aeca2ab 80
IanBenzMaxim 62:43039aeca2ab 81 void DS28E15_22_25::Page::fromSegment(unsigned int segmentNum, const Segment & segment)
IanBenzMaxim 62:43039aeca2ab 82 {
IanBenzMaxim 74:23be10c32fa3 83 if (segmentNum > (segmentsPerPage - 1))
IanBenzMaxim 74:23be10c32fa3 84 {
IanBenzMaxim 74:23be10c32fa3 85 segmentNum = (segmentsPerPage - 1);
IanBenzMaxim 74:23be10c32fa3 86 }
IanBenzMaxim 74:23be10c32fa3 87 std::memcpy(&m_data[segmentNum * sizeof(Segment::Buffer)], &static_cast<const Segment::Buffer &>(segment), Segment::length);
IanBenzMaxim 62:43039aeca2ab 88 }
IanBenzMaxim 62:43039aeca2ab 89
IanBenzMaxim 73:2cecc1372acc 90 DS28E15_22_25::BlockProtection::BlockProtection(bool readProtection, bool writeProtection, bool eepromEmulation, bool authProtection, uint8_t blockNum)
IanBenzMaxim 34:11fffbe98ef9 91 {
IanBenzMaxim 74:23be10c32fa3 92 setReadProtection(readProtection);
IanBenzMaxim 74:23be10c32fa3 93 setWriteProtection(writeProtection);
IanBenzMaxim 74:23be10c32fa3 94 setEepromEmulation(eepromEmulation);
IanBenzMaxim 74:23be10c32fa3 95 setAuthProtection(authProtection);
IanBenzMaxim 74:23be10c32fa3 96 setBlockNum(blockNum);
IanBenzMaxim 34:11fffbe98ef9 97 }
IanBenzMaxim 34:11fffbe98ef9 98
IanBenzMaxim 73:2cecc1372acc 99 void DS28E15_22_25::BlockProtection::setBlockNum(uint8_t blockNum)
IanBenzMaxim 34:11fffbe98ef9 100 {
IanBenzMaxim 74:23be10c32fa3 101 m_status &= ~blockNumMask;
IanBenzMaxim 74:23be10c32fa3 102 m_status |= (blockNum & blockNumMask);
IanBenzMaxim 34:11fffbe98ef9 103 }
IanBenzMaxim 34:11fffbe98ef9 104
IanBenzMaxim 34:11fffbe98ef9 105 bool DS28E15_22_25::BlockProtection::noProtection() const
IanBenzMaxim 34:11fffbe98ef9 106 {
IanBenzMaxim 74:23be10c32fa3 107 return !readProtection() && !writeProtection() && !eepromEmulation() && !authProtection();
IanBenzMaxim 34:11fffbe98ef9 108 }
IanBenzMaxim 25:bdb1c5a53b58 109
IanBenzMaxim 34:11fffbe98ef9 110 void DS28E15_22_25::BlockProtection::setReadProtection(bool readProtection)
IanBenzMaxim 34:11fffbe98ef9 111 {
IanBenzMaxim 74:23be10c32fa3 112 if (readProtection)
IanBenzMaxim 74:23be10c32fa3 113 {
IanBenzMaxim 74:23be10c32fa3 114 m_status |= readProtectionMask;
IanBenzMaxim 74:23be10c32fa3 115 }
IanBenzMaxim 74:23be10c32fa3 116 else
IanBenzMaxim 74:23be10c32fa3 117 {
IanBenzMaxim 74:23be10c32fa3 118 m_status &= ~readProtectionMask;
IanBenzMaxim 74:23be10c32fa3 119 }
IanBenzMaxim 34:11fffbe98ef9 120 }
IanBenzMaxim 34:11fffbe98ef9 121
IanBenzMaxim 34:11fffbe98ef9 122 void DS28E15_22_25::BlockProtection::setWriteProtection(bool writeProtection)
IanBenzMaxim 34:11fffbe98ef9 123 {
IanBenzMaxim 74:23be10c32fa3 124 if (writeProtection)
IanBenzMaxim 74:23be10c32fa3 125 {
IanBenzMaxim 74:23be10c32fa3 126 m_status |= writeProtectionMask;
IanBenzMaxim 74:23be10c32fa3 127 }
IanBenzMaxim 74:23be10c32fa3 128 else
IanBenzMaxim 74:23be10c32fa3 129 {
IanBenzMaxim 74:23be10c32fa3 130 m_status &= ~writeProtectionMask;
IanBenzMaxim 74:23be10c32fa3 131 }
IanBenzMaxim 34:11fffbe98ef9 132 }
IanBenzMaxim 25:bdb1c5a53b58 133
IanBenzMaxim 34:11fffbe98ef9 134 void DS28E15_22_25::BlockProtection::setEepromEmulation(bool eepromEmulation)
IanBenzMaxim 34:11fffbe98ef9 135 {
IanBenzMaxim 74:23be10c32fa3 136 if (eepromEmulation)
IanBenzMaxim 74:23be10c32fa3 137 {
IanBenzMaxim 74:23be10c32fa3 138 m_status |= eepromEmulationMask;
IanBenzMaxim 74:23be10c32fa3 139 }
IanBenzMaxim 74:23be10c32fa3 140 else
IanBenzMaxim 74:23be10c32fa3 141 {
IanBenzMaxim 74:23be10c32fa3 142 m_status &= ~eepromEmulationMask;
IanBenzMaxim 74:23be10c32fa3 143 }
IanBenzMaxim 34:11fffbe98ef9 144 }
IanBenzMaxim 34:11fffbe98ef9 145
IanBenzMaxim 34:11fffbe98ef9 146 void DS28E15_22_25::BlockProtection::setAuthProtection(bool authProtection)
IanBenzMaxim 34:11fffbe98ef9 147 {
IanBenzMaxim 74:23be10c32fa3 148 if (authProtection)
IanBenzMaxim 74:23be10c32fa3 149 {
IanBenzMaxim 74:23be10c32fa3 150 m_status |= authProtectionMask;
IanBenzMaxim 74:23be10c32fa3 151 }
IanBenzMaxim 74:23be10c32fa3 152 else
IanBenzMaxim 74:23be10c32fa3 153 {
IanBenzMaxim 74:23be10c32fa3 154 m_status &= ~authProtectionMask;
IanBenzMaxim 74:23be10c32fa3 155 }
IanBenzMaxim 34:11fffbe98ef9 156 }
IanBenzMaxim 34:11fffbe98ef9 157
IanBenzMaxim 113:13e2865603df 158 DS28E15_22_25::DS28E15_22_25(RandomAccessRomIterator & selector, bool lowVoltage, FamilyCode variant)
IanBenzMaxim 113:13e2865603df 159 : OneWireSlave(selector), m_lowVoltage(lowVoltage), m_variant(variant)
IanBenzMaxim 25:bdb1c5a53b58 160 {
IanBenzMaxim 82:c11090a32471 161 std::memset(m_manId, 0x00, m_manId.length);
IanBenzMaxim 25:bdb1c5a53b58 162 }
IanBenzMaxim 25:bdb1c5a53b58 163
IanBenzMaxim 74:23be10c32fa3 164 OneWireSlave::CmdResult DS28E15_22_25::writeAuthBlockProtection(const ISha256MacCoproc & MacCoproc, const BlockProtection & newProtection, const BlockProtection & oldProtection)
IanBenzMaxim 25:bdb1c5a53b58 165 {
IanBenzMaxim 74:23be10c32fa3 166 uint8_t buf[256], cs;
IanBenzMaxim 74:23be10c32fa3 167 int cnt = 0;
IanBenzMaxim 74:23be10c32fa3 168 Mac mac;
IanBenzMaxim 77:529edb329ee0 169
IanBenzMaxim 77:529edb329ee0 170 if (selectDevice() != OneWireMaster::Success)
IanBenzMaxim 77:529edb329ee0 171 {
IanBenzMaxim 77:529edb329ee0 172 return CommunicationError;
IanBenzMaxim 77:529edb329ee0 173 }
IanBenzMaxim 74:23be10c32fa3 174
IanBenzMaxim 75:8b627804927c 175 buf[cnt++] = AuthWriteBlockProtection;
IanBenzMaxim 74:23be10c32fa3 176 buf[cnt++] = newProtection.statusByte();
IanBenzMaxim 25:bdb1c5a53b58 177
IanBenzMaxim 74:23be10c32fa3 178 // Send command
IanBenzMaxim 77:529edb329ee0 179 master().OWWriteBlock(&buf[0], 2);
IanBenzMaxim 25:bdb1c5a53b58 180
IanBenzMaxim 74:23be10c32fa3 181 // read first CRC byte
IanBenzMaxim 77:529edb329ee0 182 master().OWReadByte(buf[cnt++]);
IanBenzMaxim 74:23be10c32fa3 183
IanBenzMaxim 74:23be10c32fa3 184 // read the last CRC and enable
IanBenzMaxim 77:529edb329ee0 185 master().OWReadBytePower(buf[cnt++]);
IanBenzMaxim 25:bdb1c5a53b58 186
IanBenzMaxim 74:23be10c32fa3 187 // now wait for the MAC computation.
IanBenzMaxim 74:23be10c32fa3 188 wait_ms(shaComputationDelayMs);
IanBenzMaxim 25:bdb1c5a53b58 189
IanBenzMaxim 74:23be10c32fa3 190 // disable strong pullup
IanBenzMaxim 77:529edb329ee0 191 master().OWSetLevel(OneWireMaster::NormalLevel);
IanBenzMaxim 25:bdb1c5a53b58 192
IanBenzMaxim 74:23be10c32fa3 193 // check CRC16
IanBenzMaxim 78:0cbbac7f2016 194 if (calculateCrc16(buf, 0, cnt) != 0xB001)
IanBenzMaxim 74:23be10c32fa3 195 {
IanBenzMaxim 77:529edb329ee0 196 return CrcError;
IanBenzMaxim 74:23be10c32fa3 197 }
IanBenzMaxim 25:bdb1c5a53b58 198
IanBenzMaxim 74:23be10c32fa3 199 ISha256MacCoproc::CmdResult result;
IanBenzMaxim 82:c11090a32471 200 result = computeProtectionWriteMac(MacCoproc, newProtection, oldProtection, romId(), manId(), mac);
IanBenzMaxim 74:23be10c32fa3 201 if (result != ISha256MacCoproc::Success)
IanBenzMaxim 74:23be10c32fa3 202 {
IanBenzMaxim 74:23be10c32fa3 203 return OperationFailure;
IanBenzMaxim 74:23be10c32fa3 204 }
IanBenzMaxim 74:23be10c32fa3 205 cnt = 0;
IanBenzMaxim 25:bdb1c5a53b58 206
IanBenzMaxim 74:23be10c32fa3 207 // send the MAC
IanBenzMaxim 77:529edb329ee0 208 master().OWWriteBlock(mac, mac.length);
IanBenzMaxim 74:23be10c32fa3 209
IanBenzMaxim 74:23be10c32fa3 210 // Read CRC and CS byte
IanBenzMaxim 77:529edb329ee0 211 master().OWReadBlock(&buf[cnt], 3);
IanBenzMaxim 74:23be10c32fa3 212 cnt += 3;
IanBenzMaxim 25:bdb1c5a53b58 213
IanBenzMaxim 74:23be10c32fa3 214 // check CRC16
IanBenzMaxim 78:0cbbac7f2016 215 if (calculateCrc16(buf, 0, (cnt - 1), calculateCrc16(mac, 0, mac.length)) != 0xB001)
IanBenzMaxim 74:23be10c32fa3 216 {
IanBenzMaxim 77:529edb329ee0 217 return CrcError;
IanBenzMaxim 74:23be10c32fa3 218 }
IanBenzMaxim 25:bdb1c5a53b58 219
IanBenzMaxim 74:23be10c32fa3 220 // check CS
IanBenzMaxim 74:23be10c32fa3 221 if (buf[cnt - 1] != 0xAA)
IanBenzMaxim 74:23be10c32fa3 222 {
IanBenzMaxim 74:23be10c32fa3 223 return OperationFailure;
IanBenzMaxim 74:23be10c32fa3 224 }
IanBenzMaxim 25:bdb1c5a53b58 225
IanBenzMaxim 74:23be10c32fa3 226 // send release and strong pull-up
IanBenzMaxim 74:23be10c32fa3 227 // DATASHEET_CORRECTION - last bit in release is a read-zero so don't check echo of write byte
IanBenzMaxim 77:529edb329ee0 228 master().OWWriteBytePower(0xAA);
IanBenzMaxim 25:bdb1c5a53b58 229
IanBenzMaxim 74:23be10c32fa3 230 // now wait for the programming.
IanBenzMaxim 74:23be10c32fa3 231 wait_ms(eepromWriteDelayMs);
IanBenzMaxim 74:23be10c32fa3 232
IanBenzMaxim 74:23be10c32fa3 233 // disable strong pullup
IanBenzMaxim 77:529edb329ee0 234 master().OWSetLevel(OneWireMaster::NormalLevel);
IanBenzMaxim 25:bdb1c5a53b58 235
IanBenzMaxim 74:23be10c32fa3 236 // read the CS byte
IanBenzMaxim 77:529edb329ee0 237 master().OWReadByte(cs);
IanBenzMaxim 25:bdb1c5a53b58 238
IanBenzMaxim 74:23be10c32fa3 239 if (cs == 0xAA)
IanBenzMaxim 74:23be10c32fa3 240 {
IanBenzMaxim 74:23be10c32fa3 241 return Success;
IanBenzMaxim 74:23be10c32fa3 242 }
IanBenzMaxim 74:23be10c32fa3 243 // else
IanBenzMaxim 74:23be10c32fa3 244 return OperationFailure;
IanBenzMaxim 25:bdb1c5a53b58 245 }
IanBenzMaxim 25:bdb1c5a53b58 246
IanBenzMaxim 74:23be10c32fa3 247 OneWireSlave::CmdResult DS28E15_22_25::writeBlockProtection(const BlockProtection & protection)
IanBenzMaxim 25:bdb1c5a53b58 248 {
IanBenzMaxim 74:23be10c32fa3 249 uint8_t buf[256], cs;
IanBenzMaxim 74:23be10c32fa3 250 int cnt = 0;
IanBenzMaxim 77:529edb329ee0 251
IanBenzMaxim 77:529edb329ee0 252 if (selectDevice() != OneWireMaster::Success)
IanBenzMaxim 77:529edb329ee0 253 {
IanBenzMaxim 77:529edb329ee0 254 return CommunicationError;
IanBenzMaxim 77:529edb329ee0 255 }
IanBenzMaxim 25:bdb1c5a53b58 256
IanBenzMaxim 75:8b627804927c 257 buf[cnt++] = WriteBlockProtection;
IanBenzMaxim 25:bdb1c5a53b58 258
IanBenzMaxim 74:23be10c32fa3 259 // compute parameter byte
IanBenzMaxim 74:23be10c32fa3 260 buf[cnt++] = protection.statusByte();
IanBenzMaxim 25:bdb1c5a53b58 261
IanBenzMaxim 77:529edb329ee0 262 master().OWWriteBlock(&buf[0], cnt);
IanBenzMaxim 25:bdb1c5a53b58 263
IanBenzMaxim 74:23be10c32fa3 264 // Read CRC
IanBenzMaxim 77:529edb329ee0 265 master().OWReadBlock(&buf[cnt], 2);
IanBenzMaxim 74:23be10c32fa3 266 cnt += 2;
IanBenzMaxim 25:bdb1c5a53b58 267
IanBenzMaxim 74:23be10c32fa3 268 // check CRC16
IanBenzMaxim 78:0cbbac7f2016 269 if (calculateCrc16(buf, 0, cnt) != 0xB001)
IanBenzMaxim 74:23be10c32fa3 270 {
IanBenzMaxim 77:529edb329ee0 271 return CrcError;
IanBenzMaxim 74:23be10c32fa3 272 }
IanBenzMaxim 25:bdb1c5a53b58 273
IanBenzMaxim 74:23be10c32fa3 274 // sent release
IanBenzMaxim 77:529edb329ee0 275 master().OWWriteBytePower(0xAA);
IanBenzMaxim 25:bdb1c5a53b58 276
IanBenzMaxim 74:23be10c32fa3 277 // now wait for the programming.
IanBenzMaxim 74:23be10c32fa3 278 wait_ms(eepromWriteDelayMs);
IanBenzMaxim 25:bdb1c5a53b58 279
IanBenzMaxim 74:23be10c32fa3 280 // disable strong pullup
IanBenzMaxim 77:529edb329ee0 281 master().OWSetLevel(OneWireMaster::NormalLevel);
IanBenzMaxim 74:23be10c32fa3 282
IanBenzMaxim 74:23be10c32fa3 283 // read the CS byte
IanBenzMaxim 77:529edb329ee0 284 master().OWReadByte(cs);
IanBenzMaxim 25:bdb1c5a53b58 285
IanBenzMaxim 74:23be10c32fa3 286 if (cs == 0xAA)
IanBenzMaxim 74:23be10c32fa3 287 {
IanBenzMaxim 74:23be10c32fa3 288 return Success;
IanBenzMaxim 74:23be10c32fa3 289 }
IanBenzMaxim 74:23be10c32fa3 290 // else
IanBenzMaxim 74:23be10c32fa3 291 return OperationFailure;
IanBenzMaxim 25:bdb1c5a53b58 292 }
IanBenzMaxim 25:bdb1c5a53b58 293
IanBenzMaxim 34:11fffbe98ef9 294 OneWireSlave::CmdResult DS28E15_22_25::readBlockProtection(unsigned int blockNum, BlockProtection & protection)
IanBenzMaxim 25:bdb1c5a53b58 295 {
IanBenzMaxim 74:23be10c32fa3 296 uint8_t buf;
IanBenzMaxim 77:529edb329ee0 297 CmdResult result;
IanBenzMaxim 77:529edb329ee0 298
IanBenzMaxim 77:529edb329ee0 299 result = readStatus(false, false, blockNum, &buf);
IanBenzMaxim 74:23be10c32fa3 300 if (result == Success)
IanBenzMaxim 74:23be10c32fa3 301 {
IanBenzMaxim 74:23be10c32fa3 302 protection.setStatusByte(buf);
IanBenzMaxim 74:23be10c32fa3 303 }
IanBenzMaxim 74:23be10c32fa3 304 return result;
IanBenzMaxim 25:bdb1c5a53b58 305 }
IanBenzMaxim 25:bdb1c5a53b58 306
IanBenzMaxim 51:a65f031e997b 307 OneWireSlave::CmdResult DS28E15_22_25::readPersonality(Personality & personality) const
IanBenzMaxim 50:e967f9befbd0 308 {
IanBenzMaxim 74:23be10c32fa3 309 return readStatus(true, false, 0, personality.bytes);
IanBenzMaxim 50:e967f9befbd0 310 }
IanBenzMaxim 50:e967f9befbd0 311
IanBenzMaxim 73:2cecc1372acc 312 OneWireSlave::CmdResult DS28E15_22_25::readStatus(bool personality, bool allpages, unsigned int blockNum, uint8_t * rdbuf) const
IanBenzMaxim 50:e967f9befbd0 313 {
IanBenzMaxim 74:23be10c32fa3 314 const size_t crcLen = 4, ds28e22_25_pagesPerBlock = 2;
IanBenzMaxim 74:23be10c32fa3 315
IanBenzMaxim 74:23be10c32fa3 316 uint8_t buf[256];
IanBenzMaxim 74:23be10c32fa3 317 size_t cnt = 0, offset = 0;
IanBenzMaxim 77:529edb329ee0 318
IanBenzMaxim 77:529edb329ee0 319 if (selectDevice() != OneWireMaster::Success)
IanBenzMaxim 77:529edb329ee0 320 {
IanBenzMaxim 77:529edb329ee0 321 return CommunicationError;
IanBenzMaxim 77:529edb329ee0 322 }
IanBenzMaxim 25:bdb1c5a53b58 323
IanBenzMaxim 75:8b627804927c 324 buf[cnt++] = ReadStatus;
IanBenzMaxim 74:23be10c32fa3 325 if (personality)
IanBenzMaxim 74:23be10c32fa3 326 {
IanBenzMaxim 74:23be10c32fa3 327 buf[cnt++] = 0xE0;
IanBenzMaxim 74:23be10c32fa3 328 }
IanBenzMaxim 74:23be10c32fa3 329 else if (allpages)
IanBenzMaxim 74:23be10c32fa3 330 {
IanBenzMaxim 74:23be10c32fa3 331 buf[cnt++] = 0;
IanBenzMaxim 74:23be10c32fa3 332 }
IanBenzMaxim 74:23be10c32fa3 333 else
IanBenzMaxim 74:23be10c32fa3 334 {
IanBenzMaxim 74:23be10c32fa3 335 // Convert to page number for DS28E22 and DS28E25
IanBenzMaxim 74:23be10c32fa3 336 buf[cnt] = blockNum;
IanBenzMaxim 113:13e2865603df 337 if ((m_variant == DS28E25_Family) || (m_variant == DS28E22_Family))
IanBenzMaxim 74:23be10c32fa3 338 {
IanBenzMaxim 74:23be10c32fa3 339 buf[cnt] *= ds28e22_25_pagesPerBlock;
IanBenzMaxim 74:23be10c32fa3 340 }
IanBenzMaxim 74:23be10c32fa3 341 cnt++;
IanBenzMaxim 74:23be10c32fa3 342 }
IanBenzMaxim 25:bdb1c5a53b58 343
IanBenzMaxim 74:23be10c32fa3 344 // send the command
IanBenzMaxim 77:529edb329ee0 345 master().OWWriteBlock(&buf[0], 2);
IanBenzMaxim 50:e967f9befbd0 346
IanBenzMaxim 74:23be10c32fa3 347 offset = cnt + 2;
IanBenzMaxim 50:e967f9befbd0 348
IanBenzMaxim 74:23be10c32fa3 349 // Set data length
IanBenzMaxim 74:23be10c32fa3 350 size_t rdnum;
IanBenzMaxim 74:23be10c32fa3 351 if (personality)
IanBenzMaxim 74:23be10c32fa3 352 {
IanBenzMaxim 74:23be10c32fa3 353 rdnum = 4;
IanBenzMaxim 74:23be10c32fa3 354 }
IanBenzMaxim 74:23be10c32fa3 355 else if (!allpages)
IanBenzMaxim 74:23be10c32fa3 356 {
IanBenzMaxim 74:23be10c32fa3 357 rdnum = 1;
IanBenzMaxim 74:23be10c32fa3 358 }
IanBenzMaxim 113:13e2865603df 359 else if ((m_variant == DS28E22_Family) || (m_variant == DS28E25_Family))
IanBenzMaxim 74:23be10c32fa3 360 {
IanBenzMaxim 75:8b627804927c 361 rdnum = DS28E25_Pages; // Need to read extra data on DS28E22 to get CRC16.
IanBenzMaxim 74:23be10c32fa3 362 }
IanBenzMaxim 74:23be10c32fa3 363 else // DS28E15
IanBenzMaxim 74:23be10c32fa3 364 {
IanBenzMaxim 75:8b627804927c 365 rdnum = DS28E15_Blocks;
IanBenzMaxim 74:23be10c32fa3 366 }
IanBenzMaxim 74:23be10c32fa3 367 rdnum += crcLen; // Add in CRC length
IanBenzMaxim 50:e967f9befbd0 368
IanBenzMaxim 74:23be10c32fa3 369 // Read the bytes
IanBenzMaxim 77:529edb329ee0 370 master().OWReadBlock(&buf[cnt], rdnum);
IanBenzMaxim 74:23be10c32fa3 371 cnt += rdnum;
IanBenzMaxim 50:e967f9befbd0 372
IanBenzMaxim 74:23be10c32fa3 373 // check the first CRC16
IanBenzMaxim 78:0cbbac7f2016 374 if (calculateCrc16(buf, 0, offset) != 0xB001)
IanBenzMaxim 74:23be10c32fa3 375 {
IanBenzMaxim 77:529edb329ee0 376 return CrcError;
IanBenzMaxim 74:23be10c32fa3 377 }
IanBenzMaxim 25:bdb1c5a53b58 378
IanBenzMaxim 74:23be10c32fa3 379 if (personality || allpages)
IanBenzMaxim 74:23be10c32fa3 380 {
IanBenzMaxim 74:23be10c32fa3 381 // check the second CRC16
IanBenzMaxim 78:0cbbac7f2016 382 if (calculateCrc16(buf, offset, (cnt - offset)) != 0xB001)
IanBenzMaxim 74:23be10c32fa3 383 {
IanBenzMaxim 77:529edb329ee0 384 return CrcError;
IanBenzMaxim 74:23be10c32fa3 385 }
IanBenzMaxim 74:23be10c32fa3 386 }
IanBenzMaxim 25:bdb1c5a53b58 387
IanBenzMaxim 74:23be10c32fa3 388 // copy the data to the read buffer
IanBenzMaxim 74:23be10c32fa3 389 rdnum -= crcLen;
IanBenzMaxim 113:13e2865603df 390 if (allpages && ((m_variant == DS28E25_Family) || (m_variant == DS28E22_Family)))
IanBenzMaxim 50:e967f9befbd0 391 {
IanBenzMaxim 113:13e2865603df 392 if (m_variant == DS28E22_Family)
IanBenzMaxim 74:23be10c32fa3 393 {
IanBenzMaxim 75:8b627804927c 394 rdnum -= (DS28E25_Pages - DS28E22_Pages);
IanBenzMaxim 74:23be10c32fa3 395 }
IanBenzMaxim 74:23be10c32fa3 396
IanBenzMaxim 74:23be10c32fa3 397 for (size_t i = 0; i < (rdnum / ds28e22_25_pagesPerBlock); i++)
IanBenzMaxim 74:23be10c32fa3 398 {
IanBenzMaxim 74:23be10c32fa3 399 rdbuf[i] = (buf[offset + (i * ds28e22_25_pagesPerBlock)] & 0xF0); // Upper nibble
IanBenzMaxim 74:23be10c32fa3 400 rdbuf[i] |= ((buf[offset + (i * ds28e22_25_pagesPerBlock)] & 0x0F) / ds28e22_25_pagesPerBlock); // Lower nibble
IanBenzMaxim 74:23be10c32fa3 401 }
IanBenzMaxim 50:e967f9befbd0 402 }
IanBenzMaxim 74:23be10c32fa3 403 else
IanBenzMaxim 74:23be10c32fa3 404 {
IanBenzMaxim 74:23be10c32fa3 405 std::memcpy(rdbuf, &buf[offset], rdnum);
IanBenzMaxim 74:23be10c32fa3 406 }
IanBenzMaxim 25:bdb1c5a53b58 407
IanBenzMaxim 74:23be10c32fa3 408 return Success;
IanBenzMaxim 25:bdb1c5a53b58 409 }
IanBenzMaxim 25:bdb1c5a53b58 410
IanBenzMaxim 73:2cecc1372acc 411 ISha256MacCoproc::CmdResult DS28E15_22_25::computeAuthMac(const ISha256MacCoproc & MacCoproc, const Page & pageData, unsigned int pageNum, const Scratchpad & challenge, const RomId & romId, const ManId & manId, Mac & mac)
IanBenzMaxim 25:bdb1c5a53b58 412 {
IanBenzMaxim 74:23be10c32fa3 413 ISha256MacCoproc::AuthMacData authMacData;
IanBenzMaxim 49:36954b62f503 414
IanBenzMaxim 74:23be10c32fa3 415 // insert ROM number or FF
IanBenzMaxim 74:23be10c32fa3 416 std::memcpy(authMacData, romId, RomId::byteLen);
IanBenzMaxim 49:36954b62f503 417
IanBenzMaxim 74:23be10c32fa3 418 authMacData[10] = pageNum;
IanBenzMaxim 25:bdb1c5a53b58 419
IanBenzMaxim 74:23be10c32fa3 420 authMacData[9] = manId[0];
IanBenzMaxim 74:23be10c32fa3 421 authMacData[8] = manId[1];
IanBenzMaxim 25:bdb1c5a53b58 422
IanBenzMaxim 74:23be10c32fa3 423 authMacData[11] = 0x00;
IanBenzMaxim 25:bdb1c5a53b58 424
IanBenzMaxim 74:23be10c32fa3 425 return MacCoproc.computeAuthMac(ISha256MacCoproc::DevicePage(pageData), challenge, authMacData, mac);
IanBenzMaxim 25:bdb1c5a53b58 426 }
IanBenzMaxim 25:bdb1c5a53b58 427
IanBenzMaxim 73:2cecc1372acc 428 ISha256MacCoproc::CmdResult DS28E15_22_25::computeAuthMacAnon(const ISha256MacCoproc & MacCoproc, const Page & pageData, unsigned int pageNum, const Scratchpad & challenge, const ManId & manId, Mac & mac)
IanBenzMaxim 49:36954b62f503 429 {
IanBenzMaxim 74:23be10c32fa3 430 RomId romId;
IanBenzMaxim 74:23be10c32fa3 431 std::memset(romId, 0xFF, RomId::byteLen);
IanBenzMaxim 74:23be10c32fa3 432 return computeAuthMac(MacCoproc, pageData, pageNum, challenge, romId, manId, mac);
IanBenzMaxim 49:36954b62f503 433 }
IanBenzMaxim 49:36954b62f503 434
IanBenzMaxim 74:23be10c32fa3 435 OneWireSlave::CmdResult DS28E15_22_25::computeReadPageMac(unsigned int page_num, bool anon, Mac & mac) const
IanBenzMaxim 25:bdb1c5a53b58 436 {
IanBenzMaxim 74:23be10c32fa3 437 uint8_t buf[256], cs;
IanBenzMaxim 74:23be10c32fa3 438 int cnt = 0;
IanBenzMaxim 77:529edb329ee0 439
IanBenzMaxim 77:529edb329ee0 440 if (selectDevice() != OneWireMaster::Success)
IanBenzMaxim 77:529edb329ee0 441 {
IanBenzMaxim 77:529edb329ee0 442 return CommunicationError;
IanBenzMaxim 77:529edb329ee0 443 }
IanBenzMaxim 25:bdb1c5a53b58 444
IanBenzMaxim 75:8b627804927c 445 buf[cnt++] = ComputePageMac;
IanBenzMaxim 74:23be10c32fa3 446 buf[cnt++] = ((anon) ? 0xE0 : 0x00) | page_num;
IanBenzMaxim 74:23be10c32fa3 447
IanBenzMaxim 74:23be10c32fa3 448 // Send command
IanBenzMaxim 77:529edb329ee0 449 master().OWWriteBlock(&buf[0], 2);
IanBenzMaxim 25:bdb1c5a53b58 450
IanBenzMaxim 74:23be10c32fa3 451 // read first CRC byte
IanBenzMaxim 77:529edb329ee0 452 master().OWReadByte(buf[cnt++]);
IanBenzMaxim 25:bdb1c5a53b58 453
IanBenzMaxim 74:23be10c32fa3 454 // read the last CRC and enable
IanBenzMaxim 77:529edb329ee0 455 master().OWReadBytePower(buf[cnt++]);
IanBenzMaxim 25:bdb1c5a53b58 456
IanBenzMaxim 74:23be10c32fa3 457 // now wait for the MAC computation.
IanBenzMaxim 74:23be10c32fa3 458 wait_ms(shaComputationDelayMs * 2);
IanBenzMaxim 25:bdb1c5a53b58 459
IanBenzMaxim 74:23be10c32fa3 460 // disable strong pullup
IanBenzMaxim 77:529edb329ee0 461 master().OWSetLevel(OneWireMaster::NormalLevel);
IanBenzMaxim 25:bdb1c5a53b58 462
IanBenzMaxim 74:23be10c32fa3 463 // check CRC16
IanBenzMaxim 78:0cbbac7f2016 464 if (calculateCrc16(buf, 0, cnt) != 0xB001)
IanBenzMaxim 74:23be10c32fa3 465 {
IanBenzMaxim 77:529edb329ee0 466 return CrcError;
IanBenzMaxim 74:23be10c32fa3 467 }
IanBenzMaxim 25:bdb1c5a53b58 468
IanBenzMaxim 74:23be10c32fa3 469 // read the CS byte
IanBenzMaxim 77:529edb329ee0 470 master().OWReadByte(cs);
IanBenzMaxim 74:23be10c32fa3 471 if (cs != 0xAA)
IanBenzMaxim 74:23be10c32fa3 472 {
IanBenzMaxim 74:23be10c32fa3 473 return OperationFailure;
IanBenzMaxim 74:23be10c32fa3 474 }
IanBenzMaxim 25:bdb1c5a53b58 475
IanBenzMaxim 74:23be10c32fa3 476 // read the MAC and CRC
IanBenzMaxim 77:529edb329ee0 477 master().OWReadBlock(&buf[0], (Mac::length + 2));
IanBenzMaxim 25:bdb1c5a53b58 478
IanBenzMaxim 74:23be10c32fa3 479 // check CRC16
IanBenzMaxim 78:0cbbac7f2016 480 if (calculateCrc16(buf, 0, (Mac::length + 2)) != 0xB001)
IanBenzMaxim 74:23be10c32fa3 481 {
IanBenzMaxim 77:529edb329ee0 482 return CrcError;
IanBenzMaxim 74:23be10c32fa3 483 }
IanBenzMaxim 25:bdb1c5a53b58 484
IanBenzMaxim 74:23be10c32fa3 485 // copy MAC to return buffer
IanBenzMaxim 74:23be10c32fa3 486 std::memcpy(mac, buf, Mac::length);
IanBenzMaxim 25:bdb1c5a53b58 487
IanBenzMaxim 74:23be10c32fa3 488 return Success;
IanBenzMaxim 25:bdb1c5a53b58 489 }
IanBenzMaxim 25:bdb1c5a53b58 490
IanBenzMaxim 74:23be10c32fa3 491 OneWireSlave::CmdResult DS28E15_22_25::computeSecret(unsigned int page_num, bool lock)
IanBenzMaxim 25:bdb1c5a53b58 492 {
IanBenzMaxim 74:23be10c32fa3 493 uint8_t buf[256], cs;
IanBenzMaxim 74:23be10c32fa3 494 int cnt = 0;
IanBenzMaxim 77:529edb329ee0 495
IanBenzMaxim 77:529edb329ee0 496 if (selectDevice() != OneWireMaster::Success)
IanBenzMaxim 77:529edb329ee0 497 {
IanBenzMaxim 77:529edb329ee0 498 return CommunicationError;
IanBenzMaxim 77:529edb329ee0 499 }
IanBenzMaxim 25:bdb1c5a53b58 500
IanBenzMaxim 75:8b627804927c 501 buf[cnt++] = ComputeAndLockSecret;
IanBenzMaxim 74:23be10c32fa3 502 buf[cnt++] = (lock) ? (0xE0 | page_num) : page_num; // lock flag
IanBenzMaxim 25:bdb1c5a53b58 503
IanBenzMaxim 74:23be10c32fa3 504 // Send command
IanBenzMaxim 77:529edb329ee0 505 master().OWWriteBlock(&buf[0], 2);
IanBenzMaxim 25:bdb1c5a53b58 506
IanBenzMaxim 74:23be10c32fa3 507 // Read CRC
IanBenzMaxim 77:529edb329ee0 508 master().OWReadBlock(&buf[cnt], 2);
IanBenzMaxim 74:23be10c32fa3 509 cnt += 2;
IanBenzMaxim 25:bdb1c5a53b58 510
IanBenzMaxim 74:23be10c32fa3 511 // check CRC16
IanBenzMaxim 78:0cbbac7f2016 512 if (calculateCrc16(buf, 0, cnt) != 0xB001)
IanBenzMaxim 74:23be10c32fa3 513 {
IanBenzMaxim 77:529edb329ee0 514 return CrcError;
IanBenzMaxim 74:23be10c32fa3 515 }
IanBenzMaxim 25:bdb1c5a53b58 516
IanBenzMaxim 74:23be10c32fa3 517 // send release and strong pull-up
IanBenzMaxim 77:529edb329ee0 518 master().OWWriteBytePower(0xAA);
IanBenzMaxim 25:bdb1c5a53b58 519
IanBenzMaxim 74:23be10c32fa3 520 // now wait for the MAC computations and secret programming.
IanBenzMaxim 74:23be10c32fa3 521 wait_ms(shaComputationDelayMs * 2 + secretEepromWriteDelayMs());
IanBenzMaxim 25:bdb1c5a53b58 522
IanBenzMaxim 74:23be10c32fa3 523 // disable strong pullup
IanBenzMaxim 77:529edb329ee0 524 master().OWSetLevel(OneWireMaster::NormalLevel);
IanBenzMaxim 74:23be10c32fa3 525
IanBenzMaxim 74:23be10c32fa3 526 // read the CS byte
IanBenzMaxim 77:529edb329ee0 527 master().OWReadByte(cs);
IanBenzMaxim 25:bdb1c5a53b58 528
IanBenzMaxim 74:23be10c32fa3 529 if (cs == 0xAA)
IanBenzMaxim 74:23be10c32fa3 530 {
IanBenzMaxim 74:23be10c32fa3 531 return Success;
IanBenzMaxim 74:23be10c32fa3 532 }
IanBenzMaxim 74:23be10c32fa3 533 // else
IanBenzMaxim 74:23be10c32fa3 534 return OperationFailure;
IanBenzMaxim 25:bdb1c5a53b58 535 }
IanBenzMaxim 25:bdb1c5a53b58 536
IanBenzMaxim 34:11fffbe98ef9 537 OneWireSlave::CmdResult DS28E15_22_25::writeScratchpad(const Scratchpad & data) const
IanBenzMaxim 25:bdb1c5a53b58 538 {
IanBenzMaxim 74:23be10c32fa3 539 uint8_t buf[256];
IanBenzMaxim 74:23be10c32fa3 540 int cnt = 0, offset;
IanBenzMaxim 77:529edb329ee0 541
IanBenzMaxim 77:529edb329ee0 542 if (selectDevice() != OneWireMaster::Success)
IanBenzMaxim 77:529edb329ee0 543 {
IanBenzMaxim 77:529edb329ee0 544 return CommunicationError;
IanBenzMaxim 77:529edb329ee0 545 }
IanBenzMaxim 25:bdb1c5a53b58 546
IanBenzMaxim 75:8b627804927c 547 buf[cnt++] = ReadWriteScratchpad;
IanBenzMaxim 113:13e2865603df 548 if ((m_variant == DS28E25_Family) || (m_variant == DS28E22_Family))
IanBenzMaxim 74:23be10c32fa3 549 {
IanBenzMaxim 74:23be10c32fa3 550 buf[cnt++] = 0x20;
IanBenzMaxim 74:23be10c32fa3 551 }
IanBenzMaxim 74:23be10c32fa3 552 else
IanBenzMaxim 74:23be10c32fa3 553 {
IanBenzMaxim 74:23be10c32fa3 554 buf[cnt++] = 0x00;
IanBenzMaxim 74:23be10c32fa3 555 }
IanBenzMaxim 25:bdb1c5a53b58 556
IanBenzMaxim 74:23be10c32fa3 557 // Send command
IanBenzMaxim 77:529edb329ee0 558 master().OWWriteBlock(&buf[0], 2);
IanBenzMaxim 25:bdb1c5a53b58 559
IanBenzMaxim 74:23be10c32fa3 560 // Read CRC
IanBenzMaxim 77:529edb329ee0 561 master().OWReadBlock(&buf[cnt], 2);
IanBenzMaxim 74:23be10c32fa3 562 cnt += 2;
IanBenzMaxim 74:23be10c32fa3 563
IanBenzMaxim 74:23be10c32fa3 564 offset = cnt;
IanBenzMaxim 25:bdb1c5a53b58 565
IanBenzMaxim 74:23be10c32fa3 566 // add the data
IanBenzMaxim 74:23be10c32fa3 567 std::memcpy(&buf[cnt], data, data.length);
IanBenzMaxim 74:23be10c32fa3 568 cnt += data.length;
IanBenzMaxim 25:bdb1c5a53b58 569
IanBenzMaxim 74:23be10c32fa3 570 // Send the data
IanBenzMaxim 77:529edb329ee0 571 master().OWWriteBlock(data, data.length);
IanBenzMaxim 74:23be10c32fa3 572
IanBenzMaxim 74:23be10c32fa3 573 // Read CRC
IanBenzMaxim 77:529edb329ee0 574 master().OWReadBlock(&buf[cnt], 2);
IanBenzMaxim 74:23be10c32fa3 575 cnt += 2;
IanBenzMaxim 25:bdb1c5a53b58 576
IanBenzMaxim 74:23be10c32fa3 577 // check first CRC16
IanBenzMaxim 78:0cbbac7f2016 578 if (calculateCrc16(buf, 0, offset) != 0xB001)
IanBenzMaxim 74:23be10c32fa3 579 {
IanBenzMaxim 77:529edb329ee0 580 return CrcError;
IanBenzMaxim 74:23be10c32fa3 581 }
IanBenzMaxim 25:bdb1c5a53b58 582
IanBenzMaxim 74:23be10c32fa3 583 // check the second CRC16
IanBenzMaxim 78:0cbbac7f2016 584 if (calculateCrc16(buf, offset, (cnt - offset)) != 0xB001)
IanBenzMaxim 74:23be10c32fa3 585 {
IanBenzMaxim 77:529edb329ee0 586 return CrcError;
IanBenzMaxim 74:23be10c32fa3 587 }
IanBenzMaxim 25:bdb1c5a53b58 588
IanBenzMaxim 74:23be10c32fa3 589 return Success;
IanBenzMaxim 25:bdb1c5a53b58 590 }
IanBenzMaxim 25:bdb1c5a53b58 591
IanBenzMaxim 49:36954b62f503 592 OneWireSlave::CmdResult DS28E15_22_25::readScratchpad(Scratchpad & data) const
IanBenzMaxim 49:36954b62f503 593 {
IanBenzMaxim 74:23be10c32fa3 594 uint8_t buf[256];
IanBenzMaxim 74:23be10c32fa3 595 int cnt = 0, offset;
IanBenzMaxim 77:529edb329ee0 596
IanBenzMaxim 77:529edb329ee0 597 if (selectDevice() != OneWireMaster::Success)
IanBenzMaxim 77:529edb329ee0 598 {
IanBenzMaxim 77:529edb329ee0 599 return CommunicationError;
IanBenzMaxim 77:529edb329ee0 600 }
IanBenzMaxim 49:36954b62f503 601
IanBenzMaxim 75:8b627804927c 602 buf[cnt++] = ReadWriteScratchpad;
IanBenzMaxim 113:13e2865603df 603 if ((m_variant == DS28E25_Family) || (m_variant == DS28E22_Family))
IanBenzMaxim 74:23be10c32fa3 604 {
IanBenzMaxim 74:23be10c32fa3 605 buf[cnt++] = 0x2F;
IanBenzMaxim 74:23be10c32fa3 606 }
IanBenzMaxim 74:23be10c32fa3 607 else
IanBenzMaxim 74:23be10c32fa3 608 {
IanBenzMaxim 74:23be10c32fa3 609 buf[cnt++] = 0x0F;
IanBenzMaxim 74:23be10c32fa3 610 }
IanBenzMaxim 49:36954b62f503 611
IanBenzMaxim 74:23be10c32fa3 612 // Send command
IanBenzMaxim 77:529edb329ee0 613 master().OWWriteBlock(&buf[0], 2);
IanBenzMaxim 49:36954b62f503 614
IanBenzMaxim 74:23be10c32fa3 615 // Read CRC
IanBenzMaxim 77:529edb329ee0 616 master().OWReadBlock(&buf[cnt], 2);
IanBenzMaxim 74:23be10c32fa3 617 cnt += 2;
IanBenzMaxim 74:23be10c32fa3 618
IanBenzMaxim 74:23be10c32fa3 619 offset = cnt;
IanBenzMaxim 49:36954b62f503 620
IanBenzMaxim 74:23be10c32fa3 621 // Receive the data
IanBenzMaxim 77:529edb329ee0 622 master().OWReadBlock(&buf[cnt], data.length);
IanBenzMaxim 74:23be10c32fa3 623 cnt += data.length;
IanBenzMaxim 74:23be10c32fa3 624
IanBenzMaxim 74:23be10c32fa3 625 // Read CRC
IanBenzMaxim 77:529edb329ee0 626 master().OWReadBlock(&buf[cnt], 2);
IanBenzMaxim 74:23be10c32fa3 627 cnt += 2;
IanBenzMaxim 49:36954b62f503 628
IanBenzMaxim 74:23be10c32fa3 629 // check first CRC16
IanBenzMaxim 78:0cbbac7f2016 630 if (calculateCrc16(buf, 0, offset) != 0xB001)
IanBenzMaxim 74:23be10c32fa3 631 {
IanBenzMaxim 77:529edb329ee0 632 return CrcError;
IanBenzMaxim 74:23be10c32fa3 633 }
IanBenzMaxim 49:36954b62f503 634
IanBenzMaxim 74:23be10c32fa3 635 // check the second CRC16
IanBenzMaxim 78:0cbbac7f2016 636 if (calculateCrc16(buf, offset, (cnt - offset)) != 0xB001)
IanBenzMaxim 74:23be10c32fa3 637 {
IanBenzMaxim 77:529edb329ee0 638 return CrcError;
IanBenzMaxim 74:23be10c32fa3 639 }
IanBenzMaxim 49:36954b62f503 640
IanBenzMaxim 74:23be10c32fa3 641 // Copy to output
IanBenzMaxim 74:23be10c32fa3 642 std::memcpy(data, &buf[offset], data.length);
IanBenzMaxim 74:23be10c32fa3 643
IanBenzMaxim 74:23be10c32fa3 644 return Success;
IanBenzMaxim 49:36954b62f503 645 }
IanBenzMaxim 49:36954b62f503 646
IanBenzMaxim 34:11fffbe98ef9 647 OneWireSlave::CmdResult DS28E15_22_25::loadSecret(bool lock)
IanBenzMaxim 25:bdb1c5a53b58 648 {
IanBenzMaxim 74:23be10c32fa3 649 uint8_t buf[256], cs;
IanBenzMaxim 74:23be10c32fa3 650 int cnt = 0;
IanBenzMaxim 77:529edb329ee0 651
IanBenzMaxim 77:529edb329ee0 652 if (selectDevice() != OneWireMaster::Success)
IanBenzMaxim 77:529edb329ee0 653 {
IanBenzMaxim 77:529edb329ee0 654 return CommunicationError;
IanBenzMaxim 77:529edb329ee0 655 }
IanBenzMaxim 25:bdb1c5a53b58 656
IanBenzMaxim 75:8b627804927c 657 buf[cnt++] = LoadAndLockSecret;
IanBenzMaxim 74:23be10c32fa3 658 buf[cnt++] = (lock) ? 0xE0 : 0x00; // lock flag
IanBenzMaxim 74:23be10c32fa3 659
IanBenzMaxim 74:23be10c32fa3 660 // Send command
IanBenzMaxim 77:529edb329ee0 661 master().OWWriteBlock(&buf[0], 2);
IanBenzMaxim 25:bdb1c5a53b58 662
IanBenzMaxim 74:23be10c32fa3 663 // Read CRC
IanBenzMaxim 77:529edb329ee0 664 master().OWReadBlock(&buf[cnt], 2);
IanBenzMaxim 74:23be10c32fa3 665 cnt += 2;
IanBenzMaxim 25:bdb1c5a53b58 666
IanBenzMaxim 74:23be10c32fa3 667 // check CRC16
IanBenzMaxim 78:0cbbac7f2016 668 if (calculateCrc16(buf, 0, cnt) != 0xB001)
IanBenzMaxim 74:23be10c32fa3 669 {
IanBenzMaxim 77:529edb329ee0 670 return CrcError;
IanBenzMaxim 74:23be10c32fa3 671 }
IanBenzMaxim 25:bdb1c5a53b58 672
IanBenzMaxim 74:23be10c32fa3 673 // send release and strong pull-up
IanBenzMaxim 77:529edb329ee0 674 master().OWWriteBytePower(0xAA);
IanBenzMaxim 25:bdb1c5a53b58 675
IanBenzMaxim 74:23be10c32fa3 676 // now wait for the secret programming.
IanBenzMaxim 74:23be10c32fa3 677 wait_ms(secretEepromWriteDelayMs());
IanBenzMaxim 74:23be10c32fa3 678
IanBenzMaxim 74:23be10c32fa3 679 // disable strong pullup
IanBenzMaxim 77:529edb329ee0 680 master().OWSetLevel(OneWireMaster::NormalLevel);
IanBenzMaxim 25:bdb1c5a53b58 681
IanBenzMaxim 74:23be10c32fa3 682 // read the CS byte
IanBenzMaxim 77:529edb329ee0 683 master().OWReadByte(cs);
IanBenzMaxim 25:bdb1c5a53b58 684
IanBenzMaxim 74:23be10c32fa3 685 if (cs == 0xAA)
IanBenzMaxim 74:23be10c32fa3 686 {
IanBenzMaxim 74:23be10c32fa3 687 return Success;
IanBenzMaxim 74:23be10c32fa3 688 }
IanBenzMaxim 74:23be10c32fa3 689 // else
IanBenzMaxim 74:23be10c32fa3 690 return OperationFailure;
IanBenzMaxim 25:bdb1c5a53b58 691 }
IanBenzMaxim 25:bdb1c5a53b58 692
IanBenzMaxim 74:23be10c32fa3 693 OneWireSlave::CmdResult DS28E15_22_25::readPage(unsigned int page, Page & rdbuf, bool continuing) const
IanBenzMaxim 25:bdb1c5a53b58 694 {
IanBenzMaxim 74:23be10c32fa3 695 uint8_t buf[256];
IanBenzMaxim 74:23be10c32fa3 696 int cnt, offset;
IanBenzMaxim 74:23be10c32fa3 697
IanBenzMaxim 74:23be10c32fa3 698 cnt = 0;
IanBenzMaxim 74:23be10c32fa3 699 offset = 0;
IanBenzMaxim 25:bdb1c5a53b58 700
IanBenzMaxim 74:23be10c32fa3 701 // check if not continuing a previous block write
IanBenzMaxim 74:23be10c32fa3 702 if (!continuing)
IanBenzMaxim 74:23be10c32fa3 703 {
IanBenzMaxim 77:529edb329ee0 704 if (selectDevice() != OneWireMaster::Success)
IanBenzMaxim 77:529edb329ee0 705 {
IanBenzMaxim 77:529edb329ee0 706 return CommunicationError;
IanBenzMaxim 77:529edb329ee0 707 }
IanBenzMaxim 77:529edb329ee0 708
IanBenzMaxim 75:8b627804927c 709 buf[cnt++] = ReadMemory;
IanBenzMaxim 74:23be10c32fa3 710 buf[cnt++] = page; // address
IanBenzMaxim 25:bdb1c5a53b58 711
IanBenzMaxim 74:23be10c32fa3 712 // Send command
IanBenzMaxim 77:529edb329ee0 713 master().OWWriteBlock(&buf[0], 2);
IanBenzMaxim 25:bdb1c5a53b58 714
IanBenzMaxim 74:23be10c32fa3 715 // Read CRC
IanBenzMaxim 77:529edb329ee0 716 master().OWReadBlock(&buf[cnt], 2);
IanBenzMaxim 74:23be10c32fa3 717 cnt += 2;
IanBenzMaxim 74:23be10c32fa3 718
IanBenzMaxim 74:23be10c32fa3 719 offset = cnt;
IanBenzMaxim 74:23be10c32fa3 720 }
IanBenzMaxim 25:bdb1c5a53b58 721
IanBenzMaxim 74:23be10c32fa3 722 // read data and CRC16
IanBenzMaxim 77:529edb329ee0 723 master().OWReadBlock(&buf[cnt], (rdbuf.length + 2));
IanBenzMaxim 74:23be10c32fa3 724 cnt += 34;
IanBenzMaxim 25:bdb1c5a53b58 725
IanBenzMaxim 74:23be10c32fa3 726 // check the first CRC16
IanBenzMaxim 74:23be10c32fa3 727 if (!continuing)
IanBenzMaxim 74:23be10c32fa3 728 {
IanBenzMaxim 78:0cbbac7f2016 729 if (calculateCrc16(buf, 0, offset) != 0xB001)
IanBenzMaxim 74:23be10c32fa3 730 {
IanBenzMaxim 77:529edb329ee0 731 return CrcError;
IanBenzMaxim 74:23be10c32fa3 732 }
IanBenzMaxim 74:23be10c32fa3 733 }
IanBenzMaxim 25:bdb1c5a53b58 734
IanBenzMaxim 74:23be10c32fa3 735 // check the second CRC16
IanBenzMaxim 78:0cbbac7f2016 736 if (calculateCrc16(buf, offset, (cnt - offset)) != 0xB001)
IanBenzMaxim 74:23be10c32fa3 737 {
IanBenzMaxim 77:529edb329ee0 738 return CrcError;
IanBenzMaxim 74:23be10c32fa3 739 }
IanBenzMaxim 25:bdb1c5a53b58 740
IanBenzMaxim 74:23be10c32fa3 741 // copy the data to the read buffer
IanBenzMaxim 74:23be10c32fa3 742 std::memcpy(rdbuf, &buf[offset], rdbuf.length);
IanBenzMaxim 25:bdb1c5a53b58 743
IanBenzMaxim 74:23be10c32fa3 744 return Success;
IanBenzMaxim 25:bdb1c5a53b58 745 }
IanBenzMaxim 25:bdb1c5a53b58 746
IanBenzMaxim 74:23be10c32fa3 747 OneWireSlave::CmdResult DS28E15_22_25::writeAuthSegmentMac(unsigned int pageNum, unsigned int segmentNum, const Segment & newData, const Mac & mac, bool continuing)
IanBenzMaxim 25:bdb1c5a53b58 748 {
IanBenzMaxim 74:23be10c32fa3 749 uint8_t buf[256], cs;
IanBenzMaxim 74:23be10c32fa3 750 int cnt, i, offset;
IanBenzMaxim 74:23be10c32fa3 751
IanBenzMaxim 74:23be10c32fa3 752 cnt = 0;
IanBenzMaxim 74:23be10c32fa3 753 offset = 0;
IanBenzMaxim 25:bdb1c5a53b58 754
IanBenzMaxim 74:23be10c32fa3 755 // check if not continuing a previous block write
IanBenzMaxim 74:23be10c32fa3 756 if (!continuing)
IanBenzMaxim 74:23be10c32fa3 757 {
IanBenzMaxim 77:529edb329ee0 758 if (selectDevice() != OneWireMaster::Success)
IanBenzMaxim 77:529edb329ee0 759 {
IanBenzMaxim 77:529edb329ee0 760 return CommunicationError;
IanBenzMaxim 77:529edb329ee0 761 }
IanBenzMaxim 77:529edb329ee0 762
IanBenzMaxim 75:8b627804927c 763 buf[cnt++] = AuthWriteMemory;
IanBenzMaxim 74:23be10c32fa3 764 buf[cnt++] = (segmentNum << 5) | pageNum; // address
IanBenzMaxim 25:bdb1c5a53b58 765
IanBenzMaxim 74:23be10c32fa3 766 // Send command
IanBenzMaxim 77:529edb329ee0 767 master().OWWriteBlock(&buf[0], 2);
IanBenzMaxim 25:bdb1c5a53b58 768
IanBenzMaxim 74:23be10c32fa3 769 // Read CRC
IanBenzMaxim 77:529edb329ee0 770 master().OWReadBlock(&buf[cnt], 2);
IanBenzMaxim 74:23be10c32fa3 771 cnt += 2;
IanBenzMaxim 25:bdb1c5a53b58 772
IanBenzMaxim 74:23be10c32fa3 773 offset = cnt;
IanBenzMaxim 74:23be10c32fa3 774 }
IanBenzMaxim 25:bdb1c5a53b58 775
IanBenzMaxim 74:23be10c32fa3 776 // add the data
IanBenzMaxim 74:23be10c32fa3 777 for (i = 0; i < newData.length; i++)
IanBenzMaxim 74:23be10c32fa3 778 {
IanBenzMaxim 74:23be10c32fa3 779 buf[cnt++] = newData[i];
IanBenzMaxim 74:23be10c32fa3 780 }
IanBenzMaxim 25:bdb1c5a53b58 781
IanBenzMaxim 74:23be10c32fa3 782 // Send data
IanBenzMaxim 77:529edb329ee0 783 master().OWWriteBlock(newData, newData.length);
IanBenzMaxim 25:bdb1c5a53b58 784
IanBenzMaxim 74:23be10c32fa3 785 // read first CRC byte
IanBenzMaxim 77:529edb329ee0 786 master().OWReadByte(buf[cnt++]);
IanBenzMaxim 25:bdb1c5a53b58 787
IanBenzMaxim 74:23be10c32fa3 788 // read the last CRC and enable power
IanBenzMaxim 77:529edb329ee0 789 master().OWReadBytePower(buf[cnt++]);
IanBenzMaxim 25:bdb1c5a53b58 790
IanBenzMaxim 74:23be10c32fa3 791 // now wait for the MAC computation.
IanBenzMaxim 74:23be10c32fa3 792 wait_ms(shaComputationDelayMs);
IanBenzMaxim 25:bdb1c5a53b58 793
IanBenzMaxim 74:23be10c32fa3 794 // disable strong pullup
IanBenzMaxim 77:529edb329ee0 795 master().OWSetLevel(OneWireMaster::NormalLevel);
IanBenzMaxim 25:bdb1c5a53b58 796
IanBenzMaxim 74:23be10c32fa3 797 // check the first CRC16
IanBenzMaxim 74:23be10c32fa3 798 if (!continuing)
IanBenzMaxim 74:23be10c32fa3 799 {
IanBenzMaxim 78:0cbbac7f2016 800 if (calculateCrc16(buf, 0, offset) != 0xB001)
IanBenzMaxim 74:23be10c32fa3 801 {
IanBenzMaxim 77:529edb329ee0 802 return CrcError;
IanBenzMaxim 74:23be10c32fa3 803 }
IanBenzMaxim 74:23be10c32fa3 804 }
IanBenzMaxim 74:23be10c32fa3 805
IanBenzMaxim 74:23be10c32fa3 806 // check the second CRC16
IanBenzMaxim 79:7f22823a5a2d 807 uint16_t CRC16 = 0;
IanBenzMaxim 25:bdb1c5a53b58 808
IanBenzMaxim 74:23be10c32fa3 809 // DS28E25/DS28E22, crc gets calculagted with CS byte
IanBenzMaxim 113:13e2865603df 810 if ((m_variant == DS28E25_Family) || (m_variant == DS28E22_Family))
IanBenzMaxim 74:23be10c32fa3 811 {
IanBenzMaxim 74:23be10c32fa3 812 if (continuing)
IanBenzMaxim 74:23be10c32fa3 813 {
IanBenzMaxim 78:0cbbac7f2016 814 CRC16 = calculateCrc16(CRC16, 0xAA);
IanBenzMaxim 74:23be10c32fa3 815 }
IanBenzMaxim 74:23be10c32fa3 816 }
IanBenzMaxim 25:bdb1c5a53b58 817
IanBenzMaxim 78:0cbbac7f2016 818 CRC16 = calculateCrc16(buf, offset, (cnt - offset), CRC16);
IanBenzMaxim 25:bdb1c5a53b58 819
IanBenzMaxim 74:23be10c32fa3 820 if (CRC16 != 0xB001)
IanBenzMaxim 74:23be10c32fa3 821 {
IanBenzMaxim 77:529edb329ee0 822 return CrcError;
IanBenzMaxim 74:23be10c32fa3 823 }
IanBenzMaxim 25:bdb1c5a53b58 824
IanBenzMaxim 74:23be10c32fa3 825 // transmit MAC as a block
IanBenzMaxim 77:529edb329ee0 826 master().OWWriteBlock(mac, mac.length);
IanBenzMaxim 25:bdb1c5a53b58 827
IanBenzMaxim 74:23be10c32fa3 828 // calculate CRC on MAC
IanBenzMaxim 78:0cbbac7f2016 829 CRC16 = calculateCrc16(mac, 0, mac.length);
IanBenzMaxim 25:bdb1c5a53b58 830
IanBenzMaxim 74:23be10c32fa3 831 // append read of CRC16 and CS byte
IanBenzMaxim 77:529edb329ee0 832 master().OWReadBlock(&buf[0], 3);
IanBenzMaxim 74:23be10c32fa3 833 cnt = 3;
IanBenzMaxim 74:23be10c32fa3 834
IanBenzMaxim 74:23be10c32fa3 835 // ckeck CRC16
IanBenzMaxim 78:0cbbac7f2016 836 CRC16 = calculateCrc16(buf, 0, (cnt - 1), CRC16);
IanBenzMaxim 25:bdb1c5a53b58 837
IanBenzMaxim 74:23be10c32fa3 838 if (CRC16 != 0xB001)
IanBenzMaxim 74:23be10c32fa3 839 {
IanBenzMaxim 77:529edb329ee0 840 return CrcError;
IanBenzMaxim 74:23be10c32fa3 841 }
IanBenzMaxim 25:bdb1c5a53b58 842
IanBenzMaxim 74:23be10c32fa3 843 // check CS
IanBenzMaxim 74:23be10c32fa3 844 if (buf[cnt - 1] != 0xAA)
IanBenzMaxim 74:23be10c32fa3 845 {
IanBenzMaxim 74:23be10c32fa3 846 return OperationFailure;
IanBenzMaxim 74:23be10c32fa3 847 }
IanBenzMaxim 25:bdb1c5a53b58 848
IanBenzMaxim 74:23be10c32fa3 849 // send release and strong pull-up
IanBenzMaxim 77:529edb329ee0 850 master().OWWriteBytePower(0xAA);
IanBenzMaxim 25:bdb1c5a53b58 851
IanBenzMaxim 74:23be10c32fa3 852 // now wait for the programming.
IanBenzMaxim 74:23be10c32fa3 853 wait_ms(eepromWriteDelayMs);
IanBenzMaxim 25:bdb1c5a53b58 854
IanBenzMaxim 74:23be10c32fa3 855 // disable strong pullup
IanBenzMaxim 77:529edb329ee0 856 master().OWSetLevel(OneWireMaster::NormalLevel);
IanBenzMaxim 25:bdb1c5a53b58 857
IanBenzMaxim 74:23be10c32fa3 858 // read the CS byte
IanBenzMaxim 77:529edb329ee0 859 master().OWReadByte(cs);
IanBenzMaxim 25:bdb1c5a53b58 860
IanBenzMaxim 74:23be10c32fa3 861 if (cs == 0xAA)
IanBenzMaxim 74:23be10c32fa3 862 {
IanBenzMaxim 74:23be10c32fa3 863 return Success;
IanBenzMaxim 74:23be10c32fa3 864 }
IanBenzMaxim 74:23be10c32fa3 865 // else
IanBenzMaxim 74:23be10c32fa3 866 return OperationFailure;
IanBenzMaxim 25:bdb1c5a53b58 867 }
IanBenzMaxim 25:bdb1c5a53b58 868
IanBenzMaxim 74:23be10c32fa3 869 ISha256MacCoproc::CmdResult DS28E15_22_25::computeSegmentWriteMac(const ISha256MacCoproc & MacCoproc, unsigned int pageNum, unsigned int segmentNum, const Segment & newData, const Segment & oldData, const RomId & romId, const ManId & manId, Mac & mac)
IanBenzMaxim 25:bdb1c5a53b58 870 {
IanBenzMaxim 74:23be10c32fa3 871 ISha256MacCoproc::WriteMacData MT;
IanBenzMaxim 25:bdb1c5a53b58 872
IanBenzMaxim 74:23be10c32fa3 873 // insert ROM number
IanBenzMaxim 74:23be10c32fa3 874 std::memcpy(&MT[0], romId, RomId::byteLen);
IanBenzMaxim 25:bdb1c5a53b58 875
IanBenzMaxim 74:23be10c32fa3 876 MT[11] = segmentNum;
IanBenzMaxim 74:23be10c32fa3 877 MT[10] = pageNum;
IanBenzMaxim 74:23be10c32fa3 878 MT[9] = manId[0];
IanBenzMaxim 74:23be10c32fa3 879 MT[8] = manId[1];
IanBenzMaxim 25:bdb1c5a53b58 880
IanBenzMaxim 74:23be10c32fa3 881 // insert old data
IanBenzMaxim 74:23be10c32fa3 882 std::memcpy(&MT[12], oldData, Segment::length);
IanBenzMaxim 25:bdb1c5a53b58 883
IanBenzMaxim 74:23be10c32fa3 884 // insert new data
IanBenzMaxim 74:23be10c32fa3 885 std::memcpy(&MT[16], newData, Segment::length);
IanBenzMaxim 74:23be10c32fa3 886
IanBenzMaxim 74:23be10c32fa3 887 return MacCoproc.computeWriteMac(MT, mac);
IanBenzMaxim 25:bdb1c5a53b58 888 }
IanBenzMaxim 25:bdb1c5a53b58 889
IanBenzMaxim 73:2cecc1372acc 890 ISha256MacCoproc::CmdResult DS28E15_22_25::computeProtectionWriteMac(const ISha256MacCoproc & MacCoproc, const BlockProtection & newProtection, const BlockProtection & oldProtection, const RomId & romId, const ManId & manId, Mac & mac)
IanBenzMaxim 25:bdb1c5a53b58 891 {
IanBenzMaxim 74:23be10c32fa3 892 ISha256MacCoproc::WriteMacData MT;
IanBenzMaxim 74:23be10c32fa3 893
IanBenzMaxim 74:23be10c32fa3 894 // insert ROM number
IanBenzMaxim 74:23be10c32fa3 895 std::memcpy(MT, romId, RomId::byteLen);
IanBenzMaxim 25:bdb1c5a53b58 896
IanBenzMaxim 74:23be10c32fa3 897 // instert block and page
IanBenzMaxim 74:23be10c32fa3 898 MT[11] = 0;
IanBenzMaxim 74:23be10c32fa3 899 MT[10] = newProtection.blockNum();
IanBenzMaxim 25:bdb1c5a53b58 900
IanBenzMaxim 74:23be10c32fa3 901 MT[9] = manId[0];
IanBenzMaxim 74:23be10c32fa3 902 MT[8] = manId[1];
IanBenzMaxim 25:bdb1c5a53b58 903
IanBenzMaxim 74:23be10c32fa3 904 // old data
IanBenzMaxim 74:23be10c32fa3 905 MT[12] = oldProtection.authProtection() ? 0x01 : 0x00;
IanBenzMaxim 74:23be10c32fa3 906 MT[13] = oldProtection.eepromEmulation() ? 0x01 : 0x00;
IanBenzMaxim 74:23be10c32fa3 907 MT[14] = oldProtection.writeProtection() ? 0x01 : 0x00;
IanBenzMaxim 74:23be10c32fa3 908 MT[15] = oldProtection.readProtection() ? 0x01 : 0x00;
IanBenzMaxim 74:23be10c32fa3 909 // new data
IanBenzMaxim 74:23be10c32fa3 910 MT[16] = newProtection.authProtection() ? 0x01 : 0x00;
IanBenzMaxim 74:23be10c32fa3 911 MT[17] = newProtection.eepromEmulation() ? 0x01 : 0x00;
IanBenzMaxim 74:23be10c32fa3 912 MT[18] = newProtection.writeProtection() ? 0x01 : 0x00;
IanBenzMaxim 74:23be10c32fa3 913 MT[19] = newProtection.readProtection() ? 0x01 : 0x00;
IanBenzMaxim 25:bdb1c5a53b58 914
IanBenzMaxim 74:23be10c32fa3 915 // compute the mac
IanBenzMaxim 74:23be10c32fa3 916 return MacCoproc.computeWriteMac(MT, mac);
IanBenzMaxim 25:bdb1c5a53b58 917 }
IanBenzMaxim 25:bdb1c5a53b58 918
IanBenzMaxim 73:2cecc1372acc 919 OneWireSlave::CmdResult DS28E15_22_25::writeAuthSegment(const ISha256MacCoproc & MacCoproc, unsigned int pageNum, unsigned int segmentNum, const Segment & newData, const Segment & oldData, bool continuing)
IanBenzMaxim 25:bdb1c5a53b58 920 {
IanBenzMaxim 74:23be10c32fa3 921 uint8_t buf[256], cs;
IanBenzMaxim 74:23be10c32fa3 922 int cnt, offset;
IanBenzMaxim 74:23be10c32fa3 923
IanBenzMaxim 74:23be10c32fa3 924 cnt = 0;
IanBenzMaxim 74:23be10c32fa3 925 offset = 0;
IanBenzMaxim 25:bdb1c5a53b58 926
IanBenzMaxim 74:23be10c32fa3 927 // check if not continuing a previous block write
IanBenzMaxim 74:23be10c32fa3 928 if (!continuing)
IanBenzMaxim 74:23be10c32fa3 929 {
IanBenzMaxim 77:529edb329ee0 930 if (selectDevice() != OneWireMaster::Success)
IanBenzMaxim 77:529edb329ee0 931 {
IanBenzMaxim 77:529edb329ee0 932 return CommunicationError;
IanBenzMaxim 77:529edb329ee0 933 }
IanBenzMaxim 77:529edb329ee0 934
IanBenzMaxim 75:8b627804927c 935 buf[cnt++] = AuthWriteMemory;
IanBenzMaxim 74:23be10c32fa3 936 buf[cnt++] = (segmentNum << 5) | pageNum; // address
IanBenzMaxim 74:23be10c32fa3 937
IanBenzMaxim 74:23be10c32fa3 938 // Send command
IanBenzMaxim 77:529edb329ee0 939 master().OWWriteBlock(&buf[0], 2);
IanBenzMaxim 25:bdb1c5a53b58 940
IanBenzMaxim 74:23be10c32fa3 941 // Read CRC
IanBenzMaxim 77:529edb329ee0 942 master().OWReadBlock(&buf[cnt], 2);
IanBenzMaxim 74:23be10c32fa3 943 cnt += 2;
IanBenzMaxim 25:bdb1c5a53b58 944
IanBenzMaxim 74:23be10c32fa3 945 offset = cnt;
IanBenzMaxim 74:23be10c32fa3 946 }
IanBenzMaxim 25:bdb1c5a53b58 947
IanBenzMaxim 74:23be10c32fa3 948 // add the data
IanBenzMaxim 74:23be10c32fa3 949 for (size_t i = 0; i < newData.length; i++)
IanBenzMaxim 74:23be10c32fa3 950 {
IanBenzMaxim 74:23be10c32fa3 951 buf[cnt++] = newData[i];
IanBenzMaxim 74:23be10c32fa3 952 }
IanBenzMaxim 25:bdb1c5a53b58 953
IanBenzMaxim 74:23be10c32fa3 954 // Send data
IanBenzMaxim 77:529edb329ee0 955 master().OWWriteBlock(newData, newData.length);
IanBenzMaxim 25:bdb1c5a53b58 956
IanBenzMaxim 74:23be10c32fa3 957 // read first CRC byte
IanBenzMaxim 77:529edb329ee0 958 master().OWReadByte(buf[cnt++]);
IanBenzMaxim 25:bdb1c5a53b58 959
IanBenzMaxim 74:23be10c32fa3 960 // read the last CRC and enable power
IanBenzMaxim 77:529edb329ee0 961 master().OWReadBytePower(buf[cnt++]);
IanBenzMaxim 25:bdb1c5a53b58 962
IanBenzMaxim 74:23be10c32fa3 963 // now wait for the MAC computation.
IanBenzMaxim 74:23be10c32fa3 964 wait_ms(shaComputationDelayMs);
IanBenzMaxim 25:bdb1c5a53b58 965
IanBenzMaxim 74:23be10c32fa3 966 // disable strong pullup
IanBenzMaxim 77:529edb329ee0 967 master().OWSetLevel(OneWireMaster::NormalLevel);
IanBenzMaxim 25:bdb1c5a53b58 968
IanBenzMaxim 74:23be10c32fa3 969 // check the first CRC16
IanBenzMaxim 74:23be10c32fa3 970 if (!continuing)
IanBenzMaxim 74:23be10c32fa3 971 {
IanBenzMaxim 78:0cbbac7f2016 972 if (calculateCrc16(buf, 0, offset) != 0xB001)
IanBenzMaxim 74:23be10c32fa3 973 {
IanBenzMaxim 77:529edb329ee0 974 return CrcError;
IanBenzMaxim 74:23be10c32fa3 975 }
IanBenzMaxim 74:23be10c32fa3 976 }
IanBenzMaxim 25:bdb1c5a53b58 977
IanBenzMaxim 74:23be10c32fa3 978 // check the second CRC16
IanBenzMaxim 79:7f22823a5a2d 979 uint16_t CRC16 = 0;
IanBenzMaxim 25:bdb1c5a53b58 980
IanBenzMaxim 74:23be10c32fa3 981 // DS28E25/DS28E22, crc gets calculagted with CS byte
IanBenzMaxim 113:13e2865603df 982 if ((m_variant == DS28E25_Family) || (m_variant == DS28E22_Family))
IanBenzMaxim 74:23be10c32fa3 983 {
IanBenzMaxim 74:23be10c32fa3 984 if (continuing)
IanBenzMaxim 78:0cbbac7f2016 985 CRC16 = calculateCrc16(CRC16, 0xAA);
IanBenzMaxim 74:23be10c32fa3 986 }
IanBenzMaxim 25:bdb1c5a53b58 987
IanBenzMaxim 78:0cbbac7f2016 988 CRC16 = calculateCrc16(buf, offset, (cnt - offset), CRC16);
IanBenzMaxim 74:23be10c32fa3 989
IanBenzMaxim 74:23be10c32fa3 990 if (CRC16 != 0xB001)
IanBenzMaxim 74:23be10c32fa3 991 {
IanBenzMaxim 77:529edb329ee0 992 return CrcError;
IanBenzMaxim 74:23be10c32fa3 993 }
IanBenzMaxim 25:bdb1c5a53b58 994
IanBenzMaxim 25:bdb1c5a53b58 995 // compute the mac
IanBenzMaxim 74:23be10c32fa3 996 ISha256MacCoproc::CmdResult result;
IanBenzMaxim 74:23be10c32fa3 997 Mac mac;
IanBenzMaxim 82:c11090a32471 998 result = computeSegmentWriteMac(MacCoproc, pageNum, segmentNum, newData, oldData, romId(), manId(), mac);
IanBenzMaxim 74:23be10c32fa3 999 if (result != ISha256MacCoproc::Success)
IanBenzMaxim 74:23be10c32fa3 1000 {
IanBenzMaxim 74:23be10c32fa3 1001 return OperationFailure;
IanBenzMaxim 74:23be10c32fa3 1002 }
IanBenzMaxim 25:bdb1c5a53b58 1003
IanBenzMaxim 74:23be10c32fa3 1004 // transmit MAC as a block
IanBenzMaxim 77:529edb329ee0 1005 master().OWWriteBlock(mac, mac.length);
IanBenzMaxim 74:23be10c32fa3 1006
IanBenzMaxim 74:23be10c32fa3 1007 // calculate CRC on MAC
IanBenzMaxim 78:0cbbac7f2016 1008 CRC16 = calculateCrc16(mac, 0, mac.length);
IanBenzMaxim 25:bdb1c5a53b58 1009
IanBenzMaxim 74:23be10c32fa3 1010 // append read of CRC16 and CS byte
IanBenzMaxim 77:529edb329ee0 1011 master().OWReadBlock(&buf[0], 3);
IanBenzMaxim 74:23be10c32fa3 1012 cnt = 3;
IanBenzMaxim 25:bdb1c5a53b58 1013
IanBenzMaxim 74:23be10c32fa3 1014 // ckeck CRC16
IanBenzMaxim 78:0cbbac7f2016 1015 CRC16 = calculateCrc16(buf, 0, (cnt - 1), CRC16);
IanBenzMaxim 25:bdb1c5a53b58 1016
IanBenzMaxim 74:23be10c32fa3 1017 if (CRC16 != 0xB001)
IanBenzMaxim 74:23be10c32fa3 1018 {
IanBenzMaxim 77:529edb329ee0 1019 return CrcError;
IanBenzMaxim 74:23be10c32fa3 1020 }
IanBenzMaxim 25:bdb1c5a53b58 1021
IanBenzMaxim 74:23be10c32fa3 1022 // check CS
IanBenzMaxim 74:23be10c32fa3 1023 if (buf[cnt - 1] != 0xAA)
IanBenzMaxim 74:23be10c32fa3 1024 {
IanBenzMaxim 74:23be10c32fa3 1025 return OperationFailure;
IanBenzMaxim 74:23be10c32fa3 1026 }
IanBenzMaxim 25:bdb1c5a53b58 1027
IanBenzMaxim 74:23be10c32fa3 1028 // send release and strong pull-up
IanBenzMaxim 77:529edb329ee0 1029 master().OWWriteBytePower(0xAA);
IanBenzMaxim 25:bdb1c5a53b58 1030
IanBenzMaxim 74:23be10c32fa3 1031 // now wait for the programming.
IanBenzMaxim 74:23be10c32fa3 1032 wait_ms(eepromWriteDelayMs);
IanBenzMaxim 25:bdb1c5a53b58 1033
IanBenzMaxim 74:23be10c32fa3 1034 // disable strong pullup
IanBenzMaxim 77:529edb329ee0 1035 master().OWSetLevel(OneWireMaster::NormalLevel);
IanBenzMaxim 25:bdb1c5a53b58 1036
IanBenzMaxim 74:23be10c32fa3 1037 // read the CS byte
IanBenzMaxim 77:529edb329ee0 1038 master().OWReadByte(cs);
IanBenzMaxim 25:bdb1c5a53b58 1039
IanBenzMaxim 74:23be10c32fa3 1040 if (cs == 0xAA)
IanBenzMaxim 74:23be10c32fa3 1041 {
IanBenzMaxim 74:23be10c32fa3 1042 return Success;
IanBenzMaxim 74:23be10c32fa3 1043 }
IanBenzMaxim 74:23be10c32fa3 1044 // else
IanBenzMaxim 74:23be10c32fa3 1045 return OperationFailure;
IanBenzMaxim 25:bdb1c5a53b58 1046 }
IanBenzMaxim 25:bdb1c5a53b58 1047
IanBenzMaxim 50:e967f9befbd0 1048 OneWireSlave::CmdResult DS28E15_22_25::readSegment(unsigned int page, unsigned int segment, Segment & data, bool continuing) const
IanBenzMaxim 25:bdb1c5a53b58 1049 {
IanBenzMaxim 74:23be10c32fa3 1050 OneWireMaster::CmdResult result;
IanBenzMaxim 74:23be10c32fa3 1051 uint8_t buf[2];
IanBenzMaxim 74:23be10c32fa3 1052
IanBenzMaxim 74:23be10c32fa3 1053 if (!continuing)
IanBenzMaxim 74:23be10c32fa3 1054 {
IanBenzMaxim 77:529edb329ee0 1055 if (selectDevice() != OneWireMaster::Success)
IanBenzMaxim 77:529edb329ee0 1056 {
IanBenzMaxim 77:529edb329ee0 1057 return CommunicationError;
IanBenzMaxim 77:529edb329ee0 1058 }
IanBenzMaxim 77:529edb329ee0 1059
IanBenzMaxim 75:8b627804927c 1060 buf[0] = ReadMemory;
IanBenzMaxim 74:23be10c32fa3 1061 buf[1] = (segment << 5) | page;
IanBenzMaxim 74:23be10c32fa3 1062
IanBenzMaxim 74:23be10c32fa3 1063 // Transmit command
IanBenzMaxim 77:529edb329ee0 1064 master().OWWriteBlock(buf, 2);
IanBenzMaxim 74:23be10c32fa3 1065
IanBenzMaxim 74:23be10c32fa3 1066 // Receive CRC
IanBenzMaxim 77:529edb329ee0 1067 result = master().OWReadBlock(buf, 2);
IanBenzMaxim 74:23be10c32fa3 1068 }
IanBenzMaxim 74:23be10c32fa3 1069 else if (segment == 0)
IanBenzMaxim 74:23be10c32fa3 1070 {
IanBenzMaxim 74:23be10c32fa3 1071 // Receive CRC from previous read
IanBenzMaxim 77:529edb329ee0 1072 result = master().OWReadBlock(buf, 2);
IanBenzMaxim 74:23be10c32fa3 1073 }
IanBenzMaxim 74:23be10c32fa3 1074
IanBenzMaxim 74:23be10c32fa3 1075 // Receive data
IanBenzMaxim 74:23be10c32fa3 1076 if (result == OneWireMaster::Success)
IanBenzMaxim 74:23be10c32fa3 1077 {
IanBenzMaxim 77:529edb329ee0 1078 result = master().OWReadBlock(data, data.length);
IanBenzMaxim 74:23be10c32fa3 1079 }
IanBenzMaxim 74:23be10c32fa3 1080
IanBenzMaxim 74:23be10c32fa3 1081 return (result == OneWireMaster::Success ? OneWireSlave::Success : OneWireSlave::CommunicationError);
IanBenzMaxim 25:bdb1c5a53b58 1082 }
IanBenzMaxim 25:bdb1c5a53b58 1083
IanBenzMaxim 74:23be10c32fa3 1084 OneWireSlave::CmdResult DS28E15_22_25::writeSegment(unsigned int page, unsigned int block, const Segment & data, bool continuing)
IanBenzMaxim 25:bdb1c5a53b58 1085 {
IanBenzMaxim 74:23be10c32fa3 1086 uint8_t buf[256], cs;
IanBenzMaxim 74:23be10c32fa3 1087 int cnt, offset;
IanBenzMaxim 25:bdb1c5a53b58 1088
IanBenzMaxim 74:23be10c32fa3 1089 cnt = 0;
IanBenzMaxim 74:23be10c32fa3 1090 offset = 0;
IanBenzMaxim 74:23be10c32fa3 1091
IanBenzMaxim 74:23be10c32fa3 1092 // check if not continuing a previous block write
IanBenzMaxim 74:23be10c32fa3 1093 if (!continuing)
IanBenzMaxim 74:23be10c32fa3 1094 {
IanBenzMaxim 77:529edb329ee0 1095 if (selectDevice() != OneWireMaster::Success)
IanBenzMaxim 77:529edb329ee0 1096 {
IanBenzMaxim 77:529edb329ee0 1097 return CommunicationError;
IanBenzMaxim 77:529edb329ee0 1098 }
IanBenzMaxim 77:529edb329ee0 1099
IanBenzMaxim 75:8b627804927c 1100 buf[cnt++] = WriteMemory;
IanBenzMaxim 74:23be10c32fa3 1101 buf[cnt++] = (block << 5) | page; // address
IanBenzMaxim 25:bdb1c5a53b58 1102
IanBenzMaxim 74:23be10c32fa3 1103 // Send command
IanBenzMaxim 77:529edb329ee0 1104 master().OWWriteBlock(&buf[0], 2);
IanBenzMaxim 25:bdb1c5a53b58 1105
IanBenzMaxim 74:23be10c32fa3 1106 // Read CRC
IanBenzMaxim 77:529edb329ee0 1107 master().OWReadBlock(&buf[cnt], 2);
IanBenzMaxim 74:23be10c32fa3 1108 cnt += 2;
IanBenzMaxim 25:bdb1c5a53b58 1109
IanBenzMaxim 74:23be10c32fa3 1110 offset = cnt;
IanBenzMaxim 74:23be10c32fa3 1111 }
IanBenzMaxim 25:bdb1c5a53b58 1112
IanBenzMaxim 74:23be10c32fa3 1113 // add the data
IanBenzMaxim 74:23be10c32fa3 1114 for (size_t i = 0; i < data.length; i++)
IanBenzMaxim 74:23be10c32fa3 1115 {
IanBenzMaxim 74:23be10c32fa3 1116 buf[cnt++] = data[i];
IanBenzMaxim 74:23be10c32fa3 1117 }
IanBenzMaxim 25:bdb1c5a53b58 1118
IanBenzMaxim 74:23be10c32fa3 1119 // Send data
IanBenzMaxim 77:529edb329ee0 1120 master().OWWriteBlock(data, data.length);
IanBenzMaxim 25:bdb1c5a53b58 1121
IanBenzMaxim 74:23be10c32fa3 1122 // Read CRC
IanBenzMaxim 77:529edb329ee0 1123 master().OWReadBlock(&buf[cnt], 2);
IanBenzMaxim 74:23be10c32fa3 1124 cnt += 2;
IanBenzMaxim 25:bdb1c5a53b58 1125
IanBenzMaxim 74:23be10c32fa3 1126 // check the first CRC16
IanBenzMaxim 74:23be10c32fa3 1127 if (!continuing)
IanBenzMaxim 74:23be10c32fa3 1128 {
IanBenzMaxim 78:0cbbac7f2016 1129 if (calculateCrc16(buf, 0, offset) != 0xB001)
IanBenzMaxim 74:23be10c32fa3 1130 {
IanBenzMaxim 77:529edb329ee0 1131 return CrcError;
IanBenzMaxim 74:23be10c32fa3 1132 }
IanBenzMaxim 74:23be10c32fa3 1133 }
IanBenzMaxim 74:23be10c32fa3 1134
IanBenzMaxim 74:23be10c32fa3 1135 // check the second CRC16
IanBenzMaxim 78:0cbbac7f2016 1136 if (calculateCrc16(buf, offset, (cnt - offset)) != 0xB001)
IanBenzMaxim 74:23be10c32fa3 1137 {
IanBenzMaxim 77:529edb329ee0 1138 return CrcError;
IanBenzMaxim 74:23be10c32fa3 1139 }
IanBenzMaxim 25:bdb1c5a53b58 1140
IanBenzMaxim 74:23be10c32fa3 1141 // send release and strong pull-up
IanBenzMaxim 77:529edb329ee0 1142 master().OWWriteBytePower(0xAA);
IanBenzMaxim 25:bdb1c5a53b58 1143
IanBenzMaxim 74:23be10c32fa3 1144 // now wait for the programming.
IanBenzMaxim 74:23be10c32fa3 1145 wait_ms(eepromWriteDelayMs);
IanBenzMaxim 74:23be10c32fa3 1146
IanBenzMaxim 74:23be10c32fa3 1147 // disable strong pullup
IanBenzMaxim 77:529edb329ee0 1148 master().OWSetLevel(OneWireMaster::NormalLevel);
IanBenzMaxim 25:bdb1c5a53b58 1149
IanBenzMaxim 74:23be10c32fa3 1150 // read the CS byte
IanBenzMaxim 77:529edb329ee0 1151 master().OWReadByte(cs);
IanBenzMaxim 25:bdb1c5a53b58 1152
IanBenzMaxim 74:23be10c32fa3 1153 if (cs == 0xAA)
IanBenzMaxim 74:23be10c32fa3 1154 {
IanBenzMaxim 74:23be10c32fa3 1155 return Success;
IanBenzMaxim 74:23be10c32fa3 1156 }
IanBenzMaxim 74:23be10c32fa3 1157 // else
IanBenzMaxim 74:23be10c32fa3 1158 return OperationFailure;
IanBenzMaxim 25:bdb1c5a53b58 1159 }
IanBenzMaxim 25:bdb1c5a53b58 1160
IanBenzMaxim 73:2cecc1372acc 1161 ISha256MacCoproc::CmdResult DS28E15_22_25::computeNextSecret(ISha256MacCoproc & MacCoproc, const Page & bindingPage, unsigned int bindingPageNum, const Scratchpad & partialSecret, const RomId & romId, const ManId & manId)
IanBenzMaxim 25:bdb1c5a53b58 1162 {
IanBenzMaxim 74:23be10c32fa3 1163 ISha256MacCoproc::SlaveSecretData slaveSecretData;
IanBenzMaxim 25:bdb1c5a53b58 1164
IanBenzMaxim 74:23be10c32fa3 1165 // insert ROM number
IanBenzMaxim 74:23be10c32fa3 1166 std::memcpy(slaveSecretData, romId, RomId::byteLen);
IanBenzMaxim 25:bdb1c5a53b58 1167
IanBenzMaxim 74:23be10c32fa3 1168 slaveSecretData[11] = 0x00;
IanBenzMaxim 74:23be10c32fa3 1169 slaveSecretData[10] = bindingPageNum;
IanBenzMaxim 74:23be10c32fa3 1170 slaveSecretData[9] = manId[0];
IanBenzMaxim 74:23be10c32fa3 1171 slaveSecretData[8] = manId[1];
IanBenzMaxim 25:bdb1c5a53b58 1172
IanBenzMaxim 74:23be10c32fa3 1173 return MacCoproc.computeSlaveSecret(ISha256MacCoproc::DevicePage(bindingPage), partialSecret, slaveSecretData);
IanBenzMaxim 25:bdb1c5a53b58 1174 }