1-Wire® library for mbed. Complete 1-Wire library that supports our silicon masters along with a bit-bang master on the MAX32600MBED platform with one common interface for mbed. Slave support has also been included and more slaves will be added as time permits.

Dependents:   MAXREFDES131_Qt_Demo MAX32630FTHR_iButton_uSD_Logger MAX32630FTHR_DS18B20_uSD_Logger MAXREFDES130_131_Demo ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DS28E17.cpp Source File

DS28E17.cpp

00001 /******************************************************************//**
00002 * Copyright (C) 2016 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 "Masters/OneWireMaster.h"
00034 #include "Slaves/Bridges/DS28E17/DS28E17.h"
00035 #include "Utilities/crc.h"
00036 
00037 using OneWire::DS28E17;
00038 using OneWire::OneWireMaster;
00039 using namespace OneWire::crc;
00040 
00041 enum Command
00042 {
00043     WriteDataWithStopCmd = 0x4B,
00044     WriteDataNoStopCmd = 0x5A,
00045     WriteDataOnlyCmd = 0x69,
00046     WriteDataOnlyWithStopCmd = 0x78,
00047     ReadDataWithStopCmd = 0x87,
00048     WriteReadDataWithStopCmd = 0x2D,
00049     WriteConfigurationCmd = 0xD2,
00050     ReadConfigurationCmd = 0xE1,
00051     EnableSleepModeCmd = 0x1E,
00052     ReadDeviceRevisionCmd = 0xC3
00053 };
00054 
00055 
00056 //*********************************************************************
00057 DS28E17::DS28E17(RandomAccessRomIterator &selector)
00058     : OneWireSlave(selector)
00059 {
00060 
00061 }
00062 
00063 
00064 //*********************************************************************
00065 DS28E17::CmdResult DS28E17::writeDataWithStop(uint8_t I2C_addr, uint8_t length,
00066                                                   uint8_t *data, uint8_t &status,
00067                                                   uint8_t &wr_status)
00068 {
00069     DS28E17::CmdResult bridge_result = DS28E17::OperationFailure;
00070 
00071     size_t send_cnt = 0;
00072     uint8_t send_block[0xff];
00073 
00074     OneWireMaster::CmdResult ow_result = selectDevice();
00075 
00076     if (ow_result == OneWireMaster::Success)
00077     {
00078         //seed the crc
00079         uint16_t crc16 = 0;
00080 
00081         // Form the 1-Wire Packet 
00082 
00083         // I2C Write Data with Stop command
00084         send_block[send_cnt] = WriteDataWithStopCmd;
00085         crc16 = calculateCrc16(crc16, send_block[send_cnt++]);
00086 
00087         // I2C Address
00088         send_block[send_cnt] = I2C_addr;
00089         crc16 = calculateCrc16(crc16, send_block[send_cnt++]);
00090 
00091         // Length field
00092         send_block[send_cnt] = length;
00093         crc16 = calculateCrc16(crc16, send_block[send_cnt++]);
00094 
00095         // Form the write data  
00096         for (size_t idx = 0; idx < length; idx++)
00097         {
00098             send_block[send_cnt] = data[idx];
00099             crc16 = calculateCrc16(crc16, send_block[send_cnt++]);
00100         }
00101 
00102         // Form the CRC16
00103         crc16 ^= 0xFFFF;
00104         send_block[send_cnt++] = ((uint8_t)(crc16 & 0xFF));
00105         send_block[send_cnt++] = ((uint8_t)((crc16 >> 8) & 0xFF));
00106 
00107         // Send Packet
00108         bridge_result = sendPacket(send_block, send_cnt, status, wr_status);
00109     }
00110 
00111     return bridge_result;
00112 }
00113 
00114 
00115 //*********************************************************************
00116 DS28E17::CmdResult DS28E17::writeDataNoStop(uint8_t I2C_addr, uint8_t length,
00117                                                 uint8_t *data, uint8_t &status,
00118                                                 uint8_t &wr_status)
00119 {
00120     DS28E17::CmdResult bridge_result = DS28E17::OperationFailure;
00121 
00122     size_t send_cnt = 0;
00123     uint8_t send_block[0xff];
00124 
00125     OneWireMaster::CmdResult ow_result = selectDevice();
00126 
00127     if (ow_result == OneWireMaster::Success)
00128     {
00129         // seed the crc
00130         uint16_t crc16 = 0;
00131 
00132         // I2C Write Data with Stop command
00133         send_block[send_cnt] = WriteDataNoStopCmd;
00134         crc16 = calculateCrc16(crc16, send_block[send_cnt++]);
00135 
00136         // I2C Address
00137         send_block[send_cnt] = I2C_addr;
00138         crc16 = calculateCrc16(crc16, send_block[send_cnt++]);
00139 
00140         // Length field
00141         send_block[send_cnt] = length;
00142         crc16 = calculateCrc16(crc16, send_block[send_cnt++]);
00143 
00144         // Form the write data
00145         for (size_t idx = 0; idx < length; idx++)
00146         {
00147             send_block[send_cnt] = data[idx];
00148             crc16 = calculateCrc16(crc16, send_block[send_cnt++]);
00149         }
00150 
00151         // Form the CRC16
00152         crc16 ^= 0xFFFF;
00153         send_block[send_cnt++] = ((uint8_t)(crc16 & 0xFF));
00154         send_block[send_cnt++] = ((uint8_t)((crc16 >> 8) & 0xFF));
00155 
00156         // Send Packet
00157         bridge_result = sendPacket(send_block, send_cnt, status, wr_status);
00158     }
00159 
00160     return bridge_result;
00161 }
00162 
00163 
00164 //*********************************************************************
00165 DS28E17::CmdResult DS28E17::writeDataOnly(uint8_t length, uint8_t *data,
00166                                               uint8_t &status, uint8_t &wr_status)
00167 {
00168     DS28E17::CmdResult bridge_result = DS28E17::OperationFailure;
00169 
00170     size_t send_cnt = 0;
00171     uint8_t send_block[0xff];
00172 
00173     OneWireMaster::CmdResult ow_result = selectDevice();
00174 
00175     if (ow_result == OneWireMaster::Success)
00176     {
00177         // seed the crc
00178         uint16_t crc16 = 0;
00179 
00180         // Form the 1-Wire Packet
00181 
00182         // I2C Write Data with Stop command
00183         send_block[send_cnt] = WriteDataOnlyCmd;
00184         crc16 = calculateCrc16(crc16, send_block[send_cnt++]);
00185 
00186         // Length field
00187         send_block[send_cnt] = length;
00188         crc16 = calculateCrc16(crc16, send_block[send_cnt++]);
00189 
00190         // Form the write data
00191         for (size_t idx = 0; idx < length; idx++)
00192         {
00193             send_block[send_cnt] = data[idx];
00194             crc16 = calculateCrc16(crc16, send_block[send_cnt++]);
00195         }
00196 
00197         // Form the CRC16
00198         crc16 ^= 0xFFFF;
00199         send_block[send_cnt++] = (crc16 & 0xFF);
00200         send_block[send_cnt++] = ((crc16 >> 8) & 0xFF);
00201 
00202         // Send Packet
00203         bridge_result = sendPacket(send_block, send_cnt, status, wr_status);
00204     }
00205 
00206     return bridge_result;
00207 }
00208 
00209 
00210 //*********************************************************************
00211 DS28E17::CmdResult DS28E17::writeDataOnlyWithStop(uint8_t length, uint8_t *data,
00212                                                       uint8_t &status, uint8_t &wr_status)
00213 {
00214     DS28E17::CmdResult bridge_result = DS28E17::OperationFailure;
00215 
00216     size_t send_cnt = 0;
00217     uint8_t send_block[0xff];
00218 
00219     OneWireMaster::CmdResult ow_result = selectDevice();
00220 
00221     if (ow_result == OneWireMaster::Success)
00222     {
00223         //seed the crc
00224         uint16_t crc16 = 0;
00225 
00226         // Form the 1-Wire Packet
00227 
00228         // I2C Write Data with Stop command
00229         send_block[send_cnt] = WriteDataOnlyWithStopCmd;
00230         crc16 = calculateCrc16(crc16, send_block[send_cnt++]);
00231 
00232         // Length field
00233         send_block[send_cnt] = length;
00234         crc16 = calculateCrc16(crc16, send_block[send_cnt++]);
00235 
00236         // Form the write data
00237         for (size_t idx = 0; idx < length; idx++)
00238         {
00239             send_block[send_cnt] = data[idx];
00240             crc16 = calculateCrc16(crc16, send_block[send_cnt++]);
00241         }
00242 
00243         // Form the CRC16
00244         crc16 ^= 0xFFFF;
00245         send_block[send_cnt++] = (crc16 & 0xFF);
00246         send_block[send_cnt++] = ((crc16 >> 8) & 0xFF);
00247 
00248         // Send Packet
00249         bridge_result = sendPacket(send_block, send_cnt, status, wr_status);
00250     }
00251 
00252     return bridge_result;
00253 }
00254 
00255 
00256 //*********************************************************************
00257 DS28E17::CmdResult DS28E17::writeReadDataWithStop(uint8_t I2C_addr, uint8_t length,
00258                                                       uint8_t *data, uint8_t nu_bytes_read,
00259                                                       uint8_t &status, uint8_t &wr_status,
00260                                                       uint8_t *read_data)
00261 {
00262     DS28E17::CmdResult bridge_result = DS28E17::OperationFailure;
00263 
00264     size_t send_cnt = 0;
00265     size_t idx = 0;
00266     uint8_t send_block[0xff];
00267 
00268     OneWireMaster::CmdResult ow_result = selectDevice();
00269 
00270     if (ow_result == OneWireMaster::Success)
00271     {
00272         //seed the crc
00273         uint16_t crc16 = 0;
00274 
00275         // Form the 1-Wire Packet
00276 
00277         // I2C Write Data with Stop command
00278         send_block[send_cnt] = WriteReadDataWithStopCmd;
00279         crc16 = calculateCrc16(crc16, send_block[send_cnt++]);
00280 
00281         // I2C Address
00282         send_block[send_cnt] = I2C_addr;
00283         crc16 = calculateCrc16(crc16, send_block[send_cnt++]);
00284 
00285         // Length field
00286         send_block[send_cnt] = length;
00287         crc16 = calculateCrc16(crc16, send_block[send_cnt++]);
00288 
00289         // Form the write data
00290         for (idx = 0; idx < length; idx++)
00291         {
00292             send_block[send_cnt] = data[idx];
00293             crc16 = calculateCrc16(crc16, send_block[send_cnt++]);
00294         }
00295 
00296         // # of bytes to Read field
00297         send_block[send_cnt] = nu_bytes_read;
00298         crc16 = calculateCrc16(crc16, send_block[send_cnt++]);
00299 
00300         // Form the CRC16
00301         crc16 ^= 0xFFFF;
00302         send_block[send_cnt++] = (crc16 & 0xFF);
00303         send_block[send_cnt++] = ((crc16 >> 8) & 0xFF);
00304 
00305         // Send Packet
00306         bridge_result = sendPacket(send_block, send_cnt, status, wr_status);
00307         if (bridge_result == DS28E17::Success)
00308         {
00309             ow_result = master().OWReadBlock(read_data, nu_bytes_read);
00310             if (ow_result == OneWireMaster::Success)
00311             {
00312                 bridge_result = DS28E17::Success;
00313             }
00314             else
00315             {
00316                 bridge_result = DS28E17::CommsReadBlockError;
00317             }
00318         }
00319     }
00320 
00321     return bridge_result;
00322 }
00323 
00324 
00325 //*********************************************************************
00326 DS28E17::CmdResult DS28E17::readDataWithStop(uint8_t I2C_addr, uint8_t nu_bytes_read,
00327                                                  uint8_t &status, uint8_t *read_data)
00328 {
00329     DS28E17::CmdResult  bridge_result = DS28E17::OperationFailure;
00330 
00331     size_t send_cnt = 0;
00332     uint8_t send_block[0xff];
00333 
00334     OneWireMaster::CmdResult ow_result = selectDevice();
00335 
00336     if (ow_result == OneWireMaster::Success)
00337     {
00338         //seed the crc for transmit bytes
00339         uint16_t crc16 = 0;
00340 
00341         // Form the 1-Wire Packet to send
00342 
00343         // I2C Write Data with Stop command
00344         send_block[send_cnt] = ReadDataWithStopCmd;
00345         crc16 = calculateCrc16(crc16, send_block[send_cnt++]);
00346 
00347         // I2C Address
00348         send_block[send_cnt] = I2C_addr;
00349         crc16 = calculateCrc16(crc16, send_block[send_cnt++]);
00350 
00351         // # of bytes to Read field
00352         send_block[send_cnt] = nu_bytes_read;
00353         crc16 = calculateCrc16(crc16, send_block[send_cnt++]);
00354 
00355         // Form the CRC16
00356         crc16 ^= 0xFFFF;
00357         send_block[send_cnt++] = (crc16 & 0xFF);
00358         send_block[send_cnt++] = ((crc16 >> 8) & 0xFF);
00359 
00360         // Send Packet
00361         bridge_result = sendPacket(send_block, send_cnt, status);
00362         if (bridge_result == DS28E17::Success)
00363         {
00364             ow_result = master().OWReadBlock(read_data, nu_bytes_read);
00365             if (ow_result == OneWireMaster::Success)
00366             {
00367                 bridge_result = DS28E17::Success;
00368             }
00369             else
00370             {
00371                 bridge_result = DS28E17::CommsReadBlockError;
00372             }
00373         }
00374     }
00375 
00376     return bridge_result;
00377 }
00378 
00379 
00380 //*********************************************************************
00381 DS28E17::CmdResult DS28E17::writeConfigReg(uint8_t data)
00382 {
00383     DS28E17::CmdResult bridge_result = DS28E17::OperationFailure;
00384 
00385     OneWireMaster::CmdResult ow_result = selectDevice();
00386 
00387     if (ow_result == OneWireMaster::Success)
00388     {
00389         // Send CMD and Data
00390         uint8_t send_block[] = { WriteConfigurationCmd, data };
00391 
00392         ow_result = master().OWWriteBlock(send_block, 2);
00393         if (ow_result == OneWireMaster::Success)
00394         {
00395             bridge_result = DS28E17::Success;
00396         }
00397         else
00398         {
00399             bridge_result = DS28E17::CommsWriteBlockError;
00400         }
00401     }
00402 
00403     return bridge_result;
00404 }
00405 
00406 
00407 //*********************************************************************
00408 DS28E17::CmdResult DS28E17::readConfigReg(uint8_t & config)
00409 {
00410     DS28E17::CmdResult bridge_result = DS28E17::OperationFailure;
00411 
00412     OneWireMaster::CmdResult ow_result = selectDevice();
00413 
00414     if (ow_result == OneWireMaster::Success)
00415     {
00416         // Send CMD and receive Data
00417         ow_result = master().OWWriteByte(ReadConfigurationCmd);
00418         if (ow_result == OneWireMaster::Success)
00419         {
00420             ow_result = master().OWReadByte(config);
00421             if (ow_result == OneWireMaster::Success)
00422             {
00423                 bridge_result = DS28E17::Success;
00424             }
00425             else
00426             {
00427                 bridge_result = DS28E17::CommsReadByteError;
00428             }
00429         }
00430         else
00431         {
00432             bridge_result = DS28E17::CommsWriteByteError;
00433         }
00434     }
00435 
00436     return bridge_result;
00437 }
00438 
00439 
00440 //*********************************************************************
00441 DS28E17::CmdResult DS28E17::enableSleepMode()
00442 {
00443     DS28E17::CmdResult bridge_result = DS28E17::OperationFailure;
00444 
00445     OneWireMaster::CmdResult ow_result = selectDevice();
00446 
00447     if (ow_result == OneWireMaster::Success)
00448     {
00449         // Send CMD
00450         ow_result = master().OWWriteByte(EnableSleepModeCmd);
00451         if (ow_result == OneWireMaster::Success)
00452         {
00453             bridge_result = DS28E17::Success;
00454         }
00455         else
00456         {
00457             bridge_result = DS28E17::CommsWriteByteError;
00458         }
00459     }
00460 
00461     return bridge_result;
00462 }
00463 
00464 
00465 //*********************************************************************
00466 DS28E17::CmdResult DS28E17::readDeviceRevision(uint8_t & rev)
00467 {
00468     DS28E17::CmdResult bridge_result = DS28E17::OperationFailure;
00469 
00470     OneWireMaster::CmdResult ow_result = selectDevice();
00471 
00472     if (ow_result == OneWireMaster::Success)
00473     {
00474         // Send CMD and receive Data
00475         ow_result = master().OWWriteByte(ReadDeviceRevisionCmd);
00476         if (ow_result == OneWireMaster::Success)
00477         {
00478             ow_result = master().OWReadByte(rev);
00479             if (ow_result == OneWireMaster::Success)
00480             {
00481                 bridge_result = DS28E17::Success;
00482             }
00483             else
00484             {
00485                 bridge_result = DS28E17::CommsReadByteError;
00486             }
00487         }
00488         else
00489         {
00490             bridge_result = DS28E17::CommsWriteByteError;
00491         }
00492     }
00493 
00494     return bridge_result;
00495 }
00496 
00497 
00498 //*********************************************************************
00499 DS28E17::CmdResult DS28E17::sendPacket(const uint8_t * data, uint8_t data_length,
00500                                         uint8_t & status, uint8_t & wr_status)
00501 {
00502     DS28E17::CmdResult bridge_result = DS28E17::CommsWriteBlockError;
00503     uint32_t poll_count = 0;
00504 
00505     OneWireMaster::CmdResult ow_result = master().OWWriteBlock(data, data_length);
00506 
00507     if (ow_result == OneWireMaster::Success)
00508     {
00509         // Poll for Zero 1-Wire bit and return if an error occurs
00510         uint8_t recvbit = 0x01;
00511         do
00512         {
00513             ow_result = master().OWReadBit(recvbit);
00514         } while (recvbit && (poll_count++ < pollLimit) && (ow_result == OneWireMaster::Success));
00515 
00516         if (ow_result == OneWireMaster::Success)
00517         {
00518             if (poll_count < pollLimit)
00519             {
00520                 //Read Status and write status
00521                 uint8_t read_block[2];
00522 
00523                 ow_result = master().OWReadBlock(read_block, 2);
00524 
00525                 if (ow_result == OneWireMaster::Success)
00526                 {
00527                     status = read_block[0];
00528                     wr_status = read_block[1];
00529                     bridge_result = DS28E17::Success;
00530                 }
00531                 else
00532                 {
00533                     bridge_result = DS28E17::CommsReadBlockError;
00534                 }
00535             }
00536             else
00537             {
00538                 bridge_result = DS28E17::TimeoutError;
00539             }
00540         }
00541         else
00542         {
00543             bridge_result = DS28E17::CommsReadBitError;
00544         }
00545     }
00546 
00547     return bridge_result;
00548 }
00549 
00550 
00551 //*********************************************************************
00552 DS28E17::CmdResult DS28E17::sendPacket(const uint8_t * data, uint8_t data_length,
00553                                         uint8_t & status)
00554 {
00555     DS28E17::CmdResult bridge_result = DS28E17::CommsWriteBlockError;
00556     uint32_t poll_count = 0;
00557 
00558     OneWireMaster::CmdResult ow_result = master().OWWriteBlock(data, data_length);
00559 
00560     if (ow_result == OneWireMaster::Success)
00561     {
00562         // Poll for Zero 1-Wire bit and return if an error occurs
00563         uint8_t recvbit = 0x01;
00564         do
00565         {
00566             ow_result = master().OWReadBit(recvbit);
00567         } while (recvbit && (poll_count++ < pollLimit) && (ow_result == OneWireMaster::Success));
00568 
00569         if (ow_result == OneWireMaster::Success)
00570         {
00571             if (poll_count < pollLimit)
00572             {
00573                 //Read Status 
00574                 ow_result = master().OWReadByte(status);
00575                 if (ow_result == OneWireMaster::Success)
00576                 {
00577                     bridge_result = DS28E17::Success;
00578                 }
00579                 else
00580                 {
00581                     bridge_result = DS28E17::CommsReadByteError;
00582                 }
00583             }
00584             else
00585             {
00586                 bridge_result = DS28E17::TimeoutError;
00587             }
00588         }
00589         else
00590         {
00591             bridge_result = DS28E17::CommsReadBitError;
00592         }
00593     }
00594 
00595     return bridge_result;
00596 }
00597