Backing up an unused program in case of future need

Dependencies:   mbed

Revision:
6:be97d38e0b01
Parent:
5:6226f3c566ef
Child:
7:024ace6d943c
--- a/1-wire.cpp	Wed May 11 16:42:35 2016 +0000
+++ b/1-wire.cpp	Tue May 31 07:35:28 2016 +0000
@@ -1,13 +1,16 @@
-#include "mbed.h"
-#include "log.h"
-#include  "io.h"
+#include   "mbed.h"
+#include    "log.h"
+#include     "io.h"
+#include "1-wire.h"
 
 //Bus zone
 //========
 static DigitalInOut pin(p25, PIN_INPUT, PullUp, 0);
 
+static volatile int busvalue;
 
-static int busvalue;
+static Timer timer;
+static Timer busytimer;
 
 //Delays
 #define           ATTACH_US    7
@@ -22,67 +25,32 @@
 #define READ_BIT_BUS_LOW_US    6
 #define         READ_BIT_US    9
 #define READ_BIT_RELEASE_US   55
-#define      BUS_TIMEOUT_MS 1000
-
-static int busbusy = false;   //Set whenever an operation starts; reset by finishbus interrupt;
-static Timer busbusytimer;
-
-static Timeout startbuslow;
-static Timeout startbusfree;
-static Timeout startbushigh;
-static Timeout startbusread;
-static Timeout startbusidle;
-static void         buslow (void) { pin.output(); pin = 0;                         }
-static void         busfree(void) { pin.input ();                                  }
-static void         bushigh(void) { pin.output(); pin = 1;                         }
-static void         busread(void) {               busvalue = pin;                  }
-static void         busidle(void) { pin.input ();                 busbusy = false; }
+#define      BUS_TIMEOUT_MS 5000
 
-static void reset()
-{
-    busbusy = true;
-    int start =    INITIAL_US - ATTACH_US; startbuslow .attach_us(&buslow,  start);
-    start += RESET_BUS_LOW_US - ATTACH_US; startbusfree.attach_us(&busfree, start);
-    start += READ_PRESENCE_US - ATTACH_US; startbusread.attach_us(&busread, start);
-    start += RESET_RELEASE_US - ATTACH_US; startbusidle.attach_us(&busidle, start);
-}
-static void writebit(int bit, int msToPullUp)
-{
-    busbusy = true;
-    int start = INITIAL_US - ATTACH_US;
-    startbuslow.attach_us(&buslow, start);
-    start += bit ? WRITE_1_BUS_LOW_US : WRITE_0_BUS_LOW_US;
-    start -= ATTACH_US;
-    if (msToPullUp)
-    {
-        startbushigh.attach_us(&bushigh, start);
-        start += msToPullUp * 1000 - ATTACH_US;
-    }
-    else
-    {
-        startbusfree.attach_us(&busfree, start);
-        start += bit ? WRITE_1_RELEASE_US : WRITE_0_RELEASE_US;
-        start -= ATTACH_US;
-    }
-    startbusidle.attach_us(&busidle,  start);
-}
-static void initiatebitread()
-{
-    busbusy = true;
-    int start =       INITIAL_US - ATTACH_US; startbuslow .attach_us(&buslow,  start);
-    start += READ_BIT_BUS_LOW_US - ATTACH_US; startbusfree.attach_us(&busfree, start);
-    start +=         READ_BIT_US - ATTACH_US; startbusread.attach_us(&busread, start);
-    start += READ_BIT_RELEASE_US - ATTACH_US; startbusidle.attach_us(&busidle, start);
-}
+static void buslow (void) { pin.output(); pin = 0;        }
+static void busfree(void) { pin.input ();                 }
+static void bushigh(void) { pin.output(); pin = 1;        }
+static void busread(void) {               busvalue = pin; }
 
 //Exchange zone
 //=============
-#define XCHG_IDLE   0
-#define XCHG_RESET  1
-#define XCHG_WRITE  2
-#define XCHG_READ   3
-#define XCHG_PULLUP 4
-static int xchgstate = XCHG_IDLE;
+#define STATE_IDLE            0
+#define RESET_LOW             1
+#define RESET_RELEASE         2
+#define XCHG_WRITE            3
+#define PULL_UP               4
+#define XCHG_READ             5
+#define SEARCH_WRITE          6
+#define SEARCH_BIT            7
+#define SEARCH_READ_BIT_TRUE  8
+#define SEARCH_READ_BIT_COMP  9
+#define SEARCH_WRITE_BIT     10
+static int state = STATE_IDLE;
+
+#define JOB_NONE   0
+#define JOB_XCHG   1
+#define JOB_SEARCH 2
+static int job = JOB_NONE;
 
 static int  lensend = 0;
 static int  lenrecv = 0;
