Implementation of 1-Wire with added Alarm Search Functionality

Dependents:   Max32630_One_Wire_Interface

Committer:
IanBenzMaxim
Date:
Thu Apr 14 14:38:42 2016 -0500
Revision:
61:268612a10614
Parent:
51:a65f031e997b
Child:
62:43039aeca2ab
Fixed broken CRC16 calculation during Authenticated Write Block Protection operation on DS28E15/22/25.

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