Implementation of 1-Wire with added Alarm Search Functionality

Dependents:   Max32630_One_Wire_Interface

Committer:
IanBenzMaxim
Date:
Tue Mar 22 15:18:00 2016 -0500
Revision:
25:bdb1c5a53b58
Child:
27:d5aaefa252f1
Added support for DS28E15/22/25. Added OneWireSlave class used by DS28E15_22_25 as a starting point for a slave base class.

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