Library to communicate with Maxim OneWire protocol devices Modified timings and IRQ overrides

Dependents:   RdGasUseMonitor

Fork of Onewire by Simon Barker

Revision:
7:0a87f8c2d9e6
Parent:
6:d2452e9b169b
Child:
8:5d0bd95b586f
--- a/Onewire.cpp	Mon Oct 05 14:03:29 2015 +0000
+++ b/Onewire.cpp	Thu Oct 15 21:39:21 2015 +0000
@@ -63,10 +63,10 @@
     {
         __enable_irq();
         wait_us(100);
-        return 1;
+        return ONEWIRE_OK;
     }
     __enable_irq();
-    return 0;
+    return ONEWIRE_SEARCH_INIT_FAIL;
 }
 
 int Onewire::readByte() 
@@ -126,141 +126,122 @@
         _search_ROM_NO[i] = 0;
 }
 
-// Search Copied from Arduino code
+// Search Based on Maxim DS18B20 Algorithm
+// https://www.maximintegrated.com/en/app-notes/index.mvp/id/187
 //
-// Perform a search.
-// Returns 
+// Perform a search, returns:
 // ONEWIRE_OK if a new address has been returned.
 // ONEWIRE_SEARCH_ALL_DONE = all devices found
 // ONEWIRE_SEARCH_INIT_FAIL = failed to init
 // ONEWIRE_SEARCH_NOT_FOUND = no devices found If this function returns a '1' then it has
