Extended MaximInterface
Dependents: mbed_DS28EC20_GPIO
Revision 0:f77ad7f72d04, committed 2017-11-06
- Comitter:
- IanBenzMaxim
- Date:
- Mon Nov 06 14:39:18 2017 -0600
- Child:
- 1:d6de0a14c777
- Commit message:
- Initial commit.
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Devices/DS18B20.cpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,256 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#include <MaximInterface/Links/OneWireMaster.hpp> +#include <MaximInterface/Utilities/Error.hpp> +#include "DS18B20.hpp" + +namespace MaximInterface { + +enum DS18B20_CMDS { + WRITE_SCRATCHPAD = 0x4E, + READ_SCRATCHPAD = 0xBE, + COPY_SCRATCHPAD = 0x48, + CONV_TEMPERATURE = 0x44, + READ_POWER_SUPPY = 0xB4, + RECALL = 0xB8 +}; + +error_code DS18B20::initialize() { + Scratchpad scratchpad; + return readScratchpad(scratchpad); +} + +error_code DS18B20::writeScratchpad(uint_least8_t th, uint_least8_t tl, + uint_least8_t res) { + error_code result = selectRom(*master); + if (!result) { + const uint_least8_t sendBlock[] = {WRITE_SCRATCHPAD, th, tl, res}; + result = + master->writeBlock(sendBlock, sizeof(sendBlock) / sizeof(sendBlock[0])); + if (!result) { + resolution = res; + } + } + return result; +} + +error_code DS18B20::readScratchpad(Scratchpad & scratchpad) { + error_code result = selectRom(*master); + if (result) { + return result; + } + result = + master->writeByteSetLevel(READ_SCRATCHPAD, OneWireMaster::NormalLevel); + if (result) { + return result; + } + result = master->readBlock(scratchpad.data(), scratchpad.size()); + if (result) { + return result; + } + uint_least8_t receivedCrc; + result = master->readByte(receivedCrc); + if (result) { + return result; + } + if (receivedCrc == calculateCrc8(scratchpad.data(), scratchpad.size())) { + resolution = scratchpad[4]; + } else { + result = make_error_code(CrcError); + } + return result; +} + +error_code DS18B20::readPowerSupply(bool & localPower) { + error_code result = selectRom(*master); + if (result) { + return result; + } + result = + master->writeByteSetLevel(READ_POWER_SUPPY, OneWireMaster::NormalLevel); + if (result) { + return result; + } + result = master->touchBitSetLevel(localPower, OneWireMaster::NormalLevel); + return result; +} + +error_code DS18B20::copyScratchpad() { + bool hasLocalPower; + error_code result = readPowerSupply(hasLocalPower); + if (result) { + return result; + } + result = selectRom(*master); + if (result) { + return result; + } + if (hasLocalPower) { + result = + master->writeByteSetLevel(COPY_SCRATCHPAD, OneWireMaster::NormalLevel); + bool recvbit = 0; + while (!recvbit && !result) { + result = master->touchBitSetLevel(recvbit, OneWireMaster::NormalLevel); + } + } else { + result = + master->writeByteSetLevel(COPY_SCRATCHPAD, OneWireMaster::StrongLevel); + if (!result) { + (*sleep)(10); + result = master->setLevel(OneWireMaster::NormalLevel); + } + } + return result; +} + +error_code DS18B20::convertTemperature() { + bool hasLocalPower; + error_code result = readPowerSupply(hasLocalPower); + if (result) { + return result; + } + result = selectRom(*master); + if (result) { + return result; + } + if (hasLocalPower) { + result = + master->writeByteSetLevel(CONV_TEMPERATURE, OneWireMaster::NormalLevel); + bool recvbit = 0; + while (!result && !recvbit) { + result = master->touchBitSetLevel(recvbit, OneWireMaster::NormalLevel); + } + } else { + result = + master->writeByteSetLevel(CONV_TEMPERATURE, OneWireMaster::StrongLevel); + if (!result) { + int sleepTime; + switch (resolution) { + case nineBitResolution: + sleepTime = 94; + break; + + case tenBitResolution: + sleepTime = 188; + break; + + case elevenBitResolution: + sleepTime = 375; + break; + + case twelveBitResolution: + default: + sleepTime = 750; + break; + } + (*sleep)(sleepTime); + result = master->setLevel(OneWireMaster::NormalLevel); + } + } + return result; +} + +error_code DS18B20::recallEeprom() { + error_code result = selectRom(*master); + if (!result) { + result = master->writeByte(RECALL); + } + return result; +} + +const error_category & DS18B20::errorCategory() { + static class : public error_category { + public: + virtual const char * name() const { return "DS18B20"; } + + virtual std::string message(int condition) const { + switch (condition) { + case CrcError: + return "CRC Error"; + + case DataError: + return "Data Error"; + + default: + return defaultErrorMessage(condition); + } + } + } instance; + return instance; +} + +error_code readTemperature(DS18B20 & ds18b20, int & temperature) { + error_code result = ds18b20.convertTemperature(); + if (result) { + return result; + } + DS18B20::Scratchpad scratchpad; + result = ds18b20.readScratchpad(scratchpad); + if (result) { + return result; + } + + unsigned int tempData = + (static_cast<unsigned int>(scratchpad[1]) << 8) | scratchpad[0]; + const unsigned int signMask = 0xF800; + if ((tempData & signMask) == signMask) { + temperature = -0x800; + } else if ((tempData & signMask) == 0) { + temperature = 0; + } else { + return make_error_code(DS18B20::DataError); + } + unsigned int precisionMask; + switch (scratchpad[4]) { + case DS18B20::nineBitResolution: + default: + precisionMask = 0x7; + break; + + case DS18B20::tenBitResolution: + precisionMask = 0x3; + break; + + case DS18B20::elevenBitResolution: + precisionMask = 0x1; + break; + + case DS18B20::twelveBitResolution: + precisionMask = 0x0; + break; + } + temperature += static_cast<int>(tempData & ~(signMask | precisionMask)); + return error_code(); +} + +} // namespace MaximInterface
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Devices/DS18B20.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,136 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_DS18B20 +#define MaximInterface_DS18B20 + +#include <MaximInterface/Links/SelectRom.hpp> +#include <MaximInterface/Links/Sleep.hpp> +#include <MaximInterface/Utilities/Export.h> + +namespace MaximInterface { + +/// DS18B20 Programmable Resolution 1-Wire Digital Thermometer +/// @details The DS18B20 digital thermometer provides 9-bit to 12-bit +/// Celsius temperature measurements and has an alarm function with +/// nonvolatile user-programmable upper and lower trigger points. The +/// DS18B20 communicates over a 1-Wire bus that by definition requires +/// only one data line (and ground) for communication with a central +/// microprocessor. In addition, the DS18B20 can derive power directly +/// from the data line ("parasite power"), eliminating the need for an +/// external power supply. +class DS18B20 { +public: + enum ErrorValue { CrcError = 1, DataError }; + + static const uint_least8_t nineBitResolution = 0x1F; + static const uint_least8_t tenBitResolution = 0x3F; + static const uint_least8_t elevenBitResolution = 0x5F; + static const uint_least8_t twelveBitResolution = 0x7F; + + /// Holds the contents of the device scratchpad. + typedef array<uint_least8_t, 8> Scratchpad; + + DS18B20(const Sleep & sleep, OneWireMaster & master, + const SelectRom & selectRom) + : selectRom(selectRom), master(&master), sleep(&sleep), resolution(0) {} + + void setSleep(const Sleep & sleep) { this->sleep = &sleep; } + void setMaster(OneWireMaster & master) { this->master = &master; } + void setSelectRom(const SelectRom & selectRom) { + this->selectRom = selectRom; + } + + /// Initializes the device for first time use. + MaximInterface_EXPORT error_code initialize(); + + /// Write Scratchpad Command + /// @details If the result of a temperature measurement is higher + /// than TH or lower than TL, an alarm flag inside the device is + /// set. This flag is updated with every temperature measurement. + /// As long as the alarm flag is set, the DS1920 will respond to + /// the alarm search command. + /// @param[in] th 8-bit upper temperature threshold, MSB indicates sign. + /// @param[in] tl 8-bit lower temperature threshold, LSB indicates sign. + /// @param[in] res Resolution of the DS18B20. + MaximInterface_EXPORT error_code writeScratchpad(uint_least8_t th, + uint_least8_t tl, + uint_least8_t res); + + /// Read Scratchpad Command + /// @param[out] scratchpad Contents of scratchpad. + MaximInterface_EXPORT error_code readScratchpad(Scratchpad & scratchpad); + + /// Copy Scratchpad Command + /// @details This command copies from the scratchpad into the + /// EEPROM of the DS18B20, storing the temperature trigger bytes + /// and resolution in nonvolatile memory. + MaximInterface_EXPORT error_code copyScratchpad(); + + /// Read Power Supply command + /// @details This command determines if the DS18B20 is parasite + /// powered or has a local supply + /// @param[out] localPower + /// True if the device is powered by a local power supply, or false if the + /// device is parasitically powered. + MaximInterface_EXPORT error_code readPowerSupply(bool & localPower); + + /// Convert Temperature Command + /// @details This command begins a temperature conversion. + MaximInterface_EXPORT error_code convertTemperature(); + + /// Recall Command + /// @details This command recalls the temperature trigger values + /// and resolution stored in EEPROM to the scratchpad. + MaximInterface_EXPORT error_code recallEeprom(); + + MaximInterface_EXPORT static const error_category & errorCategory(); + +private: + SelectRom selectRom; + OneWireMaster * master; + const Sleep * sleep; + uint_least8_t resolution; +}; + +/// Reads the current temperature as an integer value with decimal. +/// @param[out] temperature Temperature in degrees Celsius multiplied by 2. +MaximInterface_EXPORT error_code readTemperature(DS18B20 & ds18b20, + int & temperature); + +inline error_code make_error_code(DS18B20::ErrorValue e) { + return error_code(e, DS18B20::errorCategory()); +} + +} // namespace MaximInterface + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Devices/DS1920.cpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,157 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#include <MaximInterface/Links/OneWireMaster.hpp> +#include <MaximInterface/Utilities/Error.hpp> +#include "DS1920.hpp" + +namespace MaximInterface { + +enum DS1920_CMDS { + WRITE_SCRATCHPAD = 0x4E, + READ_SCRATCHPAD = 0xBE, + COPY_SCRATCHPAD = 0x48, + CONV_TEMPERATURE = 0x44, + RECALL = 0xB8 +}; + +error_code DS1920::writeScratchpad(uint_least8_t th, uint_least8_t tl) { + error_code result = selectRom(*master); + if (!result) { + const uint_least8_t sendBlock[] = {WRITE_SCRATCHPAD, th, tl}; + result = + master->writeBlock(sendBlock, sizeof(sendBlock) / sizeof(sendBlock[0])); + } + return result; +} + +error_code DS1920::readScratchpad(Scratchpad & scratchpad) { + error_code result = selectRom(*master); + if (!result) { + result = master->writeByte(READ_SCRATCHPAD); + if (!result) { + result = master->readBlock(scratchpad.data(), scratchpad.size()); + if (!result) { + uint_least8_t receivedCrc; + result = master->readByte(receivedCrc); + if (!result && (receivedCrc != + calculateCrc8(scratchpad.data(), scratchpad.size()))) { + result = make_error_code(CrcError); + } + } + } + } + return result; +} + +error_code DS1920::copyScratchpad() { + error_code result = selectRom(*master); + if (!result) { + result = + master->writeByteSetLevel(COPY_SCRATCHPAD, OneWireMaster::StrongLevel); + if (!result) { + (*sleep)(10); + result = master->setLevel(OneWireMaster::NormalLevel); + } + } + return result; +} + +error_code DS1920::convertTemperature() { + error_code result = selectRom(*master); + if (!result) { + result = + master->writeByteSetLevel(CONV_TEMPERATURE, OneWireMaster::StrongLevel); + if (!result) { + (*sleep)(750); + result = master->setLevel(OneWireMaster::NormalLevel); + } + } + return result; +} + +error_code DS1920::recallEeprom() { + error_code result = selectRom(*master); + if (!result) { + result = master->writeByte(RECALL); + } + return result; +} + +const error_category & DS1920::errorCategory() { + static class : public error_category { + public: + virtual const char * name() const { return "DS1920"; } + + virtual std::string message(int condition) const { + switch (condition) { + case CrcError: + return "CRC Error"; + + case DataError: + return "Data Error"; + + default: + return defaultErrorMessage(condition); + } + } + } instance; + return instance; +} + +error_code readTemperature(DS1920 & ds1920, int & temperature) { + error_code result = ds1920.convertTemperature(); + if (result) { + return result; + } + DS1920::Scratchpad scratchpad; + result = ds1920.readScratchpad(scratchpad); + if (result) { + return result; + } + + unsigned int tempData = + (static_cast<unsigned int>(scratchpad[1]) << 8) | scratchpad[0]; + const unsigned int signMask = 0xFF00; + if ((tempData & signMask) == signMask) { + temperature = -0x100; + tempData &= ~signMask; + } else if ((tempData & signMask) == 0) { + temperature = 0; + } else { + return make_error_code(DS1920::DataError); + } + temperature += static_cast<int>(tempData); + return error_code(); +} + +} // namespace MaximInterface
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Devices/DS1920.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,118 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_DS1920 +#define MaximInterface_DS1920 + +#include <MaximInterface/Links/SelectRom.hpp> +#include <MaximInterface/Links/Sleep.hpp> +#include <MaximInterface/Utilities/Export.h> + +namespace MaximInterface { + +/// DS1920 1-Wire Temperature iButton +/// @details The iButton® temperature logger (DS1920) provides +/// direct-to-digital 9-bit temperature readings over a range of +/// -55°C to +100°C in 0.5° increments. The iButton communicates with +/// a processor using the 1-Wire® protocol through a hardware port +/// interface. The port interface provides both the physical link and +/// handles the communication protocols that enable the processor to +/// access iButton resources with simple commands. Two bytes of +/// EEPROM can be used either to set alarm triggers or for storing +/// user data. +class DS1920 { +public: + enum ErrorValue { CrcError = 1, DataError }; + + /// Holds the contents of the device scratchpad. + typedef array<uint_least8_t, 8> Scratchpad; + + DS1920(const Sleep & sleep, OneWireMaster & master, + const SelectRom & selectRom) + : selectRom(selectRom), master(&master), sleep(&sleep) {} + + void setSleep(const Sleep & sleep) { this->sleep = &sleep; } + void setMaster(OneWireMaster & master) { this->master = &master; } + void setSelectRom(const SelectRom & selectRom) { + this->selectRom = selectRom; + } + + /// Write Scratchpad Command + /// @details If the result of a temperature measurement is higher + /// than TH or lower than TL, an alarm flag inside the device is + /// set. This flag is updated with every temperature measurement. + /// As long as the alarm flag is set, the DS1920 will respond to + /// the alarm search command. + /// @param[in] th 8-bit upper temperature threshold, MSB indicates sign. + /// @param[in] tl 8-bit lower temperature threshold, MSB indicates sign. + MaximInterface_EXPORT error_code writeScratchpad(uint_least8_t th, + uint_least8_t tl); + + /// Read Scratchpad Command + /// @param[out] scratchpad Contents of scratchpad. + MaximInterface_EXPORT error_code readScratchpad(Scratchpad & scratchpad); + + /// Copy Scratchpad Command + /// @details This command copies from the scratchpad into the + /// EEPROM of the DS1920, storing the temperature trigger bytes + /// in nonvolatile memory. + MaximInterface_EXPORT error_code copyScratchpad(); + + /// Convert Temperature Command + /// @details This command begins a temperature conversion. + MaximInterface_EXPORT error_code convertTemperature(); + + /// Recall Command + /// @details This command recalls the temperature trigger values + /// stored in EEPROM to the scratchpad. + MaximInterface_EXPORT error_code recallEeprom(); + + MaximInterface_EXPORT static const error_category & errorCategory(); + +private: + SelectRom selectRom; + OneWireMaster * master; + const Sleep * sleep; +}; + +/// Reads the current temperature as an integer value. +/// @param[out] temperature Temperature in degrees Celsius multiplied by 16. +MaximInterface_EXPORT error_code readTemperature(DS1920 & ds1920, + int & temperature); + +inline error_code make_error_code(DS1920::ErrorValue e) { + return error_code(e, DS1920::errorCategory()); +} + +} // namespace MaximInterface + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Devices/DS2413.cpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,127 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#include <MaximInterface/Links/OneWireMaster.hpp> +#include <MaximInterface/Utilities/Error.hpp> +#include "DS2413.hpp" + +namespace MaximInterface { + +error_code DS2413::readStatus(Status & status) const { + uint_least8_t val; + const error_code result = pioAccessRead(val); + if (!result) { + status.pioAInputState = (val & 0x1) == 0x1; + status.pioAOutputState = (val & 0x2) == 0x2; + status.pioBInputState = (val & 0x4) == 0x4; + status.pioBOutputState = (val & 0x8) == 0x8; + } + return result; +} + +error_code DS2413::writeOutputState(bool pioAState, bool pioBState) { + uint_least8_t val = 0xFC; + if (pioAState) { + val |= 0x1; + } + if (pioBState) { + val |= 0x2; + } + return pioAccessWrite(val); +} + +error_code DS2413::pioAccessRead(uint_least8_t & val) const { + error_code result = selectRom(*master); + if (!result) { + result = master->writeByte(0xF5); + if (!result) { + result = master->readByte(val); + if (!result && (val != ((val ^ 0xF0) >> 4))) { + result = make_error_code(CommunicationError); + } + } + } + return result; +} + +error_code DS2413::pioAccessWrite(uint_least8_t val) { + error_code result = selectRom(*master); + if (!result) { + uint_least8_t block[] = {0x5A, val, static_cast<uint_least8_t>(val ^ 0xFF)}; + result = master->writeBlock(block, sizeof(block) / sizeof(block[0])); + if (!result) { + result = master->readByte(block[0]); + if (!result && block[0] != 0xAA) { + result = make_error_code(CommunicationError); + } + } + } + return result; +} + +const error_category & DS2413::errorCategory() { + static class : public error_category { + public: + virtual const char * name() const { return "DS2413"; } + + virtual std::string message(int condition) const { + switch (condition) { + case CommunicationError: + return "Communication Error"; + + default: + return defaultErrorMessage(condition); + } + } + } instance; + return instance; +} + +error_code writePioAOutputState(DS2413 & ds2413, bool pioAState) { + DS2413::Status status; + error_code result = ds2413.readStatus(status); + if (!result && pioAState != status.pioAOutputState) { + result = ds2413.writeOutputState(pioAState, status.pioBOutputState); + } + return result; +} + +error_code writePioBOutputState(DS2413 & ds2413, bool pioBState) { + DS2413::Status status; + error_code result = ds2413.readStatus(status); + if (!result && pioBState != status.pioBOutputState) { + result = ds2413.writeOutputState(status.pioAOutputState, pioBState); + } + return result; +} + +} // namespace MaximInterface
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Devices/DS2413.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,102 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_DS2413 +#define MaximInterface_DS2413 + +#include <stdint.h> +#include <MaximInterface/Links/SelectRom.hpp> +#include <MaximInterface/Utilities/Export.h> + +namespace MaximInterface { + +/// DS2413 1-Wire Dual Channel Addressable Switch +/// @details The DS2413 is a dual-channel programmable I/O 1-Wire® +/// chip. The PIO outputs are configured as open-drain and provide up +/// to 20mA continuous sink capability and off-state operating voltage +/// up to 28V. Control and sensing of the PIO pins is performed with +/// a dedicated device-level command protocol. To provide a high level +/// of fault tolerance in the end application, the 1-Wire I/O and PIO +/// pins are all capable of withstanding continuous application of +/// voltages up to 28V max. Communication and operation of the DS2413 +/// is performed with the single contact Maxim 1-Wire serial interface. +class DS2413 { +public: + enum ErrorValue { CommunicationError = 1 }; + + struct Status { + bool pioAInputState; + bool pioAOutputState; + bool pioBInputState; + bool pioBOutputState; + }; + + DS2413(OneWireMaster & master, const SelectRom & selectRom) + : selectRom(selectRom), master(&master) {} + + void setMaster(OneWireMaster & master) { this->master = &master; } + void setSelectRom(const SelectRom & selectRom) { + this->selectRom = selectRom; + } + + /// Read the input and output logic states for all PIO pins. + MaximInterface_EXPORT error_code readStatus(Status & status) const; + + /// Write the output logic states for all PIO pins. + MaximInterface_EXPORT error_code writeOutputState(bool pioAState, + bool pioBState); + + MaximInterface_EXPORT static const error_category & errorCategory(); + +private: + error_code pioAccessRead(uint_least8_t & val) const; + error_code pioAccessWrite(uint_least8_t val); + + SelectRom selectRom; + OneWireMaster * master; +}; + +/// @{ +/// Write the output logic state for only a single PIO pin. +MaximInterface_EXPORT error_code writePioAOutputState(DS2413 & ds2413, + bool pioAState); +MaximInterface_EXPORT error_code writePioBOutputState(DS2413 & ds2413, + bool pioBState); +/// @} + +inline error_code make_error_code(DS2413::ErrorValue e) { + return error_code(e, DS2413::errorCategory()); +} + +} // namespace MaximInterface + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Devices/DS2431.cpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,187 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#include <algorithm> +#include <MaximInterface/Links/OneWireMaster.hpp> +#include <MaximInterface/Utilities/Error.hpp> +#include "DS2431.hpp" + +namespace MaximInterface { + +enum Command { + WriteScratchpad = 0x0F, + ReadScratchpad = 0xAA, + CopyScratchpad = 0x55, + ReadMemory = 0xF0 +}; + +error_code writeMemory(DS2431 & device, DS2431::Address targetAddress, + const DS2431::Scratchpad & data) { + error_code result = device.writeScratchpad(targetAddress, data); + if (result) { + return result; + } + DS2431::Scratchpad readData; + uint_least8_t esByte; + result = device.readScratchpad(readData, esByte); + if (result) { + return result; + } + result = device.copyScratchpad(targetAddress, esByte); + return result; +} + +error_code DS2431::readMemory(Address beginAddress, uint_least8_t * data, + size_t dataLen) const { + error_code owmResult = selectRom(*master); + if (owmResult) { + return owmResult; + } + const uint_least8_t sendBlock[] = {ReadMemory, beginAddress, 0x00}; + owmResult = + master->writeBlock(sendBlock, sizeof(sendBlock) / sizeof(sendBlock[0])); + if (owmResult) { + return owmResult; + } + owmResult = master->readBlock(data, dataLen); + return owmResult; +} + +error_code DS2431::writeScratchpad(Address targetAddress, + const Scratchpad & data) { + error_code owmResult = selectRom(*master); + if (owmResult) { + return owmResult; + } + array<uint_least8_t, 3 + Scratchpad::csize> block = {WriteScratchpad, + targetAddress, 0x00}; + std::copy(data.begin(), data.end(), block.begin() + 3); + owmResult = master->writeBlock(block.data(), block.size()); + if (owmResult) { + return owmResult; + } + const uint_fast16_t calculatedCrc = + calculateCrc16(block.data(), block.size()) ^ 0xFFFFU; + owmResult = master->readBlock(block.data(), 2); + if (owmResult) { + return owmResult; + } + if (calculatedCrc != + ((static_cast<uint_fast16_t>(block[1]) << 8) | block[0])) { + owmResult = make_error_code(CrcError); + } + return owmResult; +} + +error_code DS2431::readScratchpad(Scratchpad & data, uint_least8_t & esByte) { + typedef array<uint_least8_t, 6 + Scratchpad::csize> Block; + + error_code owmResult = selectRom(*master); + if (owmResult) { + return owmResult; + } + Block block = {ReadScratchpad}; + owmResult = master->writeByte(block.front()); + if (owmResult) { + return owmResult; + } + owmResult = master->readBlock(block.data() + 1, block.size() - 1); + if (owmResult) { + return owmResult; + } + Block::const_iterator blockIt = block.end(); + uint_fast16_t receivedCrc = static_cast<uint_fast16_t>(*(--blockIt)) << 8; + receivedCrc |= *(--blockIt); + const uint_fast16_t expectedCrc = + calculateCrc16(block.data(), block.size() - 2) ^ 0xFFFFU; + if (expectedCrc == receivedCrc) { + Block::const_iterator blockItEnd = blockIt; + blockIt -= data.size(); + std::copy(blockIt, blockItEnd, data.begin()); + esByte = *(--blockIt); + } else { + owmResult = make_error_code(CrcError); + } + return owmResult; +} + +error_code DS2431::copyScratchpad(Address targetAddress, uint_least8_t esByte) { + error_code owmResult = selectRom(*master); + if (owmResult) { + return owmResult; + } + uint_least8_t block[] = {CopyScratchpad, targetAddress, 0x00}; + owmResult = master->writeBlock(block, sizeof(block) / sizeof(block[0])); + if (owmResult) { + return owmResult; + } + owmResult = master->writeByteSetLevel(esByte, OneWireMaster::StrongLevel); + if (owmResult) { + return owmResult; + } + (*sleep)(10); + owmResult = master->setLevel(OneWireMaster::NormalLevel); + if (owmResult) { + return owmResult; + } + owmResult = master->readByte(block[0]); + if (owmResult) { + return owmResult; + } + if (block[0] != 0xAA) { + owmResult = make_error_code(OperationFailure); + } + return owmResult; +} + +const error_category & DS2431::errorCategory() { + static class : public error_category { + public: + virtual const char * name() const { return "DS2431"; } + + virtual std::string message(int condition) const { + switch (condition) { + case CrcError: + return "CRC Error"; + + case OperationFailure: + return "Operation Failure"; + + default: + return defaultErrorMessage(condition); + } + } + } instance; + return instance; +} + +} // namespace MaximInterface
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Devices/DS2431.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,121 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_DS2431 +#define MaximInterface_DS2431 + +#include <MaximInterface/Links/SelectRom.hpp> +#include <MaximInterface/Links/Sleep.hpp> +#include <MaximInterface/Utilities/Export.h> + +namespace MaximInterface { + +/// DS2431 1024-bit 1-Wire EEPROM +/// @details The DS2431 is a 1024-bit, 1-Wire® EEPROM chip organized +/// as four memory pages of 256 bits each. Data is written to an 8-byte +/// scratchpad, verified, and then copied to the EEPROM memory. As a +/// special feature, the four memory pages can individually be write +/// protected or put in EPROM-emulation mode, where bits can only be +/// changed from a 1 to a 0 state. The DS2431 communicates over the +/// single-conductor 1-Wire bus. The communication follows the standard +/// 1-Wire protocol. Each device has its own unalterable and unique +/// 64-bit ROM registration number that is factory lasered into the chip. +/// The registration number is used to address the device in a multidrop, +/// 1-Wire net environment. +class DS2431 { +public: + enum ErrorValue { CrcError = 1, OperationFailure }; + + typedef array<uint_least8_t, 8> Scratchpad; + typedef uint_least8_t Address; + + DS2431(const Sleep & sleep, OneWireMaster & master, + const SelectRom & selectRom) + : selectRom(selectRom), master(&master), sleep(&sleep) {} + + void setSleep(const Sleep & sleep) { this->sleep = &sleep; } + void setMaster(OneWireMaster & master) { this->master = &master; } + void setSelectRom(const SelectRom & selectRom) { + this->selectRom = selectRom; + } + + /// Reads block of data from EEPROM memory. + /// @param[in] beginAddress EEPROM memory address to start reading from. + /// @param[out] data EEPROM data read from the device. + /// @param[in] dataLen Length of data parameter and number of bytes to read. + MaximInterface_EXPORT error_code readMemory(Address beginAddress, + uint_least8_t * data, + size_t dataLen) const; + + /// Writes 8 bytes to the scratchpad. + /// @param[in] targetAddress EEPROM memory address that this data. + /// will be copied to. Must be on row boundary. + /// @param[in] data Data to write to scratchpad. + MaximInterface_EXPORT error_code writeScratchpad(Address targetAddress, + const Scratchpad & data); + + /// Reads contents of scratchpad. + /// @param[out] data Data read from scratchpad. + /// @param[out] esByte E/S byte read before scratchpad data. + MaximInterface_EXPORT error_code readScratchpad(Scratchpad & data, + uint_least8_t & esByte); + + /// Copies contents of scratchpad to EEPROM. + /// @param[in] targetAddress EEPROM memory address that scratchpad + /// will be copied to. Must be on row boundary. + /// @param[in] esByte E/S byte from preceding Read Scratchpad command. + MaximInterface_EXPORT error_code copyScratchpad(Address targetAddress, + uint_least8_t esByte); + + MaximInterface_EXPORT static const error_category & errorCategory(); + +private: + SelectRom selectRom; + OneWireMaster * master; + const Sleep * sleep; +}; + +/// Writes data to EEPROM using Write Scratchpad, Read Scratchpad, +/// and Copy Scratchpad commands. +/// @param[in] targetAddress EEPROM memory address to start writing at. +/// @param[in] data Data to write to EEPROM. +MaximInterface_EXPORT error_code writeMemory(DS2431 & device, + DS2431::Address targetAddress, + const DS2431::Scratchpad & data); + +inline error_code make_error_code(DS2431::ErrorValue e) { + return error_code(e, DS2431::errorCategory()); +} + +} // namespace MaximInterface + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Devices/DS2465.cpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,827 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#include <MaximInterface/Utilities/Error.hpp> +#include "DS2465.hpp" + +namespace MaximInterface { + +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. +static const int eepromPageWriteDelayMs = 8 * eepromSegmentWriteDelayMs; +/// 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 +}; + +/// DS2465 Status Bits +enum StatusBit { + Status_1WB = 0x01, + Status_PPD = 0x02, + Status_SD = 0x04, + Status_LL = 0x08, + Status_RST = 0x10, + Status_SBR = 0x20, + Status_TSB = 0x40, + Status_DIR = 0x80 +}; + +static const size_t maxBlockSize = 63; + +error_code DS2465::initialize(Config config) { + // reset DS2465 + error_code result = resetDevice(); + if (!result) { + // write the default configuration setup + result = writeConfig(config); + } + return result; +} + +error_code DS2465::computeNextMasterSecret(bool swap, int pageNum, + 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])); + } + return result; +} + +error_code DS2465::computeWriteMac(bool regwrite, bool swap, int pageNum, + 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])); + if (!result) { + (*sleep)(shaComputationDelayMs); + } + } + return result; +} + +error_code DS2465::computeAuthMac(bool swap, int pageNum, + 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])); + if (!result) { + (*sleep)(shaComputationDelayMs * 2); + } + } + return result; +} + +error_code DS2465::computeSlaveSecret(bool swap, int pageNum, + 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])); + if (!result) { + (*sleep)(shaComputationDelayMs * 2); + } + } + return result; +} + +error_code DS2465::readPage(int pageNum, Page & data) const { + uint_least8_t addr; + switch (pageNum) { + case 0: + addr = UserMemoryPage0; + break; + case 1: + addr = UserMemoryPage1; + break; + default: + return make_error_code(ArgumentOutOfRangeError); + } + return readMemory(addr, data.data(), data.size()); +} + +error_code DS2465::writePage(int pageNum, const Page & data) { + error_code result = writeMemory(Scratchpad, data.data(), data.size()); + if (!result) { + result = copyScratchpad(false, pageNum, false, 0); + } + if (!result) { + (*sleep)(eepromPageWriteDelayMs); + } + return result; +} + +error_code DS2465::writeSegment(int pageNum, int segmentNum, + const Segment & data) { + error_code result = writeMemory(Scratchpad, data.data(), data.size()); + if (!result) { + result = copyScratchpad(false, pageNum, true, segmentNum); + } + if (!result) { + (*sleep)(eepromSegmentWriteDelayMs); + } + return result; +} + +error_code DS2465::writeMasterSecret(const Hash & masterSecret) { + error_code result = + writeMemory(Scratchpad, masterSecret.data(), masterSecret.size()); + if (!result) { + result = copyScratchpad(true, 0, false, 0); + } + if (!result) { + (*sleep)(eepromPageWriteDelayMs); + } + return result; +} + +error_code DS2465::copyScratchpad(bool destSecret, int pageNum, bool notFull, + int segmentNum) { + error_code result = make_error_code(ArgumentOutOfRangeError); + if (pageNum >= 0 && segmentNum >= 0) { + uint_least8_t command[] = { + CopyScratchpadCmd, + static_cast<uint_least8_t>(destSecret ? 0 + : (0x80 | (pageNum << 4) | + (notFull << 3) | segmentNum))}; + result = + writeMemory(CommandReg, command, sizeof(command) / sizeof(command[0])); + } + return result; +} + +error_code DS2465::configureLevel(Level level) { + // Check if supported level + if (!((level == NormalLevel) || (level == StrongLevel))) { + return make_error_code(InvalidLevelError); + } + // Check if requested level already set + if (curConfig.getSPU() == (level == StrongLevel)) { + return error_code(); + } + // Set the level + Config newConfig = curConfig; + newConfig.setSPU(level == StrongLevel); + return writeConfig(newConfig); +} + +error_code DS2465::setLevel(Level newLevel) { + if (newLevel == StrongLevel) { + return make_error_code(InvalidLevelError); + } + + return configureLevel(newLevel); +} + +error_code DS2465::setSpeed(Speed newSpeed) { + // Check if supported speed + if (!((newSpeed == OverdriveSpeed) || (newSpeed == StandardSpeed))) { + return make_error_code(InvalidSpeedError); + } + // Check if requested speed is already set + if (curConfig.get1WS() == (newSpeed == OverdriveSpeed)) { + return error_code(); + } + // Set the speed + Config newConfig = curConfig; + newConfig.set1WS(newSpeed == OverdriveSpeed); + return writeConfig(newConfig); +} + +error_code DS2465::triplet(TripletData & data) { + // 1-Wire Triplet (Case B) + // S AD,0 [A] 1WT [A] SS [A] Sr AD,1 [A] [Status] A [Status] A\ P + // \--------/ + // Repeat until 1WB bit has changed to 0 + // [] indicates from slave + // 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])); + if (!result) { + uint_least8_t status; + result = pollBusy(&status); + if (!result) { + // check bit results in status byte + data.readBit = ((status & Status_SBR) == Status_SBR); + data.readBitComplement = ((status & Status_TSB) == Status_TSB); + data.writeBit = ((status & Status_DIR) == Status_DIR); + } + } + return result; +} + +error_code DS2465::readBlock(uint_least8_t * recvBuf, size_t recvLen) { + // 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) { + const uint_least8_t command[] = { + OwReceiveBlockCmd, + static_cast<uint_least8_t>(std::min(recvLen, maxBlockSize))}; + result = + writeMemory(CommandReg, command, sizeof(command) / sizeof(command[0])); + if (!result) { + result = pollBusy(); + } + if (!result) { + result = readMemory(Scratchpad, recvBuf, command[1]); + } + recvBuf += command[1]; + recvLen -= command[1]; + } + return result; +} + +error_code DS2465::writeBlock(const uint_least8_t * sendBuf, size_t sendLen) { + error_code result; + while ((sendLen > 0) && !result) { + const uint_least8_t command[] = { + OwTransmitBlockCmd, + static_cast<uint_least8_t>(std::min(sendLen, maxBlockSize))}; + + // prefill scratchpad with required data + result = writeMemory(Scratchpad, sendBuf, 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])); + } + if (!result) { + result = pollBusy(); + } + sendBuf += command[1]; + sendLen -= command[1]; + } + return result; +} + +error_code DS2465::writeMacBlock() const { + // 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 + + const uint_least8_t command[] = {OwTransmitBlockCmd, 0xFF}; + error_code result = + writeMemory(CommandReg, command, sizeof(command) / sizeof(command[0])); + if (!result) { + result = pollBusy(); + } + return result; +} + +error_code DS2465::readByteSetLevel(uint_least8_t & recvByte, + Level afterLevel) { + // 1-Wire Read Bytes (Case C) + // S AD,0 [A] CommandReg [A] 1WRB [A] Sr AD,1 [A] [Status] A [Status] A + // \--------/ + // Repeat until 1WB bit has changed to 0 + // Sr AD,0 [A] SRP [A] E1 [A] Sr AD,1 [A] DD A\ P + // + // [] indicates from slave + // DD data read + + error_code result = configureLevel(afterLevel); + if (result) { + return result; + } + + uint_least8_t buf = OwReadByteCmd; + result = writeMemory(CommandReg, &buf, 1); + + if (!result) { + result = pollBusy(); + } + + if (!result) { + result = readMemory(ReadDataReg, &buf, 1); + } + + if (!result) { + recvByte = buf; + } + + return result; +} + +error_code DS2465::writeByteSetLevel(uint_least8_t sendByte, Level afterLevel) { + // 1-Wire Write Byte (Case B) + // S AD,0 [A] CommandReg [A] 1WWB [A] DD [A] Sr AD,1 [A] [Status] A [Status] + // A\ P + // \--------/ + // Repeat until 1WB bit has changed to 0 + // [] indicates from slave + // DD data to write + + error_code result = configureLevel(afterLevel); + if (result) { + return result; + } + + const uint_least8_t command[] = {OwWriteByteCmd, sendByte}; + + result = + writeMemory(CommandReg, command, sizeof(command) / sizeof(command[0])); + if (!result) { + result = pollBusy(); + } + + return result; +} + +error_code DS2465::touchBitSetLevel(bool & sendRecvBit, Level afterLevel) { + // 1-Wire bit (Case B) + // S AD,0 [A] CommandReg [A] 1WSB [A] BB [A] Sr AD,1 [A] [Status] A [Status] + // A\ P + // \--------/ + // Repeat until 1WB bit has changed to 0 + // [] indicates from slave + // BB indicates byte containing bit value in msbit + + error_code result = configureLevel(afterLevel); + if (result) { + return result; + } + + 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); + } + + 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 { + // Write SRAM (Case A) + // S AD,0 [A] VSA [A] DD [A] P + // \-----/ + // Repeat for each data byte + // [] indicates from slave + // VSA valid SRAM memory address + // DD memory data to write + + error_code result = i2cMaster->start(i2cAddress_); + if (result) { + i2cMaster->stop(); + return result; + } + result = i2cMaster->writeByte(addr); + if (result) { + i2cMaster->stop(); + return result; + } + result = i2cMaster->writeBlock(buf, bufLen); + if (result) { + i2cMaster->stop(); + return result; + } + result = i2cMaster->stop(); + return result; +} + +error_code DS2465::readMemory(uint_least8_t addr, uint_least8_t * buf, + size_t bufLen) const { + // Read (Case A) + // S AD,0 [A] MA [A] Sr AD,1 [A] [DD] A [DD] A\ P + // \-----/ + // Repeat for each data byte, NAK last byte + // [] indicates from slave + // MA memory address + // DD memory data read + + error_code result = i2cMaster->start(i2cAddress_); + if (result) { + i2cMaster->stop(); + return result; + } + result = i2cMaster->writeByte(addr); + if (result) { + i2cMaster->stop(); + return result; + } + result = readMemory(buf, bufLen); + return result; +} + +error_code DS2465::readMemory(uint_least8_t * buf, size_t bufLen) const { + error_code result = i2cMaster->start(i2cAddress_ | 1); + if (result) { + i2cMaster->stop(); + return result; + } + result = i2cMaster->readBlock(I2CMaster::Nack, buf, bufLen); + if (result) { + i2cMaster->stop(); + return result; + } + result = i2cMaster->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); + if (!result) { + result = readMemory(ConfigReg, &configBuf, 1); + } + if (!result) { + if (configBuf != config.readByte()) + result = make_error_code(HardwareError); + } + if (!result) { + curConfig = config; + } + return result; +} + +error_code DS2465::writePortParameter(PortParameter param, int val) { + if (val < 0 || val > 15) { + return make_error_code(ArgumentOutOfRangeError); + } + + uint_least8_t addr = 0; + switch (param) { + case tRSTL_STD: + case tRSTL_OD: + addr = tRSTL_Reg; + break; + case tMSP_STD: + case tMSP_OD: + addr = tMSP_Reg; + break; + case tW0L_STD: + case tW0L_OD: + addr = tW0L_Reg; + break; + case tREC0: + addr = tREC0_Reg; + break; + case RWPU: + addr = RWPU_Reg; + break; + case tW1L_OD: + addr = tW1L_Reg; + break; + } + + uint_least8_t data; + error_code result = readMemory(addr, &data, 1); + if (result) { + return result; + } + + uint_least8_t newData; + if (param == tRSTL_OD || param == tMSP_OD || param == tW0L_OD) { + newData = (data & 0x0F) | (val << 4); + } else { + newData = (data & 0xF0) | val; + } + + if (newData != data) { + result = writeMemory(addr, &newData, 1); + } + return result; +} + +error_code DS2465::pollBusy(uint_least8_t * pStatus) const { + const int pollLimit = 200; + + int pollCount = 0; + uint_least8_t status; + do { + error_code result = readMemory(&status, 1); + if (result) { + return result; + } + if (pStatus != NULL) { + *pStatus = status; + } + if (pollCount++ >= pollLimit) { + return make_error_code(HardwareError); + } + } while (status & Status_1WB); + + return error_code(); +} + +error_code DS2465::reset() { + // 1-Wire reset (Case B) + // S AD,0 [A] CommandReg [A] 1WRS [A] Sr AD,1 [A] [Status] A [Status] A\ P + // \--------/ + // Repeat until 1WB bit has changed to 0 + // [] indicates from slave + + uint_least8_t buf = OwResetCmd; + error_code result = writeMemory(CommandReg, &buf, 1); + + if (!result) { + result = pollBusy(&buf); + } + + if (!result) { + if ((buf & Status_SD) == Status_SD) { + result = make_error_code(ShortDetectedError); + } + else if ((buf & Status_PPD) != Status_PPD) { + result = make_error_code(NoSlaveError); + } + } + + return result; +} + +error_code DS2465::resetDevice() { + // Device Reset + // S AD,0 [A] CommandReg [A] 1WMR [A] Sr AD,1 [A] [SS] A\ P + // [] indicates from slave + // SS status byte to read to verify state + + uint_least8_t buf = DeviceResetCmd; + error_code result = writeMemory(CommandReg, &buf, 1); + + if (!result) { + result = readMemory(&buf, 1); + } + + if (!result) { + if ((buf & 0xF7) != 0x10) { + result = make_error_code(HardwareError); + } + } + + if (!result) { + reset(); // do a command to get 1-Wire master reset out of holding state + } + + return result; +} + +error_code DS2465::computeNextMasterSecret(const SlaveSecretData & data) { + error_code result = writeMemory(Scratchpad, data.data(), data.size()); + 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()); + 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()); + if (!result) { + result = computeWriteMac(false, false, 0, 0); + } + return result; +} + +error_code DS2465::computeWriteMac(const WriteMacData & data, + Hash & mac) const { + error_code result = computeWriteMac(data); + if (!result) { + result = readMemory(mac.data(), mac.size()); + } + return result; +} + +error_code DS2465::computeAndTransmitWriteMac(const WriteMacData & data) const { + error_code result = computeWriteMac(data); + if (!result) { + result = writeMacBlock(); + } + return result; +} + +error_code DS2465::computeWriteMacWithSwap(const WriteMacData & data, + int pageNum, int segmentNum) const { + error_code result = writeMemory(Scratchpad, data.data(), data.size()); + if (!result) { + result = computeWriteMac(false, true, pageNum, segmentNum); + } + return result; +} + +error_code DS2465::computeWriteMacWithSwap(const WriteMacData & data, + int pageNum, int segmentNum, + Hash & mac) const { + error_code result = computeWriteMacWithSwap(data, pageNum, segmentNum); + if (!result) { + result = readMemory(mac.data(), mac.size()); + } + return result; +} + +error_code DS2465::computeAndTransmitWriteMacWithSwap(const WriteMacData & data, + int pageNum, + int segmentNum) const { + error_code result = computeWriteMacWithSwap(data, pageNum, segmentNum); + if (!result) { + result = writeMacBlock(); + } + return result; +} + +error_code DS2465::computeSlaveSecret(const SlaveSecretData & data) { + error_code result = writeMemory(Scratchpad, data.data(), data.size()); + 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()); + 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()); + if (!result) { + result = computeAuthMac(false, 0, FullPage); + } + return result; +} + +error_code DS2465::computeAuthMac(const AuthMacData & data, Hash & mac) const { + error_code result = computeAuthMac(data); + if (!result) { + result = readMemory(mac.data(), mac.size()); + } + return result; +} + +error_code DS2465::computeAndTransmitAuthMac(const AuthMacData & data) const { + error_code result = computeAuthMac(data); + if (!result) { + result = writeMacBlock(); + } + return result; +} + +error_code DS2465::computeAuthMacWithSwap(const AuthMacData & data, int pageNum, + PageRegion region) const { + error_code result = writeMemory(Scratchpad, data.data(), data.size()); + 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 result = computeAuthMacWithSwap(data, pageNum, region); + if (!result) { + result = readMemory(mac.data(), mac.size()); + } + return result; +} + +error_code DS2465::computeAndTransmitAuthMacWithSwap(const AuthMacData & data, + int pageNum, + PageRegion region) const { + error_code result = computeAuthMacWithSwap(data, pageNum, region); + if (!result) { + result = writeMacBlock(); + } + return result; +} + +const error_category & DS2465::errorCategory() { + static class : public error_category { + public: + virtual const char * name() const { return "DS2465"; } + + virtual std::string message(int condition) const { + switch (condition) { + case HardwareError: + return "Hardware Error"; + + case ArgumentOutOfRangeError: + return "Argument Out of Range Error"; + + default: + return defaultErrorMessage(condition); + } + } + } instance; + return instance; +} + +} // namespace MaximInterface
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Devices/DS2465.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,358 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_DS2465 +#define MaximInterface_DS2465 + +#include <MaximInterface/Links/I2CMaster.hpp> +#include <MaximInterface/Links/OneWireMaster.hpp> +#include <MaximInterface/Links/Sleep.hpp> +#include <MaximInterface/Utilities/Export.h> +#include <MaximInterface/Utilities/Sha256.hpp> + +namespace MaximInterface { + +/// Interface to the DS2465 1-Wire master and SHA-256 coprocessor. +class DS2465 : public OneWireMaster { +public: + enum ErrorValue { HardwareError = 1, ArgumentOutOfRangeError }; + + /// 1-Wire port adjustment parameters. + /// @note See datasheet page 13. + enum PortParameter { + tRSTL_STD, + tRSTL_OD, + tMSP_STD, + tMSP_OD, + tW0L_STD, + tW0L_OD, + tREC0, + RWPU, + tW1L_OD + }; + + /// Page region to use for swapping. + enum PageRegion { FullPage = 0x03, FirstHalf = 0x01, SecondHalf = 0x02 }; + + /// Holds the contents of a device memory segment. + typedef array<uint_least8_t, 4> Segment; + + /// Holds the contents of a device memory page. + typedef array<uint_least8_t, 32> Page; + + static const int memoryPages = 2; + static const int segmentsPerPage = Page::csize / Segment::csize; + + /// Represents a DS2465 configuration. + class Config { + public: + /// Default construct with power-on config. + explicit Config(uint_least8_t readByte = optionAPU) + : readByte_(readByte & 0xF) {} + + /// @{ + /// 1-Wire Speed + bool get1WS() const { return (readByte_ & option1WS) == option1WS; } + void set1WS(bool new1WS) { + if (new1WS) { + readByte_ |= option1WS; + } else { + readByte_ &= ~option1WS; + } + } + /// @} + + /// @{ + /// Strong Pullup + bool getSPU() const { return (readByte_ & optionSPU) == optionSPU; } + void setSPU(bool newSPU) { + if (newSPU) { + readByte_ |= optionSPU; + } else { + readByte_ &= ~optionSPU; + } + } + /// @} + + /// @{ + /// 1-Wire Power Down + bool getPDN() const { return (readByte_ & optionPDN) == optionPDN; } + void setPDN(bool newPDN) { + if (newPDN) { + readByte_ |= optionPDN; + } else { + readByte_ &= ~optionPDN; + } + } + /// @} + + /// @{ + /// Active Pullup + bool getAPU() const { return (readByte_ & optionAPU) == optionAPU; } + void setAPU(bool newAPU) { + if (newAPU) { + readByte_ |= optionAPU; + } else { + readByte_ &= ~optionAPU; + } + } + /// @} + + /// Byte representation that is read from the DS2465. + uint_least8_t readByte() const { return readByte_; } + + private: + static const unsigned int option1WS = 0x8; + static const unsigned int optionSPU = 0x4; + static const unsigned int optionPDN = 0x2; + static const unsigned int optionAPU = 0x1; + + uint_least8_t readByte_; + }; + + // Const member functions should not change the settings of the DS2465 or + // affect the state of the 1-Wire bus. Read pointer, scratchpad, MAC output + // register, and command register on the DS2465 are considered mutable. + + DS2465(const Sleep & sleep, I2CMaster & i2cMaster, + uint_least8_t i2cAddress = 0x30) + : sleep(&sleep), i2cMaster(&i2cMaster), i2cAddress_(i2cAddress & 0xFE) {} + + void setSleep(const Sleep & sleep) { this->sleep = &sleep; } + void setI2CMaster(I2CMaster & i2cMaster) { this->i2cMaster = &i2cMaster; } + uint_least8_t i2cAddress() const { return i2cAddress_; } + void setI2CAddress(uint_least8_t i2cAddress) { + this->i2cAddress_ = (i2cAddress & 0xFE); + } + + /// Initialize hardware for use. + MaximInterface_EXPORT error_code initialize(Config config = Config()); + + /// Write a new configuration to the DS2465. + /// @param[in] config New configuration to write. + MaximInterface_EXPORT error_code writeConfig(Config config); + + /// Write a new port configuration parameter to the DS2465. + /// @param[in] param Parameter to adjust. + /// @param[in] val New parameter value to set. Consult datasheet for value + /// mappings. + MaximInterface_EXPORT error_code writePortParameter(PortParameter param, + int val); + + // 1-Wire Master Commands + + MaximInterface_EXPORT virtual error_code reset(); + MaximInterface_EXPORT virtual error_code touchBitSetLevel(bool & sendRecvBit, + Level afterLevel); + MaximInterface_EXPORT virtual error_code + readByteSetLevel(uint_least8_t & recvByte, Level afterLevel); + MaximInterface_EXPORT virtual error_code + writeByteSetLevel(uint_least8_t sendByte, Level afterLevel); + MaximInterface_EXPORT virtual error_code readBlock(uint_least8_t * recvBuf, + size_t recvLen); + MaximInterface_EXPORT virtual error_code + writeBlock(const uint_least8_t * sendBuf, size_t sendLen); + MaximInterface_EXPORT virtual error_code setSpeed(Speed newSpeed); + /// @note The DS2465 only supports enabling strong pullup following a 1-Wire + /// read or write operation. + MaximInterface_EXPORT virtual error_code setLevel(Level newLevel); + MaximInterface_EXPORT virtual error_code triplet(TripletData & data); + + // DS2465 Coprocessor Commands + + /// Read data from an EEPROM memory page. + /// @param pageNum Page number to read from. + MaximInterface_EXPORT error_code readPage(int pageNum, Page & data) const; + + /// Write data to an EEPROM memory page. + /// @param pageNum Page number to copy to. + MaximInterface_EXPORT error_code writePage(int pageNum, const Page & data); + + /// Write data to an EEPROM memory segment. + /// @param pageNum Page number to copy to. + /// @param segmentNum Segment number to copy to. + MaximInterface_EXPORT error_code writeSegment(int pageNum, int segmentNum, + const Segment & data); + + /// Write data to the secret EEPROM memory page. + MaximInterface_EXPORT error_code + writeMasterSecret(const Sha256::Hash & masterSecret); + + /// Compute Next Master Secret. + /// @param data Combined data fields for computation. + MaximInterface_EXPORT error_code + computeNextMasterSecret(const Sha256::SlaveSecretData & data); + + /// Compute Next Master Secret with page swapping. + /// @param data Combined data fields for computation. + /// @param pageNum Page number to swap in. + /// @param region Region of the page to swap in. + MaximInterface_EXPORT error_code computeNextMasterSecretWithSwap( + const Sha256::SlaveSecretData & data, int pageNum, PageRegion region); + + /// Compute Write MAC. + /// @param data Combined data fields for computation. + /// @param[out] mac Computed Write MAC. + MaximInterface_EXPORT error_code + computeWriteMac(const Sha256::WriteMacData & data, Sha256::Hash & mac) const; + + /// Compute Write MAC. + /// @param data Combined data fields for computation. + MaximInterface_EXPORT error_code + computeAndTransmitWriteMac(const Sha256::WriteMacData & data) const; + + /// Compute Write MAC with page swapping. + /// @param data Combined data fields for computation. + /// @param pageNum Page number to swap in. + /// @param segmentNum Segment number to swap in. + /// @param[out] mac Computed Write MAC. + MaximInterface_EXPORT error_code + computeWriteMacWithSwap(const Sha256::WriteMacData & data, int pageNum, + int segmentNum, Sha256::Hash & mac) const; + + /// Compute Write MAC with page swapping. + /// @param data Combined data fields for computation. + /// @param pageNum Page number to swap in. + /// @param segmentNum Segment number to swap in. + MaximInterface_EXPORT error_code computeAndTransmitWriteMacWithSwap( + const Sha256::WriteMacData & data, int pageNum, int segmentNum) const; + + /// Compute Slave Secret (S-Secret). + /// @param data Combined data fields for computation. + MaximInterface_EXPORT error_code + computeSlaveSecret(const Sha256::SlaveSecretData & data); + + /// Compute Slave Secret (S-Secret) with page swapping. + /// @param data Combined data fields for computation. + /// @param pageNum Page number to swap in. + /// @param region Region of the page to swap in. + MaximInterface_EXPORT error_code computeSlaveSecretWithSwap( + const Sha256::SlaveSecretData & data, int pageNum, PageRegion region); + + /// Compute Authentication MAC. + /// @param data Combined data fields for computation. + /// @param[out] mac Computed Auth MAC. + MaximInterface_EXPORT error_code + computeAuthMac(const Sha256::AuthMacData & data, Sha256::Hash & mac) const; + + /// Compute Authentication MAC. + /// @param data Combined data fields for computation. + MaximInterface_EXPORT error_code + computeAndTransmitAuthMac(const Sha256::AuthMacData & data) const; + + /// Compute Authentication MAC with page swapping. + /// @param data Combined data fields for computation. + /// @param pageNum Page number to swap in. + /// @param region Region of the page to swap in. + /// @param[out] mac Computed Auth MAC. + MaximInterface_EXPORT error_code + computeAuthMacWithSwap(const Sha256::AuthMacData & data, int pageNum, + PageRegion region, Sha256::Hash & mac) const; + + /// Compute Authentication MAC with page swapping. + /// @param data Combined data fields for computation. + /// @param pageNum Page number to swap in. + /// @param region Region of the page to swap in. + MaximInterface_EXPORT error_code computeAndTransmitAuthMacWithSwap( + const Sha256::AuthMacData & data, int pageNum, PageRegion region) const; + + MaximInterface_EXPORT static const error_category & errorCategory(); + +private: + const Sleep * sleep; + I2CMaster * i2cMaster; + uint_least8_t i2cAddress_; + Config curConfig; + + /// Performs a soft reset on the DS2465. + /// @note This is not a 1-Wire Reset. + error_code resetDevice(); + + /// Polls the DS2465 status waiting for the 1-Wire Busy bit (1WB) to be cleared. + /// @param[out] pStatus Optionally retrive the status byte when 1WB cleared. + /// @returns Success or TimeoutError if poll limit reached. + error_code pollBusy(uint_least8_t * pStatus = NULL) const; + + /// Ensure that the desired 1-Wire level is set in the configuration. + /// @param level Desired 1-Wire level. + error_code configureLevel(Level level); + + /// Const since only for internal use. + error_code writeMemory(uint_least8_t addr, const uint_least8_t * buf, + size_t bufLen) const; + + /// Read memory from the DS2465. + /// @param addr Address to begin reading from. + /// @param[out] buf Buffer to hold read data. + /// @param bufLen Length of buffer, buf, and number of bytes to read. + error_code readMemory(uint_least8_t addr, uint_least8_t * buf, + size_t bufLen) const; + + /// Read memory from the DS2465 at the current pointer. + /// @param[out] buf Buffer to hold read data. + /// @param bufLen Length of buffer, buf, and number of bytes to read. + error_code readMemory(uint_least8_t * buf, size_t bufLen) const; + + /// Write the last computed MAC to the 1-Wire bus. + error_code writeMacBlock() const; + + error_code computeWriteMac(const Sha256::WriteMacData & data) const; + + error_code computeWriteMacWithSwap(const Sha256::WriteMacData & data, + int pageNum, int segmentNum) const; + + error_code computeAuthMac(const Sha256::AuthMacData & data) const; + + error_code computeAuthMacWithSwap(const Sha256::AuthMacData & data, + int pageNum, PageRegion region) const; + + // Legacy implementations + error_code copyScratchpad(bool destSecret, int pageNum, bool notFull, + int segmentNum); + + error_code computeNextMasterSecret(bool swap, int pageNum, PageRegion region); + + error_code computeWriteMac(bool regwrite, bool swap, int pageNum, + int segmentNum) const; + + error_code computeSlaveSecret(bool swap, int pageNum, PageRegion region); + + error_code computeAuthMac(bool swap, int pageNum, PageRegion region) const; +}; + +inline error_code make_error_code(DS2465::ErrorValue e) { + return error_code(e, DS2465::errorCategory()); +} + +} // namespace MaximInterface + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Devices/DS2480B.cpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,687 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#include <MaximInterface/Utilities/Error.hpp> +#include "DS2480B.hpp" + +// Mode Commands +#define MODE_DATA 0xE1 +#define MODE_COMMAND 0xE3 +#define MODE_STOP_PULSE 0xF1 + +// Return byte value +#define RB_CHIPID_MASK 0x1C +#define RB_RESET_MASK 0x03 +#define RB_1WIRESHORT 0x00 +#define RB_PRESENCE 0x01 +#define RB_ALARMPRESENCE 0x02 +#define RB_NOPRESENCE 0x03 + +#define RB_BIT_MASK 0x03 +#define RB_BIT_ONE 0x03 +#define RB_BIT_ZERO 0x00 + +// Masks for all bit ranges +#define CMD_MASK 0x80 +#define FUNCTSEL_MASK 0x60 +#define BITPOL_MASK 0x10 +#define SPEEDSEL_MASK 0x0C +#define MODSEL_MASK 0x02 +#define PARMSEL_MASK 0x70 +#define PARMSET_MASK 0x0E + +// Command or config bit +#define CMD_COMM 0x81 +#define CMD_CONFIG 0x01 + +// Function select bits +#define FUNCTSEL_BIT 0x00 +#define FUNCTSEL_SEARCHON 0x30 +#define FUNCTSEL_SEARCHOFF 0x20 +#define FUNCTSEL_RESET 0x40 +#define FUNCTSEL_CHMOD 0x60 + +// Bit polarity/Pulse voltage bits +#define BITPOL_ONE 0x10 +#define BITPOL_ZERO 0x00 +#define BITPOL_5V 0x00 +#define BITPOL_12V 0x10 + +// One Wire speed bits +#define SPEEDSEL_STD 0x00 +#define SPEEDSEL_FLEX 0x04 +#define SPEEDSEL_OD 0x08 +#define SPEEDSEL_PULSE 0x0C + +// Data/Command mode select bits +#define MODSEL_DATA 0x00 +#define MODSEL_COMMAND 0x02 + +// 5V Follow Pulse select bits +#define PRIME5V_TRUE 0x02 +#define PRIME5V_FALSE 0x00 + +// Parameter select bits +#define PARMSEL_PARMREAD 0x00 +#define PARMSEL_SLEW 0x10 +#define PARMSEL_12VPULSE 0x20 +#define PARMSEL_5VPULSE 0x30 +#define PARMSEL_WRITE1LOW 0x40 +#define PARMSEL_SAMPLEOFFSET 0x50 +#define PARMSEL_ACTIVEPULLUPTIME 0x60 +#define PARMSEL_BAUDRATE 0x70 + +// Pull down slew rate. +#define PARMSET_Slew15Vus 0x00 +#define PARMSET_Slew2p2Vus 0x02 +#define PARMSET_Slew1p65Vus 0x04 +#define PARMSET_Slew1p37Vus 0x06 +#define PARMSET_Slew1p1Vus 0x08 +#define PARMSET_Slew0p83Vus 0x0A +#define PARMSET_Slew0p7Vus 0x0C +#define PARMSET_Slew0p55Vus 0x0E + +// 12V programming pulse time table +#define PARMSET_32us 0x00 +#define PARMSET_64us 0x02 +#define PARMSET_128us 0x04 +#define PARMSET_256us 0x06 +#define PARMSET_512us 0x08 +#define PARMSET_1024us 0x0A +#define PARMSET_2048us 0x0C +#define PARMSET_infinite 0x0E + +// 5V strong pull up pulse time table +#define PARMSET_16p4ms 0x00 +#define PARMSET_65p5ms 0x02 +#define PARMSET_131ms 0x04 +#define PARMSET_262ms 0x06 +#define PARMSET_524ms 0x08 +#define PARMSET_1p05s 0x0A +#define PARMSET_dynamic 0x0C +#define PARMSET_infinite 0x0E + +// Write 1 low time +#define PARMSET_Write8us 0x00 +#define PARMSET_Write9us 0x02 +#define PARMSET_Write10us 0x04 +#define PARMSET_Write11us 0x06 +#define PARMSET_Write12us 0x08 +#define PARMSET_Write13us 0x0A +#define PARMSET_Write14us 0x0C +#define PARMSET_Write15us 0x0E + +// Data sample offset and Write 0 recovery time +#define PARMSET_SampOff3us 0x00 +#define PARMSET_SampOff4us 0x02 +#define PARMSET_SampOff5us 0x04 +#define PARMSET_SampOff6us 0x06 +#define PARMSET_SampOff7us 0x08 +#define PARMSET_SampOff8us 0x0A +#define PARMSET_SampOff9us 0x0C +#define PARMSET_SampOff10us 0x0E + +// Active pull up on time +#define PARMSET_PullUp0p0us 0x00 +#define PARMSET_PullUp0p5us 0x02 +#define PARMSET_PullUp1p0us 0x04 +#define PARMSET_PullUp1p5us 0x06 +#define PARMSET_PullUp2p0us 0x08 +#define PARMSET_PullUp2p5us 0x0A +#define PARMSET_PullUp3p0us 0x0C +#define PARMSET_PullUp3p5us 0x0E + +// DS2480B program voltage available +#define DS2480BPROG_MASK 0x20 + +namespace MaximInterface { + +error_code DS2480B::initialize() { + // reset modes + level = NormalLevel; + baud = Baud9600bps; + mode = MODSEL_COMMAND; + speed = SPEEDSEL_FLEX; + + // set the baud rate to 9600 + error_code result = setComBaud(baud); + if (result) { + return result; + } + + // send a break to reset the DS2480B + result = breakCom(); + if (result) { + return result; + } + + // delay to let line settle + (*sleep)(2); + + // flush the buffers + result = uart->clearReadBuffer(); + if (result) { + return result; + } + + // send the timing byte + uint_least8_t packet[5]; + packet[0] = 0xC1; + result = uart->writeBlock(packet, 1); + if (result) { + return result; + } + + // delay to let line settle + (*sleep)(2); + + // set the FLEX configuration parameters + // default PDSRC = 1.37Vus + int packetLen = 0; + packet[packetLen++] = CMD_CONFIG | PARMSEL_SLEW | PARMSET_Slew1p37Vus; + // default W1LT = 10us + packet[packetLen++] = CMD_CONFIG | PARMSEL_WRITE1LOW | PARMSET_Write10us; + // default DSO/WORT = 8us + packet[packetLen++] = CMD_CONFIG | PARMSEL_SAMPLEOFFSET | PARMSET_SampOff8us; + + // construct the command to read the baud rate (to test command block) + packet[packetLen++] = CMD_CONFIG | PARMSEL_PARMREAD | (PARMSEL_BAUDRATE >> 3); + + // also do 1 bit operation (to test 1-Wire block) + packet[packetLen++] = CMD_COMM | FUNCTSEL_BIT | baud | BITPOL_ONE; + + // flush the buffers + result = uart->clearReadBuffer(); + if (result) { + return result; + } + + // send the packet + result = uart->writeBlock(packet, packetLen); + if (result) { + return result; + } + + // read back the response + result = uart->readBlock(packet, sizeof(packet) / sizeof(packet[0])); + if (result) { + return result; + } + + // look at the baud rate and bit operation + // to see if the response makes sense + if (!(((packet[3] & 0xF1) == 0x00) && ((packet[3] & 0x0E) == baud) && + ((packet[4] & 0xF0) == 0x90) && ((packet[4] & 0x0C) == baud))) { + result = make_error_code(HardwareError); + } + + return result; +} + +error_code DS2480B::reset() { + uint_least8_t packet[2]; + int packetLen = 0; + + // check for correct mode + if (mode != MODSEL_COMMAND) { + mode = MODSEL_COMMAND; + packet[packetLen++] = MODE_COMMAND; + } + + // construct the command + packet[packetLen++] = (CMD_COMM | FUNCTSEL_RESET | speed); + + // flush the buffers + error_code result = uart->clearReadBuffer(); + if (result) { + return result; + } + + // send the packet + result = uart->writeBlock(packet, packetLen); + if (result) { + return result; + } + + // read back the 1 byte response + result = uart->readBlock(packet, 1); + if (result) { + return result; + } + + // make sure this byte looks like a reset byte + if ((packet[0] & RB_RESET_MASK) == RB_1WIRESHORT) { + result = make_error_code(ShortDetectedError); + } + else if ((packet[0] & RB_RESET_MASK) == RB_NOPRESENCE) { + result = make_error_code(NoSlaveError); + } + + return result; +} + +error_code DS2480B::touchBitSetLevel(bool & sendRecvBit, Level afterLevel) { + uint_least8_t packet[2]; + int packetLen = 0; + + // check for correct mode + if (mode != MODSEL_COMMAND) { + mode = MODSEL_COMMAND; + packet[packetLen++] = MODE_COMMAND; + } + + // construct the command + packet[packetLen++] = (sendRecvBit ? BITPOL_ONE : BITPOL_ZERO) | CMD_COMM | + FUNCTSEL_BIT | speed; + + // flush the buffers + error_code result = uart->clearReadBuffer(); + if (result) { + return result; + } + + // send the packet + result = uart->writeBlock(packet, packetLen); + if (result) { + return result; + } + + // read back the response + result = uart->readBlock(packet, 1); + if (result) { + return result; + } + + // interpret the response + if ((packet[0] & 0xE0) == 0x80) { + sendRecvBit = ((packet[0] & RB_BIT_MASK) == RB_BIT_ONE); + result = setLevel(afterLevel); + } else { + result = make_error_code(HardwareError); + } + + return result; +} + +error_code DS2480B::writeByteSetLevel(uint_least8_t sendByte, + Level afterLevel) { + uint_least8_t packet[3]; + int packetLen = 0; + + // check for correct mode + if (mode != MODSEL_DATA) { + mode = MODSEL_DATA; + packet[packetLen++] = MODE_DATA; + } + + // add the byte to send + packet[packetLen++] = sendByte; + + // check for duplication of data that looks like COMMAND mode + if (sendByte == MODE_COMMAND) { + packet[packetLen++] = sendByte; + } + + // flush the buffers + error_code result = uart->clearReadBuffer(); + if (result) { + return result; + } + + // send the packet + result = uart->writeBlock(packet, packetLen); + if (result) { + return result; + } + + // read back the 1 byte response + result = uart->readBlock(packet, 1); + if (result) { + return result; + } + + if (packet[0] == sendByte) { + result = setLevel(afterLevel); + } else { + result = make_error_code(HardwareError); + } + + return result; +} + +error_code DS2480B::readByteSetLevel(uint_least8_t & recvByte, + Level afterLevel) { + uint_least8_t packet[2]; + int packetLen = 0; + + // check for correct mode + if (mode != MODSEL_DATA) { + mode = MODSEL_DATA; + packet[packetLen++] = MODE_DATA; + } + + // add the byte to send + packet[packetLen++] = 0xFF; + + // flush the buffers + error_code result = uart->clearReadBuffer(); + if (result) { + return result; + } + + // send the packet + result = uart->writeBlock(packet, packetLen); + if (result) { + return result; + } + + // read back the 1 byte response + result = uart->readBlock(packet, 1); + if (result) { + return result; + } + + recvByte = packet[0]; + result = setLevel(afterLevel); + + return result; +} + +error_code DS2480B::setSpeed(Speed newSpeed) { + error_code result; + bool setSpeed = false; + + // check if supported speed + switch (newSpeed) { + case OverdriveSpeed: + // check if change from current mode + if (speed != SPEEDSEL_OD) { + result = changeBaud(Baud115200bps); + if (!result) { + speed = SPEEDSEL_OD; + setSpeed = true; + } + } + break; + + case StandardSpeed: + // check if change from current mode + if (speed != SPEEDSEL_STD) { + result = changeBaud(Baud9600bps); + if (!result) { + speed = SPEEDSEL_STD; + setSpeed = true; + } + } + break; + + default: + result = make_error_code(InvalidSpeedError); + break; + } + + // if baud rate is set correctly then change DS2480 speed + if (setSpeed) { + uint_least8_t packet[2]; + int packetLen = 0; + + // check if correct mode + if (mode != MODSEL_COMMAND) { + mode = MODSEL_COMMAND; + packet[packetLen++] = MODE_COMMAND; + } + + // proceed to set the DS2480 communication speed + packet[packetLen++] = CMD_COMM | FUNCTSEL_SEARCHOFF | speed; + + // send the packet + result = uart->writeBlock(packet, packetLen); + } + + return result; +} + +error_code DS2480B::setLevel(Level newLevel) { + error_code result; + // check if need to change level + if (newLevel != level) { + uint_least8_t packet[4]; + int packetLen = 0; + + // check for correct mode + if (mode != MODSEL_COMMAND) { + mode = MODSEL_COMMAND; + packet[packetLen++] = MODE_COMMAND; + } + + switch (newLevel) { + case NormalLevel: + // stop pulse command + packet[packetLen++] = MODE_STOP_PULSE; + + // add the command to begin the pulse WITHOUT prime + packet[packetLen++] = CMD_COMM | FUNCTSEL_CHMOD | SPEEDSEL_PULSE | + BITPOL_5V | PRIME5V_FALSE; + + // stop pulse command + packet[packetLen++] = MODE_STOP_PULSE; + + // flush the buffers + result = uart->clearReadBuffer(); + if (result) { + return result; + } + + // send the packet + result = uart->writeBlock(packet, packetLen); + if (result) { + return result; + } + + // read back the 1 byte response + result = uart->readBlock(packet, 2); + if (result) { + return result; + } + + // check response byte + if (((packet[0] & 0xE0) == 0xE0) && ((packet[1] & 0xE0) == 0xE0)) { + level = NormalLevel; + } else { + result = make_error_code(HardwareError); + } + break; + + case StrongLevel: + // set the SPUD time value + packet[packetLen++] = CMD_CONFIG | PARMSEL_5VPULSE | PARMSET_infinite; + // add the command to begin the pulse + packet[packetLen++] = + CMD_COMM | FUNCTSEL_CHMOD | SPEEDSEL_PULSE | BITPOL_5V; + + // flush the buffers + result = uart->clearReadBuffer(); + if (result) { + return result; + } + + // send the packet + result = uart->writeBlock(packet, packetLen); + if (result) { + return result; + } + + // read back the 1 byte response from setting time limit + result = uart->readBlock(packet, 1); + if (result) { + return result; + } + + // check response byte + if ((packet[0] & 0x81) == 0) { + level = newLevel; + } else { + result = make_error_code(HardwareError); + } + break; + + default: + result = make_error_code(InvalidLevelError); + break; + } + } + return result; +} + +error_code DS2480B::changeBaud(BaudRate newBaud) { + error_code result; + + //see if different then current baud rate + if (baud != newBaud) { + uint_least8_t packet[2]; + int packetLen = 0; + + // build the command packet + // check for correct mode + if (mode != MODSEL_COMMAND) { + mode = MODSEL_COMMAND; + packet[packetLen++] = MODE_COMMAND; + } + // build the command + const uint_least8_t baudByte = CMD_CONFIG | PARMSEL_BAUDRATE | newBaud; + packet[packetLen++] = baudByte; + + // flush the buffers + result = uart->clearReadBuffer(); + if (result) { + return result; + } + + // send the packet + result = uart->writeBlock(packet, packetLen); + if (result) { + return result; + } + + // make sure buffer is flushed + (*sleep)(5); + + // change our baud rate + result = setComBaud(newBaud); + if (result) { + return result; + } + baud = newBaud; + + // wait for things to settle + (*sleep)(5); + + // build a command packet to read back baud rate + packet[0] = CMD_CONFIG | PARMSEL_PARMREAD | (PARMSEL_BAUDRATE >> 3); + + // flush the buffers + result = uart->clearReadBuffer(); + if (result) { + return result; + } + + // send the packet + result = uart->writeBlock(packet, 1); + if (result) { + return result; + } + + // read back the 1 byte response + result = uart->readBlock(packet, 1); + if (result) { + return result; + } + + // verify correct baud + if (!((packet[0] & 0x0E) == (baudByte & 0x0E))) { + result = make_error_code(HardwareError); + } + } + + return result; +} + +error_code DS2480B::setComBaud(BaudRate newBaud) { + switch (newBaud) { + case Baud115200bps: + return uart->setBaud(115200); + + case Baud57600bps: + return uart->setBaud(57600); + + case Baud19200bps: + return uart->setBaud(19200); + + case Baud9600bps: + default: + return uart->setBaud(9600); + } +} + +error_code DS2480B::breakCom() { + // Switch to lower baud rate to ensure break is longer than 2 ms. + error_code result = uart->setBaud(4800); + if (result) { + return result; + } + result = uart->sendBreak(); + if (result) { + return result; + } + result = setComBaud(baud); + return result; +} + +const error_category & DS2480B::errorCategory() { + static class : public error_category { + public: + virtual const char * name() const { return "DS2480B"; } + + virtual std::string message(int condition) const { + switch (condition) { + case HardwareError: + return "Hardware Error"; + + default: + return defaultErrorMessage(condition); + } + } + } instance; + return instance; +} + +} // namespace MaximInterface
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Devices/DS2480B.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,97 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_DS2480B +#define MaximInterface_DS2480B + +#include <MaximInterface/Links/OneWireMaster.hpp> +#include <MaximInterface/Links/Sleep.hpp> +#include <MaximInterface/Links/Uart.hpp> +#include <MaximInterface/Utilities/Export.h> + +namespace MaximInterface { + +/// Serial to 1-Wire Line Driver +class DS2480B : public OneWireMaster { +public: + enum ErrorValue { + HardwareError = 1, + }; + + DS2480B(const Sleep & sleep, Uart & uart) : sleep(&sleep), uart(&uart) {} + + void setSleep(const Sleep & sleep) { this->sleep = &sleep; } + void setUart(Uart & uart) { this->uart = &uart; } + + MaximInterface_EXPORT error_code initialize(); + + MaximInterface_EXPORT virtual error_code reset(); + MaximInterface_EXPORT virtual error_code touchBitSetLevel(bool & sendRecvBit, + Level afterLevel); + MaximInterface_EXPORT virtual error_code + writeByteSetLevel(uint_least8_t sendByte, Level afterLevel); + MaximInterface_EXPORT virtual error_code + readByteSetLevel(uint_least8_t & recvByte, Level afterLevel); + MaximInterface_EXPORT virtual error_code setSpeed(Speed newSpeed); + MaximInterface_EXPORT virtual error_code setLevel(Level newLevel); + + MaximInterface_EXPORT static const error_category & errorCategory(); + +private: + /// Baud rates for DS2480B + enum BaudRate { + Baud9600bps = 0, ///< 9600 bps + Baud19200bps = 2, ///< 19200 bps + Baud57600bps = 4, ///< 57600 bps + Baud115200bps = 6 ///< 115200 bps + }; + + error_code changeBaud(BaudRate newBaud); + error_code setComBaud(BaudRate newBaud); + error_code breakCom(); + + const Sleep * sleep; + Uart * uart; + + Level level; + BaudRate baud; + uint_least8_t mode; + uint_least8_t speed; +}; + +inline error_code make_error_code(DS2480B::ErrorValue e) { + return error_code(e, DS2480B::errorCategory()); +} + +} // namespace MaximInterface + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Devices/DS2482_DS2484.cpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,449 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#include <MaximInterface/Utilities/Error.hpp> +#include "DS2482_DS2484.hpp" + +namespace MaximInterface { + +enum Command { + DeviceResetCmd = 0xF0, + WriteDeviceConfigCmd = 0xD2, + AdjustOwPortCmd = 0xC3, // DS2484 only + ChannelSelectCmd = 0xC3, // DS2482-800 only + SetReadPointerCmd = 0xE1, + OwResetCmd = 0xB4, + OwWriteByteCmd = 0xA5, + OwReadByteCmd = 0x96, + OwSingleBitCmd = 0x87, + OwTripletCmd = 0x78 +}; + +// Device register pointers. +enum Register { + ConfigReg = 0xC3, + StatusReg = 0xF0, + ReadDataReg = 0xE1 +}; + +// Device Status bits +enum StatusBit { + Status_1WB = 0x01, + Status_PPD = 0x02, + Status_SD = 0x04, + Status_LL = 0x08, + Status_RST = 0x10, + Status_SBR = 0x20, + Status_TSB = 0x40, + Status_DIR = 0x80 +}; + +error_code DS2482_DS2484::initialize(Config config) { + // reset device + error_code result = resetDevice(); + if (result) { + return result; + } + + // write the default configuration setup + result = writeConfig(config); + return result; +} + +error_code DS2482_DS2484::resetDevice() { + // Device Reset + // S AD,0 [A] DRST [A] Sr AD,1 [A] [SS] A\ P + // [] indicates from slave + // SS status byte to read to verify state + + uint_least8_t buf; + error_code result = sendCommand(DeviceResetCmd); + + if (!result) { + result = readRegister(buf); + } + + if (!result) { + if ((buf & 0xF7) != 0x10) { + result = make_error_code(HardwareError); + } + } + + if (!result) { + reset(); // do a command to get 1-Wire master reset out of holding state + } + + return result; +} + +error_code DS2482_DS2484::triplet(TripletData & data) { + // 1-Wire Triplet (Case B) + // S AD,0 [A] 1WT [A] SS [A] Sr AD,1 [A] [Status] A [Status] A\ P + // \--------/ + // Repeat until 1WB bit has changed to 0 + // [] indicates from slave + // SS indicates byte containing search direction bit value in msbit + + error_code result = sendCommand(OwTripletCmd, data.writeBit ? 0x80 : 0x00); + if (!result) { + uint_least8_t status; + result = pollBusy(&status); + if (!result) { + // check bit results in status byte + data.readBit = ((status & Status_SBR) == Status_SBR); + data.readBitComplement = ((status & Status_TSB) == Status_TSB); + data.writeBit = ((status & Status_DIR) == Status_DIR); + } + } + return result; +} + +error_code DS2482_DS2484::reset() { + // 1-Wire reset (Case B) + // S AD,0 [A] 1WRS [A] Sr AD,1 [A] [Status] A [Status] A\ P + // \--------/ + // Repeat until 1WB bit has changed to 0 + // [] indicates from slave + + error_code result = sendCommand(OwResetCmd); + uint_least8_t buf; + + if (!result) { + result = pollBusy(&buf); + } + + if (!result) { + if ((buf & Status_SD) == Status_SD) { + result = make_error_code(ShortDetectedError); + } + else if ((buf & Status_PPD) != Status_PPD) { + result = make_error_code(NoSlaveError); + } + } + + return result; +} + +error_code DS2482_DS2484::touchBitSetLevel(bool & sendRecvBit, Level afterLevel) { + // 1-Wire bit (Case B) + // S AD,0 [A] 1WSB [A] BB [A] Sr AD,1 [A] [Status] A [Status] A\ P + // \--------/ + // Repeat until 1WB bit has changed to 0 + // [] indicates from slave + // BB indicates byte containing bit value in msbit + + error_code result = configureLevel(afterLevel); + + if (!result) { + result = sendCommand(OwSingleBitCmd, sendRecvBit ? 0x80 : 0x00); + } + + uint_least8_t status; + + if (!result) { + result = pollBusy(&status); + } + + if (!result) { + sendRecvBit = ((status & Status_SBR) == Status_SBR); + } + + return result; +} + +error_code DS2482_DS2484::writeByteSetLevel(uint_least8_t sendByte, Level afterLevel) { + // 1-Wire Write Byte (Case B) + // S AD,0 [A] 1WWB [A] DD [A] Sr AD,1 [A] [Status] A [Status] A\ P + // \--------/ + // Repeat until 1WB bit has changed to 0 + // [] indicates from slave + // DD data to write + + error_code result = configureLevel(afterLevel); + if (result) { + return result; + } + + result = sendCommand(OwWriteByteCmd, sendByte); + if (!result) { + result = pollBusy(); + } + + return result; +} + +error_code DS2482_DS2484::readByteSetLevel(uint_least8_t & recvByte, + Level afterLevel) { + // 1-Wire Read Bytes (Case C) + // S AD,0 [A] 1WRB [A] Sr AD,1 [A] [Status] A [Status] A + // \--------/ + // Repeat until 1WB bit has changed to 0 + // Sr AD,0 [A] SRP [A] E1 [A] Sr AD,1 [A] DD A\ P + // + // [] indicates from slave + // DD data read + + error_code result = configureLevel(afterLevel); + if (result) { + return result; + } + + result = sendCommand(OwReadByteCmd); + + if (!result) { + result = pollBusy(); + } + + uint_least8_t buf; + + if (!result) { + result = readRegister(ReadDataReg, buf); + } + + if (!result) { + recvByte = buf; + } + + return result; +} + +error_code DS2482_DS2484::setSpeed(Speed newSpeed) { + // Check if supported speed + if (!((newSpeed == OverdriveSpeed) || (newSpeed == StandardSpeed))) { + return make_error_code(InvalidSpeedError); + } + // Check if requested speed is already set + if (curConfig.get1WS() == (newSpeed == OverdriveSpeed)) { + return error_code(); + } + // Set the speed + Config newConfig = curConfig; + newConfig.set1WS(newSpeed == OverdriveSpeed); + return writeConfig(newConfig); +} + +error_code DS2482_DS2484::setLevel(Level newLevel) { + if (newLevel == StrongLevel) { + return make_error_code(InvalidLevelError); + } + + return configureLevel(newLevel); +} + +error_code DS2482_DS2484::writeConfig(Config config) { + uint_least8_t configBuf = ((config.readByte() ^ 0xF) << 4) | config.readByte(); + error_code result = sendCommand(WriteDeviceConfigCmd, configBuf); + if (!result) { + result = readRegister(ConfigReg, configBuf); + } + if (!result) { + if (configBuf != config.readByte()) { + result = make_error_code(HardwareError); + } + } + if (!result) { + curConfig = config; + } + return result; +} + +error_code DS2482_DS2484::readRegister(uint_least8_t reg, uint_least8_t & buf) const { + error_code result = sendCommand(SetReadPointerCmd, reg); + if (!result) { + result = readRegister(buf); + } + return result; +} + +error_code DS2482_DS2484::readRegister(uint_least8_t & buf) const { + return i2cMaster->readPacket(i2cAddress_, &buf, 1); +} + +error_code DS2482_DS2484::pollBusy(uint_least8_t * pStatus) { + const int pollLimit = 200; + + int pollCount = 0; + uint_least8_t status; + do { + error_code result = readRegister(status); + if (result) { + return result; + } + if (pStatus != NULL) { + *pStatus = status; + } + if (pollCount++ >= pollLimit) { + return make_error_code(HardwareError); + } + } while (status & Status_1WB); + + return error_code(); +} + +error_code DS2482_DS2484::configureLevel(Level level) { + // Check if supported level + if (!((level == NormalLevel) || (level == StrongLevel))) { + return make_error_code(InvalidLevelError); + } + // Check if requested level already set + if (curConfig.getSPU() == (level == StrongLevel)) { + return error_code(); + } + // Set the level + Config newConfig = curConfig; + newConfig.setSPU(level == StrongLevel); + return writeConfig(newConfig); +} + +error_code DS2482_DS2484::sendCommand(uint_least8_t cmd) const { + return i2cMaster->writePacket(i2cAddress_, &cmd, 1); +} + +error_code DS2482_DS2484::sendCommand(uint_least8_t cmd, uint_least8_t param) const { + uint_least8_t buf[] = {cmd, param}; + return i2cMaster->writePacket(i2cAddress_, buf, sizeof(buf) / sizeof(buf[0])); +} + +const error_category & DS2482_DS2484::errorCategory() { + static class : public error_category { + public: + virtual const char * name() const { return "DS2482_DS2484"; } + + virtual std::string message(int condition) const { + switch (condition) { + case HardwareError: + return "Hardware Error"; + + case ArgumentOutOfRangeError: + return "Argument Out of Range Error"; + + default: + return defaultErrorMessage(condition); + } + } + } instance; + return instance; +} + +error_code DS2482_800::selectChannel(int channel) { + // Channel Select (Case A) + // S AD,0 [A] CHSL [A] CC [A] Sr AD,1 [A] [RR] A\ P + // [] indicates from slave + // CC channel value + // RR channel read back + + uint_least8_t ch; + uint_least8_t ch_read; + switch (channel) { + case 0: + ch = 0xF0; + ch_read = 0xB8; + break; + + case 1: + ch = 0xE1; + ch_read = 0xB1; + break; + + case 2: + ch = 0xD2; + ch_read = 0xAA; + break; + + case 3: + ch = 0xC3; + ch_read = 0xA3; + break; + + case 4: + ch = 0xB4; + ch_read = 0x9C; + break; + + case 5: + ch = 0xA5; + ch_read = 0x95; + break; + + case 6: + ch = 0x96; + ch_read = 0x8E; + break; + + case 7: + ch = 0x87; + ch_read = 0x87; + break; + + default: + return make_error_code(ArgumentOutOfRangeError); + }; + + error_code result = sendCommand(ChannelSelectCmd, ch); + if (!result) { + result = readRegister(ch); + if (!result) { + // check for failure due to incorrect read back of channel + if (ch != ch_read) { + result = make_error_code(HardwareError); + } + } + } + + return result; +} + +error_code DS2484::adjustPort(PortParameter param, int val) { + if (val < 0 || val > 15) { + return make_error_code(ArgumentOutOfRangeError); + } + + error_code result = sendCommand(AdjustOwPortCmd, (param << 4) | val); + if (result) { + return result; + } + + uint_least8_t portConfig; + for (int paramNum = param + 1; paramNum > 0; paramNum--) { + result = readRegister(portConfig); + if (result) { + return result; + } + } + if (val != portConfig) { + result = make_error_code(HardwareError); + } + + return result; +} + +} // namespace MaximInterface
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Devices/DS2482_DS2484.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,228 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_DS2482_DS2484 +#define MaximInterface_DS2482_DS2484 + +#include <MaximInterface/Links/OneWireMaster.hpp> +#include <MaximInterface/Links/I2CMaster.hpp> +#include <MaximInterface/Utilities/Export.h> + +namespace MaximInterface { + +/// Interface to the DS2484, DS2482-100, DS2482-101, DS2482-800 1-Wire masters. +class DS2482_DS2484 : public OneWireMaster { +public: + enum ErrorValue { HardwareError = 1, ArgumentOutOfRangeError }; + + /// Represents a device configuration. + class Config { + public: + /// Default construct with power-on config. + explicit Config(uint_least8_t readByte = optionAPU) + : readByte_(readByte & 0xF) {} + + /// @{ + /// 1-Wire Speed + bool get1WS() const { return (readByte_ & option1WS) == option1WS; } + void set1WS(bool new1WS) { + if (new1WS) { + readByte_ |= option1WS; + } else { + readByte_ &= ~option1WS; + } + } + /// @} + + /// @{ + /// Strong Pullup + bool getSPU() const { return (readByte_ & optionSPU) == optionSPU; } + void setSPU(bool newSPU) { + if (newSPU) { + readByte_ |= optionSPU; + } else { + readByte_ &= ~optionSPU; + } + } + /// @} + + /// @{ + /// 1-Wire Power Down + bool getPDN() const { return (readByte_ & optionPDN) == optionPDN; } + void setPDN(bool newPDN) { + if (newPDN) { + readByte_ |= optionPDN; + } else { + readByte_ &= ~optionPDN; + } + } + /// @} + + /// @{ + /// Active Pullup + bool getAPU() const { return (readByte_ & optionAPU) == optionAPU; } + void setAPU(bool newAPU) { + if (newAPU) { + readByte_ |= optionAPU; + } else { + readByte_ &= ~optionAPU; + } + } + /// @} + + /// Byte representation that is read from the device. + uint_least8_t readByte() const { return readByte_; } + + private: + static const unsigned int option1WS = 0x8; + static const unsigned int optionSPU = 0x4; + static const unsigned int optionPDN = 0x2; + static const unsigned int optionAPU = 0x1; + + uint_least8_t readByte_; + }; + + void setI2CMaster(I2CMaster & i2cMaster) { this->i2cMaster = &i2cMaster; } + uint_least8_t i2cAddress() const { return i2cAddress_; } + void setI2CAddress(uint_least8_t i2cAddress) { + this->i2cAddress_ = i2cAddress; + } + + /// Initialize hardware for use. + MaximInterface_EXPORT error_code initialize(Config config = Config()); + + /// Write a new configuration to the device. + /// @param[in] config New configuration to write. + MaximInterface_EXPORT error_code writeConfig(Config config); + + /// @note Perform a 1-Wire triplet using the device command. + MaximInterface_EXPORT virtual error_code triplet(TripletData & data); + + MaximInterface_EXPORT virtual error_code reset(); + MaximInterface_EXPORT virtual error_code touchBitSetLevel(bool & sendRecvBit, + Level afterLevel); + MaximInterface_EXPORT virtual error_code + readByteSetLevel(uint_least8_t & recvByte, Level afterLevel); + MaximInterface_EXPORT virtual error_code + writeByteSetLevel(uint_least8_t sendByte, Level afterLevel); + MaximInterface_EXPORT virtual error_code setSpeed(Speed newSpeed); + MaximInterface_EXPORT virtual error_code setLevel(Level newLevel); + + MaximInterface_EXPORT static const error_category & errorCategory(); + +protected: + DS2482_DS2484(I2CMaster & i2cMaster, uint_least8_t i2cAddress) + : i2cMaster(&i2cMaster), i2cAddress_(i2cAddress) {} + + /// @note Allow marking const since not public. + error_code sendCommand(uint_least8_t cmd) const; + + /// @note Allow marking const since not public. + error_code sendCommand(uint_least8_t cmd, uint_least8_t param) const; + + /// Reads a register from the device. + /// @param reg Register to read from. + /// @param[out] buf Buffer to hold read data. + error_code readRegister(uint_least8_t reg, uint_least8_t & buf) const; + + /// Reads the current register from the device. + /// @param[out] buf Buffer to hold read data. + error_code readRegister(uint_least8_t & buf) const; + +private: + /// Performs a soft reset on the device. + /// @note This is not a 1-Wire Reset. + error_code resetDevice(); + + /// Polls the device status waiting for the 1-Wire Busy bit (1WB) to be cleared. + /// @param[out] pStatus Optionally retrieve the status byte when 1WB cleared. + /// @returns Success or TimeoutError if poll limit reached. + error_code pollBusy(uint_least8_t * pStatus = NULL); + + /// Ensure that the desired 1-Wire level is set in the configuration. + /// @param level Desired 1-Wire level. + error_code configureLevel(Level level); + + I2CMaster * i2cMaster; + uint_least8_t i2cAddress_; + Config curConfig; +}; + +inline error_code make_error_code(DS2482_DS2484::ErrorValue e) { + return error_code(e, DS2482_DS2484::errorCategory()); +} + +class DS2482_100 : public DS2482_DS2484 { +public: + DS2482_100(I2CMaster & i2c_bus, uint_least8_t adrs) + : DS2482_DS2484(i2c_bus, adrs) {} +}; + +/// DS2482-800 I2C to 1-Wire Master +class DS2482_800 : public DS2482_DS2484 { +public: + DS2482_800(I2CMaster & i2c_bus, uint_least8_t adrs) + : DS2482_DS2484(i2c_bus, adrs) {} + + /// Select the active 1-Wire channel. + /// @param channel Channel number to select from 0 to 7. + MaximInterface_EXPORT error_code selectChannel(int channel); +}; + +/// DS2484 I2C to 1-Wire Master +class DS2484 : public DS2482_DS2484 { +public: + /// 1-Wire port adjustment parameters. + /// @note See datasheet page 13. + enum PortParameter { + tRSTL = 0, + tRSTL_OD, + tMSP, + tMSP_OD, + tW0L, + tW0L_OD, + tREC0, // OD N/A + RWPU = 8 // OD N/A + }; + + explicit DS2484(I2CMaster & i2c_bus, uint_least8_t adrs = 0x30) + : DS2482_DS2484(i2c_bus, adrs) {} + + /// Adjust 1-Wire port parameters. + /// @param param Parameter to adjust. + /// @param val New parameter value to set. Consult datasheet for value mappings. + MaximInterface_EXPORT error_code adjustPort(PortParameter param, int val); +}; + +} // namespace MaximInterface + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Devices/DS28C36_DS2476.cpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,805 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#include <MaximInterface/Links/I2CMaster.hpp> +#include <MaximInterface/Utilities/Error.hpp> +#include <MaximInterface/Utilities/RomId.hpp> +#include "DS28C36_DS2476.hpp" + +using std::copy; +using std::vector; + +namespace MaximInterface { + +using namespace Ecc256; + +// DS28C36 commands. +enum Command { + WriteMemory = 0x96, + ReadMemory = 0x69, + WriteBuffer = 0x87, + ReadBuffer = 0x5A, + ReadPageProtection = 0xAA, + SetPageProtection = 0xC3, + DecrementCounter = 0xC9, + ReadRng = 0xD2, + EncryptedReadMemory = 0x4B, + ComputeAndReadPathAuthentication = 0xA5, + AuthenticatedSha2WriteMemory = 0x99, + ComputeAndLockSha2Secret = 0x3C, + GenerateEcc256KeyPair = 0xCB, + ComputeMultiblockHash = 0x33, + VerifyEcdsaSignature = 0x59, + AuthenticateEcdsaPublicKey = 0xA8, + AuthenticatedEcdsaWriteMemory = 0x89 +}; + +static error_code convertResultByte(uint_least8_t resultByte) { + error_code errorCode; + if (resultByte != 0xAA) { + errorCode.assign((resultByte == 0x00) + ? static_cast<int>(DS28C36::AuthenticationError) + : resultByte, + DS28C36::errorCategory()); + } + return errorCode; +} + +error_code DS28C36::writeMemory(int pageNum, const Page & page) { + if (pageNum < 0 || pageNum >= memoryPages) { + return make_error_code(InvalidParameterError); + } + + vector<uint_least8_t> buffer; + buffer.reserve(1 + page.size()); + buffer.push_back(pageNum); + buffer.insert(buffer.end(), page.begin(), page.end()); + error_code result = writeCommand(WriteMemory, &buffer[0], buffer.size()); + if (!result) { + sleep(writeMemoryTimeMs); + result = readResponse(buffer); + if (!result) { + if (buffer.size() == 1) { + result = convertResultByte(buffer[0]); + } else { + result = make_error_code(InvalidResponseError); + } + } + } + return result; +} + +error_code DS28C36::readMemory(int pageNum, Page & page) { + if (pageNum < 0 || pageNum >= memoryPages) { + return make_error_code(InvalidParameterError); + } + + vector<uint_least8_t> buffer; + buffer.push_back(pageNum); + error_code result = writeCommand(ReadMemory, &buffer[0], buffer.size()); + if (!result) { + sleep(readMemoryTimeMs); + result = readResponse(buffer); + if (!result) { + if (buffer.size() == (1 + page.size())) { + result = convertResultByte(buffer[0]); + copy(buffer.begin() + 1, buffer.end(), page.begin()); + } else { + result = make_error_code(InvalidResponseError); + } + } + } + return result; +} + +error_code DS28C36::writeBuffer(const uint_least8_t * data, size_t dataSize) { + return writeCommand(WriteBuffer, data, dataSize); +} + +error_code DS28C36::readBuffer(vector<uint_least8_t> & data) { + error_code result = writeCommand(ReadBuffer, NULL, 0); + if (!result) { + result = readResponse(data); + } + return result; +} + +error_code DS28C36::readPageProtection(int pageNum, + PageProtection & protection) { + if (pageNum < 0 || pageNum >= memoryPages) { + return make_error_code(InvalidParameterError); + } + + vector<uint_least8_t> buffer; + buffer.push_back(pageNum); + error_code result = + writeCommand(ReadPageProtection, &buffer[0], buffer.size()); + if (!result) { + sleep(readMemoryTimeMs); + result = readResponse(buffer); + if (!result) { + if (buffer.size() == 1) { + protection = buffer[0]; + } else { + result = make_error_code(InvalidResponseError); + } + } + } + return result; +} + +error_code DS28C36::setPageProtection(int pageNum, + const PageProtection & protection) { + if (pageNum < 0 || pageNum >= memoryPages) { + return make_error_code(InvalidParameterError); + } + + vector<uint_least8_t> buffer; + buffer.push_back(pageNum); + buffer.push_back(static_cast<uint_least8_t>(protection.to_ulong())); + error_code result = + writeCommand(SetPageProtection, &buffer[0], buffer.size()); + if (!result) { + sleep(writeMemoryTimeMs); + result = readResponse(buffer); + if (!result) { + if (buffer.size() == 1) { + result = convertResultByte(buffer[0]); + } else { + result = make_error_code(InvalidResponseError); + } + } + } + return result; +} + +error_code DS28C36::decrementCounter() { + error_code result = writeCommand(DecrementCounter, NULL, 0); + if (!result) { + sleep(writeMemoryTimeMs); + vector<uint_least8_t> buffer; + result = readResponse(buffer); + if (!result) { + if (buffer.size() == 1) { + result = convertResultByte(buffer[0]); + } else { + result = make_error_code(InvalidResponseError); + } + } + } + return result; +} + +error_code DS28C36::readRng(int numBytes, vector<uint_least8_t> & data) { + if ((numBytes < 1) || (numBytes > 64)) { + return make_error_code(InvalidParameterError); + } + + data.clear(); + data.push_back(numBytes - 1); + error_code result = writeCommand(ReadRng, &data[0], data.size()); + if (!result) { + sleep(sha256ComputationTimeMs); + result = readResponse(data); + if (!result) { + if (data.size() != + static_cast<vector<uint_least8_t>::size_type>(numBytes)) { + result = make_error_code(InvalidResponseError); + } + } + } + return result; +} + +error_code DS28C36::encryptedReadMemory(int pageNum, SecretNum secretNum, + EncryptedPage & page) { + if (pageNum < 0 || pageNum >= memoryPages) { + return make_error_code(InvalidParameterError); + } + + vector<uint_least8_t> buffer; + buffer.push_back((secretNum << 6) | pageNum); + error_code result = + writeCommand(EncryptedReadMemory, &buffer[0], buffer.size()); + if (!result) { + sleep(readMemoryTimeMs + sha256ComputationTimeMs); + result = readResponse(buffer); + if (!result) { + if (buffer.size() == (1 + page.challenge.size() + page.data.size())) { + result = convertResultByte(buffer[0]); + vector<uint_least8_t>::const_iterator begin = buffer.begin() + 1; + vector<uint_least8_t>::const_iterator end = + begin + page.challenge.size(); + copy(begin, end, page.challenge.begin()); + begin = end; + end = begin + page.data.size(); + copy(begin, end, page.data.begin()); + } else { + result = make_error_code(InvalidResponseError); + } + } + } + return result; +} + +error_code +DS28C36::computeAndReadPageAuthentication(int pageNum, AuthType authType, + vector<uint_least8_t> & data) { + if (pageNum < 0 || pageNum >= memoryPages) { + return make_error_code(InvalidParameterError); + } + + data.clear(); + data.push_back((authType << 5) | pageNum); + error_code result = + writeCommand(ComputeAndReadPathAuthentication, &data[0], data.size()); + if (!result) { + sleep(readMemoryTimeMs + ((authType < EcdsaWithKeyA) + ? sha256ComputationTimeMs + : generateEcdsaSignatureTimeMs)); + result = readResponse(data); + if (!result) { + if (data.size() > 1) { + result = convertResultByte(data[0]); + data.erase(data.begin()); + } else { + result = make_error_code(InvalidResponseError); + } + } + } + return result; +} + +error_code +DS28C36::computeAndReadEcdsaPageAuthentication(int pageNum, KeyNum keyNum, + Signature & signature) { + AuthType authType; + switch (keyNum) { + case KeyNumA: + authType = EcdsaWithKeyA; + break; + case KeyNumB: + authType = EcdsaWithKeyB; + break; + case KeyNumC: + authType = EcdsaWithKeyC; + break; + default: + return make_error_code(InvalidParameterError); + } + vector<uint_least8_t> data; + error_code result = computeAndReadPageAuthentication(pageNum, authType, data); + if (!result) { + vector<uint_least8_t>::const_iterator begin = data.begin(); + vector<uint_least8_t>::const_iterator end = begin + signature.s.size(); + copy(begin, end, signature.s.begin()); + begin = end; + end = begin + signature.r.size(); + copy(begin, end, signature.r.begin()); + } + return result; +} + +error_code DS28C36::computeAndReadHmacPageAuthentication(int pageNum, + SecretNum secretNum, + Sha256::Hash & hmac) { + AuthType authType; + switch (secretNum) { + case SecretNumA: + authType = HmacWithSecretA; + break; + case SecretNumB: + authType = HmacWithSecretB; + break; + case SecretNumS: + authType = HmacWithSecretS; + break; + default: + return make_error_code(InvalidParameterError); + } + vector<uint_least8_t> data; + error_code result = computeAndReadPageAuthentication(pageNum, authType, data); + if (!result) { + copy(data.begin(), data.end(), hmac.begin()); + } + return result; +} + +error_code DS28C36::authenticatedSha2WriteMemory(int pageNum, + SecretNum secretNum, + const Page & page) { + if (pageNum < 0 || pageNum >= memoryPages) { + return make_error_code(InvalidParameterError); + } + + vector<uint_least8_t> buffer; + buffer.reserve(1 + page.size()); + buffer.push_back((secretNum << 6) | pageNum); + buffer.insert(buffer.end(), page.begin(), page.end()); + error_code result = + writeCommand(AuthenticatedSha2WriteMemory, &buffer[0], buffer.size()); + if (!result) { + sleep(writeMemoryTimeMs + (2 * sha256ComputationTimeMs)); + result = readResponse(buffer); + if (buffer.size() == 1) { + result = convertResultByte(buffer[0]); + } else { + result = make_error_code(InvalidResponseError); + } + } + return result; +} + +error_code DS28C36::computeAndLockSha2Secret(int pageNum, SecretNum msecretNum, + SecretNum dsecretNum, + bool writeProtectEnable) { + // User pages only + if (pageNum < UserData0 || pageNum > UserData15) { + return make_error_code(InvalidParameterError); + } + + vector<uint_least8_t> buffer; + buffer.push_back((dsecretNum << 6) | (msecretNum << 4) | pageNum); + buffer.push_back(writeProtectEnable ? 0x80 : 0x00); + error_code result = + writeCommand(ComputeAndLockSha2Secret, &buffer[0], buffer.size()); + if (!result) { + sleep(sha256ComputationTimeMs + + ((writeProtectEnable ? 2 : 1) * writeMemoryTimeMs)); + result = readResponse(buffer); + if (buffer.size() == 1) { + result = convertResultByte(buffer[0]); + } else { + result = make_error_code(InvalidResponseError); + } + } + return result; +} + +error_code DS28C36::generateEcc256KeyPair(KeyNum keyNum, + bool writeProtectEnable) { + if (keyNum == KeyNumS) { + return make_error_code(InvalidParameterError); + } + + vector<uint_least8_t> buffer; + uint_least8_t parameter = keyNum; + if (writeProtectEnable) { + parameter |= 0x80; + } + buffer.push_back(parameter); + error_code result = + writeCommand(GenerateEcc256KeyPair, &buffer[0], buffer.size()); + if (!result) { + sleep(generateEccKeyPairTimeMs); + result = readResponse(buffer); + if (!result) { + if (buffer.size() == 1) { + result = convertResultByte(buffer[0]); + } else { + result = make_error_code(InvalidResponseError); + } + } + } + return result; +} + +error_code DS28C36::computeMultiblockHash(bool firstBlock, bool lastBlock, + const uint_least8_t * data, + size_t dataSize) { + uint_least8_t parameter = 0; + if (firstBlock) { + parameter |= 0x40; + } + if (lastBlock) { + parameter |= 0x80; + } + vector<uint_least8_t> buffer; + buffer.reserve(1 + dataSize); + buffer.push_back(parameter); + buffer.insert(buffer.end(), data, data + dataSize); + error_code result = + writeCommand(ComputeMultiblockHash, &buffer[0], buffer.size()); + if (!result) { + sleep(sha256ComputationTimeMs); + result = readResponse(buffer); + if (!result) { + if (buffer.size() == 1) { + result = convertResultByte(buffer[0]); + } else { + result = make_error_code(InvalidResponseError); + } + } + } + return result; +} + +error_code DS28C36::verifyEcdsaSignature(KeyNum keyNum, HashType hashType, + const Signature & signature, + PioState pioa, PioState piob) { + uint_least8_t parameter = keyNum | (hashType << 2); + if (pioa != Unchanged) { + parameter |= 0x20; + } + if (pioa == Conducting) { + parameter |= 0x10; + } + if (piob != Unchanged) { + parameter |= 0x80; + } + if (piob == Conducting) { + parameter |= 0x40; + } + vector<uint_least8_t> buffer; + buffer.reserve(1 + signature.r.size() + signature.s.size()); + buffer.push_back(parameter); + buffer.insert(buffer.end(), signature.r.begin(), signature.r.end()); + buffer.insert(buffer.end(), signature.s.begin(), signature.s.end()); + error_code result = + writeCommand(VerifyEcdsaSignature, &buffer[0], buffer.size()); + if (!result) { + sleep(verifyEsdsaSignatureOrComputeEcdhTimeMs + + ((hashType == DataInBuffer) ? sha256ComputationTimeMs : 0)); + result = readResponse(buffer); + if (!result) { + if (buffer.size() == 1) { + result = convertResultByte(buffer[0]); + } else { + result = make_error_code(InvalidResponseError); + } + } + } + return result; +} + +error_code DS28C36::authenticateEcdsaPublicKey(bool authWrites, bool ecdh, + KeyNum keyNum, int csOffset, + const Signature & signature) { + if (((keyNum != KeyNumA) && (keyNum != KeyNumB)) || (csOffset < 0) || + (csOffset > 31)) { + return make_error_code(InvalidParameterError); + } + + uint_least8_t parameter = (csOffset << 3) | (keyNum << 2); + if (ecdh) { + parameter |= 0x02; + } + if (authWrites) { + parameter |= 0x01; + } + vector<uint_least8_t> buffer; + buffer.reserve(1 + signature.r.size() + signature.s.size()); + buffer.push_back(parameter); + buffer.insert(buffer.end(), signature.r.begin(), signature.r.end()); + buffer.insert(buffer.end(), signature.s.begin(), signature.s.end()); + error_code result = + writeCommand(AuthenticateEcdsaPublicKey, &buffer[0], buffer.size()); + if (!result) { + sleep((ecdh ? 2 : 1) * verifyEsdsaSignatureOrComputeEcdhTimeMs); + result = readResponse(buffer); + if (!result) { + if (buffer.size() == 1) { + result = convertResultByte(buffer[0]); + } else { + result = make_error_code(InvalidResponseError); + } + } + } + return result; +} + +error_code DS28C36::authenticatedEcdsaWriteMemory(int pageNum, + const Page & page) { + if (pageNum < 0 || pageNum >= memoryPages) { + return make_error_code(InvalidParameterError); + } + + vector<uint_least8_t> buffer; + buffer.reserve(1 + page.size()); + buffer.push_back(pageNum); + buffer.insert(buffer.end(), page.begin(), page.end()); + error_code result = + writeCommand(AuthenticatedEcdsaWriteMemory, &buffer[0], buffer.size()); + if (!result) { + sleep(verifyEsdsaSignatureOrComputeEcdhTimeMs + writeMemoryTimeMs + + sha256ComputationTimeMs); + result = readResponse(buffer); + if (!result) { + if (buffer.size() == 1) { + result = convertResultByte(buffer[0]); + } else { + result = make_error_code(InvalidResponseError); + } + } + } + return result; +} + +error_code DS28C36::writeCommand(uint_least8_t command, + const uint_least8_t * parameters, + size_t parametersSize) { + error_code result = master->start(address_); + if (result) { + master->stop(); + return result; + } + result = master->writeByte(command); + if (result) { + master->stop(); + return result; + } + if (parameters) { + result = master->writeByte(static_cast<uint_least8_t>(parametersSize)); + if (result) { + master->stop(); + return result; + } + result = master->writeBlock(parameters, parametersSize); + if (result) { + master->stop(); + return result; + } + } + result = master->stop(); + return result; +} + +error_code DS28C36::readResponse(vector<uint_least8_t> & response) { + error_code result = master->start(address_ | 1); + if (result) { + master->stop(); + return result; + } + uint_least8_t length; + result = master->readByte(I2CMaster::Ack, length); + if (result) { + master->stop(); + return result; + } + response.resize(length); + result = master->readBlock(I2CMaster::Nack, &response[0], response.size()); + if (result) { + master->stop(); + return result; + } + result = master->stop(); + return result; +} + +DS28C36::PageAuthenticationData +DS28C36::createPageAuthenticationData(const RomId & romId, const Page & page, + const Page & challenge, int pageNum, + const ManId & manId) { + PageAuthenticationData data; + PageAuthenticationData::iterator dataIt = data.begin(); + dataIt = copy(romId.begin(), romId.end(), dataIt); + dataIt = copy(page.begin(), page.end(), dataIt); + dataIt = copy(challenge.begin(), challenge.end(), dataIt); + *dataIt = static_cast<uint_least8_t>(pageNum); + ++dataIt; + copy(manId.begin(), manId.end(), dataIt); + return data; +} + +const error_category & DS28C36::errorCategory() { + static class : public error_category { + public: + virtual const char * name() const { return "DS28C36"; } + + virtual std::string message(int condition) const { + switch (condition) { + case ProtectionError: + return "Protection Error"; + + case InvalidParameterError: + return "Invalid Parameter Error"; + + case InvalidSequenceError: + return "Invalid Sequence Error"; + + case InvalidEcdsaInputOrResultError: + return "Invalid ECDSA Input or Result Error"; + + case AuthenticationError: + return "Authentication Error"; + + case InvalidResponseError: + return "Invalid Response Error"; + + default: + return defaultErrorMessage(condition); + } + } + } instance; + return instance; +} + +error_code readRomIdAndManId(DS28C36 & ds28c36, RomId * romId, ManId * manId) { + DS28C36::Page page; + const error_code result = ds28c36.readMemory(DS28C36::RomOptions, page); + if (!result) { + DS28C36::Page::const_iterator pageIt = page.begin() + 22; + if (manId) { + copy(pageIt, pageIt + ManId::size(), manId->begin()); + } + pageIt += ManId::size(); + if (romId) { + copy(pageIt, pageIt + RomId::size(), romId->begin()); + } + } + return result; +} + +error_code readRng(DS28C36 & ds28c36, uint_least8_t * data, size_t dataSize) { + error_code result; + vector<uint_least8_t> buffer; + while (dataSize > 0) { + result = ds28c36.readRng(static_cast<int>(std::min<size_t>(dataSize, 64)), + buffer); + if (result) { + break; + } + copy(buffer.begin(), buffer.end(), data); + data += buffer.size(); + dataSize -= buffer.size(); + } + return result; +} + +error_code computeMultiblockHash(DS28C36 & ds28c36, const uint_least8_t * data, + const size_t dataSize) { + error_code result; + size_t remainingSize = dataSize; + while ((remainingSize > 0) && !result) { + const size_t chunkSize = std::min<size_t>(remainingSize, 64); + result = ds28c36.computeMultiblockHash( + remainingSize == dataSize, remainingSize == chunkSize, data, chunkSize); + data += chunkSize; + remainingSize -= chunkSize; + } + return result; +} + +error_code verifyEcdsaSignature(DS28C36 & ds28c36, DS28C36::KeyNum publicKey, + const uint_least8_t * data, size_t dataSize, + const Signature & signature, + DS28C36::PioState pioa, + DS28C36::PioState piob) { + error_code result = computeMultiblockHash(ds28c36, data, dataSize); + if (!result) { + result = ds28c36.verifyEcdsaSignature(publicKey, DS28C36::THASH, signature, + pioa, piob); + } + return result; +} + +error_code verifyEcdsaSignature(DS28C36 & ds28c36, const PublicKey & publicKey, + const uint_least8_t * data, size_t dataSize, + const Signature & signature, + DS28C36::PioState pioa, + DS28C36::PioState piob) { + error_code result = ds28c36.writeMemory(DS28C36::PublicKeySX, publicKey.x); + if (!result) { + result = ds28c36.writeMemory(DS28C36::PublicKeySY, publicKey.y); + } + if (!result) { + result = verifyEcdsaSignature(ds28c36, DS28C36::KeyNumS, data, dataSize, + signature, pioa, piob); + } + return result; +} + +// DS2476 additional commands. +enum DS2476_Command { + GenerateEcdsaSignature = 0x1E, + ComputeSha2UniqueSecret = 0x55, + ComputeSha2Hmac = 0x2D +}; + +error_code DS2476::generateEcdsaSignature(KeyNum keyNum, + Ecc256::Signature & signature) { + if (keyNum == KeyNumS) { + return make_error_code(InvalidParameterError); + } + + vector<uint_least8_t> buffer; + buffer.push_back(keyNum); + error_code result = + writeCommand(GenerateEcdsaSignature, &buffer[0], buffer.size()); + if (!result) { + sleep(generateEcdsaSignatureTimeMs); + result = readResponse(buffer); + if (!result) { + if (buffer.size() == (1 + signature.r.size() + signature.s.size())) { + result = convertResultByte(buffer[0]); + vector<uint_least8_t>::const_iterator begin = buffer.begin() + 1; + vector<uint_least8_t>::const_iterator end = begin + signature.s.size(); + copy(begin, end, signature.s.begin()); + begin = end; + end = begin + signature.r.size(); + copy(begin, end, signature.r.begin()); + } else { + result = make_error_code(InvalidResponseError); + } + } + } + return result; +} + +error_code DS2476::computeSha2UniqueSecret(SecretNum msecretNum) { + vector<uint_least8_t> buffer; + buffer.push_back(msecretNum << 4); + error_code result = + writeCommand(ComputeSha2UniqueSecret, &buffer[0], buffer.size()); + if (!result) { + sleep(sha256ComputationTimeMs); + result = readResponse(buffer); + if (!result) { + if (buffer.size() == 1) { + convertResultByte(buffer[0]); + } else { + result = make_error_code(InvalidResponseError); + } + } + } + return result; +} + +error_code DS2476::computeSha2Hmac(Sha256::Hash & hmac) { + error_code result = writeCommand(ComputeSha2Hmac, NULL, 0); + if (!result) { + sleep(sha256ComputationTimeMs); + vector<uint_least8_t> buffer; + result = readResponse(buffer); + if (!result) { + if (buffer.size() == (1 + hmac.size())) { + result = convertResultByte(buffer[0]); + copy(buffer.begin() + 1, buffer.end(), hmac.begin()); + } else { + result = make_error_code(InvalidResponseError); + } + } + } + return result; +} + +error_code enableCoprocessor(DS2476 & ds2476) { + DS2476::Page gpioControl; + error_code result = ds2476.readMemory(DS2476::GpioControl, gpioControl); + if (!result && gpioControl[0] != 0xAA) { + gpioControl[0] = 0xAA; + result = ds2476.writeMemory(DS2476::GpioControl, gpioControl); + } + return result; +} + +} // namespace MaximInterface
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Devices/DS28C36_DS2476.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,407 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_DS28C36_DS2476 +#define MaximInterface_DS28C36_DS2476 + +#include <vector> +#include <MaximInterface/Links/I2CMaster.hpp> +#include <MaximInterface/Links/Sleep.hpp> +#include <MaximInterface/Utilities/array.hpp> +#include <MaximInterface/Utilities/Ecc256.hpp> +#include <MaximInterface/Utilities/Export.h> +#include <MaximInterface/Utilities/RomId.hpp> +#include <MaximInterface/Utilities/ManId.hpp> +#include <MaximInterface/Utilities/Sha256.hpp> +#include <MaximInterface/Utilities/system_error.hpp> +#include <MaximInterface/Utilities/FlagSet.hpp> + +namespace MaximInterface { + +/// Interface to the DS28C36 authenticator. +class DS28C36 { +public: + /// Device command results. + enum ErrorValue { + ProtectionError = 0x55, + InvalidParameterError = 0x77, + InvalidSequenceError = 0x33, + InvalidEcdsaInputOrResultError = 0x22, + AuthenticationError = 0x100, + InvalidResponseError = 0x101 ///< Response does not match expected format. + }; + + /// Device memory pages. + enum PageNum { + UserData0 = 0, + UserData1, + UserData2, + UserData3, + UserData4, + UserData5, + UserData6, + UserData7, + UserData8, + UserData9, + UserData10, + UserData11, + UserData12, + UserData13, + UserData14, + UserData15, + PublicKeyAX, + PublicKeyAY, + PublicKeyBX, + PublicKeyBY, + PublicKeyCX, + PublicKeyCY, + PrivateKeyA, + PrivateKeyB, + PrivateKeyC, + SecretA, + SecretB, + DecrementCounter, + RomOptions, + GpioControl, + PublicKeySX, + PublicKeySY + }; + + /// Available keys for ECDSA operations. + enum KeyNum { KeyNumA = 0, KeyNumB = 1, KeyNumC = 2, KeyNumS = 3 }; + + /// Available secrets for HMAC operations. + enum SecretNum { SecretNumA = 0, SecretNumB = 1, SecretNumS = 2 }; + + /// Data hash type when verifying an ECDSA signature. + enum HashType { + HashInBuffer = 0, ///< Hash is loaded in the buffer. + DataInBuffer = 1, ///< Compute hash from data loaded in the buffer. + THASH = 2 ///< Use THASH from Compute Multiblock Hash command. + }; + + /// Available PIO states when verifying an ECDSA signature. + enum PioState { Unchanged, Conducting, HighImpedance }; + + /// Holds a device memory page. + typedef array<uint_least8_t, 32> Page; + + /// Holds page authentication input data. + typedef array<uint_least8_t, 75> PageAuthenticationData; + + /// Page protection types. + enum PageProtectionType { + RP = 0x01, ///< Read protection. + WP = 0x02, ///< Write protection. + EM = 0x04, ///< EPROM emulation mode. + APH = 0x08, ///< Authentication write protection HMAC. + EPH = 0x10, ///< Encryption and authenticated write protection HMAC. + AUTH = 0x20, ///< Public Key C is set to authority public key. + ECH = 0x40, ///< Encrypted read and write using shared key from ECDH. + ECW = 0x80 ///< Authentication write protection ECDSA. + }; + typedef FlagSet<PageProtectionType, 8> PageProtection; + + /// Holds an encrypted device memory page. + struct EncryptedPage { + array<uint_least8_t, 8> challenge; + Page data; + }; + + /// Number of memory pages on the device. + static const int memoryPages = 32; + + DS28C36(const Sleep & sleep, I2CMaster & master, uint_least8_t address = 0x36) + : sleep_(&sleep), master(&master), address_(address & 0xFE) {} + + void setSleep(const Sleep & sleep) { this->sleep_ = &sleep; } + void setMaster(I2CMaster & master) { this->master = &master; } + uint_least8_t address() const { return address_; } + void setAddress(uint_least8_t address) { this->address_ = (address & 0xFE); } + + /// Write memory with no protection. + /// @param pageNum Number of page to write. + /// @param page Data to write. + MaximInterface_EXPORT error_code writeMemory(int pageNum, const Page & page); + + /// Read memory with no protection. + /// @param pageNum Number of page to read. + /// @param[out] page Data that was read. + MaximInterface_EXPORT error_code readMemory(int pageNum, Page & page); + + /// Write the temporary buffer. + /// @param data Data to write. + /// @param dataSize Size of data to write. + MaximInterface_EXPORT error_code writeBuffer(const uint_least8_t * data, + size_t dataSize); + + /// Read the temporary buffer. + /// @param[out] data Data that was read. + MaximInterface_EXPORT error_code + readBuffer(std::vector<uint_least8_t> & data); + + /// Read the protection settings of a page. + /// @param pageNum Number of page to read. + /// @param[out] protection Protection that was read. + MaximInterface_EXPORT error_code + readPageProtection(int pageNum, PageProtection & protection); + + /// Set the protection settings of a page. + /// @param pageNum Number of page to write. + /// @param protection Protection to write. + MaximInterface_EXPORT error_code + setPageProtection(int pageNum, const PageProtection & protection); + + /// Decrement the decrement-only counter. + MaximInterface_EXPORT error_code decrementCounter(); + + /// Read a block of random data from the RNG. + /// @param numBytes Number of bytes to read from 1 to 64. + /// @param[out] data Random data from RNG. + MaximInterface_EXPORT error_code readRng(int numBytes, + std::vector<uint_least8_t> & data); + + /// Read memory with encryption. + /// @param pageNum Number of page to read from. + /// @param secretNum Secret to use for encryption. + /// @param[out] page Data that was read. + MaximInterface_EXPORT error_code encryptedReadMemory(int pageNum, + SecretNum secretNum, + EncryptedPage & page); + + /// Compute and read page authentication with ECDSA. + /// @param pageNum Number of page to authenticate. + /// @param keyNum Private key to use for authentication. + /// Key S cannot be used with this command. + /// @param[out] signature Computed page signature. + MaximInterface_EXPORT error_code computeAndReadEcdsaPageAuthentication( + int pageNum, KeyNum keyNum, Ecc256::Signature & signature); + + /// Compute and read page authentication with HMAC. + /// @param pageNum Number of page to authenticate. + /// @param secretNum Secret to use for authentication. + /// @param[out] hmac Computed page HMAC. + MaximInterface_EXPORT error_code computeAndReadHmacPageAuthentication( + int pageNum, SecretNum secretNum, Sha256::Hash & hmac); + + /// Write with SHA2 authentication. + /// @param pageNum Number of page to write. + /// @param secretNum Secret to use for authentication. + /// @param page Data to write. + MaximInterface_EXPORT error_code authenticatedSha2WriteMemory( + int pageNum, SecretNum secretNum, const Page & page); + + /// Compute SHA2 secret and optionally lock. + /// @param pageNum Number of page to use in computation. + /// @param msecretNum Master secret to use in computation. + /// @param dsecretNum Destination secret to receive the computation result. + /// @param writeProtectEnable + /// True to lock the destination secret against further writes. + MaximInterface_EXPORT error_code + computeAndLockSha2Secret(int pageNum, SecretNum msecretNum, + SecretNum dsecretNum, bool writeProtectEnable); + + /// Generate a new ECDSA key pair. + /// @param keyNum Key to generate. Key S cannot be used with this command. + /// @param writeProtectEnable True to lock the key against further writes. + MaximInterface_EXPORT error_code + generateEcc256KeyPair(KeyNum keyNum, bool writeProtectEnable); + + /// Compute a hash over multiple blocks. + /// @param firstBlock True if this is the first block being hashed. + /// @param lastBlock True if this is the last block being hashed. + /// @param data Data block to hash. + /// @param dataSize Size of data to hash. + /// Should be 64 bytes unless this is the last block. + MaximInterface_EXPORT error_code + computeMultiblockHash(bool firstBlock, bool lastBlock, + const uint_least8_t * data, size_t dataSize); + + /// Verify ECDSA signature. + /// @param keyNum Public key to use for verification. + /// @param hashType Source of the data hash input. + /// @param signature Signature to verify. + /// @param pioa New state of PIOA if verification successful. + /// @param piob New state of PIOB if verification successful. + MaximInterface_EXPORT error_code verifyEcdsaSignature( + KeyNum keyNum, HashType hashType, const Ecc256::Signature & signature, + PioState pioa = Unchanged, PioState piob = Unchanged); + + /// Authenticate a public key for authenticated writes or encrypted reads with ECDH. + /// @param authWrites True to select authentication for writes. + /// @param ecdh True to select ECDH key exchange. + /// @param keyNum Private key to use for ECDH key exchange. + /// Key A or B can be selected. + /// @param csOffset Certificate customization field ending offset in buffer. + /// @param signature Signature to use for authentication of public key S. + MaximInterface_EXPORT error_code + authenticateEcdsaPublicKey(bool authWrites, bool ecdh, KeyNum keyNum, + int csOffset, const Ecc256::Signature & signature); + + /// Write with ECDSA authentication. + /// @param pageNum Number of page to write. + /// @param page Data to write. + MaximInterface_EXPORT error_code + authenticatedEcdsaWriteMemory(int pageNum, const Page & page); + + /// Create data used by the Compute and Read Page Authentication command to + /// generate a signature. + MaximInterface_EXPORT static PageAuthenticationData + createPageAuthenticationData(const RomId & romId, const Page & page, + const Page & challenge, int pageNum, + const ManId & manId); + + MaximInterface_EXPORT static const error_category & errorCategory(); + +protected: + // Timing constants. + static const int generateEcdsaSignatureTimeMs = 50; + static const int generateEccKeyPairTimeMs = 100; + static const int verifyEsdsaSignatureOrComputeEcdhTimeMs = 150; + static const int sha256ComputationTimeMs = 3; + static const int readMemoryTimeMs = /*1*/ 2; + static const int writeMemoryTimeMs = 15; + + error_code writeCommand(uint_least8_t command, + const uint_least8_t * parameters, + size_t parametersSize); + error_code readResponse(std::vector<uint_least8_t> & response); + + void sleep(int ms) const { (*sleep_)(ms); } + +private: + enum AuthType { + HmacWithSecretA = 0, + HmacWithSecretB = 1, + HmacWithSecretS = 2, + EcdsaWithKeyA = 3, + EcdsaWithKeyB = 4, + EcdsaWithKeyC = 5 + }; + + const Sleep * sleep_; + I2CMaster * master; + uint_least8_t address_; + + /// Compute any type of authentication on page. + /// @param pageNum Number of page to authenticate. + /// @param authType Method to use to compute authentication. + /// @param[out] data Raw computed page authentication. + error_code + computeAndReadPageAuthentication(int pageNum, AuthType authType, + std::vector<uint_least8_t> & data); +}; + +/// Read the device ROM ID and MAN ID using the Read Memory command on the +/// ROM Options page. +/// @param[out] romId +/// Read ROM ID valid when operation is successful. May be set to NULL. +/// @param[out] manId +/// Read MAN ID valid when operation is successful. May be set to NULL. +MaximInterface_EXPORT error_code readRomIdAndManId(DS28C36 & ds28c36, + RomId * romId, + ManId * manId); + +/// Read arbitrary length random data with successive Read RNG commands. +/// @param[out] data Buffer to receive random data. +/// @param dataSize Size of data buffer. +MaximInterface_EXPORT error_code readRng(DS28C36 & ds28c36, + uint_least8_t * data, size_t dataSize); + +/// Hash arbitrary length data with successive Compute Multiblock Hash commands. +/// @param data Data to hash. +/// @param dataSize Size of data to hash. +MaximInterface_EXPORT error_code computeMultiblockHash( + DS28C36 & ds28c36, const uint_least8_t * data, const size_t dataSize); + +/// Verify ECDSA signature. +/// @param publicKey Public key to use for verification. +/// @param data Data to verify. +/// @param dataSize Size of data to verify. +/// @param signature Signature to verify. +/// @param pioa New state of PIOA if verification successful. +/// @param piob New state of PIOB if verification successful. +MaximInterface_EXPORT error_code verifyEcdsaSignature( + DS28C36 & ds28c36, DS28C36::KeyNum publicKey, const uint_least8_t * data, + size_t dataSize, const Ecc256::Signature & signature, + DS28C36::PioState pioa = DS28C36::Unchanged, + DS28C36::PioState piob = DS28C36::Unchanged); + +/// Verify ECDSA signature. +/// @param publicKey +/// Public key to use for verification which is loaded into Public Key S. +/// @param data Data to verify. +/// @param dataSize Size of data to verify. +/// @param signature Signature to verify. +/// @param pioa New state of PIOA if verification successful. +/// @param piob New state of PIOB if verification successful. +MaximInterface_EXPORT error_code +verifyEcdsaSignature(DS28C36 & ds28c36, const Ecc256::PublicKey & publicKey, + const uint_least8_t * data, size_t dataSize, + const Ecc256::Signature & signature, + DS28C36::PioState pioa = DS28C36::Unchanged, + DS28C36::PioState piob = DS28C36::Unchanged); + +inline error_code make_error_code(DS28C36::ErrorValue e) { + return error_code(e, DS28C36::errorCategory()); +} + +/// Interface to the DS2476 coprocessor. +class DS2476 : public DS28C36 { +public: + DS2476(const Sleep & sleep, I2CMaster & master, uint_least8_t address = 0x76) + : DS28C36(sleep, master, address) {} + + /// Generate ECDSA signature. + /// @param keyNum Private key to use to create signature. + /// Key S cannot be used with this command. + /// @param[out] signature Computed signature. + MaximInterface_EXPORT error_code + generateEcdsaSignature(KeyNum keyNum, Ecc256::Signature & signature); + + /// Compute unique SHA2 secret. + /// @param msecretNum Master secret to use in computation. + MaximInterface_EXPORT error_code + computeSha2UniqueSecret(SecretNum msecretNum); + + /// Compute SHA2 HMAC. + /// @param[out] hmac Computed HMAC. + MaximInterface_EXPORT error_code computeSha2Hmac(Sha256::Hash & hmac); +}; + +/// Enable coprocessor functionality on the DS2476 by writing to the +/// ROM Options page. +MaximInterface_EXPORT error_code enableCoprocessor(DS2476 & ds2476); + +} // namespace MaximInterface + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Devices/DS28E15_22_25.cpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,715 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#include <algorithm> +#include "DS28E15_22_25.hpp" +#include <MaximInterface/Utilities/crc.hpp> +#include <MaximInterface/Utilities/Error.hpp> + +using std::copy; + +namespace MaximInterface { + +using namespace Sha256; + +static const int shaComputationDelayMs = 3; +static const int eepromWriteDelayMs = 10; +static inline int secretEepromWriteDelayMs(bool lowPower) { + return lowPower ? 200 : 100; +} +static const int ds28e22_25_pagesPerBlock = 2; + +static error_code +writeDataWithCrc(OneWireMaster & master, const uint_least8_t * data, + size_t dataLen, + OneWireMaster::Level level = OneWireMaster::NormalLevel, + uint_fast16_t crcStart = 0) { + error_code result = master.writeBlock(data, dataLen); + if (result) { + return result; + } + uint_least8_t response[2]; + result = master.readByte(response[0]); + if (result) { + return result; + } + result = master.readByteSetLevel(response[1], level); + if (result) { + return result; + } + if (calculateCrc16(response, sizeof(response) / sizeof(response[0]), + calculateCrc16(data, dataLen, crcStart)) != 0xB001) { + result = make_error_code(DS28E15_22_25::CrcError); + } + return result; +} + +error_code +DS28E15_22_25::writeCommandWithCrc(Command command, uint_least8_t parameter, + OneWireMaster::Level level) const { + error_code result = selectRom(*master); + if (!result) { + const uint_least8_t data[] = {static_cast<uint_least8_t>(command), + parameter}; + result = + writeDataWithCrc(*master, data, sizeof(data) / sizeof(data[0]), level); + } + return result; +} + +static error_code readDataWithCrc(OneWireMaster & master, uint_least8_t * data, + size_t dataLen) { + error_code result = master.readBlock(data, dataLen); + if (result) { + return result; + } + uint_least8_t response[2]; + const size_t responseLen = sizeof(response) / sizeof(response[0]); + result = master.readBlock(response, responseLen); + if (result) { + return result; + } + if (calculateCrc16(response, responseLen, calculateCrc16(data, dataLen)) != + 0xB001) { + result = make_error_code(DS28E15_22_25::CrcError); + } + return result; +} + +static error_code readCsByte(OneWireMaster & master) { + uint_least8_t response; + error_code result = master.readByte(response); + if (result) { + return result; + } + if (response != 0xAA) { + result = make_error_code(DS28E15_22_25::OperationFailure); + } + return result; +} + +static error_code releaseSequence(OneWireMaster & master, const Sleep & sleep, + int delayTimeMs) { + error_code result = master.writeBytePower(0xAA); + if (result) { + return result; + } + sleep(delayTimeMs); + result = master.setLevel(OneWireMaster::NormalLevel); + if (result) { + return result; + } + return readCsByte(master); +} + +DS28E15_22_25::BlockProtection::BlockProtection(bool readProtection, + bool writeProtection, + bool eepromEmulation, + bool authProtection, + int blockNum) { + setReadProtection(readProtection); + setWriteProtection(writeProtection); + setEepromEmulation(eepromEmulation); + setAuthProtection(authProtection); + setBlockNum(blockNum); +} + +void DS28E15_22_25::BlockProtection::setBlockNum(int blockNum) { + status &= ~blockNumMask; + status |= (blockNum & blockNumMask); +} + +bool DS28E15_22_25::BlockProtection::noProtection() const { + return !readProtection() && !writeProtection() && !eepromEmulation() && + !authProtection(); +} + +void DS28E15_22_25::BlockProtection::setReadProtection(bool readProtection) { + if (readProtection) { + status |= readProtectionMask; + } else { + status &= ~readProtectionMask; + } +} + +void DS28E15_22_25::BlockProtection::setWriteProtection(bool writeProtection) { + if (writeProtection) { + status |= writeProtectionMask; + } else { + status &= ~writeProtectionMask; + } +} + +void DS28E15_22_25::BlockProtection::setEepromEmulation(bool eepromEmulation) { + if (eepromEmulation) { + status |= eepromEmulationMask; + } else { + status &= ~eepromEmulationMask; + } +} + +void DS28E15_22_25::BlockProtection::setAuthProtection(bool authProtection) { + if (authProtection) { + status |= authProtectionMask; + } else { + status &= ~authProtectionMask; + } +} + +error_code +DS28E15_22_25::writeAuthBlockProtection(const BlockProtection & newProtection, + const Hash & mac) { + error_code result = + writeCommandWithCrc(AuthWriteBlockProtection, newProtection.statusByte(), + OneWireMaster::StrongLevel); + if (result) { + return result; + } + + (*sleep)(shaComputationDelayMs); + result = master->setLevel(OneWireMaster::NormalLevel); + if (result) { + return result; + } + + result = writeDataWithCrc(*master, mac.data(), mac.size()); + if (result) { + return result; + } + + result = readCsByte(*master); + if (result) { + return result; + } + + result = releaseSequence(*master, *sleep, eepromWriteDelayMs); + return result; +} + +error_code +DS28E15_22_25::writeBlockProtection(const BlockProtection & protection) { + error_code result = + writeCommandWithCrc(WriteBlockProtection, protection.statusByte()); + if (result) { + return result; + } + + result = releaseSequence(*master, *sleep, eepromWriteDelayMs); + return result; +} + +error_code DS28E15_22_25::doReadBlockProtection(int blockNum, + BlockProtection & protection, + Variant variant) const { + uint_least8_t buffer = blockNum; + if (variant == DS28E22 || variant == DS28E25) { + buffer *= ds28e22_25_pagesPerBlock; + } + error_code result = writeCommandWithCrc(ReadStatus, buffer); + if (!result) { + result = master->readByte(buffer); + if (!result) { + protection.setStatusByte(buffer); + } + } + return result; +} + +AuthMacData DS28E15_22_25::createAuthMacData(const Page & pageData, int pageNum, + const Scratchpad & challenge, + const RomId & romId, + const ManId & manId) { + AuthMacData authMacData; + AuthMacData::iterator authMacDataIt = authMacData.begin(); + authMacDataIt = copy(pageData.begin(), pageData.end(), authMacDataIt); + authMacDataIt = copy(challenge.begin(), challenge.end(), authMacDataIt); + authMacDataIt = copy(romId.begin(), romId.end(), authMacDataIt); + *authMacDataIt = manId[1]; + *(++authMacDataIt) = manId[0]; + *(++authMacDataIt) = pageNum; + *(++authMacDataIt) = 0x00; + return authMacData; +} + +AuthMacData DS28E15_22_25::createAnonAuthMacData(const Page & pageData, + int pageNum, + const Scratchpad & challenge, + const ManId & manId) { + RomId romId; + romId.fill(0xFF); + return createAuthMacData(pageData, pageNum, challenge, romId, manId); +} + +error_code DS28E15_22_25::computeReadPageMac(int page_num, bool anon, + Hash & mac) const { + error_code result = + writeCommandWithCrc(ComputePageMac, (anon ? 0xE0 : 0x00) | page_num, + OneWireMaster::StrongLevel); + if (result) { + return result; + } + + (*sleep)(shaComputationDelayMs * 2); + result = master->setLevel(OneWireMaster::NormalLevel); + if (result) { + return result; + } + + result = readCsByte(*master); + if (result) { + return result; + } + + result = readDataWithCrc(*master, mac.data(), mac.size()); + return result; +} + +error_code DS28E15_22_25::doComputeSecret(int page_num, bool lock, + bool lowPower) { + error_code result = writeCommandWithCrc(ComputeAndLockSecret, + lock ? (0xE0 | page_num) : page_num); + if (result) { + return result; + } + + result = releaseSequence(*master, *sleep, + shaComputationDelayMs * 2 + + secretEepromWriteDelayMs(lowPower)); + return result; +} + +error_code DS28E15_22_25::doWriteScratchpad(const Scratchpad & data, + Variant variant) { + const uint_least8_t parameter = + (variant == DS28E22 || variant == DS28E25) ? 0x20 : 0x00; + error_code result = writeCommandWithCrc(ReadWriteScratchpad, parameter); + if (result) { + return result; + } + + result = writeDataWithCrc(*master, data.data(), data.size()); + return result; +} + +error_code DS28E15_22_25::doReadScratchpad(Scratchpad & data, + Variant variant) const { + const uint_least8_t parameter = + (variant == DS28E22 || variant == DS28E25) ? 0x2F : 0x0F; + error_code result = writeCommandWithCrc(ReadWriteScratchpad, parameter); + if (result) { + return result; + } + + result = readDataWithCrc(*master, data.data(), data.size()); + return result; +} + +error_code DS28E15_22_25::doLoadSecret(bool lock, bool lowPower) { + error_code result = + writeCommandWithCrc(LoadAndLockSecret, lock ? 0xE0 : 0x00); + if (result) { + return result; + } + + result = releaseSequence(*master, *sleep, secretEepromWriteDelayMs(lowPower)); + return result; +} + +error_code DS28E15_22_25::readPage(int page, Page & rdbuf) const { + error_code result = writeCommandWithCrc(ReadMemory, page); + if (result) { + return result; + } + + result = continueReadPage(rdbuf); + return result; +} + +error_code DS28E15_22_25::continueReadPage(Page & rdbuf) const { + return readDataWithCrc(*master, rdbuf.data(), rdbuf.size()); +} + +error_code DS28E15_22_25::doWriteAuthSegment(const Segment & newData, + const Hash & mac, Variant variant, + bool continuing) { + // CRC gets calculated with CS byte when continuing on DS28E22 and DS28E25. + const uint_fast16_t crcStart = + ((variant == DS28E22 || variant == DS28E25) && continuing) + ? calculateCrc16(0xAA) + : 0; + error_code result = writeDataWithCrc(*master, newData.data(), newData.size(), + OneWireMaster::StrongLevel, crcStart); + if (result) { + return result; + } + + (*sleep)(shaComputationDelayMs); + result = master->setLevel(OneWireMaster::NormalLevel); + if (result) { + return result; + } + + result = writeDataWithCrc(*master, mac.data(), mac.size()); + if (result) { + return result; + } + + result = readCsByte(*master); + if (result) { + return result; + } + + result = releaseSequence(*master, *sleep, eepromWriteDelayMs); + return result; +} + +error_code DS28E15_22_25::doWriteAuthSegment(int pageNum, int segmentNum, + const Segment & newData, + const Hash & mac, + Variant variant) { + error_code result = + writeCommandWithCrc(AuthWriteMemory, (segmentNum << 5) | pageNum); + if (result) { + return result; + } + + result = doWriteAuthSegment(newData, mac, variant, false); + return result; +} + +error_code DS28E15_22_25::doContinueWriteAuthSegment(const Segment & newData, + const Hash & mac, + Variant variant) { + return doWriteAuthSegment(newData, mac, variant, true); +} + +WriteMacData DS28E15_22_25::createSegmentWriteMacData( + int pageNum, int segmentNum, const Segment & newData, + const Segment & oldData, const RomId & romId, const ManId & manId) { + WriteMacData MT; + + // insert ROM number + copy(romId.begin(), romId.end(), MT.begin()); + + MT[11] = segmentNum; + MT[10] = pageNum; + MT[9] = manId[0]; + MT[8] = manId[1]; + + // insert old data + copy(oldData.begin(), oldData.end(), MT.begin() + 12); + + // insert new data + copy(newData.begin(), newData.end(), MT.begin() + 16); + + return MT; +} + +WriteMacData DS28E15_22_25::createProtectionWriteMacData( + const BlockProtection & newProtection, + const BlockProtection & oldProtection, const RomId & romId, + const ManId & manId) { + WriteMacData MT; + + // insert ROM number + copy(romId.begin(), romId.end(), MT.begin()); + + // instert block and page + MT[11] = 0; + MT[10] = newProtection.blockNum(); + + MT[9] = manId[0]; + MT[8] = manId[1]; + + // old data + MT[12] = oldProtection.authProtection() ? 0x01 : 0x00; + MT[13] = oldProtection.eepromEmulation() ? 0x01 : 0x00; + MT[14] = oldProtection.writeProtection() ? 0x01 : 0x00; + MT[15] = oldProtection.readProtection() ? 0x01 : 0x00; + // new data + MT[16] = newProtection.authProtection() ? 0x01 : 0x00; + MT[17] = newProtection.eepromEmulation() ? 0x01 : 0x00; + MT[18] = newProtection.writeProtection() ? 0x01 : 0x00; + MT[19] = newProtection.readProtection() ? 0x01 : 0x00; + + // compute the mac + return MT; +} + +error_code DS28E15_22_25::readSegment(int page, int segment, + Segment & data) const { + error_code result = writeCommandWithCrc(ReadMemory, (segment << 5) | page); + if (result) { + return result; + } + + result = continueReadSegment(data); + return result; +} + +error_code DS28E15_22_25::continueReadSegment(Segment & data) const { + return master->readBlock(data.data(), data.size()); +} + +error_code DS28E15_22_25::writeSegment(int page, int block, + const Segment & data) { + error_code result = writeCommandWithCrc(WriteMemory, (block << 5) | page); + if (result) { + return result; + } + + result = continueWriteSegment(data); + return result; +} + +error_code DS28E15_22_25::continueWriteSegment(const Segment & data) { + error_code result = writeDataWithCrc(*master, data.data(), data.size()); + if (result) { + return result; + } + + result = releaseSequence(*master, *sleep, eepromWriteDelayMs); + return result; +} + +SlaveSecretData +DS28E15_22_25::createSlaveSecretData(const Page & bindingPage, + int bindingPageNum, + const Scratchpad & partialSecret, + const RomId & romId, const ManId & manId) { + SlaveSecretData slaveSecretData; + SlaveSecretData::iterator slaveSecretDataIt = slaveSecretData.begin(); + slaveSecretDataIt = + copy(bindingPage.begin(), bindingPage.end(), slaveSecretDataIt); + slaveSecretDataIt = + copy(partialSecret.begin(), partialSecret.end(), slaveSecretDataIt); + slaveSecretDataIt = copy(romId.begin(), romId.end(), slaveSecretDataIt); + *slaveSecretDataIt = manId[1]; + *(++slaveSecretDataIt) = manId[0]; + *(++slaveSecretDataIt) = bindingPageNum; + *(++slaveSecretDataIt) = 0x00; + return slaveSecretData; +} + +error_code DS28E15_22_25::doReadAllBlockProtection(BlockProtection * protection, + const size_t protectionLen, + Variant variant) const { + error_code result = writeCommandWithCrc(ReadStatus, 0); + if (!result) { + if (variant == DS28E22 || variant == DS28E25) { + // Need to read extra data on DS28E22 to get CRC16. + uint_least8_t buf[DS28E25::memoryPages]; + result = readDataWithCrc(*master, buf, DS28E25::memoryPages); + if (!result) { + const int blocks = ((variant == DS28E22) ? DS28E22::memoryPages + : DS28E25::memoryPages) / + ds28e22_25_pagesPerBlock; + for (size_t i = 0; + i < std::min(protectionLen, static_cast<size_t>(blocks)); i++) { + protection[i].setStatusByte( + (buf[i * ds28e22_25_pagesPerBlock] & 0xF0) | // Upper nibble + ((buf[i * ds28e22_25_pagesPerBlock] & 0x0F) / + ds28e22_25_pagesPerBlock)); // Lower nibble + } + } + } else // DS28E15 + { + uint_least8_t buf[DS28E15::protectionBlocks]; + result = readDataWithCrc(*master, buf, DS28E15::protectionBlocks); + if (!result) { + for (size_t i = 0; + i < std::min(protectionLen, + static_cast<size_t>(DS28E15::protectionBlocks)); + i++) { + protection[i].setStatusByte(buf[i]); + } + } + } + } + return result; +} + +const error_category & DS28E15_22_25::errorCategory() { + static class : public error_category { + public: + virtual const char * name() const { return "DS28E15_22_25"; } + + virtual std::string message(int condition) const { + switch (condition) { + case CrcError: + return "CRC Error"; + + case OperationFailure: + return "Operation Failure"; + + default: + return defaultErrorMessage(condition); + } + } + } instance; + return instance; +} + +error_code DS28E15_22_25::loadSecret(bool lock) { + // Use worst-case low power timing if the device type is not known. + return doLoadSecret(lock, true); +} + +error_code DS28E15_22_25::computeSecret(int pageNum, bool lock) { + // Use worst-case low power timing if the device type is not known. + return doComputeSecret(pageNum, lock, true); +} + +error_code DS28E15_22_25::readPersonality(Personality & personality) const { + error_code result = writeCommandWithCrc(ReadStatus, 0xE0); + if (!result) { + array<uint_least8_t, 4> data; + result = readDataWithCrc(*master, data.data(), data.size()); + if (!result) { + personality.PB1 = data[0]; + personality.PB2 = data[1]; + personality.manId[0] = data[2]; + personality.manId[1] = data[3]; + } + } + return result; +} + +error_code DS28EL15::writeScratchpad(const Scratchpad & data) { + return doWriteScratchpad(data, DS28E15); +} + +error_code DS28EL15::readScratchpad(Scratchpad & data) const { + return doReadScratchpad(data, DS28E15); +} + +error_code DS28EL15::readBlockProtection(int blockNum, + BlockProtection & protection) const { + return doReadBlockProtection(blockNum, protection, DS28E15); +} + +error_code DS28EL15::writeAuthSegment(int pageNum, int segmentNum, + const Segment & newData, + const Hash & mac) { + return doWriteAuthSegment(pageNum, segmentNum, newData, mac, DS28E15); +} + +error_code DS28EL15::continueWriteAuthSegment(const Segment & newData, + const Hash & mac) { + return doContinueWriteAuthSegment(newData, mac, DS28E15); +} + +error_code DS28EL15::readAllBlockProtection( + array<BlockProtection, protectionBlocks> & protection) const { + return doReadAllBlockProtection(protection.data(), protection.size(), + DS28E15); +} + +error_code DS28E15::loadSecret(bool lock) { return doLoadSecret(lock, false); } + +error_code DS28E15::computeSecret(int pageNum, bool lock) { + return doComputeSecret(pageNum, lock, false); +} + +error_code DS28EL22::writeScratchpad(const Scratchpad & data) { + return doWriteScratchpad(data, DS28E22); +} + +error_code DS28EL22::readScratchpad(Scratchpad & data) const { + return doReadScratchpad(data, DS28E22); +} + +error_code DS28EL22::readBlockProtection(int blockNum, + BlockProtection & protection) const { + return doReadBlockProtection(blockNum, protection, DS28E22); +} + +error_code DS28EL22::writeAuthSegment(int pageNum, int segmentNum, + const Segment & newData, + const Hash & mac) { + return doWriteAuthSegment(pageNum, segmentNum, newData, mac, DS28E22); +} + +error_code DS28EL22::continueWriteAuthSegment(const Segment & newData, + const Hash & mac) { + return doContinueWriteAuthSegment(newData, mac, DS28E22); +} + +error_code DS28EL22::readAllBlockProtection( + array<BlockProtection, protectionBlocks> & protection) const { + return doReadAllBlockProtection(protection.data(), protection.size(), + DS28E22); +} + +error_code DS28E22::loadSecret(bool lock) { return doLoadSecret(lock, false); } + +error_code DS28E22::computeSecret(int pageNum, bool lock) { + return doComputeSecret(pageNum, lock, false); +} + +error_code DS28EL25::writeScratchpad(const Scratchpad & data) { + return doWriteScratchpad(data, DS28E25); +} + +error_code DS28EL25::readScratchpad(Scratchpad & data) const { + return doReadScratchpad(data, DS28E25); +} + +error_code DS28EL25::readBlockProtection(int blockNum, + BlockProtection & protection) const { + return doReadBlockProtection(blockNum, protection, DS28E25); +} + +error_code DS28EL25::writeAuthSegment(int pageNum, int segmentNum, + const Segment & newData, + const Hash & mac) { + return doWriteAuthSegment(pageNum, segmentNum, newData, mac, DS28E25); +} + +error_code DS28EL25::continueWriteAuthSegment(const Segment & newData, + const Hash & mac) { + return doContinueWriteAuthSegment(newData, mac, DS28E25); +} + +error_code DS28EL25::readAllBlockProtection( + array<BlockProtection, protectionBlocks> & protection) const { + return doReadAllBlockProtection(protection.data(), protection.size(), + DS28E25); +} + +error_code DS28E25::loadSecret(bool lock) { return doLoadSecret(lock, false); } + +error_code DS28E25::computeSecret(int pageNum, bool lock) { + return doComputeSecret(pageNum, lock, false); +} + +} // namespace MaximInterface
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Devices/DS28E15_22_25.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,539 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_DS28E15_22_25 +#define MaximInterface_DS28E15_22_25 + +#include <MaximInterface/Links/OneWireMaster.hpp> +#include <MaximInterface/Links/SelectRom.hpp> +#include <MaximInterface/Links/Sleep.hpp> +#include <MaximInterface/Utilities/array.hpp> +#include <MaximInterface/Utilities/Export.h> +#include <MaximInterface/Utilities/ManId.hpp> +#include <MaximInterface/Utilities/Sha256.hpp> + +namespace MaximInterface { + +/// Interface to the DS28E15/22/25 series of authenticators +/// including low power variants. +class DS28E15_22_25 { +public: + enum ErrorValue { CrcError = 1, OperationFailure }; + + /// Holds the contents of a device memory segment. + typedef array<uint_least8_t, 4> Segment; + + /// Holds the contents of a device memory page. + typedef array<uint_least8_t, 32> Page; + + /// Number of segments per page. + static const int segmentsPerPage = Page::csize / Segment::csize; + + /// Holds the contents of the device scratchpad. + typedef array<uint_least8_t, 32> Scratchpad; + + /// Container for the device personality. + struct Personality { + uint_least8_t PB1; + uint_least8_t PB2; + ManId manId; + + bool secretLocked() const { return PB2 & 0x01; } + }; + + /// Represents the status of a memory protection block. + class BlockProtection { + private: + static const unsigned int readProtectionMask = 0x80, + writeProtectionMask = 0x40, + eepromEmulationMask = 0x20, + authProtectionMask = 0x10, + blockNumMask = 0x0F; + uint_least8_t status; + + public: + explicit BlockProtection(uint_least8_t status = 0x00) : status(status) {} + MaximInterface_EXPORT BlockProtection(bool readProtection, + bool writeProtection, + bool eepromEmulation, + bool authProtection, + int blockNum); + + /// Get the byte representation used by the device. + uint_least8_t statusByte() const { return status; } + /// Set the byte representation used by the device. + void setStatusByte(uint_least8_t status) { this->status = status; } + + /// Get the Block Number which is indexed from zero. + int blockNum() const { return (status & blockNumMask); } + /// Set the Block Number which is indexed from zero. + MaximInterface_EXPORT void setBlockNum(int blockNum); + + /// Get the Read Protection status. + /// @returns True if Read Protection is enabled. + bool readProtection() const { + return ((status & readProtectionMask) == readProtectionMask); + } + /// Set the Read Protection status. + MaximInterface_EXPORT void setReadProtection(bool readProtection); + + /// Get the Write Protection status. + /// @returns True if Write Protection is enabled. + bool writeProtection() const { + return ((status & writeProtectionMask) == writeProtectionMask); + } + /// Set the Write Protection status. + MaximInterface_EXPORT void setWriteProtection(bool writeProtection); + + /// Get the EEPROM Emulation Mode status. + /// @returns True if EEPROM Emulation Mode is enabled. + bool eepromEmulation() const { + return ((status & eepromEmulationMask) == eepromEmulationMask); + } + /// Set the EEPROM Emulation Mode status. + MaximInterface_EXPORT void setEepromEmulation(bool eepromEmulation); + + /// Get the Authentication Protection status. + /// @returns True if Authentication Protection is enabled. + bool authProtection() const { + return ((status & authProtectionMask) == authProtectionMask); + } + /// Set the Authentication Protection status. + MaximInterface_EXPORT void setAuthProtection(bool authProtection); + + /// Check if no protection options are enabled. + /// @returns True if no protection options are enabled. + MaximInterface_EXPORT bool noProtection() const; + }; + + /// Format data to hash for an Authenticated Write to a memory segment. + /// @param pageNum Page number for write operation. + /// @param segmentNum Segment number within page for write operation. + /// @param[in] newData New data to write to the segment. + /// @param[in] oldData Existing data contained in the segment. + /// @param[in] romId 1-Wire ROM ID of the device. + /// @param[in] manId Manufacturer ID of the device. + MaximInterface_EXPORT static Sha256::WriteMacData + createSegmentWriteMacData(int pageNum, int segmentNum, + const Segment & newData, const Segment & oldData, + const RomId & romId, const ManId & manId); + + /// Format data to hash for an Authenticated Write to a memory protection block. + /// @param[in] newProtection New protection status to write. + /// @param[in] oldProtection Existing protection status in device. + /// @param[in] romId 1-Wire ROM ID of the device. + /// @param[in] manId Manufacturer ID of the device. + MaximInterface_EXPORT static Sha256::WriteMacData + createProtectionWriteMacData(const BlockProtection & newProtection, + const BlockProtection & oldProtection, + const RomId & romId, const ManId & manId); + + /// Format data to hash to compute the next secret from the existing secret. + /// @param[in] bindingPage Binding data from a device memory page. + /// @param bindingPageNum Number of the page where the binding data is from. + /// @param[in] partialSecret Partial secret data from the device scratchpad. + /// @param[in] romId 1-Wire ROM ID of the device. + /// @param[in] manId Manufacturer ID of the device. + MaximInterface_EXPORT static Sha256::SlaveSecretData + createSlaveSecretData(const Page & bindingPage, int bindingPageNum, + const Scratchpad & partialSecret, const RomId & romId, + const ManId & manId); + + /// Format data to hash for device authentication. + /// @param[in] pageData Data from a device memory page. + /// @param pageNum Number of the page to use data from. + /// @param[in] challenge Random challenge to prevent replay attacks. + /// @param[in] romId 1-Wire ROM ID of the device. + /// @param[in] manId Manufacturer ID of the device. + MaximInterface_EXPORT static Sha256::AuthMacData + createAuthMacData(const Page & pageData, int pageNum, + const Scratchpad & challenge, const RomId & romId, + const ManId & manId); + + /// Format datat to hash for device authentication using anonymous mode. + /// @param[in] pageData Data from a device memory page. + /// @param pageNum Number of the page to use data from. + /// @param[in] challenge Random challenge to prevent replay attacks. + /// @param[in] manId Manufacturer ID of the device. + MaximInterface_EXPORT static Sha256::AuthMacData + createAnonAuthMacData(const Page & pageData, int pageNum, + const Scratchpad & challenge, const ManId & manId); + + void setSleep(const Sleep & sleep) { this->sleep = &sleep; } + void setMaster(OneWireMaster & master) { this->master = &master; } + void setSelectRom(const SelectRom & selectRom) { + this->selectRom = selectRom; + } + + // Const member functions should not affect the state of the memory, + // block protection, or secret on the device. + + /// Read memory segment using the Read Memory command on the device. + /// @param pageNum Page number for read operation. + /// @param segmentNum Segment number within page for read operation. + /// @param[out] data Buffer to read data from the segment into. + MaximInterface_EXPORT error_code readSegment(int pageNum, int segmentNum, + Segment & data) const; + + /// Continue an in-progress readSegment operation. + /// @note A CRC16 will encountered after reading the last segment of a page. + /// @param[out] data Buffer to read data from the segment into. + MaximInterface_EXPORT error_code continueReadSegment(Segment & data) const; + + /// Write memory segment using the Write Memory command. + /// @note 1-Wire ROM selection should have already occurred. + /// @param pageNum Page number for write operation. + /// @param segmentNum Segment number within page for write operation. + /// @param[in] data Data to write to the memory segment. + MaximInterface_EXPORT error_code writeSegment(int pageNum, int segmentNum, + const Segment & data); + + /// Continue an in-progress Write Memory command. + /// @param[in] data Data to write to the memory segment. + MaximInterface_EXPORT error_code continueWriteSegment(const Segment & data); + + /// Read memory page using the Read Memory command on the device. + /// @param pageNum Page number for write operation. + /// @param[out] rdbuf Buffer to read data from the page into. + MaximInterface_EXPORT error_code readPage(int pageNum, Page & rdbuf) const; + + /// Continue an in-progress readPageOperation. + /// @param[out] rdbuf Buffer to read data from the page into. + MaximInterface_EXPORT error_code continueReadPage(Page & rdbuf) const; + + /// Perform a Compute Page MAC command on the device. + /// Read back the MAC and verify the CRC16. + /// @param pageNum Page number to use for the computation. + /// @param anon True to compute in anonymous mode where ROM ID is not used. + /// @param[out] mac The device computed MAC. + MaximInterface_EXPORT error_code computeReadPageMac(int pageNum, bool anon, + Sha256::Hash & mac) const; + + /// Update the status of a memory protection block using the + /// Write Page Protection command. + /// @param[in] Desired protection status for the block. + /// It is not possible to disable existing protections. + /// @param continuing True to continue a previous Write Page Protection command. + /// False to begin a new command. + MaximInterface_EXPORT error_code + writeBlockProtection(const BlockProtection & protection); + + /// Update the status of a memory protection block using the + /// Authenticated Write Page Protection command. + /// @param[in] newProtection New protection status to write. + /// @param[in] mac Write MAC computed for this operation. + MaximInterface_EXPORT error_code writeAuthBlockProtection( + const BlockProtection & newProtection, const Sha256::Hash & mac); + + /// Perform Load and Lock Secret command on the device. + /// @note The secret should already be stored in the scratchpad on the device. + /// @param lock Prevent further changes to the secret on the device after loading. + MaximInterface_EXPORT error_code loadSecret(bool lock); + + /// Perform a Compute and Lock Secret command on the device. + /// @param pageNum Page number to use as the binding data. + /// @param lock Prevent further changes to the secret on the device after computing. + MaximInterface_EXPORT error_code computeSecret(int pageNum, bool lock); + + /// Read the personality bytes using the Read Status command. + /// @param[out] personality Receives personality read from device. + MaximInterface_EXPORT error_code + readPersonality(Personality & personality) const; + + MaximInterface_EXPORT static const error_category & errorCategory(); + +protected: + enum Variant { DS28E15, DS28E22, DS28E25 }; + + DS28E15_22_25(const Sleep & sleep, OneWireMaster & master, + const SelectRom & selectRom) + : selectRom(selectRom), master(&master), sleep(&sleep) {} + + error_code doWriteScratchpad(const Scratchpad & data, Variant variant); + + error_code doReadScratchpad(Scratchpad & data, Variant variant) const; + + error_code doReadBlockProtection(int blockNum, BlockProtection & protection, + Variant variant) const; + + error_code doWriteAuthSegment(int pageNum, int segmentNum, + const Segment & newData, + const Sha256::Hash & mac, Variant variant); + + error_code doContinueWriteAuthSegment(const Segment & newData, + const Sha256::Hash & mac, + Variant variant); + + error_code doReadAllBlockProtection(BlockProtection * protection, + size_t protectionLen, + Variant variant) const; + + error_code doLoadSecret(bool lock, bool lowPower); + + error_code doComputeSecret(int pageNum, bool lock, bool lowPower); + +private: + enum Command { + WriteMemory = 0x55, + ReadMemory = 0xF0, + LoadAndLockSecret = 0x33, + ComputeAndLockSecret = 0x3C, + ReadWriteScratchpad = 0x0F, + ComputePageMac = 0xA5, + ReadStatus = 0xAA, + WriteBlockProtection = 0xC3, + AuthWriteMemory = 0x5A, + AuthWriteBlockProtection = 0xCC, + }; + + error_code doWriteAuthSegment(const Segment & newData, + const Sha256::Hash & mac, Variant variant, + bool continuing); + + error_code writeCommandWithCrc( + Command command, uint_least8_t parameter, + OneWireMaster::Level level = OneWireMaster::NormalLevel) const; + + SelectRom selectRom; + OneWireMaster * master; + const Sleep * sleep; +}; + +inline error_code make_error_code(DS28E15_22_25::ErrorValue e) { + return error_code(e, DS28E15_22_25::errorCategory()); +} + +inline bool operator==(DS28E15_22_25::BlockProtection lhs, + DS28E15_22_25::BlockProtection rhs) { + return lhs.statusByte() == rhs.statusByte(); +} + +inline bool operator!=(DS28E15_22_25::BlockProtection lhs, + DS28E15_22_25::BlockProtection rhs) { + return !operator==(lhs, rhs); +} + +/// Interface to the DS28EL15 (low power) authenticator. +class DS28EL15 : public DS28E15_22_25 { +public: + // DS28E15_22_25 traits + static const int memoryPages = 2; + static const int protectionBlocks = 4; + + DS28EL15(const Sleep & sleep, OneWireMaster & master, + const SelectRom & selectRom) + : DS28E15_22_25(sleep, master, selectRom) {} + + /// Perform Write Scratchpad operation on the device. + /// @param[in] data Data to write to the scratchpad. + MaximInterface_EXPORT error_code writeScratchpad(const Scratchpad & data); + + /// Perform a Read Scratchpad operation on the device. + /// @param[out] data Buffer to read data from the scratchpad into. + MaximInterface_EXPORT error_code readScratchpad(Scratchpad & data) const; + + /// Read the status of a memory protection block using the Read Status command. + /// @param blockNum Block number to to read status of. + /// @param[out] protection Receives protection status read from device. + MaximInterface_EXPORT error_code + readBlockProtection(int blockNum, BlockProtection & protection) const; + + /// Write memory segment using the Authenticated Write Memory command. + /// @param pageNum Page number for write operation. + /// @param segmentNum Segment number within page for write operation. + /// @param[in] newData New data to write to the segment. + /// @param[in] mac Write MAC computed for this operation. + MaximInterface_EXPORT error_code writeAuthSegment(int pageNum, int segmentNum, + const Segment & newData, + const Sha256::Hash & mac); + + /// Continue an in-progress Authenticated Write Memory command. + /// @param[in] newData New data to write to the segment. + /// @param[in] mac Write MAC computed for this operation. + MaximInterface_EXPORT error_code + continueWriteAuthSegment(const Segment & newData, const Sha256::Hash & mac); + + /// Read the status of all memory protection blocks using the Read Status command. + /// @param[out] protection Receives protection statuses read from device. + MaximInterface_EXPORT error_code readAllBlockProtection( + array<BlockProtection, protectionBlocks> & protection) const; +}; + +/// Interface to the DS28E15 authenticator. +class DS28E15 : public DS28EL15 { +public: + DS28E15(const Sleep & sleep, OneWireMaster & master, + const SelectRom & selectRom) + : DS28EL15(sleep, master, selectRom) {} + + /// Perform Load and Lock Secret command on the device. + /// @note The secret should already be stored in the scratchpad on the device. + /// @param lock Prevent further changes to the secret on the device after loading. + MaximInterface_EXPORT error_code loadSecret(bool lock); + + /// Perform a Compute and Lock Secret command on the device. + /// @param pageNum Page number to use as the binding data. + /// @param lock Prevent further changes to the secret on the device after computing. + MaximInterface_EXPORT error_code computeSecret(int pageNum, bool lock); +}; + +/// Interface to the DS28EL22 (low power) authenticator. +class DS28EL22 : public DS28E15_22_25 { +public: + // DS28E15_22_25 traits + static const int memoryPages = 8; + static const int protectionBlocks = 4; + + DS28EL22(const Sleep & sleep, OneWireMaster & master, + const SelectRom & selectRom) + : DS28E15_22_25(sleep, master, selectRom) {} + + /// Perform Write Scratchpad operation on the device. + /// @param[in] data Data to write to the scratchpad. + MaximInterface_EXPORT error_code writeScratchpad(const Scratchpad & data); + + /// Perform a Read Scratchpad operation on the device. + /// @param[out] data Buffer to read data from the scratchpad into. + MaximInterface_EXPORT error_code readScratchpad(Scratchpad & data) const; + + /// Read the status of a memory protection block using the Read Status command. + /// @param blockNum Block number to to read status of. + /// @param[out] protection Receives protection status read from device. + MaximInterface_EXPORT error_code + readBlockProtection(int blockNum, BlockProtection & protection) const; + + /// Write memory segment using the Authenticated Write Memory command. + /// @param pageNum Page number for write operation. + /// @param segmentNum Segment number within page for write operation. + /// @param[in] newData New data to write to the segment. + /// @param[in] mac Write MAC computed for this operation. + MaximInterface_EXPORT error_code writeAuthSegment(int pageNum, int segmentNum, + const Segment & newData, + const Sha256::Hash & mac); + + /// Continue an in-progress Authenticated Write Memory command. + /// @param[in] newData New data to write to the segment. + /// @param[in] mac Write MAC computed for this operation. + MaximInterface_EXPORT error_code + continueWriteAuthSegment(const Segment & newData, const Sha256::Hash & mac); + + /// Read the status of all memory protection blocks using the Read Status command. + /// @param[out] protection Receives protection statuses read from device. + MaximInterface_EXPORT error_code readAllBlockProtection( + array<BlockProtection, protectionBlocks> & protection) const; +}; + +/// Interface to the DS28E22 authenticator. +class DS28E22 : public DS28EL22 { +public: + DS28E22(const Sleep & sleep, OneWireMaster & master, + const SelectRom & selectRom) + : DS28EL22(sleep, master, selectRom) {} + + /// Perform Load and Lock Secret command on the device. + /// @note The secret should already be stored in the scratchpad on the device. + /// @param lock Prevent further changes to the secret on the device after loading. + MaximInterface_EXPORT error_code loadSecret(bool lock); + + /// Perform a Compute and Lock Secret command on the device. + /// @param pageNum Page number to use as the binding data. + /// @param lock Prevent further changes to the secret on the device after computing. + MaximInterface_EXPORT error_code computeSecret(int pageNum, bool lock); +}; + +/// Interface to the DS28EL25 (low power) authenticator. +class DS28EL25 : public DS28E15_22_25 { +public: + // DS28E15_22_25 traits + static const int memoryPages = 16; + static const int protectionBlocks = 8; + + DS28EL25(const Sleep & sleep, OneWireMaster & master, + const SelectRom & selectRom) + : DS28E15_22_25(sleep, master, selectRom) {} + + /// Perform Write Scratchpad operation on the device. + /// @param[in] data Data to write to the scratchpad. + MaximInterface_EXPORT error_code writeScratchpad(const Scratchpad & data); + + /// Perform a Read Scratchpad operation on the device. + /// @param[out] data Buffer to read data from the scratchpad into. + MaximInterface_EXPORT error_code readScratchpad(Scratchpad & data) const; + + /// Read the status of a memory protection block using the Read Status command. + /// @param blockNum Block number to to read status of. + /// @param[out] protection Receives protection status read from device. + MaximInterface_EXPORT error_code + readBlockProtection(int blockNum, BlockProtection & protection) const; + + /// Write memory segment using the Authenticated Write Memory command. + /// @param pageNum Page number for write operation. + /// @param segmentNum Segment number within page for write operation. + /// @param[in] newData New data to write to the segment. + /// @param[in] mac Write MAC computed for this operation. + MaximInterface_EXPORT error_code writeAuthSegment(int pageNum, int segmentNum, + const Segment & newData, + const Sha256::Hash & mac); + + /// Continue an in-progress Authenticated Write Memory command. + /// @param[in] newData New data to write to the segment. + /// @param[in] mac Write MAC computed for this operation. + MaximInterface_EXPORT error_code + continueWriteAuthSegment(const Segment & newData, const Sha256::Hash & mac); + + /// Read the status of all memory protection blocks using the Read Status command. + /// @param[out] protection Receives protection statuses read from device. + MaximInterface_EXPORT error_code readAllBlockProtection( + array<BlockProtection, protectionBlocks> & protection) const; +}; + +/// Interface to the DS28E25 authenticator. +class DS28E25 : public DS28EL25 { +public: + DS28E25(const Sleep & sleep, OneWireMaster & master, + const SelectRom & selectRom) + : DS28EL25(sleep, master, selectRom) {} + + /// Perform Load and Lock Secret command on the device. + /// @note The secret should already be stored in the scratchpad on the device. + /// @param lock Prevent further changes to the secret on the device after loading. + MaximInterface_EXPORT error_code loadSecret(bool lock); + + /// Perform a Compute and Lock Secret command on the device. + /// @param pageNum Page number to use as the binding data. + /// @param lock Prevent further changes to the secret on the device after computing. + MaximInterface_EXPORT error_code computeSecret(int pageNum, bool lock); +}; + +} // namespace MaximInterface + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Devices/DS28E17.cpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,279 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#include <stddef.h> +#include <MaximInterface/Links/OneWireMaster.hpp> +#include <MaximInterface/Utilities/crc.hpp> +#include <MaximInterface/Utilities/Error.hpp> +#include "DS28E17.hpp" + +namespace MaximInterface { + +error_code DS28E17::writeDataWithStop(uint_least8_t I2C_addr, + const uint_least8_t * data, + size_t data_len, + uint_least8_t * wr_status) { + return sendPacket(WriteDataWithStopCmd, &I2C_addr, data, data_len, NULL, 0, + wr_status); +} + +error_code DS28E17::writeDataNoStop(uint_least8_t I2C_addr, + const uint_least8_t * data, size_t data_len, + uint_least8_t * wr_status) { + return sendPacket(WriteDataNoStopCmd, &I2C_addr, data, data_len, NULL, 0, + wr_status); +} + +error_code DS28E17::writeDataOnly(const uint_least8_t * data, size_t data_len, + uint_least8_t * wr_status) { + return sendPacket(WriteDataOnlyCmd, NULL, data, data_len, NULL, 0, wr_status); +} + +error_code DS28E17::writeDataOnlyWithStop(const uint_least8_t * data, + size_t data_len, + uint_least8_t * wr_status) { + return sendPacket(WriteDataOnlyWithStopCmd, NULL, data, data_len, NULL, 0, + wr_status); +} + +error_code DS28E17::writeReadDataWithStop(uint_least8_t I2C_addr, + const uint_least8_t * write_data, + size_t write_data_len, + uint_least8_t * read_data, + size_t read_data_len, + uint_least8_t * wr_status) { + return sendPacket(WriteReadDataWithStopCmd, &I2C_addr, write_data, + write_data_len, read_data, read_data_len, wr_status); +} + +error_code DS28E17::readDataWithStop(uint_least8_t I2C_addr, + uint_least8_t * data, size_t data_len) { + return sendPacket(ReadDataWithStopCmd, &I2C_addr, NULL, 0, data, data_len, + NULL); +} + +error_code DS28E17::writeConfigReg(I2CSpeed speed) { + error_code result = selectRom(*master); + if (!result) { + // Send CMD and Data + const uint_least8_t send_block[] = {WriteConfigurationCmd, + static_cast<uint_least8_t>(speed)}; + result = master->writeBlock(send_block, + sizeof(send_block) / sizeof(send_block[0])); + } + return result; +} + +error_code DS28E17::readConfigReg(I2CSpeed & speed) { + error_code result = selectRom(*master); + if (!result) { + // Send CMD and receive Data + result = master->writeByte(ReadConfigurationCmd); + if (!result) { + uint_least8_t config; + result = master->readByte(config); + if (!result) { + switch (config) { + case Speed100kHz: + case Speed400kHz: + case Speed900kHz: + speed = static_cast<I2CSpeed>(config); + break; + + default: + result = make_error_code(OutOfRangeError); + break; + } + } + } + } + return result; +} + +error_code DS28E17::enableSleepMode() { + error_code result = selectRom(*master); + if (!result) { + // Send CMD + result = master->writeByte(EnableSleepModeCmd); + } + return result; +} + +error_code DS28E17::readDeviceRevision(uint_least8_t & rev) { + error_code result = selectRom(*master); + if (!result) { + // Send CMD and receive Data + result = master->writeByte(ReadDeviceRevisionCmd); + if (!result) { + result = master->readByte(rev); + } + } + return result; +} + +error_code DS28E17::sendPacket(Command command, const uint_least8_t * I2C_addr, + const uint_least8_t * write_data, + size_t write_data_len, uint_least8_t * read_data, + size_t read_data_len, + uint_least8_t * wr_status) { + const int pollLimit = 10000; + const size_t minDataLen = 1; + const size_t maxDataLen = 255; + + if ((write_data && + (write_data_len < minDataLen || write_data_len > maxDataLen)) || + (read_data && + (read_data_len < minDataLen || read_data_len > maxDataLen))) { + return make_error_code(OutOfRangeError); + } + + error_code result = selectRom(*master); + if (result) { + return result; + } + uint_fast16_t crc16 = calculateCrc16(command); + result = master->writeByte(command); + if (result) { + return result; + } + if (I2C_addr) { + crc16 = calculateCrc16(*I2C_addr, crc16); + result = master->writeByte(*I2C_addr); + if (result) { + return result; + } + } + if (write_data) { + crc16 = calculateCrc16(static_cast<uint_fast8_t>(write_data_len), crc16); + result = master->writeByte(static_cast<uint_least8_t>(write_data_len)); + if (result) { + return result; + } + crc16 = calculateCrc16(write_data, write_data_len, crc16); + result = master->writeBlock(write_data, write_data_len); + if (result) { + return result; + } + } + if (read_data) { + crc16 = calculateCrc16(static_cast<uint_fast8_t>(read_data_len), crc16); + result = master->writeByte(static_cast<uint_least8_t>(read_data_len)); + if (result) { + return result; + } + } + crc16 ^= 0xFFFFU; + const uint_least8_t crc16Bytes[] = {static_cast<uint_least8_t>(crc16), + static_cast<uint_least8_t>(crc16 >> 8)}; + result = master->writeBlock(crc16Bytes, + sizeof(crc16Bytes) / sizeof(crc16Bytes[0])); + if (result) { + return result; + } + // Poll for Zero 1-Wire bit and return if an error occurs + int poll_count = 0; + bool recvbit; + do { + if (poll_count++ < pollLimit) { + return make_error_code(TimeoutError); + } + result = master->readBit(recvbit); + if (result) { + return result; + } + } while (recvbit); + uint_least8_t status; + result = master->readByte(status); + if (result) { + return result; + } + if ((status & 0x1) == 0x1) { + return make_error_code(InvalidCrc16Error); + } + if ((status & 0x2) == 0x2) { + return make_error_code(AddressNackError); + } + if ((status & 0x8) == 0x8) { + return make_error_code(InvalidStartError); + } + if (write_data) { + result = master->readByte(status); + if (result) { + return result; + } + if (wr_status) { + *wr_status = status; + } + if (status != 0) { + return make_error_code(WriteNackError); + } + } + if (read_data) { + result = master->readBlock(read_data, read_data_len); + } + return result; +} + +const error_category & DS28E17::errorCategory() { + static class : public error_category { + public: + virtual const char * name() const { return "DS28E17"; } + + virtual std::string message(int condition) const { + switch (condition) { + case TimeoutError: + return "Timeout Error"; + + case OutOfRangeError: + return "Out of Range Error"; + + case InvalidCrc16Error: + return "Invalid CRC16 Error"; + + case AddressNackError: + return "Address Nack Error"; + + case InvalidStartError: + return "Invalid Start Error"; + + case WriteNackError: + return "Write Nack Error"; + + default: + return defaultErrorMessage(condition); + } + } + } instance; + return instance; +} + +} // namespace MaximInterface
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Devices/DS28E17.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,212 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_DS28E17 +#define MaximInterface_DS28E17 + +#include <stdint.h> +#include <MaximInterface/Links/SelectRom.hpp> +#include <MaximInterface/Utilities/Export.h> + +namespace MaximInterface { + +/// DS28E17 1-Wire®-to-I2C Master Bridge +/// @details The DS28E17 is a 1-Wire slave to I2C master bridge +/// device that interfaces directly to I2C slaves at standard +/// (100kHz max) or fast (400kHz max). Data transfers serially by +/// means of the 1-Wire® protocol, which requires only a single data +/// lead and a ground return. Every DS28E17 is guaranteed to have a +/// unique 64-bit ROM registration number that serves as a node +/// address in the 1-Wire network. Multiple DS28E17 devices can +/// coexist with other devices in the 1-Wire network and be accessed +/// individually without affecting other devices. The DS28E17 allows +/// using complex I2C devices such as display controllers, ADCs, DACs, +/// I2C sensors, etc. in a 1-Wire environment. Each self-timed DS28E17 +/// provides 1-Wire access for a single I2C interface. +class DS28E17 { +public: + enum ErrorValue { + TimeoutError = 1, + OutOfRangeError, + InvalidCrc16Error, + AddressNackError, + InvalidStartError, + WriteNackError + }; + + enum I2CSpeed { Speed100kHz, Speed400kHz, Speed900kHz }; + + DS28E17(OneWireMaster & master, const SelectRom & selectRom) + : selectRom(selectRom), master(&master) {} + + void setMaster(OneWireMaster & master) { this->master = &master; } + void setSelectRom(const SelectRom & selectRom) { + this->selectRom = selectRom; + } + + /// Write Data With Stop command. + /// @details Output on I2C: S, Address + Write, Write Data [1-255], P + /// @param[in] I2C_addr + /// I2C slave address. The least significant bit of the I2C + /// address is automatically cleared by the command. + /// @param[in] data I2C data to write. + /// @param[in] data_len Length of data. Valid from 1-255. + /// @param[out] wr_status + /// Indicates which write byte NACK’d. A value of 00h indicates all bytes + /// were acknowledged by the slave. A non-zero value indicates the byte number + /// that NACK’d. May be set to NULL. + MaximInterface_EXPORT error_code + writeDataWithStop(uint_least8_t I2C_addr, const uint_least8_t * data, + size_t data_len, uint_least8_t * wr_status = NULL); + + /// Write Data No Stop command. + /// @details Output on I2C: S, Address + Write, Write Data [1-255] + /// @param[in] I2C_addr + /// I2C slave address. The least significant bit of the I2C address + /// is automatically cleared by the command. + /// @param[in] data I2C data to write. + /// @param[in] data_len Length of data. Valid from 1-255. + /// @param[out] wr_status + /// Indicates which write byte NACK’d. A value of 00h indicates all bytes + /// were acknowledged by the slave. A non-zero value indicates the byte number + /// that NACK’d. May be set to NULL. + MaximInterface_EXPORT error_code + writeDataNoStop(uint_least8_t I2C_addr, const uint_least8_t * data, + size_t data_len, uint_least8_t * wr_status = NULL); + + /// Write Data Only command. + /// @details Output on I2C: Write Data [1-255] + /// @param[in] data I2C data to write. + /// @param[in] data_len Length of data. Valid from 1-255. + /// @param[out] wr_status + /// Indicates which write byte NACK’d. A value of 00h indicates all bytes + /// were acknowledged by the slave. A non-zero value indicates the byte number + /// that NACK’d. May be set to NULL. + MaximInterface_EXPORT error_code + writeDataOnly(const uint_least8_t * data, size_t data_len, + uint_least8_t * wr_status = NULL); + + /// Write Data Only With Stop command. + /// @details Output on I2C: Write Data [1-255], P + /// @param[in] data I2C data to write. + /// @param[in] data_len Length of data. Valid from 1-255. + /// @param[out] wr_status + /// Indicates which write byte NACK’d. A value of 00h indicates all bytes + /// were acknowledged by the slave. A non-zero value indicates the byte number + /// that NACK’d. May be set to NULL. + MaximInterface_EXPORT error_code + writeDataOnlyWithStop(const uint_least8_t * data, size_t data_len, + uint_least8_t * wr_status = NULL); + + /// Write, Read Data With Stop command. + /// @details Output on I2C: + /// S, Slave Address + Write, Write Data [1-255], + /// Sr, Address + Read, Read Data [1-255], P (NACK last read byte) + /// @param[in] I2C_addr + /// I2C slave address. The least significant bit of the I2C address + /// is automatically cleared and set by the command. + /// @param[in] write_data I2C data to write. + /// @param[in] write_data_len Length of write_data. Valid from 1-255. + /// @param[out] read_data I2C data that was read. + /// @param[in] read_data_len Length of read_data. Valid from 1-255. + /// @param[out] wr_status + /// Indicates which write byte NACK’d. A value of 00h indicates all bytes + /// were acknowledged by the slave. A non-zero value indicates the byte number + /// that NACK’d. May be set to NULL. + MaximInterface_EXPORT error_code writeReadDataWithStop( + uint_least8_t I2C_addr, const uint_least8_t * write_data, + size_t write_data_len, uint_least8_t * read_data, size_t read_data_len, + uint_least8_t * wr_status = NULL); + + /// Read Data With Stop command. + /// @details Output on I2C: + /// S, Slave Address + Read, Read Data [1-255], P (NACK last read byte) + /// @param[in] I2C_addr + /// I2C slave address. The least significant bit of the I2C address + /// is automatically set by the command. + /// @param[out] data I2C data that was read. + /// @param[in] data_len Length of data. Valid from 1-255. + MaximInterface_EXPORT error_code readDataWithStop(uint_least8_t I2C_addr, + uint_least8_t * data, + size_t data_len); + + /// Write to Configuration Register of DS28E17. + MaximInterface_EXPORT error_code writeConfigReg(I2CSpeed speed); + + /// Read the Configuration Register of DS28E17. + /// @param[out] speed Speed read from configuration register. + MaximInterface_EXPORT error_code readConfigReg(I2CSpeed & speed); + + /// The Enable Sleep Mode command puts the device into a low current mode. + /// @details All 1-Wire communication is ignored until woken up. Immediately + /// after the command, the device monitors the WAKEUP input pin and exits + /// sleep mode on a rising edge. + MaximInterface_EXPORT error_code enableSleepMode(); + + /// Read the Device Revision of DS28E17. + /// @details The upper nibble is the major revision, + /// and the lower nibble is the minor revision. + /// @param[out] rev Device Revision. + MaximInterface_EXPORT error_code readDeviceRevision(uint_least8_t & rev); + + MaximInterface_EXPORT static const error_category & errorCategory(); + +private: + enum Command { + WriteDataWithStopCmd = 0x4B, + WriteDataNoStopCmd = 0x5A, + WriteDataOnlyCmd = 0x69, + WriteDataOnlyWithStopCmd = 0x78, + ReadDataWithStopCmd = 0x87, + WriteReadDataWithStopCmd = 0x2D, + WriteConfigurationCmd = 0xD2, + ReadConfigurationCmd = 0xE1, + EnableSleepModeCmd = 0x1E, + ReadDeviceRevisionCmd = 0xC3 + }; + + error_code sendPacket(Command command, const uint_least8_t * I2C_addr, + const uint_least8_t * write_data, size_t write_data_len, + uint_least8_t * read_data, size_t read_data_len, + uint_least8_t * wr_status); + + SelectRom selectRom; + OneWireMaster * master; +}; + +inline error_code make_error_code(DS28E17::ErrorValue e) { + return error_code(e, DS28E17::errorCategory()); +} + +} // namespace MaximInterface + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Devices/DS9400.cpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,75 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#include "DS9400.hpp" + +namespace MaximInterface { + +error_code DS9400::start() { return uart->writeByte('S'); } + +error_code DS9400::start(uint_least8_t address) { + error_code result = start(); + if (!result) { + result = writeByte(address); + } + return result; +} + +error_code DS9400::stop() { return uart->writeByte('P'); } + +error_code DS9400::writeByte(uint_least8_t data) { + const uint_least8_t packet[] = {'Q', data}; + error_code result = uart->clearReadBuffer(); + if (!result) { + result = uart->writeBlock(packet, sizeof(packet) / sizeof(packet[0])); + if (!result) { + result = uart->readByte(data); + if (!result && data != 0) { + result = make_error_code(I2CMaster::NackError); + } + } + } + return result; +} + +error_code DS9400::readByte(AckStatus status, uint_least8_t & data) { + error_code result = uart->clearReadBuffer(); + if (!result) { + result = uart->writeByte(status == Ack ? 'R' : 'N'); + if (!result) { + result = uart->readByte(data); + } + } + return result; +} + +} // namespace MaximInterface \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Devices/DS9400.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,61 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_DS9400 +#define MaximInterface_DS9400 + +#include <MaximInterface/Links/I2CMaster.hpp> +#include <MaximInterface/Links/Uart.hpp> +#include <MaximInterface/Utilities/Export.h> + +namespace MaximInterface { + +class DS9400 : public I2CMaster { +public: + explicit DS9400(Uart & uart) : uart(&uart) {} + + void setUart(Uart & uart) { this->uart = &uart; } + + MaximInterface_EXPORT error_code start(); + MaximInterface_EXPORT virtual error_code start(uint_least8_t address); + MaximInterface_EXPORT virtual error_code stop(); + MaximInterface_EXPORT virtual error_code writeByte(uint_least8_t data); + MaximInterface_EXPORT virtual error_code readByte(AckStatus status, + uint_least8_t & data); + +private: + Uart * uart; +}; + +} // namespace MaximInterface + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Links/I2CMaster.cpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,104 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#include <MaximInterface/Utilities/Error.hpp> +#include "I2CMaster.hpp" + +namespace MaximInterface { + +error_code I2CMaster::writeBlock(const uint_least8_t * data, size_t dataLen) { + error_code result; + for (size_t i = 0; (i < dataLen) && !result; i++) { + result = writeByte(data[i]); + } + return result; +} + +error_code I2CMaster::writePacket(uint_least8_t address, + const uint_least8_t * data, size_t dataLen, + bool sendStop) { + error_code result = start(address & 0xFE); + if (!result) { + result = writeBlock(data, dataLen); + } + if (sendStop) { + error_code stopResult = stop(); + if (!result) { + result = stopResult; + } + } + return result; +} + +error_code I2CMaster::readBlock(AckStatus status, uint_least8_t * data, + size_t dataLen) { + error_code result; + for (size_t i = 0; (i < dataLen) && !result; i++) { + result = readByte(i == (dataLen - 1) ? status : Ack, data[i]); + } + return result; +} + +error_code I2CMaster::readPacket(uint_least8_t address, uint_least8_t * data, + size_t dataLen, bool sendStop) { + error_code result = start(address | 0x01); + if (!result) { + result = readBlock(Nack, data, dataLen); + } + if (sendStop) { + error_code stopResult = stop(); + if (!result) { + result = stopResult; + } + } + return result; +} + +const error_category & I2CMaster::errorCategory() { + static class : public error_category { + public: + virtual const char * name() const { return "I2CMaster"; } + + virtual std::string message(int condition) const { + switch (condition) { + case NackError: + return "Nack Error"; + + default: + return defaultErrorMessage(condition); + } + } + } instance; + return instance; +} + +} // namespace MaximInterface \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Links/I2CMaster.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,89 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_I2CMaster +#define MaximInterface_I2CMaster + +#include <stddef.h> +#include <stdint.h> +#include <MaximInterface/Utilities/Export.h> +#include <MaximInterface/Utilities/system_error.hpp> + +namespace MaximInterface { + +class I2CMaster { +public: + enum ErrorValue { + NackError = 1 ///< Transaction stopped due to a NACK from the slave device. + }; + + enum AckStatus { Ack = 1, Nack = 0 }; + + virtual ~I2CMaster() {} + + virtual error_code start(uint_least8_t address) = 0; + virtual error_code stop() = 0; + virtual error_code writeByte(uint_least8_t data) = 0; + MaximInterface_EXPORT virtual error_code + writeBlock(const uint_least8_t * data, size_t dataLen); + MaximInterface_EXPORT virtual error_code + writePacket(uint_least8_t address, const uint_least8_t * data, size_t dataLen, + bool sendStop); + error_code writePacket(uint_least8_t address, const uint_least8_t * data, + size_t dataLen) { + return writePacket(address, data, dataLen, true); + } + virtual error_code readByte(AckStatus status, uint_least8_t & data) = 0; + MaximInterface_EXPORT virtual error_code + readBlock(AckStatus status, uint_least8_t * data, size_t dataLen); + MaximInterface_EXPORT virtual error_code readPacket(uint_least8_t address, + uint_least8_t * data, + size_t dataLen, + bool sendStop); + error_code readPacket(uint_least8_t address, uint_least8_t * data, + size_t dataLen) { + return readPacket(address, data, dataLen, true); + } + + MaximInterface_EXPORT static const error_category & errorCategory(); +}; + +inline error_code make_error_code(I2CMaster::ErrorValue e) { + return error_code(e, I2CMaster::errorCategory()); +} +inline error_condition make_error_condition(I2CMaster::ErrorValue e) { + return error_condition(e, I2CMaster::errorCategory()); +} + +} // namespace MaximInterface + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Links/I2CMasterDecorator.cpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,74 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#include "I2CMasterDecorator.hpp" + +namespace MaximInterface { + +error_code I2CMasterDecorator::start(uint_least8_t address) { + return i2c->start(address); +} + +error_code I2CMasterDecorator::stop() { return i2c->stop(); } + +error_code I2CMasterDecorator::writeByte(uint_least8_t data) { + return i2c->writeByte(data); +} + +error_code I2CMasterDecorator::writeBlock(const uint_least8_t * data, + size_t dataLen) { + return i2c->writeBlock(data, dataLen); +} + +error_code I2CMasterDecorator::writePacket(uint_least8_t address, + const uint_least8_t * data, + size_t dataLen, bool sendStop) { + return i2c->writePacket(address, data, dataLen, sendStop); +} + +error_code I2CMasterDecorator::readByte(AckStatus status, + uint_least8_t & data) { + return i2c->readByte(status, data); +} + +error_code I2CMasterDecorator::readBlock(AckStatus status, uint_least8_t * data, + size_t dataLen) { + return i2c->readBlock(status, data, dataLen); +} + +error_code I2CMasterDecorator::readPacket(uint_least8_t address, + uint_least8_t * data, size_t dataLen, + bool sendStop) { + return i2c->readPacket(address, data, dataLen, sendStop); +} + +} // namespace MaximInterface \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Links/I2CMasterDecorator.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,71 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_I2CMasterDecorator +#define MaximInterface_I2CMasterDecorator + +#include <MaximInterface/Utilities/Export.h> +#include "I2CMaster.hpp" + +namespace MaximInterface { + +class I2CMasterDecorator : public I2CMaster { +protected: + explicit I2CMasterDecorator(I2CMaster & i2c) : i2c(&i2c) {} + +public: + void setI2CMaster(I2CMaster & i2c) { this->i2c = &i2c; } + + MaximInterface_EXPORT virtual error_code start(uint_least8_t address); + MaximInterface_EXPORT virtual error_code stop(); + MaximInterface_EXPORT virtual error_code writeByte(uint_least8_t data); + MaximInterface_EXPORT virtual error_code + writeBlock(const uint_least8_t * data, size_t dataLen); + MaximInterface_EXPORT virtual error_code + writePacket(uint_least8_t address, const uint_least8_t * data, size_t dataLen, + bool sendStop); + MaximInterface_EXPORT virtual error_code readByte(AckStatus status, + uint_least8_t & data); + MaximInterface_EXPORT virtual error_code + readBlock(AckStatus status, uint_least8_t * data, size_t dataLen); + MaximInterface_EXPORT virtual error_code readPacket(uint_least8_t address, + uint_least8_t * data, + size_t dataLen, + bool sendStop); + +private: + I2CMaster * i2c; +}; + +} // namespace MaximInterface + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Links/LoggingI2CMaster.cpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,141 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#include <utility> +#include <MaximInterface/Utilities/HexConversions.hpp> +#include "LoggingI2CMaster.hpp" + +using std::string; + +namespace MaximInterface { + +static const char startString[] = "S "; +static const char stopString[] = "P"; + +static string formatDataString(const uint_least8_t * data, size_t dataSize, + bool read) { + string dataBuilder; + for (size_t i = 0; i < dataSize; i++) { + if (read) { + dataBuilder.append(1, '['); + } + dataBuilder.append(byteArrayToHexString(data + i, 1)); + if (read) { + dataBuilder.append(1, ']'); + } + dataBuilder.append(1, ' '); + } + return dataBuilder; +} + +void LoggingI2CMaster::tryWriteMessage() { + if (writeMessage) { + writeMessage(messageBuilder); + } + messageBuilder.clear(); +} + +error_code LoggingI2CMaster::start(uint_least8_t address) { + messageBuilder.append(startString); + messageBuilder.append(formatDataString(&address, 1, false)); + return I2CMasterDecorator::start(address); +} + +error_code LoggingI2CMaster::stop() { + messageBuilder.append(stopString); + tryWriteMessage(); + return I2CMasterDecorator::stop(); +} + +error_code LoggingI2CMaster::writeByte(uint_least8_t data) { + messageBuilder.append(formatDataString(&data, 1, false)); + return I2CMasterDecorator::writeByte(data); +} + +error_code LoggingI2CMaster::writeBlock(const uint_least8_t * data, + size_t dataLen) { + messageBuilder.append(formatDataString(data, dataLen, false)); + return I2CMasterDecorator::writeBlock(data, dataLen); +} + +error_code LoggingI2CMaster::writePacket(uint_least8_t address, + const uint_least8_t * data, + size_t dataLen, bool sendStop) { + messageBuilder.append(startString); + messageBuilder.append(formatDataString(&address, 1, false)); + error_code result = + I2CMasterDecorator::writePacket(address, data, dataLen, sendStop); + if (!result) { + messageBuilder.append(formatDataString(data, dataLen, false)); + } + if (sendStop || result) { + messageBuilder.append(stopString); + tryWriteMessage(); + } + return result; +} + +error_code LoggingI2CMaster::readByte(AckStatus status, uint_least8_t & data) { + error_code result = I2CMasterDecorator::readByte(status, data); + if (!result) { + messageBuilder.append(formatDataString(&data, 1, true)); + } + return result; +} + +error_code LoggingI2CMaster::readBlock(AckStatus status, uint_least8_t * data, + size_t dataLen) { + error_code result = I2CMasterDecorator::readBlock(status, data, dataLen); + if (!result) { + messageBuilder.append(formatDataString(data, dataLen, true)); + } + return result; +} + +error_code LoggingI2CMaster::readPacket(uint_least8_t address, + uint_least8_t * data, size_t dataLen, + bool sendStop) { + messageBuilder.append(startString); + messageBuilder.append(formatDataString(&address, 1, false)); + error_code result = + I2CMasterDecorator::readPacket(address, data, dataLen, sendStop); + if (!result) { + messageBuilder.append(formatDataString(data, dataLen, true)); + } + if (sendStop || result) { + messageBuilder.append(stopString); + tryWriteMessage(); + } + return result; +} + +} // namespace MaximInterface \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Links/LoggingI2CMaster.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,79 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_LoggingI2CMaster +#define MaximInterface_LoggingI2CMaster + +#include <string> +#include <MaximInterface/Links/I2CMasterDecorator.hpp> +#include <MaximInterface/Utilities/Export.h> +#include <MaximInterface/Utilities/WriteMessage.hpp> + +namespace MaximInterface { + +class LoggingI2CMaster : public I2CMasterDecorator { +public: + explicit LoggingI2CMaster( + I2CMaster & i2c, const WriteMessage & writeMessage = WriteMessage()) + : I2CMasterDecorator(i2c), writeMessage(writeMessage), messageBuilder() {} + + void setWriteMessage(const WriteMessage & writeMessage) { + this->writeMessage = writeMessage; + } + + MaximInterface_EXPORT virtual error_code start(uint_least8_t address); + MaximInterface_EXPORT virtual error_code stop(); + MaximInterface_EXPORT virtual error_code writeByte(uint_least8_t data); + MaximInterface_EXPORT virtual error_code + writeBlock(const uint_least8_t * data, size_t dataLen); + MaximInterface_EXPORT virtual error_code + writePacket(uint_least8_t address, const uint_least8_t * data, size_t dataLen, + bool sendStop); + MaximInterface_EXPORT virtual error_code readByte(AckStatus status, + uint_least8_t & data); + MaximInterface_EXPORT virtual error_code + readBlock(AckStatus status, uint_least8_t * data, size_t dataLen); + MaximInterface_EXPORT virtual error_code readPacket(uint_least8_t address, + uint_least8_t * data, + size_t dataLen, + bool sendStop); + +private: + void tryWriteMessage(); + + WriteMessage writeMessage; + std::string messageBuilder; +}; + +} // namespace MaximInterface + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Links/LoggingOneWireMaster.cpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,147 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#include <MaximInterface/Utilities/HexConversions.hpp> +#include "LoggingOneWireMaster.hpp" + +using std::string; + +namespace MaximInterface { + +static const char strongLevelString[] = "<SP_ON>"; + +static string formatDataString(const uint_least8_t * data, size_t dataSize, + bool read) { + string dataBuilder; + for (size_t i = 0; i < dataSize; i++) { + if (read) { + dataBuilder.append(1, '['); + } + dataBuilder.append(byteArrayToHexString(data + i, 1)); + if (read) { + dataBuilder.append(1, ']'); + } + dataBuilder.append(1, ' '); + } + return dataBuilder; +} + +void LoggingOneWireMaster::tryWriteMessage(const std::string & message) { + if (writeMessage) { + writeMessage(message); + } +} + +error_code LoggingOneWireMaster::reset() { + error_code result = OneWireMasterDecorator::reset(); + tryWriteMessage(!result ? "RP" : "RN"); + return result; +} + +error_code LoggingOneWireMaster::writeByteSetLevel(uint_least8_t sendByte, + Level afterLevel) { + tryWriteMessage(formatDataString(&sendByte, 1, false)); + if (afterLevel == StrongLevel) { + tryWriteMessage(strongLevelString); + } + return OneWireMasterDecorator::writeByteSetLevel(sendByte, afterLevel); +} + +error_code LoggingOneWireMaster::readByteSetLevel(uint_least8_t & recvByte, + Level afterLevel) { + error_code result = + OneWireMasterDecorator::readByteSetLevel(recvByte, afterLevel); + if (!result) { + tryWriteMessage(formatDataString(&recvByte, 1, true)); + if (afterLevel == StrongLevel) { + tryWriteMessage(strongLevelString); + } + } + return result; +} + +error_code LoggingOneWireMaster::writeBlock(const uint_least8_t * sendBuf, + size_t sendLen) { + tryWriteMessage(formatDataString(sendBuf, sendLen, false)); + return OneWireMasterDecorator::writeBlock(sendBuf, sendLen); +} + +error_code LoggingOneWireMaster::readBlock(uint_least8_t * recvBuf, + size_t recvLen) { + error_code result = OneWireMasterDecorator::readBlock(recvBuf, recvLen); + if (!result) { + tryWriteMessage(formatDataString(recvBuf, recvLen, true)); + } + return result; +} + +error_code LoggingOneWireMaster::setSpeed(Speed newSpeed) { + error_code result = OneWireMasterDecorator::setSpeed(newSpeed); + if (!result) { + string newSpeedString; + switch (newSpeed) { + case StandardSpeed: + newSpeedString = "<STD>"; + break; + + case OverdriveSpeed: + newSpeedString = "<OVR>"; + break; + } + if (!newSpeedString.empty()) { + tryWriteMessage(newSpeedString); + } + } + return result; +} + +error_code LoggingOneWireMaster::setLevel(Level newLevel) { + error_code result = OneWireMasterDecorator::setLevel(newLevel); + if (!result) { + string newLevelString; + switch (newLevel) { + case NormalLevel: + newLevelString = "<SP_OFF>"; + break; + + case StrongLevel: + newLevelString = strongLevelString; + break; + } + if (!newLevelString.empty()) { + tryWriteMessage(newLevelString); + } + } + return result; +} + +} // namespace MaximInterface \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Links/LoggingOneWireMaster.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,74 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_LoggingOneWireMaster +#define MaximInterface_LoggingOneWireMaster + +#include <string> +#include <MaximInterface/Links/OneWireMasterDecorator.hpp> +#include <MaximInterface/Utilities/Export.h> +#include <MaximInterface/Utilities/WriteMessage.hpp> + +namespace MaximInterface { + +class LoggingOneWireMaster : public OneWireMasterDecorator { +public: + explicit LoggingOneWireMaster( + OneWireMaster & master, + const WriteMessage & writeMessage = WriteMessage()) + : OneWireMasterDecorator(master), writeMessage(writeMessage) {} + + void setWriteMessage(const WriteMessage & writeMessage) { + this->writeMessage = writeMessage; + } + + MaximInterface_EXPORT virtual error_code reset(); + MaximInterface_EXPORT virtual error_code + writeByteSetLevel(uint_least8_t sendByte, Level afterLevel); + MaximInterface_EXPORT virtual error_code + readByteSetLevel(uint_least8_t & recvByte, Level afterLevel); + MaximInterface_EXPORT virtual error_code + writeBlock(const uint_least8_t * sendBuf, size_t sendLen); + MaximInterface_EXPORT virtual error_code readBlock(uint_least8_t * recvBuf, + size_t recvLen); + MaximInterface_EXPORT virtual error_code setSpeed(Speed newSpeed); + MaximInterface_EXPORT virtual error_code setLevel(Level newLevel); + +private: + void tryWriteMessage(const std::string & message); + + WriteMessage writeMessage; +}; + +} // namespace MaximInterface + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Links/LoggingSleep.cpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,47 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#include <sstream> +#include "LoggingSleep.hpp" + +namespace MaximInterface { + +void LoggingSleep::operator()(int ms) const { + if (writeMessage) { + std::ostringstream message; + message << "<DELAY" << ms << '>'; + writeMessage(message.str()); + } + SleepDecorator::operator()(ms); +} + +} // namespace MaximInterface
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Links/LoggingSleep.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,60 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_LoggingSleep +#define MaximInterface_LoggingSleep + +#include <MaximInterface/Utilities/Export.h> +#include <MaximInterface/Utilities/WriteMessage.hpp> +#include "SleepDecorator.hpp" + +namespace MaximInterface { + +class LoggingSleep : public SleepDecorator { +public: + LoggingSleep(const Sleep & sleep, + const WriteMessage & writeMessage = WriteMessage()) + : SleepDecorator(sleep), writeMessage(writeMessage) {} + + void setWriteMessage(const WriteMessage & writeMessage) { + this->writeMessage = writeMessage; + } + + MaximInterface_EXPORT void operator()(int ms) const; + +private: + WriteMessage writeMessage; +}; + +} // namespace MaximInterface + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Links/OneWireMaster.cpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,131 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#include <MaximInterface/Utilities/Error.hpp> +#include "OneWireMaster.hpp" + +namespace MaximInterface { + +error_code OneWireMaster::writeByteSetLevel(uint_least8_t sendByte, + Level afterLevel) { + error_code result; + for (int idx = 0; (idx < 8) && !result; idx++) { + result = writeBit(((sendByte >> idx) & 1) == 1); + } + if (!result) { + result = setLevel(afterLevel); + } + return result; +} + +error_code OneWireMaster::readByteSetLevel(uint_least8_t & recvByte, + Level afterLevel) { + recvByte = 0; + error_code result; + for (int idx = 0; idx < 8; idx++) { + bool recvBit; + result = readBit(recvBit); + if (result) { + break; + } + if (recvBit) { + recvByte |= (1 << idx); + } + } + if (!result) { + result = setLevel(afterLevel); + } + return result; +} + +error_code OneWireMaster::writeBlock(const uint_least8_t * sendBuf, + size_t sendLen) { + error_code result; + for (size_t idx = 0; (idx < sendLen) && !result; idx++) { + result = writeByte(sendBuf[idx]); + } + return result; +} + +error_code OneWireMaster::readBlock(uint_least8_t * recvBuf, size_t recvLen) { + error_code result; + for (size_t idx = 0; (idx < recvLen) && !result; idx++) { + result = readByte(recvBuf[idx]); + } + return result; +} + +error_code OneWireMaster::triplet(TripletData & data) { + error_code result = readBit(data.readBit); + if (!result) { + result = readBit(data.readBitComplement); + } + if (!result) { + if (data.readBit) { + data.writeBit = 1; + } else if (data.readBitComplement) { + data.writeBit = 0; + } + // else: use data.writeBit parameter + result = writeBit(data.writeBit); + } + return result; +} + +const error_category & OneWireMaster::errorCategory() { + static class : public error_category { + public: + virtual const char * name() const { return "OneWireMaster"; } + + virtual std::string message(int condition) const { + switch (condition) { + case NoSlaveError: + return "No Slave Error"; + + case ShortDetectedError: + return "Short Detected Error"; + + case InvalidSpeedError: + return "Invalid Speed Error"; + + case InvalidLevelError: + return "Invalid Level Error"; + + default: + return defaultErrorMessage(condition); + } + } + } instance; + return instance; +} + +} // namespace MaximInterface
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Links/OneWireMaster.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,172 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_OneWireMaster +#define MaximInterface_OneWireMaster + +#include <stddef.h> +#include <stdint.h> +#include <MaximInterface/Utilities/Export.h> +#include <MaximInterface/Utilities/system_error.hpp> + +namespace MaximInterface { + +/// Base class for all 1-Wire Masters. +class OneWireMaster { +public: + /// Speed of the 1-Wire bus. + enum Speed { StandardSpeed = 0x00, OverdriveSpeed = 0x01 }; + + /// Level of the 1-Wire bus. + enum Level { NormalLevel = 0x00, StrongLevel = 0x02 }; + + /// Result of all 1-Wire commands. + enum ErrorValue { + NoSlaveError = 1, ///< Slave not detected, typically due to no presence pulse. + ShortDetectedError, + InvalidSpeedError, + InvalidLevelError + }; + + struct TripletData { + bool writeBit; + bool readBit; + bool readBitComplement; + }; + + virtual ~OneWireMaster() {} + + /// Reset all of the devices on the 1-Wire bus and check for a presence pulse. + /// @returns NoSlaveError if reset was performed but no presence pulse was detected. + virtual error_code reset() = 0; + + /// Send and receive one bit of communication and set a new level on the + /// 1-Wire bus. + /// @param[in,out] sendRecvBit + /// Input containing the bit to send and output containing the received bit. + /// @param afterLevel Level to set the 1-Wire bus to after communication. + virtual error_code touchBitSetLevel(bool & sendRecvBit, Level afterLevel) = 0; + + /// Send one byte of communication and set a new level on the 1-Wire bus. + /// @param sendByte Byte to send on the 1-Wire bus. + /// @param afterLevel Level to set the 1-Wire bus to after communication. + MaximInterface_EXPORT virtual error_code + writeByteSetLevel(uint_least8_t sendByte, Level afterLevel); + + /// Receive one byte of communication and set a new level on the 1-Wire bus. + /// @param recvByte Buffer to receive the data from the 1-Wire bus. + /// @param afterLevel Level to set the 1-Wire bus to after communication. + MaximInterface_EXPORT virtual error_code + readByteSetLevel(uint_least8_t & recvByte, Level afterLevel); + + /// Send a block of communication on the 1-Wire bus. + /// @param[in] sendBuf Buffer to send on the 1-Wire bus. + /// @param sendLen Length of the buffer to send. + MaximInterface_EXPORT virtual error_code + writeBlock(const uint_least8_t * sendBuf, size_t sendLen); + + /// Receive a block of communication on the 1-Wire bus. + /// @param[out] recvBuf Buffer to receive the data from the 1-Wire bus. + /// @param recvLen Length of the buffer to receive. + MaximInterface_EXPORT virtual error_code readBlock(uint_least8_t * recvBuf, + size_t recvLen); + + /// Set the 1-Wire bus communication speed. + virtual error_code setSpeed(Speed newSpeed) = 0; + + /// Set the 1-Wire bus level. + virtual error_code setLevel(Level newLevel) = 0; + + /// 1-Wire Triplet operation. + /// @details Perform one bit of a 1-Wire search. This command + /// does two read bits and one write bit. The write bit is either + /// the default direction (all devices have same bit) or in case + /// of a discrepancy, the data.writeBit parameter is used. + ///@param[in,out] data + /// Input with desired writeBit in case both read bits are zero. + /// Output with all data fields set. + MaximInterface_EXPORT virtual error_code triplet(TripletData & data); + + /// Send one bit of communication and set a new level on the 1-Wire bus. + /// @param sendBit Bit to send on the 1-Wire bus. + /// @param afterLevel Level to set the 1-Wire bus to after communication. + error_code writeBitSetLevel(bool sendBit, Level afterLevel) { + return touchBitSetLevel(sendBit, afterLevel); + } + + /// Receive one bit of communication and set a new level on the 1-Wire bus. + /// @param[out] recvBit Received data from the 1-Wire bus. + /// @param afterLevel Level to set the 1-Wire bus to after communication. + error_code readBitSetLevel(bool & recvBit, Level afterLevel) { + recvBit = 1; + return touchBitSetLevel(recvBit, afterLevel); + } + + // Alternate forms of the read and write functions. + error_code writeBit(bool sendBit) { + return writeBitSetLevel(sendBit, NormalLevel); + } + error_code readBit(bool & recvBit) { + return readBitSetLevel(recvBit, NormalLevel); + } + error_code writeBitPower(bool sendBit) { + return writeBitSetLevel(sendBit, StrongLevel); + } + error_code readBitPower(bool & recvBit) { + return readBitSetLevel(recvBit, StrongLevel); + } + error_code writeByte(uint_least8_t sendByte) { + return writeByteSetLevel(sendByte, NormalLevel); + } + error_code readByte(uint_least8_t & recvByte) { + return readByteSetLevel(recvByte, NormalLevel); + } + error_code writeBytePower(uint_least8_t sendByte) { + return writeByteSetLevel(sendByte, StrongLevel); + } + error_code readBytePower(uint_least8_t & recvByte) { + return readByteSetLevel(recvByte, StrongLevel); + } + + MaximInterface_EXPORT static const error_category & errorCategory(); +}; + +inline error_code make_error_code(OneWireMaster::ErrorValue e) { + return error_code(e, OneWireMaster::errorCategory()); +} +inline error_condition make_error_condition(OneWireMaster::ErrorValue e) { + return error_condition(e, OneWireMaster::errorCategory()); +} + +} // namespace MaximInterface + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Links/OneWireMasterDecorator.cpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,76 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#include "OneWireMasterDecorator.hpp" + +namespace MaximInterface { + +error_code OneWireMasterDecorator::reset() { return master->reset(); } + +error_code OneWireMasterDecorator::touchBitSetLevel(bool & sendRecvBit, + Level afterLevel) { + return master->touchBitSetLevel(sendRecvBit, afterLevel); +} + +error_code OneWireMasterDecorator::writeByteSetLevel(uint_least8_t sendByte, + Level afterLevel) { + return master->writeByteSetLevel(sendByte, afterLevel); +} + +error_code OneWireMasterDecorator::readByteSetLevel(uint_least8_t & recvByte, + Level afterLevel) { + return master->readByteSetLevel(recvByte, afterLevel); +} + +error_code OneWireMasterDecorator::writeBlock(const uint_least8_t * sendBuf, + size_t sendLen) { + return master->writeBlock(sendBuf, sendLen); +} + +error_code OneWireMasterDecorator::readBlock(uint_least8_t * recvBuf, + size_t recvLen) { + return master->readBlock(recvBuf, recvLen); +} + +error_code OneWireMasterDecorator::setSpeed(Speed newSpeed) { + return master->setSpeed(newSpeed); +} + +error_code OneWireMasterDecorator::setLevel(Level newLevel) { + return master->setLevel(newLevel); +} + +error_code OneWireMasterDecorator::triplet(TripletData & data) { + return master->triplet(data); +} + +} // namespace MaximInterface \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Links/OneWireMasterDecorator.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,69 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_OneWireMasterDecorator +#define MaximInterface_OneWireMasterDecorator + +#include <MaximInterface/Utilities/Export.h> +#include "OneWireMaster.hpp" + +namespace MaximInterface { + +class OneWireMasterDecorator : public OneWireMaster { +protected: + explicit OneWireMasterDecorator(OneWireMaster & master) : master(&master) {} + +public: + void setOneWireMaster(OneWireMaster & master) { this->master = &master; } + + MaximInterface_EXPORT virtual error_code reset(); + MaximInterface_EXPORT virtual error_code touchBitSetLevel(bool & sendRecvBit, + Level afterLevel); + MaximInterface_EXPORT virtual error_code + writeByteSetLevel(uint_least8_t sendByte, Level afterLevel); + MaximInterface_EXPORT virtual error_code + readByteSetLevel(uint_least8_t & recvByte, Level afterLevel); + MaximInterface_EXPORT virtual error_code + writeBlock(const uint_least8_t * sendBuf, size_t sendLen); + MaximInterface_EXPORT virtual error_code readBlock(uint_least8_t * recvBuf, + size_t recvLen); + MaximInterface_EXPORT virtual error_code setSpeed(Speed newSpeed); + MaximInterface_EXPORT virtual error_code setLevel(Level newLevel); + MaximInterface_EXPORT virtual error_code triplet(TripletData & data); + +private: + OneWireMaster * master; +}; + +} // namespace MaximInterface + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Links/RomCommands.cpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,222 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#include <algorithm> +#include "RomCommands.hpp" + +namespace MaximInterface { + +enum RomCmd { + ReadRomCmd = 0x33, + MatchRomCmd = 0x55, + SearchRomCmd = 0xF0, + SkipRomCmd = 0xCC, + ResumeRomCmd = 0xA5, + OverdriveSkipRomCmd = 0x3C, + OverdriveMatchRomCmd = 0x69 +}; + +void skipCurrentFamily(SearchRomState & searchState) { + // set the Last discrepancy to last family discrepancy + searchState.lastDiscrepancy = searchState.lastFamilyDiscrepancy; + + // clear the last family discrepancy + searchState.lastFamilyDiscrepancy = 0; + + // check for end of list + if (searchState.lastDiscrepancy == 0) { + searchState.lastDevice = true; + } +} + +error_code verifyRom(OneWireMaster & master, const RomId & romId) { + SearchRomState searchState(romId); + error_code result = searchRom(master, searchState); + if (!result) { + // check if same device found + if (romId != searchState.romId) { + result = make_error_code(OneWireMaster::NoSlaveError); + } + } + return result; +} + +error_code readRom(OneWireMaster & master, RomId & romId) { + error_code result = master.reset(); + if (!result) { + result = master.writeByte(ReadRomCmd); + } + + // read the ROM + RomId readId; + if (!result) { + result = master.readBlock(readId.data(), readId.size()); + } + + // verify CRC8 + if (!result) { + if (valid(readId)) { + romId = readId; + } else { + result = make_error_code(OneWireMaster::NoSlaveError); + } + } + + return result; +} + +error_code skipRom(OneWireMaster & master) { + error_code result = master.reset(); + if (!result) { + result = master.writeByte(SkipRomCmd); + } + return result; +} + +error_code matchRom(OneWireMaster & master, const RomId & romId) { + // use MatchROM + error_code result = master.reset(); + if (!result) { + uint_least8_t buf[1 + RomId::csize]; + buf[0] = MatchRomCmd; + std::copy(romId.begin(), romId.end(), buf + 1); + // send command and rom + result = master.writeBlock(buf, sizeof(buf) / sizeof(buf[0])); + } + return result; +} + +error_code overdriveSkipRom(OneWireMaster & master) { + error_code result = master.setSpeed(OneWireMaster::StandardSpeed); + + if (!result) { + result = master.reset(); + } + + if (!result) { + result = master.writeByte(OverdriveSkipRomCmd); + } + + if (!result) { + result = master.setSpeed(OneWireMaster::OverdriveSpeed); + } + + return result; +} + +error_code overdriveMatchRom(OneWireMaster & master, const RomId & romId) { + // use overdrive MatchROM + master.setSpeed(OneWireMaster::StandardSpeed); + + error_code result = master.reset(); + if (!result) { + result = master.writeByte(OverdriveMatchRomCmd); + if (!result) { + master.setSpeed(OneWireMaster::OverdriveSpeed); + // send ROM + result = master.writeBlock(romId.data(), romId.size()); + } + } + return result; +} + +error_code resumeRom(OneWireMaster & master) { + error_code result = master.reset(); + if (!result) { + result = master.writeByte(ResumeRomCmd); + } + return result; +} + +error_code searchRom(OneWireMaster & master, SearchRomState & searchState) { + if (searchState.lastDevice) { + searchState = SearchRomState(); + } + + error_code result = master.reset(); + if (result) { + return result; + } + result = master.writeByte(SearchRomCmd); + if (result) { + return result; + } + + SearchRomState newSearchState = searchState; + for (int idBitNumber = 1; idBitNumber <= 64; idBitNumber++) { + const int idByteNumber = (idBitNumber - 1) / 8; + const unsigned int idBitMask = 1 << ((idBitNumber - 1) % 8); + + OneWireMaster::TripletData tripletData; + if (idBitNumber == newSearchState.lastDiscrepancy) { + tripletData.writeBit = 1; + } else if (idBitNumber > newSearchState.lastDiscrepancy) { + tripletData.writeBit = 0; + } else // idBitNumber < searchState.lastDiscrepancy + { + tripletData.writeBit = + (newSearchState.romId[idByteNumber] & idBitMask) == idBitMask; + } + + result = master.triplet(tripletData); + if (result) { + return result; + } + if (tripletData.readBit && tripletData.readBitComplement) { + return make_error_code(OneWireMaster::NoSlaveError); + } + + if (tripletData.writeBit) { + newSearchState.romId[idByteNumber] |= idBitMask; + } else { + newSearchState.romId[idByteNumber] &= ~idBitMask; + if (!tripletData.readBit && !tripletData.readBitComplement) { + newSearchState.lastDiscrepancy = idBitNumber; + if (idBitNumber <= 8) { + newSearchState.lastFamilyDiscrepancy = idBitNumber; + } + } + } + } + + if (valid(newSearchState.romId)) { + if (newSearchState.lastDiscrepancy == searchState.lastDiscrepancy) { + newSearchState.lastDevice = true; + } + searchState = newSearchState; + } else { + result = make_error_code(OneWireMaster::NoSlaveError); + } + return result; +} + +} // namespace MaximInterface
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Links/RomCommands.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,121 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +/// @file ROM Commands for enumerating and selecting 1-Wire devices. + +#ifndef MaximInterface_RomCommands +#define MaximInterface_RomCommands + +#include <stdint.h> +#include <MaximInterface/Utilities/Export.h> +#include <MaximInterface/Utilities/RomId.hpp> +#include "OneWireMaster.hpp" + +namespace MaximInterface { + +/// State used by Search ROM command. +struct SearchRomState { + RomId romId; + int_least8_t lastDiscrepancy; + int_least8_t lastFamilyDiscrepancy; + bool lastDevice; + + SearchRomState() + : romId(), lastDiscrepancy(0), lastFamilyDiscrepancy(0), + lastDevice(false) {} + + explicit SearchRomState(const RomId & romId) + : romId(romId), lastDiscrepancy(64), lastFamilyDiscrepancy(0), + lastDevice(false) {} + + explicit SearchRomState(RomId::value_type familyCode) + : romId(), lastDiscrepancy(64), lastFamilyDiscrepancy(0), + lastDevice(false) { + setFamilyCode(romId, familyCode); + } +}; + +/// Set the search state to skip the current device family on the next +/// Search ROM command. +MaximInterface_EXPORT void skipCurrentFamily(SearchRomState & searchState); + +/// Verify that the device with the specified ROM ID is present. +MaximInterface_EXPORT error_code verifyRom(OneWireMaster & master, + const RomId & romId); + +/// Use Read ROM command to read ROM ID from device on bus. +/// @note Only use this command with a single drop bus, data +/// collisions will occur if more than 1 device on bus. +/// @param[out] romId ROM ID read from device. +MaximInterface_EXPORT error_code readRom(OneWireMaster & master, RomId & romId); + +/// Issue Skip ROM command on bus. +/// @note Only use this command with a single drop bus, data +/// collisions will occur if more than 1 device on bus. +MaximInterface_EXPORT error_code skipRom(OneWireMaster & master); + +/// Use the Match ROM command to select the device by its known ID. +/// @note This command causes all devices supporting Overdrive +/// mode to switch to Overdrive timing. +/// @param[in] romId ROM ID of device to select. +MaximInterface_EXPORT error_code matchRom(OneWireMaster & master, + const RomId & romId); + +/// Issue Overdrive Skip ROM command on bus. +/// @note This command causes all devices supporting Overdrive +/// mode to switch to Overdrive timing. +/// @note Only use this command with a single drop bus, data +/// collisions will occur if more than 1 device on bus. +MaximInterface_EXPORT error_code overdriveSkipRom(OneWireMaster & master); + +/// Use the Overdrive Match ROM command to select the device by its known ID. +/// @param[in] romId ROM ID of device to select. +MaximInterface_EXPORT error_code overdriveMatchRom(OneWireMaster & master, + const RomId & romId); + +/// Perform a Resume ROM command on bus. +/// @details Resumes communication with the last device selected +/// though a Match ROM or Search ROM operation. +MaximInterface_EXPORT error_code resumeRom(OneWireMaster & master); + +/// Find device on the 1-Wire bus. +/// @details +/// This command uses the Search ROM command to enumerate all 1-Wire devices in +/// sequence. Begin with a new search state and continue using the same search +/// state until the last device flag is set which indicates that all devices +/// have been discovered. +MaximInterface_EXPORT error_code searchRom(OneWireMaster & master, + SearchRomState & searchState); + +} // namespace MaximInterface + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Links/SelectRom.cpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,52 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#include "SelectRom.hpp" + +namespace MaximInterface { + +error_code SelectMatchRom::operator()(OneWireMaster & master) const { + return matchRom(master, romId_); +} + +error_code SelectMatchRomWithResume::operator()(OneWireMaster & master) const { + error_code result; + if (romId_ == data->lastRom) { + result = resumeRom(master); + } else { + result = matchRom(master, romId_); + data->lastRom = romId_; + } + return result; +} + +} // namespace MaximInterface
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Links/SelectRom.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,93 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_SelectRom +#define MaximInterface_SelectRom + +#include <MaximInterface/Utilities/Export.h> +#include <MaximInterface/Utilities/Function.hpp> +#include <MaximInterface/Utilities/RomId.hpp> +#include <MaximInterface/Utilities/system_error.hpp> +#include "RomCommands.hpp" + +namespace MaximInterface { + +class OneWireMaster; + +typedef Function<error_code(OneWireMaster &)> SelectRom; + +/// Selector for a multidrop 1-Wire bus. +class SelectMatchRom { +public: + typedef SelectRom::argument_type argument_type; + typedef SelectRom::result_type result_type; + + explicit SelectMatchRom(const RomId & romId = RomId()) : romId_(romId) {} + + const RomId & romId() const { return romId_; } + void setRomId(const RomId & romId) { romId_ = romId; } + + MaximInterface_EXPORT error_code operator()(OneWireMaster & master) const; + +private: + RomId romId_; +}; + +/// Selector for a multidrop 1-Wire bus where slaves support the Resume ROM command. +class SelectMatchRomWithResume { +public: + typedef SelectRom::argument_type argument_type; + typedef SelectRom::result_type result_type; + + struct SharedData { + RomId lastRom; + + SharedData() : lastRom() {} + }; + + explicit SelectMatchRomWithResume(SharedData & data, + const RomId & romId = RomId()) + : romId_(romId), data(&data) {} + + const RomId & romId() const { return romId_; } + void setRomId(const RomId & romId) { romId_ = romId; } + + MaximInterface_EXPORT error_code operator()(OneWireMaster & master) const; + +private: + RomId romId_; + SharedData * data; +}; + +} // namespace MaximInterface + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Links/Sleep.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,47 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_Sleep +#define MaximInterface_Sleep + +namespace MaximInterface { + +class Sleep { +public: + virtual ~Sleep() {} + + virtual void operator()(int ms) const = 0; +}; + +} // namespace MaximInterface + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Links/SleepDecorator.cpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,39 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#include "SleepDecorator.hpp" + +namespace MaximInterface { + +void SleepDecorator::operator()(int ms) const { (*sleep)(ms); } + +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Links/SleepDecorator.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,55 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_SleepDecorator +#define MaximInterface_SleepDecorator + +#include <MaximInterface/Utilities/Export.h> +#include "Sleep.hpp" + +namespace MaximInterface { + +class SleepDecorator : public Sleep { +protected: + explicit SleepDecorator(const Sleep & sleep) : sleep(&sleep) {} + +public: + void setSleep(const Sleep & sleep) { this->sleep = &sleep; } + MaximInterface_EXPORT virtual void operator()(int ms) const; + +private: + const Sleep * sleep; +}; + +} // namespace MaximInterface + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Links/Uart.cpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,75 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#include <MaximInterface/Utilities/Error.hpp> +#include "Uart.hpp" + +namespace MaximInterface { + +error_code Uart::writeBlock(const uint_least8_t * data, size_t dataLen) { + error_code result; + for (size_t i = 0; i < dataLen && !result; i++) { + result = writeByte(data[i]); + } + return result; +} + +error_code Uart::readBlock(uint_least8_t * data, size_t dataLen) { + error_code result; + for (size_t i = 0; i < dataLen && !result; i++) { + result = readByte(data[i]); + } + return result; +} + +const error_category & Uart::errorCategory() { + static class : public error_category { + public: + virtual const char * name() const { return "UART"; } + + virtual std::string message(int condition) const { + switch (condition) { + case TimeoutError: + return "Timeout Error"; + + case OverrunError: + return "Overrun Error"; + + default: + return defaultErrorMessage(condition); + } + } + } instance; + return instance; +} + +} // namespace MaximInterface \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Links/Uart.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,75 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_Uart +#define MaximInterface_Uart + +#include <stdint.h> +#include <stddef.h> + +#include <MaximInterface/Utilities/Export.h> +#include <MaximInterface/Utilities/system_error.hpp> + +namespace MaximInterface { + +class Uart { +public: + enum ErrorValue { + TimeoutError = 1, ///< Read operation aborted due to timeout. + OverrunError ///< Received data lost due to read buffer overrun. + }; + + virtual ~Uart() {} + + virtual error_code setBaud(int_least32_t baud) = 0; + virtual error_code sendBreak() = 0; + virtual error_code clearReadBuffer() = 0; + virtual error_code writeByte(uint_least8_t data) = 0; + MaximInterface_EXPORT virtual error_code + writeBlock(const uint_least8_t * data, size_t dataLen); + virtual error_code readByte(uint_least8_t & data) = 0; + MaximInterface_EXPORT virtual error_code readBlock(uint_least8_t * data, + size_t dataLen); + + MaximInterface_EXPORT static const error_category & errorCategory(); +}; + +inline error_code make_error_code(Uart::ErrorValue e) { + return error_code(e, Uart::errorCategory()); +} +inline error_condition make_error_condition(Uart::ErrorValue e) { + return error_condition(e, Uart::errorCategory()); +} + +} // namespace MaximInterface + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MaximInterface.vcxproj Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,254 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{7E1C5898-64B8-422F-8030-F8D2EFB5B0CB}</ProjectGuid> + <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> + <Keyword>ManagedCProj</Keyword> + <RootNamespace>MaximInterface</RootNamespace> + <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v140</PlatformToolset> + <CLRSupport>true</CLRSupport> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v140</PlatformToolset> + <CLRSupport>true</CLRSupport> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v140</PlatformToolset> + <CLRSupport>true</CLRSupport> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v140</PlatformToolset> + <CLRSupport>true</CLRSupport> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <IncludePath>$(ProjectDir)\..;$(IncludePath)</IncludePath> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <IncludePath>$(ProjectDir)\..;$(IncludePath)</IncludePath> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + <IncludePath>$(ProjectDir)\..;$(IncludePath)</IncludePath> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + <IncludePath>$(ProjectDir)\..;$(IncludePath)</IncludePath> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>NOMINMAX;WIN32;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <Link> + <AdditionalDependencies /> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <Link> + <AdditionalDependencies /> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PreprocessorDefinitions>NOMINMAX;WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <Link> + <AdditionalDependencies /> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PreprocessorDefinitions>NOMINMAX;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <Link> + <AdditionalDependencies /> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <Reference Include="OneWireLinkLayer"> + <HintPath>Platforms\dotnet\OneWireLinkLayer\OneWireLinkLayer.dll</HintPath> + </Reference> + <Reference Include="System" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="Devices\DS18B20.cpp" /> + <ClCompile Include="Devices\DS1920.cpp" /> + <ClCompile Include="Devices\DS2413.cpp" /> + <ClCompile Include="Devices\DS2431.cpp" /> + <ClCompile Include="Devices\DS2465.cpp" /> + <ClCompile Include="Devices\DS2480B.cpp" /> + <ClCompile Include="Devices\DS2482_DS2484.cpp" /> + <ClCompile Include="Devices\DS28C36_DS2476.cpp" /> + <ClCompile Include="Devices\DS28E15_22_25.cpp" /> + <ClCompile Include="Devices\DS28E17.cpp" /> + <ClCompile Include="Devices\DS28E38.cpp" /> + <ClCompile Include="Devices\DS9400.cpp" /> + <ClCompile Include="Links\I2CMaster.cpp" /> + <ClCompile Include="Links\I2CMasterDecorator.cpp" /> + <ClCompile Include="Links\LoggingI2CMaster.cpp" /> + <ClCompile Include="Links\LoggingOneWireMaster.cpp" /> + <ClCompile Include="Links\OneWireMaster.cpp" /> + <ClCompile Include="Links\OneWireMasterDecorator.cpp" /> + <ClCompile Include="Links\RomCommands.cpp" /> + <ClCompile Include="Links\SelectRom.cpp" /> + <ClCompile Include="Links\LoggingSleep.cpp" /> + <ClCompile Include="Links\SleepDecorator.cpp" /> + <ClCompile Include="Links\Uart.cpp" /> + <ClCompile Include="Platforms\dotnet\DS9481P_300.cpp"> + <ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)dotnet\</ObjectFileName> + <ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)dotnet\</ObjectFileName> + <ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)dotnet\</ObjectFileName> + <ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)dotnet\</ObjectFileName> + </ClCompile> + <ClCompile Include="Platforms\dotnet\OneWireLinkLayerMaster.cpp"> + <ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)dotnet\</ObjectFileName> + <ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)dotnet\</ObjectFileName> + <ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)dotnet\</ObjectFileName> + <ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)dotnet\</ObjectFileName> + </ClCompile> + <ClCompile Include="Platforms\dotnet\Sleep.cpp"> + <ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)\dotnet\</ObjectFileName> + <ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)\dotnet\</ObjectFileName> + <ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)\dotnet\</ObjectFileName> + <ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)\dotnet\</ObjectFileName> + </ClCompile> + <ClCompile Include="Platforms\dotnet\Uart.cpp"> + <ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)\dotnet\</ObjectFileName> + <ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)\dotnet\</ObjectFileName> + <ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)\dotnet\</ObjectFileName> + <ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)\dotnet\</ObjectFileName> + </ClCompile> + <ClCompile Include="Utilities\crc.cpp" /> + <ClCompile Include="Utilities\Ecc256.cpp" /> + <ClCompile Include="Utilities\Error.cpp" /> + <ClCompile Include="Utilities\HexConversions.cpp" /> + <ClCompile Include="Utilities\system_error.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="Devices\DS18B20.hpp" /> + <ClInclude Include="Devices\DS1920.hpp" /> + <ClInclude Include="Devices\DS2413.hpp" /> + <ClInclude Include="Devices\DS2431.hpp" /> + <ClInclude Include="Devices\DS2465.hpp" /> + <ClInclude Include="Devices\DS2480B.hpp" /> + <ClInclude Include="Devices\DS2482_DS2484.hpp" /> + <ClInclude Include="Devices\DS28C36_DS2476.hpp" /> + <ClInclude Include="Devices\DS28E15_22_25.hpp" /> + <ClInclude Include="Devices\DS28E17.hpp" /> + <ClInclude Include="Devices\DS28E38.hpp" /> + <ClInclude Include="Devices\DS9400.hpp" /> + <ClInclude Include="Links\I2CMaster.hpp" /> + <ClInclude Include="Links\I2CMasterDecorator.hpp" /> + <ClInclude Include="Links\LoggingI2CMaster.hpp" /> + <ClInclude Include="Links\LoggingOneWireMaster.hpp" /> + <ClInclude Include="Links\OneWireMaster.hpp" /> + <ClInclude Include="Links\OneWireMasterDecorator.hpp" /> + <ClInclude Include="Links\RomCommands.hpp" /> + <ClInclude Include="Links\SelectRom.hpp" /> + <ClInclude Include="Links\LoggingSleep.hpp" /> + <ClInclude Include="Links\Sleep.hpp" /> + <ClInclude Include="Links\SleepDecorator.hpp" /> + <ClInclude Include="Links\Uart.hpp" /> + <ClInclude Include="Platforms\dotnet\ChangeSizeType.hpp" /> + <ClInclude Include="Platforms\dotnet\DelegateWrapper.hpp" /> + <ClInclude Include="Platforms\dotnet\DS9481P_300.hpp" /> + <ClInclude Include="Platforms\dotnet\MoveOnly.hpp" /> + <ClInclude Include="Platforms\dotnet\OneWireLinkLayerMaster.hpp" /> + <ClInclude Include="Platforms\dotnet\Sleep.hpp" /> + <ClInclude Include="Platforms\dotnet\Uart.hpp" /> + <ClInclude Include="Utilities\array.hpp" /> + <ClInclude Include="Utilities\crc.hpp" /> + <ClInclude Include="Utilities\Ecc256.hpp" /> + <ClInclude Include="Utilities\Error.hpp" /> + <ClInclude Include="Utilities\Export.h" /> + <ClInclude Include="Utilities\FlagSet.hpp" /> + <ClInclude Include="Utilities\Function.hpp" /> + <ClInclude Include="Utilities\HexConversions.hpp" /> + <ClInclude Include="Utilities\ManId.hpp" /> + <ClInclude Include="Utilities\RomId.hpp" /> + <ClInclude Include="Utilities\Segment.hpp" /> + <ClInclude Include="Utilities\Sha256.hpp" /> + <ClInclude Include="Utilities\system_error.hpp" /> + <ClInclude Include="Utilities\type_traits.hpp" /> + <ClInclude Include="Utilities\Uncopyable.hpp" /> + <ClInclude Include="Utilities\WriteMessage.hpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> + <Target Name="CopyOneWireLinkLayerDependenciesToOutDir" AfterTargets="Link"> + <ItemGroup Condition="'$(Platform)'=='Win32'"> + <Files Include="Platforms\dotnet\OneWireLinkLayer\IB*32.dll" /> + </ItemGroup> + <ItemGroup Condition="'$(Platform)'=='x64'"> + <Files Include="Platforms\dotnet\OneWireLinkLayer\IB*64.dll" /> + </ItemGroup> + <Copy SourceFiles="@(Files)" DestinationFolder="$(OutDir)" SkipUnchangedFiles="true" /> + </Target> +</Project> \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MaximInterface.vcxproj.filters Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,282 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + <Filter Include="Header Files\Platforms/dotnet"> + <UniqueIdentifier>{20e2adae-b837-416c-9711-27583e3c230b}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files\Platforms/dotnet"> + <UniqueIdentifier>{63d67a30-8ace-4b0d-8f09-ca770ba4211e}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files\Devices"> + <UniqueIdentifier>{e279ae2d-8636-4b89-8c6c-69db07e90944}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files\Devices"> + <UniqueIdentifier>{1441f2db-880a-41e6-9db3-3fcf2e082fc1}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files\Links"> + <UniqueIdentifier>{63236a03-f900-4307-9ae0-db9f5ad41a32}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files\Utilities"> + <UniqueIdentifier>{92539371-ab18-4bd0-b3d6-2449d18a6620}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files\Links"> + <UniqueIdentifier>{bd04ab64-fd11-4c55-bada-233093987852}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files\Utilities"> + <UniqueIdentifier>{017fb907-ad1f-4072-a2f1-7cd23bb1c735}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="Platforms\dotnet\DS9481P_300.cpp"> + <Filter>Source Files\Platforms/dotnet</Filter> + </ClCompile> + <ClCompile Include="Platforms\dotnet\OneWireLinkLayerMaster.cpp"> + <Filter>Source Files\Platforms/dotnet</Filter> + </ClCompile> + <ClCompile Include="Platforms\dotnet\Sleep.cpp"> + <Filter>Source Files\Platforms/dotnet</Filter> + </ClCompile> + <ClCompile Include="Platforms\dotnet\Uart.cpp"> + <Filter>Source Files\Platforms/dotnet</Filter> + </ClCompile> + <ClCompile Include="Devices\DS18B20.cpp"> + <Filter>Source Files\Devices</Filter> + </ClCompile> + <ClCompile Include="Devices\DS28E15_22_25.cpp"> + <Filter>Source Files\Devices</Filter> + </ClCompile> + <ClCompile Include="Devices\DS28E17.cpp"> + <Filter>Source Files\Devices</Filter> + </ClCompile> + <ClCompile Include="Devices\DS28E38.cpp"> + <Filter>Source Files\Devices</Filter> + </ClCompile> + <ClCompile Include="Devices\DS1920.cpp"> + <Filter>Source Files\Devices</Filter> + </ClCompile> + <ClCompile Include="Devices\DS2413.cpp"> + <Filter>Source Files\Devices</Filter> + </ClCompile> + <ClCompile Include="Devices\DS2431.cpp"> + <Filter>Source Files\Devices</Filter> + </ClCompile> + <ClCompile Include="Devices\DS2465.cpp"> + <Filter>Source Files\Devices</Filter> + </ClCompile> + <ClCompile Include="Devices\DS2480B.cpp"> + <Filter>Source Files\Devices</Filter> + </ClCompile> + <ClCompile Include="Devices\DS9400.cpp"> + <Filter>Source Files\Devices</Filter> + </ClCompile> + <ClCompile Include="Utilities\crc.cpp"> + <Filter>Source Files\Utilities</Filter> + </ClCompile> + <ClCompile Include="Utilities\Ecc256.cpp"> + <Filter>Source Files\Utilities</Filter> + </ClCompile> + <ClCompile Include="Utilities\HexConversions.cpp"> + <Filter>Source Files\Utilities</Filter> + </ClCompile> + <ClCompile Include="Utilities\system_error.cpp"> + <Filter>Source Files\Utilities</Filter> + </ClCompile> + <ClCompile Include="Links\I2CMaster.cpp"> + <Filter>Source Files\Links</Filter> + </ClCompile> + <ClCompile Include="Links\I2CMasterDecorator.cpp"> + <Filter>Source Files\Links</Filter> + </ClCompile> + <ClCompile Include="Links\LoggingI2CMaster.cpp"> + <Filter>Source Files\Links</Filter> + </ClCompile> + <ClCompile Include="Links\LoggingOneWireMaster.cpp"> + <Filter>Source Files\Links</Filter> + </ClCompile> + <ClCompile Include="Links\LoggingSleep.cpp"> + <Filter>Source Files\Links</Filter> + </ClCompile> + <ClCompile Include="Links\OneWireMaster.cpp"> + <Filter>Source Files\Links</Filter> + </ClCompile> + <ClCompile Include="Links\OneWireMasterDecorator.cpp"> + <Filter>Source Files\Links</Filter> + </ClCompile> + <ClCompile Include="Links\RomCommands.cpp"> + <Filter>Source Files\Links</Filter> + </ClCompile> + <ClCompile Include="Links\SelectRom.cpp"> + <Filter>Source Files\Links</Filter> + </ClCompile> + <ClCompile Include="Links\SleepDecorator.cpp"> + <Filter>Source Files\Links</Filter> + </ClCompile> + <ClCompile Include="Links\Uart.cpp"> + <Filter>Source Files\Links</Filter> + </ClCompile> + <ClCompile Include="Devices\DS28C36_DS2476.cpp"> + <Filter>Source Files\Devices</Filter> + </ClCompile> + <ClCompile Include="Devices\DS2482_DS2484.cpp"> + <Filter>Source Files\Devices</Filter> + </ClCompile> + <ClCompile Include="Utilities\Error.cpp"> + <Filter>Source Files\Utilities</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="Platforms\dotnet\ChangeSizeType.hpp"> + <Filter>Header Files\Platforms/dotnet</Filter> + </ClInclude> + <ClInclude Include="Platforms\dotnet\DelegateWrapper.hpp"> + <Filter>Header Files\Platforms/dotnet</Filter> + </ClInclude> + <ClInclude Include="Platforms\dotnet\DS9481P_300.hpp"> + <Filter>Header Files\Platforms/dotnet</Filter> + </ClInclude> + <ClInclude Include="Platforms\dotnet\MoveOnly.hpp"> + <Filter>Header Files\Platforms/dotnet</Filter> + </ClInclude> + <ClInclude Include="Platforms\dotnet\OneWireLinkLayerMaster.hpp"> + <Filter>Header Files\Platforms/dotnet</Filter> + </ClInclude> + <ClInclude Include="Platforms\dotnet\Sleep.hpp"> + <Filter>Header Files\Platforms/dotnet</Filter> + </ClInclude> + <ClInclude Include="Platforms\dotnet\Uart.hpp"> + <Filter>Header Files\Platforms/dotnet</Filter> + </ClInclude> + <ClInclude Include="Devices\DS18B20.hpp"> + <Filter>Header Files\Devices</Filter> + </ClInclude> + <ClInclude Include="Devices\DS28E15_22_25.hpp"> + <Filter>Header Files\Devices</Filter> + </ClInclude> + <ClInclude Include="Devices\DS28E17.hpp"> + <Filter>Header Files\Devices</Filter> + </ClInclude> + <ClInclude Include="Devices\DS28E38.hpp"> + <Filter>Header Files\Devices</Filter> + </ClInclude> + <ClInclude Include="Devices\DS1920.hpp"> + <Filter>Header Files\Devices</Filter> + </ClInclude> + <ClInclude Include="Devices\DS2413.hpp"> + <Filter>Header Files\Devices</Filter> + </ClInclude> + <ClInclude Include="Devices\DS2431.hpp"> + <Filter>Header Files\Devices</Filter> + </ClInclude> + <ClInclude Include="Devices\DS2465.hpp"> + <Filter>Header Files\Devices</Filter> + </ClInclude> + <ClInclude Include="Devices\DS2480B.hpp"> + <Filter>Header Files\Devices</Filter> + </ClInclude> + <ClInclude Include="Devices\DS9400.hpp"> + <Filter>Header Files\Devices</Filter> + </ClInclude> + <ClInclude Include="Utilities\array.hpp"> + <Filter>Header Files\Utilities</Filter> + </ClInclude> + <ClInclude Include="Utilities\crc.hpp"> + <Filter>Header Files\Utilities</Filter> + </ClInclude> + <ClInclude Include="Utilities\Ecc256.hpp"> + <Filter>Header Files\Utilities</Filter> + </ClInclude> + <ClInclude Include="Utilities\Function.hpp"> + <Filter>Header Files\Utilities</Filter> + </ClInclude> + <ClInclude Include="Utilities\HexConversions.hpp"> + <Filter>Header Files\Utilities</Filter> + </ClInclude> + <ClInclude Include="Utilities\ManId.hpp"> + <Filter>Header Files\Utilities</Filter> + </ClInclude> + <ClInclude Include="Utilities\RomId.hpp"> + <Filter>Header Files\Utilities</Filter> + </ClInclude> + <ClInclude Include="Utilities\Sha256.hpp"> + <Filter>Header Files\Utilities</Filter> + </ClInclude> + <ClInclude Include="Utilities\system_error.hpp"> + <Filter>Header Files\Utilities</Filter> + </ClInclude> + <ClInclude Include="Utilities\type_traits.hpp"> + <Filter>Header Files\Utilities</Filter> + </ClInclude> + <ClInclude Include="Utilities\Uncopyable.hpp"> + <Filter>Header Files\Utilities</Filter> + </ClInclude> + <ClInclude Include="Utilities\WriteMessage.hpp"> + <Filter>Header Files\Utilities</Filter> + </ClInclude> + <ClInclude Include="Links\I2CMaster.hpp"> + <Filter>Header Files\Links</Filter> + </ClInclude> + <ClInclude Include="Links\I2CMasterDecorator.hpp"> + <Filter>Header Files\Links</Filter> + </ClInclude> + <ClInclude Include="Links\LoggingI2CMaster.hpp"> + <Filter>Header Files\Links</Filter> + </ClInclude> + <ClInclude Include="Links\LoggingOneWireMaster.hpp"> + <Filter>Header Files\Links</Filter> + </ClInclude> + <ClInclude Include="Links\LoggingSleep.hpp"> + <Filter>Header Files\Links</Filter> + </ClInclude> + <ClInclude Include="Links\OneWireMaster.hpp"> + <Filter>Header Files\Links</Filter> + </ClInclude> + <ClInclude Include="Links\OneWireMasterDecorator.hpp"> + <Filter>Header Files\Links</Filter> + </ClInclude> + <ClInclude Include="Links\RomCommands.hpp"> + <Filter>Header Files\Links</Filter> + </ClInclude> + <ClInclude Include="Links\SelectRom.hpp"> + <Filter>Header Files\Links</Filter> + </ClInclude> + <ClInclude Include="Links\Sleep.hpp"> + <Filter>Header Files\Links</Filter> + </ClInclude> + <ClInclude Include="Links\SleepDecorator.hpp"> + <Filter>Header Files\Links</Filter> + </ClInclude> + <ClInclude Include="Links\Uart.hpp"> + <Filter>Header Files\Links</Filter> + </ClInclude> + <ClInclude Include="Devices\DS28C36_DS2476.hpp"> + <Filter>Header Files\Devices</Filter> + </ClInclude> + <ClInclude Include="Devices\DS2482_DS2484.hpp"> + <Filter>Header Files\Devices</Filter> + </ClInclude> + <ClInclude Include="Utilities\FlagSet.hpp"> + <Filter>Header Files\Utilities</Filter> + </ClInclude> + <ClInclude Include="Utilities\Error.hpp"> + <Filter>Header Files\Utilities</Filter> + </ClInclude> + <ClInclude Include="Utilities\Export.h"> + <Filter>Header Files\Utilities</Filter> + </ClInclude> + <ClInclude Include="Utilities\Segment.hpp"> + <Filter>Header Files\Utilities</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Platforms/dotnet/.mbedignore Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,1 @@ +* \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Platforms/dotnet/ChangeSizeType.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,63 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#pragma once + +#include <algorithm> +#include <limits> +#include <type_traits> + +namespace MaximInterface { + +/// Adapts functions taking a data pointer and data size where the size type is +/// not size_t. The function will be called multiple times if necessary to +/// process all data. +template <typename NewSize, typename Func, typename Data> +void changeSizeType(Func func, Data data, size_t dataSize) { + using namespace std; + + // Check if NewSize can represent the maximum value of dataSize. + if (numeric_limits<decltype(dataSize)>::max() > + static_cast<make_unsigned_t<NewSize>>(numeric_limits<NewSize>::max())) { + do { + const auto chunkSize = + min<decltype(dataSize)>(dataSize, numeric_limits<NewSize>::max()); + func(data, static_cast<NewSize>(chunkSize)); + data += chunkSize; + dataSize -= chunkSize; + } while (dataSize > 0); + } else { + func(data, static_cast<NewSize>(dataSize)); + } +} + +} // namespace MaximInterface \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Platforms/dotnet/DS9481P_300.cpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,283 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#include <utility> +#include <msclr/marshal_cppstd.h> +#include <MaximInterface/Utilities/Error.hpp> +#include "DS9481P_300.hpp" + +using System::IO::Ports::SerialPort; +using msclr::interop::marshal_as; +using std::string; + +namespace MaximInterface { + +DS9481P_300::DS9481P_300() + : currentBus(Bus::None), linkLayerMaster("{DS9097U_DS9480}"), + oneWireMaster_(*this), serial(), ds9400(serial), i2cMaster_(*this) {} + +DS9481P_300::~DS9481P_300() { disconnect(); } + +error_code DS9481P_300::connect(const string & portName) { + return connected() ? make_error_code(ConnectionStateError) + : selectBus(Bus::OneWire, portName); +} + +void DS9481P_300::disconnect() { selectBus(Bus::None); } + +string DS9481P_300::portName() const { + switch (currentBus) { + case Bus::I2C: + return serial.portName(); + + case Bus::OneWire: + return linkLayerMaster.portName(); + } + return ""; +} + +error_code DS9481P_300::selectBus(Bus newBus) { + return connected() ? selectBus(newBus, portName()) + : make_error_code(ConnectionStateError); +} + +error_code DS9481P_300::selectBus(Bus newBus, const string & portName) { + error_code result; + if (currentBus != newBus) { + const auto selectI2C = [this](const string & portName) { + auto result = serial.connect(portName); + if (!result) { + // Escape DS2480 Mode. + result = serial.writeByte(0xE5); + } + if (!result) { + // Wait for awake notification. + uint_least8_t data; + result = serial.readByte(data); + } + return result; + }; + + const auto selectOneWire = [this](const string & portName) { + return linkLayerMaster.connect(portName); + }; + + switch (currentBus) { + case Bus::None: + switch (newBus) { + case Bus::OneWire: + result = selectOneWire(portName); + break; + + case Bus::I2C: + result = selectI2C(portName); + break; + } + break; + + case Bus::OneWire: + linkLayerMaster.disconnect(); + switch (newBus) { + case Bus::I2C: + result = selectI2C(portName); + break; + } + break; + + case Bus::I2C: { + constexpr uint_least8_t buffer[] = {'C', 'O'}; + result = serial.writeBlock(buffer, sizeof(buffer) / sizeof(buffer[0])); + if (!result) { + serial.disconnect(); + switch (newBus) { + case Bus::OneWire: + result = selectOneWire(portName); + break; + } + } + } break; + } + if (!result) { + currentBus = newBus; + } + } + return result; +} + +error_code DS9481P_300::OneWireMasterImpl::reset() { + return selectAndExecute([this] { return OneWireMasterDecorator::reset(); }); +} + +error_code DS9481P_300::OneWireMasterImpl::touchBitSetLevel(bool & sendRecvBit, + Level afterLevel) { + return selectAndExecute([this, &sendRecvBit, afterLevel] { + return OneWireMasterDecorator::touchBitSetLevel(sendRecvBit, afterLevel); + }); +} + +error_code +DS9481P_300::OneWireMasterImpl::writeByteSetLevel(uint_least8_t sendByte, + Level afterLevel) { + return selectAndExecute([this, sendByte, afterLevel] { + return OneWireMasterDecorator::writeByteSetLevel(sendByte, afterLevel); + }); +} + +error_code +DS9481P_300::OneWireMasterImpl::readByteSetLevel(uint_least8_t & recvByte, + Level afterLevel) { + return selectAndExecute([this, &recvByte, afterLevel] { + return OneWireMasterDecorator::readByteSetLevel(recvByte, afterLevel); + }); +} + +error_code +DS9481P_300::OneWireMasterImpl::writeBlock(const uint_least8_t * sendBuf, + size_t sendLen) { + return selectAndExecute([this, sendBuf, sendLen] { + return OneWireMasterDecorator::writeBlock(sendBuf, sendLen); + }); +} + +error_code DS9481P_300::OneWireMasterImpl::readBlock(uint_least8_t * recvBuf, + size_t recvLen) { + return selectAndExecute([this, recvBuf, recvLen] { + return OneWireMasterDecorator::readBlock(recvBuf, recvLen); + }); +} + +error_code DS9481P_300::OneWireMasterImpl::setSpeed(Speed newSpeed) { + return selectAndExecute( + [this, newSpeed] { return OneWireMasterDecorator::setSpeed(newSpeed); }); +} + +error_code DS9481P_300::OneWireMasterImpl::setLevel(Level newLevel) { + return selectAndExecute( + [this, newLevel] { return OneWireMasterDecorator::setLevel(newLevel); }); +} + +error_code DS9481P_300::OneWireMasterImpl::triplet(TripletData & data) { + return selectAndExecute( + [this, &data] { return OneWireMasterDecorator::triplet(data); }); +} + +template <typename Func> +error_code DS9481P_300::OneWireMasterImpl::selectAndExecute(Func operation) { + auto result = parent->selectBus(Bus::OneWire); + if (!result) { + result = operation(); + } + return result; +} + +error_code DS9481P_300::I2CMasterImpl::start(uint_least8_t address) { + return selectAndExecute( + [this, address] { return I2CMasterDecorator::start(address); }); +} + +error_code DS9481P_300::I2CMasterImpl::stop() { + return selectAndExecute([this] { return I2CMasterDecorator::stop(); }); +} + +error_code DS9481P_300::I2CMasterImpl::writeByte(uint_least8_t data) { + return selectAndExecute( + [this, data] { return I2CMasterDecorator::writeByte(data); }); +} + +error_code DS9481P_300::I2CMasterImpl::writeBlock(const uint_least8_t * data, + size_t dataLen) { + return selectAndExecute([this, data, dataLen] { + return I2CMasterDecorator::writeBlock(data, dataLen); + }); +} + +error_code DS9481P_300::I2CMasterImpl::writePacket(uint_least8_t address, + const uint_least8_t * data, + size_t dataLen, + bool sendStop) { + return selectAndExecute([this, address, data, dataLen, sendStop] { + return I2CMasterDecorator::writePacket(address, data, dataLen, sendStop); + }); +} + +error_code DS9481P_300::I2CMasterImpl::readByte(AckStatus status, + uint_least8_t & data) { + return selectAndExecute([this, status, &data] { + return I2CMasterDecorator::readByte(status, data); + }); +} + +error_code DS9481P_300::I2CMasterImpl::readBlock(AckStatus status, + uint_least8_t * data, + size_t dataLen) { + return selectAndExecute([this, status, data, dataLen] { + return I2CMasterDecorator::readBlock(status, data, dataLen); + }); +} + +error_code DS9481P_300::I2CMasterImpl::readPacket(uint_least8_t address, + uint_least8_t * data, + size_t dataLen, + bool sendStop) { + return selectAndExecute([this, address, data, dataLen, sendStop] { + return I2CMasterDecorator::readPacket(address, data, dataLen, sendStop); + }); +} + +template <typename Func> +error_code DS9481P_300::I2CMasterImpl::selectAndExecute(Func operation) { + auto result = parent->selectBus(Bus::I2C); + if (!result) { + result = operation(); + } + return result; +} + +const error_category & DS9481P_300::errorCategory() { + static class : public error_category { + public: + virtual const char * name() const { return "DS9481P_300"; } + + virtual std::string message(int condition) const { + switch (condition) { + case ConnectionStateError: + return "Connection State Error"; + + default: + return defaultErrorMessage(condition); + } + } + } instance; + return instance; +} + +} // namespace MaximInterface \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Platforms/dotnet/DS9481P_300.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,148 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#pragma once + +#include <string> +#include <MaximInterface/Devices/DS9400.hpp> +#include <MaximInterface/Links/I2CMasterDecorator.hpp> +#include <MaximInterface/Links/OneWireMasterDecorator.hpp> +#include <MaximInterface/Utilities/Export.h> +#include "MoveOnly.hpp" +#include "OneWireLinkLayerMaster.hpp" +#include "Uart.hpp" + +namespace MaximInterface { + +/// DS9481P-300 USB to 1-Wire and I2C adapter. +class DS9481P_300 : private MoveOnly { +public: + enum ErrorValue { ConnectionStateError = 1 }; + + MaximInterface_EXPORT DS9481P_300(); + MaximInterface_EXPORT ~DS9481P_300(); + + DS9481P_300(DS9481P_300 &&) = default; + DS9481P_300 & operator=(DS9481P_300 &&) = default; + + /// Access the 1-Wire master when connected to an adapter. + OneWireMaster & oneWireMaster() { return oneWireMaster_; } + + /// Access the I2C master when connected to an adapter. + I2CMaster & i2cMaster() { return i2cMaster_; } + + /// Connect to an adapter on the specified COM port. + MaximInterface_EXPORT error_code connect(const std::string & portName); + + /// Disconnect from the adapter on the current COM port. + MaximInterface_EXPORT void disconnect(); + + /// Check if currently connected to an adapter. + /// @returns True if connected. + bool connected() const { return currentBus != Bus::None; } + + /// Get the currently connected COM port name. + MaximInterface_EXPORT std::string portName() const; + + MaximInterface_EXPORT static const error_category & errorCategory(); + +private: + class OneWireMasterImpl : public OneWireMasterDecorator { + public: + explicit OneWireMasterImpl(DS9481P_300 & parent) + : OneWireMasterDecorator(parent.linkLayerMaster), parent(&parent) {} + + virtual error_code reset() override; + virtual error_code touchBitSetLevel(bool & sendRecvBit, + Level afterLevel) override; + virtual error_code writeByteSetLevel(uint_least8_t sendByte, + Level afterLevel) override; + virtual error_code readByteSetLevel(uint_least8_t & recvByte, + Level afterLevel) override; + virtual error_code writeBlock(const uint_least8_t * sendBuf, + size_t sendLen) override; + virtual error_code readBlock(uint_least8_t * recvBuf, + size_t recvLen) override; + virtual error_code setSpeed(Speed newSpeed) override; + virtual error_code setLevel(Level newLevel) override; + virtual error_code triplet(TripletData & data) override; + + private: + DS9481P_300 * parent; + + template <typename Func> error_code selectAndExecute(Func operation); + }; + + class I2CMasterImpl : public I2CMasterDecorator { + public: + explicit I2CMasterImpl(DS9481P_300 & parent) noexcept + : I2CMasterDecorator(parent.ds9400), parent(&parent) {} + + virtual error_code start(uint_least8_t address) override; + virtual error_code stop() override; + virtual error_code writeByte(uint_least8_t data) override; + virtual error_code writeBlock(const uint_least8_t * data, + size_t dataLen) override; + virtual error_code writePacket(uint_least8_t address, + const uint_least8_t * data, size_t dataLen, + bool sendStop) override; + virtual error_code readByte(AckStatus status, + uint_least8_t & data) override; + virtual error_code readBlock(AckStatus status, uint_least8_t * data, + size_t dataLen) override; + virtual error_code readPacket(uint_least8_t address, uint_least8_t * data, + size_t dataLen, bool sendStop) override; + + private: + DS9481P_300 * parent; + + template <typename Func> error_code selectAndExecute(Func operation); + }; + + enum class Bus { None, OneWire, I2C }; + + Bus currentBus; + OneWireLinkLayerMaster linkLayerMaster; + OneWireMasterImpl oneWireMaster_; + dotnet::Uart serial; + DS9400 ds9400; + I2CMasterImpl i2cMaster_; + + error_code selectBus(Bus newBus); + error_code selectBus(Bus newBus, const std::string & portName); +}; + +inline error_code make_error_code(DS9481P_300::ErrorValue e) { + return error_code(e, DS9481P_300::errorCategory()); +} + +} // namespace MaximInterface \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Platforms/dotnet/DelegateWrapper.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,118 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#pragma once + +#include <msclr/marshal_cppstd.h> +#include <vcclr.h> + +namespace MaximInterface { +namespace detail { + +template <typename DelegateT> class DelegateWrapperBase { +public: + using Delegate = DelegateT; + +protected: + DelegateWrapperBase(Delegate ^ target) : target_(target) {} + ~DelegateWrapperBase() = default; + +public: + Delegate ^ target() const { return static_cast<Delegate ^>(target_); } + void setTarget(Delegate ^ target) { target_ = target; } + void swap(DelegateWrapperBase & other) { target_.swap(other.target_); } + explicit operator bool() const { return target() != nullptr; } + +private: + gcroot<Delegate ^> target_; +}; + +template <typename DelegateT> +inline void swap(DelegateWrapperBase<DelegateT> & lhs, + DelegateWrapperBase<DelegateT> & rhs) { + lhs.swap(rhs); +} + +template <typename R, typename... Args> +class DelegateWrapperImpl + : public DelegateWrapperBase<System::Func<Args..., R> > { +protected: + DelegateWrapperImpl(Delegate ^ target) : DelegateWrapperBase(target) {} + +public: + R operator()(Args... args) { return target()(args...); } +}; + +template <typename... Args> +class DelegateWrapperImpl<void, Args...> + : public DelegateWrapperBase<System::Action<Args...> > { +protected: + DelegateWrapperImpl(Delegate ^ target) : DelegateWrapperBase(target) {} + +public: + void operator()(Args... args) const { target()(args...); } +}; + +} // namespace detail + +/// @{ +/// Functor wrapper for .NET delegates. +template <typename> class DelegateWrapper; + +template <typename R, typename... Args> +class DelegateWrapper<R(Args...)> + : public detail::DelegateWrapperImpl<R, Args...> { +public: + DelegateWrapper(Delegate ^ target = nullptr) : DelegateWrapperImpl(target) {} +}; + +template <typename R, typename... Args> +class DelegateWrapper<R __clrcall(Args...)> + : public detail::DelegateWrapperImpl<R, Args...> { +public: + DelegateWrapper(Delegate ^ target = nullptr) : DelegateWrapperImpl(target) {} +}; +/// @} + +/// Wrapper for using a .NET delegate as a MaximInterface::WriteMessage. +class WriteMessageDelegateWrapper + : public DelegateWrapper<void(System::String ^)> { +public: + WriteMessageDelegateWrapper(Delegate ^ target = nullptr) + : DelegateWrapper(target) {} + + void operator()(const std::string & arg) const { + target()(msclr::interop::marshal_as<System::String ^>(arg)); + } +}; + +} // namespace MaximInterface \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Platforms/dotnet/MoveOnly.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,51 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_MoveOnly +#define MaximInterface_MoveOnly + +namespace MaximInterface { + +class MoveOnly { +protected: + MoveOnly() = default; + ~MoveOnly() = default; + + MoveOnly(const MoveOnly &) = delete; + MoveOnly(MoveOnly &&) = default; + const MoveOnly & operator=(const MoveOnly &) = delete; + MoveOnly & operator=(MoveOnly &&) = default; +}; + +} // namespace MaximInterface + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Platforms/dotnet/OneWireLinkLayerMaster.cpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,337 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#include <stdexcept> +#include <msclr/auto_gcroot.h> +#include <msclr/marshal_cppstd.h> +#include <MaximInterface/Utilities/Error.hpp> +#include "ChangeSizeType.hpp" +#include "OneWireLinkLayerMaster.hpp" + +using DalSemi::OneWire::Adapter::AdapterException; +using System::IntPtr; +using System::Runtime::InteropServices::Marshal; +using System::String; +using msclr::interop::marshal_as; +using std::string; + +namespace MaximInterface { + +struct OneWireLinkLayerMaster::Data { + msclr::auto_gcroot<DalSemi::OneWire::Adapter::PortAdapter ^> adapter; + bool connected = false; +}; + +OneWireLinkLayerMaster::OneWireLinkLayerMaster(const string & adapterName) + : data(std::make_unique<Data>()) { + try { + data->adapter = DalSemi::OneWire::AccessProvider::GetAdapter( + marshal_as<String ^>(adapterName)); + } catch (AdapterException ^ e) { + throw std::invalid_argument(marshal_as<string>(e->Message)); + } +} + +OneWireLinkLayerMaster::~OneWireLinkLayerMaster() = default; + +OneWireLinkLayerMaster::OneWireLinkLayerMaster( + OneWireLinkLayerMaster && rhs) noexcept = default; + +OneWireLinkLayerMaster & OneWireLinkLayerMaster:: +operator=(OneWireLinkLayerMaster && rhs) noexcept = default; + +error_code OneWireLinkLayerMaster::connect(const string & portName) { + if (connected()) { + return make_error_code(AlreadyConnectedError); + } + + error_code result; + try { + auto adapterResult = + data->adapter->OpenPort(marshal_as<String ^>(portName)); + if (adapterResult) { + adapterResult = data->adapter->BeginExclusive(true); + if (adapterResult) { + data->connected = true; + } else { + data->adapter->FreePort(); + result = make_error_code(OpenPortError); + } + } else { + result = make_error_code(OpenPortError); + } + } catch (AdapterException ^) { + result = make_error_code(CommunicationError); + } + return result; +} + +void OneWireLinkLayerMaster::disconnect() { + data->adapter->EndExclusive(); + data->adapter->FreePort(); + data->connected = false; +} + +bool OneWireLinkLayerMaster::connected() const { return data->connected; } + +string OneWireLinkLayerMaster::adapterName() const { + return marshal_as<string>(data->adapter->AdapterName); +} + +string OneWireLinkLayerMaster::portName() const { + return connected() ? marshal_as<string>(data->adapter->PortName) : ""; +} + +error_code OneWireLinkLayerMaster::reset() { + using DalSemi::OneWire::Adapter::OWResetResult; + + error_code result; + try { + switch (data->adapter->Reset()) { + case OWResetResult::RESET_SHORT: + result = make_error_code(ShortDetectedError); + break; + + case OWResetResult::RESET_NOPRESENCE: + result = make_error_code(NoSlaveError); + break; + } + } catch (AdapterException ^) { + result = make_error_code(CommunicationError); + } + return result; +} + +error_code OneWireLinkLayerMaster::touchBitSetLevel(bool & sendRecvBit, + Level afterLevel) { + error_code result; + try { + switch (afterLevel) { + case StrongLevel: { + auto adapterResult = data->adapter->StartPowerDelivery( + DalSemi::OneWire::Adapter::OWPowerStart::CONDITION_AFTER_BIT); + if (!adapterResult) { + result = make_error_code(PowerDeliveryError); + } + } break; + + case NormalLevel: + break; + + default: + result = make_error_code(InvalidLevelError); + break; + } + if (!result) { + if (sendRecvBit) { + sendRecvBit = data->adapter->GetBit(); + } else { + data->adapter->PutBit(0); + } + } + } catch (AdapterException ^) { + result = make_error_code(CommunicationError); + } + return result; +} + +error_code OneWireLinkLayerMaster::writeByteSetLevel(uint_least8_t sendByte, + Level afterLevel) { + error_code result; + try { + switch (afterLevel) { + case StrongLevel: { + auto adapterResult = data->adapter->StartPowerDelivery( + DalSemi::OneWire::Adapter::OWPowerStart::CONDITION_AFTER_BYTE); + if (!adapterResult) { + result = make_error_code(PowerDeliveryError); + } + } break; + + case NormalLevel: + break; + + default: + result = make_error_code(InvalidLevelError); + break; + } + if (!result) { + data->adapter->PutByte(sendByte); + } + } catch (AdapterException ^) { + result = make_error_code(CommunicationError); + } + return result; +} + +error_code OneWireLinkLayerMaster::readByteSetLevel(uint_least8_t & recvByte, + Level afterLevel) { + error_code result; + try { + switch (afterLevel) { + case StrongLevel: { + auto adapterResult = data->adapter->StartPowerDelivery( + DalSemi::OneWire::Adapter::OWPowerStart::CONDITION_AFTER_BYTE); + if (!adapterResult) { + result = make_error_code(PowerDeliveryError); + } + } break; + + case NormalLevel: + break; + + default: + result = make_error_code(InvalidLevelError); + break; + } + if (!result) { + recvByte = data->adapter->GetByte(); + } + } catch (AdapterException ^) { + result = make_error_code(CommunicationError); + } + return result; +} + +error_code OneWireLinkLayerMaster::writeBlock(const uint_least8_t * sendBuf, + size_t sendLen) { + error_code result; + try { + changeSizeType<int>( + [this](const uint_least8_t * data, int dataSize) { + auto dataManaged = gcnew array<uint_least8_t>(dataSize); + Marshal::Copy(static_cast<IntPtr>(const_cast<uint_least8_t *>(data)), + dataManaged, 0, dataSize); + this->data->adapter->DataBlock(dataManaged, 0, dataSize); + }, + sendBuf, sendLen); + } catch (AdapterException ^) { + result = make_error_code(CommunicationError); + } + return result; +} + +error_code OneWireLinkLayerMaster::readBlock(uint_least8_t * recvBuf, + size_t recvLen) { + error_code result; + try { + changeSizeType<int>( + [this](uint_least8_t * data, int dataSize) { + auto dataManaged = gcnew array<uint_least8_t>(dataSize); + this->data->adapter->GetBlock(dataManaged, dataSize); + Marshal::Copy(dataManaged, 0, static_cast<IntPtr>(data), dataSize); + }, + recvBuf, recvLen); + } catch (AdapterException ^) { + result = make_error_code(CommunicationError); + } + return result; +} + +error_code OneWireLinkLayerMaster::setSpeed(Speed newSpeed) { + using DalSemi::OneWire::Adapter::OWSpeed; + + error_code result; + try { + switch (newSpeed) { + case OverdriveSpeed: + data->adapter->Speed = OWSpeed::SPEED_OVERDRIVE; + break; + + case StandardSpeed: + data->adapter->Speed = OWSpeed::SPEED_REGULAR; + break; + + default: + result = make_error_code(InvalidSpeedError); + break; + } + } catch (AdapterException ^) { + result = make_error_code(CommunicationError); + } + return result; +} + +error_code OneWireLinkLayerMaster::setLevel(Level newLevel) { + error_code result; + try { + switch (newLevel) { + case StrongLevel: { + auto setResult = data->adapter->StartPowerDelivery( + DalSemi::OneWire::Adapter::OWPowerStart::CONDITION_NOW); + if (!setResult) { + result = make_error_code(PowerDeliveryError); + } + } break; + + case NormalLevel: + data->adapter->SetPowerNormal(); + break; + + default: + result = make_error_code(InvalidLevelError); + break; + } + } catch (AdapterException ^) { + result = make_error_code(CommunicationError); + } + return result; +} + +const error_category & OneWireLinkLayerMaster::errorCategory() { + static class : public error_category { + public: + virtual const char * name() const { return "OneWireLinkLayerMaster"; } + + virtual string message(int condition) const { + switch (condition) { + case CommunicationError: + return "Communication Error"; + + case OpenPortError: + return "Open Port Error"; + + case PowerDeliveryError: + return "Power Delivery Error"; + + case AlreadyConnectedError: + return "Already Connected Error"; + + default: + return defaultErrorMessage(condition); + } + } + } instance; + return instance; +} + +} // namespace MaximInterface \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Platforms/dotnet/OneWireLinkLayerMaster.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,103 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#pragma once + +#include <memory> +#include <string> +#include <MaximInterface/Links/OneWireMaster.hpp> +#include <MaximInterface/Utilities/Export.h> +#include "MoveOnly.hpp" + +namespace MaximInterface { + +/// 1-Wire interface using the OneWireLinkLayer DLL from the Compact.NET API. +class OneWireLinkLayerMaster : public OneWireMaster, private MoveOnly { +public: + enum ErrorValue { + CommunicationError = 1, + OpenPortError, + PowerDeliveryError, + AlreadyConnectedError + }; + + /// @param adapterName Adapter type name recogized by OneWireLinkLayer. + MaximInterface_EXPORT OneWireLinkLayerMaster(const std::string & adapterName); + MaximInterface_EXPORT ~OneWireLinkLayerMaster(); + + MaximInterface_EXPORT + OneWireLinkLayerMaster(OneWireLinkLayerMaster &&) noexcept; + MaximInterface_EXPORT OneWireLinkLayerMaster & + operator=(OneWireLinkLayerMaster &&) noexcept; + + /// Connect to an adapter on the specified COM port. + MaximInterface_EXPORT error_code connect(const std::string & portName); + + /// Disconnect from the adapter on the current COM port. + MaximInterface_EXPORT void disconnect(); + + /// Check if currently connected to an adapter. + /// @returns True if connected. + MaximInterface_EXPORT bool connected() const; + + /// Get the adapter type name. + MaximInterface_EXPORT std::string adapterName() const; + + /// Get the currently connected COM port name. + MaximInterface_EXPORT std::string portName() const; + + MaximInterface_EXPORT virtual error_code reset() override; + MaximInterface_EXPORT virtual error_code + touchBitSetLevel(bool & sendRecvBit, Level afterLevel) override; + MaximInterface_EXPORT virtual error_code + writeByteSetLevel(uint_least8_t sendByte, Level afterLevel) override; + MaximInterface_EXPORT virtual error_code + readByteSetLevel(uint_least8_t & recvByte, Level afterLevel) override; + MaximInterface_EXPORT virtual error_code + writeBlock(const uint_least8_t * sendBuf, size_t sendLen) override; + MaximInterface_EXPORT virtual error_code readBlock(uint_least8_t * recvBuf, + size_t recvLen) override; + MaximInterface_EXPORT virtual error_code setSpeed(Speed newSpeed) override; + MaximInterface_EXPORT virtual error_code setLevel(Level newLevel) override; + + MaximInterface_EXPORT static const error_category & errorCategory(); + +private: + struct Data; + std::unique_ptr<Data> data; +}; + +inline error_code make_error_code(OneWireLinkLayerMaster::ErrorValue e) { + return error_code(e, OneWireLinkLayerMaster::errorCategory()); +} + +} // namespace MaximInterface \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Platforms/dotnet/Sleep.cpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,57 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#include "Sleep.hpp" + +namespace MaximInterface { +namespace dotnet { + +void sleep(const int ms) { + constexpr int timeSlice_ms = 20; + if (ms > timeSlice_ms / 2) { + System::Threading::Thread::Sleep(ms); + } else { + auto watch = System::Diagnostics::Stopwatch::StartNew(); + while (watch->ElapsedMilliseconds < ms); + watch->Stop(); + } +} + +Sleep & Sleep::instance() { + static Sleep instance; + return instance; +} + +void Sleep::operator()(int ms) const { sleep(ms); } + +} // namespace dotnet +} // namespace MaximInterface \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Platforms/dotnet/Sleep.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,55 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#pragma once + +#include <MaximInterface/Links/Sleep.hpp> +#include <MaximInterface/Utilities/Export.h> +#include <MaximInterface/Utilities/Uncopyable.hpp> + +namespace MaximInterface { +namespace dotnet { + +MaximInterface_EXPORT void sleep(int ms); + +class Sleep : public MaximInterface::Sleep, private Uncopyable { +public: + MaximInterface_EXPORT static Sleep & instance(); + + MaximInterface_EXPORT virtual void operator()(int ms) const override; + +private: + Sleep() = default; +}; + +} // namespace dotnet +} // namespace MaximInterface \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Platforms/dotnet/Uart.cpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,218 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#include <msclr/auto_gcroot.h> +#include <msclr/marshal_cppstd.h> +#include <MaximInterface/Utilities/Error.hpp> +#include "ChangeSizeType.hpp" +#include "Sleep.hpp" +#include "Uart.hpp" + +using msclr::interop::marshal_as; +using std::string; +using namespace System; +using System::IO::Ports::SerialPort; +using System::Runtime::InteropServices::Marshal; + +namespace MaximInterface { +namespace dotnet { + +template <typename Type, typename Input> static bool isType(Input in) { + return dynamic_cast<Type>(in) != nullptr; +} + +template <typename Func> +static error_code executeTryCatchOperation(Func tryOperation) { + return executeTryCatchOperation(tryOperation, [] {}); +} + +template <typename TryFunc, typename CatchFunc> +static error_code executeTryCatchOperation(TryFunc tryOperation, + CatchFunc catchOperation) { + error_code result; + try { + tryOperation(); + } catch (Exception ^ e) { + catchOperation(); + if (isType<ArgumentException ^>(e)) { + result = make_error_code(Uart::ArgumentError); + } else if (isType<InvalidOperationException ^>(e)) { + result = make_error_code(Uart::InvalidOperationError); + } else if (isType<System::IO::IOException ^>(e)) { + result = make_error_code(Uart::IOError); + } else if (isType<UnauthorizedAccessException ^>(e)) { + result = make_error_code(Uart::UnauthorizedAccessError); + } else if (isType<TimeoutException ^>(e)) { + result = make_error_code(Uart::TimeoutError); + } else { + throw; + } + } + return result; +} + +template <typename Func> +static error_code executeIfConnected(const Uart & serial, Func operation) { + return serial.connected() ? operation() + : make_error_code(Uart::NotConnectedError); +} + +struct Uart::Data { + msclr::auto_gcroot<SerialPort ^> port; +}; + +Uart::Uart() : data(std::make_unique<Data>()) {} + +Uart::~Uart() = default; + +Uart::Uart(Uart &&) noexcept = default; + +Uart & Uart::operator=(Uart &&) noexcept = default; + +error_code Uart::connect(const string & portName) { + data->port = gcnew SerialPort; + return executeTryCatchOperation( + [this, &portName] { + data->port->PortName = marshal_as<String ^>(portName); + data->port->DtrEnable = true; + data->port->Open(); + }, + [this] { data->port.reset(); }); +} + +void Uart::disconnect() { data->port.reset(); } + +bool Uart::connected() const { return data->port.get() != nullptr; } + +string Uart::portName() const { + return connected() ? marshal_as<string>(data->port->PortName) : ""; +} + +error_code Uart::setBaud(int_least32_t baud) { + return executeIfConnected(*this, [this, baud] { + return executeTryCatchOperation( + [this, baud] { data->port->BaudRate = baud; }); + }); +} + +error_code Uart::sendBreak() { + return executeIfConnected(*this, [this] { + return executeTryCatchOperation([this] { + data->port->BreakState = true; + sleep(1); + data->port->BreakState = false; + }); + }); +} + +error_code Uart::clearReadBuffer() { + return executeIfConnected(*this, [this] { + return executeTryCatchOperation([this] { data->port->ReadExisting(); }); + }); +} + +error_code Uart::writeByte(uint_least8_t data) { return writeBlock(&data, 1); } + +error_code Uart::writeBlock(const uint_least8_t * data, size_t dataLen) { + return executeIfConnected(*this, [this, data, dataLen] { + return executeTryCatchOperation([this, data, dataLen] { + changeSizeType<int>( + [this](const uint_least8_t * dataChunk, int dataChunkSize) { + auto dataManaged = gcnew array<uint_least8_t>(dataChunkSize); + Marshal::Copy( + static_cast<IntPtr>(const_cast<uint_least8_t *>(dataChunk)), + dataManaged, 0, dataChunkSize); + this->data->port->Write(dataManaged, 0, dataChunkSize); + }, + data, dataLen); + }); + }); +} + +error_code Uart::readByte(uint_least8_t & data) { + return executeIfConnected(*this, [this, &data] { + return executeTryCatchOperation( + [this, &data] { data = this->data->port->ReadByte(); }); + }); +} + +error_code Uart::readBlock(uint_least8_t * data, size_t dataLen) { + return executeIfConnected(*this, [this, data, dataLen] { + return executeTryCatchOperation([this, data, dataLen] { + changeSizeType<int>( + [this](uint_least8_t * dataChunk, int dataChunkSize) { + auto dataManaged = gcnew array<uint_least8_t>(dataChunkSize); + int bytesRead = 0; + do { + bytesRead += this->data->port->Read(dataManaged, bytesRead, + dataChunkSize - bytesRead); + } while (bytesRead < dataChunkSize); + Marshal::Copy(dataManaged, 0, static_cast<IntPtr>(dataChunk), + dataChunkSize); + }, + data, dataLen); + }); + }); +} + +const error_category & Uart::errorCategory() { + static class : public error_category { + public: + virtual const char * name() const { return "dotnet UART"; } + + virtual string message(int condition) const { + switch (condition) { + case NotConnectedError: + return "Not Connected Error"; + + case ArgumentError: + return "Argument Error"; + + case InvalidOperationError: + return "Invalid Operation Error"; + + case IOError: + return "IO Error"; + + case UnauthorizedAccessError: + return "Unauthorized Access Error"; + + default: + return defaultErrorMessage(condition); + } + } + } instance; + return instance; +} + +} // namespace dotnet +} // namespace MaximInterface \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Platforms/dotnet/Uart.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,98 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#pragma once + +#include <memory> +#include <string> +#include <MaximInterface/Links/Uart.hpp> +#include <MaximInterface/Utilities/Export.h> +#include "MoveOnly.hpp" + +namespace MaximInterface { +namespace dotnet { + +/// UART interface using .NET type System::IO::Ports::SerialPort. +class Uart : public MaximInterface::Uart, private MoveOnly { +public: + enum ErrorValue { + NotConnectedError = 1, + ArgumentError, + InvalidOperationError, + IOError, + UnauthorizedAccessError + }; + + MaximInterface_EXPORT Uart(); + MaximInterface_EXPORT ~Uart(); + + MaximInterface_EXPORT Uart(Uart &&) noexcept; + MaximInterface_EXPORT Uart & operator=(Uart &&) noexcept; + + /// Connect a specified COM port. + MaximInterface_EXPORT error_code connect(const std::string & portName); + + /// Disconnect from the current COM port. + MaximInterface_EXPORT void disconnect(); + + /// Check if currently connected to a COM port. + /// @returns True if connected. + MaximInterface_EXPORT bool connected() const; + + /// Get the currently connected COM port name. + MaximInterface_EXPORT std::string portName() const; + + MaximInterface_EXPORT virtual error_code setBaud(int_least32_t baud) override; + MaximInterface_EXPORT virtual error_code sendBreak() override; + MaximInterface_EXPORT virtual error_code clearReadBuffer() override; + MaximInterface_EXPORT virtual error_code + writeByte(uint_least8_t data) override; + MaximInterface_EXPORT virtual error_code + writeBlock(const uint_least8_t * data, size_t dataLen) override; + MaximInterface_EXPORT virtual error_code + readByte(uint_least8_t & data) override; + MaximInterface_EXPORT virtual error_code readBlock(uint_least8_t * data, + size_t dataLen) override; + + MaximInterface_EXPORT static const error_category & errorCategory(); + +private: + struct Data; + std::unique_ptr<Data> data; +}; + +inline error_code make_error_code(Uart::ErrorValue e) { + return error_code(e, Uart::errorCategory()); +} + +} // namespace dotnet +} // namespace MaximInterface \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Platforms/mbed/I2CMaster.cpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,75 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#include "I2CMaster.hpp" + +namespace MaximInterface { +namespace mbed { + +error_code I2CMaster::start(uint_least8_t address) { + i2c->start(); + return writeByte(address); +} + +error_code I2CMaster::stop() { + i2c->stop(); + return error_code(); +} + +error_code I2CMaster::writeByte(uint_least8_t data) { + return (i2c->write(data) == 1) ? error_code() : make_error_code(NackError); +} + +error_code I2CMaster::writePacket(uint_least8_t address, + const uint_least8_t * data, size_t dataLen, + bool sendStop) { + return (i2c->write(address, reinterpret_cast<const char *>(data), dataLen, + !sendStop) == 0) + ? error_code() + : make_error_code(NackError); +} + +error_code I2CMaster::readByte(AckStatus status, uint_least8_t & data) { + data = i2c->read(status == Ack); + return error_code(); +} + +error_code I2CMaster::readPacket(uint_least8_t address, uint_least8_t * data, + size_t dataLen, bool sendStop) { + return (i2c->read(address, reinterpret_cast<char *>(data), dataLen, + !sendStop) == 0) + ? error_code() + : make_error_code(NackError); +} + +} // namespace mbed +} // namespace MaximInterface \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Platforms/mbed/I2CMaster.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,66 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_mbed_I2CMaster +#define MaximInterface_mbed_I2CMaster + +#include <drivers/I2C.h> +#include <MaximInterface/Links/I2CMaster.hpp> + +namespace MaximInterface { +namespace mbed { + +/// Wrapper for mbed::I2C. +class I2CMaster : public MaximInterface::I2CMaster { +public: + explicit I2CMaster(::mbed::I2C & i2c) : i2c(&i2c) {} + + void setI2C(::mbed::I2C & i2c) { this->i2c = &i2c; } + + virtual error_code start(uint_least8_t address); + virtual error_code stop(); + virtual error_code writeByte(uint_least8_t data); + virtual error_code writePacket(uint_least8_t address, + const uint_least8_t * data, size_t dataLen, + bool sendStop); + virtual error_code readByte(AckStatus status, uint_least8_t & data); + virtual error_code readPacket(uint_least8_t address, uint_least8_t * data, + size_t dataLen, bool sendStop); + +private: + ::mbed::I2C * i2c; +}; + +} // namespace mbed +} // namespace MaximInterface + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Platforms/mbed/Sleep.cpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,49 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#include <wait_api.h> +#include "Sleep.hpp" + +namespace MaximInterface { +namespace mbed { + +void sleep(int ms) { wait_ms(ms); } + +Sleep & Sleep::instance() { + static Sleep instance; + return instance; +} + +void Sleep::operator()(int ms) const { sleep(ms); } + +} // namespace mbed +} // namespace MaximInterface \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Platforms/mbed/Sleep.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,57 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_mbed_Sleep +#define MaximInterface_mbed_Sleep + +#include <MaximInterface/Links/Sleep.hpp> +#include <MaximInterface/Utilities/Uncopyable.hpp> + +namespace MaximInterface { +namespace mbed { + +void sleep(int ms); + +class Sleep : public MaximInterface::Sleep, private Uncopyable { +public: + static Sleep & instance(); + + virtual void operator()(int ms) const; + +private: + Sleep() {} +}; + +} // namespace mbed +} // namespace MaximInterface + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Platforms/mbed/TARGET_Maxim/TARGET_MAX32600/GpioOneWireMaster.cpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,173 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifdef TARGET_MAX32600 + +#include "GpioOneWireMaster.hpp" +#include "owlink.h" +#include <gpio_regs.h> +#include <clkman_regs.h> + +namespace MaximInterface { + +static const OneWireTiming stdTiming = { + 560, // tRSTL + 68, // tMSP + 64, // tW0L + 8, // tW1L + 12, // tMSR + 70, // tSLOT +}; + +static const OneWireTiming odTiming = { + 56, // tRSTL + 8, // tMSP + 8, // tW0L + 1, // tW1L + 1, // tMSR + 10, // tSLOT +}; + +GpioOneWireMaster::GpioOneWireMaster(PinName owGpio, PinName extSpu, + bool extSpuActiveHigh) + : port(PINNAME_TO_PORT(owGpio)), pin(PINNAME_TO_PIN(owGpio)), + speed(StandardSpeed), extSpu(extSpu), extSpuActiveHigh(extSpuActiveHigh) { +} + +error_code GpioOneWireMaster::initialize() { + if (MXC_CLKMAN->clk_ctrl_1_gpio == MXC_E_CLKMAN_CLK_SCALE_DISABLED) { + MXC_CLKMAN->clk_ctrl_1_gpio = MXC_E_CLKMAN_CLK_SCALE_ENABLED; + } + + /* Set function */ + MXC_GPIO->func_sel[port] &= ~(0xF << (4 * pin)); + + /* Normal input is always enabled */ + MXC_GPIO->in_mode[port] &= ~(0xF << (4 * pin)); + + writeGpioHigh(); + setLevel(NormalLevel); + + return error_code(); +} + +error_code GpioOneWireMaster::reset() { + const OneWireTiming & curTiming(speed == OverdriveSpeed ? odTiming + : stdTiming); + const uint16_t tREC = curTiming.tRSTL - curTiming.tMSP; // tSLOT = 2 *tRSTL + + __disable_irq(); // Enter critical section + + writeGpioLow(); // Pull low + ow_usdelay(curTiming.tRSTL); // Wait specified time for reset pulse + writeGpioHigh(); // Let go of pin + ow_usdelay(curTiming.tMSP); // Wait specified time for master sample + const bool pd_pulse = readGpio(); // Get sample + ow_usdelay(tREC); // Wait for slot time to finish including recovery + + __enable_irq(); // Exit critical section + + return pd_pulse ? make_error_code(NoSlaveError) : error_code(); +} + +error_code GpioOneWireMaster::touchBitSetLevel(bool & sendRecvBit, + Level afterLevel) { + __disable_irq(); // Enter critical section + + uint8_t sendRecvUint = sendRecvBit; + ow_bit(&sendRecvUint, &MXC_GPIO->in_val[port], &MXC_GPIO->out_val[port], + (1 << pin), ((speed == OverdriveSpeed) ? &odTiming : &stdTiming)); + setLevel(afterLevel); + sendRecvBit = sendRecvUint; + + __enable_irq(); // Exit critical section + + return error_code(); +} + +error_code GpioOneWireMaster::setSpeed(Speed newSpeed) { + if (!((newSpeed == StandardSpeed) || (newSpeed == OverdriveSpeed))) { + return make_error_code(InvalidSpeedError); + } + speed = newSpeed; + return error_code(); +} + +error_code GpioOneWireMaster::setLevel(Level newLevel) { + error_code result; + switch (newLevel) { + case NormalLevel: + setGpioMode(MXC_V_GPIO_OUT_MODE_OPEN_DRAIN); + if (extSpu.is_connected()) { + extSpu = !extSpuActiveHigh; + } + break; + + case StrongLevel: + if (extSpu.is_connected()) { + extSpu = extSpuActiveHigh; + } else { + setGpioMode(MXC_V_GPIO_OUT_MODE_NORMAL_DRIVE); + } + break; + + default: + result = make_error_code(InvalidLevelError); + break; + } + return result; +} + +inline void GpioOneWireMaster::writeGpioLow() { + MXC_GPIO->out_val[port] &= ~(1 << pin); +} + +inline void GpioOneWireMaster::writeGpioHigh() { + MXC_GPIO->out_val[port] |= (1 << pin); +} + +inline bool GpioOneWireMaster::readGpio() { + return ((MXC_GPIO->in_val[port] & (1 << pin)) >> pin); +} + +inline void GpioOneWireMaster::setGpioMode(unsigned int mode) { + //read port out_mode + uint32_t ow_out_mode = MXC_GPIO->out_mode[port]; + //clear the mode for ow_pin + ow_out_mode &= ~(0xF << (pin * 4)); + //write ow_pin mode and original data back + MXC_GPIO->out_mode[port] = (ow_out_mode | (mode << (pin * 4))); +} + +} // namespace MaximInterface + +#endif /* TARGET_MAX32600 */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Platforms/mbed/TARGET_Maxim/TARGET_MAX32600/GpioOneWireMaster.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,70 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_GpioOneWireMaster +#define MaximInterface_GpioOneWireMaster + +#include <MaximInterface/Links/OneWireMaster.hpp> +#include <DigitalOut.h> + +namespace MaximInterface { + +class GpioOneWireMaster : public OneWireMaster { +public: + /// @param owGpio Pin to use for 1-Wire bus + /// @param extSpu Pin to use for external Strong Pullup + explicit GpioOneWireMaster(PinName owGpio, PinName extSpu = NC, + bool extSpuActiveHigh = false); + + error_code initialize(); + + virtual error_code reset(); + virtual error_code touchBitSetLevel(bool & sendRecvBit, Level afterLevel); + virtual error_code setSpeed(Speed newSpeed); + virtual error_code setLevel(Level newLevel); + +private: + unsigned int port; + unsigned int pin; + Speed speed; + mbed::DigitalOut extSpu; + bool extSpuActiveHigh; + + inline void writeGpioLow(); + inline void writeGpioHigh(); + inline bool readGpio(); + inline void setGpioMode(unsigned int mode); +}; + +} // namespace MaximInterface + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Platforms/mbed/TARGET_Maxim/TARGET_MAX32600/TOOLCHAIN_ARM_STD/owlink.s Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,199 @@ +/******************************************************************//** +* Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +**********************************************************************/ + +// ow_usdelay configuration +#define PROC_CLOCK_MHZ (__SYSTEM_HFX / 1000000) // Processor clock in MHz +#define OVERHEAD_TUNING 18 // Fraction where OverheadTime(us) = OVERHEAD_TUNING / PROC_CLOCK_MHZ +// Make PROC_CLOCK_MHZ and OVERHEAD_TUNING divisible by PROC_CYCLES_PER_LOOP for best results + +// ow_usdelay constants +#define PIPELINE_REFILL_PROC_CYCLES 1 // ARM specifies 1-3 cycles for pipeline refill following a branch +#define PROC_CYCLES_PER_LOOP (2 + PIPELINE_REFILL_PROC_CYCLES) +#define LOOPS_PER_US (PROC_CLOCK_MHZ / PROC_CYCLES_PER_LOOP) // Number of loop passes for a 1 us delay +#define LOOPS_REMOVED_TUNING (OVERHEAD_TUNING / PROC_CYCLES_PER_LOOP) + +// OwTiming offsets +#define tRSTL_OFFSET 0 +#define tMSP_OFFSET 2 +#define tW0L_OFFSET 4 +#define tW1L_OFFSET 6 +#define tMSR_OFFSET 8 +#define tSLOT_OFFSET 10 + +// Define a code section + AREA owlink, CODE +// void ow_usdelay(unsigned int time_us) + EXPORT ow_usdelay +ow_usdelay + cmp R0, #0 // Return if time_us equals zero + beq ow_usdelay_return + mov R2, #LOOPS_PER_US + mul R0, R0, R2 + sub R0, R0, #LOOPS_REMOVED_TUNING +loop + subs R0, R0, #1 + bne loop +ow_usdelay_return + bx R14 + +// static void write_ow_gpio_low(unsigned int * portReg, unsigned int pinMask) + MACRO +$label write_ow_gpio_low + ldr R2, [R0] + bic R2, R2, R1 + str R2, [R0] + MEND + +// static void write_ow_gpio_high(unsigned int * portReg, unsigned int pinMask) + MACRO +$label write_ow_gpio_high + ldr R2, [R0] + orr R2, R2, R1 + str R2, [R0] + MEND + +// void ow_bit(uint8_t * sendrecvbit, volatile uint32_t * inPortReg, volatile uint32_t * outPortReg, unsigned int pinMask, const OwTiming * timing) + EXPORT ow_bit +ow_bit + push {R4-R8, R14} + // Retrive extra parameters from stack + add R6, SP, #24 // Find beginning of stack: 6 scratch registers * 4 bytes each + ldr R6, [R6] // Load timing struct + ldrh R4, [R6, #tSLOT_OFFSET] + ldrh R5, [R6, #tMSR_OFFSET] + // R0: sendrecvbit + // R1: inPortReg + // R2: outPortReg + // R3: pinMask + // R4: tSLOT + // R5: tMSR + // R6: timing + // R7: Scratch + // R8: Scratch + // R14: Scratch + + // Reorganize registers for upcoming function calls + mov R8, R1 // inPortReg to R8 + mov R7, R2 // outPortReg to R7 + mov R1, R3 // pinMask to R1 + mov R3, R0 // sendrecvbit to R3 + // R0: Scratch + // R1: pinMask + // R2: Scratch + // R3: sendrecvbit + // R4: tSLOT + // R5: tMSR + // R6: timing + // R7: outPortReg + // R8: inPortReg + // R14: Scratch + + // if (*sendrecvbit & 1) + ldrb R14, [R3] + tst R14, #1 + beq write_zero + ldrh R6, [R6, #tW1L_OFFSET] // tW1L + sub R4, R4, R5 // tREC = tSLOT - tMSR + sub R5, R5, R6 // delay2 = tMSR - tLW1L + // R0: Scratch + // R1: pinMask + // R2: Scratch + // R3: sendrecvbit + // R4: tREC + // R5: delay2 + // R6: tW1L + // R7: outPortReg + // R8: inPortReg + // R14: Scratch + mov R0, R7 // outPortReg + write_ow_gpio_low // Pull low + mov R0, R6 // tLOW + bl ow_usdelay // Delay for tLOW + mov R0, R7 // outPortReg + write_ow_gpio_high // Release pin + mov R0, R5 // delay2 + bl ow_usdelay // Delay for sample time + ldr R5, [R8] // Read *inPortReg + b recovery_delay + // else +write_zero + ldrh R6, [R6, #tW0L_OFFSET] // tW0L + sub R4, R4, R6 // tREC = tSLOT - tLW0L + sub R6, R6, R5 // delay2 = tW0L - tMSR + // R0: Scratch + // R1: pinMask + // R2: Scratch + // R3: sendrecvbit + // R4: tREC + // R5: tMSR + // R6: delay2 + // R7: outPortReg + // R8: inPortReg + // R14: Scratch + mov R0, R7 // outPortReg + write_ow_gpio_low // Pull low + mov R0, R5 // tMSR + bl ow_usdelay // Delay for tMSR + ldr R5, [R8] // Read *inPortReg + mov R0, R6 // delay2 + bl ow_usdelay // Delay for release + mov R0, R7 // outPortReg + write_ow_gpio_high // Release pin + // endif (*sendrecvbit & 1) + // R0: Scratch + // R1: pinMask + // R2: Scratch + // R3: sendrecvbit + // R4: tREC + // R5: *inPortReg + // R6: Scratch + // R7: outPortReg + // R8: inPortReg + // R14: Scratch + +recovery_delay + mov R0, R4 + bl ow_usdelay // Delay for tREC + + // Parse received bit + // *sendrecvbit = ((*inPortReg & pinMask) == pinMask) + and R5, R5, R1 + cmp R5, R1 + ite eq + moveq R5, #1 + movne R5, #0 + strb R5, [R3] + + pop {R4-R8, R14} + bx R14 + + END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Platforms/mbed/TARGET_Maxim/TARGET_MAX32600/TOOLCHAIN_GCC_ARM/owlink.S Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,200 @@ +/******************************************************************//** +* Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +**********************************************************************/ + +// ow_usdelay configuration +#define PROC_CLOCK_MHZ (__SYSTEM_HFX / 1000000) // Processor clock in MHz +#define OVERHEAD_TUNING 18 // Fraction where OverheadTime(us) = OVERHEAD_TUNING / PROC_CLOCK_MHZ +// Make PROC_CLOCK_MHZ and OVERHEAD_TUNING divisible by PROC_CYCLES_PER_LOOP for best results + +// ow_usdelay constants +#define PIPELINE_REFILL_PROC_CYCLES 1 // ARM specifies 1-3 cycles for pipeline refill following a branch +#define PROC_CYCLES_PER_LOOP (2 + PIPELINE_REFILL_PROC_CYCLES) +#define LOOPS_PER_US (PROC_CLOCK_MHZ / PROC_CYCLES_PER_LOOP) // Number of loop passes for a 1 us delay +#define LOOPS_REMOVED_TUNING (OVERHEAD_TUNING / PROC_CYCLES_PER_LOOP) + +// OwTiming offsets +#define tRSTL_OFFSET 0 +#define tMSP_OFFSET 2 +#define tW0L_OFFSET 4 +#define tW1L_OFFSET 6 +#define tMSR_OFFSET 8 +#define tSLOT_OFFSET 10 + +// Define a code section + .syntax unified + .section .text +// void ow_usdelay(unsigned int time_us) + .thumb_func + .global ow_usdelay +ow_usdelay: + cmp R0, #0 // Return if time_us equals zero + beq ow_usdelay_return + mov R2, #LOOPS_PER_US + mul R0, R0, R2 + sub R0, R0, #LOOPS_REMOVED_TUNING +loop: + subs R0, R0, #1 + bne loop +ow_usdelay_return: + bx R14 + +// static void write_ow_gpio_low(unsigned int * portReg, unsigned int pinMask) +.macro write_ow_gpio_low + ldr R2, [R0] + bic R2, R2, R1 + str R2, [R0] + .endm + +// static void write_ow_gpio_high(unsigned int * portReg, unsigned int pinMask) +.macro write_ow_gpio_high + ldr R2, [R0] + orr R2, R2, R1 + str R2, [R0] + .endm + +// void ow_bit(uint8_t * sendrecvbit, volatile uint32_t * inPortReg, volatile uint32_t * outPortReg, unsigned int pinMask, const OwTiming * timing) + .thumb_func + .global ow_bit +ow_bit: + push {R4-R8, R14} + // Retrive extra parameters from stack + add R6, SP, #24 // Find beginning of stack: 6 scratch registers * 4 bytes each + ldr R6, [R6] // Load timing struct + ldrh R4, [R6, #tSLOT_OFFSET] + ldrh R5, [R6, #tMSR_OFFSET] + // R0: sendrecvbit + // R1: inPortReg + // R2: outPortReg + // R3: pinMask + // R4: tSLOT + // R5: tMSR + // R6: timing + // R7: Scratch + // R8: Scratch + // R14: Scratch + + // Reorganize registers for upcoming function calls + mov R8, R1 // inPortReg to R8 + mov R7, R2 // outPortReg to R7 + mov R1, R3 // pinMask to R1 + mov R3, R0 // sendrecvbit to R3 + // R0: Scratch + // R1: pinMask + // R2: Scratch + // R3: sendrecvbit + // R4: tSLOT + // R5: tMSR + // R6: timing + // R7: outPortReg + // R8: inPortReg + // R14: Scratch + + // if (*sendrecvbit & 1) + ldrb R14, [R3] + tst R14, #1 + beq write_zero + ldrh R6, [R6, #tW1L_OFFSET] // tW1L + sub R4, R4, R5 // tREC = tSLOT - tMSR + sub R5, R5, R6 // delay2 = tMSR - tLW1L + // R0: Scratch + // R1: pinMask + // R2: Scratch + // R3: sendrecvbit + // R4: tREC + // R5: delay2 + // R6: tW1L + // R7: outPortReg + // R8: inPortReg + // R14: Scratch + mov R0, R7 // outPortReg + write_ow_gpio_low // Pull low + mov R0, R6 // tLOW + bl ow_usdelay // Delay for tLOW + mov R0, R7 // outPortReg + write_ow_gpio_high // Release pin + mov R0, R5 // delay2 + bl ow_usdelay // Delay for sample time + ldr R5, [R8] // Read *inPortReg + b recovery_delay + // else +write_zero: + ldrh R6, [R6, #tW0L_OFFSET] // tW0L + sub R4, R4, R6 // tREC = tSLOT - tLW0L + sub R6, R6, R5 // delay2 = tW0L - tMSR + // R0: Scratch + // R1: pinMask + // R2: Scratch + // R3: sendrecvbit + // R4: tREC + // R5: tMSR + // R6: delay2 + // R7: outPortReg + // R8: inPortReg + // R14: Scratch + mov R0, R7 // outPortReg + write_ow_gpio_low // Pull low + mov R0, R5 // tMSR + bl ow_usdelay // Delay for tMSR + ldr R5, [R8] // Read *inPortReg + mov R0, R6 // delay2 + bl ow_usdelay // Delay for release + mov R0, R7 // outPortReg + write_ow_gpio_high // Release pin + // endif (*sendrecvbit & 1) + // R0: Scratch + // R1: pinMask + // R2: Scratch + // R3: sendrecvbit + // R4: tREC + // R5: *inPortReg + // R6: Scratch + // R7: outPortReg + // R8: inPortReg + // R14: Scratch + +recovery_delay: + mov R0, R4 + bl ow_usdelay // Delay for tREC + + // Parse received bit + // *sendrecvbit = ((*inPortReg & pinMask) == pinMask) + and R5, R5, R1 + cmp R5, R1 + ite eq + moveq R5, #1 + movne R5, #0 + strb R5, [R3] + + pop {R4-R8, R14} + bx R14 + .end + \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Platforms/mbed/TARGET_Maxim/TARGET_MAX32600/TOOLCHAIN_IAR/owlink.s Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,197 @@ +/******************************************************************//** +* Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +**********************************************************************/ + +// ow_usdelay configuration +#define PROC_CLOCK_MHZ (__SYSTEM_HFX / 1000000) // Processor clock in MHz +#define OVERHEAD_TUNING 18 // Fraction where OverheadTime(us) = OVERHEAD_TUNING / PROC_CLOCK_MHZ +// Make PROC_CLOCK_MHZ and OVERHEAD_TUNING divisible by PROC_CYCLES_PER_LOOP for best results + +// ow_usdelay constants +#define PIPELINE_REFILL_PROC_CYCLES 1 // ARM specifies 1-3 cycles for pipeline refill following a branch +#define PROC_CYCLES_PER_LOOP (2 + PIPELINE_REFILL_PROC_CYCLES) +#define LOOPS_PER_US (PROC_CLOCK_MHZ / PROC_CYCLES_PER_LOOP) // Number of loop passes for a 1 us delay +#define LOOPS_REMOVED_TUNING (OVERHEAD_TUNING / PROC_CYCLES_PER_LOOP) + +// OwTiming offsets +#define tRSTL_OFFSET 0 +#define tMSP_OFFSET 2 +#define tW0L_OFFSET 4 +#define tW1L_OFFSET 6 +#define tMSR_OFFSET 8 +#define tSLOT_OFFSET 10 + +// Define a code section + SECTION owlink : CODE + +// void ow_usdelay(unsigned int time_us) + EXPORT ow_usdelay +ow_usdelay + cmp R0, #0 // Return if time_us equals zero + beq ow_usdelay_return + mov R2, #LOOPS_PER_US + mul R0, R0, R2 + sub R0, R0, #LOOPS_REMOVED_TUNING +loop + subs R0, R0, #1 + bne loop +ow_usdelay_return + bx R14 + +// static void write_ow_gpio_low(unsigned int * portReg, unsigned int pinMask) +write_ow_gpio_low MACRO + ldr R2, [R0] + bic R2, R2, R1 + str R2, [R0] + ENDM + +// static void write_ow_gpio_high(unsigned int * portReg, unsigned int pinMask) +write_ow_gpio_high MACRO + ldr R2, [R0] + orr R2, R2, R1 + str R2, [R0] + ENDM + +// void ow_bit(uint8_t * sendrecvbit, volatile uint32_t * inPortReg, volatile uint32_t * outPortReg, unsigned int pinMask, const OwTiming * timing) + EXPORT ow_bit +ow_bit + push {R4-R8, R14} + // Retrive extra parameters from stack + add R6, SP, #24 // Find beginning of stack: 6 scratch registers * 4 bytes each + ldr R6, [R6] // Load timing struct + ldrh R4, [R6, #tSLOT_OFFSET] + ldrh R5, [R6, #tMSR_OFFSET] + // R0: sendrecvbit + // R1: inPortReg + // R2: outPortReg + // R3: pinMask + // R4: tSLOT + // R5: tMSR + // R6: timing + // R7: Scratch + // R8: Scratch + // R14: Scratch + + // Reorganize registers for upcoming function calls + mov R8, R1 // inPortReg to R8 + mov R7, R2 // outPortReg to R7 + mov R1, R3 // pinMask to R1 + mov R3, R0 // sendrecvbit to R3 + // R0: Scratch + // R1: pinMask + // R2: Scratch + // R3: sendrecvbit + // R4: tSLOT + // R5: tMSR + // R6: timing + // R7: outPortReg + // R8: inPortReg + // R14: Scratch + + // if (*sendrecvbit & 1) + ldrb R14, [R3] + tst R14, #1 + beq write_zero + ldrh R6, [R6, #tW1L_OFFSET] // tW1L + sub R4, R4, R5 // tREC = tSLOT - tMSR + sub R5, R5, R6 // delay2 = tMSR - tLW1L + // R0: Scratch + // R1: pinMask + // R2: Scratch + // R3: sendrecvbit + // R4: tREC + // R5: delay2 + // R6: tW1L + // R7: outPortReg + // R8: inPortReg + // R14: Scratch + mov R0, R7 // outPortReg + write_ow_gpio_low // Pull low + mov R0, R6 // tLOW + bl ow_usdelay // Delay for tLOW + mov R0, R7 // outPortReg + write_ow_gpio_high // Release pin + mov R0, R5 // delay2 + bl ow_usdelay // Delay for sample time + ldr R5, [R8] // Read *inPortReg + b recovery_delay + // else +write_zero + ldrh R6, [R6, #tW0L_OFFSET] // tW0L + sub R4, R4, R6 // tREC = tSLOT - tLW0L + sub R6, R6, R5 // delay2 = tW0L - tMSR + // R0: Scratch + // R1: pinMask + // R2: Scratch + // R3: sendrecvbit + // R4: tREC + // R5: tMSR + // R6: delay2 + // R7: outPortReg + // R8: inPortReg + // R14: Scratch + mov R0, R7 // outPortReg + write_ow_gpio_low // Pull low + mov R0, R5 // tMSR + bl ow_usdelay // Delay for tMSR + ldr R5, [R8] // Read *inPortReg + mov R0, R6 // delay2 + bl ow_usdelay // Delay for release + mov R0, R7 // outPortReg + write_ow_gpio_high // Release pin + // endif (*sendrecvbit & 1) + // R0: Scratch + // R1: pinMask + // R2: Scratch + // R3: sendrecvbit + // R4: tREC + // R5: *inPortReg + // R6: Scratch + // R7: outPortReg + // R8: inPortReg + // R14: Scratch + +recovery_delay + mov R0, R4 + bl ow_usdelay // Delay for tREC + + // Parse received bit + // *sendrecvbit = ((*inPortReg & pinMask) == pinMask) + and R5, R5, R1 + cmp R5, R1 + ite eq + moveq R5, #1 + movne R5, #0 + strb R5, [R3] + + pop {R4-R8, R14} + bx R14 + END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Platforms/mbed/TARGET_Maxim/TARGET_MAX32600/owlink.h Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,72 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_owlink +#define MaximInterface_owlink + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/// Timing parameters for the 1-Wire bus. +/// @note All times are in terms of microseconds. +struct OneWireTiming { + uint16_t tRSTL; ///< Reset Low Time + uint16_t tMSP; ///< Presence-Detect Sample Time + uint16_t tW0L; ///< Write-Zero Low Time + uint16_t tW1L; ///< Write-One Low Time + uint16_t tMSR; ///< Read Sample Time + uint16_t tSLOT; ///< Time Slot Duration +}; + +/// Delay for the specified number of microseconds. +void ow_usdelay(unsigned int time_us); + +/// Send and receive one bit of communication and set a new level on the 1-Wire bus. +/// @note GPIO pin must be configured for open drain operation. +/// @param[in,out] sendRecvBit Buffer containing the bit to send on 1-Wire bus in lsb. +/// Read data from 1-Wire bus will be returned in lsb. +/// @param inReg Input register for GPIO pin. +/// @param outReg Output register for GPIO pin. +/// @param pinMask Pin mask for input and output registers. +/// @param[in] timing 1-Wire timing parameters to use. +void ow_bit(uint8_t * sendRecvBit, volatile uint32_t * inReg, + volatile uint32_t * outPortReg, unsigned int pinMask, + const OneWireTiming * timing); + +#ifdef __cplusplus +} +#endif + +#endif /* MaximInterface_owlink */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Platforms/mbed/Uart.cpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,106 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#include <MaximInterface/Utilities/Error.hpp> +#include <Timer.h> +#include "Uart.hpp" + +static const int timeout_ms = 10000; + +namespace MaximInterface { +namespace mbed { + +error_code Uart::setBaud(int_least32_t baud) { + serial->baud(baud); + return error_code(); +} + +error_code Uart::sendBreak() { + serial->send_break(); + return error_code(); +} + +error_code Uart::clearReadBuffer() { + while (serial->readable()) { + serial->getc(); + } + return error_code(); +} + +error_code Uart::writeByte(uint_least8_t data) { + if (!serial->writeable()) { + ::mbed::Timer timer; + timer.start(); + while (!serial->writeable()) { + if (timer.read_ms() >= timeout_ms) { + return make_error_code(HardwareError); + } + } + } + serial->putc(data); + return error_code(); +} + +error_code Uart::readByte(uint_least8_t & data) { + if (!serial->readable()) { + ::mbed::Timer timer; + timer.start(); + while (!serial->readable()) { + if (timer.read_ms() >= timeout_ms) { + return make_error_code(TimeoutError); + } + } + } + data = serial->getc(); + return error_code(); +} + +const error_category & Uart::errorCategory() { + static class : public error_category { + public: + virtual const char * name() const { return "mbed UART"; } + + virtual std::string message(int condition) const { + switch (condition) { + case HardwareError: + return "Hardware Error"; + + default: + return defaultErrorMessage(condition); + } + } + } instance; + return instance; +} + +} // namespace mbed +} // namespace MaximInterface \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Platforms/mbed/Uart.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,72 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_mbed_Uart +#define MaximInterface_mbed_Uart + +#include <drivers/Serial.h> +#include <MaximInterface/Links/Uart.hpp> + +namespace MaximInterface { +namespace mbed { + +/// Wrapper for mbed::Serial. +class Uart : public MaximInterface::Uart { +public: + enum ErrorValue { + HardwareError = 1 ///< Write operation aborted due to timeout. + }; + + explicit Uart(::mbed::Serial & serial) : serial(&serial) {} + + void setSerial(::mbed::Serial & serial) { this->serial = &serial; } + + virtual error_code setBaud(int_least32_t baud); + virtual error_code sendBreak(); + virtual error_code clearReadBuffer(); + virtual error_code writeByte(uint_least8_t data); + virtual error_code readByte(uint_least8_t & data); + + static const error_category & errorCategory(); + +private: + ::mbed::Serial * serial; +}; + +inline error_code make_error_code(Uart::ErrorValue e) { + return error_code(e, Uart::errorCategory()); +} + +} // namespace mbed +} // namespace MaximInterface + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Platforms/mxc/.mbedignore Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,1 @@ +* \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Platforms/mxc/Error.cpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,61 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#include <MaximInterface/Links/I2CMaster.hpp> +#include <MaximInterface/Utilities/Error.hpp> +#include <mxc_errors.h> +#include "Error.hpp" + +namespace MaximInterface { +namespace mxc { + +const error_category & errorCategory() { + static class : public error_category { + public: + virtual const char * name() const { return "mxc"; } + + virtual std::string message(int condition) const { + return defaultErrorMessage(condition); + } + + // Make E_COMM_ERR equivalent to I2CMaster::NackError. + virtual bool equivalent(int code, const error_condition & condition) const { + return (code == E_COMM_ERR) + ? (condition == make_error_condition(I2CMaster::NackError)) + : error_category::equivalent(code, condition); + } + } instance; + return instance; +} + +} // namespace mxc +} // namespace MaximInterface
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Platforms/mxc/Error.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,53 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +/// @file Common functionality for mapping mxc return codes to +/// MaximInterface::error_code. + +#ifndef MaximInterface_mxc_Error +#define MaximInterface_mxc_Error + +#include <MaximInterface/Utilities/system_error.hpp> + +namespace MaximInterface { +namespace mxc { + +const error_category & errorCategory(); + +inline error_code makeErrorCode(int mxcResult) { + return error_code(mxcResult, errorCategory()); +} + +} // namespace mxc +} // namespace MaximInterface + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Platforms/mxc/I2CMaster.cpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,116 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#include <mxc_device.h> +#include "Error.hpp" +#include "I2CMaster.hpp" + +namespace MaximInterface { +namespace mxc { + +static void verifyTransactionStarted(mxc_i2cm_regs_t & i2cm) { + if (!(i2cm.trans & MXC_F_I2CM_TRANS_TX_IN_PROGRESS)) { + i2cm.trans |= MXC_F_I2CM_TRANS_TX_START; + } +} + +error_code I2CMaster::initialize(const sys_cfg_i2cm_t & sysCfg, + i2cm_speed_t speed) { + return makeErrorCode(I2CM_Init(i2cm, &sysCfg, speed)); +} + +error_code I2CMaster::shutdown() { return makeErrorCode(I2CM_Shutdown(i2cm)); } + +error_code I2CMaster::writeByte(uint_least8_t data, bool start) { + const uint16_t fifoData = + static_cast<uint16_t>(data & 0xFF) | + (start ? MXC_S_I2CM_TRANS_TAG_START : MXC_S_I2CM_TRANS_TAG_TXDATA_ACK); + const error_code result = + makeErrorCode(I2CM_WriteTxFifo(i2cm, i2cmFifo, fifoData)); + if (result) { + I2CM_Recover(i2cm); + } else { + verifyTransactionStarted(*i2cm); + } + return result; +} + +error_code I2CMaster::start(uint_least8_t address) { + return writeByte(address, true); +} + +error_code I2CMaster::stop() { + error_code result = makeErrorCode( + I2CM_WriteTxFifo(i2cm, i2cmFifo, MXC_S_I2CM_TRANS_TAG_STOP)); + if (!result) { + result = makeErrorCode(I2CM_TxInProgress(i2cm)); + } + return result; +} + +error_code I2CMaster::writeByte(uint_least8_t data) { + return writeByte(data, false); +} + +error_code I2CMaster::readByte(AckStatus status, uint_least8_t & data) { + uint16_t fifoData = (status == Nack) ? MXC_S_I2CM_TRANS_TAG_RXDATA_NACK + : MXC_S_I2CM_TRANS_TAG_RXDATA_COUNT; + error_code result = makeErrorCode(I2CM_WriteTxFifo(i2cm, i2cmFifo, fifoData)); + if (!result) { + verifyTransactionStarted(*i2cm); + do { + int timeout = 0x5000; + while ((i2cm->bb & MXC_F_I2CM_BB_RX_FIFO_CNT) == 0) { + if ((--timeout <= 0) || (i2cm->trans & MXC_F_I2CM_TRANS_TX_TIMEOUT)) { + result = makeErrorCode(E_TIME_OUT); + goto exit; + } + if (i2cm->trans & + (MXC_F_I2CM_TRANS_TX_LOST_ARBITR | MXC_F_I2CM_TRANS_TX_NACKED)) { + result = make_error_code(NackError); + goto exit; + } + } + fifoData = i2cmFifo->rx; + } while (fifoData & MXC_S_I2CM_RSTLS_TAG_EMPTY); + data = fifoData & 0xFF; + } + +exit: + if (result) { + I2CM_Recover(i2cm); + } + return result; +} + +} // namespace mxc +} // namespace MaximInterface
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Platforms/mxc/I2CMaster.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,73 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_mxc_I2CMaster +#define MaximInterface_mxc_I2CMaster + +#include <MaximInterface/Links/I2CMaster.hpp> +#include <i2cm.h> + +namespace MaximInterface { +namespace mxc { + +class I2CMaster : public MaximInterface::I2CMaster { +public: + I2CMaster(mxc_i2cm_regs_t & i2cm, mxc_i2cm_fifo_regs_t & i2cmFifo) + : i2cm(&i2cm), i2cmFifo(&i2cmFifo) {} + + void set_mxc_i2cm(mxc_i2cm_regs_t & i2cm, mxc_i2cm_fifo_regs_t & i2cmFifo) { + this->i2cm = &i2cm; + this->i2cmFifo = &i2cmFifo; + } + + /// Initialize the hardware interface for use. + error_code initialize(const sys_cfg_i2cm_t & sysCfg, i2cm_speed_t speed); + + /// Shutdown the hardware interface after use. + error_code shutdown(); + + virtual error_code start(uint_least8_t address); + virtual error_code stop(); + virtual error_code writeByte(uint_least8_t data); + virtual error_code readByte(AckStatus status, uint_least8_t & data); + +private: + error_code writeByte(uint_least8_t data, bool start); + + mxc_i2cm_regs_t * i2cm; + mxc_i2cm_fifo_regs_t * i2cmFifo; +}; + +} // namespace mxc +} // namespace MaximInterface + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Platforms/mxc/OneWireMaster.cpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,103 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#include "Error.hpp" +#include "OneWireMaster.hpp" + +namespace MaximInterface { +namespace mxc { + +error_code OneWireMaster::initialize(const owm_cfg_t & owmCfg, + const sys_cfg_owm_t & sysCfgOwm) { + extStrongPup = (owmCfg.ext_pu_mode != OWM_EXT_PU_UNUSED); + return makeErrorCode(OWM_Init(owm, &owmCfg, &sysCfgOwm)); +} + +error_code OneWireMaster::shutdown() { + return makeErrorCode(OWM_Shutdown(owm)); +} + +error_code OneWireMaster::reset() { + return OWM_Reset(owm) ? error_code() : make_error_code(NoSlaveError); +} + +error_code OneWireMaster::touchBitSetLevel(bool & sendRecvBit, + Level afterLevel) { + sendRecvBit = OWM_TouchBit(owm, sendRecvBit); + return setLevel(afterLevel); +} + +error_code OneWireMaster::writeByteSetLevel(uint_least8_t sendByte, + Level afterLevel) { + error_code result = makeErrorCode(OWM_WriteByte(owm, sendByte)); + if (!result) { + result = setLevel(afterLevel); + } + return result; +} + +error_code OneWireMaster::readByteSetLevel(uint_least8_t & recvByte, + Level afterLevel) { + recvByte = OWM_ReadByte(owm); + return setLevel(afterLevel); +} + +error_code OneWireMaster::setSpeed(Speed newSpeed) { + error_code result; + if (newSpeed == OverdriveSpeed) { + OWM_SetOverdrive(owm, 1); + } else if (newSpeed == StandardSpeed) { + OWM_SetOverdrive(owm, 0); + } else { + result = make_error_code(InvalidSpeedError); + } + return result; +} + +error_code OneWireMaster::setLevel(Level newLevel) { + error_code result; + if (extStrongPup) { + if (newLevel == StrongLevel) { + OWM_SetExtPullup(owm, 1); + } else if (newLevel == NormalLevel) { + OWM_SetExtPullup(owm, 0); + } else { + result = make_error_code(InvalidLevelError); + } + } else if (newLevel != NormalLevel) { + result = make_error_code(InvalidLevelError); + } + return result; +} + +} // namespace mxc +} // namespace MaximInterface
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Platforms/mxc/OneWireMaster.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,74 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_mxc_OneWireMaster +#define MaximInterface_mxc_OneWireMaster + +#include <MaximInterface/Links/OneWireMaster.hpp> +#include <owm.h> + +namespace MaximInterface { +namespace mxc { + +/// MCU peripheral 1-Wire master (OWM) +class OneWireMaster : public MaximInterface::OneWireMaster { +public: + explicit OneWireMaster(mxc_owm_regs_t & owm) + : owm(&owm), extStrongPup(false) {} + + void set_mxc_owm(mxc_owm_regs_t & owm) { this->owm = &owm; } + + /// Initialize the hardware interface for use. + error_code initialize(const owm_cfg_t & owmCfg, + const sys_cfg_owm_t & sysCfgOwm); + + /// Shutdown the hardware interface after use. + error_code shutdown(); + + virtual error_code reset(); + virtual error_code touchBitSetLevel(bool & sendRecvBit, Level afterLevel); + virtual error_code writeByteSetLevel(uint_least8_t sendByte, + Level afterLevel); + virtual error_code readByteSetLevel(uint_least8_t & recvByte, + Level afterLevel); + virtual error_code setSpeed(Speed newSpeed); + virtual error_code setLevel(Level newLevel); + +private: + mxc_owm_regs_t * owm; + bool extStrongPup; +}; + +} // namespace mxc +} // namespace MaximInterface + +#endif /* MaximInterface_mxc_OneWireMaster */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Platforms/mxc/Sleep.cpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,45 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#include "Sleep.hpp" + +namespace MaximInterface { +namespace mxc { + +void Sleep::operator()(int ms) const { + if (ms > 0) { + TMR_Delay(tmr, MSEC(static_cast<unsigned long>(ms))); + } +} + +} // namespace mxc +} // namespace MaximInterface
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Platforms/mxc/Sleep.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,57 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_mxc_Sleep +#define MaximInterface_mxc_Sleep + +#include <MaximInterface/Links/Sleep.hpp> +#include <tmr_utils.h> + +namespace MaximInterface { +namespace mxc { + +class Sleep : public MaximInterface::Sleep { +public: + explicit Sleep(mxc_tmr_regs_t & tmr) : tmr(&tmr) {} + + void set_mxc_tmr(mxc_tmr_regs_t & tmr) { this->tmr = &tmr; } + + virtual void operator()(int ms) const; + +private: + mxc_tmr_regs_t * tmr; +}; + +} // namespace mxc +} // namespace MaximInterface + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Utilities/Ecc256.cpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,54 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#include <algorithm> +#include "Ecc256.hpp" + +namespace MaximInterface { +namespace Ecc256 { + +CertificateData createCertificateData(const PublicKey & publicKey, + const RomId & romId, + const ManId & manId) { + using std::copy; + + CertificateData data; + CertificateData::iterator dataIt = data.begin(); + dataIt = copy(publicKey.x.begin(), publicKey.x.end(), dataIt); + dataIt = copy(publicKey.y.begin(), publicKey.y.end(), dataIt); + dataIt = copy(romId.begin(), romId.end(), dataIt); + copy(manId.begin(), manId.end(), dataIt); + return data; +} + +} // namespace Ecc256 +} // namespace MaximInterface
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Utilities/Ecc256.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,75 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_Ecc256 +#define MaximInterface_Ecc256 + +#include <stdint.h> +#include "array.hpp" +#include "Export.h" +#include "ManId.hpp" +#include "RomId.hpp" + +namespace MaximInterface { +namespace Ecc256 { + +typedef array<uint_least8_t, 32> Scalar; +struct Point { + Scalar x; + Scalar y; +}; + +typedef Scalar PrivateKey; +typedef Point PublicKey; +struct KeyPair { + PrivateKey privateKey; + PublicKey publicKey; +}; + +struct Signature { + Scalar r; + Scalar s; +}; + +/// Data used to create a device key certificate for ECC-256 authenticators. +typedef array<uint_least8_t, 2 * Scalar::csize + RomId::csize + ManId::csize> + CertificateData; + +/// Formats data for creating a device key certificate from the public key, +/// ROM ID, and MAN ID. +MaximInterface_EXPORT CertificateData createCertificateData( + const PublicKey & publicKey, const RomId & romId, const ManId & manId); + +} // namespace Ecc256 +} // namespace MaximInterface + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Utilities/Error.cpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,41 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#include "Error.hpp" + +namespace MaximInterface { + +const char * defaultErrorMessage(int condition) { + return (condition == 0) ? "Success" : "Unknown Error"; +} + +} // namespace MaximInterface \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Utilities/Error.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,46 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_Error +#define MaximInterface_Error + +#include "Export.h" + +namespace MaximInterface { + +/// Get the default error message associated with a condition. Typically used +/// by an error_category when the condition is unknown. +MaximInterface_EXPORT const char * defaultErrorMessage(int condition); + +} + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Utilities/Export.h Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,43 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_EXPORT + #ifdef _MSC_VER + #ifdef _DLL + #define MaximInterface_EXPORT __declspec(dllexport) + #else + #define MaximInterface_EXPORT __declspec(dllimport) + #endif /* _DLL */ + #else + #define MaximInterface_EXPORT + #endif /* _MSC_VER */ +#endif /* MaximInterface_EXPORT */ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Utilities/FlagSet.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,188 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_FlagSet +#define MaximInterface_FlagSet + +#include <stddef.h> +#include <bitset> + +namespace MaximInterface { + +/// Provides functionality similar to std::bitset except using a bit flag, +/// typically of an enum type, as the indexer. +template <typename Flag, size_t flagBits> class FlagSet { +public: + class reference { + public: + reference(FlagSet & flagSet, Flag flag) : flagSet(&flagSet), flag(flag) {} + reference & operator=(bool x) { + flagSet->set(flag, x); + return *this; + } + reference & operator=(const reference & x) { + return operator=(static_cast<bool>(x)); + } + operator bool() const { return flagSet->test(flag); } + bool operator~() const { return reference(*this).flip(); } + reference & flip() { + *this = !*this; + return *this; + } + + private: + FlagSet * flagSet; + Flag flag; + }; + + FlagSet() : bits() {} + FlagSet(unsigned long val) : bits(val) {} + + template <typename CharT, typename Traits, typename Alloc> + explicit FlagSet( + const std::basic_string<CharT, Traits, Alloc> & str, + typename std::basic_string<CharT, Traits, Alloc>::size_type pos = 0, + typename std::basic_string<CharT, Traits, Alloc>::size_type n = + std::basic_string<CharT, Traits, Alloc>::npos) + : bits(str, pos, n) {} + + bool operator==(const FlagSet & rhs) const { return bits == rhs.bits; } + bool operator!=(const FlagSet & rhs) const { return !operator==(rhs); } + + // Element access + bool operator[](Flag flag) const { return test(flag); } + reference operator[](Flag flag) { return reference(*this, flag); } + bool test(Flag flag) const { return (bits.to_ulong() & flag) == flag; } + bool any() const { return bits.any(); } + bool none() const { return bits.none(); } + size_t count() const { return bits.count(); } + + // Capacity + size_t size() const { return bits.size(); } + + // Modifiers + FlagSet & operator&=(const FlagSet & other) { + bits &= other.bits; + return *this; + } + FlagSet & operator|=(const FlagSet & other) { + bits |= other.bits; + return *this; + } + FlagSet & operator^=(const FlagSet & other) { + bits ^= other.bits; + return *this; + } + FlagSet operator~() const { return ~bits; } + + FlagSet & set() { + bits.set(); + return *this; + } + FlagSet & set(Flag flag, bool value = true) { + if (value) { + bits |= flag; + } else { + bits &= ~std::bitset<flagBits>(flag); + } + return *this; + } + FlagSet & reset() { + bits.reset(); + return *this; + } + FlagSet & reset(Flag flag) { return set(flag, false); } + FlagSet & flip() { + bits.flip(); + return *this; + } + FlagSet & flip(Flag flag) { + bits ^= flag; + return *this; + } + + // Conversions + template <typename CharT, typename Traits, typename Allocator> + std::basic_string<CharT, Traits, Allocator> to_string() const { + return bits.template to_string<CharT, Traits, Allocator>(); + } + unsigned long to_ulong() const { return bits.to_ulong(); } + +private: + std::bitset<flagBits> bits; + + template <typename CharT, typename Traits> + friend std::basic_ostream<CharT, Traits> & + operator<<(std::basic_ostream<CharT, Traits> & os, const FlagSet & x); + + template <typename CharT, class Traits> + friend std::basic_istream<CharT, Traits> & + operator>>(std::basic_istream<CharT, Traits> & is, FlagSet & x); +}; + +template <typename Flag, size_t flagBits> +FlagSet<Flag, flagBits> operator&(const FlagSet<Flag, flagBits> & lhs, + const FlagSet<Flag, flagBits> & rhs) { + return FlagSet<Flag, flagBits>(lhs) &= rhs; +} + +template <typename Flag, size_t flagBits> +FlagSet<Flag, flagBits> operator|(const FlagSet<Flag, flagBits> & lhs, + const FlagSet<Flag, flagBits> & rhs) { + return FlagSet<Flag, flagBits>(lhs) |= rhs; +} + +template <typename Flag, size_t flagBits> +FlagSet<Flag, flagBits> operator^(const FlagSet<Flag, flagBits> & lhs, + const FlagSet<Flag, flagBits> & rhs) { + return FlagSet<Flag, flagBits>(lhs) ^= rhs; +} + +template <typename CharT, typename Traits, typename Flag, size_t flagBits> +std::basic_ostream<CharT, Traits> & +operator<<(std::basic_ostream<CharT, Traits> & os, + const FlagSet<Flag, flagBits> & x) { + os << x.bits; + return os; +} + +template <typename CharT, class Traits, typename Flag, size_t flagBits> +std::basic_istream<CharT, Traits> & +operator>>(std::basic_istream<CharT, Traits> & is, + FlagSet<Flag, flagBits> & x) { + is >> x.bits; + return is; +} + +} // namespace MaximInterface + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Utilities/Function.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,466 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_Function +#define MaximInterface_Function + +#include <stddef.h> +#include "type_traits.hpp" + +// Include for std::swap. +#include <algorithm> +#include <utility> + +namespace MaximInterface { +namespace detail { + +// Provides char buffer storage for a given type. +// Suitability of alignment for type should be verified with alignment_of. +template <typename Type, size_t TypeSize> union TypeStorage { +public: + operator const Type *() const { return reinterpret_cast<const Type *>(data); } + + operator Type *() { + return const_cast<Type *>( + static_cast<const Type *>(static_cast<const TypeStorage &>(*this))); + } + + const Type & operator*() const { return **this; } + + Type & operator*() { + return const_cast<Type &>( + static_cast<const TypeStorage &>(*this).operator*()); + } + + const Type * operator->() const { return *this; } + + Type * operator->() { + return const_cast<Type *>( + static_cast<const TypeStorage &>(*this).operator->()); + } + +private: + char data[TypeSize]; + long double aligner; +}; + +// Computes the internal target size for TypeStorage based on a desired total +// size. No internal storage will be allocated if the requested size is smaller +// than the required data elements of TypeWrapper or if the requested size is +// smaller than minimum size of TypeStorage. +template <typename Target, size_t totalSize> class TypeWrapperTotalSize { +private: + typedef TypeStorage<Target, 1> MinSizeStorage; + static const size_t otherDataSize = sizeof(Target *); + // Round down to be a multiple of alignment_of<MinSizeTargetStorage>::value. + static const size_t internalTargetRawSize = + (totalSize - otherDataSize) / alignment_of<MinSizeStorage>::value * + alignment_of<MinSizeStorage>::value; + +public: + // Use internal storage if internalTargetRawSize is valid and at least as + // large as the minimum size of TypeStorage. + static const size_t internalTargetSize = + ((totalSize > otherDataSize) && + (internalTargetRawSize >= sizeof(MinSizeStorage))) + ? internalTargetRawSize + : 0; +}; + +// Basic type erasure implementation with small object optimization. +template <typename Target, template <typename> class TargetAdapter, + size_t internalTargetSize = + TypeWrapperTotalSize<Target, 32>::internalTargetSize> +class TypeWrapper { +private: + typedef TypeStorage<Target, internalTargetSize> TargetStorage; + +public: + TypeWrapper() : currentTarget(NULL) {} + + TypeWrapper(const TypeWrapper & other) { + if (other.currentTarget == other.internalTarget) { + other.currentTarget->clone(internalTarget); + currentTarget = internalTarget; + } else if (other.currentTarget) { + currentTarget = other.currentTarget->clone(); + } else { + currentTarget = NULL; + } + } + + template <typename Source> TypeWrapper(Source source) { + if (sizeof(TargetAdapter<Source>) <= internalTargetSize && + alignment_of<TargetAdapter<Source> >::value <= + alignment_of<TargetStorage>::value) { + new (internalTarget) TargetAdapter<Source>(source); + currentTarget = internalTarget; + } else { + currentTarget = new TargetAdapter<Source>(source); + } + } + + ~TypeWrapper() { + if (currentTarget == internalTarget) { + currentTarget->~Target(); + } else { + delete currentTarget; + } + } + + const TypeWrapper & operator=(const TypeWrapper & rhs) { + TypeWrapper(rhs).swap(*this); + return *this; + } + + template <typename Source> const TypeWrapper & operator=(Source source) { + TypeWrapper(source).swap(*this); + return *this; + } + + void clear() { TypeWrapper().swap(*this); } + + void swap(TypeWrapper & other) { + if (this == &other) { + return; + } + + if (currentTarget == internalTarget && + other.currentTarget == other.internalTarget) { + TargetStorage temp; + currentTarget->clone(temp); + currentTarget->~Target(); + currentTarget = NULL; + other.currentTarget->clone(internalTarget); + other.currentTarget->~Target(); + other.currentTarget = NULL; + currentTarget = internalTarget; + temp->clone(other.internalTarget); + temp->~Target(); + other.currentTarget = other.internalTarget; + } else if (currentTarget == internalTarget) { + currentTarget->clone(other.internalTarget); + currentTarget->~Target(); + currentTarget = other.currentTarget; + other.currentTarget = other.internalTarget; + } else if (other.currentTarget == other.internalTarget) { + other.currentTarget->clone(internalTarget); + other.currentTarget->~Target(); + other.currentTarget = currentTarget; + currentTarget = internalTarget; + } else { + using std::swap; + swap(currentTarget, other.currentTarget); + } + } + + const Target * target() const { return currentTarget; } + +private: + TargetStorage internalTarget; + Target * currentTarget; +}; + +// TypeWrapper specialization with no internal storage space. +template <typename Target, template <typename> class TargetAdapter> +class TypeWrapper<Target, TargetAdapter, 0> { +public: + TypeWrapper() : currentTarget(NULL) {} + + TypeWrapper(const TypeWrapper & other) { + if (other.currentTarget) { + currentTarget = other.currentTarget->clone(); + } else { + currentTarget = NULL; + } + } + + template <typename Source> + TypeWrapper(Source source) + : currentTarget(new TargetAdapter<Source>(source)) {} + + ~TypeWrapper() { delete currentTarget; } + + const TypeWrapper & operator=(const TypeWrapper & rhs) { + TypeWrapper(rhs).swap(*this); + return *this; + } + + template <typename Source> const TypeWrapper & operator=(Source source) { + TypeWrapper(source).swap(*this); + return *this; + } + + void clear() { TypeWrapper().swap(*this); } + + void swap(TypeWrapper & other) { + using std::swap; + swap(currentTarget, other.currentTarget); + } + + const Target * target() const { return currentTarget; } + +private: + Target * currentTarget; +}; + +} // namespace detail + +// Function wrapper similar to std::function for 0-2 argument functions. +template <typename> class Function; + +// Function implementation for zero argument functions. +template <typename ResultType> class Function<ResultType()> { +public: + typedef ResultType result_type; + + Function(ResultType (*func)() = NULL) : callableWrapper() { + if (func) { + callableWrapper = func; + } + } + + template <typename F> Function(F func) : callableWrapper(func) {} + + const Function & operator=(ResultType (*func)()) { + if (func) { + callableWrapper = func; + } else { + callableWrapper.clear(); + } + return *this; + } + + template <typename F> const Function & operator=(F func) { + callableWrapper = func; + return *this; + } + + void swap(Function & other) { callableWrapper.swap(other.callableWrapper); } + + operator bool() const { return callableWrapper.target() != NULL; } + + ResultType operator()() const { + return callableWrapper.target() ? (*callableWrapper.target())() + : ResultType(); + } + +private: + class Callable { + public: + virtual ~Callable() {} + virtual ResultType operator()() const = 0; + virtual Callable * clone() const = 0; + virtual void clone(void * buffer) const = 0; + }; + + template <typename F> class CallableAdapter : public Callable { + public: + CallableAdapter(F func) : func(func) {} + + virtual ResultType operator()() const { return func(); } + + virtual Callable * clone() const { return new CallableAdapter(*this); } + + virtual void clone(void * buffer) const { + new (buffer) CallableAdapter(*this); + } + + private: + F func; + }; + + detail::TypeWrapper<Callable, CallableAdapter> callableWrapper; +}; + +template <typename ResultType> +inline void swap(Function<ResultType()> & lhs, Function<ResultType()> & rhs) { + lhs.swap(rhs); +} + +// Function implementation for one argument functions. +template <typename ArgumentType, typename ResultType> +class Function<ResultType(ArgumentType)> { +public: + typedef ArgumentType argument_type; + typedef ResultType result_type; + + Function(ResultType (*func)(ArgumentType) = NULL) : callableWrapper() { + if (func) { + callableWrapper = func; + } + } + + template <typename F> Function(F func) : callableWrapper(func) {} + + const Function & operator=(ResultType (*func)(ArgumentType)) { + if (func) { + callableWrapper = func; + } else { + callableWrapper.clear(); + } + return *this; + } + + template <typename F> const Function & operator=(F func) { + callableWrapper = func; + return *this; + } + + void swap(Function & other) { callableWrapper.swap(other.callableWrapper); } + + operator bool() const { return callableWrapper.target() != NULL; } + + ResultType operator()(ArgumentType arg) const { + return callableWrapper.target() ? (*callableWrapper.target())(arg) + : ResultType(); + } + +private: + class Callable { + public: + virtual ~Callable() {} + virtual ResultType operator()(ArgumentType) const = 0; + virtual Callable * clone() const = 0; + virtual void clone(void * buffer) const = 0; + }; + + template <typename F> class CallableAdapter : public Callable { + public: + CallableAdapter(F func) : func(func) {} + + virtual ResultType operator()(ArgumentType arg) const { return func(arg); } + + virtual Callable * clone() const { return new CallableAdapter(*this); } + + virtual void clone(void * buffer) const { + new (buffer) CallableAdapter(*this); + } + + private: + F func; + }; + + detail::TypeWrapper<Callable, CallableAdapter> callableWrapper; +}; + +template <typename ArgumentType, typename ResultType> +inline void swap(Function<ResultType(ArgumentType)> & lhs, + Function<ResultType(ArgumentType)> & rhs) { + lhs.swap(rhs); +} + +// Function implementation for two argument functions. +template <typename FirstArgumentType, typename SecondArgumentType, + typename ResultType> +class Function<ResultType(FirstArgumentType, SecondArgumentType)> { +public: + typedef FirstArgumentType first_argument_type; + typedef SecondArgumentType second_argument_type; + typedef ResultType result_type; + + Function(ResultType (*func)(FirstArgumentType, SecondArgumentType) = NULL) + : callableWrapper() { + if (func) { + callableWrapper = func; + } + } + + template <typename F> Function(F func) : callableWrapper(func) {} + + const Function & operator=(ResultType (*func)(FirstArgumentType, + SecondArgumentType)) { + if (func) { + callableWrapper = func; + } else { + callableWrapper.clear(); + } + return *this; + } + + template <typename F> const Function & operator=(F func) { + callableWrapper = func; + return *this; + } + + void swap(Function & other) { callableWrapper.swap(other.callableWrapper); } + + operator bool() const { return callableWrapper.target() != NULL; } + + ResultType operator()(FirstArgumentType arg1, SecondArgumentType arg2) const { + return callableWrapper.target() ? (*callableWrapper.target())(arg1, arg2) + : ResultType(); + } + +private: + class Callable { + public: + virtual ~Callable() {} + virtual ResultType operator()(FirstArgumentType, + SecondArgumentType) const = 0; + virtual Callable * clone() const = 0; + virtual void clone(void * buffer) const = 0; + }; + + template <typename F> class CallableAdapter : public Callable { + public: + CallableAdapter(F func) : func(func) {} + + virtual ResultType operator()(FirstArgumentType arg1, + SecondArgumentType arg2) const { + return func(arg1, arg2); + } + + virtual Callable * clone() const { return new CallableAdapter(*this); } + + virtual void clone(void * buffer) const { + new (buffer) CallableAdapter(*this); + } + + private: + F func; + }; + + detail::TypeWrapper<Callable, CallableAdapter> callableWrapper; +}; + +template <typename FirstArgumentType, typename SecondArgumentType, + typename ResultType> +inline void +swap(Function<ResultType(FirstArgumentType, SecondArgumentType)> & lhs, + Function<ResultType(FirstArgumentType, SecondArgumentType)> & rhs) { + lhs.swap(rhs); +} + +} // namespace MaximInterface + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Utilities/HexConversions.cpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,62 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#include <cstdio> +#include "HexConversions.hpp" + +namespace MaximInterface { + +static const unsigned int charsPerByte = 2; + +std::string byteArrayToHexString(const uint_least8_t * byteArray, + size_t byteArraySize) { + std::string hexString; + char hexBuf[charsPerByte + 1]; + for (size_t i = 0; i < byteArraySize; i++) { + std::sprintf(hexBuf, "%2.2X", byteArray[i] & 0xFF); + hexString.append(hexBuf, charsPerByte); + } + return hexString; +} + +std::vector<uint_least8_t> hexStringToByteArray(const std::string & hexString) { + std::vector<uint_least8_t> byteArray; + byteArray.reserve(hexString.size() / charsPerByte + 1); + for (std::string::size_type i = 0; i < hexString.size(); i += charsPerByte) { + unsigned int byte; + std::sscanf(hexString.substr(i, charsPerByte).c_str(), "%2x", &byte); + byteArray.push_back(byte); + } + return byteArray; +} + +} // namespace MaximInterface
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Utilities/HexConversions.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,54 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_HexConversions +#define MaximInterface_HexConversions + +#include <stddef.h> +#include <stdint.h> +#include <string> +#include <vector> +#include <MaximInterface/Utilities/Export.h> + +namespace MaximInterface { + +/// Convert a byte array to a hex string. +MaximInterface_EXPORT std::string +byteArrayToHexString(const uint_least8_t * byteArray, size_t byteArraySize); + +/// Convert a hex string to a byte array. +MaximInterface_EXPORT std::vector<uint_least8_t> +hexStringToByteArray(const std::string & hexString); + +} // namespace MaximInterface + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Utilities/ManId.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,45 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_ManId +#define MaximInterface_ManId + +#include "array.hpp" + +namespace MaximInterface { + +/// Standard container for a manufacturer ID. +typedef array<uint_least8_t, 2> ManId; + +} // namespace MaximInterface + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Utilities/RomId.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,70 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_RomId +#define MaximInterface_RomId + +#include "array.hpp" +#include "crc.hpp" + +namespace MaximInterface { + +/// Standard container for a 1-Wire ROM ID. +typedef array<uint_least8_t, 8> RomId; + +/// @{ +/// Access the Family Code byte. +inline RomId::value_type familyCode(const RomId & romId) { + return romId.front(); +} +inline void setFamilyCode(RomId & romId, RomId::value_type familyCode) { + romId.front() = familyCode; +} +/// @} + +/// @{ +/// Access the CRC8 byte. +inline RomId::value_type crc8(const RomId & romId) { return romId.back(); } +inline void setCrc8(RomId & romId, RomId::value_type crc8) { + romId.back() = crc8; +} +/// @} + +/// Check if the ROM ID is valid (Family Code and CRC8 are both valid). +/// @returns True if the ROM ID is valid. +inline bool valid(const RomId & romId) { + return calculateCrc8(romId.data(), romId.size() - 1) == crc8(romId); +} + +} // namespace MaximInterface + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Utilities/Segment.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,131 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_Segment +#define MaximInterface_Segment + +#include <iterator> +#include <utility> +#include "type_traits.hpp" + +namespace MaximInterface { + +/// Advances a given iterator by a given number of elements with bounds checking. +/// InputIt must meet the requirements of InputIterator. +/// @param[in,out] it Iterator to advance. +/// @param bound +/// Past-the-end boundary iterator. If distance is positive, bound must be +/// reachable by incrementing the given iterator. If distance is negative, bound +/// must be reachable by decrementing the given iterator. +/// @param distance +/// Number of elements to advance the given iterator. If distance is positive, +/// the given iterator is incremented. If distance is negative, the given +/// iterator is decremented, and InputIt must meet the requirements of +/// BidirectionalIterator. +/// @returns The number of elements that the given iterator was advanced. +template <typename InputIt> +typename std::iterator_traits<InputIt>::difference_type checkedAdvance( + InputIt & it, const InputIt bound, + typename std::iterator_traits<InputIt>::difference_type distance) { + typedef + typename std::iterator_traits<InputIt>::difference_type difference_type; + + // Use constant-time operations if InputIt is a random access iterator. + if (is_same<typename std::iterator_traits<InputIt>::iterator_category, + std::random_access_iterator_tag>::value) { + const difference_type boundDistance = std::distance(it, bound); + if (boundDistance >= 0) { + if (distance > boundDistance) { + distance = boundDistance; + } else if (distance < 0) { + distance = 0; + } + } else { + if (distance < boundDistance) { + distance = boundDistance; + } else if (distance > 0) { + distance = 0; + } + } + std::advance(it, distance); + } else { + const difference_type startingDistance = distance; + while (distance != 0 && it != bound) { + if (distance > 0) { + ++it; + --distance; + } else { + --it; + ++distance; + } + } + if (startingDistance > 0) { + distance = startingDistance - distance; + } else { + distance = startingDistance + distance; + } + } + return distance; +} + +/// Locates an iterator sub-range using segment number addressing. Useful for +/// devices that divide the memory space into uniform chunks such as pages and +/// segments. ForwardIt must meet the requirements of ForwardIterator. +/// @param begin Beginning of the input data range. +/// @param end End of the input data range. +/// @param segmentSize Number of elements contained in a segment. +/// @param segmentNum Zero-indexed number of the desired segment. +/// @returns Pair of iterators representing the sub-range of the segment within +/// the input range. If the segment does not exist within the input range, both +/// iterators in the pair are set to the end interator of the input range. +template <typename ForwardIt, typename Index> +std::pair<ForwardIt, ForwardIt> createSegment( + ForwardIt begin, const ForwardIt end, + const typename std::iterator_traits<ForwardIt>::difference_type segmentSize, + Index segmentNum) { + ForwardIt segmentEnd = begin; + typename std::iterator_traits<ForwardIt>::difference_type lastSegmentSize = + checkedAdvance(segmentEnd, end, segmentSize); + while (segmentNum > 0 && segmentEnd != end) { + begin = segmentEnd; + lastSegmentSize = checkedAdvance(segmentEnd, end, segmentSize); + --segmentNum; + } + if (segmentNum > 0 || lastSegmentSize != segmentSize) { + begin = segmentEnd; + } + return std::make_pair(begin, segmentEnd); +} + +} // namespace MaximInterface + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Utilities/Sha256.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,59 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_Sha256 +#define MaximInterface_Sha256 + +#include <stdint.h> +#include "array.hpp" + +namespace MaximInterface { +namespace Sha256 { + +/// Container for a SHA-256 hash. +typedef array<uint_least8_t, 32> Hash; + +// Data used by SHA-256 MAC authenticators including DS28E15/22/25 and DS2465. + +/// Data for Compute Write MAC operation. +typedef array<uint_least8_t, 20> WriteMacData; + +/// Data for the Compute Auth. MAC operation. +typedef array<uint_least8_t, 76>AuthMacData; + +/// Data for the Compute Slave Secret operation. +typedef array<uint_least8_t, 76> SlaveSecretData; + +} // namespace Sha256 +} // namespace MaximInterface + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Utilities/Uncopyable.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,50 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_Uncopyable +#define MaximInterface_Uncopyable + +namespace MaximInterface { + +class Uncopyable { +protected: + Uncopyable() {} + ~Uncopyable() {} + +private: + Uncopyable(const Uncopyable &); + const Uncopyable & operator=(const Uncopyable &); +}; + +} // namespace MaximInterface + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Utilities/WriteMessage.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,46 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_WriteMessage +#define MaximInterface_WriteMessage + +#include <string> +#include "Function.hpp" + +namespace MaximInterface { + +/// Writes a message string to an output. +typedef Function<void(const std::string &)> WriteMessage; + +} + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Utilities/array.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,151 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_array +#define MaximInterface_array + +#include <stddef.h> +#include <stdint.h> +#include <algorithm> +#include <iterator> + +namespace MaximInterface { + +/// Generic array class similar to std::array. +template <typename T, size_t N> class array { +public: + typedef T value_type; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef value_type & reference; + typedef const value_type & const_reference; + typedef value_type * pointer; + typedef const value_type * const_pointer; + typedef pointer iterator; + typedef const_pointer const_iterator; + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + + // Element access + reference operator[](size_type pos) { + return const_cast<reference>( + static_cast<const array &>(*this).operator[](pos)); + } + const_reference operator[](size_type pos) const { return _buffer[pos]; } + reference front() { + return const_cast<reference>(static_cast<const array &>(*this).front()); + } + const_reference front() const { return _buffer[0]; } + reference back() { + return const_cast<reference>(static_cast<const array &>(*this).back()); + } + const_reference back() const { return _buffer[size() - 1]; } + pointer data() { + return const_cast<pointer>(static_cast<const array &>(*this).data()); + } + const_pointer data() const { return _buffer; } + + // Iterators + iterator begin() { + return const_cast<iterator>(static_cast<const array &>(*this).cbegin()); + } + const_iterator begin() const { return cbegin(); } + const_iterator cbegin() const { return _buffer; } + iterator end() { + return const_cast<iterator>(static_cast<const array &>(*this).cend()); + } + const_iterator end() const { return cend(); } + const_iterator cend() const { return _buffer + size(); } + reverse_iterator rbegin() { return reverse_iterator(end()); } + const_reverse_iterator rbegin() const { + return const_reverse_iterator(end()); + } + const_reverse_iterator crbegin() const { return rbegin(); } + reverse_iterator rend() { return reverse_iterator(begin()); } + const_reverse_iterator rend() const { + return const_reverse_iterator(begin()); + } + const_reverse_iterator crend() const { return rend(); } + + // Capacity + static bool empty() { return size() == 0; } + static size_type size() { return N; } + static size_type max_size() { return size(); } + static const size_type csize = + N; ///< Alternative to size() when a constant expression is required. + + // Operations + void fill(const_reference value) { std::fill(begin(), end(), value); } + void swap(array & other) { std::swap_ranges(begin(), end(), other.begin()); } + + T _buffer[N]; +}; + +template <typename T, size_t N> +inline bool operator==(const array<T, N> & lhs, const array<T, N> & rhs) { + return std::equal(lhs.begin(), lhs.end(), rhs.begin()); +} + +template <typename T, size_t N> +inline bool operator!=(const array<T, N> & lhs, const array<T, N> & rhs) { + return !operator==(lhs, rhs); +} + +template <typename T, size_t N> +inline bool operator<(const array<T, N> & lhs, const array<T, N> & rhs) { + return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), + rhs.end()); +} + +template <typename T, size_t N> +inline bool operator>(const array<T, N> & lhs, const array<T, N> & rhs) { + return operator<(rhs, lhs); +} + +template <typename T, size_t N> +inline bool operator<=(const array<T, N> & lhs, const array<T, N> & rhs) { + return !operator>(lhs, rhs); +} + +template <typename T, size_t N> +inline bool operator>=(const array<T, N> & lhs, const array<T, N> & rhs) { + return !operator<(lhs, rhs); +} + +template <typename T, size_t N> +inline void swap(array<T, N> & lhs, array<T, N> & rhs) { + lhs.swap(rhs); +} + +} // namespace MaximInterface + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Utilities/crc.cpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,86 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#include "crc.hpp" + +namespace MaximInterface { + +uint_fast8_t calculateCrc8(uint_fast8_t data, uint_fast8_t crc) { + // See Application Note 27 + crc ^= data; + crc &= 0xff; + for (int i = 0; i < 8; i++) { + if (crc & 1) { + crc = (crc >> 1) ^ 0x8c; + } else { + crc = (crc >> 1); + } + } + return crc; +} + +uint_fast8_t calculateCrc8(const uint_least8_t * data, size_t dataLen, + uint_fast8_t crc) { + for (size_t i = 0; i < dataLen; i++) { + crc = calculateCrc8(data[i], crc); + } + return crc; +} + +uint_fast16_t calculateCrc16(uint_fast8_t data, uint_fast16_t crc) { + const uint_least8_t oddparity[] = {0, 1, 1, 0, 1, 0, 0, 1, + 1, 0, 0, 1, 0, 1, 1, 0}; + + uint_fast16_t data16 = (data ^ crc) & 0xff; + crc = (crc >> 8) & 0xff; + + if (oddparity[data16 & 0xf] ^ oddparity[data16 >> 4]) { + crc ^= 0xc001; + } + + data16 <<= 6; + crc ^= data16; + data16 <<= 1; + crc ^= data16; + + return crc; +} + +uint_fast16_t calculateCrc16(const uint_least8_t * data, size_t dataLen, + uint_fast16_t crc) { + for (size_t i = 0; i < dataLen; i++) { + crc = calculateCrc16(data[i], crc); + } + return crc; +} + +} // namespace MaximInterface
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Utilities/crc.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,77 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_crc +#define MaximInterface_crc + +#include <stddef.h> +#include <stdint.h> +#include <MaximInterface/Utilities/Export.h> + +namespace MaximInterface { + +/// Perform a CRC8 calculation. +/// @param data Data to pass though the CRC generator. +/// @param crc Beginning state of the CRC generator. +/// @returns The calculated CRC8. +MaximInterface_EXPORT uint_fast8_t calculateCrc8(uint_fast8_t data, + uint_fast8_t crc = 0); + +/// Perform a CRC8 calculation with variable length data. +/// @param[in] data Data array to pass through the CRC generator. +/// @param dataLen Length of the data array to process. +/// @param crc Beginning state of the CRC generator. +/// @returns The calculated CRC8. +MaximInterface_EXPORT uint_fast8_t calculateCrc8(const uint_least8_t * data, + size_t dataLen, + uint_fast8_t crc = 0); + +/// Perform a CRC16 calculation. +/// @param data Data to pass though the CRC generator. +/// @param crc Beginning state of the CRC generator. +/// @returns The calculated CRC16. +MaximInterface_EXPORT uint_fast16_t calculateCrc16(uint_fast8_t data, + uint_fast16_t crc = 0); + +/// Perform a CRC16 calculation with variable length data. +/// @param[in] data Data array to pass through the CRC generator. +/// @param data_offset Offset of the data array to begin processing. +/// @param data_len Length of the data array to process. +/// @param crc Beginning state of the CRC generator. +/// @returns The calculated CRC16. +MaximInterface_EXPORT uint_fast16_t calculateCrc16(const uint_least8_t * data, + size_t dataLen, + uint_fast16_t crc = 0); + +} // namespace MaximInterface + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Utilities/system_error.cpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,63 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#include "Error.hpp" +#include "system_error.hpp" + +namespace MaximInterface { + +error_condition error_category::default_error_condition(int code) const { + return error_condition(code, *this); +} + +bool error_category::equivalent(int code, + const error_condition & condition) const { + return default_error_condition(code) == condition; +} + +bool error_category::equivalent(const error_code & code, int condition) const { + return *this == code.category() && code.value() == condition; +} + +const error_category & system_category() { + static class : public error_category { + public: + virtual const char * name() const { return "system"; } + + virtual std::string message(int condition) const { + return defaultErrorMessage(condition); + } + } instance; + return instance; +} + +} // namespace MaximInterface \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Utilities/system_error.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,167 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_system_error +#define MaximInterface_system_error + +#include <string> +#include <MaximInterface/Utilities/Export.h> +#include "Uncopyable.hpp" + +namespace MaximInterface { + +class error_condition; +class error_code; + +class error_category : private Uncopyable { +public: + virtual ~error_category() {} + + virtual const char * name() const = 0; + MaximInterface_EXPORT virtual error_condition + default_error_condition(int code) const; + MaximInterface_EXPORT virtual bool + equivalent(int code, const error_condition & condition) const; + MaximInterface_EXPORT virtual bool equivalent(const error_code & code, + int condition) const; + virtual std::string message(int condition) const = 0; +}; +inline bool operator==(const error_category & lhs, const error_category & rhs) { + return &lhs == &rhs; +} +inline bool operator!=(const error_category & lhs, const error_category & rhs) { + return !operator==(lhs, rhs); +} +inline bool operator<(const error_category & lhs, const error_category & rhs) { + return &lhs < &rhs; +} + +MaximInterface_EXPORT const error_category & system_category(); + +class error_condition { +public: + error_condition() : value_(0), category_(&system_category()) {} + error_condition(int value, const error_category & category) + : value_(value), category_(&category) {} + + void assign(int value, const error_category & category) { + value_ = value; + category_ = &category; + } + void clear() { + value_ = 0; + category_ = &system_category(); + } + int value() const { return value_; } + const error_category & category() const { return *category_; } + std::string message() const { return category().message(value()); } + operator bool() const { return value() != 0; } + +private: + int value_; + const error_category * category_; +}; +inline bool operator==(const error_condition & lhs, + const error_condition & rhs) { + return (lhs.value() == rhs.value()) && (lhs.category() == rhs.category()); +} +inline bool operator!=(const error_condition & lhs, + const error_condition & rhs) { + return !operator==(lhs, rhs); +} +inline bool operator<(const error_condition & lhs, + const error_condition & rhs) { + return (lhs.category() < rhs.category()) || + ((lhs.category() == rhs.category()) && (lhs.value() < rhs.value())); +} + +class error_code { +public: + error_code() : value_(0), category_(&system_category()) {} + error_code(int value, const error_category & category) + : value_(value), category_(&category) {} + + void assign(int value, const error_category & category) { + value_ = value; + category_ = &category; + } + void clear() { + value_ = 0; + category_ = &system_category(); + } + int value() const { return value_; } + const error_category & category() const { return *category_; } + error_condition default_error_condition() const { + return category().default_error_condition(value()); + } + std::string message() const { return category().message(value()); } + operator bool() const { return value() != 0; } + +private: + int value_; + const error_category * category_; +}; +inline bool operator==(const error_code & lhs, const error_code & rhs) { + return (lhs.value() == rhs.value()) && (lhs.category() == rhs.category()); +} +inline bool operator!=(const error_code & lhs, const error_code & rhs) { + return !operator==(lhs, rhs); +} +inline bool operator<(const error_code & lhs, const error_code & rhs) { + return (lhs.category() < rhs.category()) || + ((lhs.category() == rhs.category()) && (lhs.value() < rhs.value())); +} + +template <typename CharT, typename Traits> +std::basic_ostream<CharT, Traits> & +operator<<(std::basic_ostream<CharT, Traits> & os, const error_code & ec) { + os << ec.category().name() << ':' << ec.value(); + return os; +} + +inline bool operator==(const error_code & lhs, const error_condition & rhs) { + return lhs.category().equivalent(lhs.value(), rhs) || + rhs.category().equivalent(lhs, rhs.value()); +} +inline bool operator!=(const error_code & lhs, const error_condition & rhs) { + return !operator==(lhs, rhs); +} +inline bool operator==(const error_condition & lhs, const error_code & rhs) { + return operator==(rhs, lhs); +} +inline bool operator!=(const error_condition & lhs, const error_code & rhs) { + return !operator==(lhs, rhs); +} + +} // namespace MaximInterface + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Utilities/type_traits.hpp Mon Nov 06 14:39:18 2017 -0600 @@ -0,0 +1,77 @@ +/******************************************************************************* +* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ + +#ifndef MaximInterface_type_traits +#define MaximInterface_type_traits + +namespace MaximInterface { + +template <typename T, T v> struct integral_constant { + static const T value = v; + typedef T value_type; + typedef integral_constant<T, v> type; + operator T() { return v; } +}; + +typedef integral_constant<bool, true> true_type; +typedef integral_constant<bool, false> false_type; + +template <typename T, typename U> struct is_same : false_type {}; +template <typename T> struct is_same<T, T> : true_type {}; + +template <bool B, typename T, typename F> struct conditional { + typedef T type; +}; +template <typename T, typename F> struct conditional<false, T, F> { + typedef F type; +}; + +template <bool B, typename T = void> struct enable_if {}; +template <typename T> struct enable_if<true, T> { typedef T type; }; + +namespace detail { + +template <typename T> struct alignment_of_helper { + char a; + T b; +}; + +} // namespace detail + +template <typename T> +struct alignment_of + : integral_constant<size_t, + sizeof(detail::alignment_of_helper<T>) - sizeof(T)> {}; + +} // namespace MaximInterface + +#endif