From df19dd48ad606b8957706583c488238cce95091f Mon Sep 17 00:00:00 2001
From: Ruud Overeem <overeem@astron.nl>
Date: Thu, 10 Jan 2008 09:03:29 +0000
Subject: [PATCH] Bug 1141: Updated the handle to void*. Note: void* can not be
 shown in PVSS so the beamID cannot be shown anymore. Since the beamID
 represents an address in memory this does not make sense anyway. The BeamID
 is still logged in the logfile so when there are trouble one should check
 those.

---
 .../StationCU/src/BeamControl/BeamControl.cc  |   6 +-
 .../StationCU/src/BeamControl/BeamControl.h   |   2 +-
 .../CalibrationControl/CalibrationControl.cc  |   2 +-
 .../DigitalBoardControl/DigitalBoardControl.h |   2 +-
 .../src/HardwareMonitor/RCUConstants.h        |   4 +-
 .../src/HardwareMonitor/RSPMonitor.cc         |  63 ++++---
 .../StationPermDatapointDefs.h                |   1 +
 .../src/HardwareMonitor/TBBMonitor.cc         | 166 +++++++++++++-----
 .../StationCU/src/StationControl/ActiveObs.cc |   9 +-
 .../src/StationControl/StationControl.cc      |   4 +-
 10 files changed, 182 insertions(+), 77 deletions(-)

diff --git a/MAC/APL/StationCU/src/BeamControl/BeamControl.cc b/MAC/APL/StationCU/src/BeamControl/BeamControl.cc
index d11bfe1c651..16b9931bc87 100644
--- a/MAC/APL/StationCU/src/BeamControl/BeamControl.cc
+++ b/MAC/APL/StationCU/src/BeamControl/BeamControl.cc
@@ -218,7 +218,7 @@ GCFEvent::TResult BeamControl::initial_state(GCFEvent& event,
 			itsPropertySet->setValue(PN_BC_ANGLE2,		GCFPVString(""));
 			itsPropertySet->setValue(PN_BC_ANGLETIMES,	GCFPVString(""));
 			itsPropertySet->setValue(PN_BC_SUBARRAY,	GCFPVString(""));
-			itsPropertySet->setValue(PN_BC_BEAMID,		GCFPVInteger(0));
+//			itsPropertySet->setValue(PN_BC_BEAMID,		GCFPVInteger(0));
 		  
 			// Start ParentControl task
 			LOG_DEBUG ("Enabling ParentControl task and wait for my name");
@@ -655,7 +655,7 @@ uint16	BeamControl::handleBeamAllocAck(GCFEvent&	event)
 		return (CT_RESULT_BEAMALLOC_FAILED);
 	}
 	itsBeamID = ackEvent.handle;
-	itsPropertySet->setValue(PN_BC_BEAMID, GCFPVInteger(itsBeamID));
+//	itsPropertySet->setValue(PN_BC_BEAMID, GCFPVInteger(itsBeamID));
 
 	// read new angles from parameterfile.
 	vector<string>	sourceTimes;
@@ -736,7 +736,7 @@ bool BeamControl::handleBeamFreeAck(GCFEvent&		event)
 	itsPropertySet->setValue(PN_BC_ANGLE1,		GCFPVString(""));
 	itsPropertySet->setValue(PN_BC_ANGLE2,		GCFPVString(""));
 	itsPropertySet->setValue(PN_BC_ANGLETIMES,	GCFPVString(""));
-	itsPropertySet->setValue(PN_BC_BEAMID,		GCFPVInteger(0));
+//	itsPropertySet->setValue(PN_BC_BEAMID,		GCFPVInteger(0));
 
 	itsBeamID = 0;
 
diff --git a/MAC/APL/StationCU/src/BeamControl/BeamControl.h b/MAC/APL/StationCU/src/BeamControl/BeamControl.h
index 482fe277ca2..63d5f18c9aa 100644
--- a/MAC/APL/StationCU/src/BeamControl/BeamControl.h
+++ b/MAC/APL/StationCU/src/BeamControl/BeamControl.h
@@ -112,7 +112,7 @@ private:
 	// ParameterSet variables
 	string					itsTreePrefix;
 	uint32					itsInstanceNr;
-	uint32					itsBeamID;				// returned from BeamServer
+	void*					itsBeamID;				// returned from BeamServer
 };
 
   };//StationCU
diff --git a/MAC/APL/StationCU/src/CalibrationControl/CalibrationControl.cc b/MAC/APL/StationCU/src/CalibrationControl/CalibrationControl.cc
index 38e67613daf..e7537d8f9ce 100644
--- a/MAC/APL/StationCU/src/CalibrationControl/CalibrationControl.cc
+++ b/MAC/APL/StationCU/src/CalibrationControl/CalibrationControl.cc
@@ -183,7 +183,7 @@ GCFEvent::TResult CalibrationControl::initial_state(GCFEvent& event,
 		LOG_INFO_STR ("Activating PropertySet" << propSetName);
 		itsPropertySet = new RTDBPropertySet(propSetName,
 											 PST_CAL_CTRL,
-											 PSAT_RW_TMP,
+											 PSAT_RW | PSAT_TMP,
 											 this);
 		// Wait for timer that is set on DP_CREATED event
 	}
diff --git a/MAC/APL/StationCU/src/DigitalBoardControl/DigitalBoardControl.h b/MAC/APL/StationCU/src/DigitalBoardControl/DigitalBoardControl.h
index 638e6c88b83..f62c9a5b67c 100644
--- a/MAC/APL/StationCU/src/DigitalBoardControl/DigitalBoardControl.h
+++ b/MAC/APL/StationCU/src/DigitalBoardControl/DigitalBoardControl.h
@@ -109,7 +109,7 @@ private:
 	uint32					itsInstanceNr;
 	time_t					itsStartTime;		// timestamp the controller was started
 	uint32					itsClock;
-	uint32					itsSubscription;
+	void*					itsSubscription;
 };
 
   };//StationCU
