Fork to see if I can get working

Dependencies:   BufferedSerial OneWire WinbondSPIFlash libxDot-dev-mbed5-deprecated

Fork of xDotBridge_update_test20180823 by Matt Briggs

Files at this revision

API Documentation at this revision

Comitter:
Matt Briggs
Date:
Mon Feb 27 08:06:36 2017 -0700
Parent:
54:c04d7b6fa075
Child:
56:40b454c952cc
Commit message:
Adding lots of NVM code to store parameters in eeprom. Also some work on documentation.

Changed in this revision

xDotBridge.doxyfile Show annotated file Show diff for this revision Revisions of this file
xDotBridge/README.md Show annotated file Show diff for this revision Revisions of this file
xDotBridge/config.h Show annotated file Show diff for this revision Revisions of this file
xDotBridge/inc/BaseboardIO.h Show annotated file Show diff for this revision Revisions of this file
xDotBridge/inc/CommProtocolPeerBrute.h Show annotated file Show diff for this revision Revisions of this file
xDotBridge/manualTest/testBaseboardIO/testBaseboardIO.cpp Show annotated file Show diff for this revision Revisions of this file
xDotBridge/manualTest/testLRRPins/testLRRPins.cpp Show annotated file Show diff for this revision Revisions of this file
xDotBridge/manualTest/testPVD/testPVD.cpp Show annotated file Show diff for this revision Revisions of this file
xDotBridge/src/BaseboardIO.cpp Show annotated file Show diff for this revision Revisions of this file
xDotBridge/src/CommProtocolPeerBrute.cpp Show annotated file Show diff for this revision Revisions of this file
xDotBridge/src/main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/xDotBridge.doxyfile	Wed Feb 22 15:39:40 2017 -0700
+++ b/xDotBridge.doxyfile	Mon Feb 27 08:06:36 2017 -0700
@@ -982,7 +982,7 @@
 # (index.html). This can be useful if you have a project on for instance GitHub
 # and want to reuse the introduction page also for the doxygen output.
 
-USE_MDFILE_AS_MAINPAGE = 
+USE_MDFILE_AS_MAINPAGE = README.md
 
 #---------------------------------------------------------------------------
 # Configuration options related to source browsing
--- a/xDotBridge/README.md	Wed Feb 22 15:39:40 2017 -0700
+++ b/xDotBridge/README.md	Mon Feb 27 08:06:36 2017 -0700
@@ -95,7 +95,8 @@
 
 ### Add additional RXs to pair group:
 1.  To add an additional RX.  Pair it using the exact same process as adding a TX
-utilizing the above instructions.
+utilizing the above instructions _i.e. pair the unit whichh will eventually become a
+RX as if was a TX_.
 2.  When pairing as a TX is complete; Convert the paired TX to a paired RX by switching the DIP
 switch to RX mode.  This RX will now receive any TX alerts which are in range an in pair group.
 
@@ -114,23 +115,44 @@
 * Future idea maybe a RX with WAN enabled acts as a repeater to conduit.
 
 # Nonvolatile Memory Map
-## Radio Parameters
-TBD.  Most of this should be stored automatically by dot-firmware.  WIll try to figure out where in overall
-memory map.  Reserved dot NVM 0x0000 -> 0x0FFF
+## Stored by dot firmware
+ * 64-bit EUI
+ * Network ID
+ * DLC
+ * ULC
+ * Enc keys
+
+
+## Protocol Parameters
+==============================================
+= Dot Relative Addr | Size (in Bytes) | Name =
+==============================================
+= 0x1000 | 2 Bytes | Protocol Flag           =
+==============================================
+= 0x1002 | 2 Bytes | Protocol Rev            =
+==============================================
+= 0x1004 | 2 Bytes | Logical Address Serial  =
+==============================================
+= 0x1006 | 4 Bytes | Last Message SeqNum     =
+==============================================
+Space used is 10 bytes
 
 ## IO Baseboard Parameters
 ==============================================
 = Dot Relative Addr | Size (in Bytes) | Name =
 ==============================================
