Maxim Integrated / OneWire

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 RomCommands.cpp Source File

RomCommands.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 "RomId/RomCommands.h "
00034 
00035 using namespace OneWire::crc;
00036 
00037 namespace OneWire
00038 {
00039     namespace RomCommands
00040     {
00041         enum OwRomCmd
00042         {
00043             ReadRomCmd = 0x33,
00044             MatchRomCmd = 0x55,
00045             SearchRomCmd = 0xF0,
00046             SkipRomCmd = 0xCC,
00047             ResumeCmd = 0xA5,
00048             OverdriveSkipRomCmd = 0x3C,
00049             OverdriveMatchRomCmd = 0x69,
00050             AlarmSearchCmd = 0xEC
00051         };
00052         
00053         void SearchState::reset()
00054         {
00055             last_discrepancy = 0;
00056             last_device_flag = false;
00057             last_family_discrepancy = 0;
00058             romId = RomId();
00059         }
00060 
00061         void SearchState::findFamily(uint8_t familyCode)
00062         {
00063             reset();
00064             romId.familyCode() = familyCode;
00065             last_discrepancy = 64;
00066         }
00067 
00068         void SearchState::skipCurrentFamily()
00069         {
00070             // set the Last discrepancy to last family discrepancy
00071             last_discrepancy = last_family_discrepancy;
00072 
00073             // clear the last family discrpepancy
00074             last_family_discrepancy = 0;
00075 
00076             // check for end of list
00077             if (last_discrepancy == 0)
00078             {
00079                 last_device_flag = true;
00080             }
00081         }
00082 
00083         OneWireMaster::CmdResult OWFirst(OneWireMaster & master, SearchState & searchState)
00084         {
00085             // Reset and begin a new search
00086             searchState.reset();
00087             return OWSearch(master, searchState);
00088         }
00089 
00090         OneWireMaster::CmdResult OWNext(OneWireMaster & master, SearchState & searchState)
00091         {
00092             // Continue the previous search
00093             return OWSearch(master, searchState);
00094         }
00095 
00096         OneWireMaster::CmdResult OWVerify(OneWireMaster & master, const RomId & romId)
00097         {
00098             OneWireMaster::CmdResult result;
00099             SearchState searchState;
00100 
00101             searchState.romId = romId;
00102 
00103             // set search to find the same device
00104             searchState.last_discrepancy = 64;
00105             searchState.last_device_flag = false;
00106 
00107             result = OWSearch(master, searchState);
00108             if (result == OneWireMaster::Success)
00109             {
00110                 // check if same device found
00111                 if (romId != searchState.romId)
00112                 {
00113                     result = OneWireMaster::OperationFailure;
00114                 }
00115             }
00116 
00117             return result;
00118         }
00119 
00120         OneWireMaster::CmdResult OWReadRom(OneWireMaster & master, RomId & romId)
00121         {
00122             OneWireMaster::CmdResult result;
00123             RomId readId;
00124 
00125             result = master.OWReset();
00126             if (result == OneWireMaster::Success)
00127             {
00128                 result = master.OWWriteByte(ReadRomCmd);
00129             }
00130 
00131             // read the ROM
00132             if (result == OneWireMaster::Success)
00133             {
00134                 result = master.OWReadBlock(readId.buffer.data(), readId.buffer.size());
00135             }
00136 
00137             // verify CRC8
00138             if (result == OneWireMaster::Success)
00139             {
00140                 if (readId.valid())
00141                 {
00142                     romId = readId;
00143                 }
00144                 else
00145                 {
00146                     result = OneWireMaster::OperationFailure;
00147                 }
00148             }
00149 
00150             return result;
00151         }
00152         
00153         OneWireMaster::CmdResult OWSkipRom(OneWireMaster & master)
00154         {
00155             OneWireMaster::CmdResult result;
00156 
00157             result = master.OWReset();
00158             if (result == OneWireMaster::Success)
00159             {
00160                 result = master.OWWriteByte(SkipRomCmd);
00161             }
00162 
00163             return result;
00164         }
00165         
00166         OneWireMaster::CmdResult OWMatchRom(OneWireMaster & master, const RomId & romId)
00167         {
00168             OneWireMaster::CmdResult result;
00169 
00170             uint8_t buf[1 + RomId::Buffer::csize];
00171 
00172             // use MatchROM
00173             result = master.OWReset();
00174             if (result == OneWireMaster::Success)
00175             {
00176                 buf[0] = MatchRomCmd;
00177                 std::memcpy(&buf[1], romId.buffer.data(), romId.buffer.size());
00178                 // send command and rom
00179                 result = master.OWWriteBlock(buf, 1 + romId.buffer.size());
00180             }
00181 
00182             return result;
00183         }
00184         
00185         OneWireMaster::CmdResult OWOverdriveSkipRom(OneWireMaster & master)
00186         {
00187             OneWireMaster::CmdResult result = master.OWSetSpeed(OneWireMaster::StandardSpeed);
00188 
00189             if (result == OneWireMaster::Success)
00190             {
00191                 result = master.OWReset();
00192             }
00193 
00194             if (result == OneWireMaster::Success)
00195             {
00196                 result = master.OWWriteByte(OverdriveSkipRomCmd);
00197             }
00198 
00199             if (result == OneWireMaster::Success)
00200             {
00201                 result = master.OWSetSpeed(OneWireMaster::OverdriveSpeed);
00202             }
00203 
00204             return result;
00205         }
00206           
00207         OneWireMaster::CmdResult OWOverdriveMatchRom(OneWireMaster & master, const RomId & romId)
00208         {
00209             OneWireMaster::CmdResult result;
00210 
00211             // use overdrive MatchROM
00212             master.OWSetSpeed(OneWireMaster::StandardSpeed);
00213 
00214             result = master.OWReset();
00215             if (result == OneWireMaster::Success)
00216             {
00217                 result = master.OWWriteByte(OverdriveMatchRomCmd);
00218                 if (result == OneWireMaster::Success)
00219                 {
00220                     master.OWSetSpeed(OneWireMaster::OverdriveSpeed);
00221                     // send ROM
00222                     result = master.OWWriteBlock(romId.buffer.data(), romId.buffer.size());
00223                 }
00224             }
00225             return result;
00226         }
00227         
00228         OneWireMaster::CmdResult OWResume(OneWireMaster & master)
00229         {
00230             OneWireMaster::CmdResult result;
00231 
00232             result = master.OWReset();
00233             if (result == OneWireMaster::Success)
00234             {
00235                 result = master.OWWriteByte(ResumeCmd);
00236             }
00237 
00238             return result;
00239         }
00240 
00241         OneWireMaster::CmdResult OWSearch(OneWireMaster & master, SearchState & searchState)
00242         {
00243             return OWSearchAll(master, searchState, false);
00244         }
00245         
00246         OneWireMaster::CmdResult OWAlarmSearch(OneWireMaster & master, SearchState & searchState)
00247         {
00248             return OWSearchAll(master, searchState, true);
00249         }
00250         
00251         OneWireMaster::CmdResult OWFirstAlarm(OneWireMaster & master, SearchState & searchState)
00252         {
00253             searchState.reset();
00254             return OWAlarmSearch(master, searchState);
00255         }
00256         
00257         OneWireMaster::CmdResult OWNextAlarm(OneWireMaster & master, SearchState & searchState)
00258         {
00259             return OWAlarmSearch(master, searchState);
00260         }
00261 
00262         OneWireMaster::CmdResult OWSearchAll(OneWireMaster & master, SearchState & searchState, bool alarmSearch)
00263         {
00264             uint8_t id_bit_number;
00265             uint8_t last_zero, rom_byte_number;
00266             uint8_t id_bit, cmp_id_bit;
00267             uint8_t rom_byte_mask;
00268             bool search_result;
00269             uint8_t crc8 = 0;
00270             OneWireMaster::SearchDirection search_direction;
00271 
00272             // initialize for search
00273             id_bit_number = 1;
00274             last_zero = 0;
00275             rom_byte_number = 0;
00276             rom_byte_mask = 1;
00277             search_result = false;
00278 
00279             // if the last call was not the last one
00280             if (!searchState.last_device_flag)
00281             {
00282                 // 1-Wire reset
00283                 OneWireMaster::CmdResult result = master.OWReset();
00284                 if (result != OneWireMaster::Success)
00285                 {
00286                     // reset the search
00287                     searchState.reset();
00288                     return result;
00289                 }
00290 
00291                 // issue the search command 
00292                 if(alarmSearch){
00293                     master.OWWriteByte(AlarmSearchCmd);
00294                 }
00295                 else{
00296                     master.OWWriteByte(SearchRomCmd);
00297                 }
00298 
00299                 // loop to do the search
00300                 do
00301                 {
00302                     // if this discrepancy if before the Last Discrepancy
00303                     // on a previous next then pick the same as last time
00304                     if (id_bit_number < searchState.last_discrepancy)
00305                     {
00306                         if ((searchState.romId.buffer[rom_byte_number] & rom_byte_mask) > 0)
00307                         {
00308                             search_direction = OneWireMaster::WriteOne;
00309                         }
00310                         else
00311                         {
00312                             search_direction = OneWireMaster::WriteZero;
00313                         }
00314                     }
00315                     else
00316                     {
00317                         // if equal to last pick 1, if not then pick 0
00318                         if (id_bit_number == searchState.last_discrepancy)
00319                         {
00320                             search_direction = OneWireMaster::WriteOne;
00321                         }
00322                         else
00323                         {
00324                             search_direction = OneWireMaster::WriteZero;
00325                         }
00326                     }
00327 
00328                     // Peform a triple operation on the DS2465 which will perform 2 read bits and 1 write bit
00329                     result = master.OWTriplet(search_direction, id_bit, cmp_id_bit);
00330                     if (result != OneWireMaster::Success)
00331                     {
00332                         return result;
00333                     }
00334 
00335                     // check for no devices on 1-wire
00336                     if (id_bit && cmp_id_bit)
00337                     {
00338                         break;
00339                     }
00340                     else
00341                     {
00342                         if (!id_bit && !cmp_id_bit && (search_direction == OneWireMaster::WriteZero))
00343                         {
00344                             last_zero = id_bit_number;
00345 
00346                             // check for Last discrepancy in family
00347                             if (last_zero < 9)
00348                             {
00349                                 searchState.last_family_discrepancy = last_zero;
00350                             }
00351                         }
00352 
00353                         // set or clear the bit in the ROM byte rom_byte_number
00354                         // with mask rom_byte_mask
00355                         if (search_direction == OneWireMaster::WriteOne)
00356                         {
00357                             searchState.romId.buffer[rom_byte_number] |= rom_byte_mask;
00358                         }
00359                         else
00360                         {
00361                             searchState.romId.buffer[rom_byte_number] &= (uint8_t)~rom_byte_mask;
00362                         }
00363 
00364                         // increment the byte counter id_bit_number
00365                         // and shift the mask rom_byte_mask
00366                         id_bit_number++;
00367                         rom_byte_mask <<= 1;
00368 
00369                         // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask
00370                         if (rom_byte_mask == 0)
00371                         {
00372                             crc8 = calculateCrc8(crc8, searchState.romId.buffer[rom_byte_number]);  // accumulate the CRC
00373                             rom_byte_number++;
00374                             rom_byte_mask = 1;
00375                         }
00376                     }
00377                 } while (rom_byte_number < searchState.romId.buffer.size());  // loop until through all ROM bytes 0-7
00378 
00379                 // if the search was successful then
00380                 if (!((id_bit_number <= (searchState.romId.buffer.size() * 8)) || (crc8 != 0)))
00381                 {
00382                     // search successful so set m_last_discrepancy,m_last_device_flag,search_result
00383                     searchState.last_discrepancy = last_zero;
00384 
00385                     // check for last device
00386                     if (searchState.last_discrepancy == 0)
00387                     {
00388                         searchState.last_device_flag = true;
00389                     }
00390 
00391                     search_result = true;
00392                 }
00393             }
00394 
00395             // if no device found then reset counters so next 'search' will be like a first
00396             if (!search_result || (searchState.romId.familyCode () == 0))
00397             {
00398                 searchState.reset();
00399                 search_result = false;
00400             }
00401 
00402             return (search_result ? OneWireMaster::Success : OneWireMaster::OperationFailure);
00403         }
00404     }
00405 }