diff --git a/MAC/APL/StationCU/src/HardwareMonitor/RCUConstants.h b/MAC/APL/StationCU/src/HardwareMonitor/RCUConstants.h
index 66275bcbd8f..778592274dc 100644
--- a/MAC/APL/StationCU/src/HardwareMonitor/RCUConstants.h
+++ b/MAC/APL/StationCU/src/HardwareMonitor/RCUConstants.h
@@ -40,8 +40,8 @@ static const uint32	LB_POWER_MASK		= 0x00004000;
 static const uint32	HB_POWER_MASK		= 0x00008000;
 static const uint32	ADC_POWER_MASK		= 0x00010000;
 static const uint32	USE_LBH_MASK		= 0x00020000;
-static const uint32	LB_FILTER_MASK		= 0x00060000;
-static const uint32	LB_FILTER_OFFSET	= 17;
+static const uint32	LB_FILTER_MASK		= 0x00040000;
+static const uint32	LB_FILTER_OFFSET	= 18;
 static const uint32	ATT_MASK			= 0x00F80000;
 static const uint32	ATT_OFFSET			= 19;
 
diff --git a/MAC/APL/StationCU/src/HardwareMonitor/RSPMonitor.cc b/MAC/APL/StationCU/src/HardwareMonitor/RSPMonitor.cc
index 3db6468ca61..62bbdaa414f 100644
--- a/MAC/APL/StationCU/src/HardwareMonitor/RSPMonitor.cc
+++ b/MAC/APL/StationCU/src/HardwareMonitor/RSPMonitor.cc
@@ -25,6 +25,7 @@
 #include <GCF/GCF_PVTypes.h>
 #include <GCF/GCF_ServiceInfo.h>
 #include <APL/APLCommon/ControllerDefines.h>
+#include <APL/RTDBCommon/RTDButilities.h>
 #include <APL/RSP_Protocol/RSP_Protocol.ph>
 #include <GCF/RTDB/DP_Protocol.ph>
 //#include <APL/APLCommon/StationInfo.h>
@@ -34,13 +35,13 @@
 #include "RCUConstants.h"
 #include "StationPermDatapointDefs.h"
 