-= 0x1000 | 2 Bytes | Baseboard Flag          =
+= 0x2000 | 2 Bytes | Baseboard Flag          =
+==============================================
+= 0x2002 | 2 Bytes | Baseboard Rev           =
 ==============================================
-= 0x1002 | 2 Bytes | Baseboard Rev           =
+= 0x2004 | 2 Bytes | Baseboard Serial        =
 ==============================================
-= 0x1004 | 2 Bytes | Baseboard Serial        =
+= 0x2006 | 2 Bytes | Baseboard Configuration =
 ==============================================
-= 0x1004 | 2 Bytes | Baseboard Configuration =
+= 0x2010 | 8 Bytes | PortEx0 64 bit ROM Addr =
+==============================================
+= 0x2018 | 8 Bytes | PortEx1 64 bit ROM Addr =
 ==============================================
-= 0x1010 | 4 Bytes | PortEx0 64 bit ROM Addr =
-==============================================
-= 0x1014 | 4 Bytes | PortEx1 64 bit ROM Addr =
-==============================================
+
+Space used is 32 bytes
+
--- a/xDotBridge/config.h	Wed Feb 22 15:39:40 2017 -0700
+++ b/xDotBridge/config.h	Mon Feb 27 08:06:36 2017 -0700
@@ -5,21 +5,19 @@
 #ifndef CONFIG_H_
 #define CONFIG_H_
 
-//#define __TEST__ 1 // Comment out for main application
+#define __TEST__ 1 // Comment out for main application
 
-// Manual test
-//#define __TEST_BBIO__ // Comment out for main application
+// Manual test.  Comment out for main application.  Or comment for individual test.
+//#define __TEST_BBIO__
+//#define __TEST_LRR__  // Comment out for main application
 //#define __TEST_PVD__  // Comment out for main application
-//#define __TEST_LRR__  // Comment out for main application
+
 // These define which wireless bridge you are generating code for
-#define BRIDGE_TX_BRUTE 0
-
 #define LED_FEEDBACK 1  // If 1 then LED is shown and 0 LED is not shown to conserve power
 
 // Make eclipse IDE happy by adding in macros which are typically added at compile time
 #ifndef TARGET_XDOT_L151CC
 #define TARGET_XDOT_L151CC
-// Note these seem to need to be added to eclipse indexer to make everyone happy
 #define DEVICE_SERIAL 1
 #define DEVICE_I2C 1
 #define DEVICE_INTERRUPTIN 1
--- a/xDotBridge/inc/BaseboardIO.h	Wed Feb 22 15:39:40 2017 -0700
+++ b/xDotBridge/inc/BaseboardIO.h	Mon Feb 27 08:06:36 2017 -0700
@@ -9,6 +9,42 @@
 #ifndef BASEBOARDIO_H_
 #define BASEBOARDIO_H_
 
