Aleksandrs Gumenuks / MaximInterface_Extended

Dependents:   mbed_DS28EC20_GPIO

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DS2465.hpp Source File

DS2465.hpp

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 #ifndef MaximInterface_DS2465
00034 #define MaximInterface_DS2465
00035 
00036 #include <MaximInterface/Links/I2CMaster.hpp>
00037 #include <MaximInterface/Links/OneWireMaster.hpp>
00038 #include <MaximInterface/Links/Sleep.hpp>
00039 #include <MaximInterface/Utilities/array_span.hpp>
00040 #include <MaximInterface/Utilities/Export.h>
00041 #include <MaximInterface/Utilities/Sha256.hpp>
00042 
00043 namespace MaximInterface {
00044 
00045 /// Interface to the DS2465 1-Wire master and SHA-256 coprocessor.
00046 class DS2465 : public OneWireMaster {
00047 public:
00048   enum ErrorValue { HardwareError = 1, ArgumentOutOfRangeError };
00049 
00050   /// @brief 1-Wire port adjustment parameters.
00051   /// @note See datasheet page 13.
00052   enum PortParameter {
00053     tRSTL_STD,
00054     tRSTL_OD,
00055     tMSP_STD,
00056     tMSP_OD,
00057     tW0L_STD,
00058     tW0L_OD,
00059     tREC0,
00060     RWPU,
00061     tW1L_OD
00062   };
00063 
00064   /// Page region to use for swapping.
00065   enum PageRegion { FullPage = 0x03, FirstHalf = 0x01, SecondHalf = 0x02 };
00066 
00067   /// Holds the contents of a device memory segment.
00068   typedef array_span<uint_least8_t, 4> Segment;
00069 
00070   /// Holds the contents of a device memory page.
00071   typedef array_span<uint_least8_t, 32> Page;
00072 
00073   static const int memoryPages = 2;
00074   static const int segmentsPerPage = Page::size / Segment::size;
00075 
00076   /// Represents a DS2465 configuration.
00077   class Config {
00078   public:
00079     /// Default construct with power-on config.
00080     explicit Config(uint_least8_t readByte = optionAPU)
00081         : readByte_(readByte & 0xF) {}
00082 
00083     /// @name 1WS
00084     /// @brief 1-Wire Speed
00085     /// @{
00086     
00087     /// Get 1WS bit.
00088     bool get1WS() const { return (readByte_ & option1WS) == option1WS; }
00089     
00090     /// Set 1WS bit.
00091     Config & set1WS(bool new1WS) {
00092       if (new1WS) {
00093         readByte_ |= option1WS;
00094       } else {
00095         readByte_ &= ~option1WS;
00096       }
00097       return *this;
00098     }
00099     
00100     /// @}
00101 
00102     /// @name SPU
00103     /// @brief Strong Pullup
00104     /// @{
00105     
00106     /// Get SPU bit.
00107     bool getSPU() const { return (readByte_ & optionSPU) == optionSPU; }
00108     
00109     /// Set SPU bit.
00110     Config & setSPU(bool newSPU) {
00111       if (newSPU) {
00112         readByte_ |= optionSPU;
00113       } else {
00114         readByte_ &= ~optionSPU;
00115       }
00116       return *this;
00117     }
00118     
00119     /// @}
00120 
00121     /// @name PDN
00122     /// @brief 1-Wire Power Down
00123     /// @{
00124     
00125     /// Get PDN bit.
00126     bool getPDN() const { return (readByte_ & optionPDN) == optionPDN; }
00127     
00128     /// Set PDN bit.
00129     Config & setPDN(bool newPDN) {
00130       if (newPDN) {
00131         readByte_ |= optionPDN;
00132       } else {
00133         readByte_ &= ~optionPDN;
00134       }
00135       return *this;
00136     }
00137     
00138     /// @}
00139 
00140     /// @name APU
00141     /// @brief Active Pullup
00142     /// @{
00143     
00144     /// Get APU bit.
00145     bool getAPU() const { return (readByte_ & optionAPU) == optionAPU; }
00146     
00147     /// Set APU bit.
00148     Config & setAPU(bool newAPU) {
00149       if (newAPU) {
00150         readByte_ |= optionAPU;
00151       } else {
00152         readByte_ &= ~optionAPU;
00153       }
00154       return *this;
00155     }
00156     
00157     /// @}
00158 
00159     /// Byte representation that is read from the DS2465.
00160     uint_least8_t readByte() const { return readByte_; }
00161 
00162   private:
00163     static const unsigned int option1WS = 0x8;
00164     static const unsigned int optionSPU = 0x4;
00165     static const unsigned int optionPDN = 0x2;
00166     static const unsigned int optionAPU = 0x1;
00167 
00168     uint_least8_t readByte_;
00169   };
00170 
00171   // Const member functions should not change the settings of the DS2465 or
00172   // affect the state of the 1-Wire bus. Read pointer, scratchpad, MAC output
00173   // register, and command register on the DS2465 are considered mutable.
00174 
00175   DS2465(Sleep & sleep, I2CMaster & master, uint_least8_t address = 0x30)
00176       : sleep(&sleep), master(&master), address_(address & 0xFE) {}
00177 
00178   void setSleep(Sleep & sleep) { this->sleep = &sleep; }
00179   
00180   void setMaster(I2CMaster & master) { this->master = &master; }
00181   
00182   uint_least8_t address() const { return address_; }
00183   
00184   void setAddress(uint_least8_t address) { address_ = address & 0xFE; }
00185 
00186   /// Initialize hardware for use.
00187   MaximInterface_EXPORT error_code initialize(Config config = Config());
00188 
00189   /// @brief Write a new configuration to the DS2465.
00190   /// @param[in] config New configuration to write.
00191   MaximInterface_EXPORT error_code writeConfig(Config config);
00192 
00193   /// @brief Write a new port configuration parameter to the DS2465.
00194   /// @param[in] param Parameter to adjust.
00195   /// @param[in] val
00196   /// New parameter value to set. Consult datasheet for value mappings.
00197   MaximInterface_EXPORT error_code writePortParameter(PortParameter param,
00198                                                       int val);
00199 
00200   // 1-Wire Master Commands
00201 
00202   MaximInterface_EXPORT virtual error_code reset();
00203   
00204   MaximInterface_EXPORT virtual error_code touchBitSetLevel(bool & sendRecvBit,
00205                                                             Level afterLevel);
00206   
00207   MaximInterface_EXPORT virtual error_code
00208   readByteSetLevel(uint_least8_t & recvByte, Level afterLevel);
00209   
00210   MaximInterface_EXPORT virtual error_code
00211   writeByteSetLevel(uint_least8_t sendByte, Level afterLevel);
00212   
00213   MaximInterface_EXPORT virtual error_code
00214   readBlock(span<uint_least8_t> recvBuf);
00215   
00216   MaximInterface_EXPORT virtual error_code
00217   writeBlock(span<const uint_least8_t> sendBuf);
00218   
00219   MaximInterface_EXPORT virtual error_code setSpeed(Speed newSpeed);
00220   
00221   /// @copydoc OneWireMaster::setLevel
00222   /// @note
00223   /// The DS2465 only supports enabling strong pullup following a 1-Wire read or
00224   /// write operation.
00225   MaximInterface_EXPORT virtual error_code setLevel (Level newLevel);
00226   
00227   MaximInterface_EXPORT virtual error_code triplet(TripletData & data);
00228 
00229   // DS2465 Coprocessor Commands
00230 
00231   /// @brief Read data from an EEPROM memory page.
00232   /// @param pageNum Page number to read from.
00233   /// @param[out] data Data that was read.
00234   MaximInterface_EXPORT error_code readPage(int pageNum, Page::span data) const;
00235 
00236   /// @brief Write data to an EEPROM memory page.
00237   /// @param pageNum Page number to copy to.
00238   /// @param data Data to write.
00239   MaximInterface_EXPORT error_code writePage(int pageNum,
00240                                              Page::const_span data);
00241 
00242   /// @brief Write data to an EEPROM memory segment.
00243   /// @param pageNum Page number to copy to.
00244   /// @param segmentNum Segment number to copy to.
00245   /// @param data Data to write.
00246   MaximInterface_EXPORT error_code writeSegment(int pageNum, int segmentNum,
00247                                                 Segment::const_span data);
00248 
00249   /// Write data to the secret EEPROM memory page.
00250   MaximInterface_EXPORT error_code
00251   writeMasterSecret(Sha256::Hash::const_span masterSecret);
00252 
00253   /// @brief Compute Next Master Secret.
00254   /// @param data Combined data fields for computation.
00255   MaximInterface_EXPORT error_code
00256   computeNextMasterSecret(Sha256::AuthenticationData::const_span data);
00257 
00258   /// @brief Compute Next Master Secret with page swapping.
00259   /// @param data Combined data fields for computation.
00260   /// @param pageNum Page number to swap in.
00261   /// @param region Region of the page to swap in.
00262   MaximInterface_EXPORT error_code
00263   computeNextMasterSecretWithSwap(Sha256::AuthenticationData::const_span data,
00264                                   int pageNum, PageRegion region);
00265 
00266   /// @brief Compute Write MAC.
00267   /// @param data Combined data fields for computation.
00268   /// @param[out] mac Computed Write MAC.
00269   MaximInterface_EXPORT error_code computeWriteMac(
00270       Sha256::WriteMacData::const_span data, Sha256::Hash::span mac) const;
00271 
00272   /// @brief Compute Write MAC.
00273   /// @param data Combined data fields for computation.
00274   MaximInterface_EXPORT error_code
00275   computeAndTransmitWriteMac(Sha256::WriteMacData::const_span data) const;
00276 
00277   /// @brief Compute Write MAC with page swapping.
00278   /// @param data Combined data fields for computation.
00279   /// @param pageNum Page number to swap in.
00280   /// @param segmentNum Segment number to swap in.
00281   /// @param[out] mac Computed Write MAC.
00282   MaximInterface_EXPORT error_code
00283   computeWriteMacWithSwap(Sha256::WriteMacData::const_span data, int pageNum,
00284                           int segmentNum, Sha256::Hash::span mac) const;
00285 
00286   /// @brief Compute Write MAC with page swapping.
00287   /// @param data Combined data fields for computation.
00288   /// @param pageNum Page number to swap in.
00289   /// @param segmentNum Segment number to swap in.
00290   MaximInterface_EXPORT error_code computeAndTransmitWriteMacWithSwap(
00291       Sha256::WriteMacData::const_span data, int pageNum, int segmentNum) const;
00292 
00293   /// @brief Compute Slave Secret (S-Secret).
00294   /// @param data Combined data fields for computation.
00295   MaximInterface_EXPORT error_code
00296   computeSlaveSecret(Sha256::AuthenticationData::const_span data);
00297 
00298   /// @brief Compute Slave Secret (S-Secret) with page swapping.
00299   /// @param data Combined data fields for computation.
00300   /// @param pageNum Page number to swap in.
00301   /// @param region Region of the page to swap in.
00302   MaximInterface_EXPORT error_code
00303   computeSlaveSecretWithSwap(Sha256::AuthenticationData::const_span data,
00304                              int pageNum, PageRegion region);
00305 
00306   /// @brief Compute Authentication MAC.
00307   /// @param data Combined data fields for computation.
00308   /// @param[out] mac Computed Auth MAC.
00309   MaximInterface_EXPORT error_code
00310   computeAuthMac(Sha256::AuthenticationData::const_span data,
00311                  Sha256::Hash::span mac) const;
00312 
00313   /// @brief Compute Authentication MAC.
00314   /// @param data Combined data fields for computation.
00315   MaximInterface_EXPORT error_code
00316   computeAndTransmitAuthMac(Sha256::AuthenticationData::const_span data) const;
00317 
00318   /// @brief Compute Authentication MAC with page swapping.
00319   /// @param data Combined data fields for computation.
00320   /// @param pageNum Page number to swap in.
00321   /// @param region Region of the page to swap in.
00322   /// @param[out] mac Computed Auth MAC.
00323   MaximInterface_EXPORT error_code computeAuthMacWithSwap(
00324       Sha256::AuthenticationData::const_span data, int pageNum,
00325       PageRegion region, Sha256::Hash::span mac) const;
00326 
00327   /// @brief Compute Authentication MAC with page swapping.
00328   /// @param data Combined data fields for computation.
00329   /// @param pageNum Page number to swap in.
00330   /// @param region Region of the page to swap in.
00331   MaximInterface_EXPORT error_code
00332   computeAndTransmitAuthMacWithSwap(Sha256::AuthenticationData::const_span data,
00333                                     int pageNum, PageRegion region) const;
00334 
00335   MaximInterface_EXPORT static const error_category & errorCategory();
00336 
00337 private:
00338   const Sleep * sleep;
00339   I2CMaster * master;
00340   uint_least8_t address_;
00341   Config curConfig;
00342 
00343   /// @brief Performs a soft reset on the DS2465.
00344   /// @note This is not a 1-Wire Reset.
00345   error_code resetDevice();
00346 
00347   /// @brief
00348   /// Polls the DS2465 status waiting for the 1-Wire Busy bit (1WB) to be
00349   /// cleared.
00350   /// @param[out] pStatus Optionally retrive the status byte when 1WB cleared.
00351   /// @returns Success or TimeoutError if poll limit reached.
00352   error_code pollBusy(uint_least8_t * pStatus = NULL) const;
00353 
00354   /// @brief Ensure that the desired 1-Wire level is set in the configuration.
00355   /// @param level Desired 1-Wire level.
00356   error_code configureLevel(Level level);
00357 
00358   /// @note Const since only for internal use.
00359   error_code writeMemory(uint_least8_t addr,
00360                          span<const uint_least8_t> buf) const;
00361 
00362   /// @brief Read memory from the DS2465.
00363   /// @param addr Address to begin reading from.
00364   /// @param[out] buf Buffer to hold read data.
00365   error_code readMemory(uint_least8_t addr, span<uint_least8_t> buf) const;
00366 
00367   /// @brief Read memory from the DS2465 at the current pointer.
00368   /// @param[out] buf Buffer to hold read data.
00369   error_code readMemory(span<uint_least8_t> buf) const;
00370 
00371   /// Write the last computed MAC to the 1-Wire bus.
00372   error_code writeMacBlock() const;
00373 
00374   error_code computeWriteMac(Sha256::WriteMacData::const_span data) const;
00375 
00376   error_code computeWriteMacWithSwap(Sha256::WriteMacData::const_span data,
00377                                      int pageNum, int segmentNum) const;
00378 
00379   error_code computeAuthMac(Sha256::AuthenticationData::const_span data) const;
00380 
00381   error_code computeAuthMacWithSwap(Sha256::AuthenticationData::const_span data,
00382                                     int pageNum, PageRegion region) const;
00383 
00384   // Legacy implementations
00385   error_code copyScratchpad(bool destSecret, int pageNum, bool notFull,
00386                             int segmentNum);
00387 
00388   error_code computeNextMasterSecret(bool swap, int pageNum, PageRegion region);
00389 
00390   error_code computeWriteMac(bool regwrite, bool swap, int pageNum,
00391                              int segmentNum) const;
00392 
00393   error_code computeSlaveSecret(bool swap, int pageNum, PageRegion region);
00394 
00395   error_code computeAuthMac(bool swap, int pageNum, PageRegion region) const;
00396 };
00397 
00398 inline error_code make_error_code(DS2465::ErrorValue e) {
00399   return error_code(e, DS2465::errorCategory());
00400 }
00401 
00402 } // namespace MaximInterface
00403 
00404 #endif