-using namespace LOFAR::GCF::Common;
-using namespace LOFAR::GCF::TM;
-using namespace LOFAR::GCF::RTDB;
-using namespace std;
 
 namespace LOFAR {
 	using namespace APLCommon;
+	using namespace APL::RTDBCommon;
+	using namespace GCF::Common;
+	using namespace GCF::TM;
+	using namespace GCF::RTDB;
 	namespace StationCU {
 	
 //
@@ -188,6 +189,10 @@ GCFEvent::TResult RSPMonitor::connect2RSP(GCFEvent& event,
 		itsTimerPort->setTimer(2.0);
 		break;
 
+	case F_TIMER:
+		itsRSPDriver->open();	// results in F_COON or F_DISCON
+		break;
+
 	case DP_SET:
 		break;
 
@@ -419,11 +424,15 @@ GCFEvent::TResult RSPMonitor::askVersion(GCFEvent& event,
 			versionStr = formatString("%d.%d", ack.versions.bp()(rsp).rsp_version >> 4,
 											   ack.versions.bp()(rsp).rsp_version & 0xF);
 			itsRSPs[rsp]->setValue(PN_RSP_VERSION, GCFPVString(versionStr), double(ack.timestamp));
+			setObjectState(getName(), itsRSPs[rsp]->getFullScope(), (ack.versions.bp()(rsp).rsp_version) ? 
+															RTDB_OBJ_STATE_OPERATIONAL : RTDB_OBJ_STATE_OFF);
 			
 			// BP version
 			versionStr = formatString("%d.%d", ack.versions.bp()(rsp).fpga_maj,
 											   ack.versions.bp()(rsp).fpga_min);
 			itsRSPs[rsp]->setValue(PN_RSP_BP_VERSION, GCFPVString(versionStr), double(ack.timestamp));
+			setObjectState(getName(), itsRSPs[rsp]->getFullScope()+".BP", (ack.versions.bp()(rsp).rsp_version) ? 
+															RTDB_OBJ_STATE_OPERATIONAL : RTDB_OBJ_STATE_OFF);
 			
 			// APx versions
 			for (int ap = 0; ap < MEPHeader::N_AP; ap++) {
@@ -431,6 +440,10 @@ GCFEvent::TResult RSPMonitor::askVersion(GCFEvent& event,
 												   ack.versions.ap()(rsp * MEPHeader::N_AP + ap).fpga_min);
 				DPEname = formatString (PN_RSP_AP_VERSION_MASK, ap);
 				itsRSPs[rsp]->setValue(DPEname, GCFPVString(versionStr), double(ack.timestamp));
+				setObjectState(getName(), formatString("%s.AP%d", itsRSPs[rsp]->getFullScope().c_str(), ap),
+										(ack.versions.ap()(rsp * MEPHeader::N_AP + ap).fpga_maj +
+										 ack.versions.ap()(rsp * MEPHeader::N_AP + ap).fpga_min) ? 
+										RTDB_OBJ_STATE_OPERATIONAL : RTDB_OBJ_STATE_OFF);
 			}
 		}
 
@@ -490,7 +503,7 @@ GCFEvent::TResult RSPMonitor::askRSPinfo(GCFEvent& event,
 		if (ack.status != SUCCESS) {
 			LOG_ERROR_STR ("Failed to get the status information, trying other information");
 			itsOwnPropertySet->setValue(PN_HWM_RSP_ERROR,GCFPVString("getStatus error"));
-#if 0
+#if 1
 			TRAN(RSPMonitor::askRCUinfo);				// go to next state.
 #else
 			LOG_WARN ("SKIPPING RCU INFO FOR A MOMENT");
@@ -572,7 +585,7 @@ GCFEvent::TResult RSPMonitor::askRSPinfo(GCFEvent& event,
 
 		LOG_DEBUG_STR ("RSPboard information updated, going to RCU information");
 		itsOwnPropertySet->setValue(PN_HWM_RSP_ERROR,GCFPVString(""));
-#if 0
+#if 1
 		TRAN(RSPMonitor::askRCUinfo);				// go to next state.
 #else
 		LOG_WARN ("SKIPPING RCU INFO FOR A MOMENT");
@@ -622,11 +635,14 @@ GCFEvent::TResult RSPMonitor::askRCUinfo(GCFEvent& event, GCFPortInterface& port
 		// update PVSS
 		itsOwnPropertySet->setValue(PN_HWM_RSP_CURRENT_ACTION,GCFPVString("updating RSP info"));
 		itsOwnPropertySet->setValue(PN_HWM_RSP_ERROR,GCFPVString(""));
+		longlong	one(1);
 		RSPGetrcuEvent	getStatus;
 		getStatus.timestamp.setNow();
 		getStatus.cache = true;
-		getStatus.rcumask = bitset<MEPHeader::MAX_N_RCUS>((1<<itsNrRCUs)-1);
+		getStatus.rcumask = bitset<MEPHeader::MAX_N_RCUS>((one<<itsNrRCUs)-1);
 		itsRSPDriver->send(getStatus);
+		LOG_DEBUG(formatString("MAX_N_RCUS=%d", MEPHeader::MAX_N_RCUS));
+		LOG_DEBUG(formatString("itsRCUs=%d, rcumask=%08lX", itsNrRCUs, getStatus.rcumask.to_uint32()));
 		break;
 	}
 
@@ -638,49 +654,50 @@ GCFEvent::TResult RSPMonitor::askRCUinfo(GCFEvent& event, GCFPortInterface& port
 			TRAN(RSPMonitor::waitForNextCycle);			// go to next state.
 			break;
 		}
-
+#if 1
 		// move the information to the database.
 		string		versionStr;
 		string		DPEname;
 		for (uint32	rcu = 0; rcu < itsNrRCUs; rcu++) {
-			LOG_DEBUG_STR("Updating rcu " << rcu);
 			uint32		rawValue = ack.settings()(rcu).getRaw();
+			LOG_DEBUG(formatString("Updating rcu %d with %08lX", rcu, rawValue));
 			// update all RCU variables
 			itsRCUs[rcu]->setValue(PN_RCU_DELAY, 
 						GCFPVUnsigned(uint32(rawValue & DELAY_MASK)),
-						double(ack.timestamp));
+						double(ack.timestamp), false);
 			itsRCUs[rcu]->setValue(PN_RCU_INPUT_ENABLE, 
 						GCFPVBool(rawValue & INPUT_ENABLE_MASK),
-						double(ack.timestamp));
+						double(ack.timestamp), false);
 			itsRCUs[rcu]->setValue(PN_RCU_LBL_ENABLE, 
-						GCFPVBool(rawValue & LBL_ANT_POWER_MASK), double(ack.timestamp));
+						GCFPVBool(rawValue & LBL_ANT_POWER_MASK), double(ack.timestamp), false);
 			itsRCUs[rcu]->setValue(PN_RCU_LBH_ENABLE, 
-						GCFPVBool(rawValue & LBH_ANT_POWER_MASK), double(ack.timestamp));
+						GCFPVBool(rawValue & LBH_ANT_POWER_MASK), double(ack.timestamp), false);
 			itsRCUs[rcu]->setValue(PN_RCU_HBA_ENABLE, 
-						GCFPVBool(rawValue & HBA_ANT_POWER_MASK), double(ack.timestamp));
+						GCFPVBool(rawValue & HBA_ANT_POWER_MASK), double(ack.timestamp), false);
 			itsRCUs[rcu]->setValue(PN_RCU_BAND_SEL_LBA_HBA, 
 						GCFPVBool(rawValue & USE_LB_MASK),
-						double(ack.timestamp));
+						double(ack.timestamp), false);
 			itsRCUs[rcu]->setValue(PN_RCU_HBA_FILTER_SEL, 
 						GCFPVUnsigned((rawValue & HB_FILTER_MASK) >> HB_FILTER_OFFSET),
-						double(ack.timestamp));
+						double(ack.timestamp), false);
 			itsRCUs[rcu]->setValue(PN_RCU_VL_ENABLE, 
-						GCFPVBool(rawValue & LB_POWER_MASK), double(ack.timestamp));
+						GCFPVBool(rawValue & LB_POWER_MASK), double(ack.timestamp), false);
 			itsRCUs[rcu]->setValue(PN_RCU_VH_ENABLE, 
-						GCFPVBool(rawValue & HB_POWER_MASK), double(ack.timestamp));
+						GCFPVBool(rawValue & HB_POWER_MASK), double(ack.timestamp), false);
 			itsRCUs[rcu]->setValue(PN_RCU_VDD_VCC_ENABLE, 
-						GCFPVBool(rawValue & ADC_POWER_MASK), double(ack.timestamp));
+						GCFPVBool(rawValue & ADC_POWER_MASK), double(ack.timestamp), false);
 			itsRCUs[rcu]->setValue(PN_RCU_BAND_SEL_LBL_LBH, 
 						GCFPVBool(rawValue & USE_LBH_MASK),
-						double(ack.timestamp));
+						double(ack.timestamp), false);
 			itsRCUs[rcu]->setValue(PN_RCU_LBA_FILTER_SEL, 
 						GCFPVUnsigned((rawValue & LB_FILTER_MASK) >> LB_FILTER_OFFSET),
-						double(ack.timestamp));
+						double(ack.timestamp), false);
 			itsRCUs[rcu]->setValue(PN_RCU_ATTENUATION, 
 						GCFPVUnsigned(uint32((rawValue & ATT_MASK) >> ATT_OFFSET)),
-						double(ack.timestamp));
+						double(ack.timestamp), false);
+			itsRCUs[rcu]->flush();
 		} // for all boards
