Aleksandrs Gumenuks / MaximInterface_Extended

Dependents:   mbed_DS28EC20_GPIO

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DS2431.cpp Source File

DS2431.cpp

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