Index: /trunk/FACT++/src/ftmctrl.cc
===================================================================
--- /trunk/FACT++/src/ftmctrl.cc	(revision 11296)
+++ /trunk/FACT++/src/ftmctrl.cc	(revision 11297)
@@ -27,8 +27,20 @@
 class ConnectionFTM : public Connection
 {
+public:
+    enum States
+    {
+        // State Machine states
+        kDisconnected = 1,
+        kConnected,
+        kIdle,
+        kConfigured,  // Returned if idle and fBufStaticData==fStaticData
+        kTakingData,
+    };
+
+private:
     vector<uint16_t> fBuffer;
 
     bool fHasHeader;
-    int  fState;
+    FTM::States fState;
 
     bool fIsVerbose;
@@ -62,5 +74,5 @@
 
 protected:
-    map<uint16_t, int> fCounter;
+    map<uint16_t, uint32_t> fCounter;
 
     FTM::Header      fHeader;
@@ -69,4 +81,6 @@
     FTM::DynamicData fDynamicData;
     FTM::Error       fError;
+
+    FTM::StaticData  fBufStaticData;
 
     virtual void UpdateFirstHeader()
@@ -155,25 +169,25 @@
     }
 
-    bool CheckConsistency()
+    bool CheckConsistency(FTM::StaticData &data)
     {
         bool warn1 = false;
-        if (fStaticData.IsEnabled(FTM::StaticData::kPedestal) != (fStaticData.GetSequencePed()  >0) ||
-            fStaticData.IsEnabled(FTM::StaticData::kLPint)    != (fStaticData.GetSequenceLPint()>0) ||
-            fStaticData.IsEnabled(FTM::StaticData::kLPext)    != (fStaticData.GetSequenceLPext()>0))
+        if (data.IsEnabled(FTM::StaticData::kPedestal) != (data.GetSequencePed()  >0) ||
+            data.IsEnabled(FTM::StaticData::kLPint)    != (data.GetSequenceLPint()>0) ||
+            data.IsEnabled(FTM::StaticData::kLPext)    != (data.GetSequenceLPext()>0))
         {
             warn1 = true;
-            fStaticData.Enable(FTM::StaticData::kPedestal, fStaticData.GetSequencePed()>0);
-            fStaticData.Enable(FTM::StaticData::kLPint,    fStaticData.GetSequenceLPint()>0);
-            fStaticData.Enable(FTM::StaticData::kLPext,    fStaticData.GetSequenceLPext()>0);
+            data.Enable(FTM::StaticData::kPedestal, data.GetSequencePed()>0);
+            data.Enable(FTM::StaticData::kLPint,    data.GetSequenceLPint()>0);
+            data.Enable(FTM::StaticData::kLPext,    data.GetSequenceLPext()>0);
         }
 
         bool warn2 = false;
-        const uint16_t ref = fStaticData[0].fPrescaling;
+        const uint16_t ref = data[0].fPrescaling;
         for (int i=1; i<40; i++)
         {
-            if (fStaticData[i].fPrescaling != ref)
+            if (data[i].fPrescaling != ref)
             {
                 warn2 = true;
-                fStaticData[i].fPrescaling = ref;
+                data[i].fPrescaling = ref;
             }
         }
@@ -239,17 +253,4 @@
 
             // Convert FTM state into FtmCtrl state
-            switch (fHeader.fState)
-            {
-            case FTM::kFtmIdle:
-            case FTM::kFtmConfig:
-                fState = FTM::kIdle;
-                break;
-
-            case FTM::kFtmCalib:
-            case FTM::kFtmRunning:
-                fState = FTM::kTakingData;
-                break;
-            }
-
             if (++fCounter[FTM::kHeader]==1)
                 UpdateFirstHeader();
@@ -315,13 +316,16 @@
 
             case FTM::kStaticData:
-                fStaticData = fBuffer;
-
                 if (fCounter[FTM::kStaticData]==1)
-                    if (!CheckConsistency())
+                {
+                    // This check is only done at startup
+                    FTM::StaticData data = fBuffer;
+                    if (!CheckConsistency(data))
                     {
-                        CmdSendStatDat();
+                        CmdSendStatDat(data);
                         break;
                     }
-
+                }
+
+                fStaticData = fBuffer;
                 UpdateStaticData();
                 break;
@@ -365,5 +369,5 @@
         fInTimeout.cancel();
 
-        fHeader.clear();
+        //fHeader.clear();
         fHasHeader = false;
         fBuffer.resize(sizeof(FTM::Header)/2);
@@ -374,6 +378,6 @@
     void ConnectionEstablished()
     {
-        fState = FTM::kConnected;
         fCounter.clear();
+        fBufStaticData.clear();
 
         fHeader.clear();
@@ -483,5 +487,5 @@
 public:
     ConnectionFTM(ba::io_service& ioservice, MessageImp &imp) : Connection(ioservice, imp()),
-        fState(0), fIsVerbose(true), fIsDynamicOut(true), fIsHexOutput(true)
+        fIsVerbose(true), fIsDynamicOut(true), fIsHexOutput(true)
     {
         SetLogStream(&imp);
@@ -508,7 +512,9 @@
     }
 
-    void CmdSendStatDat()
-    {
-        PostCmd(fStaticData.HtoN(), FTM::kCmdWrite, FTM::kCmdStaticData);
+    void CmdSendStatDat(const FTM::StaticData &data)
+    {
+        fBufStaticData = data;
+
+        PostCmd(data.HtoN(), FTM::kCmdWrite, FTM::kCmdStaticData);
 
         // Request the changed configuration to ensure the
@@ -549,4 +555,6 @@
         const boost::array<uint16_t, 2> data = {{ addr, val }};
         PostCmd(data, FTM::kCmdWrite, FTM::kCmdRegister);
+
+        fBufStaticData.clear();
 
         // Request the changed configuration to ensure the
@@ -614,4 +622,5 @@
     }
 */
+
     bool LoadStaticData(string name)
     {
@@ -636,7 +645,5 @@
             return false;
 
-        fStaticData = data;
-
-        CmdSendStatDat();
+        CmdSendStatDat(data);
 
         return true;
@@ -665,9 +672,11 @@
             return false;
 
+        FTM::StaticData data = fStaticData;
+
         if (patch<0)
         {
             bool ident = true;
             for (int i=0; i<160; i++)
-                if (fStaticData[i/4].fDAC[patch%4] != value)
+                if (data[i/4].fDAC[patch%4] != value)
                 {
                     ident = false;
@@ -679,16 +688,16 @@
 
             for (int i=0; i<160; i++)
-                fStaticData[i/4].fDAC[i%4] = value;
+                data[i/4].fDAC[i%4] = value;
         }
         else
         {
-            if (fStaticData[patch/4].fDAC[patch%4] == value)
+            if (data[patch/4].fDAC[patch%4] == value)
                 return true;
 
-            fStaticData[patch/4].fDAC[patch%4] = value;
+            data[patch/4].fDAC[patch%4] = value;
         }
 
         // Maybe move to a "COMMIT" command?
-        CmdSendStatDat();
+        CmdSendStatDat(data);
 
         return true;
@@ -700,7 +709,9 @@
             return false;
 
+        FTM::StaticData data = fStaticData;
+
         bool ident = true;
         for (int i=0; i<40; i++)
-            if (fStaticData[i].fPrescaling != value)
+            if (data[i].fPrescaling != value)
             {
                 ident = false;
@@ -712,8 +723,8 @@
 
         for (int i=0; i<40; i++)
-            fStaticData[i].fPrescaling = value;
+            data[i].fPrescaling = value;
 
         // Maybe move to a "COMMIT" command?
-        CmdSendStatDat();
+        CmdSendStatDat(data);
 
         return true;
@@ -725,22 +736,24 @@
             return false;
 
+        FTM::StaticData data = fStaticData;
+
         if (board<0)
         {
             if (enable)
-                fStaticData.EnableAllFTU();
+                data.EnableAllFTU();
             else
-                fStaticData.DisableAllFTU();
+                data.DisableAllFTU();
         }
         else
         {
             if (enable)
-                fStaticData.EnableFTU(board);
+                data.EnableFTU(board);
             else
-                fStaticData.DisableFTU(board);
+                data.DisableFTU(board);
 
         }
 
         // Maybe move to a "COMMIT" command?
-        CmdSendStatDat();
+        CmdSendStatDat(data);
 
         return true;
@@ -752,8 +765,10 @@
             return false;
 
-        fStaticData.ToggleFTU(board);
+        FTM::StaticData data = fStaticData;
+
+        data.ToggleFTU(board);
 
         // Maybe move to a "COMMIT" command?
-        CmdSendStatDat();
+        CmdSendStatDat(data);
 
         return true;
@@ -768,7 +783,11 @@
             return true;
 
+        FTM::StaticData data = fStaticData;
+
+        dest = reinterpret_cast<uint16_t*>(&data) + (dest - reinterpret_cast<uint16_t*>(&fStaticData));
+
         *dest = val;
 
-        CmdSendStatDat();
+        CmdSendStatDat(data);
 
         return true;
@@ -801,16 +820,14 @@
     void Enable(FTM::StaticData::GeneralSettings type, bool enable)
     {
-        if (fStaticData.IsEnabled(type)!=enable)
-        {
-            fStaticData.Enable(type, enable);
-            CmdSendStatDat();
-        }
+        //if (fStaticData.IsEnabled(type)==enable)
+        //    return;
+
+        FTM::StaticData data = fStaticData;
+        data.Enable(type, enable);
+        CmdSendStatDat(data);
     }
 
     bool SetTriggerSeq(const uint16_t d[3])
     {
-        const uint16_t oldset = fStaticData.fGeneralSettings;
-        const uint16_t oldseq = fStaticData.fTriggerSequence;
-
 	if (d[0]>FTM::StaticData::kMaxSequence ||
             d[1]>FTM::StaticData::kMaxSequence ||
@@ -818,13 +835,18 @@
             return false;
 
-        fStaticData.Enable(FTM::StaticData::kPedestal, d[0]>0);
-        fStaticData.Enable(FTM::StaticData::kLPext,    d[1]>0);
-        fStaticData.Enable(FTM::StaticData::kLPint,    d[2]>0);
-
-        fStaticData.fTriggerSequence =
+        FTM::StaticData data = fStaticData;
+
+        data.Enable(FTM::StaticData::kPedestal, d[0]>0);
+        data.Enable(FTM::StaticData::kLPext,    d[1]>0);
+        data.Enable(FTM::StaticData::kLPint,    d[2]>0);
+
+        data.fTriggerSequence =
             (uint16_t(d[0])<<10) | (uint16_t(d[2])<<5) | uint16_t(d[1]);
 
-        if (oldseq!=fStaticData.fTriggerSequence || oldset!=fStaticData.fGeneralSettings)
-            CmdSendStatDat();
+        //if (fStaticData.fTriggerSeq     !=data.fTriggerSequence ||
+        //    fStaticData.fGeneralSettings!=data.fGeneralSettings)
+        //    CmdSendStatDat(data);
+
+        CmdSendStatDat(data);
 
         return true;
@@ -839,7 +861,9 @@
             return true;
 
-        fStaticData.fMultiplicityPhysics = n;
-
-        CmdSendStatDat();
+        FTM::StaticData data = fStaticData;
+
+        data.fMultiplicityPhysics = n;
+
+        CmdSendStatDat(data);
 
         return true;
@@ -854,7 +878,9 @@
             return true;
 
-        fStaticData.fWindowPhysics = win;
-
-        CmdSendStatDat();
+        FTM::StaticData data = fStaticData;
+
+        data.fWindowPhysics = win;
+
+        CmdSendStatDat(data);
 
         return true;
@@ -869,7 +895,9 @@
             return true;
 
-        fStaticData.fMultiplicityCalib = n;
-
-        CmdSendStatDat();
+        FTM::StaticData data = fStaticData;
+
+        data.fMultiplicityCalib = n;
+
+        CmdSendStatDat(data);
 
         return true;
@@ -884,7 +912,9 @@
             return true;
 
-        fStaticData.fWindowCalib = win;
-
-        CmdSendStatDat();
+        FTM::StaticData data = fStaticData;
+
+        data.fWindowCalib = win;
+
+        CmdSendStatDat(data);
 
         return true;
@@ -893,4 +923,6 @@
     bool SetClockRegister(const uint64_t reg[])
     {
+        FTM::StaticData data = fStaticData;
+
         for (int i=0; i<8; i++)
         {
@@ -898,8 +930,8 @@
                 return false;
 
-            fStaticData.fClockConditioner[i] = reg[i];
-        }
-
-        CmdSendStatDat();
+            data.fClockConditioner[i] = reg[i];
+        }
+
+        CmdSendStatDat(data);
 
         return true;
@@ -911,11 +943,13 @@
             return false;
 
+        FTM::StaticData data = fStaticData;
+
         if (idx==-1)
             for (int i=0; i<=FTM::StaticData::kMaxPixelIdx; i++)
-                fStaticData.EnablePixel(i, enable);
+                data.EnablePixel(i, enable);
         else
-            fStaticData.EnablePixel(idx, enable);
-
-        CmdSendStatDat();
+            data.EnablePixel(idx, enable);
+
+        CmdSendStatDat(data);
 
         return true;
@@ -927,8 +961,10 @@
             return false;
 
+        FTM::StaticData data = fStaticData;
+
         for (int i=0; i<=FTM::StaticData::kMaxPixelIdx; i++)
-            fStaticData.EnablePixel(i, i==idx);
-
-        CmdSendStatDat();
+            data.EnablePixel(i, i==idx);
+
+        CmdSendStatDat(data);
 
         return true;
@@ -940,8 +976,10 @@
             return false;
 
+        FTM::StaticData data = fStaticData;
+
         for (int i=0; i<=FTM::StaticData::kMaxPixelIdx; i++)
-            fStaticData.EnablePixel(i, i/9==idx);
-
-        CmdSendStatDat();
+            data.EnablePixel(i, i/9==idx);
+
+        CmdSendStatDat(data);
 
         return true;
@@ -953,12 +991,38 @@
             return false;
 
-        fStaticData.EnablePixel(idx, !fStaticData.Enabled(idx));
-
-        CmdSendStatDat();
+        FTM::StaticData data = fStaticData;
+
+        data.EnablePixel(idx, !fStaticData.Enabled(idx));
+
+        CmdSendStatDat(data);
 
         return true;
     }
 
-    int GetState() const { return IsConnected() ? fState : (int)FTM::kDisconnected; }
+    States GetState() const
+    {
+        if (!IsConnected())
+            return kDisconnected;
+
+        switch (fHeader.fState)
+        {
+        case FTM::kFtmUndefined:
+            return kConnected;
+
+        case FTM::kFtmRunning:
+        case FTM::kFtmCalib:
+            return kTakingData;
+
+        case FTM::kFtmIdle:
+        case FTM::kFtmConfig:
+            return fStaticData == fBufStaticData ? kConfigured : kIdle;
+        }
+
+        throw runtime_error("ConnectionFTM::GetState - Impossible code reached.");
+    }
+
+    int GetCounter(FTM::Types type) { return fCounter[type]; }
+
+    const FTM::StaticData &GetStaticData() const { return fStaticData; }
 };
 
@@ -1084,14 +1148,4 @@
     S fFTM;
 
-    enum states_t
-    {
-        kStateDisconnected = FTM::kDisconnected,
-        kStateConnected    = FTM::kConnected,
-        kStateIdle         = FTM::kIdle,
-        kStateTakingData   = FTM::kTakingData,
-
-        kCmdTest
-    };
-
     bool CheckEventSize(size_t has, const char *name, size_t size)
     {
@@ -1550,10 +1604,41 @@
         switch (evt.GetTargetState())
         {
-        case kStateDisconnected:
-        case kStateConnected:
+        case kDisconnected:
+        case kConnected:
         }
 
         return T::kSM_FatalError;
     }*/
+
+    int64_t fCounterReg;
+    int64_t fCounterStat;
+
+    typedef map<string, FTM::StaticData> Configs;
+    Configs fConfigs;
+    Configs::const_iterator fTargetConfig;
+
+    int ConfigureFTM(const EventImp &evt)
+    {
+        const string name = evt.GetText();
+
+        fTargetConfig = fConfigs.find(name);
+        if (fTargetConfig==fConfigs.end())
+        {
+            T::Error("Configuration '"+name+"' not found.");
+            return T::GetCurrentState();
+        }
+
+        T::Message("Starting configuration for '"+name+"'");
+
+        fCounterReg = fFTM.GetCounter(FTM::kRegister);
+        fFTM.CmdStopRun();
+
+        return FTM::kConfiguring1;
+    }
+
+    int ResetConfig(const EventImp &)
+    {
+        return fFTM.GetState();
+    }
 
     int Execute()
@@ -1566,5 +1651,72 @@
         poll_one();
 
-        return fFTM.GetState();
+        // If FTM is neither in data taking nor idle,
+        // leave configuration state
+        switch (fFTM.GetState())
+        {
+        case ConnectionFTM::kDisconnected: return FTM::kDisconnected;
+        case ConnectionFTM::kConnected:    return FTM::kConnected;
+        case ConnectionFTM::kTakingData:   return FTM::kTakingData;
+        default:
+            break;
+        }
+
+        switch (T::GetCurrentState())
+        {
+        case FTM::kConfiguring1:
+            // If FTM has received an anwer to the stop_run command
+            // the counter for the registers has been increased
+            if (fFTM.GetCounter(FTM::kRegister)<=fCounterReg)
+                break;
+
+            // If now the state is not idle as expected this means we had
+            // an error (maybe old events waiting in the queue)
+            if (fFTM.GetState()!=ConnectionFTM::kIdle &&
+                fFTM.GetState()!=ConnectionFTM::kConfigured)
+                return FTM::kConfigError1;
+
+            fCounterStat = fFTM.GetCounter(FTM::kStaticData);
+
+            T::Message("Trigger successfully disabled... sending new configuration.");
+
+            fFTM.CmdSendStatDat(fTargetConfig->second);
+
+            // Next state is: wait for the answer to our configuration
+            return FTM::kConfiguring2;
+
+        case FTM::kConfiguring2:
+        case FTM::kConfigured:
+            // If FTM has received an anwer to the stop_run command
+            // the counter for the registers has been increased
+            if (fFTM.GetCounter(FTM::kStaticData)<=fCounterStat)
+                break;
+
+            // If now the configuration is not what we expected
+            // we had an error (maybe old events waiting in the queue?)
+            // ======================
+            if (fFTM.GetState()!=ConnectionFTM::kConfigured)
+                return FTM::kConfigError2;
+            // ======================
+
+            // Check configuration again when a new static data block
+            // will be received
+            fCounterStat = fFTM.GetCounter(FTM::kStaticData);
+
+            T::Message("Sending new configuration was successfull.");
+
+            // Next state is: wait for the answer to our configuration
+            return FTM::kConfigured;
+
+        default:
+            switch (fFTM.GetState())
+            {
+            case ConnectionFTM::kIdle:         return FTM::kIdle;
+            case ConnectionFTM::kConfigured:   return FTM::kIdle;
+            default:
+                throw runtime_error("StateMachienFTM - Execute() - Inavlid state.");
+            }
+        }
+
+        return T::GetCurrentState();
     }
 
@@ -1582,39 +1734,49 @@
 
         // State names
-        AddStateName(kStateDisconnected, "Disconnected",
-                     "FTM board not connected via ethernet.");
-
-        AddStateName(kStateConnected, "Connected",
-                     "Ethernet connection to FTM established (no state received yet).");
-
-        AddStateName(kStateIdle, "Idle",
-                     "Ethernet connection to FTM established, FTM in idle state.");
-
-        AddStateName(kStateTakingData, "TakingData",
-                     "Ethernet connection to FTM established, FTM is in taking data state.");
+        T::AddStateName(FTM::kDisconnected, "Disconnected",
+                        "FTM board not connected via ethernet.");
+
+        T::AddStateName(FTM::kConnected, "Connected",
+                        "Ethernet connection to FTM established (no state received yet).");
+
+        T::AddStateName(FTM::kIdle, "Idle",
+                        "Ethernet connection to FTM established, FTM in idle state.");
+
+        T::AddStateName(FTM::kConfiguring1, "Configuring1",
+                        "Command to diable run sent... waiting for response.");
+        T::AddStateName(FTM::kConfiguring2, "Configuring2",
+                        "New configuration sent... waiting for response.");
+        T::AddStateName(FTM::kConfigured,   "Configured",
+                        "Received answer identical with target configuration.");
+
+        T::AddStateName(FTM::kTakingData, "TakingData",
+                        "Ethernet connection to FTM established, FTM is in taking data state.");
+
+        T::AddStateName(FTM::kConfigError1, "ErrorInConfig1", "");
+        T::AddStateName(FTM::kConfigError2, "ErrorInConfig2", "");
 
         // FTM Commands
-        AddEvent("TOGGLE_LED", kStateIdle)
+        T::AddEvent("TOGGLE_LED", FTM::kIdle)
             (Wrapper(boost::bind(&ConnectionFTM::CmdToggleLed, &fFTM)))
             ("toggle led");
 
-        AddEvent("PING", kStateIdle)
+        T::AddEvent("PING", FTM::kIdle)
             (Wrapper(boost::bind(&ConnectionFTM::CmdPing, &fFTM)))
             ("send ping");
 
-        AddEvent("REQUEST_DYNAMIC_DATA", kStateIdle)
+        T::AddEvent("REQUEST_DYNAMIC_DATA", FTM::kIdle)
             (Wrapper(boost::bind(&ConnectionFTM::CmdReqDynDat, &fFTM)))
             ("request transmission of dynamic data block");
 
-        AddEvent("REQUEST_STATIC_DATA", kStateIdle)
+        T::AddEvent("REQUEST_STATIC_DATA", FTM::kIdle)
             (Wrapper(boost::bind(&ConnectionFTM::CmdReqStatDat, &fFTM)))
             ("request transmission of static data from FTM to memory");
 
-        AddEvent("GET_REGISTER", "I", kStateIdle)
+        T::AddEvent("GET_REGISTER", "I", FTM::kIdle)
             (boost::bind(&StateMachineFTM::GetRegister, this, _1))
             ("read register from address addr"
             "|addr[short]:Address of register");
 
-        AddEvent("SET_REGISTER", "I:2", kStateIdle)
+        T::AddEvent("SET_REGISTER", "I:2", FTM::kIdle)
             (boost::bind(&StateMachineFTM::SetRegister, this, _1))
             ("set register to value"
@@ -1622,22 +1784,22 @@
             "|val[short]:Value to be set");
 
-        AddEvent("START_RUN", kStateIdle)
+        T::AddEvent("START_RUN", FTM::kIdle, FTM::kConfigured)
             (Wrapper(boost::bind(&ConnectionFTM::CmdStartRun, &fFTM)))
             ("start a run (start distributing triggers)");
 
-        AddEvent("STOP_RUN", kStateTakingData)
+        T::AddEvent("STOP_RUN", FTM::kTakingData)
             (Wrapper(boost::bind(&ConnectionFTM::CmdStopRun, &fFTM)))
             ("stop a run (stop distributing triggers)");
 
-        AddEvent("TAKE_N_EVENTS", "I", kStateIdle)
+        T::AddEvent("TAKE_N_EVENTS", "I", FTM::kIdle)
             (boost::bind(&StateMachineFTM::TakeNevents, this, _1))
             ("take n events (distribute n triggers)|number[int]:Number of events to be taken");
 
-        AddEvent("DISABLE_REPORTS", "B", kStateIdle)
+        T::AddEvent("DISABLE_REPORTS", "B", FTM::kIdle)
             (boost::bind(&StateMachineFTM::DisableReports, this, _1))
             ("disable sending rate reports"
              "|status[bool]:disable or enable that the FTM sends rate reports (yes/no)");
 
-        AddEvent("SET_THRESHOLD", "I:2", kStateIdle)
+        T::AddEvent("SET_THRESHOLD", "I:2", FTM::kIdle)
             (boost::bind(&StateMachineFTM::SetThreshold, this, _1))
             ("Set the comparator threshold"
@@ -1645,10 +1807,10 @@
              "|Threshold[counts]:Threshold to be set in binary counts");
 
-        AddEvent("SET_PRESCALING", "I:1", kStateIdle)
+        T::AddEvent("SET_PRESCALING", "I:1", FTM::kIdle)
             (boost::bind(&StateMachineFTM::SetPrescaling, this, _1))
             (""
              "|[]:");
 
-        AddEvent("ENABLE_FTU", "I:1;B:1", kStateIdle)
+        T::AddEvent("ENABLE_FTU", "I:1;B:1", FTM::kIdle)
             (boost::bind(&StateMachineFTM::EnableFTU, this, _1))
             ("Enable or disable FTU"
@@ -1656,50 +1818,50 @@
              "|Enable[bool]:Whether FTU should be enabled or disabled (yes/no)");
 
-        AddEvent("DISABLE_PIXEL", "S:1", kStateIdle)
+        T::AddEvent("DISABLE_PIXEL", "S:1", FTM::kIdle)
             (boost::bind(&StateMachineFTM::EnablePixel, this, _1, false))
             ("(-1 or all)");
 
-        AddEvent("ENABLE_PIXEL", "S:1", kStateIdle)
+        T::AddEvent("ENABLE_PIXEL", "S:1", FTM::kIdle)
             (boost::bind(&StateMachineFTM::EnablePixel, this, _1, true))
             ("(-1 or all)");
 
-        AddEvent("DISABLE_ALL_PIXELS_EXCEPT", "S:1", kStateIdle)
+        T::AddEvent("DISABLE_ALL_PIXELS_EXCEPT", "S:1", FTM::kIdle)
             (boost::bind(&StateMachineFTM::DisableAllPixelsExcept, this, _1))
             ("");
 
-        AddEvent("DISABLE_ALL_PATCHES_EXCEPT", "S:1", kStateIdle)
+        T::AddEvent("DISABLE_ALL_PATCHES_EXCEPT", "S:1", FTM::kIdle)
             (boost::bind(&StateMachineFTM::DisableAllPatchesExcept, this, _1))
             ("");
 
-        AddEvent("TOGGLE_PIXEL", "S:1", kStateIdle)
+        T::AddEvent("TOGGLE_PIXEL", "S:1", FTM::kIdle)
             (boost::bind(&StateMachineFTM::TogglePixel, this, _1))
             ("");
 
-        AddEvent("TOGGLE_FTU", "I:1", kStateIdle)
+        T::AddEvent("TOGGLE_FTU", "I:1", FTM::kIdle)
             (boost::bind(&StateMachineFTM::ToggleFTU, this, _1))
             ("Toggle status of FTU (this is mainly meant to be used in the GUI)"
              "|Board[idx]:Index of the board (0-39)");
 
-        AddEvent("SET_TRIGGER_INTERVAL", "I:1", kStateIdle)
+        T::AddEvent("SET_TRIGGER_INTERVAL", "I:1", FTM::kIdle)
             (boost::bind(&StateMachineFTM::SetTriggerInterval, this, _1))
             ("Sets the trigger interval which is the distance between two consecutive artificial triggers."
              "|interval[int]:The applied trigger interval is: interval*4ns+8ns");
 
-        AddEvent("SET_TRIGGER_DELAY", "I:1", kStateIdle)
+        T::AddEvent("SET_TRIGGER_DELAY", "I:1", FTM::kIdle)
             (boost::bind(&StateMachineFTM::SetTriggerDelay, this, _1))
             (""
              "|delay[int]:The applied trigger delay is: delay*4ns+8ns");
 
-        AddEvent("SET_TIME_MARKER_DELAY", "I:1", kStateIdle)
+        T::AddEvent("SET_TIME_MARKER_DELAY", "I:1", FTM::kIdle)
             (boost::bind(&StateMachineFTM::SetTimeMarkerDelay, this, _1))
             (""
             "|delay[int]:The applied time marker delay is: delay*4ns+8ns");
 
-        AddEvent("SET_DEAD_TIME", "I:1", kStateIdle)
+        T::AddEvent("SET_DEAD_TIME", "I:1", FTM::kIdle)
             (boost::bind(&StateMachineFTM::SetDeadTime, this, _1))
             (""
             "|dead_time[int]:The applied dead time is: dead_time*4ns+8ns");
 
-        AddEvent("ENABLE_TRIGGER", "B:1", kStateIdle)
+        T::AddEvent("ENABLE_TRIGGER", "B:1", FTM::kIdle)
             (boost::bind(&StateMachineFTM::Enable, this, _1, FTM::StaticData::kTrigger))
             ("Switch on the physics trigger"
@@ -1707,5 +1869,5 @@
 
         // FIXME: Switch on/off depending on sequence
-        AddEvent("ENABLE_EXT1", "B:1", kStateIdle)
+        T::AddEvent("ENABLE_EXT1", "B:1", FTM::kIdle)
             (boost::bind(&StateMachineFTM::Enable, this, _1, FTM::StaticData::kExt1))
             ("Switch on the triggers through the first external line"
@@ -1713,20 +1875,20 @@
 
         // FIXME: Switch on/off depending on sequence
-        AddEvent("ENABLE_EXT2", "B:1", kStateIdle)
+        T::AddEvent("ENABLE_EXT2", "B:1", FTM::kIdle)
             (boost::bind(&StateMachineFTM::Enable, this, _1, FTM::StaticData::kExt2))
             ("Switch on the triggers through the second external line"
              "|Enable[bool]:Enable ext2 trigger (yes/no)");
 
-        AddEvent("ENABLE_VETO", "B:1", kStateIdle)
+        T::AddEvent("ENABLE_VETO", "B:1", FTM::kIdle)
             (boost::bind(&StateMachineFTM::Enable, this, _1, FTM::StaticData::kVeto))
             ("Enable veto line"
              "|Enable[bool]:Enable veto (yes/no)");
 
-        AddEvent("ENABLE_CLOCK_CONDITIONER", "B:1", kStateIdle)
+        T::AddEvent("ENABLE_CLOCK_CONDITIONER", "B:1", FTM::kIdle)
             (boost::bind(&StateMachineFTM::Enable, this, _1, FTM::StaticData::kClockConditioner))
             ("Enable clock conidtioner output in favor of time marker output"
              "|Enable[bool]:Enable clock conditioner (yes/no)");
 
-        AddEvent("SET_TRIGGER_SEQUENCE", "S:3", kStateIdle)
+        T::AddEvent("SET_TRIGGER_SEQUENCE", "S:3", FTM::kIdle)
             (boost::bind(&StateMachineFTM::SetTriggerSeq, this, _1))
             ("Setup the sequence of artificial triggers produced by the FTM"
@@ -1735,38 +1897,46 @@
              "|LPint[short]:number of triggers of the internal light pulser");
 
-        AddEvent("SET_TRIGGER_MULTIPLICITY", "S:1", kStateIdle)
+        T::AddEvent("SET_TRIGGER_MULTIPLICITY", "S:1", FTM::kIdle)
             (boost::bind(&StateMachineFTM::SetTriggerMultiplicity, this, _1))
             ("Setup the Multiplicity condition for physcis triggers"
              "|N[int]:Number of requirered coincident triggers from sum-patches (1-40)");
 
-        AddEvent("SET_TRIGGER_WINDOW", "S:1", kStateIdle)
+        T::AddEvent("SET_TRIGGER_WINDOW", "S:1", FTM::kIdle)
             (boost::bind(&StateMachineFTM::SetTriggerWindow, this, _1))
             ("");
 
-        AddEvent("SET_CALIBRATION_MULTIPLICITY", "S:1", kStateIdle)
+        T::AddEvent("SET_CALIBRATION_MULTIPLICITY", "S:1", FTM::kIdle)
             (boost::bind(&StateMachineFTM::SetCalibMultiplicity, this, _1))
             ("Setup the Multiplicity condition for artificial (calibration) triggers"
              "|N[int]:Number of requirered coincident triggers from sum-patches (1-40)");
 
-        AddEvent("SET_CALIBRATION_WINDOW", "S:1", kStateIdle)
+        T::AddEvent("SET_CALIBRATION_WINDOW", "S:1", FTM::kIdle)
             (boost::bind(&StateMachineFTM::SetCalibWindow, this, _1))
             ("");
 
-        AddEvent("SET_CLOCK_FREQUENCY", "I:1", kStateIdle)
+        T::AddEvent("SET_CLOCK_FREQUENCY", "I:1", FTM::kIdle)
             (boost::bind(&StateMachineFTM::SetClockFrequency, this, _1))
             ("");
 
-        AddEvent("SET_CLOCK_REGISTER", "X:8", kStateIdle)
+        T::AddEvent("SET_CLOCK_REGISTER", "X:8", FTM::kIdle)
             (boost::bind(&StateMachineFTM::SetClockRegister, this, _1))
             ("");
 
-
-
-        AddEvent("RESET_CRATE", "S:1", kStateIdle)
+        T::AddEvent("CONFIGURE", "C", FTM::kIdle, FTM::kTakingData)
+            (boost::bind(&StateMachineFTM::ConfigureFTM, this, _1))
+            ("");
+
+        T::AddEvent("RESET_CONFIGURE", FTM::kConfiguring1, FTM::kConfiguring2, FTM::kConfigured, FTM::kConfigError1, FTM::kConfigError2)
+            (boost::bind(&StateMachineFTM::ResetConfig, this, _1))
+            ("");
+
+
+
+        T::AddEvent("RESET_CRATE", "S:1", FTM::kIdle)
             (boost::bind(&StateMachineFTM::ResetCrate, this, _1))
             ("Reset one of the crates 0-3"
              "|crate[short]:Crate number to be reseted (0-3)");
 
-        AddEvent("RESET_CAMERA", kStateIdle)
+        T::AddEvent("RESET_CAMERA", FTM::kIdle)
             (Wrapper(boost::bind(&ConnectionFTM::CmdResetCamera, &fFTM)))
             ("Reset all crates. The commands are sent in the order 0,1,2,3");
@@ -1774,10 +1944,10 @@
 
         // Load/save static data block
-        T::AddEvent("SAVE", "C", kStateIdle)
+        T::AddEvent("SAVE", "C", FTM::kIdle)
             (boost::bind(&StateMachineFTM::SaveStaticData, this, _1))
             ("Saves the static data (FTM configuration) from memory to a file"
              "|filename[string]:Filename (can include a path), .bin is automatically added");
 
-        T::AddEvent("LOAD", "C", kStateIdle)
+        T::AddEvent("LOAD", "C", FTM::kIdle)
             (boost::bind(&StateMachineFTM::LoadStaticData, this, _1))
             ("Loads the static data (FTM configuration) from a file into memory and sends it to the FTM"
@@ -1804,9 +1974,9 @@
 
         // Conenction commands
-        AddEvent("DISCONNECT", kStateConnected, kStateIdle)
+        T::AddEvent("DISCONNECT", FTM::kConnected, FTM::kIdle)
             (boost::bind(&StateMachineFTM::Disconnect, this))
             ("disconnect from ethernet");
 
-        AddEvent("RECONNECT", "O", kStateDisconnected, kStateConnected, kStateIdle)
+        T::AddEvent("RECONNECT", "O", FTM::kDisconnected, FTM::kConnected, FTM::kIdle, FTM::kConfigured)
             (boost::bind(&StateMachineFTM::Reconnect, this, _1))
             ("(Re)connect ethernet connection to FTM, a new address can be given"
@@ -1830,4 +2000,7 @@
 
 //        fFTM.SetDefaultSetup(conf.Get<string>("default-setup"));
+
+        fConfigs["test"] = FTM::StaticData();
+
 
         return -1;
