Extended MaximInterface
Dependents: mbed_DS28EC20_GPIO
Diff: Devices/DS2465.cpp
- Revision:
- 6:a8c83a2e6fa4
- Parent:
- 0:f77ad7f72d04
- Child:
- 7:471901a04573
--- a/Devices/DS2465.cpp Fri Jan 19 10:25:02 2018 -0600 +++ b/Devices/DS2465.cpp Wed Jan 23 13:11:04 2019 -0600 @@ -37,24 +37,6 @@ using namespace Sha256; -enum MemoryAddress { - Scratchpad = 0x00, - CommandReg = 0x60, - StatusReg = 0x61, - ReadDataReg = 0x62, - MacReadoutReg = 0x63, - MemoryProtectionReg = 0x64, - ConfigReg = 0x67, - tRSTL_Reg = 0x68, - tMSP_Reg = 0x69, - tW0L_Reg = 0x6A, - tREC0_Reg = 0x6B, - RWPU_Reg = 0x6C, - tW1L_Reg = 0x6D, - UserMemoryPage0 = 0x80, - UserMemoryPage1 = 0xA0 -}; - /// Delay required after writing an EEPROM segment. static const int eepromSegmentWriteDelayMs = 10; /// Delay required after writing an EEPROM page such as the secret memory. @@ -62,26 +44,12 @@ /// Delay required for a SHA computation to complete. static const int shaComputationDelayMs = 2; -/// DS2465 Commands -enum Command { - DeviceResetCmd = 0xF0, - WriteDeviceConfigCmd = 0xD2, - OwResetCmd = 0xB4, - OwWriteByteCmd = 0xA5, - OwReadByteCmd = 0x96, - OwSingleBitCmd = 0x87, - OwTripletCmd = 0x78, - OwTransmitBlockCmd = 0x69, - OwReceiveBlockCmd = 0xE1, - CopyScratchpadCmd = 0x5A, - ComputeSlaveSecretCmd = 0x4B, - ComputeSlaveAuthMacCmd = 0x3C, - ComputeSlaveWriteMacCmd = 0x2D, - ComputeNextMasterSecretCmd = 0x1E, - SetProtectionCmd = 0x0F -}; +static const uint_least8_t scratchpad = 0x00; +static const uint_least8_t commandReg = 0x60; -/// DS2465 Status Bits +static const uint_least8_t owTransmitBlockCmd = 0x69; + +/// DS2465 Status bits. enum StatusBit { Status_1WB = 0x01, Status_PPD = 0x02, @@ -93,7 +61,10 @@ Status_DIR = 0x80 }; -static const size_t maxBlockSize = 63; +static const int maxBlockSize = 63; + +const int DS2465::memoryPages; +const int DS2465::segmentsPerPage; error_code DS2465::initialize(Config config) { // reset DS2465 @@ -109,12 +80,10 @@ PageRegion region) { error_code result = make_error_code(ArgumentOutOfRangeError); if (pageNum >= 0) { - uint_least8_t command[] = { - ComputeNextMasterSecretCmd, - static_cast<uint_least8_t>(swap ? (0xC8 | (pageNum << 4) | region) - : 0xBF)}; - result = - writeMemory(CommandReg, command, sizeof(command) / sizeof(command[0])); + const uint_least8_t command[] = { + 0x1E, static_cast<uint_least8_t>(swap ? (0xC8 | (pageNum << 4) | region) + : 0xBF)}; + result = writeMemory(commandReg, command); } return result; } @@ -123,14 +92,12 @@ int segmentNum) const { error_code result = make_error_code(ArgumentOutOfRangeError); if (pageNum >= 0 && segmentNum >= 0) { - uint_least8_t command[] = { - ComputeSlaveWriteMacCmd, - static_cast<uint_least8_t>((regwrite << 7) | (swap << 6) | - (pageNum << 4) | segmentNum)}; - result = - writeMemory(CommandReg, command, sizeof(command) / sizeof(command[0])); + const uint_least8_t command[] = { + 0x2D, static_cast<uint_least8_t>((regwrite << 7) | (swap << 6) | + (pageNum << 4) | segmentNum)}; + result = writeMemory(commandReg, command); if (!result) { - (*sleep)(shaComputationDelayMs); + sleep->invoke(shaComputationDelayMs); } } return result; @@ -140,14 +107,12 @@ PageRegion region) const { error_code result = make_error_code(ArgumentOutOfRangeError); if (pageNum >= 0) { - uint_least8_t command[] = { - ComputeSlaveAuthMacCmd, - static_cast<uint_least8_t>(swap ? (0xC8 | (pageNum << 4) | region) - : 0xBF)}; - result = - writeMemory(CommandReg, command, sizeof(command) / sizeof(command[0])); + const uint_least8_t command[] = { + 0x3C, static_cast<uint_least8_t>(swap ? (0xC8 | (pageNum << 4) | region) + : 0xBF)}; + result = writeMemory(commandReg, command); if (!result) { - (*sleep)(shaComputationDelayMs * 2); + sleep->invoke(shaComputationDelayMs * 2); } } return result; @@ -157,65 +122,62 @@ PageRegion region) { error_code result = make_error_code(ArgumentOutOfRangeError); if (pageNum >= 0) { - uint_least8_t command[] = { - ComputeSlaveSecretCmd, - static_cast<uint_least8_t>(swap ? (0xC8 | (pageNum << 4) | region) - : 0xBF)}; - result = - writeMemory(CommandReg, command, sizeof(command) / sizeof(command[0])); + const uint_least8_t command[] = { + 0x4B, static_cast<uint_least8_t>(swap ? (0xC8 | (pageNum << 4) | region) + : 0xBF)}; + result = writeMemory(commandReg, command); if (!result) { - (*sleep)(shaComputationDelayMs * 2); + sleep->invoke(shaComputationDelayMs * 2); } } return result; } -error_code DS2465::readPage(int pageNum, Page & data) const { +error_code DS2465::readPage(int pageNum, Page::span data) const { uint_least8_t addr; switch (pageNum) { case 0: - addr = UserMemoryPage0; + addr = 0x80; break; case 1: - addr = UserMemoryPage1; + addr = 0xA0; break; default: return make_error_code(ArgumentOutOfRangeError); } - return readMemory(addr, data.data(), data.size()); + return readMemory(addr, data); } -error_code DS2465::writePage(int pageNum, const Page & data) { - error_code result = writeMemory(Scratchpad, data.data(), data.size()); +error_code DS2465::writePage(int pageNum, Page::const_span data) { + error_code result = writeMemory(scratchpad, data); if (!result) { result = copyScratchpad(false, pageNum, false, 0); } if (!result) { - (*sleep)(eepromPageWriteDelayMs); + sleep->invoke(eepromPageWriteDelayMs); } return result; } error_code DS2465::writeSegment(int pageNum, int segmentNum, - const Segment & data) { - error_code result = writeMemory(Scratchpad, data.data(), data.size()); + Segment::const_span data) { + error_code result = writeMemory(scratchpad, data); if (!result) { result = copyScratchpad(false, pageNum, true, segmentNum); } if (!result) { - (*sleep)(eepromSegmentWriteDelayMs); + sleep->invoke(eepromSegmentWriteDelayMs); } return result; } -error_code DS2465::writeMasterSecret(const Hash & masterSecret) { - error_code result = - writeMemory(Scratchpad, masterSecret.data(), masterSecret.size()); +error_code DS2465::writeMasterSecret(Hash::const_span masterSecret) { + error_code result = writeMemory(scratchpad, masterSecret); if (!result) { result = copyScratchpad(true, 0, false, 0); } if (!result) { - (*sleep)(eepromPageWriteDelayMs); + sleep->invoke(eepromPageWriteDelayMs); } return result; } @@ -224,13 +186,12 @@ int segmentNum) { error_code result = make_error_code(ArgumentOutOfRangeError); if (pageNum >= 0 && segmentNum >= 0) { - uint_least8_t command[] = { - CopyScratchpadCmd, + const uint_least8_t command[] = { + 0x5A, static_cast<uint_least8_t>(destSecret ? 0 : (0x80 | (pageNum << 4) | (notFull << 3) | segmentNum))}; - result = - writeMemory(CommandReg, command, sizeof(command) / sizeof(command[0])); + result = writeMemory(commandReg, command); } return result; } @@ -282,9 +243,8 @@ // SS indicates byte containing search direction bit value in msbit const uint_least8_t command[] = { - OwTripletCmd, static_cast<uint_least8_t>(data.writeBit ? 0x80 : 0x00)}; - error_code result = - writeMemory(CommandReg, command, sizeof(command) / sizeof(command[0])); + 0x78, static_cast<uint_least8_t>(data.writeBit ? 0x80 : 0x00)}; + error_code result = writeMemory(commandReg, command); if (!result) { uint_least8_t status; result = pollBusy(&status); @@ -298,54 +258,54 @@ return result; } -error_code DS2465::readBlock(uint_least8_t * recvBuf, size_t recvLen) { +error_code DS2465::readBlock(span<uint_least8_t> recvBuf) { // 1-Wire Receive Block (Case A) // S AD,0 [A] CommandReg [A] 1WRF [A] PR [A] P // [] indicates from slave // PR indicates byte containing parameter error_code result; - while ((recvLen > 0) && !result) { + span<uint_least8_t>::index_type recvIdx = 0; + while (recvIdx < recvBuf.size() && !result) { const uint_least8_t command[] = { - OwReceiveBlockCmd, - static_cast<uint_least8_t>(std::min(recvLen, maxBlockSize))}; - result = - writeMemory(CommandReg, command, sizeof(command) / sizeof(command[0])); + 0xE1, + static_cast<uint_least8_t>(std::min<span<uint_least8_t>::index_type>( + recvBuf.size() - recvIdx, maxBlockSize))}; + result = writeMemory(commandReg, command); if (!result) { result = pollBusy(); } if (!result) { - result = readMemory(Scratchpad, recvBuf, command[1]); + result = readMemory(scratchpad, recvBuf.subspan(recvIdx, command[1])); } - recvBuf += command[1]; - recvLen -= command[1]; + recvIdx += command[1]; } return result; } -error_code DS2465::writeBlock(const uint_least8_t * sendBuf, size_t sendLen) { +error_code DS2465::writeBlock(span<const uint_least8_t> sendBuf) { error_code result; - while ((sendLen > 0) && !result) { + span<const uint_least8_t>::index_type sendIdx = 0; + while (sendIdx < sendBuf.size() && !result) { const uint_least8_t command[] = { - OwTransmitBlockCmd, - static_cast<uint_least8_t>(std::min(sendLen, maxBlockSize))}; + owTransmitBlockCmd, static_cast<uint_least8_t>( + std::min<span<const uint_least8_t>::index_type>( + sendBuf.size() - sendIdx, maxBlockSize))}; // prefill scratchpad with required data - result = writeMemory(Scratchpad, sendBuf, command[1]); + result = writeMemory(scratchpad, sendBuf.subspan(sendIdx, command[1])); // 1-Wire Transmit Block (Case A) // S AD,0 [A] CommandReg [A] 1WTB [A] PR [A] P // [] indicates from slave // PR indicates byte containing parameter if (!result) { - result = writeMemory(CommandReg, command, - sizeof(command) / sizeof(command[0])); + result = writeMemory(commandReg, command); } if (!result) { result = pollBusy(); } - sendBuf += command[1]; - sendLen -= command[1]; + sendIdx += command[1]; } return result; } @@ -356,9 +316,8 @@ // [] indicates from slave // PR indicates byte containing parameter - const uint_least8_t command[] = {OwTransmitBlockCmd, 0xFF}; - error_code result = - writeMemory(CommandReg, command, sizeof(command) / sizeof(command[0])); + const uint_least8_t command[] = {owTransmitBlockCmd, 0xFF}; + error_code result = writeMemory(commandReg, command); if (!result) { result = pollBusy(); } @@ -381,21 +340,18 @@ return result; } - uint_least8_t buf = OwReadByteCmd; - result = writeMemory(CommandReg, &buf, 1); - - if (!result) { - result = pollBusy(); + const uint_least8_t command = 0x96; + result = writeMemory(commandReg, make_span(&command, 1)); + if (result) { + return result; } - if (!result) { - result = readMemory(ReadDataReg, &buf, 1); + result = pollBusy(); + if (result) { + return result; } - if (!result) { - recvByte = buf; - } - + result = readMemory(0x62, make_span(&recvByte, 1)); return result; } @@ -413,14 +369,13 @@ return result; } - const uint_least8_t command[] = {OwWriteByteCmd, sendByte}; - - result = - writeMemory(CommandReg, command, sizeof(command) / sizeof(command[0])); - if (!result) { - result = pollBusy(); + const uint_least8_t command[] = {0xA5, sendByte}; + result = writeMemory(commandReg, command); + if (result) { + return result; } + result = pollBusy(); return result; } @@ -439,25 +394,22 @@ } const uint_least8_t command[] = { - OwSingleBitCmd, static_cast<uint_least8_t>(sendRecvBit ? 0x80 : 0x00)}; - uint_least8_t status; - - result = - writeMemory(CommandReg, command, sizeof(command) / sizeof(command[0])); - - if (!result) { - result = pollBusy(&status); + 0x87, static_cast<uint_least8_t>(sendRecvBit ? 0x80 : 0x00)}; + result = writeMemory(commandReg, command); + if (result) { + return result; } + uint_least8_t status; + result = pollBusy(&status); if (!result) { sendRecvBit = ((status & Status_SBR) == Status_SBR); } - return result; } -error_code DS2465::writeMemory(uint_least8_t addr, const uint_least8_t * buf, - size_t bufLen) const { +error_code DS2465::writeMemory(uint_least8_t addr, + span<const uint_least8_t> buf) const { // Write SRAM (Case A) // S AD,0 [A] VSA [A] DD [A] P // \-----/ @@ -466,27 +418,27 @@ // VSA valid SRAM memory address // DD memory data to write - error_code result = i2cMaster->start(i2cAddress_); + error_code result = master->start(address_); if (result) { - i2cMaster->stop(); + master->stop(); return result; } - result = i2cMaster->writeByte(addr); + result = master->writeByte(addr); if (result) { - i2cMaster->stop(); + master->stop(); return result; } - result = i2cMaster->writeBlock(buf, bufLen); + result = master->writeBlock(buf); if (result) { - i2cMaster->stop(); + master->stop(); return result; } - result = i2cMaster->stop(); + result = master->stop(); return result; } -error_code DS2465::readMemory(uint_least8_t addr, uint_least8_t * buf, - size_t bufLen) const { +error_code DS2465::readMemory(uint_least8_t addr, + span<uint_least8_t> buf) const { // Read (Case A) // S AD,0 [A] MA [A] Sr AD,1 [A] [DD] A [DD] A\ P // \-----/ @@ -495,40 +447,42 @@ // MA memory address // DD memory data read - error_code result = i2cMaster->start(i2cAddress_); + error_code result = master->start(address_); if (result) { - i2cMaster->stop(); + master->stop(); return result; } - result = i2cMaster->writeByte(addr); + result = master->writeByte(addr); if (result) { - i2cMaster->stop(); + master->stop(); return result; } - result = readMemory(buf, bufLen); + result = readMemory(buf); return result; } -error_code DS2465::readMemory(uint_least8_t * buf, size_t bufLen) const { - error_code result = i2cMaster->start(i2cAddress_ | 1); +error_code DS2465::readMemory(span<uint_least8_t> buf) const { + error_code result = master->start(address_ | 1); if (result) { - i2cMaster->stop(); + master->stop(); return result; } - result = i2cMaster->readBlock(I2CMaster::Nack, buf, bufLen); + result = master->readBlock(I2CMaster::Nack, buf); if (result) { - i2cMaster->stop(); + master->stop(); return result; } - result = i2cMaster->stop(); + result = master->stop(); return result; } error_code DS2465::writeConfig(Config config) { - uint_least8_t configBuf = ((config.readByte() ^ 0xF) << 4) | config.readByte(); - error_code result = writeMemory(ConfigReg, &configBuf, 1); + const uint_least8_t configReg = 0x67; + uint_least8_t configBuf = + ((config.readByte() ^ 0xF) << 4) | config.readByte(); + error_code result = writeMemory(configReg, make_span(&configBuf, 1)); if (!result) { - result = readMemory(ConfigReg, &configBuf, 1); + result = readMemory(configReg, make_span(&configBuf, 1)); } if (!result) { if (configBuf != config.readByte()) @@ -549,29 +503,29 @@ switch (param) { case tRSTL_STD: case tRSTL_OD: - addr = tRSTL_Reg; + addr = 0x68; break; case tMSP_STD: case tMSP_OD: - addr = tMSP_Reg; + addr = 0x69; break; case tW0L_STD: case tW0L_OD: - addr = tW0L_Reg; + addr = 0x6A; break; case tREC0: - addr = tREC0_Reg; + addr = 0x6B; break; case RWPU: - addr = RWPU_Reg; + addr = 0x6C; break; case tW1L_OD: - addr = tW1L_Reg; + addr = 0x6D; break; } uint_least8_t data; - error_code result = readMemory(addr, &data, 1); + error_code result = readMemory(addr, make_span(&data, 1)); if (result) { return result; } @@ -584,7 +538,7 @@ } if (newData != data) { - result = writeMemory(addr, &newData, 1); + result = writeMemory(addr, make_span(&newData, 1)); } return result; } @@ -595,7 +549,7 @@ int pollCount = 0; uint_least8_t status; do { - error_code result = readMemory(&status, 1); + error_code result = readMemory(make_span(&status, 1)); if (result) { return result; } @@ -617,8 +571,8 @@ // Repeat until 1WB bit has changed to 0 // [] indicates from slave - uint_least8_t buf = OwResetCmd; - error_code result = writeMemory(CommandReg, &buf, 1); + uint_least8_t buf = 0xB4; + error_code result = writeMemory(commandReg, make_span(&buf, 1)); if (!result) { result = pollBusy(&buf); @@ -627,8 +581,7 @@ if (!result) { if ((buf & Status_SD) == Status_SD) { result = make_error_code(ShortDetectedError); - } - else if ((buf & Status_PPD) != Status_PPD) { + } else if ((buf & Status_PPD) != Status_PPD) { result = make_error_code(NoSlaveError); } } @@ -642,11 +595,11 @@ // [] indicates from slave // SS status byte to read to verify state - uint_least8_t buf = DeviceResetCmd; - error_code result = writeMemory(CommandReg, &buf, 1); + uint_least8_t buf = 0xF0; + error_code result = writeMemory(commandReg, make_span(&buf, 1)); if (!result) { - result = readMemory(&buf, 1); + result = readMemory(make_span(&buf, 1)); } if (!result) { @@ -662,42 +615,44 @@ return result; } -error_code DS2465::computeNextMasterSecret(const SlaveSecretData & data) { - error_code result = writeMemory(Scratchpad, data.data(), data.size()); +error_code +DS2465::computeNextMasterSecret(AuthenticationData::const_span data) { + error_code result = writeMemory(scratchpad, data); if (!result) { result = computeNextMasterSecret(false, 0, FullPage); } return result; } -error_code DS2465::computeNextMasterSecretWithSwap(const SlaveSecretData & data, - int pageNum, - PageRegion region) { - error_code result = writeMemory(Scratchpad, data.data(), data.size()); +error_code +DS2465::computeNextMasterSecretWithSwap(AuthenticationData::const_span data, + int pageNum, PageRegion region) { + error_code result = writeMemory(scratchpad, data); if (!result) { result = computeNextMasterSecret(true, pageNum, region); } return result; } -error_code DS2465::computeWriteMac(const WriteMacData & data) const { - error_code result = writeMemory(Scratchpad, data.data(), data.size()); +error_code DS2465::computeWriteMac(WriteMacData::const_span data) const { + error_code result = writeMemory(scratchpad, data); if (!result) { result = computeWriteMac(false, false, 0, 0); } return result; } -error_code DS2465::computeWriteMac(const WriteMacData & data, - Hash & mac) const { +error_code DS2465::computeWriteMac(WriteMacData::const_span data, + Hash::span mac) const { error_code result = computeWriteMac(data); if (!result) { - result = readMemory(mac.data(), mac.size()); + result = readMemory(mac); } return result; } -error_code DS2465::computeAndTransmitWriteMac(const WriteMacData & data) const { +error_code +DS2465::computeAndTransmitWriteMac(WriteMacData::const_span data) const { error_code result = computeWriteMac(data); if (!result) { result = writeMacBlock(); @@ -705,28 +660,28 @@ return result; } -error_code DS2465::computeWriteMacWithSwap(const WriteMacData & data, +error_code DS2465::computeWriteMacWithSwap(WriteMacData::const_span data, int pageNum, int segmentNum) const { - error_code result = writeMemory(Scratchpad, data.data(), data.size()); + error_code result = writeMemory(scratchpad, data); if (!result) { result = computeWriteMac(false, true, pageNum, segmentNum); } return result; } -error_code DS2465::computeWriteMacWithSwap(const WriteMacData & data, +error_code DS2465::computeWriteMacWithSwap(WriteMacData::const_span data, int pageNum, int segmentNum, - Hash & mac) const { + Hash::span mac) const { error_code result = computeWriteMacWithSwap(data, pageNum, segmentNum); if (!result) { - result = readMemory(mac.data(), mac.size()); + result = readMemory(mac); } return result; } -error_code DS2465::computeAndTransmitWriteMacWithSwap(const WriteMacData & data, - int pageNum, - int segmentNum) const { +error_code +DS2465::computeAndTransmitWriteMacWithSwap(WriteMacData::const_span data, + int pageNum, int segmentNum) const { error_code result = computeWriteMacWithSwap(data, pageNum, segmentNum); if (!result) { result = writeMacBlock(); @@ -734,40 +689,43 @@ return result; } -error_code DS2465::computeSlaveSecret(const SlaveSecretData & data) { - error_code result = writeMemory(Scratchpad, data.data(), data.size()); +error_code DS2465::computeSlaveSecret(AuthenticationData::const_span data) { + error_code result = writeMemory(scratchpad, data); if (!result) { result = computeSlaveSecret(false, 0, FullPage); } return result; } -error_code DS2465::computeSlaveSecretWithSwap(const SlaveSecretData & data, - int pageNum, PageRegion region) { - error_code result = writeMemory(Scratchpad, data.data(), data.size()); +error_code +DS2465::computeSlaveSecretWithSwap(AuthenticationData::const_span data, + int pageNum, PageRegion region) { + error_code result = writeMemory(scratchpad, data); if (!result) { result = computeSlaveSecret(true, pageNum, region); } return result; } -error_code DS2465::computeAuthMac(const AuthMacData & data) const { - error_code result = writeMemory(Scratchpad, data.data(), data.size()); +error_code DS2465::computeAuthMac(AuthenticationData::const_span data) const { + error_code result = writeMemory(scratchpad, data); if (!result) { result = computeAuthMac(false, 0, FullPage); } return result; } -error_code DS2465::computeAuthMac(const AuthMacData & data, Hash & mac) const { +error_code DS2465::computeAuthMac(AuthenticationData::const_span data, + Hash::span mac) const { error_code result = computeAuthMac(data); if (!result) { - result = readMemory(mac.data(), mac.size()); + result = readMemory(mac); } return result; } -error_code DS2465::computeAndTransmitAuthMac(const AuthMacData & data) const { +error_code +DS2465::computeAndTransmitAuthMac(AuthenticationData::const_span data) const { error_code result = computeAuthMac(data); if (!result) { result = writeMacBlock(); @@ -775,27 +733,28 @@ return result; } -error_code DS2465::computeAuthMacWithSwap(const AuthMacData & data, int pageNum, +error_code DS2465::computeAuthMacWithSwap(AuthenticationData::const_span data, + int pageNum, PageRegion region) const { - error_code result = writeMemory(Scratchpad, data.data(), data.size()); + error_code result = writeMemory(scratchpad, data); if (!result) { result = computeAuthMac(true, pageNum, region); } return result; } -error_code DS2465::computeAuthMacWithSwap(const AuthMacData & data, int pageNum, - PageRegion region, Hash & mac) const { +error_code DS2465::computeAuthMacWithSwap(AuthenticationData::const_span data, + int pageNum, PageRegion region, + Hash::span mac) const { error_code result = computeAuthMacWithSwap(data, pageNum, region); if (!result) { - result = readMemory(mac.data(), mac.size()); + result = readMemory(mac); } return result; } -error_code DS2465::computeAndTransmitAuthMacWithSwap(const AuthMacData & data, - int pageNum, - PageRegion region) const { +error_code DS2465::computeAndTransmitAuthMacWithSwap( + AuthenticationData::const_span data, int pageNum, PageRegion region) const { error_code result = computeAuthMacWithSwap(data, pageNum, region); if (!result) { result = writeMacBlock();