Implementation of 1-Wire with added Alarm Search Functionality

Dependents:   Max32630_One_Wire_Interface

Committer:
IanBenzMaxim
Date:
Sat May 14 14:27:56 2016 -0500
Revision:
76:84e6c4994e29
Parent:
75:8b627804927c
Child:
77:529edb329ee0
Move ROM commands outside of OneWireMaster to increase cohesiveness of the class. Do not use subdivide OneWire namespace since it will likely not provide value on this project.

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