1-Wire® library for mbed. Complete 1-Wire library that supports our silicon masters along with a bit-bang master on the MAX32600MBED platform with one common interface for mbed. Slave support has also been included and more slaves will be added as time permits.
Dependents: MAXREFDES131_Qt_Demo MAX32630FTHR_iButton_uSD_Logger MAX32630FTHR_DS18B20_uSD_Logger MAXREFDES130_131_Demo ... more
Superseded by MaximInterface.
OneWire_Memory/Authenticators/DS28E15_22_25/DS28E15_22_25.cpp@32:bce180b544ed, 2016-03-30 (annotated)
- Committer:
- IanBenzMaxim
- Date:
- Wed Mar 30 16:50:29 2016 -0500
- Revision:
- 32:bce180b544ed
- Parent:
- 27:d5aaefa252f1
- Child:
- 33:a4c015046956
1. Move the implementation of OWSearch() into OneWireMaster since it is a fairly complex algorithm that shouldn?t be implemented over and over. It will also match all other ROM function that are implemented there.
2. Create a new member function, OWTriplet(), in OneWireMaster to handle the virtual section of OWSearch(). Create a default implementation of OWTriplet() that uses OWReadByte() and OWWriteByte(). Masters only need to implement this function if they have a search accelerator of some sort.
3. Create type SearchState that will encapsulate all persistent data used by the search ROM functions. This will also make it easy to not have the search state part of the permanent OneWireMaster class data.
4. Rename OWSpeed() to OWSetSpeed() and OWLevel() to OWSetLevel() for naming consistency.
Who changed what in which revision?
User | Revision | Line number | New 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 | 32:bce180b544ed | 157 | m_OW_master.OWSetLevel(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 | 32:bce180b544ed | 192 | m_OW_master.OWSetLevel(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 | 32:bce180b544ed | 249 | m_OW_master.OWSetLevel(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 | 32:bce180b544ed | 441 | m_OW_master.OWSetLevel(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 | 32:bce180b544ed | 502 | m_OW_master.OWSetLevel(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 | 32:bce180b544ed | 600 | m_OW_master.OWSetLevel(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 | 32:bce180b544ed | 723 | m_OW_master.OWSetLevel(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 | 32:bce180b544ed | 774 | m_OW_master.OWSetLevel(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 | 32:bce180b544ed | 912 | m_OW_master.OWSetLevel(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 | 32:bce180b544ed | 970 | m_OW_master.OWSetLevel(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 | 32:bce180b544ed | 1073 | m_OW_master.OWSetLevel(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 | } |