From b8558db3eb7cd58eb5919930d91b6a0c0c0dcf2f Mon Sep 17 00:00:00 2001
From: Ruud Overeem <overeem@astron.nl>
Date: Fri, 8 Aug 2008 12:18:00 +0000
Subject: [PATCH] Bug 1156: Added commands for reading the SPU board and
 writing and reading raw blocks of data.

---
 MAC/APL/PIC/RSPDriver/src/Cache.cc            |  84 +-
 MAC/APL/PIC/RSPDriver/src/Cache.h             | 258 +++--
 MAC/APL/PIC/RSPDriver/src/GetRawBlockCmd.cc   | 157 +++
 MAC/APL/PIC/RSPDriver/src/GetRawBlockCmd.h    |  81 ++
 MAC/APL/PIC/RSPDriver/src/GetSPUStatusCmd.cc  | 142 +++
 MAC/APL/PIC/RSPDriver/src/Makefile.am         |   8 +
 MAC/APL/PIC/RSPDriver/src/RSPDriver.cc        | 987 +++++++++---------
 MAC/APL/PIC/RSPDriver/src/RSPDriver.h         |   5 +-
 MAC/APL/PIC/RSPDriver/src/RawBlockRead.cc     | 136 +++
 MAC/APL/PIC/RSPDriver/src/RawBlockRead.h      |  57 +
 MAC/APL/PIC/RSPDriver/src/RawBlockWrite.cc    | 134 +++
 MAC/APL/PIC/RSPDriver/src/RawBlockWrite.h     |  57 +
 MAC/APL/PIC/RSPDriver/src/RawEvent.cc         | 180 ++--
 MAC/APL/PIC/RSPDriver/src/Scheduler.cc        | 786 +++++++-------
 MAC/APL/PIC/RSPDriver/src/SetRawBlockCmd.cc   | 158 +++
 MAC/APL/PIC/RSPDriver/src/SetRawBlockCmd.h    |  81 ++
 MAC/APL/PIC/RSPDriver/src/SyncAction.cc       |  84 +-
 MAC/APL/PIC/RSPDriver/src/rspctl.cc           | 787 +++++++-------
 MAC/APL/PIC/RSPDriver/src/rspctl.h            |  23 +
 .../APL/RSP_Protocol/AllRegisterState.h       | 386 +++----
 .../include/APL/RSP_Protocol/MEPData.h        |  59 +-
 .../include/APL/RSP_Protocol/MEPHeader.h      | 804 +++++++-------
 .../PIC/RSP_Protocol/src/AllRegisterState.cc  | 108 +-
 .../PIC/RSP_Protocol/src/EPA_Protocol.prot    |   2 +
 MAC/APL/PIC/RSP_Protocol/src/MEPData.cc       |   5 +
 MAC/APL/PIC/RSP_Protocol/src/MEPHeader.cc     |   3 +
 .../PIC/RSP_Protocol/src/RSP_Protocol.prot    | 115 +-
 27 files changed, 3459 insertions(+), 2228 deletions(-)
 create mode 100644 MAC/APL/PIC/RSPDriver/src/GetRawBlockCmd.cc
 create mode 100644 MAC/APL/PIC/RSPDriver/src/GetRawBlockCmd.h
 create mode 100644 MAC/APL/PIC/RSPDriver/src/GetSPUStatusCmd.cc
 create mode 100644 MAC/APL/PIC/RSPDriver/src/RawBlockRead.cc
 create mode 100644 MAC/APL/PIC/RSPDriver/src/RawBlockRead.h
 create mode 100644 MAC/APL/PIC/RSPDriver/src/RawBlockWrite.cc
 create mode 100644 MAC/APL/PIC/RSPDriver/src/RawBlockWrite.h
 create mode 100644 MAC/APL/PIC/RSPDriver/src/SetRawBlockCmd.cc
 create mode 100644 MAC/APL/PIC/RSPDriver/src/SetRawBlockCmd.h

diff --git a/MAC/APL/PIC/RSPDriver/src/Cache.cc b/MAC/APL/PIC/RSPDriver/src/Cache.cc
index df0da81f35f..292886ddabc 100644
--- a/MAC/APL/PIC/RSPDriver/src/Cache.cc
+++ b/MAC/APL/PIC/RSPDriver/src/Cache.cc
@@ -77,6 +77,7 @@ CacheBuffer::CacheBuffer(Cache* cache) : m_cache(cache)
   LOG_DEBUG_STR("m_spustatus.subrack().size()  =" << m_spustatus.subrack().size()  * sizeof(EPA_Protocol::SPUBoardStatus));
   LOG_DEBUG_STR("m_tbbsettings().size()        =" << m_tbbsettings().size()        * sizeof(bitset<MEPHeader::N_SUBBANDS>));
   LOG_DEBUG_STR("m_bypasssettings().size()     =" << m_bypasssettings().size()     * sizeof(EPA_Protocol::DIAGBypass));
+  LOG_DEBUG_STR("m_rawDataBlock.size()         =" << ETH_DATA_LEN + sizeof (uint16));
 
   LOG_INFO_STR(formatString("CacheBuffer size = %d bytes",
 	         m_beamletweights().size()    	       
@@ -95,7 +96,8 @@ CacheBuffer::CacheBuffer(Cache* cache) : m_cache(cache)
 	       + m_tdstatus.board().size()    
 	       + m_spustatus.subrack().size()    
 	       + m_tbbsettings().size()
-	       + m_bypasssettings().size()));
+	       + m_bypasssettings().size()
+		   + ETH_DATA_LEN + sizeof(uint16)));
 }
 
 CacheBuffer::~CacheBuffer()
@@ -237,6 +239,12 @@ void CacheBuffer::reset(void)
   m_bypasssettings().resize(StationSettings::instance()->nrRcus() / MEPHeader::N_POL);
   BypassSettings::Control	control;
   m_bypasssettings() = control;
+
+	// clear rawdatablock
+	itsRawDataBlock.address = 0;
+	itsRawDataBlock.offset  = 0;
+	itsRawDataBlock.dataLen = 0;
+	memset(itsRawDataBlock.data, 0, RSP_RAW_BLOCK_SIZE);
 }
 
 RTC::Timestamp CacheBuffer::getTimestamp() const
@@ -329,75 +337,75 @@ BypassSettings& CacheBuffer::getBypassSettings()
   return m_bypasssettings;
 }
 
+RawDataBlock_t&	CacheBuffer::getRawDataBlock()
+{
+	return (itsRawDataBlock);
+}
+
 void CacheBuffer::setTimestamp(const RTC::Timestamp& timestamp)
 {
   m_timestamp = timestamp;
 }
 
-/**
- * Cache implementation
- */
-
+//
+// Cache implementation
+//
 Cache& Cache::getInstance()
 {
-  if (0 == m_instance)
-  {
-    m_instance = new Cache;
-    return *m_instance;
-  }
-  else return *m_instance;
+	if (!m_instance) {
+		m_instance = new Cache;
+	}
+	return (*m_instance);
 }
 
 Cache::Cache() : m_front(0), m_back(0)
 {
-  //
-  // initialize preset waveforms
-  //
-  WGSettings::initWaveformPresets();
+	// initialize preset waveforms
+	WGSettings::initWaveformPresets();
 
-  m_front = new CacheBuffer(this); ASSERT(m_front);
-  m_back = new CacheBuffer(this);  ASSERT(m_back);
+	m_front = new CacheBuffer(this); ASSERT(m_front);
+	m_back = new CacheBuffer(this);  ASSERT(m_back);
 
-  getState().init(StationSettings::instance()->nrRspBoards(),
-		  StationSettings::instance()->nrBlps(),
-		  StationSettings::instance()->nrRcus());
+	getState().init(StationSettings::instance()->nrRspBoards(),
+					StationSettings::instance()->nrBlps(),
+					StationSettings::instance()->nrRcus());
 
-  // start by writing the correct clock setting
-  Sequencer::getInstance().startSequence(Sequencer::SETCLOCK);
+	// start by writing the correct clock setting
+	Sequencer::getInstance().startSequence(Sequencer::SETCLOCK);
 }
 
 Cache::~Cache()
 {
-  if (m_front) delete m_front;
-  if (m_back) delete m_back;
+	if (m_front) delete m_front;
+	if (m_back) delete m_back;
 }
 
 void Cache::reset(void)
 {
-  m_front->reset();
-  m_back->reset();
+	m_front->reset();
+	m_back->reset();
 }
 
 void Cache::swapBuffers()
 {
-  if (GET_CONFIG("RSPDriver.XC_FILL", i)) {
-    // fill xcorr array by copying and taking complex conjugate of values mirrored in the diagonal
-    Array<complex<double>, 4> xc(m_back->getXCStats()());
-    firstIndex  i; secondIndex j; thirdIndex  k; fourthIndex  l;
-    xc = where(xc(i,j,k,l)==complex<double>(0,0), conj(xc(j,i,l,k)), xc(i,j,k,l));
-  }
-
-  CacheBuffer *tmp = m_front;
-  m_front = m_back;
-  m_back  = tmp;
+	if (GET_CONFIG("RSPDriver.XC_FILL", i)) {
+		// fill xcorr array by copying and taking complex conjugate of values mirrored in the diagonal
+		Array<complex<double>, 4> xc(m_back->getXCStats()());
+		firstIndex  i; secondIndex j; thirdIndex  k; fourthIndex  l;
+		xc = where(xc(i,j,k,l)==complex<double>(0,0), conj(xc(j,i,l,k)), xc(i,j,k,l));
+	}
+
+	CacheBuffer *tmp = m_front;
+	m_front = m_back;
+	m_back  = tmp;
 }
 
 CacheBuffer& Cache::getFront()
 {
-  return *m_front;
+	return *m_front;
 }
 
 CacheBuffer& Cache::getBack()
 {
-  return *m_back;
+	return *m_back;
 }
diff --git a/MAC/APL/PIC/RSPDriver/src/Cache.h b/MAC/APL/PIC/RSPDriver/src/Cache.h
index 5205c499541..264ce76dfde 100644
--- a/MAC/APL/PIC/RSPDriver/src/Cache.h
+++ b/MAC/APL/PIC/RSPDriver/src/Cache.h
@@ -33,59 +33,58 @@
 namespace LOFAR {
   namespace RSP {
 
-    class Cache; // forward declaration
-    class CacheBuffer
-    {
-    public:
-      /**
-       * Constructors for a Cache object.
-       */
-      CacheBuffer(Cache* cache);
-
-      /* Destructor for Cache. */
-      virtual ~CacheBuffer();
-
-      /*
-       * Reset cache to default values.
-       * Also called by constructor to initialize the cache.
-       */
-      void reset(void);
-
-      /*@{*/
-      /**
-       * Data access methods.
-       */
-      RTC::Timestamp                   getTimestamp() const;
-      RSP_Protocol::BeamletWeights&    getBeamletWeights();
-      RSP_Protocol::SubbandSelection&  getSubbandSelection();
-      RSP_Protocol::RCUSettings&       getRCUSettings();
-      RSP_Protocol::HBASettings&       getHBASettings();
-      RSP_Protocol::HBASettings&       getHBAReadings();
-      RSP_Protocol::RSUSettings&       getRSUSettings();
-      RSP_Protocol::WGSettings&        getWGSettings();
-      RSP_Protocol::SystemStatus&      getSystemStatus();
-      RSP_Protocol::Statistics&        getSubbandStats();
-      RSP_Protocol::Statistics&        getBeamletStats();
-      RSP_Protocol::XCStatistics&      getXCStats();
-      RSP_Protocol::Versions&          getVersions();
-      uint32&                          getClock();
-      RSP_Protocol::TDStatus&          getTDStatus();
-      RSP_Protocol::SPUStatus&         getSPUStatus();
-      RSP_Protocol::TBBSettings&       getTBBSettings();
-      RSP_Protocol::BypassSettings&    getBypassSettings();
-      /*@}*/
-
-      /**
-       * update timestamp
-       */
-      void setTimestamp(const RTC::Timestamp& timestamp);
-
-      /**
-       * Get const pointer to parent cache.
-       */
-      Cache& getCache() { return *m_cache; }
-
-    private:
+class Cache; // forward declaration
+
+typedef struct {
+	uint32		address;
+	uint16		offset;
+	uint16		dataLen;
+	uint8		data [RSP_RAW_BLOCK_SIZE];
+} RawDataBlock_t;
+
+class CacheBuffer
+{
+public:
+	// Constructors for a Cache object.
+	CacheBuffer(Cache* cache);
+
+	// Destructor for Cache. 
+	virtual ~CacheBuffer();
+
+	// Reset cache to default values.
+	// Also called by constructor to initialize the cache.
+	void reset(void);
+
+	/*@{*/
+	// Data access methods.
+	RTC::Timestamp                   getTimestamp() const;
+	RSP_Protocol::BeamletWeights&    getBeamletWeights();
+	RSP_Protocol::SubbandSelection&  getSubbandSelection();
+	RSP_Protocol::RCUSettings&       getRCUSettings();
+	RSP_Protocol::HBASettings&       getHBASettings();
+	RSP_Protocol::HBASettings&       getHBAReadings();
+	RSP_Protocol::RSUSettings&       getRSUSettings();
+	RSP_Protocol::WGSettings&        getWGSettings();
+	RSP_Protocol::SystemStatus&      getSystemStatus();
+	RSP_Protocol::Statistics&        getSubbandStats();
+	RSP_Protocol::Statistics&        getBeamletStats();
+	RSP_Protocol::XCStatistics&      getXCStats();
+	RSP_Protocol::Versions&          getVersions();
+	uint32&                          getClock();
+	RSP_Protocol::TDStatus&          getTDStatus();
+	RSP_Protocol::SPUStatus&         getSPUStatus();
+	RSP_Protocol::TBBSettings&       getTBBSettings();
+	RSP_Protocol::BypassSettings&    getBypassSettings();
+	RawDataBlock_t&					 getRawDataBlock();
+	/*@}*/
+
+	// update timestamp
+	void setTimestamp(const RTC::Timestamp& timestamp);
+
+	// Get const pointer to parent cache.
+	Cache& getCache() { return *m_cache; }
+
+private:
 	// NOTE [reo]: The relation between the RSPprotocol classes,
 	//	the EPAProtocol classes and the cache is not implemented 
 	//	in the right way. The Cache should consist of (blitz)
@@ -97,92 +96,73 @@ namespace LOFAR {
 	//	indicates that the RSP class can contain many elements,
 	//	which is never the case.
 
-      CacheBuffer(); // prevent default construction
-
-      RTC::Timestamp                 m_timestamp;
-
-      RSP_Protocol::BeamletWeights   m_beamletweights;
-      RSP_Protocol::SubbandSelection m_subbandselection;
-      RSP_Protocol::RCUSettings      m_rcusettings;
-      RSP_Protocol::HBASettings      m_hbasettings;
-      RSP_Protocol::HBASettings      m_hbareadings;
-      RSP_Protocol::RSUSettings      m_rsusettings;
-      RSP_Protocol::WGSettings       m_wgsettings;
-      RSP_Protocol::Statistics       m_subbandstats;
-      RSP_Protocol::Statistics       m_beamletstats;
-      RSP_Protocol::XCStatistics     m_xcstats;
-      RSP_Protocol::SystemStatus     m_systemstatus;
-      RSP_Protocol::Versions         m_versions;
-      uint32                         m_clock;
-      RSP_Protocol::TDStatus         m_tdstatus;
-      RSP_Protocol::SPUStatus        m_spustatus;
-      RSP_Protocol::TBBSettings      m_tbbsettings;
-      RSP_Protocol::BypassSettings   m_bypasssettings;
-
-      Cache* m_cache;
-    };
-
-    /**
-     * Singleton class containing the data caches.
-     */
-    class Cache
-    {
-    public:
-      /*@{*/
-      /**
-       * Constructor/destructor
-       */
-      static Cache& getInstance();
-      virtual ~Cache();
-      /*@}*/
-
-      /*
-       * Reset cache front and back buffers.
-       */
-      void reset(void);
-
-      /**
-       * Swap the front and back buffers.
-       */
-      void swapBuffers();
-
-      /**
-       * Get front/back buffers.
-       */
-      CacheBuffer& getFront();
-      CacheBuffer& getBack();
-
-      /**
-       * Get register states.
-       */
-      AllRegisterState& getState() { return m_allstate; }
-
-    private:
-
-      /**
-       * Direct construction not allowed.
-       */
-      Cache();
-
-      /**
-       * Keep register update state.
-       */
-      AllRegisterState m_allstate; // communication status of all register
-
-      /*@{*/
-      /**
-       * Front and back buffers.
-       */
-      CacheBuffer* m_front;
-      CacheBuffer* m_back;
-      /*@}*/
-
-      /**
-       * Singleton class.
-       */
-      static Cache* m_instance;
-    };
-  };
+	CacheBuffer(); // prevent default construction
+
+	// --- datamembers ---
+	RTC::Timestamp                 m_timestamp;
+	RSP_Protocol::BeamletWeights   m_beamletweights;
+	RSP_Protocol::SubbandSelection m_subbandselection;
+	RSP_Protocol::RCUSettings      m_rcusettings;
+	RSP_Protocol::HBASettings      m_hbasettings;
+	RSP_Protocol::HBASettings      m_hbareadings;
+	RSP_Protocol::RSUSettings      m_rsusettings;
+	RSP_Protocol::WGSettings       m_wgsettings;
+	RSP_Protocol::Statistics       m_subbandstats;
+	RSP_Protocol::Statistics       m_beamletstats;
+	RSP_Protocol::XCStatistics     m_xcstats;
+	RSP_Protocol::SystemStatus     m_systemstatus;
+	RSP_Protocol::Versions         m_versions;
+	uint32                         m_clock;
+	RSP_Protocol::TDStatus         m_tdstatus;
+	RSP_Protocol::SPUStatus        m_spustatus;
+	RSP_Protocol::TBBSettings      m_tbbsettings;
+	RSP_Protocol::BypassSettings   m_bypasssettings;
+	RawDataBlock_t				   itsRawDataBlock;
+
+	Cache* m_cache;		// pointer to container
 };
+
+// Singleton class containing the data caches.
+class Cache
+{
+public:
+	/*@{*/
+	// Constructor/destructor
+	static Cache& getInstance();
+	virtual ~Cache();
+	/*@}*/
+
+	// Reset cache front and back buffers.
+	void reset(void);
+
+	// Swap the front and back buffers.
+	void swapBuffers();
+
+	// Get front/back buffers.
+	CacheBuffer& getFront();
+	CacheBuffer& getBack();
+
+	// Get register states.
+	AllRegisterState& getState() { return m_allstate; }
+
+private:
+	// Direct construction not allowed.
+	Cache();
+
+	// Keep register update state.
+	AllRegisterState m_allstate; // communication status of all register
+
+	/*@{*/
+	// Front and back buffers.
+	CacheBuffer* m_front;
+	CacheBuffer* m_back;
+	/*@}*/
+
+	// Singleton class.
+	static Cache* m_instance;
+};
+
+  }; // namespace 
+}; // namespace LOFAR
      
 #endif /* CACHE_H_ */
diff --git a/MAC/APL/PIC/RSPDriver/src/GetRawBlockCmd.cc b/MAC/APL/PIC/RSPDriver/src/GetRawBlockCmd.cc
new file mode 100644
index 00000000000..aa10d9a1e5e
--- /dev/null
+++ b/MAC/APL/PIC/RSPDriver/src/GetRawBlockCmd.cc
@@ -0,0 +1,157 @@
+//#  GetRawBlockCmd.cc: implementation of the GetRawBlockCmd class
+//#
+//#  Copyright (C) 2008
+//#  ASTRON (Netherlands Foundation for Research in Astronomy)
+//#  P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
+//#
+//#  This program is free software; you can redistribute it and/or modify
+//#  it under the terms of the GNU General Public License as published by
+//#  the Free Software Foundation; either version 2 of the License, or
+//#  (at your option) any later version.
+//#
+//#  This program is distributed in the hope that it will be useful,
+//#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//#  GNU General Public License for more details.
+//#
+//#  You should have received a copy of the GNU General Public License
+//#  along with this program; if not, write to the Free Software
+//#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//#
+//#  $Id$
+
+#include <lofar_config.h>
+#include <Common/LofarLogger.h>
+#include <Common/hexdump.h>
+
+#include <APL/RSP_Protocol/RSP_Protocol.ph>
+#include <APL/RTCCommon/PSAccess.h>
+#include <blitz/array.h>
+
+#include "StationSettings.h"
+#include "GetRawBlockCmd.h"
+
+namespace LOFAR {
+  namespace RSP {
+//	using namespace blitz;
+	using namespace RSP_Protocol;
+	using namespace RTC;		// Timestamp
+
+//
+// GetRawBlockCmd(event, port, oper)
+//
+GetRawBlockCmd::GetRawBlockCmd(GCFEvent& event, GCFPortInterface& port, Operation oper)
+{
+	itsEvent = new RSPGetblockEvent(event);
+
+	setOperation(oper);
+	setPeriod(0);
+	setPort(port);
+}
+
+//
+// ~GetRawBlockCmd()
+//
+GetRawBlockCmd::~GetRawBlockCmd()
+{
+	delete itsEvent;
+}
+
+//
+// ack(cache)
+//
+void GetRawBlockCmd::ack(CacheBuffer& cache)
+{
+	RSPGetblockackEvent ack;
+	RawDataBlock_t&		rdb = cache.getRawDataBlock();
+	ack.timestamp = getTimestamp();
+	ack.boardID	  = itsEvent->boardID;
+	ack.status 	  = SUCCESS;
+	ack.dataLen   = rdb.dataLen;
+	memcpy(ack.data, rdb.data, ack.dataLen);
+
+	getPort()->send(ack);
+}
+
+//
+// apply(cache, setModFlag)
+//
+void GetRawBlockCmd::apply(CacheBuffer& cache, bool setModFlag)
+{
+	// fill the cache with the request and tickle it.
+//	LOG_INFO(formatString("@@@GetRawBlockCmd::apply(%d,%0X,%d,%d)", 
+//			itsEvent->boardID, itsEvent->address, itsEvent->offset, itsEvent->dataLen));
+
+	// NOTE: [REO] I expected that the next 4 lines could also be in the if(setModFlag)
+	//		 but it turned out that the info is than in the front cache when the RawDataBlockRead
+	//		 command needs it!!!
+	//		 Since only one command can be scheduled at the time, I write it in both caches.
+
+	// copy information (always?) to the cache
+	RawDataBlock_t&	rdb = cache.getRawDataBlock();
+	rdb.address = itsEvent->address;
+	rdb.offset  = itsEvent->offset;
+	rdb.dataLen = itsEvent->dataLen;
+
+	if (setModFlag) {
+		// tell cache(status) that we expect a write(!) action.
+		cache.getCache().getState().rawdataread().write(itsEvent->boardID);
+	}
+}
+
+//
+// complete(cache)
+//
+void GetRawBlockCmd::complete(CacheBuffer& cache)
+{
+	ack(cache);
+}
+
+//
+// getTimeStamp()
+//
+const Timestamp& GetRawBlockCmd::getTimestamp() const
+{
+	return (itsEvent->timestamp);
+}
+
+//
+// setTimestamp(timestamp)
+//
+void GetRawBlockCmd::setTimestamp(const Timestamp& timestamp)
+{
+	itsEvent->timestamp = timestamp;
+}
+
+//
+// validate()
+//
+bool GetRawBlockCmd::validate() const
+{
+	return (true);
+}
+
+//
+// readFromCache()
+//
+bool GetRawBlockCmd::readFromCache() const
+{
+	return (false);
+}
+
+//
+// ack_fail()
+//
+void GetRawBlockCmd::ack_fail()
+{
+	RSPGetblockackEvent ack;
+	ack.timestamp = getTimestamp();
+	ack.status 	  = FAILURE;
+	ack.dataLen   = 0;
+	LOG_INFO ("GetRawBlockCmd::ack_fail");
+
+	getPort()->send(ack);
+}
+
+  } // namepsace RSP
+} // namespace LOFAR
diff --git a/MAC/APL/PIC/RSPDriver/src/GetRawBlockCmd.h b/MAC/APL/PIC/RSPDriver/src/GetRawBlockCmd.h
new file mode 100644
index 00000000000..c8d615683f9
--- /dev/null
+++ b/MAC/APL/PIC/RSPDriver/src/GetRawBlockCmd.h
@@ -0,0 +1,81 @@
+//#  -*- mode: c++ -*-
+//#
+//#  GetRawBlockCmd.h: Get system status command.
+//#
+//#  Copyright (C) 2008
+//#  ASTRON (Netherlands Foundation for Research in Astronomy)
+//#  P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
+//#
+//#  This program is free software; you can redistribute it and/or modify
+//#  it under the terms of the GNU General Public License as published by
+//#  the Free Software Foundation; either version 2 of the License, or
+//#  (at your option) any later version.
+//#
+//#  This program is distributed in the hope that it will be useful,
+//#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//#  GNU General Public License for more details.
+//#
+//#  You should have received a copy of the GNU General Public License
+//#  along with this program; if not, write to the Free Software
+//#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//#
+//#  $Id$
+
+#ifndef GET_RAWBLOCK_CMD_H
+#define GET_RAWBLOCK_CMD_H
+
+#include "Command.h"
+#include <APL/RSP_Protocol/RSP_Protocol.ph>
+
+#include <Common/LofarTypes.h>
+#include <GCF/TM/GCF_Control.h>
+
+namespace LOFAR {
+  namespace RSP {
+
+class GetRawBlockCmd : public Command
+{
+public:
+	// Constructors for a GetRawBlockCmd object.
+	GetRawBlockCmd(GCFEvent& event, GCFPortInterface& port, Operation oper);
+
+	// Destructor for GetRawBlockCmd. */
+	virtual ~GetRawBlockCmd();
+
+	// Acknowledge the command by sending the appropriate
+	// response on m_port.
+	virtual void ack(CacheBuffer& cache);
+
+	// Make necessary changes to the cache for the next synchronization.
+	// Any changes will be sent to the RSP boards.
+	virtual void apply(CacheBuffer& cache, bool setModFlag = true);
+
+	// Complete the command by sending the appropriate response on
+	// the m_answerport;
+	virtual void complete(CacheBuffer& cache);
+
+	//@{
+	// get timestamp of the event
+	virtual const RTC::Timestamp& getTimestamp() const;
+	virtual void setTimestamp(const RTC::Timestamp& timestamp);
+	//@}
+
+	// Range check the parameters of the event.
+	virtual bool validate() const;
+
+	// Return true if value should be read from cache.
+	bool readFromCache() const;
+
+	// Send failure ack.
+	void ack_fail();
+
+private:
+	GetRawBlockCmd();				// Default construction is not allowed.
+	RSPGetblockEvent* 	itsEvent;
+};
+
+  } // namespace RSP
+} // namespace LOFAR
+     
+#endif /* GET_RAWBLOCK_CMD_H */
diff --git a/MAC/APL/PIC/RSPDriver/src/GetSPUStatusCmd.cc b/MAC/APL/PIC/RSPDriver/src/GetSPUStatusCmd.cc
new file mode 100644
index 00000000000..5d621e5e1bf
--- /dev/null
+++ b/MAC/APL/PIC/RSPDriver/src/GetSPUStatusCmd.cc
@@ -0,0 +1,142 @@
+//#  GetSPUStatusCmd.cc: implementation of the GetSPUStatusCmd class
+//#
+//#  Copyright (C) 2008
+//#  ASTRON (Netherlands Foundation for Research in Astronomy)
+//#  P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
+//#
+//#  This program is free software; you can redistribute it and/or modify
+//#  it under the terms of the GNU General Public License as published by
+//#  the Free Software Foundation; either version 2 of the License, or
+//#  (at your option) any later version.
+//#
+//#  This program is distributed in the hope that it will be useful,
+//#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//#  GNU General Public License for more details.
+//#
+//#  You should have received a copy of the GNU General Public License
+//#  along with this program; if not, write to the Free Software
+//#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//#
+//#  $Id$
+
+#include <lofar_config.h>
+#include <Common/LofarLogger.h>
+
+#include <APL/RSP_Protocol/RSP_Protocol.ph>
+#include <APL/RTCCommon/PSAccess.h>
+#include <blitz/array.h>
+
+#include "StationSettings.h"
+#include "GetSPUStatusCmd.h"
+
+namespace LOFAR {
+  namespace RSP {
+//	using namespace blitz;
+	using namespace RSP_Protocol;
+	using namespace RTC;		// Timestamp
+
+//
+// GetSPUStatusCmd(event, port, oper)
+//
+GetSPUStatusCmd::GetSPUStatusCmd(GCFEvent& event, GCFPortInterface& port, Operation oper)
+{
+	itsEvent = new RSPGetspustatusEvent(event);
+
+	setOperation(oper);
+	setPeriod(0);
+	setPort(port);
+}
+
+//
+// ~GetSPUStatusCmd()
+//
+GetSPUStatusCmd::~GetSPUStatusCmd()
+{
+	delete itsEvent;
+}
+
+//
+// ack(cache)
+//
+void GetSPUStatusCmd::ack(CacheBuffer& cache)
+{
+	RSPGetspustatusackEvent ack;
+	ack.timestamp = getTimestamp();
+	ack.status = SUCCESS;
+	ack.spustatus.subrack().resize(cache.getSPUStatus().subrack().size());
+	ack.spustatus = cache.getSPUStatus();
+
+	getPort()->send(ack);
+}
+
+//
+// apply(cache, setModFlag)
+//
+void GetSPUStatusCmd::apply(CacheBuffer& /*cache*/, bool /*setModFlag*/)
+{
+	// no-op
+}
+
+//
+// complete(cache)
+//
+void GetSPUStatusCmd::complete(CacheBuffer& cache)
+{
+	ack(cache);
+}
+
+//
+// getTimeStamp()
+//
+const Timestamp& GetSPUStatusCmd::getTimestamp() const
+{
+	return (itsEvent->timestamp);
+}
+
+//
+// setTimestamp(timestamp)
+//
+void GetSPUStatusCmd::setTimestamp(const Timestamp& timestamp)
+{
+	itsEvent->timestamp = timestamp;
+}
+
+//
+// validate()
+//
+bool GetSPUStatusCmd::validate() const
+{
+	return (true);
+}
+
+//
+// readFromCache()
+//
+bool GetSPUStatusCmd::readFromCache() const
+{
+	return (itsEvent->cache);
+}
+
+//
+// ack_fail()
+//
+void GetSPUStatusCmd::ack_fail()
+{
+	RSPGetspustatusackEvent ack;
+
+	ack.timestamp = Timestamp(0,0);
+	ack.status = FAILURE;
+
+	// send back dummy status array
+	ack.spustatus.subrack().resize(1);
+	SPUBoardStatus spustatusinit;
+	memset(&spustatusinit, 0, sizeof(SPUBoardStatus));
+
+	ack.spustatus.subrack()(0) = spustatusinit;
+
+	getPort()->send(ack);
+}
+
+  } // namepsace RSP
+} // namespace LOFAR
diff --git a/MAC/APL/PIC/RSPDriver/src/Makefile.am b/MAC/APL/PIC/RSPDriver/src/Makefile.am
index 995ca09b932..56f52e824b4 100644
--- a/MAC/APL/PIC/RSPDriver/src/Makefile.am
+++ b/MAC/APL/PIC/RSPDriver/src/Makefile.am
@@ -150,6 +150,10 @@ RSPDriverFiles = \
 	GetBypassCmd.cc \
 	GetSPUStatusCmd.h \
 	GetSPUStatusCmd.cc \
+	GetRawBlockCmd.h \
+	GetRawBlockCmd.cc \
+	SetRawBlockCmd.h \
+	SetRawBlockCmd.cc \
 	\
 	SyncAction.h \
 	SyncAction.cc \
@@ -175,6 +179,10 @@ RSPDriverFiles = \
 	RCUResultRead.cc \
 	RCURead.h \
 	RCURead.cc \
+	RawBlockRead.h \
+	RawBlockRead.cc \
+	RawBlockWrite.h \
+	RawBlockWrite.cc \
 	StatusRead.h \
 	StatusRead.cc \
 	SstRead.h \
diff --git a/MAC/APL/PIC/RSPDriver/src/RSPDriver.cc b/MAC/APL/PIC/RSPDriver/src/RSPDriver.cc
index 730e5aa8bab..fe81c82b77d 100644
--- a/MAC/APL/PIC/RSPDriver/src/RSPDriver.cc
+++ b/MAC/APL/PIC/RSPDriver/src/RSPDriver.cc
@@ -82,6 +82,8 @@
 #include "SetBypassCmd.h"
 #include "GetBypassCmd.h"
 #include "GetSPUStatusCmd.h"
+#include "SetRawBlockCmd.h"
+#include "GetRawBlockCmd.h"
 
 #include "RSUWrite.h"
 #include "BSWrite.h"
@@ -116,6 +118,8 @@
 #include "BypassRead.h"
 #include "BypassWrite.h"
 #include "RADWrite.h"
+#include "RawBlockRead.h"
+#include "RawBlockWrite.h"
 #include "TimestampWrite.h"
 
 #include "Cache.h"
@@ -195,7 +199,7 @@ void parseOptions(int           argc,
 //
 RSPDriver::RSPDriver(string name) :
 	GCFTask((State)&RSPDriver::initial, name), 
-	m_board			(0), 
+	m_boardPorts			(0), 
 	m_scheduler		(),
 	m_update_counter(0), 
 	m_n_updates		(0), 
@@ -253,8 +257,8 @@ RSPDriver::RSPDriver(string name) :
 
 	// open port with RSP board
 	LOG_DEBUG("Connecting to RSPboards");
-	m_board = new GCFETHRawPort[StationSettings::instance()->nrRspBoards()];
-	ASSERT(m_board);
+	m_boardPorts = new GCFETHRawPort[StationSettings::instance()->nrRspBoards()];
+	ASSERT(m_boardPorts);
 
 	//
 	// Get MAC addresses of RSPBoards
@@ -269,11 +273,11 @@ RSPDriver::RSPDriver(string name) :
 		strncpy(macaddrstr, GET_CONFIG_STRING(paramname), 64);
 
 		LOG_DEBUG_STR("initializing board " << boardname << ":" << macaddrstr);
-		m_board[boardid].init(*this, boardname, GCFPortInterface::SAP, EPA_PROTOCOL,true /*raw*/);
-		m_board[boardid].setAddr(GET_CONFIG_STRING("RSPDriver.IF_NAME"), macaddrstr);
+		m_boardPorts[boardid].init(*this, boardname, GCFPortInterface::SAP, EPA_PROTOCOL,true /*raw*/);
+		m_boardPorts[boardid].setAddr(GET_CONFIG_STRING("RSPDriver.IF_NAME"), macaddrstr);
 
 		// set ethertype to 0x10FA so Ethereal can decode EPA messages
-		m_board[boardid].setEtherType(ETHERTYPE_EPA);
+		m_boardPorts[boardid].setEtherType(ETHERTYPE_EPA);
 	}
 
 	addAllSyncActions();
@@ -284,7 +288,7 @@ RSPDriver::RSPDriver(string name) :
 //
 RSPDriver::~RSPDriver()
 {
-	delete [] m_board;
+	delete [] m_boardPorts;
 }
 
 //