-
+#endif
 		LOG_DEBUG ("Updated all RCU information, waiting for next cycle");
 		itsOwnPropertySet->setValue(PN_HWM_RSP_ERROR,GCFPVString(""));
 		TRAN(RSPMonitor::waitForNextCycle);			// go to next state.
diff --git a/MAC/APL/StationCU/src/HardwareMonitor/StationPermDatapointDefs.h b/MAC/APL/StationCU/src/HardwareMonitor/StationPermDatapointDefs.h
index 8de85dddd27..189f9e6adb2 100644
--- a/MAC/APL/StationCU/src/HardwareMonitor/StationPermDatapointDefs.h
+++ b/MAC/APL/StationCU/src/HardwareMonitor/StationPermDatapointDefs.h
@@ -98,6 +98,7 @@
 #define PN_RCU_TRIGGER_STOPLEVEL	"Trigger.stoplevel"
 #define PN_RCU_TRIGGER_FILTER	"Trigger.filter"
 #define PN_RCU_TRIGGER_WINDOW	"Trigger.window"
+#define PN_RCU_TRIGGER_OPERATING_MODE	"Trigger.operatingMode"
 #define PN_RCU_TRIGGER_COEFF0	"Trigger.coeff0"
 #define PN_RCU_TRIGGER_COEFF1	"Trigger.coeff1"
 #define PN_RCU_TRIGGER_COEFF2	"Trigger.coeff2"
diff --git a/MAC/APL/StationCU/src/HardwareMonitor/TBBMonitor.cc b/MAC/APL/StationCU/src/HardwareMonitor/TBBMonitor.cc
index 8bf9793b37e..757354d3530 100644
--- a/MAC/APL/StationCU/src/HardwareMonitor/TBBMonitor.cc
+++ b/MAC/APL/StationCU/src/HardwareMonitor/TBBMonitor.cc
@@ -27,6 +27,7 @@
 #include <GCF/GCF_ServiceInfo.h>
 #include <APL/APLCommon/ControllerDefines.h>
 #include <APL/APLCommon/APLUtilities.h>
+#include <APL/RTDBCommon/RTDButilities.h>
 #include <APL/TBB_Protocol/TBB_Protocol.ph>
 #include <GCF/RTDB/DP_Protocol.ph>
 //#include <APL/APLCommon/StationInfo.h>
@@ -36,13 +37,13 @@
 #include "RCUConstants.h"
 #include "StationPermDatapointDefs.h"
 