+const uint16_t BASEBOARDIO_NVM_START_ADDR = 0x1000;
+const uint16_t BASEBOARDIO_NVM_SIZE = 32; // Bytes
+const uint16_t BASEBOARDIO_FLAG = 0x5A00;
+const uint16_t BASEBOARDIO_REV = 0x0000;
+
+class NvmBBIOObj {
+public:
+    NvmBBIOObj();
+    void setDefaults();
+    CmdResult fromBytes(uint8_t *data, uint8_t size);
+    CmdResult toBytes(uint8_t *data, uint8_t &size);
+
+    uint16_t getBaseboardIOFlag();
+    bool validBaseboardIOFlag();
+    uint16_t getBaseboardIORev();
+    bool validBaseboardIORev();
+
+    uint16_t getSerialNum();
+    void setSerialNum(uint16_t in);
+    uint32_t getBaseboardIOConfig();
+    void setBaseboardIOConfig(uint32_t in);
+    void getPortExpanderROM0(uint8_t *addr);
+    void setPortExpanderROM0(const uint8_t *addr);
+    void getPortExpanderROM1(uint8_t *addr);
+    void setPortExpanderROM1(const uint8_t *addr);
+    // Make public to save memory
+    uint8_t mPortExpanderROM0[8];
+    uint8_t mPortExpanderROM1[8];
+
+private:
+    uint16_t mBaseboardIOFlag;
+    uint16_t mBaseboardIORev;
+    uint16_t mSerialNum;
+    uint16_t mBaseboardIOConfig;
+};
+
 /**
  *  @class BaseboardIO
  *  @brief This class abstracts utilizing the IO mostly found on the baseboard
@@ -318,6 +354,7 @@
 
 private:
     // Initialized during constructor
+    NvmBBIOObj mNvmObj;
     OneWire mOWMaster;
     InterruptIn mCCIn;
     InterruptIn mTamper;
@@ -325,14 +362,9 @@
     DigitalOut mLed;
     DigitalOut mSwitchedIOCtrl;
 
-    // Initialized during init()
-//    void (*mCCInIntCallback) (void);
-//    void (*mTamperIntCallback) (void);
-//    void (*mPairBtnIntCallback) (void);
-
-    uint8_t mPortExpanderROM0[8];
+//    uint8_t mPortExpanderROM0[8]; // FIXME could probably get rid of
     uint8_t mPortExpanderVal0;
-    uint8_t mPortExpanderROM1[8];
+//    uint8_t mPortExpanderROM1[8];
     uint8_t mPortExpanderVal1;
 
     DS2408 *mPortEx0;
@@ -343,7 +375,6 @@
     }
     void disableSwitchedIO () {
         mSwitchedIOCtrl = 1; // deassertted since PMOS
-//        mSwitchedIOCtrl = 0; // FIXME
     }
 
     /**
@@ -405,4 +436,5 @@
     CmdResult openRelay();
 };
 
+
 #endif /* BASEBOARDIO_BASEBOARDIO_H_ */
--- a/xDotBridge/inc/CommProtocolPeerBrute.h	Wed Feb 22 15:39:40 2017 -0700
+++ b/xDotBridge/inc/CommProtocolPeerBrute.h	Mon Feb 27 08:06:36 2017 -0700
@@ -18,6 +18,33 @@
 static uint8_t pair_network_session_key[] = { 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04 };
 static uint8_t pair_data_session_key[] =    { 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04 };
 
+const uint16_t PROTOCOL_NVM_START_ADDR = 0x1000;
+const uint16_t PROTOCOL_NVM_SIZE = 12; // Bytes
+const uint16_t PROTOCOL_FLAG = 0x5A00;
+const uint16_t PROTOCOL_REV = 0x0000;
+class NvmProtocolObj {
+public:
+    NvmProtocolObj();
+    void setDefaults();
+    CmdResult fromBytes(uint8_t *data, uint8_t size);
+    CmdResult toBytes(uint8_t *data, uint8_t &size);
+
+    uint16_t getProtocolFlag();
+    bool validProtocolFlag();
+    uint16_t getProtocolRev();
+    bool validProtocolRev();
+
+    uint16_t getLogicalAddr();
+    void setLogicalAddr(uint16_t in);
+    uint32_t getLastMsgSeq();
+    void setLastMsgSeq(uint32_t in);
+private:
+    uint16_t mProtocolFlag;
+    uint16_t mProtocolRev;
+    uint16_t mLogicalAddr;
+    uint32_t mSeqNum;
+};
+
 /**
  *  @class PeerBruteCommProtocol
  *  @brief This class implements a peer-to-peer (P2P) brute force protocol.
@@ -63,6 +90,7 @@
      * @return Returns the result of all the commands
      */
     CmdResult init();