@@ -294,7 +298,7 @@ bool RSPDriver::isEnabled()
 {
 	bool enabled = true;
 	for (int boardid = 0; boardid < StationSettings::instance()->nrRspBoards(); boardid++) {
-		if (!m_board[boardid].isConnected()) {
+		if (!m_boardPorts[boardid].isConnected()) {
 			enabled = false;
 			break;
 		}
@@ -337,348 +341,343 @@ bool RSPDriver::isEnabled()
  */
 void RSPDriver::addAllSyncActions()
 {
-  /**
-   * For each board a separate BWSync instance is created which handles
-   * the synchronization of data between the board and the cache for that board.
-   */
-  for (int boardid = 0; boardid < StationSettings::instance()->nrRspBoards(); boardid++) {
-    /*
-     * Always read status and version first.
-     */
-    if (1 == GET_CONFIG("RSPDriver.READ_STATUS", i)) {
-      StatusRead* statusread = new StatusRead(m_board[boardid], boardid);
-      ASSERT(statusread);
-      m_scheduler.addSyncAction(statusread);
-    }
-    if (1 == GET_CONFIG("RSPDriver.READ_VERSION", i)) {
-      VersionsRead* versionread = new VersionsRead(m_board[boardid], boardid);
-      ASSERT(versionread);
-      m_scheduler.addSyncAction(versionread);
-    }
+	// For each board a separate BWSync instance is created which handles
+	// the synchronization of data between the board and the cache for that board.
+	for (int boardid = 0; boardid < StationSettings::instance()->nrRspBoards(); boardid++) {
+		// Always read status and version first.
+		if (1 == GET_CONFIG("RSPDriver.READ_STATUS", i)) {
+			StatusRead* statusread = new StatusRead(m_boardPorts[boardid], boardid);
+			ASSERT(statusread);
+			m_scheduler.addSyncAction(statusread);
+		}
+		if (1 == GET_CONFIG("RSPDriver.READ_VERSION", i)) {
+			VersionsRead* versionread = new VersionsRead(m_boardPorts[boardid], boardid);
+			ASSERT(versionread);
+			m_scheduler.addSyncAction(versionread);
+		}
 
-    /*
-     * Schedule register writes for soft PPS if configured.
-     *
-     * - This means disabling the external sync on all FPGA's
-     *   by broadcasting a CR_CONTROL write.
-     * - Requesting a soft PPS by writing a 1 in the SYNC bit
-     *   of the RSU_RESET register.
-     */  
-    if (1 == GET_CONFIG("RSPDriver.SOFTPPS", i)) {
-      WriteReg* writereg = 0;
-
-      // Disable External Sync for all FPGA's
-      writereg = new WriteReg(m_board[boardid], boardid,
-                              MEPHeader::DST_ALL,
-                              MEPHeader::CR,
-                              MEPHeader::CR_SYNCDISABLE,
-                              MEPHeader::CR_CONTROL_SIZE);
-      ASSERT(writereg);
-      writereg->setSrcAddress((void*)&g_CR_SYNCDISABLE);
-      m_scheduler.addSyncAction(writereg);
-
-      // Send PPS to BP which sends signal to configuration device
-      // which in turn sends a PPS to the AP's
-      writereg = new WriteReg(m_board[boardid], boardid,
-                              MEPHeader::DST_RSP,
-                              MEPHeader::RSU,
-                              MEPHeader::RSU_RESET,
-                              MEPHeader::RSU_RESET_SIZE);
-      ASSERT(writereg);
-      writereg->setSrcAddress((void*)&g_RSU_RESET_SYNC);
-      m_scheduler.addSyncAction(writereg);
-    }
+		// Schedule register writes for soft PPS if configured.
+		//
+		// - This means disabling the external sync on all FPGA's
+		//   by broadcasting a CR_CONTROL write.
+		// - Requesting a soft PPS by writing a 1 in the SYNC bit
+		//   of the RSU_RESET register.
+		if (1 == GET_CONFIG("RSPDriver.SOFTPPS", i)) {
+			WriteReg* writereg = 0;
+
+			// Disable External Sync for all FPGA's
+			writereg = new WriteReg(m_boardPorts[boardid], boardid,
+									MEPHeader::DST_ALL,
+									MEPHeader::CR,
+									MEPHeader::CR_SYNCDISABLE,
+									MEPHeader::CR_CONTROL_SIZE);
+			ASSERT(writereg);
+			writereg->setSrcAddress((void*)&g_CR_SYNCDISABLE);
+			m_scheduler.addSyncAction(writereg);
+
+			// Send PPS to BP which sends signal to configuration device
+			// which in turn sends a PPS to the AP's
+			writereg = new WriteReg(m_boardPorts[boardid], boardid,
+									MEPHeader::DST_RSP,
+									MEPHeader::RSU,
+									MEPHeader::RSU_RESET,
+									MEPHeader::RSU_RESET_SIZE);
+			ASSERT(writereg);
+			writereg->setSrcAddress((void*)&g_RSU_RESET_SYNC);
+			m_scheduler.addSyncAction(writereg);
+		}
 
-    // order is important; TDSResultRead should be added before TDSProtocolWrite
-    if (1 == GET_CONFIG("RSPDriver.READWRITE_TDS_PROTOCOL", i)) {
-      TDSResultWrite* tdsresultwrite = new TDSResultWrite(m_board[boardid], boardid);
-      ASSERT(tdsresultwrite);
-      m_scheduler.addSyncAction(tdsresultwrite);
+		// order is important; TDSResultRead should be added before TDSProtocolWrite
+		if (1 == GET_CONFIG("RSPDriver.READWRITE_TDS_PROTOCOL", i)) {
+			TDSResultWrite* tdsresultwrite = new TDSResultWrite(m_boardPorts[boardid], boardid);
+			ASSERT(tdsresultwrite);
+			m_scheduler.addSyncAction(tdsresultwrite);
 
-      TDSProtocolWrite* tdsprotocolwrite = new TDSProtocolWrite(m_board[boardid], boardid);
-      ASSERT(tdsprotocolwrite);
-      m_scheduler.addSyncAction(tdsprotocolwrite);
+			TDSProtocolWrite* tdsprotocolwrite = new TDSProtocolWrite(m_boardPorts[boardid], boardid);
+			ASSERT(tdsprotocolwrite);
+			m_scheduler.addSyncAction(tdsprotocolwrite);
 
-      TDSResultRead* tdsresultread = new TDSResultRead(m_board[boardid], boardid);
-      ASSERT(tdsresultread);
-      m_scheduler.addSyncAction(tdsresultread);
-    }
+			TDSResultRead* tdsresultread = new TDSResultRead(m_boardPorts[boardid], boardid);
+			ASSERT(tdsresultread);
+			m_scheduler.addSyncAction(tdsresultread);
+		}
 
-    if (1 == GET_CONFIG("RSPDriver.READWRITE_TDSSTATUS", i)) {
-      TDSStatusWrite* tdsstatuswrite = new TDSStatusWrite(m_board[boardid], boardid);
-      ASSERT(tdsstatuswrite);
-      m_scheduler.addSyncAction(tdsstatuswrite);
-      
-      TDSStatusRead* tdsstatusread = new TDSStatusRead(m_board[boardid], boardid);
-      ASSERT(tdsstatusread);
-      m_scheduler.addSyncAction(tdsstatusread);
-    }
+		if (1 == GET_CONFIG("RSPDriver.READWRITE_TDSSTATUS", i)) {
+			TDSStatusWrite* tdsstatuswrite = new TDSStatusWrite(m_boardPorts[boardid], boardid);
+			ASSERT(tdsstatuswrite);
+			m_scheduler.addSyncAction(tdsstatuswrite);
 
-    /*
-     * Clear the board if needed.
-     * This needs to be first after WRITE_TDS_PROTOCOL, but before
-     * WRITE_BS.
-     */
-    if (1 == GET_CONFIG("RSPDriver.WRITE_RSU", i)) {
-      RSUWrite* rsuwrite = new RSUWrite(m_board[boardid], boardid, m_scheduler);
-      ASSERT(rsuwrite);
-      m_scheduler.addSyncAction(rsuwrite);
-    }
+			TDSStatusRead* tdsstatusread = new TDSStatusRead(m_boardPorts[boardid], boardid);
+			ASSERT(tdsstatusread);
+			m_scheduler.addSyncAction(tdsstatusread);
+		}
 
-    /*
-     * Set correct number of samples per interval
-     * This needs to be done before RCU and WG registers,
-     * but after WRITE_TDS_PROTOCOL
-     */
-    if (1 == GET_CONFIG("RSPDriver.WRITE_BS", i)) {
-      for (int blp = 0; blp < StationSettings::instance()->nrBlpsPerBoard(); blp++) {
-        BSWrite* bswrite = new BSWrite(m_board[boardid], boardid, blp, m_scheduler);
-        ASSERT(bswrite);
-        m_scheduler.addSyncAction(bswrite);
-      }
-    }
+		// Clear the board if needed.
+		// This needs to be first after WRITE_TDS_PROTOCOL, but before
+		// WRITE_BS.
+		if (1 == GET_CONFIG("RSPDriver.WRITE_RSU", i)) {
+			RSUWrite* rsuwrite = new RSUWrite(m_boardPorts[boardid], boardid, m_scheduler);
+			ASSERT(rsuwrite);
+			m_scheduler.addSyncAction(rsuwrite);
+		}
 
-    if (1 == GET_CONFIG("RSPDriver.READ_BST", i)) {
-      BstRead* bstread = 0;
+		// Set correct number of samples per interval
+		// This needs to be done before RCU and WG registers,
+		// but after WRITE_TDS_PROTOCOL
+		if (1 == GET_CONFIG("RSPDriver.WRITE_BS", i)) {
+			for (int blp = 0; blp < StationSettings::instance()->nrBlpsPerBoard(); blp++) {
+				BSWrite* bswrite = new BSWrite(m_boardPorts[boardid], boardid, blp, m_scheduler);
+				ASSERT(bswrite);
+				m_scheduler.addSyncAction(bswrite);
+			}
+		}
 
-      bstread = new BstRead(m_board[boardid], boardid);
-      ASSERT(bstread);
-      m_scheduler.addSyncAction(bstread);
-    }
+		if (1 == GET_CONFIG("RSPDriver.READ_BST", i)) {
+			BstRead* bstread = 0;
+			bstread = new BstRead(m_boardPorts[boardid], boardid);
+			ASSERT(bstread);
+			m_scheduler.addSyncAction(bstread);
+		}
 
-    if (1 == GET_CONFIG("RSPDriver.READ_XST", i)) {
-      XstRead* xstread = 0;
+		if (1 == GET_CONFIG("RSPDriver.READ_XST", i)) {
+			XstRead* xstread = 0;
 
-      for (int regid = MEPHeader::XST_STATS; regid < MEPHeader::XST_NR_STATS; regid++)
-      {
-        xstread = new XstRead(m_board[boardid], boardid, regid);
-        ASSERT(xstread);
-        m_scheduler.addSyncAction(xstread);
-      }
-    }
+			for (int regid = MEPHeader::XST_STATS; regid < MEPHeader::XST_NR_STATS; regid++) {
+				xstread = new XstRead(m_boardPorts[boardid], boardid, regid);
+				ASSERT(xstread);
+				m_scheduler.addSyncAction(xstread);
+			}
+		}
 
-    if (1 == GET_CONFIG("RSPDriver.WRITE_CDO", i)) {
-      CDOWrite* cdowrite = new CDOWrite(m_board[boardid], boardid);
+		if (1 == GET_CONFIG("RSPDriver.WRITE_CDO", i)) {
+			CDOWrite* cdowrite = new CDOWrite(m_boardPorts[boardid], boardid);
+			m_scheduler.addSyncAction(cdowrite);
+
+			if (1 == GET_CONFIG("RSPDriver.READ_CDO", i)) {
+				// Read back CDO header contents
+				ReadReg* readreg = new ReadReg(m_boardPorts[boardid], boardid,
+												MEPHeader::DST_RSP,
+												MEPHeader::CDO,
+												MEPHeader::CDO_HEADER,
+												MEPHeader::CDO_HEADER_SIZE);
+				ASSERT(readreg);
+				m_scheduler.addSyncAction(readreg);
+			}
+		}
 
-      m_scheduler.addSyncAction(cdowrite);
+		if (1 == GET_CONFIG("RSPDriver.WRITE_RAD", i)) {
+			RADWrite* radwrite = new RADWrite(m_boardPorts[boardid], boardid);
+			m_scheduler.addSyncAction(radwrite);
+		}
 
-      if (1 == GET_CONFIG("RSPDriver.READ_CDO", i)) {
-	// Read back CDO header contents
-	ReadReg* readreg = new ReadReg(m_board[boardid], boardid,
-				       MEPHeader::DST_RSP,
-				       MEPHeader::CDO,
-				       MEPHeader::CDO_HEADER,
-				       MEPHeader::CDO_HEADER_SIZE);
-	ASSERT(readreg);
-	m_scheduler.addSyncAction(readreg);
-      }
-    }
+		for (int action = 0; action < 2; action++) {
+			if (action == GET_CONFIG("RSPDriver.LOOPBACK_MODE", i)) {
+				if (1 == GET_CONFIG("RSPDriver.WRITE_WG", i)) {
+					WGWrite* wgwrite = new WGWrite(m_boardPorts[boardid], boardid);
+					ASSERT(wgwrite);
+					m_scheduler.addSyncAction(wgwrite);
+				}
+			}
+			else {
+				if (1 == GET_CONFIG("RSPDriver.READ_WG", i)) {
+					WGRead* wgread = new WGRead(m_boardPorts[boardid], boardid);
+					ASSERT(wgread);
+					m_scheduler.addSyncAction(wgread);
+				}
+			}
+		}
 
-    if (1 == GET_CONFIG("RSPDriver.WRITE_RAD", i)) {
-      RADWrite* radwrite = new RADWrite(m_board[boardid], boardid);
-      m_scheduler.addSyncAction(radwrite);
-    }
+		// write Spectral Invertion information
+		if (GET_CONFIG("RSPDriver.WRITE_SI", i)) {
+			for (int blp = 0; blp < StationSettings::instance()->nrBlpsPerBoard(); blp++) {
+				BypassWrite* bypasswrite = new BypassWrite(m_boardPorts[boardid], boardid, blp);
+				ASSERT(bypasswrite);
+				m_scheduler.addSyncAction(bypasswrite);
+			}
+		}
 
-    for (int action = 0; action < 2; action++) {
-      if (action == GET_CONFIG("RSPDriver.LOOPBACK_MODE", i)) {
-        if (1 == GET_CONFIG("RSPDriver.WRITE_WG", i)) {
-          WGWrite* wgwrite = new WGWrite(m_board[boardid], boardid);
-          ASSERT(wgwrite);
-          m_scheduler.addSyncAction(wgwrite);
-        }
-      }
-      else {
-        if (1 == GET_CONFIG("RSPDriver.READ_WG", i)) {
-          WGRead* wgread = new WGRead(m_board[boardid], boardid);
-          ASSERT(wgread);
-          m_scheduler.addSyncAction(wgread);
-        }
-      }
-    }
+		if (1 == GET_CONFIG("RSPDriver.WRITE_TBB", i)) {
+			TBBSettingsWrite* tbbsettingswrite = new TBBSettingsWrite(m_boardPorts[boardid], boardid);
+			ASSERT(tbbsettingswrite);
+			m_scheduler.addSyncAction(tbbsettingswrite);
 
-    // write Spectral Invertion information
-    if (GET_CONFIG("RSPDriver.WRITE_SI", i)) {
-      for (int blp = 0; blp < StationSettings::instance()->nrBlpsPerBoard(); blp++) {
-        BypassWrite* bypasswrite = new BypassWrite(m_board[boardid], boardid, blp);
-        ASSERT(bypasswrite);
-        m_scheduler.addSyncAction(bypasswrite);
-	  }
-    }
+			TBBBandselWrite* tbbbandselwrite = new TBBBandselWrite(m_boardPorts[boardid], boardid);
+			ASSERT(tbbbandselwrite);
+			m_scheduler.addSyncAction(tbbbandselwrite);
+		}
 
-    if (1 == GET_CONFIG("RSPDriver.WRITE_TBB", i)) {
-      TBBSettingsWrite* tbbsettingswrite = new TBBSettingsWrite(m_board[boardid], boardid);
-      ASSERT(tbbsettingswrite);
-      m_scheduler.addSyncAction(tbbsettingswrite);
+		for (int action = 0; action < 2; action++) {
+			if (action == GET_CONFIG("RSPDriver.LOOPBACK_MODE", i)) {
+				if (1 == GET_CONFIG("RSPDriver.WRITE_SS", i)) {
+					SSWrite* sswrite = new SSWrite(m_boardPorts[boardid], boardid);
+					ASSERT(sswrite);
+					m_scheduler.addSyncAction(sswrite);
+				}
+			}
+			else {
+				if (1 == GET_CONFIG("RSPDriver.READ_SS", i)) {
+					SSRead* ssread = new SSRead(m_boardPorts[boardid], boardid);
+					ASSERT(ssread);
+					m_scheduler.addSyncAction(ssread);
+				}
+			}
+		}
 
-      TBBBandselWrite* tbbbandselwrite = new TBBBandselWrite(m_board[boardid], boardid);
-      ASSERT(tbbbandselwrite);
-      m_scheduler.addSyncAction(tbbbandselwrite);
-    }
-    
-    for (int action = 0; action < 2; action++) {
-      if (action == GET_CONFIG("RSPDriver.LOOPBACK_MODE", i)) {
-        if (1 == GET_CONFIG("RSPDriver.WRITE_SS", i)) {
-          SSWrite* sswrite = new SSWrite(m_board[boardid], boardid);
-          ASSERT(sswrite);
-          m_scheduler.addSyncAction(sswrite);
-        }
-      }
-      else {
-        if (1 == GET_CONFIG("RSPDriver.READ_SS", i)) {
-          SSRead* ssread = new SSRead(m_board[boardid], boardid);
-          ASSERT(ssread);
-          m_scheduler.addSyncAction(ssread);
-        }
-      }
-    }
+		//
+		// Depending on the value of RSPDriver.LOOPBACK_MODE either the 
+		// WRITE is done first or the READ is done first.
+		//
+		// If LOOPBACK_MODE == 0, the WRITE is done first.
+		// In this mode you can check with Ethereal that what was
+		// written is correctly read back from the board. This can
+		// be used to check that the RSP hardware or the EPAStub
+		// function correctly.
+		//
+		// If LOOPBACK_MODE == 1, the READ is done first.
+		// In this mode you can check with Ethereal that what was
+		// read from the EPAStub is written back in the same way.
+		// This is used to check whether the RSPDriver stores the
+		// information at the correct location in its cache.
+		//
+		// This is done in the same way for all read/write registers.
+		//
+		for (int action = 0; action < 2; action++) {
+			if (action == GET_CONFIG("RSPDriver.LOOPBACK_MODE", i)) {
+				if (1 == GET_CONFIG("RSPDriver.WRITE_BF", i)) {
+					BWWrite* bwwrite = 0;
+					for (int blp = 0; blp < StationSettings::instance()->nrBlpsPerBoard(); blp++) {
+						bwwrite = new BWWrite(m_boardPorts[boardid], boardid, blp, MEPHeader::BF_XROUT);
+						ASSERT(bwwrite);
+						m_scheduler.addSyncAction(bwwrite);
+						bwwrite = new BWWrite(m_boardPorts[boardid], boardid, blp, MEPHeader::BF_XIOUT);
+						ASSERT(bwwrite);
+						m_scheduler.addSyncAction(bwwrite);
+						bwwrite = new BWWrite(m_boardPorts[boardid], boardid, blp, MEPHeader::BF_YROUT);
+						ASSERT(bwwrite);
+						m_scheduler.addSyncAction(bwwrite);
+						bwwrite = new BWWrite(m_boardPorts[boardid], boardid, blp, MEPHeader::BF_YIOUT);
+						ASSERT(bwwrite);
+						m_scheduler.addSyncAction(bwwrite);
+					}
+				}
+
+				if (1 == GET_CONFIG("RSPDriver.WRITE_XBF", i)) {
+					XWWrite* xwwrite = 0;
+					for (int blp = 0; blp < StationSettings::instance()->nrBlpsPerBoard(); blp++) {
+						xwwrite = new XWWrite(m_boardPorts[boardid], boardid, blp, MEPHeader::BF_XROUT);
+						ASSERT(xwwrite);
+						m_scheduler.addSyncAction(xwwrite);
+						xwwrite = new XWWrite(m_boardPorts[boardid], boardid, blp, MEPHeader::BF_XIOUT);
+						ASSERT(xwwrite);
+						m_scheduler.addSyncAction(xwwrite);
+						xwwrite = new XWWrite(m_boardPorts[boardid], boardid, blp, MEPHeader::BF_YROUT);
+						ASSERT(xwwrite);
+						m_scheduler.addSyncAction(xwwrite);
+						xwwrite = new XWWrite(m_boardPorts[boardid], boardid, blp, MEPHeader::BF_YIOUT);
+						ASSERT(xwwrite);
+						m_scheduler.addSyncAction(xwwrite);
+					}
+				}
+			}
+			else {
+				if (1 == GET_CONFIG("RSPDriver.READ_BF", i)) {
+					BWRead* bwread = 0;
+					for (int blp = 0; blp < StationSettings::instance()->nrBlpsPerBoard(); blp++) {
+						bwread = new BWRead(m_boardPorts[boardid], boardid, blp, MEPHeader::BF_XROUT);
+						ASSERT(bwread);
+						m_scheduler.addSyncAction(bwread);
+						bwread = new BWRead(m_boardPorts[boardid], boardid, blp, MEPHeader::BF_XIOUT);
+						ASSERT(bwread);
+						m_scheduler.addSyncAction(bwread);
+						bwread = new BWRead(m_boardPorts[boardid], boardid, blp, MEPHeader::BF_YROUT);
+						ASSERT(bwread);
+						m_scheduler.addSyncAction(bwread);
+						bwread = new BWRead(m_boardPorts[boardid], boardid, blp, MEPHeader::BF_YIOUT);
+						ASSERT(bwread);
+						m_scheduler.addSyncAction(bwread);
+					}
+				}
+			}
+		}
 
-    //
-    // Depending on the value of RSPDriver.LOOPBACK_MODE either the 
-    // WRITE is done first or the READ is done first.
-    //
-    // If LOOPBACK_MODE == 0, the WRITE is done first.
-    // In this mode you can check with Ethereal that what was
-    // written is correctly read back from the board. This can
-    // be used to check that the RSP hardware or the EPAStub
-    // function correctly.
-    //
-    // If LOOPBACK_MODE == 1, the READ is done first.
-    // In this mode you can check with Ethereal that what was
-    // read from the EPAStub is written back in the same way.
-    // This is used to check whether the RSPDriver stores the
-    // information at the correct location in its cache.
-    //
-    // This is done in the same way for all read/write registers.
-    //
-    for (int action = 0; action < 2; action++) {
-      if (action == GET_CONFIG("RSPDriver.LOOPBACK_MODE", i)) {
-        if (1 == GET_CONFIG("RSPDriver.WRITE_BF", i)) {
-          BWWrite* bwwrite = 0;
-
-          for (int blp = 0; blp < StationSettings::instance()->nrBlpsPerBoard(); blp++) {
-            bwwrite = new BWWrite(m_board[boardid], boardid, blp, MEPHeader::BF_XROUT);
-            ASSERT(bwwrite);
-            m_scheduler.addSyncAction(bwwrite);
-            bwwrite = new BWWrite(m_board[boardid], boardid, blp, MEPHeader::BF_XIOUT);
-            ASSERT(bwwrite);
-            m_scheduler.addSyncAction(bwwrite);
-            bwwrite = new BWWrite(m_board[boardid], boardid, blp, MEPHeader::BF_YROUT);
-            ASSERT(bwwrite);
-            m_scheduler.addSyncAction(bwwrite);
-            bwwrite = new BWWrite(m_board[boardid], boardid, blp, MEPHeader::BF_YIOUT);
-            ASSERT(bwwrite);
-            m_scheduler.addSyncAction(bwwrite);
-          }
-        }
-        if (1 == GET_CONFIG("RSPDriver.WRITE_XBF", i)) {
-          XWWrite* xwwrite = 0;
-
-          for (int blp = 0; blp < StationSettings::instance()->nrBlpsPerBoard(); blp++) {
-            xwwrite = new XWWrite(m_board[boardid], boardid, blp, MEPHeader::BF_XROUT);
-            ASSERT(xwwrite);
-            m_scheduler.addSyncAction(xwwrite);
-            xwwrite = new XWWrite(m_board[boardid], boardid, blp, MEPHeader::BF_XIOUT);
-            ASSERT(xwwrite);
-            m_scheduler.addSyncAction(xwwrite);
-            xwwrite = new XWWrite(m_board[boardid], boardid, blp, MEPHeader::BF_YROUT);
-            ASSERT(xwwrite);
-            m_scheduler.addSyncAction(xwwrite);
-            xwwrite = new XWWrite(m_board[boardid], boardid, blp, MEPHeader::BF_YIOUT);
-            ASSERT(xwwrite);
-            m_scheduler.addSyncAction(xwwrite);
-          }
-        }
-      }
-      else {
-        if (1 == GET_CONFIG("RSPDriver.READ_BF", i)) {
-          BWRead* bwread = 0;
-
-          for (int blp = 0; blp < StationSettings::instance()->nrBlpsPerBoard(); blp++) {
-            bwread = new BWRead(m_board[boardid], boardid, blp, MEPHeader::BF_XROUT);
-            ASSERT(bwread);
-            m_scheduler.addSyncAction(bwread);
-            bwread = new BWRead(m_board[boardid], boardid, blp, MEPHeader::BF_XIOUT);
-            ASSERT(bwread);
-            m_scheduler.addSyncAction(bwread);
-            bwread = new BWRead(m_board[boardid], boardid, blp, MEPHeader::BF_YROUT);
-            ASSERT(bwread);
-            m_scheduler.addSyncAction(bwread);
-            bwread = new BWRead(m_board[boardid], boardid, blp, MEPHeader::BF_YIOUT);
-            ASSERT(bwread);
-            m_scheduler.addSyncAction(bwread);
-          }
-        }
-      }
-    }
-    
-    if (1 == GET_CONFIG("RSPDriver.READ_SST", i)) {
-      SstRead* sstread = 0;
+		if (1 == GET_CONFIG("RSPDriver.READ_SST", i)) {
+			SstRead* sstread = 0;
+			sstread = new SstRead(m_boardPorts[boardid], boardid);
+			ASSERT(sstread);
+			m_scheduler.addSyncAction(sstread);
+		}
 
-      sstread = new SstRead(m_board[boardid], boardid);
-      ASSERT(sstread);
-      m_scheduler.addSyncAction(sstread);
+		for (int action = 0; action < 2; action++) {
+			if (action == GET_CONFIG("RSPDriver.LOOPBACK_MODE", i)) {
+				if (1 == GET_CONFIG("RSPDriver.WRITE_RCU", i)) {
+					RCUWrite* rcuwrite = new RCUWrite(m_boardPorts[boardid], boardid);
+					ASSERT(rcuwrite);
+					m_scheduler.addSyncAction(rcuwrite);
+				}
+			}
+			else {
+				if (1 == GET_CONFIG("RSPDriver.READ_RCU", i)) {
+					RCURead* rcuread = new RCURead(m_boardPorts[boardid], boardid);
+					ASSERT(rcuread);
+					m_scheduler.addSyncAction(rcuread);
+				}
+			}
+		}
 
-    }
+		// order is important; RCUProtocolWrite should go before RCUResultRead
+		if (1 == GET_CONFIG("RSPDriver.WRITE_RCU_PROTOCOL", i)) {
+			RCUProtocolWrite* rcuprotocolwrite = new RCUProtocolWrite(m_boardPorts[boardid], boardid);
+			ASSERT(rcuprotocolwrite);
+			m_scheduler.addSyncAction(rcuprotocolwrite);
+		}
 
-    for (int action = 0; action < 2; action++) {
-      if (action == GET_CONFIG("RSPDriver.LOOPBACK_MODE", i)) {
-        if (1 == GET_CONFIG("RSPDriver.WRITE_RCU", i)) {
-          RCUWrite* rcuwrite = new RCUWrite(m_board[boardid], boardid);
-          ASSERT(rcuwrite);
-          m_scheduler.addSyncAction(rcuwrite);
-        }
-      }
-      else {
-        if (1 == GET_CONFIG("RSPDriver.READ_RCU", i)) {
-          RCURead* rcuread = new RCURead(m_board[boardid], boardid);
-          ASSERT(rcuread);
-          m_scheduler.addSyncAction(rcuread);
-        }
-      }
-    }
+		if (1 == GET_CONFIG("RSPDriver.READ_RCU_RESULT", i)) {
+			RCUResultRead* rcuresultread = new RCUResultRead(m_boardPorts[boardid], boardid);
+			ASSERT(rcuresultread);
+			m_scheduler.addSyncAction(rcuresultread);
+		}
 
-    // order is important; RCUProtocolWrite should go before RCUResultRead
-    if (1 == GET_CONFIG("RSPDriver.WRITE_RCU_PROTOCOL", i)) {
-      RCUProtocolWrite* rcuprotocolwrite = new RCUProtocolWrite(m_board[boardid], boardid);
-      ASSERT(rcuprotocolwrite);
-      m_scheduler.addSyncAction(rcuprotocolwrite);
-    }
+		// order is important; HBAProtocolWrite should go before HBAResultRead,
+		// these two should go before RCUProtocolWrite/RCUResultRead
+		if (1 == GET_CONFIG("RSPDriver.WRITE_HBA_PROTOCOL", i)) {
+			HBAProtocolWrite* hbaprotocolwrite = new HBAProtocolWrite(m_boardPorts[boardid], boardid);
+			ASSERT(hbaprotocolwrite);
+			m_scheduler.addSyncAction(hbaprotocolwrite);
+		}
 
-    if (1 == GET_CONFIG("RSPDriver.READ_RCU_RESULT", i)) {
-      RCUResultRead* rcuresultread = new RCUResultRead(m_board[boardid], boardid);
-      ASSERT(rcuresultread);
-      m_scheduler.addSyncAction(rcuresultread);
-    }
+		if (1 == GET_CONFIG("RSPDriver.READ_HBA_RESULT", i)) {
+			HBAResultRead* hbaresultread = new HBAResultRead(m_boardPorts[boardid], boardid);
+			ASSERT(hbaresultread);
+			m_scheduler.addSyncAction(hbaresultread);
+		}
 
-    // order is important; HBAProtocolWrite should go before HBAResultRead,
-    // these two should go before RCUProtocolWrite/RCUResultRead
-    if (1 == GET_CONFIG("RSPDriver.WRITE_HBA_PROTOCOL", i)) {
-      HBAProtocolWrite* hbaprotocolwrite = new HBAProtocolWrite(m_board[boardid], boardid);
-      ASSERT(hbaprotocolwrite);
-      m_scheduler.addSyncAction(hbaprotocolwrite);
-    }
+		// read Spectral Invertion information
+		//    if (GET_CONFIG("RSPDriver.READ_SI", i)) {
+		//      for (int blp = 0; blp < StationSettings::instance()->nrBlpsPerBoard(); blp++) {
+		//        BypassRead* bypassread = new BypassRead(m_boardPorts[boardid], boardid, blp);
+		//          ASSERT(bypassread);
+		//        m_scheduler.addSyncAction(bypassread);
+		//	  }
+		//    }
+
+		if (GET_CONFIG("RSPDriver.READ_RAW_DATA", i) == 1) {
+			RawBlockRead* rawRead = new RawBlockRead(m_boardPorts[boardid], boardid);
+			ASSERT(rawRead);
+			m_scheduler.addSyncAction(rawRead);
+		}
 
-    if (1 == GET_CONFIG("RSPDriver.READ_HBA_RESULT", i)) {
-      HBAResultRead* hbaresultread = new HBAResultRead(m_board[boardid], boardid);
-      ASSERT(hbaresultread);
-      m_scheduler.addSyncAction(hbaresultread);
-    }
+		if (GET_CONFIG("RSPDriver.WRITE_RAW_DATA", i) == 1) {
+			RawBlockWrite* rawWrite = new RawBlockWrite(m_boardPorts[boardid], boardid);
+			ASSERT(rawWrite);
+			m_scheduler.addSyncAction(rawWrite);
+		}
 
-    // read Spectral Invertion information
-//    if (GET_CONFIG("RSPDriver.READ_SI", i)) {
-//      for (int blp = 0; blp < StationSettings::instance()->nrBlpsPerBoard(); blp++) {
-//        BypassRead* bypassread = new BypassRead(m_board[boardid], boardid, blp);
-//          ASSERT(bypassread);
-//        m_scheduler.addSyncAction(bypassread);
-//	  }
-//    }
-
-    if (1 == GET_CONFIG("RSPDriver.WRITE_TIMESTAMP", i)) {
-      TimestampWrite* timestampwrite = new TimestampWrite(m_board[boardid], boardid, m_scheduler);
-      ASSERT(timestampwrite);
-      m_scheduler.addSyncAction(timestampwrite);
-    }
-  } // for (boardid...)
+		if (1 == GET_CONFIG("RSPDriver.WRITE_TIMESTAMP", i)) {
+			TimestampWrite* timestampwrite = new TimestampWrite(m_boardPorts[boardid], boardid, m_scheduler);
+			ASSERT(timestampwrite);
+			m_scheduler.addSyncAction(timestampwrite);
+		}
+	} // for (boardid...)
 }
 
 //
@@ -687,8 +686,8 @@ void RSPDriver::addAllSyncActions()
 void RSPDriver::openBoards()
 {
 	for (int boardid = 0; boardid < StationSettings::instance()->nrRspBoards(); boardid++) {
-		if (!m_board[boardid].isConnected())  {
-			m_board[boardid].open();
+		if (!m_boardPorts[boardid].isConnected())  {
+			m_boardPorts[boardid].open();
 		}
 	}
 }
@@ -698,17 +697,17 @@ void RSPDriver::openBoards()
 //
 int RSPDriver::fetchPPS()
 {
-  int result = 0;
+	int result = 0;
 #ifdef HAVE_SYS_TIMEPPS_H
-  do {
-    struct timespec timeout = PPS_FETCH_TIMEOUT; // prevent permanent lock
-    result = time_pps_fetch(m_ppshandle, PPS_TSFMT_TSPEC, &m_ppsinfo, &timeout);
-  } while ((result < 0) && (EINTR == errno || EAGAIN == errno));
+	do {
+		struct timespec timeout = PPS_FETCH_TIMEOUT; // prevent permanent lock
+		result = time_pps_fetch(m_ppshandle, PPS_TSFMT_TSPEC, &m_ppsinfo, &timeout);
+	} while ((result < 0) && (EINTR == errno || EAGAIN == errno));
 #else
-  LOG_FATAL("fetchPPS should not be called when HAVE_SYS_TIMEPPS_H is not defined");
-  exit(EXIT_FAILURE);
+	LOG_FATAL("fetchPPS should not be called when HAVE_SYS_TIMEPPS_H is not defined");
+	exit(EXIT_FAILURE);
 #endif
-  return result;
+	return result;
 }
 
 //
@@ -716,137 +715,124 @@ int RSPDriver::fetchPPS()
 //
 GCFEvent::TResult RSPDriver::initial(GCFEvent& event, GCFPortInterface& port)
 {
-  GCFEvent::TResult status = GCFEvent::HANDLED;
-  
-  switch(event.signal) {
-    case F_INIT:
-    {
-      if (GET_CONFIG("RSPDriver.SYNC_MODE", i) == SYNC_PPS) {
-#ifdef HAVE_SYS_TIMEPPS_H
-        pps_params_t parm;
-
-        // standard time format and trigger on rising edge, API version 1
-        memset(&parm, 0, sizeof(pps_params_t));
-        parm.mode = PPS_TSFMT_TSPEC;
-	if (GET_CONFIG("RSPDriver.PPS_TRIGGER", i)) {
-	  parm.mode |= PPS_CAPTUREASSERT; // trigger on ASSERT
-	} else {
-	  parm.mode |= PPS_CAPTURECLEAR; // trigger on CLEAR
-	}
-        parm.api_version = PPS_API_VERS_1;
-
-        if ((m_ppsfd = open(GET_CONFIG_STRING("RSPDriver.PPS_DEVICE"), O_RDWR)) < 0) {
-          LOG_FATAL_STR("Error opening '" << GET_CONFIG_STRING("RSPDriver.PPS_DEVICE") << "': " << strerror(errno));
-          exit(EXIT_FAILURE);
-        }
-
-        if (time_pps_create(m_ppsfd, &m_ppshandle) < 0) {
-          LOG_FATAL_STR("PPS device does not support PPS API?: " << strerror(errno));
-          exit(EXIT_FAILURE);
-        }
+	GCFEvent::TResult status = GCFEvent::HANDLED;
 
-        int caps = 0;
-        if (time_pps_getcap(m_ppshandle, &caps) < 0) {
-          LOG_FATAL_STR("Cannot get PPS device capabilities:" << strerror(errno));
-          exit(EXIT_FAILURE);
-        }
-        LOG_INFO(formatString("PPS device capabilities are 0x%x\n", caps));
+	switch(event.signal) {
+	case F_INIT: {
+		if (GET_CONFIG("RSPDriver.SYNC_MODE", i) == SYNC_PPS) {
+#ifdef HAVE_SYS_TIMEPPS_H
+			pps_params_t parm;
+
+			// standard time format and trigger on rising edge, API version 1
+			memset(&parm, 0, sizeof(pps_params_t));
+			parm.mode = PPS_TSFMT_TSPEC;
+			if (GET_CONFIG("RSPDriver.PPS_TRIGGER", i)) {
+				parm.mode |= PPS_CAPTUREASSERT; // trigger on ASSERT
+			} else {
+				parm.mode |= PPS_CAPTURECLEAR; // trigger on CLEAR
+			}
+			parm.api_version = PPS_API_VERS_1;
+
+			if ((m_ppsfd = open(GET_CONFIG_STRING("RSPDriver.PPS_DEVICE"), O_RDWR)) < 0) {
+				LOG_FATAL_STR("Error opening '" << GET_CONFIG_STRING("RSPDriver.PPS_DEVICE") << "': " << strerror(errno));
+				exit(EXIT_FAILURE);
+			}
+
+			if (time_pps_create(m_ppsfd, &m_ppshandle) < 0) {
+				LOG_FATAL_STR("PPS device does not support PPS API?: " << strerror(errno));
+				exit(EXIT_FAILURE);
+			}
+
+			int caps = 0;
+			if (time_pps_getcap(m_ppshandle, &caps) < 0) {
+				LOG_FATAL_STR("Cannot get PPS device capabilities:" << strerror(errno));
+				exit(EXIT_FAILURE);
+			}
+			LOG_INFO(formatString("PPS device capabilities are 0x%x\n", caps));
 
 #if 0
-        if (!(caps & PPS_CANWAIT & PPS_CAPTUREASSERT)) {
-          LOG_FATAL("PPS device does not support PPS_CANWAIT & PPS_CAPTUREASSERT. PPS device unsuitable.");
-          exit(EXIT_FAILURE);
-        }
+			if (!(caps & PPS_CANWAIT & PPS_CAPTUREASSERT)) {
+				LOG_FATAL("PPS device does not support PPS_CANWAIT & PPS_CAPTUREASSERT. PPS device unsuitable.");
+				exit(EXIT_FAILURE);
+			}
 #endif
 
-        if (time_pps_setparams(m_ppshandle, &parm) < 0) {
-          LOG_FATAL_STR("Error settings parameters on PPS device:" << strerror(errno));
-          exit(EXIT_FAILURE);
-        }
+			if (time_pps_setparams(m_ppshandle, &parm) < 0) {
+				LOG_FATAL_STR("Error settings parameters on PPS device:" << strerror(errno));
+				exit(EXIT_FAILURE);
+			}
 
-        // now we're setup to use time_pps_fetch...
+			// now we're setup to use time_pps_fetch...
 #else
-        LOG_FATAL("HAVE_SYS_TIMEPPS_H not defined. Platform doesn't support PPSkit interface.");
-        exit(EXIT_FAILURE);
+			LOG_FATAL("HAVE_SYS_TIMEPPS_H not defined. Platform doesn't support PPSkit interface.");
+			exit(EXIT_FAILURE);
 #endif
-      }
-    }
-    break;
+		} // sync mode
+	} // F_INIT
+	break;
 
-    case F_ENTRY:
-    {
+	case F_ENTRY: {
 #if 0
-      if (GET_CONFIG("RSPDriver.SYNC_MODE", i) == SYNC_PARALLEL)
-      {
-        if (!m_clock.isConnected()) m_clock.open();
-      }
+	if (GET_CONFIG("RSPDriver.SYNC_MODE", i) == SYNC_PARALLEL) {
+		if (!m_clock.isConnected()) m_clock.open();
+	}
 #endif
-      openBoards();
-    }
-    break;
+		openBoards();
+	}
+	break;
 
-    case F_CONNECTED:
-    {
-      LOG_INFO(formatString("CONNECTED: port '%s'", port.getName().c_str()));
-      if (isEnabled())
-      {
-        TRAN(RSPDriver::enabled);
-      }
-    }
-    break;
+	case F_CONNECTED: {
+		LOG_INFO(formatString("CONNECTED: port '%s'", port.getName().c_str()));
+		if (isEnabled()) {
+			TRAN(RSPDriver::enabled);
+		}
+	}
+	break;
 
-    case F_DISCONNECTED:
-    {
-      port.setTimer((long)3); // try again in 3 seconds
-      LOG_WARN(formatString("port '%s' disconnected, retry in 3 seconds...", port.getName().c_str()));
-      port.close();
-    }
-    break;
+	case F_DISCONNECTED: {
+		port.setTimer((long)3); // try again in 3 seconds
+		LOG_WARN(formatString("port '%s' disconnected, retry in 3 seconds...", port.getName().c_str()));
+		port.close();
+	}
+	break;
 
-    case F_TIMER:
-    {
-      LOG_DEBUG(formatString("port '%s' retry of open...", port.getName().c_str()));
-      port.open();
-    }
-    break;
+	case F_TIMER: {
+		LOG_DEBUG(formatString("port '%s' retry of open...", port.getName().c_str()));
+		port.open();
+	}
+	break;
 
-    case F_DATAIN:
-    {
+	case F_DATAIN: {
 #if 0
-      if (&port == &m_clock)
-      {
-        /**
-         * We don't need the clock here yet, simply read the value
-         * and ignore
-         */
-        uint8 count = 0;
-        (void)port.recv(&count, sizeof(uint8));
-      }
-      else
-      {
+		if (&port == &m_clock) {
+			// We don't need the clock here yet, simply read the value
+			// and ignore
+			uint8 count = 0;
+			(void)port.recv(&count, sizeof(uint8));
+		}
+		else {
 #endif
-        // ignore in this state
-        static char buf[ETH_DATA_LEN];
-        (void)port.recv(buf, ETH_DATA_LEN);
+			// ignore in this state
+			static char buf[ETH_DATA_LEN];
+			(void)port.recv(buf, ETH_DATA_LEN);
 #if 0
-      }
+		}
 #endif
-    }
-    break;
+	}
+	break;
 
-    case F_EXIT:
-    {
-      // cancel timers
-      m_board[0].cancelAllTimers();
-    }
-    break;
+	case F_EXIT: {
+		// cancel timers
+		m_boardPorts[0].cancelAllTimers();
+	}
+	break;
 
-    default:
-      status = GCFEvent::NOT_HANDLED;
-      break;
-  }
+	default:
+		status = GCFEvent::NOT_HANDLED;
+		break;
+	}
 
-  return status;
+	return status;
 }
 
 //
@@ -854,12 +840,10 @@ GCFEvent::TResult RSPDriver::initial(GCFEvent& event, GCFPortInterface& port)
 //
 void RSPDriver::undertaker()
 {
-  for (list<GCFPortInterface*>::iterator it = m_dead_clients.begin();
-       it != m_dead_clients.end();
-       it++) {
-    delete (*it);
-  }
-  m_dead_clients.clear();
+	for (list<GCFPortInterface*>::iterator it = m_dead_clients.begin(); it != m_dead_clients.end(); it++) {
+		delete (*it);
+	}
+	m_dead_clients.clear();
 }
 
 //
@@ -872,8 +856,7 @@ GCFEvent::TResult RSPDriver::enabled(GCFEvent& event, GCFPortInterface& port)
   undertaker(); // destroy dead clients
 
   switch (event.signal) {
-    case F_ENTRY:
-    {
+    case F_ENTRY: {
       // start waiting for clients
       if (!m_acceptor.isConnected()) {
 		m_acceptor.open();
@@ -887,7 +870,7 @@ GCFEvent::TResult RSPDriver::enabled(GCFEvent& event, GCFPortInterface& port)
 		struct timeval		sysTime;
 		gettimeofday(&sysTime, 0);
 		usleep (1999000 - sysTime.tv_usec);		// try to wait for a second passage
-        m_board[0].setTimer(1.0, syncItv); 		// Start the update timer after 1 second 
+        m_boardPorts[0].setTimer(1.0, syncItv); 		// Start the update timer after 1 second 
 		LOG_INFO("Hopefully on whole second now");
       }
       else if (GET_CONFIG("RSPDriver.SYNC_MODE", i) == SYNC_FAST) {
@@ -895,7 +878,7 @@ GCFEvent::TResult RSPDriver::enabled(GCFEvent& event, GCFPortInterface& port)
         // single timeout after 1 second to set
         // off as-fast-as-possible update mode
         //
-        m_board[0].setTimer(1.0);
+        m_boardPorts[0].setTimer(1.0);
 
         //
         // periodic timeout on m_acceptor port
@@ -923,10 +906,10 @@ GCFEvent::TResult RSPDriver::enabled(GCFEvent& event, GCFPortInterface& port)
 
         // start a single shot timer that is slightly shorter that 1 second
         // when the timer expires, wait for the true PPS using time_pps_fetch
-        m_board[0].setTimer(0.99); // 1st event after 1 second
+        m_boardPorts[0].setTimer(0.99); // 1st event after 1 second
 #else
         LOG_WARN("HAVE_SYS_TIMEPPS_H not defined. Platform doesn't support PPSkit interface. Using software timer.");
-        m_board[0].setTimer((long)1); // next event in one (software) second
+        m_boardPorts[0].setTimer((long)1); // next event in one (software) second
 #endif
       }
     }
@@ -1008,9 +991,11 @@ GCFEvent::TResult RSPDriver::enabled(GCFEvent& event, GCFPortInterface& port)
     case RSP_SETTBB: 				rsp_settbb(event, port); 			break; 
     case RSP_GETTBB: 				rsp_gettbb(event, port); 			break; 
     case RSP_GETSPUSTATUS: 			rsp_getspustatus(event, port); 		break; 
+    case RSP_SETBLOCK: 				rsp_setRawBlock(event, port); 		break; 
+    case RSP_GETBLOCK: 				rsp_getRawBlock(event, port); 		break; 
 
     case F_TIMER: {
-      if (&port == &m_board[0]) {
+      if (&port == &m_boardPorts[0]) {
         //
         // If SYNC_MODE == SOFTWARE|FAST then run the scheduler
         // directly on the software timer.
@@ -1040,7 +1025,7 @@ GCFEvent::TResult RSPDriver::enabled(GCFEvent& event, GCFPortInterface& port)
             timer.id   = 0;
             timer.arg  = 0;
 
-            m_board[0].setTimer((long)1); // next event after exactly 1 second
+            m_boardPorts[0].setTimer((long)1); // next event after exactly 1 second
           
           } else {
 
@@ -1064,9 +1049,9 @@ GCFEvent::TResult RSPDriver::enabled(GCFEvent& event, GCFPortInterface& port)
               LOG_WARN_STR("Missed " << m_ppsinfo.assert_sequence - prevppsinfo.assert_sequence - 1 << " PPS events.");
             }         
           }
-          m_board[0].setTimer(0.95); // next event in just under 1 second
+          m_boardPorts[0].setTimer(0.95); // next event in just under 1 second
 #else
-          m_board[0].setTimer((long)1); // next event in one (software) second
+          m_boardPorts[0].setTimer((long)1); // next event in one (software) second
 #endif
 
 	  // delay the driver some number of microseconds after it receives the PPS tick
@@ -1096,8 +1081,7 @@ GCFEvent::TResult RSPDriver::enabled(GCFEvent& event, GCFPortInterface& port)
     }
     break;
 
-    case F_DISCONNECTED:
-    {
+    case F_DISCONNECTED: {
       LOG_INFO(formatString("DISCONNECTED: port '%s'", port.getName().c_str()));
       port.close();
 
@@ -1105,7 +1089,7 @@ GCFEvent::TResult RSPDriver::enabled(GCFEvent& event, GCFPortInterface& port)
         LOG_FATAL("Failed to start listening for client connections.");
         exit(EXIT_FAILURE);
       }
-      else if (&port == &m_board[0] || &port == &m_board[1] || &port == &m_acceptor) {
+      else if (&port == &m_boardPorts[0] || &port == &m_boardPorts[1] || &port == &m_acceptor) {
         m_acceptor.close();
         TRAN(RSPDriver::initial);
       }
@@ -1119,11 +1103,10 @@ GCFEvent::TResult RSPDriver::enabled(GCFEvent& event, GCFPortInterface& port)
     }
     break;
 
-    case F_EXIT:
-    {
+    case F_EXIT: {
       // cancel timers
       m_acceptor.cancelAllTimers();
-      m_board[0].cancelAllTimers();
+      m_boardPorts[0].cancelAllTimers();
     }
     break;
 
@@ -1137,7 +1120,7 @@ GCFEvent::TResult RSPDriver::enabled(GCFEvent& event, GCFPortInterface& port)
         //
         if ((GET_CONFIG("RSPDriver.SYNC_MODE", i) == SYNC_FAST) &&
             m_scheduler.syncHasCompleted()) {
-          m_board[0].setTimer(0.0); // immediate
+          m_boardPorts[0].setTimer(0.0); // immediate
           m_update_counter++;
         }
       }
@@ -1153,13 +1136,13 @@ GCFEvent::TResult RSPDriver::enabled(GCFEvent& event, GCFPortInterface& port)
 bool RSPDriver::isBoardPort(GCFPortInterface& port)
 {
   /**
-   * The addresses of the elements of the m_board array
+   * The addresses of the elements of the m_boardPorts array
    * are consecutive in memory, therefor we can do a range
    * check on the address to determine whether it is a port
    * to a board.
    */
-  if (   &port >= &m_board[0]
-      && &port <= &m_board[StationSettings::instance()->nrRspBoards()])
+  if (   &port >= &m_boardPorts[0]
+      && &port <= &m_boardPorts[StationSettings::instance()->nrRspBoards()])
     return true;
   
   return false;
@@ -2433,8 +2416,7 @@ void RSPDriver::rsp_settbb(GCFEvent& event, GCFPortInterface& port)
 {
   Ptr<SetTBBCmd> command = new SetTBBCmd(event, port, Command::WRITE);
 
-  if (!command->validate())
-  {
+  if (!command->validate()) {
     LOG_ERROR("SETTBB: invalid parameter");
     
     RSPSettbbackEvent ack;
@@ -2445,14 +2427,12 @@ void RSPDriver::rsp_settbb(GCFEvent& event, GCFPortInterface& port)
   }
 
   // if timestamp == Timestamp(0,0) apply changes immediately
-  if (Timestamp(0,0) == command->getTimestamp())
-  {
+  if (Timestamp(0,0) == command->getTimestamp()) {
     LOG_INFO("applying TBB control immediately");
     command->apply(Cache::getInstance().getFront(), true);
     command->apply(Cache::getInstance().getBack(), false);
   }
-  else
-  {
+  else {
     (void)m_scheduler.enter(Ptr<Command>(&(*command)));
   }
   command->ack(Cache::getInstance().getFront());
@@ -2465,8 +2445,7 @@ void RSPDriver::rsp_gettbb(GCFEvent& event, GCFPortInterface& port)
 {
   Ptr<GetTBBCmd> command = new GetTBBCmd(event, port, Command::READ);
 
-  if (!command->validate())
-  {
+  if (!command->validate()) {
     LOG_ERROR("GETTBB: invalid parameter");
     
     RSPGettbbackEvent ack;
@@ -2480,13 +2459,11 @@ void RSPDriver::rsp_gettbb(GCFEvent& event, GCFPortInterface& port)
   
   // if null timestamp get value from the cache and acknowledge immediately
   if ( (Timestamp(0,0) == command->getTimestamp())
-       && (true == command->readFromCache()))
-  {
+       && (true == command->readFromCache())) {
     command->setTimestamp(Cache::getInstance().getFront().getTimestamp());
     command->ack(Cache::getInstance().getFront());
   }
-  else
-  {
+  else {
     (void)m_scheduler.enter(Ptr<Command>(&(*command)));
   }
 }
@@ -2513,6 +2490,58 @@ void RSPDriver::rsp_getspustatus(GCFEvent& event, GCFPortInterface& port)
 	}
 }
 
+//
+// rsp_getRawBlock(event, port)
+//
+void RSPDriver::rsp_getRawBlock(GCFEvent& event, GCFPortInterface& port) 
+{
+	Ptr<GetRawBlockCmd> command = new GetRawBlockCmd(event, port, Command::READ);
+
+	if (!command->validate()) {
+		LOG_ERROR("GetRawBlock: invalid parameter");
+
+		RSPGetblockackEvent ack;
+		ack.timestamp = Timestamp(0,0);
+		ack.status = FAILURE;
+		port.send(ack);
+		return;
+	}
+
+	// temp debugging TODO
+//	RSPGetblockEvent	e(event);
+//	LOG_INFO(formatString("@@@Scheduling GetRawBlockCmd(%d,%x,%d,%d)", e.boardID, e.address, e.offset, e.dataLen));
+
+	// command is ok, schedule it.
+	(void)m_scheduler.enter(Ptr<Command>(&(*command)));
+
+}
+
+//
+// rsp_setRawBlock(event, port)
+//
+void RSPDriver::rsp_setRawBlock(GCFEvent& event, GCFPortInterface& port) 
+{
+	Ptr<SetRawBlockCmd> command = new SetRawBlockCmd(event, port, Command::WRITE);
+
+	if (!command->validate()) {
+		LOG_ERROR("SetRawBlock: invalid parameter");
+
+		RSPSetblockackEvent ack;
+		ack.timestamp = Timestamp(0,0);
+		ack.status = FAILURE;
+		port.send(ack);
+		return;
+	}
+
+	// temp debugging TODO
+//	RSPSetblockEvent	e(event);
+//	LOG_INFO(formatString("@@@Scheduling SetRawBlockCmd(%d,%x,%d,%d)", e.boardID, e.address, e.offset, e.dataLen));
+
+	// command is ok, schedule it.
+	(void)m_scheduler.enter(Ptr<Command>(&(*command)));
+}
+
+
   } // namespace RSP
 } // namespace LOFAR
 
diff --git a/MAC/APL/PIC/RSPDriver/src/RSPDriver.h b/MAC/APL/PIC/RSPDriver/src/RSPDriver.h
index 811bbfd4a09..09e49a68035 100644
--- a/MAC/APL/PIC/RSPDriver/src/RSPDriver.h
+++ b/MAC/APL/PIC/RSPDriver/src/RSPDriver.h
@@ -169,6 +169,9 @@ namespace LOFAR {
       void rsp_getbypass(GCFEvent& event, GCFPortInterface &port);
 
       void rsp_getspustatus(GCFEvent& event, GCFPortInterface &port);
+
+      void rsp_getRawBlock(GCFEvent& event, GCFPortInterface &port);
+      void rsp_setRawBlock(GCFEvent& event, GCFPortInterface &port);
       /*@}*/
 
     private:
@@ -184,7 +187,7 @@ namespace LOFAR {
 
       // ports
       GCFTCPPort                   m_acceptor;     // listen for clients on this port
-      GCFETHRawPort*               m_board;        // array of ports, one for each RSP board
+      GCFETHRawPort*               m_boardPorts;   // array of ports, one for each RSP board
       std::list<GCFPortInterface*> m_client_list;  // list of clients
       std::list<GCFPortInterface*> m_dead_clients; // list of clients to cleanup
 
diff --git a/MAC/APL/PIC/RSPDriver/src/RawBlockRead.cc b/MAC/APL/PIC/RSPDriver/src/RawBlockRead.cc
new file mode 100644
index 00000000000..119181813ca
--- /dev/null
+++ b/MAC/APL/PIC/RSPDriver/src/RawBlockRead.cc
@@ -0,0 +1,136 @@
+//#  RawBlockRead.cc: implementation of the RawBlockRead class
+//#
+//#  Copyright (C) 2002-2004
+//#  ASTRON (Netherlands Foundation for Research in Astronomy)
+//#  P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
+//#
+//#  This program is free software; you can redistribute it and/or modify
+//#  it under the terms of the GNU General Public License as published by
+//#  the Free Software Foundation; either version 2 of the License, or
+//#  (at your option) any later version.
+//#
+//#  This program is distributed in the hope that it will be useful,
+//#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//#  GNU General Public License for more details.
+//#
+//#  You should have received a copy of the GNU General Public License
+//#  along with this program; if not, write to the Free Software
+//#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//#
+//#  $Id$
+
+#include <lofar_config.h>
+#include <Common/LofarLogger.h>
+#include <Common/hexdump.h>
+#include <APL/RSP_Protocol/EPA_Protocol.ph>
+
+#include <APL/RTCCommon/PSAccess.h>
+#include <string.h>
+
+#include "StationSettings.h"
+#include "HBAProtocolWrite.h"
+#include "RawBlockRead.h"
+#include "Cache.h"
+
+#include <netinet/in.h>
+
+using namespace LOFAR;
+using namespace RSP;
+using namespace EPA_Protocol;
+using namespace blitz;
+
+//
+// RawBlockRead(port, boardID)
+//
+RawBlockRead::RawBlockRead(GCFPortInterface& board_port, int board_id)
+  : SyncAction(board_port, board_id, 1)
+{
+	memset(&m_hdr, 0, sizeof(MEPHeader));
+}
+
+//
+// ~RawBlockRead()
+//
+RawBlockRead::~RawBlockRead()
+{
+  /* TODO: delete event? */
+}
+
+//
+// sendrequest()
+//
+void RawBlockRead::sendrequest()
+{
+	// skip update if nothing was modified
+	if (Cache::getInstance().getState().rawdataread().get(getBoardId()) != RTC::RegisterState::WRITE) {
+		Cache::getInstance().getState().rawdataread().unmodified(getBoardId());
+		setContinue(true);
+//		LOG_INFO_STR("@@@RawBlockRead::sendrequest(" << getBoardId() << "):false");
+		return;
+	}
+//	LOG_INFO_STR("@@@RawBlockRead::sendrequest(" << getBoardId() << "):true");
+
+	// Cache was modified, construct an EPA message and send it.
+	// Note that the buffer in the cache already contains the whole message, just copy the bytes
+	// to the right places in the message.
+	EPAReadEvent	rawData;
+	RawDataBlock_t&	rdb = Cache::getInstance().getBack().getRawDataBlock();
+	rawData.hdr.set(MEPHeader::RSP_RAWDATA_READ, 0, MEPHeader::READ, rdb.dataLen, rdb.offset);
+	// overwrite complete address
+	memcpy((void*)&(rawData.hdr.m_fields.addr), (void*)&(rdb.address), sizeof(rdb.address));
+	m_hdr = rawData.hdr; // remember header to match with ack
+
+//	string	hDump;	// DEBUG
+//	hexdump(hDump, (void*)&m_hdr.m_fields, MEPHeader::SIZE); // DEBUG
+//	LOG_INFO (hDump);
+
+	// finally send the message
+	getBoardPort().send(rawData);
+}
+
+//
+// sendrequest_status()
+//
+void RawBlockRead::sendrequest_status()
+{
+	// intentionally left empty
+}
+
+//
+// handleack(event, port)
+//
+GCFEvent::TResult RawBlockRead::handleack(GCFEvent& event, GCFPortInterface& /*port*/)
+{
+//	LOG_INFO_STR("@@@RawBlockRead::handleack(" << getBoardId() << ")");
+
+  	// Note: we don't have to check the event.signal here because it is always safe to 
+	//		 convert an event to a generic readackEvent.
+	//		 We can't even check it because the user made up the address and there for the response-type.
+	EPAReadackEvent ack(event);
+
+//	string	hDump;		/// DEBUG
+//	hexdump(hDump, (void*)&(ack.hdr.m_fields), MEPHeader::SIZE);
+//	LOG_INFO (hDump);
+
+	// check result
+	if (!ack.hdr.isValidAck(m_hdr)) {
+		LOG_ERROR("RawBlockRead::handleack: invalid ack");
+		Cache::getInstance().getState().rawdataread().write_error(getBoardId());
+		return GCFEvent::HANDLED;
+	}
+
+	// Mark command ok.
+	Cache::getInstance().getState().rawdataread().write_ack(getBoardId());
+
+	// copy the stuff
+	RawDataBlock_t&		rdb = Cache::getInstance().getBack().getRawDataBlock();
+	rdb.dataLen = ack.hdr.m_fields.payload_length;
+	memcpy(rdb.data, ack.data, rdb.dataLen);
+
+//	hDump.clear();		/// DEBUG
+//	hexdump(hDump, (void*)&(rdb.data), rdb.dataLen);
+//	LOG_INFO (hDump);
+
+	return GCFEvent::HANDLED;
+}
diff --git a/MAC/APL/PIC/RSPDriver/src/RawBlockRead.h b/MAC/APL/PIC/RSPDriver/src/RawBlockRead.h
new file mode 100644
index 00000000000..57e4d632f64
--- /dev/null
+++ b/MAC/APL/PIC/RSPDriver/src/RawBlockRead.h
@@ -0,0 +1,57 @@
+//#  -*- mode: c++ -*-
+//#
+//#  RawBlockRead.h: Synchronize HBA settings with HBA hardware via RCU interface.
+//#
+//#  Copyright (C) 2002-2004
+//#  ASTRON (Netherlands Foundation for Research in Astronomy)
+//#  P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
+//#
+//#  This program is free software; you can redistribute it and/or modify
+//#  it under the terms of the GNU General Public License as published by
+//#  the Free Software Foundation; either version 2 of the License, or
+//#  (at your option) any later version.
+//#
+//#  This program is distributed in the hope that it will be useful,
+//#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//#  GNU General Public License for more details.
+//#
+//#  You should have received a copy of the GNU General Public License
+//#  along with this program; if not, write to the Free Software
+//#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//#
+//#  $Id$
+
+#ifndef RSPRAWDATAREAD_H_
+#define RSPRAWDATAREAD_H_
+
+#include <APL/RSP_Protocol/MEPHeader.h>
+
+#include "SyncAction.h"
+
+namespace LOFAR {
+  namespace RSP {
+
+class RawBlockRead : public SyncAction
+{
+public:
+	// Constructors for a RawBlockRead object.
+	RawBlockRead(GCFPortInterface& board_port, int board_id);
+	virtual ~RawBlockRead();
+
+	// Send the write message.
+	virtual void sendrequest();
+
+	// Send the read request.
+	virtual void sendrequest_status();
+
+	// Handle the read result.
+	virtual GCFEvent::TResult handleack(GCFEvent& event, GCFPortInterface& port);
+
+private:
+	EPA_Protocol::MEPHeader m_hdr;
+};
+  }; // namespace RSP
+}; // namespace LOFAR
+     
+#endif /* RSPRAWDATAREAD_H_ */
diff --git a/MAC/APL/PIC/RSPDriver/src/RawBlockWrite.cc b/MAC/APL/PIC/RSPDriver/src/RawBlockWrite.cc
new file mode 100644
index 00000000000..926776d4c33
--- /dev/null
+++ b/MAC/APL/PIC/RSPDriver/src/RawBlockWrite.cc
@@ -0,0 +1,134 @@
+//#  RawBlockWrite.cc: implementation of the RawBlockWrite class
+//#
+//#  Copyright (C) 2002-2004
+//#  ASTRON (Netherlands Foundation for Research in Astronomy)
+//#  P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
+//#
+//#  This program is free software; you can redistribute it and/or modify
+//#  it under the terms of the GNU General Public License as published by
+//#  the Free Software Foundation; either version 2 of the License, or
+//#  (at your option) any later version.
+//#
+//#  This program is distributed in the hope that it will be useful,
+//#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//#  GNU General Public License for more details.
+//#
+//#  You should have received a copy of the GNU General Public License
+//#  along with this program; if not, write to the Free Software
+//#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//#
+//#  $Id$
+
+#include <lofar_config.h>
+#include <Common/LofarLogger.h>
+#include <Common/hexdump.h>
+#include <APL/RSP_Protocol/EPA_Protocol.ph>
+
+#include <APL/RTCCommon/PSAccess.h>
+#include <string.h>
+
+#include "StationSettings.h"
+#include "HBAProtocolWrite.h"
+#include "RawBlockWrite.h"
+#include "Cache.h"
+
+#include <netinet/in.h>
+
+using namespace LOFAR;
+using namespace RSP;
+using namespace EPA_Protocol;
+using namespace blitz;
+
+//
+// RawBlockWrite(port, boardID)
+//
+RawBlockWrite::RawBlockWrite(GCFPortInterface& board_port, int board_id)
+  : SyncAction(board_port, board_id, 1)
+{
+	memset(&m_hdr, 0, sizeof(MEPHeader));
+}
+
+//
+// ~RawBlockWrite()
+//
+RawBlockWrite::~RawBlockWrite()
+{
+  /* TODO: delete event? */
+}
+
+//
+// sendrequest()
+//
+void RawBlockWrite::sendrequest()
+{
+	// skip update if nothing was modified
+	if (Cache::getInstance().getState().rawdatawrite().get(getBoardId()) != RTC::RegisterState::WRITE) {
+		Cache::getInstance().getState().rawdatawrite().unmodified(getBoardId());
+		setContinue(true);
+//		LOG_INFO_STR("@@@RawBlockWrite::sendrequest(" << getBoardId() << "):false");
+		return;
+	}
+//	LOG_INFO_STR("@@@RawBlockWrite::sendrequest(" << getBoardId() << "):true");
+
+	// Cache was modified, construct an EPA message and send it.
+	EPAWriteEvent	writeEvent;
+	RawDataBlock_t&	rdb = Cache::getInstance().getBack().getRawDataBlock();	// pointer to info
+	// construct header, but overwrite complete address with address from user
+	writeEvent.hdr.set(MEPHeader::RSP_RAWDATA_WRITE, 0, MEPHeader::WRITE, rdb.dataLen, rdb.offset);
+	memcpy((void*)&(writeEvent.hdr.m_fields.addr), (void*)&(rdb.address), sizeof(rdb.address));
+	// construct data part
+	writeEvent.payload.setBuffer(rdb.data, rdb.dataLen);
+
+	m_hdr = writeEvent.hdr; // remember header to match with ack
+
+//	string	hDump;	// DEBUG
+//	hexdump(hDump, (void*)&m_hdr.m_fields, MEPHeader::SIZE); // DEBUG
+//	LOG_INFO (hDump);
+//	hDump.clear();
+//	hexdump(hDump, writeEvent.payload.getBuffer(), writeEvent.payload.getDataLen());
+//	LOG_INFO (hDump);
+
+	// finally send the message
+	getBoardPort().send(writeEvent);
+
+	// we never want a rawBlock command to be repeated so mark it 'done' on forehand.
+	Cache::getInstance().getState().rawdatawrite().write_ack(getBoardId());
+}
+
+//
+// sendrequest_status()
+//
+void RawBlockWrite::sendrequest_status()
+{
+	// intentionally left empty
+}
+
+//
+// handleack(event, port)
+//
+GCFEvent::TResult RawBlockWrite::handleack(GCFEvent& event, GCFPortInterface& /*port*/)
+{
+//	LOG_INFO_STR("@@@RawBlockWrite::handleack(" << getBoardId() << ")");
+
+  	// Note: we don't have to check the event.signal here because it is always safe to 
+	//		 convert an event to a generic readackEvent.
+	//		 We can't even check it because the user made up the address and therefor the response-type.
+	EPAWriteackEvent ack(event);
+
+//	string	hDump;		/// DEBUG
+//	hexdump(hDump, (void*)&(ack.hdr.m_fields), MEPHeader::SIZE);
+//	LOG_INFO (hDump);
+
+	// check result
+	if (!ack.hdr.isValidAck(m_hdr)) {
+		LOG_ERROR("RawBlockWrite::handleack: invalid ack");
+		Cache::getInstance().getState().rawdatawrite().write_error(getBoardId());
+		return GCFEvent::HANDLED;
+	}
+
+	// Mark command ok.
+	Cache::getInstance().getState().rawdatawrite().write_ack(getBoardId());
+
+	return GCFEvent::HANDLED;
+}
diff --git a/MAC/APL/PIC/RSPDriver/src/RawBlockWrite.h b/MAC/APL/PIC/RSPDriver/src/RawBlockWrite.h
new file mode 100644
index 00000000000..7df842637be
--- /dev/null
+++ b/MAC/APL/PIC/RSPDriver/src/RawBlockWrite.h
@@ -0,0 +1,57 @@
+//#  -*- mode: c++ -*-
+//#
+//#  RawBlockWrite.h: Synchronize HBA settings with HBA hardware via RCU interface.
+//#
+//#  Copyright (C) 2002-2004
+//#  ASTRON (Netherlands Foundation for Research in Astronomy)
+//#  P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
+//#
+//#  This program is free software; you can redistribute it and/or modify
+//#  it under the terms of the GNU General Public License as published by
+//#  the Free Software Foundation; either version 2 of the License, or
+//#  (at your option) any later version.
+//#
+//#  This program is distributed in the hope that it will be useful,
+//#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//#  GNU General Public License for more details.
+//#
+//#  You should have received a copy of the GNU General Public License
+//#  along with this program; if not, write to the Free Software
+//#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//#
+//#  $Id$
+
+#ifndef RAWBLOCKWRITE_H_
+#define RAWBLOCKWRITE_H_
+
+#include <APL/RSP_Protocol/MEPHeader.h>
+
+#include "SyncAction.h"
+
+namespace LOFAR {
+  namespace RSP {
+
+class RawBlockWrite : public SyncAction
+{
+public:
+	// Constructors for a RawBlockWrite object.
+	RawBlockWrite(GCFPortInterface& board_port, int board_id);
+	virtual ~RawBlockWrite();
+
+	// Send the write message.
+	virtual void sendrequest();
+
+	// Send the read request.
+	virtual void sendrequest_status();
+
+	// Handle the read result.
+	virtual GCFEvent::TResult handleack(GCFEvent& event, GCFPortInterface& port);
+
+private:
+	EPA_Protocol::MEPHeader m_hdr;
+};
+  }; // namespace RSP
+}; // namespace LOFAR
+     
+#endif /* RAWBLOCKWRITE_H_ */
diff --git a/MAC/APL/PIC/RSPDriver/src/RawEvent.cc b/MAC/APL/PIC/RSPDriver/src/RawEvent.cc
index 567f47b9ad3..314db3de62d 100644
--- a/MAC/APL/PIC/RSPDriver/src/RawEvent.cc
+++ b/MAC/APL/PIC/RSPDriver/src/RawEvent.cc
@@ -23,6 +23,7 @@
 
 #include <lofar_config.h>
 #include <Common/LofarLogger.h>
+#include <Common/hexdump.h>
 #include <GCF/TM/GCF_ETHRawPort.h>
 
 #include <APL/RSP_Protocol/EPA_Protocol.ph>
@@ -709,103 +710,104 @@ GCFEvent::TResult RawEvent::dispatch(GCFTask& task, GCFPortInterface& port)
 {
 
 #if 0
-  cout << " sizeof(RawFrame)              =" << sizeof(RawFrame) << endl
-       << " sizeof(GCFEvent)              =" << sizeof(GCFEvent) << endl
-       << " sizeof(MEPHeader::FieldsType) =" << sizeof(MEPHeader::FieldsType) << endl
-       << " sizeof(payload)               =" << sizeof(buf.payload) << endl;
+	cout << " sizeof(RawFrame)              =" << sizeof(RawFrame) << endl
+		 << " sizeof(GCFEvent)              =" << sizeof(GCFEvent) << endl
+		 << " sizeof(MEPHeader::FieldsType) =" << sizeof(MEPHeader::FieldsType) << endl
+		 << " sizeof(payload)               =" << sizeof(buf.payload) << endl;
 #endif
 
-  GCFEvent::TResult status = GCFEvent::NOT_HANDLED;
-
-  // Receive a raw packet
-  ssize_t size = port.recv(&buf.mephdr, ETH_DATA_LEN);
-
-  if (size < (ssize_t)sizeof(buf.mephdr)) return GCFEvent::NOT_HANDLED;
-
-  LOG_DEBUG(formatString("F_DATAIN: type=0x%02x, status=%d, frame_length=%d, "
-			 "addr=(0x%04x 0x%02x 0x%02x), payload_length=%d, "
-			 "seqnr=%d",
-			 buf.mephdr.type,
-			 buf.mephdr.status,
-			 buf.mephdr.frame_length,
-			 buf.mephdr.addr.dstid,
-			 buf.mephdr.addr.pid,
-			 buf.mephdr.addr.regid,
-			 buf.mephdr.payload_length,
-			 buf.mephdr.seqnr));
-
-  unsigned short signal = 0; // signal == 0 indicates unrecognised or invalid MEP message
-
-  //
-  // Decode the header fields
-  //
-  if (   buf.mephdr.type       >= MEPHeader::MIN_TYPE
-      && buf.mephdr.type       <= MEPHeader::MAX_TYPE
-      && buf.mephdr.addr.pid   >= MEPHeader::MIN_PID
-      && buf.mephdr.addr.pid   <= MEPHeader::MAX_PID
-      && buf.mephdr.addr.regid <= MEPHeader::MAX_REGID)
-      /* always true due to limited range of datatype
-	 && buf.mephdr.addr.regid >= MEPHeader::MIN_REGID */
-  {
-    //
-    // If no error, lookup signal number, else assign ACK_ERROR signal number
-    //
-    if (0 == buf.mephdr.status)
-    {
-      signal = signal_lut[buf.mephdr.addr.pid - MEPHeader::MIN_PID][buf.mephdr.addr.regid][buf.mephdr.type];
-    }
-    else 
-    {
-      if (MEPHeader::READACK == buf.mephdr.type) signal = EPA_READACK_ERROR;
-      else if (MEPHeader::WRITEACK == buf.mephdr.type) signal = EPA_WRITEACK_ERROR;
-      else 
-      {
-	LOG_WARN("Protocol violation: received message other than MEPHeader::READACK or MEPHeader::WRITEACK with error != 0 set.");
-      }
-    }
-  } else {
-    LOG_WARN("Received message with out-of-range header fields");
-  }
-  
-  if (signal) // signal == 0 indicates unrecognised or invalid MEP message
-  {
-    (void)new((void*)&buf.event) GCFEvent(signal); // placement new does in place construction
-
-    // set the event length
-    buf.event.length = sizeof(buf.mephdr) + buf.mephdr.payload_length;
-
-    // check if there is more data than needed
-    if (size - (sizeof(GCFEvent) + sizeof(MEPHeader::FieldsType)) > 0)
-    {
-      LOG_DEBUG(formatString("discarding %d bytes", size - (sizeof(GCFEvent) + sizeof(MEPHeader::FieldsType))));
-    }
-
-    //
-    // Print debugging info
-    // 
+	GCFEvent::TResult status = GCFEvent::NOT_HANDLED;
+
+	// Receive a raw packet
+	ssize_t size = port.recv(&buf.mephdr, ETH_DATA_LEN);
+
+	// always need at least header_size bytes.
+	if (size < (ssize_t)sizeof(buf.mephdr)) {
+		return GCFEvent::NOT_HANDLED;
+	}
+
+	LOG_DEBUG(formatString("F_DATAIN: type=0x%02x, status=%d, frame_length=%d, "
+					"addr=(0x%04x 0x%02x 0x%02x), payload_length=%d, seqnr=%d",
+					buf.mephdr.type,
+					buf.mephdr.status,
+					buf.mephdr.frame_length,
+					buf.mephdr.addr.dstid,
+					buf.mephdr.addr.pid,
+					buf.mephdr.addr.regid,
+					buf.mephdr.payload_length,
+					buf.mephdr.seqnr));
+
+	unsigned short signal = 0; // signal == 0 indicates unrecognised or invalid MEP message
+
+	//
+	// Decode the header fields
+	//
+	if (   buf.mephdr.type       >= MEPHeader::MIN_TYPE
+		&& buf.mephdr.type       <= MEPHeader::MAX_TYPE
+		&& buf.mephdr.addr.pid   >= MEPHeader::MIN_PID
+		&& buf.mephdr.addr.pid   <= MEPHeader::MAX_PID
+		&& buf.mephdr.addr.regid <= MEPHeader::MAX_REGID) {
+		/* always true due to limited range of datatype
+		&& buf.mephdr.addr.regid >= MEPHeader::MIN_REGID */
+		//
+		// If no error, lookup signal number, else assign ACK_ERROR signal number
+		//
+		if (buf.mephdr.status == 0) {
+			signal = signal_lut[buf.mephdr.addr.pid - MEPHeader::MIN_PID][buf.mephdr.addr.regid][buf.mephdr.type];
+		}
+		else {
+			if (MEPHeader::READACK == buf.mephdr.type) {
+				signal = EPA_READACK_ERROR;
+			}
+			else if (MEPHeader::WRITEACK == buf.mephdr.type) {
+				signal = EPA_WRITEACK_ERROR;
+			}
+			else {
+				LOG_WARN("Protocol violation: received message other than MEPHeader::READACK or MEPHeader::WRITEACK with error != 0 set.");
+			}
+		} // status
+	} else {
+		LOG_WARN("Received message with out-of-range header fields");
+		string	hDump;
+		hexdump (hDump, (char*)&buf.mephdr, sizeof(buf.mephdr));
+		LOG_INFO (hDump);
+	}
+
+	if (signal) { // signal == 0 indicates unrecognised or invalid MEP message
+		(void)new((void*)&buf.event) GCFEvent(signal); // placement new does in place construction
+
+		// set the event length
+		buf.event.length = sizeof(buf.mephdr) + buf.mephdr.payload_length;
+
+		// check if there is more data than needed
+		if (size - (sizeof(GCFEvent) + sizeof(MEPHeader::FieldsType)) > 0) {
+			LOG_DEBUG(formatString("discarding %d bytes", size - (sizeof(GCFEvent) + sizeof(MEPHeader::FieldsType))));
+		}
+
+		//
+		// Print debugging info
+		// 
 #if 0
-    if ((F_DATAIN != buf.event.signal) && 
+		if ((F_DATAIN != buf.event.signal) && 
 			(F_DATAOUT != buf.event.signal) &&
 			(F_EVT_PROTOCOL(buf.event) != F_FSM_PROTOCOL) &&
-			(F_EVT_PROTOCOL(buf.event) != F_PORT_PROTOCOL))
-    {
-      LOG_DEBUG(formatString("%s receives '%s' on port '%s'",
-			     task.getName().c_str(), 
-			     task.evtstr(buf.event), port.getName().c_str()));
-    }
+			(F_EVT_PROTOCOL(buf.event) != F_PORT_PROTOCOL)) {
+				LOG_DEBUG(formatString("%s receives '%s' on port '%s'",
+				task.getName().c_str(), 
+				task.evtstr(buf.event), port.getName().c_str()));
+		}
 #endif
 
-    //
-    // dispatch the MEP message as a GCFEvent (which it now is)
-    //
-    status = task.dispatch(buf.event, port);
-  }
-  else
-  {
-    LOG_WARN("F_DATAIN: Discarding unknown message.");
-  }
+		//
+		// dispatch the MEP message as a GCFEvent (which it now is)
+		//
+		status = task.dispatch(buf.event, port);
+	}
+	else {
+		LOG_WARN("F_DATAIN: Discarding unknown message.");
+	}
 
-  return status;
+	return (status);
 }
  
 
diff --git a/MAC/APL/PIC/RSPDriver/src/Scheduler.cc b/MAC/APL/PIC/RSPDriver/src/Scheduler.cc
index 465178f5d5a..72a2a8ff4a8 100644
--- a/MAC/APL/PIC/RSPDriver/src/Scheduler.cc
+++ b/MAC/APL/PIC/RSPDriver/src/Scheduler.cc
@@ -38,471 +38,473 @@ int Scheduler::SYNC_INTERVAL_INT = 1; // default
 
 Scheduler::Scheduler()
 {
-  SYNC_INTERVAL_INT = (int)trunc(GET_CONFIG("RSPDriver.SYNC_INTERVAL", f)+0.5);
+	SYNC_INTERVAL_INT = (int)trunc(GET_CONFIG("RSPDriver.SYNC_INTERVAL", f)+0.5);
 }
 
 Scheduler::~Scheduler()
 {
-  /* clear the various queues */
-  while (!m_later_queue.empty())    m_later_queue.pop();
-  while (!m_now_queue.empty())      m_now_queue.pop();
-  while (!m_periodic_queue.empty()) m_periodic_queue.pop();
-  while (!m_done_queue.empty())     m_done_queue.pop();
-
-  for (map< GCFPortInterface*, vector<SyncAction*> >::iterator port = m_syncactions.begin();
-       port != m_syncactions.end();
-       port++)
-  {
-    for (vector<SyncAction*>::iterator sa = (*port).second.begin();
-	 sa != (*port).second.end();
-	 sa++)
-    {
-      delete (*sa);
-    }
-  }
+	/* clear the various queues */
+	while (!m_later_queue.empty())    m_later_queue.pop();
+	while (!m_now_queue.empty())      m_now_queue.pop();
+	while (!m_periodic_queue.empty()) m_periodic_queue.pop();
+	while (!m_done_queue.empty())     m_done_queue.pop();
+
+	for (map< GCFPortInterface*, vector<SyncAction*> >::iterator port = m_syncactions.begin();
+			port != m_syncactions.end(); port++) {
+		for (vector<SyncAction*>::iterator sa = (*port).second.begin();
+				sa != (*port).second.end(); sa++) {
+			delete (*sa);
+		}
+	}
 }
 
+//
+// run(event, port)
+//
 GCFEvent::TResult Scheduler::run(GCFEvent& event, GCFPortInterface& /*port*/)
 {
-  const GCFTimerEvent* timeout = static_cast<const GCFTimerEvent*>(&event);
-  
-  if (F_TIMER == event.signal)
-  {
-    LOG_DEBUG("Scheduler::run");
-
-    if (!syncHasCompleted())
-    {
-      LOG_ERROR("previous sync has not yet completed!, skipping sync");
-      for (map< GCFPortInterface*, bool >::iterator it = m_sync_completed.begin();
-	   it != m_sync_completed.end();
-	   it++)
-      {
-	if (!(*it).second)
-	{
-	  LOG_WARN(formatString("port %s has not yet completed sync, trying to continue...",
-				(*it).first->getName().c_str()));
+	const GCFTimerEvent* timeout = static_cast<const GCFTimerEvent*>(&event);
+
+	if (F_TIMER == event.signal) {
+		LOG_DEBUG("Scheduler::run");
+
+		if (!syncHasCompleted()) {
+			LOG_ERROR("previous sync has not yet completed!, skipping sync");
+			for (map< GCFPortInterface*, bool >::iterator it = m_sync_completed.begin();
+					it != m_sync_completed.end(); it++) {
+				if (!(*it).second) {
+					LOG_WARN(formatString("port %s has not yet completed sync, trying to continue...",
+							(*it).first->getName().c_str()));
+				}
+
+				// reset the statemachines of all SyncActions for this port
+				resetSync(*(*it).first);
+			}
+
+			// This is caused by a problem with the firmware
+			// or a loose cable, simply try to continue.
+			//
+			// In the future some more elaborate fault handling
+			// might be required.
+			completeSync();
+		}
+
+		// round to nearest second t, warn if time is too far off from top of second
+		//
+		//        t-1        t         t+1
+		//            XXXX|<--->|XXXX
+		unsigned long topofsecond = timeout->sec;
+		if (timeout->usec >= 1e6-1000) {
+			topofsecond++; // round to next whole second
+		}
+		if (timeout->usec > 1000 && timeout->usec < 1e6 - 1000) {
+			LOG_WARN_STR("Scheduler time too far off from top off second: usec=" << timeout->usec);
+		}
+		setCurrentTime(topofsecond, 0);
+
+		scheduleCommands();
+		processCommands();
+
+		initiateSync(event); // matched by completeSync
+	}
+	else {
+		LOG_ERROR("\nreceived invalid event != F_TIMER\n");
 	}
 
-	//
-	// reset the statemachines of all SyncActions for this port
-	//
-	resetSync(*(*it).first);
-      }
-
-      //
-      // This is caused by a problem with the firmware
-      // or a loose cable, simply try to continue.
-      //
-      // In the future some more elaborate fault handling
-      // might be required.
-      //
-      completeSync();
-    }
-
-    //
-    // round to nearest second t, warn if time is too far off from top of second
-    //
-    //        t-1        t         t+1
-    //            XXXX|<--->|XXXX
-    //
-    unsigned long topofsecond = timeout->sec;
-    if (timeout->usec >= 1e6-1000) topofsecond++; // round to next whole second
-    if (timeout->usec > 1000 && timeout->usec < 1e6 - 1000) {
-      LOG_WARN_STR("Scheduler time too far off from top off second: usec=" << timeout->usec);
-    }
-    setCurrentTime(topofsecond, 0);
-
-    scheduleCommands();
-    processCommands();
-
-    initiateSync(event); // matched by completeSync
-  }
-  else
-  {
-    LOG_ERROR("\nreceived invalid event != F_TIMER\n");
-  }
-
-  return GCFEvent::HANDLED;
+	return GCFEvent::HANDLED;
 }
 
+//
+// dispatch (event, port)
+//
 GCFEvent::TResult Scheduler::dispatch(GCFEvent& event, GCFPortInterface& port)
 {
-  GCFEvent::TResult status = GCFEvent::NOT_HANDLED;
-  GCFTimerEvent timer;
-  GCFEvent* current_event = &event;
-  bool sync_completed = true;
-  
-  /**
-   * Dispatch the event to the first SyncAction that
-   * has not yet reached its 'final' state.
-   */
-  vector<SyncAction*>::iterator sa;
-  int i = 0;
-  for (sa = m_syncactions[&port].begin();
-       sa != m_syncactions[&port].end();
-       sa++, i++)
-  {
-    if (!(*sa)->hasCompleted())
-    {
-      // stil busy
-      sync_completed = false;
-
-      status = (*sa)->dispatch(*current_event, (*sa)->getBoardPort());
-
-      //
-      // if the syncaction has not yet been completed, break the loop
-      // it will receive another event to continue
-      //
-      if (!(*sa)->hasCompleted()) break;
-      else
-      {
-	sync_completed = true;
-	current_event = &timer; 
-      }
-    }
-  }
-
-  if (sync_completed)
-  {
-    m_sync_completed[&port] = true;
-  }
-
-  if (syncHasCompleted())
-  {
-    completeSync();
-  }
-
-  return status;
+	GCFEvent::TResult status = GCFEvent::NOT_HANDLED;
+	GCFTimerEvent 	  timer;
+	GCFEvent* 	 	  current_event = &event;
+	bool 			  sync_completed = true;
+
+	// Dispatch the event to the first SyncAction that
+	// has not yet reached its 'final' state.
+	vector<SyncAction*>::iterator sa;
+	int i = 0;
+	for (sa = m_syncactions[&port].begin(); sa != m_syncactions[&port].end(); sa++, i++) {
+		if (!(*sa)->hasCompleted()) {
+			// stil busy
+			sync_completed = false;
+			status = (*sa)->dispatch(*current_event, (*sa)->getBoardPort());
+
+			// if the syncaction has not yet been completed, break the loop
+			// it will receive another event to continue
+			if (!(*sa)->hasCompleted()) {
+				break;
+			}
+			else {
+				sync_completed = true;
+				current_event = &timer; 
+			}
+		}
+	}
+
+	if (sync_completed) {
+		m_sync_completed[&port] = true;
+	}
+
+	if (syncHasCompleted()) {		// all boards ready???
+		completeSync();
+	}
+
+	return status;
 }
 
+//
+// syncHasCompleted
+//
+// Check if all boards have finished their sequence.
+//
 bool Scheduler::syncHasCompleted()
 {
-  bool result = true;
-  
-  for (map< GCFPortInterface*, bool >::iterator it = m_sync_completed.begin();
-       it != m_sync_completed.end();
-       it++)
-  {
-    if (!(*it).second) { result = false; }
-  }
-
-  return result;
+	for (map< GCFPortInterface*, bool >::iterator it = m_sync_completed.begin();
+			it != m_sync_completed.end(); it++) {
+		if (!(*it).second) { 
+			return(false);
+		}
+	}
+
+	return (true);
 }
 
-int Scheduler::pqueue_remove_commands(pqueue& pq,
-				      GCFPortInterface& port,
-				      memptr_t handle)
+//
+// pqueue_remove_commands(pqueue, port, memptr)
+//
+int Scheduler::pqueue_remove_commands(pqueue&			pq,
+									  GCFPortInterface& port,
+									  memptr_t 			handle)
 {
-  int count = 0;
-  
-  // copy pq
-  pqueue tmp(pq);
-
-  // clear pq, it will be filled again in the next loop
-  while (!pq.empty()) pq.pop();
-
-  while (!tmp.empty())
-  {
-    // pop item from the queue
-    Ptr<Command> c = tmp.top();
-    tmp.pop();
-
-    // if port matches, delete c, else push back onto pq
-    if ((c->getPort() == &port) && (0 == handle || &(*c) == (Command*)handle))
-    {
-      count++;
-      // don't push back on pq, c will be deleted when it goes out of scope
-    }
-    else pq.push(c);
-  }
-  
-  return count;
+	int count = 0;
+
+	// copy pq
+	pqueue tmp(pq);
+
+	// clear pq, it will be filled again in the next loop
+	while (!pq.empty())  {
+		pq.pop();
+	}
+
+	while (!tmp.empty()) {
+		// pop item from the queue
+		Ptr<Command> c = tmp.top();
+		tmp.pop();
+
+		// if port matches, delete c, else push back onto pq
+		if ((c->getPort() == &port) && (0 == handle || &(*c) == (Command*)handle)) {
+			count++;
+			// don't push back on pq, c will be deleted when it goes out of scope
+		}
+		else {
+			pq.push(c);
+		}
+	}
+
+	return count;
 }
 
+//
+// cancel(port)
+//
 int Scheduler::cancel(GCFPortInterface& port)
 {
-  int count = 0;
-  
-  // cancel all commands related to this port
-  // irrespective of the queue they are in
-
-  count += pqueue_remove_commands(m_later_queue,    port);
-  count += pqueue_remove_commands(m_now_queue,      port);
-  count += pqueue_remove_commands(m_periodic_queue, port);
-  count += pqueue_remove_commands(m_done_queue,     port);
-
-  return count;
+	// cancel all commands related to this port
+	// irrespective of the queue they are in
+	int count = 0;
+	count += pqueue_remove_commands(m_later_queue,    port);
+	count += pqueue_remove_commands(m_now_queue,      port);
+	count += pqueue_remove_commands(m_periodic_queue, port);
+	count += pqueue_remove_commands(m_done_queue,     port);
+
+	return count;
 }
 
+//
+// remove_subscription(port, memptr)
+//
 int Scheduler::remove_subscription(GCFPortInterface& port, memptr_t handle)
 {
-  int count = 0;
+	int count = 0;
+	count += pqueue_remove_commands(m_later_queue,    port, handle);
+	count += pqueue_remove_commands(m_now_queue,      port, handle);
+	count += pqueue_remove_commands(m_periodic_queue, port, handle);
+	count += pqueue_remove_commands(m_done_queue,     port, handle);
 
-  count += pqueue_remove_commands(m_later_queue,    port, handle);
-  count += pqueue_remove_commands(m_now_queue,      port, handle);
-  count += pqueue_remove_commands(m_periodic_queue, port, handle);
-  count += pqueue_remove_commands(m_done_queue,     port, handle);
-
-  return count;
+	return count;
 }
 
+//
+// addSyncAction(action)
+//
 void Scheduler::addSyncAction(SyncAction* action)
 {
-  m_syncactions[&(action->getBoardPort())].push_back(action);
+	m_syncactions[&(action->getBoardPort())].push_back(action);
 }
 
+//
+// enter(command, queue)
+//
 Timestamp Scheduler::enter(Ptr<Command> command, QueueID queue)
 {
-  Timestamp scheduled_time = command->getTimestamp();
-
-  /* determine at which time the command can actually be carried out */
-  if (scheduled_time.sec() < m_current_time.sec() + SCHEDULING_DELAY)
-  {
-    if (scheduled_time.sec() > 0) // filter Timestamp(0,0) case
-    {
-      LOG_WARN(formatString("command missed deadline by %d seconds",
-			    m_current_time.sec() - scheduled_time.sec()));
-    }
-    
-    scheduled_time = m_current_time + (long)SCHEDULING_DELAY;
-  }
-  
-  // set the actual time at which the command is sent to the boards
-  command->setTimestamp(scheduled_time);
-    
-  // print time, ugly
-  char timestr[32];
-  time_t sec = scheduled_time.sec();
-  strftime(timestr, 32, "%T", gmtime(&sec));
-  LOG_DEBUG(formatString("Scheduler::enter scheduled_time=%s.%d UTC", timestr, scheduled_time.usec()));
-
-  // push the command on the appropriate queue
-  switch (queue)
-  {
-    case LATER:
-      m_later_queue.push(command);
-      break;
-
-    case PERIODIC:
-      m_periodic_queue.push(command);
-      break;
-
-    default:
-      LOG_FATAL("invalid QueueID");
-      exit(EXIT_FAILURE);
-      break;
-  }
-  
-  return Timestamp(0,0); // this return value should not be used anymore
+	Timestamp scheduled_time = command->getTimestamp();
+
+	/* determine at which time the command can actually be carried out */
+	if (scheduled_time.sec() < m_current_time.sec() + SCHEDULING_DELAY) {
+		if (scheduled_time.sec() > 0)  { // filter Timestamp(0,0) case
+			LOG_WARN(formatString("command missed deadline by %d seconds",
+			m_current_time.sec() - scheduled_time.sec()));
+		}
+
+		scheduled_time = m_current_time + (long)SCHEDULING_DELAY;
+	}
+
+	// set the actual time at which the command is sent to the boards
+	command->setTimestamp(scheduled_time);
+
+	// print time, ugly
+	char timestr[32];
+	time_t sec = scheduled_time.sec();
+	strftime(timestr, 32, "%T", gmtime(&sec));
+	LOG_DEBUG(formatString("Scheduler::enter scheduled_time=%s.%d UTC", timestr, scheduled_time.usec()));
+
+	// push the command on the appropriate queue
+	switch (queue) {
+	case LATER:
+		m_later_queue.push(command);
+		break;
+
+	case PERIODIC:
+		m_periodic_queue.push(command);
+		break;
+
+	default:
+		LOG_FATAL("invalid QueueID");
+		exit(EXIT_FAILURE);
+		break;
+	}
+
+	return Timestamp(0,0); // this return value should not be used anymore
 }
 
+//
+// setCurrentTime(sec, usec)
+//
 void Scheduler::setCurrentTime(long sec, long usec)
 {
-  /* adjust the current time */
-  m_current_time = Timestamp(sec, usec);
+	/* adjust the current time */
+	m_current_time = Timestamp(sec, usec);
 }
 
+//
+// getCurrentTime()
+//
 Timestamp Scheduler::getCurrentTime() const
 {
-  return m_current_time;
+	return m_current_time;
 }
 
+//
+// scheduleCommands()
+//
+// Schedule commands from later-queue and periodic-queue by setting them in the now-queue
+//
 void Scheduler::scheduleCommands()
 {
-  int scheduling_offset = 0;
-
-  /**
-   * All commands with a timestamp equal to the
-   * wall-clock time (m_current_time) plus one second
-   * should be scheduled now.
-   */
-  while (!m_later_queue.empty())
-  {
-    Ptr<Command> command = m_later_queue.top();
-
-    // write commands need to be scheduled on sync period ahead of time
-    // to be effective in the hardware at the specified timestamp
-    scheduling_offset = 0;
-    if (Command::WRITE == command->getOperation())
-    {
-      scheduling_offset = SYNC_INTERVAL_INT;
-    }
-
-    /* detect late commands, but just execute them */
-    if (command->getTimestamp() <= m_current_time + (long)(scheduling_offset - SYNC_INTERVAL_INT))
-    {
-      LOG_WARN_STR("command is late, timestamp=" << command->getTimestamp()
-		   << ", current_time=" << m_current_time);
-    }
-
-    if (command->getTimestamp() <= m_current_time + (long)scheduling_offset)
-    {
-      LOG_DEBUG_STR("scheduling command with time=" << command->getTimestamp());
-
-      m_now_queue.push(command);
-      m_later_queue.pop();
-    }
-    else break;
-  }
-
-  /* copy periodic commands to the now queue */
-  pqueue pq = m_periodic_queue;
-  
-  while (!pq.empty())
-  {
-    Ptr<Command> command = pq.top();
-
-    // read commands need to be scheduled on sync period ahead of time
-    // to be effective in the hardware at the specified timestamp
-    scheduling_offset = 0;
-    if (Command::WRITE == command->getOperation())
-    {
-      scheduling_offset = SYNC_INTERVAL_INT;
-    }
-
-    /* detect late commands, but just execute them */
-    if (command->getTimestamp() <= m_current_time + (long)(scheduling_offset - SYNC_INTERVAL_INT))
-    {
-      LOG_WARN_STR("periodic command is late, timestamp=" << command->getTimestamp()
-		   << ", current_time=" << m_current_time);
-    }
-
-    if (command->getTimestamp() <= m_current_time + (long)scheduling_offset)
-    {
-      LOG_DEBUG_STR("scheduling periodic command with time=" << command->getTimestamp());
-      m_now_queue.push(command);
-    }
-
-    pq.pop(); // next
-  }
+	int scheduling_offset = 0;
+
+	// All commands with a timestamp equal to the
+	// wall-clock time (m_current_time) plus one second
+	// should be scheduled now.
+	while (!m_later_queue.empty()) {
+		Ptr<Command> command = m_later_queue.top();
+
+		// write commands need to be scheduled on sync period ahead of time
+		// to be effective in the hardware at the specified timestamp
+		scheduling_offset = 0;
+		if (Command::WRITE == command->getOperation()) {
+			scheduling_offset = SYNC_INTERVAL_INT;
+		}
+
+		/* detect late commands, but just execute them */
+		if (command->getTimestamp() <= m_current_time + (long)(scheduling_offset - SYNC_INTERVAL_INT)) {
+			LOG_WARN_STR("command is late, timestamp=" << command->getTimestamp()
+						<< ", current_time=" << m_current_time);
+		}
+
+		if (command->getTimestamp() <= m_current_time + (long)scheduling_offset) {
+			LOG_DEBUG_STR("scheduling command with time=" << command->getTimestamp());
+
+			m_now_queue.push(command);
+			m_later_queue.pop();
+		}
+		else {
+			break;
+		}
+	}
+
+	/* copy periodic commands to the now queue */
+	pqueue pq = m_periodic_queue;
+
+	while (!pq.empty()) {
+		Ptr<Command> command = pq.top();
+
+		// read commands need to be scheduled on sync period ahead of time
+		// to be effective in the hardware at the specified timestamp
+		scheduling_offset = 0;
+		if (Command::WRITE == command->getOperation()) {
+			scheduling_offset = SYNC_INTERVAL_INT;
+		}
+
+		/* detect late commands, but just execute them */
+		if (command->getTimestamp() <= m_current_time + (long)(scheduling_offset - SYNC_INTERVAL_INT)) {
+			LOG_WARN_STR("periodic command is late, timestamp=" << command->getTimestamp()
+			<< ", current_time=" << m_current_time);
+		}
+
+		if (command->getTimestamp() <= m_current_time + (long)scheduling_offset) {
+			LOG_DEBUG_STR("scheduling periodic command with time=" << command->getTimestamp());
+			m_now_queue.push(command);
+		}
+
+		pq.pop(); // next
+	}
 }
 
+//
+// processCommands()
+//
+// Call 'apply' on every command in the now_queue
+//
 void Scheduler::processCommands()
 {
-  Cache::getInstance().getFront().setTimestamp(getCurrentTime());
-  Cache::getInstance().getFront().setTimestamp(getCurrentTime());
-
-  while (!m_now_queue.empty())
-  {
-    Ptr<Command> command = m_now_queue.top();
-
-    /* *
-     * Let the commands apply their changes to 
-     * the front and back caches.
-     */
-    command->apply(Cache::getInstance().getFront(), true);
-    command->apply(Cache::getInstance().getBack(), false);
-
-    /* move from the now queue to the done queue */
-    m_now_queue.pop();
-    m_done_queue.push(command);
-  }
+	Cache::getInstance().getFront().setTimestamp(getCurrentTime());
+	Cache::getInstance().getFront().setTimestamp(getCurrentTime());
+
+	while (!m_now_queue.empty()) {
+		Ptr<Command> command = m_now_queue.top();
+
+		// Let the commands apply their changes to 
+		// the front and back caches.
+		command->apply(Cache::getInstance().getFront(), true);
+		command->apply(Cache::getInstance().getBack(), false);
+
+		// move from the now queue to the done queue
+		m_now_queue.pop();
+		m_done_queue.push(command);
+	}
 }
 
+//
+// initiateSync(event)
+//
 void Scheduler::initiateSync(GCFEvent& event)
 {
-  m_sync_completed.clear();
-
-  /**
-   * Send the first syncaction for each board the timer
-   * event to set of the data communication to each board.
-   */
-  for (map< GCFPortInterface*, vector<SyncAction*> >::iterator port = m_syncactions.begin();
-       port != m_syncactions.end();
-       port++)
-  {
-    // reset sync flag
-    m_sync_completed[(*port).first] = false;
-
-    for (vector<SyncAction*>::iterator sa = (*port).second.begin();
-	 sa != (*port).second.end();
-	 sa++)
-    {
-      (*sa)->setCompleted(false);
-    }
-    
-    // dispatch F_TIMER event to first syncactions for each board
-    if (!(*port).second.empty())
-    {
-      for (unsigned int i = 0; i < (*port).second.size(); i++) {
-	(*port).second[i]->dispatch(event, (*port).second[i]->getBoardPort());
-	if (!(*port).second[i]->doContinue()) break;
-      }
-    }
-  }
+	m_sync_completed.clear();
+
+	// Send the first syncaction for each board the timer
+	// event to set of the data communication to each board.
+	for (map< GCFPortInterface*, vector<SyncAction*> >::iterator port = m_syncactions.begin();
+			port != m_syncactions.end(); port++) { 
+		// first reset our sync flag
+		m_sync_completed[(*port).first] = false;
+
+		// also mark all commands as not completed yet.
+		for (vector<SyncAction*>::iterator sa = (*port).second.begin();
+				sa != (*port).second.end(); sa++) { 
+			(*sa)->setCompleted(false);
+		}
+
+		// dispatch F_TIMER event to first syncactions for each board
+		if (!(*port).second.empty()) {
+			for (unsigned int i = 0; i < (*port).second.size(); i++) {
+				(*port).second[i]->dispatch(event, (*port).second[i]->getBoardPort());
+				if (!(*port).second[i]->doContinue()) {
+					break;
+				}
+			}
+		}
+	}
 }
 
+//
+// resetSync(port)
+//
+// Reset the state machines of all Sync Actions
+// for the port, to attempt another sync in the next
+// update period.
+//
 void Scheduler::resetSync(GCFPortInterface& port)
 {
-  /**
-   * Reset the state machines of all Sync Actions
-   * for the port, to attempt another sync in the next
-   * update period.
-   */
-  vector<SyncAction*>::iterator sa;
-  int i = 0;
-  for (sa = m_syncactions[&port].begin();
-       sa != m_syncactions[&port].end();
-       sa++, i++)
-  {
-    (*sa)->reset();
-  }
+	vector<SyncAction*>::iterator sa;
+	for (sa = m_syncactions[&port].begin(); sa != m_syncactions[&port].end(); sa++) {
+		(*sa)->reset();
+	}
 }
 
+//
+//completeSync()
+//
 void Scheduler::completeSync()
 {
-  // print current state for all registers
-  ostringstream logStream;
-  Cache::getInstance().getState().print(logStream);
-  LOG_DEBUG_STR(logStream);
+	// print current state for all registers
+	ostringstream logStream;
+	Cache::getInstance().getState().print(logStream);
+	LOG_DEBUG_STR(logStream);
 
-  // swap the buffers
-  // new data from the boards which was in the back buffers
-  // will end up in the front buffers.
-  Cache::getInstance().swapBuffers();
+	// swap the buffers
+	// new data from the boards which was in the back buffers
+	// will end up in the front buffers.
+	Cache::getInstance().swapBuffers();
 
-  // complete any outstanding commands
-  completeCommands();
+	// complete any outstanding commands
+	completeCommands();
 
-  // clear from DONE to IDLE state
-  Cache::getInstance().getState().clear();
+	// clear from DONE to IDLE state
+	Cache::getInstance().getState().clear();
 
-  // schedule next update
-  Cache::getInstance().getState().schedule(); // if IDLE transition to READ or CHECK
+	// schedule next update
+	Cache::getInstance().getState().schedule(); // if IDLE transition to READ or CHECK
 }
 
+//
+// completeCommands()
+//
 void Scheduler::completeCommands()
 {
-  while (!m_done_queue.empty())
-  {
-    Ptr<Command> command = m_done_queue.top();
-    
-    command->complete(Cache::getInstance().getFront());
-    
-    // re-timestamp periodic commands for the next period
-    if (command->getPeriod())
-    {
-      // Set the next time at which the periodic command should be executed.
-      //
-      // This is not as simple as doing command->setTimestamp(command->getTimestamp() + (long)command->getPeriod());
-      // because command->getTimestamp() returns the previous time at which the command
-      // was executed. In some cases (due to missed PPSes) the sum of the previous timestamp
-      // and the period will be in the past causing the periodic command to be logged as
-      // 'late' from that point onwards.
-      //
-      // To correctly compute the next time at which a periodic command should execute, take
-      // the absolute current time and add the period, but make sure the periodic command
-      // continues to be executed on the grid defined by the period. E.g. if a command is 
-      // executed every 4 seconds starting on second 1, so 1,5,9, etc and some PPSes are missed
-      // lets say PPS 10,11,12,13 (and current time is 13) then it should continue at time 17.
-      //
-      Timestamp newtime = getCurrentTime()
-	                     + ((long)command->getPeriod()
-				- ((long)command->getTimestamp() % (long)command->getPeriod()));
-      command->setTimestamp(newtime);
-    }
-
-    m_done_queue.pop();
-  }
+	while (!m_done_queue.empty()) {
+		Ptr<Command> command = m_done_queue.top();
+
+		command->complete(Cache::getInstance().getFront());
+
+		// re-timestamp periodic commands for the next period
+		if (command->getPeriod()) {
+			// Set the next time at which the periodic command should be executed.
+			//
+			// This is not as simple as doing command->setTimestamp(command->getTimestamp() + command->getPeriod());
+			// because command->getTimestamp() returns the previous time at which the command
+			// was executed. In some cases (due to missed PPSes) the sum of the previous timestamp
+			// and the period will be in the past causing the periodic command to be logged as
+			// 'late' from that point onwards.
+			//
+			// To correctly compute the next time at which a periodic command should execute, take
+			// the absolute current time and add the period, but make sure the periodic command
+			// continues to be executed on the grid defined by the period. E.g. if a command is 
+			// executed every 4 seconds starting on second 1, so 1,5,9, etc and some PPSes are missed
+			// lets say PPS 10,11,12,13 (and current time is 13) then it should continue at time 17.
+			//
+			Timestamp newtime = getCurrentTime()
+								+ ((long)command->getPeriod()
+								- ((long)command->getTimestamp() % (long)command->getPeriod()));
+			command->setTimestamp(newtime);
+		}
+
+		m_done_queue.pop();
+	}
 }
 
diff --git a/MAC/APL/PIC/RSPDriver/src/SetRawBlockCmd.cc b/MAC/APL/PIC/RSPDriver/src/SetRawBlockCmd.cc
new file mode 100644
index 00000000000..bc5d7aeeeb8
--- /dev/null
+++ b/MAC/APL/PIC/RSPDriver/src/SetRawBlockCmd.cc
@@ -0,0 +1,158 @@
+//#  SetRawBlockCmd.cc: implementation of the SetRawBlockCmd class
+//#
+//#  Copyright (C) 2008
+//#  ASTRON (Netherlands Foundation for Research in Astronomy)
+//#  P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
+//#
+//#  This program is free software; you can redistribute it and/or modify
+//#  it under the terms of the GNU General Public License as published by
+//#  the Free Software Foundation; either version 2 of the License, or
+//#  (at your option) any later version.
+//#
+//#  This program is distributed in the hope that it will be useful,
+//#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//#  GNU General Public License for more details.
+//#
+//#  You should have received a copy of the GNU General Public License
+//#  along with this program; if not, write to the Free Software
+//#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//#
+//#  $Id$
+
+#include <lofar_config.h>
+#include <Common/LofarLogger.h>
+#include <Common/hexdump.h>
+
+#include <APL/RSP_Protocol/RSP_Protocol.ph>
+#include <APL/RTCCommon/PSAccess.h>
+#include <blitz/array.h>
+
+#include "StationSettings.h"
+#include "SetRawBlockCmd.h"
+
+namespace LOFAR {
+  namespace RSP {
+//	using namespace blitz;
+	using namespace RSP_Protocol;
+	using namespace RTC;		// Timestamp
+
+//
+// SetRawBlockCmd(event, port, oper)
+//
+SetRawBlockCmd::SetRawBlockCmd(GCFEvent& event, GCFPortInterface& port, Operation oper)
+{
+	itsEvent = new RSPSetblockEvent(event);
+
+	setOperation(oper);
+	setPeriod(0);
+	setPort(port);
+}
+
+//
+// ~SetRawBlockCmd()
+//
+SetRawBlockCmd::~SetRawBlockCmd()
+{
+	delete itsEvent;
+}
+
+//
+// ack(cache)
+//
+void SetRawBlockCmd::ack(CacheBuffer& cache)
+{
+	RSPSetblockackEvent ack;
+	ack.timestamp = getTimestamp();
+	ack.boardID	  = itsEvent->boardID;
+	ack.status 	  = SUCCESS;
+
+	getPort()->send(ack);
+}
+
+//
+// apply(cache, setModFlag)
+//
+void SetRawBlockCmd::apply(CacheBuffer& cache, bool setModFlag)
+{
+	// fill the cache with the request and tickle it.
+//	LOG_INFO(formatString("@@@SetRawBlockCmd::apply(%d,%0X,%d,%d)", 
+//			itsEvent->boardID, itsEvent->address, itsEvent->offset, itsEvent->dataLen));
+
+	// NOTE: [REO] I expected that the next 4 lines could also be in the if(setModFlag)
+	//		 but it turned out that the info is than in the front cache when the RawDataBlockRead
+	//		 command needs it!!!
+	//		 Since only one command can be scheduled at the time, I write it in both caches.
+
+	// copy information (always?) to the cache
+	RawDataBlock_t&	rdb = cache.getRawDataBlock();
+	rdb.address = itsEvent->address;
+	rdb.offset  = itsEvent->offset;
+	rdb.dataLen = itsEvent->dataLen;
+	memcpy(rdb.data, itsEvent->data, rdb.dataLen);
+
+//	string hDump;
+//	hexdump(hDump, rdb.data, rdb.dataLen);
+//	LOG_INFO(hDump);
+
+	if (setModFlag) {
+		// tell cache(status) that we expect a write action.
+		cache.getCache().getState().rawdatawrite().write(itsEvent->boardID);
+	}
+}
+
+//
+// complete(cache)
+//
+void SetRawBlockCmd::complete(CacheBuffer& cache)
+{
+	ack(cache);
+}
+
+//
+// getTimeStamp()
+//
+const Timestamp& SetRawBlockCmd::getTimestamp() const
+{
+	return (itsEvent->timestamp);
+}
+
+//
+// setTimestamp(timestamp)
+//
+void SetRawBlockCmd::setTimestamp(const Timestamp& timestamp)
+{
+	itsEvent->timestamp = timestamp;
+}
+
+//
+// validate()
+//
+bool SetRawBlockCmd::validate() const
+{
+	return (true);
+}
+
+//
+// readFromCache()
+//
+bool SetRawBlockCmd::readFromCache() const
+{
+	return (false);
+}
+
+//
+// ack_fail()
+//
+void SetRawBlockCmd::ack_fail()
+{
+	RSPSetblockackEvent ack;
+	ack.timestamp = getTimestamp();
+	ack.status 	  = FAILURE;
+	LOG_INFO ("SetRawBlockCmd::ack_fail");
+
+	getPort()->send(ack);
+}
+
+  } // namepsace RSP
+} // namespace LOFAR
diff --git a/MAC/APL/PIC/RSPDriver/src/SetRawBlockCmd.h b/MAC/APL/PIC/RSPDriver/src/SetRawBlockCmd.h
new file mode 100644
index 00000000000..898a3385d70
--- /dev/null
+++ b/MAC/APL/PIC/RSPDriver/src/SetRawBlockCmd.h
@@ -0,0 +1,81 @@
+//#  -*- mode: c++ -*-
+//#
+//#  SetRawBlockCmd.h: Get system status command.
+//#
+//#  Copyright (C) 2008
+//#  ASTRON (Netherlands Foundation for Research in Astronomy)
+//#  P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
+//#
+//#  This program is free software; you can redistribute it and/or modify
+//#  it under the terms of the GNU General Public License as published by
+//#  the Free Software Foundation; either version 2 of the License, or
+//#  (at your option) any later version.
+//#
+//#  This program is distributed in the hope that it will be useful,
+//#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//#  GNU General Public License for more details.
+//#
+//#  You should have received a copy of the GNU General Public License
+//#  along with this program; if not, write to the Free Software
+//#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//#
+//#  $Id$
+
+#ifndef SET_RAWBLOCK_CMD_H
+#define SET_RAWBLOCK_CMD_H
+
+#include "Command.h"
+#include <APL/RSP_Protocol/RSP_Protocol.ph>
+
+#include <Common/LofarTypes.h>
+#include <GCF/TM/GCF_Control.h>
+
+namespace LOFAR {
+  namespace RSP {
+
+class SetRawBlockCmd : public Command
+{
+public:
+	// Constructors for a SetRawBlockCmd object.
+	SetRawBlockCmd(GCFEvent& event, GCFPortInterface& port, Operation oper);
+
+	// Destructor for SetRawBlockCmd. */
+	virtual ~SetRawBlockCmd();
+
+	// Acknowledge the command by sending the appropriate
+	// response on m_port.
+	virtual void ack(CacheBuffer& cache);
+
+	// Make necessary changes to the cache for the next synchronization.
+	// Any changes will be sent to the RSP boards.
+	virtual void apply(CacheBuffer& cache, bool setModFlag = true);
+
+	// Complete the command by sending the appropriate response on
+	// the m_answerport;
+	virtual void complete(CacheBuffer& cache);
+
+	//@{
+	// get timestamp of the event
+	virtual const RTC::Timestamp& getTimestamp() const;
+	virtual void setTimestamp(const RTC::Timestamp& timestamp);
+	//@}
+
+	// Range check the parameters of the event.
+	virtual bool validate() const;
+
+	// Return true if value should be read from cache.
+	bool readFromCache() const;
+
+	// Send failure ack.
+	void ack_fail();
+
+private:
+	SetRawBlockCmd();				// Default construction is not allowed.
+	RSPSetblockEvent* 	itsEvent;
+};
+
+  } // namespace RSP
+} // namespace LOFAR
+     
+#endif /* SET_RAWBLOCK_CMD_H */
diff --git a/MAC/APL/PIC/RSPDriver/src/SyncAction.cc b/MAC/APL/PIC/RSPDriver/src/SyncAction.cc
index fdb30f937c8..230b03f942a 100644
--- a/MAC/APL/PIC/RSPDriver/src/SyncAction.cc
+++ b/MAC/APL/PIC/RSPDriver/src/SyncAction.cc
@@ -82,53 +82,53 @@ GCFEvent::TResult SyncAction::idle_state(GCFEvent& event, GCFPortInterface& /*po
 
 GCFEvent::TResult SyncAction::sendrequest_state(GCFEvent& event, GCFPortInterface& /*port*/)
 {
-  GCFEvent::TResult status = GCFEvent::HANDLED;
-
-  switch (event.signal) {
-    case F_ENTRY: {
-      for (;;) {
-	if (!m_atinit && Sequencer::getInstance().isActive()) {
-	  // skip this action and continue with the next
-	  setContinue(true); // continue with next action
-	} else {
-	  // send initial request
-	  setContinue(false); // initialize on each entry
-	  sendrequest();
+	GCFEvent::TResult status = GCFEvent::HANDLED;
+
+	switch (event.signal) {
+	case F_ENTRY: {
+		for (;;) {
+			if (!m_atinit && Sequencer::getInstance().isActive()) {
+				// skip this action and continue with the next
+				setContinue(true); // continue with next action
+			} else {
+				// send initial request
+				setContinue(false); // initialize on each entry
+				sendrequest();
+			}
+
+			// if sendrequest calls setContinue(true), then no event
+			// has been sent, move on to next index
+			if (doContinue()) {
+				// OK, move on to the next index
+				m_current_index++;
+				m_retries = 0;
+				if (m_current_index >= m_n_indices) {
+					// done
+					setCompleted(true);
+					TRAN(SyncAction::idle_state);
+					break; // break the loop
+				}
+			}
+			else {
+				TRAN(SyncAction::waitack_state);
+				break; // break the loop
+			}
+		}
 	}
+	break;
 
-	// if sendrequest calls setContinue(true), then no event
-	// has been sent, move on to next index
-	if (doContinue()) {
-	  // OK, move on to the next index
-	  m_current_index++;
-	  m_retries = 0;
-	  if (m_current_index >= m_n_indices) {
-	    // done
-	    setCompleted(true);
-	    TRAN(SyncAction::idle_state);
-	    break; // break the loop
-	  }
-	}
-	else {
-	  TRAN(SyncAction::waitack_state);
-	  break; // break the loop
+	case F_TIMER: {
+		LOG_FATAL("missed real-time deadline");
+		exit(EXIT_FAILURE);
 	}
-      }
-    }
-    break;
-
-    case F_TIMER: {
-      LOG_FATAL("missed real-time deadline");
-      exit(EXIT_FAILURE);
-    }
-    break;
+	break;
 
-    default:
-      status = GCFEvent::NOT_HANDLED;
-      break;
-  }
+	default:
+		status = GCFEvent::NOT_HANDLED;
+	break;
+	}
 
-  return GCFEvent::HANDLED;
+	return GCFEvent::HANDLED;
 }
 
 GCFEvent::TResult SyncAction::waitack_state(GCFEvent& event, GCFPortInterface& port)
diff --git a/MAC/APL/PIC/RSPDriver/src/rspctl.cc b/MAC/APL/PIC/RSPDriver/src/rspctl.cc
index 53a4810e5d5..c4401b6cb93 100644
--- a/MAC/APL/PIC/RSPDriver/src/rspctl.cc
+++ b/MAC/APL/PIC/RSPDriver/src/rspctl.cc
@@ -54,6 +54,9 @@
 
 #include "rspctl.h"
 
+#define xtod(c) ((c>='0' && c<='9') ? c-'0' : ((c>='A' && c<='F') ? \
+                c-'A'+10 : ((c>='a' && c<='f') ? c-'a'+10 : 0)))
+
 namespace LOFAR {
   namespace rspctl {
 	using namespace std;
@@ -67,7 +70,7 @@ namespace LOFAR {
 double WGCommand::AMPLITUDE_SCALE = (1.0 * ((uint32)(1 << 11)-1) / (uint32)(1 << 11)) * (uint32)(1 << 31);
 
 // local funtions
-static void usage();
+static void usage(bool);
 
 // getting real or sent hba values
 static bool	realDelays = false;
@@ -108,33 +111,24 @@ inline complex<double> convert_to_amplphase(complex<double> val)
   double phase = 0.0;
   double amplitude = real(val)*real(val) + imag(val)*imag(val);
 
-  if (amplitude > 0.0)
-  {
+  if (amplitude > 0.0) {
     amplitude = 12 + 5*log10(amplitude); // adjust scaling to allow comparison to subband statistics
   }
 
-  if (0.0 == real(val))
-  {
-
+  if (0.0 == real(val)) {
     if (imag(val) > 0)
       phase = 90.0;
     else if (imag(val) < 0)
       phase = 270;
-
   }
-  else
-  {
-
+  else {
     phase = 45.0 * atan(imag(val)/real(val)) / atan(1.0);
-
-    if (real(val) > 0.0)
-    {
+    if (real(val) > 0.0) {
       if (imag(val) < 0)
         phase += 360.0;
     }
     else
       phase += 180.0;
-
   }
 
   return complex<double>(amplitude, phase);
@@ -181,8 +175,7 @@ WeightsCommand::WeightsCommand(GCFPortInterface& port) : Command(port), m_type(W
 
 void WeightsCommand::send()
 {
-  switch (itsStage)
-  {
+  switch (itsStage) {
   //if (getMode())
   //{
   case 0: {
@@ -236,10 +229,8 @@ GCFEvent::TResult WeightsCommand::ack(GCFEvent& e)
 {
   GCFEvent::TResult status = GCFEvent::HANDLED;
 
-  switch (e.signal)
-  {
-    case RSP_GETWEIGHTSACK:
-    {
+  switch (e.signal) {
+    case RSP_GETWEIGHTSACK: {
       RSPGetweightsackEvent ack(e);
       bitset<MEPHeader::MAX_N_RCUS> mask = getRCUMask();
 			itsWeights.resize(1, mask.count(), MEPHeader::N_BEAMLETS);
@@ -315,8 +306,7 @@ SubbandsCommand::SubbandsCommand(GCFPortInterface& port) : Command(port), m_type
 
 void SubbandsCommand::send()
 {
-  if (getMode())
-  {
+  if (getMode()) {
     // GET
     RSPGetsubbandsEvent getsubbands;
 
@@ -327,8 +317,7 @@ void SubbandsCommand::send()
 
     m_rspport.send(getsubbands);
   }
-  else
-  {
+  else {
     // SET
     RSPSetsubbandsEvent setsubbands;
     setsubbands.timestamp = Timestamp(0,0);
@@ -365,8 +354,7 @@ void SubbandsCommand::send()
       }
       break;
 
-    case SubbandSelection::XLET:
-      {
+    case SubbandSelection::XLET: {
 	setsubbands.subbands().resize(1,1);
 	std::list<int>::iterator it = m_subbandlist.begin();
 	setsubbands.subbands() = (*it);
@@ -387,10 +375,8 @@ GCFEvent::TResult SubbandsCommand::ack(GCFEvent& e)
 {
   GCFEvent::TResult status = GCFEvent::HANDLED;
 
-  switch (e.signal)
-  {
-    case RSP_GETSUBBANDSACK:
-    {
+  switch (e.signal) {
+    case RSP_GETSUBBANDSACK: {
       RSPGetsubbandsackEvent ack(e);
       bitset<MEPHeader::MAX_N_RCUS> mask = getRCUMask();
 
@@ -398,14 +384,11 @@ GCFEvent::TResult SubbandsCommand::ack(GCFEvent& e)
       msg << "getsubbandsack.timestamp=" << ack.timestamp;
       logMessage(cout, msg.str());
 
-      if (SUCCESS == ack.status)
-      {
+      if (SUCCESS == ack.status) {
         int rcuin = 0;
-        for (int rcuout = 0; rcuout < get_ndevices(); rcuout++)
-        {
+        for (int rcuout = 0; rcuout < get_ndevices(); rcuout++) {
 
-          if (mask[rcuout])
-          {
+          if (mask[rcuout]) {
             std::ostringstream logStream;
             logStream << ack.subbands()(rcuin++, Range::all());
 	    if (SubbandSelection::BEAMLET == m_type) {
@@ -416,23 +399,20 @@ GCFEvent::TResult SubbandsCommand::ack(GCFEvent& e)
           }
         }
       }
-      else
-      {
+      else {
         logMessage(cerr,"Error: RSP_GETSUBBANDS command failed.");
       }
     }
     break;
 
-    case RSP_SETSUBBANDSACK:
-    {
+    case RSP_SETSUBBANDSACK: {
       RSPSetsubbandsackEvent ack(e);
 
       std::ostringstream msg;
       msg << "setsubbandsack.timestamp=" << ack.timestamp;
       logMessage(cout, msg.str());
 
-      if (SUCCESS != ack.status)
-      {
+      if (SUCCESS != ack.status) {
         logMessage(cerr,"Error: RSP_SETSUBBANDS command failed.");
       }
     }
@@ -454,8 +434,7 @@ RCUCommand::RCUCommand(GCFPortInterface& port) : Command(port)
 
 void RCUCommand::send()
 {
-  if (getMode())
-  {
+  if (getMode()) {
     // GET
     RSPGetrcuEvent getrcu;
 
@@ -465,8 +444,7 @@ void RCUCommand::send()
 
     m_rspport.send(getrcu);
   }
-  else
-  {
+  else {
     // SET
     RSPSetrcuEvent setrcu;
     setrcu.timestamp = Timestamp(0,0);
@@ -486,38 +464,30 @@ void RCUCommand::send()
 
 GCFEvent::TResult RCUCommand::ack(GCFEvent& e)
 {
-  switch (e.signal)
-  {
-    case RSP_GETRCUACK:
-    {
+  switch (e.signal) {
+    case RSP_GETRCUACK: {
       RSPGetrcuackEvent ack(e);
       bitset<MEPHeader::MAX_N_RCUS> mask = getRCUMask();
 
-      if (SUCCESS == ack.status)
-      {
+      if (SUCCESS == ack.status) {
         int rcuin = 0;
-        for (int rcuout = 0; rcuout < get_ndevices(); rcuout++)
-        {
+        for (int rcuout = 0; rcuout < get_ndevices(); rcuout++) {
 
-          if (mask[rcuout])
-          {
+          if (mask[rcuout]) {
             logMessage(cout,formatString("RCU[%2d].control=0x%08x",rcuout, ack.settings()(rcuin++).getRaw()));
           }
         }
       }
-      else
-      {
+      else {
         logMessage(cerr,"Error: RSP_GETRCU command failed.");
       }
     }
     break;
 
-    case RSP_SETRCUACK:
-    {
+    case RSP_SETRCUACK: {
       RSPSetrcuackEvent ack(e);
 
-      if (SUCCESS != ack.status)
-      {
+      if (SUCCESS != ack.status) {
         logMessage(cerr,"Error: RSP_SETRCU command failed.");
       }
     }
@@ -591,8 +561,7 @@ void HBACommand::send()
 GCFEvent::TResult HBACommand::ack(GCFEvent& e)
 {
 	switch (e.signal) {
-	case RSP_GETHBAACK:
-	{
+	case RSP_GETHBAACK: {
 		RSPGethbaackEvent ack(e);
 		bitset<MEPHeader::MAX_N_RCUS> mask = getRCUMask();
 
@@ -617,8 +586,7 @@ GCFEvent::TResult HBACommand::ack(GCFEvent& e)
 	}
 	break;
 
-	case RSP_READHBAACK:
-	{
+	case RSP_READHBAACK: {
 		RSPReadhbaackEvent ack(e);
 		bitset<MEPHeader::MAX_N_RCUS> mask = getRCUMask();
 
@@ -648,8 +616,7 @@ GCFEvent::TResult HBACommand::ack(GCFEvent& e)
 	}
 	break;
 
-	case RSP_SETHBAACK:
-	{
+	case RSP_SETHBAACK: {
 		RSPSethbaackEvent ack(e);
 		if (SUCCESS != ack.status) {
 			logMessage(cerr,"Error: RSP_SETHBA command failed.");
@@ -740,8 +707,7 @@ ClockCommand::ClockCommand(GCFPortInterface& port) : Command(port)
 
 void ClockCommand::send()
 {
-  if (getMode())
-  {
+  if (getMode()) {
     // GET
     RSPGetclockEvent getclock;
 
@@ -754,8 +720,7 @@ void ClockCommand::send()
 
     m_rspport.send(getclock);
   }
-  else
-  {
+  else {
     // SET
     RSPSetclockEvent setclock;
     setclock.timestamp = Timestamp(0,0);
@@ -768,10 +733,8 @@ void ClockCommand::send()
 
 GCFEvent::TResult ClockCommand::ack(GCFEvent& e)
 {
-  switch (e.signal)
-  {
-    case RSP_GETCLOCKACK:
-    {
+  switch (e.signal) {
+    case RSP_GETCLOCKACK: {
       /**
        * This signal is handled in SubClockCommand.
        * We should never end up here.
@@ -781,12 +744,10 @@ GCFEvent::TResult ClockCommand::ack(GCFEvent& e)
     }
     break;
 
-    case RSP_SETCLOCKACK:
-    {
+    case RSP_SETCLOCKACK: {
       RSPSetclockackEvent ack(e);
 
-      if (SUCCESS != ack.status)
-      {
+      if (SUCCESS != ack.status) {
         logMessage(cerr,"Error: RSP_SETCLOCK command failed.");
       }
     }
@@ -806,8 +767,7 @@ SubClockCommand::SubClockCommand(GCFPortInterface& port) : Command(port)
 
 void SubClockCommand::send()
 {
-  if (getMode())
-  {
+  if (getMode()) {
     // Get current clock setting
     RSPGetclockEvent getclock;
 
@@ -816,8 +776,7 @@ void SubClockCommand::send()
 
     m_rspport.send(getclock);
   }
-  else
-  {
+  else {
     // SET not supported
     logMessage(cerr, "SubClockCommand: SET not supported");
     exit(EXIT_FAILURE);
@@ -826,13 +785,10 @@ void SubClockCommand::send()
 
 GCFEvent::TResult SubClockCommand::ack(GCFEvent& e)
 {
-  switch (e.signal)
-  {
-    case RSP_GETCLOCKACK:
-    {
+  switch (e.signal) {
+    case RSP_GETCLOCKACK: {
       RSPGetclockackEvent ack(e);
-      if (SUCCESS == ack.status)
-      {
+      if (SUCCESS == ack.status) {
 	g_sample_frequency = 1.0e6 * ack.clock;
 
 	if (g_getclock) {
@@ -853,35 +809,29 @@ GCFEvent::TResult SubClockCommand::ack(GCFEvent& e)
 	  m_rspport.send(subclock);
 	}
       }
-      else
-      {
+      else {
         logMessage(cerr,"Error: RSP_GETCLOCK command failed.");
       }
     }
     break;
 
-    case RSP_SUBCLOCKACK:
-    {
+    case RSP_SUBCLOCKACK: {
       RSPSubclockackEvent ack(e);
-      if (SUCCESS != ack.status)
-      {
+      if (SUCCESS != ack.status) {
 	logMessage(cerr,"Error: RSP_UPDCLOCK command failed.");
 	exit(EXIT_FAILURE);
       }
     }
     break;
 
-    case RSP_UPDCLOCK:
-    {
+    case RSP_UPDCLOCK: {
       RSPUpdclockEvent upd(e);
 
-      if (SUCCESS == upd.status)
-      {
+      if (SUCCESS == upd.status) {
 	logMessage(cout,formatString("Received new sample frequency: clock=%dMHz", upd.clock));
 	g_sample_frequency = 1.0e6 * upd.clock;
       }
-      else
-      {
+      else {
         logMessage(cerr,"Error: RSP_UPDCLOCK command failed.");
       }
     }
@@ -971,8 +921,7 @@ TBBCommand::TBBCommand(GCFPortInterface& port) : Command(port), m_type(0)
 
 void TBBCommand::send()
 {
-  if (getMode())
-  {
+  if (getMode()) {
     // GET
     RSPGettbbEvent gettbb;
 
@@ -982,8 +931,7 @@ void TBBCommand::send()
 
     m_rspport.send(gettbb);
   }
-  else
-  {
+  else {
     // SET
     RSPSettbbEvent settbb;
 
@@ -995,15 +943,13 @@ void TBBCommand::send()
     // if only 1 subband selected, apply selection to all
     switch (m_type) {
 
-    case TRANSIENT:
-      {
+    case TRANSIENT: {
 	settbb.settings().resize(1);
 	settbb.settings()(0).reset();
       }
       break;
 
-    case SUBBANDS:
-      {
+    case SUBBANDS: {
 	settbb.settings().resize(1);
 	settbb.settings()(0).reset();
 
@@ -1030,10 +976,8 @@ GCFEvent::TResult TBBCommand::ack(GCFEvent& e)
 {
   GCFEvent::TResult status = GCFEvent::HANDLED;
 
-  switch (e.signal)
-  {
-    case RSP_GETTBBACK:
-    {
+  switch (e.signal) {
+    case RSP_GETTBBACK: {
       RSPGettbbackEvent ack(e);
 
       std::ostringstream msg;
@@ -1048,10 +992,8 @@ GCFEvent::TResult TBBCommand::ack(GCFEvent& e)
 
       // print settings
       int rcuin = 0;
-      for (int rcuout = 0; rcuout < get_ndevices(); rcuout++)
-      {
-	if (getRCUMask()[rcuout])
-        {
+      for (int rcuout = 0; rcuout < get_ndevices(); rcuout++) {
+	if (getRCUMask()[rcuout]) {
 	  cout << formatString("RCU[%02u].tbbsettings= ", rcuout);
 //	  for (unsigned int ilong = 0; ilong < ack.settings()(0).size()/(sizeof(unsigned long) * BITSOFBYTE); ilong++) {
 
@@ -1069,16 +1011,14 @@ GCFEvent::TResult TBBCommand::ack(GCFEvent& e)
     }
     break;
 
-    case RSP_SETTBBACK:
-    {
+    case RSP_SETTBBACK: {
       RSPSettbbackEvent ack(e);
 
       std::ostringstream msg;
       msg << "settbback.timestamp=" << ack.timestamp;
       logMessage(cout, msg.str());
 
-      if (SUCCESS != ack.status)
-      {
+      if (SUCCESS != ack.status) {
         logMessage(cerr, "Error: RSP_SETTBB command failed.");
       }
     }
@@ -1216,8 +1156,7 @@ RegisterStateCommand::RegisterStateCommand(GCFPortInterface& port) :
 
 void RegisterStateCommand::send()
 {
-  if (getMode())
-  {
+  if (getMode()) {
     // GET == SUBSCRIBE
     RSPSubregisterstateEvent subregstate;
 
@@ -1226,8 +1165,7 @@ void RegisterStateCommand::send()
 
     m_rspport.send(subregstate);
   }
-  else
-  {
+  else {
     // SET not supported
     logMessage(cerr, "Error: RegisterStateCommand: SET not supported");
     exit(EXIT_FAILURE);
@@ -1236,11 +1174,9 @@ void RegisterStateCommand::send()
 
 GCFEvent::TResult RegisterStateCommand::ack(GCFEvent& e)
 {
-  if (RSP_SUBREGISTERSTATEACK == e.signal)
-  {
+  if (RSP_SUBREGISTERSTATEACK == e.signal) {
     RSPSubregisterstateackEvent ack(e);
-    if (SUCCESS != ack.status)
-    {
+    if (SUCCESS != ack.status) {
       logMessage(cerr,"Error: RSP_UPDREGISTERSTATE command failed.");
       exit(EXIT_FAILURE);
     }
@@ -1250,15 +1186,13 @@ GCFEvent::TResult RegisterStateCommand::ack(GCFEvent& e)
 
   RSPUpdregisterstateEvent upd(e);
 
-  if (SUCCESS == upd.status)
-  {
+  if (SUCCESS == upd.status) {
     std::ostringstream logStream;
     logStream << "registerstate update at " << upd.timestamp << endl;
     upd.state.print(logStream);
     logMessage(cout,logStream.str());
   }
-  else 
-  {
+  else {
     logMessage(cerr, "Error: register state update failed.");
   }
 
@@ -1267,8 +1201,7 @@ GCFEvent::TResult RegisterStateCommand::ack(GCFEvent& e)
 
 void RegisterStateCommand::stop()
 {
-  if (getMode())
-  {
+  if (getMode()) {
     // UNSUBSCRIBE
     RSPUnsubregisterstateEvent unsubregstate;
     unsubregstate.handle = m_subscriptionhandle;
@@ -1331,6 +1264,125 @@ GCFEvent::TResult SPUStatusCommand::ack(GCFEvent& event)
 	GCFTask::stop();
 	return (GCFEvent::HANDLED);
 }
+//
+// RawBlock
+//
+RawBlockCommand::RawBlockCommand(GCFPortInterface&	port):
+	Command(port),
+	itsRSPboard(0),
+	itsAddress(0),
+	itsOffset(0),
+	itsDataLen(0)
+{
+	memset (&itsData[0], 0, RSP_RAW_BLOCK_SIZE);
+}
+
+// send()
+void RawBlockCommand::send()
+{
+	// read mode?
+	if (getMode()) { 
+		// construct message
+		RSPGetblockEvent	 rbCmd;
+		rbCmd.timestamp = Timestamp(0,0);
+		rbCmd.boardID	= itsRSPboard;
+		rbCmd.address	= itsAddress;
+		rbCmd.offset	= itsOffset;
+		rbCmd.dataLen	= itsDataLen;
+		// and send it.
+		m_rspport.send(rbCmd);
+		return;
+	}
+
+	// write block
+	RSPSetblockEvent	 rbCmd;
+	rbCmd.timestamp = Timestamp(0,0);
+	rbCmd.boardID	= itsRSPboard;
+	rbCmd.address	= itsAddress;
+	rbCmd.offset	= itsOffset;
+	rbCmd.dataLen	= itsDataLen;
+	memcpy(rbCmd.data, itsData, itsDataLen);
+	// and send it.
+	m_rspport.send(rbCmd);
+
+}
+
+// ack(event)
+GCFEvent::TResult RawBlockCommand::ack(GCFEvent&	event)
+{
+	switch (event.signal) {
+	case RSP_GETBLOCKACK: {
+		RSPGetblockackEvent ack(event);
+		LOG_DEBUG(formatString("RAWBLOCKREAD:board=%d, status=%d, dataLen=%d", ack.boardID, ack.status, ack.dataLen));
+		if (ack.status != SUCCESS) {
+			cerr << "Error: readBlock command failed, code = " << ack.status << endl;
+		}
+		else {
+			// show result to the user
+			hexdump (ack.data, ack.dataLen);
+			// TODO write to file
+		} 
+	}
+	break;
+
+	case RSP_SETBLOCKACK: {
+		RSPSetblockackEvent ack(event);
+		LOG_DEBUG(formatString("RAWBLOCKWRITE:board:%d, status=%d", ack.boardID, ack.status));
+		if (ack.status != SUCCESS) {
+			cerr << "Error: writeBlock command failed, code = " << ack.status << endl;
+		}
+	}
+	break;
+
+	default:
+		cerr << "Unknown answer return while reading or writing a datablock" << endl;
+	}
+
+	GCFTask::stop();
+	return (GCFEvent::HANDLED);
+}
+
+// setAddressInfo(RSPboard, address, offset)
+void RawBlockCommand::setAddressInfo(uint16 RSPboard, uint32 address, uint16 offset)
+{
+	itsRSPboard	= RSPboard;
+	itsAddress	= address;
+	itsOffset	= offset;
+}
+
+// setDataInfo(filename, datalen, dataPtr)
+void RawBlockCommand::setDataInfo (const string& filename, uint16 dataLen, uint8*	dataPtr)
+{
+	if (filename.empty()) {
+		itsDataLen = dataLen > RSP_RAW_BLOCK_SIZE ? RSP_RAW_BLOCK_SIZE : dataLen;
+		if (dataPtr) {		// Note: for 'reads' the dataPtr = 0
+			memcpy (&itsData[0], dataPtr, dataLen);
+			cout << dataLen << " bytes of data in command" << endl;
+		}
+		return;
+	}
+
+	// TODO: add code for using a file
+}
+
+// getAddressInfo(RSPboard, address, offset)
+void RawBlockCommand::getAddressInfo(uint16* RSPboard, uint32* address, uint16* offset) 
+{
+	*RSPboard	= itsRSPboard;
+	*address	= itsAddress;
+	*offset		= itsOffset;
+}
+
+// getDataInfo(filename, datalen, dataPtr)
+void RawBlockCommand::getDataInfo(const string& filename, uint16* datalen, uint8** dataHandle) 
+{
+	if (filename.empty()) {
+		*datalen 	= itsDataLen;
+		*dataHandle = &itsData[0];
+		return;
+	}
+	// TODO: add code for using a file
+}
 
 //
 // Weights
@@ -1347,8 +1399,7 @@ WGCommand::WGCommand(GCFPortInterface& port) :
 
 void WGCommand::send()
 {
-  if (getMode())
-  {
+  if (getMode()) {
     // GET
     RSPGetwgEvent wgget;
     wgget.timestamp = Timestamp(0,0);
@@ -1356,8 +1407,7 @@ void WGCommand::send()
     wgget.cache = true;
     m_rspport.send(wgget);
   }
-  else
-  {
+  else {
     // SET
     RSPSetwgEvent wgset;
 
@@ -1373,12 +1423,10 @@ void WGCommand::send()
     wgset.settings()(0).ampl        = m_amplitude;
     wgset.settings()(0).nof_samples = MEPHeader::N_WAVE_SAMPLES;
 
-    if (m_frequency < 1e-6)
-    {
+    if (m_frequency < 1e-6) {
       wgset.settings()(0).mode = WGSettings::MODE_OFF;
     }
-    else /* frequency ok */
-    {
+    else  {	/* frequency ok */
       if (m_mode == 0) { 	/* forget to set mode? assume calc mode */
         wgset.settings()(0).mode = WGSettings::MODE_CALC;
     	wgset.settings()(0).nof_samples = MEPHeader::N_WAVE_SAMPLES;
@@ -1398,23 +1446,18 @@ GCFEvent::TResult WGCommand::ack(GCFEvent& e)
 {
   GCFEvent::TResult status = GCFEvent::HANDLED;
 
-  switch (e.signal)
-  {
-    case RSP_GETWGACK:
-    {
+  switch (e.signal) {
+    case RSP_GETWGACK: {
       RSPGetwgackEvent ack(e);
 
-      if (SUCCESS == ack.status)
-      {
+      if (SUCCESS == ack.status) {
 
         // print settings
         bitset<MEPHeader::MAX_N_RCUS> mask = getRCUMask();
         int rcuin = 0;
-        for (int rcuout = 0; rcuout < get_ndevices(); rcuout++)
-        {
+        for (int rcuout = 0; rcuout < get_ndevices(); rcuout++) {
 
-          if (mask[rcuout])
-          {
+          if (mask[rcuout]) {
             logMessage(cout,formatString("RCU[%02u].wg=[freq=%11u, phase=%3u(%5.3f), ampl=%11u, nof_samples=%6u, mode=%3u]",
                    rcuout,
                    ack.settings()(rcuin).freq,
@@ -1427,19 +1470,16 @@ GCFEvent::TResult WGCommand::ack(GCFEvent& e)
           }
         }
       }
-      else
-      {
+      else {
         logMessage(cerr,"Error: RSP_GETWG command failed.");
       }
     }
     break;
 
-    case RSP_SETWGACK:
-    {
+    case RSP_SETWGACK: {
       RSPSetwgackEvent ack(e);
 
-      if (SUCCESS != ack.status)
-      {
+      if (SUCCESS != ack.status) {
         logMessage(cerr,"Error: RSP_SETWG command failed.");
       }
     }
@@ -1639,14 +1679,11 @@ StatisticsCommand::StatisticsCommand(GCFPortInterface& port) : StatisticsBaseCom
 
 void StatisticsCommand::send()
 {
-  if (getMode())
-  {
-    if(m_directory.length()>0)
-    {
+  if (getMode()) {
+    if(m_directory.length()>0) {
       logMessage(cout,formatString("Dumping statistics in %s",m_directory.c_str()));
     }
-    else
-    {
+    else {
       char cwd[PATH_MAX];
       logMessage(cout,formatString("Dumping statistics in %s",getcwd(cwd,PATH_MAX)));
     }
@@ -1662,8 +1699,7 @@ void StatisticsCommand::send()
 
     m_rspport.send(substats);
   }
-  else
-  {
+  else {
     // SET
     logMessage(cerr,"Error: set mode not support for option '--statistics'");
     GCFTask::stop();
@@ -1672,8 +1708,7 @@ void StatisticsCommand::send()
 
 void StatisticsCommand::stop()
 {
-  if (getMode())
-  {
+  if (getMode()) {
     // UNSUBSCRIBE
     RSPUnsubstatsEvent unsubstats;
     unsubstats.handle = m_subscriptionhandle;
@@ -1683,16 +1718,13 @@ void StatisticsCommand::stop()
 
 void StatisticsCommand::capture_statistics(Array<double, 2>& stats, const Timestamp& timestamp)
 {
-  if (0 == m_nseconds)
-  {
+  if (0 == m_nseconds) {
     // initialize values array
     m_stats.resize(stats.shape());
     m_stats = 0.0;
   }
-  else
-  {
-    if ( sum(stats.shape()) != sum(m_stats.shape()) )
-    {
+  else {
+    if ( sum(stats.shape()) != sum(m_stats.shape()) ) {
       logMessage(cerr, "Error: statistics shape mismatch");
       exit(EXIT_FAILURE);
     }
@@ -1705,27 +1737,22 @@ void StatisticsCommand::capture_statistics(Array<double, 2>& stats, const Timest
   }
   m_nseconds++; // advance to next second
 
-  if (0 == (int32)m_nseconds % m_integration)
-  {
-    if (m_integration > 0) 
-    {
+  if (0 == (int32)m_nseconds % m_integration) {
+    if (m_integration > 0) {
       m_stats /= m_integration;
     }
 
     LOG_DEBUG_STR("statistics update at " << timestamp);
     
-    if(m_duration == 0)
-    {
+    if(m_duration == 0) {
       plot_statistics(m_stats, timestamp);
     }
-    else
-    {
+    else {
       dump_statistics(m_stats, timestamp);
       
       Timestamp timeNow;
       timeNow.setNow();
-      if(timeNow >= m_endTime)
-      {
+      if(timeNow >= m_endTime) {
         logMessage(cout,"Statistics capturing successfully ended.");
         stop();
         GCFTask::stop();
@@ -1745,8 +1772,7 @@ void StatisticsCommand::plot_statistics(Array<double, 2>& stats, const Timestamp
   // initialize the freq array
   firstIndex i;
 
-  if (!handle)
-  {
+  if (!handle) {
     handle = gnuplot_init();
     if (!handle)
       return;
@@ -1757,8 +1783,7 @@ void StatisticsCommand::plot_statistics(Array<double, 2>& stats, const Timestamp
   gnuplot_cmd(handle, "set ylabel \"dB\"\n");
   gnuplot_cmd(handle, "set yrange [0:160]\n");
 
-  switch (m_type)
-  {
+  switch (m_type) {
     case Statistics::SUBBAND_POWER:
       gnuplot_cmd(handle, "set xlabel \"Frequency (MHz)\"\n");
       gnuplot_cmd(handle, "set xrange [0:%f]\n", g_sample_frequency / 2.0);
@@ -1779,16 +1804,13 @@ void StatisticsCommand::plot_statistics(Array<double, 2>& stats, const Timestamp
 
   // splot devices
   int count = 0;
-  for (int rcuout = 0; rcuout < get_ndevices(); rcuout++)
-  {
-    if (mask[rcuout])
-    {
+  for (int rcuout = 0; rcuout < get_ndevices(); rcuout++) {
+    if (mask[rcuout]) {
       if (count > 0)
         gnuplot_cmd(handle, ",");
       count++;
 
-      switch (m_type)
-      {
+      switch (m_type) {
         case Statistics::SUBBAND_POWER:
           gnuplot_cmd(handle, "\"-\" using (%.1f/%.1f*$1):(10*log10($2)) title \"(RCU=%d)\" with steps ",
 		      g_sample_frequency, n_freqbands*2.0, rcuout);
@@ -1815,10 +1837,8 @@ void StatisticsCommand::dump_statistics(Array<double, 2>& stats, const Timestamp
   bitset<MEPHeader::MAX_N_RCUS> mask = getRCUMask();
 
   int result_device=0;
-  for (int deviceout = 0; deviceout < get_ndevices(); deviceout++)
-  {
-    if (mask[deviceout])
-    {
+  for (int deviceout = 0; deviceout < get_ndevices(); deviceout++) {
+    if (mask[deviceout]) {
       char timestring[256];
       time_t seconds = timestamp.sec();
       strftime(timestring, 255, "%Y%m%d_%H%M%S", gmtime(&seconds));
@@ -1826,8 +1846,7 @@ void StatisticsCommand::dump_statistics(Array<double, 2>& stats, const Timestamp
 
       LOG_INFO_STR("dumping statistics at " << timestring);
 
-      switch (m_type)
-      {
+      switch (m_type) {
         case Statistics::SUBBAND_POWER:
           snprintf(fileName, PATH_MAX, "%s%s_sst_rcu%03d.dat", m_directory.c_str(), timestring, deviceout);
           break;
@@ -1845,8 +1864,7 @@ void StatisticsCommand::dump_statistics(Array<double, 2>& stats, const Timestamp
 
       FILE* file = getFile(deviceout,fileName);
       if (stats.extent(secondDim)
-          != (int)fwrite(stats(result_device, Range::all()).data(), sizeof(double), stats.extent(secondDim), file))
-      {
+          != (int)fwrite(stats(result_device, Range::all()).data(), sizeof(double), stats.extent(secondDim), file)) {
         logMessage(cerr,formatString("Error: unable to write to file %s",fileName));
         exit(EXIT_FAILURE);
       }
@@ -1857,12 +1875,10 @@ void StatisticsCommand::dump_statistics(Array<double, 2>& stats, const Timestamp
 
 GCFEvent::TResult StatisticsCommand::ack(GCFEvent& e)
 {
-  if (e.signal == RSP_SUBSTATSACK)
-  {
+  if (e.signal == RSP_SUBSTATSACK) {
     RSPSubstatsackEvent ack(e);
 
-    if (SUCCESS != ack.status)
-    {
+    if (SUCCESS != ack.status) {
       logMessage(cerr,"Error: failed to subscribe to statistics");
       exit(EXIT_FAILURE);
     }
@@ -1875,12 +1891,10 @@ GCFEvent::TResult StatisticsCommand::ack(GCFEvent& e)
 
   RSPUpdstatsEvent upd(e);
 
-  if (SUCCESS == upd.status)
-  {
+  if (SUCCESS == upd.status) {
     capture_statistics(upd.stats(),upd.timestamp);
   }
-  else
-  {
+  else {
     logMessage(cerr,"Error: statistics update failed.");
   }
 
@@ -1894,14 +1908,11 @@ XCStatisticsCommand::XCStatisticsCommand(GCFPortInterface& port) : StatisticsBas
 
 void XCStatisticsCommand::send()
 {
-  if (getMode())
-  {
-    if(m_directory.length()>0)
-    {
+  if (getMode()) {
+    if(m_directory.length()>0) {
       logMessage(cout,formatString("Dumping statistics in %s",m_directory.c_str()));
     }
-    else
-    {
+    else {
       char cwd[PATH_MAX];
       logMessage(cout,formatString("Dumping statistics in %s",getcwd(cwd,PATH_MAX)));
     }
@@ -1917,8 +1928,7 @@ void XCStatisticsCommand::send()
 
     m_rspport.send(subxcstats);
   }
-  else
-  {
+  else {
     // SET
     logMessage(cerr,"Error: set mode not support for option '--xcstatistics'");
     GCFTask::stop();
@@ -1927,8 +1937,7 @@ void XCStatisticsCommand::send()
 
 void XCStatisticsCommand::stop()
 {
-  if (getMode())
-  {
+  if (getMode()) {
     // UNSUBSCRIBE
     RSPUnsubxcstatsEvent unsubxcstats;
     unsubxcstats.handle = m_subscriptionhandle;
@@ -1938,16 +1947,13 @@ void XCStatisticsCommand::stop()
 
 void XCStatisticsCommand::capture_xcstatistics(Array<complex<double>, 4>& stats, const Timestamp& timestamp){
 
-  if (0 == m_nseconds)
-  {
+  if (0 == m_nseconds) {
     // initialize values array
     m_stats.resize(stats.shape());
     m_stats = 0.0;
   }
-  else
-  {
-    if ( sum(stats.shape()) != sum(m_stats.shape()) )
-    {
+  else {
+    if ( sum(stats.shape()) != sum(m_stats.shape()) ) {
       logMessage(cerr, "Error: xcstatistics shape mismatch");
       exit(EXIT_FAILURE);
     }
@@ -1960,17 +1966,14 @@ void XCStatisticsCommand::capture_xcstatistics(Array<complex<double>, 4>& stats,
   }
   m_nseconds++; // advance to next second
 
-  if (0 == (int32)m_nseconds % m_integration)
-  {
-    if (m_integration > 0) 
-    {
+  if (0 == (int32)m_nseconds % m_integration) {
+    if (m_integration > 0) {
       m_stats /= m_integration;
     }
 
     LOG_DEBUG_STR("xcstatistics update at " << timestamp);
     
-    if(m_duration == 0)
-    {
+    if(m_duration == 0) {
       blitz::Array<complex<double>, 4> pastats;
       pastats.resize(m_stats.shape());
       pastats = convert_to_amplphase(m_stats);
@@ -1988,14 +1991,12 @@ void XCStatisticsCommand::capture_xcstatistics(Array<complex<double>, 4>& stats,
 
       plot_xcstatistics(m_stats, timestamp);
     }
-    else
-    {
+    else {
       dump_xcstatistics(m_stats, timestamp);
       
       Timestamp timeNow;
       timeNow.setNow();
-      if(timeNow >= m_endTime)
-      {
+      if(timeNow >= m_endTime) {
         logMessage(cout,"XCStatistics capturing successfully ended.");
         stop();
         GCFTask::stop();
@@ -2074,8 +2075,7 @@ void XCStatisticsCommand::dump_xcstatistics(Array<complex<double>, 4>& stats, co
 
   if (thestats.size()
       != (int)fwrite(thestats.data(), sizeof(complex<double>),
-         thestats.size(), file))
-  {
+         thestats.size(), file)) {
     logMessage(cerr,formatString("Error: unable to write to file %s",fileName));
     exit(EXIT_FAILURE);
   }
@@ -2083,17 +2083,14 @@ void XCStatisticsCommand::dump_xcstatistics(Array<complex<double>, 4>& stats, co
 
 GCFEvent::TResult XCStatisticsCommand::ack(GCFEvent& e)
 {
-  if (e.signal == RSP_SUBXCSTATSACK)
-  {
+  if (e.signal == RSP_SUBXCSTATSACK) {
     RSPSubxcstatsackEvent ack(e);
 
-    if (SUCCESS != ack.status)
-    {
+    if (SUCCESS != ack.status) {
       logMessage(cerr,"Error: failed to subscribe to xcstatistics");
       exit(EXIT_FAILURE);
     }
-    else
-    {
+    else {
       m_subscriptionhandle = ack.handle;
     }
 
@@ -2105,8 +2102,7 @@ GCFEvent::TResult XCStatisticsCommand::ack(GCFEvent& e)
 
   RSPUpdxcstatsEvent upd(e);
 
-  if (SUCCESS == upd.status)
-  {
+  if (SUCCESS == upd.status) {
 #if 0
     Range r1, r2;
     if (!getRSPRange2(r1, r2)) {
@@ -2141,10 +2137,8 @@ GCFEvent::TResult VersionCommand::ack(GCFEvent& e)
 {
   RSPGetversionackEvent ack(e);
 
-  if (SUCCESS == ack.status)
-  {
-    for (int rsp=0; rsp < get_ndevices(); rsp++)
-    {
+  if (SUCCESS == ack.status) {
+    for (int rsp=0; rsp < get_ndevices(); rsp++) {
       logMessage(cout,formatString("RSP[%2d] RSP version = %d, BP version = %d.%d, AP version = %d.%d",
                                    rsp,
 				   ack.versions.bp()(rsp).rsp_version,
@@ -2154,8 +2148,7 @@ GCFEvent::TResult VersionCommand::ack(GCFEvent& e)
 				   ack.versions.ap()(rsp).fpga_min));
     }
   }
-  else
-  {
+  else {
     logMessage(cerr,"Error: RSP_GETVERSION command failed.");
   }
   GCFTask::stop();
@@ -2211,13 +2204,11 @@ GCFEvent::TResult RSPCtl::initial(GCFEvent& e, GCFPortInterface& port)
 	LOG_DEBUG_STR ("initial:" << eventName(e) << "@" << port.getName());
   GCFEvent::TResult status = GCFEvent::HANDLED;
 
-  switch(e.signal)
-  {
+  switch(e.signal) {
     case F_INIT:
     break;
 
-    case F_ENTRY:
-    {
+    case F_ENTRY: {
       if (!m_server.isConnected())
         if (!m_server.open()) {
 	  logMessage(cerr, "Error: failed to open port to RSPDriver");
@@ -2226,18 +2217,15 @@ GCFEvent::TResult RSPCtl::initial(GCFEvent& e, GCFPortInterface& port)
     }
     break;
 
-    case F_CONNECTED:
-    {
-      if (m_server.isConnected())
-      {
+    case F_CONNECTED: {
+      if (m_server.isConnected()) {
         RSPGetconfigEvent getconfig;
         m_server.send(getconfig);
       }
     }
     break;
 
-    case RSP_GETCONFIGACK:
-    {
+    case RSP_GETCONFIGACK: {
       RSPGetconfigackEvent ack(e);
       m_nrcus        = ack.n_rcus;
       m_nrspboards   = ack.n_rspboards;
@@ -2248,15 +2236,13 @@ GCFEvent::TResult RSPCtl::initial(GCFEvent& e, GCFPortInterface& port)
     }
     break;
 
-    case F_DISCONNECTED:
-    {
+    case F_DISCONNECTED: {
       port.setTimer((long)1);
       port.close();
     }
     break;
 
-    case F_TIMER:
-    {
+    case F_TIMER: {
       // try again
       m_server.open();
     }
@@ -2277,15 +2263,13 @@ GCFEvent::TResult RSPCtl::docommand(GCFEvent& e, GCFPortInterface& port)
 	GCFEvent::TResult status = GCFEvent::HANDLED;
 
 	switch (e.signal) {
-	case F_ENTRY:
-	{
+	case F_ENTRY: {
 		m_subclock.send(); // subscribe to clock updates
 		// after receiving the clock update execute the actual requested command
 	}
 	break;
 
-	case F_CONNECTED:
-	{
+	case F_CONNECTED: {
 		// connection with te frontend! send the command to the rsp driver
 		FECommand* feCommand = dynamic_cast<FECommand*>(m_command);
 		if(feCommand != 0) {
@@ -2332,6 +2316,8 @@ GCFEvent::TResult RSPCtl::docommand(GCFEvent& e, GCFPortInterface& port)
 	case RSP_GETBYPASSACK:
 	case RSP_SETBYPASSACK:
 	case RSP_GETSPUSTATUSACK:
+	case RSP_GETBLOCKACK:
+	case RSP_SETBLOCKACK:
 		status = m_command->ack(e); // handle the acknowledgement
 	break;
 
@@ -2345,7 +2331,7 @@ GCFEvent::TResult RSPCtl::docommand(GCFEvent& e, GCFPortInterface& port)
 			// reparse options
 			if (0 == (m_command = parse_options(m_argc, m_argv))) {
 				logMessage(cerr,"Warning: no command specified.");
-				usage();
+//				usage(false);
 				exit(EXIT_FAILURE);
 			}
 			// check if a connection must be made with a frontend. If so, connect first
@@ -2389,7 +2375,7 @@ void RSPCtl::mainloop()
   GCFTask::run();
 }
 
-static void usage()
+static void usage(bool exportMode)
 {
   cout << "rspctl usage:" << endl;
   cout << endl;
@@ -2499,13 +2485,30 @@ static void usage()
   cout << "rspctl --rspclear           [--select=<set>]   # clear FPGA registers on RSPboard" << endl;
   cout << "rspctl --hbadelays[=<list>] [--select=<set>]   # set or get the 16 delays of one or more HBA's" << endl;
   cout << "rspctl --tbbmode[=transient | =subbands,<set>] # set or get TBB mode, 'transient' or 'subbands', if subbands then specify subband set" << endl;
+  if (exportMode) {
+	cout << endl;
+	cout << "--- Raw register control -------------------------------------------------------------------------------------" << endl;
+	cout << " ### WARNING: to following commands may crash the RSPboard when used wrong! ###" << endl;
+	cout << "rspctl --readblock=RSPboard,hexAddress,offset,datalength    # read datalength bytes from given address" << endl;
+//	cout << "rspctl --readblock=RSPboard,hexAddress,offset,filename      # read datalength bytes from given address" << endl;
+//	cout << "         Data is written to the file in binairy format." << endl;
+	cout << endl;
+	cout << "rspctl --writeblock=RSPboard,hexAddress,offset,hexData      # write data to given address" << endl;
+//	cout << "         HexData must start with '0x'." << endl;
+//	cout << "rspctl --writeblock=RSPboard,hexAddress,offset,filename     # write data to given address" << endl;
+//	cout << "         When filecontents starts with 0x is it read as hexdata," << endl;
+//	cout << "         otherwise the file is treated as a binairy file." << endl;
+	cout << "In all cases the maximum number of databytes is " << RSP_RAW_BLOCK_SIZE << endl;
+	cout << "Address order: BLPID, RSP, PID, REGID" << endl;
+	cout << endl;
+  }
 }
 
 Command* RSPCtl::parse_options(int argc, char** argv)
 {
-	Command*    command        = 0;
-	RCUCommand* rcumodecommand = 0;
-	HBACommand* hbacommand     = 0;
+	Command*    		command         = 0;
+	RCUCommand* 		rcumodecommand  = 0;
+	HBACommand* 		hbacommand      = 0;
 	list<int> 	select;
 	list<int> 	beamlets;
 	bool 		xcangle = false;
@@ -2557,11 +2560,13 @@ Command* RSPCtl::parse_options(int argc, char** argv)
 		{ "specinv",	    optional_argument, 0, 'I' },
 		{ "phase",          required_argument, 0, 'P' },
 		{ "tdstatus",       no_argument,       0, 'Q' },
-//		{ "rspreset",       optional_argument, 0, 'R' },
 		{ "realdelays",     optional_argument, 0, 'R' },
 		{ "regstate",       no_argument,       0, 'S' },
 		{ "tbbmode",        optional_argument, 0, 'T' },
 		{ "spustate",       no_argument, 	   0, 'V' },
+		{ "expert",         no_argument, 	   0, 'X' },
+		{ "readblock",      required_argument, 0, '1' },
+		{ "writeblock",     required_argument, 0, '2' },
 
 		{ 0, 0, 0, 0 },
 	};
@@ -2569,7 +2574,7 @@ Command* RSPCtl::parse_options(int argc, char** argv)
 	realDelays = false;
 	while (1) {
 		int option_index = 0;
-		int c = getopt_long(argc, argv, "l:b:w::a::s::r::g::qQt::xz::vc::hf:d:i:I:", long_options, &option_index);
+		int c = getopt_long(argc, argv, "a::b:c::d:e::f:g::hi:l:m:n:p::qr::s::t::vw::xy:z::A:BC::D:E::G:H::I::P:QR::ST::VX1:2:", long_options, &option_index);
 
 		if (c == -1)	// end of argument list reached?
 			break;
@@ -3091,7 +3096,11 @@ Command* RSPCtl::parse_options(int argc, char** argv)
 		break;
 
 		case 'h':	// --help
-			usage();
+			usage(false);
+		break;
+
+		case 'X':	// --export help
+			usage(true);
 		break;
 
 #ifdef ENABLE_RSPFE
@@ -3177,6 +3186,85 @@ Command* RSPCtl::parse_options(int argc, char** argv)
 			}
 		break;
 
+		case '1': 		// readblock=RSPboard,hexAddress,offset,(datalen|filename)
+		case '2': {		// writeblock=RSPboard,hexAddress,offset,(datalen|filename)
+			// allocate the right command
+			if (command) {
+				delete (command);
+			}
+			RawBlockCommand*	rbCmd = new RawBlockCommand(m_server);
+			command = rbCmd;
+			rbCmd->setMode(c == '1');
+
+			// we definitely need arguments
+			if (!optarg) {
+				usage(false);
+				logMessage(cerr, "Need arguments for dataBlock");
+				exit(EXIT_FAILURE);
+			}
+
+			// try to parse the arguments
+			uint32	rspBoard;
+			uint32	address;
+			uint32	offset;
+			uint32	dataLen;
+			char	dataStr[4096];
+			char	addrStr[1024];
+			if (c == '1') {	// read block
+				int numItems = sscanf(optarg, "%u,%[0-9A-Fa-f],%u,%u", &rspBoard, &addrStr[0], &offset, &dataLen);
+				if (numItems != 4) {
+					logMessage(cerr, "Need 4 arguments: rspBoardNr, hexAddress, offset, datalen");
+					exit(EXIT_FAILURE);
+				}
+			}
+			else { // write block has different fourth parameter.
+				int numItems = sscanf(optarg, "%u,%[0-9A-Fa-f],%u,%s", &rspBoard, &addrStr[0], &offset, &dataStr[0]);
+				if (numItems != 4) {
+					logMessage(cerr, "Need 4 arguments: rspBoardNr, hexAddress, offset, hexData");
+					exit(EXIT_FAILURE);
+				}
+				if (strlen(dataStr) % 1) {
+					logMessage(cerr, "Datastring must have an even number of characters");
+					exit(EXIT_FAILURE);
+				}
+				dataLen = strlen(dataStr) / 2;
+			}
+
+			// minor checking on the arguments.
+			if (rspBoard > (uint32)m_nrspboards || dataLen == 0 || dataLen > (uint32)RSP_RAW_BLOCK_SIZE) {
+				cerr <<  "Range error" << endl;
+				cerr <<  "RSPboard: 0.." << m_nrspboards << endl;
+				cerr <<  "Datalength: 1.." << RSP_RAW_BLOCK_SIZE << endl;
+				exit(EXIT_FAILURE);
+			}
+
+			// convert addrString to address value (reverse order on intel)
+			if (strlen(addrStr) != 8) {
+				logMessage(cerr, "Address string must have 8 characters");
+				exit(EXIT_FAILURE);
+			}
+			address = 0;
+			for (int i = 3; i >= 0; i--) {
+				address = (address << 8) + (uint8)(xtod(addrStr[i*2])<<4 | xtod(addrStr[i*2+1]));
+			}
+
+			// write the usersetttings to the command.
+			rbCmd->setAddressInfo(rspBoard, address, offset);
+			if (c == '1') {		// read block
+				rbCmd->setDataInfo("", dataLen, 0);
+			}
+			else {
+				// Transfer dataStr to databuffer
+				uint8	databuf[2048];
+				for (uint16	i = 0; i < dataLen; i++) {
+					databuf[i] = (uint8)(xtod(dataStr[i*2])<<4 | xtod(dataStr[i*2+1]));
+				}
+				rbCmd->setDataInfo("", dataLen, &databuf[0]);
+			}
+		}
+		break;
+
+
 		case '?':
 		default:
 			logMessage(cerr, "Error: invalid option");
@@ -3195,71 +3283,72 @@ Command* RSPCtl::parse_options(int argc, char** argv)
 
 std::list<int> RSPCtl::strtolist(const char* str, int max)
 {
-  string inputstring(str);
-  char* start = (char*)inputstring.c_str();
-  char* end   = 0;
-  bool  range = false;
-  long prevval = 0;
-  list<int> resultset;
-
-  resultset.clear();
-
-  while (start) {
-    long val = strtol(start, &end, 10); // read decimal numbers
-    start = (end ? (*end ? end + 1 : 0) : 0); // advance
-    if (val >= max || val < 0) {
-      logMessage(cerr,formatString("Error: value %ld out of range",val));
-      resultset.clear();
-      return resultset;
-    }
+	string inputstring(str);
+	char* start 	= (char*)inputstring.c_str();
+	char* end   	= 0;
+	bool  range 	= false;
+	long  prevval 	= 0;
+	list<int> resultset;
+
+	resultset.clear();
+
+	while (start) {
+		long val = strtol(start, &end, 10); // read decimal numbers
+		start = (end ? (*end ? end + 1 : 0) : 0); // advance
+		if (val >= max || val < 0) {
+			logMessage(cerr,formatString("Error: value %ld out of range",val));
+			resultset.clear();
+			return resultset;
+		}
 
-    if (end) {
-      switch (*end) {
-        case ',':
-        case 0: {
-          if (range) {
-            if (0 == prevval && 0 == val)
-              val = max - 1;
-            if (val < prevval) {
-              logMessage(cerr,"Error: invalid range specification");
-              resultset.clear();
-              return resultset;
-            }
-            for (long i = prevval; i <= val; i++)
-              resultset.push_back(i);
-          }
-          else {
-            resultset.push_back(val);
-          }
-          range=false;
-        }
-        break;
+		if (end) {
+			switch (*end) {
+			case ',':
+			case 0: {
+				if (range) {
+					if (0 == prevval && 0 == val) {
+						val = max - 1;
+					}
+					if (val < prevval) {
+						logMessage(cerr,"Error: invalid range specification");
+						resultset.clear();
+						return resultset;
+					}
+					for (long i = prevval; i <= val; i++)
+						resultset.push_back(i);
+					}
+					else {
+						resultset.push_back(val);
+					}
+					range=false;
+				}
+				break;
 
-        case ':':
-          range=true;
-          break;
+			case ':':
+				range=true;
+				break;
 
-        default:
-          logMessage(cerr,formatString("Error: invalid character %c",*end));
-          resultset.clear();
-          return resultset;
-          break;
-      }
-    }
-    prevval = val;
-  }
+			default:
+				logMessage(cerr,formatString("Error: invalid character %c",*end));
+				resultset.clear();
+				return resultset;
+				break;
+			} // switch
+		} // if (end)
+		prevval = val;
+	} // while
 
-  return resultset;
+	return (resultset);
 }
 
 void RSPCtl::logMessage(ostream& stream, const string& message)
 {
-  if(m_command != 0) {
-    m_command->logMessage(stream,message);
-  }
-  else {
-    stream << message << endl;
-  }
+	if(m_command != 0) {
+		m_command->logMessage(stream,message);
+	}
+	else {
+		stream << message << endl;
+	}
 }
 
   } // namespace rspctl
@@ -3274,21 +3363,21 @@ using namespace LOFAR::rspctl;
 
 int main(int argc, char** argv)
 {
-  GCFTask::init(argc, argv, "rspctl");
+	GCFTask::init(argc, argv, "rspctl");
 
-  LOG_INFO(formatString("Program %s has started", argv[0]));
+	LOG_INFO(formatString("Program %s has started", argv[0]));
 
-  RSPCtl c("RSPCtl", argc, argv);
+	RSPCtl c("RSPCtl", argc, argv);
 
-  try {
-    c.mainloop();
-  }
-  catch (Exception e) {
-    cerr << "Exception: " << e.text() << endl;
-    exit(EXIT_FAILURE);
-  }
+	try {
+		c.mainloop();
+	}
+	catch (Exception e) {
+		cerr << "Exception: " << e.text() << endl;
+		exit(EXIT_FAILURE);
+	}
 
-  LOG_INFO("Normal termination of program");
+	LOG_INFO("Normal termination of program");
 
-  return 0;
+	return (0);
 }
diff --git a/MAC/APL/PIC/RSPDriver/src/rspctl.h b/MAC/APL/PIC/RSPDriver/src/rspctl.h
index f66c5f00577..46119d44685 100644
--- a/MAC/APL/PIC/RSPDriver/src/rspctl.h
+++ b/MAC/APL/PIC/RSPDriver/src/rspctl.h
@@ -644,6 +644,29 @@ private:
 	blitz::Array<RSP_Protocol::SPUStatus, 1> 	itsSPUs;
 };
 
+//
+// class RawBlockCommand
+//
+class RawBlockCommand : public Command
+{
+public:
+	RawBlockCommand(GCFPortInterface& port);
+	virtual ~RawBlockCommand() {}
+	virtual void send();
+	virtual GCFEvent::TResult ack(GCFEvent& e);
+	void	setAddressInfo(uint16 RSPboard, uint32 address, uint16 offset);
+	void	setDataInfo   (const string& filename, uint16 dataLen, uint8*	dataPtr);
+	void	getAddressInfo(uint16* RSPboard, uint32* address, uint16* offset);
+	void	getDataInfo   (const string& filename, uint16* dataLen, uint8** dataHandle);
+private:
+	uint16	itsRSPboard;
+	uint32	itsAddress;
+	uint16	itsOffset;
+	uint16	itsDataLen;
+	string	itsFileName;
+	uint8	itsData[ETH_DATA_LEN];
+};
+
 //
 // class VersionCommand
 //
diff --git a/MAC/APL/PIC/RSP_Protocol/include/APL/RSP_Protocol/AllRegisterState.h b/MAC/APL/PIC/RSP_Protocol/include/APL/RSP_Protocol/AllRegisterState.h
index 6a5e5669910..5d87716f242 100644
--- a/MAC/APL/PIC/RSP_Protocol/include/APL/RSP_Protocol/AllRegisterState.h
+++ b/MAC/APL/PIC/RSP_Protocol/include/APL/RSP_Protocol/AllRegisterState.h
@@ -34,214 +34,225 @@
 namespace LOFAR {
   namespace RSP_Protocol {
 
-    /**
-     * This class is used to contain the RegisterState of all registers.
-     *
-     * It is used in the following events:
-     * GETREGISTERSTATEACK
-     * UPDREGISTERSTATE
-     *
-     */
-    class AllRegisterState
-      {
-      public:
-
-	/**
-	 * Constructors for a AllRegisterState object.
-	 */
+// This class is used to contain the RegisterState of all registers.
+//
+// It is used in the following events:
+// GETREGISTERSTATEACK
+// UPDREGISTERSTATE
+//
+class AllRegisterState
+{
+public:
+	// Constructors for a AllRegisterState object.
 	AllRegisterState() : m_nrcus(0) {}
-
-	/* Destructor for AllRegisterState. */
 	virtual ~AllRegisterState() {}
 
-      public:
-
+	//
+	// init(nrRSP, nrBLP, nrRCU)
+	//
 	void init(int nrRspBoards, int nrBlps, int nrRcus) {
+		m_nrcus = nrRcus;
 
-	  m_nrcus = nrRcus;
-
-	  //
-	  // resize to appropriate size and mark modified
-	  // to force initial update
-	  //
-	  sys_state.resize(nrRspBoards);
-	  bf_state.resize(nrRcus * EPA_Protocol::MEPHeader::N_PHASE); // XR, XI, YR, YI
-	  ss_state.resize(nrBlps);
-	  rcusettings_state.resize(nrRcus);
-	  rcuprotocol_state.resize(nrRcus);
-	  hbaprotocol_state.resize(nrRcus);
-	  rsuclear_state.resize(nrRspBoards);
-	  diagwgsettings_state.resize(nrRcus * EPA_Protocol::MEPHeader::N_DIAG_WG_REGISTERS);
-	  sst_state.resize(nrBlps * EPA_Protocol::MEPHeader::SST_N_FRAGMENTS);
-	  bst_state.resize(nrRspBoards);
-	  xst_state.resize(nrRspBoards * EPA_Protocol::MEPHeader::XST_NR_STATS);
-	  cdo_state.resize(nrRspBoards * EPA_Protocol::MEPHeader::N_CDO_REGISTERS);
-	  bs_state.resize(nrBlps);
-	  tdclear_state.resize(nrRspBoards);
-	  tdwrite_state.resize(nrRspBoards);
-	  tdread_state.resize(nrRspBoards);
-	  rad_state.resize(nrRspBoards);
-	  ts_state.resize(nrRspBoards);
-	  tdstatuswrite_state.resize(nrRspBoards);
-	  tdstatusread_state.resize(nrRspBoards);
-	  tbbsettings_state.resize(nrRcus);
-	  tbbbandsel_state.resize(nrRcus);
-	  bypasssettings_state.resize(nrBlps);
+		//
+		// resize to appropriate size and mark modified
+		// to force initial update
+		//
+		sys_state.resize(nrRspBoards);
+		bf_state.resize(nrRcus * EPA_Protocol::MEPHeader::N_PHASE); // XR, XI, YR, YI
+		ss_state.resize(nrBlps);
+		rcusettings_state.resize(nrRcus);
+		rcuprotocol_state.resize(nrRcus);
+		hbaprotocol_state.resize(nrRcus);
+		rsuclear_state.resize(nrRspBoards);
+		diagwgsettings_state.resize(nrRcus * EPA_Protocol::MEPHeader::N_DIAG_WG_REGISTERS);
+		sst_state.resize(nrBlps * EPA_Protocol::MEPHeader::SST_N_FRAGMENTS);
+		bst_state.resize(nrRspBoards);
+		xst_state.resize(nrRspBoards * EPA_Protocol::MEPHeader::XST_NR_STATS);
+		cdo_state.resize(nrRspBoards * EPA_Protocol::MEPHeader::N_CDO_REGISTERS);
+		bs_state.resize(nrBlps);
+		tdclear_state.resize(nrRspBoards);
+		tdwrite_state.resize(nrRspBoards);
+		tdread_state.resize(nrRspBoards);
+		rad_state.resize(nrRspBoards);
+		ts_state.resize(nrRspBoards);
+		tdstatuswrite_state.resize(nrRspBoards);
+		tdstatusread_state.resize(nrRspBoards);
+		tbbsettings_state.resize(nrRcus);
+		tbbbandsel_state.resize(nrRcus);
+		bypasssettings_state.resize(nrBlps);
+		rawdatawrite_state.resize(nrRspBoards);
+		rawdataread_state.resize(nrRspBoards);
 	}
 
-	/*
-	 * Force update of some (not all) register.
-	 * Register excluded from update are 
-	 * tds, bs, rsuclear
-	 */
+	// Force update of some (not all) register.
+	// Register excluded from update are 
+	// tds, bs, rsuclear
+	//
+	// force()
+	//
 	void force() {
-	  sys_state.reset();
-	  bf_state.reset();
-	  ss_state.reset();
-	  rcusettings_state.reset();
-	  rcuprotocol_state.reset();
-	  hbaprotocol_state.reset();
-	  rsuclear_state.reset();
-	  diagwgsettings_state.reset();
-	  sst_state.reset();
-	  bst_state.reset();
-	  xst_state.reset();
-	  cdo_state.reset();
-	  bs_state.reset();
-	  tdclear_state.reset();
-	  tdwrite_state.reset();
-	  tdread_state.reset();
-	  rad_state.reset();
-	  ts_state.reset();
-	  tdstatuswrite_state.reset();
-	  tdstatusread_state.reset();
-	  tbbsettings_state.reset();
-	  tbbbandsel_state.reset();
-	  bypasssettings_state.reset();
+		sys_state.reset();
+		bf_state.reset();
+		ss_state.reset();
+		rcusettings_state.reset();
+		rcuprotocol_state.reset();
+		hbaprotocol_state.reset();
+		rsuclear_state.reset();
+		diagwgsettings_state.reset();
+		sst_state.reset();
+		bst_state.reset();
+		xst_state.reset();
+		cdo_state.reset();
+		bs_state.reset();
+		tdclear_state.reset();
+		tdwrite_state.reset();
+		tdread_state.reset();
+		rad_state.reset();
+		ts_state.reset();
+		tdstatuswrite_state.reset();
+		tdstatusread_state.reset();
+		tbbsettings_state.reset();
+		tbbbandsel_state.reset();
+		bypasssettings_state.reset();
+		rawdatawrite_state.reset();
+		rawdataread_state.reset();
 
-	  sys_state.read();
-	  bf_state.write();
-	  ss_state.write();
-	  rcusettings_state.write();
-	  rcuprotocol_state.write();
-	  hbaprotocol_state.write();
-	  rsuclear_state.check();
-	  diagwgsettings_state.write();
-	  sst_state.read();
-	  bst_state.read();
-	  xst_state.read();
-	  cdo_state.check();
-	  bs_state.check();
-	  tdclear_state.check();
-	  tdwrite_state.check();
-	  tdread_state.check();
-	  rad_state.write();
-	  ts_state.write();
-	  tdstatuswrite_state.write();
-	  tdstatusread_state.read();
-	  tbbsettings_state.check();
-	  tbbbandsel_state.check();
-	  bypasssettings_state.write(); // REO: When is this function called???
+		sys_state.read();
+		bf_state.write();
+		ss_state.write();
+		rcusettings_state.write();
+		rcuprotocol_state.write();
+		hbaprotocol_state.write();
+		rsuclear_state.check();
+		diagwgsettings_state.write();
+		sst_state.read();
+		bst_state.read();
+		xst_state.read();
+		cdo_state.check();
+		bs_state.check();
+		tdclear_state.check();
+		tdwrite_state.check();
+		tdread_state.check();
+		rad_state.write();
+		ts_state.write();
+		tdstatuswrite_state.write();
+		tdstatusread_state.read();
+		tbbsettings_state.check();
+		tbbbandsel_state.check();
+		bypasssettings_state.write(); // REO: When is this function called???
+		rawdatawrite_state.check();
+		rawdataread_state.check();
 	}
 
+	//
+	// schedule()
+	//
 	void schedule() {
-	  sys_state.read();
-	  bf_state.write(); // always write bf
-	  ss_state.write(); // always write ss
-	  rcusettings_state.check();
-	  rcuprotocol_state.check();
-	  hbaprotocol_state.check();
-	  rsuclear_state.check();
-	  diagwgsettings_state.check();
-	  sst_state.read();
-	  bst_state.read();
-	  xst_state.read();
-	  cdo_state.check();
-	  bs_state.check();
-	  tdclear_state.check();
-	  tdwrite_state.check();
-	  tdread_state.check();
-	  rad_state.check();
-	  ts_state.write(); // always write timestamp
-	  tdstatuswrite_state.write();
-	  tdstatusread_state.read();
-	  tbbsettings_state.check();
-	  tbbbandsel_state.check();
-	  bypasssettings_state.check(); // REO ?
+		sys_state.read();
+		bf_state.write(); // always write bf
+		ss_state.write(); // always write ss
+		rcusettings_state.check();
+		rcuprotocol_state.check();
+		hbaprotocol_state.check();
+		rsuclear_state.check();
+		diagwgsettings_state.check();
+		sst_state.read();
+		bst_state.read();
+		xst_state.read();
+		cdo_state.check();
+		bs_state.check();
+		tdclear_state.check();
+		tdwrite_state.check();
+		tdread_state.check();
+		rad_state.check();
+		ts_state.write(); // always write timestamp
+		tdstatuswrite_state.write();
+		tdstatusread_state.read();
+		tbbsettings_state.check();
+		tbbbandsel_state.check();
+		bypasssettings_state.check(); // REO ?
+		rawdatawrite_state.check();
+		rawdataread_state.check();
 	}
 
+	//
+	// clear()
+	//
 	void clear() {
-	  sys_state.clear();
-	  bf_state.clear();
-	  ss_state.clear();
-	  rcusettings_state.clear();
-	  rcuprotocol_state.clear();
-	  hbaprotocol_state.clear();
-	  rsuclear_state.clear();
-	  diagwgsettings_state.clear();
-	  sst_state.clear();
-	  bst_state.clear();
-	  xst_state.clear();
-	  cdo_state.clear();
-	  bs_state.clear();
-	  tdclear_state.clear();
-	  tdwrite_state.clear();
-	  tdread_state.clear();
-	  rad_state.clear();
-	  ts_state.clear();
-	  tdstatuswrite_state.clear();
-	  tdstatusread_state.clear();
-	  tbbsettings_state.clear();
-	  tbbbandsel_state.clear();
-	  bypasssettings_state.clear();
+		sys_state.clear();
+		bf_state.clear();
+		ss_state.clear();
+		rcusettings_state.clear();
+		rcuprotocol_state.clear();
+		hbaprotocol_state.clear();
+		rsuclear_state.clear();
+		diagwgsettings_state.clear();
+		sst_state.clear();
+		bst_state.clear();
+		xst_state.clear();
+		cdo_state.clear();
+		bs_state.clear();
+		tdclear_state.clear();
+		tdwrite_state.clear();
+		tdread_state.clear();
+		rad_state.clear();
+		ts_state.clear();
+		tdstatuswrite_state.clear();
+		tdstatusread_state.clear();
+		tbbsettings_state.clear();
+		tbbbandsel_state.clear();
+		bypasssettings_state.clear();
+		rawdatawrite_state.clear();
+		rawdataread_state.clear();
 	}
 
+	//
+	// print(os)
+	//
 	void print(std::ostream& out) const {
-	  out << "                  ";
-	  for (int i = 0; i < m_nrcus * EPA_Protocol::MEPHeader::N_POL; i++) {
-	    out << (i % 10) << " ";
-	  }
-	  out << endl;
-	  out << "System Status     "; sys_state.print(out);
-	  out << "BF                "; bf_state.print(out);
-	  out << "Subband Selection "; ss_state.print(out);
-	  out << "RCUSettings       "; rcusettings_state.print(out);
-	  out << "RCUProtocol       "; rcuprotocol_state.print(out);
-	  out << "HBAProtocol       "; hbaprotocol_state.print(out);
-	  out << "RSUClear          "; rsuclear_state.print(out);
-	  out << "DIAGWGSettings    "; diagwgsettings_state.print(out);
-	  out << "SubbandStats      "; sst_state.print(out);
-	  out << "BeamletStats      "; bst_state.print(out);
-	  out << "XCorrelationStats "; xst_state.print(out);
-	  out << "CDO               "; cdo_state.print(out);
-	  out << "BS                "; bs_state.print(out);
-	  out << "TDSClear          "; tdclear_state.print(out);
-	  out << "TDSWrite          "; tdwrite_state.print(out);
-	  out << "TDSRead           "; tdread_state.print(out);
-	  out << "RAD               "; rad_state.print(out);
-	  out << "Timestamp         "; ts_state.print(out);
-	  out << "TDS Status (write)"; tdstatuswrite_state.print(out);
-	  out << "TDS Status (read) "; tdstatusread_state.print(out);
-	  out << "TBBSettings       "; tbbsettings_state.print(out);
-	  out << "TBBBandsel        "; tbbbandsel_state.print(out);
-	  out << "DIAGBypassSettings"; bypasssettings_state.print(out);
-	  out << endl;
+		out << "                  ";
+		for (int i = 0; i < m_nrcus * EPA_Protocol::MEPHeader::N_POL; i++) {
+		out << (i % 10) << " ";
+		}
+		out << endl;
+		out << "System Status       "; sys_state.print(out);
+		out << "BF                  "; bf_state.print(out);
+		out << "Subband Selection   "; ss_state.print(out);
+		out << "RCUSettings         "; rcusettings_state.print(out);
+		out << "RCUProtocol         "; rcuprotocol_state.print(out);
+		out << "HBAProtocol         "; hbaprotocol_state.print(out);
+		out << "RSUClear            "; rsuclear_state.print(out);
+		out << "DIAGWGSettings      "; diagwgsettings_state.print(out);
+		out << "SubbandStats        "; sst_state.print(out);
+		out << "BeamletStats        "; bst_state.print(out);
+		out << "XCorrelationStats   "; xst_state.print(out);
+		out << "CDO                 "; cdo_state.print(out);
+		out << "BS                  "; bs_state.print(out);
+		out << "TDSClear            "; tdclear_state.print(out);
+		out << "TDSWrite            "; tdwrite_state.print(out);
+		out << "TDSRead             "; tdread_state.print(out);
+		out << "RAD                 "; rad_state.print(out);
+		out << "Timestamp           "; ts_state.print(out);
+		out << "TDS Status (write)  "; tdstatuswrite_state.print(out);
+		out << "TDS Status (read)   "; tdstatusread_state.print(out);
+		out << "TBBSettings         "; tbbsettings_state.print(out);
+		out << "TBBBandsel          "; tbbbandsel_state.print(out);
+		out << "DIAGBypassSettings  "; bypasssettings_state.print(out);
+		out << "RawDataBlock(write) "; rawdatawrite_state.print(out);
+		out << "RawDataBlock(read)  "; rawdataread_state.print(out);
+		out << endl;
 	}
 
 	/*@{*/
-	/**
-	 * marshalling methods
-	 */
+	// marshalling methods
 	unsigned int getSize();
 	unsigned int pack  (void* buffer);
 	unsigned int unpack(void *buffer);
 	/*@}*/
 
-      public:
+public:
 	/*@{*/
-	/**
-	 * Accessor methods
-	 */
+	// Accessor methods
 	RTC::RegisterState& sys()            { return sys_state; }
 	RTC::RegisterState& bf()             { return bf_state; }
 	RTC::RegisterState& ss()             { return ss_state; }
@@ -265,9 +276,13 @@ namespace LOFAR {
 	RTC::RegisterState& tbbsettings()    { return tbbsettings_state; }
 	RTC::RegisterState& tbbbandsel()     { return tbbbandsel_state; }
 	RTC::RegisterState& bypasssettings() { return bypasssettings_state; }
+	RTC::RegisterState& rawdatawrite()   { return rawdatawrite_state; }
+	RTC::RegisterState& rawdataread()    { return rawdataread_state; }
+
 	/*@}*/
 
-      private:
+private:
+	// ----- data members -----
 	RTC::RegisterState sys_state;            // RSR state
 	RTC::RegisterState bf_state;             // BF weights state
 	RTC::RegisterState ss_state;             // SS state
@@ -291,10 +306,13 @@ namespace LOFAR {
 	RTC::RegisterState tbbsettings_state;    // TBB settings state
 	RTC::RegisterState tbbbandsel_state;     // TBB bandsel state
 	RTC::RegisterState bypasssettings_state; // Bypass (specinv) state
+	RTC::RegisterState rawdatawrite_state;	 // Write userdefined datablock
+	RTC::RegisterState rawdataread_state;	 // Read userdefined datablock
 
 	int m_nrcus;
-      };
-  };
+};
+
+  }; // namespace RSP_Protocol
 }; // namespace LOFAR
 
 #endif /* ALLREGISTERSTATE_H_ */
diff --git a/MAC/APL/PIC/RSP_Protocol/include/APL/RSP_Protocol/MEPData.h b/MAC/APL/PIC/RSP_Protocol/include/APL/RSP_Protocol/MEPData.h
index 041dedcce01..04201c6fb1d 100644
--- a/MAC/APL/PIC/RSP_Protocol/include/APL/RSP_Protocol/MEPData.h
+++ b/MAC/APL/PIC/RSP_Protocol/include/APL/RSP_Protocol/MEPData.h
@@ -28,43 +28,34 @@
 #include <unistd.h>
 
 namespace LOFAR {
-namespace EPA_Protocol
+  namespace EPA_Protocol {
+
+class MEPData
 {
-  class MEPData
-  {
-    public:
-      /**
-       * Constructors for a MEPData object.
-       */
-      MEPData() : m_dataptr(0), m_count(0) { }
-	  
-      /* Destructor for MEPData. */
-      virtual ~MEPData() {}
+public:
+	// Constructors for a MEPData object.
+	MEPData() : m_dataptr(0), m_count(0) { }
+	virtual ~MEPData() {}
 
-    public:
-      /**
-       * Member access.
-       */
-      void  setBuffer(void* buf, size_t size);
-      void* getBuffer() const;
+	// Member access.
+	void  	setBuffer(void* buf, size_t size);
+	void* 	getBuffer() const;
+	size_t	getDataLen() const;
 
-    public:
-      /*@{*/
-      /**
-       * marshalling methods
-       */
-      unsigned int getSize();
-      unsigned int pack  (void* buffer);
-      unsigned int unpack(void *buffer);
-      /*@}*/
+	/*@{*/
+	// marshalling methods
+	unsigned int getSize();
+	unsigned int pack  (void* buffer);
+	unsigned int unpack(void *buffer);
+	/*@}*/
 
-    private:
-      /**
-       * MEP Payload data
-       */
-      void*  m_dataptr; // pointer to user data, not owned by this class
-      size_t m_count;
-  };
-};
+private:
+	// MEP Payload data
+	void*  m_dataptr; // pointer to user data, not owned by this class
+	size_t m_count;
 };
+
+  }; // namepsace EPA_Protocol
+}; // namespace LOFAR
+
 #endif /* MEPDATA_H_ */
diff --git a/MAC/APL/PIC/RSP_Protocol/include/APL/RSP_Protocol/MEPHeader.h b/MAC/APL/PIC/RSP_Protocol/include/APL/RSP_Protocol/MEPHeader.h
index 2ed25e993a3..a338060cade 100644
--- a/MAC/APL/PIC/RSP_Protocol/include/APL/RSP_Protocol/MEPHeader.h
+++ b/MAC/APL/PIC/RSP_Protocol/include/APL/RSP_Protocol/MEPHeader.h
@@ -35,433 +35,383 @@
 namespace LOFAR {
   namespace EPA_Protocol {
 
-    class MEPHeader
-    {
-    public:
-      /**
-       * Constructors for a MEPHeader object.
-       */
-      MEPHeader() { }
-	  
-      /* Destructor for MEPHeader. */
-      virtual ~MEPHeader() {}
-
-      /**
-       * Size of MEP header in bytes.
-       */
-      static const unsigned int SIZE = 16;
-
-      /*@{*/
-      /**
-       * Message types.
-       */
-      static const uint8 TYPE_UNSET = 0x00;
-      static const uint8 READ       = 0x01;
-      static const uint8 WRITE      = 0x02;
-      static const uint8 READACK    = 0x03;
-      static const uint8 WRITEACK   = 0x04;
-
-      static const int MIN_TYPE = READ;
-      static const int MAX_TYPE = WRITEACK; /* counting from 0 */
-      /*@}*/
-
-      /*@{*/
-      /**
-       * Address constants
-       *
-       * Definition of the addr.dstid values.
-       * Any of DST_BLP* and DST_RSP may be or-ed together
-       * to multicast to those destinations.
-       */
-      static const uint16 DST_BLP0     = 0x0001; /* BLP 0, byte 0, bit 0  */
-      static const uint16 DST_BLP1     = 0x0002; /* BLP 1, byte 0, bit 1  */
-      static const uint16 DST_BLP2     = 0x0004; /* BLP 2, byte 0, bit 2  */
-      static const uint16 DST_BLP3     = 0x0008; /* BLP 3, byte 0, bit 3  */
-      static const uint16 DST_RSP      = 0x0100; /* RSP,   byte 1, bit 0 */
-
-      /* multicast constants */
-      static const uint16 DST_ALL_BLPS = DST_BLP0 | DST_BLP1 | DST_BLP2 | DST_BLP3; /* All BLP, but not the RSP */
-      static const uint16 DST_ALL      = DST_ALL_BLPS | DST_RSP;                    /* All FPGA's (including RSP) */
-      /*@}*/
-
-      /*@{*/
-      /**
-       * Process IDs
-       *
-       * Constants extracted from MEP VHDL
-       *
-       * CONSTANT c_mep_pid_rsr     : NATURAL :=  1;
-       * CONSTANT c_mep_pid_rsu     : NATURAL :=  2;
-       * CONSTANT c_mep_pid_diag    : NATURAL :=  3;
-       * CONSTANT c_mep_pid_ss      : NATURAL :=  4;
-       * CONSTANT c_mep_pid_bf      : NATURAL :=  5;
-       * CONSTANT c_mep_pid_bst     : NATURAL :=  6;
-       * CONSTANT c_mep_pid_sst     : NATURAL :=  7;
-       * CONSTANT c_mep_pid_rcuh    : NATURAL :=  8;
-       * CONSTANT c_mep_pid_cr      : NATURAL :=  9;
-       * CONSTANT c_mep_pid_xst     : NATURAL := 10;
-       * CONSTANT c_mep_pid_cdo     : NATURAL := 11;
-       * CONSTANT c_mep_pid_bs      : NATURAL := 12;
-       * CONSTANT c_mep_pid_serdes  : NATURAL := 13;
-       * CONSTANT c_mep_pid_tdsh    : NATURAL := 14;
-       * CONSTANT c_mep_pid_tbb     : NATURAL := 15;
-       * 
-       */
-      static const uint8 RSR       = 0x01; /* Status overview            [RSP/BLP] */
-      static const uint8 RSU       = 0x02; /* FPGA remote system update. [RSP    ] */
-      static const uint8 DIAG      = 0x03; /* Diagnostics                [RSP/BLP] */
-      static const uint8 SS        = 0x04; /* Subband select             [    BLP] */
-      static const uint8 BF        = 0x05; /* Beamformer                 [    BLP] */
-      static const uint8 BST       = 0x06; /* Beamformer statistics      [RSP    ] */
-      static const uint8 SST       = 0x07; /* Subband statistics         [    BLP] */
-      static const uint8 RCU       = 0x08; /* RCU control                [    BLP] */
-      static const uint8 CR        = 0x09; /* Clock and reset            [RSP/BLP] */
-      static const uint8 XST       = 0x0A; /* Clock and reset            [RSP/BLP] */
-      static const uint8 CDO       = 0x0B; /* CEP Data Output            [RSP    ] */
-      static const uint8 BS        = 0x0C; /* Block Synchronization      [    BLP] */
-      static const uint8 SERDES    = 0x0D; /* Reserved1                            */
-      static const uint8 TDS       = 0x0E; /* Time distribution board    [RSP    ] */
-      static const uint8 TBB       = 0x0F; /* Transient Buffer Board     [    BLP] */ /* Is this correct? Should it not be RSP? */
-      static const uint8 CEP       = 0x10; /* CEP management             [RSP    ] */
-      static const uint8 LCU       = 0x11; /* LCU management             [RSP    ] */
-      static const uint8 RAD       = 0x12; /* RAD management             [RSP    ] */
-
-      static const int MIN_PID = RSR; /* loops over PID should be from */ 
-      static const int MAX_PID = RAD; /* pid = MIN_PID; pid <= MAX_PID */
-      /*@}*/
-
-      /*@{*/
-      /**
-       * Register IDs
-       */
-      static const uint8 RSR_STATUS       = 0x00;
-      static const uint8 RSR_VERSION      = 0x01;
-      static const uint8 RSR_TIMESTAMP    = 0x02;
-
-      static const uint8 RSU_FLASHRW      = 0x01;
-      static const uint8 RSU_FLASHERASE   = 0x02;
-      static const uint8 RSU_RECONFIGURE  = 0x03;
-      static const uint8 RSU_RESET        = 0x04;
-
-      static const uint8 DIAG_WGX         = 0x00;
-      static const uint8 DIAG_WGY         = 0x01;
-      static const uint8 DIAG_WGXWAVE     = 0x02;
-      static const uint8 DIAG_WGYWAVE     = 0x03;
-      static const uint8 DIAG_BYPASS      = 0x04;
-      static const uint8 DIAG_RESULTS     = 0x05;
-      static const uint8 DIAG_SELFTEST    = 0x06;
-      
-      static const uint8 SS_SELECT        = 0x00;
-
-      static const uint8 BF_XROUT         = 0x00;
-      static const uint8 BF_XIOUT         = 0x01;
-      static const uint8 BF_YROUT         = 0x02;
-      static const uint8 BF_YIOUT         = 0x03;
-
-      static const uint8 BST_POWER_LANE_0 = 0x00;
-      static const uint8 BST_POWER_LANE_1 = 0x01;
-      static const uint8 BST_POWER_LANE_2 = 0x02;
-      static const uint8 BST_POWER_LANE_3 = 0x03;
-
-      static const uint8 SST_POWER        = 0x00;
-
-      static const uint8 RCU_SETTINGS     = 0x00;
-      static const uint8 RCU_PROTOCOLX    = 0x01;
-      static const uint8 RCU_RESULTX      = 0x02;
-      static const uint8 RCU_PROTOCOLY    = 0x03;
-      static const uint8 RCU_RESULTY      = 0x04;
-
-      static const uint8 CR_SOFTCLEAR     = 0x00;
-      static const uint8 CR_SOFTSYNC      = 0x01;
-      static const uint8 CR_SYNCDISABLE   = 0x02;
-
-      /*
-       * Cross correlation registers.
-       */
-      
-
-      static const uint8 XST_STATS    = 0x00;
-      static const uint8 XST_NR_STATS = 32;
-
-      /**
-       * The CDO register will be extended to 
-       * allow setting the UDP/IP header and some
-       * settings to set interleaving of beamlets.
-       */
-      static const uint8 CDO_SETTINGS = 0x00;
-      static const uint8 CDO_HEADER   = 0x01;
-
-      static const uint8 BS_NOF_SAMPLES_PER_SYNC = 0x00;
-
-      static const uint8 TDS_PROTOCOL            = 0x00;
-      static const uint8 TDS_RESULT              = 0x01;
-
-      /**
-       * Placeholder register for future TBB control via the RSP board.
-       */
-      static const uint8 TBB_SETTINGSX = 0x00;
-      static const uint8 TBB_SETTINGSY = 0x01;
-      static const uint8 TBB_BANDSELX  = 0x02;
-      static const uint8 TBB_BANDSELY  = 0x03;
-
-      /**
-       * RAD_BP register controls how local and remove crosslet and
-       * beamlet data from the SERDES lanes is combined on an RSP 
-       * board. This can be used to define logical start and end-points
-       * for the cross-correlation and beamforming data travelling on the
-       * SERDES rings.
-       */
-      static const uint8 RAD_BP           = 0x00;
-
-      static const int MIN_REGID          = 0x00;
-      static const int MAX_REGID          = XST_NR_STATS - 1;
-
-      /*@}*/
-
-      /*@{*/
-      /**
-       * Define the number of beamlets N_BEAMLETS
-       * supported by the EPA firmware. For FTS-1
-       * the number of beamlets supported is 128.
-       * For the final LOFAR remote station
-       * 256 beamlets will be supported.
-       *
-       * Many register sizes are derived from
-       * the number of beamlets.
-       *
-       * The N_SUBBANDS(512) defines the number of
-       * subbands produced by the EPA digital filter.
-       * The N_BEAMLETS are a selection from this
-       * number of beamlets.
-       */
-      static const uint16 N_POL            = 2;                    // number of polarizations
-      static const uint16 N_PHASE          = 2;                    // number of phases in a complex number
-      static const uint16 N_PHASEPOL       = N_PHASE * N_POL;      // number of phase polarizations
-      static const uint16 MAX_N_RCUS       = 128 * MEPHeader::N_POL;
-      static const uint16 N_BLPS           = 4;                    // number of BLP's per RSP board
-      static const uint16 N_SUBBANDS       = 512;
-      static const uint16 N_REMOTE_XLETS   = 54; 
-      static const uint16 N_SERDES_LANES   = 4;
-      static const uint16 N_TOTAL_XLETS    = N_SERDES_LANES * N_REMOTE_XLETS;
-      static const uint16 N_LOCAL_XLETS    = 4;
-      static const uint16 N_BEAMLETS       = 216;
-      static const uint16 N_LOCAL_BEAMLETS = 54; // N_BEAMLETS / N_SERDES_LANES
-      static const uint16 XLET_SIZE        = N_POL * sizeof(std::complex<uint32>);
-      static const uint16 WEIGHT_SIZE      = N_POL * sizeof(std::complex<uint16>);
-
-      static const uint16 N_HBA_DELAYS     = 16; // number of High Band antenna delay elements
-      
-      // TBB related constants
-      static const uint16 TBB_MAXPAYLOADSIZE     = 1948; // available TBB payload bytes
-      static const uint16 TBB_NTRANSIENTSAMPLES  = 1024; // number of 12-bit transient samples per frame
-      static const uint16 TBB_SPECTRALSAMPLESIZE = sizeof(std::complex<uint16>);
-      /*@}*/
-
-      
-      /*@{*/
-      /**
-       * Define size of each register.
-       */
-      static const uint16 RSR_STATUS_SIZE       = 200;
-      static const uint16 RSR_VERSION_SIZE      = 2;
-      static const uint16 RSR_TIMESTAMP_SIZE    = 4;
-      
-      static const uint16 RSU_FLASHRW_SIZE      = 1024;
-      static const uint16 RSU_FLASHERASE_SIZE   = 1;
-      static const uint16 RSU_RECONFIGURE_SIZE  = 1;
-      static const uint16 RSU_RESET_SIZE        = 1;
-
-      static const uint16 DIAG_WGX_SIZE         = 12;
-      static const uint16 DIAG_WGY_SIZE         = 12;
-      static const uint16 DIAG_WGXWAVE_SIZE     = 8192;
-      static const uint16 DIAG_WGYWAVE_SIZE     = 8192;
-      static const uint16 DIAG_BYPASS_SIZE      = 2;
-      static const uint16 DIAG_RESULTS_SIZE     = 4096; // also 8192 ?
-      static const uint16 DIAG_SELFTEST_SIZE    = 4;
-      
-      static const uint16 SS_SELECT_SIZE        = (N_LOCAL_XLETS + N_BEAMLETS) * N_POL * sizeof(uint16); // = 960?
-
-      static const uint16 BF_XROUT_SIZE         = (N_LOCAL_XLETS + N_BEAMLETS) * WEIGHT_SIZE;
-      static const uint16 BF_XIOUT_SIZE         = (N_LOCAL_XLETS + N_BEAMLETS) * WEIGHT_SIZE;
-      static const uint16 BF_YROUT_SIZE         = (N_LOCAL_XLETS + N_BEAMLETS) * WEIGHT_SIZE;
-      static const uint16 BF_YIOUT_SIZE         = (N_LOCAL_XLETS + N_BEAMLETS) * WEIGHT_SIZE;
-
-      static const uint16 BST_POWER_SIZE        = N_LOCAL_BEAMLETS * N_POL * sizeof(uint32);
-
-      static const uint16 SST_POWER_SIZE        = N_SUBBANDS * N_POL * sizeof(uint32);
-
-      static const uint16 RCU_SETTINGS_SIZE     = 2;
-      static const uint16 RCU_PROTOCOL_SIZE     = 512;
-      static const uint16 RCU_RESULT_SIZE       = 512;
-
-      static const uint16 CR_CONTROL_SIZE       = 1;
-
-      // (N_LOCAL_XLETS + N_REMOTE_XLETS) * XLET_SIZE; // 928 (!= 3424?)
-      static const uint16 XST_STATS_SIZE        = N_REMOTE_XLETS * XLET_SIZE; // 864
-
-      /**
-       * The CDO register will be extended to 
-       * allow setting the UDP/IP header and some
-       * settings to set interleaving of beamlets.
-       */
-      static const uint16 CDO_SETTINGS_SIZE     = 30;
-      static const uint16 CDO_HEADER_SIZE       = 32;
-
-      static const uint16 BS_NOF_SAMPLES_PER_SYNC_SIZE = 4;
-
-      static const uint16 TDS_PROTOCOL_SIZE     = 4096;
-      static const uint16 TDS_RESULT_SIZE       = 1024;
-
-      /**
-       * Placeholder register for future TBB control via the RSP board.
-       */
-      static const uint16 TBB_SETTINGS_SIZE = 8;
-      static const uint16 TBB_BANDSEL_SIZE  = 64;
-
-      /**
-       * Size of the RAD_BP register.
-       */
-      static const uint16 RAD_BP_SIZE = 4; // four bytes = 32 bits, 8 bits per lane
-
-      //
-      // Registers too large to send in a single ethernet frame
-      // (> 1500 bytes) will be sent in a number of fragments of this size.
-      //
-      static const uint16 FRAGMENT_SIZE        = 1024;
-      static const uint16 N_AP                 = 4;
-      static const uint16 BF_N_FRAGMENTS       = 2;
-      static const uint16 N_WAVE_SAMPLES       = DIAG_WGXWAVE_SIZE / sizeof(int32);
-      static const uint16 SST_N_FRAGMENTS      = SST_POWER_SIZE / FRAGMENT_SIZE;
-      static const uint16 N_SST_STATS          = FRAGMENT_SIZE / sizeof(uint32);
-      static const uint16 N_DIAG_WG_REGISTERS  = 2;
-      static const uint16 N_CDO_REGISTERS      = 2;
-      static const uint16 N_RCUPROTOCOL_WRITES = 2;
-      static const uint16 N_HBAPROTOCOL_WRITES = 2;
-    
-      /*@}*/
-
-    public:
-      /*@{*/
-      /**
-       * marshalling methods
-       */
-      unsigned int getSize();
-      unsigned int pack  (void* buffer);
-      unsigned int unpack(void *buffer);
-      /*@}*/
-
-    public:
-      /**
-       * MEP 4.x header fields
-       */
-      typedef struct
-      {
-	uint8  type;           /* Message type */
-	uint8  status;         /* Error indicator */
-	uint16 frame_length;   /* Frame length */
-	typedef struct 
-	{
-	  uint16 dstid;        /* Beamlet processor and RSP ID */
-	  uint8  pid;          /* Process ID */
-	  uint8  regid;        /* Register ID */
-	} AddrType;
-	AddrType addr;         /* addr */
-	uint16 offset;         /* Offset address */
-	uint16 payload_length; /* Payload length (size) */
-	uint16 seqnr;          /* Sequence number */
-	uint16 _reserved;      /* Do not use; future use */
-      } FieldsType;
-
-      FieldsType m_fields;
-
-    public:
-
-      /*@{*/
-      /**
-       * Methods to set header fields.
-       */
-      void set(uint8  type,
-	       uint16 dstid,
-	       uint8  pid,
-	       uint8  regid,
-	       uint16 payload_length,
-	       uint16 offset = 0);
-
-      void set(MEPHeader::FieldsType hdrtemplate,
-	       uint16 dstid          = DST_RSP,
-	       uint8  type           = MEPHeader::TYPE_UNSET,
-	       uint16 payload_length = 0,
-	       uint16 offset         = 0);
-      /*@}*/
-
-      /**
-       * Method to check if this MEPHeader is a valid
-       * acknowledgement for a specific request.
-       */
-      bool isValidAck(const MEPHeader& reqhdr);
-
-      /*@{*/
-      //
-      // The following static constants are templates
-      // to produce EPA message headers. This is done by 
-      // copying the template and then make modifications
-      // to the appropriate parts of the header.
-      //
-      static const FieldsType RSR_STATUS_HDR;
-      static const FieldsType RSR_VERSION_HDR;
-      static const FieldsType RSR_TIMESTAMP_HDR;
-      
-      static const FieldsType RSU_FLASHRW_HDR;
-      static const FieldsType RSU_FLASHERASE_HDR;
-      static const FieldsType RSU_RECONFIGURE_HDR;
-      static const FieldsType RSU_RESET_HDR;
-
-      static const FieldsType DIAG_WGX_HDR;
-      static const FieldsType DIAG_WGY_HDR;
-      static const FieldsType DIAG_WGXWAVE_HDR;
-      static const FieldsType DIAG_WGYWAVE_HDR;
-      static const FieldsType DIAG_BYPASS_HDR;
-      static const FieldsType DIAG_RESULTS_HDR;
-      static const FieldsType DIAG_SELFTEST_HDR;
-      
-      static const FieldsType SS_SELECT_HDR;
-
-      static const FieldsType BF_XROUT_HDR;
-      static const FieldsType BF_XIOUT_HDR;
-      static const FieldsType BF_YROUT_HDR;
-      static const FieldsType BF_YIOUT_HDR;
-
-      static const FieldsType BST_POWER_HDR;
-
-      static const FieldsType SST_POWER_HDR;
-
-      static const FieldsType RCU_SETTINGS_HDR;
-      static const FieldsType RCU_PROTOCOLX_HDR;
-      static const FieldsType RCU_RESULTX_HDR;
-      static const FieldsType RCU_PROTOCOLY_HDR;
-      static const FieldsType RCU_RESULTY_HDR;
-
-      static const FieldsType CR_CONTROL_HDR;
-
-      static const FieldsType XST_STATS_HDR;
-
-      static const FieldsType CDO_SETTINGS_HDR;
-      static const FieldsType CDO_HEADER_HDR;
-
-      static const FieldsType BS_NOF_SAMPLES_PER_SYNC_HDR;
-
-      static const FieldsType TDS_PROTOCOL_HDR;
-      static const FieldsType TDS_RESULT_HDR;
-
-      static const FieldsType TBB_SETTINGSX_HDR;
-      static const FieldsType TBB_SETTINGSY_HDR;
-      static const FieldsType TBB_BANDSELX_HDR;
-      static const FieldsType TBB_BANDSELY_HDR;
-
-      static const FieldsType RAD_BP_HDR;
-      /*@}*/
-    };
-  };
+class MEPHeader
+{
+public:
+	// Constructors for a MEPHeader object.
+	MEPHeader() { }
+	virtual ~MEPHeader() {}
+
+	// Size of MEP header in bytes.
+	static const unsigned int SIZE = 16;
+
+	/*@{*/
+	// Message types.
+	static const uint8 TYPE_UNSET = 0x00;
+	static const uint8 READ       = 0x01;
+	static const uint8 WRITE      = 0x02;
+	static const uint8 READACK    = 0x03;
+	static const uint8 WRITEACK   = 0x04;
+
+	static const int MIN_TYPE = READ;
+	static const int MAX_TYPE = WRITEACK; /* counting from 0 */
+	/*@}*/
+
+	/*@{*/
+	// Address constants
+	//
+	// Definition of the addr.dstid values.
+	// Any of DST_BLP* and DST_RSP may be or-ed together
+	// to multicast to those destinations.
+	static const uint16 DST_BLP0     = 0x0001; /* BLP 0, byte 0, bit 0  */
+	static const uint16 DST_BLP1     = 0x0002; /* BLP 1, byte 0, bit 1  */
+	static const uint16 DST_BLP2     = 0x0004; /* BLP 2, byte 0, bit 2  */
+	static const uint16 DST_BLP3     = 0x0008; /* BLP 3, byte 0, bit 3  */
+	static const uint16 DST_RSP      = 0x0100; /* RSP,   byte 1, bit 0 */
+
+	// multicast constants 
+	static const uint16 DST_ALL_BLPS = DST_BLP0 | DST_BLP1 | DST_BLP2 | DST_BLP3; /* All BLP, but not the RSP */
+	static const uint16 DST_ALL      = DST_ALL_BLPS | DST_RSP;                    /* All FPGA's (including RSP) */
+	/*@}*/
+
+	/*@{*/
+	// Process IDs
+	//
+	// Constants extracted from MEP VHDL
+	//
+	// CONSTANT c_mep_pid_rsr     : NATURAL :=  1;
+	// CONSTANT c_mep_pid_rsu     : NATURAL :=  2;
+	// CONSTANT c_mep_pid_diag    : NATURAL :=  3;
+	// CONSTANT c_mep_pid_ss      : NATURAL :=  4;
+	// CONSTANT c_mep_pid_bf      : NATURAL :=  5;
+	// CONSTANT c_mep_pid_bst     : NATURAL :=  6;
+	// CONSTANT c_mep_pid_sst     : NATURAL :=  7;
+	// CONSTANT c_mep_pid_rcuh    : NATURAL :=  8;
+	// CONSTANT c_mep_pid_cr      : NATURAL :=  9;
+	// CONSTANT c_mep_pid_xst     : NATURAL := 10;
+	// CONSTANT c_mep_pid_cdo     : NATURAL := 11;
+	// CONSTANT c_mep_pid_bs      : NATURAL := 12;
+	// CONSTANT c_mep_pid_serdes  : NATURAL := 13;
+	// CONSTANT c_mep_pid_tdsh    : NATURAL := 14;
+	// CONSTANT c_mep_pid_tbb     : NATURAL := 15;
+	// 
+	static const uint8 RSR       = 0x01; /* Status overview            [RSP/BLP] */
+	static const uint8 RSU       = 0x02; /* FPGA remote system update. [RSP    ] */
+	static const uint8 DIAG      = 0x03; /* Diagnostics                [RSP/BLP] */
+	static const uint8 SS        = 0x04; /* Subband select             [    BLP] */
+	static const uint8 BF        = 0x05; /* Beamformer                 [    BLP] */
+	static const uint8 BST       = 0x06; /* Beamformer statistics      [RSP    ] */
+	static const uint8 SST       = 0x07; /* Subband statistics         [    BLP] */
+	static const uint8 RCU       = 0x08; /* RCU control                [    BLP] */
+	static const uint8 CR        = 0x09; /* Clock and reset            [RSP/BLP] */
+	static const uint8 XST       = 0x0A; /* Clock and reset            [RSP/BLP] */
+	static const uint8 CDO       = 0x0B; /* CEP Data Output            [RSP    ] */
+	static const uint8 BS        = 0x0C; /* Block Synchronization      [    BLP] */
+	static const uint8 SERDES    = 0x0D; /* Reserved1                            */
+	static const uint8 TDS       = 0x0E; /* Time distribution board    [RSP    ] */
+	static const uint8 TBB       = 0x0F; /* Transient Buffer Board     [    BLP] */ /* Is this correct? Should it not be RSP? */
+	static const uint8 CEP       = 0x10; /* CEP management             [RSP    ] */
+	static const uint8 LCU       = 0x11; /* LCU management             [RSP    ] */
+	static const uint8 RAD       = 0x12; /* RAD management             [RSP    ] */
+
+	static const int MIN_PID = RSR; /* loops over PID should be from */ 
+	static const int MAX_PID = RAD; /* pid = MIN_PID; pid <= MAX_PID */
+	/*@}*/
+
+	/*@{*/
+	// Register IDs
+	static const uint8 RSR_STATUS       = 0x00;
+	static const uint8 RSR_VERSION      = 0x01;
+	static const uint8 RSR_TIMESTAMP    = 0x02;
+
+	static const uint8 RSU_FLASHRW      = 0x01;
+	static const uint8 RSU_FLASHERASE   = 0x02;
+	static const uint8 RSU_RECONFIGURE  = 0x03;
+	static const uint8 RSU_RESET        = 0x04;
+
+	static const uint8 DIAG_WGX         = 0x00;
+	static const uint8 DIAG_WGY         = 0x01;
+	static const uint8 DIAG_WGXWAVE     = 0x02;
+	static const uint8 DIAG_WGYWAVE     = 0x03;
+	static const uint8 DIAG_BYPASS      = 0x04;
+	static const uint8 DIAG_RESULTS     = 0x05;
+	static const uint8 DIAG_SELFTEST    = 0x06;
+
+	static const uint8 SS_SELECT        = 0x00;
+
+	static const uint8 BF_XROUT         = 0x00;
+	static const uint8 BF_XIOUT         = 0x01;
+	static const uint8 BF_YROUT         = 0x02;
+	static const uint8 BF_YIOUT         = 0x03;
+
+	static const uint8 BST_POWER_LANE_0 = 0x00;
+	static const uint8 BST_POWER_LANE_1 = 0x01;
+	static const uint8 BST_POWER_LANE_2 = 0x02;
+	static const uint8 BST_POWER_LANE_3 = 0x03;
+
+	static const uint8 SST_POWER        = 0x00;
+
+	static const uint8 RCU_SETTINGS     = 0x00;
+	static const uint8 RCU_PROTOCOLX    = 0x01;
+	static const uint8 RCU_RESULTX      = 0x02;
+	static const uint8 RCU_PROTOCOLY    = 0x03;
+	static const uint8 RCU_RESULTY      = 0x04;
+
+	static const uint8 CR_SOFTCLEAR     = 0x00;
+	static const uint8 CR_SOFTSYNC      = 0x01;
+	static const uint8 CR_SYNCDISABLE   = 0x02;
+
+	// Cross correlation registers.
+	static const uint8 XST_STATS    = 0x00;
+	static const uint8 XST_NR_STATS = 32;
+
+	// The CDO register will be extended to 
+	// allow setting the UDP/IP header and some
+	// settings to set interleaving of beamlets.
+	static const uint8 CDO_SETTINGS = 0x00;
+	static const uint8 CDO_HEADER   = 0x01;
+
+	static const uint8 BS_NOF_SAMPLES_PER_SYNC = 0x00;
+
+	static const uint8 TDS_PROTOCOL            = 0x00;
+	static const uint8 TDS_RESULT              = 0x01;
+
+	// Placeholder register for future TBB control via the RSP board.
+	static const uint8 TBB_SETTINGSX = 0x00;
+	static const uint8 TBB_SETTINGSY = 0x01;
+	static const uint8 TBB_BANDSELX  = 0x02;
+	static const uint8 TBB_BANDSELY  = 0x03;
+
+	// RAD_BP register controls how local and remove crosslet and
+	// beamlet data from the SERDES lanes is combined on an RSP 
+	// board. This can be used to define logical start and end-points
+	// for the cross-correlation and beamforming data travelling on the
+	// SERDES rings.
+	static const uint8 RAD_BP           = 0x00;
+
+	static const int MIN_REGID          = 0x00;
+	static const int MAX_REGID          = XST_NR_STATS - 1;
+	/*@}*/
+
+	/*@{*/
+	// Define the number of beamlets N_BEAMLETS
+	// supported by the EPA firmware. For FTS-1
+	// the number of beamlets supported is 128.
+	// For the final LOFAR remote station
+	// 256 beamlets will be supported.
+	//
+	// Many register sizes are derived from
+	// the number of beamlets.
+	//
+	// The N_SUBBANDS(512) defines the number of
+	// subbands produced by the EPA digital filter.
+	// The N_BEAMLETS are a selection from this
+	// number of beamlets.
+	static const uint16 N_POL            = 2;                    // number of polarizations
+	static const uint16 N_PHASE          = 2;                    // number of phases in a complex number
+	static const uint16 N_PHASEPOL       = N_PHASE * N_POL;      // number of phase polarizations
+	static const uint16 MAX_N_RCUS       = 128 * MEPHeader::N_POL;
+	static const uint16 N_BLPS           = 4;                    // number of BLP's per RSP board
+	static const uint16 N_SUBBANDS       = 512;
+	static const uint16 N_REMOTE_XLETS   = 54; 
+	static const uint16 N_SERDES_LANES   = 4;
+	static const uint16 N_TOTAL_XLETS    = N_SERDES_LANES * N_REMOTE_XLETS;
+	static const uint16 N_LOCAL_XLETS    = 4;
+	static const uint16 N_BEAMLETS       = 216;
+	static const uint16 N_LOCAL_BEAMLETS = 54; // N_BEAMLETS / N_SERDES_LANES
+	static const uint16 XLET_SIZE        = N_POL * sizeof(std::complex<uint32>);
+	static const uint16 WEIGHT_SIZE      = N_POL * sizeof(std::complex<uint16>);
+
+	static const uint16 N_HBA_DELAYS     = 16; // number of High Band antenna delay elements
+
+	// TBB related constants
+	static const uint16 TBB_MAXPAYLOADSIZE     = 1948; // available TBB payload bytes
+	static const uint16 TBB_NTRANSIENTSAMPLES  = 1024; // number of 12-bit transient samples per frame
+	static const uint16 TBB_SPECTRALSAMPLESIZE = sizeof(std::complex<uint16>);
+	/*@}*/
+
+
+	/*@{*/
+	// Define size of each register.
+	static const uint16 RSR_STATUS_SIZE       = 200;
+	static const uint16 RSR_VERSION_SIZE      = 2;
+	static const uint16 RSR_TIMESTAMP_SIZE    = 4;
+
+	static const uint16 RSU_FLASHRW_SIZE      = 1024;
+	static const uint16 RSU_FLASHERASE_SIZE   = 1;
+	static const uint16 RSU_RECONFIGURE_SIZE  = 1;
+	static const uint16 RSU_RESET_SIZE        = 1;
+
+	static const uint16 DIAG_WGX_SIZE         = 12;
+	static const uint16 DIAG_WGY_SIZE         = 12;
+	static const uint16 DIAG_WGXWAVE_SIZE     = 8192;
+	static const uint16 DIAG_WGYWAVE_SIZE     = 8192;
+	static const uint16 DIAG_BYPASS_SIZE      = 2;
+	static const uint16 DIAG_RESULTS_SIZE     = 4096; // also 8192 ?
+	static const uint16 DIAG_SELFTEST_SIZE    = 4;
+
+	static const uint16 SS_SELECT_SIZE        = (N_LOCAL_XLETS + N_BEAMLETS) * N_POL * sizeof(uint16); // = 960?
+
+	static const uint16 BF_XROUT_SIZE         = (N_LOCAL_XLETS + N_BEAMLETS) * WEIGHT_SIZE;
+	static const uint16 BF_XIOUT_SIZE         = (N_LOCAL_XLETS + N_BEAMLETS) * WEIGHT_SIZE;
+	static const uint16 BF_YROUT_SIZE         = (N_LOCAL_XLETS + N_BEAMLETS) * WEIGHT_SIZE;
+	static const uint16 BF_YIOUT_SIZE         = (N_LOCAL_XLETS + N_BEAMLETS) * WEIGHT_SIZE;
+
+	static const uint16 BST_POWER_SIZE        = N_LOCAL_BEAMLETS * N_POL * sizeof(uint32);
+
+	static const uint16 SST_POWER_SIZE        = N_SUBBANDS * N_POL * sizeof(uint32);
+
+	static const uint16 RCU_SETTINGS_SIZE     = 2;
+	static const uint16 RCU_PROTOCOL_SIZE     = 512;
+	static const uint16 RCU_RESULT_SIZE       = 512;
+
+	static const uint16 CR_CONTROL_SIZE       = 1;
+
+	// (N_LOCAL_XLETS + N_REMOTE_XLETS) * XLET_SIZE; // 928 (!= 3424?)
+	static const uint16 XST_STATS_SIZE        = N_REMOTE_XLETS * XLET_SIZE; // 864
+
+	// The CDO register will be extended to 
+	// allow setting the UDP/IP header and some
+	// settings to set interleaving of beamlets.
+	static const uint16 CDO_SETTINGS_SIZE     = 30;
+	static const uint16 CDO_HEADER_SIZE       = 32;
+
+	static const uint16 BS_NOF_SAMPLES_PER_SYNC_SIZE = 4;
+
+	static const uint16 TDS_PROTOCOL_SIZE     = 4096;
+	static const uint16 TDS_RESULT_SIZE       = 1024;
+
+	// Placeholder register for future TBB control via the RSP board.
+	static const uint16 TBB_SETTINGS_SIZE = 8;
+	static const uint16 TBB_BANDSEL_SIZE  = 64;
+
+	// Size of the RAD_BP register.
+	static const uint16 RAD_BP_SIZE = 4; // four bytes = 32 bits, 8 bits per lane
+
+	// Registers too large to send in a single ethernet frame
+	// (> 1500 bytes) will be sent in a number of fragments of this size.
+	static const uint16 FRAGMENT_SIZE        = 1024;
+	static const uint16 N_AP                 = 4;
+	static const uint16 BF_N_FRAGMENTS       = 2;
+	static const uint16 N_WAVE_SAMPLES       = DIAG_WGXWAVE_SIZE / sizeof(int32);
+	static const uint16 SST_N_FRAGMENTS      = SST_POWER_SIZE / FRAGMENT_SIZE;
+	static const uint16 N_SST_STATS          = FRAGMENT_SIZE / sizeof(uint32);
+	static const uint16 N_DIAG_WG_REGISTERS  = 2;
+	static const uint16 N_CDO_REGISTERS      = 2;
+	static const uint16 N_RCUPROTOCOL_WRITES = 2;
+	static const uint16 N_HBAPROTOCOL_WRITES = 2;
+	/*@}*/
+
+	/*@{*/
+	// marshalling methods
+	unsigned int getSize();
+	unsigned int pack  (void* buffer);
+	unsigned int unpack(void *buffer);
+	/*@}*/
+
+	// MEP 4.x header fields
+	typedef struct {
+		uint8  type;           /* Message type */
+		uint8  status;         /* Error indicator */
+		uint16 frame_length;   /* Frame length */
+		typedef struct {
+			uint16 dstid;        /* Beamlet processor and RSP ID */
+			uint8  pid;          /* Process ID */
+			uint8  regid;        /* Register ID */
+		} AddrType;
+		AddrType addr;         /* addr */
+		uint16 offset;         /* Offset address */
+		uint16 payload_length; /* Payload length (size) */
+		uint16 seqnr;          /* Sequence number */
+		uint16 _reserved;      /* Do not use; future use */
+	} FieldsType;
+
+	FieldsType m_fields;
+
+	/*@{*/
+	// Methods to set header fields.
+	void set(uint8  type,
+			 uint16 dstid,
+			 uint8  pid,
+			 uint8  regid,
+			 uint16 payload_length,
+			 uint16 offset = 0);
+
+	void set(MEPHeader::FieldsType hdrtemplate,
+			 uint16 dstid          = DST_RSP,
+			 uint8  type           = MEPHeader::TYPE_UNSET,
+			 uint16 payload_length = 0,
+			 uint16 offset         = 0);
+	/*@}*/
+
+	// Method to check if this MEPHeader is a valid
+	// acknowledgement for a specific request.
+	bool isValidAck(const MEPHeader& reqhdr);
+
+	/*@{*/
+	// The following static constants are templates
+	// to produce EPA message headers. This is done by 
+	// copying the template and then make modifications
+	// to the appropriate parts of the header.
+	static const FieldsType RSR_STATUS_HDR;
+	static const FieldsType RSR_VERSION_HDR;
+	static const FieldsType RSR_TIMESTAMP_HDR;
+
+	static const FieldsType RSU_FLASHRW_HDR;
+	static const FieldsType RSU_FLASHERASE_HDR;
+	static const FieldsType RSU_RECONFIGURE_HDR;
+	static const FieldsType RSU_RESET_HDR;
+
+	static const FieldsType DIAG_WGX_HDR;
+	static const FieldsType DIAG_WGY_HDR;
+	static const FieldsType DIAG_WGXWAVE_HDR;
+	static const FieldsType DIAG_WGYWAVE_HDR;
+	static const FieldsType DIAG_BYPASS_HDR;
+	static const FieldsType DIAG_RESULTS_HDR;
+	static const FieldsType DIAG_SELFTEST_HDR;
+
+	static const FieldsType SS_SELECT_HDR;
+
+	static const FieldsType BF_XROUT_HDR;
+	static const FieldsType BF_XIOUT_HDR;
+	static const FieldsType BF_YROUT_HDR;
+	static const FieldsType BF_YIOUT_HDR;
+
+	static const FieldsType BST_POWER_HDR;
+
+	static const FieldsType SST_POWER_HDR;
+
+	static const FieldsType RCU_SETTINGS_HDR;
+	static const FieldsType RCU_PROTOCOLX_HDR;
+	static const FieldsType RCU_RESULTX_HDR;
+	static const FieldsType RCU_PROTOCOLY_HDR;
+	static const FieldsType RCU_RESULTY_HDR;
+
+	static const FieldsType CR_CONTROL_HDR;
+
+	static const FieldsType XST_STATS_HDR;
+
+	static const FieldsType CDO_SETTINGS_HDR;
+	static const FieldsType CDO_HEADER_HDR;
+
+	static const FieldsType BS_NOF_SAMPLES_PER_SYNC_HDR;
+
+	static const FieldsType TDS_PROTOCOL_HDR;
+	static const FieldsType TDS_RESULT_HDR;
+
+	static const FieldsType TBB_SETTINGSX_HDR;
+	static const FieldsType TBB_SETTINGSY_HDR;
+	static const FieldsType TBB_BANDSELX_HDR;
+	static const FieldsType TBB_BANDSELY_HDR;
+
+	static const FieldsType RAD_BP_HDR;
+
+	static const FieldsType RSP_RAWDATA_WRITE;
+	static const FieldsType RSP_RAWDATA_READ;
+	/*@}*/
 };
 
+  }; // namespace EPA_PROTOCOL
+}; // namespace LOFAR
+
 #endif /* MEPHEADER_H_ */
diff --git a/MAC/APL/PIC/RSP_Protocol/src/AllRegisterState.cc b/MAC/APL/PIC/RSP_Protocol/src/AllRegisterState.cc
index 1953560721e..a259f1746a2 100644
--- a/MAC/APL/PIC/RSP_Protocol/src/AllRegisterState.cc
+++ b/MAC/APL/PIC/RSP_Protocol/src/AllRegisterState.cc
@@ -56,67 +56,73 @@ unsigned int AllRegisterState::getSize()
     + tdstatusread_state.getSize()
     + tbbsettings_state.getSize()
     + tbbbandsel_state.getSize()
-    + bypasssettings_state.getSize();
+    + bypasssettings_state.getSize()
+	+ rawdatawrite_state.getSize()
+	+ rawdataread_state.getSize();
 }
 
 unsigned int AllRegisterState::pack  (void* buffer)
 {
-  unsigned int offset = 0;
+	unsigned int offset = 0;
 
-  offset += sys_state.pack((char*)buffer + offset);
-  offset += bf_state.pack((char*)buffer + offset);
-  offset += ss_state.pack((char*)buffer + offset);
-  offset += rcusettings_state.pack((char*)buffer + offset);
-  offset += rcuprotocol_state.pack((char*)buffer + offset);
-  offset += hbaprotocol_state.pack((char*)buffer + offset);
-  offset += rsuclear_state.pack((char*)buffer + offset);
-  offset += diagwgsettings_state.pack((char*)buffer + offset);
-  offset += sst_state.pack((char*)buffer + offset);
-  offset += bst_state.pack((char*)buffer + offset);
-  offset += xst_state.pack((char*)buffer + offset);
-  offset += cdo_state.pack((char*)buffer + offset);
-  offset += bs_state.pack((char*)buffer + offset);
-  offset += tdclear_state.pack((char*)buffer + offset);
-  offset += tdwrite_state.pack((char*)buffer + offset);
-  offset += tdread_state.pack((char*)buffer + offset);
-  offset += rad_state.pack((char*)buffer + offset);
-  offset += ts_state.pack((char*)buffer + offset);
-  offset += tdstatuswrite_state.pack((char*)buffer + offset);
-  offset += tdstatusread_state.pack((char*)buffer + offset);
-  offset += tbbsettings_state.pack((char*)buffer + offset);
-  offset += tbbbandsel_state.pack((char*)buffer + offset);
-  offset += bypasssettings_state.pack((char*)buffer + offset);
+	offset += sys_state.pack((char*)buffer + offset);
+	offset += bf_state.pack((char*)buffer + offset);
+	offset += ss_state.pack((char*)buffer + offset);
+	offset += rcusettings_state.pack((char*)buffer + offset);
+	offset += rcuprotocol_state.pack((char*)buffer + offset);
+	offset += hbaprotocol_state.pack((char*)buffer + offset);
+	offset += rsuclear_state.pack((char*)buffer + offset);
+	offset += diagwgsettings_state.pack((char*)buffer + offset);
+	offset += sst_state.pack((char*)buffer + offset);
+	offset += bst_state.pack((char*)buffer + offset);
+	offset += xst_state.pack((char*)buffer + offset);
+	offset += cdo_state.pack((char*)buffer + offset);
+	offset += bs_state.pack((char*)buffer + offset);
+	offset += tdclear_state.pack((char*)buffer + offset);
+	offset += tdwrite_state.pack((char*)buffer + offset);
+	offset += tdread_state.pack((char*)buffer + offset);
+	offset += rad_state.pack((char*)buffer + offset);
+	offset += ts_state.pack((char*)buffer + offset);
+	offset += tdstatuswrite_state.pack((char*)buffer + offset);
+	offset += tdstatusread_state.pack((char*)buffer + offset);
+	offset += tbbsettings_state.pack((char*)buffer + offset);
+	offset += tbbbandsel_state.pack((char*)buffer + offset);
+	offset += bypasssettings_state.pack((char*)buffer + offset);
+	offset += rawdatawrite_state.pack((char*)buffer + offset);
+	offset += rawdataread_state.pack((char*)buffer + offset);
 
-  return offset;
+	return (offset);
 }
 
 unsigned int AllRegisterState::unpack(void *buffer)
 {
-  unsigned int offset = 0;
+	unsigned int offset = 0;
 
-  offset += sys_state.unpack((char*)buffer + offset);
-  offset += bf_state.unpack((char*)buffer + offset);
-  offset += ss_state.unpack((char*)buffer + offset);
-  offset += rcusettings_state.unpack((char*)buffer + offset);
-  offset += rcuprotocol_state.unpack((char*)buffer + offset);
-  offset += hbaprotocol_state.unpack((char*)buffer + offset);
-  offset += rsuclear_state.unpack((char*)buffer + offset);
-  offset += diagwgsettings_state.unpack((char*)buffer + offset);
-  offset += sst_state.unpack((char*)buffer + offset);
-  offset += bst_state.unpack((char*)buffer + offset);
-  offset += xst_state.unpack((char*)buffer + offset);
-  offset += cdo_state.unpack((char*)buffer + offset);
-  offset += bs_state.unpack((char*)buffer + offset);
-  offset += tdclear_state.unpack((char*)buffer + offset);
-  offset += tdwrite_state.unpack((char*)buffer + offset);
-  offset += tdread_state.unpack((char*)buffer + offset);
-  offset += rad_state.unpack((char*)buffer + offset);
-  offset += ts_state.unpack((char*)buffer + offset);
-  offset += tdstatuswrite_state.unpack((char*)buffer + offset);
-  offset += tdstatusread_state.unpack((char*)buffer + offset);
-  offset += tbbsettings_state.unpack((char*)buffer + offset);
-  offset += tbbbandsel_state.unpack((char*)buffer + offset);
-  offset += bypasssettings_state.unpack((char*)buffer + offset);
+	offset += sys_state.unpack((char*)buffer + offset);
+	offset += bf_state.unpack((char*)buffer + offset);
+	offset += ss_state.unpack((char*)buffer + offset);
+	offset += rcusettings_state.unpack((char*)buffer + offset);
+	offset += rcuprotocol_state.unpack((char*)buffer + offset);
+	offset += hbaprotocol_state.unpack((char*)buffer + offset);
+	offset += rsuclear_state.unpack((char*)buffer + offset);
+	offset += diagwgsettings_state.unpack((char*)buffer + offset);
+	offset += sst_state.unpack((char*)buffer + offset);
+	offset += bst_state.unpack((char*)buffer + offset);
+	offset += xst_state.unpack((char*)buffer + offset);
+	offset += cdo_state.unpack((char*)buffer + offset);
+	offset += bs_state.unpack((char*)buffer + offset);
+	offset += tdclear_state.unpack((char*)buffer + offset);
+	offset += tdwrite_state.unpack((char*)buffer + offset);
+	offset += tdread_state.unpack((char*)buffer + offset);
+	offset += rad_state.unpack((char*)buffer + offset);
+	offset += ts_state.unpack((char*)buffer + offset);
+	offset += tdstatuswrite_state.unpack((char*)buffer + offset);
+	offset += tdstatusread_state.unpack((char*)buffer + offset);
+	offset += tbbsettings_state.unpack((char*)buffer + offset);
+	offset += tbbbandsel_state.unpack((char*)buffer + offset);
+	offset += bypasssettings_state.unpack((char*)buffer + offset);
+	offset += rawdatawrite_state.unpack((char*)buffer + offset);
+	offset += rawdataread_state.unpack((char*)buffer + offset);
 
-  return offset;
+	return (offset);
 }
diff --git a/MAC/APL/PIC/RSP_Protocol/src/EPA_Protocol.prot b/MAC/APL/PIC/RSP_Protocol/src/EPA_Protocol.prot
index 91399441505..f15e652ce23 100644
--- a/MAC/APL/PIC/RSP_Protocol/src/EPA_Protocol.prot
+++ b/MAC/APL/PIC/RSP_Protocol/src/EPA_Protocol.prot
@@ -257,6 +257,8 @@ prelude = << PRELUDE_END
 		uint8	temperature;
 	};
 
+#define	RSP_RAW_DATABLOCK_SIZE		1480
+
 PRELUDE_END;
 
 //
diff --git a/MAC/APL/PIC/RSP_Protocol/src/MEPData.cc b/MAC/APL/PIC/RSP_Protocol/src/MEPData.cc
index e6497c08c90..2bf7cb2bb17 100644
--- a/MAC/APL/PIC/RSP_Protocol/src/MEPData.cc
+++ b/MAC/APL/PIC/RSP_Protocol/src/MEPData.cc
@@ -62,3 +62,8 @@ void* MEPData::getBuffer() const
   return m_dataptr;
 }
 
+size_t MEPData::getDataLen() const
+{
+  return m_count;
+}
+
diff --git a/MAC/APL/PIC/RSP_Protocol/src/MEPHeader.cc b/MAC/APL/PIC/RSP_Protocol/src/MEPHeader.cc
index 151a0fc5f51..1f8847ca44b 100644
--- a/MAC/APL/PIC/RSP_Protocol/src/MEPHeader.cc
+++ b/MAC/APL/PIC/RSP_Protocol/src/MEPHeader.cc
@@ -87,6 +87,9 @@ const MEPHeader::FieldsType MEPHeader::TBB_BANDSELY_HDR      = { WRITE, 0, 0, {
 
 const MEPHeader::FieldsType MEPHeader::RAD_BP_HDR            = { WRITE, 0, 0, { DST_RSP, RAD, RAD_BP }, 0, RAD_BP_SIZE, 0, 0 };
 
+const MEPHeader::FieldsType MEPHeader::RSP_RAWDATA_WRITE     = { WRITE, 0, 0, { 0xABBA, 0xBB, 0xAA }, 0xEFFE, 0xEBBE, 0x3412, 0 };
+const MEPHeader::FieldsType MEPHeader::RSP_RAWDATA_READ      = { READ , 0, 0, { 0xABBA, 0xBB, 0xAA }, 0xEFFE, 0xEBBE, 0x3412, 0 };
+
 unsigned int MEPHeader::getSize()
 {
   return MEPHeader::SIZE;
diff --git a/MAC/APL/PIC/RSP_Protocol/src/RSP_Protocol.prot b/MAC/APL/PIC/RSP_Protocol/src/RSP_Protocol.prot
index bc473e96b95..f3cc98882d1 100644
--- a/MAC/APL/PIC/RSP_Protocol/src/RSP_Protocol.prot
+++ b/MAC/APL/PIC/RSP_Protocol/src/RSP_Protocol.prot
@@ -36,9 +36,10 @@ prelude = << PRELUDE_END
 
 typedef	void*	memptr_t;
 
-static const int MAX_N_RSPBOARDS = 24;
-static const int SUCCESS         = 1;
-static const int FAILURE         = 0;
+static const int MAX_N_RSPBOARDS 	= 24;
+static const int SUCCESS         	= 1;
+static const int FAILURE         	= 0;
+static const int RSP_RAW_BLOCK_SIZE = 1480;
 
 // The protocol implements the following messages.
 // SETWEIGHTS			(timestamp,	rcumask,weights)
@@ -155,6 +156,11 @@ static const int FAILURE         = 0;
 // GETSPUSTATUS			(timestamp,	cache)
 // GETSPUSTATUSACK		(timestamp,	status,	spustatus)
 
+// SETBLOCK				(timestamp, boardID, address, offset, datalen, data)
+// SETBLOCKACK			(timestamp, boardID, status);
+// GETBLOCK				(timestamp, boardID, address, offset, datalen)
+// GETBLOCKACK			(timestamp, boardID, status, datalen, data);
+
 PRELUDE_END;
 
 //
@@ -1854,3 +1860,106 @@ event = {
 	};
 };
 
+// SETBLOCK (timestamp, boardID, procID, pid, regid, offset, datalen, data)
+event = {
+	signal = SETBLOCK;
+	dir = IN;
+	param = { 
+		name = "timestamp";
+		type = "RTC::Timestamp";
+		userdefined;
+	};
+	param = {
+		name = "boardID";
+		type = "uint16";
+	};
+	param = {
+		name = "address";
+		type = "uint32";
+	};
+	param = {
+		name = "offset";
+		type = "uint16";
+	};
+	param = {
+		name = "dataLen";
+		type = "uint16";
+	};
+	param = {
+		name = "data";
+		type = "uint8[RSP_RAW_BLOCK_SIZE]";
+	};
+};
+ 	
+// SETBLOCKACK (timestamp, boardID, status);
+event = {
+	signal = SETBLOCKACK;
+	dir = IN;
+	param = { 
+		name = "timestamp";
+		type = "RTC::Timestamp";
+		userdefined;
+	};
+	param = {
+		name = "boardID";
+		type = "uint16";
+	};
+	param = {
+		name = "status";
+		type = "uint16";
+	};
+};
+
+// GETBLOCK (timestamp, boardID, procID, pid, regid, offset, datalen)
+event = {
+	signal = GETBLOCK;
+	dir = IN;
+	param = { 
+		name = "timestamp";
+		type = "RTC::Timestamp";
+		userdefined;
+	};
+	param = {
+		name = "boardID";
+		type = "uint16";
+	};
+	param = {
+		name = "address";
+		type = "uint32";
+	};
+	param = {
+		name = "offset";
+		type = "uint16";
+	};
+	param = {
+		name = "dataLen";
+		type = "uint16";
+	};
+};
+ 	
+// GETBLOCKACK (timestamp, boardID, status, datalen, data);
+event = {
+	signal = GETBLOCKACK;
+	dir = IN;
+	param = { 
+		name = "timestamp";
+		type = "RTC::Timestamp";
+		userdefined;
+	};
+	param = {
+		name = "boardID";
+		type = "uint16";
+	};
+	param = {
+		name = "status";
+		type = "uint16";
+	};
+	param = {
+		name = "dataLen";
+		type = "uint16";
+	};
+	param = {
+		name = "data";
+		type = "uint8[RSP_RAW_BLOCK_SIZE]";
+	};
+};
-- 
GitLab