Device interface library for multiple platforms including Mbed.
Dependents: DeepCover Embedded Security in IoT MaximInterface MAXREFDES155#
DS28E17.cpp
00001 /******************************************************************************* 00002 * Copyright (C) Maxim Integrated Products, Inc., All Rights Reserved. 00003 * 00004 * Permission is hereby granted, free of charge, to any person obtaining a 00005 * copy of this software and associated documentation files (the "Software"), 00006 * to deal in the Software without restriction, including without limitation 00007 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00008 * and/or sell copies of the Software, and to permit persons to whom the 00009 * Software is furnished to do so, subject to the following conditions: 00010 * 00011 * The above copyright notice and this permission notice shall be included 00012 * in all copies or substantial portions of the Software. 00013 * 00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00015 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00016 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 00017 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES 00018 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 00019 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 00020 * OTHER DEALINGS IN THE SOFTWARE. 00021 * 00022 * Except as contained in this notice, the name of Maxim Integrated 00023 * Products, Inc. shall not be used except as stated in the Maxim Integrated 00024 * Products, Inc. Branding Policy. 00025 * 00026 * The mere transfer of this software does not imply any licenses 00027 * of trade secrets, proprietary technology, copyrights, patents, 00028 * trademarks, maskwork rights, or any other form of intellectual 00029 * property whatsoever. Maxim Integrated Products, Inc. retains all 00030 * ownership rights. 00031 *******************************************************************************/ 00032 00033 #include <stddef.h> 00034 #include <MaximInterfaceCore/Crc.hpp> 00035 #include <MaximInterfaceCore/Error.hpp> 00036 #include <MaximInterfaceCore/OneWireMaster.hpp> 00037 #include "DS28E17.hpp" 00038 00039 #define TRY MaximInterfaceCore_TRY 00040 #define TRY_VALUE MaximInterfaceCore_TRY_VALUE 00041 00042 namespace MaximInterfaceDevices { 00043 00044 using namespace Core; 00045 00046 Result<void> DS28E17::writeDataWithStop(uint_least8_t I2C_addr, 00047 span<const uint_least8_t> data) { 00048 return sendPacket(WriteDataWithStopCmd, &I2C_addr, data, 00049 span<uint_least8_t>()); 00050 } 00051 00052 Result<void> DS28E17::writeDataNoStop(uint_least8_t I2C_addr, 00053 span<const uint_least8_t> data) { 00054 return sendPacket(WriteDataNoStopCmd, &I2C_addr, data, span<uint_least8_t>()); 00055 } 00056 00057 Result<void> DS28E17::writeDataOnly(span<const uint_least8_t> data) { 00058 return sendPacket(WriteDataOnlyCmd, NULL, data, span<uint_least8_t>()); 00059 } 00060 00061 Result<void> DS28E17::writeDataOnlyWithStop(span<const uint_least8_t> data) { 00062 return sendPacket(WriteDataOnlyWithStopCmd, NULL, data, 00063 span<uint_least8_t>()); 00064 } 00065 00066 Result<void> 00067 DS28E17::writeReadDataWithStop(uint_least8_t I2C_addr, 00068 span<const uint_least8_t> write_data, 00069 span<uint_least8_t> read_data) { 00070 return sendPacket(WriteReadDataWithStopCmd, &I2C_addr, write_data, read_data); 00071 } 00072 00073 Result<void> DS28E17::readDataWithStop(uint_least8_t I2C_addr, 00074 span<uint_least8_t> data) { 00075 return sendPacket(ReadDataWithStopCmd, &I2C_addr, span<const uint_least8_t>(), 00076 data); 00077 } 00078 00079 Result<void> DS28E17::writeConfigReg(I2CSpeed speed) { 00080 Result<void> result = selectRom(*master); 00081 if (result) { 00082 // Send CMD and Data 00083 const uint_least8_t send_block[] = {WriteConfigurationCmd, 00084 static_cast<uint_least8_t>(speed)}; 00085 result = master->writeBlock(send_block); 00086 } 00087 return result; 00088 } 00089 00090 Result<DS28E17::I2CSpeed> DS28E17::readConfigReg() const { 00091 TRY(selectRom(*master)); 00092 // Send CMD and receive Data 00093 TRY(master->writeByte(ReadConfigurationCmd)); 00094 uint_least8_t config; 00095 TRY_VALUE(config, master->readByte()); 00096 switch (config) { 00097 case Speed100kHz: 00098 case Speed400kHz: 00099 case Speed900kHz: 00100 return static_cast<I2CSpeed>(config); 00101 } 00102 return OutOfRangeError; 00103 } 00104 00105 Result<void> DS28E17::enableSleepMode() { 00106 Result<void> result = selectRom(*master); 00107 if (result) { 00108 // Send CMD 00109 result = master->writeByte(EnableSleepModeCmd); 00110 } 00111 return result; 00112 } 00113 00114 Result<uint_least8_t> DS28E17::readDeviceRevision() const { 00115 Result<void> result = selectRom(*master); 00116 if (!result) { 00117 return result.error(); 00118 } 00119 result = master->writeByte(ReadDeviceRevisionCmd); 00120 if (!result) { 00121 return result.error(); 00122 } 00123 return master->readByte(); 00124 } 00125 00126 Result<void> DS28E17::sendPacket(Command command, 00127 const uint_least8_t * I2C_addr, 00128 span<const uint_least8_t> write_data, 00129 span<uint_least8_t> read_data) { 00130 const int pollLimit = 10000; 00131 const span<const uint_least8_t>::index_type maxDataLen = 255; 00132 00133 if ((!write_data.empty() && write_data.size() > maxDataLen) || 00134 (!read_data.empty() && read_data.size() > maxDataLen)) { 00135 return OutOfRangeError; 00136 } 00137 00138 Result<void> result = selectRom(*master); 00139 if (!result) { 00140 return result; 00141 } 00142 uint_fast16_t crc16 = calculateCrc16(command); 00143 result = master->writeByte(command); 00144 if (!result) { 00145 return result; 00146 } 00147 if (I2C_addr) { 00148 crc16 = calculateCrc16(crc16, *I2C_addr); 00149 result = master->writeByte(*I2C_addr); 00150 if (!result) { 00151 return result; 00152 } 00153 } 00154 if (!write_data.empty()) { 00155 crc16 = calculateCrc16(crc16, static_cast<uint_fast8_t>(write_data.size())); 00156 result = master->writeByte(static_cast<uint_least8_t>(write_data.size())); 00157 if (!result) { 00158 return result; 00159 } 00160 crc16 = calculateCrc16(crc16, write_data); 00161 result = master->writeBlock(write_data); 00162 if (!result) { 00163 return result; 00164 } 00165 } 00166 if (!read_data.empty()) { 00167 crc16 = calculateCrc16(crc16, static_cast<uint_fast8_t>(read_data.size())); 00168 result = master->writeByte(static_cast<uint_least8_t>(read_data.size())); 00169 if (!result) { 00170 return result; 00171 } 00172 } 00173 crc16 ^= 0xFFFF; 00174 const uint_least8_t crc16Bytes[] = {static_cast<uint_least8_t>(crc16), 00175 static_cast<uint_least8_t>(crc16 >> 8)}; 00176 result = master->writeBlock(crc16Bytes); 00177 if (!result) { 00178 return result; 00179 } 00180 // Poll for Zero 1-Wire bit and return if an error occurs 00181 int poll_count = 0; 00182 bool recvBit; 00183 do { 00184 if (poll_count++ < pollLimit) { 00185 return TimeoutError; 00186 } 00187 TRY_VALUE(recvBit, master->readBit()); 00188 } while (recvBit); 00189 uint_least8_t status; 00190 TRY_VALUE(status, master->readByte()); 00191 if ((status & 0x1) == 0x1) { 00192 return InvalidCrc16Error; 00193 } 00194 if ((status & 0x2) == 0x2) { 00195 return AddressNackError; 00196 } 00197 if ((status & 0x8) == 0x8) { 00198 return InvalidStartError; 00199 } 00200 if (!write_data.empty()) { 00201 TRY_VALUE(status, master->readByte()); 00202 if (status != 0) { 00203 return error_code(status, errorCategory()); 00204 } 00205 } 00206 if (!read_data.empty()) { 00207 result = master->readBlock(read_data); 00208 } 00209 return result; 00210 } 00211 00212 const error_category & DS28E17::errorCategory() { 00213 static class : public error_category { 00214 public: 00215 virtual const char * name() const { 00216 return "MaximInterfaceDevices.DS28E17"; 00217 } 00218 00219 virtual std::string message(int condition) const { 00220 switch (condition) { 00221 case TimeoutError: 00222 return "Timeout Error"; 00223 00224 case OutOfRangeError: 00225 return "Out of Range Error"; 00226 00227 case InvalidCrc16Error: 00228 return "Invalid CRC16 Error"; 00229 00230 case AddressNackError: 00231 return "Address Nack Error"; 00232 00233 case InvalidStartError: 00234 return "Invalid Start Error"; 00235 } 00236 if (condition >= 1 && condition <= 255) { 00237 return "Write Nack Error"; 00238 } 00239 return defaultErrorMessage(condition); 00240 } 00241 } instance; 00242 return instance; 00243 } 00244 00245 } // namespace MaximInterfaceDevices
Generated on Tue Jul 12 2022 11:13:11 by 1.7.2