Device interface library for multiple platforms including Mbed.

Dependents:   DeepCover Embedded Security in IoT MaximInterface MAXREFDES155#

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DS2431.cpp Source File

DS2431.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 <algorithm>
00034 #include <MaximInterfaceCore/Error.hpp>
00035 #include <MaximInterfaceCore/OneWireMaster.hpp>
00036 #include "DS2431.hpp"
00037 
00038 namespace MaximInterfaceDevices {
00039 
00040 using namespace Core;
00041 
00042 Result<void> writeMemory(DS2431 & device, uint_least8_t targetAddress,
00043                          DS2431::Scratchpad::const_span data) {
00044   Result<void> result = device.writeScratchpad(targetAddress, data);
00045   if (!result) {
00046     return result;
00047   }
00048   uint_least8_t esByte;
00049   if (const Result<std::pair<uint_least8_t, DS2431::Scratchpad::array> >
00050           scratchpad = device.readScratchpad()) {
00051     esByte = scratchpad.value().first;
00052   } else {
00053     return scratchpad.error();
00054   }
00055   result = device.copyScratchpad(targetAddress, esByte);
00056   return result;
00057 }
00058 
00059 Result<void> DS2431::readMemory(uint_least8_t beginAddress,
00060                                 span<uint_least8_t> data) const {
00061   Result<void> result = selectRom(*master);
00062   if (!result) {
00063     return result;
00064   }
00065   const uint_least8_t sendBlock[] = {0xF0, beginAddress, 0x00};
00066   result = master->writeBlock(sendBlock);
00067   if (!result) {
00068     return result;
00069   }
00070   result = master->readBlock(data);
00071   return result;
00072 }
00073 
00074 Result<void> DS2431::writeScratchpad(uint_least8_t targetAddress,
00075                                      Scratchpad::const_span data) {
00076   Result<void> result = selectRom(*master);
00077   if (!result) {
00078     return result;
00079   }
00080   uint_least8_t block[3 + Scratchpad::size] = {0x0F, targetAddress, 0x00};
00081   std::copy(data.begin(), data.end(), block + 3);
00082   result = master->writeBlock(block);
00083   if (!result) {
00084     return result;
00085   }
00086   const uint_fast16_t calculatedCrc = calculateCrc16(block) ^ 0xFFFF;
00087   result = master->readBlock(make_span(block, 2));
00088   if (!result) {
00089     return result;
00090   }
00091   if (calculatedCrc !=
00092       ((static_cast<uint_fast16_t>(block[1]) << 8) | block[0])) {
00093     result = CrcError;
00094   }
00095   return result;
00096 }
00097 
00098 Result<std::pair<uint_least8_t, DS2431::Scratchpad::array> >
00099 DS2431::readScratchpad() const {
00100   typedef array<uint_least8_t, 6 + Scratchpad::size> Block;
00101 
00102   Result<void> result = selectRom(*master);
00103   if (!result) {
00104     return result.error();
00105   }
00106   Block block = {0xAA};
00107   result = master->writeByte(block.front());
00108   if (!result) {
00109     return result.error();
00110   }
00111   result = master->readBlock(make_span(block).subspan(1));
00112   if (!result) {
00113     return result.error();
00114   }
00115   Block::const_iterator blockIt = block.end();
00116   uint_fast16_t receivedCrc = static_cast<uint_fast16_t>(*(--blockIt)) << 8;
00117   receivedCrc |= *(--blockIt);
00118   const uint_fast16_t expectedCrc =
00119       calculateCrc16(make_span(block.data(), block.size() - 2)) ^ 0xFFFF;
00120   if (expectedCrc != receivedCrc) {
00121     return CrcError;
00122   }
00123   std::pair<uint_least8_t, Scratchpad::array> data;
00124   Block::const_iterator blockItEnd = blockIt;
00125   blockIt -= data.second.size();
00126   std::copy(blockIt, blockItEnd, data.second.begin());
00127   data.first = *(--blockIt);
00128   return data;
00129 }
00130 
00131 Result<void> DS2431::copyScratchpad(uint_least8_t targetAddress,
00132                                     uint_least8_t esByte) {
00133   Result<void> result = selectRom(*master);
00134   if (!result) {
00135     return result;
00136   }
00137   uint_least8_t block[] = {0x55, targetAddress, 0x00};
00138   result = master->writeBlock(block);
00139   if (!result) {
00140     return result;
00141   }
00142   result = master->writeByteSetLevel(esByte, OneWireMaster::StrongLevel);
00143   if (!result) {
00144     return result;
00145   }
00146   sleep->invoke(10);
00147   result = master->setLevel(OneWireMaster::NormalLevel);
00148   if (!result) {
00149     return result;
00150   }
00151   MaximInterfaceCore_TRY_VALUE(block[0], master->readByte());
00152   if (block[0] != 0xAA) {
00153     result = OperationFailure;
00154   }
00155   return result;
00156 }
00157 
00158 const error_category & DS2431::errorCategory() {
00159   static class : public error_category {
00160   public:
00161     virtual const char * name() const { return "MaximInterfaceDevices.DS2431"; }
00162 
00163     virtual std::string message(int condition) const {
00164       switch (condition) {
00165       case CrcError:
00166         return "CRC Error";
00167 
00168       case OperationFailure:
00169         return "Operation Failure";
00170       }
00171       return defaultErrorMessage(condition);
00172     }
00173   } instance;
00174   return instance;
00175 }
00176 
00177 } // namespace MaximInterfaceDevices