-// enumerated the next device and you may retrieve the ROM from the
-// Onewire::address variable. If there are no devices, no further
-// devices, or something horrible happens in the middle of the
-// enumeration then a 0 is returned.  If a new device is found then
-// its address is copied to newAddr.  Use Onewire::reset_search() to
-// start over.
-//
-// --- Replaced by the one from the Dallas Semiconductor web site ---
-//--------------------------------------------------------------------------
-// Perform the 1-Wire Search Algorithm on the 1-Wire bus using the existing
-// search state.
-// Return TRUE  : device found, ROM number in ROM_NO buffer
-//        FALSE : device not found, end of search
+// ONEWIRE_SEARCH_STUCK_HIGH = bus is stuck high
+// ONEWIRE_SEARCH_COMP_BIT_ERR = complement bit error
 //
 uint8_t Onewire::search(uint8_t *newAddr)
 {
-   uint8_t id_bit_number = 1;
-   uint8_t last_zero = 0, rom_byte_number = 0;
-   uint8_t search_result = ONEWIRE_SEARCH_ALL_DONE;
-   uint8_t id_bit = 0, cmp_id_bit = 0;
-
-   // initialize for search
-   unsigned char rom_byte_mask = 1, search_direction = 0;
+    // initialize for search
+    uint8_t last_zero = 0;
+    unsigned char search_direction = 0;
 
-   // if the last call was not the last one
-   if (!_search_LastDeviceFlag)
-   {
-      // 1-Wire reset
-      if (!init())
-      {
-         // reset the search
-         _search_LastDiscrepancy = 0;
-         _search_LastDeviceFlag = false;
-         _search_LastFamilyDiscrepancy = 0;
-         return ONEWIRE_SEARCH_INIT_FAIL;
-      }
-
-      // issue the search command
-      writeByte(0xF0);
+    // if the previous call was the last one
+    if (_search_LastDeviceFlag)
+        return ONEWIRE_SEARCH_ALL_DONE;
+        
+    // 1-Wire reset
+    int initRslt = init();
+    wait_us(410);
+    if (initRslt != ONEWIRE_OK)
+    {
+        // reset the search
+        reset_search();
+        return initRslt;
+    }
+    
+    // issue the search command
+    writeByte(0xF0);
+    
+    // loop to do the search
+    for (int id_bit_number = 1; id_bit_number <= 64; id_bit_number++)
+    {
+        // read a bit and its complement
+        uint8_t id_bit = readBit();
+        uint8_t cmp_id_bit = readBit();
+        
+        // check for no devices on 1-wire
+        if ((id_bit == 1) && (cmp_id_bit == 1))
+        {
+            reset_search();
+            return ONEWIRE_SEARCH_COMP_BIT_ERR;
+        }
 
-      // loop to do the search
-      do
-      {
-         // read a bit and its complement
-         id_bit = readBit();
-         cmp_id_bit = readBit();
-
-         // check for no devices on 1-wire
-         if ((id_bit == 1) && (cmp_id_bit == 1))
-            break;
-         else
-         {
-            // all devices coupled have 0 or 1
-            if (id_bit != cmp_id_bit)
-               search_direction = id_bit;  // bit write value for search
+        // all devices coupled have 0 or 1
+        int byteNo = (id_bit_number - 1) / 8;
+        int byteMask = 1 << ((id_bit_number - 1) % 8);
+        if (id_bit != cmp_id_bit)
+        {
+            search_direction = id_bit;  // bit write value for search
+        }           
+        else
+        {
+            if (id_bit_number == _search_LastDiscrepancy)
+            {
+                search_direction = 1;
+            }
+            else if (id_bit_number > _search_LastDiscrepancy)
+            {
+                search_direction = 0;
+            }
             else
             {
-               // if this discrepancy if before the Last Discrepancy
-               // on a previous next then pick the same as last time
-               if (id_bit_number < _search_LastDiscrepancy)
-                  search_direction = ((_search_ROM_NO[rom_byte_number] & rom_byte_mask) > 0);
-               else
-                  // if equal to last pick 1, if not then pick 0
-                  search_direction = (id_bit_number == _search_LastDiscrepancy);
-
-               // if 0 was picked then record its position in LastZero
-               if (search_direction == 0)
-               {
-                  last_zero = id_bit_number;
-
-                  // check for Last discrepancy in family
-                  if (last_zero < 9)
-                     _search_LastFamilyDiscrepancy = last_zero;
-               }
+                search_direction = ((_search_ROM_NO[byteNo] & byteMask) > 0);
             }
-
-            // set or clear the bit in the ROM byte rom_byte_number
-            // with mask rom_byte_mask
-            if (search_direction == 1)
-              _search_ROM_NO[rom_byte_number] |= rom_byte_mask;
-            else
-              _search_ROM_NO[rom_byte_number] &= ~rom_byte_mask;
-
-            // serial number search direction write bit
-            writeBit(search_direction);
-
-            // 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)
+            
+            // if 0 was picked then record its position in LastZero
+            if (search_direction == 0)
             {
-                rom_byte_number++;
-                rom_byte_mask = 1;
+                last_zero = id_bit_number;
+                // check for Last discrepancy in family
+                if (last_zero < 9)
+                    _search_LastFamilyDiscrepancy = last_zero;
             }
-         }
-      }
-      while(rom_byte_number < ONEWIRE_ADDR_BYTES);  // loop until through all ROM bytes 0-7
-
-      // if the search was successful then
-      if (!(id_bit_number < 65))
-      {
-         // search successful so set LastDiscrepancy,LastDeviceFlag,search_result
-         _search_LastDiscrepancy = last_zero;
-
-         // check for last device
-         if (_search_LastDiscrepancy == 0)
-            _search_LastDeviceFlag = true;
+        }
+        
+        // set or clear the bit in the ROM byte rom_byte_number
+        // with mask rom_byte_mask
+        
+        if (search_direction == 1)
+            _search_ROM_NO[byteNo] |= byteMask;
+        else
+            _search_ROM_NO[byteNo] &= ~byteMask;
+        
+        // serial number search direction write bit
+        writeBit(search_direction);
+    }
+    
+    // search successful so set LastDiscrepancy,LastDeviceFlag,search_result
+    _search_LastDiscrepancy = last_zero;
+    // check for last device
+    if (_search_LastDiscrepancy == 0)
+        _search_LastDeviceFlag = true;
+    
+    // Copy address to return
+    for (int i = 0; i < ONEWIRE_ADDR_BYTES; i++)
+        newAddr[i] = _search_ROM_NO[i];
+        
+    return ONEWIRE_OK;
+}
 
-         search_result = ONEWIRE_OK;
-      }
-   }
-
-   // if no device found then reset counters so next 'search' will be like a first
-   if (!_search_ROM_NO[0])
-   {
-      _search_LastDiscrepancy = 0;
-      _search_LastDeviceFlag = false;
-      _search_LastFamilyDiscrepancy = 0;
-      search_result = ONEWIRE_SEARCH_NOT_FOUND;
-   }
-   if (search_result != ONEWIRE_OK)
-        return search_result;
-   for (int i = 0; i < ONEWIRE_ADDR_BYTES; i++)
-       newAddr[i] = _search_ROM_NO[i];
-   return search_result;
-  }
-
+char* Onewire::GetErrorStr(int errCode)
+{
+    switch(errCode)
+    {
+        case ONEWIRE_OK: return "OK";
+        case ONEWIRE_SEARCH_ALL_DONE: return "All Done";
+        case ONEWIRE_SEARCH_INIT_FAIL: return "Init Fail";
+        case ONEWIRE_SEARCH_NOT_FOUND: return "Not Found";
+        case ONEWIRE_SEARCH_STUCK_HIGH: return "Stuck High";
+        case ONEWIRE_SEARCH_COMP_BIT_ERR: return "Comp Bit Err";
+    }
+    return "Unknown Err";
+}
+