@@ -90,6 +58,52 @@
 static char*  precv = NULL;
 static int pullupms = 0;
 
+static void initiateResetLow(int jobtype)
+{
+    buslow();
+    timer.stop();
+    timer.reset();
+    timer.start();
+    state = RESET_LOW;
+    job = jobtype;
+}
+static void readPresenceAndAwaitResetRelease()
+{
+    busfree();
+    wait_us(READ_PRESENCE_US);
+    busread();
+    timer.stop();
+    timer.reset();
+    timer.start();
+    state = RESET_RELEASE;
+}
+static void writeBit(int bit)
+{
+    buslow();
+    wait_us(bit ? WRITE_1_BUS_LOW_US : WRITE_0_BUS_LOW_US);
+    busfree();
+    wait_us(bit ? WRITE_1_RELEASE_US : WRITE_0_RELEASE_US);
+}
+static void writeBitWithPullUp(int bit)
+{
+    buslow();
+    wait_us(bit ? WRITE_1_BUS_LOW_US : WRITE_0_BUS_LOW_US);
+    bushigh();
+    timer.stop();
+    timer.reset();
+    timer.start();
+    state = PULL_UP;
+}
+static void readBit()
+{
+    buslow();
+    wait_us(READ_BIT_BUS_LOW_US);
+    busfree();
+    wait_us(READ_BIT_US);
+    busread();
+    wait_us(READ_BIT_RELEASE_US);
+}
+
 static char crc;
 static void resetCrc()
 {
@@ -97,14 +111,9 @@
 }
 static void addBitToCrc(int bit)
 {
-    //Logical Exclusive Or of the 9th output of the shift register with the input
-    int feedback = !(crc & 0x80) != !bit;
-    
-    //Move the shift register one place to the left leaving a zero in the lsb
-    crc <<= 1;
-    
-    //Exclusive Or the shift register with polynomial X5 + X4 + 1
-    if (feedback) crc ^= 0x31;
+    int feedback = !(crc & 0x80) != !bit; //Logical Exclusive Or of the msb of the shift register with the input
+    crc <<= 1;                            //Move the shift register one place to the left leaving a zero in the lsb and losing the msb
+    if (feedback) crc ^= 0x31;            //Exclusive Or the shift register with polynomial X5 + X4 + 1
 }
 
 static void resetBitPosition(int* pByteIndex, char* pBitMask)
