From 59acf13841c0ae85362e0b9dfc97b3475acf1ced Mon Sep 17 00:00:00 2001
From: wierenga <sdos@astron.nl>
Date: Wed, 14 Jun 2006 07:52:09 +0000
Subject: [PATCH] BugID: 337 First stab at HBA control implementation.

---
 MAC/APL/PIC/RSPDriver/src/Cache.cc            |  11 +-
 MAC/APL/PIC/RSPDriver/src/Cache.h             |   2 +
 MAC/APL/PIC/RSPDriver/src/GetHBACmd.cc        | 113 +++++++
 MAC/APL/PIC/RSPDriver/src/GetHBACmd.h         |  92 ++++++
 MAC/APL/PIC/RSPDriver/src/HBAProtocolWrite.cc | 286 ++++++++++++++++++
 MAC/APL/PIC/RSPDriver/src/HBAProtocolWrite.h  |  80 +++++
 MAC/APL/PIC/RSPDriver/src/HBAResultRead.cc    | 114 +++++++
 MAC/APL/PIC/RSPDriver/src/HBAResultRead.h     |  67 ++++
 MAC/APL/PIC/RSPDriver/src/RSPDriver.cc        | 162 +++++++++-
 MAC/APL/PIC/RSPDriver/src/RSPDriver.h         |   5 +
 MAC/APL/PIC/RSPDriver/src/SetHBACmd.cc        |  99 ++++++
 MAC/APL/PIC/RSPDriver/src/SetHBACmd.h         |  87 ++++++
 MAC/APL/PIC/RSPDriver/src/UpdHBACmd.cc        | 139 +++++++++
 MAC/APL/PIC/RSPDriver/src/UpdHBACmd.h         |  87 ++++++
 .../APL/RSP_Protocol/AllRegisterState.h       |   9 +-
 .../include/APL/RSP_Protocol/HBASettings.h    |  68 +++++
 .../include/APL/RSP_Protocol/MEPHeader.h      |   2 +
 .../include/APL/RSP_Protocol/Makefile.am      |   1 +
 .../include/APL/RSP_Protocol/RCUSettings.h    |  23 +-
 .../PIC/RSP_Protocol/src/AllRegisterState.cc  |   3 +
 .../PIC/RSP_Protocol/src/EPA_Protocol.prot    |   4 +-
 MAC/APL/PIC/RSP_Protocol/src/HBASettings.cc   |  55 ++++
 MAC/APL/PIC/RSP_Protocol/src/Makefile.am      |   1 +
 .../PIC/RSP_Protocol/src/RSP_Protocol.prot    | 161 ++++++++++
 24 files changed, 1656 insertions(+), 15 deletions(-)
 create mode 100644 MAC/APL/PIC/RSPDriver/src/GetHBACmd.cc
 create mode 100644 MAC/APL/PIC/RSPDriver/src/GetHBACmd.h
 create mode 100644 MAC/APL/PIC/RSPDriver/src/HBAProtocolWrite.cc
 create mode 100644 MAC/APL/PIC/RSPDriver/src/HBAProtocolWrite.h
 create mode 100644 MAC/APL/PIC/RSPDriver/src/HBAResultRead.cc
 create mode 100644 MAC/APL/PIC/RSPDriver/src/HBAResultRead.h
 create mode 100644 MAC/APL/PIC/RSPDriver/src/SetHBACmd.cc
 create mode 100644 MAC/APL/PIC/RSPDriver/src/SetHBACmd.h
 create mode 100644 MAC/APL/PIC/RSPDriver/src/UpdHBACmd.cc
 create mode 100644 MAC/APL/PIC/RSPDriver/src/UpdHBACmd.h
 create mode 100644 MAC/APL/PIC/RSP_Protocol/include/APL/RSP_Protocol/HBASettings.h
 create mode 100644 MAC/APL/PIC/RSP_Protocol/src/HBASettings.cc

diff --git a/MAC/APL/PIC/RSPDriver/src/Cache.cc b/MAC/APL/PIC/RSPDriver/src/Cache.cc
index 3dee349ee47..feed7b85d25 100644
--- a/MAC/APL/PIC/RSPDriver/src/Cache.cc
+++ b/MAC/APL/PIC/RSPDriver/src/Cache.cc
@@ -86,11 +86,15 @@ CacheBuffer::CacheBuffer(Cache* cache) : m_cache(cache)
     LOG_WARN_STR("m_subbandselection()=" << m_subbandselection());
   }
 
+  // initialize RCU settings
   m_rcusettings().resize(StationSettings::instance()->nrRcus());
   RCUSettings::Control rcumode;
   rcumode.setMode(RCUSettings::Control::MODE_OFF);
   m_rcusettings() = rcumode;
-  // allocate modified flags for all receivers
+
+  // initialize HBA settings
+  m_hbasettings().resize(StationSettings::instance()->nrRcus(), MEPHeader::N_HBA_DELAYS);
+  m_hbasettings() = 0; // initialize to 0
 
   // RSU settings
   m_rsusettings().resize(StationSettings::instance()->nrRspBoards());
@@ -189,6 +193,11 @@ RCUSettings& CacheBuffer::getRCUSettings()
   return m_rcusettings;
 }
 