+    CmdResult dotDefaults();
 
     /**
      * @brief Sets weather this object is configured as a TX or RX
@@ -163,9 +191,10 @@
     uint32_t getULC();
 
 private:
-    uint8_t mNetworkAddr[4];
-    uint8_t mNetwork_session_key[16];
-    uint8_t mData_session_key[16];
+//    uint8_t mNetworkAddr[4];
+//    uint8_t mNetwork_session_key[16];
+//    uint8_t mData_session_key[16];
+    NvmProtocolObj mMemObj;
     bool mIsTx;
     uint32_t mPrevDownLinkCnt;
 
@@ -214,4 +243,5 @@
     CmdResult genEncypKeys();
 };
 
+
 #endif
--- a/xDotBridge/manualTest/testBaseboardIO/testBaseboardIO.cpp	Wed Feb 22 15:39:40 2017 -0700
+++ b/xDotBridge/manualTest/testBaseboardIO/testBaseboardIO.cpp	Mon Feb 27 08:06:36 2017 -0700
@@ -1,6 +1,6 @@
 #include "mbed.h"
 #include <string>
-#include "..\..\config.h"
+#include "../../config.h"
 #include "BaseboardIO.h"
 #include "MTSLog.h"
 
--- a/xDotBridge/manualTest/testLRRPins/testLRRPins.cpp	Wed Feb 22 15:39:40 2017 -0700
+++ b/xDotBridge/manualTest/testLRRPins/testLRRPins.cpp	Mon Feb 27 08:06:36 2017 -0700
@@ -1,6 +1,6 @@
 #include "mbed.h"
 #include <string>
-#include "..\..\config.h"
+#include "../../config.h"
 
 #ifdef __TEST_LRR__
 DigitalOut gpio0(GPIO0);
--- a/xDotBridge/manualTest/testPVD/testPVD.cpp	Wed Feb 22 15:39:40 2017 -0700
+++ b/xDotBridge/manualTest/testPVD/testPVD.cpp	Mon Feb 27 08:06:36 2017 -0700
@@ -1,6 +1,6 @@
 #include "mbed.h"
 #include "stm32l1xx_hal_pwr.h"
-#include "..\..\config.h"
+#include "../../config.h"
 
 #ifdef __TEST_PVD__
 
--- a/xDotBridge/src/BaseboardIO.cpp	Wed Feb 22 15:39:40 2017 -0700
+++ b/xDotBridge/src/BaseboardIO.cpp	Mon Feb 27 08:06:36 2017 -0700
@@ -7,6 +7,7 @@
 
 #include "BaseboardIO.h"
 #include "MTSLog.h"
+#include "dot_util.h" // FIXME just need the reference to dot somehow
 
 const float COIL_ON_TIME = 0.030; // 30 ms
 
@@ -46,12 +47,6 @@
       mLed(GPIO0),
       mSwitchedIOCtrl(I2C_SCL, 0)
 {
-//    mCCInIntCallback = NULL;
-//    mTamperIntCallback = NULL;
-//    mPairBtnIntCallback = NULL;
-
-    std::memset(mPortExpanderROM0, 0x00, 8);
-    std::memset(mPortExpanderROM1, 0x00, 8);
     mPortExpanderVal0 = 0x00;
     mPortExpanderVal1 = 0x00;
 
@@ -62,19 +57,43 @@
 {
     // Setup port expanders
     if (readInfoFromNVM() == cmdSuccess) {
-        // Values stored just read them foo
-        logError("Not implemented yet!!!");
+        logInfo("Stored ROM0 Addr: %02x:%02x:%02x:%02x:%02x:%02x:%02x%02x found.",
+                mNvmObj.mPortExpanderROM0[7],
+                mNvmObj.mPortExpanderROM0[6],
+                mNvmObj.mPortExpanderROM0[5],
+                mNvmObj.mPortExpanderROM0[4],
+                mNvmObj.mPortExpanderROM0[3],
+                mNvmObj.mPortExpanderROM0[2],
+                mNvmObj.mPortExpanderROM0[1],
+                mNvmObj.mPortExpanderROM0[0]);
+        logInfo("Stored ROM1 Addr: %02x:%02x:%02x:%02x:%02x:%02x:%02x%02x found.",
+                mNvmObj.mPortExpanderROM1[7],
+                mNvmObj.mPortExpanderROM1[6],
+                mNvmObj.mPortExpanderROM1[5],
+                mNvmObj.mPortExpanderROM1[4],
+                mNvmObj.mPortExpanderROM1[3],
+                mNvmObj.mPortExpanderROM1[2],
+                mNvmObj.mPortExpanderROM1[1],
+                mNvmObj.mPortExpanderROM1[0]);
+        logInfo("BaseboardIO parameters successfully loaded from NVM");
     }
     else { // EEPROM values not there or corrupt.  Should only happen in factory.
+        mNvmObj.setDefaults();
         // Find ROM address and test which one is which.  Requires user
         // switches to be in known state.
         if (identifyPortExpanders() != cmdSuccess) {
             logError("Error identifying port expanders");
             return cmdError;
         }
+        if (writeInfoToNVM() == cmdSuccess) {
+            logInfo("Baseboard config saved to NVM");
+        }
+        else {
+            logError("Baseboard config failed to save to NVM");
+        }
     }
-    mPortEx0 = new DS2408(&mOWMaster, mPortExpanderROM0);
-    mPortEx1 = new DS2408(&mOWMaster, mPortExpanderROM1);
+    mPortEx0 = new DS2408(&mOWMaster, mNvmObj.mPortExpanderROM0);
+    mPortEx1 = new DS2408(&mOWMaster, mNvmObj.mPortExpanderROM1);
 
     // Put relay in known state
     if (relayNormal() != cmdSuccess) {
@@ -277,13 +296,37 @@
 // private
 CmdResult BaseboardIO::readInfoFromNVM()
 {
-    logError("Not implemented yet!!!");
-    return cmdError;
+    bool nvmReadResult;
+    uint8_t *data = new uint8_t [BASEBOARDIO_NVM_SIZE];
+
+    nvmReadResult = dot->nvmRead(BASEBOARDIO_NVM_START_ADDR, data, BASEBOARDIO_NVM_SIZE);
+    if (!nvmReadResult) {
+        delete [] data;
+        return cmdError;
+    }
+    mNvmObj.fromBytes(data, BASEBOARDIO_NVM_SIZE);
+    delete [] data;
+    if (!mNvmObj.validBaseboardIOFlag()) {
+        logWarning("Invalid BaseboardIO Flag.  Using default values.");
+        return cmdError;
+    }
+    else if (!mNvmObj.validBaseboardIORev()) {
+        logWarning("Invalid BaseboardIO Rev.  Using default values.");
+        return cmdError;
+    }
+    else {
+        return cmdSuccess;
+    }
 }
 CmdResult BaseboardIO::writeInfoToNVM()
 {
-    logError("Not implemented yet!!!");
-    return cmdError;
+    uint8_t *data = new uint8_t [BASEBOARDIO_NVM_SIZE];
+    uint8_t size = BASEBOARDIO_NVM_SIZE;
+    mNvmObj.toBytes(data, size);
+    dot->nvmWrite(BASEBOARDIO_NVM_START_ADDR, data, BASEBOARDIO_NVM_SIZE);
+
+    delete [] data;
+    return cmdSuccess;
 }
 CmdResult BaseboardIO::identifyPortExpanders()
 {
@@ -308,10 +351,10 @@
             logInfo("ROM Addr: %02x:%02x:%02x:%02x:%02x:%02x:%02x%02x found.",
                     addr[7],addr[6],addr[5],addr[4],addr[3],addr[2],addr[1],addr[0]);
             if (i == 0) {
-                std::memcpy(mPortExpanderROM0, addr, sizeof(mPortExpanderROM0));
+                std::memcpy(mNvmObj.mPortExpanderROM0, addr, sizeof(mNvmObj.mPortExpanderROM0));
             }
             else if (i == 1) {
-                std::memcpy(mPortExpanderROM1, addr, sizeof(mPortExpanderROM1));
+                std::memcpy(mNvmObj.mPortExpanderROM1, addr, sizeof(mNvmObj.mPortExpanderROM1));
             }
             i++;
         }
@@ -331,8 +374,8 @@
     // If switches are set in factory default mode then port expander 1 should read 0xFF and
     // port expander 2 should read 0xF0.
 
-    mPortEx0 = new DS2408(&mOWMaster, mPortExpanderROM0);
-    mPortEx1 = new DS2408(&mOWMaster, mPortExpanderROM1);
+    mPortEx0 = new DS2408(&mOWMaster, mNvmObj.mPortExpanderROM0);
+    mPortEx1 = new DS2408(&mOWMaster, mNvmObj.mPortExpanderROM1);
 
 
     enableSwitchedIO();
@@ -356,14 +399,14 @@
         logInfo("ROMS Swap Not Needed.");
     }
     else if ((mPortExpanderVal0 == 0xF0) and (mPortExpanderVal1 == 0xFF)) { // Just need to swap
-        std::memcpy(addr, mPortExpanderROM0, sizeof(addr)); // Store Orig ROM0 -> addr
-        std::memcpy(mPortExpanderROM0, mPortExpanderROM1, sizeof(mPortExpanderROM0)); // Store Orig ROM1 -> ROM0
-        std::memcpy(mPortExpanderROM1, addr, sizeof(mPortExpanderROM1)); // Store Orig ROM0 (addr) -> ROM1
+        std::memcpy(addr, mNvmObj.mPortExpanderROM0, sizeof(addr)); // Store Orig ROM0 -> addr
+        std::memcpy(mNvmObj.mPortExpanderROM0, mNvmObj.mPortExpanderROM1, sizeof(mNvmObj.mPortExpanderROM0)); // Store Orig ROM1 -> ROM0
+        std::memcpy(mNvmObj.mPortExpanderROM1, addr, sizeof(mNvmObj.mPortExpanderROM1)); // Store Orig ROM0 (addr) -> ROM1
         logInfo("Swapped ROMS.");
     }
     else {
         logError("Error during port expander ID.  Port expanders not in "
-                "expected states.  Check user switches.  Got %02X and %02X",
+                "expected states (0xFF and 0xF0).  Check user switches.  Got %02X and %02X",
                 mPortExpanderVal0, mPortExpanderVal1);
         delete mPortEx0;
         delete mPortEx1;
@@ -432,3 +475,97 @@
 
     return cmdSuccess;
 }
+
+// NvmBBIOObj
+NvmBBIOObj::NvmBBIOObj()
+{
+    setDefaults();
+}
+void NvmBBIOObj::setDefaults()
+{
+    mBaseboardIOFlag = BASEBOARDIO_FLAG;
+    mBaseboardIORev  = BASEBOARDIO_REV;
+    mSerialNum = 0x0000;
+    mBaseboardIOConfig = 0x0000;
+    std::memset(mPortExpanderROM0, 0x00, 8);
+    std::memset(mPortExpanderROM1, 0x00, 8);
+}
+CmdResult NvmBBIOObj::fromBytes(uint8_t *data, uint8_t size)
+{
+    if (size != BASEBOARDIO_NVM_SIZE) {
+        return cmdError;
+    }
+
+    mBaseboardIOFlag    = *((uint16_t *) (data));
+    mBaseboardIORev     = *((uint16_t *) (data+2));
+    mSerialNum          = *((uint32_t *) (data+4));
+    mBaseboardIOConfig  = *((uint32_t *) (data+6));
+
+    std::memcpy(&mPortExpanderROM0, data+0x10, 8);
+    std::memcpy(&mPortExpanderROM1, data+0x18, 8);
+
+    return cmdSuccess;
+}
+CmdResult NvmBBIOObj::toBytes(uint8_t *data, uint8_t &size) {
+    // TODO check data size
+
+    *((uint16_t *) (data))   = mBaseboardIOFlag;
+    *((uint16_t *) (data+2)) = mBaseboardIORev;
+    *((uint32_t *) (data+4)) = mSerialNum;
+    *((uint32_t *) (data+6)) = mBaseboardIOConfig;
+
+    std::memcpy(data+0x10, &mPortExpanderROM0, 8);
+    std::memcpy(data+0x18, &mPortExpanderROM1, 8);
+
+    size = BASEBOARDIO_NVM_SIZE;
+
+    return cmdSuccess;
+}
+uint16_t NvmBBIOObj::getBaseboardIOFlag()
+{
+    return mBaseboardIOFlag;
+}
+bool NvmBBIOObj::validBaseboardIOFlag()
+{
+    return mBaseboardIOFlag == BASEBOARDIO_FLAG;
+}
+uint16_t NvmBBIOObj::getBaseboardIORev()
+{
+    return mBaseboardIORev;
+}
+bool NvmBBIOObj::validBaseboardIORev()
+{
+    return mBaseboardIORev == BASEBOARDIO_REV;
+}
+uint16_t NvmBBIOObj::getSerialNum()
+{
+    return mSerialNum;
+}
+void NvmBBIOObj::setSerialNum(uint16_t in)
+{
+    mSerialNum = in;
+}
+uint32_t NvmBBIOObj::getBaseboardIOConfig()
+{
+    return mBaseboardIOConfig;
+}
+void NvmBBIOObj::setBaseboardIOConfig(uint32_t in)
+{
+    mBaseboardIOConfig = in;
+}
+void NvmBBIOObj::getPortExpanderROM0(uint8_t *addr)
+{
+    std::memcpy(addr, &mPortExpanderROM0, 8);
+}
+void NvmBBIOObj::setPortExpanderROM0(const uint8_t *addr)
+{
+    std::memcpy(&mPortExpanderROM0, addr, 8);
+}
+void NvmBBIOObj::getPortExpanderROM1(uint8_t *addr)
+{
+    std::memcpy(addr, &mPortExpanderROM1, 8);
+}
+void NvmBBIOObj::setPortExpanderROM1(const uint8_t *addr)
+{
+    std::memcpy(&mPortExpanderROM1, addr, 8);
+}
--- a/xDotBridge/src/CommProtocolPeerBrute.cpp	Wed Feb 22 15:39:40 2017 -0700
+++ b/xDotBridge/src/CommProtocolPeerBrute.cpp	Mon Feb 27 08:06:36 2017 -0700
@@ -27,12 +27,23 @@
 
 CmdResult CommProtocolPeerBrute::init()
 {
+    // FIXME add NVM stuff
+    dotDefaults();
+
+}
+CmdResult CommProtocolPeerBrute::dotDefaults()
+{
+    // TODO add more error checking
+    logWarning("defaulting Dot configuration");
+    dot->resetConfig();
+
     // Common Configuration
     dot->setAesEncryption(true);  // Enable encryption
     dot->setTxWait(false);
     dot->setAck(0);  // Disable Ack
     dot->setClass("C"); // Set class C
     dot->setTxPower(TX_PWR);
+    dot->setPreserveSession(true); // TODO need to better handle counters
 
     // TODO break out in a utility function
     // update configuration if necessary
@@ -78,9 +89,7 @@
     // as long as both Dots are configured correctly, they should be able to communicate
 
     // FIXME just using pairing keys for now
-    wait(0.1);
     update_peer_to_peer_config(pair_network_address, pair_network_session_key, pair_data_session_key, tx_frequency, tx_datarate, tx_power);
-    wait(0.1);
     dot->saveConfig();
     return cmdSuccess;
 }
@@ -180,14 +189,39 @@
 
 CmdResult CommProtocolPeerBrute::readInfoFromNVM()
 {
-    logError("Not implemented yet!!!");
-    return cmdError;
+    // TODO store / retrieve network keys
+    bool nvmReadResult;
+    uint8_t *data = new uint8_t [PROTOCOL_NVM_SIZE];
+
+    nvmReadResult = dot->nvmRead(PROTOCOL_NVM_START_ADDR, data, PROTOCOL_NVM_SIZE);
+    if (!nvmReadResult) {
+        delete [] data;
+        return cmdError;
+    }
+    mMemObj.fromBytes(data, PROTOCOL_NVM_SIZE);
+    delete [] data;
+    if (!mMemObj.validProtocolFlag()) {
+        logWarning("Invalid Protocol Flag.  Using default values.");
+        mMemObj.setDefaults();
+        dotDefaults();
+    }
+    else if (!mMemObj.validProtocolRev()) {
+        logWarning("Invalid Protocol Rev.  Using default values.");
+        mMemObj.setDefaults();
+        dotDefaults();
+    }
+    return cmdSuccess;
 }
 
 CmdResult CommProtocolPeerBrute::writeInfoToNVM()
 {
-    logError("Not implemented yet!!!");
-    return cmdError;
+    uint8_t *data = new uint8_t [PROTOCOL_NVM_SIZE];
+    uint8_t size = PROTOCOL_NVM_SIZE;
+    mMemObj.toBytes(data, size);
+    dot->nvmWrite(PROTOCOL_NVM_START_ADDR, data, PROTOCOL_NVM_SIZE);
+
+    delete [] data;
+    return cmdSuccess;
 }
 
 CmdResult CommProtocolPeerBrute::resetCounters()
@@ -202,3 +236,69 @@
     logError("Not implemented yet!!!");
     return cmdError;
 }
+
+// NvmProtocolObj
+NvmProtocolObj::NvmProtocolObj()
+{
+    setDefaults();
+}
+void NvmProtocolObj::setDefaults()
+{
+    mProtocolFlag = PROTOCOL_FLAG;
+    mProtocolRev = PROTOCOL_REV;
+    mLogicalAddr = 0x00000000;
+    mSeqNum = 0x00000000;
+}
+CmdResult NvmProtocolObj::fromBytes(uint8_t *data, uint8_t size)
+{
+    if (size != PROTOCOL_NVM_SIZE) {
+        return cmdError;
+    }
+
+    mProtocolFlag   = *((uint16_t *) (data));
+    mProtocolRev    = *((uint16_t *) (data+2));
+    mLogicalAddr    = *((uint32_t *) (data+4));
+    mSeqNum         = *((uint32_t *) (data+6));
+
+    return cmdSuccess;
+}
+CmdResult NvmProtocolObj::toBytes(uint8_t *data, uint8_t &size) {
+    // TODO check data size
+
+    *((uint16_t *) (data))   = mProtocolFlag;
+    *((uint16_t *) (data+2)) = mProtocolRev;
+    *((uint32_t *) (data+4)) = mLogicalAddr;
+    *((uint32_t *) (data+6)) = mSeqNum;
+
+    size = PROTOCOL_NVM_SIZE;
+
+    return cmdSuccess;
+}
+uint16_t NvmProtocolObj::getProtocolFlag()
+{
+    return mProtocolFlag;
+}
+bool NvmProtocolObj::validProtocolFlag()
+{
+    return mProtocolFlag == PROTOCOL_FLAG;
+}
+uint16_t NvmProtocolObj::getProtocolRev()
+{
+    return mProtocolRev;
+}
+bool NvmProtocolObj::validProtocolRev()
+{
+    return mProtocolRev == PROTOCOL_REV;
+}
+uint16_t NvmProtocolObj::getLogicalAddr()
+{
+    return mLogicalAddr;
+}
+void NvmProtocolObj::setLogicalAddr(uint16_t in)
+{
+    mLogicalAddr= in;
+}
+uint32_t NvmProtocolObj::getLastMsgSeq()
+{
+    return mSeqNum;
+}
--- a/xDotBridge/src/main.cpp	Wed Feb 22 15:39:40 2017 -0700
+++ b/xDotBridge/src/main.cpp	Mon Feb 27 08:06:36 2017 -0700
@@ -46,10 +46,11 @@
     dot = mDot::getInstance();
 
     logInfo("mbed-os library version: %d", MBED_LIBRARY_VERSION);
+    logInfo(" libxDot-mbed5 library ID: %s", dot->getId().c_str());
 
     // start from a well-known state
-    logInfo("defaulting Dot configuration");
-    dot->resetConfig();
+//    logInfo("defaulting Dot configuration");
+//    dot->resetConfig();
 
     // make sure library logging is turned on
     dot->setLogLevel(mts::MTSLog::INFO_LEVEL);
@@ -206,6 +207,8 @@
         intCnt++;
     }
 
+    delete protocol;
+    delete bbio;
     return 0;
 }
 #endif