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

Superseded by MaximInterface.

Revision:
32:bce180b544ed
Parent:
27:d5aaefa252f1
Child:
36:b6b5985a5e40
--- a/OneWire_Masters/OneWireMaster.cpp	Tue Mar 29 16:36:12 2016 -0500
+++ b/OneWire_Masters/OneWireMaster.cpp	Wed Mar 30 16:50:29 2016 -0500
@@ -41,22 +41,20 @@
 const uint16_t OneWireMaster::_oddparity[] = { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 };
 
 
-OneWireMaster::CmdResult OneWireMaster::OWFirst(RomId & romId)
+OneWireMaster::CmdResult OneWireMaster::OWFirst(SearchState & searchState)
 {
     // reset the search state
-    _last_discrepancy = 0;
-    _last_device_flag = 0;
-    _last_family_discrepancy = 0;
+    searchState.reset();
 
-   return OWSearch(romId);  
+   return OWSearch(searchState);  
 }
 
 
 //*********************************************************************
-OneWireMaster::CmdResult OneWireMaster::OWNext(RomId & romId)
+OneWireMaster::CmdResult OneWireMaster::OWNext(SearchState & searchState)
 {
     // leave the search state alone
-    return OWSearch(romId);
+    return OWSearch(searchState);
 }
 
 
@@ -64,66 +62,50 @@
 OneWireMaster::CmdResult OneWireMaster::OWVerify(const RomId & romId)
 {
     OneWireMaster::CmdResult result;
-    RomId romIdCopy(romId);
-    int ld_backup, ldf_backup, lfd_backup;
-
-    // keep a backup copy of the current state
-    ld_backup = _last_discrepancy;
-    ldf_backup = _last_device_flag;
-    lfd_backup = _last_family_discrepancy;
+    SearchState searchState;
 
     // set search to find the same device
-    _last_discrepancy = 64;
-    _last_device_flag = false;
+    searchState.last_discrepancy = 64;
+    searchState.last_device_flag = false;
 
-    result = OWSearch(romIdCopy);
+    result = OWSearch(searchState);
     if (result == OneWireMaster::Success) 
     {
         // check if same device found
-        if (romId != romIdCopy) 
+        if (romId != searchState.romId) 
         {
             result = OneWireMaster::OperationFailure;
         }
     }
 
-    // restore the search state
-    _last_discrepancy = ld_backup;
-    _last_device_flag = ldf_backup;
-    _last_family_discrepancy = lfd_backup;
-
-    // return the result of the verify
     return result;
 }
 
 
 //*********************************************************************
-void OneWireMaster::OWTargetSetup(RomId & romId)
+void OneWireMaster::OWTargetSetup(SearchState & searchState)
 {
     // set the search state to find SearchFamily type devices
-    for (int i = 1; i < 8; i++) 
-    {
-        romId[i] = 0;
-    }
-    
-    _last_discrepancy = 64;
-    _last_family_discrepancy = 0;
-    _last_device_flag = false;
+    std::uint8_t familyCode = searchState.romId.familyCode();
+    searchState.reset();
+    searchState.romId.setFamilyCode(familyCode);
+    searchState.last_discrepancy = 64;
 }
 
 
 //*********************************************************************
-void OneWireMaster::OWFamilySkipSetup(void)
+void OneWireMaster::OWFamilySkipSetup(SearchState & searchState)
 {
     // set the Last discrepancy to last family discrepancy
-    _last_discrepancy = _last_family_discrepancy;
+    searchState.last_discrepancy = searchState.last_family_discrepancy;
 
     // clear the last family discrpepancy
-    _last_family_discrepancy = 0;
+    searchState.last_family_discrepancy = 0;
 
     // check for end of list
-    if (_last_discrepancy == 0)
+    if (searchState.last_discrepancy == 0)
     {
-        _last_device_flag = true;
+        searchState.last_device_flag = true;
     }
 }
 
