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

Dependents:   MAXREFDES131_Qt_Demo MAX32630FTHR_iButton_uSD_Logger MAX32630FTHR_DS18B20_uSD_Logger MAXREFDES130_131_Demo ... more

Superseded by MaximInterface.

Committer:
IanBenzMaxim
Date:
Thu May 12 14:38:16 2016 -0500
Revision:
73:2cecc1372acc
Parent:
OneWire_Memory/Authenticators/DS28E15_22_25/DS28E15_22_25.cpp@62:43039aeca2ab
Child:
74:23be10c32fa3
Added namespaces. Renamed files and directories for consistency. Use <stdint.h> instead of <cstdint> since it is not supported by C++98.

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