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

Dependents:   RdGasUseMonitor

Fork of Onewire by Simon Barker

Files at this revision

API Documentation at this revision

Comitter:
Bobty
Date:
Sat Feb 21 17:16:16 2015 +0000
Parent:
0:d961f715d82b
Child:
2:b7ee49dbd7ef
Commit message:
Added search function to find existing addresses

Changed in this revision

Onewire.cpp Show annotated file Show diff for this revision Revisions of this file
Onewire.h Show annotated file Show diff for this revision Revisions of this file
--- a/Onewire.cpp	Sun Jun 23 15:17:39 2013 +0000
+++ b/Onewire.cpp	Sat Feb 21 17:16:16 2015 +0000
@@ -87,3 +87,154 @@
     return crc;
 }
 
+//
+// You need to use this function to start a search again from the beginning.
+// You do not need to do it for the first search, though you could.
+//
+void Onewire::reset_search()
+{
+  // reset the search state
+  _search_LastDiscrepancy = 0;
+  _search_LastDeviceFlag = false;
+  _search_LastFamilyDiscrepancy = 0;
+  for(int i = 7; ; i--) {
+    _search_ROM_NO[i] = 0;
+    if ( i == 0) break;
+  }
+}
+
+//
+// Perform a search. 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
+//
+uint8_t Onewire::search(uint8_t *newAddr)
+{
+   uint8_t id_bit_number;
+   uint8_t last_zero, rom_byte_number, search_result;
+   uint8_t id_bit, cmp_id_bit;
+
+   unsigned char rom_byte_mask, search_direction;
+
+   // initialize for search
+   id_bit_number = 1;
+   last_zero = 0;
+   rom_byte_number = 0;
+   rom_byte_mask = 1;
+   search_result = 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 false;
+      }
+
+      // issue the search command
+      writeByte(0xF0);
+
+      // 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
+            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;
+               }
+            }
+
+            // 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)
+            {
+                rom_byte_number++;
+                rom_byte_mask = 1;
+            }
+         }
+      }
+      while(rom_byte_number < 8);  // 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;
+
+         search_result = true;
+      }
+   }
+
+   // if no device found then reset counters so next 'search' will be like a first
+   if (!search_result || !_search_ROM_NO[0])
+   {
+      _search_LastDiscrepancy = 0;
+      _search_LastDeviceFlag = false;
+      _search_LastFamilyDiscrepancy = 0;
+      search_result = false;
+   }
+   for (int i = 0; i < 8; i++)
+       newAddr[i] = _search_ROM_NO[i];
+   return search_result;
+  }
+
--- a/Onewire.h	Sun Jun 23 15:17:39 2013 +0000
+++ b/Onewire.h	Sat Feb 21 17:16:16 2015 +0000
@@ -6,15 +6,31 @@
 class Onewire{
 
 public:
-  Onewire(PinName oneBus);
-  void writeBit(int bit);
+    Onewire(PinName oneBus);
+    void writeBit(int bit);
     int readBit();
     int init();
     int readByte();
     void writeByte(char data);
     unsigned char CRC(unsigned char* addr, unsigned char len);
 
+    // Clear the search state so that if will start from the beginning again.
+    void reset_search();
+    // Look for the next device. Returns 1 if a new address has been
+    // returned. A zero might mean that the bus is shorted, there are
+    // no devices, or you have already retrieved all of them.  It
+    // might be a good idea to check the CRC to make sure you didn't
+    // get garbage.  The order is deterministic. You will always get
+    // the same devices in the same order.
+    uint8_t search(uint8_t *newAddr);    
+    
 private:
-  DigitalInOut oneBus_;
+    DigitalInOut oneBus_;
+  
+    // search state
+    unsigned char _search_ROM_NO[8];
+    uint8_t _search_LastDiscrepancy;
+    uint8_t _search_LastFamilyDiscrepancy;
+    uint8_t _search_LastDeviceFlag;
 };
 #endif
\ No newline at end of file