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