Implementation of 1-Wire with added Alarm Search Functionality

Dependents:   Max32630_One_Wire_Interface

Committer:
IanBenzMaxim
Date:
Fri May 13 07:48:35 2016 -0500
Revision:
74:23be10c32fa3
Parent:
73:2cecc1372acc
Child:
75:8b627804927c
Assimilated indentation and braces.

Who changed what in which revision?

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