@@ -128,7 +137,8 @@
 }
 void setBitAtPosition(int byteIndex, char bitMask, int bit)
 {
-    if (bit) precv[byteIndex] |= bitMask;
+    if ( bit) precv[byteIndex] |=  bitMask;
+    else      precv[byteIndex] &= ~bitMask;
 }
 int moreBitsToRead(int byteIndex)
 {
@@ -138,22 +148,24 @@
 {
     return byteIndex < lensend;
 }
+
+int result = ONE_WIRE_RESULT_OK;
+int OneWireResult()
+{
+    return result;
+}
 int OneWireInit()
 {
-    startbuslow.detach();
-    startbushigh.detach();
-    startbusfree.detach();
-    startbusread.detach();
-    startbusidle.detach();
-    busidle();
-    xchgstate = XCHG_IDLE;
-    busbusytimer.stop();
-    busbusytimer.reset();
+    busfree();
+    busytimer.stop();
+    busytimer.reset();
+    state = STATE_IDLE;
+    job   =  JOB_NONE;
     return 0;
 }
 int OneWireBusy()
 {
-    return xchgstate;
+    return state;
 }
 void OneWireExchange(int lenBytesToSend, int lenBytesToRecv, char *pBytesToSend, char *pBytesToRecv, int msToPullUp)
 {
@@ -162,8 +174,66 @@
     psend = pBytesToSend;
     precv = pBytesToRecv;
     pullupms = msToPullUp;
-    xchgstate = XCHG_RESET;
-    reset();
+    initiateResetLow(JOB_XCHG);
+}
+static int* pallfound;
+static char* prom;
+static void setRomBit(int position, int bit)
+{
+    int bitindex = position & 0x07;
+    int byteindex = position >> 3;
+    int bitmask = 1 << bitindex;
+    if (bit) *(prom + byteindex) |=  bitmask;
+    else     *(prom + byteindex) &= ~bitmask;
+}
+static int getRomBit(int position)
+{    
+    int bitindex = position & 0x07;
+    int byteindex = position >> 3;
+    int bitmask = 1 << bitindex;
+    return *(prom + byteindex) & bitmask;
+}
+static int thisFurthestForkLeftPosn;
+static int lastFurthestForkLeftPosn;
+static char searchCommand;
+static int searchBitPosn;
+static int searchBitTrue;
+static int searchBitComp;
+static int chooseDirectionToTake()
+{
+    if ( searchBitTrue &&  searchBitComp) return -1; //No devices are participating in the search
+    if ( searchBitTrue && !searchBitComp) return  1; //Only devices with a one  at this point are participating
+    if (!searchBitTrue &&  searchBitComp) return  0; //Only devices with a zero at this point are participating
+    //Both bits are zero so devices with both 0s and 1s at this point are still participating
+    
+    //If we have not yet reached the furthest away point we forked left (0) last time then just do whatever we did last time
+    if (searchBitPosn <  lastFurthestForkLeftPosn) return getRomBit(searchBitPosn);
+    
+    //If we are at the furthest away point that we forked left (0) last time then this time fork right (1)
+    if (searchBitPosn == lastFurthestForkLeftPosn) return 1;
+    
+    //We are at a new fork point further than we have been before so fork left (0) and record that we did so.
+    thisFurthestForkLeftPosn = searchBitPosn;
+    return 0; 
+}
+void OneWireSearch(char command, char* pDeviceRom, int* pAllDevicesFound) //Specify the buffer to receive the rom for the first search and NULL thereafter.
+{
+    if (pDeviceRom)
+    {
+        pallfound = pAllDevicesFound;
+        *pallfound = false;
+        lastFurthestForkLeftPosn = -1;
+        prom = pDeviceRom;
+        for (int i = 0; i < 8; i++) *(prom + i) = 0;
+    }
+    thisFurthestForkLeftPosn = -1;
+    lensend = 1;
+    lenrecv = 0;
+    searchCommand = command;
+    psend = &searchCommand;
+    precv = NULL;
+    pullupms = 0;
+    initiateResetLow(JOB_SEARCH);
 }
 char OneWireCrc()
 {
@@ -174,45 +244,64 @@
     static int byteindex;
     static char bitmask;
     
-    if (busbusy)
+    if (state)
     {
-        busbusytimer.start();
-        if (busbusytimer.read_ms() > BUS_TIMEOUT_MS)
+        busytimer.start();
+        if (busytimer.read_ms() > BUS_TIMEOUT_MS)
         {
             LogCrLf("1-wire bus timed out so protocol has been reset to idle.");
             OneWireInit();
+            result = ONE_WIRE_RESULT_TIMED_OUT;
+            return 0;
         }
-        return 0;
     }
     else
     {
-        busbusytimer.stop();
-        busbusytimer.reset();
+        busytimer.stop();
+        busytimer.reset();
     }
     
-    switch(xchgstate)
+    switch(state)
     {
-        case XCHG_IDLE:
+        case STATE_IDLE:
             break;
-        case XCHG_RESET:
-            if (busvalue)
+        case RESET_LOW:
+            if (timer.read_us() > RESET_BUS_LOW_US) readPresenceAndAwaitResetRelease();
+            break;
+        case RESET_RELEASE:
+            if (timer.read_us() > RESET_RELEASE_US)
             {
-                LogCrLf("No 1-wire device presence detected on the bus");
-                xchgstate = XCHG_IDLE;
-            }
-            else
-            {
-                resetBitPosition(&byteindex, &bitmask);
-                xchgstate = XCHG_WRITE;
+                busfree();
+                timer.stop();
+                timer.reset();
+                if (busvalue)
+                {
+                    LogCrLf("No 1-wire device presence detected on the bus");
+                    result = ONE_WIRE_RESULT_NO_DEVICE_PRESENT;
+                    state = STATE_IDLE;
+                }
+                else
+                {
+                    resetBitPosition(&byteindex, &bitmask);
+                    switch (job)
+                    {
+                        case JOB_XCHG:   state =   XCHG_WRITE; break;
+                        case JOB_SEARCH: state = SEARCH_WRITE; break;
+                        default:
+                            LogF("Unknown job in RESET_RELEASE %d\r\n", job);
+                            return -1;
+                    }
+                }
             }
             break;
+            
         case XCHG_WRITE:
             if (moreBitsToWrite(byteindex))
             {
                 int bit = getBitAtPosition(byteindex, bitmask);
                 incrementBitPosition(&byteindex, &bitmask);
-                if (moreBitsToWrite(byteindex)) writebit(bit, 0);
-                else                            writebit(bit, pullupms);
+                if (moreBitsToWrite(byteindex)) writeBit(bit);
+                else                            writeBitWithPullUp(bit);
             }
             else
             {
@@ -220,31 +309,102 @@
                 if (moreBitsToRead(byteindex))
                 {
                     resetCrc();
-                    initiatebitread();
-                    xchgstate = XCHG_READ;
+                    readBit();
+                    state = XCHG_READ;
                     
                 }
                 else
                 {
-                    xchgstate = XCHG_IDLE;
+                    result = ONE_WIRE_RESULT_OK;
+                    state = STATE_IDLE;
                 }
             }
             break;
+        case PULL_UP:
+            if (timer.read_ms() > pullupms)
+            {
+                busfree();
+                switch (job)
+                {
+                    case JOB_XCHG: state = XCHG_WRITE; break;
+                    default:
+                        LogF("Unknown job in PULL_UP %d\r\n", job);
+                        return -1;
+                }
+            }
+            break;        
         case XCHG_READ:
             addBitToCrc(busvalue);
             setBitAtPosition(byteindex, bitmask, busvalue);
             incrementBitPosition(&byteindex, &bitmask);
             if (moreBitsToRead(byteindex))
             {
-                initiatebitread();
+                readBit();
+            }
+            else
+            {
+                state = STATE_IDLE;
+                result = crc ? ONE_WIRE_RESULT_CRC_ERROR : ONE_WIRE_RESULT_OK;
+            }
+            break;
+            
+        case SEARCH_WRITE:
+            if (moreBitsToWrite(byteindex))
+            {
+                int bit = getBitAtPosition(byteindex, bitmask);
+                incrementBitPosition(&byteindex, &bitmask);
+                writeBit(bit);
             }
             else
             {
-                xchgstate = XCHG_IDLE;
+                searchBitPosn = 0;
+                state = SEARCH_BIT;
+            }
+            break;
+        case SEARCH_BIT:
+            readBit();
+            state = SEARCH_READ_BIT_TRUE;
+            break;
+        case SEARCH_READ_BIT_TRUE:
+            searchBitTrue = busvalue;
+            readBit();
+            state = SEARCH_READ_BIT_COMP;
+            break;
+        case SEARCH_READ_BIT_COMP:
+            searchBitComp = busvalue;
+            state = SEARCH_WRITE_BIT;
+            break;
+        case SEARCH_WRITE_BIT:
+            LogF("%d%d - ", searchBitTrue, searchBitComp);
+            int direction;
+            direction = chooseDirectionToTake();
+            if (direction == -1)
+            {
+                LogCrLf("No devices have responded");
+                result = ONE_WIRE_RESULT_NO_DEVICE_PARTICIPATING;
+                state = STATE_IDLE;
+            }
+            else
+            {
+                LogF(" %d -> %d\r\n", direction, searchBitPosn);
+                setRomBit(searchBitPosn, direction);
+                writeBit(direction);
+                searchBitPosn++;
+                if (searchBitPosn < 64)
+                {
+                    state = SEARCH_BIT;
+                }
+                else
+                {
+                    if (thisFurthestForkLeftPosn == -1) *pallfound = true;
+                    lastFurthestForkLeftPosn = thisFurthestForkLeftPosn;
+                    result = ONE_WIRE_RESULT_OK;
+                    state = STATE_IDLE;
+                }
             }
             break;
         default:
-            LogF("Unknown xchgstate %d\r\n", xchgstate);
+            LogF("Unknown state %d\r\n", state);
             return -1;
     }
     return 0;