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:
Mon Apr 11 14:48:43 2016 -0500
Revision:
50:e967f9befbd0
Parent:
49:36954b62f503
Child:
51:a65f031e997b
Added operation continuing support to readSegment(). Removed continuing support from writeBlockProtection() since this is not listed in the datasheet. Added support to read status of all protection blocks with type safety. Modify readStatus() for DS28E22 and DS28E25 to use Block Number instead of Page Number to match DS28E15. Added operation to read personality bytes.

Who changed what in which revision?

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