+HBASettings& CacheBuffer::getHBASettings()
+{
+  return m_hbasettings;
+}
+
 RSUSettings& CacheBuffer::getRSUSettings()
 {
   return m_rsusettings;
diff --git a/MAC/APL/PIC/RSPDriver/src/Cache.h b/MAC/APL/PIC/RSPDriver/src/Cache.h
index 6af88ec9e89..adbe5bbeca1 100644
--- a/MAC/APL/PIC/RSPDriver/src/Cache.h
+++ b/MAC/APL/PIC/RSPDriver/src/Cache.h
@@ -53,6 +53,7 @@ namespace LOFAR {
       RSP_Protocol::BeamletWeights&    getBeamletWeights();
       RSP_Protocol::SubbandSelection&  getSubbandSelection();
       RSP_Protocol::RCUSettings&       getRCUSettings();
+      RSP_Protocol::HBASettings&       getHBASettings();
       RSP_Protocol::RSUSettings&       getRSUSettings();
       RSP_Protocol::WGSettings&        getWGSettings();
       RSP_Protocol::SystemStatus&      getSystemStatus();
@@ -82,6 +83,7 @@ namespace LOFAR {
       RSP_Protocol::BeamletWeights   m_beamletweights;
       RSP_Protocol::SubbandSelection m_subbandselection;
       RSP_Protocol::RCUSettings      m_rcusettings;
+      RSP_Protocol::HBASettings      m_hbasettings;
       RSP_Protocol::RSUSettings      m_rsusettings;
       RSP_Protocol::WGSettings       m_wgsettings;
       RSP_Protocol::Statistics       m_subbandstats;
diff --git a/MAC/APL/PIC/RSPDriver/src/GetHBACmd.cc b/MAC/APL/PIC/RSPDriver/src/GetHBACmd.cc
new file mode 100644
index 00000000000..9e06b0a1392
--- /dev/null
+++ b/MAC/APL/PIC/RSPDriver/src/GetHBACmd.cc
@@ -0,0 +1,113 @@
+//#  GetHBACmd.cc: implementation of the GetHBACmd 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 <APL/RSP_Protocol/RSP_Protocol.ph>
+#include <APL/RTCCommon/PSAccess.h>
+
+#include <blitz/array.h>
+
+#include "StationSettings.h"
+#include "GetHBACmd.h"
+
+using namespace blitz;
+using namespace LOFAR;
+using namespace RSP;
+using namespace RSP_Protocol;
+using namespace RTC;
+
+GetHBACmd::GetHBACmd(GCFEvent& event, GCFPortInterface& port, Operation oper)
+{
+  m_event = new RSPGethbaEvent(event);
+
+  setOperation(oper);
+  setPeriod(0);
+  setPort(port);
+}
+
+GetHBACmd::~GetHBACmd()
+{
+  delete m_event;
+}
+
+void GetHBACmd::ack(CacheBuffer& cache)
+{
+  RSPGethbaackEvent ack;
+
+  ack.timestamp = getTimestamp();
+  ack.status = SUCCESS;
+
+  ack.settings().resize(m_event->rcumask.count());
+  
+  int result_rcu = 0;
+  for (int cache_rcu = 0; cache_rcu < StationSettings::instance()->nrRcus(); cache_rcu++)
+  {
+    if (m_event->rcumask[cache_rcu])
+    {
+      if (cache_rcu < StationSettings::instance()->nrRcus())
+      {
+	ack.settings()(result_rcu) = cache.getHBASettings()()(cache_rcu);
+      }
+      else
+      {
+	LOG_WARN(formatString("invalid RCU index %d, there are only %d RCU's", cache_rcu, 
+		StationSettings::instance()->nrRcus()));
+      }
+      
+      result_rcu++;
+    }
+  }
+  
+  getPort()->send(ack);
+}
+
+void GetHBACmd::apply(CacheBuffer& /*cache*/, bool /*setModFlag*/)
+{
+  /* intentionally left empty */
+}
+
+void GetHBACmd::complete(CacheBuffer& cache)
+{
+  ack(cache);
+}
+
+const RTC::Timestamp& GetHBACmd::getTimestamp() const
+{
+  return m_event->timestamp;
+}
+
+void GetHBACmd::setTimestamp(const RTC::Timestamp& timestamp)
+{
+  m_event->timestamp = timestamp;
+}
+
+bool GetHBACmd::validate() const
+{
+  return ((m_event->rcumask.count() <= (unsigned int)StationSettings::instance()->nrRcus()));
+}
+
+bool GetHBACmd::readFromCache() const
+{
+  return m_event->cache;
+}
diff --git a/MAC/APL/PIC/RSPDriver/src/GetHBACmd.h b/MAC/APL/PIC/RSPDriver/src/GetHBACmd.h
new file mode 100644
index 00000000000..416965e545c
--- /dev/null
+++ b/MAC/APL/PIC/RSPDriver/src/GetHBACmd.h
@@ -0,0 +1,92 @@
+//#  -*- mode: c++ -*-
+//#
+//#  GetHBACmd.h: Beamformer Weights settings command.
+//#
+//#  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 GETHBACMD_H_
+#define GETHBACMD_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 GetHBACmd : public Command
+    {
+    public:
+      /**
+       * Constructors for a GetHBACmd object.
+       */
+      GetHBACmd(GCFEvent& event, GCFPortInterface& port, Operation oper);
+	  
+      /* Destructor for GetHBACmd. */
+      virtual ~GetHBACmd();
+
+      /**
+       * 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);
+      /*@}*/
+
+      /**
+       * Validate the event that underlies the command.
+       */
+      virtual bool validate() const;
+
+      /**
+       * Return true if value should be read from cache.
+       */
+      bool readFromCache() const;
+
+    private:
+      GetHBACmd();
+
+      RSPGethbaEvent* m_event;
+    };
+  };
+};
+     
+#endif /* GETHBACMD_H_ */
diff --git a/MAC/APL/PIC/RSPDriver/src/HBAProtocolWrite.cc b/MAC/APL/PIC/RSPDriver/src/HBAProtocolWrite.cc
new file mode 100644
index 00000000000..e0564142beb
--- /dev/null
+++ b/MAC/APL/PIC/RSPDriver/src/HBAProtocolWrite.cc
@@ -0,0 +1,286 @@
+//#  HBAProtocolWrite.cc: implementation of the HBAProtocolWrite 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 <APL/RSP_Protocol/EPA_Protocol.ph>
+
+#include <APL/RTCCommon/PSAccess.h>
+#include <string.h>
+
+#include "StationSettings.h"
+#include "HBAProtocolWrite.h"
+#include "Cache.h"
+
+#include <netinet/in.h>
+
+using namespace LOFAR;
+using namespace RSP;
+using namespace EPA_Protocol;
+using namespace blitz;
+
+namespace LOFAR {
+  namespace RSP {
+
+    //
+    // The byte sequences originate from the LOFAR-ASTRON-MEM-175 Document
+    // "HBA Control Design Description"
+    //
+
+    uint8 HBAProtocolWrite::i2c_protocol[HBAProtocolWrite::PROTOCOL_SIZE] 
+    = {
+      // Instruct client to do a broadcast access to the 16 HBA delay servers (43 bytes)
+      13,   // PROTOCOL_C_WRITE_BLOCK_NO_CNT
+       2,   // I2C address for RCU
+       0,   // Request register access command
+      39,   // Count of number of data bytes to write
+       0,   // Cast type is broadcast
+      32,   // Length of the request data for one server
+       0,   // Expected length of the response from one server
+       1,   // First server address participating in the cast
+      16,   // Laster server address participating in the cast
+       4,   // Function set word
+       0,   // Server X-delay register ID
+      0xFF, // X-delay data for server 1 (offset = PROTOCOL_DELAY_OFFSET)
+      0xFF, // Y-delay data for server 1
+      0xFF, // X-delay data for server 2
+      0xFF, // Y-delay data for server 2
+      0xFF, // X-delay data for server 3
+      0xFF, // Y-delay data for server 3
+      0xFF, // X-delay data for server 4
+      0xFF, // Y-delay data for server 4
+      0xFF, // X-delay data for server 5
+      0xFF, // Y-delay data for server 5
+      0xFF, // X-delay data for server 6
+      0xFF, // Y-delay data for server 6
+      0xFF, // X-delay data for server 7
+      0xFF, // Y-delay data for server 7
+      0xFF, // X-delay data for server 8
+      0xFF, // Y-delay data for server 8
+      0xFF, // X-delay data for server 9
+      0xFF, // Y-delay data for server 9
+      0xFF, // X-delay data for server 10
+      0xFF, // Y-delay data for server 10
+      0xFF, // X-delay data for server 11
+      0xFF, // Y-delay data for server 11
+      0xFF, // X-delay data for server 12
+      0xFF, // Y-delay data for server 12
+      0xFF, // X-delay data for server 13
+      0xFF, // Y-delay data for server 13
+      0xFF, // X-delay data for server 14
+      0xFF, // Y-delay data for server 14
+      0xFF, // X-delay data for server 15
+      0xFF, // Y-delay data for server 15
+      0xFF, // X-delay data for server 16
+      0xFF, // Y-delay data for server 16
+      
+      // Wait to allow for the broadcast to finish (5 bytes)
+      18, // PROTOCOL_C_WAIT
+      0, 0, 0, 0, // Timeout value least significant - most significant
+
+      // Instruct the client to do a read back multicast access to the 16 HBA delay servers (11 bytes)
+      13, // PROTOCOL_C_WRITE_BLOCK_NO_CNT
+       2, // Client i2c slave address
+       0, // Request register access command
+       7, // Count of number of data bytes to write
+       1, // Cast type is multicast
+       0, // Length of the request data for one server
+       2, // Expected length of the response from one server
+       1, // First server address participating in the cast
+      16, // Last server address participating in the cast
+       5, // Function get word
+       0, // Server X-delay register ID
+
+      // Wait to allow for the multicast to finish
+      18, // PROTOCOL_C_WAIT (5 bytes)
+      0, 0, 0, 0, // Timeout value least significant - most significant
+
+      // Read back the response results from the client (4 bytes)
+      14, // PROTOCOL_C_READ_BLOCK_NO_CNT
+       2, // Client i2c slave address
+       1, // Response register access command
+      33, // Count of number of data bytes to read
+
+      // Mark the end of the protocol list (1 byte)
+      19, // PROTOCOL_C_END
+    };
+
+    uint8 HBAProtocolWrite::i2c_result[HBAProtocolWrite::RESULT_SIZE] 
+    = {
+      // Expected protocol result (39 bytes)
+      0,    // Table 15 PROTOCOL_C_WRITE_BLOCK_NO_CNT went OK
+      0,    // Table 16 PROCOCOL_C_WAIT went OK
+      0,    // Table 17 PROTOCOL_C_WRITE_BLOCK_NO_CNT went OK
+      0,    // Table 18 PROTOCOL_C_WAIT went OK
+      0,    // Expected response status
+      0xFF, // X-delay data from server 1 (offset = RESULT_DELAY_OFFSET)
+      0xFF, // Y-delay data from server 1
+      0xFF, // X-delay data from server 2
+      0xFF, // Y-delay data from server 2
+      0xFF, // X-delay data from server 3
+      0xFF, // Y-delay data from server 3
+      0xFF, // X-delay data from server 4
+      0xFF, // Y-delay data from server 4
+      0xFF, // X-delay data from server 5
+      0xFF, // Y-delay data from server 5
+      0xFF, // X-delay data from server 6
+      0xFF, // Y-delay data from server 6
+      0xFF, // X-delay data from server 7
+      0xFF, // Y-delay data from server 7
+      0xFF, // X-delay data from server 8
+      0xFF, // Y-delay data from server 8
+      0xFF, // X-delay data from server 9
+      0xFF, // Y-delay data from server 9
+      0xFF, // X-delay data from server 10
+      0xFF, // Y-delay data from server 10
+      0xFF, // X-delay data from server 11
+      0xFF, // Y-delay data from server 11
+      0xFF, // X-delay data from server 12
+      0xFF, // Y-delay data from server 12
+      0xFF, // X-delay data from server 13
+      0xFF, // Y-delay data from server 13
+      0xFF, // X-delay data from server 14
+      0xFF, // Y-delay data from server 14
+      0xFF, // X-delay data from server 15
+      0xFF, // Y-delay data from server 15
+      0xFF, // X-delay data from server 16
+      0xFF, // Y-delay data from server 16
+      0,    // Table 19 PROTOCOL_C_READ_BLOCK_NO_CNT went OK
+      0,    // Table 20 PROTOCOL_C_END went OK
+    };
+  };
+};
+
+#define N_WRITES 2 // 2 writes, one for protocol register, one to clear results register
+
+HBAProtocolWrite::HBAProtocolWrite(GCFPortInterface& board_port, int board_id)
+  : SyncAction(board_port, board_id, StationSettings::instance()->nrBlpsPerBoard() * N_WRITES)
+  // using nrBlpsPerBoard() because only the Y RCU's (odd numbered 1,3,5,...)
+  // control both the X and Y delays of HBA
+{
+  memset(&m_hdr, 0, sizeof(MEPHeader));
+}
+
+HBAProtocolWrite::~HBAProtocolWrite()
+{
+  /* TODO: delete event? */
+}
+
+void HBAProtocolWrite::sendrequest()
+{
+  uint8 global_blp = (getBoardId() * StationSettings::instance()->nrBlpsPerBoard()) + (getCurrentIndex() / N_WRITES);
+
+  // only update if rcuprotocol is not being updated and one of hbaprotocol needs updating
+  if (RTC::RegisterState::IDLE != Cache::getInstance().getState().rcuprotocol().get(global_blp * MEPHeader::N_POL)
+      || RTC::RegisterState::IDLE != Cache::getInstance().getState().rcuprotocol().get(global_blp * MEPHeader::N_POL + 1))
+  {
+    setContinue(true);
+    return;
+  }
+   
+  if (RTC::RegisterState::WRITE != Cache::getInstance().getState().hbaprotocol().get(global_blp * MEPHeader::N_POL)
+      && RTC::RegisterState::WRITE != Cache::getInstance().getState().hbaprotocol().get(global_blp * MEPHeader::N_POL + 1))
+  {
+    Cache::getInstance().getState().hbaprotocol().unmodified(global_blp * MEPHeader::N_POL);
+    Cache::getInstance().getState().hbaprotocol().unmodified(global_blp * MEPHeader::N_POL + 1);
+    setContinue(true);
+    return;
+  }
+
+  // delays for at least on HBA need to be written, and the RCUProtocol register is not in use by RCUProtocolWrite
+
+  switch (getCurrentIndex() % N_WRITES) {
+    
+  case 0:
+    {
+      // reverse and copy control bytes into i2c_protocol
+      Array<uint8, 2> delays(i2c_protocol + PROTOCOL_DELAY_OFFSET,
+			     shape(MEPHeader::N_HBA_DELAYS, 2),
+			     neverDeleteData);
+
+      delays(Range::all(), 0) = Cache::getInstance().getBack().getHBASettings()()(global_blp * MEPHeader::N_POL, Range::all());
+      delays(Range::all(), 1) = Cache::getInstance().getBack().getHBASettings()()(global_blp * MEPHeader::N_POL + 1, Range::all());
+
+      // create the event
+      EPARcuProtocolEvent rcuprotocol;
+      rcuprotocol.hdr.set(MEPHeader::RCU_PROTOCOLY_HDR, 1 << (getCurrentIndex() / N_WRITES), MEPHeader::WRITE, sizeof(i2c_protocol));
+      rcuprotocol.protocol.setBuffer(i2c_protocol, sizeof(i2c_protocol));
+  
+      m_hdr = rcuprotocol.hdr; // remember header to match with ack
+      getBoardPort().send(rcuprotocol);
+    }
+    break;
+
+  case 1:
+    {
+      EPAWriteEvent rcuresultwrite;
+
+      // set the result register to 0xFF's
+      rcuresultwrite.hdr.set(MEPHeader::WRITE, 1 << (getCurrentIndex() / N_WRITES),
+			     MEPHeader::RCU, MEPHeader::RCU_RESULTY, sizeof(i2c_result), 0);
+      uint8 clear[RESULT_SIZE];
+      memset(clear, 0xFF, RESULT_SIZE); // clear result
+      rcuresultwrite.payload.setBuffer(clear, RESULT_SIZE);
+
+      m_hdr = rcuresultwrite.hdr; // remember header to match with ack
+      getBoardPort().send(rcuresultwrite);
+    }
+    break;
+  }
+}
+
+void HBAProtocolWrite::sendrequest_status()
+{
+  // intentionally left empty
+}
+
+GCFEvent::TResult HBAProtocolWrite::handleack(GCFEvent& event, GCFPortInterface& /*port*/)
+{
+  if (EPA_WRITEACK != event.signal)
+  {
+    LOG_WARN("HBAProtocolWrite::handleack:: unexpected ack");
+    return GCFEvent::NOT_HANDLED;
+  }
+  
+  EPAWriteackEvent ack(event);
+
+  uint8 global_blp = (getBoardId() * StationSettings::instance()->nrBlpsPerBoard()) + (getCurrentIndex() / N_WRITES);
+
+  if (!ack.hdr.isValidAck(m_hdr))
+  {
+    LOG_ERROR("HBAProtocolWrite::handleack: invalid ack");
+    Cache::getInstance().getState().hbaprotocol().write_error(global_blp * MEPHeader::N_POL);
+    Cache::getInstance().getState().hbaprotocol().write_error(global_blp * MEPHeader::N_POL + 1);
+    return GCFEvent::NOT_HANDLED;
+  }
+
+  if (1 == (getCurrentIndex() % N_WRITES)) {
+
+    // Mark modification as applied when write of RCU result register has completed
+
+    Cache::getInstance().getState().hbaprotocol().read_schedule(global_blp * MEPHeader::N_POL);
+    Cache::getInstance().getState().hbaprotocol().read_schedule(global_blp * MEPHeader::N_POL + 1);
+
+  }
+  
+  return GCFEvent::HANDLED;
+}
diff --git a/MAC/APL/PIC/RSPDriver/src/HBAProtocolWrite.h b/MAC/APL/PIC/RSPDriver/src/HBAProtocolWrite.h
new file mode 100644
index 00000000000..cc78e4c6ad3
--- /dev/null
+++ b/MAC/APL/PIC/RSPDriver/src/HBAProtocolWrite.h
@@ -0,0 +1,80 @@
+//#  -*- mode: c++ -*-
+//#
+//#  HBAProtocolWrite.h: Synchronize rcu settings with RSP hardware.
+//#
+//#  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 HBAPROTOCOLWRITE_H_
+#define HBAPROTOCOLWRITE_H_
+
+#include <APL/RSP_Protocol/MEPHeader.h>
+
+#include "SyncAction.h"
+
+namespace LOFAR {
+  namespace RSP {
+
+    class HBAProtocolWrite : public SyncAction
+    {
+    public:
+      /**
+       * Constructors for a HBAProtocolWrite object.
+       */
+      HBAProtocolWrite(GCFPortInterface& board_port, int board_id);
+
+      /* Destructor for HBAProtocolWrite. */
+      virtual ~HBAProtocolWrite();
+
+      /**
+       * 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;
+
+      friend class HBAResultRead;
+
+      static const int PROTOCOL_SIZE         = 69;
+      static const int PROTOCOL_DELAY_OFFSET = 11; // offset of delay settings in i2c_protocol
+      static const int RESULT_SIZE           = 39;
+      static const int RESULT_DELAY_OFFSET   = 5;  // offset of delay settings in i2c_result
+
+      // construct i2c sequence
+      static uint8 i2c_protocol[PROTOCOL_SIZE];
+
+      // construct expected i2c result
+      static uint8 i2c_result[RESULT_SIZE];
+    };
+  };
+};
+     
+#endif /* HBAPROTOCOLWRITE_H_ */
diff --git a/MAC/APL/PIC/RSPDriver/src/HBAResultRead.cc b/MAC/APL/PIC/RSPDriver/src/HBAResultRead.cc
new file mode 100644
index 00000000000..75ec0c4c72e
--- /dev/null
+++ b/MAC/APL/PIC/RSPDriver/src/HBAResultRead.cc
@@ -0,0 +1,114 @@
+//#  HBAResultRead.cc: implementation of the HBAResultRead 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 <APL/RSP_Protocol/EPA_Protocol.ph>
+
+#include <APL/RTCCommon/PSAccess.h>
+#include <string.h>
+
+#include "StationSettings.h"
+#include "HBAProtocolWrite.h"
+#include "HBAResultRead.h"
+#include "Cache.h"
+
+#include <netinet/in.h>
+
+using namespace LOFAR;
+using namespace RSP;
+using namespace EPA_Protocol;
+
+HBAResultRead::HBAResultRead(GCFPortInterface& board_port, int board_id)
+  : SyncAction(board_port, board_id, StationSettings::instance()->nrBlpsPerBoard())
+{
+  memset(&m_hdr, 0, sizeof(MEPHeader));
+}
+
+HBAResultRead::~HBAResultRead()
+{
+  /* TODO: delete event? */
+}
+
+void HBAResultRead::sendrequest()
+{
+  uint8 global_rcu = (getBoardId() * StationSettings::instance()->nrRcusPerBoard()) + getCurrentIndex();
+
+  // skip update if the RCU settings have not been applied yet
+  if (RTC::RegisterState::READ != Cache::getInstance().getState().hbaprotocol().get(global_rcu)) {
+    setContinue(true);
+    return;
+  }
+
+  // set appropriate header
+  MEPHeader::FieldsType hdr;
+  if (0 == global_rcu % MEPHeader::N_POL) {
+    hdr = MEPHeader::RCU_RESULTX_HDR;
+  } else {
+    hdr = MEPHeader::RCU_RESULTY_HDR;
+  }
+
+  EPAReadEvent rcuresult;
+  rcuresult.hdr.set(hdr, 1 << (getCurrentIndex() / MEPHeader::N_POL), MEPHeader::READ, sizeof(HBAProtocolWrite::i2c_result));
+  
+  m_hdr = rcuresult.hdr; // remember header to match with ack
+  getBoardPort().send(rcuresult);
+}
+
+void HBAResultRead::sendrequest_status()
+{
+  // intentionally left empty
+}
+
+GCFEvent::TResult HBAResultRead::handleack(GCFEvent& event, GCFPortInterface& /*port*/)
+{
+  if (EPA_RCU_RESULT != event.signal)
+  {
+    LOG_WARN("HBAResultRead::handleack:: unexpected ack");
+    return GCFEvent::NOT_HANDLED;
+  }
+  
+  EPARcuResultEvent ack(event);
+
+  uint8 global_rcu = (getBoardId() * StationSettings::instance()->nrRcusPerBoard()) + getCurrentIndex();
+
+  if (!ack.hdr.isValidAck(m_hdr))
+  {
+    LOG_ERROR("HBAResultRead::handleack: invalid ack");
+    Cache::getInstance().getState().hbaprotocol().read_error(global_rcu);
+    return GCFEvent::HANDLED;
+  }
+
+  // reverse and copy control bytes into i2c_result
+  RCUSettings::Control& rcucontrol = Cache::getInstance().getBack().getRCUSettings()()((global_rcu));
+  uint32 control = htonl(rcucontrol.getRaw());
+  memcpy(HBAProtocolWrite::i2c_result + 1, &control, 3);
+
+  if (0 == memcmp(HBAProtocolWrite::i2c_result, ack.result, sizeof(HBAProtocolWrite::i2c_result))) {
+    Cache::getInstance().getState().hbaprotocol().read_ack(global_rcu);
+  } else {
+    LOG_WARN("HBAResultRead::handleack: unexpected I2C result response");
+    Cache::getInstance().getState().hbaprotocol().read_error(global_rcu);
+  }
+
+  return GCFEvent::HANDLED;
+}
diff --git a/MAC/APL/PIC/RSPDriver/src/HBAResultRead.h b/MAC/APL/PIC/RSPDriver/src/HBAResultRead.h
new file mode 100644
index 00000000000..7405aced20d
--- /dev/null
+++ b/MAC/APL/PIC/RSPDriver/src/HBAResultRead.h
@@ -0,0 +1,67 @@
+//#  -*- mode: c++ -*-
+//#
+//#  HBAResultRead.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 HBARESULTREAD_H_
+#define HBARESULTREAD_H_
+
+#include <APL/RSP_Protocol/MEPHeader.h>
+
+#include "SyncAction.h"
+
+namespace LOFAR {
+  namespace RSP {
+
+    class HBAResultRead : public SyncAction
+    {
+    public:
+      /**
+       * Constructors for a HBAResultRead object.
+       */
+      HBAResultRead(GCFPortInterface& board_port, int board_id);
+
+      /* Destructor for HBAResultRead. */
+      virtual ~HBAResultRead();
+
+      /**
+       * 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;
+    };
+  };
+};
+     
+#endif /* HBARESULTREAD_H_ */
diff --git a/MAC/APL/PIC/RSPDriver/src/RSPDriver.cc b/MAC/APL/PIC/RSPDriver/src/RSPDriver.cc
index 56bc1322eed..d14790e2bc3 100644
--- a/MAC/APL/PIC/RSPDriver/src/RSPDriver.cc
+++ b/MAC/APL/PIC/RSPDriver/src/RSPDriver.cc
@@ -57,6 +57,9 @@
 #include "SetRCUCmd.h"
 #include "GetRCUCmd.h"
 #include "UpdRCUCmd.h"
+#include "SetHBACmd.h"
+#include "GetHBACmd.h"
+#include "UpdHBACmd.h"
 #include "SetRSUCmd.h"
 #include "SetWGCmd.h"
 #include "GetWGCmd.h"
@@ -80,6 +83,8 @@
 #include "RCUWrite.h"
 #include "RCUProtocolWrite.h"
 #include "RCUResultRead.h"
+#include "HBAProtocolWrite.h"
+#include "HBAResultRead.h"
 #include "RCURead.h"
 #include "StatusRead.h"
 #include "SstRead.h"
@@ -302,7 +307,8 @@ bool RSPDriver::isEnabled()
  * - STATUS (RSP Status): read RSP status info  // StatusRead
  * - BF:      write beamformer weights          // BWWrite
  * - SS:      write subband selection settings  // SSWrite
- * - RCU:     write RCU control settings        // RCUWrite/RCUProtocolWrite
+ * - RCU:     write RCU control settings        // RCUWrite/RCUProtocolWrite/RCUResultRead
+ * - HBA:     write HBA control settings        // HBAProtocolWrite/HBAResultRead
  * - TDS:     write TDS control settings        // TDSProtocolWrite/TDSResultRead
  * - SST:     read subband statistics           // SstRead
  * - BST:     read beamlet statistics           // BstRead
@@ -616,6 +622,22 @@ void RSPDriver::addAllSyncActions()
       m_scheduler.addSyncAction(rcuresultread);
     }
 
+    // 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);
+    }
+
+    if (1 == GET_CONFIG("RSPDriver.READ_HBA_RESULT", i))
+    {
+      HBAResultRead* hbaresultread = new HBAResultRead(m_board[boardid], boardid);
+      ASSERT(hbaresultread);
+      m_scheduler.addSyncAction(hbaresultread);
+    }
+
   } // for (boardid...)
 }
 
@@ -936,6 +958,22 @@ GCFEvent::TResult RSPDriver::enabled(GCFEvent& event, GCFPortInterface& port)
       rsp_unsubrcu(event, port);
       break;
       
+    case RSP_SETHBA:
+      rsp_sethba(event, port);
+      break;
+
+    case RSP_GETHBA:
+      rsp_gethba(event, port);
+      break;
+      
+    case RSP_SUBHBA:
+      rsp_subhba(event, port);
+      break;
+      
+    case RSP_UNSUBHBA:
+      rsp_unsubhba(event, port);
+      break;
+      
     case RSP_SETRSU:
       rsp_setrsu(event, port);
       break;
@@ -1563,6 +1601,126 @@ void RSPDriver::rsp_unsubrcu(GCFEvent& event, GCFPortInterface& port)
   port.send(ack);
 }
 
+//
+// rsp_sethba(event,port)
+//
+void RSPDriver::rsp_sethba(GCFEvent& event, GCFPortInterface& port)
+{
+  Ptr<SetHBACmd> command = new SetHBACmd(event, port, Command::WRITE);
+
+  if (!command->validate())
+  {
+    LOG_ERROR("SETHBA: invalid parameter");
+    
+    RSPSethbaackEvent ack;
+    ack.timestamp = Timestamp(0,0);
+    ack.status = FAILURE;
+    port.send(ack);
+    return;
+  }
+
+  // if timestamp == Timestamp(0,0) apply changes immediately
+  if (Timestamp(0,0) == command->getTimestamp())
+  {
+    LOG_INFO("applying HBA control immediately");
+    command->apply(Cache::getInstance().getFront(), true);
+    command->apply(Cache::getInstance().getBack(), false);
+  }
+  else
+  {
+    (void)m_scheduler.enter(Ptr<Command>(&(*command)));
+  }
+  command->ack(Cache::getInstance().getFront());
+}
+
+//
+// rsp_gethba(event,port)
+//
+void RSPDriver::rsp_gethba(GCFEvent& event, GCFPortInterface& port)
+{
+  Ptr<GetHBACmd> command = new GetHBACmd(event, port, Command::READ);
+
+  if (!command->validate())
+  {
+    LOG_ERROR("GETHBA: invalid parameter");
+    
+    RSPGethbaackEvent ack;
+    ack.timestamp = Timestamp(0,0);
+    ack.status = FAILURE;
+    ack.settings().resize(1);
+    port.send(ack);
+    return;
+  }
+  
+  // if null timestamp get value from the cache and acknowledge immediately
+  if ( (Timestamp(0,0) == command->getTimestamp())
+       && (true == command->readFromCache()))
+  {
+    command->setTimestamp(Cache::getInstance().getFront().getTimestamp());
+    command->ack(Cache::getInstance().getFront());
+  }
+  else
+  {
+    (void)m_scheduler.enter(Ptr<Command>(&(*command)));
+  }
+}
+
+//
+// rsp_subhba(event,port)
+//
+void RSPDriver::rsp_subhba(GCFEvent& event, GCFPortInterface& port)
+{
+  // subscription is done by entering a UpdHBACmd in the periodic queue
+  Ptr<UpdHBACmd> command = new UpdHBACmd(event, port, Command::READ);
+  RSPSubhbaackEvent ack;
+
+  if (!command->validate())
+  {
+    LOG_ERROR("SUBHBA: invalid parameter");
+    
+    ack.timestamp = m_scheduler.getCurrentTime();
+    ack.status = FAILURE;
+    ack.handle = 0;
+
+    port.send(ack);
+    return;
+  }
+  else
+  {
+    ack.timestamp = m_scheduler.getCurrentTime();
+    ack.status = SUCCESS;
+    ack.handle = (uint32)&(*command);
+    port.send(ack);
+  }
+
+  (void)m_scheduler.enter(Ptr<Command>(&(*command)),
+                          Scheduler::PERIODIC);
+}
+
+//
+// rsp_unsubhba(event,port)
+//
+void RSPDriver::rsp_unsubhba(GCFEvent& event, GCFPortInterface& port)
+{
+  RSPUnsubhbaEvent unsub(event);
+
+  RSPUnsubhbaackEvent ack;
+  ack.timestamp = m_scheduler.getCurrentTime();
+  ack.status = FAILURE;
+  ack.handle = unsub.handle;
+
+  if (m_scheduler.remove_subscription(port, unsub.handle) > 0)
+  {
+    ack.status = SUCCESS;
+  }
+  else
+  {
+    LOG_ERROR("UNSUBHBA: failed to remove subscription");
+  }
+
+  port.send(ack);
+}
+
 //
 // rsp_setrsu(event,port)
 //
@@ -1572,7 +1730,7 @@ void RSPDriver::rsp_setrsu(GCFEvent& event, GCFPortInterface& port)
 
   if (!command->validate())
   {
-    LOG_ERROR("SETRCU: invalid parameter");
+    LOG_ERROR("SETRSU: invalid parameter");
     
     RSPSetrsuackEvent ack;
     ack.timestamp = Timestamp(0,0);
diff --git a/MAC/APL/PIC/RSPDriver/src/RSPDriver.h b/MAC/APL/PIC/RSPDriver/src/RSPDriver.h
index 0d62fdef692..53974b11a9f 100644
--- a/MAC/APL/PIC/RSPDriver/src/RSPDriver.h
+++ b/MAC/APL/PIC/RSPDriver/src/RSPDriver.h
@@ -122,6 +122,11 @@ namespace LOFAR {
       void rsp_subrcu  (GCFEvent& event, GCFPortInterface &port);
       void rsp_unsubrcu(GCFEvent& event, GCFPortInterface &port);
 
+      void rsp_sethba  (GCFEvent& event, GCFPortInterface &port);
+      void rsp_gethba  (GCFEvent& event, GCFPortInterface &port);
+      void rsp_subhba  (GCFEvent& event, GCFPortInterface &port);
+      void rsp_unsubhba(GCFEvent& event, GCFPortInterface &port);
+
       void rsp_setrsu  (GCFEvent& event, GCFPortInterface &port);
 
       void rsp_setwg(GCFEvent& event, GCFPortInterface &port);
diff --git a/MAC/APL/PIC/RSPDriver/src/SetHBACmd.cc b/MAC/APL/PIC/RSPDriver/src/SetHBACmd.cc
new file mode 100644
index 00000000000..b34095a9e2c
--- /dev/null
+++ b/MAC/APL/PIC/RSPDriver/src/SetHBACmd.cc
@@ -0,0 +1,99 @@
+//#  SetHBACmd.cc: implementation of the SetHBACmd 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 <APL/RSP_Protocol/RSP_Protocol.ph>
+#include <APL/RTCCommon/PSAccess.h>
+#include <blitz/array.h>
+
+#include "StationSettings.h"
+#include "SetHBACmd.h"
+
+using namespace blitz;
+using namespace LOFAR;
+using namespace RSP;
+using namespace RSP_Protocol;
+using namespace RTC;
+
+SetHBACmd::SetHBACmd(GCFEvent& event, GCFPortInterface& port, Operation oper)
+{
+  m_event = new RSPSethbaEvent(event);
+
+  setOperation(oper);
+  setPeriod(0);
+  setPort(port);
+}
+
+SetHBACmd::~SetHBACmd()
+{
+  delete m_event;
+}
+
+void SetHBACmd::ack(CacheBuffer& /*cache*/)
+{
+  RSPSethbaackEvent ack;
+
+  ack.timestamp = getTimestamp();
+  ack.status = SUCCESS;
+  
+  getPort()->send(ack);
+}
+
+void SetHBACmd::apply(CacheBuffer& cache, bool setModFlag)
+{
+  for (int cache_rcu = 0;
+       cache_rcu < StationSettings::instance()->nrRcus(); cache_rcu++) {
+    if (m_event->rcumask[cache_rcu]) {
+      cache.getHBASettings()()(cache_rcu) = m_event->settings()(0);
+      if (setModFlag) {
+	// reset BS if needed
+	cache.getCache().getState().bs().write(cache_rcu / MEPHeader::N_POL);
+
+        cache.getCache().getState().hbaprotocol().write(cache_rcu);
+      }
+    }
+  }
+}
+
+void SetHBACmd::complete(CacheBuffer& /*cache*/)
+{
+  LOG_INFO_STR("SetHBACmd completed at time=" << getTimestamp());
+}
+
+const Timestamp& SetHBACmd::getTimestamp() const
+{
+  return m_event->timestamp;
+}
+
+void SetHBACmd::setTimestamp(const Timestamp& timestamp)
+{
+  m_event->timestamp = timestamp;
+}
+
+bool SetHBACmd::validate() const
+{
+  return ((m_event->rcumask.count() <= (unsigned int)StationSettings::instance()->nrRcus())
+	  && (1 == m_event->settings().dimensions())
+	  && (1 == m_event->settings().extent(firstDim)));
+}
diff --git a/MAC/APL/PIC/RSPDriver/src/SetHBACmd.h b/MAC/APL/PIC/RSPDriver/src/SetHBACmd.h
new file mode 100644
index 00000000000..6f2cde743d2
--- /dev/null
+++ b/MAC/APL/PIC/RSPDriver/src/SetHBACmd.h
@@ -0,0 +1,87 @@
+//#  -*- mode: c++ -*-
+//#
+//#  SetHBACmd.h: Beamformer Weights settings command.
+//#
+//#  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 SETHBACMD_H_
+#define SETHBACMD_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 SetHBACmd : public Command
+    {
+    public:
+      /**
+       * Constructors for a SetHBACmd object.
+       */
+      SetHBACmd(GCFEvent& event, GCFPortInterface& port, Operation oper);
+	  
+      /* Destructor for SetHBACmd. */
+      virtual ~SetHBACmd();
+
+      /**
+       * 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);
+      /*@}*/
+
+      /**
+       * Validate the event that underlies the command.
+       */
+      virtual bool validate() const;
+
+    private:
+      SetHBACmd();
+
+      RSPSethbaEvent* m_event;
+    };
+  };
+};
+     
+#endif /* SETHBACMD_H_ */
diff --git a/MAC/APL/PIC/RSPDriver/src/UpdHBACmd.cc b/MAC/APL/PIC/RSPDriver/src/UpdHBACmd.cc
new file mode 100644
index 00000000000..4ff206294c5
--- /dev/null
+++ b/MAC/APL/PIC/RSPDriver/src/UpdHBACmd.cc
@@ -0,0 +1,139 @@
+//#  UpdHBACmd.cc: implementation of the UpdHBACmd 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 <APL/RSP_Protocol/RSP_Protocol.ph>
+#include <APL/RTCCommon/PSAccess.h>
+#include <blitz/array.h>
+
+#include "StationSettings.h"
+#include "UpdHBACmd.h"
+
+using namespace blitz;
+using namespace LOFAR;
+using namespace RSP;
+using namespace RSP_Protocol;
+using namespace RTC;
+
+//
+// UpdHBACmd(event, port, oper)
+//
+UpdHBACmd::UpdHBACmd(GCFEvent& event, GCFPortInterface& port, Operation oper)
+{
+  // Constructor of UpdHBACmd is only called on a SubHBAEvent
+  // convert event to Subhba event
+  m_event = new RSPSubhbaEvent(event);
+
+  setOperation(oper);
+  setPeriod(m_event->period);
+  setPort(port);
+}
+
+//
+// ~UpdHBACmd()
+//
+UpdHBACmd::~UpdHBACmd()
+{
+  // delete our own event again
+  delete m_event;
+}
+
+//
+// ack(cache)
+//
+void UpdHBACmd::ack(CacheBuffer& /*cache*/)
+{
+  // intentionally left empty
+}
+
+//
+// apply(cache)
+//
+void UpdHBACmd::apply(CacheBuffer& /*cache*/, bool /*setModFlag*/)
+{
+  // no-op
+}
+
+//
+// complete(cache)
+//
+void UpdHBACmd::complete(CacheBuffer& cache)
+{
+  // construct ack message
+  RSPUpdhbaEvent ack;
+
+  ack.timestamp = getTimestamp();
+  ack.status 	  = SUCCESS;
+  ack.handle 	  = (uint32)this; // opaque ptr used to refer to the subscr.
+
+  // Allocate room in subbands array
+  ack.settings().resize(m_event->rcumask.count());
+
+  // loop over RCU's to get the results.
+  int result_rcu = 0;
+  for (int cache_rcu = 0; cache_rcu < StationSettings::instance()->nrRcus(); cache_rcu++) {
+
+    if (m_event->rcumask[cache_rcu]) {
+      if (cache_rcu < StationSettings::instance()->nrRcus()) {
+	ack.settings()(result_rcu)=cache.getHBASettings()()(cache_rcu);
+      }
+      else {
+	LOG_WARN(
+		 formatString("invalid RCU index %d, there are only %d RCU's",
+			      cache_rcu, StationSettings::instance()->nrRcus())); 
+      }
+
+      result_rcu++;
+    }
+  }
+
+  // Finally send the answer
+  getPort()->send(ack);
+}
+
+//
+// getTimestamp()
+//
+const Timestamp& UpdHBACmd::getTimestamp() const
+{
+  return m_event->timestamp;
+}
+
+//
+// setTimestamp(timestamp)
+//
+void UpdHBACmd::setTimestamp(const Timestamp& timestamp)
+{
+  m_event->timestamp = timestamp;
+}
+
+//
+// validate()
+//
+bool UpdHBACmd::validate() const
+{
+  // check ranges
+  return ((m_event->rcumask.count() <= 
+	   (unsigned int)StationSettings::instance()->nrRcus()));
+}
diff --git a/MAC/APL/PIC/RSPDriver/src/UpdHBACmd.h b/MAC/APL/PIC/RSPDriver/src/UpdHBACmd.h
new file mode 100644
index 00000000000..e7b14437761
--- /dev/null
+++ b/MAC/APL/PIC/RSPDriver/src/UpdHBACmd.h
@@ -0,0 +1,87 @@
+//#  -*- mode: c++ -*-
+//#
+//#  UpdHBACmd.h: HBA setting upd command.
+//#
+//#  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 UPDHBACMD_H_
+#define UPDHBACMD_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 UpdHBACmd : public Command
+    {
+    public:
+      /**
+       * Constructors for a UpdHBACmd object.
+       */
+      UpdHBACmd(GCFEvent& event, GCFPortInterface& port, Operation oper);
+	  
+      /* Destructor for UpdHBACmd. */
+      virtual ~UpdHBACmd();
+
+      /**
+       * 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;
+
+    private:
+      UpdHBACmd();
+
+      RSPSubhbaEvent* m_event;
+    };
+  };
+};
+     
+#endif /* UPDHBACMD_H_ */
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 c5f6720c9ec..6f48d86a57e 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
@@ -69,6 +69,7 @@ namespace LOFAR {
 	  ss_state.resize(nrBlps);
 	  rcusettings_state.resize(nrRcus);
 	  rcuprotocol_state.resize(nrRcus);
+	  hbaprotocol_state.resize(nrRcus);
 	  rsuclear_state.resize(nrRspBoards);
 	  diagwgsettings_state.resize(nrRcus);
 	  sst_state.resize(nrBlps);
@@ -87,6 +88,7 @@ namespace LOFAR {
 	  ss_state.write_force();
 	  rcusettings_state.write_force();
 	  rcuprotocol_state.write_force();
+	  hbaprotocol_state.write_force();
 	  rsuclear_state.write_force();
 	  diagwgsettings_state.write_force();
 	  sst_state.read();
@@ -103,6 +105,7 @@ namespace LOFAR {
 	  ss_state.write_force();
 	  rcusettings_state.check();
 	  rcuprotocol_state.check();
+	  hbaprotocol_state.check();
 	  rsuclear_state.check();
 	  diagwgsettings_state.check();
 	  sst_state.read();
@@ -119,6 +122,7 @@ namespace LOFAR {
 	  ss_state.clear();
 	  rcusettings_state.clear();
 	  rcuprotocol_state.clear();
+	  hbaprotocol_state.clear();
 	  rsuclear_state.clear();
 	  diagwgsettings_state.clear();
 	  sst_state.clear();
@@ -140,6 +144,7 @@ namespace LOFAR {
 	  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);
@@ -170,13 +175,14 @@ namespace LOFAR {
 	RTC::RegisterState& ss()             { return ss_state; }
 	RTC::RegisterState& rcusettings()    { return rcusettings_state; }
 	RTC::RegisterState& rcuprotocol()    { return rcuprotocol_state; }
+	RTC::RegisterState& hbaprotocol()    { return hbaprotocol_state; }
 	RTC::RegisterState& rsuclear()       { return rsuclear_state; }
 	RTC::RegisterState& diagwgsettings() { return diagwgsettings_state; }
 	RTC::RegisterState& sst()            { return sst_state; }
 	RTC::RegisterState& bst()            { return bst_state; }
 	RTC::RegisterState& xst()            { return xst_state; }
 	RTC::RegisterState& cdo()            { return cdo_state; }
-	RTC::RegisterState& bs()            { return bs_state; }
+	RTC::RegisterState& bs()             { return bs_state; }
 	RTC::RegisterState& tds()            { return tds_state; }
 	/*@}*/
 
@@ -186,6 +192,7 @@ namespace LOFAR {
 	RTC::RegisterState ss_state;             // SS state
 	RTC::RegisterState rcusettings_state;    // RCU settings state
 	RTC::RegisterState rcuprotocol_state;    // RCU protocol state
+	RTC::RegisterState hbaprotocol_state;    // HBA protocol state
 	RTC::RegisterState rsuclear_state;       // RSU clear state
 	RTC::RegisterState diagwgsettings_state; // DIAG WG settings state
 	RTC::RegisterState sst_state;            // SST state
diff --git a/MAC/APL/PIC/RSP_Protocol/include/APL/RSP_Protocol/HBASettings.h b/MAC/APL/PIC/RSP_Protocol/include/APL/RSP_Protocol/HBASettings.h
new file mode 100644
index 00000000000..b234e193d36
--- /dev/null
+++ b/MAC/APL/PIC/RSP_Protocol/include/APL/RSP_Protocol/HBASettings.h
@@ -0,0 +1,68 @@
+//#  -*- mode: c++ -*-
+//#
+//#  HBASettings.h: HBA control information
+//#
+//#  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 HBASETTINGS_H_
+#define HBASETTINGS_H_
+
+#include <APL/RSP_Protocol/EPA_Protocol.ph>
+//#include <APL/RTCCommon/RegisterState.h>
+
+#include <complex>
+#include <blitz/array.h>
+#include <Common/LofarTypes.h>
+
+namespace LOFAR {
+  namespace RSP_Protocol {
+
+    class HBASettings
+    {
+    public:
+
+      HBASettings() {}
+      virtual ~HBASettings() {}
+
+      /* get HBA delay settings array */
+      blitz::Array<uint8, 2>& operator()();
+
+    public:
+
+      /*@{*/
+      /**
+       * marshalling methods
+       */
+      unsigned int getSize();
+      unsigned int pack  (void* buffer);
+      unsigned int unpack(void *buffer);
+      /*@}*/
+
+    private:
+      // two dimensional (nRcus x MEPHeader::N_HBA_DELAYS)
+      blitz::Array<uint8, 2> m_delay;
+    };
+  
+    inline blitz::Array<uint8, 2>& HBASettings::operator()() { return m_delay; }
+  };
+}; // namespace LOFAR
+
+#endif /* HBASETTINGS_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 121d4f3ca2e..e9af170228f 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
@@ -226,6 +226,8 @@ namespace LOFAR {
       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 XLET_SIZE        = N_POL * sizeof(std::complex<uint32>);
+
+      static const uint16 N_HBA_DELAYS     = 16; // number of High Band antenna delay elements
  
       //
       // Registers too large to send in a single ethernet frame
diff --git a/MAC/APL/PIC/RSP_Protocol/include/APL/RSP_Protocol/Makefile.am b/MAC/APL/PIC/RSP_Protocol/include/APL/RSP_Protocol/Makefile.am
index 623f956af4d..d69b7a83c75 100644
--- a/MAC/APL/PIC/RSP_Protocol/include/APL/RSP_Protocol/Makefile.am
+++ b/MAC/APL/PIC/RSP_Protocol/include/APL/RSP_Protocol/Makefile.am
@@ -3,6 +3,7 @@ INSTHDRS = \
 	MEPData.h \
 	BeamletWeights.h \
 	RCUSettings.h \
+	HBASettings.h \
 	RSUSettings.h \
 	Statistics.h \
 	SubbandSelection.h \
diff --git a/MAC/APL/PIC/RSP_Protocol/include/APL/RSP_Protocol/RCUSettings.h b/MAC/APL/PIC/RSP_Protocol/include/APL/RSP_Protocol/RCUSettings.h
index aed0dfdfda9..0e171a2a42b 100644
--- a/MAC/APL/PIC/RSP_Protocol/include/APL/RSP_Protocol/RCUSettings.h
+++ b/MAC/APL/PIC/RSP_Protocol/include/APL/RSP_Protocol/RCUSettings.h
@@ -114,7 +114,8 @@ namespace LOFAR {
 	 *
 	 * 0x01000000 PRSG        pseudo random sequence generator on (1), off (0)
 	 * 0x02000000 RESET       on (1) hold board in reset
-	 * 0xFC000000 TBD         reserved
+	 * 0x04000000 ENABLE      enable RCU input
+	 * 0xF8000000 TBD         reserved
 	 */
 	void   setRaw(uint32 raw) { m_value = raw; }
 	uint32 getRaw() const { return m_value; }
@@ -155,8 +156,8 @@ namespace LOFAR {
 	 * Enable (true) or disable (false) spectral inversion.
 	 */
 	void setSpecinv(bool value) {
-	  if (value) m_value |= SPECINV_MASK;  // set RESET bit
-	  else       m_value &= ~SPECINV_MASK; // clear RESET bit
+	  if (value) m_value |= SPECINV_MASK;  // set SPECINV bit
+	  else       m_value &= ~SPECINV_MASK; // clear SPECINV bit
 	}
 	bool getSpecinv() const { return m_value & SPECINV_MASK; }
 
@@ -169,6 +170,15 @@ namespace LOFAR {
 	}
 	uint8 getDelay() const { return m_value & DELAY_MASK; }
 
+	/**
+	 * Set rcu enable (0 = disable, 1 = enable)
+	 */
+	void setEnable(uint8 value) {
+	  if (value) m_value |= ENABLE_MASK;  // set ENABLE bit
+	  else       m_value &= ~ENABLE_MASK; // clear ENABLE bit
+	}
+	bool getEnable() const { return m_value & ENABLE_MASK; }
+
       private:
 
 	// constants used to set the appropriate mode
@@ -181,6 +191,7 @@ namespace LOFAR {
 	static const uint32 RESET_MASK   = 0x02000000;
 	static const uint32 SPECINV_MASK = 0x00000080;
 	static const uint32 DELAY_MASK   = 0x0000007F;
+	static const uint32 ENABLE_MASK  = 0x04000000;
 
 	uint32 m_value;
       };
@@ -188,8 +199,6 @@ namespace LOFAR {
       /* get reference settings array */
       blitz::Array<Control, 1>& operator()();
 
-      //RTC::RegisterState& getState();
-
     public:
 
       /*@{*/
@@ -203,13 +212,9 @@ namespace LOFAR {
 
     private:
       blitz::Array<Control, 1> m_registers;
-
-      //RTC::RegisterState       m_state;
     };
   
     inline blitz::Array<RCUSettings::Control, 1>& RCUSettings::operator()() { return m_registers; }
-    //inline RTC::RegisterState& RCUSettings::getState()                      { return m_state; }
-
   };
 }; // namespace LOFAR
 
diff --git a/MAC/APL/PIC/RSP_Protocol/src/AllRegisterState.cc b/MAC/APL/PIC/RSP_Protocol/src/AllRegisterState.cc
index 7e4e029fff1..56ed581cfbd 100644
--- a/MAC/APL/PIC/RSP_Protocol/src/AllRegisterState.cc
+++ b/MAC/APL/PIC/RSP_Protocol/src/AllRegisterState.cc
@@ -39,6 +39,7 @@ unsigned int AllRegisterState::getSize()
     + ss_state.getSize()
     + rcusettings_state.getSize()
     + rcuprotocol_state.getSize()
+    + hbaprotocol_state.getSize()
     + rsuclear_state.getSize()
     + diagwgsettings_state.getSize()
     + sst_state.getSize()
@@ -58,6 +59,7 @@ unsigned int AllRegisterState::pack  (void* buffer)
   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);
@@ -79,6 +81,7 @@ unsigned int AllRegisterState::unpack(void *buffer)
   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);
diff --git a/MAC/APL/PIC/RSP_Protocol/src/EPA_Protocol.prot b/MAC/APL/PIC/RSP_Protocol/src/EPA_Protocol.prot
index 7f629b5cc75..70db71c1d4d 100644
--- a/MAC/APL/PIC/RSP_Protocol/src/EPA_Protocol.prot
+++ b/MAC/APL/PIC/RSP_Protocol/src/EPA_Protocol.prot
@@ -198,9 +198,9 @@ prelude = << PRELUDE_END
   typedef struct RCUHandler
   {
     uint8 input_delay_x:7; // input delay for X-receiver
-    uint8 ffi0         :1;
+    uint8 enable_x     :1; // enable X-receiver data output
     uint8 input_delay_y:7; // input delay for Y-receiver
-    uint8 ffi1         :1;
+    uint8 enable_y     :1; // enable Y-receiver data output
   };
 
   typedef struct CRControl
diff --git a/MAC/APL/PIC/RSP_Protocol/src/HBASettings.cc b/MAC/APL/PIC/RSP_Protocol/src/HBASettings.cc
new file mode 100644
index 00000000000..d2102bf7cf3
--- /dev/null
+++ b/MAC/APL/PIC/RSP_Protocol/src/HBASettings.cc
@@ -0,0 +1,55 @@
+//#  HBASettings.h: implementation of the HBASettings 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 <APL/RSP_Protocol/HBASettings.h>
+#include <APL/RTCCommon/Marshalling.h>
+
+using namespace std;
+using namespace blitz;
+using namespace LOFAR;
+using namespace RSP_Protocol;
+
+unsigned int HBASettings::getSize()
+{
+  return MSH_ARRAY_SIZE(m_delay, uint8);
+}
+
+unsigned int HBASettings::pack  (void* buffer)
+{
+  unsigned int offset = 0;
+  
+  MSH_PACK_ARRAY(buffer, offset, m_delay, uint8);
+
+  return offset;
+}
+
+unsigned int HBASettings::unpack(void *buffer)
+{
+  unsigned int offset = 0;
+
+  MSH_UNPACK_ARRAY(buffer, offset, m_delay, uint8, 2);
+
+  return offset;
+}
diff --git a/MAC/APL/PIC/RSP_Protocol/src/Makefile.am b/MAC/APL/PIC/RSP_Protocol/src/Makefile.am
index 4151494b7b1..9e6ad47f703 100644
--- a/MAC/APL/PIC/RSP_Protocol/src/Makefile.am
+++ b/MAC/APL/PIC/RSP_Protocol/src/Makefile.am
@@ -35,6 +35,7 @@ librsp_protocol_la_SOURCES = \
 	$(BUILT_SOURCES) \
 	BeamletWeights.cc \
 	RCUSettings.cc \
+	HBASettings.cc \
 	RSUSettings.cc \
 	Statistics.cc \
 	SubbandSelection.cc \
diff --git a/MAC/APL/PIC/RSP_Protocol/src/RSP_Protocol.prot b/MAC/APL/PIC/RSP_Protocol/src/RSP_Protocol.prot
index 11f62f5c78a..1dc3b8b3a4a 100644
--- a/MAC/APL/PIC/RSP_Protocol/src/RSP_Protocol.prot
+++ b/MAC/APL/PIC/RSP_Protocol/src/RSP_Protocol.prot
@@ -18,6 +18,7 @@ include = '<APL/RTCCommon/Timestamp.h>';
 include = '<APL/RSP_Protocol/BeamletWeights.h>';
 include = '<APL/RSP_Protocol/SubbandSelection.h>';
 include = '<APL/RSP_Protocol/RCUSettings.h>';
+include = '<APL/RSP_Protocol/HBASettings.h>';
 include = '<APL/RSP_Protocol/RSUSettings.h>';
 include = '<APL/RSP_Protocol/WGSettings.h>';
 include = '<APL/RSP_Protocol/SystemStatus.h>';
@@ -1239,3 +1240,163 @@ event = {
     type = "uint32";
   };
 };
+
+//
+// HBA Control
+//
+event = {
+  signal = SETHBA;
+  dir = IN;
+  param = {
+    name = "timestamp";
+    type = "RTC::Timestamp";
+    userdefined;
+  };
+  param = {
+    name = "rcumask";
+    type = "std::bitset<MAX_N_RCUS>";
+  };
+  param = {
+    name = "settings";
+    type = "HBASettings";
+    userdefined;
+  };
+};
+
+event = {
+  signal = SETHBAACK;
+  dir = OUT;
+  param = {
+    name = "timestamp";
+    type = "RTC::Timestamp";
+    userdefined;
+  };
+  param = {
+    name = "status";
+    type = "int16";
+  };
+};
+
+event = {
+  signal = GETHBA;
+  dir = IN;
+  param = {
+    name = "timestamp";
+    type = "RTC::Timestamp";
+    userdefined;
+  };
+  param = {
+    name = "rcumask";
+    type = "std::bitset<MAX_N_RCUS>";
+  };
+  param = {
+    name = "cache";
+    type = "uint8";
+  };
+};
+
+event = {
+  signal = GETHBAACK;
+  dir = OUT;
+  param = {
+    name = "timestamp";
+    type = "RTC::Timestamp";
+    userdefined;
+  };
+  param = {
+    name = "status";
+    type = "int16";
+  };
+  param = {
+    name = "settings";
+    type = "HBASettings";
+    userdefined;
+  };
+};
+
+event = {
+  signal = SUBHBA;
+  dir = IN;
+  param = {
+    name = "timestamp";
+    type = "RTC::Timestamp";
+    userdefined;
+  };
+  param = {
+    name = "rcumask";
+    type = "std::bitset<MAX_N_RCUS>";
+  };
+  param = {
+    name = "period";
+    type = "uint16";
+  };
+};
+
+event = {
+  signal = SUBHBAACK;
+  dir = OUT;
+  param = {
+    name = "timestamp";
+    type = "RTC::Timestamp";
+    userdefined;
+  };
+  param = {
+    name = "status";
+    type = "int16";
+  };
+  param = {
+    name = "handle";
+    type = "uint32";
+  };
+};
+
+event = {
+  signal = UPDHBA;
+  dir = OUT;
+  param = {
+    name = "timestamp";
+    type = "RTC::Timestamp";
+    userdefined;
+  };
+  param = {
+    name = "status";
+    type = "int16";
+  };
+  param = {
+    name = "handle";
+    type = "uint32";
+  };
+  param = {
+    name = "settings";
+    type = "HBASettings";
+    userdefined;
+  };
+};
+
+event = {
+  signal = UNSUBHBA;
+  dir = IN;
+  param = {
+    name = "handle";
+    type = "uint32";
+  };
+};
+
+event = {
+  signal = UNSUBHBAACK;
+  dir = OUT;
+  param = {
+    name = "timestamp";
+    type = "RTC::Timestamp";
+    userdefined;
+  };
+  param = {
+    name = "status";
+    type = "int16";
+  };
+  param = {
+    name = "handle";
+    type = "uint32";
+  };
+};
+
-- 
GitLab