Implementation of 1-Wire with added Alarm Search Functionality

Dependents:   Max32630_One_Wire_Interface

Committer:
IanBenzMaxim
Date:
Fri Mar 25 11:11:59 2016 -0500
Revision:
27:d5aaefa252f1
Parent:
25:bdb1c5a53b58
Child:
32:bce180b544ed
Do not reconfigure DS2465 if requested speed or level is already set. Use forward declarations to speed up compilation.

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 25:bdb1c5a53b58 30 // delay durations
IanBenzMaxim 25:bdb1c5a53b58 31 #ifdef LOW_VOLTAGE
IanBenzMaxim 25:bdb1c5a53b58 32 #define SHA_COMPUTATION_DELAY 4
IanBenzMaxim 25:bdb1c5a53b58 33 #define EEPROM_WRITE_DELAY 15
IanBenzMaxim 25:bdb1c5a53b58 34 #define SECRET_EEPROM_DELAY 200
IanBenzMaxim 25:bdb1c5a53b58 35 #else
IanBenzMaxim 25:bdb1c5a53b58 36 #define SHA_COMPUTATION_DELAY 3
IanBenzMaxim 25:bdb1c5a53b58 37 #define EEPROM_WRITE_DELAY 10
IanBenzMaxim 25:bdb1c5a53b58 38 #define SECRET_EEPROM_DELAY 90
IanBenzMaxim 25:bdb1c5a53b58 39 #endif
IanBenzMaxim 25:bdb1c5a53b58 40
IanBenzMaxim 25:bdb1c5a53b58 41 // 1-Wire commands
IanBenzMaxim 25:bdb1c5a53b58 42 #define CMD_WRITE_MEMORY 0x55
IanBenzMaxim 25:bdb1c5a53b58 43 #define CMD_READ_MEMORY 0xF0
IanBenzMaxim 25:bdb1c5a53b58 44 #define CMD_LOAD_LOCK_SECRET 0x33
IanBenzMaxim 25:bdb1c5a53b58 45 #define CMD_COMPUTE_LOCK_SECRET 0x3C
IanBenzMaxim 25:bdb1c5a53b58 46 #define CMD_SELECT_SECRET 0x0F
IanBenzMaxim 25:bdb1c5a53b58 47 #define CMD_COMPUTE_PAGEMAC 0xA5
IanBenzMaxim 25:bdb1c5a53b58 48 #define CMD_READ_STATUS 0xAA
IanBenzMaxim 25:bdb1c5a53b58 49 #define CMD_WRITE_BLOCK_PROTECT 0xC3
IanBenzMaxim 25:bdb1c5a53b58 50 #define CMD_WRITE_AUTH_MEMORY 0x5A
IanBenzMaxim 25:bdb1c5a53b58 51 #define CMD_WRITE_AUTH_PROTECT 0xCC
IanBenzMaxim 25:bdb1c5a53b58 52 #define CMD_PIO_READ 0xDD
IanBenzMaxim 25:bdb1c5a53b58 53 #define CMD_PIO_WRITE 0x96
IanBenzMaxim 25:bdb1c5a53b58 54
IanBenzMaxim 25:bdb1c5a53b58 55 #define BLOCK_READ_PROTECT 0x80
IanBenzMaxim 25:bdb1c5a53b58 56 #define BLOCK_WRITE_PROTECT 0x40
IanBenzMaxim 25:bdb1c5a53b58 57 #define BLOCK_EPROM_PROTECT 0x20
IanBenzMaxim 25:bdb1c5a53b58 58 #define BLOCK_WRITE_AUTH_PROTECT 0x10
IanBenzMaxim 25:bdb1c5a53b58 59
IanBenzMaxim 25:bdb1c5a53b58 60 #define PROT_BIT_AUTHWRITE 0x10
IanBenzMaxim 25:bdb1c5a53b58 61 #define PROT_BIT_EPROM 0x20
IanBenzMaxim 25:bdb1c5a53b58 62 #define PROT_BIT_WRITE 0x40
IanBenzMaxim 25:bdb1c5a53b58 63 #define PROT_BIT_READ 0x80
IanBenzMaxim 25:bdb1c5a53b58 64
IanBenzMaxim 25:bdb1c5a53b58 65 DS28E15_22_25::DS28E15_22_25(OneWireMaster& OW_master)
IanBenzMaxim 25:bdb1c5a53b58 66 : m_OW_master(OW_master)
IanBenzMaxim 25:bdb1c5a53b58 67 {
IanBenzMaxim 25:bdb1c5a53b58 68 std::memset(manId, 0x00, manIdLen);
IanBenzMaxim 25:bdb1c5a53b58 69 }
IanBenzMaxim 25:bdb1c5a53b58 70
IanBenzMaxim 25:bdb1c5a53b58 71 DS28E15_22_25::DevicePages DS28E15_22_25::devicePages()
IanBenzMaxim 25:bdb1c5a53b58 72 {
IanBenzMaxim 25:bdb1c5a53b58 73 DevicePages pages;
IanBenzMaxim 25:bdb1c5a53b58 74
IanBenzMaxim 25:bdb1c5a53b58 75 switch (romId.familyCode())
IanBenzMaxim 25:bdb1c5a53b58 76 {
IanBenzMaxim 25:bdb1c5a53b58 77 case DS28E25_FAMILY:
IanBenzMaxim 25:bdb1c5a53b58 78 pages = DS28E25_PAGES;
IanBenzMaxim 25:bdb1c5a53b58 79 break;
IanBenzMaxim 25:bdb1c5a53b58 80
IanBenzMaxim 25:bdb1c5a53b58 81 case DS28E22_FAMILY:
IanBenzMaxim 25:bdb1c5a53b58 82 pages = DS28E22_PAGES;
IanBenzMaxim 25:bdb1c5a53b58 83 break;
IanBenzMaxim 25:bdb1c5a53b58 84
IanBenzMaxim 25:bdb1c5a53b58 85 case DS28E15_FAMILY:
IanBenzMaxim 25:bdb1c5a53b58 86 pages = DS28E15_PAGES;
IanBenzMaxim 25:bdb1c5a53b58 87 break;
IanBenzMaxim 25:bdb1c5a53b58 88
IanBenzMaxim 25:bdb1c5a53b58 89 default:
IanBenzMaxim 25:bdb1c5a53b58 90 pages = UNKNOWN_PAGES;
IanBenzMaxim 25:bdb1c5a53b58 91 break;
IanBenzMaxim 25:bdb1c5a53b58 92 }
IanBenzMaxim 25:bdb1c5a53b58 93
IanBenzMaxim 25:bdb1c5a53b58 94 return pages;
IanBenzMaxim 25:bdb1c5a53b58 95 }
IanBenzMaxim 25:bdb1c5a53b58 96
IanBenzMaxim 25:bdb1c5a53b58 97 DS28E15_22_25::DeviceBlocks DS28E15_22_25::deviceBlocks()
IanBenzMaxim 25:bdb1c5a53b58 98 {
IanBenzMaxim 25:bdb1c5a53b58 99 DeviceBlocks blocks;
IanBenzMaxim 25:bdb1c5a53b58 100
IanBenzMaxim 25:bdb1c5a53b58 101 switch (romId.familyCode())
IanBenzMaxim 25:bdb1c5a53b58 102 {
IanBenzMaxim 25:bdb1c5a53b58 103 case DS28E25_FAMILY:
IanBenzMaxim 25:bdb1c5a53b58 104 blocks = DS28E25_BLOCKS;
IanBenzMaxim 25:bdb1c5a53b58 105 break;
IanBenzMaxim 25:bdb1c5a53b58 106
IanBenzMaxim 25:bdb1c5a53b58 107 case DS28E22_FAMILY:
IanBenzMaxim 25:bdb1c5a53b58 108 blocks = DS28E22_BLOCKS;
IanBenzMaxim 25:bdb1c5a53b58 109 break;
IanBenzMaxim 25:bdb1c5a53b58 110
IanBenzMaxim 25:bdb1c5a53b58 111 case DS28E15_FAMILY:
IanBenzMaxim 25:bdb1c5a53b58 112 blocks = DS28E15_BLOCKS;
IanBenzMaxim 25:bdb1c5a53b58 113 break;
IanBenzMaxim 25:bdb1c5a53b58 114
IanBenzMaxim 25:bdb1c5a53b58 115 default:
IanBenzMaxim 25:bdb1c5a53b58 116 blocks = UNKNOWN_BLOCKS;
IanBenzMaxim 25:bdb1c5a53b58 117 break;
IanBenzMaxim 25:bdb1c5a53b58 118 }
IanBenzMaxim 25:bdb1c5a53b58 119
IanBenzMaxim 25:bdb1c5a53b58 120 return blocks;
IanBenzMaxim 25:bdb1c5a53b58 121 }
IanBenzMaxim 25:bdb1c5a53b58 122
IanBenzMaxim 25:bdb1c5a53b58 123 //--------------------------------------------------------------------------
IanBenzMaxim 25:bdb1c5a53b58 124 // Write page protection byte.
IanBenzMaxim 25:bdb1c5a53b58 125 //
IanBenzMaxim 25:bdb1c5a53b58 126 // Parameters
IanBenzMaxim 25:bdb1c5a53b58 127 // block - block number (0 to 7) which covers two pages each
IanBenzMaxim 25:bdb1c5a53b58 128 // new_value - new protection byte
IanBenzMaxim 25:bdb1c5a53b58 129 // old_value - old protection byte
IanBenzMaxim 25:bdb1c5a53b58 130 // manid - manufacturer ID
IanBenzMaxim 25:bdb1c5a53b58 131 // contflag - Flag to indicate the write is continued from the last
IanBenzMaxim 25:bdb1c5a53b58 132 //
IanBenzMaxim 25:bdb1c5a53b58 133 // Returns: true - protection written
IanBenzMaxim 25:bdb1c5a53b58 134 // false - Failed to set protection
IanBenzMaxim 25:bdb1c5a53b58 135 //
IanBenzMaxim 25:bdb1c5a53b58 136 OneWireSlave::CmdResult DS28E15_22_25::WriteAuthBlockProtection(const ISha256MacCoprocessor & MacCoproc, std::uint8_t newProtection, std::uint8_t oldProtection, bool contflag)
IanBenzMaxim 25:bdb1c5a53b58 137 {
IanBenzMaxim 25:bdb1c5a53b58 138 std::uint8_t buf[256], cs;
IanBenzMaxim 25:bdb1c5a53b58 139 int cnt = 0;
IanBenzMaxim 25:bdb1c5a53b58 140
IanBenzMaxim 25:bdb1c5a53b58 141 buf[cnt++] = CMD_WRITE_AUTH_PROTECT;
IanBenzMaxim 25:bdb1c5a53b58 142 buf[cnt++] = newProtection;
IanBenzMaxim 25:bdb1c5a53b58 143
IanBenzMaxim 25:bdb1c5a53b58 144 // Send command
IanBenzMaxim 25:bdb1c5a53b58 145 m_OW_master.OWWriteBlock(&buf[0], 2);
IanBenzMaxim 25:bdb1c5a53b58 146
IanBenzMaxim 25:bdb1c5a53b58 147 // read first CRC byte
IanBenzMaxim 25:bdb1c5a53b58 148 m_OW_master.OWReadByte(buf[cnt++]);
IanBenzMaxim 25:bdb1c5a53b58 149
IanBenzMaxim 25:bdb1c5a53b58 150 // read the last CRC and enable
IanBenzMaxim 25:bdb1c5a53b58 151 m_OW_master.OWReadBytePower(buf[cnt++]);
IanBenzMaxim 25:bdb1c5a53b58 152
IanBenzMaxim 25:bdb1c5a53b58 153 // now wait for the MAC computation.
IanBenzMaxim 25:bdb1c5a53b58 154 wait_ms(SHA_COMPUTATION_DELAY);
IanBenzMaxim 25:bdb1c5a53b58 155
IanBenzMaxim 25:bdb1c5a53b58 156 // disable strong pullup
IanBenzMaxim 25:bdb1c5a53b58 157 m_OW_master.OWLevel(OneWireMaster::LEVEL_NORMAL);
IanBenzMaxim 25:bdb1c5a53b58 158
IanBenzMaxim 25:bdb1c5a53b58 159 // check CRC16
IanBenzMaxim 25:bdb1c5a53b58 160 if (OneWireMaster::calculateCRC16(buf, 0, cnt) != 0xB001)
IanBenzMaxim 25:bdb1c5a53b58 161 return CommunicationError;
IanBenzMaxim 25:bdb1c5a53b58 162
IanBenzMaxim 25:bdb1c5a53b58 163 ISha256MacCoprocessor::CmdResult result;
IanBenzMaxim 25:bdb1c5a53b58 164 result = CalculateProtectionWriteMAC256(MacCoproc, newProtection, oldProtection, romId, manId, reinterpret_cast<std::uint8_t (&)[macLen]>(buf));
IanBenzMaxim 25:bdb1c5a53b58 165 if (result != ISha256MacCoprocessor::Success)
IanBenzMaxim 25:bdb1c5a53b58 166 return OperationFailure;
IanBenzMaxim 25:bdb1c5a53b58 167 cnt = macLen;
IanBenzMaxim 25:bdb1c5a53b58 168
IanBenzMaxim 25:bdb1c5a53b58 169 // send the MAC
IanBenzMaxim 25:bdb1c5a53b58 170 m_OW_master.OWWriteBlock(&buf[0], macLen);
IanBenzMaxim 25:bdb1c5a53b58 171
IanBenzMaxim 25:bdb1c5a53b58 172 // Read CRC and CS byte
IanBenzMaxim 25:bdb1c5a53b58 173 m_OW_master.OWReadBlock(&buf[cnt], 3);
IanBenzMaxim 25:bdb1c5a53b58 174 cnt += 3;
IanBenzMaxim 25:bdb1c5a53b58 175
IanBenzMaxim 25:bdb1c5a53b58 176 // ckeck CRC16
IanBenzMaxim 25:bdb1c5a53b58 177 if (OneWireMaster::calculateCRC16(buf, 0, (cnt - 1)) != 0xB001)
IanBenzMaxim 25:bdb1c5a53b58 178 return CommunicationError;
IanBenzMaxim 25:bdb1c5a53b58 179
IanBenzMaxim 25:bdb1c5a53b58 180 // check CS
IanBenzMaxim 25:bdb1c5a53b58 181 if (buf[cnt-1] != 0xAA)
IanBenzMaxim 25:bdb1c5a53b58 182 return OperationFailure;
IanBenzMaxim 25:bdb1c5a53b58 183
IanBenzMaxim 25:bdb1c5a53b58 184 // send release and strong pull-up
IanBenzMaxim 25:bdb1c5a53b58 185 // DATASHEET_CORRECTION - last bit in release is a read-zero so don't check echo of write byte
IanBenzMaxim 25:bdb1c5a53b58 186 m_OW_master.OWWriteBytePower(0xAA);
IanBenzMaxim 25:bdb1c5a53b58 187
IanBenzMaxim 25:bdb1c5a53b58 188 // now wait for the MAC computation.
IanBenzMaxim 25:bdb1c5a53b58 189 wait_ms(EEPROM_WRITE_DELAY);
IanBenzMaxim 25:bdb1c5a53b58 190
IanBenzMaxim 25:bdb1c5a53b58 191 // disable strong pullup
IanBenzMaxim 25:bdb1c5a53b58 192 m_OW_master.OWLevel(OneWireMaster::LEVEL_NORMAL);
IanBenzMaxim 25:bdb1c5a53b58 193
IanBenzMaxim 25:bdb1c5a53b58 194 // read the CS byte
IanBenzMaxim 25:bdb1c5a53b58 195 m_OW_master.OWReadByte(cs);
IanBenzMaxim 25:bdb1c5a53b58 196
IanBenzMaxim 25:bdb1c5a53b58 197 if (cs == 0xAA)
IanBenzMaxim 25:bdb1c5a53b58 198 return Success;
IanBenzMaxim 25:bdb1c5a53b58 199 // else
IanBenzMaxim 25:bdb1c5a53b58 200 return OperationFailure;
IanBenzMaxim 25:bdb1c5a53b58 201 }
IanBenzMaxim 25:bdb1c5a53b58 202
IanBenzMaxim 25:bdb1c5a53b58 203 //--------------------------------------------------------------------------
IanBenzMaxim 25:bdb1c5a53b58 204 // Write page protection byte.
IanBenzMaxim 25:bdb1c5a53b58 205 //
IanBenzMaxim 25:bdb1c5a53b58 206 // Parameters
IanBenzMaxim 25:bdb1c5a53b58 207 // block - block number (0 to 7) which covers two pages each
IanBenzMaxim 25:bdb1c5a53b58 208 // prot - protection byte
IanBenzMaxim 25:bdb1c5a53b58 209 // contflag - Flag to indicate the write is continued from the last
IanBenzMaxim 25:bdb1c5a53b58 210 //
IanBenzMaxim 25:bdb1c5a53b58 211 // Returns: true - protection written
IanBenzMaxim 25:bdb1c5a53b58 212 // false - Failed to set protection
IanBenzMaxim 25:bdb1c5a53b58 213 //
IanBenzMaxim 25:bdb1c5a53b58 214 OneWireSlave::CmdResult DS28E15_22_25::WriteBlockProtection(std::uint8_t protection, bool continuing)
IanBenzMaxim 25:bdb1c5a53b58 215 {
IanBenzMaxim 25:bdb1c5a53b58 216 std::uint8_t buf[256], cs;
IanBenzMaxim 25:bdb1c5a53b58 217 int cnt = 0;
IanBenzMaxim 25:bdb1c5a53b58 218
IanBenzMaxim 25:bdb1c5a53b58 219 // check if not continuing a previous block write
IanBenzMaxim 25:bdb1c5a53b58 220 if (!continuing)
IanBenzMaxim 25:bdb1c5a53b58 221 {
IanBenzMaxim 25:bdb1c5a53b58 222 buf[cnt++] = CMD_WRITE_BLOCK_PROTECT;
IanBenzMaxim 25:bdb1c5a53b58 223 }
IanBenzMaxim 25:bdb1c5a53b58 224
IanBenzMaxim 25:bdb1c5a53b58 225 // compute parameter byte
IanBenzMaxim 25:bdb1c5a53b58 226 buf[cnt++] = protection;
IanBenzMaxim 25:bdb1c5a53b58 227
IanBenzMaxim 25:bdb1c5a53b58 228 m_OW_master.OWWriteBlock(&buf[0], cnt);
IanBenzMaxim 25:bdb1c5a53b58 229
IanBenzMaxim 25:bdb1c5a53b58 230 // Read CRC
IanBenzMaxim 25:bdb1c5a53b58 231 m_OW_master.OWReadBlock(&buf[cnt], 2);
IanBenzMaxim 25:bdb1c5a53b58 232 cnt += 2;
IanBenzMaxim 25:bdb1c5a53b58 233
IanBenzMaxim 25:bdb1c5a53b58 234 // check CRC16
IanBenzMaxim 25:bdb1c5a53b58 235 if (OneWireMaster::calculateCRC16(buf, 0, cnt) != 0xB001)
IanBenzMaxim 25:bdb1c5a53b58 236 return CommunicationError;
IanBenzMaxim 25:bdb1c5a53b58 237
IanBenzMaxim 25:bdb1c5a53b58 238 // DATASHEET_CORRECTION, on continue need second release byte
IanBenzMaxim 25:bdb1c5a53b58 239 if (continuing)
IanBenzMaxim 25:bdb1c5a53b58 240 m_OW_master.OWWriteByte(0xAA);
IanBenzMaxim 25:bdb1c5a53b58 241
IanBenzMaxim 25:bdb1c5a53b58 242 // sent release
IanBenzMaxim 25:bdb1c5a53b58 243 m_OW_master.OWWriteBytePower(0xAA);
IanBenzMaxim 25:bdb1c5a53b58 244
IanBenzMaxim 25:bdb1c5a53b58 245 // now wait for programming
IanBenzMaxim 25:bdb1c5a53b58 246 wait_ms(EEPROM_WRITE_DELAY);
IanBenzMaxim 25:bdb1c5a53b58 247
IanBenzMaxim 25:bdb1c5a53b58 248 // disable strong pullup
IanBenzMaxim 25:bdb1c5a53b58 249 m_OW_master.OWLevel(OneWireMaster::LEVEL_NORMAL);
IanBenzMaxim 25:bdb1c5a53b58 250
IanBenzMaxim 25:bdb1c5a53b58 251 // read the CS byte
IanBenzMaxim 25:bdb1c5a53b58 252 m_OW_master.OWReadByte(cs);
IanBenzMaxim 25:bdb1c5a53b58 253
IanBenzMaxim 25:bdb1c5a53b58 254 if (cs == 0xAA)
IanBenzMaxim 25:bdb1c5a53b58 255 return Success;
IanBenzMaxim 25:bdb1c5a53b58 256 // else
IanBenzMaxim 25:bdb1c5a53b58 257 return OperationFailure;
IanBenzMaxim 25:bdb1c5a53b58 258 }
IanBenzMaxim 25:bdb1c5a53b58 259
IanBenzMaxim 25:bdb1c5a53b58 260
IanBenzMaxim 25:bdb1c5a53b58 261
IanBenzMaxim 25:bdb1c5a53b58 262
IanBenzMaxim 25:bdb1c5a53b58 263 OneWireSlave::CmdResult DS28E15_22_25::ReadBlockProtectionStatus(unsigned int blockNum, std::uint8_t & status)
IanBenzMaxim 25:bdb1c5a53b58 264 {
IanBenzMaxim 25:bdb1c5a53b58 265 unsigned char buf;
IanBenzMaxim 25:bdb1c5a53b58 266 CmdResult result = ReadStatus(false, false, blockNum, &buf);
IanBenzMaxim 25:bdb1c5a53b58 267 if (result == Success)
IanBenzMaxim 25:bdb1c5a53b58 268 status = buf;
IanBenzMaxim 25:bdb1c5a53b58 269 return result;
IanBenzMaxim 25:bdb1c5a53b58 270 }
IanBenzMaxim 25:bdb1c5a53b58 271
IanBenzMaxim 25:bdb1c5a53b58 272 //--------------------------------------------------------------------------
IanBenzMaxim 25:bdb1c5a53b58 273 // Read status bytes, either personality or page protection.
IanBenzMaxim 25:bdb1c5a53b58 274 //
IanBenzMaxim 25:bdb1c5a53b58 275 // Parameters
IanBenzMaxim 25:bdb1c5a53b58 276 // personality - flag to indicate the read is the 4 personality bytes (true)
IanBenzMaxim 25:bdb1c5a53b58 277 // or page page protection (false)
IanBenzMaxim 25:bdb1c5a53b58 278 // allpages - flag to indicate if just one page (false) or all (true) page protection
IanBenzMaxim 25:bdb1c5a53b58 279 // bytes.
IanBenzMaxim 25:bdb1c5a53b58 280 // page_num - page number if reading protection 0 to 1
IanBenzMaxim 25:bdb1c5a53b58 281 // rdbuf - 16 byte buffer personality bytes (length 4) or page protection
IanBenzMaxim 25:bdb1c5a53b58 282 // (length 1 or 16)
IanBenzMaxim 25:bdb1c5a53b58 283 //
IanBenzMaxim 25:bdb1c5a53b58 284 // Returns: true - status read
IanBenzMaxim 25:bdb1c5a53b58 285 // false - Failed to read status
IanBenzMaxim 25:bdb1c5a53b58 286 //
IanBenzMaxim 25:bdb1c5a53b58 287 OneWireSlave::CmdResult DS28E15_22_25::ReadStatus(bool personality, bool allpages, unsigned int pageNum, unsigned char *rdbuf) const
IanBenzMaxim 25:bdb1c5a53b58 288 {
IanBenzMaxim 25:bdb1c5a53b58 289 unsigned char buf[256];
IanBenzMaxim 25:bdb1c5a53b58 290 int cnt, offset, rdnum;
IanBenzMaxim 25:bdb1c5a53b58 291
IanBenzMaxim 25:bdb1c5a53b58 292 cnt = 0;
IanBenzMaxim 25:bdb1c5a53b58 293 offset = 0;
IanBenzMaxim 25:bdb1c5a53b58 294
IanBenzMaxim 25:bdb1c5a53b58 295 buf[cnt++] = CMD_READ_STATUS;
IanBenzMaxim 25:bdb1c5a53b58 296 if (personality)
IanBenzMaxim 25:bdb1c5a53b58 297 buf[cnt++] = 0xE0;
IanBenzMaxim 25:bdb1c5a53b58 298 else if (!allpages)
IanBenzMaxim 25:bdb1c5a53b58 299 buf[cnt++] = pageNum;
IanBenzMaxim 25:bdb1c5a53b58 300 else
IanBenzMaxim 25:bdb1c5a53b58 301 buf[cnt++] = 0;
IanBenzMaxim 25:bdb1c5a53b58 302
IanBenzMaxim 25:bdb1c5a53b58 303 // send the command
IanBenzMaxim 25:bdb1c5a53b58 304 m_OW_master.OWWriteBlock(&buf[0], 2);
IanBenzMaxim 25:bdb1c5a53b58 305
IanBenzMaxim 25:bdb1c5a53b58 306 offset = cnt + 2;
IanBenzMaxim 25:bdb1c5a53b58 307
IanBenzMaxim 25:bdb1c5a53b58 308 // adjust data length
IanBenzMaxim 25:bdb1c5a53b58 309 if ((romId.familyCode() == DS28E25_FAMILY) || (romId.familyCode() == DS28E22_FAMILY))
IanBenzMaxim 25:bdb1c5a53b58 310 {
IanBenzMaxim 25:bdb1c5a53b58 311 if (personality)
IanBenzMaxim 25:bdb1c5a53b58 312 rdnum = 8;
IanBenzMaxim 25:bdb1c5a53b58 313 else if (allpages)
IanBenzMaxim 25:bdb1c5a53b58 314 rdnum = 20;
IanBenzMaxim 25:bdb1c5a53b58 315 else
IanBenzMaxim 25:bdb1c5a53b58 316 rdnum = 5;
IanBenzMaxim 25:bdb1c5a53b58 317 }
IanBenzMaxim 25:bdb1c5a53b58 318 else
IanBenzMaxim 25:bdb1c5a53b58 319 {
IanBenzMaxim 25:bdb1c5a53b58 320 if ((personality) || (allpages))
IanBenzMaxim 25:bdb1c5a53b58 321 rdnum = 8;
IanBenzMaxim 25:bdb1c5a53b58 322 else
IanBenzMaxim 25:bdb1c5a53b58 323 rdnum = 5;
IanBenzMaxim 25:bdb1c5a53b58 324 }
IanBenzMaxim 25:bdb1c5a53b58 325
IanBenzMaxim 25:bdb1c5a53b58 326 // Read the bytes
IanBenzMaxim 25:bdb1c5a53b58 327 m_OW_master.OWReadBlock(&buf[cnt],rdnum);
IanBenzMaxim 25:bdb1c5a53b58 328 cnt += rdnum;
IanBenzMaxim 25:bdb1c5a53b58 329
IanBenzMaxim 25:bdb1c5a53b58 330 // check the first CRC16
IanBenzMaxim 25:bdb1c5a53b58 331 if (OneWireMaster::calculateCRC16(buf, 0, offset) != 0xB001)
IanBenzMaxim 25:bdb1c5a53b58 332 return CommunicationError;
IanBenzMaxim 25:bdb1c5a53b58 333
IanBenzMaxim 25:bdb1c5a53b58 334 if ((((romId.familyCode() == DS28E25_FAMILY) || (romId.familyCode() == DS28E22_FAMILY))
IanBenzMaxim 25:bdb1c5a53b58 335 && (allpages || (pageNum == 15))) ||
IanBenzMaxim 25:bdb1c5a53b58 336 (personality || allpages || (pageNum == 1)))
IanBenzMaxim 25:bdb1c5a53b58 337 {
IanBenzMaxim 25:bdb1c5a53b58 338 // check the second CRC16
IanBenzMaxim 25:bdb1c5a53b58 339 if (OneWireMaster::calculateCRC16(buf, offset, (cnt - offset)) != 0xB001)
IanBenzMaxim 25:bdb1c5a53b58 340 return CommunicationError;
IanBenzMaxim 25:bdb1c5a53b58 341 }
IanBenzMaxim 25:bdb1c5a53b58 342
IanBenzMaxim 25:bdb1c5a53b58 343 // copy the data to the read buffer
IanBenzMaxim 25:bdb1c5a53b58 344 memcpy(rdbuf, &buf[offset], rdnum - 4);
IanBenzMaxim 25:bdb1c5a53b58 345
IanBenzMaxim 25:bdb1c5a53b58 346 return Success;
IanBenzMaxim 25:bdb1c5a53b58 347 }
IanBenzMaxim 25:bdb1c5a53b58 348
IanBenzMaxim 25:bdb1c5a53b58 349
IanBenzMaxim 25:bdb1c5a53b58 350
IanBenzMaxim 25:bdb1c5a53b58 351
IanBenzMaxim 25:bdb1c5a53b58 352 ISha256MacCoprocessor::CmdResult DS28E15_22_25::CalculateAuthMAC256(const ISha256MacCoprocessor & MacCoproc, unsigned int pageNum, const std::uint8_t (&challenge)[scratchpadSize], const std::uint8_t (&pageData)[pageSize], const RomId & romId, const std::uint8_t (&manId)[manIdLen], bool anon, std::uint8_t (&mac)[macLen])
IanBenzMaxim 25:bdb1c5a53b58 353 {
IanBenzMaxim 25:bdb1c5a53b58 354 std::uint8_t pageBuf[pageSize], challengeBuf[scratchpadSize], AuthMAC_data[ISha256MacCoprocessor::AuthMAC_data_len];
IanBenzMaxim 25:bdb1c5a53b58 355
IanBenzMaxim 25:bdb1c5a53b58 356 // insert page data
IanBenzMaxim 25:bdb1c5a53b58 357 std::memcpy(pageBuf, pageData, pageSize);
IanBenzMaxim 25:bdb1c5a53b58 358
IanBenzMaxim 25:bdb1c5a53b58 359 // insert challenge
IanBenzMaxim 25:bdb1c5a53b58 360 std::memcpy(challengeBuf, challenge, scratchpadSize);
IanBenzMaxim 25:bdb1c5a53b58 361
IanBenzMaxim 25:bdb1c5a53b58 362 // insert ROM number or FF
IanBenzMaxim 25:bdb1c5a53b58 363 if (anon)
IanBenzMaxim 25:bdb1c5a53b58 364 std::memset(AuthMAC_data, 0xFF, RomId::byteLen);
IanBenzMaxim 25:bdb1c5a53b58 365 else
IanBenzMaxim 25:bdb1c5a53b58 366 std::memcpy(AuthMAC_data, romId, RomId::byteLen);
IanBenzMaxim 25:bdb1c5a53b58 367
IanBenzMaxim 25:bdb1c5a53b58 368 AuthMAC_data[10] = pageNum;
IanBenzMaxim 25:bdb1c5a53b58 369
IanBenzMaxim 25:bdb1c5a53b58 370 AuthMAC_data[9] = manId[0];
IanBenzMaxim 25:bdb1c5a53b58 371 AuthMAC_data[8] = manId[1];
IanBenzMaxim 25:bdb1c5a53b58 372
IanBenzMaxim 25:bdb1c5a53b58 373 AuthMAC_data[11] = 0x00;
IanBenzMaxim 25:bdb1c5a53b58 374
IanBenzMaxim 25:bdb1c5a53b58 375 return MacCoproc.ComputeAndRead_AuthMAC(pageBuf, challengeBuf, AuthMAC_data, mac);
IanBenzMaxim 25:bdb1c5a53b58 376 }
IanBenzMaxim 25:bdb1c5a53b58 377
IanBenzMaxim 25:bdb1c5a53b58 378 //--------------------------------------------------------------------------
IanBenzMaxim 25:bdb1c5a53b58 379 // Verify provided MAC and page data. Optionally do
IanBenzMaxim 25:bdb1c5a53b58 380 // annonymous mode (anon != 0).
IanBenzMaxim 25:bdb1c5a53b58 381 //
IanBenzMaxim 25:bdb1c5a53b58 382 // Parameters
IanBenzMaxim 25:bdb1c5a53b58 383 // page_num - page number to read 0 - 16
IanBenzMaxim 25:bdb1c5a53b58 384 // challange - 32 byte buffer containing the challenge
IanBenzMaxim 25:bdb1c5a53b58 385 // page_data - 32 byte buffer to contain the data read
IanBenzMaxim 25:bdb1c5a53b58 386 // manid - 2 byte buffer containing the manufacturer ID (general device: 00h,00h)
IanBenzMaxim 25:bdb1c5a53b58 387 // mac - 32 byte buffer of mac read
IanBenzMaxim 25:bdb1c5a53b58 388 // anon - Flag to indicate Annonymous mode
IanBenzMaxim 25:bdb1c5a53b58 389 //
IanBenzMaxim 25:bdb1c5a53b58 390 // Returns: true - page read has correct MAC
IanBenzMaxim 25:bdb1c5a53b58 391 // false - Failed to read page or incorrect MAC
IanBenzMaxim 25:bdb1c5a53b58 392 //
IanBenzMaxim 25:bdb1c5a53b58 393 ISha256MacCoprocessor::CmdResult DS28E15_22_25::AuthVerify(const ISha256MacCoprocessor & MacCoproc, unsigned int page_num, const std::uint8_t (&challenge)[scratchpadSize], const std::uint8_t (&pageData)[pageSize], const RomId & romId, const std::uint8_t (&manId)[manIdLen], bool anon, const std::uint8_t (&mac)[macLen])
IanBenzMaxim 25:bdb1c5a53b58 394 {
IanBenzMaxim 25:bdb1c5a53b58 395 std::uint8_t calc_mac[macLen];
IanBenzMaxim 25:bdb1c5a53b58 396 ISha256MacCoprocessor::CmdResult result;
IanBenzMaxim 25:bdb1c5a53b58 397 result = CalculateAuthMAC256(MacCoproc, page_num, challenge, pageData, romId, manId, anon, calc_mac);
IanBenzMaxim 25:bdb1c5a53b58 398 if (result == ISha256MacCoprocessor::Success)
IanBenzMaxim 25:bdb1c5a53b58 399 {
IanBenzMaxim 25:bdb1c5a53b58 400 if (memcmp(mac, calc_mac, macLen) != 0)
IanBenzMaxim 25:bdb1c5a53b58 401 result = ISha256MacCoprocessor::OperationFailure;
IanBenzMaxim 25:bdb1c5a53b58 402 }
IanBenzMaxim 25:bdb1c5a53b58 403 return result;
IanBenzMaxim 25:bdb1c5a53b58 404 }
IanBenzMaxim 25:bdb1c5a53b58 405
IanBenzMaxim 25:bdb1c5a53b58 406 //--------------------------------------------------------------------------
IanBenzMaxim 25:bdb1c5a53b58 407 // Do Compute Page MAC command and return MAC. Optionally do
IanBenzMaxim 25:bdb1c5a53b58 408 // annonymous mode (anon != 0).
IanBenzMaxim 25:bdb1c5a53b58 409 //
IanBenzMaxim 25:bdb1c5a53b58 410 // Parameters
IanBenzMaxim 25:bdb1c5a53b58 411 // sn - secret number 0 or 1
IanBenzMaxim 25:bdb1c5a53b58 412 // page_num - page number to read 0 - 16
IanBenzMaxim 25:bdb1c5a53b58 413 // challange - 32 byte buffer containing the challenge
IanBenzMaxim 25:bdb1c5a53b58 414 // mac - 32 byte buffer for page data read
IanBenzMaxim 25:bdb1c5a53b58 415 // anon - Flag to indicate Annonymous mode
IanBenzMaxim 25:bdb1c5a53b58 416 //
IanBenzMaxim 25:bdb1c5a53b58 417 // Returns: true - page read has correct MAC
IanBenzMaxim 25:bdb1c5a53b58 418 // false - Failed to read page or incorrect MAC
IanBenzMaxim 25:bdb1c5a53b58 419 //
IanBenzMaxim 25:bdb1c5a53b58 420 OneWireSlave::CmdResult DS28E15_22_25::ComputeReadPageMAC(unsigned int page_num, bool anon, std::uint8_t (&mac)[macLen]) const
IanBenzMaxim 25:bdb1c5a53b58 421 {
IanBenzMaxim 25:bdb1c5a53b58 422 std::uint8_t buf[256],cs;
IanBenzMaxim 25:bdb1c5a53b58 423 int cnt = 0;
IanBenzMaxim 25:bdb1c5a53b58 424
IanBenzMaxim 25:bdb1c5a53b58 425 buf[cnt++] = CMD_COMPUTE_PAGEMAC;
IanBenzMaxim 25:bdb1c5a53b58 426 buf[cnt++] = ((anon) ? 0xE0 : 0x00) | page_num;
IanBenzMaxim 25:bdb1c5a53b58 427
IanBenzMaxim 25:bdb1c5a53b58 428 // Send command
IanBenzMaxim 25:bdb1c5a53b58 429 m_OW_master.OWWriteBlock(&buf[0], 2);
IanBenzMaxim 25:bdb1c5a53b58 430
IanBenzMaxim 25:bdb1c5a53b58 431 // read first CRC byte
IanBenzMaxim 25:bdb1c5a53b58 432 m_OW_master.OWReadByte(buf[cnt++]);
IanBenzMaxim 25:bdb1c5a53b58 433
IanBenzMaxim 25:bdb1c5a53b58 434 // read the last CRC and enable
IanBenzMaxim 25:bdb1c5a53b58 435 m_OW_master.OWReadBytePower(buf[cnt++]);
IanBenzMaxim 25:bdb1c5a53b58 436
IanBenzMaxim 25:bdb1c5a53b58 437 // now wait for the MAC computation.
IanBenzMaxim 25:bdb1c5a53b58 438 wait_ms(SHA_COMPUTATION_DELAY * 2);
IanBenzMaxim 25:bdb1c5a53b58 439
IanBenzMaxim 25:bdb1c5a53b58 440 // disable strong pullup
IanBenzMaxim 25:bdb1c5a53b58 441 m_OW_master.OWLevel(OneWireMaster::LEVEL_NORMAL);
IanBenzMaxim 25:bdb1c5a53b58 442
IanBenzMaxim 25:bdb1c5a53b58 443 // check CRC16
IanBenzMaxim 25:bdb1c5a53b58 444 if (OneWireMaster::calculateCRC16(buf, 0, cnt) != 0xB001)
IanBenzMaxim 25:bdb1c5a53b58 445 return CommunicationError;
IanBenzMaxim 25:bdb1c5a53b58 446
IanBenzMaxim 25:bdb1c5a53b58 447 // read the CS byte
IanBenzMaxim 25:bdb1c5a53b58 448 m_OW_master.OWReadByte(cs);
IanBenzMaxim 25:bdb1c5a53b58 449 if (cs != 0xAA)
IanBenzMaxim 25:bdb1c5a53b58 450 return OperationFailure;
IanBenzMaxim 25:bdb1c5a53b58 451
IanBenzMaxim 25:bdb1c5a53b58 452 // read the MAC and CRC
IanBenzMaxim 25:bdb1c5a53b58 453 m_OW_master.OWReadBlock(&buf[0], (macLen + 2));
IanBenzMaxim 25:bdb1c5a53b58 454
IanBenzMaxim 25:bdb1c5a53b58 455 // check CRC16
IanBenzMaxim 25:bdb1c5a53b58 456 if (OneWireMaster::calculateCRC16(buf, 0, (macLen + 2)) != 0xB001)
IanBenzMaxim 25:bdb1c5a53b58 457 return CommunicationError;
IanBenzMaxim 25:bdb1c5a53b58 458
IanBenzMaxim 25:bdb1c5a53b58 459 // copy MAC to return buffer
IanBenzMaxim 25:bdb1c5a53b58 460 memcpy(mac, buf, macLen);
IanBenzMaxim 25:bdb1c5a53b58 461
IanBenzMaxim 25:bdb1c5a53b58 462 return Success;
IanBenzMaxim 25:bdb1c5a53b58 463 }
IanBenzMaxim 25:bdb1c5a53b58 464
IanBenzMaxim 25:bdb1c5a53b58 465 //----------------------------------------------------------------------
IanBenzMaxim 25:bdb1c5a53b58 466 // Compute secret operation on the DS28E25/DS28E22/DS28E15.
IanBenzMaxim 25:bdb1c5a53b58 467 //
IanBenzMaxim 25:bdb1c5a53b58 468 // 'sn' - secret number 0 or 1
IanBenzMaxim 25:bdb1c5a53b58 469 // 'partial' - partial secret to load (32 bytes)
IanBenzMaxim 25:bdb1c5a53b58 470 // 'pagedata' - page data to compute (32 bytes)
IanBenzMaxim 25:bdb1c5a53b58 471 // 'lock' - option to lock the secret after the load (lock = true)
IanBenzMaxim 25:bdb1c5a53b58 472 //
IanBenzMaxim 25:bdb1c5a53b58 473 // Return: true - load complete
IanBenzMaxim 25:bdb1c5a53b58 474 // false - error during load, device not present
IanBenzMaxim 25:bdb1c5a53b58 475 //
IanBenzMaxim 25:bdb1c5a53b58 476 OneWireSlave::CmdResult DS28E15_22_25::ComputeSecret(unsigned int page_num, bool lock)
IanBenzMaxim 25:bdb1c5a53b58 477 {
IanBenzMaxim 25:bdb1c5a53b58 478 std::uint8_t buf[256], cs;
IanBenzMaxim 25:bdb1c5a53b58 479 int cnt = 0;
IanBenzMaxim 25:bdb1c5a53b58 480
IanBenzMaxim 25:bdb1c5a53b58 481 buf[cnt++] = CMD_COMPUTE_LOCK_SECRET;
IanBenzMaxim 25:bdb1c5a53b58 482 buf[cnt++] = (lock) ? (0xE0 | page_num) : page_num; // lock flag
IanBenzMaxim 25:bdb1c5a53b58 483
IanBenzMaxim 25:bdb1c5a53b58 484 // Send command
IanBenzMaxim 25:bdb1c5a53b58 485 m_OW_master.OWWriteBlock(&buf[0], 2);
IanBenzMaxim 25:bdb1c5a53b58 486
IanBenzMaxim 25:bdb1c5a53b58 487 // Read CRC
IanBenzMaxim 25:bdb1c5a53b58 488 m_OW_master.OWReadBlock(&buf[cnt], 2);
IanBenzMaxim 25:bdb1c5a53b58 489 cnt += 2;
IanBenzMaxim 25:bdb1c5a53b58 490
IanBenzMaxim 25:bdb1c5a53b58 491 // check CRC16
IanBenzMaxim 25:bdb1c5a53b58 492 if (OneWireMaster::calculateCRC16(buf, 0, cnt) != 0xB001)
IanBenzMaxim 25:bdb1c5a53b58 493 return CommunicationError;
IanBenzMaxim 25:bdb1c5a53b58 494
IanBenzMaxim 25:bdb1c5a53b58 495 // send release and strong pull-up
IanBenzMaxim 25:bdb1c5a53b58 496 m_OW_master.OWWriteBytePower(0xAA);
IanBenzMaxim 25:bdb1c5a53b58 497
IanBenzMaxim 25:bdb1c5a53b58 498 // now wait for the MAC computation.
IanBenzMaxim 25:bdb1c5a53b58 499 wait_ms(SHA_COMPUTATION_DELAY * 2 + SECRET_EEPROM_DELAY);
IanBenzMaxim 25:bdb1c5a53b58 500
IanBenzMaxim 25:bdb1c5a53b58 501 // disable strong pullup
IanBenzMaxim 25:bdb1c5a53b58 502 m_OW_master.OWLevel(OneWireMaster::LEVEL_NORMAL);
IanBenzMaxim 25:bdb1c5a53b58 503
IanBenzMaxim 25:bdb1c5a53b58 504 // read the CS byte
IanBenzMaxim 25:bdb1c5a53b58 505 m_OW_master.OWReadByte(cs);
IanBenzMaxim 25:bdb1c5a53b58 506
IanBenzMaxim 25:bdb1c5a53b58 507 if (cs == 0xAA)
IanBenzMaxim 25:bdb1c5a53b58 508 return Success;
IanBenzMaxim 25:bdb1c5a53b58 509 // else
IanBenzMaxim 25:bdb1c5a53b58 510 return OperationFailure;
IanBenzMaxim 25:bdb1c5a53b58 511 }
IanBenzMaxim 25:bdb1c5a53b58 512
IanBenzMaxim 25:bdb1c5a53b58 513 //----------------------------------------------------------------------
IanBenzMaxim 25:bdb1c5a53b58 514 // Write the scratchpad (challenge or secret)
IanBenzMaxim 25:bdb1c5a53b58 515 //
IanBenzMaxim 25:bdb1c5a53b58 516 // 'sn' - secret number 0 or 1
IanBenzMaxim 25:bdb1c5a53b58 517 // 'data' - data to write to the scratchpad (32 bytes)
IanBenzMaxim 25:bdb1c5a53b58 518 //
IanBenzMaxim 25:bdb1c5a53b58 519 // Return: true - select complete
IanBenzMaxim 25:bdb1c5a53b58 520 // false - error during select, device not present
IanBenzMaxim 25:bdb1c5a53b58 521 //
IanBenzMaxim 25:bdb1c5a53b58 522 OneWireSlave::CmdResult DS28E15_22_25::WriteScratchpad(const uint8_t (&data)[scratchpadSize]) const
IanBenzMaxim 25:bdb1c5a53b58 523 {
IanBenzMaxim 25:bdb1c5a53b58 524 std::uint8_t buf[256];
IanBenzMaxim 25:bdb1c5a53b58 525 int cnt = 0, offset;
IanBenzMaxim 25:bdb1c5a53b58 526
IanBenzMaxim 25:bdb1c5a53b58 527 buf[cnt++] = CMD_SELECT_SECRET;
IanBenzMaxim 25:bdb1c5a53b58 528 if ((romId.familyCode() == DS28E25_FAMILY) || (romId.familyCode() == DS28E22_FAMILY))
IanBenzMaxim 25:bdb1c5a53b58 529 buf[cnt++] = 0x20;
IanBenzMaxim 25:bdb1c5a53b58 530 else
IanBenzMaxim 25:bdb1c5a53b58 531 buf[cnt++] = 0x00;
IanBenzMaxim 25:bdb1c5a53b58 532
IanBenzMaxim 25:bdb1c5a53b58 533 // Send command
IanBenzMaxim 25:bdb1c5a53b58 534 m_OW_master.OWWriteBlock(&buf[0], 2);
IanBenzMaxim 25:bdb1c5a53b58 535
IanBenzMaxim 25:bdb1c5a53b58 536 // Read CRC
IanBenzMaxim 25:bdb1c5a53b58 537 m_OW_master.OWReadBlock(&buf[cnt], 2);
IanBenzMaxim 25:bdb1c5a53b58 538 cnt += 2;
IanBenzMaxim 25:bdb1c5a53b58 539
IanBenzMaxim 25:bdb1c5a53b58 540 offset = cnt;
IanBenzMaxim 25:bdb1c5a53b58 541
IanBenzMaxim 25:bdb1c5a53b58 542 // add the data
IanBenzMaxim 25:bdb1c5a53b58 543 memcpy(&buf[cnt], data, scratchpadSize);
IanBenzMaxim 25:bdb1c5a53b58 544 cnt += scratchpadSize;
IanBenzMaxim 25:bdb1c5a53b58 545
IanBenzMaxim 25:bdb1c5a53b58 546 // Send the data
IanBenzMaxim 25:bdb1c5a53b58 547 m_OW_master.OWWriteBlock(data, scratchpadSize);
IanBenzMaxim 25:bdb1c5a53b58 548
IanBenzMaxim 25:bdb1c5a53b58 549 // Read CRC
IanBenzMaxim 25:bdb1c5a53b58 550 m_OW_master.OWReadBlock(&buf[cnt], 2);
IanBenzMaxim 25:bdb1c5a53b58 551 cnt += 2;
IanBenzMaxim 25:bdb1c5a53b58 552
IanBenzMaxim 25:bdb1c5a53b58 553 // check first CRC16
IanBenzMaxim 25:bdb1c5a53b58 554 if (OneWireMaster::calculateCRC16(buf, 0, offset) != 0xB001)
IanBenzMaxim 25:bdb1c5a53b58 555 return CommunicationError;
IanBenzMaxim 25:bdb1c5a53b58 556
IanBenzMaxim 25:bdb1c5a53b58 557 // check the second CRC16
IanBenzMaxim 25:bdb1c5a53b58 558 if (OneWireMaster::calculateCRC16(buf, offset, (cnt - offset)) != 0xB001)
IanBenzMaxim 25:bdb1c5a53b58 559 return CommunicationError;
IanBenzMaxim 25:bdb1c5a53b58 560
IanBenzMaxim 25:bdb1c5a53b58 561 return Success;
IanBenzMaxim 25:bdb1c5a53b58 562 }
IanBenzMaxim 25:bdb1c5a53b58 563
IanBenzMaxim 25:bdb1c5a53b58 564 //----------------------------------------------------------------------
IanBenzMaxim 25:bdb1c5a53b58 565 // Load first secret operation on the DS28E25/DS28E22/DS28E15.
IanBenzMaxim 25:bdb1c5a53b58 566 //
IanBenzMaxim 25:bdb1c5a53b58 567 // 'sn' - secret number 0 or 1
IanBenzMaxim 25:bdb1c5a53b58 568 // 'secret' - secret to load (32 bytes)
IanBenzMaxim 25:bdb1c5a53b58 569 // 'lock' - option to lock the secret after the load (lock = true)
IanBenzMaxim 25:bdb1c5a53b58 570 //
IanBenzMaxim 25:bdb1c5a53b58 571 // Return: true - load complete
IanBenzMaxim 25:bdb1c5a53b58 572 // false - error during load, device not present
IanBenzMaxim 25:bdb1c5a53b58 573 //
IanBenzMaxim 25:bdb1c5a53b58 574 OneWireSlave::CmdResult DS28E15_22_25::LoadSecret(bool lock)
IanBenzMaxim 25:bdb1c5a53b58 575 {
IanBenzMaxim 25:bdb1c5a53b58 576 std::uint8_t buf[256], cs;
IanBenzMaxim 25:bdb1c5a53b58 577 int cnt = 0;
IanBenzMaxim 25:bdb1c5a53b58 578
IanBenzMaxim 25:bdb1c5a53b58 579 buf[cnt++] = CMD_LOAD_LOCK_SECRET;
IanBenzMaxim 25:bdb1c5a53b58 580 buf[cnt++] = (lock) ? 0xE0 : 0x00; // lock flag
IanBenzMaxim 25:bdb1c5a53b58 581
IanBenzMaxim 25:bdb1c5a53b58 582 // Send command
IanBenzMaxim 25:bdb1c5a53b58 583 m_OW_master.OWWriteBlock(&buf[0], 2);
IanBenzMaxim 25:bdb1c5a53b58 584
IanBenzMaxim 25:bdb1c5a53b58 585 // Read CRC
IanBenzMaxim 25:bdb1c5a53b58 586 m_OW_master.OWReadBlock(&buf[cnt], 2);
IanBenzMaxim 25:bdb1c5a53b58 587 cnt += 2;
IanBenzMaxim 25:bdb1c5a53b58 588
IanBenzMaxim 25:bdb1c5a53b58 589 // check CRC16
IanBenzMaxim 25:bdb1c5a53b58 590 if (OneWireMaster::calculateCRC16(buf, 0, cnt) != 0xB001)
IanBenzMaxim 25:bdb1c5a53b58 591 return CommunicationError;
IanBenzMaxim 25:bdb1c5a53b58 592
IanBenzMaxim 25:bdb1c5a53b58 593 // send release and strong pull-up
IanBenzMaxim 25:bdb1c5a53b58 594 m_OW_master.OWWriteBytePower(0xAA);
IanBenzMaxim 25:bdb1c5a53b58 595
IanBenzMaxim 25:bdb1c5a53b58 596 // now wait for the MAC computation.
IanBenzMaxim 25:bdb1c5a53b58 597 wait_ms(SECRET_EEPROM_DELAY);
IanBenzMaxim 25:bdb1c5a53b58 598
IanBenzMaxim 25:bdb1c5a53b58 599 // disable strong pullup
IanBenzMaxim 25:bdb1c5a53b58 600 m_OW_master.OWLevel(OneWireMaster::LEVEL_NORMAL);
IanBenzMaxim 25:bdb1c5a53b58 601
IanBenzMaxim 25:bdb1c5a53b58 602 // read the CS byte
IanBenzMaxim 25:bdb1c5a53b58 603 m_OW_master.OWReadByte(cs);
IanBenzMaxim 25:bdb1c5a53b58 604
IanBenzMaxim 25:bdb1c5a53b58 605 if (cs == 0xAA)
IanBenzMaxim 25:bdb1c5a53b58 606 return Success;
IanBenzMaxim 25:bdb1c5a53b58 607 // else
IanBenzMaxim 25:bdb1c5a53b58 608 return OperationFailure;
IanBenzMaxim 25:bdb1c5a53b58 609 }
IanBenzMaxim 25:bdb1c5a53b58 610
IanBenzMaxim 25:bdb1c5a53b58 611 //--------------------------------------------------------------------------
IanBenzMaxim 25:bdb1c5a53b58 612 // Read page and verify CRC. Multiple pages can
IanBenzMaxim 25:bdb1c5a53b58 613 // be read without re-selecting the device using the continue flag.
IanBenzMaxim 25:bdb1c5a53b58 614 //
IanBenzMaxim 25:bdb1c5a53b58 615 // Parameters
IanBenzMaxim 25:bdb1c5a53b58 616 // page - page number where the block to write is located (0 to 15)
IanBenzMaxim 25:bdb1c5a53b58 617 // rdbuf - 32 byte buffer to contain the data to read
IanBenzMaxim 25:bdb1c5a53b58 618 // contflag - Flag to indicate the write is continued from the last
IanBenzMaxim 25:bdb1c5a53b58 619 //
IanBenzMaxim 25:bdb1c5a53b58 620 // Returns: true - block read and verified CRC
IanBenzMaxim 25:bdb1c5a53b58 621 // false - Failed to write block (no presence or invalid CRC16)
IanBenzMaxim 25:bdb1c5a53b58 622 //
IanBenzMaxim 25:bdb1c5a53b58 623 OneWireSlave::CmdResult DS28E15_22_25::readPage(unsigned int page, std::uint8_t (&rdbuf)[pageSize], bool continuing) const
IanBenzMaxim 25:bdb1c5a53b58 624 {
IanBenzMaxim 25:bdb1c5a53b58 625 std::uint8_t buf[256];
IanBenzMaxim 25:bdb1c5a53b58 626 int cnt, offset;
IanBenzMaxim 25:bdb1c5a53b58 627
IanBenzMaxim 25:bdb1c5a53b58 628 cnt = 0;
IanBenzMaxim 25:bdb1c5a53b58 629 offset = 0;
IanBenzMaxim 25:bdb1c5a53b58 630
IanBenzMaxim 25:bdb1c5a53b58 631 // check if not continuing a previous block write
IanBenzMaxim 25:bdb1c5a53b58 632 if (!continuing)
IanBenzMaxim 25:bdb1c5a53b58 633 {
IanBenzMaxim 25:bdb1c5a53b58 634 buf[cnt++] = CMD_READ_MEMORY;
IanBenzMaxim 25:bdb1c5a53b58 635 buf[cnt++] = page; // address
IanBenzMaxim 25:bdb1c5a53b58 636
IanBenzMaxim 25:bdb1c5a53b58 637 // Send command
IanBenzMaxim 25:bdb1c5a53b58 638 m_OW_master.OWWriteBlock(&buf[0], 2);
IanBenzMaxim 25:bdb1c5a53b58 639
IanBenzMaxim 25:bdb1c5a53b58 640 // Read CRC
IanBenzMaxim 25:bdb1c5a53b58 641 m_OW_master.OWReadBlock(&buf[cnt], 2);
IanBenzMaxim 25:bdb1c5a53b58 642 cnt += 2;
IanBenzMaxim 25:bdb1c5a53b58 643
IanBenzMaxim 25:bdb1c5a53b58 644 offset = cnt;
IanBenzMaxim 25:bdb1c5a53b58 645 }
IanBenzMaxim 25:bdb1c5a53b58 646
IanBenzMaxim 25:bdb1c5a53b58 647 // read data and CRC16
IanBenzMaxim 25:bdb1c5a53b58 648 m_OW_master.OWReadBlock(&buf[cnt], (pageSize + 2));
IanBenzMaxim 25:bdb1c5a53b58 649 cnt+=34;
IanBenzMaxim 25:bdb1c5a53b58 650
IanBenzMaxim 25:bdb1c5a53b58 651 // check the first CRC16
IanBenzMaxim 25:bdb1c5a53b58 652 if (!continuing)
IanBenzMaxim 25:bdb1c5a53b58 653 {
IanBenzMaxim 25:bdb1c5a53b58 654 if (OneWireMaster::calculateCRC16(buf, 0, offset) != 0xB001)
IanBenzMaxim 25:bdb1c5a53b58 655 return CommunicationError;
IanBenzMaxim 25:bdb1c5a53b58 656 }
IanBenzMaxim 25:bdb1c5a53b58 657
IanBenzMaxim 25:bdb1c5a53b58 658 // check the second CRC16
IanBenzMaxim 25:bdb1c5a53b58 659 if (OneWireMaster::calculateCRC16(buf, offset, (cnt - offset)) != 0xB001)
IanBenzMaxim 25:bdb1c5a53b58 660 return CommunicationError;
IanBenzMaxim 25:bdb1c5a53b58 661
IanBenzMaxim 25:bdb1c5a53b58 662 // copy the data to the read buffer
IanBenzMaxim 25:bdb1c5a53b58 663 memcpy(rdbuf, &buf[offset], pageSize);
IanBenzMaxim 25:bdb1c5a53b58 664
IanBenzMaxim 25:bdb1c5a53b58 665 return Success;
IanBenzMaxim 25:bdb1c5a53b58 666 }
IanBenzMaxim 25:bdb1c5a53b58 667
IanBenzMaxim 25:bdb1c5a53b58 668 //--------------------------------------------------------------------------
IanBenzMaxim 25:bdb1c5a53b58 669 // Write a 4 byte memory block using an authenticated write (with MAC).
IanBenzMaxim 25:bdb1c5a53b58 670 // The MAC must be pre-calculated.
IanBenzMaxim 25:bdb1c5a53b58 671 //
IanBenzMaxim 25:bdb1c5a53b58 672 // Parameters
IanBenzMaxim 25:bdb1c5a53b58 673 // page - page number where the block to write is located (0 to 15)
IanBenzMaxim 25:bdb1c5a53b58 674 // block - block number in page (0 to 7)
IanBenzMaxim 25:bdb1c5a53b58 675 // new_data - 4 byte buffer containing the data to write
IanBenzMaxim 25:bdb1c5a53b58 676 // mac - mac to use for the write
IanBenzMaxim 25:bdb1c5a53b58 677 // contflag - Flag to indicate the write is continued from the last
IanBenzMaxim 25:bdb1c5a53b58 678 //
IanBenzMaxim 25:bdb1c5a53b58 679 // Returns: true - block written
IanBenzMaxim 25:bdb1c5a53b58 680 // false - Failed to write block (no presence or invalid CRC16)
IanBenzMaxim 25:bdb1c5a53b58 681 //
IanBenzMaxim 25:bdb1c5a53b58 682 OneWireSlave::CmdResult DS28E15_22_25::writeAuthSegmentMAC(unsigned int pageNum, unsigned int segmentNum, const std::uint8_t (&newData)[segmentSize], const std::uint8_t (&mac)[macLen], bool continuing)
IanBenzMaxim 25:bdb1c5a53b58 683 {
IanBenzMaxim 25:bdb1c5a53b58 684 std::uint8_t buf[256], cs;
IanBenzMaxim 25:bdb1c5a53b58 685 int cnt, i, offset;
IanBenzMaxim 25:bdb1c5a53b58 686
IanBenzMaxim 25:bdb1c5a53b58 687 cnt = 0;
IanBenzMaxim 25:bdb1c5a53b58 688 offset = 0;
IanBenzMaxim 25:bdb1c5a53b58 689
IanBenzMaxim 25:bdb1c5a53b58 690 // check if not continuing a previous block write
IanBenzMaxim 25:bdb1c5a53b58 691 if (!continuing)
IanBenzMaxim 25:bdb1c5a53b58 692 {
IanBenzMaxim 25:bdb1c5a53b58 693 buf[cnt++] = CMD_WRITE_AUTH_MEMORY;
IanBenzMaxim 25:bdb1c5a53b58 694 buf[cnt++] = (segmentNum << 5) | pageNum; // address
IanBenzMaxim 25:bdb1c5a53b58 695
IanBenzMaxim 25:bdb1c5a53b58 696 // Send command
IanBenzMaxim 25:bdb1c5a53b58 697 m_OW_master.OWWriteBlock(&buf[0], 2);
IanBenzMaxim 25:bdb1c5a53b58 698
IanBenzMaxim 25:bdb1c5a53b58 699 // Read CRC
IanBenzMaxim 25:bdb1c5a53b58 700 m_OW_master.OWReadBlock(&buf[cnt], 2);
IanBenzMaxim 25:bdb1c5a53b58 701 cnt += 2;
IanBenzMaxim 25:bdb1c5a53b58 702
IanBenzMaxim 25:bdb1c5a53b58 703 offset = cnt;
IanBenzMaxim 25:bdb1c5a53b58 704 }
IanBenzMaxim 25:bdb1c5a53b58 705
IanBenzMaxim 25:bdb1c5a53b58 706 // add the data
IanBenzMaxim 25:bdb1c5a53b58 707 for (i = 0; i < 4; i++)
IanBenzMaxim 25:bdb1c5a53b58 708 buf[cnt++] = newData[i];
IanBenzMaxim 25:bdb1c5a53b58 709
IanBenzMaxim 25:bdb1c5a53b58 710 // Send data
IanBenzMaxim 25:bdb1c5a53b58 711 m_OW_master.OWWriteBlock(newData, segmentSize);
IanBenzMaxim 25:bdb1c5a53b58 712
IanBenzMaxim 25:bdb1c5a53b58 713 // read first CRC byte
IanBenzMaxim 25:bdb1c5a53b58 714 m_OW_master.OWReadByte(buf[cnt++]);
IanBenzMaxim 25:bdb1c5a53b58 715
IanBenzMaxim 25:bdb1c5a53b58 716 // read the last CRC and enable power
IanBenzMaxim 25:bdb1c5a53b58 717 m_OW_master.OWReadBytePower(buf[cnt++]);
IanBenzMaxim 25:bdb1c5a53b58 718
IanBenzMaxim 25:bdb1c5a53b58 719 // now wait for the MAC computation.
IanBenzMaxim 25:bdb1c5a53b58 720 wait_ms(SHA_COMPUTATION_DELAY);
IanBenzMaxim 25:bdb1c5a53b58 721
IanBenzMaxim 25:bdb1c5a53b58 722 // disable strong pullup
IanBenzMaxim 25:bdb1c5a53b58 723 m_OW_master.OWLevel(OneWireMaster::LEVEL_NORMAL);
IanBenzMaxim 25:bdb1c5a53b58 724
IanBenzMaxim 25:bdb1c5a53b58 725 // check the first CRC16
IanBenzMaxim 25:bdb1c5a53b58 726 if (!continuing)
IanBenzMaxim 25:bdb1c5a53b58 727 {
IanBenzMaxim 25:bdb1c5a53b58 728 if (OneWireMaster::calculateCRC16(buf, 0, offset) != 0xB001)
IanBenzMaxim 25:bdb1c5a53b58 729 return CommunicationError;
IanBenzMaxim 25:bdb1c5a53b58 730 }
IanBenzMaxim 25:bdb1c5a53b58 731
IanBenzMaxim 25:bdb1c5a53b58 732 // check the second CRC16
IanBenzMaxim 25:bdb1c5a53b58 733 unsigned short CRC16 = 0;
IanBenzMaxim 25:bdb1c5a53b58 734
IanBenzMaxim 25:bdb1c5a53b58 735 // DS28E25/DS28E22, crc gets calculagted with CS byte
IanBenzMaxim 25:bdb1c5a53b58 736 if ((romId.familyCode() == DS28E25_FAMILY) || (romId.familyCode() == DS28E22_FAMILY))
IanBenzMaxim 25:bdb1c5a53b58 737 {
IanBenzMaxim 25:bdb1c5a53b58 738 if (continuing)
IanBenzMaxim 25:bdb1c5a53b58 739 CRC16 = OneWireMaster::calculateCRC16(CRC16, 0xAA);
IanBenzMaxim 25:bdb1c5a53b58 740 }
IanBenzMaxim 25:bdb1c5a53b58 741
IanBenzMaxim 25:bdb1c5a53b58 742 CRC16 = OneWireMaster::calculateCRC16(buf, offset, (cnt - offset), CRC16);
IanBenzMaxim 25:bdb1c5a53b58 743
IanBenzMaxim 25:bdb1c5a53b58 744 if (CRC16 != 0xB001)
IanBenzMaxim 25:bdb1c5a53b58 745 return CommunicationError;
IanBenzMaxim 25:bdb1c5a53b58 746
IanBenzMaxim 25:bdb1c5a53b58 747 // transmit MAC as a block
IanBenzMaxim 25:bdb1c5a53b58 748 m_OW_master.OWWriteBlock(mac, macLen);
IanBenzMaxim 25:bdb1c5a53b58 749
IanBenzMaxim 25:bdb1c5a53b58 750 // calculate CRC on MAC
IanBenzMaxim 25:bdb1c5a53b58 751 CRC16 = OneWireMaster::calculateCRC16(mac, 0, macLen);
IanBenzMaxim 25:bdb1c5a53b58 752
IanBenzMaxim 25:bdb1c5a53b58 753 // append read of CRC16 and CS byte
IanBenzMaxim 25:bdb1c5a53b58 754 m_OW_master.OWReadBlock(&buf[0], 3);
IanBenzMaxim 25:bdb1c5a53b58 755 cnt = 3;
IanBenzMaxim 25:bdb1c5a53b58 756
IanBenzMaxim 25:bdb1c5a53b58 757 // ckeck CRC16
IanBenzMaxim 25:bdb1c5a53b58 758 CRC16 = OneWireMaster::calculateCRC16(buf, 0, (cnt - 1), CRC16);
IanBenzMaxim 25:bdb1c5a53b58 759
IanBenzMaxim 25:bdb1c5a53b58 760 if (CRC16 != 0xB001)
IanBenzMaxim 25:bdb1c5a53b58 761 return CommunicationError;
IanBenzMaxim 25:bdb1c5a53b58 762
IanBenzMaxim 25:bdb1c5a53b58 763 // check CS
IanBenzMaxim 25:bdb1c5a53b58 764 if (buf[cnt-1] != 0xAA)
IanBenzMaxim 25:bdb1c5a53b58 765 return OperationFailure;
IanBenzMaxim 25:bdb1c5a53b58 766
IanBenzMaxim 25:bdb1c5a53b58 767 // send release and strong pull-up
IanBenzMaxim 25:bdb1c5a53b58 768 m_OW_master.OWWriteBytePower(0xAA);
IanBenzMaxim 25:bdb1c5a53b58 769
IanBenzMaxim 25:bdb1c5a53b58 770 // now wait for the MAC computation.
IanBenzMaxim 25:bdb1c5a53b58 771 wait_ms(EEPROM_WRITE_DELAY);
IanBenzMaxim 25:bdb1c5a53b58 772
IanBenzMaxim 25:bdb1c5a53b58 773 // disable strong pullup
IanBenzMaxim 25:bdb1c5a53b58 774 m_OW_master.OWLevel(OneWireMaster::LEVEL_NORMAL);
IanBenzMaxim 25:bdb1c5a53b58 775
IanBenzMaxim 25:bdb1c5a53b58 776 // read the CS byte
IanBenzMaxim 25:bdb1c5a53b58 777 m_OW_master.OWReadByte(cs);
IanBenzMaxim 25:bdb1c5a53b58 778
IanBenzMaxim 25:bdb1c5a53b58 779 if (cs == 0xAA)
IanBenzMaxim 25:bdb1c5a53b58 780 return Success;
IanBenzMaxim 25:bdb1c5a53b58 781 // else
IanBenzMaxim 25:bdb1c5a53b58 782 return OperationFailure;
IanBenzMaxim 25:bdb1c5a53b58 783 }
IanBenzMaxim 25:bdb1c5a53b58 784
IanBenzMaxim 25:bdb1c5a53b58 785 //--------------------------------------------------------------------------
IanBenzMaxim 25:bdb1c5a53b58 786 // Compute MAC to write a 4 byte memory block using an authenticated
IanBenzMaxim 25:bdb1c5a53b58 787 // write.
IanBenzMaxim 25:bdb1c5a53b58 788 //
IanBenzMaxim 25:bdb1c5a53b58 789 // Parameters
IanBenzMaxim 25:bdb1c5a53b58 790 // page - page number where the block to write is located (0 to 15)
IanBenzMaxim 25:bdb1c5a53b58 791 // block - block number in page (0 to 7)
IanBenzMaxim 25:bdb1c5a53b58 792 // new_data - 4 byte buffer containing the data to write
IanBenzMaxim 25:bdb1c5a53b58 793 // old_data - 4 byte buffer containing the data to write
IanBenzMaxim 25:bdb1c5a53b58 794 // manid - 2 byte buffer containing the manufacturer ID (general device: 00h,00h)
IanBenzMaxim 25:bdb1c5a53b58 795 // mac - buffer to put the calculated mac into
IanBenzMaxim 25:bdb1c5a53b58 796 //
IanBenzMaxim 25:bdb1c5a53b58 797 // Returns: true - mac calculated
IanBenzMaxim 25:bdb1c5a53b58 798 // false - Failed to calculate
IanBenzMaxim 25:bdb1c5a53b58 799 //
IanBenzMaxim 25:bdb1c5a53b58 800 ISha256MacCoprocessor::CmdResult DS28E15_22_25::CalculateSegmentWriteMAC256(const ISha256MacCoprocessor & MacCoproc, unsigned int pageNum, unsigned int segmentNum, const std::uint8_t (&newData)[segmentSize], const std::uint8_t (&oldData)[segmentSize], const RomId & romId, const std::uint8_t (&manId)[manIdLen], std::uint8_t (&mac)[macLen])
IanBenzMaxim 25:bdb1c5a53b58 801 {
IanBenzMaxim 25:bdb1c5a53b58 802 std::uint8_t MT[ISha256MacCoprocessor::WriteMAC_data_len];
IanBenzMaxim 25:bdb1c5a53b58 803
IanBenzMaxim 25:bdb1c5a53b58 804 // insert ROM number
IanBenzMaxim 25:bdb1c5a53b58 805 memcpy(&MT[0], romId, RomId::byteLen);
IanBenzMaxim 25:bdb1c5a53b58 806
IanBenzMaxim 25:bdb1c5a53b58 807 MT[11] = segmentNum;
IanBenzMaxim 25:bdb1c5a53b58 808 MT[10] = pageNum;
IanBenzMaxim 25:bdb1c5a53b58 809 MT[9] = manId[0];
IanBenzMaxim 25:bdb1c5a53b58 810 MT[8] = manId[1];
IanBenzMaxim 25:bdb1c5a53b58 811
IanBenzMaxim 25:bdb1c5a53b58 812 // insert old data
IanBenzMaxim 25:bdb1c5a53b58 813 memcpy(&MT[12], oldData, segmentSize);
IanBenzMaxim 25:bdb1c5a53b58 814
IanBenzMaxim 25:bdb1c5a53b58 815 // insert new data
IanBenzMaxim 25:bdb1c5a53b58 816 memcpy(&MT[16], newData, segmentSize);
IanBenzMaxim 25:bdb1c5a53b58 817
IanBenzMaxim 25:bdb1c5a53b58 818 return MacCoproc.ComputeAndRead_WriteMAC(MT, mac);
IanBenzMaxim 25:bdb1c5a53b58 819 }
IanBenzMaxim 25:bdb1c5a53b58 820
IanBenzMaxim 25:bdb1c5a53b58 821
IanBenzMaxim 25:bdb1c5a53b58 822
IanBenzMaxim 25:bdb1c5a53b58 823
IanBenzMaxim 25:bdb1c5a53b58 824 ISha256MacCoprocessor::CmdResult DS28E15_22_25::CalculateProtectionWriteMAC256(const ISha256MacCoprocessor & MacCoproc, std::uint8_t newProtection, std::uint8_t oldProtection, const RomId & romId, const std::uint8_t (&manId)[manIdLen], std::uint8_t (&mac)[macLen])
IanBenzMaxim 25:bdb1c5a53b58 825 {
IanBenzMaxim 25:bdb1c5a53b58 826 std::uint8_t MT[ISha256MacCoprocessor::WriteMAC_data_len];
IanBenzMaxim 25:bdb1c5a53b58 827
IanBenzMaxim 25:bdb1c5a53b58 828 // insert ROM number
IanBenzMaxim 25:bdb1c5a53b58 829 std::memcpy(MT, romId, RomId::byteLen);
IanBenzMaxim 25:bdb1c5a53b58 830
IanBenzMaxim 25:bdb1c5a53b58 831 // instert block and page
IanBenzMaxim 25:bdb1c5a53b58 832 MT[11] = 0;
IanBenzMaxim 25:bdb1c5a53b58 833 MT[10] = newProtection & 0x0F;
IanBenzMaxim 25:bdb1c5a53b58 834
IanBenzMaxim 25:bdb1c5a53b58 835 MT[9] = manId[0];
IanBenzMaxim 25:bdb1c5a53b58 836 MT[8] = manId[1];
IanBenzMaxim 25:bdb1c5a53b58 837
IanBenzMaxim 25:bdb1c5a53b58 838 // old data
IanBenzMaxim 25:bdb1c5a53b58 839 MT[12] = (oldProtection & PROT_BIT_AUTHWRITE) ? 0x01 : 0x00;
IanBenzMaxim 25:bdb1c5a53b58 840 MT[13] = (oldProtection & PROT_BIT_EPROM) ? 0x01 : 0x00;
IanBenzMaxim 25:bdb1c5a53b58 841 MT[14] = (oldProtection & PROT_BIT_WRITE) ? 0x01 : 0x00;
IanBenzMaxim 25:bdb1c5a53b58 842 MT[15] = (oldProtection & PROT_BIT_READ) ? 0x01 : 0x00;
IanBenzMaxim 25:bdb1c5a53b58 843 // new data
IanBenzMaxim 25:bdb1c5a53b58 844 MT[16] = (newProtection & PROT_BIT_AUTHWRITE) ? 0x01 : 0x00;
IanBenzMaxim 25:bdb1c5a53b58 845 MT[17] = (newProtection & PROT_BIT_EPROM) ? 0x01 : 0x00;
IanBenzMaxim 25:bdb1c5a53b58 846 MT[18] = (newProtection & PROT_BIT_WRITE) ? 0x01 : 0x00;
IanBenzMaxim 25:bdb1c5a53b58 847 MT[19] = (newProtection & PROT_BIT_READ) ? 0x01 : 0x00;
IanBenzMaxim 25:bdb1c5a53b58 848
IanBenzMaxim 25:bdb1c5a53b58 849 // compute the mac
IanBenzMaxim 25:bdb1c5a53b58 850 return MacCoproc.ComputeAndRead_WriteMAC(MT, mac);
IanBenzMaxim 25:bdb1c5a53b58 851 }
IanBenzMaxim 25:bdb1c5a53b58 852
IanBenzMaxim 25:bdb1c5a53b58 853 //--------------------------------------------------------------------------
IanBenzMaxim 25:bdb1c5a53b58 854 // Write a 4 byte memory block using an authenticated write (with MAC).
IanBenzMaxim 25:bdb1c5a53b58 855 // The block location is selected by the
IanBenzMaxim 25:bdb1c5a53b58 856 // page number and offset block within the page. Multiple blocks can
IanBenzMaxim 25:bdb1c5a53b58 857 // be programmed without re-selecting the device using the continue flag.
IanBenzMaxim 25:bdb1c5a53b58 858 // This function does not use the Authenticated Write operation.
IanBenzMaxim 25:bdb1c5a53b58 859 //
IanBenzMaxim 25:bdb1c5a53b58 860 // Parameters
IanBenzMaxim 25:bdb1c5a53b58 861 // page - page number where the block to write is located (0 to 15)
IanBenzMaxim 25:bdb1c5a53b58 862 // block - block number in page (0 to 7)
IanBenzMaxim 25:bdb1c5a53b58 863 // new_data - 4 byte buffer containing the data to write
IanBenzMaxim 25:bdb1c5a53b58 864 // old_data - 4 byte buffer containing the data to write
IanBenzMaxim 25:bdb1c5a53b58 865 // manid - 2 byte buffer containing the manufacturer ID (general device: 00h,00h)
IanBenzMaxim 25:bdb1c5a53b58 866 // contflag - Flag to indicate the write is continued from the last
IanBenzMaxim 25:bdb1c5a53b58 867 //
IanBenzMaxim 25:bdb1c5a53b58 868 // Returns: true - block written
IanBenzMaxim 25:bdb1c5a53b58 869 // false - Failed to write block (no presence or invalid CRC16)
IanBenzMaxim 25:bdb1c5a53b58 870 //
IanBenzMaxim 25:bdb1c5a53b58 871 OneWireSlave::CmdResult DS28E15_22_25::writeAuthSegment(const ISha256MacCoprocessor & MacCoproc, unsigned int pageNum, unsigned int segmentNum, const std::uint8_t (&newData)[segmentSize], const std::uint8_t (&oldData)[segmentSize], bool continuing)
IanBenzMaxim 25:bdb1c5a53b58 872 {
IanBenzMaxim 25:bdb1c5a53b58 873 std::uint8_t buf[256], cs;
IanBenzMaxim 25:bdb1c5a53b58 874 int cnt, offset;
IanBenzMaxim 25:bdb1c5a53b58 875
IanBenzMaxim 25:bdb1c5a53b58 876 cnt = 0;
IanBenzMaxim 25:bdb1c5a53b58 877 offset = 0;
IanBenzMaxim 25:bdb1c5a53b58 878
IanBenzMaxim 25:bdb1c5a53b58 879 // check if not continuing a previous block write
IanBenzMaxim 25:bdb1c5a53b58 880 if (!continuing)
IanBenzMaxim 25:bdb1c5a53b58 881 {
IanBenzMaxim 25:bdb1c5a53b58 882 buf[cnt++] = CMD_WRITE_AUTH_MEMORY;
IanBenzMaxim 25:bdb1c5a53b58 883 buf[cnt++] = (segmentNum << 5) | pageNum; // address
IanBenzMaxim 25:bdb1c5a53b58 884
IanBenzMaxim 25:bdb1c5a53b58 885 // Send command
IanBenzMaxim 25:bdb1c5a53b58 886 m_OW_master.OWWriteBlock(&buf[0], 2);
IanBenzMaxim 25:bdb1c5a53b58 887
IanBenzMaxim 25:bdb1c5a53b58 888 // Read CRC
IanBenzMaxim 25:bdb1c5a53b58 889 m_OW_master.OWReadBlock(&buf[cnt], 2);
IanBenzMaxim 25:bdb1c5a53b58 890 cnt += 2;
IanBenzMaxim 25:bdb1c5a53b58 891
IanBenzMaxim 25:bdb1c5a53b58 892 offset = cnt;
IanBenzMaxim 25:bdb1c5a53b58 893 }
IanBenzMaxim 25:bdb1c5a53b58 894
IanBenzMaxim 25:bdb1c5a53b58 895 // add the data
IanBenzMaxim 25:bdb1c5a53b58 896 for (size_t i = 0; i < segmentSize; i++)
IanBenzMaxim 25:bdb1c5a53b58 897 buf[cnt++] = newData[i];
IanBenzMaxim 25:bdb1c5a53b58 898
IanBenzMaxim 25:bdb1c5a53b58 899 // Send data
IanBenzMaxim 25:bdb1c5a53b58 900 m_OW_master.OWWriteBlock(newData, segmentSize);
IanBenzMaxim 25:bdb1c5a53b58 901
IanBenzMaxim 25:bdb1c5a53b58 902 // read first CRC byte
IanBenzMaxim 25:bdb1c5a53b58 903 m_OW_master.OWReadByte(buf[cnt++]);
IanBenzMaxim 25:bdb1c5a53b58 904
IanBenzMaxim 25:bdb1c5a53b58 905 // read the last CRC and enable power
IanBenzMaxim 25:bdb1c5a53b58 906 m_OW_master.OWReadBytePower(buf[cnt++]);
IanBenzMaxim 25:bdb1c5a53b58 907
IanBenzMaxim 25:bdb1c5a53b58 908 // now wait for the MAC computation.
IanBenzMaxim 25:bdb1c5a53b58 909 wait_ms(SHA_COMPUTATION_DELAY);
IanBenzMaxim 25:bdb1c5a53b58 910
IanBenzMaxim 25:bdb1c5a53b58 911 // disable strong pullup
IanBenzMaxim 25:bdb1c5a53b58 912 m_OW_master.OWLevel(OneWireMaster::LEVEL_NORMAL);
IanBenzMaxim 25:bdb1c5a53b58 913
IanBenzMaxim 25:bdb1c5a53b58 914 // check the first CRC16
IanBenzMaxim 25:bdb1c5a53b58 915 if (!continuing)
IanBenzMaxim 25:bdb1c5a53b58 916 {
IanBenzMaxim 25:bdb1c5a53b58 917 if (OneWireMaster::calculateCRC16(buf, 0, offset) != 0xB001)
IanBenzMaxim 25:bdb1c5a53b58 918 return CommunicationError;
IanBenzMaxim 25:bdb1c5a53b58 919 }
IanBenzMaxim 25:bdb1c5a53b58 920
IanBenzMaxim 25:bdb1c5a53b58 921 // check the second CRC16
IanBenzMaxim 25:bdb1c5a53b58 922 unsigned short CRC16 = 0;
IanBenzMaxim 25:bdb1c5a53b58 923
IanBenzMaxim 25:bdb1c5a53b58 924 // DS28E25/DS28E22, crc gets calculagted with CS byte
IanBenzMaxim 25:bdb1c5a53b58 925 if ((romId.familyCode() == DS28E25_FAMILY) || (romId.familyCode() == DS28E22_FAMILY))
IanBenzMaxim 25:bdb1c5a53b58 926 {
IanBenzMaxim 25:bdb1c5a53b58 927 if (continuing)
IanBenzMaxim 25:bdb1c5a53b58 928 CRC16 = OneWireMaster::calculateCRC16(CRC16, 0xAA);
IanBenzMaxim 25:bdb1c5a53b58 929 }
IanBenzMaxim 25:bdb1c5a53b58 930
IanBenzMaxim 25:bdb1c5a53b58 931 CRC16 = OneWireMaster::calculateCRC16(buf, offset, (cnt - offset), CRC16);
IanBenzMaxim 25:bdb1c5a53b58 932
IanBenzMaxim 25:bdb1c5a53b58 933 if (CRC16 != 0xB001)
IanBenzMaxim 25:bdb1c5a53b58 934 return CommunicationError;
IanBenzMaxim 25:bdb1c5a53b58 935
IanBenzMaxim 25:bdb1c5a53b58 936 // compute the mac
IanBenzMaxim 25:bdb1c5a53b58 937 ISha256MacCoprocessor::CmdResult result;
IanBenzMaxim 25:bdb1c5a53b58 938 result = CalculateSegmentWriteMAC256(MacCoproc, pageNum, segmentNum, newData, oldData, romId, manId, reinterpret_cast<std::uint8_t (&)[macLen]>(buf));
IanBenzMaxim 25:bdb1c5a53b58 939 if (result != ISha256MacCoprocessor::Success)
IanBenzMaxim 25:bdb1c5a53b58 940 return OperationFailure;
IanBenzMaxim 25:bdb1c5a53b58 941
IanBenzMaxim 25:bdb1c5a53b58 942 // transmit MAC as a block
IanBenzMaxim 25:bdb1c5a53b58 943 cnt = 0;
IanBenzMaxim 25:bdb1c5a53b58 944 m_OW_master.OWWriteBlock(buf, macLen);
IanBenzMaxim 25:bdb1c5a53b58 945
IanBenzMaxim 25:bdb1c5a53b58 946 // calculate CRC on MAC
IanBenzMaxim 25:bdb1c5a53b58 947 CRC16 = OneWireMaster::calculateCRC16(buf, 0, macLen);
IanBenzMaxim 25:bdb1c5a53b58 948
IanBenzMaxim 25:bdb1c5a53b58 949 // append read of CRC16 and CS byte
IanBenzMaxim 25:bdb1c5a53b58 950 m_OW_master.OWReadBlock(&buf[0], 3);
IanBenzMaxim 25:bdb1c5a53b58 951 cnt = 3;
IanBenzMaxim 25:bdb1c5a53b58 952
IanBenzMaxim 25:bdb1c5a53b58 953 // ckeck CRC16
IanBenzMaxim 25:bdb1c5a53b58 954 CRC16 = OneWireMaster::calculateCRC16(buf, 0, (cnt - 1), CRC16);
IanBenzMaxim 25:bdb1c5a53b58 955
IanBenzMaxim 25:bdb1c5a53b58 956 if (CRC16 != 0xB001)
IanBenzMaxim 25:bdb1c5a53b58 957 return CommunicationError;
IanBenzMaxim 25:bdb1c5a53b58 958
IanBenzMaxim 25:bdb1c5a53b58 959 // check CS
IanBenzMaxim 25:bdb1c5a53b58 960 if (buf[cnt-1] != 0xAA)
IanBenzMaxim 25:bdb1c5a53b58 961 return OperationFailure;
IanBenzMaxim 25:bdb1c5a53b58 962
IanBenzMaxim 25:bdb1c5a53b58 963 // send release and strong pull-up
IanBenzMaxim 25:bdb1c5a53b58 964 m_OW_master.OWWriteBytePower(0xAA);
IanBenzMaxim 25:bdb1c5a53b58 965
IanBenzMaxim 25:bdb1c5a53b58 966 // now wait for the MAC computation.
IanBenzMaxim 25:bdb1c5a53b58 967 wait_ms(EEPROM_WRITE_DELAY);
IanBenzMaxim 25:bdb1c5a53b58 968
IanBenzMaxim 25:bdb1c5a53b58 969 // disable strong pullup
IanBenzMaxim 25:bdb1c5a53b58 970 m_OW_master.OWLevel(OneWireMaster::LEVEL_NORMAL);
IanBenzMaxim 25:bdb1c5a53b58 971
IanBenzMaxim 25:bdb1c5a53b58 972 // read the CS byte
IanBenzMaxim 25:bdb1c5a53b58 973 m_OW_master.OWReadByte(cs);
IanBenzMaxim 25:bdb1c5a53b58 974
IanBenzMaxim 25:bdb1c5a53b58 975 if (cs == 0xAA)
IanBenzMaxim 25:bdb1c5a53b58 976 return Success;
IanBenzMaxim 25:bdb1c5a53b58 977 // else
IanBenzMaxim 25:bdb1c5a53b58 978 return OperationFailure;
IanBenzMaxim 25:bdb1c5a53b58 979 }
IanBenzMaxim 25:bdb1c5a53b58 980
IanBenzMaxim 25:bdb1c5a53b58 981
IanBenzMaxim 25:bdb1c5a53b58 982
IanBenzMaxim 25:bdb1c5a53b58 983
IanBenzMaxim 25:bdb1c5a53b58 984 OneWireSlave::CmdResult DS28E15_22_25::readSegment(unsigned int page, unsigned int segment, std::uint8_t (&data)[segmentSize]) const
IanBenzMaxim 25:bdb1c5a53b58 985 {
IanBenzMaxim 25:bdb1c5a53b58 986 OneWireMaster::CmdResult result;
IanBenzMaxim 25:bdb1c5a53b58 987 std::uint8_t buf[2];
IanBenzMaxim 25:bdb1c5a53b58 988
IanBenzMaxim 25:bdb1c5a53b58 989 buf[0] = CMD_READ_MEMORY;
IanBenzMaxim 25:bdb1c5a53b58 990 buf[1] = (segment << 5) | page;
IanBenzMaxim 25:bdb1c5a53b58 991
IanBenzMaxim 25:bdb1c5a53b58 992 // Transmit command
IanBenzMaxim 25:bdb1c5a53b58 993 m_OW_master.OWWriteBlock(buf, 2);
IanBenzMaxim 25:bdb1c5a53b58 994
IanBenzMaxim 25:bdb1c5a53b58 995 // Receive CRC
IanBenzMaxim 25:bdb1c5a53b58 996 result = m_OW_master.OWReadBlock(buf, 2);
IanBenzMaxim 25:bdb1c5a53b58 997
IanBenzMaxim 25:bdb1c5a53b58 998 // Receive data
IanBenzMaxim 25:bdb1c5a53b58 999 if (result == OneWireMaster::Success)
IanBenzMaxim 25:bdb1c5a53b58 1000 result = m_OW_master.OWReadBlock(data, segmentSize);
IanBenzMaxim 25:bdb1c5a53b58 1001
IanBenzMaxim 25:bdb1c5a53b58 1002 return (result == OneWireMaster::Success ? OneWireSlave::Success : OneWireSlave::CommunicationError);
IanBenzMaxim 25:bdb1c5a53b58 1003 }
IanBenzMaxim 25:bdb1c5a53b58 1004
IanBenzMaxim 25:bdb1c5a53b58 1005 //--------------------------------------------------------------------------
IanBenzMaxim 25:bdb1c5a53b58 1006 // Write a 4 byte memory block. The block location is selected by the
IanBenzMaxim 25:bdb1c5a53b58 1007 // page number and offset blcok within the page. Multiple blocks can
IanBenzMaxim 25:bdb1c5a53b58 1008 // be programmed without re-selecting the device using the continue flag.
IanBenzMaxim 25:bdb1c5a53b58 1009 // This function does not use the Authenticated Write operation.
IanBenzMaxim 25:bdb1c5a53b58 1010 //
IanBenzMaxim 25:bdb1c5a53b58 1011 // Parameters
IanBenzMaxim 25:bdb1c5a53b58 1012 // page - page number where the block to write is located (0 to 15)
IanBenzMaxim 25:bdb1c5a53b58 1013 // block - block number in page (0 to 7)
IanBenzMaxim 25:bdb1c5a53b58 1014 // data - 4 byte buffer containing the data to write
IanBenzMaxim 25:bdb1c5a53b58 1015 // contflag - Flag to indicate the write is continued from the last
IanBenzMaxim 25:bdb1c5a53b58 1016 //
IanBenzMaxim 25:bdb1c5a53b58 1017 // Returns: true - block written
IanBenzMaxim 25:bdb1c5a53b58 1018 // false - Failed to write block (no presence or invalid CRC16)
IanBenzMaxim 25:bdb1c5a53b58 1019 //
IanBenzMaxim 25:bdb1c5a53b58 1020 OneWireSlave::CmdResult DS28E15_22_25::writeSegment(unsigned int page, unsigned int block, const std::uint8_t (&data)[segmentSize], bool continuing)
IanBenzMaxim 25:bdb1c5a53b58 1021 {
IanBenzMaxim 25:bdb1c5a53b58 1022 std::uint8_t buf[256], cs;
IanBenzMaxim 25:bdb1c5a53b58 1023 int cnt, offset;
IanBenzMaxim 25:bdb1c5a53b58 1024
IanBenzMaxim 25:bdb1c5a53b58 1025 cnt = 0;
IanBenzMaxim 25:bdb1c5a53b58 1026 offset = 0;
IanBenzMaxim 25:bdb1c5a53b58 1027
IanBenzMaxim 25:bdb1c5a53b58 1028 // check if not continuing a previous block write
IanBenzMaxim 25:bdb1c5a53b58 1029 if (!continuing)
IanBenzMaxim 25:bdb1c5a53b58 1030 {
IanBenzMaxim 25:bdb1c5a53b58 1031 buf[cnt++] = CMD_WRITE_MEMORY;
IanBenzMaxim 25:bdb1c5a53b58 1032 buf[cnt++] = (block << 5) | page; // address
IanBenzMaxim 25:bdb1c5a53b58 1033
IanBenzMaxim 25:bdb1c5a53b58 1034 // Send command
IanBenzMaxim 25:bdb1c5a53b58 1035 m_OW_master.OWWriteBlock(&buf[0], 2);
IanBenzMaxim 25:bdb1c5a53b58 1036
IanBenzMaxim 25:bdb1c5a53b58 1037 // Read CRC
IanBenzMaxim 25:bdb1c5a53b58 1038 m_OW_master.OWReadBlock(&buf[cnt], 2);
IanBenzMaxim 25:bdb1c5a53b58 1039 cnt += 2;
IanBenzMaxim 25:bdb1c5a53b58 1040
IanBenzMaxim 25:bdb1c5a53b58 1041 offset = cnt;
IanBenzMaxim 25:bdb1c5a53b58 1042 }
IanBenzMaxim 25:bdb1c5a53b58 1043
IanBenzMaxim 25:bdb1c5a53b58 1044 // add the data
IanBenzMaxim 25:bdb1c5a53b58 1045 for (size_t i = 0; i < segmentSize; i++)
IanBenzMaxim 25:bdb1c5a53b58 1046 buf[cnt++] = data[i];
IanBenzMaxim 25:bdb1c5a53b58 1047
IanBenzMaxim 25:bdb1c5a53b58 1048 // Send data
IanBenzMaxim 25:bdb1c5a53b58 1049 m_OW_master.OWWriteBlock(data, segmentSize);
IanBenzMaxim 25:bdb1c5a53b58 1050
IanBenzMaxim 25:bdb1c5a53b58 1051 // Read CRC
IanBenzMaxim 25:bdb1c5a53b58 1052 m_OW_master.OWReadBlock(&buf[cnt], 2);
IanBenzMaxim 25:bdb1c5a53b58 1053 cnt += 2;
IanBenzMaxim 25:bdb1c5a53b58 1054
IanBenzMaxim 25:bdb1c5a53b58 1055 // check the first CRC16
IanBenzMaxim 25:bdb1c5a53b58 1056 if (!continuing)
IanBenzMaxim 25:bdb1c5a53b58 1057 {
IanBenzMaxim 25:bdb1c5a53b58 1058 if (OneWireMaster::calculateCRC16(buf, 0, offset) != 0xB001)
IanBenzMaxim 25:bdb1c5a53b58 1059 return CommunicationError;
IanBenzMaxim 25:bdb1c5a53b58 1060 }
IanBenzMaxim 25:bdb1c5a53b58 1061
IanBenzMaxim 25:bdb1c5a53b58 1062 // check the second CRC16
IanBenzMaxim 25:bdb1c5a53b58 1063 if (OneWireMaster::calculateCRC16(buf, offset, (cnt - offset)) != 0xB001)
IanBenzMaxim 25:bdb1c5a53b58 1064 return CommunicationError;
IanBenzMaxim 25:bdb1c5a53b58 1065
IanBenzMaxim 25:bdb1c5a53b58 1066 // send release and strong pull-up
IanBenzMaxim 25:bdb1c5a53b58 1067 m_OW_master.OWWriteBytePower(0xAA);
IanBenzMaxim 25:bdb1c5a53b58 1068
IanBenzMaxim 25:bdb1c5a53b58 1069 // now wait for the MAC computation.
IanBenzMaxim 25:bdb1c5a53b58 1070 wait_ms(EEPROM_WRITE_DELAY);
IanBenzMaxim 25:bdb1c5a53b58 1071
IanBenzMaxim 25:bdb1c5a53b58 1072 // disable strong pullup
IanBenzMaxim 25:bdb1c5a53b58 1073 m_OW_master.OWLevel(OneWireMaster::LEVEL_NORMAL);
IanBenzMaxim 25:bdb1c5a53b58 1074
IanBenzMaxim 25:bdb1c5a53b58 1075 // read the CS byte
IanBenzMaxim 25:bdb1c5a53b58 1076 m_OW_master.OWReadByte(cs);
IanBenzMaxim 25:bdb1c5a53b58 1077
IanBenzMaxim 25:bdb1c5a53b58 1078 if (cs == 0xAA)
IanBenzMaxim 25:bdb1c5a53b58 1079 return Success;
IanBenzMaxim 25:bdb1c5a53b58 1080 // else
IanBenzMaxim 25:bdb1c5a53b58 1081 return OperationFailure;
IanBenzMaxim 25:bdb1c5a53b58 1082 }
IanBenzMaxim 25:bdb1c5a53b58 1083
IanBenzMaxim 25:bdb1c5a53b58 1084 //----------------------------------------------------------------------
IanBenzMaxim 25:bdb1c5a53b58 1085 // Performs a Compute Next SHA-256 calculation given the provided 32-bytes
IanBenzMaxim 25:bdb1c5a53b58 1086 // of binding data and 8 byte partial secret. The first 8 bytes of the
IanBenzMaxim 25:bdb1c5a53b58 1087 // resulting MAC is set as the new secret.
IanBenzMaxim 25:bdb1c5a53b58 1088 //
IanBenzMaxim 25:bdb1c5a53b58 1089 // 'binding' - 32 byte buffer containing the binding data
IanBenzMaxim 25:bdb1c5a53b58 1090 // 'partial' - 8 byte buffer with new partial secret
IanBenzMaxim 25:bdb1c5a53b58 1091 // 'page_num' - page number that the compute is calculated on
IanBenzMaxim 25:bdb1c5a53b58 1092 // 'manid' - manufacturer ID
IanBenzMaxim 25:bdb1c5a53b58 1093 //
IanBenzMaxim 25:bdb1c5a53b58 1094 // Globals used : SECRET used in calculation and set to new secret
IanBenzMaxim 25:bdb1c5a53b58 1095 //
IanBenzMaxim 25:bdb1c5a53b58 1096 // Returns: true if compute successful
IanBenzMaxim 25:bdb1c5a53b58 1097 // false failed to do compute
IanBenzMaxim 25:bdb1c5a53b58 1098 //
IanBenzMaxim 25:bdb1c5a53b58 1099 ISha256MacCoprocessor::CmdResult DS28E15_22_25::CalculateNextSecret(ISha256MacCoprocessor & MacCoproc, const std::uint8_t (&binding)[pageSize], const std::uint8_t (&partial)[scratchpadSize], const RomId & romId, const std::uint8_t (&manId)[manIdLen], unsigned int pageNum)
IanBenzMaxim 25:bdb1c5a53b58 1100 {
IanBenzMaxim 25:bdb1c5a53b58 1101 std::uint8_t devicePage[pageSize], deviceScratchpad[scratchpadSize], SSecret_data[ISha256MacCoprocessor::SSecret_data_len];
IanBenzMaxim 25:bdb1c5a53b58 1102
IanBenzMaxim 25:bdb1c5a53b58 1103 // insert page data
IanBenzMaxim 25:bdb1c5a53b58 1104 memcpy(devicePage, binding, pageSize);
IanBenzMaxim 25:bdb1c5a53b58 1105
IanBenzMaxim 25:bdb1c5a53b58 1106 // insert challenge
IanBenzMaxim 25:bdb1c5a53b58 1107 memcpy(deviceScratchpad, partial, scratchpadSize);
IanBenzMaxim 25:bdb1c5a53b58 1108
IanBenzMaxim 25:bdb1c5a53b58 1109 // insert ROM number
IanBenzMaxim 25:bdb1c5a53b58 1110 std::memcpy(SSecret_data, romId, RomId::byteLen);
IanBenzMaxim 25:bdb1c5a53b58 1111
IanBenzMaxim 25:bdb1c5a53b58 1112 SSecret_data[11] = 0x00;
IanBenzMaxim 25:bdb1c5a53b58 1113 SSecret_data[10] = pageNum;
IanBenzMaxim 25:bdb1c5a53b58 1114 SSecret_data[9] = manId[0];
IanBenzMaxim 25:bdb1c5a53b58 1115 SSecret_data[8] = manId[1];
IanBenzMaxim 25:bdb1c5a53b58 1116
IanBenzMaxim 25:bdb1c5a53b58 1117 return MacCoproc.Compute_SSecret(devicePage, deviceScratchpad, SSecret_data);
IanBenzMaxim 25:bdb1c5a53b58 1118 }