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:
Fri Apr 08 16:11:16 2016 -0500
Revision:
49:36954b62f503
Parent:
34:11fffbe98ef9
Child:
50:e967f9befbd0
Added a Read Scratchpad operation for DS28E15/22/25. Added comments for various classes.

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 34:11fffbe98ef9 155 OneWireSlave::CmdResult DS28E15_22_25::writeAuthBlockProtection(const ISha256MacCoprocessor & MacCoproc, const BlockProtection & newProtection, const BlockProtection & oldProtection, bool contflag)
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 34:11fffbe98ef9 223 OneWireSlave::CmdResult DS28E15_22_25::writeBlockProtection(const BlockProtection & protection, bool continuing)
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 25:bdb1c5a53b58 228 // check if not continuing a previous block write
IanBenzMaxim 25:bdb1c5a53b58 229 if (!continuing)
IanBenzMaxim 25:bdb1c5a53b58 230 {
IanBenzMaxim 25:bdb1c5a53b58 231 buf[cnt++] = CMD_WRITE_BLOCK_PROTECT;
IanBenzMaxim 25:bdb1c5a53b58 232 }
IanBenzMaxim 25:bdb1c5a53b58 233
IanBenzMaxim 25:bdb1c5a53b58 234 // compute parameter byte
IanBenzMaxim 49:36954b62f503 235 buf[cnt++] = protection.statusByte();
IanBenzMaxim 25:bdb1c5a53b58 236
IanBenzMaxim 25:bdb1c5a53b58 237 m_OW_master.OWWriteBlock(&buf[0], cnt);
IanBenzMaxim 25:bdb1c5a53b58 238
IanBenzMaxim 25:bdb1c5a53b58 239 // Read CRC
IanBenzMaxim 25:bdb1c5a53b58 240 m_OW_master.OWReadBlock(&buf[cnt], 2);
IanBenzMaxim 25:bdb1c5a53b58 241 cnt += 2;
IanBenzMaxim 25:bdb1c5a53b58 242
IanBenzMaxim 25:bdb1c5a53b58 243 // check CRC16
IanBenzMaxim 25:bdb1c5a53b58 244 if (OneWireMaster::calculateCRC16(buf, 0, cnt) != 0xB001)
IanBenzMaxim 25:bdb1c5a53b58 245 return CommunicationError;
IanBenzMaxim 25:bdb1c5a53b58 246
IanBenzMaxim 25:bdb1c5a53b58 247 // DATASHEET_CORRECTION, on continue need second release byte
IanBenzMaxim 25:bdb1c5a53b58 248 if (continuing)
IanBenzMaxim 25:bdb1c5a53b58 249 m_OW_master.OWWriteByte(0xAA);
IanBenzMaxim 25:bdb1c5a53b58 250
IanBenzMaxim 25:bdb1c5a53b58 251 // sent release
IanBenzMaxim 25:bdb1c5a53b58 252 m_OW_master.OWWriteBytePower(0xAA);
IanBenzMaxim 25:bdb1c5a53b58 253
IanBenzMaxim 34:11fffbe98ef9 254 // now wait for the programming.
IanBenzMaxim 34:11fffbe98ef9 255 wait_ms(eepromWriteDelayMs);
IanBenzMaxim 25:bdb1c5a53b58 256
IanBenzMaxim 25:bdb1c5a53b58 257 // disable strong pullup
IanBenzMaxim 32:bce180b544ed 258 m_OW_master.OWSetLevel(OneWireMaster::LEVEL_NORMAL);
IanBenzMaxim 25:bdb1c5a53b58 259
IanBenzMaxim 25:bdb1c5a53b58 260 // read the CS byte
IanBenzMaxim 25:bdb1c5a53b58 261 m_OW_master.OWReadByte(cs);
IanBenzMaxim 25:bdb1c5a53b58 262
IanBenzMaxim 25:bdb1c5a53b58 263 if (cs == 0xAA)
IanBenzMaxim 25:bdb1c5a53b58 264 return Success;
IanBenzMaxim 25:bdb1c5a53b58 265 // else
IanBenzMaxim 25:bdb1c5a53b58 266 return OperationFailure;
IanBenzMaxim 25:bdb1c5a53b58 267 }
IanBenzMaxim 25:bdb1c5a53b58 268
IanBenzMaxim 34:11fffbe98ef9 269 OneWireSlave::CmdResult DS28E15_22_25::readBlockProtection(unsigned int blockNum, BlockProtection & protection)
IanBenzMaxim 25:bdb1c5a53b58 270 {
IanBenzMaxim 34:11fffbe98ef9 271 std::uint8_t buf;
IanBenzMaxim 34:11fffbe98ef9 272 CmdResult result = readStatus(false, false, blockNum, &buf);
IanBenzMaxim 25:bdb1c5a53b58 273 if (result == Success)
IanBenzMaxim 49:36954b62f503 274 protection.setStatusByte(buf);
IanBenzMaxim 25:bdb1c5a53b58 275 return result;
IanBenzMaxim 25:bdb1c5a53b58 276 }
IanBenzMaxim 25:bdb1c5a53b58 277
IanBenzMaxim 34:11fffbe98ef9 278 OneWireSlave::CmdResult DS28E15_22_25::readStatus(bool personality, bool allpages, unsigned int pageNum, std::uint8_t * rdbuf) const
IanBenzMaxim 25:bdb1c5a53b58 279 {
IanBenzMaxim 34:11fffbe98ef9 280 std::uint8_t buf[256];
IanBenzMaxim 25:bdb1c5a53b58 281 int cnt, offset, rdnum;
IanBenzMaxim 25:bdb1c5a53b58 282
IanBenzMaxim 25:bdb1c5a53b58 283 cnt = 0;
IanBenzMaxim 25:bdb1c5a53b58 284 offset = 0;
IanBenzMaxim 25:bdb1c5a53b58 285
IanBenzMaxim 25:bdb1c5a53b58 286 buf[cnt++] = CMD_READ_STATUS;
IanBenzMaxim 25:bdb1c5a53b58 287 if (personality)
IanBenzMaxim 25:bdb1c5a53b58 288 buf[cnt++] = 0xE0;
IanBenzMaxim 25:bdb1c5a53b58 289 else if (!allpages)
IanBenzMaxim 25:bdb1c5a53b58 290 buf[cnt++] = pageNum;
IanBenzMaxim 25:bdb1c5a53b58 291 else
IanBenzMaxim 25:bdb1c5a53b58 292 buf[cnt++] = 0;
IanBenzMaxim 25:bdb1c5a53b58 293
IanBenzMaxim 25:bdb1c5a53b58 294 // send the command
IanBenzMaxim 25:bdb1c5a53b58 295 m_OW_master.OWWriteBlock(&buf[0], 2);
IanBenzMaxim 25:bdb1c5a53b58 296
IanBenzMaxim 25:bdb1c5a53b58 297 offset = cnt + 2;
IanBenzMaxim 25:bdb1c5a53b58 298
IanBenzMaxim 25:bdb1c5a53b58 299 // adjust data length
IanBenzMaxim 25:bdb1c5a53b58 300 if ((romId.familyCode() == DS28E25_FAMILY) || (romId.familyCode() == DS28E22_FAMILY))
IanBenzMaxim 25:bdb1c5a53b58 301 {
IanBenzMaxim 25:bdb1c5a53b58 302 if (personality)
IanBenzMaxim 25:bdb1c5a53b58 303 rdnum = 8;
IanBenzMaxim 25:bdb1c5a53b58 304 else if (allpages)
IanBenzMaxim 25:bdb1c5a53b58 305 rdnum = 20;
IanBenzMaxim 25:bdb1c5a53b58 306 else
IanBenzMaxim 25:bdb1c5a53b58 307 rdnum = 5;
IanBenzMaxim 25:bdb1c5a53b58 308 }
IanBenzMaxim 25:bdb1c5a53b58 309 else
IanBenzMaxim 25:bdb1c5a53b58 310 {
IanBenzMaxim 25:bdb1c5a53b58 311 if ((personality) || (allpages))
IanBenzMaxim 25:bdb1c5a53b58 312 rdnum = 8;
IanBenzMaxim 25:bdb1c5a53b58 313 else
IanBenzMaxim 25:bdb1c5a53b58 314 rdnum = 5;
IanBenzMaxim 25:bdb1c5a53b58 315 }
IanBenzMaxim 25:bdb1c5a53b58 316
IanBenzMaxim 25:bdb1c5a53b58 317 // Read the bytes
IanBenzMaxim 25:bdb1c5a53b58 318 m_OW_master.OWReadBlock(&buf[cnt],rdnum);
IanBenzMaxim 25:bdb1c5a53b58 319 cnt += rdnum;
IanBenzMaxim 25:bdb1c5a53b58 320
IanBenzMaxim 25:bdb1c5a53b58 321 // check the first CRC16
IanBenzMaxim 25:bdb1c5a53b58 322 if (OneWireMaster::calculateCRC16(buf, 0, offset) != 0xB001)
IanBenzMaxim 25:bdb1c5a53b58 323 return CommunicationError;
IanBenzMaxim 25:bdb1c5a53b58 324
IanBenzMaxim 25:bdb1c5a53b58 325 if ((((romId.familyCode() == DS28E25_FAMILY) || (romId.familyCode() == DS28E22_FAMILY))
IanBenzMaxim 25:bdb1c5a53b58 326 && (allpages || (pageNum == 15))) ||
IanBenzMaxim 25:bdb1c5a53b58 327 (personality || allpages || (pageNum == 1)))
IanBenzMaxim 25:bdb1c5a53b58 328 {
IanBenzMaxim 25:bdb1c5a53b58 329 // check the second CRC16
IanBenzMaxim 25:bdb1c5a53b58 330 if (OneWireMaster::calculateCRC16(buf, offset, (cnt - offset)) != 0xB001)
IanBenzMaxim 25:bdb1c5a53b58 331 return CommunicationError;
IanBenzMaxim 25:bdb1c5a53b58 332 }
IanBenzMaxim 25:bdb1c5a53b58 333
IanBenzMaxim 25:bdb1c5a53b58 334 // copy the data to the read buffer
IanBenzMaxim 25:bdb1c5a53b58 335 memcpy(rdbuf, &buf[offset], rdnum - 4);
IanBenzMaxim 25:bdb1c5a53b58 336
IanBenzMaxim 25:bdb1c5a53b58 337 return Success;
IanBenzMaxim 25:bdb1c5a53b58 338 }
IanBenzMaxim 25:bdb1c5a53b58 339
IanBenzMaxim 49:36954b62f503 340 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 341 {
IanBenzMaxim 49:36954b62f503 342 ISha256MacCoprocessor::AuthMacData authMacData;
IanBenzMaxim 49:36954b62f503 343
IanBenzMaxim 49:36954b62f503 344 // insert ROM number or FF
IanBenzMaxim 49:36954b62f503 345 std::memcpy(authMacData, romId, RomId::byteLen);
IanBenzMaxim 49:36954b62f503 346
IanBenzMaxim 49:36954b62f503 347 authMacData[10] = pageNum;
IanBenzMaxim 25:bdb1c5a53b58 348
IanBenzMaxim 49:36954b62f503 349 authMacData[9] = manId[0];
IanBenzMaxim 49:36954b62f503 350 authMacData[8] = manId[1];
IanBenzMaxim 25:bdb1c5a53b58 351
IanBenzMaxim 49:36954b62f503 352 authMacData[11] = 0x00;
IanBenzMaxim 25:bdb1c5a53b58 353
IanBenzMaxim 49:36954b62f503 354 return MacCoproc.computeAuthMac(pageData, challenge, authMacData, mac);
IanBenzMaxim 25:bdb1c5a53b58 355 }
IanBenzMaxim 25:bdb1c5a53b58 356
IanBenzMaxim 49:36954b62f503 357 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 358 {
IanBenzMaxim 49:36954b62f503 359 RomId romId;
IanBenzMaxim 49:36954b62f503 360 std::memset(romId, 0xFF, RomId::byteLen);
IanBenzMaxim 49:36954b62f503 361 return computeAuthMac(MacCoproc, pageData, pageNum, challenge, romId, manId, mac);
IanBenzMaxim 49:36954b62f503 362 }
IanBenzMaxim 49:36954b62f503 363
IanBenzMaxim 49:36954b62f503 364 OneWireSlave::CmdResult DS28E15_22_25::computeReadPageMac(unsigned int page_num, bool anon, Mac & mac) const
IanBenzMaxim 25:bdb1c5a53b58 365 {
IanBenzMaxim 25:bdb1c5a53b58 366 std::uint8_t buf[256],cs;
IanBenzMaxim 25:bdb1c5a53b58 367 int cnt = 0;
IanBenzMaxim 25:bdb1c5a53b58 368
IanBenzMaxim 25:bdb1c5a53b58 369 buf[cnt++] = CMD_COMPUTE_PAGEMAC;
IanBenzMaxim 25:bdb1c5a53b58 370 buf[cnt++] = ((anon) ? 0xE0 : 0x00) | page_num;
IanBenzMaxim 25:bdb1c5a53b58 371
IanBenzMaxim 25:bdb1c5a53b58 372 // Send command
IanBenzMaxim 25:bdb1c5a53b58 373 m_OW_master.OWWriteBlock(&buf[0], 2);
IanBenzMaxim 25:bdb1c5a53b58 374
IanBenzMaxim 25:bdb1c5a53b58 375 // read first CRC byte
IanBenzMaxim 25:bdb1c5a53b58 376 m_OW_master.OWReadByte(buf[cnt++]);
IanBenzMaxim 25:bdb1c5a53b58 377
IanBenzMaxim 25:bdb1c5a53b58 378 // read the last CRC and enable
IanBenzMaxim 25:bdb1c5a53b58 379 m_OW_master.OWReadBytePower(buf[cnt++]);
IanBenzMaxim 25:bdb1c5a53b58 380
IanBenzMaxim 25:bdb1c5a53b58 381 // now wait for the MAC computation.
IanBenzMaxim 34:11fffbe98ef9 382 wait_ms(shaComputationDelayMs * 2);
IanBenzMaxim 25:bdb1c5a53b58 383
IanBenzMaxim 25:bdb1c5a53b58 384 // disable strong pullup
IanBenzMaxim 32:bce180b544ed 385 m_OW_master.OWSetLevel(OneWireMaster::LEVEL_NORMAL);
IanBenzMaxim 25:bdb1c5a53b58 386
IanBenzMaxim 25:bdb1c5a53b58 387 // check CRC16
IanBenzMaxim 25:bdb1c5a53b58 388 if (OneWireMaster::calculateCRC16(buf, 0, cnt) != 0xB001)
IanBenzMaxim 25:bdb1c5a53b58 389 return CommunicationError;
IanBenzMaxim 25:bdb1c5a53b58 390
IanBenzMaxim 25:bdb1c5a53b58 391 // read the CS byte
IanBenzMaxim 25:bdb1c5a53b58 392 m_OW_master.OWReadByte(cs);
IanBenzMaxim 25:bdb1c5a53b58 393 if (cs != 0xAA)
IanBenzMaxim 25:bdb1c5a53b58 394 return OperationFailure;
IanBenzMaxim 25:bdb1c5a53b58 395
IanBenzMaxim 25:bdb1c5a53b58 396 // read the MAC and CRC
IanBenzMaxim 33:a4c015046956 397 m_OW_master.OWReadBlock(&buf[0], (Mac::length + 2));
IanBenzMaxim 25:bdb1c5a53b58 398
IanBenzMaxim 25:bdb1c5a53b58 399 // check CRC16
IanBenzMaxim 33:a4c015046956 400 if (OneWireMaster::calculateCRC16(buf, 0, (Mac::length + 2)) != 0xB001)
IanBenzMaxim 25:bdb1c5a53b58 401 return CommunicationError;
IanBenzMaxim 25:bdb1c5a53b58 402
IanBenzMaxim 25:bdb1c5a53b58 403 // copy MAC to return buffer
IanBenzMaxim 33:a4c015046956 404 memcpy(mac, buf, Mac::length);
IanBenzMaxim 25:bdb1c5a53b58 405
IanBenzMaxim 25:bdb1c5a53b58 406 return Success;
IanBenzMaxim 25:bdb1c5a53b58 407 }
IanBenzMaxim 25:bdb1c5a53b58 408
IanBenzMaxim 34:11fffbe98ef9 409 OneWireSlave::CmdResult DS28E15_22_25::computeSecret(unsigned int page_num, bool lock)
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_LOCK_SECRET;
IanBenzMaxim 25:bdb1c5a53b58 415 buf[cnt++] = (lock) ? (0xE0 | page_num) : page_num; // lock flag
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 CRC
IanBenzMaxim 25:bdb1c5a53b58 421 m_OW_master.OWReadBlock(&buf[cnt], 2);
IanBenzMaxim 25:bdb1c5a53b58 422 cnt += 2;
IanBenzMaxim 25:bdb1c5a53b58 423
IanBenzMaxim 25:bdb1c5a53b58 424 // check CRC16
IanBenzMaxim 25:bdb1c5a53b58 425 if (OneWireMaster::calculateCRC16(buf, 0, cnt) != 0xB001)
IanBenzMaxim 25:bdb1c5a53b58 426 return CommunicationError;
IanBenzMaxim 25:bdb1c5a53b58 427
IanBenzMaxim 25:bdb1c5a53b58 428 // send release and strong pull-up
IanBenzMaxim 25:bdb1c5a53b58 429 m_OW_master.OWWriteBytePower(0xAA);
IanBenzMaxim 25:bdb1c5a53b58 430
IanBenzMaxim 34:11fffbe98ef9 431 // now wait for the MAC computations and secret programming.
IanBenzMaxim 34:11fffbe98ef9 432 wait_ms(shaComputationDelayMs * 2 + secretEepromWriteDelayMs());
IanBenzMaxim 25:bdb1c5a53b58 433
IanBenzMaxim 25:bdb1c5a53b58 434 // disable strong pullup
IanBenzMaxim 32:bce180b544ed 435 m_OW_master.OWSetLevel(OneWireMaster::LEVEL_NORMAL);
IanBenzMaxim 25:bdb1c5a53b58 436
IanBenzMaxim 25:bdb1c5a53b58 437 // read the CS byte
IanBenzMaxim 25:bdb1c5a53b58 438 m_OW_master.OWReadByte(cs);
IanBenzMaxim 25:bdb1c5a53b58 439
IanBenzMaxim 25:bdb1c5a53b58 440 if (cs == 0xAA)
IanBenzMaxim 25:bdb1c5a53b58 441 return Success;
IanBenzMaxim 25:bdb1c5a53b58 442 // else
IanBenzMaxim 25:bdb1c5a53b58 443 return OperationFailure;
IanBenzMaxim 25:bdb1c5a53b58 444 }
IanBenzMaxim 25:bdb1c5a53b58 445
IanBenzMaxim 34:11fffbe98ef9 446 OneWireSlave::CmdResult DS28E15_22_25::writeScratchpad(const Scratchpad & data) const
IanBenzMaxim 25:bdb1c5a53b58 447 {
IanBenzMaxim 25:bdb1c5a53b58 448 std::uint8_t buf[256];
IanBenzMaxim 25:bdb1c5a53b58 449 int cnt = 0, offset;
IanBenzMaxim 25:bdb1c5a53b58 450
IanBenzMaxim 49:36954b62f503 451 buf[cnt++] = CMD_READ_WRITE_SCRATCHPAD;
IanBenzMaxim 25:bdb1c5a53b58 452 if ((romId.familyCode() == DS28E25_FAMILY) || (romId.familyCode() == DS28E22_FAMILY))
IanBenzMaxim 25:bdb1c5a53b58 453 buf[cnt++] = 0x20;
IanBenzMaxim 25:bdb1c5a53b58 454 else
IanBenzMaxim 25:bdb1c5a53b58 455 buf[cnt++] = 0x00;
IanBenzMaxim 25:bdb1c5a53b58 456
IanBenzMaxim 25:bdb1c5a53b58 457 // Send command
IanBenzMaxim 25:bdb1c5a53b58 458 m_OW_master.OWWriteBlock(&buf[0], 2);
IanBenzMaxim 25:bdb1c5a53b58 459
IanBenzMaxim 25:bdb1c5a53b58 460 // Read CRC
IanBenzMaxim 25:bdb1c5a53b58 461 m_OW_master.OWReadBlock(&buf[cnt], 2);
IanBenzMaxim 25:bdb1c5a53b58 462 cnt += 2;
IanBenzMaxim 25:bdb1c5a53b58 463
IanBenzMaxim 25:bdb1c5a53b58 464 offset = cnt;
IanBenzMaxim 25:bdb1c5a53b58 465
IanBenzMaxim 25:bdb1c5a53b58 466 // add the data
IanBenzMaxim 33:a4c015046956 467 memcpy(&buf[cnt], data, data.length);
IanBenzMaxim 33:a4c015046956 468 cnt += data.length;
IanBenzMaxim 25:bdb1c5a53b58 469
IanBenzMaxim 25:bdb1c5a53b58 470 // Send the data
IanBenzMaxim 33:a4c015046956 471 m_OW_master.OWWriteBlock(data, data.length);
IanBenzMaxim 25:bdb1c5a53b58 472
IanBenzMaxim 25:bdb1c5a53b58 473 // Read CRC
IanBenzMaxim 25:bdb1c5a53b58 474 m_OW_master.OWReadBlock(&buf[cnt], 2);
IanBenzMaxim 25:bdb1c5a53b58 475 cnt += 2;
IanBenzMaxim 25:bdb1c5a53b58 476
IanBenzMaxim 25:bdb1c5a53b58 477 // check first CRC16
IanBenzMaxim 25:bdb1c5a53b58 478 if (OneWireMaster::calculateCRC16(buf, 0, offset) != 0xB001)
IanBenzMaxim 25:bdb1c5a53b58 479 return CommunicationError;
IanBenzMaxim 25:bdb1c5a53b58 480
IanBenzMaxim 25:bdb1c5a53b58 481 // check the second CRC16
IanBenzMaxim 25:bdb1c5a53b58 482 if (OneWireMaster::calculateCRC16(buf, offset, (cnt - offset)) != 0xB001)
IanBenzMaxim 25:bdb1c5a53b58 483 return CommunicationError;
IanBenzMaxim 25:bdb1c5a53b58 484
IanBenzMaxim 25:bdb1c5a53b58 485 return Success;
IanBenzMaxim 25:bdb1c5a53b58 486 }
IanBenzMaxim 25:bdb1c5a53b58 487
IanBenzMaxim 49:36954b62f503 488 OneWireSlave::CmdResult DS28E15_22_25::readScratchpad(Scratchpad & data) const
IanBenzMaxim 49:36954b62f503 489 {
IanBenzMaxim 49:36954b62f503 490 std::uint8_t buf[256];
IanBenzMaxim 49:36954b62f503 491 int cnt = 0, offset;
IanBenzMaxim 49:36954b62f503 492
IanBenzMaxim 49:36954b62f503 493 buf[cnt++] = CMD_READ_WRITE_SCRATCHPAD;
IanBenzMaxim 49:36954b62f503 494 if ((romId.familyCode() == DS28E25_FAMILY) || (romId.familyCode() == DS28E22_FAMILY))
IanBenzMaxim 49:36954b62f503 495 buf[cnt++] = 0x2F;
IanBenzMaxim 49:36954b62f503 496 else
IanBenzMaxim 49:36954b62f503 497 buf[cnt++] = 0x0F;
IanBenzMaxim 49:36954b62f503 498
IanBenzMaxim 49:36954b62f503 499 // Send command
IanBenzMaxim 49:36954b62f503 500 m_OW_master.OWWriteBlock(&buf[0], 2);
IanBenzMaxim 49:36954b62f503 501
IanBenzMaxim 49:36954b62f503 502 // Read CRC
IanBenzMaxim 49:36954b62f503 503 m_OW_master.OWReadBlock(&buf[cnt], 2);
IanBenzMaxim 49:36954b62f503 504 cnt += 2;
IanBenzMaxim 49:36954b62f503 505
IanBenzMaxim 49:36954b62f503 506 offset = cnt;
IanBenzMaxim 49:36954b62f503 507
IanBenzMaxim 49:36954b62f503 508 // Receive the data
IanBenzMaxim 49:36954b62f503 509 m_OW_master.OWReadBlock(&buf[cnt], data.length);
IanBenzMaxim 49:36954b62f503 510 cnt += data.length;
IanBenzMaxim 49:36954b62f503 511
IanBenzMaxim 49:36954b62f503 512 // Read CRC
IanBenzMaxim 49:36954b62f503 513 m_OW_master.OWReadBlock(&buf[cnt], 2);
IanBenzMaxim 49:36954b62f503 514 cnt += 2;
IanBenzMaxim 49:36954b62f503 515
IanBenzMaxim 49:36954b62f503 516 // check first CRC16
IanBenzMaxim 49:36954b62f503 517 if (OneWireMaster::calculateCRC16(buf, 0, offset) != 0xB001)
IanBenzMaxim 49:36954b62f503 518 return CommunicationError;
IanBenzMaxim 49:36954b62f503 519
IanBenzMaxim 49:36954b62f503 520 // check the second CRC16
IanBenzMaxim 49:36954b62f503 521 if (OneWireMaster::calculateCRC16(buf, offset, (cnt - offset)) != 0xB001)
IanBenzMaxim 49:36954b62f503 522 return CommunicationError;
IanBenzMaxim 49:36954b62f503 523
IanBenzMaxim 49:36954b62f503 524 // Copy to output
IanBenzMaxim 49:36954b62f503 525 memcpy(data, &buf[offset], data.length);
IanBenzMaxim 49:36954b62f503 526
IanBenzMaxim 49:36954b62f503 527 return Success;
IanBenzMaxim 49:36954b62f503 528 }
IanBenzMaxim 49:36954b62f503 529
IanBenzMaxim 34:11fffbe98ef9 530 OneWireSlave::CmdResult DS28E15_22_25::loadSecret(bool lock)
IanBenzMaxim 25:bdb1c5a53b58 531 {
IanBenzMaxim 25:bdb1c5a53b58 532 std::uint8_t buf[256], cs;
IanBenzMaxim 25:bdb1c5a53b58 533 int cnt = 0;
IanBenzMaxim 25:bdb1c5a53b58 534
IanBenzMaxim 25:bdb1c5a53b58 535 buf[cnt++] = CMD_LOAD_LOCK_SECRET;
IanBenzMaxim 25:bdb1c5a53b58 536 buf[cnt++] = (lock) ? 0xE0 : 0x00; // lock flag
IanBenzMaxim 25:bdb1c5a53b58 537
IanBenzMaxim 25:bdb1c5a53b58 538 // Send command
IanBenzMaxim 25:bdb1c5a53b58 539 m_OW_master.OWWriteBlock(&buf[0], 2);
IanBenzMaxim 25:bdb1c5a53b58 540
IanBenzMaxim 25:bdb1c5a53b58 541 // Read CRC
IanBenzMaxim 25:bdb1c5a53b58 542 m_OW_master.OWReadBlock(&buf[cnt], 2);
IanBenzMaxim 25:bdb1c5a53b58 543 cnt += 2;
IanBenzMaxim 25:bdb1c5a53b58 544
IanBenzMaxim 25:bdb1c5a53b58 545 // check CRC16
IanBenzMaxim 25:bdb1c5a53b58 546 if (OneWireMaster::calculateCRC16(buf, 0, cnt) != 0xB001)
IanBenzMaxim 25:bdb1c5a53b58 547 return CommunicationError;
IanBenzMaxim 25:bdb1c5a53b58 548
IanBenzMaxim 25:bdb1c5a53b58 549 // send release and strong pull-up
IanBenzMaxim 25:bdb1c5a53b58 550 m_OW_master.OWWriteBytePower(0xAA);
IanBenzMaxim 25:bdb1c5a53b58 551
IanBenzMaxim 34:11fffbe98ef9 552 // now wait for the secret programming.
IanBenzMaxim 34:11fffbe98ef9 553 wait_ms(secretEepromWriteDelayMs());
IanBenzMaxim 25:bdb1c5a53b58 554
IanBenzMaxim 25:bdb1c5a53b58 555 // disable strong pullup
IanBenzMaxim 32:bce180b544ed 556 m_OW_master.OWSetLevel(OneWireMaster::LEVEL_NORMAL);
IanBenzMaxim 25:bdb1c5a53b58 557
IanBenzMaxim 25:bdb1c5a53b58 558 // read the CS byte
IanBenzMaxim 25:bdb1c5a53b58 559 m_OW_master.OWReadByte(cs);
IanBenzMaxim 25:bdb1c5a53b58 560
IanBenzMaxim 25:bdb1c5a53b58 561 if (cs == 0xAA)
IanBenzMaxim 25:bdb1c5a53b58 562 return Success;
IanBenzMaxim 25:bdb1c5a53b58 563 // else
IanBenzMaxim 25:bdb1c5a53b58 564 return OperationFailure;
IanBenzMaxim 25:bdb1c5a53b58 565 }
IanBenzMaxim 25:bdb1c5a53b58 566
IanBenzMaxim 33:a4c015046956 567 OneWireSlave::CmdResult DS28E15_22_25::readPage(unsigned int page, Page & rdbuf, bool continuing) const
IanBenzMaxim 25:bdb1c5a53b58 568 {
IanBenzMaxim 25:bdb1c5a53b58 569 std::uint8_t buf[256];
IanBenzMaxim 25:bdb1c5a53b58 570 int cnt, offset;
IanBenzMaxim 25:bdb1c5a53b58 571
IanBenzMaxim 25:bdb1c5a53b58 572 cnt = 0;
IanBenzMaxim 25:bdb1c5a53b58 573 offset = 0;
IanBenzMaxim 25:bdb1c5a53b58 574
IanBenzMaxim 25:bdb1c5a53b58 575 // check if not continuing a previous block write
IanBenzMaxim 25:bdb1c5a53b58 576 if (!continuing)
IanBenzMaxim 25:bdb1c5a53b58 577 {
IanBenzMaxim 25:bdb1c5a53b58 578 buf[cnt++] = CMD_READ_MEMORY;
IanBenzMaxim 25:bdb1c5a53b58 579 buf[cnt++] = page; // address
IanBenzMaxim 25:bdb1c5a53b58 580
IanBenzMaxim 25:bdb1c5a53b58 581 // Send command
IanBenzMaxim 25:bdb1c5a53b58 582 m_OW_master.OWWriteBlock(&buf[0], 2);
IanBenzMaxim 25:bdb1c5a53b58 583
IanBenzMaxim 25:bdb1c5a53b58 584 // Read CRC
IanBenzMaxim 25:bdb1c5a53b58 585 m_OW_master.OWReadBlock(&buf[cnt], 2);
IanBenzMaxim 25:bdb1c5a53b58 586 cnt += 2;
IanBenzMaxim 25:bdb1c5a53b58 587
IanBenzMaxim 25:bdb1c5a53b58 588 offset = cnt;
IanBenzMaxim 25:bdb1c5a53b58 589 }
IanBenzMaxim 25:bdb1c5a53b58 590
IanBenzMaxim 25:bdb1c5a53b58 591 // read data and CRC16
IanBenzMaxim 33:a4c015046956 592 m_OW_master.OWReadBlock(&buf[cnt], (rdbuf.length + 2));
IanBenzMaxim 33:a4c015046956 593 cnt += 34;
IanBenzMaxim 25:bdb1c5a53b58 594
IanBenzMaxim 25:bdb1c5a53b58 595 // check the first CRC16
IanBenzMaxim 25:bdb1c5a53b58 596 if (!continuing)
IanBenzMaxim 25:bdb1c5a53b58 597 {
IanBenzMaxim 25:bdb1c5a53b58 598 if (OneWireMaster::calculateCRC16(buf, 0, offset) != 0xB001)
IanBenzMaxim 25:bdb1c5a53b58 599 return CommunicationError;
IanBenzMaxim 25:bdb1c5a53b58 600 }
IanBenzMaxim 25:bdb1c5a53b58 601
IanBenzMaxim 25:bdb1c5a53b58 602 // check the second CRC16
IanBenzMaxim 25:bdb1c5a53b58 603 if (OneWireMaster::calculateCRC16(buf, offset, (cnt - offset)) != 0xB001)
IanBenzMaxim 25:bdb1c5a53b58 604 return CommunicationError;
IanBenzMaxim 25:bdb1c5a53b58 605
IanBenzMaxim 25:bdb1c5a53b58 606 // copy the data to the read buffer
IanBenzMaxim 33:a4c015046956 607 memcpy(rdbuf, &buf[offset], rdbuf.length);
IanBenzMaxim 25:bdb1c5a53b58 608
IanBenzMaxim 25:bdb1c5a53b58 609 return Success;
IanBenzMaxim 25:bdb1c5a53b58 610 }
IanBenzMaxim 25:bdb1c5a53b58 611
IanBenzMaxim 34:11fffbe98ef9 612 OneWireSlave::CmdResult DS28E15_22_25::writeAuthSegmentMac(unsigned int pageNum, unsigned int segmentNum, const Segment & newData, const Mac & mac, bool continuing)
IanBenzMaxim 25:bdb1c5a53b58 613 {
IanBenzMaxim 25:bdb1c5a53b58 614 std::uint8_t buf[256], cs;
IanBenzMaxim 25:bdb1c5a53b58 615 int cnt, i, 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_WRITE_AUTH_MEMORY;
IanBenzMaxim 25:bdb1c5a53b58 624 buf[cnt++] = (segmentNum << 5) | pageNum; // 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 // add the data
IanBenzMaxim 33:a4c015046956 637 for (i = 0; i < newData.length; i++)
IanBenzMaxim 25:bdb1c5a53b58 638 buf[cnt++] = newData[i];
IanBenzMaxim 25:bdb1c5a53b58 639
IanBenzMaxim 25:bdb1c5a53b58 640 // Send data
IanBenzMaxim 33:a4c015046956 641 m_OW_master.OWWriteBlock(newData, newData.length);
IanBenzMaxim 25:bdb1c5a53b58 642
IanBenzMaxim 25:bdb1c5a53b58 643 // read first CRC byte
IanBenzMaxim 25:bdb1c5a53b58 644 m_OW_master.OWReadByte(buf[cnt++]);
IanBenzMaxim 25:bdb1c5a53b58 645
IanBenzMaxim 25:bdb1c5a53b58 646 // read the last CRC and enable power
IanBenzMaxim 25:bdb1c5a53b58 647 m_OW_master.OWReadBytePower(buf[cnt++]);
IanBenzMaxim 25:bdb1c5a53b58 648
IanBenzMaxim 34:11fffbe98ef9 649 // now wait for the MAC computation.
IanBenzMaxim 34:11fffbe98ef9 650 wait_ms(shaComputationDelayMs);
IanBenzMaxim 25:bdb1c5a53b58 651
IanBenzMaxim 25:bdb1c5a53b58 652 // disable strong pullup
IanBenzMaxim 32:bce180b544ed 653 m_OW_master.OWSetLevel(OneWireMaster::LEVEL_NORMAL);
IanBenzMaxim 25:bdb1c5a53b58 654
IanBenzMaxim 25:bdb1c5a53b58 655 // check the first CRC16
IanBenzMaxim 25:bdb1c5a53b58 656 if (!continuing)
IanBenzMaxim 25:bdb1c5a53b58 657 {
IanBenzMaxim 25:bdb1c5a53b58 658 if (OneWireMaster::calculateCRC16(buf, 0, offset) != 0xB001)
IanBenzMaxim 25:bdb1c5a53b58 659 return CommunicationError;
IanBenzMaxim 25:bdb1c5a53b58 660 }
IanBenzMaxim 25:bdb1c5a53b58 661
IanBenzMaxim 25:bdb1c5a53b58 662 // check the second CRC16
IanBenzMaxim 25:bdb1c5a53b58 663 unsigned short CRC16 = 0;
IanBenzMaxim 25:bdb1c5a53b58 664
IanBenzMaxim 25:bdb1c5a53b58 665 // DS28E25/DS28E22, crc gets calculagted with CS byte
IanBenzMaxim 25:bdb1c5a53b58 666 if ((romId.familyCode() == DS28E25_FAMILY) || (romId.familyCode() == DS28E22_FAMILY))
IanBenzMaxim 25:bdb1c5a53b58 667 {
IanBenzMaxim 25:bdb1c5a53b58 668 if (continuing)
IanBenzMaxim 25:bdb1c5a53b58 669 CRC16 = OneWireMaster::calculateCRC16(CRC16, 0xAA);
IanBenzMaxim 25:bdb1c5a53b58 670 }
IanBenzMaxim 25:bdb1c5a53b58 671
IanBenzMaxim 25:bdb1c5a53b58 672 CRC16 = OneWireMaster::calculateCRC16(buf, offset, (cnt - offset), CRC16);
IanBenzMaxim 25:bdb1c5a53b58 673
IanBenzMaxim 25:bdb1c5a53b58 674 if (CRC16 != 0xB001)
IanBenzMaxim 25:bdb1c5a53b58 675 return CommunicationError;
IanBenzMaxim 25:bdb1c5a53b58 676
IanBenzMaxim 25:bdb1c5a53b58 677 // transmit MAC as a block
IanBenzMaxim 33:a4c015046956 678 m_OW_master.OWWriteBlock(mac, mac.length);
IanBenzMaxim 25:bdb1c5a53b58 679
IanBenzMaxim 25:bdb1c5a53b58 680 // calculate CRC on MAC
IanBenzMaxim 33:a4c015046956 681 CRC16 = OneWireMaster::calculateCRC16(mac, 0, mac.length);
IanBenzMaxim 25:bdb1c5a53b58 682
IanBenzMaxim 25:bdb1c5a53b58 683 // append read of CRC16 and CS byte
IanBenzMaxim 25:bdb1c5a53b58 684 m_OW_master.OWReadBlock(&buf[0], 3);
IanBenzMaxim 25:bdb1c5a53b58 685 cnt = 3;
IanBenzMaxim 25:bdb1c5a53b58 686
IanBenzMaxim 25:bdb1c5a53b58 687 // ckeck CRC16
IanBenzMaxim 25:bdb1c5a53b58 688 CRC16 = OneWireMaster::calculateCRC16(buf, 0, (cnt - 1), CRC16);
IanBenzMaxim 25:bdb1c5a53b58 689
IanBenzMaxim 25:bdb1c5a53b58 690 if (CRC16 != 0xB001)
IanBenzMaxim 25:bdb1c5a53b58 691 return CommunicationError;
IanBenzMaxim 25:bdb1c5a53b58 692
IanBenzMaxim 25:bdb1c5a53b58 693 // check CS
IanBenzMaxim 25:bdb1c5a53b58 694 if (buf[cnt-1] != 0xAA)
IanBenzMaxim 25:bdb1c5a53b58 695 return OperationFailure;
IanBenzMaxim 25:bdb1c5a53b58 696
IanBenzMaxim 25:bdb1c5a53b58 697 // send release and strong pull-up
IanBenzMaxim 25:bdb1c5a53b58 698 m_OW_master.OWWriteBytePower(0xAA);
IanBenzMaxim 25:bdb1c5a53b58 699
IanBenzMaxim 34:11fffbe98ef9 700 // now wait for the programming.
IanBenzMaxim 34:11fffbe98ef9 701 wait_ms(eepromWriteDelayMs);
IanBenzMaxim 25:bdb1c5a53b58 702
IanBenzMaxim 25:bdb1c5a53b58 703 // disable strong pullup
IanBenzMaxim 32:bce180b544ed 704 m_OW_master.OWSetLevel(OneWireMaster::LEVEL_NORMAL);
IanBenzMaxim 25:bdb1c5a53b58 705
IanBenzMaxim 25:bdb1c5a53b58 706 // read the CS byte
IanBenzMaxim 25:bdb1c5a53b58 707 m_OW_master.OWReadByte(cs);
IanBenzMaxim 25:bdb1c5a53b58 708
IanBenzMaxim 25:bdb1c5a53b58 709 if (cs == 0xAA)
IanBenzMaxim 25:bdb1c5a53b58 710 return Success;
IanBenzMaxim 25:bdb1c5a53b58 711 // else
IanBenzMaxim 25:bdb1c5a53b58 712 return OperationFailure;
IanBenzMaxim 25:bdb1c5a53b58 713 }
IanBenzMaxim 25:bdb1c5a53b58 714
IanBenzMaxim 49:36954b62f503 715 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 716 {
IanBenzMaxim 33:a4c015046956 717 ISha256MacCoprocessor::WriteMacData MT;
IanBenzMaxim 25:bdb1c5a53b58 718
IanBenzMaxim 25:bdb1c5a53b58 719 // insert ROM number
IanBenzMaxim 25:bdb1c5a53b58 720 memcpy(&MT[0], romId, RomId::byteLen);
IanBenzMaxim 25:bdb1c5a53b58 721
IanBenzMaxim 25:bdb1c5a53b58 722 MT[11] = segmentNum;
IanBenzMaxim 25:bdb1c5a53b58 723 MT[10] = pageNum;
IanBenzMaxim 25:bdb1c5a53b58 724 MT[9] = manId[0];
IanBenzMaxim 25:bdb1c5a53b58 725 MT[8] = manId[1];
IanBenzMaxim 25:bdb1c5a53b58 726
IanBenzMaxim 25:bdb1c5a53b58 727 // insert old data
IanBenzMaxim 33:a4c015046956 728 memcpy(&MT[12], oldData, Segment::length);
IanBenzMaxim 25:bdb1c5a53b58 729
IanBenzMaxim 25:bdb1c5a53b58 730 // insert new data
IanBenzMaxim 33:a4c015046956 731 memcpy(&MT[16], newData, Segment::length);
IanBenzMaxim 25:bdb1c5a53b58 732
IanBenzMaxim 33:a4c015046956 733 return MacCoproc.computeWriteMac(MT, mac);
IanBenzMaxim 25:bdb1c5a53b58 734 }
IanBenzMaxim 25:bdb1c5a53b58 735
IanBenzMaxim 49:36954b62f503 736 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 737 {
IanBenzMaxim 33:a4c015046956 738 ISha256MacCoprocessor::WriteMacData MT;
IanBenzMaxim 25:bdb1c5a53b58 739
IanBenzMaxim 25:bdb1c5a53b58 740 // insert ROM number
IanBenzMaxim 25:bdb1c5a53b58 741 std::memcpy(MT, romId, RomId::byteLen);
IanBenzMaxim 25:bdb1c5a53b58 742
IanBenzMaxim 25:bdb1c5a53b58 743 // instert block and page
IanBenzMaxim 25:bdb1c5a53b58 744 MT[11] = 0;
IanBenzMaxim 34:11fffbe98ef9 745 MT[10] = newProtection.blockNum();
IanBenzMaxim 25:bdb1c5a53b58 746
IanBenzMaxim 25:bdb1c5a53b58 747 MT[9] = manId[0];
IanBenzMaxim 25:bdb1c5a53b58 748 MT[8] = manId[1];
IanBenzMaxim 25:bdb1c5a53b58 749
IanBenzMaxim 25:bdb1c5a53b58 750 // old data
IanBenzMaxim 34:11fffbe98ef9 751 MT[12] = oldProtection.authProtection() ? 0x01 : 0x00;
IanBenzMaxim 34:11fffbe98ef9 752 MT[13] = oldProtection.eepromEmulation() ? 0x01 : 0x00;
IanBenzMaxim 34:11fffbe98ef9 753 MT[14] = oldProtection.writeProtection() ? 0x01 : 0x00;
IanBenzMaxim 34:11fffbe98ef9 754 MT[15] = oldProtection.readProtection() ? 0x01 : 0x00;
IanBenzMaxim 25:bdb1c5a53b58 755 // new data
IanBenzMaxim 34:11fffbe98ef9 756 MT[16] = newProtection.authProtection() ? 0x01 : 0x00;
IanBenzMaxim 34:11fffbe98ef9 757 MT[17] = newProtection.eepromEmulation() ? 0x01 : 0x00;
IanBenzMaxim 34:11fffbe98ef9 758 MT[18] = newProtection.writeProtection() ? 0x01 : 0x00;
IanBenzMaxim 34:11fffbe98ef9 759 MT[19] = newProtection.readProtection() ? 0x01 : 0x00;
IanBenzMaxim 25:bdb1c5a53b58 760
IanBenzMaxim 25:bdb1c5a53b58 761 // compute the mac
IanBenzMaxim 33:a4c015046956 762 return MacCoproc.computeWriteMac(MT, mac);
IanBenzMaxim 25:bdb1c5a53b58 763 }
IanBenzMaxim 25:bdb1c5a53b58 764
IanBenzMaxim 33:a4c015046956 765 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 766 {
IanBenzMaxim 25:bdb1c5a53b58 767 std::uint8_t buf[256], cs;
IanBenzMaxim 25:bdb1c5a53b58 768 int cnt, offset;
IanBenzMaxim 25:bdb1c5a53b58 769
IanBenzMaxim 25:bdb1c5a53b58 770 cnt = 0;
IanBenzMaxim 25:bdb1c5a53b58 771 offset = 0;
IanBenzMaxim 25:bdb1c5a53b58 772
IanBenzMaxim 25:bdb1c5a53b58 773 // check if not continuing a previous block write
IanBenzMaxim 25:bdb1c5a53b58 774 if (!continuing)
IanBenzMaxim 25:bdb1c5a53b58 775 {
IanBenzMaxim 25:bdb1c5a53b58 776 buf[cnt++] = CMD_WRITE_AUTH_MEMORY;
IanBenzMaxim 25:bdb1c5a53b58 777 buf[cnt++] = (segmentNum << 5) | pageNum; // address
IanBenzMaxim 25:bdb1c5a53b58 778
IanBenzMaxim 25:bdb1c5a53b58 779 // Send command
IanBenzMaxim 25:bdb1c5a53b58 780 m_OW_master.OWWriteBlock(&buf[0], 2);
IanBenzMaxim 25:bdb1c5a53b58 781
IanBenzMaxim 25:bdb1c5a53b58 782 // Read CRC
IanBenzMaxim 25:bdb1c5a53b58 783 m_OW_master.OWReadBlock(&buf[cnt], 2);
IanBenzMaxim 25:bdb1c5a53b58 784 cnt += 2;
IanBenzMaxim 25:bdb1c5a53b58 785
IanBenzMaxim 25:bdb1c5a53b58 786 offset = cnt;
IanBenzMaxim 25:bdb1c5a53b58 787 }
IanBenzMaxim 25:bdb1c5a53b58 788
IanBenzMaxim 25:bdb1c5a53b58 789 // add the data
IanBenzMaxim 33:a4c015046956 790 for (size_t i = 0; i < newData.length; i++)
IanBenzMaxim 25:bdb1c5a53b58 791 buf[cnt++] = newData[i];
IanBenzMaxim 25:bdb1c5a53b58 792
IanBenzMaxim 25:bdb1c5a53b58 793 // Send data
IanBenzMaxim 33:a4c015046956 794 m_OW_master.OWWriteBlock(newData, newData.length);
IanBenzMaxim 25:bdb1c5a53b58 795
IanBenzMaxim 25:bdb1c5a53b58 796 // read first CRC byte
IanBenzMaxim 25:bdb1c5a53b58 797 m_OW_master.OWReadByte(buf[cnt++]);
IanBenzMaxim 25:bdb1c5a53b58 798
IanBenzMaxim 25:bdb1c5a53b58 799 // read the last CRC and enable power
IanBenzMaxim 25:bdb1c5a53b58 800 m_OW_master.OWReadBytePower(buf[cnt++]);
IanBenzMaxim 25:bdb1c5a53b58 801
IanBenzMaxim 25:bdb1c5a53b58 802 // now wait for the MAC computation.
IanBenzMaxim 34:11fffbe98ef9 803 wait_ms(shaComputationDelayMs);
IanBenzMaxim 25:bdb1c5a53b58 804
IanBenzMaxim 25:bdb1c5a53b58 805 // disable strong pullup
IanBenzMaxim 32:bce180b544ed 806 m_OW_master.OWSetLevel(OneWireMaster::LEVEL_NORMAL);
IanBenzMaxim 25:bdb1c5a53b58 807
IanBenzMaxim 25:bdb1c5a53b58 808 // check the first CRC16
IanBenzMaxim 25:bdb1c5a53b58 809 if (!continuing)
IanBenzMaxim 25:bdb1c5a53b58 810 {
IanBenzMaxim 25:bdb1c5a53b58 811 if (OneWireMaster::calculateCRC16(buf, 0, offset) != 0xB001)
IanBenzMaxim 25:bdb1c5a53b58 812 return CommunicationError;
IanBenzMaxim 25:bdb1c5a53b58 813 }
IanBenzMaxim 25:bdb1c5a53b58 814
IanBenzMaxim 25:bdb1c5a53b58 815 // check the second CRC16
IanBenzMaxim 25:bdb1c5a53b58 816 unsigned short CRC16 = 0;
IanBenzMaxim 25:bdb1c5a53b58 817
IanBenzMaxim 25:bdb1c5a53b58 818 // DS28E25/DS28E22, crc gets calculagted with CS byte
IanBenzMaxim 25:bdb1c5a53b58 819 if ((romId.familyCode() == DS28E25_FAMILY) || (romId.familyCode() == DS28E22_FAMILY))
IanBenzMaxim 25:bdb1c5a53b58 820 {
IanBenzMaxim 25:bdb1c5a53b58 821 if (continuing)
IanBenzMaxim 25:bdb1c5a53b58 822 CRC16 = OneWireMaster::calculateCRC16(CRC16, 0xAA);
IanBenzMaxim 25:bdb1c5a53b58 823 }
IanBenzMaxim 25:bdb1c5a53b58 824
IanBenzMaxim 25:bdb1c5a53b58 825 CRC16 = OneWireMaster::calculateCRC16(buf, offset, (cnt - offset), CRC16);
IanBenzMaxim 25:bdb1c5a53b58 826
IanBenzMaxim 25:bdb1c5a53b58 827 if (CRC16 != 0xB001)
IanBenzMaxim 25:bdb1c5a53b58 828 return CommunicationError;
IanBenzMaxim 25:bdb1c5a53b58 829
IanBenzMaxim 25:bdb1c5a53b58 830 // compute the mac
IanBenzMaxim 25:bdb1c5a53b58 831 ISha256MacCoprocessor::CmdResult result;
IanBenzMaxim 33:a4c015046956 832 Mac mac;
IanBenzMaxim 49:36954b62f503 833 result = computeSegmentWriteMac(MacCoproc, pageNum, segmentNum, newData, oldData, romId, manId, mac);
IanBenzMaxim 25:bdb1c5a53b58 834 if (result != ISha256MacCoprocessor::Success)
IanBenzMaxim 25:bdb1c5a53b58 835 return OperationFailure;
IanBenzMaxim 25:bdb1c5a53b58 836
IanBenzMaxim 25:bdb1c5a53b58 837 // transmit MAC as a block
IanBenzMaxim 33:a4c015046956 838 m_OW_master.OWWriteBlock(mac, mac.length);
IanBenzMaxim 25:bdb1c5a53b58 839
IanBenzMaxim 25:bdb1c5a53b58 840 // calculate CRC on MAC
IanBenzMaxim 33:a4c015046956 841 CRC16 = OneWireMaster::calculateCRC16(mac, 0, mac.length);
IanBenzMaxim 25:bdb1c5a53b58 842
IanBenzMaxim 25:bdb1c5a53b58 843 // append read of CRC16 and CS byte
IanBenzMaxim 25:bdb1c5a53b58 844 m_OW_master.OWReadBlock(&buf[0], 3);
IanBenzMaxim 25:bdb1c5a53b58 845 cnt = 3;
IanBenzMaxim 25:bdb1c5a53b58 846
IanBenzMaxim 25:bdb1c5a53b58 847 // ckeck CRC16
IanBenzMaxim 25:bdb1c5a53b58 848 CRC16 = OneWireMaster::calculateCRC16(buf, 0, (cnt - 1), CRC16);
IanBenzMaxim 25:bdb1c5a53b58 849
IanBenzMaxim 25:bdb1c5a53b58 850 if (CRC16 != 0xB001)
IanBenzMaxim 25:bdb1c5a53b58 851 return CommunicationError;
IanBenzMaxim 25:bdb1c5a53b58 852
IanBenzMaxim 25:bdb1c5a53b58 853 // check CS
IanBenzMaxim 25:bdb1c5a53b58 854 if (buf[cnt-1] != 0xAA)
IanBenzMaxim 25:bdb1c5a53b58 855 return OperationFailure;
IanBenzMaxim 25:bdb1c5a53b58 856
IanBenzMaxim 25:bdb1c5a53b58 857 // send release and strong pull-up
IanBenzMaxim 25:bdb1c5a53b58 858 m_OW_master.OWWriteBytePower(0xAA);
IanBenzMaxim 25:bdb1c5a53b58 859
IanBenzMaxim 34:11fffbe98ef9 860 // now wait for the programming.
IanBenzMaxim 34:11fffbe98ef9 861 wait_ms(eepromWriteDelayMs);
IanBenzMaxim 25:bdb1c5a53b58 862
IanBenzMaxim 25:bdb1c5a53b58 863 // disable strong pullup
IanBenzMaxim 32:bce180b544ed 864 m_OW_master.OWSetLevel(OneWireMaster::LEVEL_NORMAL);
IanBenzMaxim 25:bdb1c5a53b58 865
IanBenzMaxim 25:bdb1c5a53b58 866 // read the CS byte
IanBenzMaxim 25:bdb1c5a53b58 867 m_OW_master.OWReadByte(cs);
IanBenzMaxim 25:bdb1c5a53b58 868
IanBenzMaxim 25:bdb1c5a53b58 869 if (cs == 0xAA)
IanBenzMaxim 25:bdb1c5a53b58 870 return Success;
IanBenzMaxim 25:bdb1c5a53b58 871 // else
IanBenzMaxim 25:bdb1c5a53b58 872 return OperationFailure;
IanBenzMaxim 25:bdb1c5a53b58 873 }
IanBenzMaxim 25:bdb1c5a53b58 874
IanBenzMaxim 33:a4c015046956 875 OneWireSlave::CmdResult DS28E15_22_25::readSegment(unsigned int page, unsigned int segment, Segment & data) const
IanBenzMaxim 25:bdb1c5a53b58 876 {
IanBenzMaxim 25:bdb1c5a53b58 877 OneWireMaster::CmdResult result;
IanBenzMaxim 25:bdb1c5a53b58 878 std::uint8_t buf[2];
IanBenzMaxim 25:bdb1c5a53b58 879
IanBenzMaxim 25:bdb1c5a53b58 880 buf[0] = CMD_READ_MEMORY;
IanBenzMaxim 25:bdb1c5a53b58 881 buf[1] = (segment << 5) | page;
IanBenzMaxim 25:bdb1c5a53b58 882
IanBenzMaxim 25:bdb1c5a53b58 883 // Transmit command
IanBenzMaxim 25:bdb1c5a53b58 884 m_OW_master.OWWriteBlock(buf, 2);
IanBenzMaxim 25:bdb1c5a53b58 885
IanBenzMaxim 25:bdb1c5a53b58 886 // Receive CRC
IanBenzMaxim 25:bdb1c5a53b58 887 result = m_OW_master.OWReadBlock(buf, 2);
IanBenzMaxim 25:bdb1c5a53b58 888
IanBenzMaxim 25:bdb1c5a53b58 889 // Receive data
IanBenzMaxim 25:bdb1c5a53b58 890 if (result == OneWireMaster::Success)
IanBenzMaxim 33:a4c015046956 891 result = m_OW_master.OWReadBlock(data, data.length);
IanBenzMaxim 25:bdb1c5a53b58 892
IanBenzMaxim 25:bdb1c5a53b58 893 return (result == OneWireMaster::Success ? OneWireSlave::Success : OneWireSlave::CommunicationError);
IanBenzMaxim 25:bdb1c5a53b58 894 }
IanBenzMaxim 25:bdb1c5a53b58 895
IanBenzMaxim 33:a4c015046956 896 OneWireSlave::CmdResult DS28E15_22_25::writeSegment(unsigned int page, unsigned int block, const Segment & data, bool continuing)
IanBenzMaxim 25:bdb1c5a53b58 897 {
IanBenzMaxim 25:bdb1c5a53b58 898 std::uint8_t buf[256], cs;
IanBenzMaxim 25:bdb1c5a53b58 899 int cnt, offset;
IanBenzMaxim 25:bdb1c5a53b58 900
IanBenzMaxim 25:bdb1c5a53b58 901 cnt = 0;
IanBenzMaxim 25:bdb1c5a53b58 902 offset = 0;
IanBenzMaxim 25:bdb1c5a53b58 903
IanBenzMaxim 25:bdb1c5a53b58 904 // check if not continuing a previous block write
IanBenzMaxim 25:bdb1c5a53b58 905 if (!continuing)
IanBenzMaxim 25:bdb1c5a53b58 906 {
IanBenzMaxim 25:bdb1c5a53b58 907 buf[cnt++] = CMD_WRITE_MEMORY;
IanBenzMaxim 25:bdb1c5a53b58 908 buf[cnt++] = (block << 5) | page; // address
IanBenzMaxim 25:bdb1c5a53b58 909
IanBenzMaxim 25:bdb1c5a53b58 910 // Send command
IanBenzMaxim 25:bdb1c5a53b58 911 m_OW_master.OWWriteBlock(&buf[0], 2);
IanBenzMaxim 25:bdb1c5a53b58 912
IanBenzMaxim 25:bdb1c5a53b58 913 // Read CRC
IanBenzMaxim 25:bdb1c5a53b58 914 m_OW_master.OWReadBlock(&buf[cnt], 2);
IanBenzMaxim 25:bdb1c5a53b58 915 cnt += 2;
IanBenzMaxim 25:bdb1c5a53b58 916
IanBenzMaxim 25:bdb1c5a53b58 917 offset = cnt;
IanBenzMaxim 25:bdb1c5a53b58 918 }
IanBenzMaxim 25:bdb1c5a53b58 919
IanBenzMaxim 25:bdb1c5a53b58 920 // add the data
IanBenzMaxim 33:a4c015046956 921 for (size_t i = 0; i < data.length; i++)
IanBenzMaxim 25:bdb1c5a53b58 922 buf[cnt++] = data[i];
IanBenzMaxim 25:bdb1c5a53b58 923
IanBenzMaxim 25:bdb1c5a53b58 924 // Send data
IanBenzMaxim 33:a4c015046956 925 m_OW_master.OWWriteBlock(data, data.length);
IanBenzMaxim 25:bdb1c5a53b58 926
IanBenzMaxim 25:bdb1c5a53b58 927 // Read CRC
IanBenzMaxim 25:bdb1c5a53b58 928 m_OW_master.OWReadBlock(&buf[cnt], 2);
IanBenzMaxim 25:bdb1c5a53b58 929 cnt += 2;
IanBenzMaxim 25:bdb1c5a53b58 930
IanBenzMaxim 25:bdb1c5a53b58 931 // check the first CRC16
IanBenzMaxim 25:bdb1c5a53b58 932 if (!continuing)
IanBenzMaxim 25:bdb1c5a53b58 933 {
IanBenzMaxim 25:bdb1c5a53b58 934 if (OneWireMaster::calculateCRC16(buf, 0, offset) != 0xB001)
IanBenzMaxim 25:bdb1c5a53b58 935 return CommunicationError;
IanBenzMaxim 25:bdb1c5a53b58 936 }
IanBenzMaxim 25:bdb1c5a53b58 937
IanBenzMaxim 25:bdb1c5a53b58 938 // check the second CRC16
IanBenzMaxim 25:bdb1c5a53b58 939 if (OneWireMaster::calculateCRC16(buf, offset, (cnt - offset)) != 0xB001)
IanBenzMaxim 25:bdb1c5a53b58 940 return CommunicationError;
IanBenzMaxim 25:bdb1c5a53b58 941
IanBenzMaxim 25:bdb1c5a53b58 942 // send release and strong pull-up
IanBenzMaxim 25:bdb1c5a53b58 943 m_OW_master.OWWriteBytePower(0xAA);
IanBenzMaxim 25:bdb1c5a53b58 944
IanBenzMaxim 34:11fffbe98ef9 945 // now wait for the programming.
IanBenzMaxim 34:11fffbe98ef9 946 wait_ms(eepromWriteDelayMs);
IanBenzMaxim 25:bdb1c5a53b58 947
IanBenzMaxim 25:bdb1c5a53b58 948 // disable strong pullup
IanBenzMaxim 32:bce180b544ed 949 m_OW_master.OWSetLevel(OneWireMaster::LEVEL_NORMAL);
IanBenzMaxim 25:bdb1c5a53b58 950
IanBenzMaxim 25:bdb1c5a53b58 951 // read the CS byte
IanBenzMaxim 25:bdb1c5a53b58 952 m_OW_master.OWReadByte(cs);
IanBenzMaxim 25:bdb1c5a53b58 953
IanBenzMaxim 25:bdb1c5a53b58 954 if (cs == 0xAA)
IanBenzMaxim 25:bdb1c5a53b58 955 return Success;
IanBenzMaxim 25:bdb1c5a53b58 956 // else
IanBenzMaxim 25:bdb1c5a53b58 957 return OperationFailure;
IanBenzMaxim 25:bdb1c5a53b58 958 }
IanBenzMaxim 25:bdb1c5a53b58 959
IanBenzMaxim 49:36954b62f503 960 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 961 {
IanBenzMaxim 33:a4c015046956 962 ISha256MacCoprocessor::SlaveSecretData slaveSecretData;
IanBenzMaxim 25:bdb1c5a53b58 963
IanBenzMaxim 33:a4c015046956 964 // insert ROM number
IanBenzMaxim 33:a4c015046956 965 std::memcpy(slaveSecretData, romId, RomId::byteLen);
IanBenzMaxim 25:bdb1c5a53b58 966
IanBenzMaxim 33:a4c015046956 967 slaveSecretData[11] = 0x00;
IanBenzMaxim 49:36954b62f503 968 slaveSecretData[10] = bindingPageNum;
IanBenzMaxim 33:a4c015046956 969 slaveSecretData[9] = manId[0];
IanBenzMaxim 33:a4c015046956 970 slaveSecretData[8] = manId[1];
IanBenzMaxim 25:bdb1c5a53b58 971
IanBenzMaxim 49:36954b62f503 972 return MacCoproc.computeSlaveSecret(bindingPage, partialSecret, slaveSecretData);
IanBenzMaxim 25:bdb1c5a53b58 973 }