-using namespace LOFAR::GCF::Common;
-using namespace LOFAR::GCF::TM;
-using namespace LOFAR::GCF::RTDB;
-using namespace std;
 
 namespace LOFAR {
+	using namespace GCF::Common;
+	using namespace GCF::TM;
+	using namespace GCF::RTDB;
 	using namespace APLCommon;
+	using namespace APL::RTDBCommon;
 	namespace StationCU {
 	
 //
@@ -191,6 +192,10 @@ GCFEvent::TResult TBBMonitor::connect2TBB(GCFEvent& event, GCFPortInterface& por
 		itsTimerPort->setTimer(2.0);
 		break;
 
+	case F_TIMER:
+		itsTBBDriver->open();		// results in F_CONN or F_DISCON
+		break;
+
 	case DP_SET:
 		break;
 
@@ -229,6 +234,17 @@ GCFEvent::TResult TBBMonitor::askConfiguration(GCFEvent& event, GCFPortInterface
 		_disconnectedHandler(port);		// might result in transition to connect2TBB
 		break;
 
+	case TBB_DRIVER_BUSY_ACK:
+		LOG_DEBUG("TBBDriver is busy, retry in 3 seconds");
+		itsTimerPort->setTimer(3.0);
+		break;
+
+	case F_TIMER: {
+		TBBGetConfigEvent	getconfig;
+		itsTBBDriver->send(getconfig);
+	}
+	break;
+		
 	case TBB_GET_CONFIG_ACK: {
 		TBBGetConfigAckEvent	ack(event);
 	
@@ -311,6 +327,7 @@ GCFEvent::TResult TBBMonitor::createPropertySets(GCFEvent& event, GCFPortInterfa
 				TBB++;
 				string	PSname(formatString(tbboardNameMask.c_str(), cabinet, subrack, TBB));
 				itsTBBs[TBB] = new RTDBPropertySet(PSname, PST_TB_BOARD, PSAT_WO, this);
+				itsTBBs[TBB]->setConfirmation(false);
 			}
 
 			// new RSPboard?
@@ -321,6 +338,7 @@ GCFEvent::TResult TBBMonitor::createPropertySets(GCFEvent& event, GCFPortInterfa
 			// allocate RCU PS
 			string	PSname(formatString(rcuNameMask.c_str(), cabinet, subrack, RSP, rcu));
 			itsRCUs[rcu] = new RTDBPropertySet(PSname, PST_RCU, PSAT_WO, this);
+			itsRCUs[rcu]->setConfirmation(false);
 		}
 		itsTimerPort->setTimer(5.0);	// give database some time to finish the job
 	}
@@ -376,13 +394,24 @@ GCFEvent::TResult TBBMonitor::askVersion(GCFEvent& event, GCFPortInterface& port
 	case F_ENTRY: {
 		itsOwnPropertySet->setValue(PN_HWM_TBB_CURRENT_ACTION,GCFPVString("getting version info"));
 		itsOwnPropertySet->setValue(PN_HWM_TBB_ERROR,GCFPVString(""));
+		itsTimerPort->setTimer(0.1);
+	}
+	break;
+
+	case TBB_DRIVER_BUSY_ACK:
+		LOG_DEBUG("TBBDriver is busy, retry in 3 seconds");
+		itsTimerPort->setTimer(3.0);
+		break;
+
+	case F_TIMER: {
 		TBBVersionEvent	getVersion;
 		getVersion.boardmask = itsBoardMask.to_uint32();
 		itsTBBDriver->send(getVersion);
 	}
 	break;
-
+		
 	case TBB_VERSION_ACK: {
+		itsTimerPort->cancelAllTimers();
 		TBBVersionAckEvent		ack(event);
 		// move the information to the database.
 		string		versionStr;
@@ -391,34 +420,39 @@ GCFEvent::TResult TBBMonitor::askVersion(GCFEvent& event, GCFPortInterface& port
 			if (ack.status_mask[tbb] & TBB_SUCCESS) {
 				// TBB board version
 				versionStr = formatString("%d.%d", ack.swversion[tbb] / 10, ack.swversion[tbb] % 10);
-				itsTBBs[tbb]->setValue(PN_TBB_SW_VERSION, GCFPVString(versionStr));
+				itsTBBs[tbb]->setValue(PN_TBB_SW_VERSION, GCFPVString(versionStr), 0.0, false);
 				versionStr = formatString("%d.%d", ack.boardversion[tbb] / 10, ack.boardversion[tbb] % 10);
-				itsTBBs[tbb]->setValue(PN_TBB_BOARD_VERSION, GCFPVString(versionStr));
-				itsTBBs[tbb]->setValue(PN_TBB_BOARDID, GCFPVUnsigned(ack.boardid[tbb]));
+				itsTBBs[tbb]->setValue(PN_TBB_BOARD_VERSION, GCFPVString(versionStr), 0.0, false);
+				itsTBBs[tbb]->setValue(PN_TBB_BOARDID, GCFPVUnsigned(ack.boardid[tbb]), 0.0, false);
 			
 				// BP version
 				versionStr = formatString("%d.%d", ack.tpversion[tbb] / 10, ack.tpversion[tbb] % 10);
-				itsTBBs[tbb]->setValue(PN_TBB_TP_VERSION, GCFPVString(versionStr));
+				itsTBBs[tbb]->setValue(PN_TBB_TP_VERSION, GCFPVString(versionStr), 0.0, false);
 			
 				// MPx versions
 				versionStr = formatString("%d.%d", ack.mp0version[tbb] / 10, ack.mp0version[tbb] % 10);
-				itsTBBs[tbb]->setValue(PN_TBB_MP0_VERSION, GCFPVString(versionStr));
+				itsTBBs[tbb]->setValue(PN_TBB_MP0_VERSION, GCFPVString(versionStr), 0.0, false);
 				versionStr = formatString("%d.%d", ack.mp1version[tbb] / 10, ack.mp1version[tbb] % 10);
-				itsTBBs[tbb]->setValue(PN_TBB_MP1_VERSION, GCFPVString(versionStr));
+				itsTBBs[tbb]->setValue(PN_TBB_MP1_VERSION, GCFPVString(versionStr), 0.0, false);
 				versionStr = formatString("%d.%d", ack.mp2version[tbb] / 10, ack.mp2version[tbb] % 10);
-				itsTBBs[tbb]->setValue(PN_TBB_MP2_VERSION, GCFPVString(versionStr));
+				itsTBBs[tbb]->setValue(PN_TBB_MP2_VERSION, GCFPVString(versionStr), 0.0, false);
 				versionStr = formatString("%d.%d", ack.mp3version[tbb] / 10, ack.mp3version[tbb] % 10);
-				itsTBBs[tbb]->setValue(PN_TBB_MP3_VERSION, GCFPVString(versionStr));
+				itsTBBs[tbb]->setValue(PN_TBB_MP3_VERSION, GCFPVString(versionStr), 0.0, false);
 			}
 			else {	// board in error set ?.?
-				itsTBBs[tbb]->setValue(PN_TBB_BOARDID,		 GCFPVUnsigned(0));
-				itsTBBs[tbb]->setValue(PN_TBB_BOARD_VERSION, GCFPVString("?.?"));
-				itsTBBs[tbb]->setValue(PN_TBB_TP_VERSION,	 GCFPVString("?.?"));
-				itsTBBs[tbb]->setValue(PN_TBB_MP0_VERSION,	 GCFPVString("?.?"));
-				itsTBBs[tbb]->setValue(PN_TBB_MP1_VERSION,	 GCFPVString("?.?"));
-				itsTBBs[tbb]->setValue(PN_TBB_MP2_VERSION,	 GCFPVString("?.?"));
-				itsTBBs[tbb]->setValue(PN_TBB_MP3_VERSION,	 GCFPVString("?.?"));
+				itsTBBs[tbb]->setValue(PN_TBB_BOARDID,		 GCFPVUnsigned(0), 0.0, false);
+				itsTBBs[tbb]->setValue(PN_TBB_BOARD_VERSION, GCFPVString("?.?"), 0.0, false);
+				itsTBBs[tbb]->setValue(PN_TBB_TP_VERSION,	 GCFPVString("?.?"), 0.0, false);
+				itsTBBs[tbb]->setValue(PN_TBB_MP0_VERSION,	 GCFPVString("?.?"), 0.0, false);
+				itsTBBs[tbb]->setValue(PN_TBB_MP1_VERSION,	 GCFPVString("?.?"), 0.0, false);
+				itsTBBs[tbb]->setValue(PN_TBB_MP2_VERSION,	 GCFPVString("?.?"), 0.0, false);
+				itsTBBs[tbb]->setValue(PN_TBB_MP3_VERSION,	 GCFPVString("?.?"), 0.0, false);
 			}
+			itsTBBs[tbb]->flush();
+			
+			// set right color
+			setObjectState(getName(), itsTBBs[tbb]->getFullScope(), (ack.status_mask[tbb] & TBB_SUCCESS) ? 
+							RTDB_OBJ_STATE_OPERATIONAL : RTDB_OBJ_STATE_OFF);
 		}
 
 		LOG_DEBUG_STR ("Version information updated, going to status information");
@@ -462,6 +496,17 @@ GCFEvent::TResult TBBMonitor::askSizeInfo(GCFEvent& event, GCFPortInterface& por
 	case F_ENTRY: {
 		itsOwnPropertySet->setValue(PN_HWM_TBB_CURRENT_ACTION,GCFPVString("getting version info"));
 		itsOwnPropertySet->setValue(PN_HWM_TBB_ERROR,GCFPVString(""));
+		itsTimerPort->setTimer(0.1);
+	}
+	break;
+
+	case TBB_DRIVER_BUSY_ACK:
+		LOG_DEBUG("TBBDriver is busy, retry in 3 seconds");
+		itsTimerPort->setTimer(3.0);
+		break;
+
+	case F_TIMER: {
+		LOG_DEBUG_STR("Asking size, boardmask=" << itsBoardMask.to_uint32());
 		TBBSizeEvent	getSize;
 		getSize.boardmask = itsBoardMask.to_uint32();
 		itsTBBDriver->send(getSize);
@@ -469,6 +514,7 @@ GCFEvent::TResult TBBMonitor::askSizeInfo(GCFEvent& event, GCFPortInterface& por
 	break;
 
 	case TBB_SIZE_ACK: {
+		itsTimerPort->cancelAllTimers();
 		TBBSizeAckEvent		ack(event);
 		// move the information to the database.
 		for (uint32	tbb = 0; tbb < itsNrTBboards; tbb++) {
@@ -540,13 +586,14 @@ GCFEvent::TResult TBBMonitor::askFlashInfo(GCFEvent& event, GCFPortInterface& po
 		TBBImageInfoAckEvent		ack(event);
 		nrOfRequests--;
 		// move the information to the database.
+		LOG_DEBUG_STR("ack.status_mask=" << ack.status_mask << ", board = " << ack.board);
+		
 		if (ack.status_mask & TBB_SUCCESS) {
 			vector<GCFPValue*>		imageVersions;
 			vector<GCFPValue*>		writeDates;
 			vector<GCFPValue*>		TPfilenames;
 			vector<GCFPValue*>		MPfilenames;
 			for (int32	tbb = 0; tbb < MAX_N_IMAGES; tbb++) {
-cout << "TIMESTAMP = " << ack.write_date[tbb] << endl;
 				if (ack.write_date[tbb] != -1L) {
 					imageVersions.push_back(new GCFPVString(formatString("%d.%d", ack.image_version[tbb]/10, ack.image_version[tbb]%10)));
 					ptime		theTime(from_time_t(ack.write_date[tbb]));
@@ -564,9 +611,12 @@ cout << "TIMESTAMP = " << ack.write_date[tbb] << endl;
 			itsTBBs[ack.board]->setValue(PN_TBB_IMAGE_INFO_TP_FILE,    GCFPVDynArr(LPT_DYNSTRING, TPfilenames));
 			itsTBBs[ack.board]->setValue(PN_TBB_IMAGE_INFO_MP_FILE,    GCFPVDynArr(LPT_DYNSTRING, MPfilenames));
 		}
+		else {
+			LOG_WARN_STR("Flashinfo of boardnr " << ack.board << " contains errors, no update of Flash");
+		}
 
-		if (--nrOfRequests == 0) {
-			LOG_DEBUG_STR ("Size information updated, going to status information");
+		if (nrOfRequests == 0) {
+			LOG_DEBUG_STR ("Flash information updated, going to status information");
 			itsOwnPropertySet->setValue(PN_HWM_TBB_ERROR,GCFPVString(""));
 			TRAN(TBBMonitor::askTBBinfo);				// go to next state.
 		}
@@ -612,10 +662,12 @@ GCFEvent::TResult TBBMonitor::askTBBinfo(GCFEvent& event, GCFPortInterface& port
 		TBBStatusEvent	getStatus;
 		getStatus.boardmask = itsBoardMask.to_uint32();
 		itsTBBDriver->send(getStatus);
+		itsTimerPort->setTimer(2.0);
 	}
 	break;
 
 	case TBB_STATUS_ACK: {
+		itsTimerPort->cancelAllTimers();
 		TBBStatusAckEvent		ack(event);
 		// move the information to the database.
 		string		versionStr;
@@ -623,17 +675,20 @@ GCFEvent::TResult TBBMonitor::askTBBinfo(GCFEvent& event, GCFPortInterface& port
 		for (uint32	tbb = 0; tbb < itsNrTBboards; tbb++) {
 			if (ack.status_mask[tbb] & TBB_SUCCESS) {
 				// board voltages
-				itsTBBs[tbb]->setValue(PN_TBB_VOLTAGE12, GCFPVDouble(double(ack.V12[tbb])*(2.5/192.0)));
-				itsTBBs[tbb]->setValue(PN_TBB_VOLTAGE25, GCFPVDouble(double(ack.V25[tbb])*(3.3/192.0)));
-				itsTBBs[tbb]->setValue(PN_TBB_VOLTAGE33, GCFPVDouble(double(ack.V33[tbb])*(5.0/192.0)));
+				itsTBBs[tbb]->setValue(PN_TBB_VOLTAGE12, GCFPVDouble(double(ack.V12[tbb])*(2.5/192.0)), 0.0, false);
+				itsTBBs[tbb]->setValue(PN_TBB_VOLTAGE25, GCFPVDouble(double(ack.V25[tbb])*(3.3/192.0)), 0.0, false);
+				itsTBBs[tbb]->setValue(PN_TBB_VOLTAGE33, GCFPVDouble(double(ack.V33[tbb])*(5.0/192.0)), 0.0, false);
 				// all temperatures
-				itsTBBs[tbb]->setValue(PN_TBB_TEMPPCB, GCFPVDouble(double(ack.Tpcb[tbb])));
-				itsTBBs[tbb]->setValue(PN_TBB_TEMPTP,  GCFPVDouble(double(ack.Ttp [tbb])));
-				itsTBBs[tbb]->setValue(PN_TBB_TEMPMP0, GCFPVDouble(double(ack.Tmp0[tbb])));
-				itsTBBs[tbb]->setValue(PN_TBB_TEMPMP1, GCFPVDouble(double(ack.Tmp1[tbb])));
-				itsTBBs[tbb]->setValue(PN_TBB_TEMPMP2, GCFPVDouble(double(ack.Tmp2[tbb])));
-				itsTBBs[tbb]->setValue(PN_TBB_TEMPMP3, GCFPVDouble(double(ack.Tmp3[tbb])));
+				itsTBBs[tbb]->setValue(PN_TBB_TEMPPCB, GCFPVDouble(double(ack.Tpcb[tbb])), 0.0, false);
+				itsTBBs[tbb]->setValue(PN_TBB_TEMPTP,  GCFPVDouble(double(ack.Ttp [tbb])), 0.0, false);
+				itsTBBs[tbb]->setValue(PN_TBB_TEMPMP0, GCFPVDouble(double(ack.Tmp0[tbb])), 0.0, false);
+				itsTBBs[tbb]->setValue(PN_TBB_TEMPMP1, GCFPVDouble(double(ack.Tmp1[tbb])), 0.0, false);
+				itsTBBs[tbb]->setValue(PN_TBB_TEMPMP2, GCFPVDouble(double(ack.Tmp2[tbb])), 0.0, false);
+				itsTBBs[tbb]->setValue(PN_TBB_TEMPMP3, GCFPVDouble(double(ack.Tmp3[tbb])), 0.0, false);
+				// flush to database
+				itsTBBs[tbb]->flush();
 			}
+			
 		} // for all boards
 
 		LOG_DEBUG_STR ("TBboard information updated, going to RCU information");
@@ -642,6 +697,13 @@ GCFEvent::TResult TBBMonitor::askTBBinfo(GCFEvent& event, GCFPortInterface& port
 		break;
 	}
 
+	case F_TIMER: {
+		LOG_DEBUG_STR ("TBBDriver is not respondind, TBboard information is not available");
+		itsOwnPropertySet->setValue(PN_HWM_TBB_ERROR,GCFPVString("TBBDriver is not respondind, TBboard information is not available"));
+		TRAN(TBBMonitor::askRCUinfo);				// go to next state.
+		break;
+	}
+
 	case F_DISCONNECTED:
 		_disconnectedHandler(port);		// might result in transition to connect2TBB
 		break;
@@ -685,10 +747,12 @@ GCFEvent::TResult TBBMonitor::askRCUinfo(GCFEvent& event, GCFPortInterface& port
 		itsOwnPropertySet->setValue(PN_HWM_TBB_ERROR,GCFPVString(""));
 		TBBRcuInfoEvent	getStatus;
 		itsTBBDriver->send(getStatus);
+		itsTimerPort->setTimer(2.0);
 		break;
 	}
 
 	case TBB_RCU_INFO_ACK: {
+		itsTimerPort->cancelAllTimers();
 		TBBRcuInfoAckEvent	ack(event);
 
 		// move the information to the database.
@@ -709,6 +773,13 @@ GCFEvent::TResult TBBMonitor::askRCUinfo(GCFEvent& event, GCFPortInterface& port
 	}
 	break;
 
+	case F_TIMER: {
+		LOG_DEBUG ("TBBDriver is not responding, RCU information is not available");
+		itsOwnPropertySet->setValue(PN_HWM_TBB_ERROR,GCFPVString("TBBDriver is not responding, RCU information is not available"));
+		TRAN(TBBMonitor::askRCUSettings);			// go to next state.
+	}
+	break;
+
 	case F_DISCONNECTED:
 		_disconnectedHandler(port);		// might result in transition to connect2TBB
 		break;
@@ -751,26 +822,30 @@ GCFEvent::TResult TBBMonitor::askRCUSettings(GCFEvent& event, GCFPortInterface&
 		itsOwnPropertySet->setValue(PN_HWM_TBB_ERROR,GCFPVString(""));
 		TBBTrigSettingsEvent	getSettings;
 		itsTBBDriver->send(getSettings);
+		itsTimerPort->setTimer(2.0);
 		break;
 	}
 
 	case TBB_TRIG_SETTINGS_ACK: {
+		itsTimerPort->cancelAllTimers();
 		TBBTrigSettingsAckEvent	ack(event);
 
 		// move the information to the database.
 		for (uint32	rcu = 0; rcu < itsNrRCUs; rcu++) {
 			LOG_TRACE_FLOW_STR("Updating rcu " << rcu);
 			// update all RCU variables
-			itsRCUs[rcu]->setValue(PN_RCU_TRIGGER_STARTLEVEL, GCFPVInteger(ack.setup[rcu].start_mode)),
-			itsRCUs[rcu]->setValue(PN_RCU_TRIGGER_BASELEVEL,  GCFPVInteger(ack.setup[rcu].level)),
-			itsRCUs[rcu]->setValue(PN_RCU_TRIGGER_STOPLEVEL,  GCFPVInteger(ack.setup[rcu].stop_mode)),
-			itsRCUs[rcu]->setValue(PN_RCU_TRIGGER_FILTER, 	  GCFPVInteger(ack.setup[rcu].filter_select)),
-			itsRCUs[rcu]->setValue(PN_RCU_TRIGGER_WINDOW, 	  GCFPVInteger(ack.setup[rcu].window)),
-//			itsRCUs[rcu]->setValue(PN_RCU_TRIGGER_OPERATING_MODE, GCFPVInteger(ack.coefficients[rcu].xxx));
-			itsRCUs[rcu]->setValue(PN_RCU_TRIGGER_COEFF0, 		  GCFPVInteger(ack.coefficients[rcu].c0));
-			itsRCUs[rcu]->setValue(PN_RCU_TRIGGER_COEFF1, 		  GCFPVInteger(ack.coefficients[rcu].c1));
-			itsRCUs[rcu]->setValue(PN_RCU_TRIGGER_COEFF2, 		  GCFPVInteger(ack.coefficients[rcu].c2));
-			itsRCUs[rcu]->setValue(PN_RCU_TRIGGER_COEFF3, 		  GCFPVInteger(ack.coefficients[rcu].c3));
+			itsRCUs[rcu]->setValue(PN_RCU_TRIGGER_STARTLEVEL, GCFPVInteger(ack.setup[rcu].start_mode), 0.0, false),
+			itsRCUs[rcu]->setValue(PN_RCU_TRIGGER_BASELEVEL,  GCFPVInteger(ack.setup[rcu].level), 0.0, false),
+			itsRCUs[rcu]->setValue(PN_RCU_TRIGGER_STOPLEVEL,  GCFPVInteger(ack.setup[rcu].stop_mode), 0.0, false),
+			itsRCUs[rcu]->setValue(PN_RCU_TRIGGER_FILTER, 	  GCFPVInteger(ack.setup[rcu].filter_select), 0.0, false),
+			itsRCUs[rcu]->setValue(PN_RCU_TRIGGER_WINDOW, 	  GCFPVInteger(ack.setup[rcu].window), 0.0, false),
+			itsRCUs[rcu]->setValue(PN_RCU_TRIGGER_OPERATING_MODE, 
+													GCFPVInteger(ack.setup[rcu].operating_mode), 0.0, false);
+			itsRCUs[rcu]->setValue(PN_RCU_TRIGGER_COEFF0, 	  GCFPVInteger(ack.coefficients[rcu].c0), 0.0, false);
+			itsRCUs[rcu]->setValue(PN_RCU_TRIGGER_COEFF1, 	  GCFPVInteger(ack.coefficients[rcu].c1), 0.0, false);
+			itsRCUs[rcu]->setValue(PN_RCU_TRIGGER_COEFF2, 	  GCFPVInteger(ack.coefficients[rcu].c2), 0.0, false);
+			itsRCUs[rcu]->setValue(PN_RCU_TRIGGER_COEFF3, 	  GCFPVInteger(ack.coefficients[rcu].c3), 0.0, false);
+			itsRCUs[rcu]->flush();
 		} // for all boards
 
 		LOG_DEBUG ("Updated all TriggerSetting information, waiting for next cycle");
@@ -779,6 +854,13 @@ GCFEvent::TResult TBBMonitor::askRCUSettings(GCFEvent& event, GCFPortInterface&
 	}
 	break;
 
+	case F_TIMER: {
+		LOG_DEBUG ("TBBDriver is not responding, TriggerSetting are not available");
+		itsOwnPropertySet->setValue(PN_HWM_TBB_ERROR,GCFPVString("TBBDriver is not responding, TriggerSetting are not available"));
+		TRAN(TBBMonitor::waitForNextCycle);			// go to next state.
+	}
+	break;
+
 	case F_DISCONNECTED:
 		_disconnectedHandler(port);		// might result in transition to connect2TBB
 		break;
diff --git a/MAC/APL/StationCU/src/StationControl/ActiveObs.cc b/MAC/APL/StationCU/src/StationControl/ActiveObs.cc
index 57e3d4ca3a4..afefa18baa6 100644
--- a/MAC/APL/StationCU/src/StationControl/ActiveObs.cc
+++ b/MAC/APL/StationCU/src/StationControl/ActiveObs.cc
@@ -35,6 +35,7 @@
 #include <APL/APLCommon/ChildControl.h>
 #include <APL/APLCommon/ControllerDefines.h>
 #include <APL/APLCommon/Controller_Protocol.ph>
+#include <APL/APLCommon/StationInfo.h>
 #include <GCF/RTDB/DP_Protocol.ph>
 #include "StationControlDefines.h"
 #include "ActiveObs.h"
@@ -49,6 +50,7 @@ namespace LOFAR {
 	using namespace GCF::TM;
 	using namespace GCF::Common;
 	using namespace GCF::RTDB;
+	using namespace Deployment;
 	namespace StationCU {
 
 //
@@ -79,10 +81,13 @@ ActiveObs::ActiveObs(const string&		name,
 	itsReqState			(CTState::NOSTATE),
 	itsCurState			(CTState::NOSTATE)
 {
-	if (thePS->isDefined("Observation.TBB.TBBSetting[1].C0")) {
+	if (thePS->isDefined("Observation.TBB.TBBsetting[1].C0")) {
 		LOG_INFO("Observation also uses the TB boards");
 		itsUsesTBB = true;
 	}
+	else {
+		LOG_INFO("Observation does not use the TB boards");
+	}
 }
 
 //
@@ -135,7 +140,7 @@ GCFEvent::TResult ActiveObs::initial(GCFEvent& event,
 		break;
 
 	case DP_CREATED: {
-			// NOTE: thsi function may be called DURING the construction of the PropertySet.
+			// NOTE: this function may be called DURING the construction of the PropertySet.
 			// Always exit this event in a way that GCF can end the construction.
 			DPCreatedEvent	dpEvent(event);
 			LOG_DEBUG_STR("Result of creating " << dpEvent.DPname << " = " << dpEvent.result);
diff --git a/MAC/APL/StationCU/src/StationControl/StationControl.cc b/MAC/APL/StationCU/src/StationControl/StationControl.cc
index 8cdf3a73be7..1bbb9c4e554 100644
--- a/MAC/APL/StationCU/src/StationControl/StationControl.cc
+++ b/MAC/APL/StationCU/src/StationControl/StationControl.cc
@@ -201,7 +201,7 @@ GCFEvent::TResult StationControl::initial_state(GCFEvent& event,
 			DPCreatedEvent	dpEvent(event);
 			LOG_DEBUG_STR("Result of creating " << dpEvent.DPname << " = " << dpEvent.result);
 			itsTimerPort->cancelAllTimers();
-			itsTimerPort->setTimer(0.0);
+			itsTimerPort->setTimer(0.5);	// give RTDB time to get original value.
         }
 		break;
 	  
@@ -231,7 +231,7 @@ GCFEvent::TResult StationControl::initial_state(GCFEvent& event,
 			LOG_DEBUG_STR ("Activating PropertySet " << clkPropSetName);
 			itsClockPropSet = new RTDBPropertySet(clkPropSetName,
 												  PST_STATION_CLOCK,
-												  PSAT_WO,
+												  PSAT_RW,
 												  this);
 		}
 		else {
-- 
GitLab