Implementation of 1-Wire with added Alarm Search Functionality

Dependents:   Max32630_One_Wire_Interface

Committer:
IanBenzMaxim
Date:
Fri May 13 14:52:50 2016 -0500
Revision:
75:8b627804927c
Parent:
74:23be10c32fa3
Child:
76:84e6c4994e29
Code cleanup.

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