@@ -195,7 +177,7 @@
 //*********************************************************************    
 OneWireMaster::CmdResult OneWireMaster::OWOverdriveSkipROM(void)
 {
-    OneWireMaster::CmdResult result = OWSpeed(SPEED_STANDARD);
+    OneWireMaster::CmdResult result = OWSetSpeed(SPEED_STANDARD);
     
     if (result == OneWireMaster::Success)
     {
@@ -209,7 +191,7 @@
     
     if (result == OneWireMaster::Success)
     {
-        result = OWSpeed(SPEED_OVERDRIVE);
+        result = OWSetSpeed(SPEED_OVERDRIVE);
     }
     
     return result;
@@ -222,7 +204,7 @@
     OneWireMaster::CmdResult result;
     
     // use overdrive MatchROM
-    OWSpeed(SPEED_STANDARD);
+    OWSetSpeed(SPEED_STANDARD);
     
     result = OWReset();
     if (result == OneWireMaster::Success) 
@@ -230,7 +212,7 @@
         result = OWWriteByte(OVERDRIVE_MATCH_ROM);
         if (result == OneWireMaster::Success) 
         {
-            OWSpeed(SPEED_OVERDRIVE);
+            OWSetSpeed(SPEED_OVERDRIVE);
             // send ROM
             result = OWWriteBlock(romId, RomId::byteLen);
         }
@@ -254,6 +236,146 @@
 }
 
 
+OneWireMaster::CmdResult OneWireMaster::OWSearch(SearchState & searchState)
+{
+   std::uint8_t id_bit_number;
+   std::uint8_t last_zero, rom_byte_number;
+   std::uint8_t id_bit, cmp_id_bit;
+   std::uint8_t rom_byte_mask, status;
+   bool search_result;
+   std::uint8_t crc8 = 0;
+   SearchDirection search_direction;
+
+   // initialize for search
+   id_bit_number = 1;
+   last_zero = 0;
+   rom_byte_number = 0;
+   rom_byte_mask = 1;
+   search_result = false;
+
+   // if the last call was not the last one
+   if (!searchState.last_device_flag)
+   {       
+      // 1-Wire reset
+      OneWireMaster::CmdResult result = OWReset();
+      if (result != OneWireMaster::Success)
+      {
+         // reset the search
+         searchState.reset();
+         return result;
+      }
+
+      // issue the search command 
+      OneWireMaster::OWWriteByte(SEARCH_ROM);  
+
+      // loop to do the search
+      do
+      {
+         // if this discrepancy if before the Last Discrepancy
+         // on a previous next then pick the same as last time
+         if (id_bit_number < searchState.last_discrepancy)
+         {
+            if ((searchState.romId[rom_byte_number] & rom_byte_mask) > 0)
+               search_direction = DIRECTION_WRITE_ONE;
+            else
+               search_direction = DIRECTION_WRITE_ZERO;
+         }
+         else
+         {
+            // if equal to last pick 1, if not then pick 0
+            if (id_bit_number == searchState.last_discrepancy)
+               search_direction = DIRECTION_WRITE_ONE;
+            else
+               search_direction = DIRECTION_WRITE_ZERO;
+         }
+
+         // Peform a triple operation on the DS2465 which will perform 2 read bits and 1 write bit
+         result = OWTriplet(search_direction, id_bit, cmp_id_bit);
+         if (result != OneWireMaster::Success)
+           return result;
+
+         // check for no devices on 1-wire
+         if ((id_bit) && (cmp_id_bit))
+            break;
+         else
+         {
+            if ((!id_bit) && (!cmp_id_bit) && (search_direction == DIRECTION_WRITE_ZERO))
+            {
+               last_zero = id_bit_number;
+
+               // check for Last discrepancy in family
+               if (last_zero < 9)
+                  searchState.last_family_discrepancy = last_zero;
+            }
+
+            // set or clear the bit in the ROM byte rom_byte_number
+            // with mask rom_byte_mask
+            if (search_direction == DIRECTION_WRITE_ONE)
+               searchState.romId[rom_byte_number] |= rom_byte_mask;
+            else
+               searchState.romId[rom_byte_number] &= (std::uint8_t)~rom_byte_mask;
+
+            // increment the byte counter id_bit_number
+            // and shift the mask rom_byte_mask
+            id_bit_number++;
+            rom_byte_mask <<= 1;
+
+            // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask
+            if (rom_byte_mask == 0)
+            {
+               crc8 = RomId::calculateCRC8(crc8, searchState.romId[rom_byte_number]);  // accumulate the CRC
+               rom_byte_number++;
+               rom_byte_mask = 1;
+            }
+         }
+      }
+      while(rom_byte_number < RomId::byteLen);  // loop until through all ROM bytes 0-7
+
+      // if the search was successful then
+      if (!((id_bit_number <= (RomId::byteLen * 8)) || (crc8 != 0)))
+      {
+         // search successful so set m_last_discrepancy,m_last_device_flag,search_result
+         searchState.last_discrepancy = last_zero;
+
+         // check for last device
+         if (searchState.last_discrepancy == 0)
+            searchState.last_device_flag = true;
+
+         search_result = true;
+      }
+   }
+
+   // if no device found then reset counters so next 'search' will be like a first
+   if (!search_result || (searchState.romId.familyCode() == 0))
+   {
+      searchState.reset();
+      search_result = false;
+   }
+
+   return search_result ? OneWireMaster::Success : OneWireMaster::OperationFailure;
+}
+
+
+OneWireMaster::CmdResult OneWireMaster::OWTriplet(SearchDirection & search_direction, std::uint8_t & sbr, std::uint8_t & tsb)
+{
+    CmdResult result;
+    result = OWReadBit(sbr);
+    if (result == Success)
+        result = OWReadBit(tsb);
+    if (result == Success)
+    {
+        if (sbr == 1)
+            search_direction = DIRECTION_WRITE_ONE;
+        else if ((sbr == 0) && (tsb == 1))
+            search_direction = DIRECTION_WRITE_ZERO;
+        // else: use search_direction parameter
+        
+        result = OWWriteBit((search_direction == DIRECTION_WRITE_ONE) ? 1 : 0);
+    }
+    return result;
+}
+
+
 //--------------------------------------------------------------------------
 // Calculate a new CRC16 from the input data shorteger.  Return the current
 // CRC16 and also update the global variable CRC16.